Changeset 10945


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

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

Location:
trunk/libtransmission
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/announcer.c

    r10918 r10945  
    746746                              torrent->info.hashEscaped,
    747747                              torrent->peer_id,
    748                               (int)tr_sessionGetPeerPort( announcer->session ),
     748                              (int)tr_sessionGetPublicPeerPort( announcer->session ),
    749749                              tier->byteCounts[TR_ANN_UP],
    750750                              tier->byteCounts[TR_ANN_DOWN],
  • 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:
  • trunk/libtransmission/natpmp.h

    r9868 r10945  
    2727tr_natpmp * tr_natpmpInit( void );
    2828
    29 void        tr_natpmpClose( tr_natpmp * );
     29void tr_natpmpClose( tr_natpmp * );
    3030
    31 int         tr_natpmpPulse(         tr_natpmp *,
    32                                 int port,
    33                                 int isEnabled );
     31int tr_natpmpPulse( tr_natpmp *, tr_port port, tr_bool isEnabled, tr_port * public_port );
    3432
    3533/* @} */
  • trunk/libtransmission/peer-msgs.c

    r10931 r10945  
    846846                            && ( msgs->torrent->infoDictLength > 0 ) )
    847847        tr_bencDictAddInt( &val, "metadata_size", msgs->torrent->infoDictLength );
    848     tr_bencDictAddInt( &val, "p", tr_sessionGetPeerPort( getSession(msgs) ) );
     848    tr_bencDictAddInt( &val, "p", tr_sessionGetPublicPeerPort( getSession(msgs) ) );
    849849    tr_bencDictAddInt( &val, "reqq", REQQ );
    850850    tr_bencDictAddInt( &val, "upload_only", tr_torrentIsSeed( msgs->torrent ) );
  • trunk/libtransmission/port-forwarding.c

    r10662 r10945  
    6767
    6868static void
    69 natPulse( tr_shared * s, tr_bool doPortCheck )
    70 {
    71     const tr_port port = s->session->peerPort;
    72     const int isEnabled = s->isEnabled && !s->isShuttingDown;
     69natPulse( tr_shared * s, tr_bool do_check )
     70{
     71    const tr_port private_peer_port = s->session->private_peer_port;
     72    const int is_enabled = s->isEnabled && !s->isShuttingDown;
     73    tr_port public_peer_port;
    7374    int oldStatus;
    7475    int newStatus;
     
    8081
    8182    oldStatus = tr_sharedTraversalStatus( s );
    82     s->natpmpStatus = tr_natpmpPulse( s->natpmp, port, isEnabled );
    83     s->upnpStatus = tr_upnpPulse( s->upnp, port, isEnabled, doPortCheck );
     83
     84    s->natpmpStatus = tr_natpmpPulse( s->natpmp, private_peer_port, is_enabled, &public_peer_port );
     85    if( s->natpmpStatus == TR_PORT_MAPPED )
     86        s->session->public_peer_port = public_peer_port;
     87
     88    s->upnpStatus = tr_upnpPulse( s->upnp, private_peer_port, is_enabled, do_check );
     89
    8490    newStatus = tr_sharedTraversalStatus( s );
    8591
  • trunk/libtransmission/session.c

    r10937 r10945  
    200200    /* bind an ipv4 port to listen for incoming peers... */
    201201    b = session->public_ipv4;
    202     b->socket = tr_netBindTCP( &b->addr, session->peerPort, FALSE );
     202    b->socket = tr_netBindTCP( &b->addr, session->private_peer_port, FALSE );
    203203    if( b->socket >= 0 ) {
    204204        event_set( &b->ev, b->socket, EV_READ | EV_PERSIST, accept_incoming_peer, session );
     
    207207
    208208    /* and do the exact same thing for ipv6, if it's supported... */
    209     if( tr_net_hasIPv6( session->peerPort ) ) {
     209    if( tr_net_hasIPv6( session->private_peer_port ) ) {
    210210        b = session->public_ipv6;
    211         b->socket = tr_netBindTCP( &b->addr, session->peerPort, FALSE );
     211        b->socket = tr_netBindTCP( &b->addr, session->private_peer_port, FALSE );
    212212        if( b->socket >= 0 ) {
    213213            event_set( &b->ev, b->socket, EV_READ | EV_PERSIST, accept_incoming_peer, session );
     
    763763        tr_sessionSetPeerPortRandomOnStart( session, boolVal );
    764764    if( !tr_bencDictFindInt( settings, TR_PREFS_KEY_PEER_PORT, &i ) )
    765         i = session->peerPort;
     765        i = session->private_peer_port;
    766766    setPeerPort( session, boolVal ? getRandomPort( session ) : i );
    767767    if( tr_bencDictFindBool( settings, TR_PREFS_KEY_PORT_FORWARDING, &boolVal ) )
     
    10011001setPeerPort( tr_session * session, tr_port port )
    10021002{
    1003     session->peerPort = port;
     1003    session->private_peer_port = port;
     1004    session->public_peer_port = port;
    10041005
    10051006    tr_runInEventThread( session, peerPortChanged, session );
     
    10111012    assert( tr_isSession( session ) );
    10121013
    1013     if( session->peerPort != port )
     1014    if( session->private_peer_port != port )
    10141015    {
    10151016        setPeerPort( session, port );
     
    10221023    assert( tr_isSession( session ) );
    10231024
    1024     return session->peerPort;
     1025    return session->private_peer_port;
    10251026}
    10261027
     
    10311032
    10321033    tr_sessionSetPeerPort( session, getRandomPort( session ) );
    1033     return session->peerPort;
     1034    return session->private_peer_port;
    10341035}
    10351036
  • trunk/libtransmission/session.h

    r10937 r10945  
    123123    int                          uploadSlotsPerTorrent;
    124124
    125     tr_port                      peerPort;
     125    /* The open port on the local machine for incoming peer requests */
     126    tr_port                      private_peer_port;
     127
     128    /**
     129     * The open port on the public device for incoming peer requests.
     130     * This is usually the same as private_peer_port but can differ
     131     * if the public device is a router and it decides to use a different
     132     * port than the one requested by Transmission.
     133     */
     134    tr_port                      public_peer_port;
     135
    126136    tr_port                      randomPortLow;
    127137    tr_port                      randomPortHigh;
     
    186196};
    187197
     198static inline tr_port
     199tr_sessionGetPublicPeerPort( const tr_session * session )
     200{
     201    return session->public_peer_port;
     202}
     203
    188204tr_bool      tr_sessionAllowsDHT( const tr_session * session );
    189205
Note: See TracChangeset for help on using the changeset viewer.