Changeset 7234
- Timestamp:
- Dec 2, 2008, 5:10:54 PM (12 years ago)
- Location:
- trunk/libtransmission
- Files:
-
- 1 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/Makefile.am
r7186 r7234 110 110 clients-test \ 111 111 json-test \ 112 peer-msgs-test \ 112 113 rpc-test \ 113 114 test-peer-id \ … … 155 156 test_peer_id_LDFLAGS = ${apps_ldflags} 156 157 158 peer_msgs_test_SOURCES = peer-msgs-test.c 159 peer_msgs_test_LDADD = ${apps_ldadd} 160 peer_msgs_test_LDFLAGS = ${apps_ldflags} 161 157 162 utils_test_SOURCES = utils-test.c 158 163 utils_test_LDADD = ${apps_ldadd} -
trunk/libtransmission/handshake.c
r7231 r7234 34 34 /* enable LibTransmission extension protocol */ 35 35 #define ENABLE_LTEP * / 36 /* fast extensions */ 37 #define ENABLE_FAST * / 36 38 37 39 /*** … … 69 71 #define HANDSHAKE_SET_LTEP( bits ) ( (void)0 ) 70 72 #endif 73 74 #ifdef ENABLE_FAST 75 #define HANDSHAKE_HAS_FASTEXT( bits ) ( ( ( bits )[7] & 0x04 ) ? 1 : 0 ) 76 #define HANDSHAKE_SET_FASTEXT( bits ) ( ( bits )[7] |= 0x04 ) 77 #else 78 #define HANDSHAKE_HAS_FASTEXT( bits ) ( 0 ) 79 #define HANDSHAKE_SET_FASTEXT( bits ) ( (void)0 ) 80 #endif 71 81 72 82 /* http://www.azureuswiki.com/index.php/Extension_negotiation_protocol … … 204 214 memset( walk, 0, HANDSHAKE_FLAGS_LEN ); 205 215 HANDSHAKE_SET_LTEP( walk ); 216 HANDSHAKE_SET_FASTEXT( walk ); 206 217 207 218 walk += HANDSHAKE_FLAGS_LEN; … … 280 291 **/ 281 292 282 if( HANDSHAKE_HAS_LTEP( reserved ) ) 283 { 284 tr_peerIoEnableLTEP( handshake->io, 1 ); 285 dbgmsg( handshake, "using ltep" ); 286 } 293 tr_peerIoEnableLTEP( handshake->io, HANDSHAKE_HAS_LTEP( reserved ) ); 294 295 tr_peerIoEnableFEXT( handshake->io, HANDSHAKE_HAS_FASTEXT( reserved ) ); 287 296 288 297 return HANDSHAKE_OK; … … 644 653 645 654 /** 646 *** Extension negotiation655 *** Extensions 647 656 **/ 648 657 649 if( HANDSHAKE_HAS_LTEP( reserved ) ) 650 { 651 tr_peerIoEnableLTEP( handshake->io, 1 ); 652 dbgmsg( handshake, "using ltep" ); 653 } 658 tr_peerIoEnableLTEP( handshake->io, HANDSHAKE_HAS_LTEP( reserved ) ); 659 660 tr_peerIoEnableFEXT( handshake->io, HANDSHAKE_HAS_FASTEXT( reserved ) ); 654 661 655 662 /* torrent hash */ -
trunk/libtransmission/peer-common.h
r7151 r7234 43 43 TR_PEER_CLIENT_GOT_BLOCK, 44 44 TR_PEER_CLIENT_GOT_DATA, 45 TR_PEER_CLIENT_GOT_ALLOWED_FAST, 46 TR_PEER_CLIENT_GOT_SUGGEST, 45 47 TR_PEER_PEER_GOT_DATA, 46 48 TR_PEER_PEER_PROGRESS, … … 54 56 { 55 57 PeerEventType eventType; 56 uint32_t pieceIndex; /* for GOT_BLOCK, CANCEL */58 uint32_t pieceIndex; /* for GOT_BLOCK, CANCEL, ALLOWED, SUGGEST */ 57 59 uint32_t offset; /* for GOT_BLOCK */ 58 60 uint32_t length; /* for GOT_BLOCK + GOT_DATA */ -
trunk/libtransmission/peer-io.c
r7231 r7234 84 84 tr_bool peerIdIsSet; 85 85 tr_bool extendedProtocolSupported; 86 tr_bool fastExtensionSupported; 86 87 87 88 int magicNumber; … … 235 236 { 236 237 return ( io != NULL ) && ( io->magicNumber == MAGIC_NUMBER ); 238 } 239 240 static int 241 isFlag( int flag ) 242 { 243 return( ( flag == 0 ) || ( flag == 1 ) ); 237 244 } 238 245 … … 488 495 489 496 void 497 tr_peerIoEnableFEXT( tr_peerIo * io, 498 int flag ) 499 { 500 assert( isPeerIo( io ) ); 501 assert( isFlag( flag ) ); 502 503 dbgmsg( io, "setting FEXT support flag to %d", (flag?1:0) ); 504 io->fastExtensionSupported = flag; 505 } 506 507 int 508 tr_peerIoSupportsFEXT( const tr_peerIo * io ) 509 { 510 assert( isPeerIo( io ) ); 511 512 return io->fastExtensionSupported; 513 } 514 515 /** 516 *** 517 **/ 518 519 void 490 520 tr_peerIoEnableLTEP( tr_peerIo * io, 491 521 int flag ) 492 522 { 493 523 assert( isPeerIo( io ) ); 494 assert( flag == 0 || flag == 1 ); 495 524 assert( isFlag( flag ) ); 525 526 dbgmsg( io, "setting LTEP support flag to %d", (flag?1:0) ); 496 527 io->extendedProtocolSupported = flag; 497 528 } -
trunk/libtransmission/peer-io.h
r7231 r7234 50 50 **/ 51 51 52 void tr_peerIoEnableLTEP( tr_peerIo * io, 53 int flag ); 52 void tr_peerIoEnableLTEP( tr_peerIo * io, int flag ); 54 53 55 54 int tr_peerIoSupportsLTEP( const tr_peerIo * io ); 55 56 void tr_peerIoEnableFEXT( tr_peerIo * io, int flag ); 57 58 int tr_peerIoSupportsFEXT( const tr_peerIo * io ); 56 59 57 60 /** -
trunk/libtransmission/peer-mgr.c
r7231 r7234 338 338 { 339 339 assert( peer ); 340 assert( peer->msgs ); 341 342 tr_peerMsgsUnsubscribe( peer->msgs, peer->msgsTag ); 343 tr_peerMsgsFree( peer->msgs ); 340 341 if( peer->msgs != NULL ) 342 { 343 tr_peerMsgsUnsubscribe( peer->msgs, peer->msgsTag ); 344 tr_peerMsgsFree( peer->msgs ); 345 } 344 346 345 347 tr_peerIoFree( peer->io ); … … 811 813 for( j=0; !handled && j<peerCount; ) 812 814 { 813 const int val = tr_peerMsgsAddRequest( peers[j]->msgs, 814 index, offset, length ); 815 const int val = tr_peerMsgsAddRequest( peers[j]->msgs, index, offset, length, FALSE ); 815 816 switch( val ) 816 817 { … … 922 923 923 924 static void 925 peerSuggestedPiece( Torrent * t, 926 tr_peer * peer, 927 tr_piece_index_t pieceIndex, 928 int isFastAllowed ) 929 { 930 assert( t ); 931 assert( peer ); 932 assert( peer->msgs ); 933 934 /* is this a valid piece? */ 935 if( pieceIndex >= t->tor->info.pieceCount ) 936 return; 937 938 /* don't ask for it if we've already got it */ 939 if( tr_cpPieceIsComplete( t->tor->completion, pieceIndex ) ) 940 return; 941 942 /* don't ask for it if they don't have it */ 943 if( !tr_bitfieldHas( peer->have, pieceIndex ) ) 944 return; 945 946 /* don't ask for it if we're choked and it's not fast */ 947 if( !isFastAllowed && peer->clientIsChoked ) 948 return; 949 950 /* request the blocks that we don't have in this piece */ 951 { 952 tr_block_index_t block; 953 const tr_torrent * tor = t->tor; 954 const tr_block_index_t start = tr_torPieceFirstBlock( tor, pieceIndex ); 955 const tr_block_index_t end = start + tr_torPieceCountBlocks( tor, pieceIndex ); 956 957 for( block=start; block<end; ++block ) 958 { 959 if( !tr_cpBlockIsComplete( tor->completion, block ) ) 960 { 961 const uint32_t offset = getBlockOffsetInPiece( tor, block ); 962 const uint32_t length = tr_torBlockCountBytes( tor, block ); 963 tr_peerMsgsAddRequest( peer->msgs, pieceIndex, offset, length, TRUE ); 964 incrementPieceRequests( t, pieceIndex ); 965 } 966 } 967 } 968 } 969 970 static void 924 971 peerCallbackFunc( void * vpeer, 925 972 void * vevent, … … 964 1011 break; 965 1012 } 1013 1014 case TR_PEER_CLIENT_GOT_SUGGEST: 1015 if( peer ) 1016 peerSuggestedPiece( t, peer, e->pieceIndex, FALSE ); 1017 break; 1018 1019 case TR_PEER_CLIENT_GOT_ALLOWED_FAST: 1020 if( peer ) 1021 peerSuggestedPiece( t, peer, e->pieceIndex, TRUE ); 1022 break; 966 1023 967 1024 case TR_PEER_CLIENT_GOT_DATA: -
trunk/libtransmission/peer-msgs.c
r7231 r7234 55 55 BT_CANCEL = 8, 56 56 BT_PORT = 9, 57 BT_SUGGEST = 13, 58 BT_HAVE_ALL = 14, 59 BT_HAVE_NONE = 15, 60 BT_REJECT = 16, 57 58 BT_FEXT_SUGGEST = 13, 59 BT_FEXT_HAVE_ALL = 14, 60 BT_FEXT_HAVE_NONE = 15, 61 BT_FEXT_REJECT = 16, 62 BT_FEXT_ALLOWED_FAST = 17, 63 61 64 BT_LTEP = 20, 62 65 … … 64 67 65 68 TR_LTEP_PEX = 1, 69 70 66 71 67 72 MIN_CHOKE_PERIOD_SEC = ( 10 ), … … 91 96 /* number of pieces to remove from the bitfield when 92 97 * lazy bitfields are turned on */ 93 LAZY_PIECE_COUNT = 26 98 LAZY_PIECE_COUNT = 26, 99 100 /* number of pieces we'll allow in our fast set */ 101 MAX_FAST_SET_SIZE = 3 94 102 }; 95 103 … … 259 267 tr_bool clientSentLtepHandshake; 260 268 tr_bool peerSentLtepHandshake; 269 tr_bool haveFastSet; 261 270 262 271 uint8_t state; … … 265 274 uint16_t minActiveRequests; 266 275 uint16_t maxActiveRequests; 276 277 size_t fastsetSize; 278 tr_piece_index_t fastset[MAX_FAST_SET_SIZE]; 267 279 268 280 /* how long the outMessages batch should be allowed to grow before … … 358 370 359 371 static void 372 dbgOutMessageLen( tr_peermsgs * msgs ) 373 { 374 dbgmsg( msgs, "outMessage size is now %zu", EVBUFFER_LENGTH( msgs->outMessages ) ); 375 } 376 377 static void 378 protocolSendReject( tr_peermsgs * msgs, const struct peer_request * req ) 379 { 380 tr_peerIo * io = msgs->io; 381 struct evbuffer * out = msgs->outMessages; 382 383 assert( tr_peerIoSupportsFEXT( msgs->io ) ); 384 385 tr_peerIoWriteUint32( io, out, sizeof( uint8_t ) + 3 * sizeof( uint32_t ) ); 386 tr_peerIoWriteUint8 ( io, out, BT_FEXT_REJECT ); 387 tr_peerIoWriteUint32( io, out, req->index ); 388 tr_peerIoWriteUint32( io, out, req->offset ); 389 tr_peerIoWriteUint32( io, out, req->length ); 390 391 dbgmsg( msgs, "rejecting %u:%u->%u...", req->index, req->offset, req->length ); 392 dbgOutMessageLen( msgs ); 393 } 394 395 static void 360 396 protocolSendRequest( tr_peermsgs * msgs, 361 397 const struct peer_request * req ) 362 398 { 363 tr_peerIo * io= msgs->io;399 tr_peerIo * io = msgs->io; 364 400 struct evbuffer * out = msgs->outMessages; 365 401 … … 369 405 tr_peerIoWriteUint32( io, out, req->offset ); 370 406 tr_peerIoWriteUint32( io, out, req->length ); 371 dbgmsg( msgs, "requesting %u:%u->%u... outMessage size is now %d", 372 req->index, req->offset, req->length, (int)EVBUFFER_LENGTH( out ) ); 407 408 dbgmsg( msgs, "requesting %u:%u->%u...", req->index, req->offset, req->length ); 409 dbgOutMessageLen( msgs ); 373 410 pokeBatchPeriod( msgs, HIGH_PRIORITY_INTERVAL_SECS ); 374 411 } … … 378 415 const struct peer_request * req ) 379 416 { 380 tr_peerIo * io= msgs->io;417 tr_peerIo * io = msgs->io; 381 418 struct evbuffer * out = msgs->outMessages; 382 419 … … 386 423 tr_peerIoWriteUint32( io, out, req->offset ); 387 424 tr_peerIoWriteUint32( io, out, req->length ); 388 dbgmsg( msgs, "cancelling %u:%u->%u... outMessage size is now %d", 389 req->index, req->offset, req->length, (int)EVBUFFER_LENGTH( out ) ); 425 426 dbgmsg( msgs, "cancelling %u:%u->%u...", req->index, req->offset, req->length ); 427 dbgOutMessageLen( msgs ); 390 428 pokeBatchPeriod( msgs, IMMEDIATE_PRIORITY_INTERVAL_SECS ); 391 429 } … … 395 433 uint32_t index ) 396 434 { 397 tr_peerIo * io= msgs->io;435 tr_peerIo * io = msgs->io; 398 436 struct evbuffer * out = msgs->outMessages; 399 437 400 tr_peerIoWriteUint32( io, out, sizeof( uint8_t ) + sizeof( uint32_t) );438 tr_peerIoWriteUint32( io, out, sizeof(uint8_t) + sizeof(uint32_t) ); 401 439 tr_peerIoWriteUint8 ( io, out, BT_HAVE ); 402 440 tr_peerIoWriteUint32( io, out, index ); 403 dbgmsg( msgs, "sending Have %u.. outMessage size is now %d", 404 index, (int)EVBUFFER_LENGTH( out ) ); 441 442 dbgmsg( msgs, "sending Have %u...", index ); 443 dbgOutMessageLen( msgs ); 405 444 pokeBatchPeriod( msgs, LOW_PRIORITY_INTERVAL_SECS ); 445 } 446 447 static void 448 protocolSendAllowedFast( tr_peermsgs * msgs, uint32_t pieceIndex ) 449 { 450 tr_peerIo * io = msgs->io; 451 struct evbuffer * out = msgs->outMessages; 452 453 assert( tr_peerIoSupportsFEXT( msgs->io ) ); 454 455 tr_peerIoWriteUint32( io, out, sizeof(uint8_t) + sizeof(uint32_t) ); 456 tr_peerIoWriteUint8 ( io, out, BT_FEXT_ALLOWED_FAST ); 457 tr_peerIoWriteUint32( io, out, pieceIndex ); 458 459 dbgmsg( msgs, "sending Allowed Fast %u...", pieceIndex ); 460 dbgOutMessageLen( msgs ); 406 461 } 407 462 … … 410 465 int choke ) 411 466 { 412 tr_peerIo * io= msgs->io;467 tr_peerIo * io = msgs->io; 413 468 struct evbuffer * out = msgs->outMessages; 414 469 415 470 tr_peerIoWriteUint32( io, out, sizeof( uint8_t ) ); 416 471 tr_peerIoWriteUint8 ( io, out, choke ? BT_CHOKE : BT_UNCHOKE ); 417 dbgmsg( msgs, "sending %s... outMessage size is now %d", 418 ( choke ? "Choke" : "Unchoke" ), 419 (int)EVBUFFER_LENGTH( out ) ); 472 473 dbgmsg( msgs, "sending %s...", choke ? "Choke" : "Unchoke" ); 474 dbgOutMessageLen( msgs ); 475 pokeBatchPeriod( msgs, IMMEDIATE_PRIORITY_INTERVAL_SECS ); 476 } 477 478 static void 479 protocolSendHaveAll( tr_peermsgs * msgs ) 480 { 481 tr_peerIo * io = msgs->io; 482 struct evbuffer * out = msgs->outMessages; 483 484 assert( tr_peerIoSupportsFEXT( msgs->io ) ); 485 486 tr_peerIoWriteUint32( io, out, sizeof( uint8_t ) ); 487 tr_peerIoWriteUint8 ( io, out, BT_FEXT_HAVE_ALL ); 488 489 dbgmsg( msgs, "sending HAVE_ALL..." ); 490 dbgOutMessageLen( msgs ); 491 pokeBatchPeriod( msgs, IMMEDIATE_PRIORITY_INTERVAL_SECS ); 492 } 493 494 static void 495 protocolSendHaveNone( tr_peermsgs * msgs ) 496 { 497 tr_peerIo * io = msgs->io; 498 struct evbuffer * out = msgs->outMessages; 499 500 assert( tr_peerIoSupportsFEXT( msgs->io ) ); 501 502 tr_peerIoWriteUint32( io, out, sizeof( uint8_t ) ); 503 tr_peerIoWriteUint8 ( io, out, BT_FEXT_HAVE_NONE ); 504 505 dbgmsg( msgs, "sending HAVE_NONE..." ); 506 dbgOutMessageLen( msgs ); 420 507 pokeBatchPeriod( msgs, IMMEDIATE_PRIORITY_INTERVAL_SECS ); 421 508 } … … 487 574 e.eventType = TR_PEER_CLIENT_GOT_DATA; 488 575 e.wasPieceData = wasPieceData; 576 publish( msgs, &e ); 577 } 578 579 static void 580 fireClientGotSuggest( tr_peermsgs * msgs, uint32_t pieceIndex ) 581 { 582 tr_peer_event e = blankEvent; 583 e.eventType = TR_PEER_CLIENT_GOT_SUGGEST; 584 e.pieceIndex = pieceIndex; 585 publish( msgs, &e ); 586 } 587 588 static void 589 fireClientGotAllowedFast( tr_peermsgs * msgs, uint32_t pieceIndex ) 590 { 591 tr_peer_event e = blankEvent; 592 e.eventType = TR_PEER_CLIENT_GOT_ALLOWED_FAST; 593 e.pieceIndex = pieceIndex; 489 594 publish( msgs, &e ); 490 595 } … … 513 618 e.length = req->length; 514 619 publish( msgs, &e ); 620 } 621 622 /** 623 *** ALLOWED FAST SET 624 *** For explanation, see http://www.bittorrent.org/beps/bep_0006.html 625 **/ 626 627 size_t 628 tr_generateAllowedSet( tr_piece_index_t * setmePieces, 629 size_t desiredSetSize, 630 size_t pieceCount, 631 const uint8_t * infohash, 632 const tr_address * addr ) 633 { 634 size_t setSize = 0; 635 636 assert( setmePieces ); 637 assert( desiredSetSize <= pieceCount ); 638 assert( desiredSetSize ); 639 assert( pieceCount ); 640 assert( infohash ); 641 assert( addr ); 642 643 if( addr->type == TR_AF_INET ) 644 { 645 uint8_t w[SHA_DIGEST_LENGTH + 4]; 646 uint8_t x[SHA_DIGEST_LENGTH]; 647 648 *(uint32_t*)w = ntohl( htonl( addr->addr.addr4.s_addr ) & 0xffffff00 ); /* (1) */ 649 memcpy( w + 4, infohash, SHA_DIGEST_LENGTH ); /* (2) */ 650 tr_sha1( x, w, sizeof( w ), NULL ); /* (3) */ 651 652 while( setSize<desiredSetSize ) 653 { 654 int i; 655 for( i=0; i<5 && setSize<desiredSetSize; ++i ) /* (4) */ 656 { 657 size_t k; 658 uint32_t j = i * 4; /* (5) */ 659 uint32_t y = ntohl( *( uint32_t* )( x + j ) ); /* (6) */ 660 uint32_t index = y % pieceCount; /* (7) */ 661 662 for( k=0; k<setSize; ++k ) /* (8) */ 663 if( setmePieces[k] == index ) 664 break; 665 666 if( k == setSize ) 667 setmePieces[setSize++] = index; /* (9) */ 668 } 669 670 tr_sha1( x, x, sizeof( x ), NULL ); /* (3) */ 671 } 672 } 673 674 return setSize; 675 } 676 677 static void 678 updateFastSet( tr_peermsgs * msgs UNUSED ) 679 { 680 #if 0 681 const int fext = tr_peerIoSupportsFEXT( msgs->io ); 682 const int peerIsNeedy = msgs->info->progress < 0.10; 683 684 if( fext && peerIsNeedy && !msgs->haveFastSet ) 685 { 686 size_t i; 687 const struct tr_address * addr = tr_peerIoGetAddress( msgs->io, NULL ); 688 const tr_info * inf = &msgs->torrent->info; 689 const size_t numwant = MIN( MAX_FAST_SET_SIZE, inf->pieceCount ); 690 691 /* build the fast set */ 692 msgs->fastsetSize = tr_generateAllowedSet( msgs->fastset, numwant, inf->pieceCount, inf->hash, addr ); 693 msgs->haveFastSet = 1; 694 695 /* send it to the peer */ 696 for( i=0; i<msgs->fastsetSize; ++i ) 697 protocolSendAllowedFast( msgs, msgs->fastset[i] ); 698 } 699 #endif 515 700 } 516 701 … … 591 776 } 592 777 778 static int 779 popNextRequest( tr_peermsgs * msgs, 780 struct peer_request * setme ) 781 { 782 return reqListPop( &msgs->peerAskedFor, setme ); 783 } 784 593 785 static void 594 786 cancelAllRequestsToClient( tr_peermsgs * msgs ) 595 787 { 596 reqListClear( &msgs->peerAskedFor ); 788 struct peer_request req; 789 790 while( popNextRequest( msgs, &req ) ) 791 protocolSendReject( msgs, &req ); 597 792 } 598 793 … … 662 857 time_t oldestAllowed; 663 858 struct request_list tmp = REQUEST_LIST_INIT; 859 const int fext = tr_peerIoSupportsFEXT( msgs->io ); 664 860 665 861 /* cancel requests that have been queued for too long */ 666 862 oldestAllowed = now - QUEUED_REQUEST_TTL_SECS; 667 863 reqListCopy( &tmp, &msgs->clientWillAskFor ); 668 for( i = 0; i < tmp.count; ++i ) 669 { 864 for( i = 0; i < tmp.count; ++i ) { 670 865 const struct peer_request * req = &tmp.requests[i]; 671 866 if( req->time_requested < oldestAllowed ) … … 674 869 reqListClear( &tmp ); 675 870 676 /* cancel requests that were sent too long ago */ 677 oldestAllowed = now - SENT_REQUEST_TTL_SECS; 678 reqListCopy( &tmp, &msgs->clientAskedFor ); 679 for( i = 0; i < tmp.count; ++i ) 680 { 681 const struct peer_request * req = &tmp.requests[i]; 682 if( req->time_requested < oldestAllowed ) 683 tr_peerMsgsCancel( msgs, req->index, req->offset, req->length ); 684 } 685 reqListClear( &tmp ); 871 /* if the peer doesn't support "Reject Request", 872 * cancel requests that were sent too long ago. */ 873 if( !fext ) { 874 oldestAllowed = now - SENT_REQUEST_TTL_SECS; 875 reqListCopy( &tmp, &msgs->clientAskedFor ); 876 for( i=0; i<tmp.count; ++i ) { 877 const struct peer_request * req = &tmp.requests[i]; 878 if( req->time_requested < oldestAllowed ) 879 tr_peerMsgsCancel( msgs, req->index, req->offset, req->length ); 880 } 881 reqListClear( &tmp ); 882 } 686 883 } 687 884 … … 745 942 uint32_t index, 746 943 uint32_t offset, 747 uint32_t length ) 944 uint32_t length, 945 int doForce ) 748 946 { 749 947 struct peer_request req; … … 758 956 759 957 /* don't send requests to choked clients */ 760 if( msgs->info->clientIsChoked ) 761 { 958 if( !doForce && msgs->info->clientIsChoked ) { 762 959 dbgmsg( msgs, "declining request because they're choking us" ); 763 960 return TR_ADDREQ_CLIENT_CHOKED; … … 765 962 766 963 /* peer doesn't have this piece */ 767 if( ! tr_bitfieldHas( msgs->info->have, index ) )964 if( !doForce && !tr_bitfieldHas( msgs->info->have, index ) ) 768 965 return TR_ADDREQ_MISSING; 769 966 770 967 /* peer's queue is full */ 771 if( requestQueueIsFull( msgs ) ) {968 if( !doForce && requestQueueIsFull( msgs ) ) { 772 969 dbgmsg( msgs, "declining request because we're full" ); 773 970 return TR_ADDREQ_FULL; … … 778 975 req.offset = offset; 779 976 req.length = length; 780 if( reqListFind( &msgs->clientAskedFor, &req ) != -1 ) { 781 dbgmsg( msgs, "declining because it's a duplicate" ); 782 return TR_ADDREQ_DUPLICATE; 783 } 784 if( reqListFind( &msgs->clientWillAskFor, &req ) != -1 ) { 785 dbgmsg( msgs, "declining because it's a duplicate" ); 786 return TR_ADDREQ_DUPLICATE; 977 if( !doForce ) { 978 if( reqListFind( &msgs->clientAskedFor, &req ) != -1 ) { 979 dbgmsg( msgs, "declining because it's a duplicate" ); 980 return TR_ADDREQ_DUPLICATE; 981 } 982 if( reqListFind( &msgs->clientWillAskFor, &req ) != -1 ) { 983 dbgmsg( msgs, "declining because it's a duplicate" ); 984 return TR_ADDREQ_DUPLICATE; 985 } 787 986 } 788 987 … … 851 1050 } 852 1051 } 1052 853 1053 854 1054 /** … … 1078 1278 updatePeerProgress( tr_peermsgs * msgs ) 1079 1279 { 1080 msgs->info->progress = tr_bitfieldCountTrueBits( msgs->info->have ) 1081 / (float)msgs->torrent->info.pieceCount; 1280 msgs->info->progress = tr_bitfieldCountTrueBits( msgs->info->have ) / (float)msgs->torrent->info.pieceCount; 1082 1281 dbgmsg( msgs, "peer progress is %f", msgs->info->progress ); 1282 updateFastSet( msgs ); 1083 1283 updateInterest( msgs ); 1084 1284 firePeerProgress( msgs ); … … 1089 1289 const struct peer_request * req ) 1090 1290 { 1291 const int fext = tr_peerIoSupportsFEXT( msgs->io ); 1091 1292 const int reqIsValid = requestIsValid( msgs, req ); 1092 const int clientHasPiece = reqIsValid && tr_cpPieceIsComplete( 1093 msgs->torrent->completion, req->index ); 1293 const int clientHasPiece = reqIsValid && tr_cpPieceIsComplete( msgs->torrent->completion, req->index ); 1094 1294 const int peerIsChoked = msgs->info->peerIsChoked; 1095 1295 1096 if( !reqIsValid ) /* bad request */ 1097 { 1296 int allow = FALSE; 1297 1298 if( !reqIsValid ) 1098 1299 dbgmsg( msgs, "rejecting an invalid request." ); 1099 } 1100 else if( !clientHasPiece ) /* we don't have it */ 1101 { 1300 else if( !clientHasPiece ) 1102 1301 dbgmsg( msgs, "rejecting request for a piece we don't have." ); 1103 } 1104 else if( peerIsChoked ) /* doesn't he know he's choked? */ 1105 { 1106 tr_peerMsgsSetChoke( msgs, 1 ); 1107 } 1108 else /* YAY */ 1109 { 1302 else if( peerIsChoked ) 1303 dbgmsg( msgs, "rejecting request from choked peer" ); 1304 else 1305 allow = TRUE; 1306 1307 if( allow ) 1110 1308 reqListAppend( &msgs->peerAskedFor, req ); 1111 } 1309 else if( fext ) 1310 protocolSendReject( msgs, req ); 1112 1311 } 1113 1312 … … 1123 1322 case BT_INTERESTED: 1124 1323 case BT_NOT_INTERESTED: 1125 case BT_ HAVE_ALL:1126 case BT_ HAVE_NONE:1324 case BT_FEXT_HAVE_ALL: 1325 case BT_FEXT_HAVE_NONE: 1127 1326 return len == 1; 1128 1327 1129 1328 case BT_HAVE: 1130 case BT_SUGGEST: 1329 case BT_FEXT_SUGGEST: 1330 case BT_FEXT_ALLOWED_FAST: 1131 1331 return len == 5; 1132 1332 … … 1136 1336 case BT_REQUEST: 1137 1337 case BT_CANCEL: 1138 case BT_ REJECT:1338 case BT_FEXT_REJECT: 1139 1339 return len == 13; 1140 1340 … … 1230 1430 const uint8_t id = msgs->incoming.id; 1231 1431 const size_t startBufLen = EVBUFFER_LENGTH( inbuf ); 1432 const int fext = tr_peerIoSupportsFEXT( msgs->io ); 1232 1433 1233 1434 --msglen; /* id length */ … … 1253 1454 dbgmsg( msgs, "got Choke" ); 1254 1455 msgs->info->clientIsChoked = 1; 1255 cancelAllRequestsToPeer( msgs ); 1456 if( !fext ) 1457 cancelAllRequestsToPeer( msgs ); 1256 1458 cancelAllRequestsToClient( msgs ); 1257 1459 break; … … 1315 1517 tr_peerIoReadUint32( msgs->io, inbuf, &r.length ); 1316 1518 dbgmsg( msgs, "got a Cancel %u:%u->%u", r.index, r.offset, r.length ); 1317 reqListRemove( &msgs->peerAskedFor, &r ); 1519 if( reqListRemove( &msgs->peerAskedFor, &r ) && fext ) 1520 protocolSendReject( msgs, &r ); 1318 1521 break; 1319 1522 } … … 1328 1531 break; 1329 1532 1330 case BT_SUGGEST: 1331 { 1332 dbgmsg( msgs, "Got a BT_SUGGEST" ); 1533 case BT_FEXT_SUGGEST: 1534 dbgmsg( msgs, "Got a BT_FEXT_SUGGEST" ); 1333 1535 tr_peerIoReadUint32( msgs->io, inbuf, &ui32 ); 1334 /* we don't do anything with this yet */ 1536 if( fext ) 1537 fireClientGotSuggest( msgs, ui32 ); 1538 else { 1539 fireError( msgs, EPROTO ); 1540 return READ_ERR; 1541 } 1335 1542 break; 1336 } 1337 1338 case BT_HAVE_ALL: 1339 dbgmsg( msgs, "Got a BT_HAVE_ALL" ); 1340 tr_bitfieldAddRange( msgs->info->have, 0, 1341 msgs->torrent->info.pieceCount ); 1342 updatePeerProgress( msgs ); 1543 1544 case BT_FEXT_ALLOWED_FAST: 1545 dbgmsg( msgs, "Got a BT_FEXT_ALLOWED_FAST" ); 1546 tr_peerIoReadUint32( msgs->io, inbuf, &ui32 ); 1547 if( fext ) 1548 fireClientGotAllowedFast( msgs, ui32 ); 1549 else { 1550 fireError( msgs, EPROTO ); 1551 return READ_ERR; 1552 } 1343 1553 break; 1344 1554 1345 1346 case BT_HAVE_NONE: 1347 dbgmsg( msgs, "Got a BT_HAVE_NONE" ); 1348 tr_bitfieldClear( msgs->info->have ); 1349 updatePeerProgress( msgs ); 1555 case BT_FEXT_HAVE_ALL: 1556 dbgmsg( msgs, "Got a BT_FEXT_HAVE_ALL" ); 1557 if( fext ) { 1558 tr_bitfieldAddRange( msgs->info->have, 0, msgs->torrent->info.pieceCount ); 1559 updatePeerProgress( msgs ); 1560 } else { 1561 fireError( msgs, EPROTO ); 1562 return READ_ERR; 1563 } 1350 1564 break; 1351 1565 1352 case BT_REJECT: 1566 1567 case BT_FEXT_HAVE_NONE: 1568 dbgmsg( msgs, "Got a BT_FEXT_HAVE_NONE" ); 1569 if( fext ) { 1570 tr_bitfieldClear( msgs->info->have ); 1571 updatePeerProgress( msgs ); 1572 } else { 1573 fireError( msgs, EPROTO ); 1574 return READ_ERR; 1575 } 1576 break; 1577 1578 case BT_FEXT_REJECT: 1353 1579 { 1354 1580 struct peer_request r; 1355 dbgmsg( msgs, "Got a BT_ REJECT" );1581 dbgmsg( msgs, "Got a BT_FEXT_REJECT" ); 1356 1582 tr_peerIoReadUint32( msgs->io, inbuf, &r.index ); 1357 1583 tr_peerIoReadUint32( msgs->io, inbuf, &r.offset ); 1358 1584 tr_peerIoReadUint32( msgs->io, inbuf, &r.length ); 1359 reqListRemove( &msgs->clientAskedFor, &r ); 1585 if( fext ) 1586 reqListRemove( &msgs->clientAskedFor, &r ); 1587 else { 1588 fireError( msgs, EPROTO ); 1589 return READ_ERR; 1590 } 1360 1591 break; 1361 1592 } … … 1532 1763 } 1533 1764 1534 static int1535 popNextRequest( tr_peermsgs * msgs,1536 struct peer_request * setme )1537 {1538 return reqListPop( &msgs->peerAskedFor, setme );1539 }1540 1541 1765 static size_t 1542 1766 fillOutputBuffer( tr_peermsgs * msgs, time_t now ) … … 1545 1769 struct peer_request req; 1546 1770 const int haveMessages = EVBUFFER_LENGTH( msgs->outMessages ) != 0; 1771 const int fext = tr_peerIoSupportsFEXT( msgs->io ); 1547 1772 1548 1773 /** … … 1572 1797 1573 1798 if( ( tr_peerIoGetWriteBufferSpace( msgs->io ) >= msgs->torrent->blockSize ) 1574 && popNextRequest( msgs, &req ) 1575 && requestIsValid( msgs, &req ) 1576 && tr_cpPieceIsComplete( msgs->torrent->completion, req.index ) ) 1577 { 1578 /* send a block */ 1579 uint8_t * buf = tr_new( uint8_t, req.length ); 1580 const int err = tr_ioRead( msgs->torrent, req.index, req.offset, req.length, buf ); 1581 if( err ) { 1582 fireError( msgs, err ); 1583 bytesWritten = 0; 1584 msgs = NULL; 1585 } else { 1586 tr_peerIo * io = msgs->io; 1587 struct evbuffer * out = evbuffer_new( ); 1588 dbgmsg( msgs, "sending block %u:%u->%u", req.index, req.offset, req.length ); 1589 tr_peerIoWriteUint32( io, out, sizeof( uint8_t ) + 2 * sizeof( uint32_t ) + req.length ); 1590 tr_peerIoWriteUint8 ( io, out, BT_PIECE ); 1591 tr_peerIoWriteUint32( io, out, req.index ); 1592 tr_peerIoWriteUint32( io, out, req.offset ); 1593 tr_peerIoWriteBytes ( io, out, buf, req.length ); 1594 tr_peerIoWriteBuf( io, out, TRUE ); 1595 bytesWritten += EVBUFFER_LENGTH( out ); 1596 evbuffer_free( out ); 1597 msgs->clientSentAnythingAt = now; 1799 && popNextRequest( msgs, &req ) ) 1800 { 1801 if( requestIsValid( msgs, &req ) 1802 && tr_cpPieceIsComplete( msgs->torrent->completion, req.index ) ) 1803 { 1804 /* send a block */ 1805 uint8_t * buf = tr_new( uint8_t, req.length ); 1806 const int err = tr_ioRead( msgs->torrent, req.index, req.offset, req.length, buf ); 1807 if( err ) { 1808 fireError( msgs, err ); 1809 bytesWritten = 0; 1810 msgs = NULL; 1811 } else { 1812 tr_peerIo * io = msgs->io; 1813 struct evbuffer * out = evbuffer_new( ); 1814 dbgmsg( msgs, "sending block %u:%u->%u", req.index, req.offset, req.length ); 1815 tr_peerIoWriteUint32( io, out, sizeof( uint8_t ) + 2 * sizeof( uint32_t ) + req.length ); 1816 tr_peerIoWriteUint8 ( io, out, BT_PIECE ); 1817 tr_peerIoWriteUint32( io, out, req.index ); 1818 tr_peerIoWriteUint32( io, out, req.offset ); 1819 tr_peerIoWriteBytes ( io, out, buf, req.length ); 1820 tr_peerIoWriteBuf( io, out, TRUE ); 1821 bytesWritten += EVBUFFER_LENGTH( out ); 1822 evbuffer_free( out ); 1823 msgs->clientSentAnythingAt = now; 1824 } 1825 tr_free( buf ); 1598 1826 } 1599 tr_free( buf ); 1827 else if( fext ) /* peer needs a reject message */ 1828 { 1829 protocolSendReject( msgs, &req ); 1830 } 1600 1831 } 1601 1832 … … 1705 1936 1706 1937 tr_bitfieldFree( field ); 1938 } 1939 1940 static void 1941 tellPeerWhatWeHave( tr_peermsgs * msgs ) 1942 { 1943 const int fext = tr_peerIoSupportsFEXT( msgs->io ); 1944 1945 if( fext && ( tr_cpGetStatus( msgs->torrent->completion ) == TR_SEED ) ) 1946 { 1947 protocolSendHaveAll( msgs ); 1948 } 1949 else if( fext && ( tr_cpHaveValid( msgs->torrent->completion ) == 0 ) ) 1950 { 1951 protocolSendHaveNone( msgs ); 1952 } 1953 else 1954 { 1955 sendBitfield( msgs ); 1956 } 1707 1957 } 1708 1958 … … 1913 2163 sendLtepHandshake( m ); 1914 2164 1915 sendBitfield( m );2165 tellPeerWhatWeHave( m ); 1916 2166 1917 2167 tr_peerIoSetTimeoutSecs( m->io, 150 ); /* timeout after N seconds of -
trunk/libtransmission/peer-msgs.h
r7151 r7234 54 54 uint32_t pieceIndex, 55 55 uint32_t offset, 56 uint32_t length ); 56 uint32_t length, 57 int doForce ); 57 58 58 void tr_peerMsgsUnsubscribe( tr_peermsgs * peer, 59 tr_publisher_tag tag ); 59 void tr_peerMsgsUnsubscribe( tr_peermsgs * peer, 60 tr_publisher_tag tag ); 61 62 size_t tr_generateAllowedSet( tr_piece_index_t * setmePieces, 63 size_t desiredSetSize, 64 size_t pieceCount, 65 const uint8_t * infohash, 66 const tr_address * addr ); 67 60 68 61 69 #endif
Note: See TracChangeset
for help on using the changeset viewer.