コード例 #1
0
ファイル: tr-dht.c プロジェクト: HumbleRepose/transmission
void
tr_dhtUninit(tr_session *ss)
{
    if(session != ss)
        return;

    tr_ndbg( "DHT", "Uninitializing DHT" );

    if( dht_timer != NULL ) {
        event_free( dht_timer );
        dht_timer = NULL;
    }

    /* Since we only save known good nodes, avoid erasing older data if we
       don't know enough nodes. */
    if(tr_dhtStatus(ss, AF_INET, NULL) < TR_DHT_FIREWALLED)
        tr_ninf( "DHT", "Not saving nodes, DHT not ready" );
    else {
        tr_benc benc;
        struct sockaddr_in sins[300];
        struct sockaddr_in6 sins6[300];
        char compact[300 * 6], compact6[300 * 18];
        char *dat_file;
        int i, j, num = 300, num6 = 300;
        int n = dht_get_nodes(sins, &num, sins6, &num6);

        tr_ninf( "DHT", "Saving %d (%d + %d) nodes", n, num, num6 );

        j = 0;
        for( i=0; i<num; ++i ) {
            memcpy( compact + j, &sins[i].sin_addr, 4 );
            memcpy( compact + j + 4, &sins[i].sin_port, 2 );
            j += 6;
        }
        j = 0;
        for( i=0; i<num6; ++i ) {
            memcpy( compact6 + j, &sins6[i].sin6_addr, 16 );
            memcpy( compact6 + j + 16, &sins6[i].sin6_port, 2 );
            j += 18;
        }
        tr_bencInitDict( &benc, 3 );
        tr_bencDictAddRaw( &benc, "id", myid, 20 );
        if(num > 0)
            tr_bencDictAddRaw( &benc, "nodes", compact, num * 6 );
        if(num6 > 0)
            tr_bencDictAddRaw( &benc, "nodes6", compact6, num6 * 18 );
        dat_file = tr_buildPath( ss->configDir, "dht.dat", NULL );
        tr_bencToFile( &benc, TR_FMT_BENC, dat_file );
        tr_bencFree( &benc );
        tr_free( dat_file );
    }

    dht_uninit();
    tr_ndbg("DHT", "Done uninitializing DHT");

    session = NULL;
}
コード例 #2
0
ファイル: magnet.c プロジェクト: dmkc/transmission
void
tr_magnetCreateMetainfo( const tr_magnet_info * info, tr_benc * top )
{
    int i;
    tr_benc * d;
    tr_bencInitDict( top, 4 );

    /* announce list */
    if( info->trackerCount == 1 )
        tr_bencDictAddStr( top, "announce", info->trackers[0] );
    else {
        tr_benc * trackers = tr_bencDictAddList( top, "announce-list", info->trackerCount );
        for( i=0; i<info->trackerCount; ++i )
            tr_bencListAddStr( tr_bencListAddList( trackers, 1 ), info->trackers[i] );
    }

    /* webseeds */
    if( info->webseedCount > 0 ) {
        tr_benc * urls = tr_bencDictAddList( top, "url-list", info->webseedCount );
        for( i=0; i<info->webseedCount; ++i )
            tr_bencListAddStr( urls, info->webseeds[i] );
    }

    /* nonstandard keys */
    d = tr_bencDictAddDict( top, "magnet-info", 2 );
    tr_bencDictAddRaw( d, "info_hash", info->hash, 20 );
    if( info->displayName != NULL )
        tr_bencDictAddStr( d, "display-name", info->displayName );
}
コード例 #3
0
ファイル: resume.c プロジェクト: fangang190/canary
static void
saveProgress( tr_benc *          dict,
              const tr_torrent * tor )
{
    size_t              i, n;
    time_t *            mtimes;
    tr_benc *           p;
    tr_benc *           m;
    const tr_bitfield * bitfield;

    p = tr_bencDictAdd( dict, KEY_PROGRESS );
    tr_bencInitDict( p, 2 );

    /* add the mtimes */
    mtimes = tr_torrentGetMTimes( tor, &n );
    m = tr_bencDictAddList( p, KEY_PROGRESS_MTIMES, n );
    for( i = 0; i < n; ++i )
    {
        if( !tr_torrentIsFileChecked( tor, i ) )
            mtimes[i] = ~(time_t)0; /* force a recheck */
        tr_bencListAddInt( m, mtimes[i] );
    }

    /* add the bitfield */
    bitfield = tr_cpBlockBitfield( tor->completion );
    tr_bencDictAddRaw( p, KEY_PROGRESS_BITFIELD,
                       bitfield->bits, bitfield->byteCount );

    /* cleanup */
    tr_free( mtimes );
}
コード例 #4
0
ファイル: resume.c プロジェクト: ijuxda/transmission
static void
savePeers( tr_benc * dict, const tr_torrent * tor )
{
    int count;
    tr_pex * pex;

    count = tr_peerMgrGetPeers( (tr_torrent*) tor, &pex, TR_AF_INET, TR_PEERS_ALL, MAX_REMEMBERED_PEERS );
    if( count > 0 )
        tr_bencDictAddRaw( dict, KEY_PEERS, pex, sizeof( tr_pex ) * count );
    tr_free( pex );

    count = tr_peerMgrGetPeers( (tr_torrent*) tor, &pex, TR_AF_INET6, TR_PEERS_ALL, MAX_REMEMBERED_PEERS );
    if( count > 0 )
        tr_bencDictAddRaw( dict, KEY_PEERS6, pex, sizeof( tr_pex ) * count );

    tr_free( pex );
}
コード例 #5
0
ファイル: resume.c プロジェクト: fangang190/canary
static void
savePeers( tr_benc *          dict,
           const tr_torrent * tor )
{
    tr_pex *  pex = NULL;
    const int count = tr_peerMgrGetPeers( tor->session->peerMgr,
                                          tor->info.hash, &pex );

    if( count > 0 )
        tr_bencDictAddRaw( dict, KEY_PEERS, pex, sizeof( tr_pex ) * count );
    tr_free( pex );
}
コード例 #6
0
ファイル: resume.c プロジェクト: alex-berman/tforms
static void
saveProgress( tr_benc * dict, const tr_torrent * tor )
{
    tr_benc * l;
    tr_benc * prog;
    tr_file_index_t fi;
    const struct tr_bitfield * bitfield;
    const tr_info * inf = tr_torrentInfo( tor );
    const time_t now = tr_time( );

    prog = tr_bencDictAddDict( dict, KEY_PROGRESS, 3 );

    /* add the file/piece check timestamps... */
    l = tr_bencDictAddList( prog, KEY_PROGRESS_CHECKTIME, inf->fileCount );
    for( fi=0; fi<inf->fileCount; ++fi )
    {
        const tr_piece * p;
        const tr_piece * pend;
        time_t oldest_nonzero = now;
        time_t newest = 0;
        tr_bool has_zero = FALSE;
        const time_t mtime = tr_torrentGetFileMTime( tor, fi );
        const tr_file * f = &inf->files[fi];

        /* get the oldest and newest nonzero timestamps for pieces in this file */
        for( p=&inf->pieces[f->firstPiece], pend=&inf->pieces[f->lastPiece]; p!=pend; ++p )
        {
            if( !p->timeChecked )
                has_zero = TRUE;
            else if( oldest_nonzero > p->timeChecked )
                oldest_nonzero = p->timeChecked;
            if( newest < p->timeChecked )
                newest = p->timeChecked;
        }

        /* If some of a file's pieces have been checked more recently than
           the file's mtime, and some lest recently, then that file will
           have a list containing timestamps for each piece.
           
           However, the most common use case is that the file doesn't change
           after it's downloaded. To reduce overhead in the .resume file,
           only a single timestamp is saved for the file if *all* or *none*
           of the pieces were tested more recently than the file's mtime. */

        if( !has_zero && ( mtime <= oldest_nonzero ) ) /* all checked */
            tr_bencListAddInt( l, oldest_nonzero );
        else if( newest < mtime ) /* none checked */
            tr_bencListAddInt( l, newest );
        else { /* some are checked, some aren't... so list piece by piece */
            const int offset = oldest_nonzero - 1;
            tr_benc * ll = tr_bencListAddList( l, 2 + f->lastPiece - f->firstPiece );
            tr_bencListAddInt( ll, offset );
            for( p=&inf->pieces[f->firstPiece], pend=&inf->pieces[f->lastPiece]; p!=pend; ++p )
                tr_bencListAddInt( ll, p->timeChecked ? p->timeChecked - offset : 0 );
        }
    }

    /* add the progress */
    if( tor->completeness == TR_SEED )
        tr_bencDictAddStr( prog, KEY_PROGRESS_HAVE, "all" );

    /* add the pieces bitfield */
    bitfield = tr_cpBlockBitfield( &tor->completion );
    tr_bencDictAddRaw( prog, KEY_PROGRESS_BITFIELD, bitfield->bits,
                                                    bitfield->byteCount );
}