1177633Sdfr/* $NetBSD: svc.h,v 1.17 2000/06/02 22:57:56 fvdl Exp $ */ 2177633Sdfr 3261057Smav/*- 4261057Smav * Copyright (c) 2009, Sun Microsystems, Inc. 5261057Smav * All rights reserved. 6177633Sdfr * 7261057Smav * Redistribution and use in source and binary forms, with or without 8261057Smav * modification, are permitted provided that the following conditions are met: 9261057Smav * - Redistributions of source code must retain the above copyright notice, 10261057Smav * this list of conditions and the following disclaimer. 11261057Smav * - Redistributions in binary form must reproduce the above copyright notice, 12261057Smav * this list of conditions and the following disclaimer in the documentation 13261057Smav * and/or other materials provided with the distribution. 14261057Smav * - Neither the name of Sun Microsystems, Inc. nor the names of its 15261057Smav * contributors may be used to endorse or promote products derived 16261057Smav * from this software without specific prior written permission. 17261057Smav * 18261057Smav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19261057Smav * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20261057Smav * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21261057Smav * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22261057Smav * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23261057Smav * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24261057Smav * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25261057Smav * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26261057Smav * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27261057Smav * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28261057Smav * POSSIBILITY OF SUCH DAMAGE. 29177633Sdfr * 30177633Sdfr * from: @(#)svc.h 1.35 88/12/17 SMI 31177633Sdfr * from: @(#)svc.h 1.27 94/04/25 SMI 32177633Sdfr * $FreeBSD$ 33177633Sdfr */ 34177633Sdfr 35177633Sdfr/* 36177633Sdfr * svc.h, Server-side remote procedure call interface. 37177633Sdfr * 38177633Sdfr * Copyright (C) 1986-1993 by Sun Microsystems, Inc. 39177633Sdfr */ 40177633Sdfr 41177633Sdfr#ifndef _RPC_SVC_H 42177633Sdfr#define _RPC_SVC_H 43177633Sdfr#include <sys/cdefs.h> 44177633Sdfr 45177633Sdfr#ifdef _KERNEL 46177633Sdfr#include <sys/queue.h> 47177633Sdfr#include <sys/_lock.h> 48177633Sdfr#include <sys/_mutex.h> 49184588Sdfr#include <sys/_sx.h> 50184588Sdfr#include <sys/condvar.h> 51184588Sdfr#include <sys/sysctl.h> 52177633Sdfr#endif 53177633Sdfr 54177633Sdfr/* 55177633Sdfr * This interface must manage two items concerning remote procedure calling: 56177633Sdfr * 57177633Sdfr * 1) An arbitrary number of transport connections upon which rpc requests 58177633Sdfr * are received. The two most notable transports are TCP and UDP; they are 59177633Sdfr * created and registered by routines in svc_tcp.c and svc_udp.c, respectively; 60177633Sdfr * they in turn call xprt_register and xprt_unregister. 61177633Sdfr * 62177633Sdfr * 2) An arbitrary number of locally registered services. Services are 63177633Sdfr * described by the following four data: program number, version number, 64177633Sdfr * "service dispatch" function, a transport handle, and a boolean that 65177633Sdfr * indicates whether or not the exported program should be registered with a 66177633Sdfr * local binder service; if true the program's number and version and the 67177633Sdfr * port number from the transport handle are registered with the binder. 68177633Sdfr * These data are registered with the rpc svc system via svc_register. 69177633Sdfr * 70177633Sdfr * A service's dispatch function is called whenever an rpc request comes in 71177633Sdfr * on a transport. The request's program and version numbers must match 72177633Sdfr * those of the registered service. The dispatch function is passed two 73177633Sdfr * parameters, struct svc_req * and SVCXPRT *, defined below. 74177633Sdfr */ 75177633Sdfr 76177633Sdfr/* 77177633Sdfr * Service control requests 78177633Sdfr */ 79177633Sdfr#define SVCGET_VERSQUIET 1 80177633Sdfr#define SVCSET_VERSQUIET 2 81177633Sdfr#define SVCGET_CONNMAXREC 3 82177633Sdfr#define SVCSET_CONNMAXREC 4 83177633Sdfr 84177633Sdfr/* 85177633Sdfr * Operations for rpc_control(). 86177633Sdfr */ 87177633Sdfr#define RPC_SVC_CONNMAXREC_SET 0 /* set max rec size, enable nonblock */ 88177633Sdfr#define RPC_SVC_CONNMAXREC_GET 1 89177633Sdfr 90177633Sdfrenum xprt_stat { 91177633Sdfr XPRT_DIED, 92177633Sdfr XPRT_MOREREQS, 93177633Sdfr XPRT_IDLE 94177633Sdfr}; 95177633Sdfr 96177633Sdfrstruct __rpc_svcxprt; 97184588Sdfrstruct mbuf; 98177633Sdfr 99177633Sdfrstruct xp_ops { 100184588Sdfr#ifdef _KERNEL 101177633Sdfr /* receive incoming requests */ 102184588Sdfr bool_t (*xp_recv)(struct __rpc_svcxprt *, struct rpc_msg *, 103184588Sdfr struct sockaddr **, struct mbuf **); 104184588Sdfr /* get transport status */ 105184588Sdfr enum xprt_stat (*xp_stat)(struct __rpc_svcxprt *); 106261067Smav /* get transport acknowledge sequence */ 107261067Smav bool_t (*xp_ack)(struct __rpc_svcxprt *, uint32_t *); 108184588Sdfr /* send reply */ 109184588Sdfr bool_t (*xp_reply)(struct __rpc_svcxprt *, struct rpc_msg *, 110261067Smav struct sockaddr *, struct mbuf *, uint32_t *); 111184588Sdfr /* destroy this struct */ 112184588Sdfr void (*xp_destroy)(struct __rpc_svcxprt *); 113184588Sdfr /* catch-all function */ 114184588Sdfr bool_t (*xp_control)(struct __rpc_svcxprt *, const u_int, void *); 115184588Sdfr#else 116184588Sdfr /* receive incoming requests */ 117177633Sdfr bool_t (*xp_recv)(struct __rpc_svcxprt *, struct rpc_msg *); 118177633Sdfr /* get transport status */ 119177633Sdfr enum xprt_stat (*xp_stat)(struct __rpc_svcxprt *); 120177633Sdfr /* get arguments */ 121177633Sdfr bool_t (*xp_getargs)(struct __rpc_svcxprt *, xdrproc_t, void *); 122177633Sdfr /* send reply */ 123177633Sdfr bool_t (*xp_reply)(struct __rpc_svcxprt *, struct rpc_msg *); 124177633Sdfr /* free mem allocated for args */ 125177633Sdfr bool_t (*xp_freeargs)(struct __rpc_svcxprt *, xdrproc_t, void *); 126177633Sdfr /* destroy this struct */ 127177633Sdfr void (*xp_destroy)(struct __rpc_svcxprt *); 128177633Sdfr#endif 129177633Sdfr}; 130177633Sdfr 131177633Sdfr#ifndef _KERNEL 132177633Sdfrstruct xp_ops2 { 133177633Sdfr /* catch-all function */ 134177633Sdfr bool_t (*xp_control)(struct __rpc_svcxprt *, const u_int, void *); 135177633Sdfr}; 136177633Sdfr#endif 137177633Sdfr 138177633Sdfr#ifdef _KERNEL 139177633Sdfrstruct __rpc_svcpool; 140184588Sdfrstruct __rpc_svcthread; 141177633Sdfr#endif 142177633Sdfr 143177633Sdfr/* 144184588Sdfr * Server side transport handle. In the kernel, transports have a 145184588Sdfr * reference count which tracks the number of currently assigned 146184588Sdfr * worker threads plus one for the service pool's reference. 147177633Sdfr */ 148177633Sdfrtypedef struct __rpc_svcxprt { 149177633Sdfr#ifdef _KERNEL 150184588Sdfr volatile u_int xp_refs; 151184588Sdfr struct sx xp_lock; 152177633Sdfr struct __rpc_svcpool *xp_pool; /* owning pool (see below) */ 153177633Sdfr TAILQ_ENTRY(__rpc_svcxprt) xp_link; 154177633Sdfr TAILQ_ENTRY(__rpc_svcxprt) xp_alink; 155177633Sdfr bool_t xp_registered; /* xprt_register has been called */ 156177633Sdfr bool_t xp_active; /* xprt_active has been called */ 157184588Sdfr struct __rpc_svcthread *xp_thread; /* assigned service thread */ 158177633Sdfr struct socket* xp_socket; 159177633Sdfr const struct xp_ops *xp_ops; 160177633Sdfr char *xp_netid; /* network token */ 161184588Sdfr struct sockaddr_storage xp_ltaddr; /* local transport address */ 162184588Sdfr struct sockaddr_storage xp_rtaddr; /* remote transport address */ 163177633Sdfr void *xp_p1; /* private: for use by svc ops */ 164177633Sdfr void *xp_p2; /* private: for use by svc ops */ 165177633Sdfr void *xp_p3; /* private: for use by svc lib */ 166177633Sdfr int xp_type; /* transport type */ 167184588Sdfr int xp_idletimeout; /* idle time before closing */ 168184588Sdfr time_t xp_lastactive; /* time of last RPC */ 169191145Srmacklem u_int64_t xp_sockref; /* set by nfsv4 to identify socket */ 170193436Srmacklem int xp_upcallset; /* socket upcall is set up */ 171261067Smav uint32_t xp_snd_cnt; /* # of bytes to send to socket */ 172261067Smav uint32_t xp_snt_cnt; /* # of bytes sent to socket */ 173177633Sdfr#else 174177633Sdfr int xp_fd; 175177633Sdfr u_short xp_port; /* associated port number */ 176177633Sdfr const struct xp_ops *xp_ops; 177177633Sdfr int xp_addrlen; /* length of remote address */ 178177633Sdfr struct sockaddr_in xp_raddr; /* remote addr. (backward ABI compat) */ 179177633Sdfr /* XXX - fvdl stick this here for ABI backward compat reasons */ 180177633Sdfr const struct xp_ops2 *xp_ops2; 181177633Sdfr char *xp_tp; /* transport provider device name */ 182177633Sdfr char *xp_netid; /* network token */ 183177633Sdfr struct netbuf xp_ltaddr; /* local transport address */ 184177633Sdfr struct netbuf xp_rtaddr; /* remote transport address */ 185177633Sdfr struct opaque_auth xp_verf; /* raw response verifier */ 186177633Sdfr void *xp_p1; /* private: for use by svc ops */ 187177633Sdfr void *xp_p2; /* private: for use by svc ops */ 188177633Sdfr void *xp_p3; /* private: for use by svc lib */ 189177633Sdfr int xp_type; /* transport type */ 190177633Sdfr#endif 191177633Sdfr} SVCXPRT; 192177633Sdfr 193184588Sdfr/* 194184588Sdfr * Interface to server-side authentication flavors. 195184588Sdfr */ 196184588Sdfrtypedef struct __rpc_svcauth { 197184588Sdfr struct svc_auth_ops { 198177633Sdfr#ifdef _KERNEL 199184588Sdfr int (*svc_ah_wrap)(struct __rpc_svcauth *, struct mbuf **); 200184588Sdfr int (*svc_ah_unwrap)(struct __rpc_svcauth *, struct mbuf **); 201184588Sdfr void (*svc_ah_release)(struct __rpc_svcauth *); 202184588Sdfr#else 203184588Sdfr int (*svc_ah_wrap)(struct __rpc_svcauth *, XDR *, 204184588Sdfr xdrproc_t, caddr_t); 205184588Sdfr int (*svc_ah_unwrap)(struct __rpc_svcauth *, XDR *, 206184588Sdfr xdrproc_t, caddr_t); 207184588Sdfr#endif 208184588Sdfr } *svc_ah_ops; 209184588Sdfr void *svc_ah_private; 210184588Sdfr} SVCAUTH; 211177633Sdfr 212177633Sdfr/* 213184588Sdfr * Server transport extensions (accessed via xp_p3). 214184588Sdfr */ 215184588Sdfrtypedef struct __rpc_svcxprt_ext { 216184588Sdfr int xp_flags; /* versquiet */ 217184588Sdfr SVCAUTH xp_auth; /* interface to auth methods */ 218184588Sdfr} SVCXPRT_EXT; 219184588Sdfr 220184588Sdfr#ifdef _KERNEL 221184588Sdfr 222184588Sdfr/* 223177633Sdfr * The services list 224177633Sdfr * Each entry represents a set of procedures (an rpc program). 225177633Sdfr * The dispatch routine takes request structs and runs the 226177633Sdfr * apropriate procedure. 227177633Sdfr */ 228177633Sdfrstruct svc_callout { 229177633Sdfr TAILQ_ENTRY(svc_callout) sc_link; 230177633Sdfr rpcprog_t sc_prog; 231177633Sdfr rpcvers_t sc_vers; 232177633Sdfr char *sc_netid; 233177633Sdfr void (*sc_dispatch)(struct svc_req *, SVCXPRT *); 234177633Sdfr}; 235177633SdfrTAILQ_HEAD(svc_callout_list, svc_callout); 236177633Sdfr 237261067Smav/* 238261067Smav * The services connection loss list 239261067Smav * The dispatch routine takes request structs and runs the 240261067Smav * apropriate procedure. 241261067Smav */ 242261067Smavstruct svc_loss_callout { 243261067Smav TAILQ_ENTRY(svc_loss_callout) slc_link; 244261067Smav void (*slc_dispatch)(SVCXPRT *); 245261067Smav}; 246261067SmavTAILQ_HEAD(svc_loss_callout_list, svc_loss_callout); 247261067Smav 248184588Sdfrstruct __rpc_svcthread; 249184588Sdfr 250177633Sdfr/* 251184588Sdfr * Service request 252184588Sdfr */ 253184588Sdfrstruct svc_req { 254184588Sdfr STAILQ_ENTRY(svc_req) rq_link; /* list of requests for a thread */ 255184588Sdfr struct __rpc_svcthread *rq_thread; /* thread which is to execute this */ 256184588Sdfr uint32_t rq_xid; /* RPC transaction ID */ 257184588Sdfr uint32_t rq_prog; /* service program number */ 258184588Sdfr uint32_t rq_vers; /* service protocol version */ 259184588Sdfr uint32_t rq_proc; /* the desired procedure */ 260184588Sdfr size_t rq_size; /* space used by request */ 261184588Sdfr struct mbuf *rq_args; /* XDR-encoded procedure arguments */ 262184588Sdfr struct opaque_auth rq_cred; /* raw creds from the wire */ 263184588Sdfr struct opaque_auth rq_verf; /* verifier for the reply */ 264184588Sdfr void *rq_clntcred; /* read only cooked cred */ 265184588Sdfr SVCAUTH rq_auth; /* interface to auth methods */ 266184588Sdfr SVCXPRT *rq_xprt; /* associated transport */ 267184588Sdfr struct sockaddr *rq_addr; /* reply address or NULL if connected */ 268184588Sdfr void *rq_p1; /* application workspace */ 269184588Sdfr int rq_p2; /* application workspace */ 270184588Sdfr uint64_t rq_p3; /* application workspace */ 271261067Smav uint32_t rq_reply_seq; /* reply socket sequence # */ 272184588Sdfr char rq_credarea[3*MAX_AUTH_BYTES]; 273184588Sdfr}; 274184588SdfrSTAILQ_HEAD(svc_reqlist, svc_req); 275184588Sdfr 276184588Sdfr#define svc_getrpccaller(rq) \ 277184588Sdfr ((rq)->rq_addr ? (rq)->rq_addr : \ 278184588Sdfr (struct sockaddr *) &(rq)->rq_xprt->xp_rtaddr) 279184588Sdfr 280184588Sdfr/* 281184588Sdfr * This structure is used to manage a thread which is executing 282184588Sdfr * requests from a service pool. A service thread is in one of three 283184588Sdfr * states: 284184588Sdfr * 285184588Sdfr * SVCTHREAD_SLEEPING waiting for a request to process 286184588Sdfr * SVCTHREAD_ACTIVE processing a request 287184588Sdfr * SVCTHREAD_EXITING exiting after finishing current request 288184588Sdfr * 289184588Sdfr * Threads which have no work to process sleep on the pool's sp_active 290184588Sdfr * list. When a transport becomes active, it is assigned a service 291184588Sdfr * thread to read and execute pending RPCs. 292184588Sdfr */ 293184588Sdfrtypedef struct __rpc_svcthread { 294261066Smav struct __rpc_svcpool *st_pool; 295184588Sdfr SVCXPRT *st_xprt; /* transport we are processing */ 296184588Sdfr struct svc_reqlist st_reqs; /* RPC requests to execute */ 297261060Smav int st_idle; /* thread is on idle list */ 298184588Sdfr struct cv st_cond; /* sleeping for work */ 299184588Sdfr LIST_ENTRY(__rpc_svcthread) st_link; /* all threads list */ 300184588Sdfr LIST_ENTRY(__rpc_svcthread) st_ilink; /* idle threads list */ 301184588Sdfr LIST_ENTRY(__rpc_svcthread) st_alink; /* application thread list */ 302261066Smav int st_p2; /* application workspace */ 303261066Smav uint64_t st_p3; /* application workspace */ 304184588Sdfr} SVCTHREAD; 305184588SdfrLIST_HEAD(svcthread_list, __rpc_svcthread); 306184588Sdfr 307184588Sdfr/* 308177633Sdfr * In the kernel, we can't use global variables to store lists of 309177633Sdfr * transports etc. since otherwise we could not have two unrelated RPC 310177633Sdfr * services running, each on its own thread. We solve this by 311177633Sdfr * importing a tiny part of a Solaris kernel concept, SVCPOOL. 312177633Sdfr * 313177633Sdfr * A service pool contains a set of transports and service callbacks 314177633Sdfr * for a set of related RPC services. The pool handle should be passed 315177633Sdfr * when creating new transports etc. Future work may include extending 316177633Sdfr * this to support something similar to the Solaris multi-threaded RPC 317177633Sdfr * server. 318177633Sdfr */ 319177633SdfrTAILQ_HEAD(svcxprt_list, __rpc_svcxprt); 320184588Sdfrenum svcpool_state { 321184588Sdfr SVCPOOL_INIT, /* svc_run not called yet */ 322184588Sdfr SVCPOOL_ACTIVE, /* normal running state */ 323184588Sdfr SVCPOOL_THREADWANTED, /* new service thread requested */ 324184588Sdfr SVCPOOL_THREADSTARTING, /* new service thread started */ 325184588Sdfr SVCPOOL_CLOSING /* svc_exit called */ 326184588Sdfr}; 327184588Sdfrtypedef SVCTHREAD *pool_assign_fn(SVCTHREAD *, struct svc_req *); 328184588Sdfrtypedef void pool_done_fn(SVCTHREAD *, struct svc_req *); 329177633Sdfrtypedef struct __rpc_svcpool { 330261082Smav struct mtx sp_lock; /* protect the transport lists */ 331184588Sdfr const char *sp_name; /* pool name (e.g. "nfsd", "NLM" */ 332184588Sdfr enum svcpool_state sp_state; /* current pool state */ 333184588Sdfr struct proc *sp_proc; /* process which is in svc_run */ 334177633Sdfr struct svcxprt_list sp_xlist; /* all transports in the pool */ 335177633Sdfr struct svcxprt_list sp_active; /* transports needing service */ 336177633Sdfr struct svc_callout_list sp_callouts; /* (prog,vers)->dispatch list */ 337261067Smav struct svc_loss_callout_list sp_lcallouts; /* loss->dispatch list */ 338184588Sdfr struct svcthread_list sp_threads; /* service threads */ 339184588Sdfr struct svcthread_list sp_idlethreads; /* idle service threads */ 340184588Sdfr int sp_minthreads; /* minimum service thread count */ 341184588Sdfr int sp_maxthreads; /* maximum service thread count */ 342184588Sdfr int sp_threadcount; /* current service thread count */ 343184588Sdfr time_t sp_lastcreatetime; /* when we last started a thread */ 344184588Sdfr time_t sp_lastidlecheck; /* when we last checked idle transports */ 345184588Sdfr 346184588Sdfr /* 347184588Sdfr * Hooks to allow an application to control request to thread 348184588Sdfr * placement. 349184588Sdfr */ 350184588Sdfr pool_assign_fn *sp_assign; 351184588Sdfr pool_done_fn *sp_done; 352184588Sdfr 353184588Sdfr /* 354184588Sdfr * These variables are used to put an upper bound on the 355184588Sdfr * amount of memory used by RPC requests which are queued 356184588Sdfr * waiting for execution. 357184588Sdfr */ 358184588Sdfr unsigned int sp_space_low; 359184588Sdfr unsigned int sp_space_high; 360184588Sdfr unsigned int sp_space_used; 361184588Sdfr unsigned int sp_space_used_highest; 362184588Sdfr bool_t sp_space_throttled; 363184588Sdfr int sp_space_throttle_count; 364184588Sdfr 365184588Sdfr struct replay_cache *sp_rcache; /* optional replay cache */ 366184588Sdfr struct sysctl_ctx_list sp_sysctl; 367177633Sdfr} SVCPOOL; 368177633Sdfr 369184588Sdfr#else 370177633Sdfr 371177633Sdfr/* 372177633Sdfr * Service request 373177633Sdfr */ 374177633Sdfrstruct svc_req { 375177633Sdfr uint32_t rq_prog; /* service program number */ 376177633Sdfr uint32_t rq_vers; /* service protocol version */ 377177633Sdfr uint32_t rq_proc; /* the desired procedure */ 378177633Sdfr struct opaque_auth rq_cred; /* raw creds from the wire */ 379177633Sdfr void *rq_clntcred; /* read only cooked cred */ 380177633Sdfr SVCXPRT *rq_xprt; /* associated transport */ 381177633Sdfr}; 382177633Sdfr 383177633Sdfr/* 384177633Sdfr * Approved way of getting address of caller 385177633Sdfr */ 386177633Sdfr#define svc_getrpccaller(x) (&(x)->xp_rtaddr) 387177633Sdfr 388184588Sdfr#endif 389184588Sdfr 390177633Sdfr/* 391177633Sdfr * Operations defined on an SVCXPRT handle 392177633Sdfr * 393177633Sdfr * SVCXPRT *xprt; 394177633Sdfr * struct rpc_msg *msg; 395177633Sdfr * xdrproc_t xargs; 396177633Sdfr * void * argsp; 397177633Sdfr */ 398184588Sdfr#ifdef _KERNEL 399184588Sdfr 400184588Sdfr#define SVC_ACQUIRE(xprt) \ 401184588Sdfr refcount_acquire(&(xprt)->xp_refs) 402184588Sdfr 403184588Sdfr#define SVC_RELEASE(xprt) \ 404184588Sdfr if (refcount_release(&(xprt)->xp_refs)) \ 405184588Sdfr SVC_DESTROY(xprt) 406184588Sdfr 407184588Sdfr#define SVC_RECV(xprt, msg, addr, args) \ 408184588Sdfr (*(xprt)->xp_ops->xp_recv)((xprt), (msg), (addr), (args)) 409184588Sdfr 410184588Sdfr#define SVC_STAT(xprt) \ 411184588Sdfr (*(xprt)->xp_ops->xp_stat)(xprt) 412184588Sdfr 413261067Smav#define SVC_ACK(xprt, ack) \ 414261067Smav ((xprt)->xp_ops->xp_ack == NULL ? FALSE : \ 415261067Smav ((ack) == NULL ? TRUE : (*(xprt)->xp_ops->xp_ack)((xprt), (ack)))) 416184588Sdfr 417261067Smav#define SVC_REPLY(xprt, msg, addr, m, seq) \ 418261067Smav (*(xprt)->xp_ops->xp_reply) ((xprt), (msg), (addr), (m), (seq)) 419261067Smav 420184588Sdfr#define SVC_DESTROY(xprt) \ 421184588Sdfr (*(xprt)->xp_ops->xp_destroy)(xprt) 422184588Sdfr 423184588Sdfr#define SVC_CONTROL(xprt, rq, in) \ 424184588Sdfr (*(xprt)->xp_ops->xp_control)((xprt), (rq), (in)) 425184588Sdfr 426184588Sdfr#else 427184588Sdfr 428177633Sdfr#define SVC_RECV(xprt, msg) \ 429177633Sdfr (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) 430177633Sdfr#define svc_recv(xprt, msg) \ 431177633Sdfr (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) 432177633Sdfr 433177633Sdfr#define SVC_STAT(xprt) \ 434177633Sdfr (*(xprt)->xp_ops->xp_stat)(xprt) 435177633Sdfr#define svc_stat(xprt) \ 436177633Sdfr (*(xprt)->xp_ops->xp_stat)(xprt) 437177633Sdfr 438177633Sdfr#define SVC_GETARGS(xprt, xargs, argsp) \ 439177633Sdfr (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) 440177633Sdfr#define svc_getargs(xprt, xargs, argsp) \ 441177633Sdfr (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) 442177633Sdfr 443177633Sdfr#define SVC_REPLY(xprt, msg) \ 444177633Sdfr (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) 445177633Sdfr#define svc_reply(xprt, msg) \ 446177633Sdfr (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) 447177633Sdfr 448177633Sdfr#define SVC_FREEARGS(xprt, xargs, argsp) \ 449177633Sdfr (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) 450177633Sdfr#define svc_freeargs(xprt, xargs, argsp) \ 451177633Sdfr (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) 452177633Sdfr 453177633Sdfr#define SVC_DESTROY(xprt) \ 454177633Sdfr (*(xprt)->xp_ops->xp_destroy)(xprt) 455177633Sdfr#define svc_destroy(xprt) \ 456177633Sdfr (*(xprt)->xp_ops->xp_destroy)(xprt) 457177633Sdfr 458177633Sdfr#define SVC_CONTROL(xprt, rq, in) \ 459177633Sdfr (*(xprt)->xp_ops2->xp_control)((xprt), (rq), (in)) 460184588Sdfr 461177633Sdfr#endif 462177633Sdfr 463184588Sdfr#define SVC_EXT(xprt) \ 464184588Sdfr ((SVCXPRT_EXT *) xprt->xp_p3) 465184588Sdfr 466184588Sdfr#define SVC_AUTH(xprt) \ 467184588Sdfr (SVC_EXT(xprt)->xp_auth) 468184588Sdfr 469177633Sdfr/* 470184588Sdfr * Operations defined on an SVCAUTH handle 471184588Sdfr */ 472184588Sdfr#ifdef _KERNEL 473184588Sdfr#define SVCAUTH_WRAP(auth, mp) \ 474184588Sdfr ((auth)->svc_ah_ops->svc_ah_wrap(auth, mp)) 475184588Sdfr#define SVCAUTH_UNWRAP(auth, mp) \ 476184588Sdfr ((auth)->svc_ah_ops->svc_ah_unwrap(auth, mp)) 477184588Sdfr#define SVCAUTH_RELEASE(auth) \ 478184588Sdfr ((auth)->svc_ah_ops->svc_ah_release(auth)) 479184588Sdfr#else 480184588Sdfr#define SVCAUTH_WRAP(auth, xdrs, xfunc, xwhere) \ 481184588Sdfr ((auth)->svc_ah_ops->svc_ah_wrap(auth, xdrs, xfunc, xwhere)) 482184588Sdfr#define SVCAUTH_UNWRAP(auth, xdrs, xfunc, xwhere) \ 483184588Sdfr ((auth)->svc_ah_ops->svc_ah_unwrap(auth, xdrs, xfunc, xwhere)) 484184588Sdfr#endif 485184588Sdfr 486184588Sdfr/* 487177633Sdfr * Service registration 488177633Sdfr * 489177633Sdfr * svc_reg(xprt, prog, vers, dispatch, nconf) 490177633Sdfr * const SVCXPRT *xprt; 491177633Sdfr * const rpcprog_t prog; 492177633Sdfr * const rpcvers_t vers; 493177633Sdfr * const void (*dispatch)(); 494177633Sdfr * const struct netconfig *nconf; 495177633Sdfr */ 496177633Sdfr 497177633Sdfr__BEGIN_DECLS 498177633Sdfrextern bool_t svc_reg(SVCXPRT *, const rpcprog_t, const rpcvers_t, 499177633Sdfr void (*)(struct svc_req *, SVCXPRT *), 500177633Sdfr const struct netconfig *); 501177633Sdfr__END_DECLS 502177633Sdfr 503177633Sdfr/* 504177633Sdfr * Service un-registration 505177633Sdfr * 506177633Sdfr * svc_unreg(prog, vers) 507177633Sdfr * const rpcprog_t prog; 508177633Sdfr * const rpcvers_t vers; 509177633Sdfr */ 510177633Sdfr 511177633Sdfr__BEGIN_DECLS 512177633Sdfr#ifdef _KERNEL 513177633Sdfrextern void svc_unreg(SVCPOOL *, const rpcprog_t, const rpcvers_t); 514177633Sdfr#else 515177633Sdfrextern void svc_unreg(const rpcprog_t, const rpcvers_t); 516177633Sdfr#endif 517177633Sdfr__END_DECLS 518177633Sdfr 519261067Smav#ifdef _KERNEL 520177633Sdfr/* 521261067Smav * Service connection loss registration 522261067Smav * 523261067Smav * svc_loss_reg(xprt, dispatch) 524261067Smav * const SVCXPRT *xprt; 525261067Smav * const void (*dispatch)(); 526261067Smav */ 527261067Smav 528261067Smav__BEGIN_DECLS 529261067Smavextern bool_t svc_loss_reg(SVCXPRT *, void (*)(SVCXPRT *)); 530261067Smav__END_DECLS 531261067Smav 532261067Smav/* 533261067Smav * Service connection loss un-registration 534261067Smav * 535261067Smav * svc_loss_unreg(xprt, dispatch) 536261067Smav * const SVCXPRT *xprt; 537261067Smav * const void (*dispatch)(); 538261067Smav */ 539261067Smav 540261067Smav__BEGIN_DECLS 541261067Smavextern void svc_loss_unreg(SVCPOOL *, void (*)(SVCXPRT *)); 542261067Smav__END_DECLS 543261067Smav#endif 544261067Smav 545261067Smav/* 546177633Sdfr * Transport registration. 547177633Sdfr * 548177633Sdfr * xprt_register(xprt) 549177633Sdfr * SVCXPRT *xprt; 550177633Sdfr */ 551177633Sdfr__BEGIN_DECLS 552177633Sdfrextern void xprt_register(SVCXPRT *); 553177633Sdfr__END_DECLS 554177633Sdfr 555177633Sdfr/* 556177633Sdfr * Transport un-register 557177633Sdfr * 558177633Sdfr * xprt_unregister(xprt) 559177633Sdfr * SVCXPRT *xprt; 560177633Sdfr */ 561177633Sdfr__BEGIN_DECLS 562177633Sdfrextern void xprt_unregister(SVCXPRT *); 563177633Sdfrextern void __xprt_unregister_unlocked(SVCXPRT *); 564177633Sdfr__END_DECLS 565177633Sdfr 566177633Sdfr#ifdef _KERNEL 567177633Sdfr 568177633Sdfr/* 569177633Sdfr * Called when a transport has pending requests. 570177633Sdfr */ 571177633Sdfr__BEGIN_DECLS 572177633Sdfrextern void xprt_active(SVCXPRT *); 573177633Sdfrextern void xprt_inactive(SVCXPRT *); 574184588Sdfrextern void xprt_inactive_locked(SVCXPRT *); 575261065Smavextern void xprt_inactive_self(SVCXPRT *); 576177633Sdfr__END_DECLS 577177633Sdfr 578177633Sdfr#endif 579177633Sdfr 580177633Sdfr/* 581177633Sdfr * When the service routine is called, it must first check to see if it 582177633Sdfr * knows about the procedure; if not, it should call svcerr_noproc 583177633Sdfr * and return. If so, it should deserialize its arguments via 584177633Sdfr * SVC_GETARGS (defined above). If the deserialization does not work, 585177633Sdfr * svcerr_decode should be called followed by a return. Successful 586177633Sdfr * decoding of the arguments should be followed the execution of the 587177633Sdfr * procedure's code and a call to svc_sendreply. 588177633Sdfr * 589177633Sdfr * Also, if the service refuses to execute the procedure due to too- 590177633Sdfr * weak authentication parameters, svcerr_weakauth should be called. 591177633Sdfr * Note: do not confuse access-control failure with weak authentication! 592177633Sdfr * 593177633Sdfr * NB: In pure implementations of rpc, the caller always waits for a reply 594177633Sdfr * msg. This message is sent when svc_sendreply is called. 595177633Sdfr * Therefore pure service implementations should always call 596177633Sdfr * svc_sendreply even if the function logically returns void; use 597177633Sdfr * xdr.h - xdr_void for the xdr routine. HOWEVER, tcp based rpc allows 598177633Sdfr * for the abuse of pure rpc via batched calling or pipelining. In the 599177633Sdfr * case of a batched call, svc_sendreply should NOT be called since 600177633Sdfr * this would send a return message, which is what batching tries to avoid. 601177633Sdfr * It is the service/protocol writer's responsibility to know which calls are 602177633Sdfr * batched and which are not. Warning: responding to batch calls may 603177633Sdfr * deadlock the caller and server processes! 604177633Sdfr */ 605177633Sdfr 606177633Sdfr__BEGIN_DECLS 607184588Sdfr#ifdef _KERNEL 608184588Sdfrextern bool_t svc_sendreply(struct svc_req *, xdrproc_t, void *); 609184588Sdfrextern bool_t svc_sendreply_mbuf(struct svc_req *, struct mbuf *); 610184588Sdfrextern void svcerr_decode(struct svc_req *); 611184588Sdfrextern void svcerr_weakauth(struct svc_req *); 612184588Sdfrextern void svcerr_noproc(struct svc_req *); 613184588Sdfrextern void svcerr_progvers(struct svc_req *, rpcvers_t, rpcvers_t); 614184588Sdfrextern void svcerr_auth(struct svc_req *, enum auth_stat); 615184588Sdfrextern void svcerr_noprog(struct svc_req *); 616184588Sdfrextern void svcerr_systemerr(struct svc_req *); 617184588Sdfr#else 618177633Sdfrextern bool_t svc_sendreply(SVCXPRT *, xdrproc_t, void *); 619177633Sdfrextern void svcerr_decode(SVCXPRT *); 620177633Sdfrextern void svcerr_weakauth(SVCXPRT *); 621177633Sdfrextern void svcerr_noproc(SVCXPRT *); 622177633Sdfrextern void svcerr_progvers(SVCXPRT *, rpcvers_t, rpcvers_t); 623177633Sdfrextern void svcerr_auth(SVCXPRT *, enum auth_stat); 624177633Sdfrextern void svcerr_noprog(SVCXPRT *); 625177633Sdfrextern void svcerr_systemerr(SVCXPRT *); 626184588Sdfr#endif 627177633Sdfrextern int rpc_reg(rpcprog_t, rpcvers_t, rpcproc_t, 628177633Sdfr char *(*)(char *), xdrproc_t, xdrproc_t, 629177633Sdfr char *); 630177633Sdfr__END_DECLS 631177633Sdfr 632177633Sdfr/* 633177633Sdfr * Lowest level dispatching -OR- who owns this process anyway. 634177633Sdfr * Somebody has to wait for incoming requests and then call the correct 635177633Sdfr * service routine. The routine svc_run does infinite waiting; i.e., 636177633Sdfr * svc_run never returns. 637177633Sdfr * Since another (co-existant) package may wish to selectively wait for 638177633Sdfr * incoming calls or other events outside of the rpc architecture, the 639177633Sdfr * routine svc_getreq is provided. It must be passed readfds, the 640177633Sdfr * "in-place" results of a select system call (see select, section 2). 641177633Sdfr */ 642177633Sdfr 643177633Sdfr#ifndef _KERNEL 644177633Sdfr/* 645177633Sdfr * Global keeper of rpc service descriptors in use 646177633Sdfr * dynamic; must be inspected before each call to select 647177633Sdfr */ 648177633Sdfrextern int svc_maxfd; 649177633Sdfr#ifdef FD_SETSIZE 650177633Sdfrextern fd_set svc_fdset; 651177633Sdfr#define svc_fds svc_fdset.fds_bits[0] /* compatibility */ 652177633Sdfr#else 653177633Sdfrextern int svc_fds; 654177633Sdfr#endif /* def FD_SETSIZE */ 655177633Sdfr#endif 656177633Sdfr 657177633Sdfr/* 658177633Sdfr * a small program implemented by the svc_rpc implementation itself; 659177633Sdfr * also see clnt.h for protocol numbers. 660177633Sdfr */ 661177633Sdfr__BEGIN_DECLS 662177633Sdfrextern void rpctest_service(void); 663177633Sdfr__END_DECLS 664177633Sdfr 665177633Sdfr__BEGIN_DECLS 666184588Sdfrextern SVCXPRT *svc_xprt_alloc(void); 667184588Sdfrextern void svc_xprt_free(SVCXPRT *); 668177633Sdfr#ifndef _KERNEL 669177633Sdfrextern void svc_getreq(int); 670177633Sdfrextern void svc_getreqset(fd_set *); 671177633Sdfrextern void svc_getreq_common(int); 672177633Sdfrstruct pollfd; 673177633Sdfrextern void svc_getreq_poll(struct pollfd *, int); 674177633Sdfrextern void svc_run(void); 675177633Sdfrextern void svc_exit(void); 676177633Sdfr#else 677177633Sdfrextern void svc_run(SVCPOOL *); 678177633Sdfrextern void svc_exit(SVCPOOL *); 679184588Sdfrextern bool_t svc_getargs(struct svc_req *, xdrproc_t, void *); 680184588Sdfrextern bool_t svc_freeargs(struct svc_req *, xdrproc_t, void *); 681184588Sdfrextern void svc_freereq(struct svc_req *); 682184588Sdfr 683177633Sdfr#endif 684177633Sdfr__END_DECLS 685177633Sdfr 686177633Sdfr/* 687177633Sdfr * Socket to use on svcxxx_create call to get default socket 688177633Sdfr */ 689177633Sdfr#define RPC_ANYSOCK -1 690177633Sdfr#define RPC_ANYFD RPC_ANYSOCK 691177633Sdfr 692177633Sdfr/* 693177633Sdfr * These are the existing service side transport implementations 694177633Sdfr */ 695177633Sdfr 696177633Sdfr__BEGIN_DECLS 697177633Sdfr 698177633Sdfr#ifdef _KERNEL 699177633Sdfr 700177633Sdfr/* 701177633Sdfr * Create a new service pool. 702177633Sdfr */ 703184588Sdfrextern SVCPOOL* svcpool_create(const char *name, 704184588Sdfr struct sysctl_oid_list *sysctl_base); 705177633Sdfr 706177633Sdfr/* 707177633Sdfr * Destroy a service pool, including all registered transports. 708177633Sdfr */ 709177633Sdfrextern void svcpool_destroy(SVCPOOL *pool); 710177633Sdfr 711177633Sdfr/* 712177633Sdfr * Transport independent svc_create routine. 713177633Sdfr */ 714177633Sdfrextern int svc_create(SVCPOOL *, void (*)(struct svc_req *, SVCXPRT *), 715177633Sdfr const rpcprog_t, const rpcvers_t, const char *); 716177633Sdfr/* 717177633Sdfr * void (*dispatch)(); -- dispatch routine 718177633Sdfr * const rpcprog_t prognum; -- program number 719177633Sdfr * const rpcvers_t versnum; -- version number 720177633Sdfr * const char *nettype; -- network type 721177633Sdfr */ 722177633Sdfr 723177633Sdfr 724177633Sdfr/* 725177633Sdfr * Generic server creation routine. It takes a netconfig structure 726177633Sdfr * instead of a nettype. 727177633Sdfr */ 728177633Sdfr 729177633Sdfrextern SVCXPRT *svc_tp_create(SVCPOOL *, void (*)(struct svc_req *, SVCXPRT *), 730177633Sdfr const rpcprog_t, const rpcvers_t, const char *uaddr, 731177633Sdfr const struct netconfig *); 732177633Sdfr /* 733177633Sdfr * void (*dispatch)(); -- dispatch routine 734177633Sdfr * const rpcprog_t prognum; -- program number 735177633Sdfr * const rpcvers_t versnum; -- version number 736177633Sdfr * const char *uaddr; -- universal address of service 737177633Sdfr * const struct netconfig *nconf; -- netconfig structure 738177633Sdfr */ 739177633Sdfr 740177633Sdfrextern SVCXPRT *svc_dg_create(SVCPOOL *, struct socket *, 741177633Sdfr const size_t, const size_t); 742177633Sdfr /* 743177633Sdfr * struct socket *; -- open connection 744177633Sdfr * const size_t sendsize; -- max send size 745177633Sdfr * const size_t recvsize; -- max recv size 746177633Sdfr */ 747177633Sdfr 748177633Sdfrextern SVCXPRT *svc_vc_create(SVCPOOL *, struct socket *, 749177633Sdfr const size_t, const size_t); 750177633Sdfr /* 751177633Sdfr * struct socket *; -- open connection 752177633Sdfr * const size_t sendsize; -- max send size 753177633Sdfr * const size_t recvsize; -- max recv size 754177633Sdfr */ 755177633Sdfr 756261058Smavextern SVCXPRT *svc_vc_create_backchannel(SVCPOOL *); 757261058Smav 758177633Sdfr/* 759177633Sdfr * Generic TLI create routine 760177633Sdfr */ 761177633Sdfrextern SVCXPRT *svc_tli_create(SVCPOOL *, struct socket *, 762177633Sdfr const struct netconfig *, const struct t_bind *, const size_t, const size_t); 763177633Sdfr/* 764177633Sdfr * struct socket * so; -- connection end point 765177633Sdfr * const struct netconfig *nconf; -- netconfig structure for network 766177633Sdfr * const struct t_bind *bindaddr; -- local bind address 767177633Sdfr * const size_t sendsz; -- max sendsize 768177633Sdfr * const size_t recvsz; -- max recvsize 769177633Sdfr */ 770177633Sdfr 771177633Sdfr#else /* !_KERNEL */ 772177633Sdfr 773177633Sdfr/* 774177633Sdfr * Transport independent svc_create routine. 775177633Sdfr */ 776177633Sdfrextern int svc_create(void (*)(struct svc_req *, SVCXPRT *), 777177633Sdfr const rpcprog_t, const rpcvers_t, const char *); 778177633Sdfr/* 779177633Sdfr * void (*dispatch)(); -- dispatch routine 780177633Sdfr * const rpcprog_t prognum; -- program number 781177633Sdfr * const rpcvers_t versnum; -- version number 782177633Sdfr * const char *nettype; -- network type 783177633Sdfr */ 784177633Sdfr 785177633Sdfr 786177633Sdfr/* 787177633Sdfr * Generic server creation routine. It takes a netconfig structure 788177633Sdfr * instead of a nettype. 789177633Sdfr */ 790177633Sdfr 791177633Sdfrextern SVCXPRT *svc_tp_create(void (*)(struct svc_req *, SVCXPRT *), 792177633Sdfr const rpcprog_t, const rpcvers_t, 793177633Sdfr const struct netconfig *); 794177633Sdfr /* 795177633Sdfr * void (*dispatch)(); -- dispatch routine 796177633Sdfr * const rpcprog_t prognum; -- program number 797177633Sdfr * const rpcvers_t versnum; -- version number 798177633Sdfr * const struct netconfig *nconf; -- netconfig structure 799177633Sdfr */ 800177633Sdfr 801177633Sdfr/* 802177633Sdfr * Generic TLI create routine 803177633Sdfr */ 804177633Sdfrextern SVCXPRT *svc_tli_create(const int, const struct netconfig *, 805177633Sdfr const struct t_bind *, const u_int, 806177633Sdfr const u_int); 807177633Sdfr/* 808177633Sdfr * const int fd; -- connection end point 809177633Sdfr * const struct netconfig *nconf; -- netconfig structure for network 810177633Sdfr * const struct t_bind *bindaddr; -- local bind address 811177633Sdfr * const u_int sendsz; -- max sendsize 812177633Sdfr * const u_int recvsz; -- max recvsize 813177633Sdfr */ 814177633Sdfr 815177633Sdfr/* 816177633Sdfr * Connectionless and connectionful create routines 817177633Sdfr */ 818177633Sdfr 819177633Sdfrextern SVCXPRT *svc_vc_create(const int, const u_int, const u_int); 820177633Sdfr/* 821177633Sdfr * const int fd; -- open connection end point 822177633Sdfr * const u_int sendsize; -- max send size 823177633Sdfr * const u_int recvsize; -- max recv size 824177633Sdfr */ 825177633Sdfr 826177633Sdfr/* 827177633Sdfr * Added for compatibility to old rpc 4.0. Obsoleted by svc_vc_create(). 828177633Sdfr */ 829177633Sdfrextern SVCXPRT *svcunix_create(int, u_int, u_int, char *); 830177633Sdfr 831177633Sdfrextern SVCXPRT *svc_dg_create(const int, const u_int, const u_int); 832177633Sdfr /* 833177633Sdfr * const int fd; -- open connection 834177633Sdfr * const u_int sendsize; -- max send size 835177633Sdfr * const u_int recvsize; -- max recv size 836177633Sdfr */ 837177633Sdfr 838177633Sdfr 839177633Sdfr/* 840177633Sdfr * the routine takes any *open* connection 841177633Sdfr * descriptor as its first input and is used for open connections. 842177633Sdfr */ 843177633Sdfrextern SVCXPRT *svc_fd_create(const int, const u_int, const u_int); 844177633Sdfr/* 845177633Sdfr * const int fd; -- open connection end point 846177633Sdfr * const u_int sendsize; -- max send size 847177633Sdfr * const u_int recvsize; -- max recv size 848177633Sdfr */ 849177633Sdfr 850177633Sdfr/* 851177633Sdfr * Added for compatibility to old rpc 4.0. Obsoleted by svc_fd_create(). 852177633Sdfr */ 853177633Sdfrextern SVCXPRT *svcunixfd_create(int, u_int, u_int); 854177633Sdfr 855177633Sdfr/* 856177633Sdfr * Memory based rpc (for speed check and testing) 857177633Sdfr */ 858177633Sdfrextern SVCXPRT *svc_raw_create(void); 859177633Sdfr 860177633Sdfr/* 861177633Sdfr * svc_dg_enable_cache() enables the cache on dg transports. 862177633Sdfr */ 863177633Sdfrint svc_dg_enablecache(SVCXPRT *, const u_int); 864177633Sdfr 865177633Sdfrint __rpc_get_local_uid(SVCXPRT *_transp, uid_t *_uid); 866177633Sdfr 867177633Sdfr#endif /* !_KERNEL */ 868177633Sdfr 869177633Sdfr__END_DECLS 870177633Sdfr 871177633Sdfr#ifndef _KERNEL 872177633Sdfr/* for backward compatibility */ 873177633Sdfr#include <rpc/svc_soc.h> 874177633Sdfr#endif 875177633Sdfr 876177633Sdfr#endif /* !_RPC_SVC_H */ 877