Changeset 3818


Ignore:
Timestamp:
Nov 13, 2007, 5:36:43 AM (14 years ago)
Author:
charles
Message:
  • fix the `req->length == (uint32_t)( ((block)==((msgs->torrent)->blockCount-1))' bug.
  • there seems to be a pattern for peers that were (intentionally?) giving incomplete data to trigger the bug above. when a peer does this, give them a strike on its three-strikes-and-you're-banned count
Location:
trunk/libtransmission
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/peer-mgr.c

    r3792 r3818  
    814814
    815815static void
     816addStrike( Torrent * t, tr_peer * peer )
     817{
     818    tordbg( t, "increasing peer %s strike count to %d", tr_peerIoAddrStr(&peer->in_addr,peer->port), peer->strikes+1 );
     819
     820    if( ++peer->strikes >= MAX_BAD_PIECES_PER_PEER )
     821    {
     822        struct peer_atom * atom = getExistingAtom( t, &peer->in_addr );
     823        atom->myflags |= MYFLAG_BANNED;
     824        peer->doPurge = 1;
     825        tordbg( t, "banning peer %s", tr_peerIoAddrStr(&atom->addr,atom->port) );
     826    }
     827}
     828
     829static void
    816830msgsCallbackFunc( void * vpeer, void * vevent, void * vt )
    817831{
     
    854868        case TR_PEERMSG_CLIENT_BLOCK:
    855869            broadcastGotBlock( t, e->pieceIndex, e->offset, e->length );
     870            break;
     871
     872        case TR_PEERMSG_GOT_ASSERT_ERROR:
     873            addStrike( t, peer );
     874            peer->doPurge = 1;
    856875            break;
    857876
     
    10701089        for( i=0; i<peerCount; ++i )
    10711090        {
    1072             struct peer_atom * atom;
    1073             tr_peer * peer;
    1074 
    1075             peer = peers[i];
    1076             if( !tr_bitfieldHas( peer->blame, pieceIndex ) )
    1077                 continue;
    1078 
    1079             ++peer->strikes;
    1080             tordbg( t, "peer %s contributed to corrupt piece (%d); now has %d strikes",
    1081                        tr_peerIoAddrStr(&peer->in_addr,peer->port),
    1082                        pieceIndex, (int)peer->strikes );
    1083             if( peer->strikes < MAX_BAD_PIECES_PER_PEER )
    1084                 continue;
    1085 
    1086             atom = getExistingAtom( t, &peer->in_addr );
    1087             atom->myflags |= MYFLAG_BANNED;
    1088             peer->doPurge = 1;
    1089             tordbg( t, "banning peer %s due to corrupt data", tr_peerIoAddrStr(&atom->addr,atom->port) );
     1091            tr_peer * peer = peers[i];
     1092            if( tr_bitfieldHas( peer->blame, pieceIndex ) )
     1093            {
     1094                tordbg( t, "peer %s contributed to corrupt piece (%d); now has %d strikes",
     1095                           tr_peerIoAddrStr(&peer->in_addr,peer->port),
     1096                           pieceIndex, (int)peer->strikes+1 );
     1097                addStrike( t, peer );
     1098            }
    10901099        }
    10911100    }
  • trunk/libtransmission/peer-msgs.c

    r3792 r3818  
    252252
    253253static void
     254fireGotAssertError( tr_peermsgs * msgs )
     255{
     256    tr_peermsgs_event e = blankEvent;
     257    e.eventType = TR_PEERMSG_GOT_ASSERT_ERROR;
     258    publish( msgs, &e );
     259}
     260
     261static void
    254262fireGotError( tr_peermsgs * msgs )
    255263{
     
    969977}
    970978
    971 static void
     979static int
    972980clientGotBlock( tr_peermsgs * msgs, const uint8_t * block, const struct peer_request * req );
    973981
     
    975983readBtMessage( tr_peermsgs * msgs, struct evbuffer * inbuf )
    976984{
     985    int ret;
    977986    uint8_t id;
    978987    uint32_t ui32;
     
    986995    dbgmsg( msgs, "got BT id %d, len %d, buffer size is %d", (int)id, (int)msglen, (int)EVBUFFER_LENGTH(inbuf) );
    987996
    988 assert( messageLengthIsCorrect( msgs, id, msglen ) );
    989 
    990997    if( !messageLengthIsCorrect( msgs, id, msglen ) )
    991998    {
     
    9961003
    9971004    --msglen;
    998 
     1005    ret = 0;
    9991006    switch( id )
    10001007    {
     
    10741081            tr_peerIoReadBytes( msgs->io, inbuf, block, req.length );
    10751082            dbgmsg( msgs, "got a Block %u:%u->%u", req.index, req.offset, req.length );
    1076             clientGotBlock( msgs, block, &req );
     1083            ret = clientGotBlock( msgs, block, &req );
    10771084            tr_free( block );
    10781085            break;
     
    11351142    }
    11361143
    1137 
    11381144    dbgmsg( msgs, "startBufLen was %d, msglen was %d, current inbuf len is %d", (int)startBufLen, (int)(msglen+1), (int)EVBUFFER_LENGTH(inbuf) );
    1139 assert( msglen + 1 == msgs->incomingMessageLength );
    1140 assert( EVBUFFER_LENGTH(inbuf) == startBufLen - msgs->incomingMessageLength );
    1141 
    1142     msgs->incomingMessageLength = -1;
    1143     msgs->state = AWAITING_BT_LENGTH;
    1144     return READ_AGAIN;
     1145
     1146    if( ret == (int)TR_ERROR_ASSERT )
     1147    {
     1148        fireGotAssertError( msgs );
     1149        return READ_DONE;
     1150    }
     1151    else if( ret == TR_OK )
     1152    {
     1153        assert( msglen + 1 == msgs->incomingMessageLength );
     1154        assert( EVBUFFER_LENGTH(inbuf) == startBufLen - msgs->incomingMessageLength );
     1155
     1156        msgs->incomingMessageLength = -1;
     1157        msgs->state = AWAITING_BT_LENGTH;
     1158        return READ_AGAIN;
     1159    }
     1160    else
     1161    {
     1162        fireGotError( msgs );
     1163        return READ_DONE;
     1164    }
    11451165}
    11461166
     
    12201240}
    12211241
    1222 static void
     1242static int
    12231243clientGotBlock( tr_peermsgs * msgs, const uint8_t * data, const struct peer_request * req )
    12241244{
     
    12301250    assert( msgs != NULL );
    12311251    assert( req != NULL );
    1232     assert( req->length > 0 );
    1233     assert( req->length == (uint32_t)tr_torBlockCountBytes( msgs->torrent, block ) );
     1252
     1253    if( req->length != (uint32_t)tr_torBlockCountBytes( msgs->torrent, block ) )
     1254    {
     1255        dbgmsg( msgs, "wrong block size -- expected %u, got %d",
     1256                tr_torBlockCountBytes( msgs->torrent, block ), req->length );
     1257        return TR_ERROR_ASSERT;
     1258    }
    12341259
    12351260    /* save the block */
     
    12441269        clientGotUnwantedBlock( msgs, req );
    12451270        dbgmsg( msgs, "we didn't ask for this message..." );
    1246         return;
     1271        return 0;
    12471272    }
    12481273
     
    12601285        dbgmsg( msgs, "we have this block already..." );
    12611286        clientGotUnwantedBlock( msgs, req );
    1262         return;
     1287        return 0;
    12631288    }
    12641289
     
    12711296    i = tr_ioWrite( tor, req->index, req->offset, req->length, data );
    12721297    if( i )
    1273         return;
    1274 
    1275 #warning this sanity check is here to help track down the excess corrupt data bug, but is expensive and should be removed before the next release
    1276 {
    1277     uint8_t * check = tr_new( uint8_t, req->length );
    1278     const int val = tr_ioRead( tor, req->index, req->offset, req->length, check );
    1279     assert( !val );
    1280     assert( !memcmp( check, data, req->length ) );
    1281     tr_free( check );
    1282 }
     1298        return 0;
    12831299
    12841300    tr_cpBlockAdd( tor->completion, block );
     
    12971313        {
    12981314            gotBadPiece( msgs, req->index );
    1299             return;
     1315            return 0;
    13001316        }
    13011317
    13021318        fireClientHave( msgs, req->index );
    13031319    }
     1320
     1321    return 0;
    13041322}
    13051323
  • trunk/libtransmission/peer-msgs.h

    r3785 r3818  
    6666    TR_PEERMSG_PEER_PROGRESS,
    6767    TR_PEERMSG_GOT_ERROR,
     68    TR_PEERMSG_GOT_ASSERT_ERROR,
    6869    TR_PEERMSG_CANCEL,
    6970    TR_PEERMSG_NEED_REQ
Note: See TracChangeset for help on using the changeset viewer.