miniupnpd/natpmp.c: Properly implements NAT-PMP mapping removal
fixes #97
This commit is contained in:
parent
8baf8d351a
commit
350ca199c4
|
@ -1,5 +1,8 @@
|
|||
$Id: Changelog.txt,v 1.379 2014/10/22 08:52:17 nanard Exp $
|
||||
|
||||
2014/10/23:
|
||||
Properly implements NAT-PMP mapping removal according to RCF6886
|
||||
|
||||
2014/10/22:
|
||||
Discard NAT-PMP packets coming from the WAN
|
||||
Send SSDP announces to IPv6 link-local, site-local
|
||||
|
|
|
@ -306,19 +306,23 @@ void ProcessIncomingNATPMPPacket(int s, unsigned char *msg_buff, int len,
|
|||
"%hu->%s:%hu %s lifetime=%us",
|
||||
eport, senderaddrstr, iport,
|
||||
(req[1]==1)?"udp":"tcp", lifetime);
|
||||
if(eport==0)
|
||||
eport = iport;
|
||||
/* TODO: accept port mapping if iport ok but eport not ok
|
||||
* (and set eport correctly) */
|
||||
if(lifetime == 0) {
|
||||
/* remove the mapping */
|
||||
if(iport == 0) {
|
||||
/* remove all the mappings for this client */
|
||||
/* RFC6886 :
|
||||
* A client MAY also send an explicit packet to request deletion of a
|
||||
* mapping that is no longer needed. A client requests explicit
|
||||
* deletion of a mapping by sending a message to the NAT gateway
|
||||
* requesting the mapping, with the Requested Lifetime in Seconds set to
|
||||
* zero. The Suggested External Port MUST be set to zero by the client
|
||||
* on sending, and MUST be ignored by the gateway on reception. */
|
||||
int index = 0;
|
||||
unsigned short eport2, iport2;
|
||||
char iaddr2[16];
|
||||
int proto2;
|
||||
char desc[64];
|
||||
eport = 0; /* to indicate correct removing of port mapping */
|
||||
while(get_redirect_rule_by_index(index, 0,
|
||||
&eport2, iaddr2, sizeof(iaddr2),
|
||||
&iport2, &proto2,
|
||||
|
@ -328,11 +332,14 @@ void ProcessIncomingNATPMPPacket(int s, unsigned char *msg_buff, int len,
|
|||
index, proto2, eport2, iaddr2, iport2, desc);
|
||||
if(0 == strcmp(iaddr2, senderaddrstr)
|
||||
&& 0 == memcmp(desc, "NAT-PMP", 7)) {
|
||||
/* (iport == 0) => remove all the mappings for this client */
|
||||
if((iport == 0) || ((iport == iport2) && (proto == proto2))) {
|
||||
r = _upnp_delete_redir(eport2, proto2);
|
||||
/* TODO : check return value */
|
||||
if(r<0) {
|
||||
syslog(LOG_ERR, "failed to remove port mapping");
|
||||
index++;
|
||||
if(r < 0) {
|
||||
syslog(LOG_ERR, "Failed to remove NAT-PMP mapping eport %hu, protocol %s",
|
||||
eport2, (proto2==IPPROTO_TCP)?"TCP":"UDP");
|
||||
resp[3] = 2; /* Not Authorized/Refused */
|
||||
break;
|
||||
} else {
|
||||
syslog(LOG_INFO, "NAT-PMP %s port %hu mapping removed",
|
||||
proto2==IPPROTO_TCP?"TCP":"UDP", eport2);
|
||||
|
@ -341,25 +348,15 @@ void ProcessIncomingNATPMPPacket(int s, unsigned char *msg_buff, int len,
|
|||
index++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* To improve the interworking between nat-pmp and
|
||||
* UPnP, we should check that we remove only NAT-PMP
|
||||
* mappings */
|
||||
r = _upnp_delete_redir(eport, proto);
|
||||
/*syslog(LOG_DEBUG, "%hu %d r=%d", eport, proto, r);*/
|
||||
if(r<0) {
|
||||
syslog(LOG_ERR, "Failed to remove NAT-PMP mapping eport %hu, protocol %s",
|
||||
eport, (proto==IPPROTO_TCP)?"TCP":"UDP");
|
||||
resp[3] = 2; /* Not Authorized/Refused */
|
||||
}
|
||||
}
|
||||
eport = 0; /* to indicate correct removing of port mapping */
|
||||
} else if(iport==0) {
|
||||
resp[3] = 2; /* Not Authorized/Refused */
|
||||
} else { /* iport > 0 && lifetime > 0 */
|
||||
unsigned short eport_first = 0;
|
||||
int any_eport_allowed = 0;
|
||||
char desc[64];
|
||||
if(eport==0) /* if no suggested external port, use same a internal port */
|
||||
eport = iport;
|
||||
while(resp[3] == 0) {
|
||||
if(eport_first == 0) { /* first time in loop */
|
||||
eport_first = eport;
|
||||
|
|
Loading…
Reference in New Issue