11 #ifndef _XDRPP_SERVER_H_HEADER_INCLUDED_ 12 #define _XDRPP_SERVER_H_HEADER_INCLUDED_ 1 19 #include <xdrpp/rpc_msg.hh> 24 extern bool xdr_trace_server;
32 static constexpr
bool valid =
true;
33 static constexpr
bool is_class =
true;
34 static constexpr
bool is_struct =
true;
35 static constexpr
bool has_fixed_size =
true;
36 static constexpr std::size_t fixed_size = 24;
40 template<
typename Archive>
static void save(Archive &a,
42 archive(a, t.xid,
"xid");
43 archive(a, REPLY,
"mtype");
44 archive(a, MSG_ACCEPTED,
"stat");
45 archive(a, AUTH_NONE,
"flavor");
46 archive(a, uint32_t(0),
"body");
47 archive(a, SUCCESS,
"stat");
52 msg_ptr rpc_accepted_error_msg(uint32_t xid, accept_stat stat);
53 msg_ptr rpc_prog_mismatch_msg(uint32_t xid, uint32_t low, uint32_t high);
54 msg_ptr rpc_auth_error_msg(uint32_t xid, auth_stat stat);
55 msg_ptr rpc_rpc_mismatch_msg(uint32_t xid);
64 using std::unique_ptr<T>::unique_ptr;
66 operator T &()
const {
return *this->
get(); }
67 operator T &&() {
return std::move(*this->
get()); }
71 template<typename T, bool fs = xdr_traits<T>::has_fixed_size>
73 static constexpr
bool has_fixed_size =
false;
75 template<
typename T>
struct transparent_ptr_base<T, true> :
xdr_traits_base {
76 static constexpr
bool has_fixed_size =
true;
82 : detail::transparent_ptr_base<T> {
84 using ptr_type = std::unique_ptr<T>;
86 static constexpr
bool is_class =
true;
88 template<
typename Archive>
static void save(Archive &a,
const ptr_type &p) {
91 template<
typename Archive>
static void load(Archive &a, ptr_type &p) {
94 static size_t serial_size(
const ptr_type &p) {
95 return t_traits::serial_size(*p);
100 template<
typename Archive,
typename T>
inline void 103 archive(ar, *t, name);
107 template<
typename T>
struct wrap_transparent_ptr_helper;
109 template<
typename...T>
110 struct wrap_transparent_ptr_helper<std::tuple<T...>> {
111 using type = std::tuple<transparent_ptr<T>...>;
118 typename detail::wrap_transparent_ptr_helper<T>::type;
122 template<
typename P,
typename C,
typename T,
typename I = all_indices_of<T>>
123 struct dispatch_session_helper;
125 template<
typename P,
typename C,
typename T, std::size_t...I>
126 struct dispatch_session_helper<P, C, T, indices<I...>> {
127 template<
typename S,
typename...Rest>
static auto 128 dispatch(C &&c, S *s, T &&t, Rest &&...rest) ->
129 typename std::enable_if<!std::is_same<S, void>::value,
130 decltype(P::dispatch(std::forward<C>(c), s,
131 std::get<I>(std::forward<T>(t))...,
132 std::forward<Rest>(rest)...))>::type
134 return P::dispatch(std::forward<C>(c), s,
135 std::get<I>(std::forward<T>(t))...,
136 std::forward<Rest>(rest)...);
141 template<
typename...Rest>
static auto 142 dispatch(C &&c,
void *, T &&t, Rest &&...rest) ->
143 decltype(P::dispatch(std::forward<C>(c), std::get<I>(std::forward<T>(t))...,
144 std::forward<Rest>(rest)...))
146 return P::dispatch(std::forward<C>(c), std::get<I>(std::forward<T>(t))...,
147 std::forward<Rest>(rest)...);
163 template<
typename P,
typename C,
typename S,
typename T,
164 typename...Rest>
inline auto 166 decltype(detail::dispatch_session_helper<P, C, T>::dispatch(
167 c, s, std::forward<T>(t), std::forward<Rest>(rest)...))
169 return detail::dispatch_session_helper<P, C, T>::dispatch(
170 std::forward<C>(c), s, std::forward<T>(t),
171 std::forward<Rest>(rest)...);
178 S *allocate(
rpc_sock *s) {
return new S{s}; }
179 void deallocate(S *session) {
delete session; }
183 void *allocate(
rpc_sock *s) {
return nullptr; }
184 void deallocate(
void *) {}
189 using cb_t = std::function<void(msg_ptr)>;
191 const uint32_t prog_;
192 const uint32_t vers_;
194 service_base(uint32_t prog, uint32_t vers) : prog_(prog), vers_(vers) {}
196 virtual void process(
void *session,
rpc_msg &hdr,
xdr_get &g, cb_t reply) = 0;
198 bool check_call(
const rpc_msg &hdr) {
199 return hdr.body.mtype() == CALL
200 && hdr.body.cbody().rpcvers == 2
201 && hdr.body.cbody().prog == prog_
202 && hdr.body.cbody().vers == vers_;
205 template<
typename T>
static bool decode_arg(
xdr_get &g, T &arg) {
219 std::map<uint32_t, std::unique_ptr<service_base>>> servers_;
223 void dispatch(
void *session, msg_ptr m, service_base::cb_t reply);
232 void receive_cb(
rpc_sock *ms,
void *session, msg_ptr mp);
236 const bool use_rpcbind_;
238 bool use_rpcbind =
false);
242 virtual void *session_alloc(
rpc_sock *) = 0;
243 virtual void session_free(
void *session) = 0;
249 template<
template<
typename,
typename,
typename>
class ServiceType,
250 typename Session,
typename SessionAllocator>
252 SessionAllocator sa_;
254 void *session_alloc(
rpc_sock *s)
override {
255 return sa_.allocate(s);
257 void session_free(
void *session)
override { sa_.deallocate(session); }
268 template<
typename T,
typename Interface =
typename T::rpc_
interface_type>
270 register_service_base(
new ServiceType<T,Session,Interface>(t));
280 #endif // !_XDRPP_SERVER_H_HEADER_INCLUDED_ Structure that gets marshalled as an RPC success header.
Most of the xdrpp library is encapsulated in the xdr namespace.
Archive type for unmarshaling from a buffer.
auto dispatch_with_session(C &&c, S *s, T &&t, Rest &&...rest) -> decltype(detail::dispatch_session_helper< P, C, T >::dispatch(c, s, std::forward< T >(t), std::forward< Rest >(rest)...))
Call P::dispatch with a session pointer (unless the session type S is void, in which case the argumen...
Structure to poll for a set of file descriptors and timeouts.
A wrapper around xdr::msg_sock that separates calls from replies.
Generic class of XDR unmarshaling errors.
Default xdr_traits values for actual XDR types, used as a supertype for most xdr::xdr_traits speciali...
Trivial session allocator that just calls new and delete.
Metadata for all marshalable XDR types.
Send and receive delimited messages over non-blocking sockets.
void register_service(T &t)
Add objects implementing RPC program interfaces to the server.
Support for registering and (upon exit) unregistering with rpcbind.
typename detail::wrap_transparent_ptr_helper< T >::type wrap_transparent_ptr
Wrap xdr::transparent_ptr around each type in a tuple to generate a new tuple type.
A pointer, but that gets marshalled as the underlying object and can convert to the underlying type...
Support for marshaling XDR types in the format specified by RFC4506.
Listens for connections on a TCP socket (optionally registering the socket with rpcbind), and then serves one or more program/version interfaces to accepted connections.
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.
Support for pretty-printing XDR data types.