/* $NetBSD: clnt.h,v 1.14 2000/06/02 22:57:55 fvdl Exp $ */12/*-3* SPDX-License-Identifier: BSD-3-Clause4*5* Copyright (c) 2010, Oracle America, Inc.6* All rights reserved.7*8* Redistribution and use in source and binary forms, with or without9* modification, are permitted provided that the following conditions are met:10* - Redistributions of source code must retain the above copyright notice,11* this list of conditions and the following disclaimer.12* - Redistributions in binary form must reproduce the above copyright notice,13* this list of conditions and the following disclaimer in the documentation14* and/or other materials provided with the distribution.15* - Neither the name of the "Oracle America, Inc." nor the names of its16* contributors may be used to endorse or promote products derived17* from this software without specific prior written permission.18*19* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"20* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE21* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE22* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE23* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR24* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF25* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS26* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN27* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)28* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE29* POSSIBILITY OF SUCH DAMAGE.30*/3132/*33* clnt.h - Client side remote procedure call interface.34*35* Copyright (c) 1986-1991,1994-1999 by Sun Microsystems, Inc.36* All rights reserved.37*/3839#ifndef _RPC_CLNT_H_40#define _RPC_CLNT_H_41#include <rpc/clnt_stat.h>42#include <sys/cdefs.h>43#include <sys/refcount.h>44#include <rpc/netconfig.h>45#include <sys/un.h>4647/*48* Well-known IPV6 RPC broadcast address.49*/50#define RPCB_MULTICAST_ADDR "ff02::202"5152/*53* the following errors are in general unrecoverable. The caller54* should give up rather than retry.55*/56#define IS_UNRECOVERABLE_RPC(s) (((s) == RPC_AUTHERROR) || \57((s) == RPC_CANTENCODEARGS) || \58((s) == RPC_CANTDECODERES) || \59((s) == RPC_VERSMISMATCH) || \60((s) == RPC_PROCUNAVAIL) || \61((s) == RPC_PROGUNAVAIL) || \62((s) == RPC_PROGVERSMISMATCH) || \63((s) == RPC_CANTDECODEARGS))6465/*66* Error info.67*/68struct rpc_err {69enum clnt_stat re_status;70union {71int RE_errno; /* related system error */72enum auth_stat RE_why; /* why the auth error occurred */73struct {74rpcvers_t low; /* lowest version supported */75rpcvers_t high; /* highest version supported */76} RE_vers;77struct { /* maybe meaningful if RPC_FAILED */78int32_t s1;79int32_t s2;80} RE_lb; /* life boot & debugging only */81} ru;82#define re_errno ru.RE_errno83#define re_why ru.RE_why84#define re_vers ru.RE_vers85#define re_lb ru.RE_lb86};8788/*89* Functions of this type may be used to receive notification when RPC90* calls have to be re-transmitted etc.91*/92typedef void rpc_feedback(int cmd, int procnum, void *);9394/*95* Timers used for the pseudo-transport protocol when using datagrams96*/97struct rpc_timers {98u_short rt_srtt; /* smoothed round-trip time */99u_short rt_deviate; /* estimated deviation */100u_long rt_rtxcur; /* current (backed-off) rto */101};102103/*104* A structure used with CLNT_CALL_EXT to pass extra information used105* while processing an RPC call.106*/107struct rpc_callextra {108AUTH *rc_auth; /* auth handle to use for this call */109rpc_feedback *rc_feedback; /* callback for retransmits etc. */110void *rc_feedback_arg; /* argument for callback */111struct rpc_timers *rc_timers; /* optional RTT timers */112struct rpc_err rc_err; /* detailed call status */113};114115/*116* Client rpc handle.117* Created by individual implementations118* Client is responsible for initializing auth, see e.g. auth_none.c.119*/120typedef struct __rpc_client {121volatile u_int cl_refs; /* reference count */122AUTH *cl_auth; /* authenticator */123const struct clnt_ops {124/* call remote procedure */125enum clnt_stat (*cl_call)(struct __rpc_client *,126struct rpc_callextra *, rpcproc_t,127struct mbuf *, struct mbuf **, struct timeval);128/* abort a call */129void (*cl_abort)(struct __rpc_client *);130/* get specific error code */131void (*cl_geterr)(struct __rpc_client *,132struct rpc_err *);133/* frees results */134bool_t (*cl_freeres)(struct __rpc_client *,135xdrproc_t, void *);136/* close the connection and terminate pending RPCs */137void (*cl_close)(struct __rpc_client *);138/* destroy this structure */139void (*cl_destroy)(struct __rpc_client *);140/* the ioctl() of rpc */141bool_t (*cl_control)(struct __rpc_client *, u_int,142void *);143} *cl_ops;144void *cl_private; /* private stuff */145char *cl_netid; /* network token */146char *cl_tp; /* device name */147} CLIENT;148149/*150* Feedback values used for possible congestion and rate control151*/152#define FEEDBACK_OK 1 /* no retransmits */153#define FEEDBACK_REXMIT1 2 /* first retransmit */154#define FEEDBACK_REXMIT2 3 /* second and subsequent retransmit */155#define FEEDBACK_RECONNECT 4 /* client reconnect */156157/* Used to set version of portmapper used in broadcast */158159#define CLCR_SET_LOWVERS 3160#define CLCR_GET_LOWVERS 4161162#define RPCSMALLMSGSIZE 400 /* a more reasonable packet size */163164/*165* client side rpc interface ops166*167* Parameter types are:168*169*/170171#define CLNT_ACQUIRE(rh) \172refcount_acquire(&(rh)->cl_refs)173#define CLNT_RELEASE(rh) \174if (refcount_release(&(rh)->cl_refs)) \175CLNT_DESTROY(rh)176177/*178* void179* CLNT_CLOSE(rh);180* CLIENT *rh;181*/182#define CLNT_CLOSE(rh) ((*(rh)->cl_ops->cl_close)(rh))183184enum clnt_stat clnt_call_private(CLIENT *, struct rpc_callextra *, rpcproc_t,185xdrproc_t, void *, xdrproc_t, void *, struct timeval);186187/*188* enum clnt_stat189* CLNT_CALL_MBUF(rh, ext, proc, mreq, mrepp, timeout)190* CLIENT *rh;191* struct rpc_callextra *ext;192* rpcproc_t proc;193* struct mbuf *mreq;194* struct mbuf **mrepp;195* struct timeval timeout;196*197* Call arguments in mreq which is consumed by the call (even if there198* is an error). Results returned in *mrepp.199*/200#define CLNT_CALL_MBUF(rh, ext, proc, mreq, mrepp, secs) \201((*(rh)->cl_ops->cl_call)(rh, ext, proc, mreq, mrepp, secs))202203/*204* enum clnt_stat205* CLNT_CALL_EXT(rh, ext, proc, xargs, argsp, xres, resp, timeout)206* CLIENT *rh;207* struct rpc_callextra *ext;208* rpcproc_t proc;209* xdrproc_t xargs;210* void *argsp;211* xdrproc_t xres;212* void *resp;213* struct timeval timeout;214*/215#define CLNT_CALL_EXT(rh, ext, proc, xargs, argsp, xres, resp, secs) \216clnt_call_private(rh, ext, proc, xargs, \217argsp, xres, resp, secs)218219/*220* enum clnt_stat221* CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout)222* CLIENT *rh;223* rpcproc_t proc;224* xdrproc_t xargs;225* void *argsp;226* xdrproc_t xres;227* void *resp;228* struct timeval timeout;229*/230#define CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs) \231clnt_call_private(rh, NULL, proc, xargs, \232argsp, xres, resp, secs)233#define clnt_call(rh, proc, xargs, argsp, xres, resp, secs) \234clnt_call_private(rh, NULL, proc, xargs, \235argsp, xres, resp, secs)236237/*238* void239* CLNT_ABORT(rh);240* CLIENT *rh;241*/242#define CLNT_ABORT(rh) ((*(rh)->cl_ops->cl_abort)(rh))243#define clnt_abort(rh) ((*(rh)->cl_ops->cl_abort)(rh))244245/*246* struct rpc_err247* CLNT_GETERR(rh);248* CLIENT *rh;249*/250#define CLNT_GETERR(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp))251#define clnt_geterr(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp))252253254/*255* bool_t256* CLNT_FREERES(rh, xres, resp);257* CLIENT *rh;258* xdrproc_t xres;259* void *resp;260*/261#define CLNT_FREERES(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp))262#define clnt_freeres(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp))263264/*265* bool_t266* CLNT_CONTROL(cl, request, info)267* CLIENT *cl;268* u_int request;269* char *info;270*/271#define CLNT_CONTROL(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))272#define clnt_control(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))273274/*275* control operations that apply to both udp and tcp transports276*/277#define CLSET_TIMEOUT 1 /* set timeout (timeval) */278#define CLGET_TIMEOUT 2 /* get timeout (timeval) */279#define CLGET_SERVER_ADDR 3 /* get server's address (sockaddr) */280#define CLGET_FD 6 /* get connections file descriptor */281#define CLGET_SVC_ADDR 7 /* get server's address (netbuf) */282#define CLSET_FD_CLOSE 8 /* close fd while clnt_destroy */283#define CLSET_FD_NCLOSE 9 /* Do not close fd while clnt_destroy */284#define CLGET_XID 10 /* Get xid */285#define CLSET_XID 11 /* Set xid */286#define CLGET_VERS 12 /* Get version number */287#define CLSET_VERS 13 /* Set version number */288#define CLGET_PROG 14 /* Get program number */289#define CLSET_PROG 15 /* Set program number */290#define CLSET_SVC_ADDR 16 /* get server's address (netbuf) */291#define CLSET_PUSH_TIMOD 17 /* push timod if not already present */292#define CLSET_POP_TIMOD 18 /* pop timod */293/*294* Connectionless only control operations295*/296#define CLSET_RETRY_TIMEOUT 4 /* set retry timeout (timeval) */297#define CLGET_RETRY_TIMEOUT 5 /* get retry timeout (timeval) */298#define CLSET_ASYNC 19299#define CLSET_CONNECT 20 /* Use connect() for UDP. (int) */300301/*302* Kernel control operations. The default msleep string is "rpcrecv",303* and sleeps are non-interruptible by default.304*/305#define CLSET_WAITCHAN 21 /* set string to use in msleep call */306#define CLGET_WAITCHAN 22 /* get string used in msleep call */307#define CLSET_INTERRUPTIBLE 23 /* set interruptible flag */308#define CLGET_INTERRUPTIBLE 24 /* set interruptible flag */309#define CLSET_RETRIES 25 /* set retry count for reconnect */310#define CLGET_RETRIES 26 /* get retry count for reconnect */311#define CLSET_PRIVPORT 27 /* set privileged source port flag */312#define CLGET_PRIVPORT 28 /* get privileged source port flag */313#define CLSET_BACKCHANNEL 29 /* set backchannel for socket */314#define CLSET_TLS 30 /* set TLS for socket */315#define CLSET_BLOCKRCV 31 /* Temporarily block reception */316#define CLSET_TLSCERTNAME 32 /* TLS certificate file name */317/* Structure used as the argument for CLSET_RECONUPCALL. */318struct rpc_reconupcall {319void (*call)(CLIENT *, void *, struct ucred *);320void *arg;321};322#define CLSET_RECONUPCALL 33 /* Reconnect upcall */323324/*325* void326* CLNT_DESTROY(rh);327* CLIENT *rh;328*/329#define CLNT_DESTROY(rh) ((*(rh)->cl_ops->cl_destroy)(rh))330#define clnt_destroy(rh) ((*(rh)->cl_ops->cl_destroy)(rh))331332333/*334* RPCTEST is a test program which is accessible on every rpc335* transport/port. It is used for testing, performance evaluation,336* and network administration.337*/338339#define RPCTEST_PROGRAM ((rpcprog_t)1)340#define RPCTEST_VERSION ((rpcvers_t)1)341#define RPCTEST_NULL_PROC ((rpcproc_t)2)342#define RPCTEST_NULL_BATCH_PROC ((rpcproc_t)3)343344/*345* By convention, procedure 0 takes null arguments and returns them346*/347348#define NULLPROC ((rpcproc_t)0)349350/*351* Below are the client handle creation routines for the various352* implementations of client side rpc. They can return NULL if a353* creation failure occurs.354*/355356/*357* Generic client creation routine. Supported protocols are those that358* belong to the nettype namespace (/etc/netconfig).359*/360__BEGIN_DECLS361/*362* struct socket *so; -- socket363* struct sockaddr *svcaddr; -- servers address364* rpcprog_t prog; -- program number365* rpcvers_t vers; -- version number366* size_t sendsz; -- buffer recv size367* size_t recvsz; -- buffer send size368*/369extern CLIENT *clnt_dg_create(struct socket *so,370struct sockaddr *svcaddr, rpcprog_t program, rpcvers_t version,371size_t sendsz, size_t recvsz);372373/*374* netlink(4) client that would multicast calls on genetlink(4) family375* named "rpcnl" (with dynamic id). The server counterpart of this376* client is a userland application that uses libc/rpc/svc_nl.c to377* receive the calls and send replies.378*379* const char *name -- multicast group name380*/381extern CLIENT *client_nl_create(const char *name, const rpcprog_t prog,382const rpcvers_t version);383384/*385* struct socket *so; -- socket386* struct sockaddr *svcaddr; -- servers address387* rpcprog_t prog; -- program number388* rpcvers_t vers; -- version number389* size_t sendsz; -- buffer recv size390* size_t recvsz; -- buffer send size391* int intrflag; -- is it interruptible392*/393extern CLIENT *clnt_vc_create(struct socket *so,394struct sockaddr *svcaddr, rpcprog_t program, rpcvers_t version,395size_t sendsz, size_t recvsz, int intrflag);396397/*398* struct netconfig *nconf; -- network type399* struct sockaddr *svcaddr; -- servers address400* rpcprog_t prog; -- program number401* rpcvers_t vers; -- version number402* size_t sendsz; -- buffer recv size403* size_t recvsz; -- buffer send size404*/405extern CLIENT *clnt_reconnect_create(struct netconfig *nconf,406struct sockaddr *svcaddr, rpcprog_t program, rpcvers_t version,407size_t sendsz, size_t recvsz);408__END_DECLS409410411/*412* Print why creation failed413*/414__BEGIN_DECLS415extern void clnt_pcreateerror(const char *); /* stderr */416extern char *clnt_spcreateerror(const char *); /* string */417__END_DECLS418419/*420* Like clnt_perror(), but is more verbose in its output421*/422__BEGIN_DECLS423extern void clnt_perrno(enum clnt_stat); /* stderr */424extern char *clnt_sperrno(enum clnt_stat); /* string */425__END_DECLS426427/*428* Print an English error message, given the client error code429*/430__BEGIN_DECLS431extern void clnt_perror(CLIENT *, const char *); /* stderr */432extern char *clnt_sperror(CLIENT *, const char *); /* string */433__END_DECLS434435436/*437* If a creation fails, the following allows the user to figure out why.438*/439struct rpc_createerr {440enum clnt_stat cf_stat;441struct rpc_err cf_error; /* useful when cf_stat == RPC_PMAPFAILURE */442};443444extern struct rpc_createerr rpc_createerr;445446#endif /* !_RPC_CLNT_H_ */447448449