Changeset 3227
- Timestamp:
- Sep 28, 2007, 4:40:21 PM (15 years ago)
- Location:
- trunk/libtransmission
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/handshake.c
r3203 r3227 37 37 38 38 /* enable fast peers extension protocol */ 39 /* (disabled because it's not fully implemented yet) */40 39 /* #define ENABLE_FASTPEER */ 41 40 … … 240 239 } 241 240 242 HANDSHAKE_SET_FASTEXT 241 HANDSHAKE_SET_FASTEXT( walk ); 243 242 244 243 walk += HANDSHAKE_FLAGS_LEN; … … 331 330 assert( !ltep || !azmp ); 332 331 333 if( ltep ) { tr_peerIoEnableLTEP( handshake->io, 1 ); dbgmsg(handshake,"using ltep" ); } 334 else if( azmp ) { tr_peerIoEnableAZMP( handshake->io, 1 ); dbgmsg(handshake,"using azmp" ); } 335 else if( fpex ) { tr_peerIoEnableFEXT( handshake->io, 1 ); dbgmsg(handshake,"using fext" ); } 336 else { dbgmsg(handshake,"using no extensions" ); } 337 332 if( ltep ) { tr_peerIoEnableLTEP( handshake->io, 1 ); dbgmsg(handshake,"using ltep" ); } 333 if( azmp ) { tr_peerIoEnableAZMP( handshake->io, 1 ); dbgmsg(handshake,"using azmp" ); } 334 if( fpex ) { tr_peerIoEnableFEXT( handshake->io, 1 ); dbgmsg(handshake,"using fext" ); } 335 338 336 return HANDSHAKE_OK; 339 337 } … … 699 697 assert( !ltep || !azmp ); 700 698 701 if( ltep ) { tr_peerIoEnableLTEP( handshake->io, 1 ); dbgmsg(handshake,"using ltep" ); } 702 else if( azmp ) { tr_peerIoEnableAZMP( handshake->io, 1 ); dbgmsg(handshake,"using azmp" ); } 703 else if( fpex ) { tr_peerIoEnableFEXT( handshake->io, 1 ); dbgmsg(handshake,"using fext" ); } 704 else { dbgmsg(handshake,"using no extensions" ); } 699 if( ltep ) { tr_peerIoEnableLTEP( handshake->io, 1 ); dbgmsg(handshake,"using ltep" ); } 700 if( azmp ) { tr_peerIoEnableAZMP( handshake->io, 1 ); dbgmsg(handshake,"using azmp" ); } 701 if( fpex ) { tr_peerIoEnableFEXT( handshake->io, 1 ); dbgmsg(handshake,"using fext" ); } 705 702 706 703 /** … … 946 943 ext = 0; 947 944 948 /* FIXME: do we do something with fast peers here? */949 950 945 msg = buildHandshakeMessage( handshake, ext, &msgSize ); 951 946 tr_peerIoWriteBytes( handshake->io, outbuf, msg, msgSize ); … … 1030 1025 { 1031 1026 tr_handshake * handshake = (tr_handshake *) arg; 1032 dbgmsg( handshake, "handshake evbuffer got an error!!!!!" );1033 1027 1034 1028 /* if the error happened while we were sending a public key, we might … … 1039 1033 && ( !tr_peerIoReconnect( handshake->io ) ) ) 1040 1034 { 1035 dbgmsg( handshake, "handshake failed, trying plaintext..." ); 1041 1036 int msgSize; 1042 1037 uint8_t * msg = buildHandshakeMessage( handshake, HANDSHAKE_EXTPREF_LTEP_PREFER, &msgSize ); … … 1047 1042 else 1048 1043 { 1049 dbgmsg( handshake, "handshake evbuffer got an error!!!!!" );1044 dbgmsg( handshake, "handshake evbuffer got an error!!!!!" ); 1050 1045 tr_handshakeDone( handshake, FALSE ); 1051 1046 } -
trunk/libtransmission/peer-io.c
r3184 r3227 34 34 unsigned int extendedProtocolSupported : 1; 35 35 unsigned int fastPeersSupported : 1; 36 /* unsigned int DHTSupported : 1; */37 36 }; 38 37 -
trunk/libtransmission/peer-mgr.c
r3225 r3227 20 20 #include "clients.h" 21 21 #include "completion.h" 22 #include "crypto.h" 22 23 #include "handshake.h" 23 24 #include "net.h" … … 275 276 **/ 276 277 278 struct tr_bitfield * 279 tr_peerMgrGenerateAllowedSet( const uint32_t setCount, 280 const uint32_t pieceCount, 281 const uint8_t infohash[20], 282 const struct in_addr * ip ) 283 { 284 /* This has been checked against the spec example implementation. Feeding it with : 285 setCount = 9, pieceCount = 1313, infohash = Oxaa,0xaa,...0xaa, ip = 80.4.4.200 286 generate : 287 1059, 431, 808, 1217, 287, 376, 1188, 353, 508 288 but since we're storing in a bitfield, it won't be in this order... */ 289 /* TODO : We should translate link-local IPv4 adresses to external IP, 290 * so that being on same local network gives us the same allowed pieces */ 291 292 printf( "%d piece allowed fast set for torrent with %d pieces and hex infohash\n", setCount, pieceCount ); 293 printf( "%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x for node with IP %s:\n", 294 infohash[0], infohash[1], infohash[2], infohash[3], infohash[4], infohash[5], infohash[6], infohash[7], infohash[8], infohash[9], 295 infohash[10], infohash[11], infohash[12], infohash[13], infohash[14], infohash[15], infohash[16], infohash[7], infohash[18], infohash[19], 296 inet_ntoa( *ip ) ); 297 298 uint8_t *seed = malloc(4 + SHA_DIGEST_LENGTH); 299 char buf[4]; 300 uint32_t allowedPieceCount = 0; 301 tr_bitfield_t * ret; 302 303 ret = tr_bitfieldNew( pieceCount ); 304 305 /* We need a seed based on most significant bytes of peer address 306 concatenated with torrent's infohash */ 307 *(uint32_t*)buf = ntohl( htonl(ip->s_addr) & 0xffffff00 ); 308 309 memcpy( seed, &buf, 4 ); 310 memcpy( seed + 4, infohash, SHA_DIGEST_LENGTH ); 311 312 tr_sha1( seed, seed, 4 + SHA_DIGEST_LENGTH, NULL ); 313 314 while ( allowedPieceCount < setCount ) 315 { 316 int i; 317 for ( i = 0 ; i < 5 && allowedPieceCount < setCount ; i++ ) 318 { 319 /* We generate indices from 4-byte chunks of the seed */ 320 uint32_t j = i * 4; 321 uint32_t y = ntohl( *(uint32_t*)(seed + j) ); 322 uint32_t index = y % pieceCount; 323 324 if ( !tr_bitfieldHas( ret, index ) ) 325 { 326 tr_bitfieldAdd( ret, index ); 327 allowedPieceCount++; 328 } 329 } 330 /* We randomize the seed, in case we need to iterate more */ 331 tr_sha1( seed, seed, SHA_DIGEST_LENGTH, NULL ); 332 } 333 tr_free( seed ); 334 335 return ret; 336 } 337 277 338 tr_peerMgr* 278 339 tr_peerMgrNew( tr_handle * handle ) … … 323 384 uint32_t piece; 324 385 uint32_t peerCount; 386 uint32_t fastAllowed; 325 387 }; 326 388 … … 338 400 if (a->peerCount != b->peerCount) 339 401 return a->peerCount < b->peerCount ? -1 : 1; 402 403 /* otherwise if one *might be* fastallowed to us */ 404 if (a->fastAllowed != b->fastAllowed) 405 return a->fastAllowed < b->fastAllowed ? -1 : 1; 340 406 341 407 /* otherwise go with the earlier piece */ … … 389 455 setme->priority = inf->pieces[piece].priority; 390 456 setme->peerCount = 0; 457 /* FIXME */ 458 // setme->fastAllowed = tr_bitfieldHas( t->tor->allowedList, i); 391 459 392 460 for( k=0; k<peerCount; ++k ) { … … 1118 1186 tr_peer ** peers = getConnectedPeers( t, &peerCount ); 1119 1187 ChokeData * choke = tr_new0( ChokeData, peerCount ); 1120 1188 1121 1189 /* sort the peers by preference and rate */ 1122 1190 for( i=0; i<peerCount; ++i ) -
trunk/libtransmission/peer-mgr.h
r3197 r3227 97 97 int * setmeCount ); 98 98 99 99 100 struct tr_bitfield * 101 tr_peerMgrGenerateAllowedSet( const uint32_t setCount, 102 const uint32_t pieceCount, 103 const uint8_t infohash[20], 104 const struct in_addr * ip ); 100 105 101 106 -
trunk/libtransmission/peer-msgs.c
r3226 r3227 38 38 *** 39 39 **/ 40 41 #define MAX_ALLOWED_SET_COUNT 10 /* number of pieces generated for allow-fast, 42 threshold for fast-allowing others */ 40 43 41 44 enum … … 123 126 unsigned int peerSupportsPex : 1; 124 127 unsigned int hasSentLtepHandshake : 1; 125 128 129 tr_bitfield * clientAllowedPieces; 130 tr_bitfield * peerAllowedPieces; 131 126 132 uint8_t state; 127 133 … … 300 306 if( msgs->info->peerIsChoked != choke ) 301 307 { 302 msgs->info->peerIsChoked = choke ? 1 : 0; 303 308 msgs->info->peerIsChoked = choke; 309 tr_list * walk; 310 304 311 if( choke ) 305 tr_list_free( &msgs->peerAskedFor, tr_free ); 312 for( walk = msgs->peerAskedFor; walk != NULL; ) 313 { 314 tr_list * next = walk->next; 315 /* We shouldn't reject a peer's fast allowed requests at choke */ 316 struct peer_request *req = walk->data; 317 if ( !tr_bitfieldHas( msgs->peerAllowedPieces, req->index ) ) 318 { 319 tr_list_remove_data( &msgs->peerAskedFor, req ); 320 tr_free( req ); 321 } 322 walk = next; 323 } 306 324 307 325 dbgmsg( msgs, "sending a %s message", (choke ? "CHOKE" : "UNCHOKE") ); … … 360 378 updateInterest( msgs ); 361 379 } 380 #if 0 381 static void 382 sendFastSuggest( tr_peermsgs * msgs, 383 uint32_t pieceIndex ) 384 { 385 dbgmsg( msgs, "w00t SUGGESTing them piece #%d", pieceIndex ); 386 tr_peerIoWriteUint32( msgs->io, msgs->outMessages, sizeof(uint8_t) + sizeof(uint32_t) ); 387 tr_peerIoWriteUint8( msgs->io, msgs->outMessages, BT_SUGGEST ); 388 tr_peerIoWriteUint32( msgs->io, msgs->outMessages, pieceIndex ); 389 390 updateInterest( msgs ); 391 } 392 #endif 393 static void 394 sendFastHave( tr_peermsgs * msgs, 395 int all) 396 { 397 dbgmsg( msgs, "w00t telling them we %s pieces", (all ? "HAVE_ALL" : "HAVE_NONE" ) ); 398 tr_peerIoWriteUint32( msgs->io, msgs->outMessages, sizeof(uint8_t) ); 399 tr_peerIoWriteUint8( msgs->io, msgs->outMessages, ( all ? BT_HAVE_ALL : BT_HAVE_NONE ) ); 400 401 updateInterest( msgs ); 402 } 403 404 static void 405 sendFastReject( tr_peermsgs * msgs, 406 uint32_t pieceIndex, 407 uint32_t offset, 408 uint32_t length ) 409 { 410 assert( msgs != NULL ); 411 assert( length > 0 ); 412 413 /* reject the request */ 414 const uint32_t len = sizeof(uint8_t) + 3 * sizeof(uint32_t); 415 tr_peerIoWriteUint32( msgs->io, msgs->outMessages, len ); 416 tr_peerIoWriteUint8( msgs->io, msgs->outMessages, BT_REJECT ); 417 tr_peerIoWriteUint32( msgs->io, msgs->outMessages, pieceIndex ); 418 tr_peerIoWriteUint32( msgs->io, msgs->outMessages, offset ); 419 tr_peerIoWriteUint32( msgs->io, msgs->outMessages, length ); 420 } 421 422 static void 423 sendFastAllowed( tr_peermsgs * msgs, 424 uint32_t pieceIndex) 425 { 426 dbgmsg( msgs, "w00t telling them we ALLOW_FAST piece #%d", pieceIndex ); 427 tr_peerIoWriteUint32( msgs->io, msgs->outMessages, sizeof(uint8_t) + sizeof(uint32_t) ); 428 tr_peerIoWriteUint8( msgs->io, msgs->outMessages, BT_ALLOWED_FAST ); 429 tr_peerIoWriteUint32( msgs->io, msgs->outMessages, pieceIndex ); 430 } 431 432 433 434 static void 435 sendFastAllowedSet( tr_peermsgs * msgs ) 436 { 437 int i = 0; 438 while (i <= msgs->torrent->info.pieceCount ) 439 { 440 if ( tr_bitfieldHas( msgs->peerAllowedPieces, i) ) 441 sendFastAllowed( msgs, i ); 442 i++; 443 } 444 } 445 362 446 363 447 /** … … 633 717 assert( msglen == 0 ); 634 718 msgs->info->clientIsChoked = 1; 635 tr_list_free( &msgs->peerAskedFor, tr_free ); 719 720 tr_list * walk; 721 for( walk = msgs->peerAskedFor; walk != NULL; ) 722 { 723 tr_list * next = walk->next; 724 /* We shouldn't reject a peer's fast allowed requests at choke */ 725 struct peer_request *req = walk->data; 726 if ( !tr_bitfieldHas( msgs->peerAllowedPieces, req->index ) ) 727 { 728 tr_list_remove_data( &msgs->peerAskedFor, req ); 729 tr_free( req ); 730 } 731 walk = next; 732 } 636 733 tr_list_free( &msgs->clientAskedFor, tr_free ); 637 734 break; … … 686 783 tr_peerIoReadUint32( msgs->io, inbuf, &req->offset ); 687 784 tr_peerIoReadUint32( msgs->io, inbuf, &req->length ); 688 if( !msgs->info->peerIsChoked && requestIsValid( msgs, req ) ) 689 tr_list_append( &msgs->peerAskedFor, req ); 690 else 785 786 if ( !requestIsValid( msgs, req ) ) 787 { 788 dbgmsg( msgs, "BT_REQUEST: invalid request, ignoring" ); 691 789 tr_free( req ); 790 break; 791 } 792 /* 793 If we're not choking him -> continue 794 If we're choking him 795 it doesn't support FPE -> He's deaf, reCHOKE and bail... 796 it support FPE 797 If the asked piece is not allowed 798 OR he's above our threshold 799 OR we don't have the requested piece -> Reject 800 Else 801 Asked piece allowed AND he's below our threshold -> continue... 802 */ 803 804 805 if ( msgs->info->peerIsChoked ) 806 { 807 if ( !tr_peerIoSupportsFEXT( msgs->io ) ) 808 { 809 dbgmsg( msgs, "BT_REQUEST: peer is choked, ignoring" ); 810 /* Didn't he get it? */ 811 tr_peerMsgsSetChoke( msgs, 1 ); 812 tr_free( req ); 813 break; 814 } 815 else 816 { 817 if ( !tr_bitfieldHas( msgs->peerAllowedPieces, req->index ) 818 || ( msgs->info->progress * (float)msgs->torrent->info.pieceCount) >= MAX_ALLOWED_SET_COUNT 819 || !tr_cpPieceIsComplete( msgs->torrent->completion, req->index ) ) 820 { 821 dbgmsg( msgs, "BT_REQUEST: peer requests an un-fastallowed piece" ); 822 sendFastReject( msgs, req->index, req->offset, req->length ); 823 tr_free( req ); 824 break; 825 } 826 dbgmsg( msgs, "BT_REQUEST: fast allowed piece, accepting request" ); 827 } 828 } 829 830 tr_list_append( &msgs->peerAskedFor, req ); 692 831 break; 693 832 } … … 732 871 733 872 case BT_HAVE_ALL: { 734 /* tiennou TODO */ 873 assert( msglen == 0 ); 874 dbgmsg( msgs, "peer sent us a BT_HAVE_ALL" ); 875 memset( msgs->info->have->bits, 1, msgs->info->have->len ); 876 msgs->info->progress = tr_bitfieldCountTrueBits( msgs->info->have ) / (float)msgs->torrent->info.pieceCount; 877 dbgmsg( msgs, "after the HAVE_ALL message, peer progress is %f", msgs->info->progress ); 878 updateInterest( msgs ); 879 firePeerProgress( msgs ); 735 880 break; 736 881 } 737 882 738 883 case BT_HAVE_NONE: { 739 /* tiennou TODO */ 884 assert( msglen == 0 ); 885 dbgmsg( msgs, "peer sent us a BT_HAVE_NONE" ); 886 memset( msgs->info->have->bits, 1, msgs->info->have->len ); 887 msgs->info->progress = tr_bitfieldCountTrueBits( msgs->info->have ) / (float)msgs->torrent->info.pieceCount; 888 dbgmsg( msgs, "after the HAVE_NONE message, peer progress is %f", msgs->info->progress ); 889 updateInterest( msgs ); 890 firePeerProgress( msgs ); 740 891 break; 741 892 } 742 893 743 894 case BT_REJECT: { 744 /* tiennou TODO */ 895 struct peer_request req; 896 tr_list * node; 897 assert( msglen == 12 ); 898 dbgmsg( msgs, "peer sent us a BT_REJECT" ); 899 tr_peerIoReadUint32( msgs->io, inbuf, &req.index ); 900 tr_peerIoReadUint32( msgs->io, inbuf, &req.offset ); 901 tr_peerIoReadUint32( msgs->io, inbuf, &req.length ); 902 node = tr_list_find( msgs->peerAskedFor, &req, peer_request_compare ); 903 if( node != NULL ) { 904 void * data = node->data; 905 tr_list_remove_data( &msgs->peerAskedFor, data ); 906 tr_free( data ); 907 dbgmsg( msgs, "found the req that peer has rejected... cancelled." ); 908 } 745 909 break; 746 910 } 747 911 748 912 case BT_ALLOWED_FAST: { 749 /* tiennou TODO */ 913 assert( msglen == 4 ); 914 dbgmsg( msgs, "peer sent us a BT_ALLOWED_FAST" ); 915 tr_peerIoReadUint32( msgs->io, inbuf, &ui32 ); 916 tr_bitfieldAdd( msgs->clientAllowedPieces, ui32 ); 750 917 break; 751 918 } … … 1284 1451 msgs->outBlock = evbuffer_new( ); 1285 1452 msgs->inBlock = evbuffer_new( ); 1286 1453 msgs->peerAllowedPieces = NULL; 1454 msgs->clientAllowedPieces = NULL; 1455 1456 if ( tr_peerIoSupportsFEXT( msgs->io ) ) 1457 { 1458 /* This peer is fastpeer-enabled, generate its allowed set 1459 * (before registering our callbacks) */ 1460 if ( !msgs->peerAllowedPieces ) { 1461 const struct in_addr *peerAddr = tr_peerIoGetAddress( msgs->io, NULL ); 1462 1463 msgs->peerAllowedPieces = tr_peerMgrGenerateAllowedSet( MAX_ALLOWED_SET_COUNT, 1464 msgs->torrent->info.pieceCount, 1465 msgs->torrent->info.hash, 1466 peerAddr ); 1467 } 1468 msgs->clientAllowedPieces = tr_bitfieldNew( msgs->torrent->info.pieceCount ); 1469 } 1470 1287 1471 tr_peerIoSetIOFuncs( msgs->io, canRead, didWrite, gotError, msgs ); 1288 1472 tr_peerIoSetIOMode( msgs->io, EV_READ|EV_WRITE, 0 ); … … 1305 1489 } 1306 1490 } 1307 1308 sendBitfield( msgs ); 1491 1492 if ( tr_peerIoSupportsFEXT( msgs->io ) ) 1493 { 1494 /* This peer is fastpeer-enabled, send it have-all or have-none if appropriate */ 1495 float completion = tr_cpPercentComplete( msgs->torrent->completion ); 1496 if ( completion == 0.0f ) { 1497 sendFastHave( msgs, 0 ); 1498 } else if ( completion == 1.0f ) { 1499 sendFastHave( msgs, 1 ); 1500 } else { 1501 sendBitfield( msgs ); 1502 } 1503 uint32_t peerProgress = msgs->torrent->info.pieceCount * msgs->info->progress; 1504 1505 if ( peerProgress < MAX_ALLOWED_SET_COUNT ) 1506 sendFastAllowedSet( msgs ); 1507 } else { 1508 sendBitfield( msgs ); 1509 } 1309 1510 return msgs; 1310 1511 }
Note: See TracChangeset
for help on using the changeset viewer.