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 /trackerlogic.c | |
| parent | 4a68f8692b3c1c142849529044fcdd7aef60d3f9 (diff) | |
Make to_hex thread safe. Get rid off old /24 counting code. Protect more bucket accesses by locks.
Diffstat (limited to 'trackerlogic.c')
| -rw-r--r-- | trackerlogic.c | 129 |
1 files changed, 41 insertions, 88 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 | ||
