summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--opentracker.c91
-rw-r--r--trackerlogic.c15
-rw-r--r--trackerlogic.h4
3 files changed, 92 insertions, 18 deletions
diff --git a/opentracker.c b/opentracker.c
index 51a5b33..657f4f3 100644
--- a/opentracker.c
+++ b/opentracker.c
@@ -74,6 +74,12 @@ static void handle_timeouted( void );
74static void handle_accept( const int64 serversocket ); 74static void handle_accept( const int64 serversocket );
75static void handle_read( const int64 clientsocket ); 75static void handle_read( const int64 clientsocket );
76static void handle_write( const int64 clientsocket ); 76static void handle_write( const int64 clientsocket );
77static void handle_udp4( const int64 serversocket );
78
79static void ot_try_bind_udp4( char ip[4], uint16 port );
80static void ot_try_bind_tcp4( char ip[4], uint16 port );
81static int ot_in_udp4_sockets( int64 fd );
82static int ot_in_tcp4_sockets( int64 fd );
77 83
78static void usage( char *name ); 84static void usage( char *name );
79static void help( char *name ); 85static void help( char *name );
@@ -381,7 +387,7 @@ ANNOUNCE_WORKAROUND:
381 reply_size = sprintf( static_outbuf + SUCCESS_HTTP_HEADER_LENGTH, "d8:completei0e10:incompletei0e8:intervali%ie5:peers0:e", OT_CLIENT_REQUEST_INTERVAL_RANDOM ); 387 reply_size = sprintf( static_outbuf + SUCCESS_HTTP_HEADER_LENGTH, "d8:completei0e10:incompletei0e8:intervali%ie5:peers0:e", OT_CLIENT_REQUEST_INTERVAL_RANDOM );
382 } else { 388 } else {
383 torrent = add_peer_to_torrent( hash, &peer ); 389 torrent = add_peer_to_torrent( hash, &peer );
384 if( !torrent || !( reply_size = return_peers_for_torrent( torrent, numwant, SUCCESS_HTTP_HEADER_LENGTH + static_outbuf ) ) ) HTTPERROR_500; 390 if( !torrent || !( reply_size = return_peers_for_torrent( torrent, numwant, SUCCESS_HTTP_HEADER_LENGTH + static_outbuf, 1 ) ) ) HTTPERROR_500;
385 } 391 }
386 ot_overall_successfulannounces++; 392 ot_overall_successfulannounces++;
387 break; 393 break;
@@ -555,17 +561,76 @@ static void handle_timeouted( void ) {
555 } 561 }
556} 562}
557 563
558void handle_udp4( int64 serversocket ) { 564static void handle_udp4( int64 serversocket ) {
559 size_t r; 565 ot_peer peer;
560 char remoteip[4]; 566 ot_torrent *torrent;
561 uint16 port; 567 ot_hash *hash = NULL;
562 568 char remoteip[4];
563 r = socket_recv4(serversocket, static_inbuf, 8192, remoteip, &port); 569 unsigned long *inpacket = (unsigned long*)static_inbuf;
570 unsigned long *outpacket = (unsigned long*)static_outbuf;
571 unsigned long numwant, left, event;
572 uint16 port;
573 size_t r;
574
575 r = socket_recv4( serversocket, static_inbuf, 8192, remoteip, &port);
576
577 /* Minimum udp tracker packet size, also catches error */
578 if( r < 16 )
579 return;
564 580
565 // too lazy :) 581 switch( ntohl( inpacket[2] ) ) {
582 case 0: /* This is a connect action */
583 outpacket[0] = 0; outpacket[1] = inpacket[3];
584 outpacket[2] = inpacket[0]; outpacket[3] = inpacket[1];
585 socket_send4( serversocket, static_outbuf, 16, remoteip, port );
586 break;
587 case 1: /* This is an announce action */
588 /* Minimum udp announce packet size */
589 if( r < 98 )
590 return;
591
592 numwant = 200;
593 left = ntohl( inpacket[64/4] );
594 event = ntohl( inpacket[80/4] );
595 port = ntohl( inpacket[96/4] );
596 hash = (ot_hash*)inpacket+(16/4);
597
598 OT_SETIP( &peer, remoteip );
599 OT_SETPORT( &peer, &port );
600 OT_FLAG( &peer ) = 0;
601
602 switch( event ) {
603 case 1: OT_FLAG( &peer ) |= PEER_FLAG_COMPLETED; break;
604 case 3: OT_FLAG( &peer ) |= PEER_FLAG_STOPPED; break;
605 default: break;
606 }
607 if( !left )
608 OT_FLAG( &peer ) |= PEER_FLAG_SEEDING;
609
610 if( OT_FLAG( &peer ) & PEER_FLAG_STOPPED ) {
611 /* Peer is gone. */
612 remove_peer_from_torrent( hash, &peer );
613
614 /* Create fake packet to satisfy parser on the other end */
615 outpacket[0] = htonl( 1 );
616 outpacket[1] = inpacket[12/4];
617 outpacket[2] = outpacket[3] = outpacket[4] = 0;
618 socket_send4( serversocket, static_outbuf, 20, remoteip, port );
619 } else {
620 torrent = add_peer_to_torrent( hash, &peer );
621 if( !torrent )
622 return; /* XXX maybe send error */
623
624 outpacket[0] = htonl( 1 );
625 outpacket[1] = inpacket[12/4];
626 r = 8 + return_peers_for_torrent( torrent, numwant, static_outbuf + 8, 0 );
627 socket_send4( serversocket, static_outbuf, r, remoteip, port );
628 }
629 break;
630 }
566} 631}
567 632
568int ot_in_tcp4_sockets( int64 fd ) { 633static int ot_in_tcp4_sockets( int64 fd ) {
569 int i; 634 int i;
570 for( i=0; i<ot_sockets_tcp4_count; ++i) 635 for( i=0; i<ot_sockets_tcp4_count; ++i)
571 if( ot_sockets_tcp4[i] == fd ) 636 if( ot_sockets_tcp4[i] == fd )
@@ -573,7 +638,7 @@ int ot_in_tcp4_sockets( int64 fd ) {
573 return 0; 638 return 0;
574} 639}
575 640
576int ot_in_udp4_sockets( int64 fd ) { 641static int ot_in_udp4_sockets( int64 fd ) {
577 int i; 642 int i;
578 for( i=0; i<ot_sockets_udp4_count; ++i) 643 for( i=0; i<ot_sockets_udp4_count; ++i)
579 if( ot_sockets_udp4[i] == fd ) 644 if( ot_sockets_udp4[i] == fd )
@@ -614,7 +679,7 @@ static void server_mainloop( ) {
614 } 679 }
615} 680}
616 681
617void ot_try_bind_tcp4( char ip[4], uint16 port ) { 682static void ot_try_bind_tcp4( char ip[4], uint16 port ) {
618 int64 s = socket_tcp4( ); 683 int64 s = socket_tcp4( );
619 if( ot_sockets_tcp4_count == OT_MAXSOCKETS_TCP4 ) { 684 if( ot_sockets_tcp4_count == OT_MAXSOCKETS_TCP4 ) {
620 fprintf( stderr, "Too many tcp4 sockets, increase OT_MAXSOCKETS_TCP4 and recompile.\n"); exit(1); 685 fprintf( stderr, "Too many tcp4 sockets, increase OT_MAXSOCKETS_TCP4 and recompile.\n"); exit(1);
@@ -633,7 +698,7 @@ void ot_try_bind_tcp4( char ip[4], uint16 port ) {
633 ot_sockets_tcp4[ ot_sockets_tcp4_count++ ] = s; 698 ot_sockets_tcp4[ ot_sockets_tcp4_count++ ] = s;
634} 699}
635 700
636void ot_try_bind_udp4( char ip[4], uint16 port ) { 701static void ot_try_bind_udp4( char ip[4], uint16 port ) {
637 int64 s = socket_udp4( ); 702 int64 s = socket_udp4( );
638 if( ot_sockets_udp4_count == OT_MAXSOCKETS_UDP4 ) { 703 if( ot_sockets_udp4_count == OT_MAXSOCKETS_UDP4 ) {
639 fprintf( stderr, "Too many udp4 sockets, increase OT_MAXSOCKETS_UDP4 and recompile.\n"); exit(1); 704 fprintf( stderr, "Too many udp4 sockets, increase OT_MAXSOCKETS_UDP4 and recompile.\n"); exit(1);
@@ -655,7 +720,7 @@ int main( int argc, char **argv ) {
655 int scanon = 1; 720 int scanon = 1;
656 721
657 while( scanon ) { 722 while( scanon ) {
658 switch( getopt( argc, argv, ":i:p:d:ocbBh" ) ) { 723 switch( getopt( argc, argv, ":i:p:P:d:ocbBh" ) ) {
659 case -1 : scanon = 0; break; 724 case -1 : scanon = 0; break;
660 case 'i': scan_ip4( optarg, serverip ); break; 725 case 'i': scan_ip4( optarg, serverip ); break;
661 case 'p': ot_try_bind_tcp4( serverip, (uint16)atol( optarg ) ); break; 726 case 'p': ot_try_bind_tcp4( serverip, (uint16)atol( optarg ) ); break;
diff --git a/trackerlogic.c b/trackerlogic.c
index 18e8cf5..a2cd1ab 100644
--- a/trackerlogic.c
+++ b/trackerlogic.c
@@ -269,7 +269,7 @@ ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer ) {
269 * RANDOM may return huge values 269 * RANDOM may return huge values
270 * does not yet check not to return self 270 * does not yet check not to return self
271*/ 271*/
272size_t return_peers_for_torrent( ot_torrent *torrent, size_t amount, char *reply ) { 272size_t return_peers_for_torrent( ot_torrent *torrent, size_t amount, char *reply, int is_tcp ) {
273 char *r = reply; 273 char *r = reply;
274 size_t peer_count, seed_count, index; 274 size_t peer_count, seed_count, index;
275 275
@@ -295,7 +295,15 @@ size_t return_peers_for_torrent( ot_torrent *torrent, size_t amount, char *reply
295 } 295 }
296 if( peer_count < amount ) amount = peer_count; 296 if( peer_count < amount ) amount = peer_count;
297 297
298 r += sprintf( r, "d8:completei%zde10:incompletei%zde8:intervali%ie5:peers%zd:", seed_count, peer_count-seed_count, OT_CLIENT_REQUEST_INTERVAL_RANDOM, 6*amount ); 298 if( is_tcp )
299 r += sprintf( r, "d8:completei%zde10:incompletei%zde8:intervali%ie5:peers%zd:", seed_count, peer_count-seed_count, OT_CLIENT_REQUEST_INTERVAL_RANDOM, 6*amount );
300 else {
301 *(unsigned long*)(r+0) = htonl( OT_CLIENT_REQUEST_INTERVAL_RANDOM );
302 *(unsigned long*)(r+4) = htonl( peer_count );
303 *(unsigned long*)(r+8) = htonl( seed_count );
304 r += 12;
305 }
306
299 if( amount ) { 307 if( amount ) {
300 unsigned int pool_offset, pool_index = 0;; 308 unsigned int pool_offset, pool_index = 0;;
301 unsigned int shifted_pc = peer_count; 309 unsigned int shifted_pc = peer_count;
@@ -327,7 +335,8 @@ size_t return_peers_for_torrent( ot_torrent *torrent, size_t amount, char *reply
327 r += 6; 335 r += 6;
328 } 336 }
329 } 337 }
330 *r++ = 'e'; 338 if( is_tcp )
339 *r++ = 'e';
331 340
332 return r - reply; 341 return r - reply;
333} 342}
diff --git a/trackerlogic.h b/trackerlogic.h
index 5c83f63..360dacb 100644
--- a/trackerlogic.h
+++ b/trackerlogic.h
@@ -94,12 +94,12 @@ extern int g_check_blacklist;
94enum { STATS_MRTG, STATS_TOP5, STATS_DMEM }; 94enum { STATS_MRTG, STATS_TOP5, STATS_DMEM };
95 95
96ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer ); 96ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer );
97size_t return_peers_for_torrent( ot_torrent *torrent, size_t amount, char *reply ); 97size_t return_peers_for_torrent( ot_torrent *torrent, size_t amount, char *reply, int is_tcp );
98size_t return_fullscrape_for_tracker( char **reply ); 98size_t return_fullscrape_for_tracker( char **reply );
99size_t return_scrape_for_torrent( ot_hash *hash, char *reply ); 99size_t return_scrape_for_torrent( ot_hash *hash, char *reply );
100size_t return_sync_for_torrent( ot_hash *hash, char **reply ); 100size_t return_sync_for_torrent( ot_hash *hash, char **reply );
101size_t return_stats_for_tracker( char *reply, int mode ); 101size_t return_stats_for_tracker( char *reply, int mode );
102size_t return_memstat_for_tracker( char **reply ); 102size_t return_memstat_for_tracker( char **reply );
103void remove_peer_from_torrent( ot_hash *hash, ot_peer *peer ); 103void remove_peer_from_torrent( ot_hash *hash, ot_peer *peer );
104 104
105#endif 105#endif