Ignore:
Timestamp:
Nov 10, 2007, 4:56:27 AM (13 years ago)
Author:
charles
Message:
  • fix a bug that could corrupt peer connections, causing slower speeds and/or fewer connections
  • add more assertions to smoke out any remaining BT protocol bugs
File:
1 edited

Legend:

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

    r3775 r3777  
    953953
    954954static void
    955 clientGotBlock( tr_peermsgs * msgs, struct evbuffer * inbuf, const struct peer_request * req );
     955clientGotBlock( tr_peermsgs * msgs, const uint8_t * block, const struct peer_request * req );
    956956
    957957static int
     
    961961    uint32_t ui32;
    962962    uint32_t msglen = msgs->incomingMessageLength;
     963    const size_t startBufLen = EVBUFFER_LENGTH( inbuf );
    963964
    964965    if( EVBUFFER_LENGTH(inbuf) < msglen )
     
    966967
    967968    tr_peerIoReadUint8( msgs->io, inbuf, &id );
    968     dbgmsg( msgs, "got BT id %d, len %d", (int)id, (int)msglen );
     969    dbgmsg( msgs, "got BT id %d, len %d, buffer size is %d", (int)id, (int)msglen, (int)EVBUFFER_LENGTH(inbuf) );
     970
     971assert( messageLengthIsCorrect( msgs, id, msglen ) );
    969972
    970973    if( !messageLengthIsCorrect( msgs, id, msglen ) )
     
    979982    switch( id )
    980983    {
    981         case BT_CHOKE:
    982             dbgmsg( msgs, "got Choke" );
    983             msgs->info->clientIsChoked = 1;
    984             cancelAllRequestsToPeer( msgs );
    985             cancelAllRequestsToClientExceptFast( msgs );
    986             break;
    987 
    988         case BT_UNCHOKE:
    989             dbgmsg( msgs, "got Unchoke" );
    990             msgs->info->clientIsChoked = 0;
    991             fireNeedReq( msgs );
    992             break;
    993 
    994         case BT_INTERESTED:
    995             dbgmsg( msgs, "got Interested" );
    996             msgs->info->peerIsInterested = 1;
    997             tr_peerMsgsSetChoke( msgs, 0 );
    998             break;
    999 
    1000         case BT_NOT_INTERESTED:
    1001             dbgmsg( msgs, "got Not Interested" );
    1002             msgs->info->peerIsInterested = 0;
    1003             break;
    1004 
    1005         case BT_HAVE:
    1006             tr_peerIoReadUint32( msgs->io, inbuf, &ui32 );
    1007             dbgmsg( msgs, "got Have: %u", ui32 );
    1008             tr_bitfieldAdd( msgs->info->have, ui32 );
    1009             updatePeerProgress( msgs );
    1010             tr_rcTransferred( msgs->torrent->swarmspeed, msgs->torrent->info.pieceSize );
    1011             break;
    1012 
    1013         case BT_BITFIELD: {
    1014             const int clientIsSeed = tr_torrentIsSeed( msgs->torrent );
    1015             dbgmsg( msgs, "got a bitfield" );
    1016             tr_peerIoReadBytes( msgs->io, inbuf, msgs->info->have->bits, msglen );
    1017             updatePeerProgress( msgs );
    1018             tr_peerMsgsSetChoke( msgs, !clientIsSeed || (msgs->info->progress<1.0) );
    1019             fireNeedReq( msgs );
    1020             break;
    1021         }
    1022 
    1023         case BT_REQUEST: {
    1024             struct peer_request req;
    1025             tr_peerIoReadUint32( msgs->io, inbuf, &req.index );
    1026             tr_peerIoReadUint32( msgs->io, inbuf, &req.offset );
    1027             tr_peerIoReadUint32( msgs->io, inbuf, &req.length );
    1028             dbgmsg( msgs, "got Request: %u:%u->%u", req.index, req.offset, req.length );
    1029             peerMadeRequest( msgs, &req );
    1030             break;
    1031         }
    1032 
    1033         case BT_CANCEL: {
    1034             struct peer_request req;
    1035             tr_peerIoReadUint32( msgs->io, inbuf, &req.index );
    1036             tr_peerIoReadUint32( msgs->io, inbuf, &req.offset );
    1037             tr_peerIoReadUint32( msgs->io, inbuf, &req.length );
    1038             dbgmsg( msgs, "got a Cancel %u:%u->%u", req.index, req.offset, req.length );
    1039             tr_free( tr_list_remove( &msgs->peerAskedForFast, &req, compareRequest ) );
    1040             tr_free( tr_list_remove( &msgs->peerAskedFor, &req, compareRequest ) );
    1041             break;
    1042         }
    1043 
    1044         case BT_PIECE: {
     984        case BT_CHOKE:
     985            dbgmsg( msgs, "got Choke" );
     986            msgs->info->clientIsChoked = 1;
     987            cancelAllRequestsToPeer( msgs );
     988            cancelAllRequestsToClientExceptFast( msgs );
     989            break;
     990
     991        case BT_UNCHOKE:
     992            dbgmsg( msgs, "got Unchoke" );
     993            msgs->info->clientIsChoked = 0;
     994            fireNeedReq( msgs );
     995            break;
     996
     997        case BT_INTERESTED:
     998            dbgmsg( msgs, "got Interested" );
     999            msgs->info->peerIsInterested = 1;
     1000            tr_peerMsgsSetChoke( msgs, 0 );
     1001            break;
     1002
     1003        case BT_NOT_INTERESTED:
     1004            dbgmsg( msgs, "got Not Interested" );
     1005            msgs->info->peerIsInterested = 0;
     1006            break;
     1007
     1008        case BT_HAVE:
     1009            tr_peerIoReadUint32( msgs->io, inbuf, &ui32 );
     1010            dbgmsg( msgs, "got Have: %u", ui32 );
     1011            tr_bitfieldAdd( msgs->info->have, ui32 );
     1012            updatePeerProgress( msgs );
     1013            tr_rcTransferred( msgs->torrent->swarmspeed, msgs->torrent->info.pieceSize );
     1014            break;
     1015
     1016        case BT_BITFIELD: {
     1017            const int clientIsSeed = tr_torrentIsSeed( msgs->torrent );
     1018            dbgmsg( msgs, "got a bitfield" );
     1019            tr_peerIoReadBytes( msgs->io, inbuf, msgs->info->have->bits, msglen );
     1020            updatePeerProgress( msgs );
     1021            tr_peerMsgsSetChoke( msgs, !clientIsSeed || (msgs->info->progress<1.0) );
     1022            fireNeedReq( msgs );
     1023            break;
     1024        }
     1025
     1026        case BT_REQUEST: {
    10451027            struct peer_request req;
    1046             tr_peerIoReadUint32( msgs->io, inbuf, &req.index );
    1047             tr_peerIoReadUint32( msgs->io, inbuf, &req.offset );
     1028            tr_peerIoReadUint32( msgs->io, inbuf, &req.index );
     1029            tr_peerIoReadUint32( msgs->io, inbuf, &req.offset );
     1030            tr_peerIoReadUint32( msgs->io, inbuf, &req.length );
     1031            dbgmsg( msgs, "got Request: %u:%u->%u", req.index, req.offset, req.length );
     1032            peerMadeRequest( msgs, &req );
     1033            break;
     1034        }
     1035
     1036        case BT_CANCEL: {
     1037            struct peer_request req;
     1038            tr_peerIoReadUint32( msgs->io, inbuf, &req.index );
     1039            tr_peerIoReadUint32( msgs->io, inbuf, &req.offset );
     1040            tr_peerIoReadUint32( msgs->io, inbuf, &req.length );
     1041            dbgmsg( msgs, "got a Cancel %u:%u->%u", req.index, req.offset, req.length );
     1042            tr_free( tr_list_remove( &msgs->peerAskedForFast, &req, compareRequest ) );
     1043            tr_free( tr_list_remove( &msgs->peerAskedFor, &req, compareRequest ) );
     1044            break;
     1045        }
     1046
     1047        case BT_PIECE: {
     1048            uint8_t * block;
     1049            struct peer_request req;
     1050            tr_peerIoReadUint32( msgs->io, inbuf, &req.index );
     1051            tr_peerIoReadUint32( msgs->io, inbuf, &req.offset );
    10481052            req.length = msglen - 8;
    1049             dbgmsg( msgs, "got a Block %u:%u->%u", req.index, req.offset, req.length );
    1050             clientGotBlock( msgs, inbuf, &req );
    1051             break;
     1053            block = tr_new( uint8_t, req.length );
     1054            tr_peerIoReadBytes( msgs->io, inbuf, block, req.length );
     1055            dbgmsg( msgs, "got a Block %u:%u->%u", req.index, req.offset, req.length );
     1056            clientGotBlock( msgs, block, &req );
     1057            tr_free( block );
     1058            break;
    10521059        }
    10531060
    1054         case BT_PORT:
    1055             dbgmsg( msgs, "Got a BT_PORT" );
    1056             tr_peerIoReadUint16( msgs->io, inbuf, &msgs->info->port );
    1057             break;
    1058    
     1061        case BT_PORT:
     1062            dbgmsg( msgs, "Got a BT_PORT" );
     1063            tr_peerIoReadUint16( msgs->io, inbuf, &msgs->info->port );
     1064            break;
     1065
    10591066#if 0
    1060         case BT_SUGGEST: {
    1061             /* FIXME(tiennou) */
    1062             uint32_t index;
    1063             tr_peerIoReadUint32( msgs->io, inbuf, &index );
    1064             break;
    1065         }
    1066        
    1067         case BT_HAVE_ALL:
    1068             dbgmsg( msgs, "Got a BT_HAVE_ALL" );
     1067        case BT_SUGGEST: {
     1068            /* FIXME(tiennou) */
     1069            uint32_t index;
     1070            tr_peerIoReadUint32( msgs->io, inbuf, &index );
     1071            break;
     1072        }
     1073
     1074        case BT_HAVE_ALL:
     1075            dbgmsg( msgs, "Got a BT_HAVE_ALL" );
    10691076            tr_bitfieldAddRange( msgs->info->have, 0, msgs->torrent->info.pieceCount );
    1070             updatePeerProgress( msgs );
    1071             break;
    1072        
    1073         case BT_HAVE_NONE:
    1074             dbgmsg( msgs, "Got a BT_HAVE_NONE" );
    1075             tr_bitfieldClear( msgs->info->have );
    1076             updatePeerProgress( msgs );
    1077             break;
    1078        
    1079         case BT_REJECT: {
    1080             struct peer_request req;
    1081             dbgmsg( msgs, "Got a BT_REJECT" );
    1082             tr_peerIoReadUint32( msgs->io, inbuf, &req.index );
    1083             tr_peerIoReadUint32( msgs->io, inbuf, &req.offset );
    1084             tr_peerIoReadUint32( msgs->io, inbuf, &req.length );
    1085             tr_free( tr_list_remove( &msgs->clientAskedFor, &req, compareRequest ) );
    1086             break;
    1087         }
    1088        
    1089         case BT_ALLOWED_FAST: {
    1090             dbgmsg( msgs, "Got a BT_ALLOWED_FAST" );
    1091             tr_peerIoReadUint32( msgs->io, inbuf, &ui32 );
    1092             tr_bitfieldAdd( msgs->clientAllowedPieces, ui32 );
    1093             break;
    1094         }
     1077            updatePeerProgress( msgs );
     1078            break;
     1079
     1080        case BT_HAVE_NONE:
     1081            dbgmsg( msgs, "Got a BT_HAVE_NONE" );
     1082            tr_bitfieldClear( msgs->info->have );
     1083            updatePeerProgress( msgs );
     1084            break;
     1085
     1086        case BT_REJECT: {
     1087            struct peer_request req;
     1088            dbgmsg( msgs, "Got a BT_REJECT" );
     1089            tr_peerIoReadUint32( msgs->io, inbuf, &req.index );
     1090            tr_peerIoReadUint32( msgs->io, inbuf, &req.offset );
     1091            tr_peerIoReadUint32( msgs->io, inbuf, &req.length );
     1092            tr_free( tr_list_remove( &msgs->clientAskedFor, &req, compareRequest ) );
     1093            break;
     1094        }
     1095
     1096        case BT_ALLOWED_FAST: {
     1097            dbgmsg( msgs, "Got a BT_ALLOWED_FAST" );
     1098            tr_peerIoReadUint32( msgs->io, inbuf, &ui32 );
     1099            tr_bitfieldAdd( msgs->clientAllowedPieces, ui32 );
     1100            break;
     1101        }
    10951102#endif
    1096        
    1097         case BT_LTEP:
    1098             dbgmsg( msgs, "Got a BT_LTEP" );
    1099             parseLtep( msgs, msglen, inbuf );
    1100             break;
    1101 
    1102         default:
    1103             dbgmsg( msgs, "peer sent us an UNKNOWN: %d", (int)id );
    1104             tr_peerIoDrain( msgs->io, inbuf, msglen );
    1105             break;
    1106     }
     1103
     1104        case BT_LTEP:
     1105            dbgmsg( msgs, "Got a BT_LTEP" );
     1106            parseLtep( msgs, msglen, inbuf );
     1107            break;
     1108
     1109        default:
     1110            dbgmsg( msgs, "peer sent us an UNKNOWN: %d", (int)id );
     1111            tr_peerIoDrain( msgs->io, inbuf, msglen );
     1112assert( 0 );
     1113            break;
     1114    }
     1115
     1116
     1117    dbgmsg( msgs, "startBufLen was %d, msglen was %d, current inbuf len is %d", (int)startBufLen, (int)(msglen+1), (int)EVBUFFER_LENGTH(inbuf) );
     1118assert( msglen + 1 == msgs->incomingMessageLength );
     1119assert( EVBUFFER_LENGTH(inbuf) == startBufLen - msgs->incomingMessageLength );
    11071120
    11081121    msgs->incomingMessageLength = -1;
     
    11871200
    11881201static void
    1189 clientGotBlock( tr_peermsgs * msgs, struct evbuffer * inbuf, const struct peer_request * req )
     1202clientGotBlock( tr_peermsgs * msgs, const uint8_t * data, const struct peer_request * req )
    11901203{
    11911204    int i;
    1192     uint8_t * data;
    11931205    tr_torrent * tor = msgs->torrent;
    11941206    const int block = _tr_block( tor, req->index, req->offset );
     
    11961208
    11971209    assert( msgs != NULL );
    1198     assert( inbuf != NULL );
    11991210    assert( req != NULL );
    12001211    assert( req->length > 0 );
    1201     assert( EVBUFFER_LENGTH( inbuf ) >= req->length );
    12021212    assert( req->length == (uint32_t)tr_torBlockCountBytes( msgs->torrent, block ) );
    12031213
     
    12361246    **/
    12371247
    1238     data = tr_new( uint8_t, req->length );
    1239     tr_peerIoReadBytes( msgs->io, inbuf, data, req->length );
    12401248    msgs->info->peerSentPieceDataAt = time( NULL );
    12411249    clientGotBytes( msgs, req->length );
    12421250    i = tr_ioWrite( tor, req->index, req->offset, req->length, data );
    1243     tr_free( data );
    12441251    if( i )
    12451252        return;
Note: See TracChangeset for help on using the changeset viewer.