1 /*
  2  * CDDL HEADER START
  3  *
  4  * The contents of this file are subject to the terms of the
  5  * Common Development and Distribution License, Version 1.0 only
  6  * (the "License").  You may not use this file except in compliance
  7  * with the License.
  8  *
  9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 10  * or http://www.opensolaris.org/os/licensing.
 11  * See the License for the specific language governing permissions
 12  * and limitations under the License.
 13  *
 14  * When distributing Covered Code, include this CDDL HEADER in each
 15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 16  * If applicable, add the following below this CDDL HEADER, with the
 17  * fields enclosed by brackets "[]" replaced with your own identifying
 18  * information: Portions Copyright [yyyy] [name of copyright owner]
 19  *
 20  * CDDL HEADER END
 21  */
 22 /*
 23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
 24  * Use is subject to license terms.
 25  */
 26 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
 27 /* All Rights Reserved */
 28 /*
 29  * Portions of this source code were derived from Berkeley
 30  * 4.3 BSD under license from the Regents of the University of
 31  * California.
 32  */
 33 
 34 /*
 35  * svc.h, Server-side remote procedure call interface.
 36  */
 37 
 38  /* Copyright (c) 2006, The Ohio State University. All rights reserved.
 39   *
 40   * Portions of this source code is developed by the team members of
 41   * The Ohio State University's Network-Based Computing Laboratory (NBCL),
 42   * headed by Professor Dhabaleswar K. (DK) Panda.
 43   *
 44   * Acknowledgements to contributions from developors:
 45   *   Ranjit Noronha: noronha@cse.ohio-state.edu
 46   *   Lei Chai      : chail@cse.ohio-state.edu
 47   *   Weikuan Yu    : yuw@cse.ohio-state.edu
 48   *
 49   */
 50 
 51 #ifndef _RPC_SVC_H
 52 #define _RPC_SVC_H
 53 
 54 #pragma ident   "@(#)svc.h      1.86    05/06/10 SMI"
 55 
 56 #include <rpc/rpc_com.h>
 57 #include <rpc/rpc_msg.h>
 58 #include <sys/tihdr.h>
 59 #include <sys/poll.h>
 60 
 61 #ifdef  _KERNEL
 62 #include <rpc/svc_auth.h>
 63 #include <sys/callb.h>
 64 #endif  /* _KERNEL */
 65 
 66 /*
 67  * This interface must manage two items concerning remote procedure calling:
 68  *
 69  * 1) An arbitrary number of transport connections upon which rpc requests
 70  * are received. They are created and registered by routines in svc_generic.c,
 71  * svc_vc.c and svc_dg.c; they in turn call xprt_register and
 72  * xprt_unregister.
 73  *
 74  * 2) An arbitrary number of locally registered services.  Services are
 75  * described by the following four data: program number, version number,
 76  * "service dispatch" function, a transport handle, and a boolean that
 77  * indicates whether or not the exported program should be registered with a
 78  * local binder service;  if true the program's number and version and the
 79  * address from the transport handle are registered with the binder.
 80  * These data are registered with rpcbind via svc_reg().
 81  *
 82  * A service's dispatch function is called whenever an rpc request comes in
 83  * on a transport.  The request's program and version numbers must match
 84  * those of the registered service.  The dispatch function is passed two
 85  * parameters, struct svc_req * and SVCXPRT *, defined below.
 86  */
 87 
 88 #ifdef __cplusplus
 89 extern "C" {
 90 #endif
 91 
 92 /*
 93  * Server-side transport handles.
 94  * The actual type definitions are below.
 95  */
 96 #ifdef  _KERNEL
 97 typedef struct __svcmasterxprt  SVCMASTERXPRT;  /* Master transport handle */
 98 typedef struct __svcxprt        SVCXPRT;        /* Per-thread clone handle */
 99 typedef struct __svcpool        SVCPOOL;        /* Kernel thread pool      */
100 #else   /* _KERNEL */
101 typedef struct __svcxprt        SVCXPRT;        /* Server transport handle */
102 #endif  /* _KERNEL */
103 
104 /*
105  *  Prototype of error handler callback
106  */
107 #ifndef _KERNEL
108 typedef void (*svc_errorhandler_t)(const SVCXPRT* svc, const bool_t isAConn);
109 #endif
110 
111 /*
112  * Service request.
113  *
114  * PSARC 2003/523 Contract Private Interface
115  * svc_req
116  * Changes must be reviewed by Solaris File Sharing
117  * Changes must be communicated to contract-2003-523@sun.com
118  */
119 struct svc_req {
120         rpcprog_t       rq_prog;        /* service program number */
121         rpcvers_t       rq_vers;        /* service protocol version */
122         rpcproc_t       rq_proc;        /* the desired procedure */
123         struct opaque_auth rq_cred;     /* raw creds from the wire */
124         caddr_t         rq_clntcred;    /* read only cooked cred */
125         SVCXPRT         *rq_xprt;       /* associated transport */
126 };
127 
128 #ifdef _KERNEL
129 struct dupreq {
130         uint32_t        dr_xid;
131         rpcproc_t       dr_proc;
132         rpcvers_t       dr_vers;
133         rpcprog_t       dr_prog;
134         struct netbuf   dr_addr;
135         struct netbuf   dr_resp;
136         void            (*dr_resfree)();
137         int             dr_status;
138         struct dupreq   *dr_next;
139         struct dupreq   *dr_chain;
140 };
141 
142 /*
143  * States of requests for duplicate request caching.
144  */
145 #define DUP_NEW                 0x00    /* new entry */
146 #define DUP_INPROGRESS          0x01    /* request already going */
147 #define DUP_DONE                0x02    /* request done */
148 #define DUP_DROP                0x03    /* request dropped */
149 #define DUP_ERROR               0x04    /* error in dup req cache */
150 
151 /*
152  * Prototype for a service dispatch routine.
153  */
154 typedef void (SVC_DISPATCH)(struct svc_req *, SVCXPRT *);
155 
156 /*
157  * The service provider callout.
158  * Each entry identifies a dispatch routine to be called
159  * for a given RPC program number and a version fitting
160  * into the registered range.
161  */
162 typedef struct {
163         rpcprog_t       sc_prog;        /* RPC Program number */
164         rpcvers_t       sc_versmin;     /* Min version number */
165         rpcvers_t       sc_versmax;     /* Max version number */
166         SVC_DISPATCH    *sc_dispatch;   /* Dispatch routine   */
167 } SVC_CALLOUT;
168 
169 /*
170  * Table of service provider `callouts' for an RPC
171  * transport handle. If sct_free is TRUE then transport
172  * destructor is supposed to deallocate this table.
173  */
174 typedef struct {
175         size_t          sct_size;       /* Number of entries  */
176         bool_t          sct_free;       /* Deallocate if true */
177         SVC_CALLOUT     *sct_sc;        /* Callout entries    */
178 } SVC_CALLOUT_TABLE;
179 
180 struct svc_ops {
181         bool_t  (*xp_recv)(SVCXPRT *, mblk_t *, struct rpc_msg *);
182                 /* receive incoming requests */
183         bool_t  (*xp_getargs)(SVCXPRT *, xdrproc_t, caddr_t);
184                 /* get arguments */
185         bool_t  (*xp_reply)(SVCXPRT *, struct rpc_msg *);
186                 /* send reply */
187         bool_t  (*xp_freeargs)(SVCXPRT *, xdrproc_t, caddr_t);
188                 /* free mem allocated for args */
189         void    (*xp_destroy)(SVCMASTERXPRT *);
190                 /* destroy this struct */
191         int     (*xp_dup)(struct svc_req *, caddr_t, int,
192                                 struct dupreq **, bool_t *);
193                 /* check for dup */
194         void    (*xp_dupdone)(struct dupreq *, caddr_t, void (*)(), int, int);
195                 /* mark dup entry as completed */
196         int32_t *(*xp_getres)(SVCXPRT *, int);
197                 /* get pointer to response buffer */
198         void    (*xp_freeres)(SVCXPRT *);
199                 /* destroy pre-serialized response */
200         void    (*xp_clone_destroy)(SVCXPRT *);
201                 /* destroy a clone xprt */
202         void    (*xp_start)(SVCMASTERXPRT *);
203                 /* `ready-to-receive' */
204         bool_t  (*xp_get_wchunk)(struct svc_req *, iovec_t *);   
205 };
206 #else   /* _KERNEL */
207 /*
208  *      Service control requests
209  */
210 #define SVCGET_VERSQUIET        1
211 #define SVCSET_VERSQUIET        2
212 #define SVCGET_XID              4
213 #define SVCSET_KEEPALIVE        5
214 #define SVCSET_CONNMAXREC       6
215 #define SVCGET_CONNMAXREC       7
216 #define SVCGET_RECVERRHANDLER   8
217 #define SVCSET_RECVERRHANDLER   9
218 
219 enum xprt_stat {
220         XPRT_DIED,
221         XPRT_MOREREQS,
222         XPRT_IDLE
223 };
224 
225 struct xp_ops {
226 #ifdef  __STDC__
227         bool_t  (*xp_recv)(SVCXPRT *, struct rpc_msg *);
228                 /* receive incoming requests */
229         enum xprt_stat (*xp_stat)(SVCXPRT *);
230                 /* get transport status */
231         bool_t  (*xp_getargs)(SVCXPRT *, xdrproc_t, caddr_t);
232                 /* get arguments */
233         bool_t  (*xp_reply)(SVCXPRT *,  struct rpc_msg *);
234                 /* send reply */
235         bool_t  (*xp_freeargs)(SVCXPRT *, xdrproc_t, caddr_t);
236                 /* free mem allocated for args */
237         void    (*xp_destroy)(SVCXPRT *);
238                 /* destroy this struct */
239         bool_t  (*xp_control)(SVCXPRT *, const uint_t,  void *);
240                 /* catch-all control function */
241 #else   /* __STDC__ */
242         bool_t  (*xp_recv)(); /* receive incoming requests */
243         enum xprt_stat (*xp_stat)(); /* get transport status */
244         bool_t  (*xp_getargs)(); /* get arguments */
245         bool_t  (*xp_reply)(); /* send reply */
246         bool_t  (*xp_freeargs)(); /* free mem allocated for args */
247         void    (*xp_destroy)(); /* destroy this struct */
248         bool_t  (*xp_control)(); /* catch-all control function */
249 #endif  /* __STDC__ */
250 };
251 #endif  /* _KERNEL */
252 
253 #ifdef  _KERNEL
254 /*
255  * SVCPOOL
256  * Kernel RPC server-side thread pool structure.
257  */
258 typedef struct __svcxprt_qnode __SVCXPRT_QNODE; /* Defined in svc.c */
259 
260 struct __svcpool {
261         /*
262          * Thread pool variables.
263          *
264          * The pool's thread lock p_thread_lock protects:
265          * - p_threads, p_detached_threads, p_reserved_threads and p_closing
266          * The pool's request lock protects:
267          * - p_asleep, p_drowsy, p_reqs, p_walkers, p_req_cv.
268          * The following fields are `initialized constants':
269          * - p_id, p_stksize, p_timeout.
270          * Access to p_next and p_prev is protected by the pool
271          * list lock.
272          */
273         SVCPOOL         *p_next;                /* Next pool in the list  */
274         SVCPOOL         *p_prev;                /* Prev pool in the list  */
275         int             p_id;                   /* Pool id                */
276         int             p_threads;              /* Non-detached threads   */
277         int             p_detached_threads;     /* Detached threads       */
278         int             p_maxthreads;           /* Max threads in the pool */
279         int             p_redline;              /* `Redline' for the pool */
280         int             p_reserved_threads;     /* Reserved threads       */
281         kmutex_t        p_thread_lock;          /* Thread lock            */
282         int             p_asleep;               /* Asleep threads         */
283         int             p_drowsy;               /* Drowsy flag            */
284         kcondvar_t      p_req_cv;               /* svc_poll() sleep var.  */
285         clock_t         p_timeout;              /* svc_poll() timeout     */
286         kmutex_t        p_req_lock;             /* Request lock           */
287         int             p_reqs;                 /* Pending requests       */
288         int             p_walkers;              /* Walking threads        */
289         int             p_max_same_xprt;        /* Max reqs from the xprt */
290         int             p_stksize;              /* Stack size for svc_run */
291         bool_t          p_closing : 1;          /* Pool is closing        */
292 
293         /*
294          * Thread creator variables.
295          * The `creator signaled' flag is turned on when a signal is send
296          * to the creator thread (to create a new service thread). The
297          * creator clears when the thread is created. The protocol is not
298          * to signal the creator thread when the flag is on. However,
299          * a new thread should signal the creator if there are more
300          * requests in the queue.
301          *
302          * When the pool is closing (ie it has been already unregistered from
303          * the pool list) the last thread on the last transport should turn
304          * the p_creator_exit flag on. This tells the creator thread to
305          * free the pool structure and exit.
306          */
307         bool_t          p_creator_signaled : 1; /* Create requested flag  */
308         bool_t          p_creator_exit : 1;     /* If true creator exits  */
309         kcondvar_t      p_creator_cv;           /* Creator cond. variable */
310         kmutex_t        p_creator_lock;         /* Creator lock           */
311 
312         /*
313          * Doubly linked list containing `registered' master transport handles.
314          * There is no special structure for a list node. Instead the
315          * SVCMASTERXPRT structure has the xp_next and xp_prev fields.
316          *
317          * The p_lrwlock protects access to xprt->xp_next and xprt->xp_prev.
318          * A service thread should also acquire a reader lock before accessing
319          * any transports it is no longer linked to (to prevent them from
320          * being destroyed).
321          *
322          * The list lock governs also the `pool is closing' flag.
323          */
324         size_t          p_lcount;               /* Current count          */
325         SVCMASTERXPRT   *p_lhead;               /* List head              */
326         krwlock_t       p_lrwlock;              /* R/W lock               */
327 
328         /*
329          * Circular linked list for the `xprt-ready' queue (FIFO).
330          * Must be initialized with svc_xprt_qinit() before it is used.
331          *
332          * The writer's end is protected by the pool's request lock
333          * (pool->p_req_lock). The reader's end is protected by q_end_lock.
334          *
335          * When the queue is full the p_qoverflow flag is raised. It stays
336          * on until all the pending request are drained.
337          */
338         size_t          p_qsize;                /* Number of queue nodes  */
339         int             p_qoverflow : 1;        /* Overflow flag          */
340         __SVCXPRT_QNODE *p_qbody;               /* Queue body (array)     */
341         __SVCXPRT_QNODE *p_qtop;                /* Writer's end of FIFO   */
342         __SVCXPRT_QNODE *p_qend;                /* Reader's end of FIFO   */
343         kmutex_t        p_qend_lock;            /* Reader's end lock      */
344 
345         /*
346          * Userspace thread creator variables.
347          * Thread creation is actually done in userland, via a thread
348          * that is parked in the kernel. When that thread is signaled,
349          * it returns back down to the daemon from whence it came and
350          * does the lwp create.
351          *
352          * A parallel "creator" thread runs in the kernel. That is the
353          * thread that will signal for the user thread to return to
354          * userland and do its work.
355          *
356          * Since the thread doesn't always exist (there could be a race
357          * if two threads are created in rapid succession), we set
358          * p_signal_create_thread to FALSE when we're ready to accept work.
359          *
360          * p_user_exit is set to true when the service pool is about
361          * to close. This is done so that the user creation thread
362          * can be informed and cleanup any userland state.
363          */
364 
365         bool_t          p_signal_create_thread : 1; /* Create requested flag  */
366         bool_t          p_user_exit : 1;        /* If true creator exits  */
367         bool_t          p_user_waiting : 1;     /* Thread waiting for work */
368         kcondvar_t      p_user_cv;              /* Creator cond. variable */
369         kmutex_t        p_user_lock;            /* Creator lock           */
370         void            (*p_offline)();         /* callout for unregister */
371         void            (*p_shutdown)();        /* callout for shutdown */
372 };
373 
374 /*
375  * Server side transport handle (SVCMASTERXPRT).
376  * xprt->xp_req_lock governs the following fields in xprt:
377  *              xp_req_head, xp_req_tail.
378  * xprt->xp_thread_lock governs the following fields in xprt:
379  *              xp_threads, xp_detached_threads.
380  *
381  * xp_req_tail is only valid if xp_req_head is non-NULL
382  *
383  * The xp_threads count is the number of attached threads.  These threads
384  * are able to handle new requests, and it is expected that they will not
385  * block for a very long time handling a given request. The
386  * xp_detached_threads count is the number of threads that have detached
387  * themselves from the transport. These threads can block indefinitely
388  * while handling a request.  Once they complete the request, they exit.
389  *
390  * A kernel service provider may register a callback function "closeproc"
391  * for a transport.  When the transport is closing the last exiting attached
392  * thread - xp_threads goes to zero - it calls the callback function, passing
393  * it a reference to the transport.  This call is made with xp_thread_lock
394  * held, so any cleanup bookkeeping it does should be done quickly.
395  *
396  * When the transport is closing the last exiting thread is supposed
397  * to destroy/free the data structure.
398  */
399 typedef struct __svcxprt_common {
400         struct file     *xpc_fp;
401         struct svc_ops  *xpc_ops;
402         queue_t         *xpc_wq;        /* queue to write onto          */
403         cred_t          *xpc_cred;      /* cached cred for server to use */
404         int32_t         xpc_type;       /* transport type               */
405         int             xpc_msg_size;   /* TSDU or TIDU size            */
406         struct netbuf   xpc_rtaddr;     /* remote transport address     */
407         SVC_CALLOUT_TABLE *xpc_sct;
408 } __SVCXPRT_COMMON;
409 
410 #define xp_fp           xp_xpc.xpc_fp
411 #define xp_ops          xp_xpc.xpc_ops
412 #define xp_wq           xp_xpc.xpc_wq
413 #define xp_cred         xp_xpc.xpc_cred
414 #define xp_type         xp_xpc.xpc_type
415 #define xp_msg_size     xp_xpc.xpc_msg_size
416 #define xp_rtaddr       xp_xpc.xpc_rtaddr
417 #define xp_sct          xp_xpc.xpc_sct
418 
419 struct __svcmasterxprt {
420         SVCMASTERXPRT   *xp_next;       /* Next transport in the list   */
421         SVCMASTERXPRT   *xp_prev;       /* Prev transport in the list   */
422         __SVCXPRT_COMMON xp_xpc;        /* Fields common with the clone */
423         SVCPOOL         *xp_pool;       /* Pointer to the pool          */
424         mblk_t          *xp_req_head;   /* Request queue head           */
425         mblk_t          *xp_req_tail;   /* Request queue tail           */
426         kmutex_t        xp_req_lock;    /* Request lock                 */
427         int             xp_threads;     /* Current num. of attached threads */
428         int             xp_detached_threads; /* num. of detached threads */
429         kmutex_t        xp_thread_lock; /* Thread count lock            */
430         void            (*xp_closeproc)(const SVCMASTERXPRT *);
431                                         /* optional; see comments above */
432         char            *xp_netid;      /* network token                */
433         struct netbuf   xp_addrmask;    /* address mask                 */
434 
435         caddr_t         xp_p2;          /* private: for use by svc ops  */
436 };
437 
438 /*
439  * Service thread `clone' transport handle (SVCXPRT)
440  *
441  * PSARC 2003/523 Contract Private Interface
442  * SVCXPRT
443  * Changes must be reviewed by Solaris File Sharing
444  * Changes must be communicated to contract-2003-523@sun.com
445  *
446  * The xp_p2buf buffer is used as the storage for a transport type
447  * specific structure. It is private for the svc ops for a given
448  * transport type.
449  */
450 
451 #define        SVC_P2LEN       104     /* torplen + credctl + wlist */ 
452 
453 struct __svcxprt {
454         __SVCXPRT_COMMON xp_xpc;
455         SVCMASTERXPRT   *xp_master;     /* back ptr to master           */
456 
457         /* The following fileds are on a per-thread basis */
458         callb_cpr_t     *xp_cprp;       /* unused padding for Contract  */
459         bool_t          xp_reserved : 1; /* is thread reserved?         */
460         bool_t          xp_detached : 1; /* is thread detached?         */
461         int             xp_same_xprt;   /* Reqs from the same xprt      */
462 
463         /* The following fields are used on a per-request basis */
464         struct opaque_auth xp_verf;     /* raw response verifier        */
465         SVCAUTH         xp_auth;        /* auth flavor of current req   */
466         void            *xp_cookie;     /* a cookie                     */
467         uint32_t        xp_xid;         /* id                           */
468         XDR             xp_xdrin;       /* input xdr stream             */
469         XDR             xp_xdrout;      /* output xdr stream            */
470 
471         /* Private for svc ops */
472         char            xp_p2buf[SVC_P2LEN]; /* udp_data or cots_data_t */
473                                                 /* or clone_rdma_data_t */
474 };
475 #else   /* _KERNEL */
476 struct __svcxprt {
477         int             xp_fd;
478 #define xp_sock         xp_fd
479         ushort_t        xp_port;
480         /*
481          * associated port number.
482          * Obsolete, but still used to
483          * specify whether rendezvouser
484          * or normal connection
485          */
486         struct  xp_ops  *xp_ops;
487         int             xp_addrlen;     /* length of remote addr. Obsoleted */
488         char            *xp_tp;         /* transport provider device name */
489         char            *xp_netid;      /* network token */
490         struct netbuf   xp_ltaddr;      /* local transport address */
491         struct netbuf   xp_rtaddr;      /* remote transport address */
492         char            xp_raddr[16];   /* remote address. Now obsoleted */
493         struct opaque_auth xp_verf;     /* raw response verifier */
494         caddr_t         xp_p1;          /* private: for use by svc ops */
495         caddr_t         xp_p2;          /* private: for use by svc ops */
496         caddr_t         xp_p3;          /* private: for use by svc lib */
497         int             xp_type;        /* transport type */
498         /*
499          * callback on client death
500          * First parameter is the current structure,
501          * Second parameter :
502          *      - FALSE for the service listener
503          *      - TRUE for a real connected socket
504          */
505         svc_errorhandler_t xp_closeclnt;
506 };
507 #endif  /* _KERNEL */
508 
509 /*
510  *  Approved way of getting address of caller,
511  *  address mask, and netid of transport.
512  */
513 #define svc_getrpccaller(x) (&(x)->xp_rtaddr)
514 #ifdef _KERNEL
515 #define svc_getcaller(x) (&(x)->xp_rtaddr.buf)
516 #define svc_getaddrmask(x) (&(x)->xp_master->xp_addrmask)
517 #define svc_getnetid(x) ((x)->xp_master->xp_netid)
518 #endif  /* _KERNEL */
519 
520 /*
521  * Operations defined on an SVCXPRT handle
522  */
523 
524 #ifdef  _KERNEL
525 #define SVC_RECV(clone_xprt, mp, msg) \
526         (*(clone_xprt)->xp_ops->xp_recv)((clone_xprt), (mp), (msg))
527 
528 /*
529  * PSARC 2003/523 Contract Private Interface
530  * SVC_GETARGS
531  * Changes must be reviewed by Solaris File Sharing
532  * Changes must be communicated to contract-2003-523@sun.com
533  */
534 #define SVC_GETARGS(clone_xprt, xargs, argsp) \
535         (*(clone_xprt)->xp_ops->xp_getargs)((clone_xprt), (xargs), (argsp))
536 
537 #define SVC_REPLY(clone_xprt, msg) \
538         (*(clone_xprt)->xp_ops->xp_reply) ((clone_xprt), (msg))
539 
540 #define SVC_FREEARGS(clone_xprt, xargs, argsp) \
541         (*(clone_xprt)->xp_ops->xp_freeargs)((clone_xprt), (xargs), (argsp))
542 
543 #define SVC_GETRES(clone_xprt, size) \
544         (*(clone_xprt)->xp_ops->xp_getres)((clone_xprt), (size))
545 
546 #define SVC_FREERES(clone_xprt) \
547         (*(clone_xprt)->xp_ops->xp_freeres)(clone_xprt)
548 
549 #define SVC_DESTROY(xprt) \
550         (*(xprt)->xp_ops->xp_destroy)(xprt)
551 
552 /*
553  * PSARC 2003/523 Contract Private Interfaces
554  * SVC_DUP, SVC_DUPDONE, SVC_DUP_EXT, SVC_DUPDONE_EXT
555  * Changes must be reviewed by Solaris File Sharing
556  * Changes must be communicated to contract-2003-523@sun.com
557  *
558  * SVC_DUP and SVC_DUPDONE are defined here for backward compatibility.
559  */
560 #define SVC_DUP_EXT(clone_xprt, req, res, size, drpp, dupcachedp) \
561         (*(clone_xprt)->xp_ops->xp_dup)(req, res, size, drpp, dupcachedp)
562 
563 #define SVC_DUPDONE_EXT(clone_xprt, dr, res, resfree, size, status) \
564         (*(clone_xprt)->xp_ops->xp_dupdone)(dr, res, resfree, size, status)
565 
566 #define SVC_DUP(clone_xprt, req, res, size, drpp) \
567         (*(clone_xprt)->xp_ops->xp_dup)(req, res, size, drpp, NULL)
568 
569 #define SVC_DUPDONE(clone_xprt, dr, res, size, status) \
570         (*(clone_xprt)->xp_ops->xp_dupdone)(dr, res, NULL, size, status)
571 
572 #define SVC_CLONE_DESTROY(clone_xprt) \
573         (*(clone_xprt)->xp_ops->xp_clone_destroy)(clone_xprt)
574 
575 
576 #define SVC_START(xprt) \
577         (*(xprt)->xp_ops->xp_start)(xprt)
578 
579 #define SVC_GET_WCHUNK(xprt, req, iov) \
580         (*(xprt)->xp_ops->xp_get_wchunk)(req, iov)
581                
582 #else   /* _KERNEL */
583 
584 #define SVC_RECV(xprt, msg) \
585         (*(xprt)->xp_ops->xp_recv)((xprt), (msg))
586 #define svc_recv(xprt, msg) \
587         (*(xprt)->xp_ops->xp_recv)((xprt), (msg))
588 
589 #define SVC_STAT(xprt) \
590         (*(xprt)->xp_ops->xp_stat)(xprt)
591 #define svc_stat(xprt) \
592         (*(xprt)->xp_ops->xp_stat)(xprt)
593 
594 #define SVC_GETARGS(xprt, xargs, argsp) \
595         (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp))
596 #define svc_getargs(xprt, xargs, argsp) \
597         (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp))
598 
599 #define SVC_REPLY(xprt, msg) \
600         (*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
601 #define svc_reply(xprt, msg) \
602         (*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
603 
604 #define SVC_FREEARGS(xprt, xargs, argsp) \
605         (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp))
606 #define svc_freeargs(xprt, xargs, argsp) \
607         (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp))
608 
609 #define SVC_GETRES(xprt, size) \
610         (*(xprt)->xp_ops->xp_getres)((xprt), (size))
611 #define svc_getres(xprt, size) \
612         (*(xprt)->xp_ops->xp_getres)((xprt), (size))
613 
614 #define SVC_FREERES(xprt) \
615         (*(xprt)->xp_ops->xp_freeres)(xprt)
616 #define svc_freeres(xprt) \
617         (*(xprt)->xp_ops->xp_freeres)(xprt)
618 
619 #define SVC_DESTROY(xprt) \
620         (*(xprt)->xp_ops->xp_destroy)(xprt)
621 #define svc_destroy(xprt) \
622         (*(xprt)->xp_ops->xp_destroy)(xprt)
623 
624 /*
625  * PSARC 2003/523 Contract Private Interface
626  * SVC_CONTROL
627  * Changes must be reviewed by Solaris File Sharing
628  * Changes must be communicated to contract-2003-523@sun.com
629  */
630 #define SVC_CONTROL(xprt, rq, in) \
631         (*(xprt)->xp_ops->xp_control)((xprt), (rq), (in))
632 #endif  /* _KERNEL */
633 
634 /*
635  * Pool id's reserved for NFS, NLM, and the NFSv4 callback program.
636  */
637 #define NFS_SVCPOOL_ID          0x01
638 #define NLM_SVCPOOL_ID          0x02
639 #define NFS_CB_SVCPOOL_ID       0x03
640 #define RDC_SVCPOOL_ID          0x05    /* SNDR, PSARC 2001/699 */
641 
642 struct svcpool_args {
643         uint32_t        id;             /* Pool id */
644         uint32_t        maxthreads;     /* Max threads in the pool */
645         uint32_t        redline;        /* `Redline' for the pool */
646         uint32_t        qsize;          /* `xprt-ready' queue size */
647         uint32_t        timeout;        /* svc_poll() timeout */
648         uint32_t        stksize;        /* svc_run() stack size */
649         uint32_t        max_same_xprt;  /* Max reqs from the same xprt */
650 };
651 
652 
653 #ifdef  _KERNEL
654 /*
655  * Transport registration and thread pool creation.
656  */
657 extern int      svc_xprt_register(SVCMASTERXPRT *, int);
658 extern void     svc_xprt_unregister(SVCMASTERXPRT *);
659 extern int      svc_pool_create(struct svcpool_args *);
660 extern int      svc_wait(int);
661 extern int      svc_do_run(int);
662 #define SVCPSET_SHUTDOWN_PROC   1
663 #define SVCPSET_UNREGISTER_PROC 2
664 extern int      svc_pool_control(int, int, void *);
665 #else   /* _KERNEL */
666 #ifdef  __STDC__
667 extern bool_t   rpc_reg(const rpcprog_t, const rpcvers_t, const rpcproc_t,
668                         char *(*)(char *), const xdrproc_t, const xdrproc_t,
669                         const char *);
670 
671 /*
672  * Service registration
673  *
674  * svc_reg(xprt, prog, vers, dispatch, nconf)
675  *      const SVCXPRT *xprt;
676  *      const rpcprog_t prog;
677  *      const rpcvers_t vers;
678  *      const void (*dispatch)();
679  *      const struct netconfig *nconf;
680  */
681 extern bool_t   svc_reg(const SVCXPRT *, const rpcprog_t, const rpcvers_t,
682                         void (*)(struct svc_req *, SVCXPRT *),
683                         const struct netconfig *);
684 
685 /*
686  * Service authentication registration
687  *
688  * svc_auth_reg(cred_flavor, handler)
689  *    int cred_flavor;
690  *    enum auth_stat (*handler)();
691  */
692 extern int      svc_auth_reg(int, enum auth_stat (*)());
693 
694 /*
695  * Service un-registration
696  *
697  * svc_unreg(prog, vers)
698  *      const rpcprog_t prog;
699  *      const rpcvers_t vers;
700  */
701 extern void     svc_unreg(const rpcprog_t, const rpcvers_t);
702 
703 /*
704  * Transport registration/unregistration.
705  *
706  * xprt_register(xprt)
707  *      const SVCXPRT *xprt;
708  *
709  * xprt_unregister(xprt)
710  *      const SVCXPRT *xprt;
711  */
712 extern void     xprt_register(const SVCXPRT *);
713 extern void     xprt_unregister(const SVCXPRT *);
714 #else   /* __STDC__ */
715 extern bool_t   rpc_reg();
716 extern bool_t   svc_reg();
717 extern bool_t   svc_auth_reg();
718 extern void     svc_unreg();
719 extern void     xprt_register();
720 extern void     xprt_unregister();
721 #endif /* __STDC__ */
722 #endif  /* _KERNEL */
723 
724 
725 /*
726  * When the service routine is called, it must first check to see if it
727  * knows about the procedure;  if not, it should call svcerr_noproc
728  * and return.  If so, it should deserialize its arguments via
729  * SVC_GETARGS (defined above).  If the deserialization does not work,
730  * svcerr_decode should be called followed by a return.  Successful
731  * decoding of the arguments should be followed the execution of the
732  * procedure's code and a call to svc_sendreply.
733  *
734  * Also, if the service refuses to execute the procedure due to too-
735  * weak authentication parameters, svcerr_weakauth should be called.
736  * Note: do not confuse access-control failure with weak authentication!
737  *
738  * NB: In pure implementations of rpc, the caller always waits for a reply
739  * msg.  This message is sent when svc_sendreply is called.
740  * Therefore pure service implementations should always call
741  * svc_sendreply even if the function logically returns void;  use
742  * xdr.h - xdr_void for the xdr routine.  HOWEVER, connectionful rpc allows
743  * for the abuse of pure rpc via batched calling or pipelining.  In the
744  * case of a batched call, svc_sendreply should NOT be called since
745  * this would send a return message, which is what batching tries to avoid.
746  * It is the service/protocol writer's responsibility to know which calls are
747  * batched and which are not.  Warning: responding to batch calls may
748  * deadlock the caller and server processes!
749  */
750 #ifdef  __STDC__
751 extern bool_t   svc_sendreply(const SVCXPRT *, const xdrproc_t, const caddr_t);
752 extern void     svcerr_decode(const SVCXPRT *);
753 extern void     svcerr_weakauth(const SVCXPRT *);
754 extern void     svcerr_noproc(const SVCXPRT *);
755 extern void     svcerr_progvers(const SVCXPRT *, const rpcvers_t,
756     const rpcvers_t);
757 extern void     svcerr_auth(const SVCXPRT *, const enum auth_stat);
758 extern void     svcerr_noprog(const SVCXPRT *);
759 extern void     svcerr_systemerr(const SVCXPRT *);
760 #else   /* __STDC__ */
761 extern bool_t   svc_sendreply();
762 extern void     svcerr_decode();
763 extern void     svcerr_weakauth();
764 extern void     svcerr_noproc();
765 extern void     svcerr_progvers();
766 extern void     svcerr_auth();
767 extern void     svcerr_noprog();
768 extern void     svcerr_systemerr();
769 #endif  /* __STDC__ */
770 
771 #ifdef  _KERNEL
772 /*
773  * Kernel RPC functions.
774  */
775 extern void     svc_init(void);
776 extern void     svc_cots_init(void);
777 extern void     svc_clts_init(void);
778 extern void     mt_kstat_init(void);
779 extern void     mt_kstat_fini(void);
780 extern int      svc_tli_kcreate(struct file *, uint_t, char *,
781                                 struct netbuf *, SVCMASTERXPRT **,
782                                 SVC_CALLOUT_TABLE *,
783                                 void (*closeproc)(const SVCMASTERXPRT *),
784                                 int, bool_t);
785 extern int      svc_clts_kcreate(struct file *, uint_t, struct T_info_ack *,
786                                 SVCMASTERXPRT **);
787 extern int      svc_cots_kcreate(struct file *, uint_t, struct T_info_ack *,
788                                 SVCMASTERXPRT **);
789 extern void     svc_queuereq(queue_t *, mblk_t *);
790 extern void     svc_queueclean(queue_t *);
791 extern void     svc_queueclose(queue_t *);
792 extern int      svc_reserve_thread(SVCXPRT *);
793 extern void     svc_unreserve_thread(SVCXPRT *);
794 extern callb_cpr_t *svc_detach_thread(SVCXPRT *);
795 
796 /*
797  * For RDMA based kRPC.
798  * "rdma_xprt_record" is a reference to master transport handles
799  * in kRPC thread pools. This is an easy way of tracking and shuting
800  * down rdma based kRPC transports on demand.
801  * "rdma_xprt_group" is a list of RDMA based mster transport handles
802  * or records in a kRPC thread pool.
803  */
804 typedef struct rdma_xprt_record         rdma_xprt_record_t;
805 struct rdma_xprt_record {
806         int                     rtr_type;       /* Type of rdma; IB/VI/RDDP */
807         SVCMASTERXPRT           *rtr_xprt_ptr;  /* Ptr to master xprt handle */
808         rdma_xprt_record_t      *rtr_next;      /* Ptr to next record */
809 };
810 
811 typedef struct {
812         int                     rtg_count;      /* Number transport records */
813         int                     rtg_poolid;     /* Pool Id for this group */
814         rdma_xprt_record_t      *rtg_listhead;  /* Head of the records list */
815 } rdma_xprt_group_t;
816 
817 extern int      svc_rdma_kcreate(char *, SVC_CALLOUT_TABLE *, int,
818                         rdma_xprt_group_t *);
819 extern void     svc_rdma_kstop(SVCMASTERXPRT *);
820 extern void     svc_rdma_kdestroy(SVCMASTERXPRT *);
821 extern void     rdma_stop(rdma_xprt_group_t);
822 extern bool_t rdma_get_wchunk_seg(struct svc_req *, iovec_t *);
823 
824 /*
825  * GSS cleanup method.
826  */
827 extern void     rpc_gss_cleanup(SVCXPRT *);
828 #else   /* _KERNEL */
829 /*
830  * Lowest level dispatching -OR- who owns this process anyway.
831  * Somebody has to wait for incoming requests and then call the correct
832  * service routine.  The routine svc_run does infinite waiting; i.e.,
833  * svc_run never returns.
834  * Since another (co-existant) package may wish to selectively wait for
835  * incoming calls or other events outside of the rpc architecture, the
836  * routine svc_getreq_poll is provided.  It must be passed pollfds, the
837  * "in-place" results of a poll call (see poll, section 2).
838  */
839 
840 /*
841  * Global keeper of rpc service descriptors in use
842  * dynamic; must be inspected before each call to select or poll
843  */
844 extern pollfd_t *svc_pollfd;
845 extern int      svc_max_pollfd;
846 extern fd_set   svc_fdset;
847 #if !defined(_LP64) && FD_SETSIZE > 1024
848 extern fd_set   _new_svc_fdset;
849 #ifdef __PRAGMA_REDEFINE_EXTNAME
850 #pragma redefine_extname        svc_fdset       _new_svc_fdset
851 #else   /* __PRAGMA_REDEFINE_EXTNAME */
852 #define svc_fdset       _new_svc_fdset
853 #endif  /* __PRAGMA_REDEFINE_EXTNAME */
854 #endif  /* LP64 && FD_SETSIZE > 1024 */
855 #define svc_fds svc_fdset.fds_bits[0]   /* compatibility */
856 
857 /*
858  * A small program implemented by the svc_rpc implementation itself.
859  * Also see clnt.h for protocol numbers.
860  */
861 #ifdef __STDC__
862 extern void     svc_getreq(int);
863 extern void     svc_getreq_common(const int);
864 extern void     svc_getreqset(fd_set *); /* takes fdset instead of int */
865 extern void     svc_getreq_poll(struct pollfd *, const int);
866 extern void     svc_run(void);
867 extern void     svc_exit(void);
868 #else   /* __STDC__ */
869 extern void     rpctest_service();
870 extern void     svc_getreqset();
871 extern void     svc_getreq();
872 extern void     svc_getreq_common();
873 extern void     svc_getreqset();         /* takes fdset instead of int */
874 extern void     svc_getreq_poll();
875 extern void     svc_run();
876 extern void     svc_exit();
877 #endif  /* __STDC__ */
878 
879 /*
880  *  Functions used to manage user file descriptors
881  */
882 typedef int svc_input_id_t;
883 typedef void (*svc_callback_t)(svc_input_id_t id, int fd,
884                                 unsigned int events, void* cookie);
885 
886 #ifdef __STDC__
887 extern svc_input_id_t svc_add_input(int fd, unsigned int events,
888                                 svc_callback_t user_callback,
889                                 void* cookie);
890 extern int svc_remove_input(svc_input_id_t id);
891 #else   /* __STDC__ */
892 extern svc_input_id_t svc_add_input();
893 extern int      svc_remove_input();
894 #endif
895 
896 /*
897  * These are the existing service side transport implementations.
898  *
899  * Transport independent svc_create routine.
900  */
901 #ifdef __STDC__
902 extern int      svc_create(void (*)(struct svc_req *, SVCXPRT *),
903                                 const rpcprog_t, const rpcvers_t,
904                                 const char *);
905         /*
906          *      void (*dispatch)();             -- dispatch routine
907          *      const rpcprog_t prognum;        -- program number
908          *      const rpcvers_t versnum;        -- version number
909          *      const char *nettype;            -- network type
910          */
911 
912 /*
913  * Generic server creation routine. It takes a netconfig structure
914  * instead of a nettype.
915  */
916 extern SVCXPRT  *svc_tp_create(void (*)(struct svc_req *, SVCXPRT *),
917                                 const rpcprog_t, const rpcvers_t,
918                                 const struct netconfig *);
919         /*
920          * void (*dispatch)();                  -- dispatch routine
921          * const rpcprog_t prognum;             -- program number
922          * const rpcvers_t versnum;             -- version number
923          * const struct netconfig *nconf;       -- netconfig structure
924          */
925 
926 /*
927  * Generic TLI create routine
928  */
929 extern  SVCXPRT *svc_tli_create(const int, const struct netconfig *,
930                                 const struct t_bind *, const uint_t,
931                                 const uint_t);
932         /*
933          *      const int fd;                   -- connection end point
934          *      const struct netconfig *nconf;  -- netconfig structure
935          *      const struct t_bind *bindaddr;  -- local bind address
936          *      const uint_t sendsz;            -- max sendsize
937          *      const uint_t recvsz;            -- max recvsize
938          */
939 
940 /*
941  * Connectionless and connectionful create routines.
942  */
943 extern SVCXPRT  *svc_vc_create(const int, const uint_t, const uint_t);
944         /*
945          *      const int fd;                   -- open connection end point
946          *      const uint_t sendsize;          -- max send size
947          *      const uint_t recvsize;          -- max recv size
948          */
949 
950 extern SVCXPRT  *svc_dg_create(const int, const uint_t, const uint_t);
951         /*
952          * const int fd;                        -- open connection
953          * const uint_t sendsize;               -- max send size
954          * const uint_t recvsize;               -- max recv size
955          */
956 
957 /*
958  * the routine takes any *open* TLI file
959  * descriptor as its first input and is used for open connections.
960  */
961 extern  SVCXPRT *svc_fd_create(const int, const uint_t, const uint_t);
962         /*
963          *      const int fd;                   -- open connection end point
964          *      const uint_t sendsize;          -- max send size
965          *      const uint_t recvsize;          -- max recv size
966          */
967 
968 /*
969  * Memory based rpc (for speed check and testing)
970  */
971 extern SVCXPRT  *svc_raw_create(void);
972 
973 /*
974  * Creation of service over doors transport.
975  */
976 extern SVCXPRT  *svc_door_create(void (*)(struct svc_req *, SVCXPRT *),
977                                 const rpcprog_t, const rpcvers_t,
978                                 const uint_t);
979         /*
980          *      void (*dispatch)();             -- dispatch routine
981          *      const rpcprog_t prognum;        -- program number
982          *      const rpcvers_t versnum;        -- version number
983          *      const uint_t sendsize;          -- send buffer size
984          */
985 
986 /*
987  * Service control interface
988  */
989 extern  bool_t  svc_control(SVCXPRT *, const uint_t, void *);
990         /*
991          *      SVCXPRT *svc;                   -- service to manipulate
992          *      const uint_t req;               -- request
993          *      void *info;                     -- argument to request
994          */
995 
996 /*
997  * svc_dg_enable_cache() enables the cache on dg transports.
998  */
999 extern int svc_dg_enablecache(SVCXPRT *, const uint_t);
1000 #else   /* __STDC__ */
1001 extern int      svc_create();
1002 extern SVCXPRT  *svc_tp_create();
1003 extern SVCXPRT  *svc_tli_create();
1004 extern SVCXPRT  *svc_vc_create();
1005 extern SVCXPRT  *svc_dg_create();
1006 extern SVCXPRT  *svc_fd_create();
1007 extern SVCXPRT  *svc_raw_create();
1008 extern SVCXPRT  *svc_door_create();
1009 extern int svc_dg_enablecache();
1010 #endif  /* __STDC__ */
1011 
1012 #ifdef  PORTMAP
1013 /* For backward compatibility */
1014 #include <rpc/svc_soc.h>
1015 #endif  /* PORTMAP */
1016 
1017 /*
1018  * For user level MT hot server functions
1019  */
1020 
1021 /*
1022  * Different MT modes
1023  */
1024 #define RPC_SVC_MT_NONE         0       /* default, single-threaded */
1025 #define RPC_SVC_MT_AUTO         1       /* automatic MT mode */
1026 #define RPC_SVC_MT_USER         2       /* user MT mode */
1027 
1028 #ifdef  __STDC__
1029 extern void     svc_done(SVCXPRT *);
1030 #else
1031 extern void     svc_done();
1032 #endif  /* __STDC__ */
1033 
1034 /*
1035  * Obtaining local credentials.
1036  */
1037 typedef struct __svc_local_cred_t {
1038         uid_t   euid;   /* effective uid */
1039         gid_t   egid;   /* effective gid */
1040         uid_t   ruid;   /* real uid */
1041         gid_t   rgid;   /* real gid */
1042         pid_t   pid;    /* caller's pid, or -1 if not available */
1043 } svc_local_cred_t;
1044 
1045 #ifdef __STDC__
1046 struct ucred_s;
1047 extern void     svc_fd_negotiate_ucred(int);
1048 extern int      svc_getcallerucred(const SVCXPRT *, struct ucred_s **);
1049 extern bool_t   svc_get_local_cred(SVCXPRT *, svc_local_cred_t *);
1050 #else
1051 extern void     svc_fd_negotiate_ucred();
1052 extern int      svc_getcallerucred();
1053 extern bool_t   svc_get_local_cred();
1054 #endif  /* __STDC__ */
1055 
1056 /*
1057  * Private interfaces and structures for user level duplicate request caching.
1058  * The interfaces and data structures are not committed and subject to
1059  * change in future releases. Currently only intended for use by automountd.
1060  */
1061 struct dupreq {
1062         uint32_t        dr_xid;
1063         rpcproc_t       dr_proc;
1064         rpcvers_t       dr_vers;
1065         rpcprog_t       dr_prog;
1066         struct netbuf   dr_addr;
1067         struct netbuf   dr_resp;
1068         int             dr_status;
1069         time_t          dr_time;
1070         uint_t          dr_hash;
1071         struct dupreq   *dr_next;
1072         struct dupreq   *dr_prev;
1073         struct dupreq   *dr_chain;
1074         struct dupreq   *dr_prevchain;
1075 };
1076 
1077 /*
1078  * The fixedtime state is defined if we want to expand the routines to
1079  * handle and encompass fixed size caches.
1080  */
1081 #define DUPCACHE_FIXEDTIME      0
1082 
1083 /*
1084  * States of requests for duplicate request caching.
1085  * These are the same as defined for the kernel.
1086  */
1087 #define DUP_NEW                 0x00    /* new entry */
1088 #define DUP_INPROGRESS          0x01    /* request already going */
1089 #define DUP_DONE                0x02    /* request done */
1090 #define DUP_DROP                0x03    /* request dropped */
1091 #define DUP_ERROR               0x04    /* error in dup req cache */
1092 
1093 #ifdef __STDC__
1094 extern bool_t   __svc_dupcache_init(void *, int, char **);
1095 extern int      __svc_dup(struct svc_req *, caddr_t *, uint_t *, char *);
1096 extern int      __svc_dupdone(struct svc_req *, caddr_t, uint_t, int, char *);
1097 extern bool_t   __svc_vc_dupcache_init(SVCXPRT *, void *, int);
1098 extern int      __svc_vc_dup(struct svc_req *, caddr_t *, uint_t *);
1099 extern int      __svc_vc_dupdone(struct svc_req *, caddr_t, uint_t, int);
1100 #else
1101 extern bool_t   __svc_dupcache_init();
1102 extern int      __svc_dup();
1103 extern int      __svc_dupdone();
1104 extern bool_t   __svc_vc_dupcache_init();
1105 extern int      __svc_vc_dup();
1106 extern int      __svc_vc_dupdone();
1107 #endif  /* __STDC__ */
1108 #endif  /* _KERNEL */
1109 
1110 #ifdef  __cplusplus
1111 }
1112 #endif
1113 
1114 #endif  /* !_RPC_SVC_H */
--- EOF ---