Changeset 1208


Ignore:
Timestamp:
Dec 14, 2006, 4:29:52 AM (15 years ago)
Author:
joshe
Message:

Restructure the tracker list in tr_info_t a bit.
Fix some memory leaks.

Location:
branches/multitracker/libtransmission
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • branches/multitracker/libtransmission/metainfo.c

    r1192 r1208  
    3030 * Local prototypes
    3131 **********************************************************************/
     32static int getannounce( tr_info_t * inf, benc_val_t * meta );
    3233#define strcatUTF8( dst, src) _strcatUTF8( (dst), sizeof( dst ) - 1, (src) )
    33 
    3434static void _strcatUTF8( char *, int, char * );
    3535
     
    4444    FILE       * file;
    4545    char       * buf;
    46     benc_val_t   meta, * beInfo, * list, * val, * sublist;
    47     char       * address, * announce;
    48     int          i, j, k, tiersSet, inTier, port, random;
    49     struct stat sb;
    50     tr_announce_list_item_t * announceItem, * prevAnnounceItem, * nextAnnounceItem;
     46    benc_val_t   meta, * beInfo, * list, * val;
     47    int          i;
     48    struct stat  sb;
    5149
    5250    assert( NULL == path || NULL == savedHash );
     
    257255    {
    258256        tr_err( "Size of hashes and files don't match" );
    259         free( inf->pieces );
     257        tr_metainfoFree( inf );
    260258        tr_bencFree( &meta );
    261259        return 1;
    262260    }
     261
     262    /* get announce or announce-list */
     263    if( getannounce( inf, &meta ) )
     264    {
     265        tr_metainfoFree( inf );
     266        tr_bencFree( &meta );
     267        return 1;
     268    }
     269
     270    tr_bencFree( &meta );
     271    return 0;
     272}
     273
     274void tr_metainfoFree( tr_info_t * inf )
     275{
     276    int ii, jj;
     277
     278    free( inf->pieces );
     279    free( inf->files );
    263280   
     281    for( ii = 0; ii < inf->trackerTiers; ii++ )
     282    {
     283        for( jj = 0; jj < inf->trackerList[ii].count; jj++ )
     284        {
     285            free( inf->trackerList[ii].list[jj].address );
     286            free( inf->trackerList[ii].list[jj].announce );
     287        }
     288        free( inf->trackerList[ii].list );
     289    }
     290    free( inf->trackerList );
     291}
     292
     293static int getannounce( tr_info_t * inf, benc_val_t * meta )
     294{
     295    benc_val_t              * val, * subval, * urlval;
     296    char                    * address, * announce;
     297    int                       ii, jj, port, random;
     298    tr_tracker_info_t * sublist;
     299    int subcount;
     300    void * swapping;
     301
    264302    /* Announce-list */
    265     tiersSet = 0;
    266     if( ( val = tr_bencDictFind( &meta, "announce-list" ) ) )
    267     {
    268         list = val->val.l.vals;
    269        
    270         inf->trackerAnnounceList = calloc( sizeof( int ), val->val.l.count );
    271         tiersSet = 1;
    272        
    273         inf->trackerAnnounceTiers = 0;
    274         for( i = 0; i < val->val.l.count; i++ )
    275         {
    276             sublist = list[i].val.l.vals;
    277            
    278             inTier = 0;
    279             for( j = 0; j < list[i].val.l.count; j++ )
    280             {
    281                 if( tr_httpParseUrl( sublist[j].val.s.s, sublist[j].val.s.i,
     303    val = tr_bencDictFind( meta, "announce-list" );
     304    if( NULL != val && TYPE_LIST == val->type && 0 < val->val.l.count )
     305    {
     306        inf->trackerTiers = 0;
     307        inf->trackerList = calloc( sizeof( inf->trackerList[0] ),
     308                                   val->val.l.count );
     309
     310        /* iterate through the announce-list's tiers */
     311        for( ii = 0; ii < val->val.l.count; ii++ )
     312        {
     313            subval = &val->val.l.vals[ii];
     314            if( TYPE_LIST != subval->type || 0 >= subval->val.l.count )
     315            {
     316                continue;
     317            }
     318            subcount = 0;
     319            sublist = calloc( sizeof( sublist[0] ), subval->val.l.count );
     320
     321            /* iterate through the tier's items */
     322            for( jj = 0; jj < subval->val.l.count; jj++ )
     323            {
     324                urlval = &subval->val.l.vals[jj];
     325                if( TYPE_STR != urlval->type ||
     326                    tr_httpParseUrl( urlval->val.s.s, urlval->val.s.i,
    282327                                     &address, &port, &announce ) )
    283328                {
    284329                    continue;
    285330                }
    286                
    287                 /* Shuffle order of sublist */
    288                 random = tr_rand( inTier+1 );
    289                
    290                 prevAnnounceItem = 0;
    291                 nextAnnounceItem = inf->trackerAnnounceList[inf->trackerAnnounceTiers];
    292                 for( k = 0; k < random; k++ )
     331
     332                /* place the item info in a random location in the sublist */
     333                random = tr_rand( subcount + 1 );
     334                if( random != subcount )
    293335                {
    294                     prevAnnounceItem = nextAnnounceItem;
    295                     nextAnnounceItem = nextAnnounceItem->nextItem;
     336                    sublist[subcount] = sublist[random];
    296337                }
    297                
    298                 announceItem = calloc( sizeof( tr_announce_list_item_t ), 1 );
    299                 announceItem->nextItem = nextAnnounceItem;
    300                 if( prevAnnounceItem )
    301                 {
    302                     prevAnnounceItem->nextItem = announceItem;
    303                 }
    304                 else
    305                 {
    306                     inf->trackerAnnounceList[inf->trackerAnnounceTiers] = announceItem;
    307                 }
    308                
    309                 /* Set values */
    310                 announceItem->address  = address;
    311                 announceItem->port     = port;
    312                 announceItem->announce = announce;
    313                
    314                 inTier++;
    315             }
    316            
    317             /* Only use tier if there are useable addresses */
    318             if( inTier > 0 )
    319             {
    320                 inf->trackerAnnounceTiers++;
    321             }
    322         }
    323     }
    324    
    325     if( inf->trackerAnnounceTiers )
    326     {
    327         tr_inf( "announce-list for \"%s\":", inf->name );
    328         for( i = 0; i < inf->trackerAnnounceTiers; i++ )
    329         {
    330             tr_inf( "list %d:", i );
    331             for( announceItem = inf->trackerAnnounceList[i]; announceItem != NULL; announceItem = announceItem->nextItem )
    332             {
    333                 tr_inf( "%s:%d%s", announceItem->address, announceItem->port, announceItem->announce );
    334             }
    335         }
    336     }
    337     else
    338     {
    339         tr_inf( "no announce-list provided for \"%s\"", inf->name );
    340     }
    341    
     338                sublist[random].address  = address;
     339                sublist[random].port     = port;
     340                sublist[random].announce = announce;
     341                subcount++;
     342            }
     343
     344            /* just use sublist as is if it's full */
     345            if( subcount == subval->val.l.count )
     346            {
     347                inf->trackerList[inf->trackerTiers].list = sublist;
     348                inf->trackerList[inf->trackerTiers].count = subcount;
     349                inf->trackerTiers++;
     350            }
     351            /* if we skipped some of the tier's items then trim the sublist */
     352            else if( 0 < subcount )
     353            {
     354                inf->trackerList[inf->trackerTiers].list = calloc( sizeof( sublist[0] ), subcount );
     355                memcpy( inf->trackerList[inf->trackerTiers].list, sublist,
     356                        sizeof( sublist[0] ) * subcount );
     357                inf->trackerList[inf->trackerTiers].count = subcount;
     358                inf->trackerTiers++;
     359                free( sublist );
     360            }
     361            /* drop the whole sublist if we didn't use any items at all */
     362            else
     363            {
     364                free( sublist );
     365            }
     366        }
     367
     368        /* did we use any of the tiers? */
     369        if( 0 == inf->trackerTiers )
     370        {
     371            tr_inf( "No valid entries in \"announce-list\"" );
     372            free( inf->trackerList );
     373            inf->trackerList = NULL;
     374        }
     375        /* trim unused sublist pointers */
     376        else if( inf->trackerTiers < val->val.l.count )
     377        {
     378            swapping = inf->trackerList;
     379            inf->trackerList = calloc( sizeof( inf->trackerList[0] ),
     380                                       inf->trackerTiers );
     381            memcpy( inf->trackerList, swapping,
     382                    sizeof( inf->trackerList[0] ) * inf->trackerTiers );
     383            free( swapping );
     384        }
     385    }
     386
    342387    /* Regular announce value */
    343     if ( !inf->trackerAnnounceTiers )
    344     {
    345         if( !( val = tr_bencDictFind( &meta, "announce" ) ) )
     388    if( 0 == inf->trackerTiers )
     389    {
     390        val = tr_bencDictFind( meta, "announce" );
     391        if( NULL == val || TYPE_STR != val->type )
    346392        {
    347393            tr_err( "No \"announce\" entry" );
    348             tr_bencFree( &meta );
    349394            return 1;
    350395        }
    351        
     396
    352397        if( tr_httpParseUrl( val->val.s.s, val->val.s.i,
    353398                             &address, &port, &announce ) )
    354399        {
    355400            tr_err( "Invalid announce URL (%s)", val->val.s.s );
    356             tr_bencFree( &meta );
    357401            return 1;
    358402        }
    359        
    360         if( !tiersSet )
    361         {
    362             inf->trackerAnnounceList = calloc( sizeof( int ), 1 );
    363         }
    364         inf->trackerAnnounceTiers = 1;
    365        
    366         inf->trackerAnnounceList[0] = calloc( sizeof( tr_announce_list_item_t ), 1 );
    367         inf->trackerAnnounceList[0]->address  = address;
    368         inf->trackerAnnounceList[0]->port     = port;
    369         inf->trackerAnnounceList[0]->announce = announce;
    370        
    371         tr_inf( "announce for \"%s\": %s:%d%s", inf->name, address, port, announce );
    372     }
    373 
    374     tr_bencFree( &meta );
     403
     404        sublist                   = calloc( sizeof( sublist[0] ), 1 );
     405        sublist[0].address        = address;
     406        sublist[0].port           = port;
     407        sublist[0].announce       = announce;
     408        inf->trackerList          = calloc( sizeof( inf->trackerList[0] ), 1 );
     409        inf->trackerList[0].list  = sublist;
     410        inf->trackerList[0].count = 1;
     411        inf->trackerTiers         = 1;
     412    }
     413
    375414    return 0;
    376415}
  • branches/multitracker/libtransmission/metainfo.h

    r310 r1208  
    2828int tr_metainfoParse( tr_info_t *, const char * path,
    2929                      const char * savedHash, int saveCopy );
     30void tr_metainfoFree( tr_info_t * inf );
     31void tr_metainfoRemoveSaved( const char * hashString );
    3032
    31 void tr_metainfoRemoveSaved( const char * hashString );
    3233#endif
  • branches/multitracker/libtransmission/tracker.c

    r1192 r1208  
    2828struct tr_announce_list_ptr_s
    2929{
    30     tr_announce_list_item_t * item;
     30    tr_tracker_info_t * item;
    3131    tr_announce_list_ptr_t * nextItem;
    3232};
     
    9393tr_tracker_t * tr_trackerInit( tr_torrent_t * tor )
    9494{
     95    tr_info_t * inf = &tor->info;
     96
    9597    tr_tracker_t * tc;
    96     tr_announce_list_item_t * announceItem;
    97     tr_announce_list_ptr_t * announcePtr, * prevAnnouncePtr;
    98     int i;
     98    tr_announce_list_ptr_t * prev, * cur;
     99    int ii, jj;
    99100
    100101    tc                 = calloc( 1, sizeof( tr_tracker_t ) );
     
    112113    tc->newPort        = -1;
    113114   
    114     tc->trackerAnnounceListPtr = calloc( sizeof( int ), tor->info.trackerAnnounceTiers );
    115     for( i = 0; i < tor->info.trackerAnnounceTiers; i++ )
    116     {
    117         tc->trackerAnnounceListPtr[i] = calloc( 1, sizeof( tr_announce_list_ptr_t ) );
    118         tc->trackerAnnounceListPtr[i]->item = tor->info.trackerAnnounceList[i];
    119         prevAnnouncePtr = tc->trackerAnnounceListPtr[i];
    120        
    121         for( announceItem = tor->info.trackerAnnounceList[i]->nextItem; announceItem != NULL;
    122                 announceItem = announceItem->nextItem )
    123         {
    124             announcePtr = calloc( 1, sizeof( tr_announce_list_ptr_t ) );
    125            
    126             announcePtr->item = announceItem;
    127             prevAnnouncePtr->nextItem = announcePtr;
    128             prevAnnouncePtr = announcePtr;
     115    tc->trackerAnnounceListPtr = calloc( sizeof( int ), inf->trackerTiers );
     116    for( ii = 0; ii < inf->trackerTiers; ii++ )
     117    {
     118        prev = NULL;
     119        for( jj = 0; jj < inf->trackerList[ii].count; jj++ )
     120        {
     121            cur = calloc( sizeof( tr_announce_list_ptr_t ), 1 );
     122            cur->item = &inf->trackerList[ii].list[jj];
     123            if( NULL == prev )
     124            {
     125                tc->trackerAnnounceListPtr[ii] = cur;
     126            }
     127            else
     128            {
     129                prev->nextItem = cur;
     130            }
     131            prev = cur;
    129132        }
    130133    }
     
    166169static void setAnnounce( tr_tracker_t * tc, tr_announce_list_ptr_t * announcePtr )
    167170{
    168     tr_announce_list_item_t * announceItem = announcePtr->item;
     171    tr_tracker_info_t * announceItem = announcePtr->item;
    169172   
    170173    tc->trackerAddress  = announceItem->address;
     
    192195   
    193196    /* If more tiers then announce can definitely be changed */
    194     if( tc->announceTier + 1 < inf->trackerAnnounceTiers)
     197    if( tc->announceTier + 1 < inf->trackerTiers )
    195198    {
    196199        return;
  • branches/multitracker/libtransmission/transmission.c

    r1192 r1208  
    3131                                       int flags, int * error );
    3232static void torrentReallyStop( tr_torrent_t * );
    33 static void freeInfo( tr_info_t * inf );
    3433static void downloadLoop( void * );
    3534static void acceptLoop( void * );
     
    290289        {
    291290            *error = TR_EDUPLICATE;
    292             freeInfo( &tor->info );
     291            tr_metainfoFree( &tor->info );
    293292            free( tor );
    294293            return NULL;
     
    484483    else
    485484    {
    486         s->trackerAddress  = inf->trackerAnnounceList[0]->address;
    487         s->trackerPort     = inf->trackerAnnounceList[0]->port;
    488         s->trackerAnnounce = inf->trackerAnnounceList[0]->announce;
     485        s->trackerAddress  = inf->trackerList[0].list[0].address;
     486        s->trackerPort     = inf->trackerList[0].list[0].port;
     487        s->trackerAnnounce = inf->trackerList[0].list[0].announce;
    489488    }
    490489
     
    686685    }
    687686
    688     freeInfo( inf );
     687    tr_metainfoFree( inf );
    689688
    690689    if( tor->prev )
     
    703702
    704703    tr_lockUnlock( &h->acceptLock );
    705 }
    706 
    707 static void freeInfo( tr_info_t * inf )
    708 {
    709     int ii;
    710     tr_announce_list_item_t * jj, * dead;
    711 
    712     free( inf->pieces );
    713     free( inf->files );
    714    
    715     for( ii = 0; ii < inf->trackerAnnounceTiers; ii++ )
    716     {
    717         jj = inf->trackerAnnounceList[ii];
    718         while( NULL != jj )
    719         {
    720             dead = jj;
    721             jj = jj->nextItem;
    722             free( dead->address );
    723             free( dead->announce );
    724             free( dead );
    725         }
    726     }
    727     free( inf->trackerAnnounceList );
    728704}
    729705
  • branches/multitracker/libtransmission/transmission.h

    r1192 r1208  
    6262tr_handle_t * tr_init();
    6363
    64 typedef struct tr_announce_list_item_s tr_announce_list_item_t;
     64typedef struct tr_tracker_info_s tr_tracker_info_t;
    6565
    6666/***********************************************************************
     
    306306{
    307307    /* Path to torrent */
    308     char        torrent[MAX_PATH_LENGTH];
     308    char                 torrent[MAX_PATH_LENGTH];
    309309
    310310    /* General info */
    311     uint8_t     hash[SHA_DIGEST_LENGTH];
    312     char        hashString[2*SHA_DIGEST_LENGTH+1];
    313     char        name[MAX_PATH_LENGTH];
     311    uint8_t              hash[SHA_DIGEST_LENGTH];
     312    char                 hashString[2*SHA_DIGEST_LENGTH+1];
     313    char                 name[MAX_PATH_LENGTH];
    314314
    315315    /* Flags */
    316316#define TR_FSAVEPRIVATE 0x01    /* save a private copy of the torrent */
    317     int         flags;
    318    
    319     tr_announce_list_item_t ** trackerAnnounceList;
    320     int         trackerAnnounceTiers;
    321    
     317    int                  flags;
     318
     319    /* Tracker info */
     320    struct
     321    {
     322        tr_tracker_info_t * list;
     323        int                 count;
     324    }                  * trackerList;
     325    int                  trackerTiers;
     326
    322327    /* Torrent info */
    323     char        comment[MAX_PATH_LENGTH];
    324     char        creator[MAX_PATH_LENGTH];
    325     int         dateCreated;
     328    char                 comment[MAX_PATH_LENGTH];
     329    char                 creator[MAX_PATH_LENGTH];
     330    int                  dateCreated;
    326331
    327332    /* Pieces info */
    328     int         pieceSize;
    329     int         pieceCount;
    330     uint64_t    totalSize;
    331     uint8_t   * pieces;
     333    int                  pieceSize;
     334    int                  pieceCount;
     335    uint64_t             totalSize;
     336    uint8_t            * pieces;
    332337
    333338    /* Files info */
    334     int         multifile;
    335     int         fileCount;
    336     tr_file_t * files;
     339    int                  multifile;
     340    int                  fileCount;
     341    tr_file_t          * files;
    337342};
    338343
     
    400405};
    401406
    402 struct tr_announce_list_item_s
     407struct tr_tracker_info_s
    403408{
    404409    char * address;
    405410    int    port;
    406411    char * announce;
    407    
    408     tr_announce_list_item_t * nextItem;
    409412};
    410413
Note: See TracChangeset for help on using the changeset viewer.