diff options
author | erdgeist <> | 2007-11-06 03:21:03 +0000 |
---|---|---|
committer | erdgeist <> | 2007-11-06 03:21:03 +0000 |
commit | 785a9f13bdda7dfd4c206914645d15df7cae2af6 (patch) | |
tree | 0430d12fa4b5a212913b17b502a2327c61b27a62 | |
parent | 4a68f8692b3c1c142849529044fcdd7aef60d3f9 (diff) |
Make to_hex thread safe. Get rid off old /24 counting code. Protect more bucket accesses by locks.
-rw-r--r-- | trackerlogic.c | 129 | ||||
-rw-r--r-- | trackerlogic.h | 1 |
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!!! | 60 | static 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 | */ | ||
62 | static 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 | ||
660 | typedef struct { size_t val; ot_torrent * torrent; } ot_record; | 661 | typedef 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 | ||
797 | size_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 | |||
850 | size_t remove_peer_from_torrent( ot_hash *hash, ot_peer *peer, char *reply, int is_tcp ) { | 803 | size_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 | ||
852 | void accesslist_reset( void ) { | ||
853 | free( accesslist.data ); | ||
854 | byte_zero( &accesslist, sizeof( accesslist ) ); | ||
855 | } | ||
856 | |||
857 | int 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 | |||
898 | int trackerlogic_init( const char * const serverdir ) { | 870 | int 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 | ||
934 | void accesslist_reset( void ) { | ||
935 | free( accesslist.data ); | ||
936 | byte_zero( &accesslist, sizeof( accesslist ) ); | ||
937 | } | ||
938 | |||
939 | int 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 ); | |||
110 | size_t return_udp_scrape_for_torrent( ot_hash *hash, char *reply ); | 110 | size_t return_udp_scrape_for_torrent( ot_hash *hash, char *reply ); |
111 | size_t return_stats_for_tracker( char *reply, int mode ); | 111 | size_t return_stats_for_tracker( char *reply, int mode ); |
112 | size_t return_stats_for_slash24s( char *reply, size_t amount, ot_dword thresh ); | 112 | size_t return_stats_for_slash24s( char *reply, size_t amount, ot_dword thresh ); |
113 | size_t return_stats_for_slash24s_old( char *reply, size_t amount, ot_dword thresh ); | ||
114 | size_t return_memstat_for_tracker( char **reply ); | 113 | size_t return_memstat_for_tracker( char **reply ); |
115 | void clean_all_torrents( void ); | 114 | void clean_all_torrents( void ); |
116 | 115 | ||