1*45069Smckusick /* @(#)svc.h 2.2 88/07/29 4.0 RPCSRC; from 1.20 88/02/08 SMI */ 2*45069Smckusick /* 3*45069Smckusick * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 4*45069Smckusick * unrestricted use provided that this legend is included on all tape 5*45069Smckusick * media and as a part of the software program in whole or part. Users 6*45069Smckusick * may copy or modify Sun RPC without charge, but are not authorized 7*45069Smckusick * to license or distribute it to anyone else except as part of a product or 8*45069Smckusick * program developed by the user. 9*45069Smckusick * 10*45069Smckusick * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 11*45069Smckusick * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 12*45069Smckusick * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 13*45069Smckusick * 14*45069Smckusick * Sun RPC is provided with no support and without any obligation on the 15*45069Smckusick * part of Sun Microsystems, Inc. to assist in its use, correction, 16*45069Smckusick * modification or enhancement. 17*45069Smckusick * 18*45069Smckusick * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 19*45069Smckusick * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 20*45069Smckusick * OR ANY PART THEREOF. 21*45069Smckusick * 22*45069Smckusick * In no event will Sun Microsystems, Inc. be liable for any lost revenue 23*45069Smckusick * or profits or other special, indirect and consequential damages, even if 24*45069Smckusick * Sun has been advised of the possibility of such damages. 25*45069Smckusick * 26*45069Smckusick * Sun Microsystems, Inc. 27*45069Smckusick * 2550 Garcia Avenue 28*45069Smckusick * Mountain View, California 94043 29*45069Smckusick */ 30*45069Smckusick 31*45069Smckusick /* 32*45069Smckusick * svc.h, Server-side remote procedure call interface. 33*45069Smckusick * 34*45069Smckusick * Copyright (C) 1984, Sun Microsystems, Inc. 35*45069Smckusick */ 36*45069Smckusick 37*45069Smckusick #ifndef __SVC_HEADER__ 38*45069Smckusick #define __SVC_HEADER__ 39*45069Smckusick 40*45069Smckusick /* 41*45069Smckusick * This interface must manage two items concerning remote procedure calling: 42*45069Smckusick * 43*45069Smckusick * 1) An arbitrary number of transport connections upon which rpc requests 44*45069Smckusick * are received. The two most notable transports are TCP and UDP; they are 45*45069Smckusick * created and registered by routines in svc_tcp.c and svc_udp.c, respectively; 46*45069Smckusick * they in turn call xprt_register and xprt_unregister. 47*45069Smckusick * 48*45069Smckusick * 2) An arbitrary number of locally registered services. Services are 49*45069Smckusick * described by the following four data: program number, version number, 50*45069Smckusick * "service dispatch" function, a transport handle, and a boolean that 51*45069Smckusick * indicates whether or not the exported program should be registered with a 52*45069Smckusick * local binder service; if true the program's number and version and the 53*45069Smckusick * port number from the transport handle are registered with the binder. 54*45069Smckusick * These data are registered with the rpc svc system via svc_register. 55*45069Smckusick * 56*45069Smckusick * A service's dispatch function is called whenever an rpc request comes in 57*45069Smckusick * on a transport. The request's program and version numbers must match 58*45069Smckusick * those of the registered service. The dispatch function is passed two 59*45069Smckusick * parameters, struct svc_req * and SVCXPRT *, defined below. 60*45069Smckusick */ 61*45069Smckusick 62*45069Smckusick enum xprt_stat { 63*45069Smckusick XPRT_DIED, 64*45069Smckusick XPRT_MOREREQS, 65*45069Smckusick XPRT_IDLE 66*45069Smckusick }; 67*45069Smckusick 68*45069Smckusick /* 69*45069Smckusick * Server side transport handle 70*45069Smckusick */ 71*45069Smckusick typedef struct { 72*45069Smckusick int xp_sock; 73*45069Smckusick u_short xp_port; /* associated port number */ 74*45069Smckusick struct xp_ops { 75*45069Smckusick bool_t (*xp_recv)(); /* receive incomming requests */ 76*45069Smckusick enum xprt_stat (*xp_stat)(); /* get transport status */ 77*45069Smckusick bool_t (*xp_getargs)(); /* get arguments */ 78*45069Smckusick bool_t (*xp_reply)(); /* send reply */ 79*45069Smckusick bool_t (*xp_freeargs)();/* free mem allocated for args */ 80*45069Smckusick void (*xp_destroy)(); /* destroy this struct */ 81*45069Smckusick } *xp_ops; 82*45069Smckusick int xp_addrlen; /* length of remote address */ 83*45069Smckusick struct sockaddr_in xp_raddr; /* remote address */ 84*45069Smckusick struct opaque_auth xp_verf; /* raw response verifier */ 85*45069Smckusick caddr_t xp_p1; /* private */ 86*45069Smckusick caddr_t xp_p2; /* private */ 87*45069Smckusick } SVCXPRT; 88*45069Smckusick 89*45069Smckusick /* 90*45069Smckusick * Approved way of getting address of caller 91*45069Smckusick */ 92*45069Smckusick #define svc_getcaller(x) (&(x)->xp_raddr) 93*45069Smckusick 94*45069Smckusick /* 95*45069Smckusick * Operations defined on an SVCXPRT handle 96*45069Smckusick * 97*45069Smckusick * SVCXPRT *xprt; 98*45069Smckusick * struct rpc_msg *msg; 99*45069Smckusick * xdrproc_t xargs; 100*45069Smckusick * caddr_t argsp; 101*45069Smckusick */ 102*45069Smckusick #define SVC_RECV(xprt, msg) \ 103*45069Smckusick (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) 104*45069Smckusick #define svc_recv(xprt, msg) \ 105*45069Smckusick (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) 106*45069Smckusick 107*45069Smckusick #define SVC_STAT(xprt) \ 108*45069Smckusick (*(xprt)->xp_ops->xp_stat)(xprt) 109*45069Smckusick #define svc_stat(xprt) \ 110*45069Smckusick (*(xprt)->xp_ops->xp_stat)(xprt) 111*45069Smckusick 112*45069Smckusick #define SVC_GETARGS(xprt, xargs, argsp) \ 113*45069Smckusick (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) 114*45069Smckusick #define svc_getargs(xprt, xargs, argsp) \ 115*45069Smckusick (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) 116*45069Smckusick 117*45069Smckusick #define SVC_REPLY(xprt, msg) \ 118*45069Smckusick (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) 119*45069Smckusick #define svc_reply(xprt, msg) \ 120*45069Smckusick (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) 121*45069Smckusick 122*45069Smckusick #define SVC_FREEARGS(xprt, xargs, argsp) \ 123*45069Smckusick (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) 124*45069Smckusick #define svc_freeargs(xprt, xargs, argsp) \ 125*45069Smckusick (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) 126*45069Smckusick 127*45069Smckusick #define SVC_DESTROY(xprt) \ 128*45069Smckusick (*(xprt)->xp_ops->xp_destroy)(xprt) 129*45069Smckusick #define svc_destroy(xprt) \ 130*45069Smckusick (*(xprt)->xp_ops->xp_destroy)(xprt) 131*45069Smckusick 132*45069Smckusick 133*45069Smckusick /* 134*45069Smckusick * Service request 135*45069Smckusick */ 136*45069Smckusick struct svc_req { 137*45069Smckusick u_long rq_prog; /* service program number */ 138*45069Smckusick u_long rq_vers; /* service protocol version */ 139*45069Smckusick u_long rq_proc; /* the desired procedure */ 140*45069Smckusick struct opaque_auth rq_cred; /* raw creds from the wire */ 141*45069Smckusick caddr_t rq_clntcred; /* read only cooked cred */ 142*45069Smckusick SVCXPRT *rq_xprt; /* associated transport */ 143*45069Smckusick }; 144*45069Smckusick 145*45069Smckusick 146*45069Smckusick /* 147*45069Smckusick * Service registration 148*45069Smckusick * 149*45069Smckusick * svc_register(xprt, prog, vers, dispatch, protocol) 150*45069Smckusick * SVCXPRT *xprt; 151*45069Smckusick * u_long prog; 152*45069Smckusick * u_long vers; 153*45069Smckusick * void (*dispatch)(); 154*45069Smckusick * int protocol; /* like TCP or UDP, zero means do not register 155*45069Smckusick */ 156*45069Smckusick extern bool_t svc_register(); 157*45069Smckusick 158*45069Smckusick /* 159*45069Smckusick * Service un-registration 160*45069Smckusick * 161*45069Smckusick * svc_unregister(prog, vers) 162*45069Smckusick * u_long prog; 163*45069Smckusick * u_long vers; 164*45069Smckusick */ 165*45069Smckusick extern void svc_unregister(); 166*45069Smckusick 167*45069Smckusick /* 168*45069Smckusick * Transport registration. 169*45069Smckusick * 170*45069Smckusick * xprt_register(xprt) 171*45069Smckusick * SVCXPRT *xprt; 172*45069Smckusick */ 173*45069Smckusick extern void xprt_register(); 174*45069Smckusick 175*45069Smckusick /* 176*45069Smckusick * Transport un-register 177*45069Smckusick * 178*45069Smckusick * xprt_unregister(xprt) 179*45069Smckusick * SVCXPRT *xprt; 180*45069Smckusick */ 181*45069Smckusick extern void xprt_unregister(); 182*45069Smckusick 183*45069Smckusick 184*45069Smckusick 185*45069Smckusick 186*45069Smckusick /* 187*45069Smckusick * When the service routine is called, it must first check to see if it 188*45069Smckusick * knows about the procedure; if not, it should call svcerr_noproc 189*45069Smckusick * and return. If so, it should deserialize its arguments via 190*45069Smckusick * SVC_GETARGS (defined above). If the deserialization does not work, 191*45069Smckusick * svcerr_decode should be called followed by a return. Successful 192*45069Smckusick * decoding of the arguments should be followed the execution of the 193*45069Smckusick * procedure's code and a call to svc_sendreply. 194*45069Smckusick * 195*45069Smckusick * Also, if the service refuses to execute the procedure due to too- 196*45069Smckusick * weak authentication parameters, svcerr_weakauth should be called. 197*45069Smckusick * Note: do not confuse access-control failure with weak authentication! 198*45069Smckusick * 199*45069Smckusick * NB: In pure implementations of rpc, the caller always waits for a reply 200*45069Smckusick * msg. This message is sent when svc_sendreply is called. 201*45069Smckusick * Therefore pure service implementations should always call 202*45069Smckusick * svc_sendreply even if the function logically returns void; use 203*45069Smckusick * xdr.h - xdr_void for the xdr routine. HOWEVER, tcp based rpc allows 204*45069Smckusick * for the abuse of pure rpc via batched calling or pipelining. In the 205*45069Smckusick * case of a batched call, svc_sendreply should NOT be called since 206*45069Smckusick * this would send a return message, which is what batching tries to avoid. 207*45069Smckusick * It is the service/protocol writer's responsibility to know which calls are 208*45069Smckusick * batched and which are not. Warning: responding to batch calls may 209*45069Smckusick * deadlock the caller and server processes! 210*45069Smckusick */ 211*45069Smckusick 212*45069Smckusick extern bool_t svc_sendreply(); 213*45069Smckusick extern void svcerr_decode(); 214*45069Smckusick extern void svcerr_weakauth(); 215*45069Smckusick extern void svcerr_noproc(); 216*45069Smckusick extern void svcerr_progvers(); 217*45069Smckusick extern void svcerr_auth(); 218*45069Smckusick extern void svcerr_noprog(); 219*45069Smckusick extern void svcerr_systemerr(); 220*45069Smckusick 221*45069Smckusick /* 222*45069Smckusick * Lowest level dispatching -OR- who owns this process anyway. 223*45069Smckusick * Somebody has to wait for incoming requests and then call the correct 224*45069Smckusick * service routine. The routine svc_run does infinite waiting; i.e., 225*45069Smckusick * svc_run never returns. 226*45069Smckusick * Since another (co-existant) package may wish to selectively wait for 227*45069Smckusick * incoming calls or other events outside of the rpc architecture, the 228*45069Smckusick * routine svc_getreq is provided. It must be passed readfds, the 229*45069Smckusick * "in-place" results of a select system call (see select, section 2). 230*45069Smckusick */ 231*45069Smckusick 232*45069Smckusick /* 233*45069Smckusick * Global keeper of rpc service descriptors in use 234*45069Smckusick * dynamic; must be inspected before each call to select 235*45069Smckusick */ 236*45069Smckusick #ifdef FD_SETSIZE 237*45069Smckusick extern fd_set svc_fdset; 238*45069Smckusick #define svc_fds svc_fdset.fds_bits[0] /* compatibility */ 239*45069Smckusick #else 240*45069Smckusick extern int svc_fds; 241*45069Smckusick #endif /* def FD_SETSIZE */ 242*45069Smckusick 243*45069Smckusick /* 244*45069Smckusick * a small program implemented by the svc_rpc implementation itself; 245*45069Smckusick * also see clnt.h for protocol numbers. 246*45069Smckusick */ 247*45069Smckusick extern void rpctest_service(); 248*45069Smckusick 249*45069Smckusick extern void svc_getreq(); 250*45069Smckusick extern void svc_getreqset(); /* takes fdset instead of int */ 251*45069Smckusick extern void svc_run(); /* never returns */ 252*45069Smckusick 253*45069Smckusick /* 254*45069Smckusick * Socket to use on svcxxx_create call to get default socket 255*45069Smckusick */ 256*45069Smckusick #define RPC_ANYSOCK -1 257*45069Smckusick 258*45069Smckusick /* 259*45069Smckusick * These are the existing service side transport implementations 260*45069Smckusick */ 261*45069Smckusick 262*45069Smckusick /* 263*45069Smckusick * Memory based rpc for testing and timing. 264*45069Smckusick */ 265*45069Smckusick extern SVCXPRT *svcraw_create(); 266*45069Smckusick 267*45069Smckusick /* 268*45069Smckusick * Udp based rpc. 269*45069Smckusick */ 270*45069Smckusick extern SVCXPRT *svcudp_create(); 271*45069Smckusick extern SVCXPRT *svcudp_bufcreate(); 272*45069Smckusick 273*45069Smckusick /* 274*45069Smckusick * Tcp based rpc. 275*45069Smckusick */ 276*45069Smckusick extern SVCXPRT *svctcp_create(); 277*45069Smckusick 278*45069Smckusick 279*45069Smckusick 280*45069Smckusick #endif !__SVC_HEADER__ 281