diff options
author | Ulrich Drepper <drepper@redhat.com> | 2000-08-02 07:01:41 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2000-08-02 07:01:41 +0000 |
commit | be18eced55bb0d6431f1cd81df8febbc159ddc86 (patch) | |
tree | 5ca3c86709090813f200b6d2abac9e498a071de7 /sunrpc | |
parent | ca8d5a5f3dea0f541fc3c388b6cb01a2d27e9924 (diff) | |
download | glibc-be18eced55bb0d6431f1cd81df8febbc159ddc86.tar.gz glibc-be18eced55bb0d6431f1cd81df8febbc159ddc86.tar.xz glibc-be18eced55bb0d6431f1cd81df8febbc159ddc86.zip |
Update.
Remove incompatible IPv6 extension of RPC. * sunrpc/Makefile: Undo changes. * sunrpc/rpc_main.c: Likewise. * sunrpc/rpc/clnt.h: Likewise. * sunrpc/rpc/svc.h: Likewise. * sunrpc/bindrsvprt6.c: Removed. * sunrpc/clnt_tcp6.c: Removed. * sunrpc/clnt_udp6.c: Removed. * sunrpc/svc_tcp6.c: Removed. * sunrpc/svc_udp6.c: Removed. * intl/libintl.h: Don't use __attribute_format_arg__ for gettext, dgettext, and dcgettetxt. * intl/locale.alias: Update japanese aliases.
Diffstat (limited to 'sunrpc')
-rw-r--r-- | sunrpc/Makefile | 3 | ||||
-rw-r--r-- | sunrpc/Versions | 3 | ||||
-rw-r--r-- | sunrpc/bindrsvprt6.c | 85 | ||||
-rw-r--r-- | sunrpc/clnt_tcp6.c | 533 | ||||
-rw-r--r-- | sunrpc/clnt_udp6.c | 550 | ||||
-rw-r--r-- | sunrpc/rpc/clnt.h | 46 | ||||
-rw-r--r-- | sunrpc/rpc/svc.h | 15 | ||||
-rw-r--r-- | sunrpc/rpc_main.c | 10 | ||||
-rw-r--r-- | sunrpc/svc_tcp6.c | 411 | ||||
-rw-r--r-- | sunrpc/svc_udp6.c | 512 |
10 files changed, 4 insertions, 2164 deletions
diff --git a/sunrpc/Makefile b/sunrpc/Makefile index 9e3ff6c7c2..1ce03d7d98 100644 --- a/sunrpc/Makefile +++ b/sunrpc/Makefile @@ -66,8 +66,7 @@ routines := auth_none auth_unix authuxprot bindrsvprt \ xdr_rec xdr_ref xdr_stdio publickey xdr_sizeof \ auth_des authdes_prot des_crypt des_impl des_soft \ key_call key_prot netname openchild rtime svcauth_des xcrypt\ - clnt_unix svc_unix create_xid xdr_intXX_t \ - svc_tcp6 svc_udp6 bindrsvprt6 + clnt_unix svc_unix create_xid xdr_intXX_t others := rpcinfo install-bin := rpcgen diff --git a/sunrpc/Versions b/sunrpc/Versions index 1f9163da05..1e52b69c37 100644 --- a/sunrpc/Versions +++ b/sunrpc/Versions @@ -109,8 +109,5 @@ libc { } GLIBC_2.2 { svc_getreq_common; svc_getreq_poll; svc_max_pollfd; svc_pollfd; - svcfd6_create; svctcp6_create; svcudp6_create; svcudp6_bufcreate; - svcudp6_enablecache; - bindresvport6; } } diff --git a/sunrpc/bindrsvprt6.c b/sunrpc/bindrsvprt6.c deleted file mode 100644 index 271c9d88a3..0000000000 --- a/sunrpc/bindrsvprt6.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -/* - * Copyright (c) 1987 by Sun Microsystems, Inc. - */ - -#include <errno.h> -#include <unistd.h> -#include <string.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> - -/* - * Bind a socket to a privileged IP port - */ -int -bindresvport6 (int sd, struct sockaddr_in6 *sin) -{ - int res; - static short port; - struct sockaddr_in6 myaddr; - int i; - -#define STARTPORT 600 -#define ENDPORT (IPPORT_RESERVED - 1) -#define NPORTS (ENDPORT - STARTPORT + 1) - - if (sin == (struct sockaddr_in6 *) 0) - { - sin = &myaddr; - __bzero (sin, sizeof (*sin)); - sin->sin6_family = AF_INET6; - } - else if (sin->sin6_family != AF_INET6) - { - __set_errno (EPFNOSUPPORT); - return -1; - } - - if (port == 0) - { - port = (__getpid () % NPORTS) + STARTPORT; - } - res = -1; - __set_errno (EADDRINUSE); - - for (i = 0; i < NPORTS && res < 0 && errno == EADDRINUSE; ++i) - { - sin->sin6_port = htons (port++); - if (port > ENDPORT) - { - port = STARTPORT; - } - res = bind (sd, sin, sizeof (struct sockaddr_in6)); - } - - return res; -} diff --git a/sunrpc/clnt_tcp6.c b/sunrpc/clnt_tcp6.c deleted file mode 100644 index 3e7c4d9f6b..0000000000 --- a/sunrpc/clnt_tcp6.c +++ /dev/null @@ -1,533 +0,0 @@ -/* @(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -#if !defined(lint) && defined(SCCSIDS) -static char sccsid[] = "@(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro"; -#endif - -/* - * clnt_tcp.c, Implements a TCP/IP based, client side RPC. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - * - * TCP based RPC supports 'batched calls'. - * A sequence of calls may be batched-up in a send buffer. The rpc call - * return immediately to the client even though the call was not necessarily - * sent. The batching occurs if the results' xdr routine is NULL (0) AND - * the rpc timeout value is zero (see clnt.h, rpc). - * - * Clients should NOT casually batch calls that in fact return results; that is, - * the server side should be aware that a call is batched and not produce any - * return message. Batched calls that produce many result messages can - * deadlock (netlock) the client and the server.... - * - * Now go hang yourself. - */ - -#include <netdb.h> -#include <errno.h> -#include <stdio.h> -#include <unistd.h> -#include <rpc/rpc.h> -#include <sys/poll.h> -#include <sys/socket.h> -#include <rpc/pmap_clnt.h> - -extern u_long _create_xid (void); - -#define MCALL_MSG_SIZE 24 - -struct ct_data - { - int ct_sock; - bool_t ct_closeit; - struct timeval ct_wait; - bool_t ct_waitset; /* wait set by clnt_control? */ - struct sockaddr_in6 ct_addr; - struct rpc_err ct_error; - char ct_mcall[MCALL_MSG_SIZE]; /* marshalled callmsg */ - u_int ct_mpos; /* pos after marshal */ - XDR ct_xdrs; - }; - -static int readtcp (char *, char *, int); -static int writetcp (char *, char *, int); - -static enum clnt_stat clnttcp6_call (CLIENT *, u_long, xdrproc_t, caddr_t, - xdrproc_t, caddr_t, struct timeval); -static void clnttcp6_abort (void); -static void clnttcp6_geterr (CLIENT *, struct rpc_err *); -static bool_t clnttcp6_freeres (CLIENT *, xdrproc_t, caddr_t); -static bool_t clnttcp6_control (CLIENT *, int, char *); -static void clnttcp6_destroy (CLIENT *); - -static struct clnt_ops tcp6_ops = -{ - clnttcp6_call, - clnttcp6_abort, - clnttcp6_geterr, - clnttcp6_freeres, - clnttcp6_destroy, - clnttcp6_control -}; - -/* - * Create a client handle for a tcp/ip connection. - * If *sockp<0, *sockp is set to a newly created TCP socket and it is - * connected to raddr. If *sockp non-negative then - * raddr is ignored. The rpc/tcp package does buffering - * similar to stdio, so the client must pick send and receive buffer sizes,]; - * 0 => use the default. - * If raddr->sin_port is 0, then a binder on the remote machine is - * consulted for the right port number. - * NB: *sockp is copied into a private area. - * NB: It is the clients responsibility to close *sockp. - * NB: The rpch->cl_auth is set null authentication. Caller may wish to set this - * something more useful. - */ -CLIENT * -clnttcp6_create (struct sockaddr_in6 *raddr, u_long prog, u_long vers, - int *sockp, u_int sendsz, u_int recvsz) -{ - CLIENT *h; - struct ct_data *ct = (struct ct_data *) mem_alloc (sizeof (*ct)); - struct rpc_msg call_msg; - - h = (CLIENT *) mem_alloc (sizeof (*h)); - if (h == NULL) - { - (void) fprintf (stderr, _("clnttcp_create: out of memory\n")); - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = errno; - goto fooy; - } - /* ct = (struct ct_data *) mem_alloc (sizeof (*ct)); */ - if (ct == NULL) - { - (void) fprintf (stderr, _("clnttcp_create: out of memory\n")); - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = errno; - goto fooy; - } - - /* - * If no port number given ask the pmap for one - */ - if (raddr->sin6_port == 0) - { - u_short port; - if ((port = pmap_getport (raddr, prog, vers, IPPROTO_TCP)) == 0) - { - mem_free ((caddr_t) ct, sizeof (struct ct_data)); - mem_free ((caddr_t) h, sizeof (CLIENT)); - return ((CLIENT *) NULL); - } - raddr->sin6_port = htons (port); - } - - /* - * If no socket given, open one - */ - if (*sockp < 0) - { - *sockp = __socket (AF_INET6, SOCK_STREAM, IPPROTO_TCP); - (void) bindresvport6 (*sockp, (struct sockaddr_in6 *) 0); - if ((*sockp < 0) - || (__connect (*sockp, (struct sockaddr *) raddr, - sizeof (*raddr)) < 0)) - { - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = errno; - if (*sockp >= 0) - (void) __close (*sockp); - goto fooy; - } - ct->ct_closeit = TRUE; - } - else - { - ct->ct_closeit = FALSE; - } - - /* - * Set up private data struct - */ - ct->ct_sock = *sockp; - ct->ct_wait.tv_usec = 0; - ct->ct_waitset = FALSE; - ct->ct_addr = *raddr; - - /* - * Initialize call message - */ - call_msg.rm_xid = _create_xid (); - call_msg.rm_direction = CALL; - call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; - call_msg.rm_call.cb_prog = prog; - call_msg.rm_call.cb_vers = vers; - - /* - * pre-serialize the static part of the call msg and stash it away - */ - xdrmem_create (&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE, - XDR_ENCODE); - if (!xdr_callhdr (&(ct->ct_xdrs), &call_msg)) - { - if (ct->ct_closeit) - { - (void) __close (*sockp); - } - goto fooy; - } - ct->ct_mpos = XDR_GETPOS (&(ct->ct_xdrs)); - XDR_DESTROY (&(ct->ct_xdrs)); - - /* - * Create a client handle which uses xdrrec for serialization - * and authnone for authentication. - */ - xdrrec_create (&(ct->ct_xdrs), sendsz, recvsz, - (caddr_t) ct, readtcp, writetcp); - h->cl_ops = &tcp6_ops; - h->cl_private = (caddr_t) ct; - h->cl_auth = authnone_create (); - return h; - -fooy: - /* - * Something goofed, free stuff and barf - */ - mem_free ((caddr_t) ct, sizeof (struct ct_data)); - mem_free ((caddr_t) h, sizeof (CLIENT)); - return ((CLIENT *) NULL); -} - -static enum clnt_stat -clnttcp6_call (h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout) - CLIENT *h; - u_long proc; - xdrproc_t xdr_args; - caddr_t args_ptr; - xdrproc_t xdr_results; - caddr_t results_ptr; - struct timeval timeout; -{ - struct ct_data *ct = (struct ct_data *) h->cl_private; - XDR *xdrs = &(ct->ct_xdrs); - struct rpc_msg reply_msg; - u_long x_id; - u_int32_t *msg_x_id = (u_int32_t *) (ct->ct_mcall); /* yuk */ - bool_t shipnow; - int refreshes = 2; - - if (!ct->ct_waitset) - { - ct->ct_wait = timeout; - } - - shipnow = - (xdr_results == (xdrproc_t) 0 && timeout.tv_sec == 0 - && timeout.tv_usec == 0) ? FALSE : TRUE; - -call_again: - xdrs->x_op = XDR_ENCODE; - ct->ct_error.re_status = RPC_SUCCESS; - x_id = ntohl (--(*msg_x_id)); - if ((!XDR_PUTBYTES (xdrs, ct->ct_mcall, ct->ct_mpos)) || - (!XDR_PUTLONG (xdrs, (long *) &proc)) || - (!AUTH_MARSHALL (h->cl_auth, xdrs)) || - (!(*xdr_args) (xdrs, args_ptr))) - { - if (ct->ct_error.re_status == RPC_SUCCESS) - ct->ct_error.re_status = RPC_CANTENCODEARGS; - (void) xdrrec_endofrecord (xdrs, TRUE); - return (ct->ct_error.re_status); - } - if (!xdrrec_endofrecord (xdrs, shipnow)) - return ct->ct_error.re_status = RPC_CANTSEND; - if (!shipnow) - return RPC_SUCCESS; - /* - * Hack to provide rpc-based message passing - */ - if (timeout.tv_sec == 0 && timeout.tv_usec == 0) - { - return ct->ct_error.re_status = RPC_TIMEDOUT; - } - - - /* - * Keep receiving until we get a valid transaction id - */ - xdrs->x_op = XDR_DECODE; - while (TRUE) - { - reply_msg.acpted_rply.ar_verf = _null_auth; - reply_msg.acpted_rply.ar_results.where = NULL; - reply_msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void; - if (!xdrrec_skiprecord (xdrs)) - return (ct->ct_error.re_status); - /* now decode and validate the response header */ - if (!xdr_replymsg (xdrs, &reply_msg)) - { - if (ct->ct_error.re_status == RPC_SUCCESS) - continue; - return ct->ct_error.re_status; - } - if ((u_int32_t) reply_msg.rm_xid == (u_int32_t) x_id) - break; - } - - /* - * process header - */ - _seterr_reply (&reply_msg, &(ct->ct_error)); - if (ct->ct_error.re_status == RPC_SUCCESS) - { - if (!AUTH_VALIDATE (h->cl_auth, &reply_msg.acpted_rply.ar_verf)) - { - ct->ct_error.re_status = RPC_AUTHERROR; - ct->ct_error.re_why = AUTH_INVALIDRESP; - } - else if (!(*xdr_results) (xdrs, results_ptr)) - { - if (ct->ct_error.re_status == RPC_SUCCESS) - ct->ct_error.re_status = RPC_CANTDECODERES; - } - /* free verifier ... */ - if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) - { - xdrs->x_op = XDR_FREE; - (void) xdr_opaque_auth (xdrs, &(reply_msg.acpted_rply.ar_verf)); - } - } /* end successful completion */ - else - { - /* maybe our credentials need to be refreshed ... */ - if (refreshes-- && AUTH_REFRESH (h->cl_auth)) - goto call_again; - } /* end of unsuccessful completion */ - return ct->ct_error.re_status; -} - -static void -clnttcp6_geterr (h, errp) - CLIENT *h; - struct rpc_err *errp; -{ - struct ct_data *ct = - (struct ct_data *) h->cl_private; - - *errp = ct->ct_error; -} - -static bool_t -clnttcp6_freeres (cl, xdr_res, res_ptr) - CLIENT *cl; - xdrproc_t xdr_res; - caddr_t res_ptr; -{ - struct ct_data *ct = (struct ct_data *) cl->cl_private; - XDR *xdrs = &(ct->ct_xdrs); - - xdrs->x_op = XDR_FREE; - return (*xdr_res) (xdrs, res_ptr); -} - -static void -clnttcp6_abort () -{ -} - -static bool_t -clnttcp6_control (CLIENT *cl, int request, char *info) -{ - struct ct_data *ct = (struct ct_data *) cl->cl_private; - - - switch (request) - { - case CLSET_FD_CLOSE: - ct->ct_closeit = TRUE; - break; - case CLSET_FD_NCLOSE: - ct->ct_closeit = FALSE; - break; - case CLSET_TIMEOUT: - ct->ct_wait = *(struct timeval *) info; - ct->ct_waitset = TRUE; - break; - case CLGET_TIMEOUT: - *(struct timeval *) info = ct->ct_wait; - break; - case CLGET_SERVER_ADDR: - *(struct sockaddr_in6 *) info = ct->ct_addr; - break; - case CLGET_FD: - *(int *)info = ct->ct_sock; - break; - case CLGET_XID: - /* - * use the knowledge that xid is the - * first element in the call structure *. - * This will get the xid of the PREVIOUS call - */ - *(u_long *)info = ntohl (*(u_long *)ct->ct_mcall); - break; - case CLSET_XID: - /* This will set the xid of the NEXT call */ - *(u_long *)ct->ct_mcall = htonl (*(u_long *)info - 1); - /* decrement by 1 as clnttcp_call() increments once */ - case CLGET_VERS: - /* - * This RELIES on the information that, in the call body, - * the version number field is the fifth field from the - * begining of the RPC header. MUST be changed if the - * call_struct is changed - */ - *(u_long *)info = ntohl (*(u_long *)(ct->ct_mcall + - 4 * BYTES_PER_XDR_UNIT)); - break; - case CLSET_VERS: - *(u_long *)(ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT) - = htonl (*(u_long *)info); - break; - case CLGET_PROG: - /* - * This RELIES on the information that, in the call body, - * the program number field is the field from the - * begining of the RPC header. MUST be changed if the - * call_struct is changed - */ - *(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall + - 3 * BYTES_PER_XDR_UNIT)); - break; - case CLSET_PROG: - *(u_long *)(ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT) - = htonl(*(u_long *)info); - break; - /* The following are only possible with TI-RPC */ - case CLGET_RETRY_TIMEOUT: - case CLSET_RETRY_TIMEOUT: - case CLGET_SVC_ADDR: - case CLSET_SVC_ADDR: - case CLSET_PUSH_TIMOD: - case CLSET_POP_TIMOD: - default: - return FALSE; - } - return TRUE; -} - - -static void -clnttcp6_destroy (CLIENT *h) -{ - struct ct_data *ct = - (struct ct_data *) h->cl_private; - - if (ct->ct_closeit) - { - (void) __close (ct->ct_sock); - } - XDR_DESTROY (&(ct->ct_xdrs)); - mem_free ((caddr_t) ct, sizeof (struct ct_data)); - mem_free ((caddr_t) h, sizeof (CLIENT)); -} - -/* - * Interface between xdr serializer and tcp connection. - * Behaves like the system calls, read & write, but keeps some error state - * around for the rpc level. - */ -static int -readtcp (char *ctptr, char *buf, int len) -{ - struct ct_data *ct = (struct ct_data *)ctptr; - struct pollfd fd; - int milliseconds = (ct->ct_wait.tv_sec * 1000) + - (ct->ct_wait.tv_usec / 1000); - - if (len == 0) - return 0; - - fd.fd = ct->ct_sock; - fd.events = POLLIN; - while (TRUE) - { - switch (__poll(&fd, 1, milliseconds)) - { - case 0: - ct->ct_error.re_status = RPC_TIMEDOUT; - return -1; - - case -1: - if (errno == EINTR) - continue; - ct->ct_error.re_status = RPC_CANTRECV; - ct->ct_error.re_errno = errno; - return -1; - } - break; - } - switch (len = __read (ct->ct_sock, buf, len)) - { - - case 0: - /* premature eof */ - ct->ct_error.re_errno = ECONNRESET; - ct->ct_error.re_status = RPC_CANTRECV; - len = -1; /* it's really an error */ - break; - - case -1: - ct->ct_error.re_errno = errno; - ct->ct_error.re_status = RPC_CANTRECV; - break; - } - return len; -} - -static int -writetcp (char *ctptr, char *buf, int len) -{ - int i, cnt; - struct ct_data *ct = (struct ct_data*)ctptr; - - for (cnt = len; cnt > 0; cnt -= i, buf += i) - { - if ((i = __write (ct->ct_sock, buf, cnt)) == -1) - { - ct->ct_error.re_errno = errno; - ct->ct_error.re_status = RPC_CANTSEND; - return -1; - } - } - return len; -} diff --git a/sunrpc/clnt_udp6.c b/sunrpc/clnt_udp6.c deleted file mode 100644 index f38a8586a4..0000000000 --- a/sunrpc/clnt_udp6.c +++ /dev/null @@ -1,550 +0,0 @@ -/* @(#)clnt_udp.c 2.2 88/08/01 4.0 RPCSRC */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -#if !defined(lint) && defined(SCCSIDS) -static char sccsid[] = "@(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro"; -#endif - -/* - * clnt_udp.c, Implements a UDP/IP based, client side RPC. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - -#include <stdio.h> -#include <unistd.h> -#include <rpc/rpc.h> -#include <rpc/xdr.h> -#include <rpc/clnt.h> -#include <sys/poll.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <netdb.h> -#include <errno.h> -#include <rpc/pmap_clnt.h> -#include <net/if.h> - -extern bool_t xdr_opaque_auth (XDR *, struct opaque_auth *); -extern u_long _create_xid (void); - -/* - * UDP bases client side rpc operations - */ -static enum clnt_stat clntudp6_call (CLIENT *, u_long, xdrproc_t, caddr_t, - xdrproc_t, caddr_t, struct timeval); -static void clntudp6_abort (void); -static void clntudp6_geterr (CLIENT *, struct rpc_err *); -static bool_t clntudp6_freeres (CLIENT *, xdrproc_t, caddr_t); -static bool_t clntudp6_control (CLIENT *, int, char *); -static void clntudp6_destroy (CLIENT *); - -static struct clnt_ops udp6_ops = -{ - clntudp6_call, - clntudp6_abort, - clntudp6_geterr, - clntudp6_freeres, - clntudp6_destroy, - clntudp6_control -}; - -/* - * Private data kept per client handle - */ -struct cu_data - { - int cu_sock; - bool_t cu_closeit; - struct sockaddr_in cu_raddr; - int cu_rlen; - struct timeval cu_wait; - struct timeval cu_total; - struct rpc_err cu_error; - XDR cu_outxdrs; - u_int cu_xdrpos; - u_int cu_sendsz; - char *cu_outbuf; - u_int cu_recvsz; - char cu_inbuf[1]; - }; - -/* - * Create a UDP based client handle. - * If *sockp<0, *sockp is set to a newly created UPD socket. - * If raddr->sin_port is 0 a binder on the remote machine - * is consulted for the correct port number. - * NB: It is the clients responsibility to close *sockp. - * NB: The rpch->cl_auth is initialized to null authentication. - * Caller may wish to set this something more useful. - * - * wait is the amount of time used between retransmitting a call if - * no response has been heard; retransmission occurs until the actual - * rpc call times out. - * - * sendsz and recvsz are the maximum allowable packet sizes that can be - * sent and received. - */ -CLIENT * -clntudp6_bufcreate (struct sockaddr_in6 *raddr, u_long program, u_long version, - struct timeval wait, int *sockp, u_int sendsz, - u_int recvsz) -{ - CLIENT *cl; - struct cu_data *cu = NULL; - struct rpc_msg call_msg; - - cl = (CLIENT *) mem_alloc (sizeof (CLIENT)); - if (cl == NULL) - { - (void) fprintf (stderr, _("clntudp_create: out of memory\n")); - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = errno; - goto fooy; - } - sendsz = ((sendsz + 3) / 4) * 4; - recvsz = ((recvsz + 3) / 4) * 4; - cu = (struct cu_data *) mem_alloc (sizeof (*cu) + sendsz + recvsz); - if (cu == NULL) - { - (void) fprintf (stderr, _("clntudp_create: out of memory\n")); - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = errno; - goto fooy; - } - cu->cu_outbuf = &cu->cu_inbuf[recvsz]; - - if (raddr->sin6_port == 0) - { - u_short port; - if ((port = - pmap_getport (raddr, program, version, IPPROTO_UDP)) == 0) - { - goto fooy; - } - raddr->sin6_port = htons (port); - } - cl->cl_ops = &udp6_ops; - cl->cl_private = (caddr_t) cu; - cu->cu_raddr = *raddr; - cu->cu_rlen = sizeof (cu->cu_raddr); - cu->cu_wait = wait; - cu->cu_total.tv_sec = -1; - cu->cu_total.tv_usec = -1; - cu->cu_sendsz = sendsz; - cu->cu_recvsz = recvsz; - call_msg.rm_xid = _create_xid (); - call_msg.rm_direction = CALL; - call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; - call_msg.rm_call.cb_prog = program; - call_msg.rm_call.cb_vers = version; - xdrmem_create (&(cu->cu_outxdrs), cu->cu_outbuf, - sendsz, XDR_ENCODE); - if (!xdr_callhdr (&(cu->cu_outxdrs), &call_msg)) - { - goto fooy; - } - cu->cu_xdrpos = XDR_GETPOS (&(cu->cu_outxdrs)); - if (*sockp < 0) - { - int dontblock = 1; - - *sockp = __socket (AF_INET6, SOCK_DGRAM, IPPROTO_UDP); - if (*sockp < 0) - { - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = errno; - goto fooy; - } - /* attempt to bind to prov port */ - (void) bindresvport6 (*sockp, (struct sockaddr_in6 *) 0); - /* the sockets rpc controls are non-blocking */ - (void) __ioctl (*sockp, FIONBIO, (char *) &dontblock); - cu->cu_closeit = TRUE; - } - else - { - cu->cu_closeit = FALSE; - } - cu->cu_sock = *sockp; - cl->cl_auth = authnone_create (); - return cl; -fooy: - if (cu) - mem_free ((caddr_t) cu, sizeof (*cu) + sendsz + recvsz); - if (cl) - mem_free ((caddr_t) cl, sizeof (CLIENT)); - return (CLIENT *) NULL; -} - -CLIENT * -clntudp6_create (raddr, program, version, wait, sockp) - struct sockaddr_in *raddr; - u_long program; - u_long version; - struct timeval wait; - int *sockp; -{ - - return clntudp6_bufcreate (raddr, program, version, wait, sockp, - UDPMSGSIZE, UDPMSGSIZE); -} - -static int -is_network_up (int sock) -{ - struct ifconf ifc; - char buf[UDPMSGSIZE]; - struct ifreq ifreq, *ifr; - int n; - - ifc.ifc_len = sizeof (buf); - ifc.ifc_buf = buf; - if (__ioctl(sock, SIOCGIFCONF, (char *) &ifc) == 0) - { - ifr = ifc.ifc_req; - for (n = ifc.ifc_len / sizeof (struct ifreq); n > 0; n--, ifr++) - { - ifreq = *ifr; - if (__ioctl (sock, SIOCGIFFLAGS, (char *) &ifreq) < 0) - break; - - if ((ifreq.ifr_flags & IFF_UP) - && ifr->ifr_addr.sa_family == AF_INET) - return 1; - } - } - return 0; -} - -static enum clnt_stat -clntudp6_call (cl, proc, xargs, argsp, xresults, resultsp, utimeout) - CLIENT *cl; /* client handle */ - u_long proc; /* procedure number */ - xdrproc_t xargs; /* xdr routine for args */ - caddr_t argsp; /* pointer to args */ - xdrproc_t xresults; /* xdr routine for results */ - caddr_t resultsp; /* pointer to results */ - struct timeval utimeout; /* seconds to wait before giving up */ -{ - struct cu_data *cu = (struct cu_data *) cl->cl_private; - XDR *xdrs; - int outlen = 0; - int inlen; - socklen_t fromlen; - struct pollfd fd; - int milliseconds = (cu->cu_wait.tv_sec * 1000) + - (cu->cu_wait.tv_usec / 1000); - struct sockaddr_in from; - struct rpc_msg reply_msg; - XDR reply_xdrs; - struct timeval time_waited; - bool_t ok; - int nrefreshes = 2; /* number of times to refresh cred */ - struct timeval timeout; - int anyup; /* any network interface up */ - - if (cu->cu_total.tv_usec == -1) - { - timeout = utimeout; /* use supplied timeout */ - } - else - { - timeout = cu->cu_total; /* use default timeout */ - } - - time_waited.tv_sec = 0; - time_waited.tv_usec = 0; -call_again: - xdrs = &(cu->cu_outxdrs); - if (xargs == NULL) - goto get_reply; - xdrs->x_op = XDR_ENCODE; - XDR_SETPOS (xdrs, cu->cu_xdrpos); - /* - * the transaction is the first thing in the out buffer - */ - (*(u_short *) (cu->cu_outbuf))++; - if ((!XDR_PUTLONG (xdrs, (long *) &proc)) || - (!AUTH_MARSHALL (cl->cl_auth, xdrs)) || - (!(*xargs) (xdrs, argsp))) - return (cu->cu_error.re_status = RPC_CANTENCODEARGS); - outlen = (int) XDR_GETPOS (xdrs); - -send_again: - if (sendto (cu->cu_sock, cu->cu_outbuf, outlen, 0, - (struct sockaddr *) &(cu->cu_raddr), cu->cu_rlen) - != outlen) - { - cu->cu_error.re_errno = errno; - return (cu->cu_error.re_status = RPC_CANTSEND); - } - - /* - * Hack to provide rpc-based message passing - */ - if (timeout.tv_sec == 0 && timeout.tv_usec == 0) - { - return (cu->cu_error.re_status = RPC_TIMEDOUT); - } - get_reply: - /* - * sub-optimal code appears here because we have - * some clock time to spare while the packets are in flight. - * (We assume that this is actually only executed once.) - */ - reply_msg.acpted_rply.ar_verf = _null_auth; - reply_msg.acpted_rply.ar_results.where = resultsp; - reply_msg.acpted_rply.ar_results.proc = xresults; - fd.fd = cu->cu_sock; - fd.events = POLLIN; - anyup = 0; - for (;;) - { - switch (__poll (&fd, 1, milliseconds)) - { - - case 0: - if (anyup == 0) - { - anyup = is_network_up (cu->cu_sock); - if (!anyup) - return (cu->cu_error.re_status = RPC_CANTRECV); - } - - time_waited.tv_sec += cu->cu_wait.tv_sec; - time_waited.tv_usec += cu->cu_wait.tv_usec; - while (time_waited.tv_usec >= 1000000) - { - time_waited.tv_sec++; - time_waited.tv_usec -= 1000000; - } - if ((time_waited.tv_sec < timeout.tv_sec) || - ((time_waited.tv_sec == timeout.tv_sec) && - (time_waited.tv_usec < timeout.tv_usec))) - goto send_again; - return (cu->cu_error.re_status = RPC_TIMEDOUT); - - /* - * buggy in other cases because time_waited is not being - * updated. - */ - case -1: - if (errno == EINTR) - continue; - cu->cu_error.re_errno = errno; - return (cu->cu_error.re_status = RPC_CANTRECV); - } - do - { - fromlen = sizeof (struct sockaddr); - inlen = recvfrom (cu->cu_sock, cu->cu_inbuf, - (int) cu->cu_recvsz, 0, - (struct sockaddr *) &from, &fromlen); - } - while (inlen < 0 && errno == EINTR); - if (inlen < 0) - { - if (errno == EWOULDBLOCK) - continue; - cu->cu_error.re_errno = errno; - return (cu->cu_error.re_status = RPC_CANTRECV); - } - if (inlen < 4) - continue; - - /* see if reply transaction id matches sent id. - Don't do this if we only wait for a replay */ - if (xargs != NULL - && (*((u_int32_t *) (cu->cu_inbuf)) - != *((u_int32_t *) (cu->cu_outbuf)))) - continue; - /* we now assume we have the proper reply */ - break; - } - - /* - * now decode and validate the response - */ - xdrmem_create (&reply_xdrs, cu->cu_inbuf, (u_int) inlen, XDR_DECODE); - ok = xdr_replymsg (&reply_xdrs, &reply_msg); - /* XDR_DESTROY(&reply_xdrs); save a few cycles on noop destroy */ - if (ok) - { - _seterr_reply (&reply_msg, &(cu->cu_error)); - if (cu->cu_error.re_status == RPC_SUCCESS) - { - if (!AUTH_VALIDATE (cl->cl_auth, - &reply_msg.acpted_rply.ar_verf)) - { - cu->cu_error.re_status = RPC_AUTHERROR; - cu->cu_error.re_why = AUTH_INVALIDRESP; - } - if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) - { - xdrs->x_op = XDR_FREE; - (void) xdr_opaque_auth (xdrs, - &(reply_msg.acpted_rply.ar_verf)); - } - } /* end successful completion */ - else - { - /* maybe our credentials need to be refreshed ... */ - if (nrefreshes > 0 && AUTH_REFRESH (cl->cl_auth)) - { - nrefreshes--; - goto call_again; - } - } /* end of unsuccessful completion */ - } /* end of valid reply message */ - else - { - cu->cu_error.re_status = RPC_CANTDECODERES; - } - return cu->cu_error.re_status; -} - -static void -clntudp6_geterr (CLIENT *cl, struct rpc_err *errp) -{ - struct cu_data *cu = (struct cu_data *) cl->cl_private; - - *errp = cu->cu_error; -} - - -static bool_t -clntudp6_freeres (CLIENT *cl, xdrproc_t xdr_res, caddr_t res_ptr) -{ - struct cu_data *cu = (struct cu_data *) cl->cl_private; - XDR *xdrs = &(cu->cu_outxdrs); - - xdrs->x_op = XDR_FREE; - return (*xdr_res) (xdrs, res_ptr); -} - -static void -clntudp6_abort (void) -{ -} - -static bool_t -clntudp6_control (CLIENT *cl, int request, char *info) -{ - struct cu_data *cu = (struct cu_data *) cl->cl_private; - - switch (request) - { - case CLSET_FD_CLOSE: - cu->cu_closeit = TRUE; - break; - case CLSET_FD_NCLOSE: - cu->cu_closeit = FALSE; - break; - case CLSET_TIMEOUT: - cu->cu_total = *(struct timeval *) info; - break; - case CLGET_TIMEOUT: - *(struct timeval *) info = cu->cu_total; - break; - case CLSET_RETRY_TIMEOUT: - cu->cu_wait = *(struct timeval *) info; - break; - case CLGET_RETRY_TIMEOUT: - *(struct timeval *) info = cu->cu_wait; - break; - case CLGET_SERVER_ADDR: - *(struct sockaddr_in *) info = cu->cu_raddr; - break; - case CLGET_FD: - *(int *)info = cu->cu_sock; - break; - case CLGET_XID: - /* - * use the knowledge that xid is the - * first element in the call structure *. - * This will get the xid of the PREVIOUS call - */ - *(u_long *)info = ntohl(*(u_long *)cu->cu_outbuf); - break; - case CLSET_XID: - /* This will set the xid of the NEXT call */ - *(u_long *)cu->cu_outbuf = htonl(*(u_long *)info - 1); - /* decrement by 1 as clntudp_call() increments once */ - case CLGET_VERS: - /* - * This RELIES on the information that, in the call body, - * the version number field is the fifth field from the - * begining of the RPC header. MUST be changed if the - * call_struct is changed - */ - *(u_long *)info = ntohl(*(u_long *)(cu->cu_outbuf + - 4 * BYTES_PER_XDR_UNIT)); - break; - case CLSET_VERS: - *(u_long *)(cu->cu_outbuf + 4 * BYTES_PER_XDR_UNIT) - = htonl(*(u_long *)info); - break; - case CLGET_PROG: - /* - * This RELIES on the information that, in the call body, - * the program number field is the field from the - * begining of the RPC header. MUST be changed if the - * call_struct is changed - */ - *(u_long *)info = ntohl(*(u_long *)(cu->cu_outbuf + - 3 * BYTES_PER_XDR_UNIT)); - break; - case CLSET_PROG: - *(u_long *)(cu->cu_outbuf + 3 * BYTES_PER_XDR_UNIT) - = htonl(*(u_long *)info); - break; - /* The following are only possible with TI-RPC */ - case CLGET_SVC_ADDR: - case CLSET_SVC_ADDR: - case CLSET_PUSH_TIMOD: - case CLSET_POP_TIMOD: - default: - return FALSE; - } - return TRUE; -} - -static void -clntudp6_destroy (CLIENT *cl) -{ - struct cu_data *cu = (struct cu_data *) cl->cl_private; - - if (cu->cu_closeit) - { - (void) __close (cu->cu_sock); - } - XDR_DESTROY (&(cu->cu_outxdrs)); - mem_free ((caddr_t) cu, (sizeof (*cu) + cu->cu_sendsz + cu->cu_recvsz)); - mem_free ((caddr_t) cl, sizeof (CLIENT)); -} diff --git a/sunrpc/rpc/clnt.h b/sunrpc/rpc/clnt.h index 39519a8e38..a19fc773bc 100644 --- a/sunrpc/rpc/clnt.h +++ b/sunrpc/rpc/clnt.h @@ -341,52 +341,6 @@ extern CLIENT *clntudp_bufcreate (struct sockaddr_in *__raddr, u_int __sendsz, u_int __recvsz) __THROW; -/* - * TCP/IPv6 based rpc - * CLIENT * - * clnttcp6_create(raddr, prog, vers, sockp, sendsz, recvsz) - * struct sockaddr_in6 *raddr; - * u_long prog; - * u_long version; - * register int *sockp; - * u_int sendsz; - * u_int recvsz; - */ -extern CLIENT *clnttcp6_create __P ((struct sockaddr_in6 *__raddr, - u_long __prog, u_long __version, - int *__sockp, u_int __sendsz, - u_int __recvsz)); - -/* - * UDP/IPv6 based rpc. - * CLIENT * - * clntudp6_create(raddr, program, version, wait, sockp) - * struct sockaddr_in6 *raddr; - * u_long program; - * u_long version; - * struct timeval wait_resend; - * int *sockp; - * - * Same as above, but you specify max packet sizes. - * CLIENT * - * clntudp6_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz) - * struct sockaddr_in6 *raddr; - * u_long program; - * u_long version; - * struct timeval wait_resend; - * int *sockp; - * u_int sendsz; - * u_int recvsz; - */ -extern CLIENT *clntudp6_create __P ((struct sockaddr_in6 *__raddr, - u_long __program, u_long __version, - struct timeval __wait_resend, - int *__sockp)); -extern CLIENT *clntudp6_bufcreate __P ((struct sockaddr_in6 *__raddr, - u_long __program, u_long __version, - struct timeval __wait_resend, - int *__sockp, u_int __sendsz, - u_int __recvsz)); /* diff --git a/sunrpc/rpc/svc.h b/sunrpc/rpc/svc.h index cf23129b86..3ffca50bd0 100644 --- a/sunrpc/rpc/svc.h +++ b/sunrpc/rpc/svc.h @@ -92,7 +92,7 @@ struct SVCXPRT { /* destroy this struct */ } *xp_ops; int xp_addrlen; /* length of remote address */ - struct sockaddr_storage xp_raddr; /* remote address */ + struct sockaddr_in xp_raddr; /* remote address */ struct opaque_auth xp_verf; /* raw response verifier */ caddr_t xp_p1; /* private */ caddr_t xp_p2; /* private */ @@ -305,19 +305,6 @@ extern SVCXPRT *svctcp_create (int __sock, u_int __sendsize, u_int __recvsize) /* - * IPv6/Udp based rpc. - */ -extern SVCXPRT *svcudp6_create (int __sock) __THROW; -extern SVCXPRT *svcudp6_bufcreate (int __sock, u_int __sendsz, - u_int __recvsz) __THROW; - -/* - * IPv6/Tcp based rpc. - */ -extern SVCXPRT *svctcp6_create (int __sock, u_int __sendsize, - u_int __recvsize) __THROW; - -/* * Unix based rpc. */ extern SVCXPRT *svcunix_create (int __sock, u_int __sendsize, u_int __recvsize, diff --git a/sunrpc/rpc_main.c b/sunrpc/rpc_main.c index ba25455be4..b780bdbc7d 100644 --- a/sunrpc/rpc_main.c +++ b/sunrpc/rpc_main.c @@ -87,7 +87,7 @@ static char *pathbuf; static int cpp_pid; static const char *allv[] = { - "rpcgen", "-s", "udp", "-s", "tcp", "-s", "udp6", "-s", "tcp6" + "rpcgen", "-s", "udp", "-s", "tcp" }; static int allc = sizeof (allv) / sizeof (allv[0]); static const char *allnv[] = @@ -437,8 +437,6 @@ static const char *valid_ti_nettypes[] = "udp", "tcp", "raw", - "udp6", - "tcp6", NULL }; @@ -447,8 +445,6 @@ static const char *valid_i_nettypes[] = { "udp", "tcp", - "udp6", - "tcp6", NULL }; @@ -1306,9 +1302,7 @@ parseargs (int argc, const char *argv[], struct commandline *cmd) if (c == 's') { if (!streq (argv[i], "udp") && - !streq (argv[i], "tcp") && - !streq (argv[i], "udp6") && - !streq (argv[i], "tcp6")) + !streq (argv[i], "tcp")) return 0; } else if (c == 'o') diff --git a/sunrpc/svc_tcp6.c b/sunrpc/svc_tcp6.c deleted file mode 100644 index bf11540ee0..0000000000 --- a/sunrpc/svc_tcp6.c +++ /dev/null @@ -1,411 +0,0 @@ -/* @(#)svc_tcp.c 2.2 88/08/01 4.0 RPCSRC */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -#if !defined(lint) && defined(SCCSIDS) -static char sccsid[] = "@(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro"; -#endif - -/* - * svc_tcp.c, Server side for TCP/IP based RPC. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - * - * Actually implements two flavors of transporter - - * a tcp rendezvouser (a listener and connection establisher) - * and a record/tcp stream. - */ - -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <libintl.h> -#include <rpc/rpc.h> -#include <sys/socket.h> -#include <sys/poll.h> -#include <errno.h> -#include <stdlib.h> - -#ifdef USE_IN_LIBIO -# include <libio/iolibio.h> -# define fputs(s, f) _IO_fputs (s, f) -#endif - -/* - * Ops vector for TCP/IP based rpc service handle - */ -static bool_t svctcp6_recv (SVCXPRT *, struct rpc_msg *); -static enum xprt_stat svctcp6_stat (SVCXPRT *); -static bool_t svctcp6_getargs (SVCXPRT *, xdrproc_t, caddr_t); -static bool_t svctcp6_reply (SVCXPRT *, struct rpc_msg *); -static bool_t svctcp6_freeargs (SVCXPRT *, xdrproc_t, caddr_t); -static void svctcp6_destroy (SVCXPRT *); - -static const struct xp_ops svctcp6_op = -{ - svctcp6_recv, - svctcp6_stat, - svctcp6_getargs, - svctcp6_reply, - svctcp6_freeargs, - svctcp6_destroy -}; - -/* - * Ops vector for TCP/IP rendezvous handler - */ -static bool_t rendezvous_request (SVCXPRT *, struct rpc_msg *); -static enum xprt_stat rendezvous_stat (SVCXPRT *); - -static const struct xp_ops svctcp6_rendezvous_op = -{ - rendezvous_request, - rendezvous_stat, - (bool_t (*) (SVCXPRT *, xdrproc_t, caddr_t)) abort, - (bool_t (*) (SVCXPRT *, struct rpc_msg *)) abort, - (bool_t (*) (SVCXPRT *, xdrproc_t, caddr_t)) abort, - svctcp6_destroy -}; - -static int readtcp (char*, char *, int); -static int writetcp (char *, char *, int); -static SVCXPRT *makefd6_xprt (int, u_int, u_int) internal_function; - -struct tcp_rendezvous - { /* kept in xprt->xp_p1 */ - u_int sendsize; - u_int recvsize; - }; - -struct tcp_conn - { /* kept in xprt->xp_p1 */ - enum xprt_stat strm_stat; - u_long x_id; - XDR xdrs; - char verf_body[MAX_AUTH_BYTES]; - }; - -/* - * Usage: - * xprt = svctcp_create(sock, send_buf_size, recv_buf_size); - * - * Creates, registers, and returns a (rpc) tcp based transporter. - * Once *xprt is initialized, it is registered as a transporter - * see (svc.h, xprt_register). This routine returns - * a NULL if a problem occurred. - * - * If sock<0 then a socket is created, else sock is used. - * If the socket, sock is not bound to a port then svctcp_create - * binds it to an arbitrary port. The routine then starts a tcp - * listener on the socket's associated port. In any (successful) case, - * xprt->xp_sock is the registered socket number and xprt->xp_port is the - * associated port number. - * - * Since tcp streams do buffered io similar to stdio, the caller can specify - * how big the send and receive buffers are via the second and third parms; - * 0 => use the system default. - */ -SVCXPRT * -svctcp6_create (int sock, u_int sendsize, u_int recvsize) -{ - bool_t madesock = FALSE; - SVCXPRT *xprt; - struct tcp_rendezvous *r; - struct sockaddr_in6 addr; - socklen_t len = sizeof (struct sockaddr_in6); - - if (sock == RPC_ANYSOCK) - { - if ((sock = __socket (AF_INET6, SOCK_STREAM, IPPROTO_TCP)) < 0) - { - perror (_("svc_tcp.c - tcp socket creation problem")); - return (SVCXPRT *) NULL; - } - madesock = TRUE; - } - __bzero ((char *) &addr, sizeof (addr)); - addr.sin6_family = AF_INET6; - if (bindresvport6 (sock, &addr)) - { - addr.sin6_port = 0; - (void) bind (sock, (struct sockaddr *) &addr, len); - } - if ((getsockname (sock, (struct sockaddr *) &addr, &len) != 0) || - (listen (sock, 2) != 0)) - { - perror (_("svc_tcp.c - cannot getsockname or listen")); - if (madesock) - (void) __close (sock); - return (SVCXPRT *) NULL; - } - r = (struct tcp_rendezvous *) mem_alloc (sizeof (*r)); - if (r == NULL) - { - (void) fputs (_("svctcp_create: out of memory\n"), stderr); - return NULL; - } - r->sendsize = sendsize; - r->recvsize = recvsize; - xprt = (SVCXPRT *) mem_alloc (sizeof (SVCXPRT)); - if (xprt == NULL) - { - (void) fputs (_("svctcp_create: out of memory\n"), stderr); - return NULL; - } - xprt->xp_p2 = NULL; - xprt->xp_p1 = (caddr_t) r; - xprt->xp_verf = _null_auth; - xprt->xp_ops = &svctcp6_rendezvous_op; - xprt->xp_port = ntohs (addr.sin6_port); - xprt->xp_sock = sock; - xprt_register (xprt); - return xprt; -} - -/* - * Like svtcp_create(), except the routine takes any *open* UNIX file - * descriptor as its first input. - */ -SVCXPRT * -svcfd6_create (int fd, u_int sendsize, u_int recvsize) -{ - return makefd6_xprt (fd, sendsize, recvsize); -} - -static SVCXPRT * -internal_function -makefd6_xprt (int fd, u_int sendsize, u_int recvsize) -{ - SVCXPRT *xprt; - struct tcp_conn *cd; - - xprt = (SVCXPRT *) mem_alloc (sizeof (SVCXPRT)); - if (xprt == (SVCXPRT *) NULL) - { - (void) fputs (_("svc_tcp: makefd_xprt: out of memory\n"), stderr); - goto done; - } - cd = (struct tcp_conn *) mem_alloc (sizeof (struct tcp_conn)); - if (cd == (struct tcp_conn *) NULL) - { - (void) fputs (_("svc_tcp: makefd_xprt: out of memory\n"), stderr); - mem_free ((char *) xprt, sizeof (SVCXPRT)); - xprt = (SVCXPRT *) NULL; - goto done; - } - cd->strm_stat = XPRT_IDLE; - xdrrec_create (&(cd->xdrs), sendsize, recvsize, - (caddr_t) xprt, readtcp, writetcp); - xprt->xp_p2 = NULL; - xprt->xp_p1 = (caddr_t) cd; - xprt->xp_verf.oa_base = cd->verf_body; - xprt->xp_addrlen = 0; - xprt->xp_ops = &svctcp6_op; /* truly deals with calls */ - xprt->xp_port = 0; /* this is a connection, not a rendezvouser */ - xprt->xp_sock = fd; - xprt_register (xprt); -done: - return xprt; -} - -static bool_t -rendezvous_request (SVCXPRT *xprt, struct rpc_msg *errmsg) -{ - int sock; - struct tcp_rendezvous *r; - struct sockaddr_in6 addr; - socklen_t len; - - r = (struct tcp_rendezvous *) xprt->xp_p1; -again: - len = sizeof (struct sockaddr_in6); - if ((sock = accept (xprt->xp_sock, (struct sockaddr *) &addr, &len)) < 0) - { - if (errno == EINTR) - goto again; - return FALSE; - } - /* - * make a new transporter (re-uses xprt) - */ - xprt = makefd6_xprt (sock, r->sendsize, r->recvsize); - memcpy (&xprt->xp_raddr, &addr, sizeof (addr)); - xprt->xp_addrlen = len; - return FALSE; /* there is never an rpc msg to be processed */ -} - -static enum xprt_stat -rendezvous_stat (SVCXPRT *xprt) -{ - return XPRT_IDLE; -} - -static void -svctcp6_destroy (SVCXPRT *xprt) -{ - struct tcp_conn *cd = (struct tcp_conn *) xprt->xp_p1; - - xprt_unregister (xprt); - (void) __close (xprt->xp_sock); - if (xprt->xp_port != 0) - { - /* a rendezvouser socket */ - xprt->xp_port = 0; - } - else - { - /* an actual connection socket */ - XDR_DESTROY (&(cd->xdrs)); - } - mem_free ((caddr_t) cd, sizeof (struct tcp_conn)); - mem_free ((caddr_t) xprt, sizeof (SVCXPRT)); -} - - -/* - * reads data from the tcp connection. - * any error is fatal and the connection is closed. - * (And a read of zero bytes is a half closed stream => error.) - */ -static int -readtcp (char *xprtptr, char *buf, int len) -{ - SVCXPRT *xprt = (SVCXPRT *)xprtptr; - int sock = xprt->xp_sock; - int milliseconds = 35 * 1000; - struct pollfd pollfd; - - do - { - pollfd.fd = sock; - pollfd.events = POLLIN; - switch (__poll (&pollfd, 1, milliseconds)) - { - case -1: - if (errno == EINTR) - continue; - /*FALLTHROUGH*/ - case 0: - goto fatal_err; - default: - if ((pollfd.revents & POLLERR) || (pollfd.revents & POLLHUP) - || (pollfd.revents & POLLNVAL)) - goto fatal_err; - break; - } - } - while ((pollfd.revents & POLLIN) == 0); - - if ((len = __read (sock, buf, len)) > 0) - return len; - - fatal_err: - ((struct tcp_conn *) (xprt->xp_p1))->strm_stat = XPRT_DIED; - return -1; -} - -/* - * writes data to the tcp connection. - * Any error is fatal and the connection is closed. - */ -static int -writetcp (char *xprtptr, char * buf, int len) -{ - SVCXPRT *xprt = (SVCXPRT *)xprtptr; - int i, cnt; - - for (cnt = len; cnt > 0; cnt -= i, buf += i) - { - if ((i = __write (xprt->xp_sock, buf, cnt)) < 0) - { - ((struct tcp_conn *) (xprt->xp_p1))->strm_stat = XPRT_DIED; - return -1; - } - } - return len; -} - -static enum xprt_stat -svctcp6_stat (SVCXPRT *xprt) -{ - struct tcp_conn *cd = - (struct tcp_conn *) (xprt->xp_p1); - - if (cd->strm_stat == XPRT_DIED) - return XPRT_DIED; - if (!xdrrec_eof (&(cd->xdrs))) - return XPRT_MOREREQS; - return XPRT_IDLE; -} - -static bool_t -svctcp6_recv (SVCXPRT *xprt, struct rpc_msg *msg) -{ - struct tcp_conn *cd = (struct tcp_conn *) (xprt->xp_p1); - XDR *xdrs = &(cd->xdrs); - - xdrs->x_op = XDR_DECODE; - (void) xdrrec_skiprecord (xdrs); - if (xdr_callmsg (xdrs, msg)) - { - cd->x_id = msg->rm_xid; - return TRUE; - } - cd->strm_stat = XPRT_DIED; /* XXXX */ - return FALSE; -} - -static bool_t -svctcp6_getargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr) -{ - return ((*xdr_args) (&(((struct tcp_conn *) - (xprt->xp_p1))->xdrs), args_ptr)); -} - -static bool_t -svctcp6_freeargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr) -{ - XDR *xdrs = &(((struct tcp_conn *) (xprt->xp_p1))->xdrs); - - xdrs->x_op = XDR_FREE; - return ((*xdr_args) (xdrs, args_ptr)); -} - -static bool_t -svctcp6_reply (SVCXPRT *xprt, struct rpc_msg *msg) -{ - struct tcp_conn *cd = (struct tcp_conn *) (xprt->xp_p1); - XDR *xdrs = &(cd->xdrs); - bool_t stat; - - xdrs->x_op = XDR_ENCODE; - msg->rm_xid = cd->x_id; - stat = xdr_replymsg (xdrs, msg); - (void) xdrrec_endofrecord (xdrs, TRUE); - return stat; -} diff --git a/sunrpc/svc_udp6.c b/sunrpc/svc_udp6.c deleted file mode 100644 index 3556a2e060..0000000000 --- a/sunrpc/svc_udp6.c +++ /dev/null @@ -1,512 +0,0 @@ -/* @(#)svc_udp.c 2.2 88/07/29 4.0 RPCSRC */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -#if !defined(lint) && defined(SCCSIDS) -static char sccsid[] = "@(#)svc_udp.c 1.24 87/08/11 Copyr 1984 Sun Micro"; -#endif - -/* - * svc_udp.c, - * Server side for UDP/IP based RPC. (Does some caching in the hopes of - * achieving execute-at-most-once semantics.) - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <libintl.h> -#include <rpc/rpc.h> -#include <sys/socket.h> -#include <errno.h> - -#ifdef USE_IN_LIBIO -# include <libio/iolibio.h> -# define fputs(s, f) _IO_fputs (s, f) -#endif - -#define rpc_buffer(xprt) ((xprt)->xp_p1) -#ifndef MAX -#define MAX(a, b) ((a > b) ? a : b) -#endif - -static bool_t svcudp6_recv (SVCXPRT *, struct rpc_msg *); -static bool_t svcudp6_reply (SVCXPRT *, struct rpc_msg *); -static enum xprt_stat svcudp6_stat (SVCXPRT *); -static bool_t svcudp6_getargs (SVCXPRT *, xdrproc_t, caddr_t); -static bool_t svcudp6_freeargs (SVCXPRT *, xdrproc_t, caddr_t); -static void svcudp6_destroy (SVCXPRT *); - -static const struct xp_ops svcudp6_op = -{ - svcudp6_recv, - svcudp6_stat, - svcudp6_getargs, - svcudp6_reply, - svcudp6_freeargs, - svcudp6_destroy -}; - -static int cache_get (SVCXPRT *, struct rpc_msg *, char **replyp, - u_long *replylenp); -static void cache_set (SVCXPRT *xprt, u_long replylen); - -/* - * kept in xprt->xp_p2 - */ -struct svcudp_data - { - u_int su_iosz; /* byte size of send.recv buffer */ - u_long su_xid; /* transaction id */ - XDR su_xdrs; /* XDR handle */ - char su_verfbody[MAX_AUTH_BYTES]; /* verifier body */ - char *su_cache; /* cached data, NULL if no cache */ - }; -#define su_data(xprt) ((struct svcudp_data *)(xprt->xp_p2)) - -/* - * Usage: - * xprt = svcudp_create(sock); - * - * If sock<0 then a socket is created, else sock is used. - * If the socket, sock is not bound to a port then svcudp_create - * binds it to an arbitrary port. In any (successful) case, - * xprt->xp_sock is the registered socket number and xprt->xp_port is the - * associated port number. - * Once *xprt is initialized, it is registered as a transporter; - * see (svc.h, xprt_register). - * The routines returns NULL if a problem occurred. - */ -SVCXPRT * -svcudp6_bufcreate (sock, sendsz, recvsz) - int sock; - u_int sendsz, recvsz; -{ - bool_t madesock = FALSE; - SVCXPRT *xprt; - struct svcudp_data *su; - struct sockaddr_in6 addr; - socklen_t len = sizeof (struct sockaddr_in6); - - if (sock == RPC_ANYSOCK) - { - if ((sock = __socket (AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) < 0) - { - perror (_("svcudp_create: socket creation problem")); - return (SVCXPRT *) NULL; - } - madesock = TRUE; - } - __bzero ((char *) &addr, sizeof (addr)); - addr.sin6_family = AF_INET6; - if (bindresvport6 (sock, &addr)) - { - addr.sin6_port = 0; - (void) bind (sock, (struct sockaddr *) &addr, len); - } - if (getsockname (sock, (struct sockaddr *) &addr, &len) != 0) - { - perror (_("svcudp_create - cannot getsockname")); - if (madesock) - (void) __close (sock); - return (SVCXPRT *) NULL; - } - xprt = (SVCXPRT *) mem_alloc (sizeof (SVCXPRT)); - if (xprt == NULL) - { - (void) fputs (_("svcudp_create: out of memory\n"), stderr); - return NULL; - } - su = (struct svcudp_data *) mem_alloc (sizeof (*su)); - if (su == NULL) - { - (void) fputs (_("svcudp_create: out of memory\n"), stderr); - return NULL; - } - su->su_iosz = ((MAX (sendsz, recvsz) + 3) / 4) * 4; - if ((rpc_buffer (xprt) = mem_alloc (su->su_iosz)) == NULL) - { - (void) fputs (_("svcudp_create: out of memory\n"), stderr); - return NULL; - } - xdrmem_create (&(su->su_xdrs), rpc_buffer (xprt), su->su_iosz, XDR_DECODE); - su->su_cache = NULL; - xprt->xp_p2 = (caddr_t) su; - xprt->xp_verf.oa_base = su->su_verfbody; - xprt->xp_ops = &svcudp6_op; - xprt->xp_port = ntohs (addr.sin6_port); - xprt->xp_sock = sock; - xprt_register (xprt); - return xprt; -} - -SVCXPRT * -svcudp6_create (sock) - int sock; -{ - - return svcudp6_bufcreate (sock, UDPMSGSIZE, UDPMSGSIZE); -} - -static enum xprt_stat -svcudp6_stat (xprt) - SVCXPRT *xprt; -{ - - return XPRT_IDLE; -} - -static bool_t -svcudp6_recv (xprt, msg) - SVCXPRT *xprt; - struct rpc_msg *msg; -{ - struct svcudp_data *su = su_data (xprt); - XDR *xdrs = &(su->su_xdrs); - int rlen; - char *reply; - u_long replylen; - socklen_t len; - -again: - /* FIXME -- should xp_addrlen be a size_t? */ - len = (socklen_t) sizeof(struct sockaddr_in6); - rlen = recvfrom (xprt->xp_sock, rpc_buffer (xprt), (int) su->su_iosz, 0, - (struct sockaddr *) &(xprt->xp_raddr), &len); - xprt->xp_addrlen = len; - if (rlen == -1 && errno == EINTR) - goto again; - if (rlen < 16) /* < 4 32-bit ints? */ - return FALSE; - xdrs->x_op = XDR_DECODE; - XDR_SETPOS (xdrs, 0); - if (!xdr_callmsg (xdrs, msg)) - return FALSE; - su->su_xid = msg->rm_xid; - if (su->su_cache != NULL) - { - if (cache_get (xprt, msg, &reply, &replylen)) - { - (void) sendto (xprt->xp_sock, reply, (int) replylen, 0, - (struct sockaddr *) &xprt->xp_raddr, len); - return TRUE; - } - } - return TRUE; -} - -static bool_t -svcudp6_reply (xprt, msg) - SVCXPRT *xprt; - struct rpc_msg *msg; -{ - struct svcudp_data *su = su_data (xprt); - XDR *xdrs = &(su->su_xdrs); - int slen; - bool_t stat = FALSE; - - xdrs->x_op = XDR_ENCODE; - XDR_SETPOS (xdrs, 0); - msg->rm_xid = su->su_xid; - if (xdr_replymsg (xdrs, msg)) - { - slen = (int) XDR_GETPOS (xdrs); - if (sendto (xprt->xp_sock, rpc_buffer (xprt), slen, 0, - (struct sockaddr *) &(xprt->xp_raddr), xprt->xp_addrlen) - == slen) - { - stat = TRUE; - if (su->su_cache && slen >= 0) - { - cache_set (xprt, (u_long) slen); - } - } - } - return stat; -} - -static bool_t -svcudp6_getargs (xprt, xdr_args, args_ptr) - SVCXPRT *xprt; - xdrproc_t xdr_args; - caddr_t args_ptr; -{ - - return (*xdr_args) (&(su_data (xprt)->su_xdrs), args_ptr); -} - -static bool_t -svcudp6_freeargs (xprt, xdr_args, args_ptr) - SVCXPRT *xprt; - xdrproc_t xdr_args; - caddr_t args_ptr; -{ - XDR *xdrs = &(su_data (xprt)->su_xdrs); - - xdrs->x_op = XDR_FREE; - return (*xdr_args) (xdrs, args_ptr); -} - -static void -svcudp6_destroy (xprt) - SVCXPRT *xprt; -{ - struct svcudp_data *su = su_data (xprt); - - xprt_unregister (xprt); - (void) __close (xprt->xp_sock); - XDR_DESTROY (&(su->su_xdrs)); - mem_free (rpc_buffer (xprt), su->su_iosz); - mem_free ((caddr_t) su, sizeof (struct svcudp_data)); - mem_free ((caddr_t) xprt, sizeof (SVCXPRT)); -} - - -/***********this could be a separate file*********************/ - -/* - * Fifo cache for udp server - * Copies pointers to reply buffers into fifo cache - * Buffers are sent again if retransmissions are detected. - */ - -#define SPARSENESS 4 /* 75% sparse */ - -#define CACHE_PERROR(msg) \ - (void) fprintf(stderr,"%s\n", msg) - -#define ALLOC(type, size) \ - (type *) mem_alloc((unsigned) (sizeof(type) * (size))) - -#define BZERO(addr, type, size) \ - __bzero((char *) addr, sizeof(type) * (int) (size)) - -/* - * An entry in the cache - */ -typedef struct cache_node *cache_ptr; -struct cache_node - { - /* - * Index into cache is xid, proc, vers, prog and address - */ - u_long cache_xid; - u_long cache_proc; - u_long cache_vers; - u_long cache_prog; - struct sockaddr_in6 cache_addr; - /* - * The cached reply and length - */ - char *cache_reply; - u_long cache_replylen; - /* - * Next node on the list, if there is a collision - */ - cache_ptr cache_next; - }; - - - -/* - * The entire cache - */ -struct udp_cache - { - u_long uc_size; /* size of cache */ - cache_ptr *uc_entries; /* hash table of entries in cache */ - cache_ptr *uc_fifo; /* fifo list of entries in cache */ - u_long uc_nextvictim; /* points to next victim in fifo list */ - u_long uc_prog; /* saved program number */ - u_long uc_vers; /* saved version number */ - u_long uc_proc; /* saved procedure number */ - struct sockaddr_in6 uc_addr; /* saved caller's address */ - }; - - -/* - * the hashing function - */ -#define CACHE_LOC(transp, xid) \ - (xid % (SPARSENESS*((struct udp_cache *) su_data(transp)->su_cache)->uc_size)) - - -/* - * Enable use of the cache. - * Note: there is no disable. - */ -int -svcudp6_enablecache (SVCXPRT *transp, u_long size) -{ - struct svcudp_data *su = su_data (transp); - struct udp_cache *uc; - - if (su->su_cache != NULL) - { - CACHE_PERROR (_("enablecache: cache already enabled")); - return 0; - } - uc = ALLOC (struct udp_cache, 1); - if (uc == NULL) - { - CACHE_PERROR (_("enablecache: could not allocate cache")); - return 0; - } - uc->uc_size = size; - uc->uc_nextvictim = 0; - uc->uc_entries = ALLOC (cache_ptr, size * SPARSENESS); - if (uc->uc_entries == NULL) - { - CACHE_PERROR (_("enablecache: could not allocate cache data")); - return 0; - } - BZERO (uc->uc_entries, cache_ptr, size * SPARSENESS); - uc->uc_fifo = ALLOC (cache_ptr, size); - if (uc->uc_fifo == NULL) - { - CACHE_PERROR (_("enablecache: could not allocate cache fifo")); - return 0; - } - BZERO (uc->uc_fifo, cache_ptr, size); - su->su_cache = (char *) uc; - return 1; -} - - -/* - * Set an entry in the cache - */ -static void -cache_set (SVCXPRT *xprt, u_long replylen) -{ - cache_ptr victim; - cache_ptr *vicp; - struct svcudp_data *su = su_data (xprt); - struct udp_cache *uc = (struct udp_cache *) su->su_cache; - u_int loc; - char *newbuf; - - /* - * Find space for the new entry, either by - * reusing an old entry, or by mallocing a new one - */ - victim = uc->uc_fifo[uc->uc_nextvictim]; - if (victim != NULL) - { - loc = CACHE_LOC (xprt, victim->cache_xid); - for (vicp = &uc->uc_entries[loc]; - *vicp != NULL && *vicp != victim; - vicp = &(*vicp)->cache_next) - ; - if (*vicp == NULL) - { - CACHE_PERROR (_("cache_set: victim not found")); - return; - } - *vicp = victim->cache_next; /* remote from cache */ - newbuf = victim->cache_reply; - } - else - { - victim = ALLOC (struct cache_node, 1); - if (victim == NULL) - { - CACHE_PERROR (_("cache_set: victim alloc failed")); - return; - } - newbuf = mem_alloc (su->su_iosz); - if (newbuf == NULL) - { - CACHE_PERROR (_("cache_set: could not allocate new rpc_buffer")); - return; - } - } - - /* - * Store it away - */ - victim->cache_replylen = replylen; - victim->cache_reply = rpc_buffer (xprt); - rpc_buffer (xprt) = newbuf; - xdrmem_create (&(su->su_xdrs), rpc_buffer (xprt), su->su_iosz, XDR_ENCODE); - victim->cache_xid = su->su_xid; - victim->cache_proc = uc->uc_proc; - victim->cache_vers = uc->uc_vers; - victim->cache_prog = uc->uc_prog; - victim->cache_addr = uc->uc_addr; - loc = CACHE_LOC (xprt, victim->cache_xid); - victim->cache_next = uc->uc_entries[loc]; - uc->uc_entries[loc] = victim; - uc->uc_fifo[uc->uc_nextvictim++] = victim; - uc->uc_nextvictim %= uc->uc_size; -} - -/* - * Try to get an entry from the cache - * return 1 if found, 0 if not found - */ -static int -cache_get (xprt, msg, replyp, replylenp) - SVCXPRT *xprt; - struct rpc_msg *msg; - char **replyp; - u_long *replylenp; -{ - u_int loc; - cache_ptr ent; - struct svcudp_data *su = su_data (xprt); - struct udp_cache *uc = (struct udp_cache *) su->su_cache; - -#define EQADDR(a1, a2) (memcmp((char*)&a1, (char*)&a2, sizeof(a1)) == 0) - - loc = CACHE_LOC (xprt, su->su_xid); - for (ent = uc->uc_entries[loc]; ent != NULL; ent = ent->cache_next) - { - if (ent->cache_xid == su->su_xid && - ent->cache_proc == uc->uc_proc && - ent->cache_vers == uc->uc_vers && - ent->cache_prog == uc->uc_prog && - EQADDR (ent->cache_addr, uc->uc_addr)) - { - *replyp = ent->cache_reply; - *replylenp = ent->cache_replylen; - return 1; - } - } - /* - * Failed to find entry - * Remember a few things so we can do a set later - */ - uc->uc_proc = msg->rm_call.cb_proc; - uc->uc_vers = msg->rm_call.cb_vers; - uc->uc_prog = msg->rm_call.cb_prog; - memcpy (&uc->uc_addr, &xprt->xp_raddr, sizeof (uc->uc_addr)); - return 0; -} |