miniupnpd: AddAnyPortMapping() tries port above and below requested port
fixes #465 if the requested port is n, it will tries successively : n, n+1, n-1, n+2, n-2, n+3, n-3, etc.
This commit is contained in:
parent
1e7fb305b6
commit
de71eef493
|
@ -586,7 +586,7 @@ AddAnyPortMapping(struct upnphttp * h, const char * action, const char * ns)
|
|||
struct NameValueParserData data;
|
||||
const char * int_ip, * int_port, * ext_port, * protocol, * desc;
|
||||
const char * r_host;
|
||||
unsigned short iport, eport;
|
||||
unsigned short iport, eport, eport_below, eport_above;
|
||||
const char * leaseduration_str;
|
||||
unsigned int leaseduration;
|
||||
|
||||
|
@ -669,22 +669,37 @@ AddAnyPortMapping(struct upnphttp * h, const char * action, const char * ns)
|
|||
}
|
||||
}
|
||||
|
||||
/* TODO : accept a different external port
|
||||
* have some smart strategy to choose the port */
|
||||
/* first try the port asked in request, then
|
||||
* try +1, -1, +2, -2, etc. */
|
||||
eport_above = eport_below = eport;
|
||||
for(;;) {
|
||||
r = upnp_redirect(r_host, eport, int_ip, iport, protocol, desc, leaseduration);
|
||||
if((r==-2 || r==-3) && eport < 65535) {
|
||||
/* next port if -2 already redirected or -3 permission check failed */
|
||||
eport++;
|
||||
} else {
|
||||
if (r == 0 || r == -1) {
|
||||
/* OK or failure : Stop */
|
||||
break;
|
||||
}
|
||||
/* r : -2 / -4 already redirected or -3 permission check failed */
|
||||
if (eport_below <= 1 && eport_above == 65535) {
|
||||
/* all possible ports tried */
|
||||
r = 1;
|
||||
break;
|
||||
}
|
||||
if (eport_above == 65535 || (eport > eport_below && eport_below > 1)) {
|
||||
eport = --eport_below;
|
||||
} else {
|
||||
eport = ++eport_above;
|
||||
}
|
||||
/* loop invariant :
|
||||
* eport is equal to either eport_below or eport_above (or both) */
|
||||
}
|
||||
|
||||
ClearNameValueList(&data);
|
||||
|
||||
switch(r)
|
||||
{
|
||||
case 1: /* exhausted possible mappings */
|
||||
SoapError(h, 728, "NoPortMapsAvailable");
|
||||
break;
|
||||
case 0: /* success */
|
||||
bodylen = snprintf(body, sizeof(body), resp,
|
||||
action, ns, /*SERVICE_TYPE_WANIPC,*/
|
||||
|
|
Loading…
Reference in New Issue