Ignore:
Timestamp:
Jul 5, 2010, 9:04:17 PM (11 years ago)
Author:
charles
Message:

(trunk libT) #3383 "When port forwarding, check to see if the public port matches the private port" -- fixed

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/natpmp.c

    r9868 r10945  
    4545struct tr_natpmp
    4646{
    47     tr_bool            isMapped;
    48     tr_bool            hasDiscovered;
    49     int                port;
    50     time_t             renewTime;
    51     time_t             commandTime;
    52     tr_natpmp_state    state;
    53     natpmp_t           natpmp;
     47    tr_bool           has_discovered;
     48    tr_bool           is_mapped;
     49
     50    tr_port           public_port;
     51    tr_port           private_port;
     52
     53    time_t            renew_time;
     54    time_t            command_time;
     55    tr_natpmp_state   state;
     56    natpmp_t          natpmp;
    5457};
    5558
     
    8083    nat = tr_new0( struct tr_natpmp, 1 );
    8184    nat->state = TR_NATPMP_DISCOVER;
    82     nat->port = -1;
     85    nat->public_port = 0;
     86    nat->private_port = 0;
    8387    nat->natpmp.s = -1; /* socket */
    8488    return nat;
     
    99103canSendCommand( const struct tr_natpmp * nat )
    100104{
    101     return tr_time( ) >= nat->commandTime;
     105    return tr_time( ) >= nat->command_time;
    102106}
    103107
     
    105109setCommandTime( struct tr_natpmp * nat )
    106110{
    107     nat->commandTime = tr_time( ) + COMMAND_WAIT_SECS;
     111    nat->command_time = tr_time( ) + COMMAND_WAIT_SECS;
    108112}
    109113
    110114int
    111 tr_natpmpPulse( struct tr_natpmp * nat,
    112                 int                port,
    113                 int                isEnabled )
     115tr_natpmpPulse( struct tr_natpmp * nat, tr_port private_port, tr_bool is_enabled, tr_port * public_port )
    114116{
    115117    int ret;
    116118
    117     if( isEnabled && ( nat->state == TR_NATPMP_DISCOVER ) )
     119    if( is_enabled && ( nat->state == TR_NATPMP_DISCOVER ) )
    118120    {
    119121        int val = initnatpmp( &nat->natpmp );
     
    122124        logVal( "sendpublicaddressrequest", val );
    123125        nat->state = val < 0 ? TR_NATPMP_ERR : TR_NATPMP_RECV_PUB;
    124         nat->hasDiscovered = 1;
     126        nat->has_discovered = TRUE;
    125127        setCommandTime( nat );
    126128    }
     
    129131    {
    130132        natpmpresp_t response;
    131         const int    val = readnatpmpresponseorretry( &nat->natpmp,
    132                                                       &response );
     133        const int val = readnatpmpresponseorretry( &nat->natpmp, &response );
    133134        logVal( "readnatpmpresponseorretry", val );
    134135        if( val >= 0 )
    135136        {
    136             tr_ninf( getKey( ), _(
    137                         "Found public address \"%s\"" ),
    138                     inet_ntoa( response.pnu.publicaddress.addr ) );
     137            tr_ninf( getKey( ), _( "Found public address \"%s\"" ),
     138                     inet_ntoa( response.pnu.publicaddress.addr ) );
    139139            nat->state = TR_NATPMP_IDLE;
    140140        }
     
    147147    if( ( nat->state == TR_NATPMP_IDLE ) || ( nat->state == TR_NATPMP_ERR ) )
    148148    {
    149         if( nat->isMapped && ( !isEnabled || ( nat->port != port ) ) )
     149        if( nat->is_mapped && ( !is_enabled || ( nat->private_port != private_port ) ) )
    150150            nat->state = TR_NATPMP_SEND_UNMAP;
    151151    }
     
    153153    if( ( nat->state == TR_NATPMP_SEND_UNMAP ) && canSendCommand( nat ) )
    154154    {
    155         const int val =
    156             sendnewportmappingrequest( &nat->natpmp, NATPMP_PROTOCOL_TCP,
    157                                        nat->port, nat->port,
    158                                        0 );
     155        const int val = sendnewportmappingrequest( &nat->natpmp, NATPMP_PROTOCOL_TCP,
     156                                                   nat->private_port,
     157                                                   nat->public_port,
     158                                                   0 );
    159159        logVal( "sendnewportmappingrequest", val );
    160160        nat->state = val < 0 ? TR_NATPMP_ERR : TR_NATPMP_RECV_UNMAP;
     
    163163
    164164    if( nat->state == TR_NATPMP_RECV_UNMAP )
     165    {
     166        natpmpresp_t resp;
     167        const int val = readnatpmpresponseorretry( &nat->natpmp, &resp );
     168        logVal( "readnatpmpresponseorretry", val );
     169        if( val >= 0 )
     170        {
     171            const int private_port = resp.pnu.newportmapping.privateport;
     172
     173            tr_ninf( getKey( ), _( "no longer forwarding port %d" ), private_port );
     174
     175            if( nat->private_port == private_port )
     176            {
     177                nat->private_port = 0;
     178                nat->public_port = 0;
     179                nat->state = TR_NATPMP_IDLE;
     180                nat->is_mapped = FALSE;
     181            }
     182        }
     183        else if( val != NATPMP_TRYAGAIN )
     184        {
     185            nat->state = TR_NATPMP_ERR;
     186        }
     187    }
     188
     189    if( nat->state == TR_NATPMP_IDLE )
     190    {
     191        if( is_enabled && !nat->is_mapped && nat->has_discovered )
     192            nat->state = TR_NATPMP_SEND_MAP;
     193
     194        else if( nat->is_mapped && tr_time( ) >= nat->renew_time )
     195            nat->state = TR_NATPMP_SEND_MAP;
     196    }
     197
     198    if( ( nat->state == TR_NATPMP_SEND_MAP ) && canSendCommand( nat ) )
     199    {
     200        const int val = sendnewportmappingrequest( &nat->natpmp, NATPMP_PROTOCOL_TCP, private_port, private_port, LIFETIME_SECS );
     201        logVal( "sendnewportmappingrequest", val );
     202        nat->state = val < 0 ? TR_NATPMP_ERR : TR_NATPMP_RECV_MAP;
     203        setCommandTime( nat );
     204    }
     205
     206    if( nat->state == TR_NATPMP_RECV_MAP )
    165207    {
    166208        natpmpresp_t resp;
     
    169211        if( val >= 0 )
    170212        {
    171             const int p = resp.pnu.newportmapping.privateport;
    172             tr_ninf( getKey( ), _( "no longer forwarding port %d" ), p );
    173             if( nat->port == p )
    174             {
    175                 nat->port = -1;
    176                 nat->state = TR_NATPMP_IDLE;
    177                 nat->isMapped = 0;
    178             }
     213            nat->state = TR_NATPMP_IDLE;
     214            nat->is_mapped = TRUE;
     215            nat->renew_time = tr_time( ) + LIFETIME_SECS;
     216            nat->private_port = resp.pnu.newportmapping.privateport;
     217            nat->public_port = resp.pnu.newportmapping.mappedpublicport;
     218            tr_ninf( getKey( ), _( "Port %d forwarded successfully" ), nat->private_port );
    179219        }
    180220        else if( val != NATPMP_TRYAGAIN )
     
    184224    }
    185225
    186     if( nat->state == TR_NATPMP_IDLE )
    187     {
    188         if( isEnabled && !nat->isMapped && nat->hasDiscovered )
    189             nat->state = TR_NATPMP_SEND_MAP;
    190 
    191         else if( nat->isMapped && tr_time( ) >= nat->renewTime )
    192             nat->state = TR_NATPMP_SEND_MAP;
    193     }
    194 
    195     if( ( nat->state == TR_NATPMP_SEND_MAP ) && canSendCommand( nat ) )
    196     {
    197         const int val =
    198             sendnewportmappingrequest( &nat->natpmp, NATPMP_PROTOCOL_TCP,
    199                                        port,
    200                                        port,
    201                                        LIFETIME_SECS );
    202         logVal( "sendnewportmappingrequest", val );
    203         nat->state = val < 0 ? TR_NATPMP_ERR : TR_NATPMP_RECV_MAP;
    204         setCommandTime( nat );
    205     }
    206 
    207     if( nat->state == TR_NATPMP_RECV_MAP )
    208     {
    209         natpmpresp_t resp;
    210         const int    val = readnatpmpresponseorretry( &nat->natpmp, &resp );
    211         logVal( "readnatpmpresponseorretry", val );
    212         if( val >= 0 )
    213         {
    214             nat->state = TR_NATPMP_IDLE;
    215             nat->isMapped = 1;
    216             nat->renewTime = tr_time( ) + LIFETIME_SECS;
    217             nat->port = resp.pnu.newportmapping.privateport;
    218             tr_ninf( getKey( ), _(
    219                          "Port %d forwarded successfully" ), nat->port );
    220         }
    221         else if( val != NATPMP_TRYAGAIN )
    222         {
    223             nat->state = TR_NATPMP_ERR;
    224         }
    225     }
    226 
    227226    switch( nat->state )
    228227    {
    229228        case TR_NATPMP_IDLE:
    230             ret = nat->isMapped ? TR_PORT_MAPPED : TR_PORT_UNMAPPED; break;
     229            *public_port = nat->public_port;
     230            return nat->is_mapped ? TR_PORT_MAPPED : TR_PORT_UNMAPPED;
     231            break;
    231232
    232233        case TR_NATPMP_DISCOVER:
Note: See TracChangeset for help on using the changeset viewer.