Changeset 253


Ignore:
Timestamp:
May 13, 2006, 6:48:37 AM (15 years ago)
Author:
titer
Message:

Adds automatic peer banning.
At first, peers get only banned for the bad pieces they've contributed to, i.e. we continue to ask them for other parts of the torrent. If more bad data keeps coming, the peer gets completely banned.
Based on Jeremiah Morris' patch.

Location:
trunk/libtransmission
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/inout.c

    r239 r253  
    108108    tr_info_t    * inf = &io->tor->info;
    109109    uint64_t       offset;
    110     int            i;
     110    int            i, hashFailed;
    111111    uint8_t        hash[SHA_DIGEST_LENGTH];
    112112    uint8_t      * pieceBuf;
     
    148148    free( pieceBuf );
    149149
    150     if( memcmp( hash, &inf->pieces[20*index], SHA_DIGEST_LENGTH ) )
     150    hashFailed = memcmp( hash, &inf->pieces[20*index], SHA_DIGEST_LENGTH );
     151    if( hashFailed )
    151152    {
    152153        tr_inf( "Piece %d (slot %d): hash FAILED", index,
     
    164165                io->pieceSlot[index] );
    165166        tr_cpPieceAdd( tor->completion, index );
     167    }
     168
     169    /* Assign blame or credit to peers */
     170    for( i = 0; i < tor->peerCount; i++ )
     171    {
     172        tr_peerBlame( tor, tor->peers[i], index, !hashFailed );
    166173    }
    167174
  • trunk/libtransmission/peer.c

    r210 r253  
    5959    uint8_t        id[20];
    6060
     61    /* The pieces that the peer has */
    6162    uint8_t      * bitfield;
     63
     64    int            goodPcs;
     65    int            badPcs;
     66    int            banned;
     67    /* The pieces that the peer is contributing to */
     68    uint8_t      * blamefield;
     69    /* The bad pieces that the peer has contributed to */
     70    uint8_t      * banfield;
    6271
    6372    uint8_t      * buf;
     
    165174        free( peer->bitfield );
    166175    }
     176    if( peer->blamefield )
     177    {
     178        free( peer->blamefield );
     179    }
     180    if( peer->banfield )
     181    {
     182        free( peer->banfield );
     183    }
    167184    if( peer->buf )
    168185    {
     
    410427        }
    411428
    412         if( peer->amInterested && !peer->peerChoking )
     429        if( peer->amInterested && !peer->peerChoking && !peer->banned )
    413430        {
    414431            int block;
     
    513530    return peer->optimistic;
    514531}
     532
     533static inline int peerIsBad( tr_peer_t * peer )
     534{
     535    if( peer->goodPcs >= 5 &&
     536        peer->badPcs >= ( peer->goodPcs * 3 ) )
     537    {
     538        /* need poor success rate if we've successfully downloaded before */
     539        return 1;
     540    }
     541    else if( peer->goodPcs < 5 &&
     542             peer->badPcs >= ( 10 + peer->goodPcs ) )
     543    {
     544        /* need 10 more bad pieces than good before we discard peer */
     545        return 1;
     546    }
     547    return 0;
     548}
     549
     550void tr_peerBlame( tr_torrent_t * tor, tr_peer_t * peer,
     551                   int piece, int success )
     552{
     553    if( !peer->blamefield || !tr_bitfieldHas( peer->blamefield, piece ) )
     554    {
     555        return;
     556    }
     557
     558    if( success )
     559    {
     560        peer->goodPcs++;
     561    }
     562    else
     563    {
     564        peer->badPcs++;
     565
     566        if( !peer->banfield )
     567        {
     568            peer->banfield = calloc( ( tor->info.pieceCount + 7 ) / 8, 1 );
     569        }
     570        tr_bitfieldAdd( peer->banfield, piece );
     571
     572        if( peerIsBad( peer ) )
     573        {
     574            /* Full ban */
     575            peer_dbg( "banned (%d / %d)", peer->goodPcs, peer->badPcs );
     576            peer->banned = 1;
     577            peer->peerInterested = 0;
     578        }
     579    }
     580    tr_bitfieldRem( peer->blamefield, piece );
     581}
  • trunk/libtransmission/peer.h

    r133 r253  
    4848void        tr_peerSetOptimistic ( tr_peer_t *, int );
    4949int         tr_peerIsOptimistic  ( tr_peer_t * );
     50void        tr_peerBlame         ( tr_torrent_t *, tr_peer_t *,
     51                                   int piece, int success );
    5052
    5153#endif
  • trunk/libtransmission/peerparse.h

    r61 r253  
    281281    }
    282282
     283    /* set blame/credit for this piece */
     284    if( !peer->blamefield )
     285    {
     286        peer->blamefield = calloc( ( tor->info.pieceCount + 7 ) / 8, 1 );
     287    }
     288    tr_bitfieldAdd( peer->blamefield, index );
     289
    283290    tr_cpBlockAdd( tor->completion, block );
    284291    tr_ioWrite( tor->io, index, begin, len - 9, &p[8] );
     
    450457    uint8_t * end = &p[peer->pos];
    451458
     459    if( peer->banned )
     460    {
     461        /* Don't even parse, we only stay connected */
     462        peer->pos = 0;
     463        return 0;
     464    }
     465
    452466    while( peer->pos >= 4 )
    453467    {
  • trunk/libtransmission/peerutils.h

    r65 r253  
    268268            continue;
    269269        }
     270        if( peer->banfield && tr_bitfieldHas( peer->banfield, i ) )
     271        {
     272            /* The peer is banned for this piece */
     273            continue;
     274        }
    270275
    271276        /* We are interested in this piece, remember it */
     
    348353            continue;
    349354        }
     355        if( peer->banfield && tr_bitfieldHas( peer->banfield, i ) )
     356        {
     357            /* The peer is banned for this piece */
     358            continue;
     359        }
    350360        if( tr_cpPieceIsComplete( tor->completion, i ) )
    351361        {
Note: See TracChangeset for help on using the changeset viewer.