summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorerdgeist <>2007-10-29 17:22:05 +0000
committererdgeist <>2007-10-29 17:22:05 +0000
commit31eada6168f9c2433b0b7cd3ef21861f76d21784 (patch)
tree884b0ed46a45a163b389ccbd4823b910eaf6ef5e
parentb19bbd6a850ecd51180dfea6e025a032fb2f1fe1 (diff)
Reenabled syncing
-rw-r--r--opentracker.c31
-rw-r--r--trackerlogic.c133
-rw-r--r--trackerlogic.h7
3 files changed, 93 insertions, 78 deletions
diff --git a/opentracker.c b/opentracker.c
index d9336da..bf9db89 100644
--- a/opentracker.c
+++ b/opentracker.c
@@ -49,6 +49,10 @@ static char *accesslist_filename = NULL;
49#define WANT_ACCESS_CONTROL 49#define WANT_ACCESS_CONTROL
50#endif 50#endif
51 51
52#ifndef WANT_TRACKER_SYNC
53#define add_peer_to_torrent(A,B,C) add_peer_to_torrent(A,B)
54#endif
55
52#ifndef NO_FULLSCRAPE_LOGGING 56#ifndef NO_FULLSCRAPE_LOGGING
53#define LOG_TO_STDERR( ... ) fprintf( stderr, __VA_ARGS__ ) 57#define LOG_TO_STDERR( ... ) fprintf( stderr, __VA_ARGS__ )
54#else 58#else
@@ -91,7 +95,12 @@ struct http_data {
91int main( int argc, char **argv ); 95int main( int argc, char **argv );
92 96
93static void httperror( const int64 s, const char *title, const char *message ); 97static void httperror( const int64 s, const char *title, const char *message );
98
99#ifdef _DEBUG_HTTPERROR
94static void httpresponse( const int64 s, char *data, size_t l ); 100static void httpresponse( const int64 s, char *data, size_t l );
101#else
102static void httpresponse( const int64 s, char *data );
103#endif
95 104
96static void sendmmapdata( const int64 s, char *buffer, const size_t size ); 105static void sendmmapdata( const int64 s, char *buffer, const size_t size );
97static void senddata( const int64 s, char *buffer, const size_t size ); 106static void senddata( const int64 s, char *buffer, const size_t size );
@@ -213,7 +222,11 @@ static void senddata( const int64 s, char *buffer, size_t size ) {
213 } 222 }
214} 223}
215 224
225#ifdef _DEBUG_HTTPERROR
216static void httpresponse( const int64 s, char *data, size_t l ) { 226static void httpresponse( const int64 s, char *data, size_t l ) {
227#else
228static void httpresponse( const int64 s, char *data ) {
229#endif
217 struct http_data* h = io_getcookie( s ); 230 struct http_data* h = io_getcookie( s );
218 char *c, *reply; 231 char *c, *reply;
219 ot_peer peer; 232 ot_peer peer;
@@ -643,8 +656,13 @@ static void handle_read( const int64 clientsocket ) {
643 656
644 /* If we get the whole request in one packet, handle it without copying */ 657 /* If we get the whole request in one packet, handle it without copying */
645 if( !array_start( &h->request ) ) { 658 if( !array_start( &h->request ) ) {
646 if( memchr( static_inbuf, '\n', l ) ) 659 if( memchr( static_inbuf, '\n', l ) ) {
647 return httpresponse( clientsocket, static_inbuf, l ); 660 return httpresponse( clientsocket, static_inbuf
661#ifdef _DEBUG_HTTPERROR
662 , l
663#endif
664 );
665 }
648 h->flag |= STRUCT_HTTP_FLAG_ARRAY_USED; 666 h->flag |= STRUCT_HTTP_FLAG_ARRAY_USED;
649 return array_catb( &h->request, static_inbuf, l ); 667 return array_catb( &h->request, static_inbuf, l );
650 } 668 }
@@ -658,8 +676,13 @@ static void handle_read( const int64 clientsocket ) {
658 if( ( array_bytes( &h->request ) > 8192 ) && NOTBLESSED( h ) ) 676 if( ( array_bytes( &h->request ) > 8192 ) && NOTBLESSED( h ) )
659 return httperror( clientsocket, "500 request too long", "You sent too much headers"); 677 return httperror( clientsocket, "500 request too long", "You sent too much headers");
660 678
661 if( memchr( array_start( &h->request ), '\n', array_bytes( &h->request ) ) ) 679 if( memchr( array_start( &h->request ), '\n', array_bytes( &h->request ) ) ) {
662 return httpresponse( clientsocket, array_start( &h->request ), array_bytes( &h->request ) ); 680 return httpresponse( clientsocket, array_start( &h->request )
681#ifdef _DEBUG_HTTPERROR
682 , array_bytes( &h->request )
683#endif
684 );
685 }
663} 686}
664 687
665static void handle_write( const int64 clientsocket ) { 688static void handle_write( const int64 clientsocket ) {
diff --git a/trackerlogic.c b/trackerlogic.c
index 3aa3752..fd34d28 100644
--- a/trackerlogic.c
+++ b/trackerlogic.c
@@ -22,14 +22,11 @@
22/* GLOBAL VARIABLES */ 22/* GLOBAL VARIABLES */
23static ot_vector all_torrents[OT_BUCKET_COUNT]; 23static ot_vector all_torrents[OT_BUCKET_COUNT];
24static ot_time all_torrents_clean[OT_BUCKET_COUNT]; 24static ot_time all_torrents_clean[OT_BUCKET_COUNT];
25static ot_vector changeset;
26#if defined ( WANT_BLACKLISTING ) || defined( WANT_CLOSED_TRACKER ) 25#if defined ( WANT_BLACKLISTING ) || defined( WANT_CLOSED_TRACKER )
27static ot_vector accesslist; 26static ot_vector accesslist;
28#define WANT_ACCESS_CONTROL 27#define WANT_ACCESS_CONTROL
29#endif 28#endif
30 29
31static size_t changeset_size = 0;
32
33static int clean_single_torrent( ot_torrent *torrent ); 30static int clean_single_torrent( ot_torrent *torrent );
34 31
35/* Converter function from memory to human readable hex strings 32/* Converter function from memory to human readable hex strings
@@ -126,6 +123,9 @@ static void free_peerlist( ot_peerlist *peer_list ) {
126 for( i=0; i<OT_POOLS_COUNT; ++i ) 123 for( i=0; i<OT_POOLS_COUNT; ++i )
127 if( peer_list->peers[i].data ) 124 if( peer_list->peers[i].data )
128 free( peer_list->peers[i].data ); 125 free( peer_list->peers[i].data );
126#ifdef WANT_TRACKER_SYNC
127 free( peer_list->changeset.data );
128#endif
129 free( peer_list ); 129 free( peer_list );
130} 130}
131 131
@@ -145,7 +145,11 @@ static void vector_remove_torrent( ot_vector *vector, ot_torrent *match ) {
145 } 145 }
146} 146}
147 147
148#ifdef WANT_TRACKER_SYNC
148ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer, int from_changeset ) { 149ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer, int from_changeset ) {
150#else
151ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer ) {
152#endif
149 int exactmatch; 153 int exactmatch;
150 ot_torrent *torrent; 154 ot_torrent *torrent;
151 ot_peer *peer_dest; 155 ot_peer *peer_dest;
@@ -184,6 +188,7 @@ ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer, int from_changese
184 if( ( OT_FLAG( peer ) & ( PEER_FLAG_COMPLETED | PEER_FLAG_SEEDING ) ) == PEER_FLAG_COMPLETED ) 188 if( ( OT_FLAG( peer ) & ( PEER_FLAG_COMPLETED | PEER_FLAG_SEEDING ) ) == PEER_FLAG_COMPLETED )
185 OT_FLAG( peer ) ^= PEER_FLAG_COMPLETED; 189 OT_FLAG( peer ) ^= PEER_FLAG_COMPLETED;
186 190
191#ifdef WANT_TRACKER_SYNC
187 if( from_changeset ) { 192 if( from_changeset ) {
188 /* Check, whether peer already is in current pool, do nothing if so */ 193 /* Check, whether peer already is in current pool, do nothing if so */
189 peer_pool = &torrent->peer_list->peers[0]; 194 peer_pool = &torrent->peer_list->peers[0];
@@ -192,6 +197,7 @@ ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer, int from_changese
192 return torrent; 197 return torrent;
193 base_pool = 1; 198 base_pool = 1;
194 } 199 }
200#endif
195 201
196 peer_pool = &torrent->peer_list->peers[ base_pool ]; 202 peer_pool = &torrent->peer_list->peers[ base_pool ];
197 peer_dest = vector_find_or_insert( peer_pool, (void*)peer, sizeof( ot_peer ), OT_PEER_COMPARE_SIZE, &exactmatch ); 203 peer_dest = vector_find_or_insert( peer_pool, (void*)peer, sizeof( ot_peer ), OT_PEER_COMPARE_SIZE, &exactmatch );
@@ -431,54 +437,6 @@ size_t return_tcp_scrape_for_torrent( ot_hash *hash_list, int amount, char *repl
431} 437}
432 438
433#ifdef WANT_TRACKER_SYNC 439#ifdef WANT_TRACKER_SYNC
434/* Throw away old changeset */
435static void release_changeset( void ) {
436 ot_byte **changeset_ptrs = (ot_byte**)(changeset.data);
437 size_t i;
438
439 for( i = 0; i < changeset.size; ++i )
440 free( changeset_ptrs[i] );
441
442 free( changeset_ptrs );
443 byte_zero( &changeset, sizeof( changeset ) );
444
445 changeset_size = 0;
446}
447
448static void add_pool_to_changeset( ot_hash *hash, ot_peer *peers, size_t peer_count ) {
449 ot_byte *pool_copy = (ot_byte *)malloc( sizeof( size_t ) + sizeof( ot_hash ) + sizeof( ot_peer ) * peer_count + 13 );
450 size_t r = 0;
451
452 if( !pool_copy )
453 return;
454
455 memmove( pool_copy + sizeof( size_t ), "20:", 3 );
456 memmove( pool_copy + sizeof( size_t ) + 3, hash, sizeof( ot_hash ) );
457 r = sizeof( size_t ) + 3 + sizeof( ot_hash );
458 r += sprintf( (char*)pool_copy + r, "%zd:", sizeof( ot_peer ) * peer_count );
459 memmove( pool_copy + r, peers, sizeof( ot_peer ) * peer_count );
460 r += sizeof( ot_peer ) * peer_count;
461
462 /* Without the length field */
463 *(size_t*)pool_copy = r - sizeof( size_t );
464
465 if( changeset.size + 1 >= changeset.space ) {
466 size_t new_space = changeset.space ? OT_VECTOR_GROW_RATIO * changeset.space : OT_VECTOR_MIN_MEMBERS;
467 ot_byte *new_data = realloc( changeset.data, new_space * sizeof( ot_byte *) );
468
469 if( !new_data )
470 return free( pool_copy );
471
472 changeset.data = new_data;
473 changeset.space = new_space;
474 }
475
476 ((ot_byte**)changeset.data)[changeset.size++] = pool_copy;
477
478 /* Without the length field */
479 changeset_size += r - sizeof( size_t );
480}
481
482/* Import Changeset from an external authority 440/* Import Changeset from an external authority
483 format: d4:syncd[..]ee 441 format: d4:syncd[..]ee
484 [..]: ( 20:01234567890abcdefghij16:XXXXYYYY )+ 442 [..]: ( 20:01234567890abcdefghij16:XXXXYYYY )+
@@ -523,23 +481,45 @@ int add_changeset_to_tracker( ot_byte *data, size_t len ) {
523 d4:syncd20:<info_hash>8*N:(xxxxyyyy)*Nee 481 d4:syncd20:<info_hash>8*N:(xxxxyyyy)*Nee
524*/ 482*/
525size_t return_changeset_for_tracker( char **reply ) { 483size_t return_changeset_for_tracker( char **reply ) {
526 size_t i, r = 8; 484 size_t allocated = 0, i, replysize;
485 int bucket;
486 char *r;
487
488 /* Maybe there is time to clean_all_torrents(); */
489
490 /* Determine space needed for whole changeset */
491 for( bucket = 0; bucket < OT_BUCKET_COUNT; ++bucket ) {
492 ot_vector *torrents_list = all_torrents + bucket;
493 for( i=0; i<torrents_list->size; ++i ) {
494 ot_torrent *torrent = ((ot_torrent*)(torrents_list->data)) + i;
495 allocated += sizeof( ot_hash ) + sizeof(ot_peer) * torrent->peer_list->changeset.size + 13;
496 }
497 }
527 498
528 clean_all_torrents(); 499 /* add "d4:syncd" and "ee" */
500 allocated += 8 + 2;
529 501
530 if( !( *reply = mmap( NULL, 8 + changeset_size + 2, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0 ) ) ) return 0; 502 if( !( r = *reply = mmap( NULL, allocated, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0 ) ) )
503 return 0;
531 504
532 memmove( *reply, "d4:syncd", 8 ); 505 memmove( r, "d4:syncd", 8 ); r += 8;
533 for( i = 0; i < changeset.size; ++i ) { 506 for( bucket = 0; bucket < OT_BUCKET_COUNT; ++bucket ) {
534 ot_byte *data = ((ot_byte**)changeset.data)[i]; 507 ot_vector *torrents_list = all_torrents + bucket;
535 memmove( *reply + r, data + sizeof( size_t ), *(size_t*)data ); 508 for( i=0; i<torrents_list->size; ++i ) {
536 r += *(size_t*)data; 509 ot_torrent *torrent = ((ot_torrent*)(torrents_list->data)) + i;
510 const size_t byte_count = sizeof(ot_peer) * torrent->peer_list->changeset.size;
511 *r++ = '2'; *r++ = '0'; *r++ = ':';
512 memmove( r, torrent->hash, sizeof( ot_hash ) ); r += sizeof( ot_hash );
513 r += sprintf( r, "%zd:", byte_count );
514 memmove( r, torrent->peer_list->changeset.data, byte_count ); r += byte_count;
515 }
537 } 516 }
517 *r++ = 'e'; *r++ = 'e';
538 518
539 (*reply)[r++] = 'e'; 519 replysize = ( r - *reply );
540 (*reply)[r++] = 'e'; 520 fix_mmapallocation( *reply, allocated, replysize );
541 521
542 return r; 522 return replysize;
543} 523}
544#endif 524#endif
545 525
@@ -551,6 +531,9 @@ static int clean_single_torrent( ot_torrent *torrent ) {
551 size_t peers_count = 0, seeds_count; 531 size_t peers_count = 0, seeds_count;
552 time_t timedout = (int)( NOW - peer_list->base ); 532 time_t timedout = (int)( NOW - peer_list->base );
553 int i; 533 int i;
534#ifdef WANT_TRACKER_SYNC
535 char *new_peers;
536#endif
554 537
555 /* Torrent has idled out */ 538 /* Torrent has idled out */
556 if( timedout > OT_TORRENT_TIMEOUT ) 539 if( timedout > OT_TORRENT_TIMEOUT )
@@ -575,10 +558,20 @@ static int clean_single_torrent( ot_torrent *torrent ) {
575 memmove( peer_list->seed_counts + timedout, peer_list->seed_counts, sizeof( size_t ) * ( OT_POOLS_COUNT - timedout ) ); 558 memmove( peer_list->seed_counts + timedout, peer_list->seed_counts, sizeof( size_t ) * ( OT_POOLS_COUNT - timedout ) );
576 byte_zero( peer_list->seed_counts, sizeof( size_t ) * timedout ); 559 byte_zero( peer_list->seed_counts, sizeof( size_t ) * timedout );
577 560
578 /* Save the block modified within last OT_POOLS_TIMEOUT --- XXX no sync for now 561#ifdef WANT_TRACKER_SYNC
579 if( peer_list->peers[1].size ) 562 /* Save the block modified within last OT_POOLS_TIMEOUT */
580 add_pool_to_changeset( hash, peer_list->peers[1].data, peer_list->peers[1].size ); 563 if( peer_list->peers[1].size &&
581 */ 564 ( new_peers = realloc( peer_list->changeset.data, sizeof( ot_peer ) * peer_list->peers[1].size ) ) )
565 {
566 memmove( new_peers, peer_list->peers[1].data, peer_list->peers[1].size );
567 peer_list->changeset.data = new_peers;
568 peer_list->changeset.size = sizeof( ot_peer ) * peer_list->peers[1].size;
569 } else {
570 free( peer_list->changeset.data );
571
572 memset( &peer_list->changeset, 0, sizeof( ot_vector ) );
573 }
574#endif
582 575
583 peers_count = seeds_count = 0; 576 peers_count = seeds_count = 0;
584 for( i = 0; i < OT_POOLS_COUNT; ++i ) { 577 for( i = 0; i < OT_POOLS_COUNT; ++i ) {
@@ -606,10 +599,6 @@ void clean_all_torrents( void ) {
606 static int bucket; 599 static int bucket;
607 ot_time time_now = NOW; 600 ot_time time_now = NOW;
608 601
609/* No sync for now
610 release_changeset();
611*/
612
613 /* Search for an uncleaned bucked */ 602 /* Search for an uncleaned bucked */
614 while( ( all_torrents_clean[bucket] == time_now ) && ( ++bucket < OT_BUCKET_COUNT ) ); 603 while( ( all_torrents_clean[bucket] == time_now ) && ( ++bucket < OT_BUCKET_COUNT ) );
615 if( bucket >= OT_BUCKET_COUNT ) { 604 if( bucket >= OT_BUCKET_COUNT ) {
@@ -869,8 +858,6 @@ int init_logic( const char * const serverdir ) {
869 858
870 /* Initialize control structures */ 859 /* Initialize control structures */
871 byte_zero( all_torrents, sizeof( all_torrents ) ); 860 byte_zero( all_torrents, sizeof( all_torrents ) );
872 byte_zero( &changeset, sizeof( changeset ) );
873 changeset_size = 0;
874 861
875 return 0; 862 return 0;
876} 863}
@@ -890,8 +877,6 @@ void deinit_logic( void ) {
890 } 877 }
891 byte_zero( all_torrents, sizeof (all_torrents)); 878 byte_zero( all_torrents, sizeof (all_torrents));
892 byte_zero( all_torrents_clean, sizeof (all_torrents_clean)); 879 byte_zero( all_torrents_clean, sizeof (all_torrents_clean));
893 byte_zero( &changeset, sizeof( changeset ) );
894 changeset_size = 0;
895} 880}
896 881
897#ifdef WANT_ACCESS_CONTROL 882#ifdef WANT_ACCESS_CONTROL
diff --git a/trackerlogic.h b/trackerlogic.h
index fd8f48a..fc6c884 100644
--- a/trackerlogic.h
+++ b/trackerlogic.h
@@ -81,6 +81,9 @@ typedef struct {
81 size_t down_count; 81 size_t down_count;
82 size_t seed_counts[ OT_POOLS_COUNT ]; 82 size_t seed_counts[ OT_POOLS_COUNT ];
83 ot_vector peers[ OT_POOLS_COUNT ]; 83 ot_vector peers[ OT_POOLS_COUNT ];
84#ifdef WANT_TRACKER_SYNC
85 ot_vector changeset;
86#endif
84} ot_peerlist; 87} ot_peerlist;
85 88
86typedef struct { 89typedef struct {
@@ -97,7 +100,11 @@ void deinit_logic( void );
97 100
98enum { STATS_MRTG, STATS_TOP5, STATS_DMEM, STATS_TCP, STATS_UDP, STATS_SLASH24S, STATS_SLASH24S_OLD, SYNC_IN, SYNC_OUT }; 101enum { STATS_MRTG, STATS_TOP5, STATS_DMEM, STATS_TCP, STATS_UDP, STATS_SLASH24S, STATS_SLASH24S_OLD, SYNC_IN, SYNC_OUT };
99 102
103#ifdef WANT_TRACKER_SYNC
100ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer, int from_changeset ); 104ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer, int from_changeset );
105#else
106ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer );
107#endif
101size_t remove_peer_from_torrent( ot_hash *hash, ot_peer *peer, char *reply, int is_tcp ); 108size_t remove_peer_from_torrent( ot_hash *hash, ot_peer *peer, char *reply, int is_tcp );
102size_t return_peers_for_torrent( ot_torrent *torrent, size_t amount, char *reply, int is_tcp ); 109size_t return_peers_for_torrent( ot_torrent *torrent, size_t amount, char *reply, int is_tcp );
103size_t return_fullscrape_for_tracker( char **reply ); 110size_t return_fullscrape_for_tracker( char **reply );