Ignore:
Timestamp:
Dec 15, 2008, 12:17:08 AM (12 years ago)
Author:
charles
Message:

(trunk libT) add ipv6 support by jhujhiti. I think this is the largest user-contributed patch we've ever used... thanks jhujhiti :)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/tracker.c

    r7266 r7397  
    241241}
    242242
     243static void
     244publishNewPeersCompact( tr_tracker * t,
     245                        int          allAreSeeds,
     246                        void       * compact,
     247                        int          compactLen )
     248{
     249    int i;
     250    uint8_t *array, *walk, *compactWalk;
     251    const int peerCount = compactLen / 6;
     252    const int arrayLen = peerCount * ( sizeof( tr_address ) + 2 );
     253    tr_address addr;
     254    tr_port port;
     255   
     256    addr.type = TR_AF_INET;
     257    memset( &addr.addr, 0x00, sizeof( addr.addr ) );
     258    array = tr_new( uint8_t, arrayLen );
     259    for ( i = 0, walk = array, compactWalk = compact ; i < peerCount ; i++ )
     260    {
     261        memcpy( &addr.addr.addr4, compactWalk, 4 );
     262        memcpy( &port, compactWalk + 4, 2 );
     263       
     264        memcpy( walk, &addr, sizeof( addr ) );
     265        memcpy( walk + sizeof( addr ), &port, 2 );
     266       
     267        walk += sizeof( tr_address ) + 2;
     268        compactWalk += 6;
     269    }
     270    publishNewPeers( t, allAreSeeds, array, arrayLen );
     271    tr_free( array );
     272}
     273
     274static void
     275publishNewPeersCompact6( tr_tracker * t,
     276                         int          allAreSeeds,
     277                         void       * compact,
     278                         int          compactLen )
     279{
     280    int i;
     281    uint8_t *array, *walk, *compactWalk;
     282    const int peerCount = compactLen / 18;
     283    const int arrayLen = peerCount * ( sizeof( tr_address ) + 2 );
     284    tr_address addr;
     285    tr_port port;
     286   
     287    addr.type = TR_AF_INET6;
     288    memset( &addr.addr, 0x00, sizeof( addr.addr ) );
     289    array = tr_new( uint8_t, arrayLen );
     290    for ( i = 0, walk = array, compactWalk = compact ; i < peerCount ; i++ )
     291    {
     292        memcpy( &addr.addr.addr6, compactWalk, 16 );
     293        memcpy( &port, compactWalk + 16, 2 );
     294       
     295        memcpy( walk, &addr, sizeof( addr ) );
     296        memcpy( walk + sizeof( addr ), &port, 2 );
     297       
     298        walk += sizeof( tr_address ) + 2;
     299        compactWalk += 6;
     300    }
     301    publishNewPeers( t, allAreSeeds, array, arrayLen );
     302    tr_free( array );
     303}
     304
    243305/***
    244306****
     
    277339}
    278340
    279 /* Convert to compact form */
    280341static uint8_t *
    281342parseOldPeers( tr_benc * bePeers,
    282343               size_t *  byteCount )
    283344{
    284     /* TODO: IPv6 wtf */
    285345    int       i;
    286     uint8_t * compact, *walk;
     346    uint8_t * array, *walk;
    287347    const int peerCount = bePeers->val.l.count;
    288348
    289349    assert( bePeers->type == TYPE_LIST );
    290350
    291     compact = tr_new( uint8_t, peerCount * 6 );
    292 
    293     for( i = 0, walk = compact; i < peerCount; ++i )
    294     {
    295         const char * s;
    296         int64_t      itmp;
    297         tr_address   addr;
    298         tr_port      port;
    299         tr_benc    * peer = &bePeers->val.l.vals[i];
    300  
    301         if( tr_bencDictFindStr( peer, "ip", &s ) )
    302         {
    303             if( tr_pton( s, &addr ) == NULL )
    304                 continue;
    305             if( addr.type != TR_AF_INET )
    306                 continue;
    307         }
    308  
    309         memcpy( walk, &addr.addr.addr4.s_addr, 4 );
    310         walk += 4;
    311 
     351    array = tr_new( uint8_t, peerCount * ( sizeof( tr_address ) + 2 ) );
     352
     353    for( i = 0, walk = array; i < peerCount; ++i )
     354    {
     355        const char * s;
     356        int64_t      itmp;
     357        tr_address   addr;
     358        tr_port    port;
     359        tr_benc *    peer = &bePeers->val.l.vals[i];
     360
     361        if( tr_bencDictFindStr( peer, "ip", &s ) )
     362        {
     363            if( tr_pton( s, &addr ) == NULL )
     364                continue;
     365        }
    312366        if( !tr_bencDictFindInt( peer, "port",
    313367                                 &itmp ) || itmp < 0 || itmp > 0xffff )
    314368            continue;
    315369
     370        memcpy( walk, &addr, sizeof( tr_address ) );
    316371        port = htons( itmp );
    317         memcpy( walk, &port, 2 );
    318         walk += 2;
    319     }
    320 
    321     *byteCount = peerCount * 6;
    322     return compact;
     372        memcpy( walk + sizeof( tr_address ), &port, 2 );
     373        walk += sizeof( tr_address ) + 2;
     374    }
     375
     376    *byteCount = peerCount * sizeof( tr_address ) + 2;
     377    return array;
    323378}
    324379
     
    433488                if( tmp->type == TYPE_STR ) /* "compact" extension */
    434489                {
    435                     publishNewPeers( t, allAreSeeds, tmp->val.s.s,
    436                                      tmp->val.s.i );
     490                    publishNewPeersCompact( t, allAreSeeds, tmp->val.s.s,
     491                                            tmp->val.s.i );
    437492                }
    438493                else if( tmp->type == TYPE_LIST ) /* original protocol */
    439494                {
    440495                    size_t    byteCount = 0;
    441                     uint8_t * compact = parseOldPeers( tmp, &byteCount );
    442                     publishNewPeers( t, allAreSeeds, compact, byteCount );
    443                     tr_free( compact );
     496                    uint8_t * array = parseOldPeers( tmp, &byteCount );
     497                    publishNewPeers( t, allAreSeeds, array, byteCount );
     498                    tr_free( array );
     499                }
     500            }
     501           
     502            if( ( tmp = tr_bencDictFind( &benc, "peers6" ) ) )
     503            {
     504                const int allAreSeeds = incomplete == 0;
     505               
     506                if( tmp->type == TYPE_STR ) /* "compact" extension */
     507                {
     508                    publishNewPeersCompact6( t, allAreSeeds, tmp->val.s.s,
     509                                             tmp->val.s.i );
    444510                }
    445511            }
Note: See TracChangeset for help on using the changeset viewer.