svc.h revision 191145
1177633Sdfr/* $NetBSD: svc.h,v 1.17 2000/06/02 22:57:56 fvdl Exp $ */ 2177633Sdfr 3177633Sdfr/* 4177633Sdfr * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 5177633Sdfr * unrestricted use provided that this legend is included on all tape 6177633Sdfr * media and as a part of the software program in whole or part. Users 7177633Sdfr * may copy or modify Sun RPC without charge, but are not authorized 8177633Sdfr * to license or distribute it to anyone else except as part of a product or 9177633Sdfr * program developed by the user. 10177633Sdfr * 11177633Sdfr * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 12177633Sdfr * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR 13177633Sdfr * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 14177633Sdfr * 15177633Sdfr * Sun RPC is provided with no support and without any obligation on the 16177633Sdfr * part of Sun Microsystems, Inc. to assist in its use, correction, 17177633Sdfr * modification or enhancement. 18177633Sdfr * 19177633Sdfr * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 20177633Sdfr * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 21177633Sdfr * OR ANY PART THEREOF. 22177633Sdfr * 23177633Sdfr * In no event will Sun Microsystems, Inc. be liable for any lost revenue 24177633Sdfr * or profits or other special, indirect and consequential damages, even if 25177633Sdfr * Sun has been advised of the possibility of such damages. 26177633Sdfr * 27177633Sdfr * Sun Microsystems, Inc. 28177633Sdfr * 2550 Garcia Avenue 29177633Sdfr * Mountain View, California 94043 30177633Sdfr * 31177633Sdfr * from: @(#)svc.h 1.35 88/12/17 SMI 32177633Sdfr * from: @(#)svc.h 1.27 94/04/25 SMI 33177633Sdfr * $FreeBSD: head/sys/rpc/svc.h 191145 2009-04-16 16:26:35Z rmacklem $ 34177633Sdfr */ 35177633Sdfr 36177633Sdfr/* 37177633Sdfr * svc.h, Server-side remote procedure call interface. 38177633Sdfr * 39177633Sdfr * Copyright (C) 1986-1993 by Sun Microsystems, Inc. 40177633Sdfr */ 41177633Sdfr 42177633Sdfr#ifndef _RPC_SVC_H 43177633Sdfr#define _RPC_SVC_H 44177633Sdfr#include <sys/cdefs.h> 45177633Sdfr 46177633Sdfr#ifdef _KERNEL 47177633Sdfr#include <sys/queue.h> 48177633Sdfr#include <sys/_lock.h> 49177633Sdfr#include <sys/_mutex.h> 50184588Sdfr#include <sys/_sx.h> 51184588Sdfr#include <sys/condvar.h> 52184588Sdfr#include <sys/sysctl.h> 53177633Sdfr#endif 54177633Sdfr 55177633Sdfr/* 56177633Sdfr * This interface must manage two items concerning remote procedure calling: 57177633Sdfr * 58177633Sdfr * 1) An arbitrary number of transport connections upon which rpc requests 59177633Sdfr * are received. The two most notable transports are TCP and UDP; they are 60177633Sdfr * created and registered by routines in svc_tcp.c and svc_udp.c, respectively; 61177633Sdfr * they in turn call xprt_register and xprt_unregister. 62177633Sdfr * 63177633Sdfr * 2) An arbitrary number of locally registered services. Services are 64177633Sdfr * described by the following four data: program number, version number, 65177633Sdfr * "service dispatch" function, a transport handle, and a boolean that 66177633Sdfr * indicates whether or not the exported program should be registered with a 67177633Sdfr * local binder service; if true the program's number and version and the 68177633Sdfr * port number from the transport handle are registered with the binder. 69177633Sdfr * These data are registered with the rpc svc system via svc_register. 70177633Sdfr * 71177633Sdfr * A service's dispatch function is called whenever an rpc request comes in 72177633Sdfr * on a transport. The request's program and version numbers must match 73177633Sdfr * those of the registered service. The dispatch function is passed two 74177633Sdfr * parameters, struct svc_req * and SVCXPRT *, defined below. 75177633Sdfr */ 76177633Sdfr 77177633Sdfr/* 78177633Sdfr * Service control requests 79177633Sdfr */ 80177633Sdfr#define SVCGET_VERSQUIET 1 81177633Sdfr#define SVCSET_VERSQUIET 2 82177633Sdfr#define SVCGET_CONNMAXREC 3 83177633Sdfr#define SVCSET_CONNMAXREC 4 84177633Sdfr 85177633Sdfr/* 86177633Sdfr * Operations for rpc_control(). 87177633Sdfr */ 88177633Sdfr#define RPC_SVC_CONNMAXREC_SET 0 /* set max rec size, enable nonblock */ 89177633Sdfr#define RPC_SVC_CONNMAXREC_GET 1 90177633Sdfr 91177633Sdfrenum xprt_stat { 92177633Sdfr XPRT_DIED, 93177633Sdfr XPRT_MOREREQS, 94177633Sdfr XPRT_IDLE 95177633Sdfr}; 96177633Sdfr 97177633Sdfrstruct __rpc_svcxprt; 98184588Sdfrstruct mbuf; 99177633Sdfr 100177633Sdfrstruct xp_ops { 101184588Sdfr#ifdef _KERNEL 102177633Sdfr /* receive incoming requests */ 103184588Sdfr bool_t (*xp_recv)(struct __rpc_svcxprt *, struct rpc_msg *, 104184588Sdfr struct sockaddr **, struct mbuf **); 105184588Sdfr /* get transport status */ 106184588Sdfr enum xprt_stat (*xp_stat)(struct __rpc_svcxprt *); 107184588Sdfr /* send reply */ 108184588Sdfr bool_t (*xp_reply)(struct __rpc_svcxprt *, struct rpc_msg *, 109184588Sdfr struct sockaddr *, struct mbuf *); 110184588Sdfr /* destroy this struct */ 111184588Sdfr void (*xp_destroy)(struct __rpc_svcxprt *); 112184588Sdfr /* catch-all function */ 113184588Sdfr bool_t (*xp_control)(struct __rpc_svcxprt *, const u_int, void *); 114184588Sdfr#else 115184588Sdfr /* receive incoming requests */ 116177633Sdfr bool_t (*xp_recv)(struct __rpc_svcxprt *, struct rpc_msg *); 117177633Sdfr /* get transport status */ 118177633Sdfr enum xprt_stat (*xp_stat)(struct __rpc_svcxprt *); 119177633Sdfr /* get arguments */ 120177633Sdfr bool_t (*xp_getargs)(struct __rpc_svcxprt *, xdrproc_t, void *); 121177633Sdfr /* send reply */ 122177633Sdfr bool_t (*xp_reply)(struct __rpc_svcxprt *, struct rpc_msg *); 123177633Sdfr /* free mem allocated for args */ 124177633Sdfr bool_t (*xp_freeargs)(struct __rpc_svcxprt *, xdrproc_t, void *); 125177633Sdfr /* destroy this struct */ 126177633Sdfr void (*xp_destroy)(struct __rpc_svcxprt *); 127177633Sdfr#endif 128177633Sdfr}; 129177633Sdfr 130177633Sdfr#ifndef _KERNEL 131177633Sdfrstruct xp_ops2 { 132177633Sdfr /* catch-all function */ 133177633Sdfr bool_t (*xp_control)(struct __rpc_svcxprt *, const u_int, void *); 134177633Sdfr}; 135177633Sdfr#endif 136177633Sdfr 137177633Sdfr#ifdef _KERNEL 138177633Sdfrstruct __rpc_svcpool; 139184588Sdfrstruct __rpc_svcthread; 140177633Sdfr#endif 141177633Sdfr 142177633Sdfr/* 143184588Sdfr * Server side transport handle. In the kernel, transports have a 144184588Sdfr * reference count which tracks the number of currently assigned 145184588Sdfr * worker threads plus one for the service pool's reference. 146177633Sdfr */ 147177633Sdfrtypedef struct __rpc_svcxprt { 148177633Sdfr#ifdef _KERNEL 149184588Sdfr volatile u_int xp_refs; 150184588Sdfr struct sx xp_lock; 151177633Sdfr struct __rpc_svcpool *xp_pool; /* owning pool (see below) */ 152177633Sdfr TAILQ_ENTRY(__rpc_svcxprt) xp_link; 153177633Sdfr TAILQ_ENTRY(__rpc_svcxprt) xp_alink; 154177633Sdfr bool_t xp_registered; /* xprt_register has been called */ 155177633Sdfr bool_t xp_active; /* xprt_active has been called */ 156184588Sdfr struct __rpc_svcthread *xp_thread; /* assigned service thread */ 157177633Sdfr struct socket* xp_socket; 158177633Sdfr const struct xp_ops *xp_ops; 159177633Sdfr char *xp_netid; /* network token */ 160184588Sdfr struct sockaddr_storage xp_ltaddr; /* local transport address */ 161184588Sdfr struct sockaddr_storage xp_rtaddr; /* remote transport address */ 162177633Sdfr void *xp_p1; /* private: for use by svc ops */ 163177633Sdfr void *xp_p2; /* private: for use by svc ops */ 164177633Sdfr void *xp_p3; /* private: for use by svc lib */ 165177633Sdfr int xp_type; /* transport type */ 166184588Sdfr int xp_idletimeout; /* idle time before closing */ 167184588Sdfr time_t xp_lastactive; /* time of last RPC */ 168191145Srmacklem u_int64_t xp_sockref; /* set by nfsv4 to identify socket */ 169177633Sdfr#else 170177633Sdfr int xp_fd; 171177633Sdfr u_short xp_port; /* associated port number */ 172177633Sdfr const struct xp_ops *xp_ops; 173177633Sdfr int xp_addrlen; /* length of remote address */ 174177633Sdfr struct sockaddr_in xp_raddr; /* remote addr. (backward ABI compat) */ 175177633Sdfr /* XXX - fvdl stick this here for ABI backward compat reasons */ 176177633Sdfr const struct xp_ops2 *xp_ops2; 177177633Sdfr char *xp_tp; /* transport provider device name */ 178177633Sdfr char *xp_netid; /* network token */ 179177633Sdfr struct netbuf xp_ltaddr; /* local transport address */ 180177633Sdfr struct netbuf xp_rtaddr; /* remote transport address */ 181177633Sdfr struct opaque_auth xp_verf; /* raw response verifier */ 182177633Sdfr void *xp_p1; /* private: for use by svc ops */ 183177633Sdfr void *xp_p2; /* private: for use by svc ops */ 184177633Sdfr void *xp_p3; /* private: for use by svc lib */ 185177633Sdfr int xp_type; /* transport type */ 186177633Sdfr#endif 187177633Sdfr} SVCXPRT; 188177633Sdfr 189184588Sdfr/* 190184588Sdfr * Interface to server-side authentication flavors. 191184588Sdfr */ 192184588Sdfrtypedef struct __rpc_svcauth { 193184588Sdfr struct svc_auth_ops { 194177633Sdfr#ifdef _KERNEL 195184588Sdfr int (*svc_ah_wrap)(struct __rpc_svcauth *, struct mbuf **); 196184588Sdfr int (*svc_ah_unwrap)(struct __rpc_svcauth *, struct mbuf **); 197184588Sdfr void (*svc_ah_release)(struct __rpc_svcauth *); 198184588Sdfr#else 199184588Sdfr int (*svc_ah_wrap)(struct __rpc_svcauth *, XDR *, 200184588Sdfr xdrproc_t, caddr_t); 201184588Sdfr int (*svc_ah_unwrap)(struct __rpc_svcauth *, XDR *, 202184588Sdfr xdrproc_t, caddr_t); 203184588Sdfr#endif 204184588Sdfr } *svc_ah_ops; 205184588Sdfr void *svc_ah_private; 206184588Sdfr} SVCAUTH; 207177633Sdfr 208177633Sdfr/* 209184588Sdfr * Server transport extensions (accessed via xp_p3). 210184588Sdfr */ 211184588Sdfrtypedef struct __rpc_svcxprt_ext { 212184588Sdfr int xp_flags; /* versquiet */ 213184588Sdfr SVCAUTH xp_auth; /* interface to auth methods */ 214184588Sdfr} SVCXPRT_EXT; 215184588Sdfr 216184588Sdfr#ifdef _KERNEL 217184588Sdfr 218184588Sdfr/* 219177633Sdfr * The services list 220177633Sdfr * Each entry represents a set of procedures (an rpc program). 221177633Sdfr * The dispatch routine takes request structs and runs the 222177633Sdfr * apropriate procedure. 223177633Sdfr */ 224177633Sdfrstruct svc_callout { 225177633Sdfr TAILQ_ENTRY(svc_callout) sc_link; 226177633Sdfr rpcprog_t sc_prog; 227177633Sdfr rpcvers_t sc_vers; 228177633Sdfr char *sc_netid; 229177633Sdfr void (*sc_dispatch)(struct svc_req *, SVCXPRT *); 230177633Sdfr}; 231177633SdfrTAILQ_HEAD(svc_callout_list, svc_callout); 232177633Sdfr 233184588Sdfrstruct __rpc_svcthread; 234184588Sdfr 235177633Sdfr/* 236184588Sdfr * Service request 237184588Sdfr */ 238184588Sdfrstruct svc_req { 239184588Sdfr STAILQ_ENTRY(svc_req) rq_link; /* list of requests for a thread */ 240184588Sdfr struct __rpc_svcthread *rq_thread; /* thread which is to execute this */ 241184588Sdfr uint32_t rq_xid; /* RPC transaction ID */ 242184588Sdfr uint32_t rq_prog; /* service program number */ 243184588Sdfr uint32_t rq_vers; /* service protocol version */ 244184588Sdfr uint32_t rq_proc; /* the desired procedure */ 245184588Sdfr size_t rq_size; /* space used by request */ 246184588Sdfr struct mbuf *rq_args; /* XDR-encoded procedure arguments */ 247184588Sdfr struct opaque_auth rq_cred; /* raw creds from the wire */ 248184588Sdfr struct opaque_auth rq_verf; /* verifier for the reply */ 249184588Sdfr void *rq_clntcred; /* read only cooked cred */ 250184588Sdfr SVCAUTH rq_auth; /* interface to auth methods */ 251184588Sdfr SVCXPRT *rq_xprt; /* associated transport */ 252184588Sdfr struct sockaddr *rq_addr; /* reply address or NULL if connected */ 253184588Sdfr void *rq_p1; /* application workspace */ 254184588Sdfr int rq_p2; /* application workspace */ 255184588Sdfr uint64_t rq_p3; /* application workspace */ 256184588Sdfr char rq_credarea[3*MAX_AUTH_BYTES]; 257184588Sdfr}; 258184588SdfrSTAILQ_HEAD(svc_reqlist, svc_req); 259184588Sdfr 260184588Sdfr#define svc_getrpccaller(rq) \ 261184588Sdfr ((rq)->rq_addr ? (rq)->rq_addr : \ 262184588Sdfr (struct sockaddr *) &(rq)->rq_xprt->xp_rtaddr) 263184588Sdfr 264184588Sdfr/* 265184588Sdfr * This structure is used to manage a thread which is executing 266184588Sdfr * requests from a service pool. A service thread is in one of three 267184588Sdfr * states: 268184588Sdfr * 269184588Sdfr * SVCTHREAD_SLEEPING waiting for a request to process 270184588Sdfr * SVCTHREAD_ACTIVE processing a request 271184588Sdfr * SVCTHREAD_EXITING exiting after finishing current request 272184588Sdfr * 273184588Sdfr * Threads which have no work to process sleep on the pool's sp_active 274184588Sdfr * list. When a transport becomes active, it is assigned a service 275184588Sdfr * thread to read and execute pending RPCs. 276184588Sdfr */ 277184588Sdfrtypedef struct __rpc_svcthread { 278184588Sdfr SVCXPRT *st_xprt; /* transport we are processing */ 279184588Sdfr struct svc_reqlist st_reqs; /* RPC requests to execute */ 280184588Sdfr int st_reqcount; /* number of queued reqs */ 281184588Sdfr struct cv st_cond; /* sleeping for work */ 282184588Sdfr LIST_ENTRY(__rpc_svcthread) st_link; /* all threads list */ 283184588Sdfr LIST_ENTRY(__rpc_svcthread) st_ilink; /* idle threads list */ 284184588Sdfr LIST_ENTRY(__rpc_svcthread) st_alink; /* application thread list */ 285184588Sdfr} SVCTHREAD; 286184588SdfrLIST_HEAD(svcthread_list, __rpc_svcthread); 287184588Sdfr 288184588Sdfr/* 289177633Sdfr * In the kernel, we can't use global variables to store lists of 290177633Sdfr * transports etc. since otherwise we could not have two unrelated RPC 291177633Sdfr * services running, each on its own thread. We solve this by 292177633Sdfr * importing a tiny part of a Solaris kernel concept, SVCPOOL. 293177633Sdfr * 294177633Sdfr * A service pool contains a set of transports and service callbacks 295177633Sdfr * for a set of related RPC services. The pool handle should be passed 296177633Sdfr * when creating new transports etc. Future work may include extending 297177633Sdfr * this to support something similar to the Solaris multi-threaded RPC 298177633Sdfr * server. 299177633Sdfr */ 300177633SdfrTAILQ_HEAD(svcxprt_list, __rpc_svcxprt); 301184588Sdfrenum svcpool_state { 302184588Sdfr SVCPOOL_INIT, /* svc_run not called yet */ 303184588Sdfr SVCPOOL_ACTIVE, /* normal running state */ 304184588Sdfr SVCPOOL_THREADWANTED, /* new service thread requested */ 305184588Sdfr SVCPOOL_THREADSTARTING, /* new service thread started */ 306184588Sdfr SVCPOOL_CLOSING /* svc_exit called */ 307184588Sdfr}; 308184588Sdfrtypedef SVCTHREAD *pool_assign_fn(SVCTHREAD *, struct svc_req *); 309184588Sdfrtypedef void pool_done_fn(SVCTHREAD *, struct svc_req *); 310177633Sdfrtypedef struct __rpc_svcpool { 311177633Sdfr struct mtx sp_lock; /* protect the transport lists */ 312184588Sdfr const char *sp_name; /* pool name (e.g. "nfsd", "NLM" */ 313184588Sdfr enum svcpool_state sp_state; /* current pool state */ 314184588Sdfr struct proc *sp_proc; /* process which is in svc_run */ 315177633Sdfr struct svcxprt_list sp_xlist; /* all transports in the pool */ 316177633Sdfr struct svcxprt_list sp_active; /* transports needing service */ 317177633Sdfr struct svc_callout_list sp_callouts; /* (prog,vers)->dispatch list */ 318184588Sdfr struct svcthread_list sp_threads; /* service threads */ 319184588Sdfr struct svcthread_list sp_idlethreads; /* idle service threads */ 320184588Sdfr int sp_minthreads; /* minimum service thread count */ 321184588Sdfr int sp_maxthreads; /* maximum service thread count */ 322184588Sdfr int sp_threadcount; /* current service thread count */ 323184588Sdfr time_t sp_lastcreatetime; /* when we last started a thread */ 324184588Sdfr time_t sp_lastidlecheck; /* when we last checked idle transports */ 325184588Sdfr 326184588Sdfr /* 327184588Sdfr * Hooks to allow an application to control request to thread 328184588Sdfr * placement. 329184588Sdfr */ 330184588Sdfr pool_assign_fn *sp_assign; 331184588Sdfr pool_done_fn *sp_done; 332184588Sdfr 333184588Sdfr /* 334184588Sdfr * These variables are used to put an upper bound on the 335184588Sdfr * amount of memory used by RPC requests which are queued 336184588Sdfr * waiting for execution. 337184588Sdfr */ 338184588Sdfr unsigned int sp_space_low; 339184588Sdfr unsigned int sp_space_high; 340184588Sdfr unsigned int sp_space_used; 341184588Sdfr unsigned int sp_space_used_highest; 342184588Sdfr bool_t sp_space_throttled; 343184588Sdfr int sp_space_throttle_count; 344184588Sdfr 345184588Sdfr struct replay_cache *sp_rcache; /* optional replay cache */ 346184588Sdfr struct sysctl_ctx_list sp_sysctl; 347177633Sdfr} SVCPOOL; 348177633Sdfr 349184588Sdfr#else 350177633Sdfr 351177633Sdfr/* 352177633Sdfr * Service request 353177633Sdfr */ 354177633Sdfrstruct svc_req { 355177633Sdfr uint32_t rq_prog; /* service program number */ 356177633Sdfr uint32_t rq_vers; /* service protocol version */ 357177633Sdfr uint32_t rq_proc; /* the desired procedure */ 358177633Sdfr struct opaque_auth rq_cred; /* raw creds from the wire */ 359177633Sdfr void *rq_clntcred; /* read only cooked cred */ 360177633Sdfr SVCXPRT *rq_xprt; /* associated transport */ 361177633Sdfr}; 362177633Sdfr 363177633Sdfr/* 364177633Sdfr * Approved way of getting address of caller 365177633Sdfr */ 366177633Sdfr#define svc_getrpccaller(x) (&(x)->xp_rtaddr) 367177633Sdfr 368184588Sdfr#endif 369184588Sdfr 370177633Sdfr/* 371177633Sdfr * Operations defined on an SVCXPRT handle 372177633Sdfr * 373177633Sdfr * SVCXPRT *xprt; 374177633Sdfr * struct rpc_msg *msg; 375177633Sdfr * xdrproc_t xargs; 376177633Sdfr * void * argsp; 377177633Sdfr */ 378184588Sdfr#ifdef _KERNEL 379184588Sdfr 380184588Sdfr#define SVC_ACQUIRE(xprt) \ 381184588Sdfr refcount_acquire(&(xprt)->xp_refs) 382184588Sdfr 383184588Sdfr#define SVC_RELEASE(xprt) \ 384184588Sdfr if (refcount_release(&(xprt)->xp_refs)) \ 385184588Sdfr SVC_DESTROY(xprt) 386184588Sdfr 387184588Sdfr#define SVC_RECV(xprt, msg, addr, args) \ 388184588Sdfr (*(xprt)->xp_ops->xp_recv)((xprt), (msg), (addr), (args)) 389184588Sdfr 390184588Sdfr#define SVC_STAT(xprt) \ 391184588Sdfr (*(xprt)->xp_ops->xp_stat)(xprt) 392184588Sdfr 393184588Sdfr#define SVC_REPLY(xprt, msg, addr, m) \ 394184588Sdfr (*(xprt)->xp_ops->xp_reply) ((xprt), (msg), (addr), (m)) 395184588Sdfr 396184588Sdfr#define SVC_DESTROY(xprt) \ 397184588Sdfr (*(xprt)->xp_ops->xp_destroy)(xprt) 398184588Sdfr 399184588Sdfr#define SVC_CONTROL(xprt, rq, in) \ 400184588Sdfr (*(xprt)->xp_ops->xp_control)((xprt), (rq), (in)) 401184588Sdfr 402184588Sdfr#else 403184588Sdfr 404177633Sdfr#define SVC_RECV(xprt, msg) \ 405177633Sdfr (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) 406177633Sdfr#define svc_recv(xprt, msg) \ 407177633Sdfr (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) 408177633Sdfr 409177633Sdfr#define SVC_STAT(xprt) \ 410177633Sdfr (*(xprt)->xp_ops->xp_stat)(xprt) 411177633Sdfr#define svc_stat(xprt) \ 412177633Sdfr (*(xprt)->xp_ops->xp_stat)(xprt) 413177633Sdfr 414177633Sdfr#define SVC_GETARGS(xprt, xargs, argsp) \ 415177633Sdfr (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) 416177633Sdfr#define svc_getargs(xprt, xargs, argsp) \ 417177633Sdfr (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) 418177633Sdfr 419177633Sdfr#define SVC_REPLY(xprt, msg) \ 420177633Sdfr (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) 421177633Sdfr#define svc_reply(xprt, msg) \ 422177633Sdfr (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) 423177633Sdfr 424177633Sdfr#define SVC_FREEARGS(xprt, xargs, argsp) \ 425177633Sdfr (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) 426177633Sdfr#define svc_freeargs(xprt, xargs, argsp) \ 427177633Sdfr (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) 428177633Sdfr 429177633Sdfr#define SVC_DESTROY(xprt) \ 430177633Sdfr (*(xprt)->xp_ops->xp_destroy)(xprt) 431177633Sdfr#define svc_destroy(xprt) \ 432177633Sdfr (*(xprt)->xp_ops->xp_destroy)(xprt) 433177633Sdfr 434177633Sdfr#define SVC_CONTROL(xprt, rq, in) \ 435177633Sdfr (*(xprt)->xp_ops2->xp_control)((xprt), (rq), (in)) 436184588Sdfr 437177633Sdfr#endif 438177633Sdfr 439184588Sdfr#define SVC_EXT(xprt) \ 440184588Sdfr ((SVCXPRT_EXT *) xprt->xp_p3) 441184588Sdfr 442184588Sdfr#define SVC_AUTH(xprt) \ 443184588Sdfr (SVC_EXT(xprt)->xp_auth) 444184588Sdfr 445177633Sdfr/* 446184588Sdfr * Operations defined on an SVCAUTH handle 447184588Sdfr */ 448184588Sdfr#ifdef _KERNEL 449184588Sdfr#define SVCAUTH_WRAP(auth, mp) \ 450184588Sdfr ((auth)->svc_ah_ops->svc_ah_wrap(auth, mp)) 451184588Sdfr#define SVCAUTH_UNWRAP(auth, mp) \ 452184588Sdfr ((auth)->svc_ah_ops->svc_ah_unwrap(auth, mp)) 453184588Sdfr#define SVCAUTH_RELEASE(auth) \ 454184588Sdfr ((auth)->svc_ah_ops->svc_ah_release(auth)) 455184588Sdfr#else 456184588Sdfr#define SVCAUTH_WRAP(auth, xdrs, xfunc, xwhere) \ 457184588Sdfr ((auth)->svc_ah_ops->svc_ah_wrap(auth, xdrs, xfunc, xwhere)) 458184588Sdfr#define SVCAUTH_UNWRAP(auth, xdrs, xfunc, xwhere) \ 459184588Sdfr ((auth)->svc_ah_ops->svc_ah_unwrap(auth, xdrs, xfunc, xwhere)) 460184588Sdfr#endif 461184588Sdfr 462184588Sdfr/* 463177633Sdfr * Service registration 464177633Sdfr * 465177633Sdfr * svc_reg(xprt, prog, vers, dispatch, nconf) 466177633Sdfr * const SVCXPRT *xprt; 467177633Sdfr * const rpcprog_t prog; 468177633Sdfr * const rpcvers_t vers; 469177633Sdfr * const void (*dispatch)(); 470177633Sdfr * const struct netconfig *nconf; 471177633Sdfr */ 472177633Sdfr 473177633Sdfr__BEGIN_DECLS 474177633Sdfrextern bool_t svc_reg(SVCXPRT *, const rpcprog_t, const rpcvers_t, 475177633Sdfr void (*)(struct svc_req *, SVCXPRT *), 476177633Sdfr const struct netconfig *); 477177633Sdfr__END_DECLS 478177633Sdfr 479177633Sdfr/* 480177633Sdfr * Service un-registration 481177633Sdfr * 482177633Sdfr * svc_unreg(prog, vers) 483177633Sdfr * const rpcprog_t prog; 484177633Sdfr * const rpcvers_t vers; 485177633Sdfr */ 486177633Sdfr 487177633Sdfr__BEGIN_DECLS 488177633Sdfr#ifdef _KERNEL 489177633Sdfrextern void svc_unreg(SVCPOOL *, const rpcprog_t, const rpcvers_t); 490177633Sdfr#else 491177633Sdfrextern void svc_unreg(const rpcprog_t, const rpcvers_t); 492177633Sdfr#endif 493177633Sdfr__END_DECLS 494177633Sdfr 495177633Sdfr/* 496177633Sdfr * Transport registration. 497177633Sdfr * 498177633Sdfr * xprt_register(xprt) 499177633Sdfr * SVCXPRT *xprt; 500177633Sdfr */ 501177633Sdfr__BEGIN_DECLS 502177633Sdfrextern void xprt_register(SVCXPRT *); 503177633Sdfr__END_DECLS 504177633Sdfr 505177633Sdfr/* 506177633Sdfr * Transport un-register 507177633Sdfr * 508177633Sdfr * xprt_unregister(xprt) 509177633Sdfr * SVCXPRT *xprt; 510177633Sdfr */ 511177633Sdfr__BEGIN_DECLS 512177633Sdfrextern void xprt_unregister(SVCXPRT *); 513177633Sdfrextern void __xprt_unregister_unlocked(SVCXPRT *); 514177633Sdfr__END_DECLS 515177633Sdfr 516177633Sdfr#ifdef _KERNEL 517177633Sdfr 518177633Sdfr/* 519177633Sdfr * Called when a transport has pending requests. 520177633Sdfr */ 521177633Sdfr__BEGIN_DECLS 522177633Sdfrextern void xprt_active(SVCXPRT *); 523177633Sdfrextern void xprt_inactive(SVCXPRT *); 524184588Sdfrextern void xprt_inactive_locked(SVCXPRT *); 525177633Sdfr__END_DECLS 526177633Sdfr 527177633Sdfr#endif 528177633Sdfr 529177633Sdfr/* 530177633Sdfr * When the service routine is called, it must first check to see if it 531177633Sdfr * knows about the procedure; if not, it should call svcerr_noproc 532177633Sdfr * and return. If so, it should deserialize its arguments via 533177633Sdfr * SVC_GETARGS (defined above). If the deserialization does not work, 534177633Sdfr * svcerr_decode should be called followed by a return. Successful 535177633Sdfr * decoding of the arguments should be followed the execution of the 536177633Sdfr * procedure's code and a call to svc_sendreply. 537177633Sdfr * 538177633Sdfr * Also, if the service refuses to execute the procedure due to too- 539177633Sdfr * weak authentication parameters, svcerr_weakauth should be called. 540177633Sdfr * Note: do not confuse access-control failure with weak authentication! 541177633Sdfr * 542177633Sdfr * NB: In pure implementations of rpc, the caller always waits for a reply 543177633Sdfr * msg. This message is sent when svc_sendreply is called. 544177633Sdfr * Therefore pure service implementations should always call 545177633Sdfr * svc_sendreply even if the function logically returns void; use 546177633Sdfr * xdr.h - xdr_void for the xdr routine. HOWEVER, tcp based rpc allows 547177633Sdfr * for the abuse of pure rpc via batched calling or pipelining. In the 548177633Sdfr * case of a batched call, svc_sendreply should NOT be called since 549177633Sdfr * this would send a return message, which is what batching tries to avoid. 550177633Sdfr * It is the service/protocol writer's responsibility to know which calls are 551177633Sdfr * batched and which are not. Warning: responding to batch calls may 552177633Sdfr * deadlock the caller and server processes! 553177633Sdfr */ 554177633Sdfr 555177633Sdfr__BEGIN_DECLS 556184588Sdfr#ifdef _KERNEL 557184588Sdfrextern bool_t svc_sendreply(struct svc_req *, xdrproc_t, void *); 558184588Sdfrextern bool_t svc_sendreply_mbuf(struct svc_req *, struct mbuf *); 559184588Sdfrextern void svcerr_decode(struct svc_req *); 560184588Sdfrextern void svcerr_weakauth(struct svc_req *); 561184588Sdfrextern void svcerr_noproc(struct svc_req *); 562184588Sdfrextern void svcerr_progvers(struct svc_req *, rpcvers_t, rpcvers_t); 563184588Sdfrextern void svcerr_auth(struct svc_req *, enum auth_stat); 564184588Sdfrextern void svcerr_noprog(struct svc_req *); 565184588Sdfrextern void svcerr_systemerr(struct svc_req *); 566184588Sdfr#else 567177633Sdfrextern bool_t svc_sendreply(SVCXPRT *, xdrproc_t, void *); 568177633Sdfrextern void svcerr_decode(SVCXPRT *); 569177633Sdfrextern void svcerr_weakauth(SVCXPRT *); 570177633Sdfrextern void svcerr_noproc(SVCXPRT *); 571177633Sdfrextern void svcerr_progvers(SVCXPRT *, rpcvers_t, rpcvers_t); 572177633Sdfrextern void svcerr_auth(SVCXPRT *, enum auth_stat); 573177633Sdfrextern void svcerr_noprog(SVCXPRT *); 574177633Sdfrextern void svcerr_systemerr(SVCXPRT *); 575184588Sdfr#endif 576177633Sdfrextern int rpc_reg(rpcprog_t, rpcvers_t, rpcproc_t, 577177633Sdfr char *(*)(char *), xdrproc_t, xdrproc_t, 578177633Sdfr char *); 579177633Sdfr__END_DECLS 580177633Sdfr 581177633Sdfr/* 582177633Sdfr * Lowest level dispatching -OR- who owns this process anyway. 583177633Sdfr * Somebody has to wait for incoming requests and then call the correct 584177633Sdfr * service routine. The routine svc_run does infinite waiting; i.e., 585177633Sdfr * svc_run never returns. 586177633Sdfr * Since another (co-existant) package may wish to selectively wait for 587177633Sdfr * incoming calls or other events outside of the rpc architecture, the 588177633Sdfr * routine svc_getreq is provided. It must be passed readfds, the 589177633Sdfr * "in-place" results of a select system call (see select, section 2). 590177633Sdfr */ 591177633Sdfr 592177633Sdfr#ifndef _KERNEL 593177633Sdfr/* 594177633Sdfr * Global keeper of rpc service descriptors in use 595177633Sdfr * dynamic; must be inspected before each call to select 596177633Sdfr */ 597177633Sdfrextern int svc_maxfd; 598177633Sdfr#ifdef FD_SETSIZE 599177633Sdfrextern fd_set svc_fdset; 600177633Sdfr#define svc_fds svc_fdset.fds_bits[0] /* compatibility */ 601177633Sdfr#else 602177633Sdfrextern int svc_fds; 603177633Sdfr#endif /* def FD_SETSIZE */ 604177633Sdfr#endif 605177633Sdfr 606177633Sdfr/* 607177633Sdfr * a small program implemented by the svc_rpc implementation itself; 608177633Sdfr * also see clnt.h for protocol numbers. 609177633Sdfr */ 610177633Sdfr__BEGIN_DECLS 611177633Sdfrextern void rpctest_service(void); 612177633Sdfr__END_DECLS 613177633Sdfr 614177633Sdfr__BEGIN_DECLS 615184588Sdfrextern SVCXPRT *svc_xprt_alloc(void); 616184588Sdfrextern void svc_xprt_free(SVCXPRT *); 617177633Sdfr#ifndef _KERNEL 618177633Sdfrextern void svc_getreq(int); 619177633Sdfrextern void svc_getreqset(fd_set *); 620177633Sdfrextern void svc_getreq_common(int); 621177633Sdfrstruct pollfd; 622177633Sdfrextern void svc_getreq_poll(struct pollfd *, int); 623177633Sdfrextern void svc_run(void); 624177633Sdfrextern void svc_exit(void); 625177633Sdfr#else 626177633Sdfrextern void svc_run(SVCPOOL *); 627177633Sdfrextern void svc_exit(SVCPOOL *); 628184588Sdfrextern bool_t svc_getargs(struct svc_req *, xdrproc_t, void *); 629184588Sdfrextern bool_t svc_freeargs(struct svc_req *, xdrproc_t, void *); 630184588Sdfrextern void svc_freereq(struct svc_req *); 631184588Sdfr 632177633Sdfr#endif 633177633Sdfr__END_DECLS 634177633Sdfr 635177633Sdfr/* 636177633Sdfr * Socket to use on svcxxx_create call to get default socket 637177633Sdfr */ 638177633Sdfr#define RPC_ANYSOCK -1 639177633Sdfr#define RPC_ANYFD RPC_ANYSOCK 640177633Sdfr 641177633Sdfr/* 642177633Sdfr * These are the existing service side transport implementations 643177633Sdfr */ 644177633Sdfr 645177633Sdfr__BEGIN_DECLS 646177633Sdfr 647177633Sdfr#ifdef _KERNEL 648177633Sdfr 649177633Sdfr/* 650177633Sdfr * Create a new service pool. 651177633Sdfr */ 652184588Sdfrextern SVCPOOL* svcpool_create(const char *name, 653184588Sdfr struct sysctl_oid_list *sysctl_base); 654177633Sdfr 655177633Sdfr/* 656177633Sdfr * Destroy a service pool, including all registered transports. 657177633Sdfr */ 658177633Sdfrextern void svcpool_destroy(SVCPOOL *pool); 659177633Sdfr 660177633Sdfr/* 661177633Sdfr * Transport independent svc_create routine. 662177633Sdfr */ 663177633Sdfrextern int svc_create(SVCPOOL *, void (*)(struct svc_req *, SVCXPRT *), 664177633Sdfr const rpcprog_t, const rpcvers_t, const char *); 665177633Sdfr/* 666177633Sdfr * void (*dispatch)(); -- dispatch routine 667177633Sdfr * const rpcprog_t prognum; -- program number 668177633Sdfr * const rpcvers_t versnum; -- version number 669177633Sdfr * const char *nettype; -- network type 670177633Sdfr */ 671177633Sdfr 672177633Sdfr 673177633Sdfr/* 674177633Sdfr * Generic server creation routine. It takes a netconfig structure 675177633Sdfr * instead of a nettype. 676177633Sdfr */ 677177633Sdfr 678177633Sdfrextern SVCXPRT *svc_tp_create(SVCPOOL *, void (*)(struct svc_req *, SVCXPRT *), 679177633Sdfr const rpcprog_t, const rpcvers_t, const char *uaddr, 680177633Sdfr const struct netconfig *); 681177633Sdfr /* 682177633Sdfr * void (*dispatch)(); -- dispatch routine 683177633Sdfr * const rpcprog_t prognum; -- program number 684177633Sdfr * const rpcvers_t versnum; -- version number 685177633Sdfr * const char *uaddr; -- universal address of service 686177633Sdfr * const struct netconfig *nconf; -- netconfig structure 687177633Sdfr */ 688177633Sdfr 689177633Sdfrextern SVCXPRT *svc_dg_create(SVCPOOL *, struct socket *, 690177633Sdfr const size_t, const size_t); 691177633Sdfr /* 692177633Sdfr * struct socket *; -- open connection 693177633Sdfr * const size_t sendsize; -- max send size 694177633Sdfr * const size_t recvsize; -- max recv size 695177633Sdfr */ 696177633Sdfr 697177633Sdfrextern SVCXPRT *svc_vc_create(SVCPOOL *, struct socket *, 698177633Sdfr const size_t, const size_t); 699177633Sdfr /* 700177633Sdfr * struct socket *; -- open connection 701177633Sdfr * const size_t sendsize; -- max send size 702177633Sdfr * const size_t recvsize; -- max recv size 703177633Sdfr */ 704177633Sdfr 705177633Sdfr/* 706177633Sdfr * Generic TLI create routine 707177633Sdfr */ 708177633Sdfrextern SVCXPRT *svc_tli_create(SVCPOOL *, struct socket *, 709177633Sdfr const struct netconfig *, const struct t_bind *, const size_t, const size_t); 710177633Sdfr/* 711177633Sdfr * struct socket * so; -- connection end point 712177633Sdfr * const struct netconfig *nconf; -- netconfig structure for network 713177633Sdfr * const struct t_bind *bindaddr; -- local bind address 714177633Sdfr * const size_t sendsz; -- max sendsize 715177633Sdfr * const size_t recvsz; -- max recvsize 716177633Sdfr */ 717177633Sdfr 718177633Sdfr#else /* !_KERNEL */ 719177633Sdfr 720177633Sdfr/* 721177633Sdfr * Transport independent svc_create routine. 722177633Sdfr */ 723177633Sdfrextern int svc_create(void (*)(struct svc_req *, SVCXPRT *), 724177633Sdfr const rpcprog_t, const rpcvers_t, const char *); 725177633Sdfr/* 726177633Sdfr * void (*dispatch)(); -- dispatch routine 727177633Sdfr * const rpcprog_t prognum; -- program number 728177633Sdfr * const rpcvers_t versnum; -- version number 729177633Sdfr * const char *nettype; -- network type 730177633Sdfr */ 731177633Sdfr 732177633Sdfr 733177633Sdfr/* 734177633Sdfr * Generic server creation routine. It takes a netconfig structure 735177633Sdfr * instead of a nettype. 736177633Sdfr */ 737177633Sdfr 738177633Sdfrextern SVCXPRT *svc_tp_create(void (*)(struct svc_req *, SVCXPRT *), 739177633Sdfr const rpcprog_t, const rpcvers_t, 740177633Sdfr const struct netconfig *); 741177633Sdfr /* 742177633Sdfr * void (*dispatch)(); -- dispatch routine 743177633Sdfr * const rpcprog_t prognum; -- program number 744177633Sdfr * const rpcvers_t versnum; -- version number 745177633Sdfr * const struct netconfig *nconf; -- netconfig structure 746177633Sdfr */ 747177633Sdfr 748177633Sdfr/* 749177633Sdfr * Generic TLI create routine 750177633Sdfr */ 751177633Sdfrextern SVCXPRT *svc_tli_create(const int, const struct netconfig *, 752177633Sdfr const struct t_bind *, const u_int, 753177633Sdfr const u_int); 754177633Sdfr/* 755177633Sdfr * const int fd; -- connection end point 756177633Sdfr * const struct netconfig *nconf; -- netconfig structure for network 757177633Sdfr * const struct t_bind *bindaddr; -- local bind address 758177633Sdfr * const u_int sendsz; -- max sendsize 759177633Sdfr * const u_int recvsz; -- max recvsize 760177633Sdfr */ 761177633Sdfr 762177633Sdfr/* 763177633Sdfr * Connectionless and connectionful create routines 764177633Sdfr */ 765177633Sdfr 766177633Sdfrextern SVCXPRT *svc_vc_create(const int, const u_int, const u_int); 767177633Sdfr/* 768177633Sdfr * const int fd; -- open connection end point 769177633Sdfr * const u_int sendsize; -- max send size 770177633Sdfr * const u_int recvsize; -- max recv size 771177633Sdfr */ 772177633Sdfr 773177633Sdfr/* 774177633Sdfr * Added for compatibility to old rpc 4.0. Obsoleted by svc_vc_create(). 775177633Sdfr */ 776177633Sdfrextern SVCXPRT *svcunix_create(int, u_int, u_int, char *); 777177633Sdfr 778177633Sdfrextern SVCXPRT *svc_dg_create(const int, const u_int, const u_int); 779177633Sdfr /* 780177633Sdfr * const int fd; -- open connection 781177633Sdfr * const u_int sendsize; -- max send size 782177633Sdfr * const u_int recvsize; -- max recv size 783177633Sdfr */ 784177633Sdfr 785177633Sdfr 786177633Sdfr/* 787177633Sdfr * the routine takes any *open* connection 788177633Sdfr * descriptor as its first input and is used for open connections. 789177633Sdfr */ 790177633Sdfrextern SVCXPRT *svc_fd_create(const int, const u_int, const u_int); 791177633Sdfr/* 792177633Sdfr * const int fd; -- open connection end point 793177633Sdfr * const u_int sendsize; -- max send size 794177633Sdfr * const u_int recvsize; -- max recv size 795177633Sdfr */ 796177633Sdfr 797177633Sdfr/* 798177633Sdfr * Added for compatibility to old rpc 4.0. Obsoleted by svc_fd_create(). 799177633Sdfr */ 800177633Sdfrextern SVCXPRT *svcunixfd_create(int, u_int, u_int); 801177633Sdfr 802177633Sdfr/* 803177633Sdfr * Memory based rpc (for speed check and testing) 804177633Sdfr */ 805177633Sdfrextern SVCXPRT *svc_raw_create(void); 806177633Sdfr 807177633Sdfr/* 808177633Sdfr * svc_dg_enable_cache() enables the cache on dg transports. 809177633Sdfr */ 810177633Sdfrint svc_dg_enablecache(SVCXPRT *, const u_int); 811177633Sdfr 812177633Sdfrint __rpc_get_local_uid(SVCXPRT *_transp, uid_t *_uid); 813177633Sdfr 814177633Sdfr#endif /* !_KERNEL */ 815177633Sdfr 816177633Sdfr__END_DECLS 817177633Sdfr 818177633Sdfr#ifndef _KERNEL 819177633Sdfr/* for backward compatibility */ 820177633Sdfr#include <rpc/svc_soc.h> 821177633Sdfr#endif 822177633Sdfr 823177633Sdfr#endif /* !_RPC_SVC_H */ 824