diff options
Diffstat (limited to 'trackerlogic.c')
-rw-r--r-- | trackerlogic.c | 133 |
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 */ |
23 | static ot_vector all_torrents[OT_BUCKET_COUNT]; | 23 | static ot_vector all_torrents[OT_BUCKET_COUNT]; |
24 | static ot_time all_torrents_clean[OT_BUCKET_COUNT]; | 24 | static ot_time all_torrents_clean[OT_BUCKET_COUNT]; |
25 | static ot_vector changeset; | ||
26 | #if defined ( WANT_BLACKLISTING ) || defined( WANT_CLOSED_TRACKER ) | 25 | #if defined ( WANT_BLACKLISTING ) || defined( WANT_CLOSED_TRACKER ) |
27 | static ot_vector accesslist; | 26 | static ot_vector accesslist; |
28 | #define WANT_ACCESS_CONTROL | 27 | #define WANT_ACCESS_CONTROL |
29 | #endif | 28 | #endif |
30 | 29 | ||
31 | static size_t changeset_size = 0; | ||
32 | |||
33 | static int clean_single_torrent( ot_torrent *torrent ); | 30 | static 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 | ||
148 | ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer, int from_changeset ) { | 149 | ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer, int from_changeset ) { |
150 | #else | ||
151 | ot_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 */ | ||
435 | static 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 | |||
448 | static 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 | */ |
525 | size_t return_changeset_for_tracker( char **reply ) { | 483 | size_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 |