xdrpp
RFC4506 XDR compiler and message library
srpc.cc
1 
2 #include <cerrno>
3 #include <cstring>
4 #include <iostream>
5 #include <unistd.h>
6 #include <xdrpp/exception.h>
7 #include <xdrpp/srpc.h>
8 
9 namespace xdr {
10 
11 bool xdr_trace_client = std::getenv("XDR_TRACE_CLIENT");
12 
13 msg_ptr
14 read_message(sock_t s)
15 {
16  std::uint32_t len;
17  ssize_t n = read(s, &len, 4);
18  if (n == -1)
19  throw xdr_system_error("xdr::read_message");
20  if (n < 4)
21  throw xdr_bad_message_size("read_message: premature EOF");
22  if (n & 3)
23  throw xdr_bad_message_size("read_message: received size not multiple of 4");
24  if (n >= 0x80000000)
25  throw xdr_bad_message_size("read_message: received size too big");
26 
27  len = swap32le(len);
28  if (len & 0x80000000)
29  len &= 0x7fffffff;
30  else
31  throw xdr_bad_message_size("read_message: message fragments unimplemented");
32 
33  msg_ptr m = message_t::alloc(len);
34  n = read(s, m->data(), len);
35  if (n == -1)
36  throw xdr_system_error("xdr::read_message");
37  if (n != len)
38  throw xdr_bad_message_size("read_message: premature EOF");
39 
40  return m;
41 }
42 
43 void
44 write_message(sock_t s, const msg_ptr &m)
45 {
46  ssize_t n = write(s, m->raw_data(), m->raw_size());
47  if (n == -1)
48  throw xdr_system_error("xdr::write_message");
49  // If this assertion fails, the file descriptor may have had
50  // O_NONBLOCK set, which is not allowed for the synchronous
51  // interface.
52  assert(std::size_t(n) == m->raw_size());
53 }
54 
55 uint32_t xid_counter;
56 
57 void
58 prepare_call(uint32_t prog, uint32_t vers, uint32_t proc, rpc_msg &hdr)
59 {
60  hdr.xid = ++xid_counter;
61  hdr.body.mtype(CALL);
62  hdr.body.cbody().rpcvers = 2;
63  hdr.body.cbody().prog = prog;
64  hdr.body.cbody().vers = vers;
65  hdr.body.cbody().proc = proc;
66 }
67 
68 void
70 {
71  for (;;)
72  dispatch(nullptr, read_message(s_),
73  std::bind(write_message, s_, std::placeholders::_1));
74 }
75 
76 }
static msg_ptr alloc(std::size_t size)
Allocate a new buffer.
Definition: marshal.cc:7
Most of the xdrpp library is encapsulated in the xdr namespace.
Definition: arpc.cc:4
Constexpr std::uint32_t swap32le(std::uint32_t v)
Byteswap 32-bit value only on little-endian machines, identity function on big-endian machines...
Definition: endian.h:78
Exceptions raised by RPC calls.
Simple synchronous RPC functions.
void run()
Start serving requests. (Loops until an exception.)
Definition: srpc.cc:69