diff options
author | peter <peter@FreeBSD.org> | 1996-12-30 14:53:20 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1996-12-30 14:53:20 +0000 |
commit | 9f036a4d01cb1d8904bd1fbbc7242bc3f3846259 (patch) | |
tree | dfcedc3fc968f3c96a7c710b89beadf8b929be23 /lib | |
parent | fda0320ff7886a8cb08bbc107fbe50642eb1fc90 (diff) | |
download | FreeBSD-src-9f036a4d01cb1d8904bd1fbbc7242bc3f3846259.zip FreeBSD-src-9f036a4d01cb1d8904bd1fbbc7242bc3f3846259.tar.gz |
- prototype now in include file, plus no longer needed anyway
- fix timeout code
- better sequence number generation (for long running daemons)
- dont close an unopen socket
- use standard functions
- 64 bit type safe for wire protocols
- unlimited file descriptors
Obtained from: a diff of FreeBSD vs. OpenBSD/NetBSD rpc code.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libc/rpc/pmap_rmt.c | 81 |
1 files changed, 44 insertions, 37 deletions
diff --git a/lib/libc/rpc/pmap_rmt.c b/lib/libc/rpc/pmap_rmt.c index b8cc248..b4b277b 100644 --- a/lib/libc/rpc/pmap_rmt.c +++ b/lib/libc/rpc/pmap_rmt.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)pmap_rmt.c 1.21 87/08/27 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)pmap_rmt.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$Id: pmap_rmt.c,v 1.7 1996/06/10 04:59:05 wpaul Exp $"; +static char *rcsid = "$Id: pmap_rmt.c,v 1.8 1996/08/12 14:00:23 peter Exp $"; #endif /* @@ -47,6 +47,7 @@ static char *rcsid = "$Id: pmap_rmt.c,v 1.7 1996/06/10 04:59:05 wpaul Exp $"; #include <rpc/pmap_rmt.h> #include <sys/socket.h> #include <stdio.h> +#include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> @@ -57,8 +58,6 @@ static char *rcsid = "$Id: pmap_rmt.c,v 1.7 1996/06/10 04:59:05 wpaul Exp $"; static struct timeval timeout = { 3, 0 }; -int _rpc_dtablesize(void); - /* * pmapper remote-call-service interface. * This routine is used to call the pmapper remote call service @@ -98,7 +97,8 @@ pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_pt } else { stat = RPC_FAILED; } - (void)close(socket); + if (socket != -1) + (void)close(socket); addr->sin_port = 0; return (stat); } @@ -169,11 +169,11 @@ getbroadcastnets(addrs, sock, buf) char *buf; /* why allocxate more when we can use existing... */ { struct ifconf ifc; - struct ifreq ifreq, *ifr; + struct ifreq ifreq, *ifr; struct sockaddr_in *sin; struct in_addr addr; - char *cp, *cplim; - int n, i = 0; + char *cp, *cplim; + int n, i = 0; ifc.ifc_len = UDPMSGSIZE; ifc.ifc_buf = buf; @@ -242,13 +242,7 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult) int outlen, inlen, fromlen, nets; register int sock; int on = 1; -#ifdef FD_SETSIZE - fd_set mask; - fd_set readfds; -#else - int readfds; - register int mask; -#endif /* def FD_SETSIZE */ + fd_set *fds, readfds; register int i; bool_t done = FALSE; register u_long xid; @@ -258,8 +252,12 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult) struct rmtcallargs a; struct rmtcallres r; struct rpc_msg msg; - struct timeval t; + struct timeval t, tv; char outbuf[MAX_BROADCAST_SIZE], inbuf[UDPMSGSIZE]; + static u_int32_t disrupt; + + if (disrupt == 0) + disrupt = (u_int32_t)(long)resultsp; /* * initialization: create a socket, a broadcast address, and @@ -277,21 +275,27 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult) goto done_broad; } #endif /* def SO_BROADCAST */ -#ifdef FD_SETSIZE - FD_ZERO(&mask); - FD_SET(sock, &mask); -#else - mask = (1 << sock); -#endif /* def FD_SETSIZE */ + if (sock + 1 > FD_SETSIZE) { + int bytes = howmany(sock + 1, NFDBITS) * sizeof(fd_mask); + fds = (fd_set *)malloc(bytes); + if (fds == NULL) { + stat = RPC_CANTSEND; + goto done_broad; + } + memset(fds, 0, bytes); + } else { + fds = &readfds; + FD_ZERO(fds); + } + nets = getbroadcastnets(addrs, sock, inbuf); - bzero((char *)&baddr, sizeof (baddr)); + memset(&baddr, 0, sizeof (baddr)); baddr.sin_len = sizeof(struct sockaddr_in); baddr.sin_family = AF_INET; baddr.sin_port = htons(PMAPPORT); baddr.sin_addr.s_addr = htonl(INADDR_ANY); -/* baddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); */ (void)gettimeofday(&t, (struct timezone *)0); - msg.rm_xid = xid = getpid() ^ t.tv_sec ^ t.tv_usec; + msg.rm_xid = xid = (++disrupt) ^ getpid() ^ t.tv_sec ^ t.tv_usec; t.tv_usec = 0; msg.rm_direction = CALL; msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; @@ -318,6 +322,12 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult) /* * Basic loop: broadcast a packet and wait a while for response(s). * The response timeout grows larger per iteration. + * + * XXX This will loop about 5 times the stop. If there are + * lots of signals being received by the process it will quit + * send them all in one quick burst, not paying attention to + * the intended function of sending them slowly over half a + * minute or so */ for (t.tv_sec = 4; t.tv_sec <= 14; t.tv_sec += 2) { for (i = 0; i < nets; i++) { @@ -337,10 +347,11 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult) recv_again: msg.acpted_rply.ar_verf = _null_auth; msg.acpted_rply.ar_results.where = (caddr_t)&r; - msg.acpted_rply.ar_results.proc = xdr_rmtcallres; - readfds = mask; - switch (select(_rpc_dtablesize(), &readfds, (fd_set *)NULL, - (fd_set *)NULL, &t)) { + msg.acpted_rply.ar_results.proc = xdr_rmtcallres; + /* XXX we know the other bits are still clear */ + FD_SET(sock, fds); + tv = t; /* for select() that copies back */ + switch (select(sock + 1, fds, NULL, NULL, &tv)) { case 0: /* timed out */ stat = RPC_TIMEDOUT; @@ -365,7 +376,7 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult) stat = RPC_CANTRECV; goto done_broad; } - if (inlen < sizeof(u_long)) + if (inlen < sizeof(u_int32_t)) goto recv_again; /* * see if reply transaction id matches sent id. @@ -380,13 +391,6 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult) done = (*eachresult)(resultsp, &raddr); } /* otherwise, we just ignore the errors ... */ - } else { -#ifdef notdef - /* some kind of deserialization problem ... */ - if (msg.rm_xid == xid) - fprintf(stderr, "Broadcast deserialization problem"); - /* otherwise, just random garbage */ -#endif } xdrs->x_op = XDR_FREE; msg.acpted_rply.ar_results.proc = xdr_void; @@ -401,7 +405,10 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult) } } done_broad: - (void)close(sock); + if (fds != &readfds) + free(fds); + if (sock >= 0) + (void)close(sock); AUTH_DESTROY(unix_auth); return (stat); } |