]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/rpc/svc.h
NFS: Request use of TCP_USE_DDP for in-kernel TCP sockets
[FreeBSD/FreeBSD.git] / sys / rpc / svc.h
1 /*      $NetBSD: svc.h,v 1.17 2000/06/02 22:57:56 fvdl Exp $    */
2
3 /*-
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  * Copyright (c) 2009, Sun Microsystems, Inc.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without 
10  * modification, are permitted provided that the following conditions are met:
11  * - Redistributions of source code must retain the above copyright notice, 
12  *   this list of conditions and the following disclaimer.
13  * - Redistributions in binary form must reproduce the above copyright notice, 
14  *   this list of conditions and the following disclaimer in the documentation 
15  *   and/or other materials provided with the distribution.
16  * - Neither the name of Sun Microsystems, Inc. nor the names of its 
17  *   contributors may be used to endorse or promote products derived 
18  *   from this software without specific prior written permission.
19  * 
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 
24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 /*
34  * svc.h, Server-side remote procedure call interface.
35  *
36  * Copyright (C) 1986-1993 by Sun Microsystems, Inc.
37  */
38
39 #ifndef _RPC_SVC_H
40 #define _RPC_SVC_H
41 #include <sys/cdefs.h>
42
43 #ifdef _KERNEL
44 #include <sys/queue.h>
45 #include <sys/_lock.h>
46 #include <sys/_mutex.h>
47 #include <sys/_sx.h>
48 #include <sys/condvar.h>
49 #include <sys/sysctl.h>
50 #endif
51
52 /*
53  * This interface must manage two items concerning remote procedure calling:
54  *
55  * 1) An arbitrary number of transport connections upon which rpc requests
56  * are received.  The two most notable transports are TCP and UDP;  they are
57  * created and registered by routines in svc_tcp.c and svc_udp.c, respectively;
58  * they in turn call xprt_register and xprt_unregister.
59  *
60  * 2) An arbitrary number of locally registered services.  Services are
61  * described by the following four data: program number, version number,
62  * "service dispatch" function, a transport handle, and a boolean that
63  * indicates whether or not the exported program should be registered with a
64  * local binder service;  if true the program's number and version and the
65  * port number from the transport handle are registered with the binder.
66  * These data are registered with the rpc svc system via svc_register.
67  *
68  * A service's dispatch function is called whenever an rpc request comes in
69  * on a transport.  The request's program and version numbers must match
70  * those of the registered service.  The dispatch function is passed two
71  * parameters, struct svc_req * and SVCXPRT *, defined below.
72  */
73
74 /*
75  *      Service control requests
76  */
77 #define SVCGET_VERSQUIET        1
78 #define SVCSET_VERSQUIET        2
79 #define SVCGET_CONNMAXREC       3
80 #define SVCSET_CONNMAXREC       4
81
82 /*
83  * Operations for rpc_control().
84  */
85 #define RPC_SVC_CONNMAXREC_SET  0       /* set max rec size, enable nonblock */
86 #define RPC_SVC_CONNMAXREC_GET  1
87
88 enum xprt_stat {
89         XPRT_DIED,
90         XPRT_MOREREQS,
91         XPRT_IDLE
92 };
93
94 struct __rpc_svcxprt;
95 struct mbuf;
96
97 struct xp_ops {
98 #ifdef _KERNEL
99         /* receive incoming requests */
100         bool_t  (*xp_recv)(struct __rpc_svcxprt *, struct rpc_msg *,
101             struct sockaddr **, struct mbuf **);
102         /* get transport status */
103         enum xprt_stat (*xp_stat)(struct __rpc_svcxprt *);
104         /* get transport acknowledge sequence */
105         bool_t (*xp_ack)(struct __rpc_svcxprt *, uint32_t *);
106         /* send reply */
107         bool_t  (*xp_reply)(struct __rpc_svcxprt *, struct rpc_msg *,
108             struct sockaddr *, struct mbuf *, uint32_t *);
109         /* destroy this struct */
110         void    (*xp_destroy)(struct __rpc_svcxprt *);
111         /* catch-all function */
112         bool_t  (*xp_control)(struct __rpc_svcxprt *, const u_int, void *);
113 #else
114         /* receive incoming requests */
115         bool_t  (*xp_recv)(struct __rpc_svcxprt *, struct rpc_msg *);
116         /* get transport status */
117         enum xprt_stat (*xp_stat)(struct __rpc_svcxprt *);
118         /* get arguments */
119         bool_t  (*xp_getargs)(struct __rpc_svcxprt *, xdrproc_t, void *);
120         /* send reply */
121         bool_t  (*xp_reply)(struct __rpc_svcxprt *, struct rpc_msg *);
122         /* free mem allocated for args */
123         bool_t  (*xp_freeargs)(struct __rpc_svcxprt *, xdrproc_t, void *);
124         /* destroy this struct */
125         void    (*xp_destroy)(struct __rpc_svcxprt *);
126 #endif
127 };
128
129 #ifndef _KERNEL
130 struct xp_ops2 {
131         /* catch-all function */
132         bool_t  (*xp_control)(struct __rpc_svcxprt *, const u_int, void *);
133 };
134 #endif
135
136 #ifdef _KERNEL
137 struct __rpc_svcpool;
138 struct __rpc_svcgroup;
139 struct __rpc_svcthread;
140 #endif
141
142 /*
143  * Server side transport handle. In the kernel, transports have a
144  * reference count which tracks the number of currently assigned
145  * worker threads plus one for the service pool's reference.
146  * For NFSv4.1 sessions, a reference is also held for a backchannel.
147  * xp_p2 - Points to the CLIENT structure for the RPC server end
148  *         (the client end for callbacks).
149  *         Points to the private structure (cl_private) for the
150  *         CLIENT structure for the RPC client end (the server
151  *         end for callbacks).
152  */
153 typedef struct __rpc_svcxprt {
154 #ifdef _KERNEL
155         volatile u_int  xp_refs;
156         struct sx       xp_lock;
157         struct __rpc_svcpool *xp_pool;  /* owning pool (see below) */
158         struct __rpc_svcgroup *xp_group; /* owning group (see below) */
159         TAILQ_ENTRY(__rpc_svcxprt) xp_link;
160         TAILQ_ENTRY(__rpc_svcxprt) xp_alink;
161         bool_t          xp_registered;  /* xprt_register has been called */
162         bool_t          xp_active;      /* xprt_active has been called */
163         struct __rpc_svcthread *xp_thread; /* assigned service thread */
164         struct socket*  xp_socket;
165         const struct xp_ops *xp_ops;
166         char            *xp_netid;      /* network token */
167         struct sockaddr_storage xp_ltaddr; /* local transport address */
168         struct sockaddr_storage xp_rtaddr; /* remote transport address */
169         void            *xp_p1;         /* private: for use by svc ops */
170         void            *xp_p2;         /* private: for use by svc ops */
171         void            *xp_p3;         /* private: for use by svc lib */
172         int             xp_type;        /* transport type */
173         int             xp_idletimeout; /* idle time before closing */
174         time_t          xp_lastactive;  /* time of last RPC */
175         uint64_t        xp_sockref;     /* set by nfsv4 to identify socket */
176         int             xp_upcallset;   /* socket upcall is set up */
177         uint32_t        xp_snd_cnt;     /* # of bytes to send to socket */
178         uint32_t        xp_snt_cnt;     /* # of bytes sent to socket */
179         bool_t          xp_dontrcv;     /* Do not receive on the socket */
180         uint32_t        xp_tls;         /* RPC-over-TLS on socket */
181         uint64_t        xp_sslsec;      /* Userland SSL * */
182         uint64_t        xp_sslusec;
183         uint64_t        xp_sslrefno;
184         int             xp_sslproc;     /* Which upcall daemon being used */
185         int             xp_ngrps;       /* Cred. from TLS cert. */
186         uid_t           xp_uid;
187         gid_t           *xp_gidp;
188         int             xp_doneddp;
189 #else
190         int             xp_fd;
191         u_short         xp_port;         /* associated port number */
192         const struct xp_ops *xp_ops;
193         int             xp_addrlen;      /* length of remote address */
194         struct sockaddr_in xp_raddr;     /* remote addr. (backward ABI compat) */
195         /* XXX - fvdl stick this here for ABI backward compat reasons */
196         const struct xp_ops2 *xp_ops2;
197         char            *xp_tp;          /* transport provider device name */
198         char            *xp_netid;       /* network token */
199         struct netbuf   xp_ltaddr;       /* local transport address */
200         struct netbuf   xp_rtaddr;       /* remote transport address */
201         struct opaque_auth xp_verf;      /* raw response verifier */
202         void            *xp_p1;          /* private: for use by svc ops */
203         void            *xp_p2;          /* private: for use by svc ops */
204         void            *xp_p3;          /* private: for use by svc lib */
205         int             xp_type;         /* transport type */
206 #endif
207 } SVCXPRT;
208
209 /*
210  * Interface to server-side authentication flavors.
211  */
212 typedef struct __rpc_svcauth {
213         const struct svc_auth_ops {
214 #ifdef _KERNEL
215                 int   (*svc_ah_wrap)(struct __rpc_svcauth *,  struct mbuf **);
216                 int   (*svc_ah_unwrap)(struct __rpc_svcauth *, struct mbuf **);
217                 void  (*svc_ah_release)(struct __rpc_svcauth *);
218 #else
219                 int   (*svc_ah_wrap)(struct __rpc_svcauth *, XDR *,
220                     xdrproc_t, caddr_t);
221                 int   (*svc_ah_unwrap)(struct __rpc_svcauth *, XDR *,
222                     xdrproc_t, caddr_t);
223 #endif
224         } *svc_ah_ops;
225         void *svc_ah_private;
226 } SVCAUTH;
227
228 /*
229  * Server transport extensions (accessed via xp_p3).
230  */
231 typedef struct __rpc_svcxprt_ext {
232         int             xp_flags;       /* versquiet */
233         SVCAUTH         xp_auth;        /* interface to auth methods */
234 } SVCXPRT_EXT;
235
236 #ifdef _KERNEL
237
238 /*
239  * The services list
240  * Each entry represents a set of procedures (an rpc program).
241  * The dispatch routine takes request structs and runs the
242  * appropriate procedure.
243  */
244 struct svc_callout {
245         TAILQ_ENTRY(svc_callout) sc_link;
246         rpcprog_t           sc_prog;
247         rpcvers_t           sc_vers;
248         char               *sc_netid;
249         void                (*sc_dispatch)(struct svc_req *, SVCXPRT *);
250 };
251 TAILQ_HEAD(svc_callout_list, svc_callout);
252
253 /*
254  * The services connection loss list
255  * The dispatch routine takes request structs and runs the
256  * appropriate procedure.
257  */
258 struct svc_loss_callout {
259         TAILQ_ENTRY(svc_loss_callout) slc_link;
260         void                (*slc_dispatch)(SVCXPRT *);
261 };
262 TAILQ_HEAD(svc_loss_callout_list, svc_loss_callout);
263
264 /*
265  * Service request
266  */
267 struct svc_req {
268         STAILQ_ENTRY(svc_req) rq_link;  /* list of requests for a thread */
269         struct __rpc_svcthread *rq_thread; /* thread which is to execute this */
270         uint32_t        rq_xid;         /* RPC transaction ID */
271         uint32_t        rq_prog;        /* service program number */
272         uint32_t        rq_vers;        /* service protocol version */
273         uint32_t        rq_proc;        /* the desired procedure */
274         size_t          rq_size;        /* space used by request */
275         struct mbuf     *rq_args;       /* XDR-encoded procedure arguments */
276         struct opaque_auth rq_cred;     /* raw creds from the wire */
277         struct opaque_auth rq_verf;     /* verifier for the reply */
278         void            *rq_clntcred;   /* read only cooked cred */
279         SVCAUTH         rq_auth;        /* interface to auth methods */
280         SVCXPRT         *rq_xprt;       /* associated transport */
281         struct sockaddr *rq_addr;       /* reply address or NULL if connected */
282         void            *rq_p1;         /* application workspace */
283         int             rq_p2;          /* application workspace */
284         uint64_t        rq_p3;          /* application workspace */
285         uint32_t        rq_reply_seq;   /* reply socket sequence # */
286         char            rq_credarea[3*MAX_AUTH_BYTES];
287 };
288 STAILQ_HEAD(svc_reqlist, svc_req);
289
290 #define svc_getrpccaller(rq)                                    \
291         ((rq)->rq_addr ? (rq)->rq_addr :                        \
292             (struct sockaddr *) &(rq)->rq_xprt->xp_rtaddr)
293
294 /*
295  * This structure is used to manage a thread which is executing
296  * requests from a service pool. A service thread is in one of three
297  * states:
298  *
299  *      SVCTHREAD_SLEEPING      waiting for a request to process
300  *      SVCTHREAD_ACTIVE        processing a request
301  *      SVCTHREAD_EXITING       exiting after finishing current request
302  *
303  * Threads which have no work to process sleep on the pool's sp_active
304  * list. When a transport becomes active, it is assigned a service
305  * thread to read and execute pending RPCs.
306  */
307 typedef struct __rpc_svcthread {
308         struct mtx_padalign     st_lock; /* protects st_reqs field */
309         struct __rpc_svcpool    *st_pool;
310         SVCXPRT                 *st_xprt; /* transport we are processing */
311         struct svc_reqlist      st_reqs;  /* RPC requests to execute */
312         struct cv               st_cond; /* sleeping for work */
313         LIST_ENTRY(__rpc_svcthread) st_ilink; /* idle threads list */
314         LIST_ENTRY(__rpc_svcthread) st_alink; /* application thread list */
315         int             st_p2;          /* application workspace */
316         uint64_t        st_p3;          /* application workspace */
317 } SVCTHREAD;
318 LIST_HEAD(svcthread_list, __rpc_svcthread);
319
320 /*
321  * A thread group contain all information needed to assign subset of
322  * transports to subset of threads.  On systems with many CPUs and many
323  * threads that allows to reduce lock congestion and improve performance.
324  * Hundreds of threads on dozens of CPUs sharing the single pool lock do
325  * not scale well otherwise.
326  */
327 TAILQ_HEAD(svcxprt_list, __rpc_svcxprt);
328 enum svcpool_state {
329         SVCPOOL_INIT,           /* svc_run not called yet */
330         SVCPOOL_ACTIVE,         /* normal running state */
331         SVCPOOL_THREADWANTED,   /* new service thread requested */
332         SVCPOOL_THREADSTARTING, /* new service thread started */
333         SVCPOOL_CLOSING         /* svc_exit called */
334 };
335 typedef struct __rpc_svcgroup {
336         struct mtx_padalign sg_lock;    /* protect the thread/req lists */
337         struct __rpc_svcpool    *sg_pool;
338         enum svcpool_state sg_state;    /* current pool state */
339         struct svcxprt_list sg_xlist;   /* all transports in the group */
340         struct svcxprt_list sg_active;  /* transports needing service */
341         struct svcthread_list sg_idlethreads; /* idle service threads */
342
343         int             sg_minthreads;  /* minimum service thread count */
344         int             sg_maxthreads;  /* maximum service thread count */
345         int             sg_threadcount; /* current service thread count */
346         time_t          sg_lastcreatetime; /* when we last started a thread */
347         time_t          sg_lastidlecheck;  /* when we last checked idle transports */
348 } SVCGROUP;
349
350 /*
351  * In the kernel, we can't use global variables to store lists of
352  * transports etc. since otherwise we could not have two unrelated RPC
353  * services running, each on its own thread. We solve this by
354  * importing a tiny part of a Solaris kernel concept, SVCPOOL.
355  *
356  * A service pool contains a set of transports and service callbacks
357  * for a set of related RPC services. The pool handle should be passed
358  * when creating new transports etc. Future work may include extending
359  * this to support something similar to the Solaris multi-threaded RPC
360  * server.
361  */
362 typedef SVCTHREAD *pool_assign_fn(SVCTHREAD *, struct svc_req *);
363 typedef void pool_done_fn(SVCTHREAD *, struct svc_req *);
364 #define SVC_MAXGROUPS   16
365 typedef struct __rpc_svcpool {
366         struct mtx_padalign sp_lock;    /* protect the transport lists */
367         const char      *sp_name;       /* pool name (e.g. "nfsd", "NLM" */
368         enum svcpool_state sp_state;    /* current pool state */
369         struct proc     *sp_proc;       /* process which is in svc_run */
370         struct svc_callout_list sp_callouts; /* (prog,vers)->dispatch list */
371         struct svc_loss_callout_list sp_lcallouts; /* loss->dispatch list */
372         int             sp_minthreads;  /* minimum service thread count */
373         int             sp_maxthreads;  /* maximum service thread count */
374
375         /*
376          * Hooks to allow an application to control request to thread
377          * placement.
378          */
379         pool_assign_fn  *sp_assign;
380         pool_done_fn    *sp_done;
381
382         /*
383          * These variables are used to put an upper bound on the
384          * amount of memory used by RPC requests which are queued
385          * waiting for execution.
386          */
387         unsigned long   sp_space_low;
388         unsigned long   sp_space_high;
389         unsigned long   sp_space_used;
390         unsigned long   sp_space_used_highest;
391         bool_t          sp_space_throttled;
392         int             sp_space_throttle_count;
393
394         struct replay_cache *sp_rcache; /* optional replay cache */
395         struct sysctl_ctx_list sp_sysctl;
396
397         int             sp_groupcount;  /* Number of groups in the pool. */
398         int             sp_nextgroup;   /* Next group to assign port. */
399         SVCGROUP        sp_groups[SVC_MAXGROUPS]; /* Thread/port groups. */
400 } SVCPOOL;
401
402 #else
403
404 /*
405  * Service request
406  */
407 struct svc_req {
408         uint32_t        rq_prog;        /* service program number */
409         uint32_t        rq_vers;        /* service protocol version */
410         uint32_t        rq_proc;        /* the desired procedure */
411         struct opaque_auth rq_cred;     /* raw creds from the wire */
412         void            *rq_clntcred;   /* read only cooked cred */
413         SVCXPRT         *rq_xprt;       /* associated transport */
414 };
415
416 /*
417  *  Approved way of getting address of caller
418  */
419 #define svc_getrpccaller(x) (&(x)->xp_rtaddr)
420
421 #endif
422
423 /*
424  * Operations defined on an SVCXPRT handle
425  *
426  * SVCXPRT              *xprt;
427  * struct rpc_msg       *msg;
428  * xdrproc_t             xargs;
429  * void *                argsp;
430  */
431 #ifdef _KERNEL
432
433 #define SVC_ACQUIRE(xprt)                       \
434         refcount_acquire(&(xprt)->xp_refs)
435
436 #define SVC_RELEASE(xprt)                       \
437         if (refcount_release(&(xprt)->xp_refs)) \
438                 SVC_DESTROY(xprt)
439
440 #define SVC_RECV(xprt, msg, addr, args)                 \
441         (*(xprt)->xp_ops->xp_recv)((xprt), (msg), (addr), (args))
442
443 #define SVC_STAT(xprt)                                  \
444         (*(xprt)->xp_ops->xp_stat)(xprt)
445
446 #define SVC_ACK(xprt, ack)                              \
447         ((xprt)->xp_ops->xp_ack == NULL ? FALSE :       \
448             ((ack) == NULL ? TRUE : (*(xprt)->xp_ops->xp_ack)((xprt), (ack))))
449
450 #define SVC_REPLY(xprt, msg, addr, m, seq)                      \
451         (*(xprt)->xp_ops->xp_reply) ((xprt), (msg), (addr), (m), (seq))
452
453 #define SVC_DESTROY(xprt)                               \
454         (*(xprt)->xp_ops->xp_destroy)(xprt)
455
456 #define SVC_CONTROL(xprt, rq, in)                       \
457         (*(xprt)->xp_ops->xp_control)((xprt), (rq), (in))
458
459 #else
460
461 #define SVC_RECV(xprt, msg)                             \
462         (*(xprt)->xp_ops->xp_recv)((xprt), (msg))
463 #define svc_recv(xprt, msg)                             \
464         (*(xprt)->xp_ops->xp_recv)((xprt), (msg))
465
466 #define SVC_STAT(xprt)                                  \
467         (*(xprt)->xp_ops->xp_stat)(xprt)
468 #define svc_stat(xprt)                                  \
469         (*(xprt)->xp_ops->xp_stat)(xprt)
470
471 #define SVC_GETARGS(xprt, xargs, argsp)                 \
472         (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp))
473 #define svc_getargs(xprt, xargs, argsp)                 \
474         (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp))
475
476 #define SVC_REPLY(xprt, msg)                            \
477         (*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
478 #define svc_reply(xprt, msg)                            \
479         (*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
480
481 #define SVC_FREEARGS(xprt, xargs, argsp)                \
482         (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp))
483 #define svc_freeargs(xprt, xargs, argsp)                \
484         (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp))
485
486 #define SVC_DESTROY(xprt)                               \
487         (*(xprt)->xp_ops->xp_destroy)(xprt)
488 #define svc_destroy(xprt)                               \
489         (*(xprt)->xp_ops->xp_destroy)(xprt)
490
491 #define SVC_CONTROL(xprt, rq, in)                       \
492         (*(xprt)->xp_ops2->xp_control)((xprt), (rq), (in))
493
494 #endif
495
496 #define SVC_EXT(xprt)                                   \
497         ((SVCXPRT_EXT *) xprt->xp_p3)
498
499 #define SVC_AUTH(xprt)                                  \
500         (SVC_EXT(xprt)->xp_auth)
501
502 /*
503  * Operations defined on an SVCAUTH handle
504  */
505 #ifdef _KERNEL
506 #define SVCAUTH_WRAP(auth, mp)          \
507         ((auth)->svc_ah_ops->svc_ah_wrap(auth, mp))
508 #define SVCAUTH_UNWRAP(auth, mp)        \
509         ((auth)->svc_ah_ops->svc_ah_unwrap(auth, mp))
510 #define SVCAUTH_RELEASE(auth)   \
511         ((auth)->svc_ah_ops->svc_ah_release(auth))
512 #else
513 #define SVCAUTH_WRAP(auth, xdrs, xfunc, xwhere)         \
514         ((auth)->svc_ah_ops->svc_ah_wrap(auth, xdrs, xfunc, xwhere))
515 #define SVCAUTH_UNWRAP(auth, xdrs, xfunc, xwhere)       \
516         ((auth)->svc_ah_ops->svc_ah_unwrap(auth, xdrs, xfunc, xwhere))
517 #endif
518
519 /*
520  * Service registration
521  *
522  * svc_reg(xprt, prog, vers, dispatch, nconf)
523  *      const SVCXPRT *xprt;
524  *      const rpcprog_t prog;
525  *      const rpcvers_t vers;
526  *      const void (*dispatch)();
527  *      const struct netconfig *nconf;
528  */
529
530 __BEGIN_DECLS
531 extern bool_t   svc_reg(SVCXPRT *, const rpcprog_t, const rpcvers_t,
532                         void (*)(struct svc_req *, SVCXPRT *),
533                         const struct netconfig *);
534 __END_DECLS
535
536 /*
537  * Service un-registration
538  *
539  * svc_unreg(prog, vers)
540  *      const rpcprog_t prog;
541  *      const rpcvers_t vers;
542  */
543
544 __BEGIN_DECLS
545 #ifdef _KERNEL
546 extern void     svc_unreg(SVCPOOL *, const rpcprog_t, const rpcvers_t);
547 #else
548 extern void     svc_unreg(const rpcprog_t, const rpcvers_t);
549 #endif
550 __END_DECLS
551
552 #ifdef _KERNEL
553 /*
554  * Service connection loss registration
555  *
556  * svc_loss_reg(xprt, dispatch)
557  *      const SVCXPRT *xprt;
558  *      const void (*dispatch)();
559  */
560
561 __BEGIN_DECLS
562 extern bool_t   svc_loss_reg(SVCXPRT *, void (*)(SVCXPRT *));
563 __END_DECLS
564
565 /*
566  * Service connection loss un-registration
567  *
568  * svc_loss_unreg(xprt, dispatch)
569  *      const SVCXPRT *xprt;
570  *      const void (*dispatch)();
571  */
572
573 __BEGIN_DECLS
574 extern void     svc_loss_unreg(SVCPOOL *, void (*)(SVCXPRT *));
575 __END_DECLS
576 #endif
577
578 /*
579  * Transport registration.
580  *
581  * xprt_register(xprt)
582  *      SVCXPRT *xprt;
583  */
584 __BEGIN_DECLS
585 extern void     xprt_register(SVCXPRT *);
586 __END_DECLS
587
588 /*
589  * Transport un-register
590  *
591  * xprt_unregister(xprt)
592  *      SVCXPRT *xprt;
593  */
594 __BEGIN_DECLS
595 extern void     xprt_unregister(SVCXPRT *);
596 extern void     __xprt_unregister_unlocked(SVCXPRT *);
597 __END_DECLS
598
599 #ifdef _KERNEL
600
601 /*
602  * Called when a transport has pending requests.
603  */
604 __BEGIN_DECLS
605 extern void     xprt_active(SVCXPRT *);
606 extern void     xprt_inactive(SVCXPRT *);
607 extern void     xprt_inactive_locked(SVCXPRT *);
608 extern void     xprt_inactive_self(SVCXPRT *);
609 __END_DECLS
610
611 #endif
612
613 /*
614  * When the service routine is called, it must first check to see if it
615  * knows about the procedure;  if not, it should call svcerr_noproc
616  * and return.  If so, it should deserialize its arguments via
617  * SVC_GETARGS (defined above).  If the deserialization does not work,
618  * svcerr_decode should be called followed by a return.  Successful
619  * decoding of the arguments should be followed the execution of the
620  * procedure's code and a call to svc_sendreply.
621  *
622  * Also, if the service refuses to execute the procedure due to too-
623  * weak authentication parameters, svcerr_weakauth should be called.
624  * Note: do not confuse access-control failure with weak authentication!
625  *
626  * NB: In pure implementations of rpc, the caller always waits for a reply
627  * msg.  This message is sent when svc_sendreply is called.
628  * Therefore pure service implementations should always call
629  * svc_sendreply even if the function logically returns void;  use
630  * xdr.h - xdr_void for the xdr routine.  HOWEVER, tcp based rpc allows
631  * for the abuse of pure rpc via batched calling or pipelining.  In the
632  * case of a batched call, svc_sendreply should NOT be called since
633  * this would send a return message, which is what batching tries to avoid.
634  * It is the service/protocol writer's responsibility to know which calls are
635  * batched and which are not.  Warning: responding to batch calls may
636  * deadlock the caller and server processes!
637  */
638
639 __BEGIN_DECLS
640 #ifdef _KERNEL
641 extern bool_t   svc_sendreply(struct svc_req *, xdrproc_t, void *);
642 extern bool_t   svc_sendreply_mbuf(struct svc_req *, struct mbuf *);
643 extern void     svcerr_decode(struct svc_req *);
644 extern void     svcerr_weakauth(struct svc_req *);
645 extern void     svcerr_noproc(struct svc_req *);
646 extern void     svcerr_progvers(struct svc_req *, rpcvers_t, rpcvers_t);
647 extern void     svcerr_auth(struct svc_req *, enum auth_stat);
648 extern void     svcerr_noprog(struct svc_req *);
649 extern void     svcerr_systemerr(struct svc_req *);
650 #else
651 extern bool_t   svc_sendreply(SVCXPRT *, xdrproc_t, void *);
652 extern void     svcerr_decode(SVCXPRT *);
653 extern void     svcerr_weakauth(SVCXPRT *);
654 extern void     svcerr_noproc(SVCXPRT *);
655 extern void     svcerr_progvers(SVCXPRT *, rpcvers_t, rpcvers_t);
656 extern void     svcerr_auth(SVCXPRT *, enum auth_stat);
657 extern void     svcerr_noprog(SVCXPRT *);
658 extern void     svcerr_systemerr(SVCXPRT *);
659 #endif
660 extern int      rpc_reg(rpcprog_t, rpcvers_t, rpcproc_t,
661                         char *(*)(char *), xdrproc_t, xdrproc_t,
662                         char *);
663 __END_DECLS
664
665 /*
666  * Lowest level dispatching -OR- who owns this process anyway.
667  * Somebody has to wait for incoming requests and then call the correct
668  * service routine.  The routine svc_run does infinite waiting; i.e.,
669  * svc_run never returns.
670  * Since another (co-existent) package may wish to selectively wait for
671  * incoming calls or other events outside of the rpc architecture, the
672  * routine svc_getreq is provided.  It must be passed readfds, the
673  * "in-place" results of a select system call (see select, section 2).
674  */
675
676 #ifndef _KERNEL
677 /*
678  * Global keeper of rpc service descriptors in use
679  * dynamic; must be inspected before each call to select
680  */
681 extern int svc_maxfd;
682 #ifdef FD_SETSIZE
683 extern fd_set svc_fdset;
684 #define svc_fds svc_fdset.fds_bits[0]   /* compatibility */
685 #else
686 extern int svc_fds;
687 #endif /* def FD_SETSIZE */
688 #endif
689
690 /*
691  * a small program implemented by the svc_rpc implementation itself;
692  * also see clnt.h for protocol numbers.
693  */
694 __BEGIN_DECLS
695 extern void rpctest_service(void);
696 __END_DECLS
697
698 __BEGIN_DECLS
699 extern SVCXPRT *svc_xprt_alloc(void);
700 extern void     svc_xprt_free(SVCXPRT *);
701 #ifndef _KERNEL
702 extern void     svc_getreq(int);
703 extern void     svc_getreqset(fd_set *);
704 extern void     svc_getreq_common(int);
705 struct pollfd;
706 extern void     svc_getreq_poll(struct pollfd *, int);
707 extern void     svc_run(void);
708 extern void     svc_exit(void);
709 #else
710 extern void     svc_run(SVCPOOL *);
711 extern void     svc_exit(SVCPOOL *);
712 extern bool_t   svc_getargs(struct svc_req *, xdrproc_t, void *);
713 extern bool_t   svc_freeargs(struct svc_req *, xdrproc_t, void *);
714 extern void     svc_freereq(struct svc_req *);
715
716 #endif
717 __END_DECLS
718
719 /*
720  * Socket to use on svcxxx_create call to get default socket
721  */
722 #define RPC_ANYSOCK     -1
723 #define RPC_ANYFD       RPC_ANYSOCK
724
725 /*
726  * These are the existing service side transport implementations
727  */
728
729 __BEGIN_DECLS
730
731 #ifdef _KERNEL
732
733 /*
734  * Create a new service pool.
735  */
736 extern SVCPOOL* svcpool_create(const char *name,
737     struct sysctl_oid_list *sysctl_base);
738
739 /*
740  * Destroy a service pool, including all registered transports.
741  */
742 extern void svcpool_destroy(SVCPOOL *pool);
743
744 /*
745  * Close a service pool.  Similar to svcpool_destroy(), but it does not
746  * free the data structures.  As such, the pool can be used again.
747  */
748 extern void svcpool_close(SVCPOOL *pool);
749
750 /*
751  * Transport independent svc_create routine.
752  */
753 extern int svc_create(SVCPOOL *, void (*)(struct svc_req *, SVCXPRT *),
754     const rpcprog_t, const rpcvers_t, const char *);
755 /*
756  *      void (*dispatch)();             -- dispatch routine
757  *      const rpcprog_t prognum;        -- program number
758  *      const rpcvers_t versnum;        -- version number
759  *      const char *nettype;            -- network type
760  */
761
762
763 /*
764  * Generic server creation routine. It takes a netconfig structure
765  * instead of a nettype.
766  */
767
768 extern SVCXPRT *svc_tp_create(SVCPOOL *, void (*)(struct svc_req *, SVCXPRT *),
769     const rpcprog_t, const rpcvers_t, const char *uaddr,
770     const struct netconfig *);
771         /*
772          * void (*dispatch)();            -- dispatch routine
773          * const rpcprog_t prognum;       -- program number
774          * const rpcvers_t versnum;       -- version number
775          * const char *uaddr;             -- universal address of service
776          * const struct netconfig *nconf; -- netconfig structure
777          */
778
779 extern SVCXPRT *svc_dg_create(SVCPOOL *, struct socket *,
780     const size_t, const size_t);
781         /*
782          * struct socket *;                             -- open connection
783          * const size_t sendsize;                        -- max send size
784          * const size_t recvsize;                        -- max recv size
785          */
786
787 extern SVCXPRT *svc_vc_create(SVCPOOL *, struct socket *,
788     const size_t, const size_t);
789         /*
790          * struct socket *;                             -- open connection
791          * const size_t sendsize;                        -- max send size
792          * const size_t recvsize;                        -- max recv size
793          */
794
795 extern SVCXPRT *svc_vc_create_backchannel(SVCPOOL *);
796
797 extern void *clnt_bck_create(struct socket *, const rpcprog_t, const rpcvers_t);
798         /*
799          * struct socket *;                     -- server transport socket
800          * const rpcprog_t prog;                -- RPC program number
801          * const rpcvers_t vers;                -- RPC program version
802          */
803
804 /*
805  * Generic TLI create routine
806  */
807 extern SVCXPRT *svc_tli_create(SVCPOOL *, struct socket *,
808     const struct netconfig *, const struct t_bind *, const size_t, const size_t);
809 /*
810  *      struct socket * so;             -- connection end point
811  *      const struct netconfig *nconf;  -- netconfig structure for network
812  *      const struct t_bind *bindaddr;  -- local bind address
813  *      const size_t sendsz;             -- max sendsize
814  *      const size_t recvsz;             -- max recvsize
815  */
816
817 #else /* !_KERNEL */
818
819 /*
820  * Transport independent svc_create routine.
821  */
822 extern int svc_create(void (*)(struct svc_req *, SVCXPRT *),
823                            const rpcprog_t, const rpcvers_t, const char *);
824 /*
825  *      void (*dispatch)();             -- dispatch routine
826  *      const rpcprog_t prognum;        -- program number
827  *      const rpcvers_t versnum;        -- version number
828  *      const char *nettype;            -- network type
829  */
830
831
832 /*
833  * Generic server creation routine. It takes a netconfig structure
834  * instead of a nettype.
835  */
836
837 extern SVCXPRT *svc_tp_create(void (*)(struct svc_req *, SVCXPRT *),
838                                    const rpcprog_t, const rpcvers_t,
839                                    const struct netconfig *);
840         /*
841          * void (*dispatch)();            -- dispatch routine
842          * const rpcprog_t prognum;       -- program number
843          * const rpcvers_t versnum;       -- version number
844          * const struct netconfig *nconf; -- netconfig structure
845          */
846
847 /*
848  * Generic TLI create routine
849  */
850 extern SVCXPRT *svc_tli_create(const int, const struct netconfig *,
851                                const struct t_bind *, const u_int,
852                                const u_int);
853 /*
854  *      const int fd;                   -- connection end point
855  *      const struct netconfig *nconf;  -- netconfig structure for network
856  *      const struct t_bind *bindaddr;  -- local bind address
857  *      const u_int sendsz;             -- max sendsize
858  *      const u_int recvsz;             -- max recvsize
859  */
860
861 /*
862  * Connectionless and connectionful create routines
863  */
864
865 extern SVCXPRT *svc_vc_create(const int, const u_int, const u_int);
866 /*
867  *      const int fd;                           -- open connection end point
868  *      const u_int sendsize;                   -- max send size
869  *      const u_int recvsize;                   -- max recv size
870  */
871
872 /*
873  * Added for compatibility to old rpc 4.0. Obsoleted by svc_vc_create().
874  */
875 extern SVCXPRT *svcunix_create(int, u_int, u_int, char *);
876
877 extern SVCXPRT *svc_dg_create(const int, const u_int, const u_int);
878         /*
879          * const int fd;                                -- open connection
880          * const u_int sendsize;                        -- max send size
881          * const u_int recvsize;                        -- max recv size
882          */
883
884
885 /*
886  * the routine takes any *open* connection
887  * descriptor as its first input and is used for open connections.
888  */
889 extern SVCXPRT *svc_fd_create(const int, const u_int, const u_int);
890 /*
891  *      const int fd;                           -- open connection end point
892  *      const u_int sendsize;                   -- max send size
893  *      const u_int recvsize;                   -- max recv size
894  */
895
896 /*
897  * Added for compatibility to old rpc 4.0. Obsoleted by svc_fd_create().
898  */
899 extern SVCXPRT *svcunixfd_create(int, u_int, u_int);
900
901 /*
902  * Memory based rpc (for speed check and testing)
903  */
904 extern SVCXPRT *svc_raw_create(void);
905
906 /*
907  * svc_dg_enable_cache() enables the cache on dg transports.
908  */
909 int svc_dg_enablecache(SVCXPRT *, const u_int);
910
911 int __rpc_get_local_uid(SVCXPRT *_transp, uid_t *_uid);
912
913 #endif  /* !_KERNEL */
914
915 __END_DECLS
916
917 #ifndef _KERNEL
918 /* for backward compatibility */
919 #include <rpc/svc_soc.h>
920 #endif
921
922 #endif /* !_RPC_SVC_H */