Adapt include files for rpc_com.h/rpc_internal.h split. Add rpc_control to svc.c Implement non-blocking connections. Patch RPC-Servers to use non-blocking connections Merge from NetBSD Index: contrib/amd/conf/transp/transp_sockets.c =================================================================== RCS file: /usr/home/ncvs/src/contrib/amd/conf/transp/transp_sockets.c,v retrieving revision 1.1.1.4 diff -u -r1.1.1.4 transp_sockets.c --- contrib/amd/conf/transp/transp_sockets.c 2 Sep 2001 17:19:03 -0000 1.1.1.4 +++ contrib/amd/conf/transp/transp_sockets.c 7 Jan 2003 14:08:45 -0000 @@ -50,6 +50,9 @@ #include #include +#ifndef RPC_MAXDATASIZE +#define RPC_MAXDATASIZE 9000 +#endif /* * find the IP address that can be used to connect to the local host @@ -216,6 +219,8 @@ int create_amq_service(int *udp_soAMQp, SVCXPRT **udp_amqpp, int *tcp_soAMQp, SVCXPRT **tcp_amqpp) { + int maxrec = RPC_MAXDATASIZE; + /* first create TCP service */ if (tcp_soAMQp) { *tcp_soAMQp = socket(AF_INET, SOCK_STREAM, 0); @@ -231,6 +236,9 @@ return 2; } } +#ifdef SVCSET_CONNMAXREC + SVC_CONTROL(*tcp_amqpp, SVCSET_CONNMAXREC, &maxrec); +#endif /* next create UDP service */ if (udp_soAMQp) { Index: include/rpc/clnt.h =================================================================== RCS file: /usr/home/ncvs/src/include/rpc/clnt.h,v retrieving revision 1.20 diff -u -r1.20 clnt.h --- include/rpc/clnt.h 21 Jul 2002 20:37:58 -0000 1.20 +++ include/rpc/clnt.h 7 Jan 2003 14:27:16 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: clnt.h,v 1.14 2000/06/02 22:57:55 fvdl Exp $ */ +/* $NetBSD: clnt.h,v 1.17 2002/11/08 00:10:58 fvdl Exp $ */ /* * The contents of this file are subject to the Sun Standards @@ -60,6 +60,7 @@ #ifndef _RPC_CLNT_H_ #define _RPC_CLNT_H_ #include +#include #include #include #include Index: include/rpc/rpc_com.h =================================================================== RCS file: /usr/home/ncvs/src/include/rpc/rpc_com.h,v retrieving revision 1.5 diff -u -r1.5 rpc_com.h --- include/rpc/rpc_com.h 23 Mar 2002 17:24:55 -0000 1.5 +++ include/rpc/rpc_com.h 7 Jan 2003 14:08:45 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: rpc_com.h,v 1.3 2000/12/10 04:10:08 christos Exp $ */ +/* $NetBSD: rpc_com.h,v 1.1 2002/11/08 00:08:20 fvdl Exp $ */ /* $FreeBSD: src/include/rpc/rpc_com.h,v 1.5 2002/03/23 17:24:55 imp Exp $ */ /* @@ -53,31 +53,14 @@ #define RPC_MAXDATASIZE 9000 #define RPC_MAXADDRSIZE 1024 -#define __RPC_GETXID(now) ((u_int32_t)getpid() ^ (u_int32_t)(now)->tv_sec ^ \ - (u_int32_t)(now)->tv_usec) - __BEGIN_DECLS -extern u_int __rpc_get_a_size(int); -extern int __rpc_dtbsize(void); -extern int _rpc_dtablesize(void); -extern struct netconfig * __rpcgettp(int); -extern int __rpc_get_default_domain(char **); - -char *__rpc_taddr2uaddr_af(int, const struct netbuf *); -struct netbuf *__rpc_uaddr2taddr_af(int, const char *); -int __rpc_fixup_addr(struct netbuf *, const struct netbuf *); -int __rpc_sockinfo2netid(struct __rpc_sockinfo *, const char **); -int __rpc_seman2socktype(int); -int __rpc_socktype2seman(int); -void *rpc_nullproc(CLIENT *); -int __rpc_sockisbound(int); - -struct netbuf *__rpcb_findaddr(rpcprog_t, rpcvers_t, const struct netconfig *, - const char *, CLIENT **); -bool_t __rpc_control(int,void *); - -char *_get_next_token(char *, int); - +bool_t rpc_control (int, void *); __END_DECLS + +/* + * Operations for rpc_control(). + */ +#define RPC_SVC_CONNMAXREC_SET 0 /* set max rec size, enable nonblock */ +#define RPC_SVC_CONNMAXREC_GET 1 #endif /* _RPC_RPCCOM_H */ Index: include/rpc/svc.h =================================================================== RCS file: /usr/home/ncvs/src/include/rpc/svc.h,v retrieving revision 1.22 diff -u -r1.22 svc.h --- include/rpc/svc.h 28 Apr 2002 15:18:45 -0000 1.22 +++ include/rpc/svc.h 7 Jan 2003 14:08:45 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: svc.h,v 1.17 2000/06/02 22:57:56 fvdl Exp $ */ +/* $NetBSD: svc.h,v 1.20 2002/11/08 00:10:44 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -42,6 +42,7 @@ #ifndef _RPC_SVC_H #define _RPC_SVC_H #include +#include /* * This interface must manage two items concerning remote procedure calling: @@ -70,6 +71,8 @@ */ #define SVCGET_VERSQUIET 1 #define SVCSET_VERSQUIET 2 +#define SVCGET_CONNMAXREC 3 +#define SVCSET_CONNMAXREC 4 enum xprt_stat { Index: lib/libc/rpc/clnt_bcast.c =================================================================== RCS file: /usr/home/ncvs/src/lib/libc/rpc/clnt_bcast.c,v retrieving revision 1.5 diff -u -r1.5 clnt_bcast.c --- lib/libc/rpc/clnt_bcast.c 22 Mar 2002 23:18:36 -0000 1.5 +++ lib/libc/rpc/clnt_bcast.c 7 Jan 2003 14:08:45 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: clnt_bcast.c,v 1.3 2000/07/06 03:05:20 christos Exp $ */ +/* $NetBSD: clnt_bcast.c,v 1.9 2002/11/08 00:13:07 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -78,7 +78,7 @@ #include #include "un-namespace.h" -#include "rpc_com.h" +#include "rpc_internal.h" #define MAXBCAST 20 /* Max no of broadcasting transports */ #define INITTIME 4000 /* Time to wait initially */ Index: lib/libc/rpc/clnt_dg.c =================================================================== RCS file: /usr/home/ncvs/src/lib/libc/rpc/clnt_dg.c,v retrieving revision 1.15 diff -u -r1.15 clnt_dg.c --- lib/libc/rpc/clnt_dg.c 15 Oct 2002 22:28:59 -0000 1.15 +++ lib/libc/rpc/clnt_dg.c 7 Jan 2003 14:08:45 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: clnt_dg.c,v 1.4 2000/07/14 08:40:41 fvdl Exp $ */ +/* $NetBSD: clnt_dg.c,v 1.8 2002/11/08 00:13:07 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -60,7 +60,8 @@ #include #include #include "un-namespace.h" -#include "rpc_com.h" + +#include "rpc_internal.h" #define RPC_MAX_BACKOFF 30 /* seconds */ Index: lib/libc/rpc/clnt_generic.c =================================================================== RCS file: /usr/home/ncvs/src/lib/libc/rpc/clnt_generic.c,v retrieving revision 1.14 diff -u -r1.14 clnt_generic.c --- lib/libc/rpc/clnt_generic.c 11 Jul 2002 16:23:04 -0000 1.14 +++ lib/libc/rpc/clnt_generic.c 7 Jan 2003 14:08:45 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: clnt_generic.c,v 1.18 2000/07/06 03:10:34 christos Exp $ */ +/* $NetBSD: clnt_generic.c,v 1.20 2002/11/08 00:13:07 fvdl Exp $ */ /* * The contents of this file are subject to the Sun Standards @@ -76,7 +76,8 @@ #include #include #include "un-namespace.h" -#include "rpc_com.h" + +#include "rpc_internal.h" extern bool_t __rpc_is_local_host(const char *); int __rpc_raise_fd(int); Index: lib/libc/rpc/clnt_vc.c =================================================================== RCS file: /usr/home/ncvs/src/lib/libc/rpc/clnt_vc.c,v retrieving revision 1.15 diff -u -r1.15 clnt_vc.c --- lib/libc/rpc/clnt_vc.c 14 Jul 2002 23:35:04 -0000 1.15 +++ lib/libc/rpc/clnt_vc.c 7 Jan 2003 14:08:45 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: clnt_vc.c,v 1.4 2000/07/14 08:40:42 fvdl Exp $ */ +/* $NetBSD: clnt_vc.c,v 1.8 2002/11/08 00:13:07 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -78,7 +78,8 @@ #include #include "un-namespace.h" -#include "rpc_com.h" + +#include "rpc_internal.h" #define MCALL_MSG_SIZE 24 Index: lib/libc/rpc/getnetconfig.c =================================================================== RCS file: /usr/home/ncvs/src/lib/libc/rpc/getnetconfig.c,v retrieving revision 1.7 diff -u -r1.7 getnetconfig.c --- lib/libc/rpc/getnetconfig.c 16 Dec 2002 22:24:25 -0000 1.7 +++ lib/libc/rpc/getnetconfig.c 7 Jan 2003 14:08:45 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: getnetconfig.c,v 1.3 2000/07/06 03:10:34 christos Exp $ */ +/* $NetBSD: getnetconfig.c,v 1.8 2002/11/08 00:13:07 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -51,7 +51,8 @@ #include #include #include "un-namespace.h" -#include "rpc_com.h" + +#include "rpc_internal.h" /* * The five library routines in this file provide application access to the Index: lib/libc/rpc/pmap_clnt.c =================================================================== RCS file: /usr/home/ncvs/src/lib/libc/rpc/pmap_clnt.c,v retrieving revision 1.14 diff -u -r1.14 pmap_clnt.c --- lib/libc/rpc/pmap_clnt.c 22 Mar 2002 23:18:36 -0000 1.14 +++ lib/libc/rpc/pmap_clnt.c 7 Jan 2003 14:08:45 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: pmap_clnt.c,v 1.16 2000/07/06 03:10:34 christos Exp $ */ +/* $NetBSD: pmap_clnt.c,v 1.17 2002/11/08 00:13:07 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -58,7 +58,7 @@ #include #include -#include "rpc_com.h" +#include "rpc_internal.h" bool_t pmap_set(u_long program, u_long version, int protocol, int port) Index: lib/libc/rpc/rpc_com.h =================================================================== RCS file: lib/libc/rpc/rpc_com.h diff -N lib/libc/rpc/rpc_com.h --- lib/libc/rpc/rpc_com.h 14 Jul 2002 23:14:08 -0000 1.5 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,89 +0,0 @@ -/* $NetBSD: rpc_com.h,v 1.3 2000/12/10 04:10:08 christos Exp $ */ - -/* - * 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 - * - * $FreeBSD: src/lib/libc/rpc/rpc_com.h,v 1.5 2002/07/14 23:14:08 alfred Exp $ - */ -/* - * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. - */ - -/* - * rpc_com.h, Common definitions for both the server and client side. - * All for the topmost layer of rpc - * - * In Sun's tirpc distribution, this was installed as , - * but as it contains only non-exported interfaces, it was moved here. - */ - -#ifndef _RPC_RPCCOM_H -#define _RPC_RPCCOM_H - -#include - -/* #pragma ident "@(#)rpc_com.h 1.11 93/07/05 SMI" */ - -/* - * The max size of the transport, if the size cannot be determined - * by other means. - */ -#define RPC_MAXDATASIZE 9000 -#define RPC_MAXADDRSIZE 1024 - -#define __RPC_GETXID(now) ((u_int32_t)getpid() ^ (u_int32_t)(now)->tv_sec ^ \ - (u_int32_t)(now)->tv_usec) - -__BEGIN_DECLS -extern u_int __rpc_get_a_size(int); -extern int __rpc_dtbsize(void); -extern struct netconfig * __rpcgettp(int); -extern int __rpc_get_default_domain(char **); - -char *__rpc_taddr2uaddr_af(int, const struct netbuf *); -struct netbuf *__rpc_uaddr2taddr_af(int, const char *); -int __rpc_fixup_addr(struct netbuf *, const struct netbuf *); -int __rpc_sockinfo2netid(struct __rpc_sockinfo *, const char **); -int __rpc_seman2socktype(int); -int __rpc_socktype2seman(int); -void *rpc_nullproc(CLIENT *); -int __rpc_sockisbound(int); - -struct netbuf *__rpcb_findaddr(rpcprog_t, rpcvers_t, const struct netconfig *, - const char *, CLIENT **); -struct netbuf *__rpcb_findaddr_timed(rpcprog_t, rpcvers_t, - const struct netconfig *, const char *host, CLIENT **clpp, - struct timeval *tp); - -bool_t __rpc_control(int,void *); - -char *_get_next_token(char *, int); - -__END_DECLS - -#endif /* _RPC_RPCCOM_H */ Index: lib/libc/rpc/rpc_generic.c =================================================================== RCS file: /usr/home/ncvs/src/lib/libc/rpc/rpc_generic.c,v retrieving revision 1.9 diff -u -r1.9 rpc_generic.c --- lib/libc/rpc/rpc_generic.c 16 Dec 2002 22:24:25 -0000 1.9 +++ lib/libc/rpc/rpc_generic.c 7 Jan 2003 14:08:45 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: rpc_generic.c,v 1.4 2000/09/28 09:07:04 kleink Exp $ */ +/* $NetBSD: rpc_generic.c,v 1.10 2002/11/08 00:13:07 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -62,7 +62,8 @@ #include #include #include "un-namespace.h" -#include "rpc_com.h" + +#include "rpc_internal.h" struct handle { NCONF_HANDLE *nhandle; Index: lib/libc/rpc/rpc_internal.h =================================================================== RCS file: lib/libc/rpc/rpc_internal.h diff -N lib/libc/rpc/rpc_internal.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ lib/libc/rpc/rpc_internal.h 7 Jan 2003 14:08:45 -0000 @@ -0,0 +1,44 @@ +/* $NetBSD: rpc_internal.h,v 1.1 2002/11/08 00:13:08 fvdl Exp $ */ + +/* + * Private include file for XDR functions only used internally in libc. + * These are not exported interfaces. + */ + +#define __RPC_GETXID(now) ((u_int32_t)getpid() ^ (u_int32_t)(now)->tv_sec ^ \ + (u_int32_t)(now)->tv_usec) + +bool_t __xdrrec_getrec (XDR *, enum xprt_stat *, bool_t); +bool_t __xdrrec_setnonblock (XDR *, int); +void __xprt_unregister_unlocked (SVCXPRT *); +bool_t __svc_clean_idle (fd_set *, int, bool_t); + +bool_t __xdrrec_getrec (XDR *, enum xprt_stat *, bool_t); +bool_t __xdrrec_setnonblock (XDR *, int); + +u_int __rpc_get_a_size (int); +int __rpc_dtbsize (void); +struct netconfig * __rpcgettp (int); +int __rpc_get_default_domain (char **); + +char *__rpc_taddr2uaddr_af (int, const struct netbuf *); +struct netbuf *__rpc_uaddr2taddr_af (int, const char *); +int __rpc_fixup_addr (struct netbuf *, const struct netbuf *); +int __rpc_sockinfo2netid (struct __rpc_sockinfo *, const char **); +int __rpc_seman2socktype (int); +int __rpc_socktype2seman (int); +void *rpc_nullproc (CLIENT *); +int __rpc_sockisbound (int); + +struct netbuf *__rpcb_findaddr (rpcprog_t, rpcvers_t, + const struct netconfig *, const char *, CLIENT **); +struct netbuf *__rpcb_findaddr_timed(rpcprog_t, rpcvers_t, + const struct netconfig *, const char *host, CLIENT **clpp, + +struct timeval *tp); +bool_t __rpc_control (int,void *); + +char *_get_next_token (char *, int); + +extern SVCXPRT **__svc_xports; +extern int __svc_maxrec; Index: lib/libc/rpc/rpc_soc.c =================================================================== RCS file: /usr/home/ncvs/src/lib/libc/rpc/rpc_soc.c,v retrieving revision 1.11 diff -u -r1.11 rpc_soc.c --- lib/libc/rpc/rpc_soc.c 28 Apr 2002 15:18:46 -0000 1.11 +++ lib/libc/rpc/rpc_soc.c 7 Jan 2003 14:08:45 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: rpc_soc.c,v 1.6 2000/07/06 03:10:35 christos Exp $ */ +/* $NetBSD: rpc_soc.c,v 1.9 2002/11/08 00:13:08 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -73,7 +73,7 @@ #include #include "un-namespace.h" -#include "rpc_com.h" +#include "rpc_internal.h" extern mutex_t rpcsoc_lock; Index: lib/libc/rpc/rpcb_clnt.c =================================================================== RCS file: /usr/home/ncvs/src/lib/libc/rpc/rpcb_clnt.c,v retrieving revision 1.11 diff -u -r1.11 rpcb_clnt.c --- lib/libc/rpc/rpcb_clnt.c 26 Jul 2002 07:52:21 -0000 1.11 +++ lib/libc/rpc/rpcb_clnt.c 7 Jan 2003 14:08:45 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: rpcb_clnt.c,v 1.6 2000/07/16 06:41:43 itojun Exp $ */ +/* $NetBSD: rpcb_clnt.c,v 1.12 2002/11/08 00:13:08 fvdl Exp $ */ /* * The contents of this file are subject to the Sun Standards @@ -88,7 +88,7 @@ #include #include "un-namespace.h" -#include "rpc_com.h" +#include "rpc_internal.h" static struct timeval tottimeout = { 60, 0 }; static const struct timeval rmttimeout = { 3, 0 }; Index: lib/libc/rpc/svc.c =================================================================== RCS file: /usr/home/ncvs/src/lib/libc/rpc/svc.c,v retrieving revision 1.21 diff -u -r1.21 svc.c --- lib/libc/rpc/svc.c 28 Apr 2002 15:18:46 -0000 1.21 +++ lib/libc/rpc/svc.c 7 Jan 2003 14:08:45 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: svc.c,v 1.21 2000/07/06 03:10:35 christos Exp $ */ +/* $NetBSD: svc.c,v 1.23 2002/11/08 00:13:08 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -61,9 +61,10 @@ #endif /* PORTMAP */ #include "un-namespace.h" -#include "rpc_com.h" +#include "rpc_internal.h" -static SVCXPRT **xports; +SVCXPRT **__svc_xports; +int __svc_maxrec; #define RQCRED_SIZE 400 /* this size is excessive */ @@ -91,6 +92,7 @@ static struct svc_callout *svc_find(rpcprog_t, rpcvers_t, struct svc_callout **, char *); +static void __xprt_do_unregister (SVCXPRT *xprt, bool_t dolock); /* *************** SVCXPRT related stuff **************** */ @@ -108,27 +110,40 @@ sock = xprt->xp_fd; rwlock_wrlock(&svc_fd_lock); - if (xports == NULL) { - xports = (SVCXPRT **) + if (__svc_xports == NULL) { + __svc_xports = (SVCXPRT **) mem_alloc(FD_SETSIZE * sizeof(SVCXPRT *)); - if (xports == NULL) + if (__svc_xports == NULL) return; - memset(xports, '\0', FD_SETSIZE * sizeof(SVCXPRT *)); + memset(__svc_xports, '\0', FD_SETSIZE * sizeof(SVCXPRT *)); } if (sock < FD_SETSIZE) { - xports[sock] = xprt; + __svc_xports[sock] = xprt; FD_SET(sock, &svc_fdset); svc_maxfd = max(svc_maxfd, sock); } rwlock_unlock(&svc_fd_lock); } +void +xprt_unregister(SVCXPRT *xprt) +{ + __xprt_do_unregister(xprt, TRUE); +} + +void +__xprt_unregister_unlocked(SVCXPRT *xprt) +{ + __xprt_do_unregister(xprt, FALSE); +} + /* * De-activate a transport handle. */ -void -xprt_unregister(xprt) +static void +__xprt_do_unregister(xprt, dolock) SVCXPRT *xprt; + bool_t dolock; { int sock; @@ -136,17 +151,19 @@ sock = xprt->xp_fd; - rwlock_wrlock(&svc_fd_lock); - if ((sock < FD_SETSIZE) && (xports[sock] == xprt)) { - xports[sock] = NULL; + if (dolock) + rwlock_wrlock(&svc_fd_lock); + if ((sock < FD_SETSIZE) && (__svc_xports[sock] == xprt)) { + __svc_xports[sock] = NULL; FD_CLR(sock, &svc_fdset); if (sock >= svc_maxfd) { for (svc_maxfd--; svc_maxfd>=0; svc_maxfd--) - if (xports[svc_maxfd]) + if (__svc_xports[svc_maxfd]) break; } } - rwlock_unlock(&svc_fd_lock); + if (dolock) + rwlock_unlock(&svc_fd_lock); } /* @@ -611,7 +628,7 @@ r.rq_clntcred = &(cred_area[2*MAX_AUTH_BYTES]); rwlock_rdlock(&svc_fd_lock); - xprt = xports[fd]; + xprt = __svc_xports[fd]; rwlock_unlock(&svc_fd_lock); if (xprt == NULL) /* But do we control sock? */ @@ -667,7 +684,7 @@ * If so, then break. */ rwlock_rdlock(&svc_fd_lock); - if (xprt != xports[fd]) { + if (xprt != __svc_xports[fd]) { rwlock_unlock(&svc_fd_lock); break; } @@ -714,4 +731,25 @@ svc_getreq_common(p->fd); } } +} + +bool_t +rpc_control(int what, void *arg) +{ + int val; + + switch (what) { + case RPC_SVC_CONNMAXREC_SET: + val = *(int *)arg; + if (val <= 0) + return FALSE; + __svc_maxrec = val; + return TRUE; + case RPC_SVC_CONNMAXREC_GET: + *(int *)arg = __svc_maxrec; + return TRUE; + default: + break; + } + return FALSE; } Index: lib/libc/rpc/svc_dg.c =================================================================== RCS file: /usr/home/ncvs/src/lib/libc/rpc/svc_dg.c,v retrieving revision 1.5 diff -u -r1.5 svc_dg.c --- lib/libc/rpc/svc_dg.c 28 Apr 2002 15:18:46 -0000 1.5 +++ lib/libc/rpc/svc_dg.c 7 Jan 2003 14:08:45 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: svc_dg.c,v 1.4 2000/07/06 03:10:35 christos Exp $ */ +/* $NetBSD: svc_dg.c,v 1.7 2002/11/08 00:13:08 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -61,7 +61,7 @@ #include #include "un-namespace.h" -#include "rpc_com.h" +#include "rpc_internal.h" #define su_data(xprt) ((struct svc_dg_data *)(xprt->xp_p2)) #define rpc_buffer(xprt) ((xprt)->xp_p1) Index: lib/libc/rpc/svc_generic.c =================================================================== RCS file: /usr/home/ncvs/src/lib/libc/rpc/svc_generic.c,v retrieving revision 1.4 diff -u -r1.4 svc_generic.c --- lib/libc/rpc/svc_generic.c 22 Mar 2002 23:18:37 -0000 1.4 +++ lib/libc/rpc/svc_generic.c 7 Jan 2003 14:08:45 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: svc_generic.c,v 1.3 2000/07/06 03:10:35 christos Exp $ */ +/* $NetBSD: svc_generic.c,v 1.4 2002/11/08 00:13:08 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -61,7 +61,7 @@ #include #include "un-namespace.h" -#include "rpc_com.h" +#include "rpc_internal.h" extern int __svc_vc_setflag(SVCXPRT *, int); Index: lib/libc/rpc/svc_run.c =================================================================== RCS file: /usr/home/ncvs/src/lib/libc/rpc/svc_run.c,v retrieving revision 1.15 diff -u -r1.15 svc_run.c --- lib/libc/rpc/svc_run.c 22 Mar 2002 23:18:37 -0000 1.15 +++ lib/libc/rpc/svc_run.c 7 Jan 2003 14:08:45 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: svc_run.c,v 1.17 2000/07/06 03:10:35 christos Exp $ */ +/* $NetBSD: svc_run.c,v 1.18 2002/11/08 00:13:08 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -52,17 +52,24 @@ #include +#include "rpc_internal.h" + void svc_run() { - fd_set readfds; + fd_set readfds, cleanfds; + struct timeval timeout; extern rwlock_t svc_fd_lock; + timeout.tv_sec = 30; + timeout.tv_usec = 0; + for (;;) { rwlock_rdlock(&svc_fd_lock); readfds = svc_fdset; + cleanfds = svc_fdset; rwlock_unlock(&svc_fd_lock); - switch (_select(svc_maxfd+1, &readfds, NULL, NULL, NULL)) { + switch (select(svc_maxfd+1, &readfds, NULL, NULL, &timeout)) { case -1: FD_ZERO(&readfds); if (errno == EINTR) { @@ -71,6 +78,7 @@ _warn("svc_run: - select failed"); return; case 0: + __svc_clean_idle(&cleanfds, 30, FALSE); continue; default: svc_getreqset(&readfds); Index: lib/libc/rpc/svc_simple.c =================================================================== RCS file: /usr/home/ncvs/src/lib/libc/rpc/svc_simple.c,v retrieving revision 1.14 diff -u -r1.14 svc_simple.c --- lib/libc/rpc/svc_simple.c 22 Mar 2002 23:18:37 -0000 1.14 +++ lib/libc/rpc/svc_simple.c 7 Jan 2003 14:11:52 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: svc_simple.c,v 1.20 2000/07/06 03:10:35 christos Exp $ */ +/* $NetBSD: svc_simple.c,v 1.22 2002/11/08 00:13:08 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -59,7 +59,7 @@ #include #include "un-namespace.h" -#include "rpc_com.h" +#include "rpc_internal.h" static void universal(struct svc_req *, SVCXPRT *); Index: lib/libc/rpc/svc_vc.c =================================================================== RCS file: /usr/home/ncvs/src/lib/libc/rpc/svc_vc.c,v retrieving revision 1.15 diff -u -r1.15 svc_vc.c --- lib/libc/rpc/svc_vc.c 28 Apr 2002 15:18:46 -0000 1.15 +++ lib/libc/rpc/svc_vc.c 7 Jan 2003 14:08:45 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: svc_vc.c,v 1.7 2000/08/03 00:01:53 fvdl Exp $ */ +/* $NetBSD: svc_vc.c,v 1.10 2002/11/08 00:13:08 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -58,25 +59,29 @@ #include #include #include +#include #include #include #include #include #include - -#include "rpc_com.h" #include "un-namespace.h" +#include "rpc_internal.h" + struct cmessage { struct cmsghdr cmsg; struct cmsgcred cmcred; }; +extern rwlock_t svc_fd_lock; + static SVCXPRT *makefd_xprt(int, u_int, u_int); static bool_t rendezvous_request(SVCXPRT *, struct rpc_msg *); static enum xprt_stat rendezvous_stat(SVCXPRT *); static void svc_vc_destroy(SVCXPRT *); +static void __svc_vc_dodestroy (SVCXPRT *); static int read_vc(void *, void *, int); static int write_vc(void *, void *, int); static enum xprt_stat svc_vc_stat(SVCXPRT *); @@ -87,12 +92,15 @@ static void svc_vc_rendezvous_ops(SVCXPRT *); static void svc_vc_ops(SVCXPRT *); static bool_t svc_vc_control(SVCXPRT *xprt, const u_int rq, void *in); +static bool_t svc_vc_rendezvous_control (SVCXPRT *xprt, const u_int rq, + void *in); static int __msgread_withcred(int, void *, size_t, struct cmessage *); static int __msgwrite(int, void *, size_t); struct cf_rendezvous { /* kept in xprt->xp_p1 for rendezvouser */ u_int sendsize; u_int recvsize; + int maxrec; }; struct cf_conn { /* kept in xprt->xp_p1 for actual connection */ @@ -100,6 +108,11 @@ u_int32_t x_id; XDR xdrs; char verf_body[MAX_AUTH_BYTES]; + u_int sendsize; + u_int recvsize; + int maxrec; + bool_t nonblock; + struct timeval last_recv_time; }; /* @@ -139,6 +152,7 @@ return NULL; r->sendsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsize); r->recvsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsize); + r->maxrec = __svc_maxrec; xprt = mem_alloc(sizeof(SVCXPRT)); if (xprt == NULL) { warnx("svc_vc_create: out of memory"); @@ -285,11 +299,14 @@ SVCXPRT *xprt; struct rpc_msg *msg; { - int sock; + int sock, flags; struct cf_rendezvous *r; + struct cf_conn *cd; struct sockaddr_storage addr; socklen_t len; struct __rpc_sockinfo si; + SVCXPRT *newxprt; + fd_set cleanfds; assert(xprt != NULL); assert(msg != NULL); @@ -301,21 +318,30 @@ &len)) < 0) { if (errno == EINTR) goto again; - return (FALSE); + /* + * Clean out the most idle file descriptor when we're + * running out. + */ + if (errno == EMFILE || errno == ENFILE) { + cleanfds = svc_fdset; + __svc_clean_idle(&cleanfds, 0, FALSE); + goto again; + } + return (FALSE); } /* * make a new transporter (re-uses xprt) */ - xprt = makefd_xprt(sock, r->sendsize, r->recvsize); - xprt->xp_rtaddr.buf = mem_alloc(len); - if (xprt->xp_rtaddr.buf == NULL) + newxprt = makefd_xprt(sock, r->sendsize, r->recvsize); + newxprt->xp_rtaddr.buf = mem_alloc(len); + if (newxprt->xp_rtaddr.buf == NULL) return (FALSE); - memcpy(xprt->xp_rtaddr.buf, &addr, len); - xprt->xp_rtaddr.len = len; + memcpy(newxprt->xp_rtaddr.buf, &addr, len); + newxprt->xp_rtaddr.len = len; #ifdef PORTMAP if (addr.ss_family == AF_INET || addr.ss_family == AF_LOCAL) { - xprt->xp_raddr = *(struct sockaddr_in *)xprt->xp_rtaddr.buf; - xprt->xp_addrlen = sizeof (struct sockaddr_in); + newxprt->xp_raddr = *(struct sockaddr_in *)newxprt->xp_rtaddr.buf; + newxprt->xp_addrlen = sizeof (struct sockaddr_in); } #endif /* PORTMAP */ if (__rpc_fd2sockinfo(sock, &si) && si.si_proto == IPPROTO_TCP) { @@ -323,6 +349,28 @@ /* XXX fvdl - is this useful? */ _setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &len, sizeof (len)); } + + cd = (struct cf_conn *)newxprt->xp_p1; + + cd->recvsize = r->recvsize; + cd->sendsize = r->sendsize; + cd->maxrec = r->maxrec; + + if (cd->maxrec != 0) { + flags = fcntl(sock, F_GETFL, 0); + if (flags == -1) + return (FALSE); + if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) == -1) + return (FALSE); + if (cd->recvsize > cd->maxrec) + cd->recvsize = cd->maxrec; + cd->nonblock = TRUE; + __xdrrec_setnonblock(&cd->xdrs, cd->maxrec); + } else + cd->nonblock = FALSE; + + gettimeofday(&cd->last_recv_time, NULL); + return (FALSE); /* there is never an rpc msg to be processed */ } @@ -339,14 +387,21 @@ svc_vc_destroy(xprt) SVCXPRT *xprt; { + assert(xprt != NULL); + + xprt_unregister(xprt); + __svc_vc_dodestroy(xprt); +} + +static void +__svc_vc_dodestroy(xprt) + SVCXPRT *xprt; +{ struct cf_conn *cd; struct cf_rendezvous *r; - assert(xprt != NULL); - cd = (struct cf_conn *)xprt->xp_p1; - xprt_unregister(xprt); if (xprt->xp_fd != RPC_ANYFD) (void)_close(xprt->xp_fd); if (xprt->xp_port != 0) { @@ -380,6 +435,30 @@ return (FALSE); } +static bool_t +svc_vc_rendezvous_control(xprt, rq, in) + SVCXPRT *xprt; + const u_int rq; + void *in; +{ + struct cf_rendezvous *cfp; + + cfp = (struct cf_rendezvous *)xprt->xp_p1; + if (cfp == NULL) + return (FALSE); + switch (rq) { + case SVCGET_CONNMAXREC: + *(int *)in = cfp->maxrec; + break; + case SVCSET_CONNMAXREC: + cfp->maxrec = *(int *)in; + break; + default: + return (FALSE); + } + return (TRUE); +} + /* * reads data from the tcp or uip connection. * any error is fatal and the connection is closed. @@ -399,12 +478,28 @@ struct pollfd pollfd; struct sockaddr *sa; struct cmessage *cm; + struct cf_conn *cfp; xprt = (SVCXPRT *)xprtp; assert(xprt != NULL); sock = xprt->xp_fd; + cfp = (struct cf_conn *)xprt->xp_p1; + + if (cfp->nonblock) { + len = read(sock, buf, (size_t)len); + if (len < 0) { + if (errno == EAGAIN) + len = 0; + else + goto fatal_err; + } + if (len != 0) + gettimeofday(&cfp->last_recv_time, NULL); + return len; + } + do { pollfd.fd = sock; pollfd.events = POLLIN; @@ -432,8 +527,10 @@ } else goto fatal_err; } else { - if ((len = _read(sock, buf, (size_t)len)) > 0) + if ((len = read(sock, buf, (size_t)len)) > 0) { + gettimeofday(&cfp->last_recv_time, NULL); return (len); + } } fatal_err: @@ -454,27 +551,41 @@ SVCXPRT *xprt; int i, cnt; struct sockaddr *sa; + struct cf_conn *cd; + struct timeval tv0, tv1; xprt = (SVCXPRT *)xprtp; assert(xprt != NULL); + + cd = (struct cf_conn *)xprt->xp_p1; + + if (cd->nonblock) + gettimeofday(&tv0, NULL); sa = (struct sockaddr *)xprt->xp_rtaddr.buf; - if (sa->sa_family == AF_LOCAL) { - for (cnt = len; cnt > 0; cnt -= i, buf += i) { - if ((i = __msgwrite(xprt->xp_fd, buf, - (size_t)cnt)) < 0) { - ((struct cf_conn *)(xprt->xp_p1))->strm_stat = - XPRT_DIED; + for (cnt = len; cnt > 0; cnt -= i, buf += i) { + if (sa->sa_family == AF_LOCAL) + i = __msgwrite(xprt->xp_fd, buf, (size_t)cnt); + else + i = _write(xprt->xp_fd, buf, (size_t)cnt); + if (i < 0) { + if (errno != EAGAIN || !cd->nonblock) { + cd->strm_stat = XPRT_DIED; return (-1); } - } - } else { - for (cnt = len; cnt > 0; cnt -= i, buf += i) { - if ((i = _write(xprt->xp_fd, buf, - (size_t)cnt)) < 0) { - ((struct cf_conn *)(xprt->xp_p1))->strm_stat = - XPRT_DIED; - return (-1); + if (cd->nonblock && i != cnt) { + /* + * For non-blocking connections, do not + * take more than 2 seconds writing the + * data out. + * + * XXX 2 is an arbitrary amount. + */ + gettimeofday(&tv1, NULL); + if (tv1.tv_sec - tv0.tv_sec >= 2) { + cd->strm_stat = XPRT_DIED; + return (-1); + } } } } @@ -513,6 +624,11 @@ cd = (struct cf_conn *)(xprt->xp_p1); xdrs = &(cd->xdrs); + if (cd->nonblock) { + if (!__xdrrec_getrec(xdrs, &cd->strm_stat, TRUE)) + return FALSE; + } + xdrs->x_op = XDR_DECODE; (void)xdrrec_skiprecord(xdrs); if (xdr_callmsg(xdrs, msg)) { @@ -560,7 +676,7 @@ { struct cf_conn *cd; XDR *xdrs; - bool_t stat; + bool_t rstat; assert(xprt != NULL); assert(msg != NULL); @@ -570,9 +686,9 @@ xdrs->x_op = XDR_ENCODE; msg->rm_xid = cd->x_id; - stat = xdr_replymsg(xdrs, msg); + rstat = xdr_replymsg(xdrs, msg); (void)xdrrec_endofrecord(xdrs, TRUE); - return (stat); + return (rstat); } static void @@ -619,7 +735,7 @@ ops.xp_freeargs = (bool_t (*)(SVCXPRT *, xdrproc_t, void *))abort, ops.xp_destroy = svc_vc_destroy; - ops2.xp_control = svc_vc_control; + ops2.xp_control = svc_vc_rendezvous_control; } xprt->xp_ops = &ops; xprt->xp_ops2 = &ops2; @@ -719,4 +835,54 @@ return (-1); *uid = cmcred->cmcred_euid; return (0); +} + +/* + * Destroy xprts that have not have had any activity in 'timeout' seconds. + * If 'cleanblock' is true, blocking connections (the default) are also + * cleaned. If timeout is 0, the least active connection is picked. + */ +bool_t +__svc_clean_idle(fd_set *fds, int timeout, bool_t cleanblock) +{ + int i, ncleaned; + SVCXPRT *xprt, *least_active; + struct timeval tv, tdiff, tmax; + struct cf_conn *cd; + + gettimeofday(&tv, NULL); + tmax.tv_sec = tmax.tv_usec = 0; + least_active = NULL; + rwlock_wrlock(&svc_fd_lock); + for (i = ncleaned = 0; i <= svc_maxfd; i++) { + if (FD_ISSET(i, fds)) { + xprt = __svc_xports[i]; + if (xprt == NULL || xprt->xp_ops == NULL || + xprt->xp_ops->xp_recv != svc_vc_recv) + continue; + cd = (struct cf_conn *)xprt->xp_p1; + if (!cleanblock && !cd->nonblock) + continue; + if (timeout == 0) { + timersub(&tv, &cd->last_recv_time, &tdiff); + if (timercmp(&tdiff, &tmax, >)) { + tmax = tdiff; + least_active = xprt; + } + continue; + } + if (tv.tv_sec - cd->last_recv_time.tv_sec > timeout) { + __xprt_unregister_unlocked(xprt); + __svc_vc_dodestroy(xprt); + ncleaned++; + } + } + } + if (timeout == 0 && least_active != NULL) { + __xprt_unregister_unlocked(least_active); + __svc_vc_dodestroy(least_active); + ncleaned++; + } + rwlock_unlock(&svc_fd_lock); + return ncleaned > 0 ? TRUE : FALSE; } Index: lib/libc/xdr/xdr_rec.c =================================================================== RCS file: /usr/home/ncvs/src/lib/libc/xdr/xdr_rec.c,v retrieving revision 1.16 diff -u -r1.16 xdr_rec.c --- lib/libc/xdr/xdr_rec.c 28 Apr 2002 15:18:47 -0000 1.16 +++ lib/libc/xdr/xdr_rec.c 7 Jan 2003 14:52:45 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: xdr_rec.c,v 1.18 2000/07/06 03:10:35 christos Exp $ */ +/* $NetBSD: xdr_rec.c,v 1.19 2002/11/08 00:13:08 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -66,8 +66,14 @@ #include #include +#include +#include +#include +#include #include "un-namespace.h" +#include "../rpc/rpc_internal.h" + static bool_t xdrrec_getlong(XDR *, long *); static bool_t xdrrec_putlong(XDR *, const long *); static bool_t xdrrec_getbytes(XDR *, char *, u_int); @@ -91,7 +97,7 @@ /* * A record is composed of one or more record fragments. - * A record fragment is a two-byte header followed by zero to + * A record fragment is a four-byte header followed by zero to * 2**32-1 bytes. The header is treated as a long unsigned and is * encode/decoded to the network via htonl/ntohl. The low order 31 bits * are a byte count of the fragment. The highest order bit is a boolean: @@ -106,7 +112,6 @@ typedef struct rec_strm { char *tcp_handle; - char *the_buffer; /* * out-goung bits */ @@ -128,6 +133,15 @@ bool_t last_frag; u_int sendsize; u_int recvsize; + + bool_t nonblock; + bool_t in_haveheader; + u_int32_t in_header; + char *in_hdrp; + int in_hdrlen; + int in_reclen; + int in_received; + int in_maxrec; } RECSTREAM; static u_int fix_buf_size(u_int); @@ -136,6 +150,7 @@ static bool_t get_input_bytes(RECSTREAM *, char *, int); static bool_t set_input_fragment(RECSTREAM *); static bool_t skip_input_bytes(RECSTREAM *, long); +static bool_t realloc_stream(RECSTREAM *, int); /* @@ -168,20 +183,21 @@ */ return; } - /* - * adjust sizes and allocate buffer quad byte aligned - */ rstrm->sendsize = sendsize = fix_buf_size(sendsize); + rstrm->out_base = mem_alloc(rstrm->sendsize); + if (rstrm->out_base == NULL) { + warnx("xdrrec_create: out of memory"); + mem_free(rstrm, sizeof(RECSTREAM)); + return; + } rstrm->recvsize = recvsize = fix_buf_size(recvsize); - rstrm->the_buffer = mem_alloc(sendsize + recvsize + BYTES_PER_XDR_UNIT); - if (rstrm->the_buffer == NULL) { + rstrm->in_base = mem_alloc(recvsize); + if (rstrm->in_base == NULL) { warnx("xdrrec_create: out of memory"); + mem_free(rstrm->out_base, sendsize); + mem_free(rstrm, sizeof(RECSTREAM)); return; } - for (rstrm->out_base = rstrm->the_buffer; - (u_long)rstrm->out_base % BYTES_PER_XDR_UNIT != 0; - rstrm->out_base++); - rstrm->in_base = rstrm->out_base + sendsize; /* * now the rest ... */ @@ -200,6 +216,12 @@ rstrm->in_finger = (rstrm->in_boundry += recvsize); rstrm->fbtbc = 0; rstrm->last_frag = TRUE; + rstrm->in_haveheader = FALSE; + rstrm->in_hdrlen = 0; + rstrm->in_hdrp = (char *)(void *)&rstrm->in_header; + rstrm->nonblock = FALSE; + rstrm->in_reclen = 0; + rstrm->in_received = 0; } @@ -413,8 +435,8 @@ { RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private; - mem_free(rstrm->the_buffer, - rstrm->sendsize + rstrm->recvsize + BYTES_PER_XDR_UNIT); + mem_free(rstrm->out_base, rstrm->sendsize); + mem_free(rstrm->in_base, rstrm->recvsize); mem_free(rstrm, sizeof(RECSTREAM)); } @@ -432,6 +454,20 @@ XDR *xdrs; { RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + enum xprt_stat xstat; + + if (rstrm->nonblock) { + if (__xdrrec_getrec(xdrs, &xstat, FALSE)) { + rstrm->fbtbc = 0; + return TRUE; + } + if (rstrm->in_finger == rstrm->in_boundry && + xstat == XPRT_MOREREQS) { + rstrm->fbtbc = 0; + return TRUE; + } + return FALSE; + } while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) { if (! skip_input_bytes(rstrm, rstrm->fbtbc)) @@ -454,6 +490,15 @@ XDR *xdrs; { RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + enum xprt_stat xstat; + + if (rstrm->nonblock) { + if (__xdrrec_getrec(xdrs, &xstat, FALSE)) + return FALSE; + if (!rstrm->in_haveheader && xstat == XPRT_IDLE) + return TRUE; + return FALSE; + } while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) { if (! skip_input_bytes(rstrm, rstrm->fbtbc)) @@ -495,6 +540,99 @@ return (TRUE); } +/* + * Fill the stream buffer with a record for a non-blocking connection. + * Return true if a record is available in the buffer, false if not. + */ +bool_t +__xdrrec_getrec(xdrs, statp, expectdata) + XDR *xdrs; + enum xprt_stat *statp; + bool_t expectdata; +{ + RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + ssize_t n; + int fraglen; + + if (!rstrm->in_haveheader) { + n = rstrm->readit(rstrm->tcp_handle, rstrm->in_hdrp, + (int)sizeof (rstrm->in_header) - rstrm->in_hdrlen); + if (n == 0) { + *statp = expectdata ? XPRT_DIED : XPRT_IDLE; + return FALSE; + } + if (n < 0) { + *statp = XPRT_DIED; + return FALSE; + } + rstrm->in_hdrp += n; + rstrm->in_hdrlen += n; + if (rstrm->in_hdrlen < sizeof (rstrm->in_header)) { + *statp = XPRT_MOREREQS; + return FALSE; + } + rstrm->in_header = ntohl(rstrm->in_header); + fraglen = (int)(rstrm->in_header & ~LAST_FRAG); + if (fraglen == 0 || fraglen > rstrm->in_maxrec || + (rstrm->in_reclen + fraglen) > rstrm->in_maxrec) { + *statp = XPRT_DIED; + return FALSE; + } + rstrm->in_reclen += fraglen; + if (rstrm->in_reclen > rstrm->recvsize) + realloc_stream(rstrm, rstrm->in_reclen); + if (rstrm->in_header & LAST_FRAG) { + rstrm->in_header &= ~LAST_FRAG; + rstrm->last_frag = TRUE; + } + } + + n = rstrm->readit(rstrm->tcp_handle, + rstrm->in_base + rstrm->in_received, + (rstrm->in_reclen - rstrm->in_received)); + + if (n < 0) { + *statp = XPRT_DIED; + return FALSE; + } + + if (n == 0) { + *statp = expectdata ? XPRT_DIED : XPRT_IDLE; + return FALSE; + } + + rstrm->in_received += n; + + if (rstrm->in_received == rstrm->in_reclen) { + rstrm->in_haveheader = FALSE; + rstrm->in_hdrp = (char *)(void *)&rstrm->in_header; + rstrm->in_hdrlen = 0; + if (rstrm->last_frag) { + rstrm->fbtbc = rstrm->in_reclen; + rstrm->in_boundry = rstrm->in_base + rstrm->in_reclen; + rstrm->in_finger = rstrm->in_base; + *statp = XPRT_MOREREQS; + return TRUE; + } + } + + *statp = XPRT_MOREREQS; + return FALSE; +} + +bool_t +__xdrrec_setnonblock(xdrs, maxrec) + XDR *xdrs; + int maxrec; +{ + RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + + rstrm->nonblock = TRUE; + if (maxrec == 0) + maxrec = rstrm->recvsize; + rstrm->in_maxrec = maxrec; + return TRUE; +} /* * Internal useful routines @@ -527,6 +665,9 @@ u_int32_t i; int len; + if (rstrm->nonblock) + return FALSE; + where = rstrm->in_base; i = (u_int32_t)((u_long)rstrm->in_boundry % BYTES_PER_XDR_UNIT); where += i; @@ -618,4 +759,30 @@ if (s < 100) s = 4000; return (RNDUP(s)); +} + +/* + * Reallocate the input buffer for a non-block stream. + */ +static bool_t +realloc_stream(rstrm, size) + RECSTREAM *rstrm; + int size; +{ + ptrdiff_t diff; + char *buf; + + if (size > rstrm->recvsize) { + buf = realloc(rstrm->in_base, (size_t)size); + if (buf == NULL) + return FALSE; + diff = buf - rstrm->in_base; + rstrm->in_finger += diff; + rstrm->in_base = buf; + rstrm->in_boundry = buf + size; + rstrm->recvsize = size; + rstrm->in_size = size; + } + + return TRUE; } Index: usr.sbin/mountd/mountd.c =================================================================== RCS file: /usr/home/ncvs/src/usr.sbin/mountd/mountd.c,v retrieving revision 1.70 diff -u -r1.70 mountd.c --- usr.sbin/mountd/mountd.c 16 Oct 2002 16:04:50 -0000 1.70 +++ usr.sbin/mountd/mountd.c 7 Jan 2003 14:08:45 -0000 @@ -273,6 +273,7 @@ struct netconfig *udpconf, *tcpconf, *udp6conf, *tcp6conf; int udpsock, tcpsock, udp6sock, tcp6sock; int xcreated = 0, s; + int maxrec = RPC_MAXDATASIZE; int one = 1; int c; @@ -354,6 +355,9 @@ tcpsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); udpconf = getnetconfigent("udp"); tcpconf = getnetconfigent("tcp"); + + rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec); + if (!have_v6) goto skip_v6; udp6sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); @@ -408,7 +412,7 @@ if (tcpsock != -1 && tcpconf != NULL) { bindresvport(tcpsock, NULL); listen(tcpsock, SOMAXCONN); - tcptransp = svc_vc_create(tcpsock, 0, 0); + tcptransp = svc_vc_create(tcpsock, RPC_MAXDATASIZE, RPC_MAXDATASIZE); if (tcptransp != NULL) { if (!svc_reg(tcptransp, RPCPROG_MNT, RPCMNT_VER1, mntsrv, tcpconf)) @@ -449,7 +453,7 @@ if (have_v6 && tcp6sock != -1 && tcp6conf != NULL) { bindresvport(tcp6sock, NULL); listen(tcp6sock, SOMAXCONN); - tcp6transp = svc_vc_create(tcp6sock, 0, 0); + tcp6transp = svc_vc_create(tcp6sock, RPC_MAXDATASIZE, RPC_MAXDATASIZE); if (tcp6transp != NULL) { if (!svc_reg(tcp6transp, RPCPROG_MNT, RPCMNT_VER1, mntsrv, tcp6conf)) Index: usr.sbin/rpc.lockd/lockd.c =================================================================== RCS file: /usr/home/ncvs/src/usr.sbin/rpc.lockd/lockd.c,v retrieving revision 1.13 diff -u -r1.13 lockd.c --- usr.sbin/rpc.lockd/lockd.c 11 Apr 2002 07:19:30 -0000 1.13 +++ usr.sbin/rpc.lockd/lockd.c 7 Jan 2003 14:08:45 -0000 @@ -95,6 +95,7 @@ struct sigaction sigalarm; int grace_period = 30; struct netconfig *nconf; + int maxrec = RPC_MAXDATASIZE; while ((ch = getopt(argc, argv, "d:g:")) != (-1)) { switch (ch) { @@ -139,13 +140,16 @@ maxindex = 4; } + rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec); + for (i = 0; i < maxindex; i++) { nconf = getnetconfigent(transports[i]); if (nconf == NULL) errx(1, "cannot get %s netconf: %s.", transports[i], nc_sperror()); - transp = svc_tli_create(RPC_ANYFD, nconf, NULL, 0, 0); + transp = svc_tli_create(RPC_ANYFD, nconf, NULL, + RPC_MAXDATASIZE, RPC_MAXDATASIZE); if (transp == NULL) { errx(1, "cannot create %s service.", transports[i]); /* NOTREACHED */ Index: usr.sbin/rpc.statd/statd.c =================================================================== RCS file: /usr/home/ncvs/src/usr.sbin/rpc.statd/statd.c,v retrieving revision 1.10 diff -u -r1.10 statd.c --- usr.sbin/rpc.statd/statd.c 15 Jul 2002 19:00:34 -0000 1.10 +++ usr.sbin/rpc.statd/statd.c 7 Jan 2003 14:08:45 -0000 @@ -61,6 +61,7 @@ main(int argc, char **argv) { struct sigaction sa; + int maxrec = RPC_MAXDATASIZE; if (argc > 1) { @@ -70,6 +71,8 @@ } (void)rpcb_unset(SM_PROG, SM_VERS, NULL); + + rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec); if (!svc_create(sm_prog_1, SM_PROG, SM_VERS, "udp")) errx(1, "cannot create udp service"); Index: usr.sbin/rpc.yppasswdd/yppasswdd_main.c =================================================================== RCS file: /usr/home/ncvs/src/usr.sbin/rpc.yppasswdd/yppasswdd_main.c,v retrieving revision 1.22 diff -u -r1.22 yppasswdd_main.c --- usr.sbin/rpc.yppasswdd/yppasswdd_main.c 11 May 2002 04:10:49 -0000 1.22 +++ usr.sbin/rpc.yppasswdd/yppasswdd_main.c 7 Jan 2003 14:08:45 -0000 @@ -171,6 +171,7 @@ int ch; char *mastername; char myname[MAXHOSTNAMELEN + 2]; + int maxrec = RPC_MAXDATASIZE; extern int debug; @@ -272,6 +273,8 @@ rpcb_unset(YPPASSWDPROG, YPPASSWDVERS, NULL); rpcb_unset(MASTER_YPPASSWDPROG, MASTER_YPPASSWDVERS, NULL); + + rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec); if (svc_create(yppasswdprog_1, YPPASSWDPROG, YPPASSWDVERS, "netpath") == 0) { yp_error("cannot create yppasswd service."); Index: usr.sbin/rpcbind/rpcb_svc_com.c =================================================================== RCS file: /usr/home/ncvs/src/usr.sbin/rpcbind/rpcb_svc_com.c,v retrieving revision 1.9 diff -u -r1.9 rpcb_svc_com.c --- usr.sbin/rpcbind/rpcb_svc_com.c 1 Jan 2003 18:49:03 -0000 1.9 +++ usr.sbin/rpcbind/rpcb_svc_com.c 7 Jan 2003 14:08:45 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: rpcb_svc_com.c,v 1.6 2000/08/03 00:07:22 fvdl Exp $ */ +/* $NetBSD: rpcb_svc_com.c,v 1.9 2002/11/08 00:16:39 fvdl Exp $ */ /* $FreeBSD: src/usr.sbin/rpcbind/rpcb_svc_com.c,v 1.9 2003/01/01 18:49:03 schweikh Exp $ */ /* @@ -1073,6 +1073,7 @@ #define MASKVAL (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND) +extern bool_t __svc_clean_idle(fd_set *, int, bool_t); void my_svc_run() @@ -1085,6 +1086,7 @@ int i; #endif register struct pollfd *p; + fd_set cleanfds; for (;;) { p = pollfds; @@ -1106,7 +1108,7 @@ fprintf(stderr, ">\n"); } #endif - switch (poll_ret = poll(pollfds, nfds, INFTIM)) { + switch (poll_ret = poll(pollfds, nfds, 30 * 1000)) { case -1: /* * We ignore all errors, continuing with the assumption @@ -1114,6 +1116,8 @@ * other outside event) and not caused by poll(). */ case 0: + cleanfds = svc_fdset; + __svc_clean_idle(&cleanfds, 30, FALSE); continue; default: #ifdef SVC_RUN_DEBUG Index: usr.sbin/rpcbind/rpcbind.c =================================================================== RCS file: /usr/home/ncvs/src/usr.sbin/rpcbind/rpcbind.c,v retrieving revision 1.10 diff -u -r1.10 rpcbind.c --- usr.sbin/rpcbind/rpcbind.c 1 Jan 2003 18:49:03 -0000 1.10 +++ usr.sbin/rpcbind/rpcbind.c 7 Jan 2003 14:08:45 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: rpcbind.c,v 1.1 2000/06/02 23:15:42 fvdl Exp $ */ +/* $NetBSD: rpcbind.c,v 1.3 2002/11/08 00:16:40 fvdl Exp $ */ /* $FreeBSD: src/usr.sbin/rpcbind/rpcbind.c,v 1.10 2003/01/01 18:49:03 schweikh Exp $ */ /* @@ -124,6 +124,7 @@ struct netconfig *nconf; void *nc_handle; /* Net config handle */ struct rlimit rl; + int maxrec = RPC_MAXDATASIZE; parseargs(argc, argv); @@ -165,6 +166,9 @@ syslog(LOG_ERR, "%s: can't find local transport\n", argv[0]); exit(1); } + + rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec); + init_transport(nconf); while ((nconf = getnetconfig(nc_handle))) { @@ -431,7 +435,7 @@ listen(fd, SOMAXCONN); my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr, - 0, 0); + RPC_MAXDATASIZE, RPC_MAXDATASIZE); if (my_xprt == (SVCXPRT *)NULL) { syslog(LOG_ERR, "%s: could not create service", nconf->nc_netid); @@ -491,7 +495,7 @@ if (nconf->nc_semantics != NC_TPI_CLTS) listen(fd, SOMAXCONN); - my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr, 0, 0); + my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr, RPC_MAXDATASIZE, RPC_MAXDATASIZE); if (my_xprt == (SVCXPRT *)NULL) { syslog(LOG_ERR, "%s: could not create service", nconf->nc_netid);