summaryrefslogtreecommitdiffstats
path: root/lib/libc/rpc/pmap_rmt.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1996-12-30 14:53:20 +0000
committerpeter <peter@FreeBSD.org>1996-12-30 14:53:20 +0000
commit9f036a4d01cb1d8904bd1fbbc7242bc3f3846259 (patch)
treedfcedc3fc968f3c96a7c710b89beadf8b929be23 /lib/libc/rpc/pmap_rmt.c
parentfda0320ff7886a8cb08bbc107fbe50642eb1fc90 (diff)
downloadFreeBSD-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/libc/rpc/pmap_rmt.c')
-rw-r--r--lib/libc/rpc/pmap_rmt.c81
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);
}
OpenPOWER on IntegriCloud