miniupnpd/natpmp.c: avoid hang when all external ports in use
The NAT-PMP code attempts to find a different eport if the requested one is already in use. If all eports are in use, that would previously cause the code to iterate through the range of eports forever. To avoid this case, we keep track of the first eport we attempted to use and abort the loop once we've cycled through all possible values exactly once (which takes us back to the initial eport).
This commit is contained in:
parent
c492b6f56f
commit
c6a8879c87
|
@ -205,6 +205,7 @@ void ProcessIncomingNATPMPPacket(int s, unsigned char *msg_buff, int len,
|
|||
int proto;
|
||||
char iaddr_old[16];
|
||||
unsigned short iport_old;
|
||||
unsigned short eport_first;
|
||||
unsigned int timestamp;
|
||||
|
||||
iport = ntohs(*((uint16_t *)(req+4)));
|
||||
|
@ -266,7 +267,9 @@ void ProcessIncomingNATPMPPacket(int s, unsigned char *msg_buff, int len,
|
|||
} else if(iport==0
|
||||
|| !check_upnp_rule_against_permissions(upnppermlist, num_upnpperm, eport, senderaddr->sin_addr, iport)) {
|
||||
resp[3] = 2; /* Not Authorized/Refused */
|
||||
} else do {
|
||||
} else {
|
||||
eport_first = eport;
|
||||
do {
|
||||
r = get_redirect_rule(ext_if_name, eport, proto,
|
||||
iaddr_old, sizeof(iaddr_old),
|
||||
&iport_old, 0, 0, 0, 0,
|
||||
|
@ -284,6 +287,12 @@ void ProcessIncomingNATPMPPacket(int s, unsigned char *msg_buff, int len,
|
|||
}
|
||||
} else {
|
||||
eport++;
|
||||
if(eport == eport_first) { /* no external port available */
|
||||
syslog(LOG_ERR, "Failed to find available eport for NAT-PMP %hu %s->%s:%hu",
|
||||
eport, (proto==IPPROTO_TCP)?"tcp":"udp", senderaddrstr, iport);
|
||||
resp[3] = 3; /* Failure */
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -316,6 +325,7 @@ void ProcessIncomingNATPMPPacket(int s, unsigned char *msg_buff, int len,
|
|||
break;
|
||||
}
|
||||
} while(r==0);
|
||||
}
|
||||
*((uint16_t *)(resp+8)) = htons(iport); /* private port */
|
||||
*((uint16_t *)(resp+10)) = htons(eport); /* public port */
|
||||
*((uint32_t *)(resp+12)) = htonl(lifetime); /* Port Mapping lifetime */
|
||||
|
|
Loading…
Reference in New Issue