1    	/* $netbsd: svc.h,v 1.17 2000/06/02 22:57:56 fvdl Exp $ */
2    	
3    	/*
4    	 * Copyright (c) 2009, Sun Microsystems, Inc.
5    	 * Copyright (c) 2012-2018 Red Hat, Inc. and/or its affiliates.
6    	 * All rights reserved.
7    	 *
8    	 * Redistribution and use in source and binary forms, with or without
9    	 * modification, are permitted provided that the following conditions are met:
10   	 * - Redistributions of source code must retain the above copyright notice,
11   	 *   this list of conditions and the following disclaimer.
12   	 * - Redistributions in binary form must reproduce the above copyright notice,
13   	 *   this list of conditions and the following disclaimer in the documentation
14   	 *   and/or other materials provided with the distribution.
15   	 * - Neither the name of Sun Microsystems, Inc. nor the names of its
16   	 *   contributors may be used to endorse or promote products derived
17   	 *   from this software without specific prior written permission.
18   	 *
19   	 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20   	 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21   	 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22   	 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23   	 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24   	 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25   	 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26   	 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27   	 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28   	 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29   	 * POSSIBILITY OF SUCH DAMAGE.
30   	 *
31   	 * from: @(#)svc.h 1.35 88/12/17 SMI
32   	 * from: @(#)svc.h      1.27    94/04/25 SMI
33   	 * $FreeBSD: src/include/rpc/svc.h,v 1.24 2003/06/15 10:32:01 mbr Exp $
34   	 */
35   	
36   	/*
37   	 * svc.h, Server-side remote procedure call interface.
38   	 *
39   	 * Copyright (C) 1986-1993 by Sun Microsystems, Inc.
40   	 */
41   	
42   	#ifndef _TIRPC_SVC_H
43   	#define _TIRPC_SVC_H
44   	
45   	#include <sys/cdefs.h>
46   	#include <rpc/rpc_msg.h>
47   	#include <rpc/types.h>
48   	#include <rpc/work_pool.h>
49   	#include <misc/portable.h>
50   	#include "reentrant.h"
51   	#if defined(HAVE_BLKIN)
52   	#include <blkin/zipkin_c.h>
53   	#endif
54   	#ifdef USE_LTTNG_NTIRPC
55   	#include "lttng/xprt.h"
56   	#endif
57   	
58   	typedef struct svc_xprt SVCXPRT;
59   	
60   	enum xprt_stat {
61   		XPRT_IDLE = 0,
62   		XPRT_MOREREQS,
63   		XPRT_SUSPEND,
64   		/* always last in this order for comparisons */
65   		XPRT_DIED,
66   		XPRT_DESTROYED
67   	};
68   	
69   	/*
70   	 * This interface must manage two items concerning remote procedure calling:
71   	 *
72   	 * 1) An arbitrary number of transport connections upon which rpc requests
73   	 * are received.  The two most notable transports are TCP and UDP;  they are
74   	 * created and registered by routines in svc_vc.c and svc_dg.c, respectively.
75   	 *
76   	 * 2) An arbitrary number of locally registered services.  Services are
77   	 * described by the following four data: program number, version number,
78   	 * "service dispatch" function, a transport handle, and a boolean that
79   	 * indicates whether or not the exported program should be registered with a
80   	 * local binder service;  if true the program's number and version and the
81   	 * port number from the transport handle are registered with the binder.
82   	 * These data are registered with the rpc svc system via svc_reg.
83   	 *
84   	 * A service's dispatch function is called whenever an rpc request comes in
85   	 * on a transport.  The request's program and version numbers must match
86   	 * those of the registered service.  The dispatch function is passed two
87   	 * parameters, struct svc_req * and SVCXPRT *, defined below.
88   	 */
89   	
90   	/* Package init flags */
91   	#define SVC_INIT_DEFAULT        0x0000
92   	#define SVC_INIT_XPRTS          0x0001
93   	#define SVC_INIT_EPOLL          0x0002
94   	#define SVC_INIT_NOREG_XPRTS    0x0008
95   	#define SVC_INIT_BLKIN          0x0010
96   	
97   	#define SVC_SHUTDOWN_FLAG_NONE  0x0000
98   	
99   	/*
100  	 *      Service control requests
101  	 */
102  	#define SVCGET_VERSQUIET        1
103  	#define SVCSET_VERSQUIET        2
104  	#define SVCGET_CONNMAXREC       3
105  	#define SVCSET_CONNMAXREC       4
106  	#define SVCGET_XP_FLAGS         7
107  	#define SVCSET_XP_FLAGS         8
108  	#define SVCGET_XP_FREE_USER_DATA        15
109  	#define SVCSET_XP_FREE_USER_DATA        16
110  	
111  	/*
112  	 * Operations for rpc_control().
113  	 */
114  	#define RPC_SVC_CONNMAXREC_SET  0	/* set max rec size, enable nonblock */
115  	#define RPC_SVC_CONNMAXREC_GET  1
116  	#define RPC_SVC_XPRTS_GET       2
117  	#define RPC_SVC_XPRTS_SET       3
118  	#define RPC_SVC_FDSET_GET       4
119  	#define RPC_SVC_FDSET_SET       5
120  	
121  	typedef enum xprt_stat (*svc_xprt_fun_t) (SVCXPRT *);
122  	typedef struct svc_req *(*svc_xprt_alloc_fun_t) (SVCXPRT *, XDR *);
123  	typedef void (*svc_xprt_free_fun_t) (struct svc_req *, enum xprt_stat);
124  	
125  	typedef struct svc_init_params {
126  		svc_xprt_fun_t disconnect_cb;
127  		svc_xprt_alloc_fun_t alloc_cb;
128  		svc_xprt_free_fun_t free_cb;
129  	
130  		u_long flags;
131  		u_int max_connections;	/* xprts */
132  		u_int max_events;	/* evchan events */
133  		u_int ioq_send_max;
134  		u_int ioq_thrd_max;
135  		u_int ioq_thrd_min;
136  		u_int gss_ctx_hash_partitions;
137  		u_int gss_max_ctx;
138  		u_int gss_max_idle_gen;
139  		u_int gss_max_gc;
140  		uint32_t channels;
141  		int32_t idle_timeout;
142  	} svc_init_params;
143  	
144  	/* Svc param flags */
145  	#define SVC_FLAG_NONE             0x0000
146  	#define SVC_FLAG_NOREG_XPRTS      0x0001
147  	
148  	/*
149  	 * SVCXPRT xp_flags
150  	 */
151  	
152  	#define SVC_XPRT_FLAG_NONE		0x0000
153  	/* uint16_t actually used */
154  	#define SVC_XPRT_FLAG_ADDED		0x0001
155  	
156  	#define SVC_XPRT_FLAG_INITIAL		0x0004
157  	#define SVC_XPRT_FLAG_INITIALIZED	0x0008
158  	#define SVC_XPRT_FLAG_CLOSE		0x0010
159  	#define SVC_XPRT_FLAG_DESTROYING	0x0020	/* SVC_DESTROY() was called */
160  	#define SVC_XPRT_FLAG_RELEASING		0x0040	/* (*xp_destroy) was called */
161  	#define SVC_XPRT_FLAG_UREG		0x0080
162  	
163  	#define SVC_XPRT_FLAG_DESTROYED (SVC_XPRT_FLAG_DESTROYING \
164  					| SVC_XPRT_FLAG_RELEASING)
165  	
166  	/* uint32_t instructions */
167  	#define SVC_XPRT_FLAG_LOCKED		0x00010000
168  	#define SVC_XPRT_FLAG_UNLOCK		0x00020000
169  	
170  	/*
171  	 * SVC_REF flags
172  	 */
173  	
174  	#define SVC_REF_FLAG_NONE		SVC_XPRT_FLAG_NONE
175  	#define SVC_REF_FLAG_LOCKED		SVC_XPRT_FLAG_LOCKED
176  	
177  	/*
178  	 * SVC_RELEASE flags
179  	 */
180  	
181  	#define SVC_RELEASE_FLAG_NONE		SVC_XPRT_FLAG_NONE
182  	#define SVC_RELEASE_FLAG_LOCKED		SVC_XPRT_FLAG_LOCKED
183  	
184  	/* Don't confuse with (currently incomplete) transport type, nee socktype.
185  	 */
186  	typedef enum xprt_type {
187  		XPRT_UNKNOWN = 0,
188  		XPRT_NON_RENDEZVOUS,
189  		XPRT_UDP,
190  		XPRT_UDP_RENDEZVOUS,
191  		XPRT_TCP,
192  		XPRT_TCP_RENDEZVOUS,
193  		XPRT_SCTP,
194  		XPRT_SCTP_RENDEZVOUS,
195  		XPRT_RDMA,
196  		XPRT_RDMA_RENDEZVOUS,
197  		XPRT_VSOCK,
198  		XPRT_VSOCK_RENDEZVOUS
199  	} xprt_type_t;
200  	
201  	struct SVCAUTH;			/* forward decl. */
202  	struct svc_req;			/* forward decl. */
203  	
204  	typedef enum xprt_stat (*svc_req_fun_t) (struct svc_req *);
205  	
206  	/*
207  	 * Server side transport handle
208  	 */
209  	struct svc_xprt {
210  		struct xp_ops {
211  			/* receive incoming requests */
212  			svc_xprt_fun_t xp_recv;
213  	
214  			/* get transport status */
215  			svc_xprt_fun_t xp_stat;
216  	
217  			/* decode incoming message header (called by request_cb) */
218  			svc_req_fun_t xp_decode;
219  	
220  			/* send reply */
221  			svc_req_fun_t xp_reply;
222  	
223  			/* optional checksum (after authentication/decryption) */
224  			void (*xp_checksum) (struct svc_req *, void *, size_t);
225  	
226  			/* actually destroy after xp_destroy_it and xp_release_it */
227  			void (*xp_destroy) (SVCXPRT *, u_int, const char *, const int);
228  	
229  			/* catch-all function */
230  			bool (*xp_control) (SVCXPRT *, const u_int, void *);
231  	
232  			/* free client user data */
233  			svc_xprt_fun_t xp_free_user_data;
234  		} *xp_ops;
235  	
236  		/* handle incoming connections (per xp_fd) */
237  		union {
238  			svc_req_fun_t process_cb;
239  			svc_xprt_fun_t rendezvous_cb;
240  		}  xp_dispatch;
241  		/* Handle resumed requests */
242  		svc_req_fun_t xp_resume_cb;
243  		SVCXPRT *xp_parent;
244  	
245  		char *xp_tp;		/* transport provider device name */
246  		char *xp_netid;		/* network token */
247  	
248  		void *xp_p1;		/* private: for use by svc ops */
249  		void *xp_p2;		/* private: for use by svc ops */
250  		void *xp_p3;		/* private: for use by svc lib */
251  		void *xp_u1;		/* client user data */
252  		void *xp_u2;		/* client user data */
253  	
254  		struct rpc_address xp_local;	/* local address, length, port */
255  		struct rpc_address xp_remote;	/* remote address, length, port */
256  	
257  	#if defined(HAVE_BLKIN)
258  		/* blkin tracing */
259  		struct {
260  			char *svc_name;
261  			struct blkin_endpoint endp;
262  		} blkin;
263  	#endif
264  		/* serialize private data */
265  		mutex_t xp_lock;
266  	
267  		int xp_fd;
268  		int xp_ifindex;		/* interface index */
269  		int xp_si_type;		/* si type */
270  		int xp_type;		/* xprt type */
271  	
272  		int32_t xp_refcnt;	/* handle reference count */
273  		uint16_t xp_flags;	/* flags */
274  	};
275  	
276  	/* Service record used by exported search routines */
277  	typedef struct svc_record {
278  		rpcprog_t sc_prog;
279  		rpcvers_t sc_vers;
280  		char *sc_netid;
281  		void (*sc_dispatch) (struct svc_req *);
282  	} svc_rec_t;
283  	
284  	typedef struct svc_vers_range {
285  		rpcvers_t lowvers;
286  		rpcvers_t highvers;
287  	} svc_vers_range_t;
288  	
289  	typedef enum svc_lookup_result {
290  		SVC_LKP_SUCCESS = 0,
291  		SVC_LKP_PROG_NOTFOUND = 1,
292  		SVC_LKP_VERS_NOTFOUND = 2,
293  		SVC_LKP_NETID_NOTFOUND = 3,
294  		SVC_LKP_ERR = 667,
295  	} svc_lookup_result_t;
296  	
297  	/*
298  	 * Service request
299  	 */
300  	struct svc_req {
301  		SVCXPRT *rq_xprt;	/* associated transport */
302  	
303  		/* New with TI-RPC */
304  		char *rq_clntname;	/* read only client name */
305  		char *rq_svcname;	/* read only cooked service cred */
306  	
307  		/* New with N TI-RPC */
308  		XDR *rq_xdrs;
309  		void *rq_u1;		/* user data */
310  		void *rq_u2;		/* user data */
311  		uint64_t rq_cksum;
312  	
313  		/* Moved in N TI-RPC */
314  		struct SVCAUTH *rq_auth;	/* auth handle */
315  		void *rq_ap1;		/* auth private */
316  		void *rq_ap2;		/* auth private */
317  	
318  		/* avoid separate alloc/free */
319  		struct rpc_msg rq_msg;
320  	
321  	#if defined(HAVE_BLKIN)
322  		/* blkin tracing */
323  		struct blkin_trace bl_trace;
324  	#endif
325  		uint32_t rq_refcnt;
326  	};
327  	
328  	/*
329  	 *  Approved way of getting addresses
330  	 */
331  	#define svc_getcaller_netbuf(x) (&(x)->xp_remote.nb)
332  	#define svc_getlocal_netbuf(x) (&(x)->xp_local.nb)
333  	#define svc_getrpccaller(x) (&(x)->xp_remote.ss)
334  	#define svc_getrpclocal(x) (&(x)->xp_local.ss)
335  	
336  	extern void svc_resume(struct svc_req *req);
337  	
338  	/*
339  	 * Ganesha.  Get connected transport type.
340  	 */
341  	#define svc_get_xprt_type(x) ((x)->xp_type)
342  	
343  	/*
344  	 * Ganesha.  Original TI-RPC si type.
345  	 */
346  	#define svc_get_xprt_si_type(x) ((x)->xp_si_type)
347  	
348  	/*
349  	 * Trace transport (de-)references, with remote address
350  	 */
351  	__BEGIN_DECLS
352  	extern void svc_xprt_trace(SVCXPRT *, const char *, const char *, const int);
353  	__END_DECLS
354  	
355  	#define XPRT_TRACE(xprt, func, tag, line)				 \
356  		if (__ntirpc_pkg_params.debug_flags & TIRPC_DEBUG_FLAG_REFCNT) { \
357  			svc_xprt_trace((xprt), (func), (tag), (line));		 \
358  		}
359  	
360  	/*
361  	 * Operations defined on an SVCXPRT handle
362  	 *
363  	 * SVCXPRT *xprt;
364  	 * struct svc_req *req;
365  	 */
366  	#define SVC_RECV(xprt) \
367  		(*(xprt)->xp_ops->xp_recv)(xprt)
368  	
369  	#define SVC_STAT(xprt) \
370  		(*(xprt)->xp_ops->xp_stat)(xprt)
371  	
372  	#define SVC_DECODE(req) \
373  		(*((req)->rq_xprt)->xp_ops->xp_decode)(req)
374  	
375  	#define SVC_REPLY(req) \
376  		(*((req)->rq_xprt)->xp_ops->xp_reply)(req)
377  	
378  	#define SVC_CHECKSUM(req, what, length) \
379  		if (((req)->rq_xprt)->xp_ops->xp_checksum) \
380  			(*((req)->rq_xprt)->xp_ops->xp_checksum)(req, what, length)
381  	
382  	/* Protect a SVCXPRT with SVC_REF() for each call, request, or task thread.
383  	 */
384  	static inline void svc_ref_it(SVCXPRT *xprt, u_int flags,
385  				      const char *tag, const int line)
386  	{
387  	#ifdef USE_LTTNG_NTIRPC
388  		int32_t refs =
389  	#endif /* USE_LTTNG_NTIRPC */
390  			atomic_inc_int32_t(&xprt->xp_refcnt);
391  	
392  		if (flags & SVC_REF_FLAG_LOCKED)  {
393  			/* unlock before warning trace */
394  			mutex_unlock(&xprt->xp_lock);
395  		}
396  		XPRT_TRACE(xprt, __func__, tag, line);
397  	#ifdef USE_LTTNG_NTIRPC
398  		tracepoint(xprt, ref, tag, line, xprt, refs);
399  	#endif /* USE_LTTNG_NTIRPC */
400  	}
401  	#define SVC_REF2(xprt, flags, tag, line)				\
402  		svc_ref_it(xprt, flags, tag, line)
403  	#define SVC_REF(xprt, flags)						\
404  		svc_ref_it(xprt, flags, __func__, __LINE__)
405  	
406  	/* SVC_RELEASE() the SVC_REF().
407  	 * Idempotent SVC_XPRT_FLAG_DESTROYED (bit SVC_XPRT_FLAG_RELEASING)
408  	 * indicates that more references should not be taken.
409  	 */
410  	static inline void svc_release_it(SVCXPRT *xprt, u_int flags,
411  					  const char *tag, const int line)
412  	{
413  		int32_t refs = atomic_dec_int32_t(&xprt->xp_refcnt);
414  		uint16_t xp_flags;
415  	
416  		if (flags & SVC_RELEASE_FLAG_LOCKED) {
417  			/* unlock before warning trace */
(1) Event unlock: "pthread_mutex_unlock" unlocks "xprt->xp_lock".
(1) Event unlock: "pthread_mutex_unlock" unlocks "xprt->xp_lock".
418  			mutex_unlock(&xprt->xp_lock);
419  		}
420  		XPRT_TRACE(xprt, __func__, tag, line);
421  	#ifdef USE_LTTNG_NTIRPC
422  		tracepoint(xprt, unref, tag, line, xprt, refs);
423  	#endif /* USE_LTTNG_NTIRPC */
424  	
425  		if (likely(refs > 0)) {
426  			/* normal case */
427  			return;
428  		}
429  	
430  		/* enforce once-only semantic, trace others */
431  		xp_flags = atomic_postset_uint16_t_bits(&xprt->xp_flags,
432  							SVC_XPRT_FLAG_RELEASING);
433  	
434  		if (xp_flags & SVC_XPRT_FLAG_RELEASING) {
435  			XPRT_TRACE(xprt, "WARNING! already destroying!", tag, line);
436  			return;
437  		}
438  	
439  		/* Releasing last reference */
440  		(*(xprt)->xp_ops->xp_destroy)(xprt, flags, tag, line);
441  	}
442  	#define SVC_RELEASE2(xprt, flags, tag, line)				\
443  		svc_release_it(xprt, flags, __func__, __LINE__)
444  	#define SVC_RELEASE(xprt, flags)					\
445  		svc_release_it(xprt, flags, __func__, __LINE__)
446  	
447  	/* SVC_DESTROY() is SVC_RELEASE() with once-only semantics.
448  	 * Idempotent SVC_XPRT_FLAG_DESTROYED (bit SVC_XPRT_FLAG_DESTROYING)
449  	 * indicates that more references should not be taken.
450  	 */
451  	static inline void svc_destroy_it(SVCXPRT *xprt,
452  					  const char *tag, const int line)
453  	{
454  		uint16_t flags = atomic_postset_uint16_t_bits(&xprt->xp_flags,
455  							      SVC_XPRT_FLAG_DESTROYING);
456  	
457  		XPRT_TRACE(xprt, __func__, tag, line);
458  	
459  		if (flags & SVC_XPRT_FLAG_DESTROYING) {
460  			/* previously set, do nothing */
461  			return;
462  		}
463  	
(1) Event unlock: "svc_release_it" unlocks "xprt->xp_lock". [details]
464  		svc_release_it(xprt, SVC_RELEASE_FLAG_NONE, tag, line);
465  	}
466  	#define SVC_DESTROY(xprt)						\
467  		svc_destroy_it(xprt, __func__, __LINE__)
468  	
469  	#define SVC_CONTROL(xprt, rq, in)					\
470  		(*(xprt)->xp_ops->xp_control)((xprt), (rq), (in))
471  	
472  	/*
473  	 * Service init (optional).
474  	 */
475  	
476  	__BEGIN_DECLS
477  	extern struct work_pool svc_work_pool;
478  	
479  	bool svc_init(struct svc_init_params *);
480  	__END_DECLS
481  	/*
482  	 * Service shutdown (optional).
483  	 */
484  	__BEGIN_DECLS
485  	int svc_shutdown(u_long flags);
486  	__END_DECLS
487  	/*
488  	 * Service registration
489  	 *
490  	 * svc_reg(xprt, prog, vers, dispatch, nconf)
491  	 * const SVCXPRT *xprt;
492  	 * const rpcprog_t prog;
493  	 * const rpcvers_t vers;
494  	 * const void (*dispatch)();
495  	 * const struct netconfig *nconf;
496  	 */
497  	__BEGIN_DECLS
498  	extern bool svc_reg(SVCXPRT *, const rpcprog_t, const rpcvers_t,
499  			    void (*)(struct svc_req *),
500  			    const struct netconfig *);
501  	__END_DECLS
502  	/*
503  	 * Service un-registration
504  	 *
505  	 * svc_unreg(prog, vers)
506  	 * const rpcprog_t prog;
507  	 * const rpcvers_t vers;
508  	 */
509  	__BEGIN_DECLS
510  	extern void svc_unreg(const rpcprog_t, const rpcvers_t);
511  	__END_DECLS
512  	/*
513  	 * This is used to set local and remote addresses in a way legacy
514  	 * apps can deal with, at the same time setting up a corresponding
515  	 * netbuf -- with no alloc/free needed.
516  	 */
517  	__BEGIN_DECLS
518  	extern u_int __rpc_address_port(struct rpc_address *);
519  	extern void __rpc_address_set_length(struct rpc_address *, socklen_t);
520  	
521  	static inline void
522  	__rpc_address_setup(struct rpc_address *rpca)
523  	{
524  		rpca->nb.buf = &rpca->ss;
525  		rpca->nb.len =
526  		rpca->nb.maxlen = sizeof(struct sockaddr_storage);
527  	}
528  	__END_DECLS
529  	/*
530  	 * When the service routine is called, it must first check to see if it
531  	 * knows about the procedure;  if not, it should call svcerr_noproc
532  	 * and return.  If so, it should deserialize its arguments via
533  	 * SVC_GETARGS (defined above).  If the deserialization does not work,
534  	 * svcerr_decode should be called followed by a return.  Successful
535  	 * decoding of the arguments should be followed the execution of the
536  	 * procedure's code and a call to svc_sendreply.
537  	 *
538  	 * Also, if the service refuses to execute the procedure due to too-
539  	 * weak authentication parameters, svcerr_weakauth should be called.
540  	 * Note: do not confuse access-control failure with weak authentication!
541  	 *
542  	 * NB: In pure implementations of rpc, the caller always waits for a reply
543  	 * msg.  This message is sent when svc_sendreply is called.
544  	 * Therefore pure service implementations should always call
545  	 * svc_sendreply even if the function logically returns void;  use
546  	 * xdr.h - xdr_void for the xdr routine.  HOWEVER, tcp based rpc allows
547  	 * for the abuse of pure rpc via batched calling or pipelining.  In the
548  	 * case of a batched call, svc_sendreply should NOT be called since
549  	 * this would send a return message, which is what batching tries to avoid.
550  	 * It is the service/protocol writer's responsibility to know which calls are
551  	 * batched and which are not.  Warning: responding to batch calls may
552  	 * deadlock the caller and server processes!
553  	 */
554  	__BEGIN_DECLS
555  	extern enum xprt_stat svc_sendreply(struct svc_req *);
556  	extern enum xprt_stat svcerr_decode(struct svc_req *);
557  	extern enum xprt_stat svcerr_weakauth(struct svc_req *);
558  	extern enum xprt_stat svcerr_noproc(struct svc_req *);
559  	extern enum xprt_stat svcerr_progvers(struct svc_req *, rpcvers_t, rpcvers_t);
560  	extern enum xprt_stat svcerr_auth(struct svc_req *, enum auth_stat);
561  	extern enum xprt_stat svcerr_noprog(struct svc_req *);
562  	extern enum xprt_stat svcerr_systemerr(struct svc_req *);
563  	extern int rpc_reg(rpcprog_t, rpcvers_t, rpcproc_t, char *(*)(char *),
564  			   xdrproc_t, xdrproc_t, char *);
565  	__END_DECLS
566  	/*
567  	 * a small program implemented by the svc_rpc implementation itself;
568  	 * also see clnt.h for protocol numbers.
569  	 */
570  	__BEGIN_DECLS
571  	extern void rpctest_service(void);
572  	__END_DECLS
573  	/*
574  	 * Socket to use on svcxxx_ncreate call to get default socket
575  	 */
576  	#define RPC_ANYSOCK -1
577  	#define RPC_ANYFD RPC_ANYSOCK
578  	/*
579  	 * Usual sizes for svcxxx_ncreate
580  	 */
581  	#define RPC_MAXDATA_DEFAULT (8192)
582  	#define RPC_MAXDATA_LEGACY (262144)
583  	/*
584  	 * These are the existing service side transport implementations
585  	 */
586  	__BEGIN_DECLS
587  	/*
588  	 * Transport independent svc_create routine.
589  	 */
590  	extern int svc_ncreate(void (*)(struct svc_req *), const rpcprog_t,
591  			       const rpcvers_t, const char *);
592  	/*
593  	 *      void (*dispatch)();             -- dispatch routine
594  	 *      const rpcprog_t prognum;        -- program number
595  	 *      const rpcvers_t versnum;        -- version number
596  	 *      const char *nettype;            -- network type
597  	 */
598  	
599  	/*
600  	 * Generic server creation routine. It takes a netconfig structure
601  	 * instead of a nettype.
602  	 */
603  	
604  	extern SVCXPRT *svc_tp_ncreate(void (*)(struct svc_req *),
605  				       const rpcprog_t, const rpcvers_t,
606  				       const struct netconfig *);
607  	/*
608  	 * void (*dispatch)();            -- dispatch routine
609  	 * const rpcprog_t prognum;       -- program number
610  	 * const rpcvers_t versnum;       -- version number
611  	 * const struct netconfig *nconf; -- netconfig structure
612  	 */
613  	
614  	/*
615  	 * Generic TLI create routine
616  	 */
617  	extern SVCXPRT *svc_tli_ncreate(const int, const struct netconfig *,
618  					const struct t_bind *, const u_int,
619  					const u_int);
620  	/*
621  	 *      const int fd;                   -- connection end point
622  	 *      const struct netconfig *nconf;  -- netconfig structure for network
623  	 *      const struct t_bind *bindaddr;  -- local bind address
624  	 *      const u_int sendsz;             -- max sendsize
625  	 *      const u_int recvsz;             -- max recvsize
626  	 */
627  	__END_DECLS
628  	
629  	/*
630  	 * Connectionless and connectionful create routines
631  	 */
632  	
633  	/* uint16_t actually used */
634  	#define SVC_CREATE_FLAG_NONE		SVC_XPRT_FLAG_NONE
635  	#define SVC_CREATE_FLAG_CLOSE		SVC_XPRT_FLAG_CLOSE
636  	
637  	/* uint32_t instructions */
638  	#define SVC_CREATE_FLAG_LISTEN		0x20000000
639  	#define SVC_CREATE_FLAG_XPRT_DOREG	0x80000000
640  	#define SVC_CREATE_FLAG_XPRT_NOREG	0x08000000
641  	
642  	__BEGIN_DECLS
643  	
644  	extern SVCXPRT *svc_vc_ncreatef(const int, const u_int, const u_int,
645  					const uint32_t);
646  	/*
647  	 *      const int fd;                           -- open connection end point
648  	 *      const u_int sendsize;                   -- max send size
649  	 *      const u_int recvsize;                   -- max recv size
650  	 *      const u_int flags;                      -- flags
651  	 */
652  	
653  	static inline SVCXPRT *
654  	svc_vc_ncreate(const int fd, const u_int sendsize, const u_int recvsize)
655  	{
656  		return (svc_vc_ncreatef(fd, sendsize, recvsize, SVC_CREATE_FLAG_CLOSE));
657  	}
658  	
659  	extern SVCXPRT *svc_dg_ncreatef(const int, const u_int, const u_int,
660  					const uint32_t);
661  	/*
662  	 *      const int fd;                           -- open connection end point
663  	 *      const u_int sendsize;                   -- max send size
664  	 *      const u_int recvsize;                   -- max recv size
665  	 *      const uint32_t flags;                   -- flags
666  	 */
667  	
668  	static inline SVCXPRT *
669  	svc_dg_ncreate(const int fd, const u_int sendsize, const u_int recvsize)
670  	{
671  		return (svc_dg_ncreatef(fd, sendsize, recvsize, SVC_CREATE_FLAG_CLOSE));
672  	}
673  	
674  	/*
675  	 * the routine takes any *open* connection
676  	 */
677  	extern SVCXPRT *svc_fd_ncreatef(const int, const u_int, const u_int,
678  					const uint32_t);
679  	/*
680  	 *      const int fd;                           -- open connection end point
681  	 *      const u_int sendsize;                   -- max send size
682  	 *      const u_int recvsize;                   -- max recv size
683  	 *      const uint32_t flags;                   -- flags
684  	 */
685  	
686  	static inline SVCXPRT *
687  	svc_fd_ncreate(const int fd, const u_int sendsize, const u_int recvsize)
688  	{
689  		return (svc_fd_ncreatef(fd, sendsize, recvsize, SVC_CREATE_FLAG_NONE));
690  	}
691  	
692  	/*
693  	 * Memory based rpc (for speed check and testing)
694  	 */
695  	extern SVCXPRT *svc_raw_ncreate(void);
696  	
697  	/*
698  	 * RPC over RDMA
699  	 */
700  	struct rpc_rdma_attr {
701  		char *statistics_prefix;
702  		/* silly char * to pass to rdma_getaddrinfo() */
703  		char *node;			/**< remote peer's hostname */
704  		char *port;			/**< service port (or name) */
705  	
706  		u_int sq_depth;			/**< depth of Send Queue */
707  		u_int max_send_sge;		/**< s/g elements per send */
708  		u_int rq_depth;			/**< depth of Receive Queue. */
709  		u_int max_recv_sge;		/**< s/g elements per recv */
710  	
711  		u_int backlog;			/**< connection backlog */
712  		u_int credits;			/**< parallel messages */
713  	
714  		bool destroy_on_disconnect;	/**< should perform cleanup */
715  		bool use_srq;			/**< server use srq? */
716  	};
717  	
718  	extern SVCXPRT *rpc_rdma_ncreatef(const struct rpc_rdma_attr *, const u_int,
719  					  const u_int, const uint32_t);
720  	/*
721  	 *      const struct rpc_rdma_attr;             -- RDMA configuration
722  	 *      const u_int sendsize;                   -- max send size
723  	 *      const u_int recvsize;                   -- max recv size
724  	 *      const uint32_t flags;                   -- flags
725  	 */
726  	
727  	static inline SVCXPRT *
728  	svc_rdma_ncreate(const struct rpc_rdma_attr *xa, const u_int sendsize,
729  			 const u_int recvsize)
730  	{
731  		return rpc_rdma_ncreatef(xa, sendsize, recvsize, SVC_CREATE_FLAG_CLOSE);
732  	}
733  	
734  	/*
735  	 * Convenience functions for implementing these
736  	 */
737  	extern bool svc_validate_xprt_list(SVCXPRT *);
738  	
739  	int __rpc_get_local_uid(SVCXPRT *, uid_t *);
740  	
741  	__END_DECLS
742  	/* for backward compatibility */
743  	#include <rpc/tirpc_compat.h>
744  	#endif				/* !_TIRPC_SVC_H */
745