diff options
| author | erdgeist <> | 2009-08-26 21:22:24 +0000 |
|---|---|---|
| committer | erdgeist <> | 2009-08-26 21:22:24 +0000 |
| commit | 20955311d12966b49b3cdf62217d7508af9a4e9a (patch) | |
| tree | d3767db625079de27e9f5059be98fdcf1ccbbc54 | |
| parent | c3a58d248b3c7f39979633376b92fd271464f864 (diff) | |
Introducing the concept of vectors of nets into opentracker
| -rw-r--r-- | ot_accesslist.c | 126 | ||||
| -rw-r--r-- | ot_accesslist.h | 42 |
2 files changed, 168 insertions, 0 deletions
diff --git a/ot_accesslist.c b/ot_accesslist.c index cdf7731..4df7edb 100644 --- a/ot_accesslist.c +++ b/ot_accesslist.c | |||
| @@ -143,6 +143,132 @@ void accesslist_deinit( void ) { | |||
| 143 | } | 143 | } |
| 144 | #endif | 144 | #endif |
| 145 | 145 | ||
| 146 | int address_in_net( const ot_ip6 address, const ot_net *net ) { | ||
| 147 | int bits = net->bits; | ||
| 148 | int result = memcmp( address, &net->address, bits >> 3 ); | ||
| 149 | if( !result && ( bits & 7 ) ) | ||
| 150 | result = ( ( 0x7f00 >> ( bits & 7 ) ) & address[bits>>3] ) - net->address[bits>>3]; | ||
| 151 | return result == 0; | ||
| 152 | } | ||
| 153 | |||
| 154 | void *set_value_for_net( const ot_net *net, ot_vector *vector, const void *value, const size_t member_size ) { | ||
| 155 | size_t i; | ||
| 156 | int exactmatch; | ||
| 157 | |||
| 158 | /* Caller must have a concept of ot_net in it's member */ | ||
| 159 | if( member_size < sizeof(ot_net) ) | ||
| 160 | return 0; | ||
| 161 | |||
| 162 | /* Check each net in vector for overlap */ | ||
| 163 | uint8_t *member = ((uint8_t*)vector->data); | ||
| 164 | for( i=0; i<vector->size; ++i ) { | ||
| 165 | if( address_in_net( *(ot_ip6*)member, net ) || | ||
| 166 | address_in_net( net->address, (ot_net*)member ) ) | ||
| 167 | return 0; | ||
| 168 | member += member_size; | ||
| 169 | } | ||
| 170 | |||
| 171 | member = vector_find_or_insert( vector, (void*)net, member_size, sizeof(ot_net), &exactmatch ); | ||
| 172 | if( member ) { | ||
| 173 | memcpy( member, net, sizeof(ot_net)); | ||
| 174 | memcpy( member + sizeof(ot_net), value, member_size - sizeof(ot_net)); | ||
| 175 | } | ||
| 176 | |||
| 177 | return member; | ||
| 178 | } | ||
| 179 | |||
| 180 | /* Takes a vector filled with { ot_net net, uint8_t[x] value }; | ||
| 181 | Returns value associated with the net, or NULL if not found */ | ||
| 182 | void *get_value_for_net( const ot_ip6 address, const ot_vector *vector, const size_t member_size ) { | ||
| 183 | int exactmatch; | ||
| 184 | /* This binary search will return a pointer to the first non-containing network... */ | ||
| 185 | ot_net *net = binary_search( address, vector->data, vector->size, member_size, sizeof(ot_ip6), &exactmatch ); | ||
| 186 | if( !net ) | ||
| 187 | return NULL; | ||
| 188 | /* ... so we'll need to move back one step unless we've exactly hit the first address in network */ | ||
| 189 | if( !exactmatch && ( (void*)net > vector->data ) ) | ||
| 190 | --net; | ||
| 191 | if( !address_in_net( address, net ) ) | ||
| 192 | return NULL; | ||
| 193 | return (void*)net; | ||
| 194 | } | ||
| 195 | |||
| 196 | #ifdef WANT_FULLLOG_NETWORKS | ||
| 197 | static ot_vector g_lognets_list; | ||
| 198 | ot_log *g_logchain_first, *g_logchain_last; | ||
| 199 | |||
| 200 | static pthread_mutex_t g_lognets_list_mutex = PTHREAD_MUTEX_INITIALIZER; | ||
| 201 | void loglist_add_network( const ot_net *net ) { | ||
| 202 | pthread_mutex_lock(&g_lognets_list_mutex); | ||
| 203 | set_value_for_net( net, &g_lognets_list, NULL, sizeof(ot_net)); | ||
| 204 | pthread_mutex_unlock(&g_lognets_list_mutex); | ||
| 205 | } | ||
| 206 | |||
| 207 | void loglist_reset( ) { | ||
| 208 | pthread_mutex_lock(&g_lognets_list_mutex); | ||
| 209 | free( g_lognets_list.data ); | ||
| 210 | g_lognets_list.data = 0; | ||
| 211 | g_lognets_list.size = g_lognets_list.space = 0; | ||
| 212 | pthread_mutex_unlock(&g_lognets_list_mutex); | ||
| 213 | } | ||
| 214 | |||
| 215 | int loglist_check_address( const ot_ip6 address ) { | ||
| 216 | int result; | ||
| 217 | pthread_mutex_lock(&g_lognets_list_mutex); | ||
| 218 | result = ( NULL != get_value_for_net( address, &g_lognets_list, sizeof(ot_net)) ); | ||
| 219 | pthread_mutex_unlock(&g_lognets_list_mutex); | ||
| 220 | return result; | ||
| 221 | } | ||
| 222 | #endif | ||
| 223 | |||
| 224 | #ifdef WANT_IP_FROM_PROXY | ||
| 225 | typedef struct { | ||
| 226 | ot_net *proxy; | ||
| 227 | ot_vector networks; | ||
| 228 | } ot_proxymap; | ||
| 229 | |||
| 230 | static ot_vector g_proxies_list; | ||
| 231 | static pthread_mutex_t g_proxies_list_mutex = PTHREAD_MUTEX_INITIALIZER; | ||
| 232 | |||
| 233 | int proxylist_add_network( const ot_net *proxy, const ot_net *net ) { | ||
| 234 | ot_proxymap *map; | ||
| 235 | int exactmatch, result = 1; | ||
| 236 | pthread_mutex_lock(&g_proxies_list_mutex); | ||
| 237 | |||
| 238 | /* If we have a direct hit, use and extend the vector there */ | ||
| 239 | map = binary_search( proxy, g_proxies_list.data, g_proxies_list.size, sizeof(ot_proxymap), sizeof(ot_net), &exactmatch ); | ||
| 240 | |||
| 241 | if( !map || !exactmatch ) { | ||
| 242 | /* else see, if we've got overlapping networks | ||
| 243 | and get a new empty vector if not */ | ||
| 244 | ot_vector empty; | ||
| 245 | memset( &empty, 0, sizeof( ot_vector ) ); | ||
| 246 | map = set_value_for_net( proxy, &g_proxies_list, &empty, sizeof(ot_proxymap)); | ||
| 247 | } | ||
| 248 | |||
| 249 | if( map && set_value_for_net( net, &map->networks, NULL, sizeof(ot_net) ) ) | ||
| 250 | result = 1; | ||
| 251 | |||
| 252 | pthread_mutex_unlock(&g_proxies_list_mutex); | ||
| 253 | return result; | ||
| 254 | } | ||
| 255 | |||
| 256 | int proxylist_check_proxy( const ot_ip6 proxy, const ot_ip6 address ) { | ||
| 257 | int result = 0; | ||
| 258 | ot_proxymap *map; | ||
| 259 | |||
| 260 | pthread_mutex_lock(&g_proxies_list_mutex); | ||
| 261 | |||
| 262 | if( ( map = get_value_for_net( proxy, &g_proxies_list, sizeof(ot_proxymap) ) ) ) | ||
| 263 | if( !address || get_value_for_net( address, &map->networks, sizeof(ot_net) ) ) | ||
| 264 | result = 1; | ||
| 265 | |||
| 266 | pthread_mutex_unlock(&g_proxies_list_mutex); | ||
| 267 | return result; | ||
| 268 | } | ||
| 269 | |||
| 270 | #endif | ||
| 271 | |||
| 146 | static ot_ip6 g_adminip_addresses[OT_ADMINIP_MAX]; | 272 | static ot_ip6 g_adminip_addresses[OT_ADMINIP_MAX]; |
| 147 | static ot_permissions g_adminip_permissions[OT_ADMINIP_MAX]; | 273 | static ot_permissions g_adminip_permissions[OT_ADMINIP_MAX]; |
| 148 | static unsigned int g_adminip_count = 0; | 274 | static unsigned int g_adminip_count = 0; |
diff --git a/ot_accesslist.h b/ot_accesslist.h index 5954a4a..a1e4ad2 100644 --- a/ot_accesslist.h +++ b/ot_accesslist.h | |||
| @@ -24,6 +24,48 @@ extern char *g_accesslist_filename; | |||
| 24 | #define accesslist_hashisvalid( hash ) 1 | 24 | #define accesslist_hashisvalid( hash ) 1 |
| 25 | #endif | 25 | #endif |
| 26 | 26 | ||
| 27 | /* Test if an address is subset of an ot_net, return value is considered a bool */ | ||
| 28 | int address_in_net( const ot_ip6 address, const ot_net *net ); | ||
| 29 | |||
| 30 | /* Store a value into a vector of struct { ot_net net, uint8_t[x] value } member; | ||
| 31 | returns NULL | ||
| 32 | if member_size is too small, or | ||
| 33 | if one of the nets inside the vector are a subnet of _net_, or | ||
| 34 | if _net_ is a subnet of one of the nets inside the vector, or | ||
| 35 | if the vector could not be resized | ||
| 36 | returns pointer to new member in vector for success | ||
| 37 | member_size can be sizeof(ot_net) to reduce the lookup to a boolean mapping | ||
| 38 | */ | ||
| 39 | void *set_value_for_net( const ot_net *net, ot_vector *vector, const void *value, const size_t member_size ); | ||
| 40 | |||
| 41 | /* Takes a vector filled with struct { ot_net net, uint8_t[x] value } member; | ||
| 42 | Returns pointer to _member_ associated with the net, or NULL if not found | ||
| 43 | member_size can be sizeof(ot_net) to reduce the lookup to a boolean mapping | ||
| 44 | */ | ||
| 45 | void *get_value_for_net( const ot_ip6 address, const ot_vector *vector, const size_t member_size ); | ||
| 46 | |||
| 47 | |||
| 48 | #ifdef WANT_IP_FROM_PROXY | ||
| 49 | int proxylist_add_network( const ot_net *proxy, const ot_net *net ); | ||
| 50 | int proxylist_check_network( const ot_ip6 *proxy, const ot_ip6 address /* can be NULL to only check proxy */ ); | ||
| 51 | #endif | ||
| 52 | |||
| 53 | #ifdef WANT_FULLLOG_NETWORKS | ||
| 54 | typedef struct ot_log ot_log; | ||
| 55 | struct ot_log { | ||
| 56 | ot_ip6 ip; | ||
| 57 | uint8_t *data; | ||
| 58 | size_t size; | ||
| 59 | ot_time time; | ||
| 60 | ot_log *next; | ||
| 61 | }; | ||
| 62 | extern ot_log *g_logchain_first, *g_logchain_last; | ||
| 63 | |||
| 64 | void loglist_add_network( const ot_net *net ); | ||
| 65 | void loglist_reset( ); | ||
| 66 | int loglist_check_address( const ot_ip6 address ); | ||
| 67 | #endif | ||
| 68 | |||
| 27 | typedef enum { | 69 | typedef enum { |
| 28 | OT_PERMISSION_MAY_FULLSCRAPE = 0x1, | 70 | OT_PERMISSION_MAY_FULLSCRAPE = 0x1, |
| 29 | OT_PERMISSION_MAY_STAT = 0x2, | 71 | OT_PERMISSION_MAY_STAT = 0x2, |
