7 bool xdr_trace_server = std::getenv(
"XDR_TRACE_SERVER");
10 rpc_accepted_error_msg(uint32_t xid, accept_stat stat)
12 assert(stat != SUCCESS && stat != PROG_MISMATCH);
26 rpc_prog_mismatch_msg(uint32_t xid, uint32_t low, uint32_t high)
43 rpc_auth_error_msg(uint32_t xid, auth_stat stat)
57 rpc_rpc_mismatch_msg(uint32_t xid)
73 rpc_server_base::register_service_base(service_base *s)
75 servers_[s->prog_][s->vers_].reset(s);
79 rpc_server_base::dispatch(
void *session, msg_ptr m, service_base::cb_t reply)
84 try { archive(g, hdr); }
85 catch (
const xdr_runtime_error &e) {
86 std::cerr <<
"rpc_server_base::dispatch: ignoring malformed header: " 87 << e.what() << std::endl;
90 if (hdr.body.mtype() != CALL) {
91 std::cerr <<
"rpc_server_base::dispatch: ignoring non-CALL" << std::endl;
95 if (hdr.body.cbody().rpcvers != 2)
96 return reply(rpc_rpc_mismatch_msg(hdr.xid));
98 auto prog = servers_.find(hdr.body.cbody().prog);
99 if (prog == servers_.end())
100 return reply(rpc_accepted_error_msg(hdr.xid, PROG_UNAVAIL));
102 auto vers = prog->second.find(hdr.body.cbody().vers);
103 if (vers == prog->second.end()) {
104 uint32_t low = prog->second.cbegin()->first;
105 uint32_t high = prog->second.crbegin()->first;
106 return reply(rpc_prog_mismatch_msg(hdr.xid, low, high));
110 vers->second->process(session, hdr, g, reply);
113 catch (
const xdr_runtime_error &e) {
114 std::cerr <<
"rpc_server_base::dispatch: " << e.what() << std::endl;
116 reply(rpc_accepted_error_msg(hdr.xid, GARBAGE_ARGS));
120 rpc_tcp_listener_common::rpc_tcp_listener_common(pollset &ps, unique_sock &&s,
122 : listen_sock_(s ?
std::move(s) :
tcp_listen()), use_rpcbind_(reg),
127 std::bind(&rpc_tcp_listener_common::accept_cb,
this));
130 rpc_tcp_listener_common::~rpc_tcp_listener_common()
137 rpc_tcp_listener_common::accept_cb()
139 sock_t s =
accept(listen_sock_.
get(),
nullptr, 0);
140 if (s == invalid_sock) {
141 std::cerr <<
"rpc_tcp_listener_common: accept: " <<
sock_errmsg()
146 rpc_sock *ms =
new rpc_sock(ps_, s);
147 ms->set_servcb(std::bind(&rpc_tcp_listener_common::receive_cb,
this, ms,
148 session_alloc(ms), std::placeholders::_1));
152 rpc_tcp_listener_common::receive_cb(rpc_sock *ms,
void *session, msg_ptr mp)
155 session_free(session);
160 dispatch(session, std::move(mp), rpc_sock_reply_t(ms));
162 catch (
const xdr_runtime_error &e) {
163 std::cerr << e.what() << std::endl;
164 session_free(session);
static msg_ptr alloc(std::size_t size)
Allocate a new buffer.
Specify interest in read-ready condition.
Most of the xdrpp library is encapsulated in the xdr namespace.
Classes for implementing RPC servers.
xdr_generic_get< marshal_swap > xdr_get
Archive for unmarshaling in RFC4506 big-endian order.
void fd_cb(sock_t s, op_t op, CB &&cb)
Set a read or write callback on a particular file descriptor.
sock_t accept(sock_t s, sockaddr *addr, socklen_t *addrlen)
Wrapper around accept for sock_t.
xdr_generic_put< marshal_swap > xdr_put
Archive for marshaling in RFC4506 big-endian order.
const char * sock_errmsg()
Last socket error message (strerror(errno) on POSIX).
unique_sock tcp_listen(const char *service, int family, int backlog)
Create bind a listening TCP socket.
sock_t get() const
Return the file descriptor number, but maintain ownership.
void set_close_on_exec(sock_t s)
Set the close-on-exec flag of a file descriptor.