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