summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorerdgeist <>2007-11-06 03:21:03 +0000
committererdgeist <>2007-11-06 03:21:03 +0000
commit785a9f13bdda7dfd4c206914645d15df7cae2af6 (patch)
tree0430d12fa4b5a212913b17b502a2327c61b27a62
parent4a68f8692b3c1c142849529044fcdd7aef60d3f9 (diff)
Make to_hex thread safe. Get rid off old /24 counting code. Protect more bucket accesses by locks.
-rw-r--r--trackerlogic.c129
-rw-r--r--trackerlogic.h1
2 files changed, 41 insertions, 89 deletions
diff --git a/trackerlogic.c b/trackerlogic.c
index 80fc23e..2725399 100644
--- a/trackerlogic.c
+++ b/trackerlogic.c
@@ -56,10 +56,8 @@ static void *unlock_bucket_by_hash( ot_hash *hash ) {
56 return NULL; 56 return NULL;
57} 57}
58 58
59/* Converter function from memory to human readable hex strings 59/* Converter function from memory to human readable hex strings */
60 - definitely not thread safe!!! 60static char*to_hex(char*d,ot_byte*s){const char*m="0123456789ABCDEF";char*e=d+40;while(d<e){*d++=m[*s>>4];*d++=m[*s++&15];}*d=0;return d;}
61*/
62static char ths[2+2*20]="-";static char*to_hex(ot_byte*s){const char*m="0123456789ABCDEF";char*e=ths+41;char*t=ths+1;while(t<e){*t++=m[*s>>4];*t++=m[*s++&15];}*t=0;return ths+1;}
63 61
64/* This function gives us a binary search that returns a pointer, even if 62/* This function gives us a binary search that returns a pointer, even if
65 no exact match is found. In that case it sets exactmatch 0 and gives 63 no exact match is found. In that case it sets exactmatch 0 and gives
@@ -409,10 +407,11 @@ size_t return_memstat_for_tracker( char **reply ) {
409 407
410 for( i=0; i<OT_BUCKET_COUNT; ++i ) { 408 for( i=0; i<OT_BUCKET_COUNT; ++i ) {
411 ot_vector *torrents_list = all_torrents + i; 409 ot_vector *torrents_list = all_torrents + i;
410 char hex_out[42];
412 for( j=0; j<torrents_list->size; ++j ) { 411 for( j=0; j<torrents_list->size; ++j ) {
413 ot_peerlist *peer_list = ( ((ot_torrent*)(torrents_list->data))[j] ).peer_list; 412 ot_peerlist *peer_list = ( ((ot_torrent*)(torrents_list->data))[j] ).peer_list;
414 ot_hash *hash =&( ((ot_torrent*)(torrents_list->data))[j] ).hash; 413 ot_hash *hash =&( ((ot_torrent*)(torrents_list->data))[j] ).hash;
415 r += sprintf( r, "\n%s:\n", to_hex( (ot_byte*)hash ) ); 414 r += sprintf( r, "\n%s:\n", to_hex( hex_out, (ot_byte*)hash) );
416 for( k=0; k<OT_POOLS_COUNT; ++k ) 415 for( k=0; k<OT_POOLS_COUNT; ++k )
417 r += sprintf( r, "\t%05X %05X\n", ((unsigned int)peer_list->peers[k].size), (unsigned int)peer_list->peers[k].space ); 416 r += sprintf( r, "\t%05X %05X\n", ((unsigned int)peer_list->peers[k].size), (unsigned int)peer_list->peers[k].space );
418 } 417 }
@@ -647,6 +646,7 @@ void clean_all_torrents( void ) {
647 646
648 all_torrents_clean[bucket] = time_now; 647 all_torrents_clean[bucket] = time_now;
649 648
649 mutex_bucket_lock( bucket );
650 torrents_list = all_torrents + bucket; 650 torrents_list = all_torrents + bucket;
651 for( i=0; i<torrents_list->size; ++i ) { 651 for( i=0; i<torrents_list->size; ++i ) {
652 ot_torrent *torrent = ((ot_torrent*)(torrents_list->data)) + i; 652 ot_torrent *torrent = ((ot_torrent*)(torrents_list->data)) + i;
@@ -655,6 +655,7 @@ void clean_all_torrents( void ) {
655 --i; continue; 655 --i; continue;
656 } 656 }
657 } 657 }
658 mutex_bucket_unlock( bucket );
658} 659}
659 660
660typedef struct { size_t val; ot_torrent * torrent; } ot_record; 661typedef struct { size_t val; ot_torrent * torrent; } ot_record;
@@ -664,13 +665,14 @@ size_t return_stats_for_tracker( char *reply, int mode ) {
664 size_t torrent_count = 0, peer_count = 0, seed_count = 0, j; 665 size_t torrent_count = 0, peer_count = 0, seed_count = 0, j;
665 ot_record top5s[5], top5c[5]; 666 ot_record top5s[5], top5c[5];
666 char *r = reply; 667 char *r = reply;
667 int i; 668 int bucket;
668 669
669 byte_zero( top5s, sizeof( top5s ) ); 670 byte_zero( top5s, sizeof( top5s ) );
670 byte_zero( top5c, sizeof( top5c ) ); 671 byte_zero( top5c, sizeof( top5c ) );
671 672
672 for( i=0; i<OT_BUCKET_COUNT; ++i ) { 673 for( bucket=0; bucket<OT_BUCKET_COUNT; ++bucket ) {
673 ot_vector *torrents_list = all_torrents + i; 674 ot_vector *torrents_list = all_torrents + bucket;
675 mutex_bucket_lock( bucket );
674 torrent_count += torrents_list->size; 676 torrent_count += torrents_list->size;
675 for( j=0; j<torrents_list->size; ++j ) { 677 for( j=0; j<torrents_list->size; ++j ) {
676 ot_peerlist *peer_list = ( ((ot_torrent*)(torrents_list->data))[j] ).peer_list; 678 ot_peerlist *peer_list = ( ((ot_torrent*)(torrents_list->data))[j] ).peer_list;
@@ -690,20 +692,21 @@ size_t return_stats_for_tracker( char *reply, int mode ) {
690 } 692 }
691 peer_count += peer_list->peer_count; seed_count += peer_list->seed_count; 693 peer_count += peer_list->peer_count; seed_count += peer_list->seed_count;
692 } 694 }
695 mutex_bucket_unlock( bucket );
693 } 696 }
694 if( mode == STATS_TOP5 ) { 697 if( mode == STATS_TOP5 ) {
698 char hex_out[42];
695 int idx; 699 int idx;
696 r += sprintf( r, "Top5 torrents by peers:\n" ); 700 r += sprintf( r, "Top5 torrents by peers:\n" );
697 for( idx=0; idx<5; ++idx ) 701 for( idx=0; idx<5; ++idx )
698 if( top5c[idx].torrent ) 702 if( top5c[idx].torrent )
699 r += sprintf( r, "\t%zd\t%s\n", top5c[idx].val, to_hex(top5c[idx].torrent->hash) ); 703 r += sprintf( r, "\t%zd\t%s\n", top5c[idx].val, to_hex( hex_out, top5c[idx].torrent->hash) );
700 r += sprintf( r, "Top5 torrents by seeds:\n" ); 704 r += sprintf( r, "Top5 torrents by seeds:\n" );
701 for( idx=0; idx<5; ++idx ) 705 for( idx=0; idx<5; ++idx )
702 if( top5s[idx].torrent ) 706 if( top5s[idx].torrent )
703 r += sprintf( r, "\t%zd\t%s\n", top5s[idx].val, to_hex(top5s[idx].torrent->hash) ); 707 r += sprintf( r, "\t%zd\t%s\n", top5s[idx].val, to_hex( hex_out, top5s[idx].torrent->hash) );
704 } else { 708 } else
705 r += sprintf( r, "%zd\n%zd\nopentracker serving %zd torrents\nopentracker", peer_count, seed_count, torrent_count ); 709 r += sprintf( r, "%zd\n%zd\nopentracker serving %zd torrents\nopentracker", peer_count, seed_count, torrent_count );
706 }
707 710
708 return r - reply; 711 return r - reply;
709} 712}
@@ -720,8 +723,9 @@ size_t return_stats_for_slash24s( char *reply, size_t amount, ot_dword thresh )
720#define MSK_S24S (NUM_S24S-1) 723#define MSK_S24S (NUM_S24S-1)
721 724
722 ot_dword *counts[ NUM_BUFS ]; 725 ot_dword *counts[ NUM_BUFS ];
723 ot_dword slash24s[amount*2]; /* first dword amount, second dword subnet */ 726 ot_dword slash24s[amount*2]; /* first dword amount, second dword subnet */
724 size_t i, j, k, l; 727 int bucket;
728 size_t i, j, k, l;
725 char *r = reply; 729 char *r = reply;
726 730
727 byte_zero( counts, sizeof( counts ) ); 731 byte_zero( counts, sizeof( counts ) );
@@ -729,8 +733,9 @@ size_t return_stats_for_slash24s( char *reply, size_t amount, ot_dword thresh )
729 733
730 r += sprintf( r, "Stats for all /24s with more than %u announced torrents:\n\n", thresh ); 734 r += sprintf( r, "Stats for all /24s with more than %u announced torrents:\n\n", thresh );
731 735
732 for( i=0; i<OT_BUCKET_COUNT; ++i ) { 736 for( bucket=0; bucket<OT_BUCKET_COUNT; ++bucket ) {
733 ot_vector *torrents_list = all_torrents + i; 737 ot_vector *torrents_list = all_torrents + bucket;
738 mutex_bucket_lock( bucket );
734 for( j=0; j<torrents_list->size; ++j ) { 739 for( j=0; j<torrents_list->size; ++j ) {
735 ot_peerlist *peer_list = ( ((ot_torrent*)(torrents_list->data))[j] ).peer_list; 740 ot_peerlist *peer_list = ( ((ot_torrent*)(torrents_list->data))[j] ).peer_list;
736 for( k=0; k<OT_POOLS_COUNT; ++k ) { 741 for( k=0; k<OT_POOLS_COUNT; ++k ) {
@@ -750,6 +755,7 @@ size_t return_stats_for_slash24s( char *reply, size_t amount, ot_dword thresh )
750 } 755 }
751 } 756 }
752 } 757 }
758 mutex_bucket_unlock( bucket );
753 } 759 }
754 760
755 k = l = 0; /* Debug: count allocated bufs */ 761 k = l = 0; /* Debug: count allocated bufs */
@@ -794,59 +800,6 @@ bailout_cleanup:
794 return 0; 800 return 0;
795} 801}
796 802
797size_t return_stats_for_slash24s_old( char *reply, size_t amount, ot_dword thresh ) {
798 ot_word *count = malloc( 0x1000000 * sizeof(ot_word) );
799 ot_dword slash24s[amount*2]; /* first dword amount, second dword subnet */
800 size_t i, j, k, l;
801 char *r = reply;
802
803 if( !count )
804 return 0;
805
806 byte_zero( count, 0x1000000 * sizeof(ot_word) );
807 byte_zero( slash24s, amount * 2 * sizeof(ot_dword) );
808
809 r += sprintf( r, "Stats for all /24s with more than %d announced torrents:\n\n", ((int)thresh) );
810
811 for( i=0; i<OT_BUCKET_COUNT; ++i ) {
812 ot_vector *torrents_list = all_torrents + i;
813 for( j=0; j<torrents_list->size; ++j ) {
814 ot_peerlist *peer_list = ( ((ot_torrent*)(torrents_list->data))[j] ).peer_list;
815 for( k=0; k<OT_POOLS_COUNT; ++k ) {
816 ot_peer *peers = peer_list->peers[k].data;
817 size_t numpeers = peer_list->peers[k].size;
818 for( l=0; l<numpeers; ++l )
819 if( ++count[ ntohl(*(ot_dword*)(peers+l))>>8 ] == 65335 )
820 count[ ntohl(*(ot_dword*)(peers+l))>>8 ] = 65334;
821 }
822 }
823 }
824
825 for( i=0; i<0x1000000; ++i )
826 if( count[i] > thresh ) {
827 /* This subnet seems to announce more torrents than the last in our list */
828 int insert_pos = amount - 1;
829 while( ( insert_pos >= 0 ) && ( count[i] > slash24s[ 2 * insert_pos ] ) )
830 --insert_pos;
831 ++insert_pos;
832 memmove( slash24s + 2 * ( insert_pos + 1 ), slash24s + 2 * ( insert_pos ), 2 * sizeof( ot_dword ) * ( amount - insert_pos - 1 ) );
833 slash24s[ 2 * insert_pos ] = count[i];
834 slash24s[ 2 * insert_pos + 1 ] = i;
835 if( slash24s[ 2 * amount - 2 ] > thresh )
836 thresh = slash24s[ 2 * amount - 2 ];
837 }
838
839 free( count );
840
841 for( i=0; i < amount; ++i )
842 if( slash24s[ 2*i ] >= thresh ) {
843 unsigned long ip = slash24s[ 2*i +1 ];
844 r += sprintf( r, "% 10ld %d.%d.%d.0/24\n", (long)slash24s[ 2*i ], (int)(ip >> 16), (int)(255 & ( ip >> 8 )), (int)(ip & 255) );
845 }
846
847 return r - reply;
848}
849
850size_t remove_peer_from_torrent( ot_hash *hash, ot_peer *peer, char *reply, int is_tcp ) { 803size_t remove_peer_from_torrent( ot_hash *hash, ot_peer *peer, char *reply, int is_tcp ) {
851 int exactmatch; 804 int exactmatch;
852 size_t index; 805 size_t index;
@@ -895,6 +848,25 @@ exit_loop:
895 return (size_t)20; 848 return (size_t)20;
896} 849}
897 850
851#ifdef WANT_ACCESS_CONTROL
852void accesslist_reset( void ) {
853 free( accesslist.data );
854 byte_zero( &accesslist, sizeof( accesslist ) );
855}
856
857int accesslist_addentry( ot_hash *infohash ) {
858 int em;
859 void *insert = vector_find_or_insert( &accesslist, infohash, OT_HASH_COMPARE_SIZE, OT_HASH_COMPARE_SIZE, &em );
860
861 if( !insert )
862 return -1;
863
864 memmove( insert, infohash, OT_HASH_COMPARE_SIZE );
865
866 return 0;
867}
868#endif
869
898int trackerlogic_init( const char * const serverdir ) { 870int trackerlogic_init( const char * const serverdir ) {
899 if( serverdir && chdir( serverdir ) ) { 871 if( serverdir && chdir( serverdir ) ) {
900 fprintf( stderr, "Could not chdir() to %s\n", serverdir ); 872 fprintf( stderr, "Could not chdir() to %s\n", serverdir );
@@ -929,22 +901,3 @@ void trackerlogic_deinit( void ) {
929 901
930 mutex_deinit( ); 902 mutex_deinit( );
931} 903}
932
933#ifdef WANT_ACCESS_CONTROL
934void accesslist_reset( void ) {
935 free( accesslist.data );
936 byte_zero( &accesslist, sizeof( accesslist ) );
937}
938
939int accesslist_addentry( ot_hash *infohash ) {
940 int em;
941 void *insert = vector_find_or_insert( &accesslist, infohash, OT_HASH_COMPARE_SIZE, OT_HASH_COMPARE_SIZE, &em );
942
943 if( !insert )
944 return -1;
945
946 memmove( insert, infohash, OT_HASH_COMPARE_SIZE );
947
948 return 0;
949}
950#endif
diff --git a/trackerlogic.h b/trackerlogic.h
index 86737ab..5b03012 100644
--- a/trackerlogic.h
+++ b/trackerlogic.h
@@ -110,7 +110,6 @@ size_t return_tcp_scrape_for_torrent( ot_hash *hash, int amount, char *reply );
110size_t return_udp_scrape_for_torrent( ot_hash *hash, char *reply ); 110size_t return_udp_scrape_for_torrent( ot_hash *hash, char *reply );
111size_t return_stats_for_tracker( char *reply, int mode ); 111size_t return_stats_for_tracker( char *reply, int mode );
112size_t return_stats_for_slash24s( char *reply, size_t amount, ot_dword thresh ); 112size_t return_stats_for_slash24s( char *reply, size_t amount, ot_dword thresh );
113size_t return_stats_for_slash24s_old( char *reply, size_t amount, ot_dword thresh );
114size_t return_memstat_for_tracker( char **reply ); 113size_t return_memstat_for_tracker( char **reply );
115void clean_all_torrents( void ); 114void clean_all_torrents( void );
116 115