Changeset 7548
- Timestamp:
- Dec 30, 2008, 7:44:49 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/peer-msgs.c
r7546 r7548 107 107 **/ 108 108 109 enum110 {111 AWAITING_BT_LENGTH,112 AWAITING_BT_ID,113 AWAITING_BT_MESSAGE,114 AWAITING_BT_PIECE115 };116 117 109 struct peer_request 118 110 { … … 253 245 struct tr_incoming 254 246 { 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 */ 247 uint32_t length; /* includes the +1 for id length */ 248 struct evbuffer * block; /* piece data for incoming blocks */ 259 249 }; 260 250 … … 281 271 tr_bool haveFastSet; 282 272 283 uint8_t state;284 273 uint8_t ut_pex_id; 285 274 uint16_t pexCount; … … 1280 1269 1281 1270 tr_peerIoReadUint32( msgs->peer->io, inbuf, &len ); 1271 msgs->incoming.length = len; 1282 1272 1283 1273 if( len == 0 ) /* peer sent us a keepalive message */ 1284 1274 dbgmsg( msgs, "got KeepAlive" ); 1285 else1286 {1287 msgs->incoming.length = len;1288 msgs->state = AWAITING_BT_ID;1289 }1290 1275 1291 1276 return READ_NOW; 1292 }1293 1294 static int readBtMessage( tr_peermsgs * msgs,1295 struct evbuffer * inbuf,1296 size_t inlen );1297 1298 static int1299 readBtId( tr_peermsgs * msgs,1300 struct evbuffer * inbuf,1301 size_t inlen )1302 {1303 uint8_t id;1304 1305 if( inlen < sizeof( uint8_t ) )1306 return READ_LATER;1307 1308 tr_peerIoReadUint8( msgs->peer->io, inbuf, &id );1309 msgs->incoming.id = id;1310 1311 if( id == BT_PIECE )1312 {1313 msgs->state = AWAITING_BT_PIECE;1314 return READ_NOW;1315 }1316 else if( msgs->incoming.length != 1 )1317 {1318 msgs->state = AWAITING_BT_MESSAGE;1319 return READ_NOW;1320 }1321 else return readBtMessage( msgs, inbuf, inlen - 1 );1322 1277 } 1323 1278 … … 1408 1363 size_t * setme_piece_bytes_read ) 1409 1364 { 1410 struct peer_request * req = &msgs->incoming.blockReq;1365 struct peer_request req; 1411 1366 1412 1367 assert( EVBUFFER_LENGTH( inbuf ) >= inlen ); 1413 1368 dbgmsg( msgs, "In readBtPiece" ); 1414 1369 1415 if( !req->length ) 1416 { 1417 if( inlen < 8 ) 1418 return READ_LATER; 1419 1420 tr_peerIoReadUint32( msgs->peer->io, inbuf, &req->index ); 1421 tr_peerIoReadUint32( msgs->peer->io, inbuf, &req->offset ); 1422 req->length = msgs->incoming.length - 9; 1423 dbgmsg( msgs, "got incoming block header %u:%u->%u", req->index, req->offset, req->length ); 1424 return READ_NOW; 1425 } 1426 else 1427 { 1370 tr_peerIoReadUint32( msgs->peer->io, inbuf, &req.index ); 1371 tr_peerIoReadUint32( msgs->peer->io, inbuf, &req.offset ); 1372 req.length = msgs->incoming.length - 9; 1373 dbgmsg( msgs, "got incoming block header %u:%u->%u", req.index, req.offset, req.length ); 1374 1375 { 1428 1376 int err; 1429 1377 1430 /* read in another chunk of data */ 1431 const size_t nLeft = req->length - EVBUFFER_LENGTH( msgs->incoming.block ); 1432 size_t n = MIN( nLeft, inlen ); 1433 size_t i = n; 1434 1435 while( i > 0 ) 1436 { 1437 uint8_t buf[MAX_STACK_ARRAY_SIZE]; 1438 const size_t thisPass = MIN( i, sizeof( buf ) ); 1439 tr_peerIoReadBytes( msgs->peer->io, inbuf, buf, thisPass ); 1440 evbuffer_add( msgs->incoming.block, buf, thisPass ); 1441 i -= thisPass; 1442 } 1443 1444 fireClientGotData( msgs, n, TRUE ); 1445 *setme_piece_bytes_read += n; 1446 dbgmsg( msgs, "got %zu bytes for block %u:%u->%u ... %d remain", 1447 n, req->index, req->offset, req->length, 1448 (int)( req->length - EVBUFFER_LENGTH( msgs->incoming.block ) ) ); 1449 if( EVBUFFER_LENGTH( msgs->incoming.block ) < req->length ) 1450 return READ_LATER; 1378 /* decrypt the whole block in one go */ 1379 evbuffer_expand( msgs->incoming.block, req.length ); 1380 tr_peerIoReadBytes( msgs->peer->io, inbuf, EVBUFFER_DATA( msgs->incoming.block ), req.length ); 1381 EVBUFFER_LENGTH( msgs->incoming.block ) += req.length; 1382 1383 fireClientGotData( msgs, req.length, TRUE ); 1384 *setme_piece_bytes_read += req.length; 1385 dbgmsg( msgs, "got block %u:%u->%u", req.index, req.offset, req.length ); 1386 assert( EVBUFFER_LENGTH( msgs->incoming.block ) == req.length ); 1451 1387 1452 1388 /* we've got the whole block ... process it */ 1453 err = clientGotBlock( msgs, EVBUFFER_DATA( msgs->incoming.block ), req );1389 err = clientGotBlock( msgs, EVBUFFER_DATA( msgs->incoming.block ), &req ); 1454 1390 1455 1391 /* cleanup */ 1456 1392 evbuffer_drain( msgs->incoming.block, EVBUFFER_LENGTH( msgs->incoming.block ) ); 1457 req->length = 0;1458 msgs->state = AWAITING_BT_LENGTH;1459 1393 if( !err ) 1460 1394 return READ_NOW; … … 1467 1401 1468 1402 static int 1469 readBtMessage( tr_peermsgs * msgs, struct evbuffer * inbuf, size_t inlen ) 1470 { 1403 readBtMessage( tr_peermsgs * msgs, struct evbuffer * inbuf, size_t inlen, size_t * piece ) 1404 { 1405 int ret = READ_NOW; 1406 uint8_t id; 1471 1407 uint32_t ui32; 1472 1408 uint32_t msglen = msgs->incoming.length; 1473 const uint8_t id = msgs->incoming.id;1474 1409 const size_t startBufLen = EVBUFFER_LENGTH( inbuf ); 1475 1410 const tr_bool fext = tr_peerIoSupportsFEXT( msgs->peer->io ); 1476 1411 1477 --msglen; /* id length */1478 1479 1412 if( inlen < msglen ) 1480 1413 return READ_LATER; 1481 1414 1415 tr_peerIoReadUint8( msgs->peer->io, inbuf, &id ); 1416 1482 1417 dbgmsg( msgs, "got BT id %d, len %d, buffer size is %zu", (int)id, (int)msglen, inlen ); 1483 1418 1484 if( !messageLengthIsCorrect( msgs, id, msglen + 1) )1419 if( !messageLengthIsCorrect( msgs, id, msglen ) ) 1485 1420 { 1486 1421 dbgmsg( msgs, "bad packet - BT message #%d with a length of %d", (int)id, (int)msglen ); … … 1488 1423 return READ_ERR; 1489 1424 } 1425 1426 --msglen; 1490 1427 1491 1428 switch( id ) … … 1560 1497 1561 1498 case BT_PIECE: 1562 assert( 0 ); /* handled elsewhere! */1499 ret = readBtPiece( msgs, inbuf, msglen, piece ); 1563 1500 break; 1564 1501 … … 1639 1576 } 1640 1577 1641 assert( msglen + 1 == msgs->incoming.length ); 1642 assert( EVBUFFER_LENGTH( inbuf ) == startBufLen - msglen ); 1643 1644 msgs->state = AWAITING_BT_LENGTH; 1645 return READ_NOW; 1578 assert( EVBUFFER_LENGTH( inbuf ) == startBufLen - msglen - 1 ); 1579 1580 msgs->incoming.length = 0; 1581 return ret; 1646 1582 } 1647 1583 … … 1744 1680 1745 1681 if( !inlen ) 1746 { 1747 ret = READ_LATER; 1748 } 1749 else if( msgs->state == AWAITING_BT_PIECE ) 1750 { 1751 ret = inlen ? readBtPiece( msgs, in, inlen, piece ) : READ_LATER; 1752 } 1753 else switch( msgs->state ) 1754 { 1755 case AWAITING_BT_LENGTH: 1756 ret = readBtLength ( msgs, in, inlen ); break; 1757 1758 case AWAITING_BT_ID: 1759 ret = readBtId ( msgs, in, inlen ); break; 1760 1761 case AWAITING_BT_MESSAGE: 1762 ret = readBtMessage( msgs, in, inlen ); break; 1763 1764 default: 1765 assert( 0 ); 1766 } 1682 return READ_LATER; 1683 1684 /* Incoming data is processed in two stages. First the length is read 1685 * and then readBtMessage() waits until all the data has arrived in 1686 * the input buffer before starting to parse it */ 1687 if( msgs->incoming.length == 0 ) 1688 ret = readBtLength ( msgs, in, inlen ); 1689 else 1690 ret = readBtMessage( msgs, in, inlen, piece ); 1767 1691 1768 1692 /* log the raw data that was read */ … … 2247 2171 m->peer->peerIsInterested = 0; 2248 2172 m->peer->have = tr_bitfieldNew( torrent->info.pieceCount ); 2249 m->state = AWAITING_BT_LENGTH;2250 2173 m->pexTimer = tr_timerNew( m->session, pexPulse, m, PEX_INTERVAL ); 2251 2174 m->outMessages = evbuffer_new( );
Note: See TracChangeset
for help on using the changeset viewer.