Moved pick_port_bind() to the libcommon common code so both client and server can use it. Client can now specify a range of ephemeral ports (transaction id)

This commit is contained in:
Zack Bartel 2006-11-13 17:33:29 -08:00
parent 5f64014add
commit ec5973ac5f
4 changed files with 56 additions and 34 deletions

View file

@ -273,38 +273,6 @@ static int recv_time(int s, void *rbuf, int len, unsigned int flags,
}
}
static int
pick_port_bind(int sockfd, struct sockaddr_in *myaddr)
{
unsigned int port, firstport;
firstport = portrange
? portrange_from + rand() % (portrange_to-portrange_from+1)
: 0;
port = firstport;
do {
myaddr->sin_port = htons(port);
if (bind(sockfd, (struct sockaddr *)myaddr, sizeof *myaddr) < 0) {
/* Some versions of Linux return EINVAL instead of EADDRINUSE */
if ( !(portrange && (errno == EINVAL || errno == EADDRINUSE)) )
return -1;
/* Normally, we shouldn't have to loop, but some situations involving
aborted transfers make it possible. */
} else {
return 0;
}
port++;
if ( port > portrange_to )
port = portrange_from;
} while ( port != firstport );
return -1;
}
int
main(int argc, char **argv)
@ -750,7 +718,7 @@ main(int argc, char **argv)
from.sin_family = AF_INET;
/* Process the request... */
if (pick_port_bind(peer, &myaddr) < 0) {
if (pick_port_bind(peer, &myaddr, portrange_from, portrange_to) < 0) {
syslog(LOG_ERR, "bind: %m");
exit(EX_IOERR);
}