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