Changeset 7186
- Timestamp:
- Nov 29, 2008, 8:37:34 PM (12 years ago)
- Location:
- trunk/libtransmission
- Files:
-
- 1 deleted
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/Makefile.am
r7162 r7186 111 111 json-test \ 112 112 rpc-test \ 113 test-fastset \114 113 test-peer-id \ 115 114 utils-test … … 152 151 rpc_test_LDFLAGS = ${apps_ldflags} 153 152 154 test_fastset_SOURCES = test-fastset.c155 test_fastset_LDADD = ${apps_ldadd}156 test_fastset_LDFLAGS = ${apps_ldflags}157 158 153 test_peer_id_SOURCES = test-peer-id.c 159 154 test_peer_id_LDADD = ${apps_ldadd} -
trunk/libtransmission/handshake.c
r7173 r7186 71 71 #define HANDSHAKE_HAS_LTEP( bits ) ( 0 ) 72 72 #define HANDSHAKE_SET_LTEP( bits ) ( (void)0 ) 73 #endif74 75 #ifdef ENABLE_FASTPEER76 #define HANDSHAKE_HAS_FASTEXT( bits ) ( ( ( bits )[7] & 0x04 ) ? 1 : 0 )77 #define HANDSHAKE_SET_FASTEXT( bits ) ( ( bits )[7] |= 0x04 )78 #else79 #define HANDSHAKE_HAS_FASTEXT( bits ) ( 0 )80 #define HANDSHAKE_SET_FASTEXT( bits ) ( (void)0 )81 73 #endif 82 74 … … 215 207 memset( walk, 0, HANDSHAKE_FLAGS_LEN ); 216 208 HANDSHAKE_SET_LTEP( walk ); 217 HANDSHAKE_SET_FASTEXT( walk );218 209 219 210 walk += HANDSHAKE_FLAGS_LEN; … … 296 287 tr_peerIoEnableLTEP( handshake->io, 1 ); 297 288 dbgmsg( handshake, "using ltep" ); 298 }299 300 if( HANDSHAKE_HAS_FASTEXT( reserved ) )301 {302 tr_peerIoEnableFEXT( handshake->io, 1 );303 dbgmsg( handshake, "using fext" );304 289 } 305 290 … … 669 654 tr_peerIoEnableLTEP( handshake->io, 1 ); 670 655 dbgmsg( handshake, "using ltep" ); 671 }672 if( HANDSHAKE_HAS_FASTEXT( reserved ) )673 {674 tr_peerIoEnableFEXT( handshake->io, 1 );675 dbgmsg( handshake, "using fext" );676 656 } 677 657 -
trunk/libtransmission/peer-io.c
r7173 r7186 85 85 tr_bool peerIdIsSet; 86 86 tr_bool extendedProtocolSupported; 87 tr_bool fastPeersSupported;88 87 89 88 int magicNumber; … … 500 499 } 501 500 502 void503 tr_peerIoEnableFEXT( tr_peerIo * io,504 int flag )505 {506 assert( isPeerIo( io ) );507 assert( flag == 0 || flag == 1 );508 509 io->fastPeersSupported = flag;510 }511 512 501 int 513 502 tr_peerIoSupportsLTEP( const tr_peerIo * io ) … … 516 505 517 506 return io->extendedProtocolSupported; 518 }519 520 int521 tr_peerIoSupportsFEXT( const tr_peerIo * io )522 {523 assert( isPeerIo( io ) );524 525 return io->fastPeersSupported;526 507 } 527 508 -
trunk/libtransmission/peer-io.h
r7154 r7186 54 54 int flag ); 55 55 56 void tr_peerIoEnableFEXT( tr_peerIo * io,57 int flag );58 59 56 int tr_peerIoSupportsLTEP( const tr_peerIo * io ); 60 61 int tr_peerIoSupportsFEXT( const tr_peerIo * io );62 57 63 58 /** -
trunk/libtransmission/peer-mgr.c
r7173 r7186 456 456 } 457 457 458 /**459 * For explanation, see http://www.bittorrent.org/fast_extensions.html460 * Also see the "test-allowed-set" unit test461 *462 * @param k number of pieces in set463 * @param sz number of pieces in the torrent464 * @param infohash torrent's SHA1 hash465 * @param ip peer's address466 */467 struct tr_bitfield *468 tr_peerMgrGenerateAllowedSet(469 const uint32_t k,470 const uint32_t sz,471 const uint8_t *472 infohash,473 const struct in_addr * ip )474 {475 uint8_t w[SHA_DIGEST_LENGTH + 4];476 uint8_t x[SHA_DIGEST_LENGTH];477 tr_bitfield * a;478 uint32_t a_size;479 480 *(uint32_t*)w = ntohl( htonl( ip->s_addr ) & 0xffffff00 ); /* (1) */481 memcpy( w + 4, infohash, SHA_DIGEST_LENGTH ); /* (2) */482 tr_sha1( x, w, sizeof( w ), NULL ); /* (3) */483 484 a = tr_bitfieldNew( sz );485 a_size = 0;486 487 while( a_size < k )488 {489 int i;490 for( i = 0; i < 5 && a_size < k; ++i ) /* (4) */491 {492 uint32_t j = i * 4; /* (5) */493 uint32_t y = ntohl( *( uint32_t* )( x + j ) ); /* (6) */494 uint32_t index = y % sz; /* (7) */495 if( !tr_bitfieldHas( a, index ) ) /* (8) */496 {497 tr_bitfieldAdd( a, index ); /* (9) */498 ++a_size;499 }500 }501 tr_sha1( x, x, sizeof( x ), NULL ); /* (3) */502 }503 504 return a;505 }506 458 507 459 static int bandwidthPulse( void * vmgr ); -
trunk/libtransmission/peer-mgr.h
r7151 r7186 125 125 126 126 127 struct tr_bitfield * tr_peerMgrGenerateAllowedSet( const uint32_t setCount,128 const uint32_t pieceCount,129 const uint8_t infohash[20],130 const struct in_addr * ip );131 132 133 127 #endif -
trunk/libtransmission/peer-msgs.c
r7182 r7186 59 59 BT_HAVE_NONE = 15, 60 60 BT_REJECT = 16, 61 BT_ALLOWED_FAST = 17,62 61 BT_LTEP = 20, 63 62 … … 76 75 77 76 MAX_QUEUE_SIZE = ( 100 ), 78 79 /* (fast peers) max number of pieces we fast-allow to another peer */80 MAX_FAST_ALLOWED_COUNT = 10,81 82 /* (fast peers) max threshold for allowing fast-pieces requests */83 MAX_FAST_ALLOWED_THRESHOLD = 10,84 77 85 78 /* how long an unsent request can stay queued before it's returned … … 289 282 290 283 struct request_list peerAskedFor; 291 struct request_list peerAskedForFast;292 284 struct request_list clientAskedFor; 293 285 struct request_list clientWillAskFor; … … 600 592 601 593 static void 602 cancelAllRequestsToClient ExceptFast( tr_peermsgs * msgs )594 cancelAllRequestsToClient( tr_peermsgs * msgs ) 603 595 { 604 596 reqListClear( &msgs->peerAskedFor ); … … 625 617 msgs->info->peerIsChoked = choke; 626 618 if( choke ) 627 cancelAllRequestsToClient ExceptFast( msgs );619 cancelAllRequestsToClient( msgs ); 628 620 protocolSendChoke( msgs, choke ); 629 621 msgs->info->chokeChangedAt = now; … … 643 635 /* since we have more pieces now, we might not be interested in this peer */ 644 636 updateInterest( msgs ); 645 }646 647 #if 0648 static void649 sendFastSuggest( tr_peermsgs * msgs,650 uint32_t pieceIndex )651 {652 assert( msgs );653 654 if( tr_peerIoSupportsFEXT( msgs->io ) )655 {656 tr_peerIoWriteUint32( msgs->io, msgs->outMessages,657 sizeof( uint8_t ) + sizeof( uint32_t ) );658 tr_peerIoWriteUint8( msgs->io, msgs->outMessages, BT_SUGGEST );659 tr_peerIoWriteUint32( msgs->io, msgs->outMessages, pieceIndex );660 }661 }662 663 static void664 sendFastHave( tr_peermsgs * msgs,665 int all )666 {667 assert( msgs );668 669 if( tr_peerIoSupportsFEXT( msgs->io ) )670 {671 tr_peerIoWriteUint32( msgs->io, msgs->outMessages, sizeof( uint8_t ) );672 tr_peerIoWriteUint8( msgs->io, msgs->outMessages,673 ( all ? BT_HAVE_ALL674 : BT_HAVE_NONE ) );675 updateInterest( msgs );676 }677 }678 679 #endif680 681 static void682 sendFastReject( tr_peermsgs * msgs,683 uint32_t pieceIndex,684 uint32_t offset,685 uint32_t length )686 {687 assert( msgs );688 689 if( tr_peerIoSupportsFEXT( msgs->io ) )690 {691 struct evbuffer * out = msgs->outMessages;692 const uint32_t len = sizeof( uint8_t ) + 3 * sizeof( uint32_t );693 dbgmsg( msgs, "sending fast reject %u:%u->%u", pieceIndex, offset,694 length );695 tr_peerIoWriteUint32( msgs->io, out, len );696 tr_peerIoWriteUint8( msgs->io, out, BT_REJECT );697 tr_peerIoWriteUint32( msgs->io, out, pieceIndex );698 tr_peerIoWriteUint32( msgs->io, out, offset );699 tr_peerIoWriteUint32( msgs->io, out, length );700 pokeBatchPeriod( msgs, LOW_PRIORITY_INTERVAL_SECS );701 dbgmsg( msgs, "outMessage size is now %d",702 (int)EVBUFFER_LENGTH( out ) );703 }704 }705 706 static tr_bitfield*707 getPeerAllowedPieces( tr_peermsgs * msgs )708 {709 if( !msgs->peerAllowedPieces && tr_peerIoSupportsFEXT( msgs->io ) )710 {711 msgs->peerAllowedPieces = tr_peerMgrGenerateAllowedSet(712 MAX_FAST_ALLOWED_COUNT,713 msgs->torrent->info.pieceCount,714 msgs->torrent->info.hash,715 tr_peerIoGetAddress( msgs->io, NULL ) );716 }717 718 return msgs->peerAllowedPieces;719 }720 721 static void722 sendFastAllowed( tr_peermsgs * msgs,723 uint32_t pieceIndex )724 {725 assert( msgs );726 727 if( tr_peerIoSupportsFEXT( msgs->io ) )728 {729 struct evbuffer * out = msgs->outMessages;730 dbgmsg( msgs, "sending fast allowed" );731 tr_peerIoWriteUint32( msgs->io, out, sizeof( uint8_t ) +732 sizeof( uint32_t ) );733 tr_peerIoWriteUint8( msgs->io, out, BT_ALLOWED_FAST );734 tr_peerIoWriteUint32( msgs->io, out, pieceIndex );735 pokeBatchPeriod( msgs, LOW_PRIORITY_INTERVAL_SECS );736 dbgmsg( msgs, "outMessage size is now %d",737 (int)EVBUFFER_LENGTH( out ) );738 }739 }740 741 static void742 sendFastAllowedSet( tr_peermsgs * msgs )743 {744 tr_piece_index_t i = 0;745 746 while( i <= msgs->torrent->info.pieceCount )747 {748 if( tr_bitfieldHas( getPeerAllowedPieces( msgs ), i ) )749 sendFastAllowed( msgs, i );750 i++;751 }752 }753 754 static void755 maybeSendFastAllowedSet( tr_peermsgs * msgs )756 {757 if( tr_bitfieldCountTrueBits( msgs->info->have ) <=758 MAX_FAST_ALLOWED_THRESHOLD )759 sendFastAllowedSet( msgs );760 637 } 761 638 … … 1208 1085 } 1209 1086 1210 static int1211 clientCanSendFastBlock( const tr_peermsgs * msgs UNUSED )1212 {1213 /* don't send a fast piece if peer has MAX_FAST_ALLOWED_THRESHOLD pieces */1214 if( tr_bitfieldCountTrueBits( msgs->info->have ) >1215 MAX_FAST_ALLOWED_THRESHOLD )1216 return FALSE;1217 1218 /* ...or if we don't have ourself enough pieces */1219 if( tr_bitfieldCountTrueBits( tr_cpPieceBitfield( msgs->torrent->1220 completion ) ) <1221 MAX_FAST_ALLOWED_THRESHOLD )1222 return FALSE;1223 1224 /* Maybe a bandwidth limit ? */1225 return TRUE;1226 }1227 1228 1087 static void 1229 1088 peerMadeRequest( tr_peermsgs * msgs, … … 1234 1093 msgs->torrent->completion, req->index ); 1235 1094 const int peerIsChoked = msgs->info->peerIsChoked; 1236 const int peerIsFast = tr_peerIoSupportsFEXT( msgs->io );1237 const int pieceIsFast = reqIsValid && tr_bitfieldHas(1238 getPeerAllowedPieces( msgs ), req->index );1239 const int canSendFast = clientCanSendFastBlock( msgs );1240 1095 1241 1096 if( !reqIsValid ) /* bad request */ 1242 1097 { 1243 1098 dbgmsg( msgs, "rejecting an invalid request." ); 1244 sendFastReject( msgs, req->index, req->offset, req->length );1245 1099 } 1246 1100 else if( !clientHasPiece ) /* we don't have it */ 1247 1101 { 1248 1102 dbgmsg( msgs, "rejecting request for a piece we don't have." ); 1249 sendFastReject( msgs, req->index, req->offset, req->length ); 1250 } 1251 else if( peerIsChoked && !peerIsFast ) /* doesn't he know he's choked? */ 1103 } 1104 else if( peerIsChoked ) /* doesn't he know he's choked? */ 1252 1105 { 1253 1106 tr_peerMsgsSetChoke( msgs, 1 ); 1254 sendFastReject( msgs, req->index, req->offset, req->length );1255 }1256 else if( peerIsChoked && peerIsFast && ( !pieceIsFast || !canSendFast ) )1257 {1258 sendFastReject( msgs, req->index, req->offset, req->length );1259 1107 } 1260 1108 else /* YAY */ 1261 1109 { 1262 if( peerIsFast && pieceIsFast ) 1263 reqListAppend( &msgs->peerAskedForFast, req ); 1264 else 1265 reqListAppend( &msgs->peerAskedFor, req ); 1110 reqListAppend( &msgs->peerAskedFor, req ); 1266 1111 } 1267 1112 } … … 1284 1129 case BT_HAVE: 1285 1130 case BT_SUGGEST: 1286 case BT_ALLOWED_FAST:1287 return len == 5;1288 1131 1289 1132 case BT_BITFIELD: … … 1410 1253 msgs->info->clientIsChoked = 1; 1411 1254 cancelAllRequestsToPeer( msgs ); 1412 cancelAllRequestsToClient ExceptFast( msgs );1255 cancelAllRequestsToClient( msgs ); 1413 1256 break; 1414 1257 … … 1446 1289 msglen ); 1447 1290 updatePeerProgress( msgs ); 1448 maybeSendFastAllowedSet( msgs );1449 1291 fireNeedReq( msgs ); 1450 1292 break; … … 1471 1313 dbgmsg( msgs, "got a Cancel %u:%u->%u", r.index, r.offset, 1472 1314 r.length ); 1473 reqListRemove( &msgs->peerAskedForFast, &r );1474 1315 reqListRemove( &msgs->peerAskedFor, &r ); 1475 1316 break; … … 1498 1339 msgs->torrent->info.pieceCount ); 1499 1340 updatePeerProgress( msgs ); 1500 maybeSendFastAllowedSet( msgs );1501 1341 break; 1502 1342 … … 1506 1346 tr_bitfieldClear( msgs->info->have ); 1507 1347 updatePeerProgress( msgs ); 1508 maybeSendFastAllowedSet( msgs );1509 1348 break; 1510 1349 … … 1520 1359 } 1521 1360 1522 case BT_ALLOWED_FAST:1523 {1524 dbgmsg( msgs, "Got a BT_ALLOWED_FAST" );1525 tr_peerIoReadUint32( msgs->io, inbuf, &ui32 );1526 /* we don't do anything with this yet */1527 break;1528 }1529 1530 1361 case BT_LTEP: 1531 1362 dbgmsg( msgs, "Got a BT_LTEP" ); … … 1703 1534 struct peer_request * setme ) 1704 1535 { 1705 return reqListPop( &msgs->peerAskedForFast, setme ) 1706 || reqListPop( &msgs->peerAskedFor, setme ); 1536 return reqListPop( &msgs->peerAskedFor, setme ); 1707 1537 } 1708 1538 … … 2066 1896 m->peerAllowedPieces = NULL; 2067 1897 m->peerAskedFor = REQUEST_LIST_INIT; 2068 m->peerAskedForFast = REQUEST_LIST_INIT;2069 1898 m->clientAskedFor = REQUEST_LIST_INIT; 2070 1899 m->clientWillAskFor = REQUEST_LIST_INIT; … … 2093 1922 reqListClear( &msgs->clientWillAskFor ); 2094 1923 reqListClear( &msgs->clientAskedFor ); 2095 reqListClear( &msgs->peerAskedForFast ); 2096 reqListClear( &msgs->peerAskedFor ); 1924 2097 1925 tr_bitfieldFree( msgs->peerAllowedPieces ); 2098 1926 evbuffer_free( msgs->incoming.block );
Note: See TracChangeset
for help on using the changeset viewer.