Cleaner version implementing port range

This commit is contained in:
Peter Anvin 2005-10-13 11:41:37 -07:00
parent ae1305e2d5
commit 4187af0e6f

View file

@ -273,6 +273,37 @@ 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) {
if ( portrange && (errno == EINVAL || errno == EADDRINUSE) )
continue; /* Should not happen in normal operation, but try again */
return -1;
} else {
return 0;
}
port++;
if ( port > portrange_to )
port = portrange_from;
} while ( port != firstport );
return -1;
}
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
@ -717,32 +748,11 @@ main(int argc, char **argv)
from.sin_family = AF_INET; from.sin_family = AF_INET;
/* Process the request... */ /* Process the request... */
if (pick_port_bind(peer, &myaddr) < 0) {
while(1) { syslog(LOG_ERR, "bind: %m");
unsigned int port; exit(EX_IOERR);
if ( portrange ) {
/* Pick a (pseudo)random port in the relevant range */
port = portrange_from + rand() % (portrange_to-portrange_from+1);
} else {
port = 0; /* Let the kernel pick a port */
}
myaddr.sin_port = htons(port);
if (bind(peer, (struct sockaddr *)&myaddr, sizeof myaddr) < 0) {
if ( (errno == EINVAL || errno == EADDRINUSE) && portrange )
continue; /* Should not happen in normal operation, but try again */
syslog(LOG_ERR, "bind: %m");
exit(EX_IOERR);
} else {
break;
}
} }
if (connect(peer, (struct sockaddr *)&from, sizeof from) < 0) { if (connect(peer, (struct sockaddr *)&from, sizeof from) < 0) {
syslog(LOG_ERR, "connect: %m"); syslog(LOG_ERR, "connect: %m");
exit(EX_IOERR); exit(EX_IOERR);