Changeset 6795 for trunk/libtransmission/peer-io.c
- Timestamp:
- Sep 23, 2008, 7:11:04 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/peer-io.c
r6791 r6795 4 4 * This file is licensed by the GPL version 2. Works owned by the 5 5 * Transmission project are granted a special exemption to clause 2(b) 6 * so that the bulk of its code can remain under the MIT license. 6 * so that the bulk of its code can remain under the MIT license. 7 7 * This exemption does not extend to derived works not owned by 8 8 * the Transmission project. … … 18 18 19 19 #ifdef WIN32 20 #include <winsock2.h>20 #include <winsock2.h> 21 21 #else 22 #include <netinet/in.h> /* struct in_addr */23 #include <arpa/inet.h> /* inet_ntoa */22 #include <netinet/in.h> /* struct in_addr */ 23 #include <arpa/inet.h> /* inet_ntoa */ 24 24 #endif 25 25 … … 40 40 **/ 41 41 42 #define dbgmsg( io, fmt...) \43 tr_deepLog( __FILE__, __LINE__, tr_peerIoGetAddrStr(io), ##fmt )42 #define dbgmsg( io, fmt... ) \ 43 tr_deepLog( __FILE__, __LINE__, tr_peerIoGetAddrStr( io ), ## fmt ) 44 44 45 45 struct tr_bandwidth 46 46 { 47 unsigned int 48 size_t 49 size_t 47 unsigned int isUnlimited : 1; 48 size_t bytesUsed; 49 size_t bytesLeft; 50 50 }; 51 51 52 52 struct tr_peerIo 53 53 { 54 unsigned int isEncrypted: 1;55 unsigned int isIncoming: 1;56 unsigned int peerIdIsSet: 1;57 unsigned int extendedProtocolSupported : 1;58 unsigned int fastPeersSupported: 1;59 60 uint8_t encryptionMode;61 uint8_t timeout;62 uint16_t port;63 int socket;64 65 uint8_t peerId[20];66 time_t timeCreated;67 68 tr_session *session;69 70 struct in_addr in_addr;71 struct bufferevent *bufev;72 struct evbuffer *output;73 74 tr_can_read_cb canRead;75 tr_did_write_cb didWrite;76 tr_net_error_cb gotError;77 void *userData;78 79 size_t bufferSize[2];80 81 struct tr_bandwidth bandwidth[2];82 tr_ratecontrol *speedometer[2];83 84 tr_crypto *crypto;54 unsigned int isEncrypted : 1; 55 unsigned int isIncoming : 1; 56 unsigned int peerIdIsSet : 1; 57 unsigned int extendedProtocolSupported : 1; 58 unsigned int fastPeersSupported : 1; 59 60 uint8_t encryptionMode; 61 uint8_t timeout; 62 uint16_t port; 63 int socket; 64 65 uint8_t peerId[20]; 66 time_t timeCreated; 67 68 tr_session * session; 69 70 struct in_addr in_addr; 71 struct bufferevent * bufev; 72 struct evbuffer * output; 73 74 tr_can_read_cb canRead; 75 tr_did_write_cb didWrite; 76 tr_net_error_cb gotError; 77 void * userData; 78 79 size_t bufferSize[2]; 80 81 struct tr_bandwidth bandwidth[2]; 82 tr_ratecontrol * speedometer[2]; 83 84 tr_crypto * crypto; 85 85 }; 86 86 … … 112 112 /* bufev's output buffer exceeds our bandwidth allocation; 113 113 move the excess out of bufev so it can't be sent yet */ 114 const size_t desiredLength = io->bandwidth[TR_UP].bytesLeft;115 const size_t over = EVBUFFER_LENGTH( live ) - desiredLength;114 const size_t desiredLength = io->bandwidth[TR_UP].bytesLeft; 115 const size_t over = EVBUFFER_LENGTH( live ) - desiredLength; 116 116 struct evbuffer * buf = evbuffer_new( ); 117 117 evbuffer_add( buf, EVBUFFER_DATA( live ) + desiredLength, over ); … … 163 163 164 164 static void 165 didWriteWrapper( struct bufferevent * e, void * vio ) 166 { 167 tr_peerIo * io = vio; 165 didWriteWrapper( struct bufferevent * e, 166 void * vio ) 167 { 168 tr_peerIo * io = vio; 168 169 const size_t len = EVBUFFER_LENGTH( EVBUFFER_OUTPUT( e ) ); 169 170 … … 173 174 if( len < io->bufferSize[TR_UP] ) 174 175 { 175 const size_t n = io->bufferSize[TR_UP] - len;176 const size_t n = io->bufferSize[TR_UP] - len; 176 177 struct tr_bandwidth * b = &io->bandwidth[TR_UP]; 177 178 b->bytesLeft -= MIN( b->bytesLeft, (size_t)n ); 178 179 b->bytesUsed += n; 179 180 tr_rcTransferred( io->speedometer[TR_UP], n ); 180 dbgmsg( io, "wrote %zu bytes to peer... upload bytesLeft is now %zu", 181 n, b->bytesLeft ); 181 dbgmsg( io, 182 "wrote %zu bytes to peer... upload bytesLeft is now %zu", 183 n, 184 b->bytesLeft ); 182 185 } 183 186 … … 189 192 190 193 static void 191 canReadWrapper( struct bufferevent * e, void * vio ) 192 { 193 int done = 0; 194 int err = 0; 195 tr_peerIo * io = vio; 194 canReadWrapper( struct bufferevent * e, 195 void * vio ) 196 { 197 int done = 0; 198 int err = 0; 199 tr_peerIo * io = vio; 196 200 tr_session * session = io->session; 197 201 const size_t len = EVBUFFER_LENGTH( EVBUFFER_INPUT( e ) ); … … 202 206 if( len > io->bufferSize[TR_DOWN] ) 203 207 { 204 const size_t n = len - io->bufferSize[TR_DOWN];208 const size_t n = len - io->bufferSize[TR_DOWN]; 205 209 struct tr_bandwidth * b = io->bandwidth + TR_DOWN; 206 210 b->bytesLeft -= MIN( b->bytesLeft, (size_t)n ); 207 211 b->bytesUsed += n; 208 212 tr_rcTransferred( io->speedometer[TR_DOWN], n ); 209 dbgmsg( io, "%zu new input bytes. bytesUsed is %zu, bytesLeft is %zu", 210 n, b->bytesUsed, b->bytesLeft ); 213 dbgmsg( io, 214 "%zu new input bytes. bytesUsed is %zu, bytesLeft is %zu", 215 n, b->bytesUsed, 216 b->bytesLeft ); 211 217 212 218 adjustInputBuffer( io ); … … 229 235 done = 1; 230 236 break; 237 231 238 case READ_LATER: 232 239 done = 1; 233 240 break; 241 234 242 case READ_ERR: 235 243 err = 1; … … 246 254 247 255 static void 248 gotErrorWrapper( struct bufferevent * e, short what, void * userData ) 256 gotErrorWrapper( struct bufferevent * e, 257 short what, 258 void * userData ) 249 259 { 250 260 tr_peerIo * c = userData; 261 251 262 if( c->gotError ) 252 263 c->gotError( e, what, c->userData ); … … 272 283 bufferevent_settimeout( io->bufev, io->timeout, io->timeout ); 273 284 274 bufferevent_enable( io->bufev, EV_READ |EV_WRITE );285 bufferevent_enable( io->bufev, EV_READ | EV_WRITE ); 275 286 } 276 287 277 288 static tr_peerIo* 278 tr_peerIoNew( tr_session *session,279 const struct in_addr 280 uint16_t 281 const uint8_t *torrentHash,282 int 283 int 289 tr_peerIoNew( tr_session * session, 290 const struct in_addr * in_addr, 291 uint16_t port, 292 const uint8_t * torrentHash, 293 int isIncoming, 294 int socket ) 284 295 { 285 296 tr_peerIo * io; … … 307 318 308 319 tr_peerIo* 309 tr_peerIoNewIncoming( tr_session *session,310 const struct in_addr 311 uint16_t 312 int 320 tr_peerIoNewIncoming( tr_session * session, 321 const struct in_addr * in_addr, 322 uint16_t port, 323 int socket ) 313 324 { 314 325 assert( session ); … … 322 333 323 334 tr_peerIo* 324 tr_peerIoNewOutgoing( tr_session *session,325 const struct in_addr 326 int 327 const uint8_t *torrentHash )335 tr_peerIoNewOutgoing( tr_session * session, 336 const struct in_addr * in_addr, 337 int port, 338 const uint8_t * torrentHash ) 328 339 { 329 340 int socket; … … 337 348 338 349 return socket < 0 339 ? NULL340 : tr_peerIoNew( session, in_addr, port, torrentHash, 0, socket );350 ? NULL 351 : tr_peerIoNew( session, in_addr, port, torrentHash, 0, socket ); 341 352 } 342 353 … … 377 388 378 389 const struct in_addr* 379 tr_peerIoGetAddress( const tr_peerIo * io, uint16_t * port ) 390 tr_peerIoGetAddress( const tr_peerIo * io, 391 uint16_t * port ) 380 392 { 381 393 assert( io ); 382 394 383 395 if( port ) 384 *port = io->port;396 *port = io->port; 385 397 386 398 return &io->in_addr; … … 388 400 389 401 const char* 390 tr_peerIoAddrStr( const struct in_addr * addr, uint16_t port ) 402 tr_peerIoAddrStr( const struct in_addr * addr, 403 uint16_t port ) 391 404 { 392 405 static char buf[512]; 393 tr_snprintf( buf, sizeof(buf), "%s:%u", inet_ntoa( *addr ), ntohs( port ) ); 406 407 tr_snprintf( buf, sizeof( buf ), "%s:%u", inet_ntoa( *addr ), 408 ntohs( port ) ); 394 409 return buf; 395 410 } … … 408 423 } 409 424 410 void 411 tr_peerIoSetIOFuncs( tr_peerIo *io,412 tr_can_read_cb 413 tr_did_write_cb 414 tr_net_error_cb 415 void *userData )425 void 426 tr_peerIoSetIOFuncs( tr_peerIo * io, 427 tr_can_read_cb readcb, 428 tr_did_write_cb writecb, 429 tr_net_error_cb errcb, 430 void * userData ) 416 431 { 417 432 io->canRead = readcb; … … 438 453 439 454 io->socket = tr_netOpenTCP( &io->in_addr, io->port, 0 ); 440 455 441 456 if( io->socket >= 0 ) 442 457 { … … 447 462 return 0; 448 463 } 449 464 450 465 return -1; 451 466 } 452 467 453 468 void 454 tr_peerIoSetTimeoutSecs( tr_peerIo * io, int secs ) 469 tr_peerIoSetTimeoutSecs( tr_peerIo * io, 470 int secs ) 455 471 { 456 472 io->timeout = secs; 457 473 bufferevent_settimeout( io->bufev, io->timeout, io->timeout ); 458 bufferevent_enable( io->bufev, EV_READ |EV_WRITE );459 } 460 461 /** 462 *** 463 **/ 464 465 void 466 tr_peerIoSetTorrentHash( tr_peerIo *io,474 bufferevent_enable( io->bufev, EV_READ | EV_WRITE ); 475 } 476 477 /** 478 *** 479 **/ 480 481 void 482 tr_peerIoSetTorrentHash( tr_peerIo * io, 467 483 const uint8_t * hash ) 468 484 { … … 495 511 496 512 void 497 tr_peerIoSetPeersId( tr_peerIo *io,513 tr_peerIoSetPeersId( tr_peerIo * io, 498 514 const uint8_t * peer_id ) 499 515 { 500 516 assert( io ); 501 517 502 if( ( io->peerIdIsSet = peer_id != NULL ))518 if( ( io->peerIdIsSet = peer_id != NULL ) ) 503 519 memcpy( io->peerId, peer_id, 20 ); 504 520 else … … 506 522 } 507 523 508 const uint8_t* 524 const uint8_t* 509 525 tr_peerIoGetPeersId( const tr_peerIo * io ) 510 526 { … … 520 536 521 537 void 522 tr_peerIoEnableLTEP( tr_peerIo * io, int flag ) 523 { 524 assert( io ); 525 assert( flag==0 || flag==1 ); 526 538 tr_peerIoEnableLTEP( tr_peerIo * io, 539 int flag ) 540 { 541 assert( io ); 542 assert( flag == 0 || flag == 1 ); 543 527 544 io->extendedProtocolSupported = flag; 528 545 } 529 546 530 547 void 531 tr_peerIoEnableFEXT( tr_peerIo * io, int flag ) 532 { 533 assert( io ); 534 assert( flag==0 || flag==1 ); 535 548 tr_peerIoEnableFEXT( tr_peerIo * io, 549 int flag ) 550 { 551 assert( io ); 552 assert( flag == 0 || flag == 1 ); 553 536 554 io->fastPeersSupported = flag; 537 555 } … … 541 559 { 542 560 assert( io ); 543 561 544 562 return io->extendedProtocolSupported; 545 563 } … … 549 567 { 550 568 assert( io ); 551 569 552 570 return io->fastPeersSupported; 553 571 } … … 558 576 559 577 size_t 560 tr_peerIoGetBandwidthUsed( const tr_peerIo 561 tr_direction 562 { 563 assert( io ); 564 assert( direction ==TR_UP || direction==TR_DOWN );578 tr_peerIoGetBandwidthUsed( const tr_peerIo * io, 579 tr_direction direction ) 580 { 581 assert( io ); 582 assert( direction == TR_UP || direction == TR_DOWN ); 565 583 return io->bandwidth[direction].bytesUsed; 566 584 } 567 585 568 586 size_t 569 tr_peerIoGetBandwidthLeft( const tr_peerIo 570 tr_direction 571 { 572 assert( io ); 573 assert( direction ==TR_UP || direction==TR_DOWN );587 tr_peerIoGetBandwidthLeft( const tr_peerIo * io, 588 tr_direction direction ) 589 { 590 assert( io ); 591 assert( direction == TR_UP || direction == TR_DOWN ); 574 592 return io->bandwidth[direction].bytesLeft; 575 593 } … … 579 597 { 580 598 const size_t desiredBufferLen = 4096; 581 const size_t currentLiveLen = EVBUFFER_LENGTH( EVBUFFER_OUTPUT( io->bufev ) ); 599 const size_t currentLiveLen = 600 EVBUFFER_LENGTH( EVBUFFER_OUTPUT( io->bufev ) ); 582 601 583 602 const size_t desiredLiveLen = tr_peerIoGetBandwidthLeft( io, TR_UP ); … … 587 606 const size_t currentLen = currentLiveLen + currentLbufLen; 588 607 589 size_t freeSpace = 0;608 size_t freeSpace = 0; 590 609 591 610 if( desiredLen > currentLen ) … … 598 617 599 618 void 600 tr_peerIoSetBandwidth( tr_peerIo *io,601 tr_direction 602 size_t 619 tr_peerIoSetBandwidth( tr_peerIo * io, 620 tr_direction direction, 621 size_t bytesLeft ) 603 622 { 604 623 struct tr_bandwidth * b; 605 624 606 625 assert( io ); 607 assert( direction ==TR_UP || direction==TR_DOWN );608 609 b = io->bandwidth + direction; 626 assert( direction == TR_UP || direction == TR_DOWN ); 627 628 b = io->bandwidth + direction; 610 629 b->isUnlimited = 0; 611 630 b->bytesUsed = 0; … … 617 636 618 637 void 619 tr_peerIoSetBandwidthUnlimited( tr_peerIo *io,620 tr_direction 638 tr_peerIoSetBandwidthUnlimited( tr_peerIo * io, 639 tr_direction direction ) 621 640 { 622 641 struct tr_bandwidth * b; 623 642 624 643 assert( io ); 625 assert( direction ==TR_UP || direction==TR_DOWN );644 assert( direction == TR_UP || direction == TR_DOWN ); 626 645 627 646 b = io->bandwidth + direction; … … 646 665 } 647 666 648 649 /** 650 *** 651 **/ 652 653 tr_crypto* 667 /** 668 *** 669 **/ 670 671 tr_crypto* 654 672 tr_peerIoGetCrypto( tr_peerIo * c ) 655 673 { … … 657 675 } 658 676 659 void 677 void 660 678 tr_peerIoSetEncryption( tr_peerIo * io, 661 679 int encryptionMode ) 662 680 { 663 681 assert( io ); 664 assert( encryptionMode ==PEER_ENCRYPTION_NONE665 || encryptionMode==PEER_ENCRYPTION_RC4 );682 assert( encryptionMode == PEER_ENCRYPTION_NONE 683 || encryptionMode == PEER_ENCRYPTION_RC4 ); 666 684 667 685 io->encryptionMode = encryptionMode; … … 671 689 tr_peerIoIsEncrypted( const tr_peerIo * io ) 672 690 { 673 return io !=NULL && io->encryptionMode==PEER_ENCRYPTION_RC4;691 return io != NULL && io->encryptionMode == PEER_ENCRYPTION_RC4; 674 692 } 675 693 … … 679 697 680 698 int 681 tr_peerIoWantsBandwidth( const tr_peerIo * io, tr_direction direction ) 682 { 683 assert( direction==TR_UP || direction==TR_DOWN ); 699 tr_peerIoWantsBandwidth( const tr_peerIo * io, 700 tr_direction direction ) 701 { 702 assert( direction == TR_UP || direction == TR_DOWN ); 684 703 685 704 if( direction == TR_DOWN ) … … 690 709 { 691 710 return EVBUFFER_LENGTH( EVBUFFER_OUTPUT( io->bufev ) ) 692 || EVBUFFER_LENGTH( io->output );693 } 694 } 695 696 void 697 tr_peerIoWrite( tr_peerIo *io,698 const void 699 size_t 711 || EVBUFFER_LENGTH( io->output ); 712 } 713 } 714 715 void 716 tr_peerIoWrite( tr_peerIo * io, 717 const void * writeme, 718 size_t writemeLen ) 700 719 { 701 720 assert( tr_amInEventThread( io->session ) ); … … 711 730 712 731 void 713 tr_peerIoWriteBuf( tr_peerIo *io,732 tr_peerIoWriteBuf( tr_peerIo * io, 714 733 struct evbuffer * buf ) 715 734 { 716 735 const size_t n = EVBUFFER_LENGTH( buf ); 736 717 737 tr_peerIoWrite( io, EVBUFFER_DATA( buf ), n ); 718 738 evbuffer_drain( buf, n ); … … 724 744 725 745 void 726 tr_peerIoWriteBytes( tr_peerIo *io,727 struct evbuffer 728 const void *bytes,729 size_t 746 tr_peerIoWriteBytes( tr_peerIo * io, 747 struct evbuffer * outbuf, 748 const void * bytes, 749 size_t byteCount ) 730 750 { 731 751 uint8_t * tmp; … … 750 770 751 771 void 752 tr_peerIoWriteUint8( tr_peerIo *io,753 struct evbuffer 754 uint8_t 755 { 756 tr_peerIoWriteBytes( io, outbuf, &writeme, sizeof( uint8_t) );757 } 758 759 void 760 tr_peerIoWriteUint16( tr_peerIo *io,761 struct evbuffer 762 uint16_t 772 tr_peerIoWriteUint8( tr_peerIo * io, 773 struct evbuffer * outbuf, 774 uint8_t writeme ) 775 { 776 tr_peerIoWriteBytes( io, outbuf, &writeme, sizeof( uint8_t ) ); 777 } 778 779 void 780 tr_peerIoWriteUint16( tr_peerIo * io, 781 struct evbuffer * outbuf, 782 uint16_t writeme ) 763 783 { 764 784 uint16_t tmp = htons( writeme ); 765 tr_peerIoWriteBytes( io, outbuf, &tmp, sizeof(uint16_t) ); 766 } 767 768 void 769 tr_peerIoWriteUint32( tr_peerIo * io, 770 struct evbuffer * outbuf, 771 uint32_t writeme ) 785 786 tr_peerIoWriteBytes( io, outbuf, &tmp, sizeof( uint16_t ) ); 787 } 788 789 void 790 tr_peerIoWriteUint32( tr_peerIo * io, 791 struct evbuffer * outbuf, 792 uint32_t writeme ) 772 793 { 773 794 uint32_t tmp = htonl( writeme ); 774 tr_peerIoWriteBytes( io, outbuf, &tmp, sizeof(uint32_t) ); 795 796 tr_peerIoWriteBytes( io, outbuf, &tmp, sizeof( uint32_t ) ); 775 797 } 776 798 … … 780 802 781 803 void 782 tr_peerIoReadBytes( tr_peerIo *io,783 struct evbuffer 784 void *bytes,785 size_t 804 tr_peerIoReadBytes( tr_peerIo * io, 805 struct evbuffer * inbuf, 806 void * bytes, 807 size_t byteCount ) 786 808 { 787 809 assert( EVBUFFER_LENGTH( inbuf ) >= byteCount ); … … 804 826 805 827 void 806 tr_peerIoReadUint8( tr_peerIo *io,807 struct evbuffer 808 uint8_t *setme )809 { 810 tr_peerIoReadBytes( io, inbuf, setme, sizeof( uint8_t) );811 } 812 813 void 814 tr_peerIoReadUint16( tr_peerIo *io,815 struct evbuffer 816 uint16_t *setme )828 tr_peerIoReadUint8( tr_peerIo * io, 829 struct evbuffer * inbuf, 830 uint8_t * setme ) 831 { 832 tr_peerIoReadBytes( io, inbuf, setme, sizeof( uint8_t ) ); 833 } 834 835 void 836 tr_peerIoReadUint16( tr_peerIo * io, 837 struct evbuffer * inbuf, 838 uint16_t * setme ) 817 839 { 818 840 uint16_t tmp; 819 tr_peerIoReadBytes( io, inbuf, &tmp, sizeof(uint16_t) ); 841 842 tr_peerIoReadBytes( io, inbuf, &tmp, sizeof( uint16_t ) ); 820 843 *setme = ntohs( tmp ); 821 844 } 822 845 823 846 void 824 tr_peerIoReadUint32( tr_peerIo *io,825 struct evbuffer 826 uint32_t *setme )847 tr_peerIoReadUint32( tr_peerIo * io, 848 struct evbuffer * inbuf, 849 uint32_t * setme ) 827 850 { 828 851 uint32_t tmp; 829 tr_peerIoReadBytes( io, inbuf, &tmp, sizeof(uint32_t) ); 852 853 tr_peerIoReadBytes( io, inbuf, &tmp, sizeof( uint32_t ) ); 830 854 *setme = ntohl( tmp ); 831 855 } 832 856 833 857 void 834 tr_peerIoDrain( tr_peerIo *io,835 struct evbuffer 836 size_t 858 tr_peerIoDrain( tr_peerIo * io, 859 struct evbuffer * inbuf, 860 size_t byteCount ) 837 861 { 838 862 uint8_t * tmp = tr_new( uint8_t, byteCount ); 863 839 864 tr_peerIoReadBytes( io, inbuf, tmp, byteCount ); 840 865 tr_free( tmp ); … … 846 871 return time( NULL ) - io->timeCreated; 847 872 } 873
Note: See TracChangeset
for help on using the changeset viewer.