Changeset 7588


Ignore:
Timestamp:
Jan 2, 2009, 11:28:57 PM (12 years ago)
Author:
charles
Message:

(trunk libT) revert r7548, which broke very low speed download limits.. the simplified peer-msgs parsing didn't distinguish between piece & raw data until the piece was done downloading.

File:
1 edited

Legend:

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

    r7584 r7588  
    107107**/
    108108
     109enum
     110{
     111    AWAITING_BT_LENGTH,
     112    AWAITING_BT_ID,
     113    AWAITING_BT_MESSAGE,
     114    AWAITING_BT_PIECE
     115};
     116
    109117struct peer_request
    110118{
     
    245253struct tr_incoming
    246254{
    247     uint32_t          length; /* includes the +1 for id length */
    248     struct evbuffer * block; /* piece data for incoming blocks */
     255    uint8_t                id;
     256    uint32_t               length; /* includes the +1 for id length */
     257    struct peer_request    blockReq; /* metadata for incoming blocks */
     258    struct evbuffer *      block; /* piece data for incoming blocks */
    249259};
    250260
     
    270280    tr_bool         haveFastSet;
    271281
     282    uint8_t         state;
    272283    uint8_t         ut_pex_id;
    273284    uint16_t        pexCount;
     
    12681279
    12691280    tr_peerIoReadUint32( msgs->peer->io, inbuf, &len );
    1270     msgs->incoming.length = len;
    12711281
    12721282    if( len == 0 ) /* peer sent us a keepalive message */
    12731283        dbgmsg( msgs, "got KeepAlive" );
     1284    else
     1285    {
     1286        msgs->incoming.length = len;
     1287        msgs->state = AWAITING_BT_ID;
     1288    }
    12741289
    12751290    return READ_NOW;
     1291}
     1292
     1293static int readBtMessage( tr_peermsgs *     msgs,
     1294                          struct evbuffer * inbuf,
     1295                          size_t            inlen );
     1296
     1297static int
     1298readBtId( tr_peermsgs *     msgs,
     1299          struct evbuffer * inbuf,
     1300          size_t            inlen )
     1301{
     1302    uint8_t id;
     1303
     1304    if( inlen < sizeof( uint8_t ) )
     1305        return READ_LATER;
     1306
     1307    tr_peerIoReadUint8( msgs->peer->io, inbuf, &id );
     1308    msgs->incoming.id = id;
     1309
     1310    if( id == BT_PIECE )
     1311    {
     1312        msgs->state = AWAITING_BT_PIECE;
     1313        return READ_NOW;
     1314    }
     1315    else if( msgs->incoming.length != 1 )
     1316    {
     1317        msgs->state = AWAITING_BT_MESSAGE;
     1318        return READ_NOW;
     1319    }
     1320    else return readBtMessage( msgs, inbuf, inlen - 1 );
    12761321}
    12771322
     
    13621407             size_t           * setme_piece_bytes_read )
    13631408{
    1364     struct peer_request req;
     1409    struct peer_request * req = &msgs->incoming.blockReq;
    13651410
    13661411    assert( EVBUFFER_LENGTH( inbuf ) >= inlen );
    13671412    dbgmsg( msgs, "In readBtPiece" );
    13681413
    1369     tr_peerIoReadUint32( msgs->peer->io, inbuf, &req.index );
    1370     tr_peerIoReadUint32( msgs->peer->io, inbuf, &req.offset );
    1371     req.length = msgs->incoming.length - 9;
    1372     dbgmsg( msgs, "got incoming block header %u:%u->%u", req.index, req.offset, req.length );
    1373 
    1374     {
     1414    if( !req->length )
     1415    {
     1416        if( inlen < 8 )
     1417            return READ_LATER;
     1418
     1419        tr_peerIoReadUint32( msgs->peer->io, inbuf, &req->index );
     1420        tr_peerIoReadUint32( msgs->peer->io, inbuf, &req->offset );
     1421        req->length = msgs->incoming.length - 9;
     1422        dbgmsg( msgs, "got incoming block header %u:%u->%u", req->index, req->offset, req->length );
     1423        return READ_NOW;
     1424    }
     1425    else
     1426    {
    13751427        int err;
    13761428
    1377         /* decrypt the whole block in one go */
    1378         evbuffer_expand( msgs->incoming.block, req.length );
    1379         tr_peerIoReadBytes( msgs->peer->io, inbuf, EVBUFFER_DATA( msgs->incoming.block ), req.length );
    1380         EVBUFFER_LENGTH( msgs->incoming.block ) += req.length;
    1381 
    1382         fireClientGotData( msgs, req.length, TRUE );
    1383         *setme_piece_bytes_read += req.length;
    1384         dbgmsg( msgs, "got block %u:%u->%u", req.index, req.offset, req.length );
    1385         assert( EVBUFFER_LENGTH( msgs->incoming.block ) == req.length );
     1429        /* read in another chunk of data */
     1430        const size_t nLeft = req->length - EVBUFFER_LENGTH( msgs->incoming.block );
     1431        size_t n = MIN( nLeft, inlen );
     1432        size_t i = n;
     1433
     1434        while( i > 0 )
     1435        {
     1436            uint8_t buf[MAX_STACK_ARRAY_SIZE];
     1437            const size_t thisPass = MIN( i, sizeof( buf ) );
     1438            tr_peerIoReadBytes( msgs->peer->io, inbuf, buf, thisPass );
     1439            evbuffer_add( msgs->incoming.block, buf, thisPass );
     1440            i -= thisPass;
     1441        }
     1442
     1443        fireClientGotData( msgs, n, TRUE );
     1444        *setme_piece_bytes_read += n;
     1445        dbgmsg( msgs, "got %zu bytes for block %u:%u->%u ... %d remain",
     1446               n, req->index, req->offset, req->length,
     1447               (int)( req->length - EVBUFFER_LENGTH( msgs->incoming.block ) ) );
     1448        if( EVBUFFER_LENGTH( msgs->incoming.block ) < req->length )
     1449            return READ_LATER;
    13861450
    13871451        /* we've got the whole block ... process it */
    1388         err = clientGotBlock( msgs, EVBUFFER_DATA( msgs->incoming.block ), &req );
     1452        err = clientGotBlock( msgs, EVBUFFER_DATA( msgs->incoming.block ), req );
    13891453
    13901454        /* cleanup */
    13911455        evbuffer_drain( msgs->incoming.block, EVBUFFER_LENGTH( msgs->incoming.block ) );
     1456        req->length = 0;
     1457        msgs->state = AWAITING_BT_LENGTH;
    13921458        if( !err )
    13931459            return READ_NOW;
     
    14001466
    14011467static int
    1402 readBtMessage( tr_peermsgs * msgs, struct evbuffer * inbuf, size_t inlen, size_t * piece )
    1403 {
    1404     int           ret = READ_NOW;
    1405     uint8_t       id;
     1468readBtMessage( tr_peermsgs * msgs, struct evbuffer * inbuf, size_t inlen )
     1469{
    14061470    uint32_t      ui32;
    14071471    uint32_t      msglen = msgs->incoming.length;
     1472    const uint8_t id = msgs->incoming.id;
    14081473    const size_t  startBufLen = EVBUFFER_LENGTH( inbuf );
    14091474    const tr_bool fext = tr_peerIoSupportsFEXT( msgs->peer->io );
    14101475
     1476    --msglen; /* id length */
     1477
    14111478    if( inlen < msglen )
    14121479        return READ_LATER;
    14131480
    1414     tr_peerIoReadUint8( msgs->peer->io, inbuf, &id );
    1415 
    14161481    dbgmsg( msgs, "got BT id %d, len %d, buffer size is %zu", (int)id, (int)msglen, inlen );
    14171482
    1418     if( !messageLengthIsCorrect( msgs, id, msglen ) )
     1483    if( !messageLengthIsCorrect( msgs, id, msglen + 1 ) )
    14191484    {
    14201485        dbgmsg( msgs, "bad packet - BT message #%d with a length of %d", (int)id, (int)msglen );
     
    14221487        return READ_ERR;
    14231488    }
    1424 
    1425     --msglen;
    14261489
    14271490    switch( id )
     
    14951558
    14961559        case BT_PIECE:
    1497             ret = readBtPiece( msgs, inbuf, msglen, piece );
     1560            assert( 0 ); /* handled elsewhere! */
    14981561            break;
    14991562
     
    15741637    }
    15751638
    1576     assert( EVBUFFER_LENGTH( inbuf ) == startBufLen - msglen - 1 );
    1577 
    1578     msgs->incoming.length = 0;
    1579     return ret;
     1639    assert( msglen + 1 == msgs->incoming.length );
     1640    assert( EVBUFFER_LENGTH( inbuf ) == startBufLen - msglen );
     1641
     1642    msgs->state = AWAITING_BT_LENGTH;
     1643    return READ_NOW;
    15801644}
    15811645
     
    16781742
    16791743    if( !inlen )
    1680         return READ_LATER;
    1681 
    1682     /* Incoming data is processed in two stages. First the length is read
    1683      * and then readBtMessage() waits until all the data has arrived in
    1684      * the input buffer before starting to parse it */
    1685     if( msgs->incoming.length == 0 )
    1686         ret = readBtLength ( msgs, in, inlen );
    1687     else
    1688         ret = readBtMessage( msgs, in, inlen, piece );
     1744    {
     1745        ret = READ_LATER;
     1746    }
     1747    else if( msgs->state == AWAITING_BT_PIECE )
     1748    {
     1749        ret = inlen ? readBtPiece( msgs, in, inlen, piece ) : READ_LATER;
     1750    }
     1751    else switch( msgs->state )
     1752    {
     1753        case AWAITING_BT_LENGTH:
     1754            ret = readBtLength ( msgs, in, inlen ); break;
     1755
     1756        case AWAITING_BT_ID:
     1757            ret = readBtId     ( msgs, in, inlen ); break;
     1758
     1759        case AWAITING_BT_MESSAGE:
     1760            ret = readBtMessage( msgs, in, inlen ); break;
     1761
     1762        default:
     1763            assert( 0 );
     1764    }
    16891765
    16901766    /* log the raw data that was read */
     
    21662242    m->peer->peerIsInterested = 0;
    21672243    m->peer->have = tr_bitfieldNew( torrent->info.pieceCount );
     2244    m->state = AWAITING_BT_LENGTH;
    21682245    m->pexTimer = tr_timerNew( m->session, pexPulse, m, PEX_INTERVAL );
    21692246    m->outMessages = evbuffer_new( );
Note: See TracChangeset for help on using the changeset viewer.