1 /* $NetBSD: svc.h,v 1.17 2000/06/02 22:57:56 fvdl Exp $ */ 2 3 /* 4 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 5 * unrestricted use provided that this legend is included on all tape 6 * media and as a part of the software program in whole or part. Users 7 * may copy or modify Sun RPC without charge, but are not authorized 8 * to license or distribute it to anyone else except as part of a product or 9 * program developed by the user. 10 * 11 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 12 * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR 13 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 14 * 15 * Sun RPC is provided with no support and without any obligation on the 16 * part of Sun Microsystems, Inc. to assist in its use, correction, 17 * modification or enhancement. 18 * 19 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 20 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 21 * OR ANY PART THEREOF. 22 * 23 * In no event will Sun Microsystems, Inc. be liable for any lost revenue 24 * or profits or other special, indirect and consequential damages, even if 25 * Sun has been advised of the possibility of such damages. 26 * 27 * Sun Microsystems, Inc. 28 * 2550 Garcia Avenue 29 * Mountain View, California 94043 30 * 31 * from: @(#)svc.h 1.35 88/12/17 SMI 32 * from: @(#)svc.h 1.27 94/04/25 SMI 33 * $FreeBSD$ 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 #endif 51 52 /* 53 * This interface must manage two items concerning remote procedure calling: 54 * 55 * 1) An arbitrary number of transport connections upon which rpc requests 56 * are received. The two most notable transports are TCP and UDP; they are 57 * created and registered by routines in svc_tcp.c and svc_udp.c, respectively; 58 * they in turn call xprt_register and xprt_unregister. 59 * 60 * 2) An arbitrary number of locally registered services. Services are 61 * described by the following four data: program number, version number, 62 * "service dispatch" function, a transport handle, and a boolean that 63 * indicates whether or not the exported program should be registered with a 64 * local binder service; if true the program's number and version and the 65 * port number from the transport handle are registered with the binder. 66 * These data are registered with the rpc svc system via svc_register. 67 * 68 * A service's dispatch function is called whenever an rpc request comes in 69 * on a transport. The request's program and version numbers must match 70 * those of the registered service. The dispatch function is passed two 71 * parameters, struct svc_req * and SVCXPRT *, defined below. 72 */ 73 74 /* 75 * Service control requests 76 */ 77 #define SVCGET_VERSQUIET 1 78 #define SVCSET_VERSQUIET 2 79 #define SVCGET_CONNMAXREC 3 80 #define SVCSET_CONNMAXREC 4 81 82 /* 83 * Operations for rpc_control(). 84 */ 85 #define RPC_SVC_CONNMAXREC_SET 0 /* set max rec size, enable nonblock */ 86 #define RPC_SVC_CONNMAXREC_GET 1 87 88 enum xprt_stat { 89 XPRT_DIED, 90 XPRT_MOREREQS, 91 XPRT_IDLE 92 }; 93 94 struct __rpc_svcxprt; 95 96 struct xp_ops { 97 /* receive incoming requests */ 98 bool_t (*xp_recv)(struct __rpc_svcxprt *, struct rpc_msg *); 99 /* get transport status */ 100 enum xprt_stat (*xp_stat)(struct __rpc_svcxprt *); 101 /* get arguments */ 102 bool_t (*xp_getargs)(struct __rpc_svcxprt *, xdrproc_t, void *); 103 /* send reply */ 104 bool_t (*xp_reply)(struct __rpc_svcxprt *, struct rpc_msg *); 105 /* free mem allocated for args */ 106 bool_t (*xp_freeargs)(struct __rpc_svcxprt *, xdrproc_t, void *); 107 /* destroy this struct */ 108 void (*xp_destroy)(struct __rpc_svcxprt *); 109 #ifdef _KERNEL 110 /* catch-all function */ 111 bool_t (*xp_control)(struct __rpc_svcxprt *, const u_int, void *); 112 #endif 113 }; 114 115 #ifndef _KERNEL 116 struct xp_ops2 { 117 /* catch-all function */ 118 bool_t (*xp_control)(struct __rpc_svcxprt *, const u_int, void *); 119 }; 120 #endif 121 122 #ifdef _KERNEL 123 struct __rpc_svcpool; 124 #endif 125 126 /* 127 * Server side transport handle 128 */ 129 typedef struct __rpc_svcxprt { 130 #ifdef _KERNEL 131 struct mtx xp_lock; 132 struct __rpc_svcpool *xp_pool; /* owning pool (see below) */ 133 TAILQ_ENTRY(__rpc_svcxprt) xp_link; 134 TAILQ_ENTRY(__rpc_svcxprt) xp_alink; 135 bool_t xp_registered; /* xprt_register has been called */ 136 bool_t xp_active; /* xprt_active has been called */ 137 struct socket* xp_socket; 138 const struct xp_ops *xp_ops; 139 char *xp_netid; /* network token */ 140 struct netbuf xp_ltaddr; /* local transport address */ 141 struct netbuf xp_rtaddr; /* remote transport address */ 142 struct opaque_auth xp_verf; /* raw response verifier */ 143 uint32_t xp_xid; /* current transaction ID */ 144 XDR xp_xdrreq; /* xdr stream for decoding request */ 145 XDR xp_xdrrep; /* xdr stream for encoding reply */ 146 void *xp_p1; /* private: for use by svc ops */ 147 void *xp_p2; /* private: for use by svc ops */ 148 void *xp_p3; /* private: for use by svc lib */ 149 int xp_type; /* transport type */ 150 #else 151 int xp_fd; 152 u_short xp_port; /* associated port number */ 153 const struct xp_ops *xp_ops; 154 int xp_addrlen; /* length of remote address */ 155 struct sockaddr_in xp_raddr; /* remote addr. (backward ABI compat) */ 156 /* XXX - fvdl stick this here for ABI backward compat reasons */ 157 const struct xp_ops2 *xp_ops2; 158 char *xp_tp; /* transport provider device name */ 159 char *xp_netid; /* network token */ 160 struct netbuf xp_ltaddr; /* local transport address */ 161 struct netbuf xp_rtaddr; /* remote transport address */ 162 struct opaque_auth xp_verf; /* raw response verifier */ 163 void *xp_p1; /* private: for use by svc ops */ 164 void *xp_p2; /* private: for use by svc ops */ 165 void *xp_p3; /* private: for use by svc lib */ 166 int xp_type; /* transport type */ 167 #endif 168 } SVCXPRT; 169 170 #ifdef _KERNEL 171 172 /* 173 * The services list 174 * Each entry represents a set of procedures (an rpc program). 175 * The dispatch routine takes request structs and runs the 176 * apropriate procedure. 177 */ 178 struct svc_callout { 179 TAILQ_ENTRY(svc_callout) sc_link; 180 rpcprog_t sc_prog; 181 rpcvers_t sc_vers; 182 char *sc_netid; 183 void (*sc_dispatch)(struct svc_req *, SVCXPRT *); 184 }; 185 TAILQ_HEAD(svc_callout_list, svc_callout); 186 187 /* 188 * In the kernel, we can't use global variables to store lists of 189 * transports etc. since otherwise we could not have two unrelated RPC 190 * services running, each on its own thread. We solve this by 191 * importing a tiny part of a Solaris kernel concept, SVCPOOL. 192 * 193 * A service pool contains a set of transports and service callbacks 194 * for a set of related RPC services. The pool handle should be passed 195 * when creating new transports etc. Future work may include extending 196 * this to support something similar to the Solaris multi-threaded RPC 197 * server. 198 */ 199 TAILQ_HEAD(svcxprt_list, __rpc_svcxprt); 200 typedef struct __rpc_svcpool { 201 struct mtx sp_lock; /* protect the transport lists */ 202 struct svcxprt_list sp_xlist; /* all transports in the pool */ 203 struct svcxprt_list sp_active; /* transports needing service */ 204 struct svc_callout_list sp_callouts; /* (prog,vers)->dispatch list */ 205 bool_t sp_exited; /* true if shutting down */ 206 } SVCPOOL; 207 208 #endif 209 210 /* 211 * Service request 212 */ 213 struct svc_req { 214 uint32_t rq_prog; /* service program number */ 215 uint32_t rq_vers; /* service protocol version */ 216 uint32_t rq_proc; /* the desired procedure */ 217 struct opaque_auth rq_cred; /* raw creds from the wire */ 218 void *rq_clntcred; /* read only cooked cred */ 219 SVCXPRT *rq_xprt; /* associated transport */ 220 }; 221 222 /* 223 * Approved way of getting address of caller 224 */ 225 #define svc_getrpccaller(x) (&(x)->xp_rtaddr) 226 227 /* 228 * Operations defined on an SVCXPRT handle 229 * 230 * SVCXPRT *xprt; 231 * struct rpc_msg *msg; 232 * xdrproc_t xargs; 233 * void * argsp; 234 */ 235 #define SVC_RECV(xprt, msg) \ 236 (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) 237 #define svc_recv(xprt, msg) \ 238 (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) 239 240 #define SVC_STAT(xprt) \ 241 (*(xprt)->xp_ops->xp_stat)(xprt) 242 #define svc_stat(xprt) \ 243 (*(xprt)->xp_ops->xp_stat)(xprt) 244 245 #define SVC_GETARGS(xprt, xargs, argsp) \ 246 (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) 247 #define svc_getargs(xprt, xargs, argsp) \ 248 (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) 249 250 #define SVC_REPLY(xprt, msg) \ 251 (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) 252 #define svc_reply(xprt, msg) \ 253 (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) 254 255 #define SVC_FREEARGS(xprt, xargs, argsp) \ 256 (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) 257 #define svc_freeargs(xprt, xargs, argsp) \ 258 (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) 259 260 #define SVC_DESTROY(xprt) \ 261 (*(xprt)->xp_ops->xp_destroy)(xprt) 262 #define svc_destroy(xprt) \ 263 (*(xprt)->xp_ops->xp_destroy)(xprt) 264 265 #ifdef _KERNEL 266 #define SVC_CONTROL(xprt, rq, in) \ 267 (*(xprt)->xp_ops->xp_control)((xprt), (rq), (in)) 268 #else 269 #define SVC_CONTROL(xprt, rq, in) \ 270 (*(xprt)->xp_ops2->xp_control)((xprt), (rq), (in)) 271 #endif 272 273 /* 274 * Service registration 275 * 276 * svc_reg(xprt, prog, vers, dispatch, nconf) 277 * const SVCXPRT *xprt; 278 * const rpcprog_t prog; 279 * const rpcvers_t vers; 280 * const void (*dispatch)(); 281 * const struct netconfig *nconf; 282 */ 283 284 __BEGIN_DECLS 285 extern bool_t svc_reg(SVCXPRT *, const rpcprog_t, const rpcvers_t, 286 void (*)(struct svc_req *, SVCXPRT *), 287 const struct netconfig *); 288 __END_DECLS 289 290 /* 291 * Service un-registration 292 * 293 * svc_unreg(prog, vers) 294 * const rpcprog_t prog; 295 * const rpcvers_t vers; 296 */ 297 298 __BEGIN_DECLS 299 #ifdef _KERNEL 300 extern void svc_unreg(SVCPOOL *, const rpcprog_t, const rpcvers_t); 301 #else 302 extern void svc_unreg(const rpcprog_t, const rpcvers_t); 303 #endif 304 __END_DECLS 305 306 /* 307 * Transport registration. 308 * 309 * xprt_register(xprt) 310 * SVCXPRT *xprt; 311 */ 312 __BEGIN_DECLS 313 extern void xprt_register(SVCXPRT *); 314 __END_DECLS 315 316 /* 317 * Transport un-register 318 * 319 * xprt_unregister(xprt) 320 * SVCXPRT *xprt; 321 */ 322 __BEGIN_DECLS 323 extern void xprt_unregister(SVCXPRT *); 324 extern void __xprt_unregister_unlocked(SVCXPRT *); 325 __END_DECLS 326 327 #ifdef _KERNEL 328 329 /* 330 * Called when a transport has pending requests. 331 */ 332 __BEGIN_DECLS 333 extern void xprt_active(SVCXPRT *); 334 extern void xprt_inactive(SVCXPRT *); 335 __END_DECLS 336 337 #endif 338 339 /* 340 * When the service routine is called, it must first check to see if it 341 * knows about the procedure; if not, it should call svcerr_noproc 342 * and return. If so, it should deserialize its arguments via 343 * SVC_GETARGS (defined above). If the deserialization does not work, 344 * svcerr_decode should be called followed by a return. Successful 345 * decoding of the arguments should be followed the execution of the 346 * procedure's code and a call to svc_sendreply. 347 * 348 * Also, if the service refuses to execute the procedure due to too- 349 * weak authentication parameters, svcerr_weakauth should be called. 350 * Note: do not confuse access-control failure with weak authentication! 351 * 352 * NB: In pure implementations of rpc, the caller always waits for a reply 353 * msg. This message is sent when svc_sendreply is called. 354 * Therefore pure service implementations should always call 355 * svc_sendreply even if the function logically returns void; use 356 * xdr.h - xdr_void for the xdr routine. HOWEVER, tcp based rpc allows 357 * for the abuse of pure rpc via batched calling or pipelining. In the 358 * case of a batched call, svc_sendreply should NOT be called since 359 * this would send a return message, which is what batching tries to avoid. 360 * It is the service/protocol writer's responsibility to know which calls are 361 * batched and which are not. Warning: responding to batch calls may 362 * deadlock the caller and server processes! 363 */ 364 365 __BEGIN_DECLS 366 extern bool_t svc_sendreply(SVCXPRT *, xdrproc_t, void *); 367 extern void svcerr_decode(SVCXPRT *); 368 extern void svcerr_weakauth(SVCXPRT *); 369 extern void svcerr_noproc(SVCXPRT *); 370 extern void svcerr_progvers(SVCXPRT *, rpcvers_t, rpcvers_t); 371 extern void svcerr_auth(SVCXPRT *, enum auth_stat); 372 extern void svcerr_noprog(SVCXPRT *); 373 extern void svcerr_systemerr(SVCXPRT *); 374 extern int rpc_reg(rpcprog_t, rpcvers_t, rpcproc_t, 375 char *(*)(char *), xdrproc_t, xdrproc_t, 376 char *); 377 __END_DECLS 378 379 /* 380 * Lowest level dispatching -OR- who owns this process anyway. 381 * Somebody has to wait for incoming requests and then call the correct 382 * service routine. The routine svc_run does infinite waiting; i.e., 383 * svc_run never returns. 384 * Since another (co-existant) package may wish to selectively wait for 385 * incoming calls or other events outside of the rpc architecture, the 386 * routine svc_getreq is provided. It must be passed readfds, the 387 * "in-place" results of a select system call (see select, section 2). 388 */ 389 390 #ifndef _KERNEL 391 /* 392 * Global keeper of rpc service descriptors in use 393 * dynamic; must be inspected before each call to select 394 */ 395 extern int svc_maxfd; 396 #ifdef FD_SETSIZE 397 extern fd_set svc_fdset; 398 #define svc_fds svc_fdset.fds_bits[0] /* compatibility */ 399 #else 400 extern int svc_fds; 401 #endif /* def FD_SETSIZE */ 402 #endif 403 404 /* 405 * a small program implemented by the svc_rpc implementation itself; 406 * also see clnt.h for protocol numbers. 407 */ 408 __BEGIN_DECLS 409 extern void rpctest_service(void); 410 __END_DECLS 411 412 __BEGIN_DECLS 413 #ifndef _KERNEL 414 extern void svc_getreq(int); 415 extern void svc_getreqset(fd_set *); 416 extern void svc_getreq_common(int); 417 struct pollfd; 418 extern void svc_getreq_poll(struct pollfd *, int); 419 extern void svc_run(void); 420 extern void svc_exit(void); 421 #else 422 extern void svc_run(SVCPOOL *); 423 extern void svc_exit(SVCPOOL *); 424 #endif 425 __END_DECLS 426 427 /* 428 * Socket to use on svcxxx_create call to get default socket 429 */ 430 #define RPC_ANYSOCK -1 431 #define RPC_ANYFD RPC_ANYSOCK 432 433 /* 434 * These are the existing service side transport implementations 435 */ 436 437 __BEGIN_DECLS 438 439 #ifdef _KERNEL 440 441 /* 442 * Create a new service pool. 443 */ 444 extern SVCPOOL* svcpool_create(void); 445 446 /* 447 * Destroy a service pool, including all registered transports. 448 */ 449 extern void svcpool_destroy(SVCPOOL *pool); 450 451 /* 452 * Transport independent svc_create routine. 453 */ 454 extern int svc_create(SVCPOOL *, void (*)(struct svc_req *, SVCXPRT *), 455 const rpcprog_t, const rpcvers_t, const char *); 456 /* 457 * void (*dispatch)(); -- dispatch routine 458 * const rpcprog_t prognum; -- program number 459 * const rpcvers_t versnum; -- version number 460 * const char *nettype; -- network type 461 */ 462 463 464 /* 465 * Generic server creation routine. It takes a netconfig structure 466 * instead of a nettype. 467 */ 468 469 extern SVCXPRT *svc_tp_create(SVCPOOL *, void (*)(struct svc_req *, SVCXPRT *), 470 const rpcprog_t, const rpcvers_t, const char *uaddr, 471 const struct netconfig *); 472 /* 473 * void (*dispatch)(); -- dispatch routine 474 * const rpcprog_t prognum; -- program number 475 * const rpcvers_t versnum; -- version number 476 * const char *uaddr; -- universal address of service 477 * const struct netconfig *nconf; -- netconfig structure 478 */ 479 480 extern SVCXPRT *svc_dg_create(SVCPOOL *, struct socket *, 481 const size_t, const size_t); 482 /* 483 * struct socket *; -- open connection 484 * const size_t sendsize; -- max send size 485 * const size_t recvsize; -- max recv size 486 */ 487 488 extern SVCXPRT *svc_vc_create(SVCPOOL *, struct socket *, 489 const size_t, const size_t); 490 /* 491 * struct socket *; -- open connection 492 * const size_t sendsize; -- max send size 493 * const size_t recvsize; -- max recv size 494 */ 495 496 /* 497 * Generic TLI create routine 498 */ 499 extern SVCXPRT *svc_tli_create(SVCPOOL *, struct socket *, 500 const struct netconfig *, const struct t_bind *, const size_t, const size_t); 501 /* 502 * struct socket * so; -- connection end point 503 * const struct netconfig *nconf; -- netconfig structure for network 504 * const struct t_bind *bindaddr; -- local bind address 505 * const size_t sendsz; -- max sendsize 506 * const size_t recvsz; -- max recvsize 507 */ 508 509 #else /* !_KERNEL */ 510 511 /* 512 * Transport independent svc_create routine. 513 */ 514 extern int svc_create(void (*)(struct svc_req *, SVCXPRT *), 515 const rpcprog_t, const rpcvers_t, const char *); 516 /* 517 * void (*dispatch)(); -- dispatch routine 518 * const rpcprog_t prognum; -- program number 519 * const rpcvers_t versnum; -- version number 520 * const char *nettype; -- network type 521 */ 522 523 524 /* 525 * Generic server creation routine. It takes a netconfig structure 526 * instead of a nettype. 527 */ 528 529 extern SVCXPRT *svc_tp_create(void (*)(struct svc_req *, SVCXPRT *), 530 const rpcprog_t, const rpcvers_t, 531 const struct netconfig *); 532 /* 533 * void (*dispatch)(); -- dispatch routine 534 * const rpcprog_t prognum; -- program number 535 * const rpcvers_t versnum; -- version number 536 * const struct netconfig *nconf; -- netconfig structure 537 */ 538 539 /* 540 * Generic TLI create routine 541 */ 542 extern SVCXPRT *svc_tli_create(const int, const struct netconfig *, 543 const struct t_bind *, const u_int, 544 const u_int); 545 /* 546 * const int fd; -- connection end point 547 * const struct netconfig *nconf; -- netconfig structure for network 548 * const struct t_bind *bindaddr; -- local bind address 549 * const u_int sendsz; -- max sendsize 550 * const u_int recvsz; -- max recvsize 551 */ 552 553 /* 554 * Connectionless and connectionful create routines 555 */ 556 557 extern SVCXPRT *svc_vc_create(const int, const u_int, const u_int); 558 /* 559 * const int fd; -- open connection end point 560 * const u_int sendsize; -- max send size 561 * const u_int recvsize; -- max recv size 562 */ 563 564 /* 565 * Added for compatibility to old rpc 4.0. Obsoleted by svc_vc_create(). 566 */ 567 extern SVCXPRT *svcunix_create(int, u_int, u_int, char *); 568 569 extern SVCXPRT *svc_dg_create(const int, const u_int, const u_int); 570 /* 571 * const int fd; -- open connection 572 * const u_int sendsize; -- max send size 573 * const u_int recvsize; -- max recv size 574 */ 575 576 577 /* 578 * the routine takes any *open* connection 579 * descriptor as its first input and is used for open connections. 580 */ 581 extern SVCXPRT *svc_fd_create(const int, const u_int, const u_int); 582 /* 583 * const int fd; -- open connection end point 584 * const u_int sendsize; -- max send size 585 * const u_int recvsize; -- max recv size 586 */ 587 588 /* 589 * Added for compatibility to old rpc 4.0. Obsoleted by svc_fd_create(). 590 */ 591 extern SVCXPRT *svcunixfd_create(int, u_int, u_int); 592 593 /* 594 * Memory based rpc (for speed check and testing) 595 */ 596 extern SVCXPRT *svc_raw_create(void); 597 598 /* 599 * svc_dg_enable_cache() enables the cache on dg transports. 600 */ 601 int svc_dg_enablecache(SVCXPRT *, const u_int); 602 603 int __rpc_get_local_uid(SVCXPRT *_transp, uid_t *_uid); 604 605 #endif /* !_KERNEL */ 606 607 __END_DECLS 608 609 #ifndef _KERNEL 610 /* for backward compatibility */ 611 #include <rpc/svc_soc.h> 612 #endif 613 614 #endif /* !_RPC_SVC_H */ 615