diff options
| -rw-r--r-- | Makefile | 10 | ||||
| -rw-r--r-- | opentracker.c | 16 | ||||
| -rw-r--r-- | ot_accesslist.c | 30 | ||||
| -rw-r--r-- | ot_accesslist.h | 2 | ||||
| -rw-r--r-- | ot_hex.c | 20 | ||||
| -rw-r--r-- | ot_hex.h | 4 | ||||
| -rw-r--r-- | ot_http.c | 10 | ||||
| -rw-r--r-- | ot_ip.c | 201 | ||||
| -rw-r--r-- | ot_ip.h | 33 | ||||
| -rw-r--r-- | ot_livesync.c | 10 | ||||
| -rw-r--r-- | ot_stats.c | 13 | ||||
| -rw-r--r-- | ot_udp.c | 4 | ||||
| -rw-r--r-- | ot_vector.c | 2 | ||||
| -rw-r--r-- | proxy.c | 10 | ||||
| -rw-r--r-- | tests/runner.c | 1 | ||||
| -rw-r--r-- | tests/t_ip.c | 217 | ||||
| -rw-r--r-- | tests/test.h | 1 | ||||
| -rw-r--r-- | trackerlogic.c | 12 |
18 files changed, 531 insertions, 65 deletions
| @@ -68,9 +68,9 @@ CFLAGS+=-I$(LIBOWFAT_HEADERS) -DGIT_VERSION=$(GIT_VERSION) -Wall -pipe -pthread | |||
| 68 | LDFLAGS+=-L$(LIBOWFAT_LIBRARY) -lowfat -pthread | 68 | LDFLAGS+=-L$(LIBOWFAT_LIBRARY) -lowfat -pthread |
| 69 | 69 | ||
| 70 | BINARY =opentracker | 70 | BINARY =opentracker |
| 71 | HEADERS=trackerlogic.h scan_urlencoded_query.h ot_buf.h ot_hex.h ot_scan.h ot_mutex.h ot_random.h ot_stats.h ot_vector.h ot_clean.h ot_udp.h ot_iovec.h ot_fullscrape.h ot_accesslist.h ot_http.h ot_livesync.h ot_rijndael.h | 71 | HEADERS=trackerlogic.h scan_urlencoded_query.h ot_buf.h ot_hex.h ot_ip.h ot_scan.h ot_mutex.h ot_random.h ot_stats.h ot_vector.h ot_clean.h ot_udp.h ot_iovec.h ot_fullscrape.h ot_accesslist.h ot_http.h ot_livesync.h ot_rijndael.h |
| 72 | SOURCES=opentracker.c trackerlogic.c scan_urlencoded_query.c ot_buf.c ot_hex.c ot_scan.c ot_mutex.c ot_random.c ot_stats.c ot_vector.c ot_clean.c ot_udp.c ot_iovec.c ot_fullscrape.c ot_accesslist.c ot_http.c ot_livesync.c ot_rijndael.c | 72 | SOURCES=opentracker.c trackerlogic.c scan_urlencoded_query.c ot_buf.c ot_hex.c ot_ip.c ot_scan.c ot_mutex.c ot_random.c ot_stats.c ot_vector.c ot_clean.c ot_udp.c ot_iovec.c ot_fullscrape.c ot_accesslist.c ot_http.c ot_livesync.c ot_rijndael.c |
| 73 | SOURCES_proxy=proxy.c ot_vector.c ot_mutex.c ot_random.c ot_scan.c | 73 | SOURCES_proxy=proxy.c ot_vector.c ot_mutex.c ot_random.c ot_scan.c ot_ip.c |
| 74 | 74 | ||
| 75 | OBJECTS = $(SOURCES:%.c=%.o) | 75 | OBJECTS = $(SOURCES:%.c=%.o) |
| 76 | OBJECTS_debug = $(SOURCES:%.c=%.debug.o) | 76 | OBJECTS_debug = $(SOURCES:%.c=%.debug.o) |
| @@ -105,8 +105,8 @@ proxy.debug: $(OBJECTS_proxy_debug) $(HEADERS) | |||
| 105 | # has to. tests/stubs.c supplies the few symbols those modules reference but | 105 | # has to. tests/stubs.c supplies the few symbols those modules reference but |
| 106 | # the tests never reach. | 106 | # the tests never reach. |
| 107 | TESTBIN=tests/runner | 107 | TESTBIN=tests/runner |
| 108 | TEST_SOURCES=tests/runner.c tests/test.c tests/stubs.c tests/t_scan_urlencoded_query.c tests/t_iovec.c tests/t_vector.c tests/t_random.c tests/t_hex.c tests/t_accesslist.c tests/t_scan.c tests/t_buf.c | 108 | TEST_SOURCES=tests/runner.c tests/test.c tests/stubs.c tests/t_scan_urlencoded_query.c tests/t_iovec.c tests/t_vector.c tests/t_random.c tests/t_hex.c tests/t_accesslist.c tests/t_scan.c tests/t_buf.c tests/t_ip.c |
| 109 | TEST_UNITS=scan_urlencoded_query.c ot_buf.c ot_iovec.c ot_vector.c ot_random.c ot_hex.c ot_scan.c ot_accesslist.c | 109 | TEST_UNITS=scan_urlencoded_query.c ot_buf.c ot_ip.c ot_iovec.c ot_vector.c ot_random.c ot_hex.c ot_scan.c ot_accesslist.c |
| 110 | TEST_HEADERS=tests/test.h $(HEADERS) | 110 | TEST_HEADERS=tests/test.h $(HEADERS) |
| 111 | # Tests reach code that sits behind feature flags, so the units under test are | 111 | # Tests reach code that sits behind feature flags, so the units under test are |
| 112 | # built with those features enabled. A test binary is not a production binary. | 112 | # built with those features enabled. A test binary is not a production binary. |
diff --git a/opentracker.c b/opentracker.c index 354e837..8a39bde 100644 --- a/opentracker.c +++ b/opentracker.c | |||
| @@ -24,17 +24,17 @@ | |||
| 24 | /* Libowfat */ | 24 | /* Libowfat */ |
| 25 | #include "io.h" | 25 | #include "io.h" |
| 26 | #include "iob.h" | 26 | #include "iob.h" |
| 27 | #include "ip6.h" | ||
| 28 | #include "socket.h" | 27 | #include "socket.h" |
| 29 | 28 | ||
| 30 | /* Opentracker */ | 29 | /* Opentracker */ |
| 31 | #include "ot_accesslist.h" | 30 | #include "ot_accesslist.h" |
| 32 | #include "ot_hex.h" | 31 | #include "ot_hex.h" |
| 33 | #include "ot_http.h" | 32 | #include "ot_http.h" |
| 33 | #include "ot_ip.h" | ||
| 34 | #include "ot_livesync.h" | 34 | #include "ot_livesync.h" |
| 35 | #include "ot_mutex.h" | 35 | #include "ot_mutex.h" |
| 36 | #include "ot_scan.h" | ||
| 37 | #include "ot_random.h" | 36 | #include "ot_random.h" |
| 37 | #include "ot_scan.h" | ||
| 38 | #include "ot_stats.h" | 38 | #include "ot_stats.h" |
| 39 | #include "ot_udp.h" | 39 | #include "ot_udp.h" |
| 40 | #include "trackerlogic.h" | 40 | #include "trackerlogic.h" |
| @@ -346,7 +346,7 @@ static int64_t ot_try_bind(ot_ip6 ip, uint16_t port, PROTO_FLAG proto) { | |||
| 346 | char *protos[] = {"TCP", "UDP", "UDP mcast"}; | 346 | char *protos[] = {"TCP", "UDP", "UDP mcast"}; |
| 347 | char _debug[512]; | 347 | char _debug[512]; |
| 348 | int off = snprintf(_debug, sizeof(_debug), "Binding socket type %s to address [", protos[proto]); | 348 | int off = snprintf(_debug, sizeof(_debug), "Binding socket type %s to address [", protos[proto]); |
| 349 | off += fmt_ip6c(_debug + off, ip); | 349 | off += ip_format(_debug + off, ip); |
| 350 | snprintf(_debug + off, sizeof(_debug) - off, "]:%d...", port); | 350 | snprintf(_debug + off, sizeof(_debug) - off, "]:%d...", port); |
| 351 | fputs(_debug, stderr); | 351 | fputs(_debug, stderr); |
| 352 | } | 352 | } |
| @@ -394,14 +394,14 @@ static int scan_ip6_port(const char *src, ot_ip6 ip, uint16_t *port) { | |||
| 394 | ++s; | 394 | ++s; |
| 395 | if (*s == '[') | 395 | if (*s == '[') |
| 396 | ++s, ++bracket; /* for v6 style notation */ | 396 | ++s, ++bracket; /* for v6 style notation */ |
| 397 | if (!(off = scan_ip6(s, ip))) | 397 | if (!(off = ip_scan(s, ip))) |
| 398 | return 0; | 398 | return 0; |
| 399 | s += off; | 399 | s += off; |
| 400 | if (bracket && *s == ']') | 400 | if (bracket && *s == ']') |
| 401 | ++s; | 401 | ++s; |
| 402 | if (*s == 0 || isspace(*s)) | 402 | if (*s == 0 || isspace(*s)) |
| 403 | return s - src; | 403 | return s - src; |
| 404 | if (!ip6_isv4mapped(ip)) { | 404 | if (!ip_is_v4mapped(ip)) { |
| 405 | if (*s != ':' && *s != '.') | 405 | if (*s != ':' && *s != '.') |
| 406 | return 0; | 406 | return 0; |
| 407 | if (!bracket && *(s) == ':') | 407 | if (!bracket && *(s) == ':') |
| @@ -423,7 +423,7 @@ static int scan_ip6_net(const char *src, ot_net *net) { | |||
| 423 | int off; | 423 | int off; |
| 424 | while (isspace(*s)) | 424 | while (isspace(*s)) |
| 425 | ++s; | 425 | ++s; |
| 426 | if (!(off = scan_ip6(s, net->address))) | 426 | if (!(off = ip_scan(s, net->address))) |
| 427 | return 0; | 427 | return 0; |
| 428 | s += off; | 428 | s += off; |
| 429 | if (*s != '/') | 429 | if (*s != '/') |
| @@ -433,7 +433,7 @@ static int scan_ip6_net(const char *src, ot_net *net) { | |||
| 433 | if (!(off = scan_udec(s, &value, 128))) | 433 | if (!(off = scan_udec(s, &value, 128))) |
| 434 | return 0; | 434 | return 0; |
| 435 | net->bits = (int)value; | 435 | net->bits = (int)value; |
| 436 | if (ip6_isv4mapped(net->address)) | 436 | if (ip_is_v4mapped(net->address)) |
| 437 | net->bits += 96; | 437 | net->bits += 96; |
| 438 | if (net->bits > 128) | 438 | if (net->bits > 128) |
| 439 | return 0; | 439 | return 0; |
| @@ -761,7 +761,7 @@ int main(int argc, char **argv) { | |||
| 761 | scanon = 0; | 761 | scanon = 0; |
| 762 | break; | 762 | break; |
| 763 | case 'i': | 763 | case 'i': |
| 764 | if (!scan_ip6(optarg, serverip)) { | 764 | if (!ip_scan(optarg, serverip)) { |
| 765 | usage(argv[0]); | 765 | usage(argv[0]); |
| 766 | exit(1); | 766 | exit(1); |
| 767 | } | 767 | } |
diff --git a/ot_accesslist.c b/ot_accesslist.c index a199fa4..2465ada 100644 --- a/ot_accesslist.c +++ b/ot_accesslist.c | |||
| @@ -22,11 +22,11 @@ | |||
| 22 | #endif | 22 | #endif |
| 23 | 23 | ||
| 24 | /* Libowfat */ | 24 | /* Libowfat */ |
| 25 | #include "ip6.h" | ||
| 26 | 25 | ||
| 27 | /* Opentracker */ | 26 | /* Opentracker */ |
| 28 | #include "ot_accesslist.h" | 27 | #include "ot_accesslist.h" |
| 29 | #include "ot_hex.h" | 28 | #include "ot_hex.h" |
| 29 | #include "ot_ip.h" | ||
| 30 | #include "ot_vector.h" | 30 | #include "ot_vector.h" |
| 31 | #include "trackerlogic.h" | 31 | #include "trackerlogic.h" |
| 32 | 32 | ||
| @@ -81,7 +81,7 @@ static ot_accesslist *accesslist_make(ot_accesslist *next, size_t size) { | |||
| 81 | if (accesslist_new) { | 81 | if (accesslist_new) { |
| 82 | accesslist_new->list = size ? malloc(sizeof(ot_hash) * size) : NULL; | 82 | accesslist_new->list = size ? malloc(sizeof(ot_hash) * size) : NULL; |
| 83 | accesslist_new->size = size; | 83 | accesslist_new->size = size; |
| 84 | accesslist_new->base = g_now_minutes; | 84 | accesslist_new->base = 0; |
| 85 | accesslist_new->next = next; | 85 | accesslist_new->next = next; |
| 86 | if (size && !accesslist_new->list) { | 86 | if (size && !accesslist_new->list) { |
| 87 | free(accesslist_new); | 87 | free(accesslist_new); |
| @@ -192,16 +192,24 @@ static void accesslist_readfile(void) { | |||
| 192 | 192 | ||
| 193 | /* Now exchange the accesslist vector in the least race condition prone way */ | 193 | /* Now exchange the accesslist vector in the least race condition prone way */ |
| 194 | pthread_mutex_lock(&g_accesslist_mutex); | 194 | pthread_mutex_lock(&g_accesslist_mutex); |
| 195 | |||
| 196 | /* Mark old accesslist as "needs to live another five minutes" */ | ||
| 197 | if (g_accesslist) | ||
| 198 | g_accesslist->base = g_now_minutes; | ||
| 195 | accesslist_new->next = g_accesslist; | 199 | accesslist_new->next = g_accesslist; |
| 196 | g_accesslist = accesslist_new; /* Only now set a new list */ | 200 | g_accesslist = accesslist_new; /* Only now set a new list */ |
| 197 | 201 | ||
| 198 | #ifdef WANT_DYNAMIC_ACCESSLIST | 202 | #ifdef WANT_DYNAMIC_ACCESSLIST |
| 199 | /* If we have dynamic accesslists, reloading a new one will always void the add/delete lists. | 203 | /* If we have dynamic accesslists, reloading a new one will always void the add/delete lists. |
| 200 | Insert empty ones at the list head */ | 204 | Insert empty ones at the list head */ |
| 201 | if (g_accesslist_add && (accesslist_new = accesslist_make(g_accesslist_add, 0)) != NULL) | 205 | if (g_accesslist_add && (accesslist_new = accesslist_make(g_accesslist_add, 0)) != NULL) { |
| 206 | g_accesslist_add->base = g_now_minutes; | ||
| 202 | g_accesslist_add = accesslist_new; | 207 | g_accesslist_add = accesslist_new; |
| 203 | if (g_accesslist_delete && (accesslist_new = accesslist_make(g_accesslist_delete, 0)) != NULL) | 208 | } |
| 209 | if (g_accesslist_delete && (accesslist_new = accesslist_make(g_accesslist_delete, 0)) != NULL) { | ||
| 210 | g_accesslist_delete->base = g_now_minutes; | ||
| 204 | g_accesslist_delete = accesslist_new; | 211 | g_accesslist_delete = accesslist_new; |
| 212 | } | ||
| 205 | #endif | 213 | #endif |
| 206 | 214 | ||
| 207 | accesslist_clean(g_accesslist); | 215 | accesslist_clean(g_accesslist); |
| @@ -209,7 +217,7 @@ static void accesslist_readfile(void) { | |||
| 209 | pthread_mutex_unlock(&g_accesslist_mutex); | 217 | pthread_mutex_unlock(&g_accesslist_mutex); |
| 210 | } | 218 | } |
| 211 | 219 | ||
| 212 | int accesslist_hashisvalid(ot_hash hash) { | 220 | int accesslist_hashisvalid(const ot_hash hash) { |
| 213 | /* Get working copy of current access list */ | 221 | /* Get working copy of current access list */ |
| 214 | ot_accesslist *accesslist = g_accesslist; | 222 | ot_accesslist *accesslist = g_accesslist; |
| 215 | #ifdef WANT_DYNAMIC_ACCESSLIST | 223 | #ifdef WANT_DYNAMIC_ACCESSLIST |
| @@ -315,7 +323,8 @@ static void *accesslist_adddel_worker(char *fifoname, ot_accesslist *_Atomic | |||
| 315 | ot_accesslist *accesslist_new = accesslist_make(*removing_from, (*removing_from)->size - 1); | 323 | ot_accesslist *accesslist_new = accesslist_make(*removing_from, (*removing_from)->size - 1); |
| 316 | if (accesslist_new) { | 324 | if (accesslist_new) { |
| 317 | memcpy(accesslist_new->list, (*removing_from)->list, sizeof(ot_hash) * off); | 325 | memcpy(accesslist_new->list, (*removing_from)->list, sizeof(ot_hash) * off); |
| 318 | memcpy(accesslist_new->list + off, (*removing_from)->list + off + 1, (*removing_from)->size - off - 1); | 326 | memcpy(accesslist_new->list + off, (*removing_from)->list + off + 1, sizeof(ot_hash) * ((*removing_from)->size - off - 1)); |
| 327 | (*removing_from)->base = g_now_minutes; | ||
| 319 | *removing_from = accesslist_new; | 328 | *removing_from = accesslist_new; |
| 320 | } | 329 | } |
| 321 | } | 330 | } |
| @@ -330,7 +339,7 @@ static void *accesslist_adddel_worker(char *fifoname, ot_accesslist *_Atomic | |||
| 330 | } | 339 | } |
| 331 | } else { | 340 | } else { |
| 332 | int exactmatch = 0; | 341 | int exactmatch = 0; |
| 333 | ot_hash *insert_point = binary_search(info_hash, (*adding_to)->list, (*adding_to)->size, OT_HASH_COMPARE_SIZE, sizeof(ot_hash), &exactmatch); | 342 | ot_hash *insert_point = binary_search(info_hash, (*adding_to)->list, (*adding_to)->size, sizeof(ot_hash), OT_HASH_COMPARE_SIZE, &exactmatch); |
| 334 | 343 | ||
| 335 | /* Only if the info hash is not in the adding_to list, create a new head with that entry */ | 344 | /* Only if the info hash is not in the adding_to list, create a new head with that entry */ |
| 336 | if (!exactmatch) { | 345 | if (!exactmatch) { |
| @@ -339,7 +348,8 @@ static void *accesslist_adddel_worker(char *fifoname, ot_accesslist *_Atomic | |||
| 339 | if (accesslist_new) { | 348 | if (accesslist_new) { |
| 340 | memcpy(accesslist_new->list, (*adding_to)->list, sizeof(ot_hash) * off); | 349 | memcpy(accesslist_new->list, (*adding_to)->list, sizeof(ot_hash) * off); |
| 341 | memcpy(accesslist_new->list + off, info_hash, sizeof(info_hash)); | 350 | memcpy(accesslist_new->list + off, info_hash, sizeof(info_hash)); |
| 342 | memcpy(accesslist_new->list + off + 1, (*adding_to)->list + off, (*adding_to)->size - off); | 351 | memcpy(accesslist_new->list + off + 1, (*adding_to)->list + off, sizeof(ot_hash) * ((*adding_to)->size - off)); |
| 352 | (*adding_to)->base = g_now_minutes; | ||
| 343 | *adding_to = accesslist_new; | 353 | *adding_to = accesslist_new; |
| 344 | } | 354 | } |
| 345 | } | 355 | } |
| @@ -546,10 +556,10 @@ int accesslist_bless_net(ot_net *net, ot_permissions permissions) { | |||
| 546 | { | 556 | { |
| 547 | char _debug[512]; | 557 | char _debug[512]; |
| 548 | int off = snprintf(_debug, sizeof(_debug), "Blessing ip net "); | 558 | int off = snprintf(_debug, sizeof(_debug), "Blessing ip net "); |
| 549 | off += fmt_ip6c(_debug + off, net->address); | 559 | off += ip_format(_debug + off, net->address); |
| 550 | if (net->bits < 128) { | 560 | if (net->bits < 128) { |
| 551 | _debug[off++] = '/'; | 561 | _debug[off++] = '/'; |
| 552 | if (ip6_isv4mapped(net->address)) | 562 | if (ip_is_v4mapped(net->address)) |
| 553 | off += snprintf(_debug + off, sizeof(_debug) - off, "%d", net->bits - 96); | 563 | off += snprintf(_debug + off, sizeof(_debug) - off, "%d", net->bits - 96); |
| 554 | else | 564 | else |
| 555 | off += snprintf(_debug + off, sizeof(_debug) - off, "%d", net->bits); | 565 | off += snprintf(_debug + off, sizeof(_debug) - off, "%d", net->bits); |
diff --git a/ot_accesslist.h b/ot_accesslist.h index b3e979d..30aaebd 100644 --- a/ot_accesslist.h +++ b/ot_accesslist.h | |||
| @@ -16,7 +16,7 @@ | |||
| 16 | #define WANT_ACCESSLIST | 16 | #define WANT_ACCESSLIST |
| 17 | void accesslist_init(void); | 17 | void accesslist_init(void); |
| 18 | void accesslist_deinit(void); | 18 | void accesslist_deinit(void); |
| 19 | int accesslist_hashisvalid(ot_hash hash); | 19 | int accesslist_hashisvalid(const ot_hash hash); |
| 20 | void accesslist_cleanup(void); | 20 | void accesslist_cleanup(void); |
| 21 | 21 | ||
| 22 | /* Scan buf for up to capacity info_hashes in hexadecimal notation, one per | 22 | /* Scan buf for up to capacity info_hashes in hexadecimal notation, one per |
| @@ -10,16 +10,18 @@ | |||
| 10 | /* Opentracker */ | 10 | /* Opentracker */ |
| 11 | #include "ot_hex.h" | 11 | #include "ot_hex.h" |
| 12 | 12 | ||
| 13 | static int fromhex(unsigned char c) { | 13 | int hex_value(int c) { |
| 14 | if (c >= '0' && c <= '9') | 14 | unsigned char u = (unsigned char)c; |
| 15 | return c - '0'; | 15 | |
| 16 | c |= 0x20; /* fold upper case onto lower, digits are already handled */ | 16 | if (u >= '0' && u <= '9') |
| 17 | if (c >= 'a' && c <= 'f') | 17 | return u - '0'; |
| 18 | return c - 'a' + 10; | 18 | u |= 0x20; /* fold upper case onto lower, digits are already handled */ |
| 19 | if (u >= 'a' && u <= 'f') | ||
| 20 | return u - 'a' + 10; | ||
| 19 | return -1; | 21 | return -1; |
| 20 | } | 22 | } |
| 21 | 23 | ||
| 22 | int hex_isdigit(int c) { return fromhex((unsigned char)c) >= 0; } | 24 | int hex_isdigit(int c) { return hex_value(c) >= 0; } |
| 23 | 25 | ||
| 24 | char *hex_fromhash(char *dest, const uint8_t *hash) { | 26 | char *hex_fromhash(char *dest, const uint8_t *hash) { |
| 25 | static const char digits[] = "0123456789ABCDEF"; | 27 | static const char digits[] = "0123456789ABCDEF"; |
| @@ -43,9 +45,9 @@ int hex_tohash(ot_hash hash, const char *src) { | |||
| 43 | 45 | ||
| 44 | /* Tested one character at a time so that a string ending early stops us | 46 | /* Tested one character at a time so that a string ending early stops us |
| 45 | at its terminator rather than one byte past it */ | 47 | at its terminator rather than one byte past it */ |
| 46 | if ((high = fromhex((unsigned char)src[2 * i])) < 0) | 48 | if ((high = hex_value((unsigned char)src[2 * i])) < 0) |
| 47 | return 0; | 49 | return 0; |
| 48 | if ((low = fromhex((unsigned char)src[2 * i + 1])) < 0) | 50 | if ((low = hex_value((unsigned char)src[2 * i + 1])) < 0) |
| 49 | return 0; | 51 | return 0; |
| 50 | 52 | ||
| 51 | decoded[i] = (uint8_t)((high << 4) | low); | 53 | decoded[i] = (uint8_t)((high << 4) | low); |
| @@ -22,4 +22,8 @@ int hex_tohash(ot_hash hash, const char *src); | |||
| 22 | /* Non-zero if c is a hexadecimal digit, in either case. */ | 22 | /* Non-zero if c is a hexadecimal digit, in either case. */ |
| 23 | int hex_isdigit(int c); | 23 | int hex_isdigit(int c); |
| 24 | 24 | ||
| 25 | /* The value of a hexadecimal digit, or -1 if c is not one. Shared with the | ||
| 26 | address scanner so that both agree on what a digit is. */ | ||
| 27 | int hex_value(int c); | ||
| 28 | |||
| 25 | #endif | 29 | #endif |
| @@ -16,13 +16,13 @@ | |||
| 16 | 16 | ||
| 17 | /* Libowfat */ | 17 | /* Libowfat */ |
| 18 | #include "iob.h" | 18 | #include "iob.h" |
| 19 | #include "ip6.h" | ||
| 20 | 19 | ||
| 21 | /* Opentracker */ | 20 | /* Opentracker */ |
| 22 | #include "ot_accesslist.h" | 21 | #include "ot_accesslist.h" |
| 23 | #include "ot_fullscrape.h" | 22 | #include "ot_fullscrape.h" |
| 24 | #include "ot_http.h" | 23 | #include "ot_http.h" |
| 25 | #include "ot_iovec.h" | 24 | #include "ot_iovec.h" |
| 25 | #include "ot_ip.h" | ||
| 26 | #include "ot_mutex.h" | 26 | #include "ot_mutex.h" |
| 27 | #include "ot_scan.h" | 27 | #include "ot_scan.h" |
| 28 | #include "ot_stats.h" | 28 | #include "ot_stats.h" |
| @@ -525,7 +525,7 @@ static ssize_t http_handle_announce(const int64 sock, struct ot_workstruct * | |||
| 525 | if (accesslist_is_blessed(cookie->ip, OT_PERMISSION_MAY_PROXY)) { | 525 | if (accesslist_is_blessed(cookie->ip, OT_PERMISSION_MAY_PROXY)) { |
| 526 | ot_ip6 proxied_ip; | 526 | ot_ip6 proxied_ip; |
| 527 | char *fwd = http_header(ws->request, ws->header_size, "x-forwarded-for"); | 527 | char *fwd = http_header(ws->request, ws->header_size, "x-forwarded-for"); |
| 528 | if (fwd && scan_ip6(fwd, proxied_ip)) { | 528 | if (fwd && ip_scan(fwd, proxied_ip)) { |
| 529 | OT_SETIP(ws->peer, proxied_ip); | 529 | OT_SETIP(ws->peer, proxied_ip); |
| 530 | } else | 530 | } else |
| 531 | OT_SETIP(ws->peer, cookie->ip); | 531 | OT_SETIP(ws->peer, cookie->ip); |
| @@ -611,7 +611,7 @@ static ssize_t http_handle_announce(const int64 sock, struct ot_workstruct * | |||
| 611 | char *tmp_buf1 = ws->reply, *tmp_buf2 = ws->reply + 16; | 611 | char *tmp_buf1 = ws->reply, *tmp_buf2 = ws->reply + 16; |
| 612 | len = scan_urlencoded_query(&read_ptr, tmp_buf2, SCAN_SEARCHPATH_VALUE); | 612 | len = scan_urlencoded_query(&read_ptr, tmp_buf2, SCAN_SEARCHPATH_VALUE); |
| 613 | tmp_buf2[len] = 0; | 613 | tmp_buf2[len] = 0; |
| 614 | if ((len <= 0) || !scan_ip6(tmp_buf2, tmp_buf1)) | 614 | if ((len <= 0) || !ip_scan(tmp_buf2, tmp_buf1)) |
| 615 | HTTPERROR_400_PARAM; | 615 | HTTPERROR_400_PARAM; |
| 616 | OT_SETIP(&ws->peer, tmp_buf1); | 616 | OT_SETIP(&ws->peer, tmp_buf1); |
| 617 | } break; | 617 | } break; |
| @@ -633,7 +633,7 @@ static ssize_t http_handle_announce(const int64 sock, struct ot_workstruct * | |||
| 633 | loglist_reset(); | 633 | loglist_reset(); |
| 634 | return ws->reply_size = sprintf(ws->reply, "Successfully removed.\n"); | 634 | return ws->reply_size = sprintf(ws->reply, "Successfully removed.\n"); |
| 635 | } | 635 | } |
| 636 | parsed = scan_ip6(tmp_buf, net.address); | 636 | parsed = ip_scan(tmp_buf, net.address); |
| 637 | if (!parsed) | 637 | if (!parsed) |
| 638 | HTTPERROR_400_PARAM; | 638 | HTTPERROR_400_PARAM; |
| 639 | if (tmp_buf[parsed++] != '/') | 639 | if (tmp_buf[parsed++] != '/') |
| @@ -643,7 +643,7 @@ static ssize_t http_handle_announce(const int64 sock, struct ot_workstruct * | |||
| 643 | if (!parsed) | 643 | if (!parsed) |
| 644 | HTTPERROR_400_PARAM; | 644 | HTTPERROR_400_PARAM; |
| 645 | bits = (signed short)value; | 645 | bits = (signed short)value; |
| 646 | if (ip6_isv4mapped(net.address)) | 646 | if (ip_is_v4mapped(net.address)) |
| 647 | bits += 96; | 647 | bits += 96; |
| 648 | } | 648 | } |
| 649 | net.bits = bits; | 649 | net.bits = bits; |
| @@ -0,0 +1,201 @@ | |||
| 1 | /* This software was written by Dirk Engling <erdgeist@erdgeist.org> | ||
| 2 | It is considered beerware. Prost. Skol. Cheers or whatever. | ||
| 3 | |||
| 4 | $id$ */ | ||
| 5 | |||
| 6 | /* System */ | ||
| 7 | #include <stdint.h> | ||
| 8 | #include <string.h> | ||
| 9 | |||
| 10 | /* Opentracker */ | ||
| 11 | #include "ot_hex.h" | ||
| 12 | #include "ot_ip.h" | ||
| 13 | |||
| 14 | const char ip_v4mapped_prefix[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}; | ||
| 15 | |||
| 16 | /* The dotted quad is only ever reached through the v4 mapped form, so both | ||
| 17 | halves of it stay in here */ | ||
| 18 | |||
| 19 | static size_t ip4_format(char *dest, const uint8_t *ip) { | ||
| 20 | char *d = dest; | ||
| 21 | int i; | ||
| 22 | |||
| 23 | for (i = 0; i < 4; ++i) { | ||
| 24 | unsigned int octet = ip[i]; | ||
| 25 | |||
| 26 | if (i) | ||
| 27 | *d++ = '.'; | ||
| 28 | if (octet >= 100) | ||
| 29 | *d++ = (char)('0' + octet / 100); | ||
| 30 | if (octet >= 10) | ||
| 31 | *d++ = (char)('0' + (octet / 10) % 10); | ||
| 32 | *d++ = (char)('0' + octet % 10); | ||
| 33 | } | ||
| 34 | |||
| 35 | return (size_t)(d - dest); | ||
| 36 | } | ||
| 37 | |||
| 38 | static size_t ip4_scan(const char *src, uint8_t ip[4]) { | ||
| 39 | uint8_t octets[4]; | ||
| 40 | const char *s = src; | ||
| 41 | int i; | ||
| 42 | |||
| 43 | for (i = 0; i < 4; ++i) { | ||
| 44 | unsigned int value = 0; | ||
| 45 | int digits = 0; | ||
| 46 | |||
| 47 | if (i && *s++ != '.') | ||
| 48 | return 0; | ||
| 49 | |||
| 50 | /* Leading zeros are tolerated, a value beyond one octet is not */ | ||
| 51 | while (*s >= '0' && *s <= '9' && digits < 4) { | ||
| 52 | value = value * 10 + (unsigned int)(*s++ - '0'); | ||
| 53 | ++digits; | ||
| 54 | } | ||
| 55 | if (!digits || value > 255) | ||
| 56 | return 0; | ||
| 57 | |||
| 58 | octets[i] = (uint8_t)value; | ||
| 59 | } | ||
| 60 | |||
| 61 | memcpy(ip, octets, sizeof(octets)); | ||
| 62 | return (size_t)(s - src); | ||
| 63 | } | ||
| 64 | |||
| 65 | static unsigned int group_at(const char *ip, int n) { return ((unsigned int)(uint8_t)ip[2 * n] << 8) | (uint8_t)ip[2 * n + 1]; } | ||
| 66 | |||
| 67 | size_t ip_format(char *dest, const ot_ip6 ip) { | ||
| 68 | static const char hexdigit[] = "0123456789abcdef"; | ||
| 69 | char *d = dest; | ||
| 70 | int best_start = 0, best_len = 0, i = 0; | ||
| 71 | |||
| 72 | if (ip_is_v4mapped(ip)) | ||
| 73 | return ip4_format(dest, (const uint8_t *)ip + sizeof(ip_v4mapped_prefix)); | ||
| 74 | |||
| 75 | /* RFC 5952 4.2: the longest run of zero groups becomes "::", never a run | ||
| 76 | of one, and the first of two equal runs wins */ | ||
| 77 | while (i < 8) { | ||
| 78 | int j = i; | ||
| 79 | |||
| 80 | if (group_at(ip, i)) { | ||
| 81 | ++i; | ||
| 82 | continue; | ||
| 83 | } | ||
| 84 | while (j < 8 && !group_at(ip, j)) | ||
| 85 | ++j; | ||
| 86 | if (j - i > best_len) { | ||
| 87 | best_len = j - i; | ||
| 88 | best_start = i; | ||
| 89 | } | ||
| 90 | i = j; | ||
| 91 | } | ||
| 92 | if (best_len < 2) | ||
| 93 | best_len = 0; | ||
| 94 | |||
| 95 | for (i = 0; i < 8; ++i) { | ||
| 96 | unsigned int group; | ||
| 97 | int shift = 12; | ||
| 98 | |||
| 99 | if (best_len && i == best_start) { | ||
| 100 | *d++ = ':'; | ||
| 101 | if (i + best_len == 8) | ||
| 102 | *d++ = ':'; /* nothing follows, so close the run */ | ||
| 103 | i += best_len - 1; | ||
| 104 | continue; | ||
| 105 | } | ||
| 106 | |||
| 107 | if (i) | ||
| 108 | *d++ = ':'; | ||
| 109 | |||
| 110 | group = group_at(ip, i); | ||
| 111 | while (shift && !(group >> shift)) | ||
| 112 | shift -= 4; /* RFC 5952 4.1: no leading zeros */ | ||
| 113 | for (;; shift -= 4) { | ||
| 114 | *d++ = hexdigit[(group >> shift) & 15]; | ||
| 115 | if (!shift) | ||
| 116 | break; | ||
| 117 | } | ||
| 118 | } | ||
| 119 | |||
| 120 | return (size_t)(d - dest); | ||
| 121 | } | ||
| 122 | |||
| 123 | size_t ip_scan(const char *src, ot_ip6 ip) { | ||
| 124 | uint8_t prefix[16], suffix[16]; | ||
| 125 | size_t prefixlen = 0, suffixlen = 0; | ||
| 126 | const char *s = src; | ||
| 127 | int have_gap = 0; | ||
| 128 | int need_colon = 0; | ||
| 129 | |||
| 130 | /* A plain IPv4 address is an address too, stored v4 mapped */ | ||
| 131 | { | ||
| 132 | size_t consumed = ip4_scan(src, prefix); | ||
| 133 | if (consumed) { | ||
| 134 | memcpy(ip, ip_v4mapped_prefix, sizeof(ip_v4mapped_prefix)); | ||
| 135 | memcpy(ip + sizeof(ip_v4mapped_prefix), prefix, 4); | ||
| 136 | return consumed; | ||
| 137 | } | ||
| 138 | } | ||
| 139 | |||
| 140 | for (;;) { | ||
| 141 | unsigned int value = 0; | ||
| 142 | int digits = 0, nibble; | ||
| 143 | uint8_t *into = have_gap ? suffix : prefix; | ||
| 144 | size_t *fill = have_gap ? &suffixlen : &prefixlen; | ||
| 145 | |||
| 146 | /* RFC 4291 2.2: one run of zero groups may be written "::" */ | ||
| 147 | if (s[0] == ':' && s[1] == ':') { | ||
| 148 | if (have_gap) | ||
| 149 | return 0; | ||
| 150 | have_gap = 1; | ||
| 151 | need_colon = 0; | ||
| 152 | s += 2; | ||
| 153 | continue; | ||
| 154 | } | ||
| 155 | |||
| 156 | if (need_colon) { | ||
| 157 | if (*s != ':') | ||
| 158 | break; | ||
| 159 | ++s; | ||
| 160 | } | ||
| 161 | |||
| 162 | /* RFC 4291 2.2 form 3: the final two groups may be a dotted quad */ | ||
| 163 | if (prefixlen + suffixlen + 4 <= 16) { | ||
| 164 | size_t consumed = ip4_scan(s, into + *fill); | ||
| 165 | if (consumed) { | ||
| 166 | *fill += 4; | ||
| 167 | s += consumed; | ||
| 168 | break; | ||
| 169 | } | ||
| 170 | } | ||
| 171 | |||
| 172 | while (digits < 4 && (nibble = hex_value(*s)) >= 0) { | ||
| 173 | value = value * 16 + (unsigned int)nibble; | ||
| 174 | ++digits; | ||
| 175 | ++s; | ||
| 176 | } | ||
| 177 | if (!digits) { | ||
| 178 | if (need_colon) | ||
| 179 | --s; /* leave the separator we ate for the caller */ | ||
| 180 | break; | ||
| 181 | } | ||
| 182 | |||
| 183 | if (prefixlen + suffixlen + 2 > 16) | ||
| 184 | return 0; | ||
| 185 | |||
| 186 | into[(*fill)++] = (uint8_t)(value >> 8); | ||
| 187 | into[(*fill)++] = (uint8_t)value; | ||
| 188 | need_colon = 1; | ||
| 189 | } | ||
| 190 | |||
| 191 | if (!prefixlen && !suffixlen && !have_gap) | ||
| 192 | return 0; | ||
| 193 | if (!have_gap && prefixlen + suffixlen != 16) | ||
| 194 | return 0; /* without "::" every group has to be spelled out */ | ||
| 195 | |||
| 196 | memset(ip, 0, 16); | ||
| 197 | memcpy(ip, prefix, prefixlen); | ||
| 198 | memcpy(ip + 16 - suffixlen, suffix, suffixlen); | ||
| 199 | |||
| 200 | return (size_t)(s - src); | ||
| 201 | } | ||
| @@ -0,0 +1,33 @@ | |||
| 1 | /* This software was written by Dirk Engling <erdgeist@erdgeist.org> | ||
| 2 | It is considered beerware. Prost. Skol. Cheers or whatever. | ||
| 3 | |||
| 4 | $id$ */ | ||
| 5 | |||
| 6 | #ifndef OT_IP_H__ | ||
| 7 | #define OT_IP_H__ | ||
| 8 | |||
| 9 | #include <stddef.h> | ||
| 10 | #include <string.h> | ||
| 11 | |||
| 12 | #include "trackerlogic.h" | ||
| 13 | |||
| 14 | /* opentracker holds every address as sixteen bytes, writing IPv4 as the v4 | ||
| 15 | mapped form of RFC 4291 section 2.5.5.2. */ | ||
| 16 | extern const char ip_v4mapped_prefix[12]; | ||
| 17 | |||
| 18 | static inline int ip_is_v4mapped(const void *ip) { return !memcmp(ip, ip_v4mapped_prefix, sizeof(ip_v4mapped_prefix)); } | ||
| 19 | |||
| 20 | /* Read an address and return how many characters it took, or zero if src | ||
| 21 | does not start with one. A plain IPv4 address is accepted and stored in | ||
| 22 | its v4 mapped form. | ||
| 23 | |||
| 24 | The count lets the caller carry on where the address ended, which is how | ||
| 25 | "address:port" and "address/bits" are read. */ | ||
| 26 | size_t ip_scan(const char *src, ot_ip6 ip); | ||
| 27 | |||
| 28 | /* Write an address and return how many characters it took. Nothing is | ||
| 29 | terminated, so a caller may keep appending. A v4 mapped address is written | ||
| 30 | as the plain dotted quad rather than "::ffff:1.2.3.4". */ | ||
| 31 | size_t ip_format(char *dest, const ot_ip6 ip); | ||
| 32 | |||
| 33 | #endif | ||
diff --git a/ot_livesync.c b/ot_livesync.c index c4dc6e5..f6bb28b 100644 --- a/ot_livesync.c +++ b/ot_livesync.c | |||
| @@ -13,11 +13,11 @@ | |||
| 13 | #include <unistd.h> | 13 | #include <unistd.h> |
| 14 | 14 | ||
| 15 | /* Libowfat */ | 15 | /* Libowfat */ |
| 16 | #include "ip6.h" | ||
| 17 | #include "socket.h" | 16 | #include "socket.h" |
| 18 | 17 | ||
| 19 | /* Opentracker */ | 18 | /* Opentracker */ |
| 20 | #include "ot_accesslist.h" | 19 | #include "ot_accesslist.h" |
| 20 | #include "ot_ip.h" | ||
| 21 | #include "ot_livesync.h" | 21 | #include "ot_livesync.h" |
| 22 | #include "ot_mutex.h" | 22 | #include "ot_mutex.h" |
| 23 | #include "ot_stats.h" | 23 | #include "ot_stats.h" |
| @@ -92,7 +92,7 @@ void livesync_bind_mcast(ot_ip6 ip, uint16_t port) { | |||
| 92 | char tmpip[4] = {0, 0, 0, 0}; | 92 | char tmpip[4] = {0, 0, 0, 0}; |
| 93 | char *v4ip; | 93 | char *v4ip; |
| 94 | 94 | ||
| 95 | if (!ip6_isv4mapped(ip)) | 95 | if (!ip_is_v4mapped(ip)) |
| 96 | exerr("v6 mcast support not yet available."); | 96 | exerr("v6 mcast support not yet available."); |
| 97 | v4ip = ip + 12; | 97 | v4ip = ip + 12; |
| 98 | 98 | ||
| @@ -140,14 +140,14 @@ static void livesync_handle_peersync(struct ot_workstruct *ws, size_t peer_size) | |||
| 140 | 140 | ||
| 141 | /* Prepare peer record for v4mapped expansion */ | 141 | /* Prepare peer record for v4mapped expansion */ |
| 142 | if (peer_size == OT_PEER_SIZE4) | 142 | if (peer_size == OT_PEER_SIZE4) |
| 143 | memcpy(&ws->peer, V4mappedprefix, sizeof(V4mappedprefix)); | 143 | memcpy(&ws->peer, ip_v4mapped_prefix, sizeof(ip_v4mapped_prefix)); |
| 144 | 144 | ||
| 145 | /* Now basic sanity checks have been done on the live sync packet | 145 | /* Now basic sanity checks have been done on the live sync packet |
| 146 | We might add more testing and logging. */ | 146 | We might add more testing and logging. */ |
| 147 | while ((ssize_t)(off + sizeof(ot_hash) + peer_size) <= ws->request_size) { | 147 | while ((ssize_t)(off + sizeof(ot_hash) + peer_size) <= ws->request_size) { |
| 148 | char *peer_ip = ws->request + off + sizeof(ot_hash); | 148 | char *peer_ip = ws->request + off + sizeof(ot_hash); |
| 149 | if (peer_size == OT_PEER_SIZE4) | 149 | if (peer_size == OT_PEER_SIZE4) |
| 150 | memcpy(&ws->peer[0] + sizeof(V4mappedprefix), peer_ip, peer_size); | 150 | memcpy(&ws->peer[0] + sizeof(ip_v4mapped_prefix), peer_ip, peer_size); |
| 151 | else | 151 | else |
| 152 | memcpy(&ws->peer, peer_ip, peer_size); | 152 | memcpy(&ws->peer, peer_ip, peer_size); |
| 153 | ws->hash = (ot_hash *)(ws->request + off); | 153 | ws->hash = (ot_hash *)(ws->request + off); |
| @@ -215,7 +215,7 @@ static void *livesync_worker(void *args) { | |||
| 215 | ws.inbuf = ws.request = malloc(LIVESYNC_INCOMING_BUFFSIZE); | 215 | ws.inbuf = ws.request = malloc(LIVESYNC_INCOMING_BUFFSIZE); |
| 216 | ws.outbuf = ws.reply = 0; | 216 | ws.outbuf = ws.reply = 0; |
| 217 | 217 | ||
| 218 | memcpy(in_ip, V4mappedprefix, sizeof(V4mappedprefix)); | 218 | memcpy(in_ip, ip_v4mapped_prefix, sizeof(ip_v4mapped_prefix)); |
| 219 | 219 | ||
| 220 | while (1) { | 220 | while (1) { |
| 221 | uint32_t packet_type; | 221 | uint32_t packet_type; |
| @@ -18,13 +18,12 @@ | |||
| 18 | 18 | ||
| 19 | /* Libowfat */ | 19 | /* Libowfat */ |
| 20 | #include "io.h" | 20 | #include "io.h" |
| 21 | #include "ip4.h" | ||
| 22 | #include "ip6.h" | ||
| 23 | 21 | ||
| 24 | /* Opentracker */ | 22 | /* Opentracker */ |
| 25 | #include "ot_accesslist.h" | 23 | #include "ot_accesslist.h" |
| 26 | #include "ot_hex.h" | 24 | #include "ot_hex.h" |
| 27 | #include "ot_iovec.h" | 25 | #include "ot_iovec.h" |
| 26 | #include "ot_ip.h" | ||
| 28 | #include "ot_mutex.h" | 27 | #include "ot_mutex.h" |
| 29 | #include "ot_stats.h" | 28 | #include "ot_stats.h" |
| 30 | #include "trackerlogic.h" | 29 | #include "trackerlogic.h" |
| @@ -206,7 +205,7 @@ static size_t stats_return_busy_networks(char *reply, stats_network_node *tree, | |||
| 206 | if (scores[i - 1]) { | 205 | if (scores[i - 1]) { |
| 207 | r += sprintf(r, "%08zd: ", scores[i - 1]); | 206 | r += sprintf(r, "%08zd: ", scores[i - 1]); |
| 208 | // #ifdef WANT_V6 | 207 | // #ifdef WANT_V6 |
| 209 | r += fmt_ip6c(r, networks[i - 1]); | 208 | r += ip_format(r, networks[i - 1]); |
| 210 | #if 0 | 209 | #if 0 |
| 211 | // XXX | 210 | // XXX |
| 212 | r += fmt_ip4( r, networks[i - 1]); | 211 | r += fmt_ip4( r, networks[i - 1]); |
| @@ -470,7 +469,7 @@ static void stats_return_fulllog(size_t *iovec_entries, struct iovec **iovector, | |||
| 470 | re = r + 32 * OT_STATS_TMPSIZE; | 469 | re = r + 32 * OT_STATS_TMPSIZE; |
| 471 | } | 470 | } |
| 472 | r += sprintf(r, "%08ld: ", loglist->time); | 471 | r += sprintf(r, "%08ld: ", loglist->time); |
| 473 | r += fmt_ip6c(r, loglist->ip); | 472 | r += ip_format(r, loglist->ip); |
| 474 | *r++ = '\n'; | 473 | *r++ = '\n'; |
| 475 | memcpy(r, loglist->data, loglist->size); | 474 | memcpy(r, loglist->data, loglist->size); |
| 476 | r += loglist->size; | 475 | r += loglist->size; |
| @@ -663,7 +662,7 @@ void stats_issue_event(ot_status_event event, PROTO_FLAG proto, uintptr_t event_ | |||
| 663 | *peerid_hex = 0; | 662 | *peerid_hex = 0; |
| 664 | } | 663 | } |
| 665 | 664 | ||
| 666 | ip_readable[fmt_ip6c(ip_readable, (char *)&ws->peer)] = 0; | 665 | ip_readable[ip_format(ip_readable, (char *)&ws->peer)] = 0; |
| 667 | #if 0 | 666 | #if 0 |
| 668 | /* XXX */ | 667 | /* XXX */ |
| 669 | ip_readable[ fmt_ip4( ip_readable, (char*)&ws->peer ) ] = 0; | 668 | ip_readable[ fmt_ip4( ip_readable, (char*)&ws->peer ) ] = 0; |
| @@ -687,7 +686,7 @@ void stats_issue_event(ot_status_event event, PROTO_FLAG proto, uintptr_t event_ | |||
| 687 | ot_ip6 *ip = (ot_ip6 *)event_data; /* ugly hack to transfer ip to stats */ | 686 | ot_ip6 *ip = (ot_ip6 *)event_data; /* ugly hack to transfer ip to stats */ |
| 688 | char _debug[512]; | 687 | char _debug[512]; |
| 689 | int off = snprintf(_debug, sizeof(_debug), "[%08d] scrp: ", (unsigned int)(g_now_seconds - ot_start_time) / 60); | 688 | int off = snprintf(_debug, sizeof(_debug), "[%08d] scrp: ", (unsigned int)(g_now_seconds - ot_start_time) / 60); |
| 690 | off += fmt_ip6c(_debug + off, *ip); | 689 | off += ip_format(_debug + off, *ip); |
| 691 | off += snprintf(_debug + off, sizeof(_debug) - off, " - FULL SCRAPE\n"); | 690 | off += snprintf(_debug + off, sizeof(_debug) - off, " - FULL SCRAPE\n"); |
| 692 | (void)write(2, _debug, off); | 691 | (void)write(2, _debug, off); |
| 693 | ot_full_scrape_request_count++; | 692 | ot_full_scrape_request_count++; |
| @@ -696,7 +695,7 @@ void stats_issue_event(ot_status_event event, PROTO_FLAG proto, uintptr_t event_ | |||
| 696 | ot_ip6 *ip = (ot_ip6 *)event_data; /* ugly hack to transfer ip to stats */ | 695 | ot_ip6 *ip = (ot_ip6 *)event_data; /* ugly hack to transfer ip to stats */ |
| 697 | char _debug[512]; | 696 | char _debug[512]; |
| 698 | int off = snprintf(_debug, sizeof(_debug), "[%08d] scrp: ", (unsigned int)(g_now_seconds - ot_start_time) / 60); | 697 | int off = snprintf(_debug, sizeof(_debug), "[%08d] scrp: ", (unsigned int)(g_now_seconds - ot_start_time) / 60); |
| 699 | off += fmt_ip6c(_debug + off, *ip); | 698 | off += ip_format(_debug + off, *ip); |
| 700 | off += snprintf(_debug + off, sizeof(_debug) - off, " - FULL SCRAPE\n"); | 699 | off += snprintf(_debug + off, sizeof(_debug) - off, " - FULL SCRAPE\n"); |
| 701 | (void)write(2, _debug, off); | 700 | (void)write(2, _debug, off); |
| 702 | ot_full_scrape_request_count++; | 701 | ot_full_scrape_request_count++; |
| @@ -12,10 +12,10 @@ | |||
| 12 | 12 | ||
| 13 | /* Libowfat */ | 13 | /* Libowfat */ |
| 14 | #include "io.h" | 14 | #include "io.h" |
| 15 | #include "ip6.h" | ||
| 16 | #include "socket.h" | 15 | #include "socket.h" |
| 17 | 16 | ||
| 18 | /* Opentracker */ | 17 | /* Opentracker */ |
| 18 | #include "ot_ip.h" | ||
| 19 | #include "ot_random.h" | 19 | #include "ot_random.h" |
| 20 | #include "ot_rijndael.h" | 20 | #include "ot_rijndael.h" |
| 21 | #include "ot_stats.h" | 21 | #include "ot_stats.h" |
| @@ -176,7 +176,7 @@ int handle_udp6(int64 serversocket, struct ot_workstruct *ws) { | |||
| 176 | } else { | 176 | } else { |
| 177 | /* Limit amount of peers to OT_MAX_PEERS_UDP */ | 177 | /* Limit amount of peers to OT_MAX_PEERS_UDP */ |
| 178 | uint32_t numwant = ntohl(inpacket[92 / 4]); | 178 | uint32_t numwant = ntohl(inpacket[92 / 4]); |
| 179 | size_t max_peers = ip6_isv4mapped(remoteip) ? OT_MAX_PEERS_UDP4 : OT_MAX_PEERS_UDP6; | 179 | size_t max_peers = ip_is_v4mapped(remoteip) ? OT_MAX_PEERS_UDP4 : OT_MAX_PEERS_UDP6; |
| 180 | if (numwant > max_peers) | 180 | if (numwant > max_peers) |
| 181 | numwant = max_peers; | 181 | numwant = max_peers; |
| 182 | 182 | ||
diff --git a/ot_vector.c b/ot_vector.c index e3c3d3f..c4cd171 100644 --- a/ot_vector.c +++ b/ot_vector.c | |||
| @@ -156,8 +156,6 @@ void vector_remove_torrent(ot_vector *vector, ot_torrent *match) { | |||
| 156 | if (!vector->size) | 156 | if (!vector->size) |
| 157 | return; | 157 | return; |
| 158 | 158 | ||
| 159 | /* If this is being called after a unsuccessful malloc() for peer_list | ||
| 160 | in add_peer_to_torrent, match->peer_list actually might be NULL */ | ||
| 161 | free_peerlist(match->peer_list6); | 159 | free_peerlist(match->peer_list6); |
| 162 | free_peerlist(match->peer_list4); | 160 | free_peerlist(match->peer_list4); |
| 163 | 161 | ||
| @@ -19,13 +19,13 @@ | |||
| 19 | /* Libowfat */ | 19 | /* Libowfat */ |
| 20 | #include "io.h" | 20 | #include "io.h" |
| 21 | #include "iob.h" | 21 | #include "iob.h" |
| 22 | #include "ip6.h" | ||
| 23 | #include "socket.h" | 22 | #include "socket.h" |
| 24 | 23 | ||
| 25 | /* Opentracker */ | 24 | /* Opentracker */ |
| 25 | #include "ot_ip.h" | ||
| 26 | #include "ot_mutex.h" | 26 | #include "ot_mutex.h" |
| 27 | #include "ot_scan.h" | ||
| 28 | #include "ot_random.h" | 27 | #include "ot_random.h" |
| 28 | #include "ot_scan.h" | ||
| 29 | #include "ot_stats.h" | 29 | #include "ot_stats.h" |
| 30 | #include "ot_vector.h" | 30 | #include "ot_vector.h" |
| 31 | #include "trackerlogic.h" | 31 | #include "trackerlogic.h" |
| @@ -92,7 +92,7 @@ void livesync_bind_mcast(ot_ip6 ip, uint16_t port) { | |||
| 92 | char tmpip[4] = {0, 0, 0, 0}; | 92 | char tmpip[4] = {0, 0, 0, 0}; |
| 93 | char *v4ip; | 93 | char *v4ip; |
| 94 | 94 | ||
| 95 | if (!ip6_isv4mapped(ip)) | 95 | if (!ip_is_v4mapped(ip)) |
| 96 | exerr("v6 mcast support not yet available."); | 96 | exerr("v6 mcast support not yet available."); |
| 97 | v4ip = ip + 12; | 97 | v4ip = ip + 12; |
| 98 | 98 | ||
| @@ -539,14 +539,14 @@ static int scan_ip6_port(const char *src, ot_ip6 ip, uint16_t *port) { | |||
| 539 | ++s; | 539 | ++s; |
| 540 | if (*s == '[') | 540 | if (*s == '[') |
| 541 | ++s, ++bracket; /* for v6 style notation */ | 541 | ++s, ++bracket; /* for v6 style notation */ |
| 542 | if (!(off = scan_ip6(s, ip))) | 542 | if (!(off = ip_scan(s, ip))) |
| 543 | return 0; | 543 | return 0; |
| 544 | s += off; | 544 | s += off; |
| 545 | if (*s == 0 || isspace(*s)) | 545 | if (*s == 0 || isspace(*s)) |
| 546 | return s - src; | 546 | return s - src; |
| 547 | if (*s == ']' && bracket) | 547 | if (*s == ']' && bracket) |
| 548 | ++s; | 548 | ++s; |
| 549 | if (!ip6_isv4mapped(ip)) { | 549 | if (!ip_is_v4mapped(ip)) { |
| 550 | if ((bracket && *(s) != ':') || (*(s) != '.')) | 550 | if ((bracket && *(s) != ':') || (*(s) != '.')) |
| 551 | return 0; | 551 | return 0; |
| 552 | s++; | 552 | s++; |
diff --git a/tests/runner.c b/tests/runner.c index 25456bc..10b6625 100644 --- a/tests/runner.c +++ b/tests/runner.c | |||
| @@ -21,6 +21,7 @@ static const struct module modules[] = {{"scan_urlencoded_query", test_scan_urle | |||
| 21 | {"ot_hex", test_hex}, | 21 | {"ot_hex", test_hex}, |
| 22 | {"ot_scan", test_scan}, | 22 | {"ot_scan", test_scan}, |
| 23 | {"ot_buf", test_buf}, | 23 | {"ot_buf", test_buf}, |
| 24 | {"ot_ip", test_ip}, | ||
| 24 | {"ot_accesslist", test_accesslist}, | 25 | {"ot_accesslist", test_accesslist}, |
| 25 | {NULL, NULL}}; | 26 | {NULL, NULL}}; |
| 26 | 27 | ||
diff --git a/tests/t_ip.c b/tests/t_ip.c new file mode 100644 index 0000000..2fe3a72 --- /dev/null +++ b/tests/t_ip.c | |||
| @@ -0,0 +1,217 @@ | |||
| 1 | /* This software was written by Dirk Engling <erdgeist@erdgeist.org> | ||
| 2 | It is considered beerware. Prost. Skol. Cheers or whatever. | ||
| 3 | |||
| 4 | $id$ */ | ||
| 5 | |||
| 6 | /* System */ | ||
| 7 | #include <stdint.h> | ||
| 8 | #include <string.h> | ||
| 9 | |||
| 10 | /* Opentracker */ | ||
| 11 | #include "ot_ip.h" | ||
| 12 | #include "test.h" | ||
| 13 | |||
| 14 | static char text[64]; | ||
| 15 | |||
| 16 | static const char *formatted(const char *ip) { | ||
| 17 | text[ip_format(text, ip)] = 0; | ||
| 18 | return text; | ||
| 19 | } | ||
| 20 | |||
| 21 | /* ------------------------------------------------------------------ IPv4 */ | ||
| 22 | |||
| 23 | /* ------------------------------------------------------- RFC 5952 output */ | ||
| 24 | |||
| 25 | static void case_format_rfc5952(void) { | ||
| 26 | test_case("4.1 leading zeros in a group are suppressed"); | ||
| 27 | CHECK_STR(formatted("\x20\x01\x0d\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"), "2001:db8::1"); | ||
| 28 | |||
| 29 | test_case("4.2.1 the longest run of zero groups becomes ::"); | ||
| 30 | CHECK_STR(formatted("\x20\x01\x0d\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x01"), "2001:db8::2:1"); | ||
| 31 | |||
| 32 | test_case("4.2.2 a single zero group is never shortened"); | ||
| 33 | CHECK_STR(formatted("\x20\x01\x0d\xb8\x00\x00\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01"), "2001:db8:0:1:1:1:1:1"); | ||
| 34 | |||
| 35 | test_case("4.2.1 a longer run wins over an earlier shorter one"); | ||
| 36 | CHECK_STR(formatted("\x20\x01\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01"), "2001:0:0:1::1"); | ||
| 37 | |||
| 38 | test_case("4.2.3 of two runs of equal length the first is shortened"); | ||
| 39 | CHECK_STR(formatted("\x20\x01\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x00\x01"), "2001::1:0:0:1:1"); | ||
| 40 | |||
| 41 | test_case("4.3 hexadecimal digits are lower case"); | ||
| 42 | CHECK_STR(formatted("\xab\xcd\xef\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"), "abcd:ef01::1"); | ||
| 43 | |||
| 44 | test_case("the unspecified and loopback addresses"); | ||
| 45 | CHECK_STR(formatted("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"), "::"); | ||
| 46 | CHECK_STR(formatted("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"), "::1"); | ||
| 47 | |||
| 48 | test_case("a full address with no zero group"); | ||
| 49 | CHECK_STR(formatted("\x11\x11\x22\x22\x33\x33\x44\x44\x55\x55\x66\x66\x77\x77\x88\x88"), "1111:2222:3333:4444:5555:6666:7777:8888"); | ||
| 50 | } | ||
| 51 | |||
| 52 | static void case_format_trailing_zero_group(void) { | ||
| 53 | /* libowfat's formatter looked two bytes past the address to decide this | ||
| 54 | one, so a peer address ending in a zero group came out as "::" whenever | ||
| 55 | the bytes that happened to follow were not themselves zero. In | ||
| 56 | ot_stats.c those bytes are the peer's port. */ | ||
| 57 | const char ip[] = "\x20\x01\x0d\xb8\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x00"; | ||
| 58 | |||
| 59 | test_case("a single trailing zero group is written out, not shortened"); | ||
| 60 | CHECK_STR(formatted(ip), "2001:db8:1:2:3:4:5:0"); | ||
| 61 | |||
| 62 | test_case("and nothing beyond the sixteen bytes is consulted"); | ||
| 63 | { | ||
| 64 | char padded[20]; | ||
| 65 | memcpy(padded, ip, 16); | ||
| 66 | memset(padded + 16, 0xff, 4); /* a port and flags, as a peer record has */ | ||
| 67 | CHECK_STR(formatted(padded), "2001:db8:1:2:3:4:5:0"); | ||
| 68 | memset(padded + 16, 0x00, 4); | ||
| 69 | CHECK_STR(formatted(padded), "2001:db8:1:2:3:4:5:0"); | ||
| 70 | } | ||
| 71 | } | ||
| 72 | |||
| 73 | static void case_v4mapped(void) { | ||
| 74 | const char mapped[] = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x0a\x00\x00\x01"; | ||
| 75 | const char unmapped[] = "\x20\x01\x0d\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"; | ||
| 76 | |||
| 77 | test_case("a v4 mapped address is recognised"); | ||
| 78 | CHECK(ip_is_v4mapped(mapped)); | ||
| 79 | CHECK_INT(ip_is_v4mapped(unmapped), 0); | ||
| 80 | |||
| 81 | /* The tracker has only ever shown the plain quad, so that is the one | ||
| 82 | form the formatter produces; "::ffff:10.0.0.1" is not written anywhere */ | ||
| 83 | test_case("a mapped address is written as the plain dotted quad"); | ||
| 84 | CHECK_STR(formatted(mapped), "10.0.0.1"); | ||
| 85 | CHECK_STR(formatted("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00"), "0.0.0.0"); | ||
| 86 | CHECK_STR(formatted("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff"), "255.255.255.255"); | ||
| 87 | |||
| 88 | test_case("anything else follows RFC 5952"); | ||
| 89 | CHECK_STR(formatted(unmapped), "2001:db8::1"); | ||
| 90 | } | ||
| 91 | |||
| 92 | /* -------------------------------------------------------- RFC 4291 input */ | ||
| 93 | |||
| 94 | static void case_scan_forms(void) { | ||
| 95 | char ip[16]; | ||
| 96 | |||
| 97 | test_case("2.2 form 1, every group spelled out"); | ||
| 98 | CHECK_INT(ip_scan("1111:2222:3333:4444:5555:6666:7777:8888", ip), 39); | ||
| 99 | CHECK_MEM(ip, "\x11\x11\x22\x22\x33\x33\x44\x44\x55\x55\x66\x66\x77\x77\x88\x88", 16); | ||
| 100 | |||
| 101 | test_case("2.2 form 2, zero groups abbreviated"); | ||
| 102 | CHECK_INT(ip_scan("2001:db8::1", ip), 11); | ||
| 103 | CHECK_MEM(ip, "\x20\x01\x0d\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", 16); | ||
| 104 | CHECK_INT(ip_scan("::1", ip), 3); | ||
| 105 | CHECK_MEM(ip, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", 16); | ||
| 106 | CHECK_INT(ip_scan("::", ip), 2); | ||
| 107 | CHECK_MEM(ip, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16); | ||
| 108 | CHECK_INT(ip_scan("1::", ip), 3); | ||
| 109 | CHECK_MEM(ip, "\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16); | ||
| 110 | |||
| 111 | test_case("2.2 form 3, a dotted quad in the last two groups"); | ||
| 112 | CHECK_INT(ip_scan("::ffff:1.2.3.4", ip), 14); | ||
| 113 | CHECK_MEM(ip, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x01\x02\x03\x04", 16); | ||
| 114 | CHECK_INT(ip_scan("1:2:3:4:5:6:1.2.3.4", ip), 19); | ||
| 115 | CHECK_MEM(ip, "\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x01\x02\x03\x04", 16); | ||
| 116 | |||
| 117 | test_case("upper case input is accepted"); | ||
| 118 | CHECK_INT(ip_scan("2001:DB8::1", ip), 11); | ||
| 119 | CHECK_MEM(ip, "\x20\x01\x0d\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", 16); | ||
| 120 | } | ||
| 121 | |||
| 122 | static void case_scan_accepts_bare_ipv4(void) { | ||
| 123 | char ip[16]; | ||
| 124 | |||
| 125 | /* Every address opentracker holds is sixteen bytes, so an operator writing | ||
| 126 | a plain IPv4 address in the config has to land as the v4 mapped form */ | ||
| 127 | test_case("a bare IPv4 address is stored v4 mapped"); | ||
| 128 | CHECK_INT(ip_scan("10.0.0.1", ip), 8); | ||
| 129 | CHECK_MEM(ip, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x0a\x00\x00\x01", 16); | ||
| 130 | CHECK(ip_is_v4mapped(ip)); | ||
| 131 | } | ||
| 132 | |||
| 133 | static void case_scan_reports_length(void) { | ||
| 134 | char ip[16]; | ||
| 135 | |||
| 136 | /* The config parser continues from where the address ended, which is how | ||
| 137 | "address:port" and "address/bits" are read */ | ||
| 138 | test_case("scanning stops at the character after the address"); | ||
| 139 | CHECK_INT(ip_scan("10.0.0.1:6969", ip), 8); | ||
| 140 | CHECK_INT(ip_scan("2001:db8::1/64", ip), 11); | ||
| 141 | CHECK_INT(ip_scan("::1]", ip), 3); | ||
| 142 | CHECK_INT(ip_scan("1:2:3:4:5:6:7:8 trailing", ip), 15); | ||
| 143 | } | ||
| 144 | |||
| 145 | static void case_scan_rejects(void) { | ||
| 146 | char ip[16]; | ||
| 147 | |||
| 148 | test_case("an empty or junk string is refused"); | ||
| 149 | CHECK_INT(ip_scan("", ip), 0); | ||
| 150 | CHECK_INT(ip_scan("x", ip), 0); | ||
| 151 | CHECK_INT(ip_scan(":", ip), 0); | ||
| 152 | CHECK_INT(ip_scan(":1:2", ip), 0); | ||
| 153 | |||
| 154 | test_case("too few groups without :: are refused"); | ||
| 155 | CHECK_INT(ip_scan("1:2:3:4:5:6:7", ip), 0); | ||
| 156 | CHECK_INT(ip_scan("2001:db8:1", ip), 0); | ||
| 157 | |||
| 158 | /* libowfat accepted a prefix of each of these and carried on. Taking only | ||
| 159 | part of a malformed address is worse than refusing it, especially where | ||
| 160 | the text comes from a config file or an X-Forwarded-For header. */ | ||
| 161 | test_case("a second :: is refused rather than truncated"); | ||
| 162 | CHECK_INT(ip_scan("1::2::3", ip), 0); | ||
| 163 | CHECK_INT(ip_scan("::1::", ip), 0); | ||
| 164 | CHECK_INT(ip_scan("::::", ip), 0); | ||
| 165 | |||
| 166 | test_case("more than eight groups is refused"); | ||
| 167 | CHECK_INT(ip_scan("1:2:3:4:5:6:7:8:9", ip), 0); | ||
| 168 | |||
| 169 | test_case("a group of more than four digits is refused, not truncated"); | ||
| 170 | CHECK_INT(ip_scan("12345::1", ip), 0); | ||
| 171 | CHECK_INT(ip_scan("fffff::1", ip), 0); | ||
| 172 | } | ||
| 173 | |||
| 174 | static void case_round_trip(void) { | ||
| 175 | /* Whatever the formatter writes, the scanner has to read back */ | ||
| 176 | static const char *const samples[] = {"::", | ||
| 177 | "::1", | ||
| 178 | "1::", | ||
| 179 | "2001:db8::1", | ||
| 180 | "2001:db8:1:2:3:4:5:0", | ||
| 181 | "1111:2222:3333:4444:5555:6666:7777:8888", | ||
| 182 | "2001::1:0:0:1", | ||
| 183 | "abcd:ef01::1", | ||
| 184 | NULL}; | ||
| 185 | char ip[16], again[16]; | ||
| 186 | size_t i; | ||
| 187 | |||
| 188 | test_case("every formatted address scans back to the same bytes"); | ||
| 189 | for (i = 0; samples[i]; ++i) { | ||
| 190 | size_t n = ip_scan(samples[i], ip); | ||
| 191 | if (n != strlen(samples[i])) { | ||
| 192 | test_failf(__FILE__, __LINE__, "\"%s\" consumed %zu of %zu", samples[i], n, strlen(samples[i])); | ||
| 193 | return; | ||
| 194 | } | ||
| 195 | text[ip_format(text, ip)] = 0; | ||
| 196 | if (strcmp(text, samples[i])) { | ||
| 197 | test_failf(__FILE__, __LINE__, "\"%s\" formatted back as \"%s\"", samples[i], text); | ||
| 198 | return; | ||
| 199 | } | ||
| 200 | if (!ip_scan(text, again) || memcmp(ip, again, 16)) { | ||
| 201 | test_failf(__FILE__, __LINE__, "\"%s\" did not survive a second pass", samples[i]); | ||
| 202 | return; | ||
| 203 | } | ||
| 204 | } | ||
| 205 | ++test_checks; | ||
| 206 | } | ||
| 207 | |||
| 208 | void test_ip(void) { | ||
| 209 | case_format_rfc5952(); | ||
| 210 | case_format_trailing_zero_group(); | ||
| 211 | case_v4mapped(); | ||
| 212 | case_scan_forms(); | ||
| 213 | case_scan_accepts_bare_ipv4(); | ||
| 214 | case_scan_reports_length(); | ||
| 215 | case_scan_rejects(); | ||
| 216 | case_round_trip(); | ||
| 217 | } | ||
diff --git a/tests/test.h b/tests/test.h index 676ca33..7449b73 100644 --- a/tests/test.h +++ b/tests/test.h | |||
| @@ -84,5 +84,6 @@ void test_hex(void); | |||
| 84 | void test_accesslist(void); | 84 | void test_accesslist(void); |
| 85 | void test_scan(void); | 85 | void test_scan(void); |
| 86 | void test_buf(void); | 86 | void test_buf(void); |
| 87 | void test_ip(void); | ||
| 87 | 88 | ||
| 88 | #endif | 89 | #endif |
diff --git a/trackerlogic.c b/trackerlogic.c index d8a2f9b..db1d787 100644 --- a/trackerlogic.c +++ b/trackerlogic.c | |||
| @@ -13,26 +13,26 @@ | |||
| 13 | /* Libowfat */ | 13 | /* Libowfat */ |
| 14 | #include "io.h" | 14 | #include "io.h" |
| 15 | #include "iob.h" | 15 | #include "iob.h" |
| 16 | #include "ip6.h" | ||
| 17 | 16 | ||
| 18 | /* Opentracker */ | 17 | /* Opentracker */ |
| 19 | #include "ot_accesslist.h" | 18 | #include "ot_accesslist.h" |
| 20 | #include "ot_clean.h" | 19 | #include "ot_clean.h" |
| 21 | #include "ot_fullscrape.h" | 20 | #include "ot_fullscrape.h" |
| 22 | #include "ot_http.h" | 21 | #include "ot_http.h" |
| 22 | #include "ot_ip.h" | ||
| 23 | #include "ot_livesync.h" | 23 | #include "ot_livesync.h" |
| 24 | #include "ot_mutex.h" | 24 | #include "ot_mutex.h" |
| 25 | #include "ot_random.h" | 25 | #include "ot_random.h" |
| 26 | #include "ot_stats.h" | 26 | #include "ot_stats.h" |
| 27 | #include "ot_vector.h" | ||
| 28 | #include "ot_udp.h" | 27 | #include "ot_udp.h" |
| 28 | #include "ot_vector.h" | ||
| 29 | #include "trackerlogic.h" | 29 | #include "trackerlogic.h" |
| 30 | 30 | ||
| 31 | /* Forward declaration */ | 31 | /* Forward declaration */ |
| 32 | size_t return_peers_for_torrent(struct ot_workstruct *ws, ot_torrent *torrent, size_t amount, char *reply, PROTO_FLAG proto); | 32 | size_t return_peers_for_torrent(struct ot_workstruct *ws, ot_torrent *torrent, size_t amount, char *reply, PROTO_FLAG proto); |
| 33 | 33 | ||
| 34 | void free_peerlist(ot_peerlist *peer_list) { | 34 | void free_peerlist(ot_peerlist *peer_list) { |
| 35 | if (peer_list->peers.data) { | 35 | if (peer_list && peer_list->peers.data) { |
| 36 | if (OT_PEERLIST_HASBUCKETS(peer_list)) | 36 | if (OT_PEERLIST_HASBUCKETS(peer_list)) |
| 37 | vector_clean_list((ot_vector *)peer_list->peers.data, peer_list->peers.size); | 37 | vector_clean_list((ot_vector *)peer_list->peers.data, peer_list->peers.size); |
| 38 | else | 38 | else |
| @@ -511,7 +511,7 @@ void iterate_all_torrents(int (*for_each)(ot_torrent *torrent, uintptr_t data), | |||
| 511 | 511 | ||
| 512 | ot_peer *peer_from_peer6(ot_peer6 *peer, size_t *peer_size) { | 512 | ot_peer *peer_from_peer6(ot_peer6 *peer, size_t *peer_size) { |
| 513 | ot_ip6 *ip = (ot_ip6 *)peer; | 513 | ot_ip6 *ip = (ot_ip6 *)peer; |
| 514 | if (!ip6_isv4mapped(ip)) { | 514 | if (!ip_is_v4mapped(ip)) { |
| 515 | *peer_size = OT_PEER_SIZE6; | 515 | *peer_size = OT_PEER_SIZE6; |
| 516 | return (ot_peer *)peer; | 516 | return (ot_peer *)peer; |
| 517 | } | 517 | } |
| @@ -521,7 +521,7 @@ ot_peer *peer_from_peer6(ot_peer6 *peer, size_t *peer_size) { | |||
| 521 | 521 | ||
| 522 | size_t peer_size_from_peer6(ot_peer6 *peer) { | 522 | size_t peer_size_from_peer6(ot_peer6 *peer) { |
| 523 | ot_ip6 *ip = (ot_ip6 *)peer; | 523 | ot_ip6 *ip = (ot_ip6 *)peer; |
| 524 | if (!ip6_isv4mapped(ip)) | 524 | if (!ip_is_v4mapped(ip)) |
| 525 | return OT_PEER_SIZE6; | 525 | return OT_PEER_SIZE6; |
| 526 | return OT_PEER_SIZE4; | 526 | return OT_PEER_SIZE4; |
| 527 | } | 527 | } |
