Changeset 26
- Timestamp:
- Jan 12, 2006, 7:12:58 PM (16 years ago)
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Jamrules
r19 r26 9 9 VERSION_MINOR = 4 ; 10 10 # VERSION_STRING = $(VERSION_MAJOR).$(VERSION_MINOR) ; 11 VERSION_STRING = CVS-20051221;11 VERSION_STRING = 0.5-cvs ; 12 12 13 13 DEFINES += VERSION_MAJOR=$(VERSION_MAJOR) -
trunk/libtransmission/internal.h
r20 r26 90 90 #include "metainfo.h" 91 91 #include "tracker.h" 92 #include "fdlimit.h" 92 93 #include "peer.h" 93 94 #include "net.h" 94 95 #include "inout.h" 95 96 #include "upload.h" 96 #include "fdlimit.h"97 97 #include "clients.h" 98 98 … … 141 141 uint64_t stopDate; 142 142 143 int bindSocket;144 int bindPort;145 143 int peerCount; 146 144 tr_peer_t * peers[TR_MAX_PEER_COUNT]; … … 163 161 164 162 int bindPort; 163 int bindSocket; 164 165 int acceptPeerCount; 166 tr_peer_t * acceptPeers[TR_MAX_PEER_COUNT]; 165 167 166 168 char id[21]; 167 169 char key[21]; 170 171 volatile char acceptDie; 172 tr_thread_t acceptThread; 173 tr_lock_t acceptLock; 168 174 }; 169 175 -
trunk/libtransmission/net.c
r1 r26 107 107 } 108 108 109 int tr_netBind( int *port )110 { 111 int s , i;109 int tr_netBind( int port ) 110 { 111 int s; 112 112 struct sockaddr_in sock; 113 int minPort, maxPort; 113 #ifdef SO_REUSEADDR 114 int optval; 115 #endif 114 116 115 117 s = createSocket(); … … 119 121 } 120 122 121 minPort = *port; 122 maxPort = minPort + 1000; 123 maxPort = MIN( maxPort, 65535 ); 124 125 for( i = minPort; i <= maxPort; i++ ) 126 { 127 memset( &sock, 0, sizeof( sock ) ); 128 sock.sin_family = AF_INET; 129 sock.sin_addr.s_addr = INADDR_ANY; 130 sock.sin_port = htons( i ); 131 132 if( !bind( s, (struct sockaddr *) &sock, 133 sizeof( struct sockaddr_in ) ) ) 134 { 135 break; 136 } 137 } 138 139 if( i > maxPort ) 140 { 123 #ifdef SO_REUSEADDR 124 optval = 1; 125 setsockopt( s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof( optval ) ); 126 #endif 127 128 memset( &sock, 0, sizeof( sock ) ); 129 sock.sin_family = AF_INET; 130 sock.sin_addr.s_addr = INADDR_ANY; 131 sock.sin_port = htons( port ); 132 133 if( bind( s, (struct sockaddr *) &sock, 134 sizeof( struct sockaddr_in ) ) ) 135 { 136 tr_err( "Could not bind port %d", port ); 141 137 tr_netClose( s ); 142 tr_err( "Could not bind any port from %d to %d",143 minPort, maxPort );144 138 return -1; 145 139 } 146 140 147 tr_inf( "Binded port %d", i ); 148 *port = i; 141 tr_inf( "Binded port %d", port ); 149 142 listen( s, 5 ); 150 143 -
trunk/libtransmission/net.h
r1 r26 23 23 int tr_netResolve ( char *, struct in_addr * ); 24 24 int tr_netOpen ( struct in_addr addr, in_port_t port ); 25 int tr_netBind ( int *);25 int tr_netBind ( int ); 26 26 int tr_netAccept ( int s, struct in_addr *, in_port_t * ); 27 27 void tr_netClose ( int s ); -
trunk/libtransmission/peer.c
r3 r26 124 124 * tr_peerAddCompact 125 125 *********************************************************************** 126 * Tries to add a peer. If 's' is a negative value, will use 'addr' and 127 * 'port' to connect to the peer. Otherwise, use the already connected 128 * socket 's'. 126 * Tries to add a peer, using 'addr' and 'port' to connect to the peer. 129 127 **********************************************************************/ 130 128 void tr_peerAddCompact( tr_torrent_t * tor, struct in_addr addr, 131 in_port_t port, int s ) 132 { 133 tr_peer_t * peer; 134 135 if( s < 0 ) 136 { 137 addWithAddr( tor, addr, port ); 138 return; 139 } 140 141 if( !( peer = peerInit( tor ) ) ) 142 { 143 tr_netClose( s ); 144 tr_fdSocketClosed( tor->fdlimit, 0 ); 145 return; 146 } 129 in_port_t port ) 130 { 131 addWithAddr( tor, addr, port ); 132 } 133 134 /*********************************************************************** 135 * tr_peerInit 136 *********************************************************************** 137 * Initializes a new peer. 138 **********************************************************************/ 139 tr_peer_t * tr_peerInit( struct in_addr addr, in_port_t port, int s ) 140 { 141 tr_peer_t * peer = peerInit(); 147 142 148 143 peer->socket = s; … … 150 145 peer->port = port; 151 146 peer->status = PEER_STATUS_CONNECTING; 147 148 return peer; 149 } 150 151 void tr_peerAttach( tr_torrent_t * tor, tr_peer_t * peer ) 152 { 153 peerAttach( tor, peer ); 154 } 155 156 void tr_peerDestroy( tr_fd_t * fdlimit, tr_peer_t * peer ) 157 { 158 if( peer->bitfield ) 159 { 160 free( peer->bitfield ); 161 } 162 if( peer->buf ) 163 { 164 free( peer->buf ); 165 } 166 if( peer->outMessages ) 167 { 168 free( peer->outMessages ); 169 } 170 if( peer->status > PEER_STATUS_IDLE ) 171 { 172 tr_netClose( peer->socket ); 173 tr_fdSocketClosed( fdlimit, 0 ); 174 } 175 free( peer ); 152 176 } 153 177 … … 176 200 tr_uploadChoked( tor->upload ); 177 201 } 178 if( peer->bitfield ) 179 { 180 free( peer->bitfield ); 181 } 182 if( peer->buf ) 183 { 184 free( peer->buf ); 185 } 186 if( peer->outMessages ) 187 { 188 free( peer->outMessages ); 189 } 190 if( peer->status > PEER_STATUS_IDLE ) 191 { 192 tr_netClose( peer->socket ); 193 tr_fdSocketClosed( tor->fdlimit, 0 ); 194 } 195 free( peer ); 202 tr_peerDestroy( tor->fdlimit, peer ); 196 203 tor->peerCount--; 197 204 memmove( &tor->peers[i], &tor->peers[i+1], 198 205 ( tor->peerCount - i ) * sizeof( tr_peer_t * ) ); 206 } 207 208 /*********************************************************************** 209 * tr_peerRead 210 *********************************************************************** 211 * 212 **********************************************************************/ 213 int tr_peerRead( tr_torrent_t * tor, tr_peer_t * peer ) 214 { 215 int ret; 216 217 /* Try to read */ 218 for( ;; ) 219 { 220 if( peer->size < 1 ) 221 { 222 peer->size = 1024; 223 peer->buf = malloc( peer->size ); 224 } 225 else if( peer->pos >= peer->size ) 226 { 227 peer->size *= 2; 228 peer->buf = realloc( peer->buf, peer->size ); 229 } 230 ret = tr_netRecv( peer->socket, &peer->buf[peer->pos], 231 peer->size - peer->pos ); 232 if( ret & TR_NET_CLOSE ) 233 { 234 peer_dbg( "connection closed" ); 235 return 1; 236 } 237 else if( ret & TR_NET_BLOCK ) 238 { 239 break; 240 } 241 peer->date = tr_date(); 242 peer->pos += ret; 243 if( NULL != tor ) 244 { 245 if( parseBuf( tor, peer, ret ) ) 246 { 247 return 1; 248 } 249 } 250 else 251 { 252 if( parseBufHeader( peer ) ) 253 { 254 return 1; 255 } 256 } 257 } 258 259 return 0; 260 } 261 262 /*********************************************************************** 263 * tr_peerHash 264 *********************************************************************** 265 * 266 **********************************************************************/ 267 uint8_t * tr_peerHash( tr_peer_t * peer ) 268 { 269 return parseBufHash( peer ); 199 270 } 200 271 … … 235 306 return; 236 307 } 237 238 /* Check for incoming connections */239 if( tor->bindSocket > -1 &&240 tor->peerCount < TR_MAX_PEER_COUNT &&241 !tr_fdSocketWillCreate( tor->fdlimit, 0 ) )242 {243 int s;244 struct in_addr addr;245 in_port_t port;246 s = tr_netAccept( tor->bindSocket, &addr, &port );247 if( s > -1 )248 {249 tr_peerAddCompact( tor, addr, port, s );250 }251 else252 {253 tr_fdSocketClosed( tor->fdlimit, 0 );254 }255 }256 308 257 309 /* Shuffle peers */ … … 275 327 } 276 328 277 /* Try to read */ 278 for( ;; ) 279 { 280 if( peer->size < 1 ) 281 { 282 peer->size = 1024; 283 peer->buf = malloc( peer->size ); 284 } 285 else if( peer->pos >= peer->size ) 286 { 287 peer->size *= 2; 288 peer->buf = realloc( peer->buf, peer->size ); 289 } 290 ret = tr_netRecv( peer->socket, &peer->buf[peer->pos], 291 peer->size - peer->pos ); 292 if( ret & TR_NET_CLOSE ) 293 { 294 peer_dbg( "connection closed" ); 295 goto dropPeer; 296 } 297 else if( ret & TR_NET_BLOCK ) 298 { 299 break; 300 } 301 peer->date = tr_date(); 302 peer->pos += ret; 303 if( parseBuf( tor, peer, ret ) ) 304 { 305 goto dropPeer; 306 } 329 if( tr_peerRead( tor, tor->peers[i] ) ) 330 { 331 goto dropPeer; 307 332 } 308 333 -
trunk/libtransmission/peer.h
r1 r26 27 27 28 28 void tr_peerAddOld ( tr_torrent_t *, char *, int ); 29 void tr_peerAddCompact ( tr_torrent_t *, struct in_addr, 30 in_port_t, int ); 29 void tr_peerAddCompact ( tr_torrent_t *, struct in_addr, in_port_t ); 30 tr_peer_t * tr_peerInit ( struct in_addr, in_port_t, int ); 31 void tr_peerAttach ( tr_torrent_t *, tr_peer_t * ); 32 void tr_peerDestroy ( tr_fd_t *, tr_peer_t * ); 31 33 void tr_peerRem ( tr_torrent_t *, int ); 34 int tr_peerRead ( tr_torrent_t *, tr_peer_t * ); 35 uint8_t * tr_peerHash ( tr_peer_t * ); 32 36 void tr_peerPulse ( tr_torrent_t * ); 33 37 int tr_peerIsConnected ( tr_peer_t * ); -
trunk/libtransmission/peerparse.h
r3 r26 397 397 } 398 398 399 static inline int parseBufHeader( tr_peer_t * peer ) 400 { 401 uint8_t * p = peer->buf; 402 403 if( 4 > peer->pos ) 404 { 405 return 0; 406 } 407 408 if( p[0] != 19 || memcmp( &p[1], "Bit", 3 ) ) 409 { 410 /* Don't wait until we get 68 bytes, this is wrong 411 already */ 412 peer_dbg( "GET handshake, invalid" ); 413 tr_netSend( peer->socket, (uint8_t *) "Nice try...\r\n", 13 ); 414 return 1; 415 } 416 if( peer->pos < 68 ) 417 { 418 return 0; 419 } 420 if( memcmp( &p[4], "Torrent protocol", 16 ) ) 421 { 422 peer_dbg( "GET handshake, invalid" ); 423 return 1; 424 } 425 426 return 0; 427 } 428 429 static uint8_t * parseBufHash( tr_peer_t * peer ) 430 { 431 if( 48 > peer->pos ) 432 { 433 return NULL; 434 } 435 else 436 { 437 return peer->buf + 28; 438 } 439 } 440 399 441 static inline int parseBuf( tr_torrent_t * tor, tr_peer_t * peer, 400 442 int newBytes ) … … 413 455 char * client; 414 456 415 if( p[0] != 19 || memcmp( &p[1], "Bit", 3 ) ) 416 { 417 /* Don't wait until we get 68 bytes, this is wrong 418 already */ 419 peer_dbg( "GET handshake, invalid" ); 420 tr_netSend( peer->socket, (uint8_t *) "Nice try...\r\n", 13 ); 421 return 1; 422 } 423 424 if( peer->pos < 68 ) 425 { 426 break; 427 } 428 429 if( memcmp( &p[4], "Torrent protocol", 16 ) ) 430 { 431 peer_dbg( "GET handshake, invalid" ); 457 if( parseBufHeader( peer ) ) 458 { 432 459 return 1; 433 460 } -
trunk/libtransmission/peerutils.h
r3 r26 26 26 * peerInit 27 27 *********************************************************************** 28 * Returns NULL if we reached the maximum authorized number of peers. 29 * Otherwise, allocates a new tr_peer_t, add it to the peers list and 30 * returns a pointer to it. 28 * Allocates a new tr_peer_t and returns a pointer to it. 31 29 **********************************************************************/ 32 static tr_peer_t * peerInit( tr_torrent_t * tor)30 static tr_peer_t * peerInit() 33 31 { 34 32 tr_peer_t * peer; 35 36 if( tor->peerCount >= TR_MAX_PEER_COUNT )37 {38 return NULL;39 }40 33 41 34 peer = calloc( sizeof( tr_peer_t ), 1 ); … … 45 38 peer->keepAlive = peer->date; 46 39 40 return peer; 41 } 42 43 /*********************************************************************** 44 * peerAttach 45 *********************************************************************** 46 * Deallocates the tr_peer_t and returns 0 if we reached the maximum 47 * authorized number of peers. Otherwise, adds the tr_peer_t to the 48 * peers list. 49 **********************************************************************/ 50 static int peerAttach( tr_torrent_t * tor, tr_peer_t * peer ) 51 { 52 if( tor->peerCount >= TR_MAX_PEER_COUNT ) 53 { 54 tr_peerDestroy( tor->fdlimit, peer ); 55 return 0; 56 } 57 47 58 tor->peers[tor->peerCount++] = peer; 48 return peer;59 return 1; 49 60 } 50 61 … … 84 95 } 85 96 86 if( !( peer = peerInit( tor ) ) ) 97 peer = peerInit(); 98 if( !peerAttach( tor, peer ) ) 87 99 { 88 100 return; -
trunk/libtransmission/tracker.c
r20 r26 50 50 int size; 51 51 int pos; 52 53 int bindPort; 52 54 }; 53 55 … … 72 74 tc->buf = malloc( tc->size ); 73 75 76 tc->bindPort = h->bindPort; 77 74 78 return tc; 75 79 } … … 116 120 117 121 return 0; 122 } 123 124 void tr_trackerChangePort( tr_tracker_t * tc, int port ) 125 { 126 /* XXX this doesn't always work, should send stopped then started events */ 127 tc->bindPort = port; 118 128 } 119 129 … … 265 275 "Connection: close\r\n\r\n", 266 276 inf->trackerAnnounce, tor->hashString, tc->id, 267 t or->bindPort, tor->uploaded[9], tor->downloaded[9],277 tc->bindPort, tor->uploaded[9], tor->downloaded[9], 268 278 left, tor->key, event, inf->trackerAddress, 269 279 VERSION_MAJOR, VERSION_MINOR ); … … 451 461 memcpy( &port, &bePeers->val.s.s[6*i+4], 2 ); 452 462 453 tr_peerAddCompact( tor, addr, port , -1);463 tr_peerAddCompact( tor, addr, port ); 454 464 } 455 465 -
trunk/libtransmission/tracker.h
r6 r26 27 27 28 28 tr_tracker_t * tr_trackerInit ( tr_handle_t *, tr_torrent_t * ); 29 void tr_trackerChangePort( tr_tracker_t *, int ); 29 30 int tr_trackerPulse ( tr_tracker_t * ); 30 31 void tr_trackerCompleted ( tr_tracker_t * ); -
trunk/libtransmission/transmission.c
r23 r26 30 30 static float rateDownload( tr_torrent_t * ); 31 31 static float rateUpload( tr_torrent_t * ); 32 static void acceptLoop( void * ); 33 static void acceptStop( tr_handle_t * h ); 32 34 33 35 /*********************************************************************** … … 68 70 69 71 h->bindPort = TR_DEFAULT_PORT; 72 h->bindSocket = -1; 73 74 #ifndef BEOS_NETSERVER 75 /* BeOS net_server seems to be unable to set incoming connections to 76 non-blocking. Too bad. */ 77 if( !tr_fdSocketWillCreate( h->fdlimit, 0 ) ) 78 { 79 /* XXX should handle failure here in a better way */ 80 h->bindSocket = tr_netBind( h->bindPort ); 81 } 82 #endif 83 84 85 h->acceptDie = 0; 86 tr_lockInit( &h->acceptLock ); 87 tr_threadCreate( &h->acceptThread, acceptLoop, h ); 70 88 71 89 return h; … … 79 97 void tr_setBindPort( tr_handle_t * h, int port ) 80 98 { 81 /* FIXME multithread safety */ 99 int ii, sock; 100 101 if( h->bindPort == port ) 102 return; 103 104 #ifndef BEOS_NETSERVER 105 /* BeOS net_server seems to be unable to set incoming connections to 106 non-blocking. Too bad. */ 107 if( !tr_fdSocketWillCreate( h->fdlimit, 0 ) ) 108 { 109 /* XXX should handle failure here in a better way */ 110 sock = tr_netBind( port ); 111 } 112 #else 113 return; 114 #endif 115 116 tr_lockLock( &h->acceptLock ); 117 82 118 h->bindPort = port; 119 120 for( ii = 0; ii < h->torrentCount; ii++ ) 121 { 122 tr_lockLock( &h->torrents[ii]->lock ); 123 if( NULL != h->torrents[ii]->tracker ) 124 { 125 tr_trackerChangePort( h->torrents[ii]->tracker, port ); 126 } 127 tr_lockUnlock( &h->torrents[ii]->lock ); 128 } 129 130 if( h->bindSocket > -1 ) 131 { 132 tr_netClose( h->bindSocket ); 133 tr_fdSocketClosed( h->fdlimit, 0 ); 134 } 135 136 h->bindSocket = sock; 137 138 tr_lockUnlock( &h->acceptLock ); 83 139 } 84 140 … … 197 253 198 254 /* We have a new torrent */ 255 tr_lockLock( &h->acceptLock ); 199 256 h->torrents[h->torrentCount] = tor; 200 257 (h->torrentCount)++; 258 tr_lockUnlock( &h->acceptLock ); 201 259 202 260 return 0; … … 242 300 tor->status = TR_STATUS_CHECK; 243 301 tor->tracker = tr_trackerInit( h, tor ); 244 tor->bindPort = h->bindPort;245 #ifndef BEOS_NETSERVER246 /* BeOS net_server seems to be unable to set incoming connections to247 non-blocking. Too bad. */248 if( !tr_fdSocketWillCreate( h->fdlimit, 0 ) )249 {250 tor->bindSocket = tr_netBind( &tor->bindPort );251 }252 #endif253 302 254 303 now = tr_date(); … … 291 340 { 292 341 tr_peerRem( tor, 0 ); 293 }294 if( tor->bindSocket > -1 )295 {296 tr_netClose( tor->bindSocket );297 tr_fdSocketClosed( h->fdlimit, 0 );298 342 } 299 343 … … 446 490 } 447 491 492 tr_lockLock( &h->acceptLock ); 493 448 494 h->torrentCount--; 449 495 … … 461 507 memmove( &h->torrents[t], &h->torrents[t+1], 462 508 ( h->torrentCount - t ) * sizeof( void * ) ); 509 510 tr_lockUnlock( &h->acceptLock ); 463 511 } 464 512 465 513 void tr_close( tr_handle_t * h ) 466 514 { 515 acceptStop( h ); 467 516 tr_fdClose( h->fdlimit ); 468 517 tr_uploadClose( h->upload ); … … 568 617 return rateGeneric( tor->dates, tor->uploaded ); 569 618 } 619 620 /*********************************************************************** 621 * acceptLoop 622 **********************************************************************/ 623 static void acceptLoop( void * _h ) 624 { 625 tr_handle_t * h = _h; 626 uint64_t date1, date2; 627 int ii, jj; 628 uint8_t * hash; 629 630 tr_dbg( "Accept thread started" ); 631 632 #ifdef SYS_BEOS 633 /* This is required because on BeOS, SIGINT is sent to each thread, 634 which kills them not nicely */ 635 signal( SIGINT, SIG_IGN ); 636 #endif 637 638 tr_lockLock( &h->acceptLock ); 639 640 while( !h->acceptDie ) 641 { 642 date1 = tr_date(); 643 644 /* Check for incoming connections */ 645 if( h->bindSocket > -1 && 646 h->acceptPeerCount < TR_MAX_PEER_COUNT && 647 !tr_fdSocketWillCreate( h->fdlimit, 0 ) ) 648 { 649 int s; 650 struct in_addr addr; 651 in_port_t port; 652 s = tr_netAccept( h->bindSocket, &addr, &port ); 653 if( s > -1 ) 654 { 655 h->acceptPeers[h->acceptPeerCount++] = tr_peerInit( addr, port, s ); 656 } 657 else 658 { 659 tr_fdSocketClosed( h->fdlimit, 0 ); 660 } 661 } 662 663 for( ii = 0; ii < h->acceptPeerCount; ) 664 { 665 if( tr_peerRead( NULL, h->acceptPeers[ii] ) ) 666 { 667 tr_peerDestroy( h->fdlimit, h->acceptPeers[ii] ); 668 goto removePeer; 669 } 670 if( NULL != ( hash = tr_peerHash( h->acceptPeers[ii] ) ) ) 671 { 672 for( jj = 0; jj < h->torrentCount; jj++ ) 673 { 674 tr_lockLock( &h->torrents[jj]->lock ); 675 if( 0 == memcmp( h->torrents[jj]->info.hash, hash, 676 SHA_DIGEST_LENGTH ) ) 677 { 678 tr_peerAttach( h->torrents[jj], h->acceptPeers[ii] ); 679 tr_lockUnlock( &h->torrents[jj]->lock ); 680 goto removePeer; 681 } 682 tr_lockUnlock( &h->torrents[jj]->lock ); 683 } 684 tr_peerDestroy( h->fdlimit, h->acceptPeers[ii] ); 685 goto removePeer; 686 } 687 ii++; 688 continue; 689 removePeer: 690 h->acceptPeerCount--; 691 memmove( &h->acceptPeers[ii], &h->acceptPeers[ii+1], 692 ( h->acceptPeerCount - ii ) * sizeof( tr_peer_t * ) ); 693 } 694 695 /* Wait up to 20 ms */ 696 date2 = tr_date(); 697 if( date2 < date1 + 20 ) 698 { 699 tr_lockUnlock( &h->acceptLock ); 700 tr_wait( date1 + 20 - date2 ); 701 tr_lockLock( &h->acceptLock ); 702 } 703 } 704 705 tr_lockUnlock( &h->acceptLock ); 706 707 tr_dbg( "Accept thread exited" ); 708 } 709 710 /*********************************************************************** 711 * acceptStop 712 *********************************************************************** 713 * Joins the accept thread and frees/closes everything related to it. 714 **********************************************************************/ 715 static void acceptStop( tr_handle_t * h ) 716 { 717 int ii; 718 719 h->acceptDie = 1; 720 tr_threadJoin( &h->acceptThread ); 721 tr_lockClose( &h->acceptLock ); 722 tr_dbg( "Accept thread joined" ); 723 724 for( ii = 0; ii < h->acceptPeerCount; ii++ ) 725 { 726 tr_peerDestroy( h->fdlimit, h->acceptPeers[ii] ); 727 } 728 729 if( h->bindSocket > -1 ) 730 { 731 tr_netClose( h->bindSocket ); 732 tr_fdSocketClosed( h->fdlimit, 0 ); 733 } 734 }
Note: See TracChangeset
for help on using the changeset viewer.