forked from mirrors/tftp-hpa-google
Cleaner version implementing port range
This commit is contained in:
parent
ae1305e2d5
commit
4187af0e6f
1 changed files with 35 additions and 25 deletions
|
@ -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,31 +748,10 @@ 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) {
|
|
||||||
unsigned int port;
|
|
||||||
|
|
||||||
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");
|
syslog(LOG_ERR, "bind: %m");
|
||||||
exit(EX_IOERR);
|
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");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue