summaryrefslogtreecommitdiff
path: root/lib/libc/rpc/svc_tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/rpc/svc_tcp.c')
-rw-r--r--lib/libc/rpc/svc_tcp.c97
1 files changed, 62 insertions, 35 deletions
diff --git a/lib/libc/rpc/svc_tcp.c b/lib/libc/rpc/svc_tcp.c
index 9d19504858fb..1387ee126620 100644
--- a/lib/libc/rpc/svc_tcp.c
+++ b/lib/libc/rpc/svc_tcp.c
@@ -5,23 +5,23 @@
* 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
@@ -30,11 +30,11 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)svc_tcp.c 2.2 88/08/01 4.0 RPCSRC";*/
-static char *rcsid = "$Id: svc_tcp.c,v 1.1 1993/10/27 05:41:02 paul Exp $";
+static char *rcsid = "$Id: svc_tcp.c,v 1.8 1996/12/30 15:19:08 peter Exp $";
#endif
/*
- * svc_tcp.c, Server side for TCP/IP based RPC.
+ * svc_tcp.c, Server side for TCP/IP based RPC.
*
* Copyright (C) 1984, Sun Microsystems, Inc.
*
@@ -44,11 +44,12 @@ static char *rcsid = "$Id: svc_tcp.c,v 1.1 1993/10/27 05:41:02 paul Exp $";
*/
#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
#include <rpc/rpc.h>
#include <sys/socket.h>
#include <errno.h>
-extern bool_t abort();
-extern errno;
/*
* Ops vector for TCP/IP based rpc service handle
@@ -78,9 +79,9 @@ static enum xprt_stat rendezvous_stat();
static struct xp_ops svctcp_rendezvous_op = {
rendezvous_request,
rendezvous_stat,
- abort,
- abort,
- abort,
+ (bool_t (*)())abort,
+ (bool_t (*)())abort,
+ (bool_t (*)())abort,
svctcp_destroy
};
@@ -138,7 +139,8 @@ svctcp_create(sock, sendsize, recvsize)
}
madesock = TRUE;
}
- bzero((char *)&addr, sizeof (addr));
+ memset(&addr, 0, sizeof (addr));
+ addr.sin_len = sizeof(struct sockaddr_in);
addr.sin_family = AF_INET;
if (bindresvport(sock, &addr)) {
addr.sin_port = 0;
@@ -195,7 +197,7 @@ makefd_xprt(fd, sendsize, recvsize)
{
register SVCXPRT *xprt;
register struct tcp_conn *cd;
-
+
xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
if (xprt == (SVCXPRT *)NULL) {
(void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n");
@@ -242,6 +244,14 @@ rendezvous_request(xprt)
return (FALSE);
}
/*
+ * XXX careful for ftp bounce attacks. If discovered, close the
+ * socket and look for another connection.
+ */
+ if (addr.sin_port == htons(20)) {
+ close(sock);
+ goto again;
+ }
+ /*
* make a new transporter (re-uses xprt)
*/
xprt = makefd_xprt(sock, r->sendsize, r->recvsize);
@@ -294,35 +304,52 @@ readtcp(xprt, buf, len)
register int len;
{
register int sock = xprt->xp_sock;
-#ifdef FD_SETSIZE
- fd_set mask;
- fd_set readfds;
-
- FD_ZERO(&mask);
- FD_SET(sock, &mask);
-#else
- register int mask = 1 << sock;
- int readfds;
-#endif /* def FD_SETSIZE */
+ struct timeval start, delta, tv;
+ struct timeval tmp1, tmp2;
+ fd_set *fds, readfds;
+
+ if (sock + 1 > FD_SETSIZE) {
+ int bytes = howmany(sock+1, NFDBITS) * sizeof(fd_mask);
+ fds = (fd_set *)malloc(bytes);
+
+ if (fds == NULL)
+ goto fatal_err;
+ memset(fds, 0, bytes);
+ } else {
+ fds = &readfds;
+ FD_ZERO(fds);
+ }
+
+ delta = wait_per_try;
+ gettimeofday(&start, NULL);
do {
- readfds = mask;
- if (select(_rpc_dtablesize(), &readfds, (int*)NULL, (int*)NULL,
- &wait_per_try) <= 0) {
- if (errno == EINTR) {
- continue;
- }
+ /* XXX we know the other bits are still clear */
+ FD_SET(sock, fds);
+ tv = delta; /* in case select() implements writeback */
+ switch (select(sock + 1, fds, NULL, NULL, &tv)) {
+ case -1:
+ if (errno != EINTR)
+ goto fatal_err;
+ gettimeofday(&tmp1, NULL);
+ timersub(&tmp1, &start, &tmp2);
+ timersub(&delta, &tmp2, &tmp1);
+ if (tmp1.tv_sec < 0 || !timerisset(&tmp1))
+ goto fatal_err;
+ delta = tmp1;
+ continue;
+ case 0:
goto fatal_err;
}
-#ifdef FD_SETSIZE
- } while (!FD_ISSET(sock, &readfds));
-#else
- } while (readfds != mask);
-#endif /* def FD_SETSIZE */
+ } while (!FD_ISSET(sock, fds));
if ((len = read(sock, buf, len)) > 0) {
+ if (fds != &readfds)
+ free(fds);
return (len);
}
fatal_err:
((struct tcp_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED;
+ if (fds != &readfds)
+ free(fds);
return (-1);
}