diff options
-rw-r--r-- | ot_accesslist.c | 79 |
1 files changed, 36 insertions, 43 deletions
diff --git a/ot_accesslist.c b/ot_accesslist.c index 805ea23..e8ff74c 100644 --- a/ot_accesslist.c +++ b/ot_accesslist.c | |||
@@ -23,37 +23,25 @@ | |||
23 | 23 | ||
24 | /* GLOBAL VARIABLES */ | 24 | /* GLOBAL VARIABLES */ |
25 | #ifdef WANT_ACCESSLIST | 25 | #ifdef WANT_ACCESSLIST |
26 | char *g_accesslist_filename; | 26 | char *g_accesslist_filename; |
27 | static ot_vector accesslist; | 27 | static ot_hash *g_accesslist; |
28 | static size_t g_accesslist_size; | ||
28 | 29 | ||
29 | static void accesslist_reset( void ) { | 30 | static int vector_compare_hash(const void *hash1, const void *hash2 ) { |
30 | free( accesslist.data ); | 31 | return memcmp( hash1, hash2, OT_HASH_COMPARE_SIZE ); |
31 | byte_zero( &accesslist, sizeof( accesslist ) ); | ||
32 | } | 32 | } |
33 | 33 | ||
34 | void accesslist_deinit( void ) { | 34 | void accesslist_deinit( void ) { |
35 | accesslist_reset( ); | 35 | free( g_accesslist ); |
36 | } | 36 | g_accesslist = 0; |
37 | 37 | g_accesslist_size = 0; | |
38 | static int accesslist_addentry( ot_vector *al, ot_hash infohash ) { | ||
39 | int eger; | ||
40 | void *insert = vector_find_or_insert( al, infohash, OT_HASH_COMPARE_SIZE, OT_HASH_COMPARE_SIZE, &eger ); | ||
41 | |||
42 | if( !insert ) | ||
43 | return -1; | ||
44 | |||
45 | memcpy( insert, infohash, OT_HASH_COMPARE_SIZE ); | ||
46 | |||
47 | return 0; | ||
48 | } | 38 | } |
49 | 39 | ||
50 | /* Read initial access list */ | 40 | /* Read initial access list */ |
51 | static void accesslist_readfile( int sig ) { | 41 | static void accesslist_readfile( int sig ) { |
52 | ot_hash infohash; | 42 | ot_hash *info_hash, *accesslist_new = NULL, *accesslist_old; |
53 | ot_vector accesslist_tmp; | 43 | char *map, *map_end, *read_offs; |
54 | void *olddata; | 44 | size_t maplen; |
55 | char *map, *map_end, *read_offs; | ||
56 | size_t maplen; | ||
57 | 45 | ||
58 | if( sig != SIGHUP ) return; | 46 | if( sig != SIGHUP ) return; |
59 | 47 | ||
@@ -64,10 +52,15 @@ static void accesslist_readfile( int sig ) { | |||
64 | return; | 52 | return; |
65 | } | 53 | } |
66 | 54 | ||
67 | /* Initialise an empty accesslist vector */ | 55 | /* You need at least 41 bytes to pass an info_hash, make enough room |
68 | memset( &accesslist_tmp, 0, sizeof(accesslist_tmp)); | 56 | for the maximum amount of them */ |
69 | 57 | info_hash = accesslist_new = malloc( ( maplen / 41 ) * 20 ); | |
70 | /* No use */ | 58 | if( !accesslist_new ) { |
59 | fprintf( stderr, "Warning: Not enough memory to allocate %zd bytes for accesslist buffer. May succeed later.\n", ( maplen / 41 ) * 20 ); | ||
60 | return; | ||
61 | } | ||
62 | |||
63 | /* No use to scan if there's not enough room for another full info_hash */ | ||
71 | map_end = map + maplen - 40; | 64 | map_end = map + maplen - 40; |
72 | read_offs = map; | 65 | read_offs = map; |
73 | 66 | ||
@@ -78,45 +71,45 @@ static void accesslist_readfile( int sig ) { | |||
78 | int eger = 16 * scan_fromhex( read_offs[ 2*i ] ) + scan_fromhex( read_offs[ 1 + 2*i ] ); | 71 | int eger = 16 * scan_fromhex( read_offs[ 2*i ] ) + scan_fromhex( read_offs[ 1 + 2*i ] ); |
79 | if( eger < 0 ) | 72 | if( eger < 0 ) |
80 | continue; | 73 | continue; |
81 | infohash[i] = eger; | 74 | (*info_hash)[i] = eger; |
82 | } | 75 | } |
83 | 76 | ||
84 | read_offs += 40; | 77 | read_offs += 40; |
85 | 78 | ||
86 | /* Append accesslist to accesslist vector */ | 79 | /* Append accesslist to accesslist vector */ |
87 | if( scan_fromhex( *read_offs ) < 0 ) | 80 | if( scan_fromhex( *read_offs ) < 0 ) |
88 | accesslist_addentry( &accesslist_tmp, infohash ); | 81 | ++info_hash; |
89 | 82 | ||
90 | /* Find start of next line */ | 83 | /* Find start of next line */ |
91 | while( read_offs < map_end && *(read_offs++) != '\n' ); | 84 | while( read_offs < map_end && *(read_offs++) != '\n' ); |
92 | } | 85 | } |
93 | #ifdef _DEBUG | 86 | //#ifdef _DEBUG |
94 | fprintf( stderr, "Added %zd info_hashes to accesslist\n", accesslist_tmp.size ); | 87 | fprintf( stderr, "Added %d info_hashes to accesslist\n", info_hash - accesslist_new ); |
95 | #endif | 88 | //#endif |
96 | 89 | ||
97 | mmap_unmap( map, maplen); | 90 | mmap_unmap( map, maplen); |
98 | 91 | ||
92 | qsort( accesslist_new, info_hash - accesslist_new, sizeof( *info_hash ), vector_compare_hash ); | ||
93 | |||
99 | /* Now exchange the accesslist vector in the least race condition prone way */ | 94 | /* Now exchange the accesslist vector in the least race condition prone way */ |
100 | accesslist.size = 0; | 95 | g_accesslist_size = 0; |
101 | olddata = accesslist.data; | 96 | accesslist_old = g_accesslist; |
102 | memcpy( &accesslist, &accesslist_tmp, sizeof( &accesslist_tmp )); | 97 | g_accesslist = accesslist_new; |
103 | free( olddata ); | 98 | g_accesslist_size = info_hash - accesslist_new; |
99 | free( accesslist_old ); | ||
104 | } | 100 | } |
105 | 101 | ||
106 | int accesslist_hashisvalid( ot_hash hash ) { | 102 | int accesslist_hashisvalid( ot_hash hash ) { |
107 | int exactmatch; | 103 | void *exactmatch = bsearch( hash, g_accesslist, g_accesslist_size, OT_HASH_COMPARE_SIZE, vector_compare_hash ); |
108 | binary_search( hash, accesslist.data, accesslist.size, OT_HASH_COMPARE_SIZE, OT_HASH_COMPARE_SIZE, &exactmatch ); | ||
109 | 104 | ||
110 | #ifdef WANT_ACCESSLIST_BLACK | 105 | #ifdef WANT_ACCESSLIST_BLACK |
111 | exactmatch = !exactmatch; | 106 | return exactmatch == NULL; |
107 | #else | ||
108 | return exactmatch != NULL; | ||
112 | #endif | 109 | #endif |
113 | |||
114 | return exactmatch; | ||
115 | } | 110 | } |
116 | 111 | ||
117 | void accesslist_init( ) { | 112 | void accesslist_init( ) { |
118 | byte_zero( &accesslist, sizeof( accesslist ) ); | ||
119 | |||
120 | /* Passing "0" since read_blacklist_file also is SIGHUP handler */ | 113 | /* Passing "0" since read_blacklist_file also is SIGHUP handler */ |
121 | if( g_accesslist_filename ) { | 114 | if( g_accesslist_filename ) { |
122 | accesslist_readfile( SIGHUP ); | 115 | accesslist_readfile( SIGHUP ); |