Home | History | Annotate | Download | only in rpc
      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 (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
     26 /* All Rights Reserved */
     27 /*
     28  * Portions of this source code were derived from Berkeley
     29  * 4.3 BSD under license from the Regents of the University of
     30  * California.
     31  */
     32 
     33 /*
     34  * clnt.h - Client side remote procedure call interface.
     35  */
     36 
     37 #ifndef	_RPC_CLNT_H
     38 #define	_RPC_CLNT_H
     39 
     40 #include <sys/types.h>
     41 #include <rpc/rpc_com.h>
     42 #include <rpc/clnt_stat.h>
     43 #include <rpc/auth.h>
     44 
     45 /*
     46  * rpc calls return an enum clnt_stat.  This should be looked at more,
     47  * since each implementation is required to live with this (implementation
     48  * independent) list of errors.
     49  */
     50 #include <sys/netconfig.h>
     51 #ifdef _KERNEL
     52 #include <sys/t_kuser.h>
     53 #endif	/* _KERNEL */
     54 
     55 #ifdef __cplusplus
     56 extern "C" {
     57 #endif
     58 
     59 /*
     60  * Following defines the multicast group address used by IPV6 enabled
     61  * client to do the broadcast. IPv6 doesn't have any broadcast support
     62  * as IPv4 provides, thus it used this reserved address which is joined
     63  * by all rpc clients.
     64  */
     65 
     66 #define	RPCB_MULTICAST_ADDR "FF02::202"
     67 
     68 /*
     69  * the following errors are in general unrecoverable.  The caller
     70  * should give up rather than retry.
     71  */
     72 #define	IS_UNRECOVERABLE_RPC(s)	(((s) == RPC_AUTHERROR) || \
     73 	((s) == RPC_CANTENCODEARGS) || \
     74 	((s) == RPC_CANTDECODERES) || \
     75 	((s) == RPC_VERSMISMATCH) || \
     76 	((s) == RPC_PROCUNAVAIL) || \
     77 	((s) == RPC_PROGUNAVAIL) || \
     78 	((s) == RPC_PROGVERSMISMATCH) || \
     79 	((s) == RPC_SYSTEMERROR) || \
     80 	((s) == RPC_CANTDECODEARGS))
     81 
     82 /* Maximum rpc backoff time */
     83 #define	RPC_MAX_BACKOFF	30
     84 
     85 /*
     86  * Error info.
     87  */
     88 struct rpc_err {
     89 	enum clnt_stat re_status;
     90 	union {
     91 		struct {
     92 			int RE_errno;	/* related system error */
     93 			int RE_t_errno;	/* related tli error number */
     94 		} RE_err;
     95 		enum auth_stat RE_why;	/* why the auth error occurred */
     96 		struct {
     97 			rpcvers_t low;	/* lowest verion supported */
     98 			rpcvers_t high;	/* highest verion supported */
     99 		} RE_vers;
    100 		struct {		/* maybe meaningful if RPC_FAILED */
    101 			int32_t s1;
    102 			int32_t s2;
    103 		} RE_lb;		/* life boot & debugging only */
    104 	} ru;
    105 #define	re_errno	ru.RE_err.RE_errno
    106 #define	re_terrno	ru.RE_err.RE_t_errno
    107 #define	re_why		ru.RE_why
    108 #define	re_vers		ru.RE_vers
    109 #define	re_lb		ru.RE_lb
    110 };
    111 
    112 
    113 /*
    114  * Timers used for the pseudo-transport protocol when using datagrams
    115  */
    116 struct rpc_timers {
    117 	clock_t		rt_srtt;	/* smoothed round-trip time */
    118 	clock_t		rt_deviate;	/* estimated deviation */
    119 	clock_t		rt_rtxcur;	/* current (backed-off) rto */
    120 };
    121 
    122 /*
    123  * PSARC 2003/523 Contract Private Interface
    124  * CLIENT
    125  * Changes must be reviewed by Solaris File Sharing
    126  * Changes must be communicated to contract-2003-523 (at) sun.com
    127  *
    128  * Client rpc handle.
    129  * Created by individual implementations
    130  * Client is responsible for initializing auth, see e.g. auth_none.c.
    131  */
    132 
    133 typedef struct __client {
    134 	AUTH	*cl_auth;			/* authenticator */
    135 	struct clnt_ops {
    136 #ifdef __STDC__
    137 		/* call remote procedure */
    138 		enum clnt_stat	(*cl_call)(struct __client *, rpcproc_t,
    139 				    xdrproc_t, caddr_t, xdrproc_t,
    140 				    caddr_t, struct timeval);
    141 		/* abort a call */
    142 		void		(*cl_abort)(/* various */);
    143 		/* get specific error code */
    144 		void		(*cl_geterr)(struct __client *,
    145 				    struct rpc_err *);
    146 		/* frees results */
    147 		bool_t		(*cl_freeres)(struct __client *, xdrproc_t,
    148 				    caddr_t);
    149 		/* destroy this structure */
    150 		void		(*cl_destroy)(struct __client *);
    151 		/* the ioctl() of rpc */
    152 		bool_t		(*cl_control)(struct __client *, int, char *);
    153 		/* set rpc level timers */
    154 		int		(*cl_settimers)(struct __client *,
    155 				    struct rpc_timers *, struct rpc_timers *,
    156 				    int, void (*)(), caddr_t, uint32_t);
    157 #ifndef _KERNEL
    158 		/* send a one-way asynchronous call to remote procedure */
    159 		enum clnt_stat	(*cl_send)(struct __client *, rpcproc_t,
    160 				    xdrproc_t, caddr_t);
    161 #endif /* !_KERNEL */
    162 #else
    163 		enum clnt_stat	(*cl_call)();	/* call remote procedure */
    164 		void		(*cl_abort)();	/* abort a call */
    165 		void		(*cl_geterr)();	/* get specific error code */
    166 		bool_t		(*cl_freeres)(); /* frees results */
    167 		void		(*cl_destroy)(); /* destroy this structure */
    168 		bool_t		(*cl_control)(); /* the ioctl() of rpc */
    169 		int		(*cl_settimers)(); /* set rpc level timers */
    170 #ifndef _KERNEL
    171 		enum clnt_stat  (*cl_send)();   /* send one-way request */
    172 #endif /* !_KERNEL */
    173 #endif
    174 	} *cl_ops;
    175 	caddr_t			cl_private;	/* private stuff */
    176 #ifndef _KERNEL
    177 	char			*cl_netid;	/* network token */
    178 	char			*cl_tp;		/* device name */
    179 #else
    180 	bool_t			cl_nosignal;  /* to handle NOINTR */
    181 #endif
    182 } CLIENT;
    183 
    184 /*
    185  * Feedback values used for possible congestion and rate control
    186  */
    187 #define	FEEDBACK_REXMIT1	1	/* first retransmit */
    188 #define	FEEDBACK_OK		2	/* no retransmits */
    189 
    190 /*
    191  * The following defines the control routines
    192  * for rpcbind.
    193  */
    194 
    195 #define	CLCR_GET_RPCB_TIMEOUT	1
    196 #define	CLCR_SET_RPCB_TIMEOUT	2
    197 #define	CLCR_SET_LOWVERS	3
    198 #define	CLCR_GET_LOWVERS	4
    199 #define	CLCR_SET_RPCB_RMTTIME	5
    200 #define	CLCR_GET_RPCB_RMTTIME  	6
    201 #define	CLCR_SET_CRED_CACHE_SZ 	7
    202 #define	CLCR_GET_CRED_CACHE_SZ 	8
    203 
    204 #define	RPCSMALLMSGSIZE	400	/* a more reasonable packet size */
    205 
    206 #define	KNC_STRSIZE	128	/* maximum length of knetconfig strings */
    207 /*
    208  * PSARC 2003/523 Contract Private Interface
    209  * knetconfig
    210  * Changes must be reviewed by Solaris File Sharing
    211  * Changes must be communicated to contract-2003-523 (at) sun.com
    212  *
    213  * Note that the knetconfig strings can either be dynamically allocated, or
    214  * they can be string literals.  The code that sets up the knetconfig is
    215  * responsible for keeping track of this and freeing the strings if
    216  * necessary when the knetconfig is destroyed.
    217  */
    218 struct knetconfig {
    219 	unsigned int	knc_semantics;	/* token name */
    220 	caddr_t		knc_protofmly;	/* protocol family */
    221 	caddr_t		knc_proto;	/* protocol */
    222 	dev_t		knc_rdev;	/* device id */
    223 	unsigned int	knc_unused[8];
    224 };
    225 
    226 #ifdef _SYSCALL32
    227 struct knetconfig32 {
    228 	uint32_t	knc_semantics;	/* token name */
    229 	caddr32_t	knc_protofmly;	/* protocol family */
    230 	caddr32_t	knc_proto;	/* protocol */
    231 	dev32_t		knc_rdev;	/* device id */
    232 	uint32_t	knc_unused[8];
    233 };
    234 #endif /* _SYSCALL32 */
    235 
    236 #ifdef _KERNEL
    237 
    238 /*
    239  * Bucket defined for the call table.  Padded out to 64 bytes so that
    240  * false sharing won't be induced.
    241  */
    242 typedef	union call_table {
    243 	struct {
    244 		struct calllist_s	*uct_call_next;
    245 		struct calllist_s	*uct_call_prev;
    246 		uint_t			uct_len;
    247 		kmutex_t		uct_lock;
    248 	} ct_s;
    249 	char				uct_pad[64];
    250 } call_table_t;
    251 
    252 /*
    253  * Define some macros for easy access into the call table structure
    254  */
    255 #define	ct_call_next ct_s.uct_call_next
    256 #define	ct_call_prev ct_s.uct_call_prev
    257 #define	ct_len ct_s.uct_len
    258 #define	ct_lock ct_s.uct_lock
    259 
    260 /*
    261  * List of outstanding calls awaiting replies, for COTS, CLTS
    262  */
    263 typedef struct calllist_s {
    264 	struct calllist_s *call_next;	/* hash chain, MUST BE FIRST */
    265 	struct calllist_s *call_prev;
    266 	bool_t		call_notified;
    267 	uint_t		call_xid;	/* the xid on the call */
    268 	uint_t		call_hash;	/* hash value */
    269 	call_table_t	*call_bucket;	/* back pointer to bucket */
    270 	mblk_t		*call_reply;	/* the reply to the call */
    271 	kcondvar_t	call_cv;	/* cv to notify when reply is done */
    272 	kmutex_t	call_lock;	/* lock for cv */
    273 	struct rpc_err	call_err;	/* status on reply */
    274 #define	call_status call_err.re_status	/* error on reply (rep is invalid) */
    275 #define	call_reason call_err.re_errno	/* reason code on T_DISCON_IND */
    276 	queue_t		*call_wq;	/* the write queue the call is using */
    277 	zoneid_t	call_zoneid;	/* zoneid the call was made from */
    278 } calllist_t;
    279 
    280 /*
    281  * Define macros for call table hashing
    282  */
    283 /*
    284  * A simple hash function.  Due to the way XID's get allocated, this may be
    285  * sufficient.  This hash function provides round robin bucket selection so
    286  * that the next time a particular bucket gets picked is when there have
    287  * been N-1 calls.  N is the number of buckets.
    288  */
    289 #define	call_hash(xid, hashsize) \
    290 		(xid % hashsize);
    291 
    292 #define	call_table_enter(e)				\
    293 {							\
    294 	call_table_t *ctp = (e)->call_bucket;		\
    295 	mutex_enter(&ctp->ct_lock);			\
    296 	ctp->ct_len++;					\
    297 	(e)->call_next = ctp->ct_call_next;		\
    298 	(e)->call_prev = (calllist_t *)ctp;		\
    299 	ctp->ct_call_next->call_prev = (e);		\
    300 	ctp->ct_call_next = (e);			\
    301 	mutex_exit(&ctp->ct_lock);			\
    302 }
    303 
    304 #define	call_table_remove(e)				\
    305 {							\
    306 	call_table_t *ctp = (e)->call_bucket;		\
    307 	mutex_enter(&ctp->ct_lock);			\
    308 	ctp->ct_len--;					\
    309 	(e)->call_prev->call_next = (e)->call_next;	\
    310 	(e)->call_next->call_prev = (e)->call_prev;	\
    311 	mutex_exit(&ctp->ct_lock);			\
    312 }
    313 
    314 #define	call_table_find(ctp, xid, ele)			\
    315 {							\
    316 	calllist_t *cp;					\
    317 	(ele) = NULL;					\
    318 	mutex_enter(&(ctp)->ct_lock);			\
    319 	for (cp = (ctp)->ct_call_next;			\
    320 		cp != (calllist_t *)(ctp);		\
    321 		cp = cp->call_next) {			\
    322 		if (cp->call_xid == (xid))		\
    323 			(ele) = cp;			\
    324 	}						\
    325 }
    326 
    327 #define	DEFAULT_MIN_HASH_SIZE	32
    328 #define	DEFAULT_HASH_SIZE	1024
    329 
    330 #define	RESERVED_PORTSPACE (IPPORT_RESERVED - (IPPORT_RESERVED/2))
    331 #define	NONRESERVED_PORTSPACE (0xFFFF - IPPORT_RESERVED)
    332 
    333 /*
    334  *	Alloc_xid presents an interface which kernel RPC clients
    335  *	should use to allocate their XIDs.  Its implementation
    336  *	may change over time (for example, to allow sharing of
    337  *	XIDs between the kernel and user-level applications, so
    338  *	all XID allocation should be done by calling alloc_xid().
    339  */
    340 extern uint32_t alloc_xid(void);
    341 
    342 extern struct zone *rpc_zone(void);
    343 extern zoneid_t rpc_zoneid(void);
    344 
    345 extern int clnt_tli_kcreate(struct knetconfig *config, struct netbuf *svcaddr,
    346 	rpcprog_t, rpcvers_t, uint_t max_msgsize, int retrys,
    347 	struct cred *cred, CLIENT **ncl);
    348 
    349 extern int clnt_tli_kinit(CLIENT *h, struct knetconfig *config,
    350 	struct netbuf *addr, uint_t max_msgsize, int retries,
    351 	struct cred *cred);
    352 
    353 extern int rpc_uaddr2port(int af, char *addr);
    354 
    355 /*
    356  * kRPC internal function. Not for general use. Subject to rapid change.
    357  */
    358 extern int bindresvport(TIUSER *tiptr, struct netbuf *addr,
    359 	struct netbuf *bound_addr, bool_t istcp);
    360 
    361 /*
    362  * kRPC internal function. Not for general use. Subject to rapid change.
    363  */
    364 extern int clnt_clts_kcreate(struct knetconfig *config, struct netbuf *addr,
    365 	rpcprog_t, rpcvers_t, int retries, struct cred *cred, CLIENT **cl);
    366 
    367 /*
    368  * kRPC internal function. Not for general use. Subject to rapid change.
    369  */
    370 extern int clnt_cots_kcreate(dev_t dev, struct netbuf *addr, int family,
    371 	rpcprog_t, rpcvers_t, uint_t max_msgsize, struct cred *cred,
    372 	CLIENT **ncl);
    373 /*
    374  * kRPC internal function. Not for general use. Subject to rapid change.
    375  */
    376 extern int clnt_rdma_kcreate(char *proto, void *handle, struct netbuf *raddr,
    377 	int family, rpcprog_t pgm, rpcvers_t vers, struct cred *cred,
    378 	CLIENT **cl);
    379 /*
    380  * kRPC internal function. Not for general use. Subject to rapid change.
    381  */
    382 extern int rdma_reachable(int addr_type, struct netbuf *addr,
    383 	struct knetconfig **knconf);
    384 
    385 /*
    386  * kRPC internal function. Not for general use. Subject to rapid change.
    387  */
    388 extern void clnt_clts_kinit(CLIENT *h, struct netbuf *addr, int retries,
    389 	struct cred *cred);
    390 
    391 /*
    392  * kRPC internal function. Not for general use. Subject to rapid change.
    393  */
    394 extern void clnt_cots_kinit(CLIENT *h, dev_t dev, int family,
    395 	struct netbuf *addr, int max_msgsize, struct cred *cred);
    396 
    397 /*
    398  * kRPC internal function. Not for general use. Subject to rapid change.
    399  */
    400 extern void clnt_rdma_kinit(CLIENT *h, char *proto, void *handle,
    401 	struct netbuf *addr, struct cred *cred);
    402 
    403 /*
    404  * kRPC internal function. Not for general use. Subject to rapid change.
    405  */
    406 extern bool_t clnt_dispatch_notify(mblk_t *, zoneid_t);
    407 
    408 /*
    409  * kRPC internal function. Not for general use. Subject to rapid change.
    410  */
    411 extern bool_t clnt_dispatch_notifyconn(queue_t *, mblk_t *);
    412 
    413 /*
    414  * kRPC internal function. Not for general use. Subject to rapid change.
    415  */
    416 extern void clnt_dispatch_notifyall(queue_t *, int32_t, int32_t);
    417 
    418 /*
    419  * kRPC internal function. Not for general use. Subject to rapid change.
    420  */
    421 extern enum clnt_stat clnt_clts_kcallit_addr(CLIENT *, rpcproc_t, xdrproc_t,
    422 	caddr_t, xdrproc_t, caddr_t, struct timeval, struct netbuf *);
    423 
    424 /*
    425  * kRPC internal function. Not for general use. Subject to rapid change.
    426  */
    427 extern call_table_t *call_table_init(int);
    428 
    429 /*
    430  * kRPC internal function. Not for general use. Subject to rapid change.
    431  */
    432 extern void clnt_init(void);
    433 
    434 /*
    435  * kRPC internal function. Not for general use. Subject to rapid change.
    436  */
    437 extern void clnt_fini(void);
    438 
    439 /*
    440  * kRPC internal function. Not for general use. Subject to rapid change.
    441  */
    442 extern void clnt_clts_init(void);
    443 
    444 /*
    445  * kRPC internal function. Not for general use. Subject to rapid change.
    446  */
    447 extern void clnt_clts_fini(void);
    448 
    449 /*
    450  * kRPC internal function. Not for general use. Subject to rapid change.
    451  */
    452 extern void clnt_cots_init(void);
    453 
    454 /*
    455  * kRPC internal function. Not for general use. Subject to rapid change.
    456  */
    457 extern void clnt_cots_fini(void);
    458 
    459 /*
    460  * kRPC internal function. Not for general use. Subject to rapid change.
    461  */
    462 extern void clnt_clts_dispatch_notify(mblk_t *, int, zoneid_t);
    463 
    464 extern void rpc_poptimod(struct vnode *);
    465 extern int kstr_push(struct vnode *, char *);
    466 extern void t_kadvise(TIUSER *, uchar_t *, int);
    467 
    468 extern boolean_t connmgr_cpr_reset(void *, int);
    469 
    470 extern void put_inet_port(struct netbuf *, ushort_t);
    471 extern void put_inet6_port(struct netbuf *, ushort_t);
    472 extern void put_loopback_port(struct netbuf *, char *);
    473 extern enum clnt_stat rpcbind_getaddr(struct knetconfig *, rpcprog_t,
    474     rpcvers_t, struct netbuf *);
    475 
    476 /*
    477  * Kstat stuff
    478  */
    479 #include <sys/zone.h>
    480 
    481 extern zone_key_t rpcstat_zone_key;
    482 
    483 struct rpc_clts_client;		/* unix:0:rpc_clts_client */
    484 struct rpc_clts_server;		/* unix:0:rpc_clts_server */
    485 struct rpc_cots_client;		/* unix:0:rpc_cots_client */
    486 struct rpc_cots_server;		/* unix:0:rpc_cots_server */
    487 
    488 struct rpcstat {
    489 	struct rpc_clts_client *rpc_clts_client;
    490 	struct rpc_clts_server *rpc_clts_server;
    491 	struct rpc_cots_client *rpc_cots_client;
    492 	struct rpc_cots_server *rpc_cots_server;
    493 };
    494 
    495 extern kstat_named_t *rpcstat_zone_init_common(zoneid_t, const char *,
    496     const char *, const kstat_named_t *, size_t);
    497 extern void rpcstat_zone_fini_common(zoneid_t, const char *, const char *);
    498 
    499 extern void clnt_clts_stats_init(zoneid_t, struct rpc_clts_client **);
    500 extern void clnt_clts_stats_fini(zoneid_t, struct rpc_clts_client **);
    501 
    502 extern void svc_clts_stats_init(zoneid_t, struct rpc_clts_server **);
    503 extern void svc_clts_stats_fini(zoneid_t, struct rpc_clts_server **);
    504 
    505 extern void clnt_cots_stats_init(zoneid_t, struct rpc_cots_client **);
    506 extern void clnt_cots_stats_fini(zoneid_t, struct rpc_cots_client **);
    507 
    508 extern void svc_cots_stats_init(zoneid_t, struct rpc_cots_server **);
    509 extern void svc_cots_stats_fini(zoneid_t, struct rpc_cots_server **);
    510 
    511 #endif /* _KERNEL */
    512 
    513 /*
    514  * client side rpc interface ops
    515  */
    516 
    517 /*
    518  * enum clnt_stat
    519  * CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout)
    520  * 	CLIENT *rh;
    521  *	rpcproc_t proc;
    522  *	xdrproc_t xargs;
    523  *	caddr_t argsp;
    524  *	xdrproc_t xres;
    525  *	caddr_t resp;
    526  *	struct timeval timeout;
    527  *
    528  * PSARC 2003/523 Contract Private Interface
    529  * CLNT_CALL
    530  * Changes must be reviewed by Solaris File Sharing
    531  * Changes must be communicated to contract-2003-523 (at) sun.com
    532  */
    533 #define	CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs)	\
    534 	((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs))
    535 #define	clnt_call(rh, proc, xargs, argsp, xres, resp, secs)	\
    536 	((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs))
    537 
    538 #ifndef _KERNEL
    539 /*
    540  * enum clnt_stat
    541  * CLNT_SEND(rh, proc, xargs, argsp)
    542  * 	CLIENT *rh;
    543  *	rpcproc_t proc;
    544  *	xdrproc_t xargs;
    545  *	caddr_t argsp;
    546  *
    547  * PSARC 2000/428  Contract Private Interface
    548  */
    549 #define	CLNT_SEND(rh, proc, xargs, argsp)	\
    550 	((*(rh)->cl_ops->cl_send)(rh, proc, xargs, argsp))
    551 #define	clnt_send(rh, proc, xargs, argsp)	\
    552 	((*(rh)->cl_ops->cl_send)(rh, proc, xargs, argsp))
    553 #endif /* !_KERNEL */
    554 
    555 /*
    556  * void
    557  * CLNT_ABORT(rh);
    558  * 	CLIENT *rh;
    559  */
    560 #define	CLNT_ABORT(rh)	((*(rh)->cl_ops->cl_abort)(rh))
    561 #define	clnt_abort(rh)	((*(rh)->cl_ops->cl_abort)(rh))
    562 
    563 /*
    564  * struct rpc_err
    565  * CLNT_GETERR(rh);
    566  * 	CLIENT *rh;
    567  */
    568 #define	CLNT_GETERR(rh, errp)	((*(rh)->cl_ops->cl_geterr)(rh, errp))
    569 #define	clnt_geterr(rh, errp)	((*(rh)->cl_ops->cl_geterr)(rh, errp))
    570 
    571 /*
    572  * bool_t
    573  * CLNT_FREERES(rh, xres, resp);
    574  * 	CLIENT *rh;
    575  *	xdrproc_t xres;
    576  *	caddr_t resp;
    577  */
    578 #define	CLNT_FREERES(rh, xres, resp) \
    579 		((*(rh)->cl_ops->cl_freeres)(rh, xres, resp))
    580 #define	clnt_freeres(rh, xres, resp) \
    581 		((*(rh)->cl_ops->cl_freeres)(rh, xres, resp))
    582 
    583 /*
    584  * bool_t
    585  * CLNT_CONTROL(cl, request, info)
    586  *	CLIENT *cl;
    587  *	uint_t request;
    588  *	char *info;
    589  *
    590  * PSARC 2003/523 Contract Private Interface
    591  * CLNT_CONTROL
    592  * Changes must be reviewed by Solaris File Sharing
    593  * Changes must be communicated to contract-2003-523 (at) sun.com
    594  */
    595 #define	CLNT_CONTROL(cl, rq, in) ((*(cl)->cl_ops->cl_control)(cl, rq, in))
    596 #define	clnt_control(cl, rq, in) ((*(cl)->cl_ops->cl_control)(cl, rq, in))
    597 
    598 
    599 /*
    600  * control operations that apply to all transports
    601  */
    602 #define	CLSET_TIMEOUT		1	/* set timeout (timeval) */
    603 #define	CLGET_TIMEOUT		2	/* get timeout (timeval) */
    604 #define	CLGET_SERVER_ADDR	3	/* get server's address (sockaddr) */
    605 #define	CLGET_FD		6	/* get connections file descriptor */
    606 #define	CLGET_SVC_ADDR		7	/* get server's address (netbuf) */
    607 #define	CLSET_FD_CLOSE		8	/* close fd while clnt_destroy */
    608 #define	CLSET_FD_NCLOSE		9	/* Do not close fd while clnt_destroy */
    609 #define	CLGET_XID 		10	/* Get xid */
    610 #define	CLSET_XID		11	/* Set xid */
    611 #define	CLGET_VERS		12	/* Get version number */
    612 #define	CLSET_VERS		13	/* Set version number */
    613 #define	CLGET_PROG		14	/* Get program number */
    614 #define	CLSET_PROG		15	/* Set program number */
    615 #define	CLSET_SVC_ADDR		16	/* get server's address (netbuf) */
    616 #define	CLSET_PUSH_TIMOD	17	/* push timod if not already present */
    617 #define	CLSET_POP_TIMOD		18	/* pop timod */
    618 #ifndef _KERNEL
    619 /* 00-08-17 - NON STANDARD CONTROL PARAMETER */
    620 #define	CLSET_IO_MODE		19	/* clnt_send behavior */
    621 #define	CLGET_IO_MODE		20	/* clnt_send behavior */
    622 #define	CLSET_FLUSH_MODE	21	/* flush behavior */
    623 #define	CLGET_FLUSH_MODE	22	/* flush behavior */
    624 #define	CLFLUSH			23	/* flush now (user wants it) */
    625 #define	CLSET_CONNMAXREC_SIZE	24	/* set pending request buffer size */
    626 #define	CLGET_CONNMAXREC_SIZE	25	/* set pending request buffer size */
    627 #define	CLGET_CURRENT_REC_SIZE	26	/* get pending request buffer size */
    628 
    629 typedef enum {
    630 	RPC_CL_BESTEFFORT_FLUSH = 100,	/* flush as much as possible */
    631 					/* without blocking */
    632 	RPC_CL_BLOCKING_FLUSH,		/* flush the buffer completely */
    633 					/* (possibly blocking) */
    634 	RPC_CL_DEFAULT_FLUSH		/* flush according to the currently */
    635 					/* defined policy. */
    636 } rpcflushmode_t;
    637 
    638 
    639 typedef enum {
    640 	RPC_CL_BLOCKING = 10,	/* PASSED CLNT_CONTROL SET_IO_MODE */
    641 	RPC_CL_NONBLOCKING
    642 } rpciomode_t;
    643 #endif /* !_KERNEL */
    644 /*
    645  * Connectionless only control operations
    646  */
    647 #define	CLSET_RETRY_TIMEOUT 4   /* set retry timeout (timeval) */
    648 #define	CLGET_RETRY_TIMEOUT 5   /* get retry timeout (timeval) */
    649 
    650 #ifdef	_KERNEL
    651 /*
    652  * Connection oriented only control operation.
    653  */
    654 #define	CLSET_PROGRESS		10000	/* Report RPC_INPROGRESS if a request */
    655 					/* has been sent but no reply */
    656 					/* received yet. */
    657 #define	CLSET_BCAST		10001	/* Set RPC Broadcast hint */
    658 #define	CLGET_BCAST		10002	/* Get RPC Broadcast hint */
    659 #define	CLSET_NODELAYONERR	10003	/* Set enable/disable of delay on */
    660 					/* connection setup error	  */
    661 #define	CLGET_NODELAYONERR	10004	/* Get enable/disable of delay on */
    662 					/* connection setup error	  */
    663 #define	CLSET_BINDRESVPORT	10005	/* Set preference for reserve port */
    664 #define	CLGET_BINDRESVPORT	10006	/* Get preference for reserve port */
    665 #endif
    666 
    667 /*
    668  * void
    669  * CLNT_SETTIMERS(rh);
    670  *	CLIENT *rh;
    671  *	struct rpc_timers *t;
    672  *	struct rpc_timers *all;
    673  *	unsigned int min;
    674  *	void    (*fdbck)();
    675  *	caddr_t arg;
    676  *	uint_t  xid;
    677  */
    678 #define	CLNT_SETTIMERS(rh, t, all, min, fdbck, arg, xid) \
    679 		((*(rh)->cl_ops->cl_settimers)(rh, t, all, min, \
    680 		fdbck, arg, xid))
    681 #define	clnt_settimers(rh, t, all, min, fdbck, arg, xid) \
    682 		((*(rh)->cl_ops->cl_settimers)(rh, t, all, min, \
    683 		fdbck, arg, xid))
    684 
    685 
    686 /*
    687  * void
    688  * CLNT_DESTROY(rh);
    689  * 	CLIENT *rh;
    690  *
    691  * PSARC 2003/523 Contract Private Interface
    692  * CLNT_DESTROY
    693  * Changes must be reviewed by Solaris File Sharing
    694  * Changes must be communicated to contract-2003-523 (at) sun.com
    695  */
    696 #define	CLNT_DESTROY(rh)	((*(rh)->cl_ops->cl_destroy)(rh))
    697 #define	clnt_destroy(rh)	((*(rh)->cl_ops->cl_destroy)(rh))
    698 
    699 
    700 /*
    701  * RPCTEST is a test program which is accessable on every rpc
    702  * transport/port.  It is used for testing, performance evaluation,
    703  * and network administration.
    704  */
    705 
    706 #define	RPCTEST_PROGRAM		((rpcprog_t)1)
    707 #define	RPCTEST_VERSION		((rpcvers_t)1)
    708 #define	RPCTEST_NULL_PROC	((rpcproc_t)2)
    709 #define	RPCTEST_NULL_BATCH_PROC	((rpcproc_t)3)
    710 
    711 /*
    712  * By convention, procedure 0 takes null arguments and returns them
    713  */
    714 
    715 #define	NULLPROC ((rpcproc_t)0)
    716 
    717 /*
    718  * Below are the client handle creation routines for the various
    719  * implementations of client side rpc.  They can return NULL if a
    720  * creation failure occurs.
    721  */
    722 
    723 #ifndef _KERNEL
    724 
    725 /*
    726  * Generic client creation routine. Supported protocols are which belong
    727  * to the nettype name space
    728  */
    729 #ifdef __STDC__
    730 extern  CLIENT * clnt_create(const char *, const rpcprog_t, const rpcvers_t,
    731 	const char *);
    732 /*
    733  *
    734  * 	const char *hostname;			-- hostname
    735  *	const rpcprog_t prog;			-- program number
    736  *	const rpcvers_t vers;			-- version number
    737  *	const char *nettype;			-- network type
    738  */
    739 #else
    740 extern CLIENT * clnt_create();
    741 #endif
    742 
    743 /*
    744  * Generic client creation routine. Just like clnt_create(), except
    745  * it takes an additional timeout parameter.
    746  */
    747 #ifdef __STDC__
    748 extern  CLIENT * clnt_create_timed(const char *, const rpcprog_t,
    749 	const rpcvers_t, const char *, const struct timeval *);
    750 /*
    751  *
    752  * 	const char *hostname;			-- hostname
    753  *	const rpcprog_t prog;			-- program number
    754  *	const rpcvers_t vers;			-- version number
    755  *	const char *nettype;			-- network type
    756  *	const struct timeval *tp;		-- timeout
    757  */
    758 #else
    759 extern CLIENT * clnt_create_timed();
    760 #endif
    761 
    762 /*
    763  * Generic client creation routine. Supported protocols are which belong
    764  * to the nettype name space.
    765  */
    766 #ifdef __STDC__
    767 extern CLIENT * clnt_create_vers(const char *, const rpcprog_t, rpcvers_t *,
    768 	const rpcvers_t, const rpcvers_t, const char *);
    769 /*
    770  *	const char *host;		-- hostname
    771  *	const rpcprog_t prog;		-- program number
    772  *	rpcvers_t *vers_out;	-- servers highest available version number
    773  *	const rpcvers_t vers_low;	-- low version number
    774  *	const rpcvers_t vers_high;	-- high version number
    775  *	const char *nettype;		-- network type
    776  */
    777 #else
    778 extern CLIENT * clnt_create_vers();
    779 #endif
    780 
    781 /*
    782  * Generic client creation routine. Supported protocols are which belong
    783  * to the nettype name space.
    784  */
    785 #ifdef __STDC__
    786 extern CLIENT * clnt_create_vers_timed(const char *, const rpcprog_t,
    787 	rpcvers_t *, const rpcvers_t, const rpcvers_t, const char *,
    788 	const struct timeval *);
    789 /*
    790  *	const char *host;		-- hostname
    791  *	const rpcprog_t prog;		-- program number
    792  *	rpcvers_t *vers_out;	-- servers highest available version number
    793  *	const rpcvers_t vers_low;	-- low version number
    794  *	const prcvers_t vers_high;	-- high version number
    795  *	const char *nettype;		-- network type
    796  *	const struct timeval *tp	-- timeout
    797  */
    798 #else
    799 extern CLIENT * clnt_create_vers_timed();
    800 #endif
    801 
    802 
    803 /*
    804  * Generic client creation routine. It takes a netconfig structure
    805  * instead of nettype
    806  */
    807 #ifdef __STDC__
    808 extern CLIENT * clnt_tp_create(const char *, const rpcprog_t, const rpcvers_t,
    809 	const struct netconfig *);
    810 /*
    811  *	const char *hostname;			-- hostname
    812  *	const rpcprog_t prog;			-- program number
    813  *	const rpcvers_t vers;			-- version number
    814  *	const struct netconfig *netconf; 	-- network config structure
    815  */
    816 #else
    817 extern CLIENT * clnt_tp_create();
    818 #endif
    819 
    820 /*
    821  * Generic client creation routine. Just like clnt_tp_create(), except
    822  * it takes an additional timeout parameter.
    823  */
    824 #ifdef __STDC__
    825 extern CLIENT * clnt_tp_create_timed(const char *, const rpcprog_t,
    826 	const rpcvers_t, const struct netconfig *, const struct timeval *);
    827 /*
    828  *	const char *hostname;			-- hostname
    829  *	const rpcprog_t prog;			-- program number
    830  *	const rpcvers_t vers;			-- version number
    831  *	const struct netconfig *netconf; 	-- network config structure
    832  *	const struct timeval *tp;		-- timeout
    833  */
    834 #else
    835 extern CLIENT * clnt_tp_create_timed();
    836 #endif
    837 
    838 /*
    839  * Generic TLI create routine
    840  */
    841 
    842 #ifdef __STDC__
    843 extern CLIENT * clnt_tli_create(const int, const struct netconfig *,
    844 	struct netbuf *, const rpcprog_t, const rpcvers_t, const uint_t,
    845 	const uint_t);
    846 /*
    847  *	const int fd;		-- fd
    848  *	const struct netconfig *nconf;	-- netconfig structure
    849  *	struct netbuf *svcaddr;		-- servers address
    850  *	const rpcprog_t prog;		-- program number
    851  *	const rpcvers_t vers;		-- version number
    852  *	const uint_t sendsz;		-- send size
    853  *	const uint_t recvsz;		-- recv size
    854  */
    855 
    856 #else
    857 extern CLIENT * clnt_tli_create();
    858 #endif
    859 
    860 /*
    861  * Low level clnt create routine for connectionful transports, e.g. tcp.
    862  */
    863 #ifdef __STDC__
    864 extern  CLIENT * clnt_vc_create(const int, struct netbuf *,
    865 	const rpcprog_t, const rpcvers_t, const uint_t, const uint_t);
    866 /*
    867  *	const int fd;				-- open file descriptor
    868  *	const struct netbuf *svcaddr;		-- servers address
    869  *	const rpcprog_t prog;			-- program number
    870  *	const rpcvers_t vers;			-- version number
    871  *	const uint_t sendsz;			-- buffer recv size
    872  *	const uint_t recvsz;			-- buffer send size
    873  */
    874 #else
    875 extern CLIENT * clnt_vc_create();
    876 #endif
    877 
    878 /*
    879  * Low level clnt create routine for connectionless transports, e.g. udp.
    880  */
    881 #ifdef __STDC__
    882 extern  CLIENT * clnt_dg_create(const int, struct netbuf *,
    883 	const rpcprog_t, const rpcvers_t, const uint_t, const uint_t);
    884 /*
    885  *	const int fd;				-- open file descriptor
    886  *	const struct netbuf *svcaddr;		-- servers address
    887  *	const rpcprog_t program;		-- program number
    888  *	const rpcvers_t version;		-- version number
    889  *	const uint_t sendsz;			-- buffer recv size
    890  *	const uint_t recvsz;			-- buffer send size
    891  */
    892 #else
    893 extern CLIENT * clnt_dg_create();
    894 #endif
    895 
    896 /*
    897  * Memory based rpc (for speed check and testing)
    898  * CLIENT *
    899  * clnt_raw_create(prog, vers)
    900  *	const rpcprog_t prog;			-- program number
    901  *	const rpcvers_t vers;			-- version number
    902  */
    903 #ifdef __STDC__
    904 extern CLIENT *clnt_raw_create(const rpcprog_t, const rpcvers_t);
    905 #else
    906 extern CLIENT *clnt_raw_create();
    907 #endif
    908 
    909 /*
    910  * Client creation routine over doors transport.
    911  */
    912 #ifdef __STDC__
    913 extern  CLIENT * clnt_door_create(const rpcprog_t, const rpcvers_t,
    914 	const uint_t);
    915 /*
    916  *	const rpcprog_t prog;			-- program number
    917  *	const rpcvers_t vers;			-- version number
    918  *	const uint_t sendsz;			-- max send size
    919  */
    920 #else
    921 extern CLIENT * clnt_door_create();
    922 #endif
    923 
    924 /*
    925  * internal function. Not for general use. Subject to rapid change.
    926  */
    927 #ifdef __STDC__
    928 extern CLIENT *clnt_create_service_timed(const char *,
    929 					const char *,
    930 					const rpcprog_t,
    931 					const rpcvers_t,
    932 					const ushort_t,
    933 					const char *,
    934 					const struct timeval *);
    935 #else
    936 extern CLIENT *clnt_create_service_timed();
    937 #endif
    938 
    939 /*
    940  * Print why creation failed
    941  */
    942 #ifdef __STDC__
    943 void clnt_pcreateerror(const char *);	/* stderr */
    944 char *clnt_spcreateerror(const char *);	/* string */
    945 #else
    946 void clnt_pcreateerror();
    947 char *clnt_spcreateerror();
    948 #endif
    949 
    950 /*
    951  * Like clnt_perror(), but is more verbose in its output
    952  */
    953 #ifdef __STDC__
    954 void clnt_perrno(const enum clnt_stat);	/* stderr */
    955 #else
    956 void clnt_perrno();
    957 #endif
    958 
    959 /*
    960  * Print an error message, given the client error code
    961  */
    962 #ifdef __STDC__
    963 void clnt_perror(const CLIENT *, const char *);
    964 #else
    965 void clnt_perror();
    966 #endif
    967 
    968 /*
    969  * If a creation fails, the following allows the user to figure out why.
    970  */
    971 struct rpc_createerr {
    972 	enum clnt_stat cf_stat;
    973 	struct rpc_err cf_error; /* useful when cf_stat == RPC_PMAPFAILURE */
    974 };
    975 
    976 #ifdef	_REENTRANT
    977 extern struct rpc_createerr	*__rpc_createerr();
    978 #define	rpc_createerr	(*(__rpc_createerr()))
    979 #else
    980 extern struct rpc_createerr rpc_createerr;
    981 #endif	/* _REENTRANT */
    982 
    983 /*
    984  * The simplified interface:
    985  * enum clnt_stat
    986  * rpc_call(host, prognum, versnum, procnum, inproc, in, outproc, out, nettype)
    987  *	const char *host;
    988  *	const rpcprog_t prognum;
    989  *	const rpcvers_t versnum;
    990  *	const rpcproc_t procnum;
    991  *	const xdrproc_t inproc, outproc;
    992  *	const char *in;
    993  *	char *out;
    994  *	const char *nettype;
    995  */
    996 #ifdef __STDC__
    997 extern enum clnt_stat rpc_call(const char *, const rpcprog_t, const rpcvers_t,
    998 	const rpcproc_t, const xdrproc_t, const char *, const xdrproc_t,
    999 	char *, const char *);
   1000 #else
   1001 extern enum clnt_stat rpc_call();
   1002 #endif
   1003 
   1004 #ifdef	_REENTRANT
   1005 extern struct rpc_err	*__rpc_callerr();
   1006 #define	rpc_callerr	(*(__rpc_callerr()))
   1007 #else
   1008 extern struct rpc_err rpc_callerr;
   1009 #endif	/* _REENTRANT */
   1010 
   1011 /*
   1012  * RPC broadcast interface
   1013  * The call is broadcasted to all locally connected nets.
   1014  *
   1015  * extern enum clnt_stat
   1016  * rpc_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp,
   1017  *			eachresult, nettype)
   1018  *	const rpcprog_t		prog;		-- program number
   1019  *	const rpcvers_t		vers;		-- version number
   1020  *	const rpcproc_t		proc;		-- procedure number
   1021  *	const xdrproc_t	xargs;		-- xdr routine for args
   1022  *	caddr_t		argsp;		-- pointer to args
   1023  *	const xdrproc_t	xresults;	-- xdr routine for results
   1024  *	caddr_t		resultsp;	-- pointer to results
   1025  *	const resultproc_t	eachresult;	-- call with each result
   1026  *	const char		*nettype;	-- Transport type
   1027  *
   1028  * For each valid response received, the procedure eachresult is called.
   1029  * Its form is:
   1030  *		done = eachresult(resp, raddr, nconf)
   1031  *			bool_t done;
   1032  *			caddr_t resp;
   1033  *			struct netbuf *raddr;
   1034  *			struct netconfig *nconf;
   1035  * where resp points to the results of the call and raddr is the
   1036  * address if the responder to the broadcast.  nconf is the transport
   1037  * on which the response was received.
   1038  *
   1039  * extern enum clnt_stat
   1040  * rpc_broadcast_exp(prog, vers, proc, xargs, argsp, xresults, resultsp,
   1041  *			eachresult, inittime, waittime, nettype)
   1042  *	const rpcprog_t		prog;		-- program number
   1043  *	const rpcvers_t		vers;		-- version number
   1044  *	const rpcproc_t		proc;		-- procedure number
   1045  *	const xdrproc_t	xargs;		-- xdr routine for args
   1046  *	caddr_t		argsp;		-- pointer to args
   1047  *	const xdrproc_t	xresults;	-- xdr routine for results
   1048  *	caddr_t		resultsp;	-- pointer to results
   1049  *	const resultproc_t	eachresult;	-- call with each result
   1050  *	const int 		inittime;	-- how long to wait initially
   1051  *	const int 		waittime;	-- maximum time to wait
   1052  *	const char		*nettype;	-- Transport type
   1053  */
   1054 
   1055 typedef bool_t(*resultproc_t)(
   1056 #ifdef	__STDC__
   1057 	caddr_t,
   1058 	... /* for backward compatibility */
   1059 #endif				/* __STDC__ */
   1060 );
   1061 #ifdef __STDC__
   1062 extern enum clnt_stat rpc_broadcast(const rpcprog_t, const rpcvers_t,
   1063 	const rpcproc_t, const xdrproc_t, caddr_t, const xdrproc_t,
   1064 	caddr_t, const resultproc_t, const char *);
   1065 extern enum clnt_stat rpc_broadcast_exp(const rpcprog_t, const rpcvers_t,
   1066 	const rpcproc_t, const xdrproc_t, caddr_t, const xdrproc_t, caddr_t,
   1067 	const resultproc_t, const int, const int, const char *);
   1068 #else
   1069 extern enum clnt_stat rpc_broadcast();
   1070 extern enum clnt_stat rpc_broadcast_exp();
   1071 #endif
   1072 #endif /* !_KERNEL */
   1073 
   1074 /*
   1075  * Copy error message to buffer.
   1076  */
   1077 #ifdef __STDC__
   1078 const char *clnt_sperrno(const enum clnt_stat);
   1079 #else
   1080 char *clnt_sperrno();	/* string */
   1081 #endif
   1082 
   1083 /*
   1084  * Print an error message, given the client error code
   1085  */
   1086 #ifdef __STDC__
   1087 char *clnt_sperror(const CLIENT *, const char *);
   1088 #else
   1089 char *clnt_sperror();
   1090 #endif
   1091 
   1092 /*
   1093  * Client side rpc control routine for rpcbind.
   1094  */
   1095 #ifdef __STDC__
   1096 bool_t __rpc_control(int, void *);
   1097 #else
   1098 bool_t __rpc_control();
   1099 #endif
   1100 
   1101 #ifdef __cplusplus
   1102 }
   1103 #endif
   1104 
   1105 #ifdef PORTMAP
   1106 /* For backward compatibility */
   1107 #include <rpc/clnt_soc.h>
   1108 #endif
   1109 
   1110 #endif	/* !_RPC_CLNT_H */
   1111