#848: UPnP users always have to wait for NAT-PMP to fail first

This commit is contained in:
Charles Kerr 2008-04-12 21:47:10 +00:00
parent d15a768045
commit 002ce54335
4 changed files with 40 additions and 45 deletions

View File

@ -69,7 +69,7 @@ logVal( const char * func, int ret )
else if( ret >= 0 )
tr_ninf( getKey(), _( "%s succeeded (%d)" ), func, ret );
else
tr_ninf( getKey(), _( "%s failed (%d): %s (%d)" ), func, ret, tr_strerror(errno), errno );
tr_ndbg( getKey(), "%s failed (%d): %s (%d)", func, ret, tr_strerror(errno), errno );
}
struct tr_natpmp*
@ -104,14 +104,6 @@ setCommandTime( struct tr_natpmp * nat )
nat->commandTime = time(NULL) + COMMAND_WAIT_SECS;
}
static void
setErrorState( struct tr_natpmp * nat )
{
tr_ninf( getKey(), _( "If your router supports NAT-PMP, please make sure NAT-PMP is enabled!" ) );
tr_ninf( getKey(), _( "NAT-PMP port forwarding unsuccessful, trying UPnP next" ) );
nat->state = TR_NATPMP_ERR;
}
int
tr_natpmpPulse( struct tr_natpmp * nat, int port, int isEnabled )
{
@ -137,7 +129,7 @@ tr_natpmpPulse( struct tr_natpmp * nat, int port, int isEnabled )
tr_ninf( getKey(), _( "Found public address \"%s\"" ), inet_ntoa( response.publicaddress.addr ) );
nat->state = TR_NATPMP_IDLE;
} else if( val != NATPMP_TRYAGAIN ) {
setErrorState( nat );
nat->state = TR_NATPMP_ERR;
}
}
@ -166,7 +158,7 @@ tr_natpmpPulse( struct tr_natpmp * nat, int port, int isEnabled )
nat->port = -1;
nat->isMapped = 0;
} else if( val != NATPMP_TRYAGAIN ) {
setErrorState( nat );
nat->state = TR_NATPMP_ERR;
}
}
@ -197,9 +189,9 @@ tr_natpmpPulse( struct tr_natpmp * nat, int port, int isEnabled )
nat->isMapped = 1;
nat->renewTime = time( NULL ) + LIFETIME_SECS;
nat->port = resp.newportmapping.privateport;
tr_ninf( getKey(), _( "port %d forwarded successfully" ), nat->port );
tr_ninf( getKey(), _( "Port %d forwarded successfully" ), nat->port );
} else if( val != NATPMP_TRYAGAIN ) {
setErrorState( nat );
nat->state = TR_NATPMP_ERR;
}
}

View File

@ -1,5 +1,5 @@
/******************************************************************************
* $Id:$
* $Id$
*
* Copyright (c) 2005-2008 Transmission authors and contributors
*
@ -42,21 +42,22 @@ static const char * getKey( void ) { return _( "Port Forwarding" ); }
struct tr_shared
{
unsigned int isEnabled : 1;
unsigned int isShuttingDown : 1;
tr_nat_traversal_status natpmpStatus;
tr_nat_traversal_status upnpStatus;
int bindPort;
int bindSocket;
int publicPort;
tr_handle * h;
tr_timer * pulseTimer;
/* Incoming connections */
int bindPort;
int bindSocket;
/* port forwarding */
int isEnabled;
int publicPort;
tr_nat_traversal_status natStatus;
tr_upnp * upnp;
tr_upnp * upnp;
tr_natpmp * natpmp;
int isShuttingDown;
};
/***
@ -85,19 +86,20 @@ getNatStateStr( int state )
static void
natPulse( tr_shared * s )
{
tr_nat_traversal_status status;
const int port = s->publicPort;
const int isEnabled = s->isEnabled && !s->isShuttingDown;
int oldStatus;
int newStatus;
oldStatus = tr_sharedTraversalStatus( s );
s->natpmpStatus = tr_natpmpPulse( s->natpmp, port, isEnabled );
s->upnpStatus = tr_upnpPulse( s->upnp, port, isEnabled );
newStatus = tr_sharedTraversalStatus( s );
status = tr_natpmpPulse( s->natpmp, port, isEnabled );
if( status == TR_NAT_TRAVERSAL_ERROR )
status = tr_upnpPulse( s->upnp, port, isEnabled );
if( status != s->natStatus ) {
tr_ninf( getKey(), _( "State changed from \"%s\" to \"%s\"" ), getNatStateStr(s->natStatus), getNatStateStr(status) );
s->natStatus = status;
if( status == TR_NAT_TRAVERSAL_ERROR )
tr_nerr( getKey(), _( "Port forwarding failed." ) );
}
if( newStatus != oldStatus )
tr_ninf( getKey(), _( "State changed from \"%s\" to \"%s\"" ),
getNatStateStr(oldStatus),
getNatStateStr(newStatus) );
}
static void
@ -189,7 +191,8 @@ tr_sharedInit( tr_handle * h, int isEnabled, int publicPort )
s->upnp = tr_upnpInit();
s->pulseTimer = tr_timerNew( h, sharedPulse, s, 500 );
s->isEnabled = isEnabled ? 1 : 0;
s->natStatus = TR_NAT_TRAVERSAL_UNMAPPED;
s->upnpStatus = TR_NAT_TRAVERSAL_UNMAPPED;
s->natpmpStatus = TR_NAT_TRAVERSAL_UNMAPPED;
return s;
}
@ -226,5 +229,5 @@ tr_sharedTraversalEnable( tr_shared * s, int isEnabled )
int
tr_sharedTraversalStatus( const tr_shared * s )
{
return s->natStatus;
return MAX( s->natpmpStatus, s->upnpStatus );
}

View File

@ -219,11 +219,11 @@ int tr_getPublicPort( const tr_handle * );
typedef enum
{
TR_NAT_TRAVERSAL_MAPPING,
TR_NAT_TRAVERSAL_MAPPED,
TR_NAT_TRAVERSAL_UNMAPPING,
TR_NAT_TRAVERSAL_UNMAPPED,
TR_NAT_TRAVERSAL_ERROR,
TR_NAT_TRAVERSAL_UNMAPPED,
TR_NAT_TRAVERSAL_UNMAPPING,
TR_NAT_TRAVERSAL_MAPPING,
TR_NAT_TRAVERSAL_MAPPED
}
tr_nat_traversal_status;

View File

@ -88,7 +88,7 @@ tr_upnpPulse( tr_upnp * handle, int port, int isEnabled )
errno = 0;
devlist = upnpDiscover( 2000, NULL, NULL );
if( devlist == NULL ) {
tr_ninf( getKey(), _( "upnpDiscover failed (errno %d - %s)" ), errno, tr_strerror(errno) );
tr_ndbg( getKey(), "upnpDiscover failed (errno %d - %s)", errno, tr_strerror(errno) );
}
errno = 0;
if( UPNP_GetValidIGD( devlist, &handle->urls, &handle->data, handle->lanaddr, sizeof(handle->lanaddr))) {
@ -98,8 +98,8 @@ tr_upnpPulse( tr_upnp * handle, int port, int isEnabled )
handle->hasDiscovered = 1;
} else {
handle->state = TR_UPNP_ERR;
tr_ninf( getKey(), _( "UPNP_GetValidIGD failed (errno %d - %s)" ), errno, tr_strerror(errno) );
tr_ninf( getKey(), _( "If your router supports UPnP, please make sure UPnP is enabled!" ) );
tr_ndbg( getKey(), "UPNP_GetValidIGD failed (errno %d - %s)", errno, tr_strerror(errno) );
tr_ndbg( getKey(), "If your router supports UPnP, please make sure UPnP is enabled!" );
}
freeUPNPDevlist( devlist );
}
@ -153,8 +153,8 @@ tr_upnpPulse( tr_upnp * handle, int port, int isEnabled )
handle->port = port;
handle->state = TR_UPNP_IDLE;
} else {
tr_ninf( getKey(), _( "Port forwarding failed with error %d (errno %d - %s)" ), err, errno, tr_strerror(errno) );
tr_ninf( getKey(), _( "If your router supports UPnP, please make sure UPnP is enabled!" ) );
tr_ndbg( getKey(), "Port forwarding failed with error %d (errno %d - %s)", err, errno, tr_strerror(errno) );
tr_ndbg( getKey(), "If your router supports UPnP, please make sure UPnP is enabled!" );
handle->port = -1;
handle->state = TR_UPNP_ERR;
}