Changeset 3320


Ignore:
Timestamp:
Oct 8, 2007, 1:31:27 AM (14 years ago)
Author:
charles
Message:

ban peers that feed us too many bad blocks.

Location:
trunk/libtransmission
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/peer-mgr-private.h

    r3295 r3320  
    3737    unsigned int  doPurge : 1;
    3838
     39
     40    /* number of bad pieces they've contributed to */
     41    uint8_t strikes;
     42
    3943    uint8_t encryption_preference;
    4044    uint16_t port;
  • trunk/libtransmission/peer-mgr.c

    r3309 r3320  
    6969    /* corresponds to ut_pex's added.f flags */
    7070    ADDED_F_ENCRYPTION_FLAG = 1,
    71 
    7271    /* corresponds to ut_pex's added.f flags */
    73     ADDED_F_SEED_FLAG = 2
     72    ADDED_F_SEED_FLAG = 2,
     73
     74    /* number of bad pieces a peer is allowed to send before we ban them */
     75    MAX_BAD_PIECES_PER_PEER = 3,
     76    /* use for bitwise operations w/peer_atom.myflags */
     77    MYFLAG_BANNED = 1
    7478};
    7579
     
    8791    uint8_t from;
    8892    uint8_t flags; /* these match the added_f flags */
     93    uint8_t myflags; /* flags that aren't defined in added_f */
    8994    uint16_t port;
    9095    struct in_addr addr;
     
    341346    tr_bitfieldFree( peer->have );
    342347    tr_bitfieldFree( peer->blame );
    343     tr_bitfieldFree( peer->banned );
    344348    tr_rcClose( peer->rcToClient );
    345349    tr_rcClose( peer->rcToPeer );
     
    909913    else /* looking good */
    910914    {
    911         tr_peer * peer = getPeer( t, in_addr );
    912915        uint16_t port;
    913916        const struct in_addr * addr = tr_peerIoGetAddress( io,  &port );
     917        struct peer_atom * atom;
    914918        ensureAtomExists( t, addr, port, 0, TR_PEER_FROM_INCOMING );
    915         tr_free( peer->client );
    916         peer->client = peer_id ? tr_clientForId( peer_id ) : NULL;
    917         if( peer->msgs != NULL ) { /* we already have this peer */
     919        atom = getExistingAtom( t, addr );
     920        tr_peer * peer = getPeer( t, addr );
     921        if( atom->myflags & MYFLAG_BANNED )
     922        {
     923            tordbg( t, "banned peer %s tried to reconnect", tr_peerIoAddrStr(&atom->addr,atom->port) );
    918924            tr_peerIoFree( io );
    919925            --manager->connectionCount;
    920         } else {
     926            peer->doPurge = 1;
     927        }
     928        else if( peer->msgs != NULL ) /* we already have this peer */
     929        {
     930            tr_peerIoFree( io );
     931            --manager->connectionCount;
     932        }
     933        else
     934        {
     935            tr_free( peer->client );
     936            peer->client = peer_id ? tr_clientForId( peer_id ) : NULL;
    921937            peer->port = port;
    922938            peer->io = io;
     
    10031019
    10041020void
    1005 tr_peerMgrSetBlame( tr_peerMgr     * manager UNUSED,
    1006                     const uint8_t  * torrentHash UNUSED,
    1007                     int              pieceIndex UNUSED,
    1008                     int              success UNUSED )
    1009 {
    1010     /*fprintf( stderr, "FIXME: tr_peerMgrSetBlame\n" );*/
     1021tr_peerMgrSetBlame( tr_peerMgr     * manager,
     1022                    const uint8_t  * torrentHash,
     1023                    int              pieceIndex,
     1024                    int              success )
     1025{
     1026    if( !success )
     1027    {
     1028        int peerCount, i;
     1029        Torrent * t = getExistingTorrent( manager, torrentHash );
     1030        tr_peer ** peers;
     1031
     1032        assert( torrentIsLocked( t ) );
     1033
     1034        peers = (tr_peer **) tr_ptrArrayPeek( t->peers, &peerCount );
     1035        for( i=0; i<peerCount; ++i )
     1036        {
     1037            struct peer_atom * atom;
     1038            tr_peer * peer;
     1039
     1040            peer = peers[i];
     1041            if( !tr_bitfieldHas( peer->blame, pieceIndex ) )
     1042                continue;
     1043
     1044            ++peer->strikes;
     1045            tordbg( t, "peer %s contributed to corrupt piece (%d); now has %d strikes",
     1046                       tr_peerIoAddrStr(&peer->in_addr,peer->port),
     1047                       pieceIndex, (int)peer->strikes );
     1048            if( peer->strikes < MAX_BAD_PIECES_PER_PEER )
     1049                continue;
     1050
     1051            peer->doPurge = 1;
     1052            atom = getExistingAtom( t, &peer->in_addr );
     1053            atom->myflags |= MYFLAG_BANNED;
     1054            tordbg( t, "banning peer %s due to corrupt data", tr_peerIoAddrStr(&atom->addr,atom->port) );
     1055        }
     1056    }
    10111057}
    10121058
     
    15121558        struct peer_atom * atom = atoms[i];
    15131559
     1560        /* peer fed us too much bad data ... we only keep it around
     1561         * now to weed it out in case someone sends it to us via pex */
     1562        if( atom->myflags & MYFLAG_BANNED ) {
     1563            tordbg( t, "RECONNECT peer %d (%s) is banned...",
     1564                    i, tr_peerIoAddrStr(&atom->addr,atom->port) );
     1565            continue;
     1566        }
     1567
    15141568        /* we don't need two connections to the same peer... */
    15151569        if( peerIsInUse( t, &atom->addr ) ) {
Note: See TracChangeset for help on using the changeset viewer.