summaryrefslogtreecommitdiff
path: root/trackerlogic.c
diff options
context:
space:
mode:
Diffstat (limited to 'trackerlogic.c')
-rw-r--r--trackerlogic.c133
1 files changed, 59 insertions, 74 deletions
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