- 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.
This commit is contained in:
parent
fadfbc36c6
commit
b93e2c954d
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user