3 #include <xdrpp/rpcb_prot.hh> 13 std::vector<rpcb> registered_services;
20 srpc_client<xdr::RPCBVERS4> c{fd.get()};
21 for (
const auto &arg : registered_services)
22 c.RPCBPROC_UNSET(arg);
31 once() { atexit(run_cleanup); }
43 for (
const addrinfo *ai = ail.get(); ai; ai = ai->ai_next) {
51 arg.r_netid = ai->ai_family == AF_INET6 ?
"tcp6" :
"tcp";
53 auto res = c.RPCBPROC_GETADDR(arg);
59 switch (ai->ai_family) {
61 ((sockaddr_in *) ai->ai_addr)->sin_port = htons(port);
64 ((sockaddr_in6 *) ai->ai_addr)->sin6_port = htons(port);
71 catch(
const std::system_error &) {}
73 throw std::system_error(std::make_error_code(std::errc::connection_refused),
74 "Could not obtain port from rpcbind");
80 std::size_t low = uaddr.rfind(
'.');
81 if (low == string::npos || low == 0)
83 std::size_t high = uaddr.rfind(
'.', low - 1);
84 if (high == string::npos)
88 int hb = std::stoi(uaddr.substr(high+1));
89 int lb = std::stoi(uaddr.substr(low+1));
90 if (hb < 0 || hb > 255 || lb < 0 || lb > 255)
94 catch (std::invalid_argument &) {
97 catch (std::out_of_range &) {
105 string host, portstr;
107 unsigned port = std::stoul(portstr);
108 if (port == 0 || port >= 65536)
109 throw std::system_error(std::make_error_code(std::errc::invalid_argument),
111 host +=
"." + std::to_string(port >> 8) +
"." + std::to_string(port & 0xff);
120 struct sockaddr_storage ss;
122 socklen_t salen{
sizeof ss};
123 std::memset(&ss, 0, salen);
124 if (getsockname(s.fd_, &sa, &salen) == -1)
131 std::uint32_t prog, std::uint32_t vers)
135 auto fd =
tcp_connect(
nullptr,
"sunrpc", sa->sa_family);
141 arg.r_netid = sa->sa_family == AF_INET6 ?
"tcp6" :
"tcp";
143 arg.r_owner = std::to_string(geteuid());
144 c.RPCBPROC_UNSET(arg);
145 auto res = c.RPCBPROC_SET(arg);
147 throw std::system_error(std::make_error_code(std::errc::address_in_use),
149 registered_services.push_back(arg);
157 struct sockaddr_storage ss;
159 socklen_t salen{
sizeof ss};
160 std::memset(&ss, 0, salen);
161 if (getsockname(s.fd_, &sa, &salen) == -1)
unique_sock tcp_connect(const addrinfo *ai)
Try connecting to every addrinfo in a list until one succeeds.
void throw_sockerr(const char *)
Throw a system_error exception for the last socket error.
unique_sock tcp_connect1(const addrinfo *ai, bool ndelay)
Try connecting to the first addrinfo in a linked list.
Most of the xdrpp library is encapsulated in the xdr namespace.
std::unique_ptr< addrinfo, delete_addrinfo > unique_addrinfo
Automatically garbage-collected addrinfo pointer.
Simple synchronous RPC functions.
unique_addrinfo get_addrinfo(const char *host, int socktype, const char *service, int family)
Wrapper around getaddrinfo that returns a garbage-collected xdr::unique_addrinfo. ...
int parse_uaddr_port(const string &uaddr)
Extract the port number from an RFC1833 / RFC5665 universal network address (uaddr).
Abstract away the type of a socket (for windows).
Support for registering and (upon exit) unregistering with rpcbind.
string make_uaddr(const sockaddr *sa, socklen_t salen)
Create a uaddr for a local address or file descriptor.
void rpcbind_register(const sockaddr *sa, socklen_t salen, std::uint32_t prog, std::uint32_t vers)
Register a service listening on sa with rpcbind.
unique_sock tcp_connect_rpc(const char *host, std::uint32_t prog, std::uint32_t vers, int family)
Create a TCP connection to an RPC server on host, first querying rpcbind on host to determine the por...
void get_numinfo(const sockaddr *sa, socklen_t salen, string *host, string *serv)
Return printable versions of numeric host and port number.
typename T::template _xdr_client< synchronous_client_base > srpc_client
Create an RPC client from an interface type and connected stream socket.