[PATCH] Fix NAT-PMP race between renewal and expiry

Ask for help and report issues not specific to either the Mac OS X or GTK+ versions of Transmission
Post Reply
bodgit
Posts: 2
Joined: Sun Nov 07, 2010 2:45 pm

[PATCH] Fix NAT-PMP race between renewal and expiry

Post by bodgit »

Hi,

Found another two small NAT-PMP related bugs. When Transmission requests a mapping with the default lifetime (1 hour) the NAT-PMP IETF draft specifies that the gateway MAY reduce the lifetime but SHOULDN'T increase it beyond what the client requested. Currently Transmission assumes that the lifetime of 1 hour in the request is always honoured.

In addition, the draft specifies that the client SHOULD begin to renew the mapping halfway through the lifetime, so assuming the 1 hour lifetime is honoured, Transmission should attempt to renew the mapping after 30 minutes. Currently Transmission sets the renewal 1 hour in the future so there is a small chance of the NAT-PMP gateway expiring the mapping before Transmission has chance to renew it (excluding the behaviour in the first bug above). This means that Transmission may get a different external port upon renewal.

Patch below fixes both bugs by setting the renewal time to be half of the lifetime returned by the gateway:


Index: libtransmission/natpmp.c
===================================================================
--- libtransmission/natpmp.c (revision 11389)
+++ libtransmission/natpmp.c (working copy)
@@ -212,7 +212,7 @@
{
nat->state = TR_NATPMP_IDLE;
nat->is_mapped = TRUE;
- nat->renew_time = tr_time( ) + LIFETIME_SECS;
+ nat->renew_time = tr_time( ) + ( resp.pnu.newportmapping.lifetime / 2 );
nat->private_port = resp.pnu.newportmapping.privateport;
nat->public_port = resp.pnu.newportmapping.mappedpublicport;
tr_ninf( getKey( ), _( "Port %d forwarded successfully" ), nat->private_port );

Cheers

Matt
Post Reply