static void eventcb(struct bufferevent *bev, short what, void *ctx) { TT_BLATHER(("Got event %d", (int)what)); if (what & BEV_EVENT_CONNECTED) { SSL *ssl; X509 *peer_cert; ++n_connected; ssl = bufferevent_openssl_get_ssl(bev); tt_assert(ssl); peer_cert = SSL_get_peer_certificate(ssl); if (0==strcmp(ctx, "server")) { tt_assert(peer_cert == NULL); } else { tt_assert(peer_cert != NULL); } if (stop_when_connected) { if (--pending_connect_events == 0) event_base_loopexit(exit_base, NULL); } } else if (what & BEV_EVENT_EOF) { TT_BLATHER(("Got a good EOF")); ++got_close; bufferevent_free(bev); } else if (what & BEV_EVENT_ERROR) { TT_BLATHER(("Got an error.")); ++got_error; bufferevent_free(bev); } end: ; }
/* Bufferevent event callback for the connect_hostname test: remembers what * event we got. */ static void be_connect_hostname_event_cb(struct bufferevent *bev, short what, void *ctx) { struct be_conn_hostname_result *got = ctx; if (!got->what) { TT_BLATHER(("Got a bufferevent event %d", what)); got->what = what; if ((what & BEV_EVENT_CONNECTED) || (what & BEV_EVENT_ERROR)) { int r; ++total_connected_or_failed; TT_BLATHER(("Got %d connections or errors.", total_connected_or_failed)); if ((r = bufferevent_socket_get_dns_error(bev))) { got->dnserr = r; TT_BLATHER(("DNS error %d: %s", r, evutil_gai_strerror(r))); } if (total_connected_or_failed >= 5) event_base_loopexit(be_connect_hostname_base, NULL); } } else { TT_FAIL(("Two events on one bufferevent. %d,%d", got->what, (int)what)); } }
static void thread_deferred_cb_skew(void *arg) { struct basic_test_data *data = arg; struct timeval tv_timer = {4, 0}; struct deferred_cb_queue *queue; time_t elapsed; int i; queue = event_base_get_deferred_cb_queue(data->base); tt_assert(queue); for (i = 0; i < QUEUE_THREAD_COUNT; ++i) deferred_data[i].queue = queue; timer_start = time(NULL); event_base_once(data->base, -1, EV_TIMEOUT, timer_callback, NULL, &tv_timer); event_base_once(data->base, -1, EV_TIMEOUT, start_threads_callback, NULL, NULL); event_base_dispatch(data->base); elapsed = timer_end - timer_start; TT_BLATHER(("callback count, %u", callback_count)); TT_BLATHER(("elapsed time, %u", (unsigned)elapsed)); /* XXX be more intelligent here. just make sure skew is * within 2 seconds for now. */ tt_assert(elapsed >= 4 && elapsed <= 6); end: for (i = 0; i < QUEUE_THREAD_COUNT; ++i) THREAD_JOIN(load_threads[i]); }
static void respond_to_number(struct bufferevent *bev, void *ctx) { struct evbuffer *b = bufferevent_get_input(bev); char *line; int n; line = evbuffer_readln(b, NULL, EVBUFFER_EOL_LF); if (! line) return; n = atoi(line); if (n <= 0) TT_FAIL(("Bad number: %s", line)); TT_BLATHER(("The number was %d", n)); if (n == 1001) { ++test_is_done; bufferevent_free(bev); /* Should trigger close on other side. */ return; } if (!strcmp(ctx, "client") && n == renegotiate_at) { SSL_renegotiate(bufferevent_openssl_get_ssl(bev)); } ++n; evbuffer_add_printf(bufferevent_get_output(bev), "%d\n", n); TT_BLATHER(("Done reading; now writing.")); bufferevent_enable(bev, EV_WRITE); bufferevent_disable(bev, EV_READ); }
static void thread_basic(void *arg) { THREAD_T threads[NUM_THREADS]; struct event ev; struct timeval tv; int i; struct basic_test_data *data = arg; struct event_base *base = data->base; struct event *notification_event = NULL; struct event *sigchld_event = NULL; EVTHREAD_ALLOC_LOCK(count_lock, 0); tt_assert(count_lock); tt_assert(base); if (evthread_make_base_notifiable(base)<0) { tt_abort_msg("Couldn't make base notifiable!"); } #ifndef WIN32 if (data->setup_data && !strcmp(data->setup_data, "forking")) { pid_t pid; int status; sigchld_event = evsignal_new(base, SIGCHLD, sigchld_cb, base); /* This piggybacks on the th_notify_fd weirdly, and looks * inside libevent internals. Not a good idea in non-testing * code! */ notification_event = event_new(base, base->th_notify_fd[0], EV_READ|EV_PERSIST, notify_fd_cb, NULL); event_add(sigchld_event, NULL); event_add(notification_event, NULL); if ((pid = fork()) == 0) { event_del(notification_event); if (event_reinit(base) < 0) { TT_FAIL(("reinit")); exit(1); } event_assign(notification_event, base, base->th_notify_fd[0], EV_READ|EV_PERSIST, notify_fd_cb, NULL); event_add(notification_event, NULL); goto child; } event_base_dispatch(base); if (waitpid(pid, &status, 0) == -1) tt_abort_perror("waitpid"); TT_BLATHER(("Waitpid okay\n")); tt_assert(got_sigchld); tt_int_op(notification_fd_used, ==, 0); goto end; }
static void thread_deferred_cb_skew(void *arg) { struct timeval tv_timer = {1, 0}; struct event_base *base = NULL; struct event_config *cfg = NULL; struct timeval elapsed; int elapsed_usec; int i; cfg = event_config_new(); tt_assert(cfg); event_config_set_max_dispatch_interval(cfg, NULL, 16, 0); base = event_base_new_with_config(cfg); tt_assert(base); for (i = 0; i < QUEUE_THREAD_COUNT; ++i) deferred_data[i].queue = base; evutil_gettimeofday(&timer_start, NULL); event_base_once(base, -1, EV_TIMEOUT, timer_callback, NULL, &tv_timer); event_base_once(base, -1, EV_TIMEOUT, start_threads_callback, NULL, NULL); event_base_dispatch(base); evutil_timersub(&timer_end, &timer_start, &elapsed); TT_BLATHER(("callback count, %u", callback_count)); elapsed_usec = (unsigned)(elapsed.tv_sec*1000000 + elapsed.tv_usec); TT_BLATHER(("elapsed time, %u usec", elapsed_usec)); /* XXX be more intelligent here. just make sure skew is * within .4 seconds for now. */ tt_assert(elapsed_usec >= 600000 && elapsed_usec <= 1400000); end: for (i = 0; i < QUEUE_THREAD_COUNT; ++i) THREAD_JOIN(load_threads[i]); if (base) event_base_free(base); if (cfg) event_config_free(cfg); }
static void done_writing_cb(struct bufferevent *bev, void *ctx) { struct evbuffer *b = bufferevent_get_output(bev); if (evbuffer_get_length(b)) return; TT_BLATHER(("Done writing.")); bufferevent_disable(bev, EV_WRITE); bufferevent_enable(bev, EV_READ); }
/* Bufferevent event callback for the connect_hostname test: remembers what * event we got. */ static void be_connect_hostname_event_cb(struct bufferevent *bev, short what, void *ctx) { int *got = ctx; if (!*got) { TT_BLATHER(("Got a bufferevent event %d", what)); *got = what; if ((what & BEV_EVENT_CONNECTED) || (what & BEV_EVENT_ERROR)) { ++total_connected_or_failed; TT_BLATHER(("Got %d connections or errors.", total_connected_or_failed)); if (total_connected_or_failed >= 5) event_base_loopexit(be_connect_hostname_base, NULL); } } else { TT_FAIL(("Two events on one bufferevent. %d,%d", (int)*got, (int)what)); } }
static void gai_cb(int err, struct evutil_addrinfo *res, void *ptr) { struct gai_outcome *go = ptr; go->err = err; go->ai = res; if (--n_gai_results_pending <= 0 && exit_base_on_no_pending_results) event_base_loopexit(exit_base_on_no_pending_results, NULL); if (n_gai_results_pending < 900) TT_BLATHER(("Got an answer; expecting %d more.", n_gai_results_pending)); }
static void acceptcb(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *addr, int socklen, void *arg) { int *ptr = arg; --*ptr; TT_BLATHER(("Got one for %p", ptr)); EVUTIL_CLOSESOCKET(fd); if (! *ptr) evconnlistener_disable(listener); }
static void regress_ipv6_parse(void *ptr) { #ifdef AF_INET6 int i, j; for (i = 0; ipv6_entries[i].addr; ++i) { char written[128]; struct ipv6_entry *ent = &ipv6_entries[i]; struct in6_addr in6; int r; r = evutil_inet_pton(AF_INET6, ent->addr, &in6); if (r == 0) { if (ent->status != BAD) TT_FAIL(("%s did not parse, but it's a good address!", ent->addr)); continue; } if (ent->status == BAD) { TT_FAIL(("%s parsed, but we expected an error", ent->addr)); continue; } for (j = 0; j < 4; ++j) { /* Can't use s6_addr32 here; some don't have it. */ ev_uint32_t u = ((ev_uint32_t)in6.s6_addr[j*4 ] << 24) | ((ev_uint32_t)in6.s6_addr[j*4+1] << 16) | ((ev_uint32_t)in6.s6_addr[j*4+2] << 8) | ((ev_uint32_t)in6.s6_addr[j*4+3]); if (u != ent->res[j]) { TT_FAIL(("%s did not parse as expected.", ent->addr)); continue; } } if (ent->status == CANONICAL) { const char *w = evutil_inet_ntop(AF_INET6, &in6, written, sizeof(written)); if (!w) { TT_FAIL(("Tried to write out %s; got NULL.", ent->addr)); continue; } if (strcmp(written, ent->addr)) { TT_FAIL(("Tried to write out %s; got %s", ent->addr, written)); continue; } } } #else TT_BLATHER(("Skipping IPv6 address parsing.")); #endif }
static void test_edgetriggered(void *et) { struct event *ev = NULL; struct event_base *base = NULL; const char *test = "test string"; evutil_socket_t pair[2] = {-1,-1}; int supports_et; if (evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM, 0, pair) == -1) { tt_abort_perror("socketpair"); } called = was_et = 0; send(pair[0], test, (int)strlen(test)+1, 0); shutdown(pair[0], SHUT_WR); /* Initalize the event library */ base = event_base_new(); if (!strcmp(event_base_get_method(base), "epoll") || !strcmp(event_base_get_method(base), "epoll (with changelist)") || !strcmp(event_base_get_method(base), "kqueue")) supports_et = 1; else supports_et = 0; TT_BLATHER(("Checking for edge-triggered events with %s, which should %s" "support edge-triggering", event_base_get_method(base), supports_et?"":"not ")); /* Initalize one event */ ev = event_new(base, pair[1], EV_READ|EV_ET|EV_PERSIST, read_cb, &ev); event_add(ev, NULL); /* We're going to call the dispatch function twice. The first invocation * will read a single byte from pair[1] in either case. If we're edge * triggered, we'll only see the event once (since we only see transitions * from no data to data), so the second invocation of event_base_loop will * do nothing. If we're level triggered, the second invocation of * event_base_loop will also activate the event (because there's still * data to read). */ event_base_loop(base,EVLOOP_NONBLOCK|EVLOOP_ONCE); event_base_loop(base,EVLOOP_NONBLOCK|EVLOOP_ONCE); if (supports_et) { tt_int_op(called, ==, 1); tt_assert(was_et); } else {
static void search_cancel_server_cb(struct evdns_server_request *req, void *data) { const char *question; if (req->nquestions != 1) TT_DIE(("Only handling one question at a time; got %d", req->nquestions)); question = req->questions[0]->name; TT_BLATHER(("got question, %s", question)); tt_assert(request_count > 0); tt_assert(!evdns_server_request_respond(req, 3)); if (!--request_count) evdns_cancel_request(NULL, current_req); end: ; }
static void thread_no_events(void *arg) { THREAD_T thread; struct basic_test_data *data = arg; struct timeval starttime, endtime; int i; exit_base = data->base; memset(times,0,sizeof(times)); for (i=0;i<5;++i) { event_assign(&time_events[i], data->base, -1, 0, note_time_cb, ×[i]); } evutil_gettimeofday(&starttime, NULL); THREAD_START(thread, register_events_subthread, data->base); event_base_loop(data->base, EVLOOP_NO_EXIT_ON_EMPTY); evutil_gettimeofday(&endtime, NULL); tt_assert(event_base_got_break(data->base)); THREAD_JOIN(thread); for (i=0; i<5; ++i) { struct timeval diff; double sec; evutil_timersub(×[i], &starttime, &diff); sec = diff.tv_sec + diff.tv_usec/1.0e6; TT_BLATHER(("event %d at %.4f seconds", i, sec)); } test_timeval_diff_eq(&starttime, ×[0], 100); test_timeval_diff_eq(&starttime, ×[1], 200); test_timeval_diff_eq(&starttime, ×[2], 400); test_timeval_diff_eq(&starttime, ×[3], 450); test_timeval_diff_eq(&starttime, ×[4], 500); test_timeval_diff_eq(&starttime, &endtime, 500); end: ; }
/** Run unit tests for IPv6 encoding/decoding/manipulation functions. */ static void test_addr_ip6_helpers(void *arg) { char buf[TOR_ADDR_BUF_LEN], bug[TOR_ADDR_BUF_LEN]; char rbuf[REVERSE_LOOKUP_NAME_BUF_LEN]; struct in6_addr a1, a2; tor_addr_t t1, t2; int r, i; uint16_t port1, port2; maskbits_t mask; const char *p1; struct sockaddr_storage sa_storage; struct sockaddr_in *sin; struct sockaddr_in6 *sin6; /* Test tor_inet_ntop and tor_inet_pton: IPv6 */ (void)arg; { const char *ip = "2001::1234"; const char *ip_ffff = "::ffff:192.168.1.2"; /* good round trip */ tt_int_op(tor_inet_pton(AF_INET6, ip, &a1),OP_EQ, 1); tt_ptr_op(tor_inet_ntop(AF_INET6, &a1, buf, sizeof(buf)),OP_EQ, &buf); tt_str_op(buf,OP_EQ, ip); /* good round trip - ::ffff:0:0 style */ tt_int_op(tor_inet_pton(AF_INET6, ip_ffff, &a2),OP_EQ, 1); tt_ptr_op(tor_inet_ntop(AF_INET6, &a2, buf, sizeof(buf)),OP_EQ, &buf); tt_str_op(buf,OP_EQ, ip_ffff); /* just long enough buffer (remember \0) */ tt_str_op(tor_inet_ntop(AF_INET6, &a1, buf, strlen(ip)+1),OP_EQ, ip); tt_str_op(tor_inet_ntop(AF_INET6, &a2, buf, strlen(ip_ffff)+1),OP_EQ, ip_ffff); /* too short buffer (remember \0) */ tt_ptr_op(tor_inet_ntop(AF_INET6, &a1, buf, strlen(ip)),OP_EQ, NULL); tt_ptr_op(tor_inet_ntop(AF_INET6, &a2, buf, strlen(ip_ffff)),OP_EQ, NULL); } /* ==== Converting to and from sockaddr_t. */ sin = (struct sockaddr_in *)&sa_storage; sin->sin_family = AF_INET; sin->sin_port = htons(9090); sin->sin_addr.s_addr = htonl(0x7f7f0102); /*127.127.1.2*/ tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin, &port1); tt_int_op(tor_addr_family(&t1),OP_EQ, AF_INET); tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ, 0x7f7f0102); tt_int_op(port1, OP_EQ, 9090); memset(&sa_storage, 0, sizeof(sa_storage)); tt_int_op(sizeof(struct sockaddr_in),OP_EQ, tor_addr_to_sockaddr(&t1, 1234, (struct sockaddr *)&sa_storage, sizeof(sa_storage))); tt_int_op(1234,OP_EQ, ntohs(sin->sin_port)); tt_int_op(0x7f7f0102,OP_EQ, ntohl(sin->sin_addr.s_addr)); memset(&sa_storage, 0, sizeof(sa_storage)); sin6 = (struct sockaddr_in6 *)&sa_storage; sin6->sin6_family = AF_INET6; sin6->sin6_port = htons(7070); sin6->sin6_addr.s6_addr[0] = 128; tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin6, &port1); tt_int_op(tor_addr_family(&t1),OP_EQ, AF_INET6); tt_int_op(port1, OP_EQ, 7070); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0); tt_str_op(p1,OP_EQ, "8000::"); memset(&sa_storage, 0, sizeof(sa_storage)); tt_int_op(sizeof(struct sockaddr_in6),OP_EQ, tor_addr_to_sockaddr(&t1, 9999, (struct sockaddr *)&sa_storage, sizeof(sa_storage))); tt_int_op(AF_INET6,OP_EQ, sin6->sin6_family); tt_int_op(9999,OP_EQ, ntohs(sin6->sin6_port)); tt_int_op(0x80000000,OP_EQ, ntohl(S6_ADDR32(sin6->sin6_addr)[0])); /* ==== tor_addr_lookup: static cases. (Can't test dns without knowing we * have a good resolver. */ tt_int_op(0,OP_EQ, tor_addr_lookup("127.128.129.130", AF_UNSPEC, &t1)); tt_int_op(AF_INET,OP_EQ, tor_addr_family(&t1)); tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ, 0x7f808182); tt_int_op(0,OP_EQ, tor_addr_lookup("9000::5", AF_UNSPEC, &t1)); tt_int_op(AF_INET6,OP_EQ, tor_addr_family(&t1)); tt_int_op(0x90,OP_EQ, tor_addr_to_in6_addr8(&t1)[0]); tt_assert(tor_mem_is_zero((char*)tor_addr_to_in6_addr8(&t1)+1, 14)); tt_int_op(0x05,OP_EQ, tor_addr_to_in6_addr8(&t1)[15]); /* === Test pton: valid af_inet6 */ /* Simple, valid parsing. */ r = tor_inet_pton(AF_INET6, "0102:0304:0506:0708:090A:0B0C:0D0E:0F10", &a1); tt_int_op(r, OP_EQ, 1); for (i=0;i<16;++i) { tt_int_op(i+1,OP_EQ, (int)a1.s6_addr[i]); } /* ipv4 ending. */ test_pton6_same("0102:0304:0506:0708:090A:0B0C:0D0E:0F10", "0102:0304:0506:0708:090A:0B0C:13.14.15.16"); /* shortened words. */ test_pton6_same("0001:0099:BEEF:0000:0123:FFFF:0001:0001", "1:99:BEEF:0:0123:FFFF:1:1"); /* zeros at the beginning */ test_pton6_same("0000:0000:0000:0000:0009:C0A8:0001:0001", "::9:c0a8:1:1"); test_pton6_same("0000:0000:0000:0000:0009:C0A8:0001:0001", "::9:c0a8:0.1.0.1"); /* zeros in the middle. */ test_pton6_same("fe80:0000:0000:0000:0202:1111:0001:0001", "fe80::202:1111:1:1"); /* zeros at the end. */ test_pton6_same("1000:0001:0000:0007:0000:0000:0000:0000", "1000:1:0:7::"); /* === Test ntop: af_inet6 */ test_ntop6_reduces("0:0:0:0:0:0:0:0", "::"); test_ntop6_reduces("0001:0099:BEEF:0006:0123:FFFF:0001:0001", "1:99:beef:6:123:ffff:1:1"); //test_ntop6_reduces("0:0:0:0:0:0:c0a8:0101", "::192.168.1.1"); test_ntop6_reduces("0:0:0:0:0:ffff:c0a8:0101", "::ffff:192.168.1.1"); test_ntop6_reduces("0:0:0:0:0:0:c0a8:0101", "::192.168.1.1"); test_ntop6_reduces("002:0:0000:0:3::4", "2::3:0:0:4"); test_ntop6_reduces("0:0::1:0:3", "::1:0:3"); test_ntop6_reduces("008:0::0", "8::"); test_ntop6_reduces("0:0:0:0:0:ffff::1", "::ffff:0.0.0.1"); test_ntop6_reduces("abcd:0:0:0:0:0:7f00::", "abcd::7f00:0"); test_ntop6_reduces("0000:0000:0000:0000:0009:C0A8:0001:0001", "::9:c0a8:1:1"); test_ntop6_reduces("fe80:0000:0000:0000:0202:1111:0001:0001", "fe80::202:1111:1:1"); test_ntop6_reduces("1000:0001:0000:0007:0000:0000:0000:0000", "1000:1:0:7::"); /* Bad af param */ tt_int_op(tor_inet_pton(AF_UNSPEC, 0, 0),OP_EQ, -1); /* === Test pton: invalid in6. */ test_pton6_bad("foobar."); test_pton6_bad("-1::"); test_pton6_bad("00001::"); test_pton6_bad("10000::"); test_pton6_bad("::10000"); test_pton6_bad("55555::"); test_pton6_bad("9:-60::"); test_pton6_bad("9:+60::"); test_pton6_bad("9|60::"); test_pton6_bad("0x60::"); test_pton6_bad("::0x60"); test_pton6_bad("9:0x60::"); test_pton6_bad("1:2:33333:4:0002:3::"); test_pton6_bad("1:2:3333:4:fish:3::"); test_pton6_bad("1:2:3:4:5:6:7:8:9"); test_pton6_bad("1:2:3:4:5:6:7"); test_pton6_bad("1:2:3:4:5:6:1.2.3.4.5"); test_pton6_bad("1:2:3:4:5:6:1.2.3"); test_pton6_bad("::1.2.3"); test_pton6_bad("::1.2.3.4.5"); test_pton6_bad("::ffff:0xff.0.0.0"); test_pton6_bad("::ffff:ff.0.0.0"); test_pton6_bad("::ffff:256.0.0.0"); test_pton6_bad("::ffff:-1.0.0.0"); test_pton6_bad("99"); test_pton6_bad(""); test_pton6_bad("."); test_pton6_bad(":"); test_pton6_bad("1::2::3:4"); test_pton6_bad("a:::b:c"); test_pton6_bad(":::a:b:c"); test_pton6_bad("a:b:c:::"); test_pton6_bad("1.2.3.4"); test_pton6_bad(":1.2.3.4"); test_pton6_bad(".2.3.4"); /* Regression tests for 22789. */ test_pton6_bad("0xfoo"); test_pton6_bad("0x88"); test_pton6_bad("0xyxxy"); test_pton6_bad("0XFOO"); test_pton6_bad("0X88"); test_pton6_bad("0XYXXY"); test_pton6_bad("0x"); test_pton6_bad("0X"); /* test internal checking */ test_external_ip("fbff:ffff::2:7", 0); test_internal_ip("fc01::2:7", 0); test_internal_ip("fc01::02:7", 0); test_internal_ip("fc01::002:7", 0); test_internal_ip("fc01::0002:7", 0); test_internal_ip("fdff:ffff::f:f", 0); test_external_ip("fe00::3:f", 0); test_external_ip("fe7f:ffff::2:7", 0); test_internal_ip("fe80::2:7", 0); test_internal_ip("febf:ffff::f:f", 0); test_internal_ip("fec0::2:7:7", 0); test_internal_ip("feff:ffff::e:7:7", 0); test_external_ip("ff00::e:7:7", 0); test_internal_ip("::", 0); test_internal_ip("::1", 0); test_internal_ip("::1", 1); test_internal_ip("::", 0); test_external_ip("::", 1); test_external_ip("::2", 0); test_external_ip("2001::", 0); test_external_ip("ffff::", 0); test_external_ip("::ffff:0.0.0.0", 1); test_internal_ip("::ffff:0.0.0.0", 0); test_internal_ip("::ffff:0.255.255.255", 0); test_external_ip("::ffff:1.0.0.0", 0); test_external_ip("::ffff:9.255.255.255", 0); test_internal_ip("::ffff:10.0.0.0", 0); test_internal_ip("::ffff:10.255.255.255", 0); test_external_ip("::ffff:11.0.0.0", 0); test_external_ip("::ffff:126.255.255.255", 0); test_internal_ip("::ffff:127.0.0.0", 0); test_internal_ip("::ffff:127.255.255.255", 0); test_external_ip("::ffff:128.0.0.0", 0); test_external_ip("::ffff:172.15.255.255", 0); test_internal_ip("::ffff:172.16.0.0", 0); test_internal_ip("::ffff:172.31.255.255", 0); test_external_ip("::ffff:172.32.0.0", 0); test_external_ip("::ffff:192.167.255.255", 0); test_internal_ip("::ffff:192.168.0.0", 0); test_internal_ip("::ffff:192.168.255.255", 0); test_external_ip("::ffff:192.169.0.0", 0); test_external_ip("::ffff:169.253.255.255", 0); test_internal_ip("::ffff:169.254.0.0", 0); test_internal_ip("::ffff:169.254.255.255", 0); test_external_ip("::ffff:169.255.0.0", 0); /* tor_addr_compare(tor_addr_t x2) */ test_addr_compare("ffff::", OP_EQ, "ffff::0"); test_addr_compare("0::3:2:1", OP_LT, "0::ffff:0.3.2.1"); test_addr_compare("0::2:2:1", OP_LT, "0::ffff:0.3.2.1"); test_addr_compare("0::ffff:0.3.2.1", OP_GT, "0::0:0:0"); test_addr_compare("0::ffff:5.2.2.1", OP_LT, "::ffff:6.0.0.0"); /* XXXX wrong. */ tor_addr_parse_mask_ports("[::ffff:2.3.4.5]", 0, &t1, NULL, NULL, NULL); tor_addr_parse_mask_ports("2.3.4.5", 0, &t2, NULL, NULL, NULL); tt_int_op(tor_addr_compare(&t1, &t2, CMP_SEMANTIC), OP_EQ, 0); tor_addr_parse_mask_ports("[::ffff:2.3.4.4]", 0, &t1, NULL, NULL, NULL); tor_addr_parse_mask_ports("2.3.4.5", 0, &t2, NULL, NULL, NULL); tt_int_op(tor_addr_compare(&t1, &t2, CMP_SEMANTIC), OP_LT, 0); /* test compare_masked */ test_addr_compare_masked("ffff::", OP_EQ, "ffff::0", 128); test_addr_compare_masked("ffff::", OP_EQ, "ffff::0", 64); test_addr_compare_masked("0::2:2:1", OP_LT, "0::8000:2:1", 81); test_addr_compare_masked("0::2:2:1", OP_EQ, "0::8000:2:1", 80); /* Test undecorated tor_addr_to_str */ tt_int_op(AF_INET6,OP_EQ, tor_addr_parse(&t1, "[123:45:6789::5005:11]")); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0); tt_str_op(p1,OP_EQ, "123:45:6789::5005:11"); tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&t1, "18.0.0.1")); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0); tt_str_op(p1,OP_EQ, "18.0.0.1"); /* Test decorated tor_addr_to_str */ tt_int_op(AF_INET6,OP_EQ, tor_addr_parse(&t1, "[123:45:6789::5005:11]")); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); tt_str_op(p1,OP_EQ, "[123:45:6789::5005:11]"); tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&t1, "18.0.0.1")); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); tt_str_op(p1,OP_EQ, "18.0.0.1"); /* Test buffer bounds checking of tor_addr_to_str */ tt_int_op(AF_INET6,OP_EQ, tor_addr_parse(&t1, "::")); /* 2 + \0 */ tt_ptr_op(tor_addr_to_str(buf, &t1, 2, 0),OP_EQ, NULL); /* too short buf */ tt_str_op(tor_addr_to_str(buf, &t1, 3, 0),OP_EQ, "::"); tt_ptr_op(tor_addr_to_str(buf, &t1, 4, 1),OP_EQ, NULL); /* too short buf */ tt_str_op(tor_addr_to_str(buf, &t1, 5, 1),OP_EQ, "[::]"); tt_int_op(AF_INET6,OP_EQ, tor_addr_parse(&t1, "2000::1337")); /* 10 + \0 */ tt_ptr_op(tor_addr_to_str(buf, &t1, 10, 0),OP_EQ, NULL); /* too short buf */ tt_str_op(tor_addr_to_str(buf, &t1, 11, 0),OP_EQ, "2000::1337"); tt_ptr_op(tor_addr_to_str(buf, &t1, 12, 1),OP_EQ, NULL); /* too short buf */ tt_str_op(tor_addr_to_str(buf, &t1, 13, 1),OP_EQ, "[2000::1337]"); tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&t1, "1.2.3.4")); /* 7 + \0 */ tt_ptr_op(tor_addr_to_str(buf, &t1, 7, 0),OP_EQ, NULL); /* too short buf */ tt_str_op(tor_addr_to_str(buf, &t1, 8, 0),OP_EQ, "1.2.3.4"); tt_int_op(AF_INET, OP_EQ, tor_addr_parse(&t1, "255.255.255.255")); /* 15 + \0 */ tt_ptr_op(tor_addr_to_str(buf, &t1, 15, 0),OP_EQ, NULL); /* too short buf */ tt_str_op(tor_addr_to_str(buf, &t1, 16, 0),OP_EQ, "255.255.255.255"); tt_ptr_op(tor_addr_to_str(buf, &t1, 15, 1),OP_EQ, NULL); /* too short buf */ tt_str_op(tor_addr_to_str(buf, &t1, 16, 1),OP_EQ, "255.255.255.255"); t1.family = AF_UNSPEC; tt_ptr_op(tor_addr_to_str(buf, &t1, sizeof(buf), 0),OP_EQ, NULL); /* Test tor_addr_parse_PTR_name */ i = tor_addr_parse_PTR_name(&t1, "Foobar.baz", AF_UNSPEC, 0); tt_int_op(0,OP_EQ, i); i = tor_addr_parse_PTR_name(&t1, "Foobar.baz", AF_UNSPEC, 1); tt_int_op(0,OP_EQ, i); i = tor_addr_parse_PTR_name(&t1, "9999999999999999999999999999.in-addr.arpa", AF_UNSPEC, 1); tt_int_op(-1,OP_EQ, i); i = tor_addr_parse_PTR_name(&t1, "1.0.168.192.in-addr.arpa", AF_UNSPEC, 1); tt_int_op(1,OP_EQ, i); tt_int_op(tor_addr_family(&t1),OP_EQ, AF_INET); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); tt_str_op(p1,OP_EQ, "192.168.0.1"); i = tor_addr_parse_PTR_name(&t1, "192.168.0.99", AF_UNSPEC, 0); tt_int_op(0,OP_EQ, i); i = tor_addr_parse_PTR_name(&t1, "192.168.0.99", AF_UNSPEC, 1); tt_int_op(1,OP_EQ, i); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); tt_str_op(p1,OP_EQ, "192.168.0.99"); memset(&t1, 0, sizeof(t1)); i = tor_addr_parse_PTR_name(&t1, "0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_UNSPEC, 0); tt_int_op(1,OP_EQ, i); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); tt_str_op(p1,OP_EQ, "[9dee:effe:ebe1:beef:fedc:ba98:7654:3210]"); /* Failing cases. */ i = tor_addr_parse_PTR_name(&t1, "6.7.8.9.a.b.c.d.e.f." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_UNSPEC, 0); tt_int_op(i,OP_EQ, -1); i = tor_addr_parse_PTR_name(&t1, "6.7.8.9.a.b.c.d.e.f.a.b.c.d.e.f.0." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_UNSPEC, 0); tt_int_op(i,OP_EQ, -1); i = tor_addr_parse_PTR_name(&t1, "6.7.8.9.a.b.c.d.e.f.X.0.0.0.0.9." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_UNSPEC, 0); tt_int_op(i,OP_EQ, -1); i = tor_addr_parse_PTR_name(&t1, "32.1.1.in-addr.arpa", AF_UNSPEC, 0); tt_int_op(i,OP_EQ, -1); i = tor_addr_parse_PTR_name(&t1, ".in-addr.arpa", AF_UNSPEC, 0); tt_int_op(i,OP_EQ, -1); i = tor_addr_parse_PTR_name(&t1, "1.2.3.4.5.in-addr.arpa", AF_UNSPEC, 0); tt_int_op(i,OP_EQ, -1); i = tor_addr_parse_PTR_name(&t1, "1.2.3.4.5.in-addr.arpa", AF_INET6, 0); tt_int_op(i,OP_EQ, -1); i = tor_addr_parse_PTR_name(&t1, "6.7.8.9.a.b.c.d.e.f.a.b.c.d.e.0." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_INET, 0); tt_int_op(i,OP_EQ, -1); /* === Test tor_addr_to_PTR_name */ /* Stage IPv4 addr */ memset(&sa_storage, 0, sizeof(sa_storage)); sin = (struct sockaddr_in *)&sa_storage; sin->sin_family = AF_INET; sin->sin_addr.s_addr = htonl(0x7f010203); /* 127.1.2.3 */ tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin, NULL); /* Check IPv4 PTR - too short buffer */ tt_int_op(tor_addr_to_PTR_name(rbuf, 1, &t1),OP_EQ, -1); tt_int_op(tor_addr_to_PTR_name(rbuf, strlen("3.2.1.127.in-addr.arpa") - 1, &t1),OP_EQ, -1); /* Check IPv4 PTR - valid addr */ tt_int_op(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1),OP_EQ, strlen("3.2.1.127.in-addr.arpa")); tt_str_op(rbuf,OP_EQ, "3.2.1.127.in-addr.arpa"); /* Invalid addr family */ t1.family = AF_UNSPEC; tt_int_op(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1),OP_EQ, -1); /* Stage IPv6 addr */ memset(&sa_storage, 0, sizeof(sa_storage)); sin6 = (struct sockaddr_in6 *)&sa_storage; sin6->sin6_family = AF_INET6; sin6->sin6_addr.s6_addr[0] = 0x80; /* 8000::abcd */ sin6->sin6_addr.s6_addr[14] = 0xab; sin6->sin6_addr.s6_addr[15] = 0xcd; tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin6, NULL); { const char* addr_PTR = "d.c.b.a.0.0.0.0.0.0.0.0.0.0.0.0." "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.ip6.arpa"; /* Check IPv6 PTR - too short buffer */ tt_int_op(tor_addr_to_PTR_name(rbuf, 0, &t1),OP_EQ, -1); tt_int_op(tor_addr_to_PTR_name(rbuf, strlen(addr_PTR) - 1, &t1),OP_EQ, -1); /* Check IPv6 PTR - valid addr */ tt_int_op(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1),OP_EQ, strlen(addr_PTR)); tt_str_op(rbuf,OP_EQ, addr_PTR); } /* XXXX turn this into a separate function; it's not all IPv6. */ /* test tor_addr_parse_mask_ports */ test_addr_mask_ports_parse("[::f]/17:47-95", AF_INET6, 0, 0, 0, 0x0000000f, 17, 47, 95); tt_str_op(p1,OP_EQ, "::f"); //test_addr_parse("[::fefe:4.1.1.7/120]:999-1000"); //test_addr_parse_check("::fefe:401:107", 120, 999, 1000); test_addr_mask_ports_parse("[::ffff:4.1.1.7]/120:443", AF_INET6, 0, 0, 0x0000ffff, 0x04010107, 120, 443, 443); tt_str_op(p1,OP_EQ, "::ffff:4.1.1.7"); test_addr_mask_ports_parse("[abcd:2::44a:0]:2-65000", AF_INET6, 0xabcd0002, 0, 0, 0x044a0000, 128, 2, 65000); tt_str_op(p1,OP_EQ, "abcd:2::44a:0"); /* Try some long addresses. */ r=tor_addr_parse_mask_ports("[ffff:1111:1111:1111:1111:1111:1111:1111]", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, AF_INET6); r=tor_addr_parse_mask_ports("[ffff:1111:1111:1111:1111:1111:1111:11111]", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[ffff:1111:1111:1111:1111:1111:1111:1111:1]", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports( "[ffff:1111:1111:1111:1111:1111:1111:ffff:" "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:" "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:" "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); /* Try some failing cases. */ r=tor_addr_parse_mask_ports("[fefef::]/112", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[fefe::/112", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[fefe::", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[fefe::X]", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("efef::/112", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f::]",0,&t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[::f:f:f:f:f:f:f:f]",0,&t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f:f]",0,&t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[f:f:f:f:f::]/fred",0,&t1,&mask, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[f:f:f:f:f::]/255.255.0.0", 0,&t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); /* This one will get rejected because it isn't a pure prefix. */ r=tor_addr_parse_mask_ports("1.1.2.3/255.255.64.0",0,&t1, &mask,NULL,NULL); tt_int_op(r, OP_EQ, -1); /* Test for V4-mapped address with mask < 96. (arguably not valid) */ r=tor_addr_parse_mask_ports("[::ffff:1.1.2.2/33]",0,&t1, &mask, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("1.1.2.2/33",0,&t1, &mask, NULL, NULL); tt_int_op(r, OP_EQ, -1); /* Try extended wildcard addresses with out TAPMP_EXTENDED_STAR*/ r=tor_addr_parse_mask_ports("*4",0,&t1, &mask, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("*6",0,&t1, &mask, NULL, NULL); tt_int_op(r, OP_EQ, -1); tt_int_op(r, OP_EQ, -1); /* Try a mask with a wildcard. */ r=tor_addr_parse_mask_ports("*/16",0,&t1, &mask, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("*4/16",TAPMP_EXTENDED_STAR, &t1, &mask, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("*6/30",TAPMP_EXTENDED_STAR, &t1, &mask, NULL, NULL); tt_int_op(r, OP_EQ, -1); /* Basic mask tests*/ r=tor_addr_parse_mask_ports("1.1.2.2/31",0,&t1, &mask, NULL, NULL); tt_int_op(r, OP_EQ, AF_INET); tt_int_op(mask,OP_EQ,31); tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET); tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ,0x01010202); r=tor_addr_parse_mask_ports("3.4.16.032:1-2",0,&t1, &mask, &port1, &port2); tt_int_op(r, OP_EQ, AF_INET); tt_int_op(mask,OP_EQ,32); tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET); tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ,0x03041020); tt_uint_op(port1, OP_EQ, 1); tt_uint_op(port2, OP_EQ, 2); r=tor_addr_parse_mask_ports("1.1.2.3/255.255.128.0",0,&t1, &mask,NULL,NULL); tt_int_op(r, OP_EQ, AF_INET); tt_int_op(mask,OP_EQ,17); tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET); tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ,0x01010203); r=tor_addr_parse_mask_ports("[efef::]/112",0,&t1, &mask, &port1, &port2); tt_int_op(r, OP_EQ, AF_INET6); tt_uint_op(port1, OP_EQ, 1); tt_uint_op(port2, OP_EQ, 65535); /* Try regular wildcard behavior without TAPMP_EXTENDED_STAR */ r=tor_addr_parse_mask_ports("*:80-443",0,&t1,&mask,&port1,&port2); tt_int_op(r,OP_EQ,AF_INET); /* Old users of this always get inet */ tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET); tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ,0); tt_int_op(mask,OP_EQ,0); tt_int_op(port1,OP_EQ,80); tt_int_op(port2,OP_EQ,443); /* Now try wildcards *with* TAPMP_EXTENDED_STAR */ r=tor_addr_parse_mask_ports("*:8000-9000",TAPMP_EXTENDED_STAR, &t1,&mask,&port1,&port2); tt_int_op(r,OP_EQ,AF_UNSPEC); tt_int_op(tor_addr_family(&t1),OP_EQ,AF_UNSPEC); tt_int_op(mask,OP_EQ,0); tt_int_op(port1,OP_EQ,8000); tt_int_op(port2,OP_EQ,9000); r=tor_addr_parse_mask_ports("*4:6667",TAPMP_EXTENDED_STAR, &t1,&mask,&port1,&port2); tt_int_op(r,OP_EQ,AF_INET); tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET); tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ,0); tt_int_op(mask,OP_EQ,0); tt_int_op(port1,OP_EQ,6667); tt_int_op(port2,OP_EQ,6667); r=tor_addr_parse_mask_ports("*6",TAPMP_EXTENDED_STAR, &t1,&mask,&port1,&port2); tt_int_op(r,OP_EQ,AF_INET6); tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET6); tt_assert(tor_mem_is_zero((const char*)tor_addr_to_in6_addr32(&t1), 16)); tt_int_op(mask,OP_EQ,0); tt_int_op(port1,OP_EQ,1); tt_int_op(port2,OP_EQ,65535); /* make sure inet address lengths >= max */ tt_int_op(INET_NTOA_BUF_LEN, OP_GE, sizeof("255.255.255.255")); tt_int_op(TOR_ADDR_BUF_LEN, OP_GE, sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")); tt_assert(sizeof(tor_addr_t) >= sizeof(struct in6_addr)); /* get interface addresses */ r = get_interface_address6(LOG_DEBUG, AF_INET, &t1); tt_int_op(r, OP_LE, 0); // "it worked or it didn't" i = get_interface_address6(LOG_DEBUG, AF_INET6, &t2); tt_int_op(i, OP_LE, 0); // "it worked or it didn't" TT_BLATHER(("v4 address: %s (family=%d)", fmt_addr(&t1), tor_addr_family(&t1))); TT_BLATHER(("v6 address: %s (family=%d)", fmt_addr(&t2), tor_addr_family(&t2))); done: ; }
static void thread_conditions_simple(void *arg) { struct timeval tv_signal, tv_timeout, tv_broadcast; struct alerted_record alerted[NUM_THREADS]; THREAD_T threads[NUM_THREADS]; struct cond_wait cond; int i; struct timeval launched_at; struct event wake_one; struct event wake_all; struct basic_test_data *data = arg; struct event_base *base = data->base; int n_timed_out=0, n_signal=0, n_broadcast=0; tv_signal.tv_sec = tv_timeout.tv_sec = tv_broadcast.tv_sec = 0; tv_signal.tv_usec = 30*1000; tv_timeout.tv_usec = 150*1000; tv_broadcast.tv_usec = 500*1000; EVTHREAD_ALLOC_LOCK(cond.lock, EVTHREAD_LOCKTYPE_RECURSIVE); EVTHREAD_ALLOC_COND(cond.cond); tt_assert(cond.lock); tt_assert(cond.cond); for (i = 0; i < NUM_THREADS; ++i) { memset(&alerted[i], 0, sizeof(struct alerted_record)); alerted[i].cond = &cond; } /* Threads 5 and 6 will be allowed to time out */ memcpy(&alerted[5].delay, &tv_timeout, sizeof(tv_timeout)); memcpy(&alerted[6].delay, &tv_timeout, sizeof(tv_timeout)); evtimer_assign(&wake_one, base, wake_one_timeout, &cond); evtimer_assign(&wake_all, base, wake_all_timeout, &cond); evutil_gettimeofday(&launched_at, NULL); /* Launch the threads... */ for (i = 0; i < NUM_THREADS; ++i) { THREAD_START(threads[i], wait_for_condition, &alerted[i]); } /* Start the timers... */ tt_int_op(event_add(&wake_one, &tv_signal), ==, 0); tt_int_op(event_add(&wake_all, &tv_broadcast), ==, 0); /* And run for a bit... */ event_base_dispatch(base); /* And wait till the threads are done. */ for (i = 0; i < NUM_THREADS; ++i) THREAD_JOIN(threads[i]); /* Now, let's see what happened. At least one of 5 or 6 should * have timed out. */ n_timed_out = alerted[5].timed_out + alerted[6].timed_out; tt_int_op(n_timed_out, >=, 1); tt_int_op(n_timed_out, <=, 2); for (i = 0; i < NUM_THREADS; ++i) { const struct timeval *target_delay; struct timeval target_time, actual_delay; if (alerted[i].timed_out) { TT_BLATHER(("%d looks like a timeout\n", i)); target_delay = &tv_timeout; tt_assert(i == 5 || i == 6); } else if (evutil_timerisset(&alerted[i].alerted_at)) { long diff1,diff2; evutil_timersub(&alerted[i].alerted_at, &launched_at, &actual_delay); diff1 = timeval_msec_diff(&actual_delay, &tv_signal); diff2 = timeval_msec_diff(&actual_delay, &tv_broadcast); if (abs(diff1) < abs(diff2)) { TT_BLATHER(("%d looks like a signal\n", i)); target_delay = &tv_signal; ++n_signal; } else { TT_BLATHER(("%d looks like a broadcast\n", i)); target_delay = &tv_broadcast; ++n_broadcast; } } else { TT_FAIL(("Thread %d never got woken", i)); continue; } evutil_timeradd(target_delay, &launched_at, &target_time); test_timeval_diff_leq(&target_time, &alerted[i].alerted_at, 0, 50); } tt_int_op(n_broadcast + n_signal + n_timed_out, ==, NUM_THREADS); tt_int_op(n_signal, ==, 1); end: ; }
static void dnslogcb(int w, const char *m) { TT_BLATHER(("%s", m)); }
static void test_edgetriggered(void *et) { struct event *ev = NULL; struct event_base *base = NULL; const char *test = "test string"; evutil_socket_t pair[2] = {-1,-1}; int supports_et; /* On Linux 3.2.1 (at least, as patched by Fedora and tested by Nick), * doing a "recv" on an AF_UNIX socket resets the readability of the * socket, even though there is no state change, so we don't actually * get edge-triggered behavior. Yuck! Linux 3.1.9 didn't have this * problem. */ #ifdef __linux__ if (evutil_ersatz_socketpair_(AF_INET, SOCK_STREAM, 0, pair) == -1) { tt_abort_perror("socketpair"); } #else if (evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM, 0, pair) == -1) { tt_abort_perror("socketpair"); } #endif called = was_et = 0; tt_int_op(send(pair[0], test, (int)strlen(test)+1, 0), >, 0); shutdown(pair[0], SHUT_WR); /* Initalize the event library */ base = event_base_new(); if (!strcmp(event_base_get_method(base), "epoll") || !strcmp(event_base_get_method(base), "epoll (with changelist)") || !strcmp(event_base_get_method(base), "kqueue")) supports_et = 1; else supports_et = 0; TT_BLATHER(("Checking for edge-triggered events with %s, which should %s" "support edge-triggering", event_base_get_method(base), supports_et?"":"not ")); /* Initalize one event */ ev = event_new(base, pair[1], EV_READ|EV_ET|EV_PERSIST, read_cb, &ev); event_add(ev, NULL); /* We're going to call the dispatch function twice. The first invocation * will read a single byte from pair[1] in either case. If we're edge * triggered, we'll only see the event once (since we only see transitions * from no data to data), so the second invocation of event_base_loop will * do nothing. If we're level triggered, the second invocation of * event_base_loop will also activate the event (because there's still * data to read). */ event_base_loop(base,EVLOOP_NONBLOCK|EVLOOP_ONCE); event_base_loop(base,EVLOOP_NONBLOCK|EVLOOP_ONCE); if (supports_et) { tt_int_op(called, ==, 1); tt_assert(was_et); } else {
static void dns_gethostbyname_cb(int result, char type, int count, int ttl, void *addresses, void *arg) { dns_ok = dns_err = 0; if (result == DNS_ERR_TIMEOUT) { printf("[Timed out] "); dns_err = result; goto out; } if (result != DNS_ERR_NONE) { printf("[Error code %d] ", result); goto out; } TT_BLATHER(("type: %d, count: %d, ttl: %d: ", type, count, ttl)); switch (type) { case DNS_IPv6_AAAA: { #if defined(_EVENT_HAVE_STRUCT_IN6_ADDR) && defined(_EVENT_HAVE_INET_NTOP) && defined(INET6_ADDRSTRLEN) struct in6_addr *in6_addrs = addresses; char buf[INET6_ADDRSTRLEN+1]; int i; /* a resolution that's not valid does not help */ if (ttl < 0) goto out; for (i = 0; i < count; ++i) { const char *b = inet_ntop(AF_INET6, &in6_addrs[i], buf,sizeof(buf)); if (b) TT_BLATHER(("%s ", b)); else TT_BLATHER(("%s ", strerror(errno))); } #endif break; } case DNS_IPv4_A: { struct in_addr *in_addrs = addresses; int i; /* a resolution that's not valid does not help */ if (ttl < 0) goto out; for (i = 0; i < count; ++i) TT_BLATHER(("%s ", inet_ntoa(in_addrs[i]))); break; } case DNS_PTR: /* may get at most one PTR */ if (count != 1) goto out; TT_BLATHER(("%s ", *(char **)addresses)); break; default: goto out; } dns_ok = type; out: if (arg == NULL) event_loopexit(NULL); else event_base_loopexit((struct event_base *)arg, NULL); }
/** Run unit tests for IPv6 encoding/decoding/manipulation functions. */ static void test_addr_ip6_helpers(void) { char buf[TOR_ADDR_BUF_LEN], bug[TOR_ADDR_BUF_LEN]; char rbuf[REVERSE_LOOKUP_NAME_BUF_LEN]; struct in6_addr a1, a2; tor_addr_t t1, t2; int r, i; uint16_t port1, port2; maskbits_t mask; const char *p1; struct sockaddr_storage sa_storage; struct sockaddr_in *sin; struct sockaddr_in6 *sin6; /* Test tor_inet_ntop and tor_inet_pton: IPv6 */ { const char *ip = "2001::1234"; const char *ip_ffff = "::ffff:192.168.1.2"; /* good round trip */ test_eq(tor_inet_pton(AF_INET6, ip, &a1), 1); test_eq_ptr(tor_inet_ntop(AF_INET6, &a1, buf, sizeof(buf)), &buf); test_streq(buf, ip); /* good round trip - ::ffff:0:0 style */ test_eq(tor_inet_pton(AF_INET6, ip_ffff, &a2), 1); test_eq_ptr(tor_inet_ntop(AF_INET6, &a2, buf, sizeof(buf)), &buf); test_streq(buf, ip_ffff); /* just long enough buffer (remember \0) */ test_streq(tor_inet_ntop(AF_INET6, &a1, buf, strlen(ip)+1), ip); test_streq(tor_inet_ntop(AF_INET6, &a2, buf, strlen(ip_ffff)+1), ip_ffff); /* too short buffer (remember \0) */ test_eq_ptr(tor_inet_ntop(AF_INET6, &a1, buf, strlen(ip)), NULL); test_eq_ptr(tor_inet_ntop(AF_INET6, &a2, buf, strlen(ip_ffff)), NULL); } /* ==== Converting to and from sockaddr_t. */ sin = (struct sockaddr_in *)&sa_storage; sin->sin_family = AF_INET; sin->sin_port = 9090; sin->sin_addr.s_addr = htonl(0x7f7f0102); /*127.127.1.2*/ tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin, NULL); test_eq(tor_addr_family(&t1), AF_INET); test_eq(tor_addr_to_ipv4h(&t1), 0x7f7f0102); memset(&sa_storage, 0, sizeof(sa_storage)); test_eq(sizeof(struct sockaddr_in), tor_addr_to_sockaddr(&t1, 1234, (struct sockaddr *)&sa_storage, sizeof(sa_storage))); test_eq(1234, ntohs(sin->sin_port)); test_eq(0x7f7f0102, ntohl(sin->sin_addr.s_addr)); memset(&sa_storage, 0, sizeof(sa_storage)); sin6 = (struct sockaddr_in6 *)&sa_storage; sin6->sin6_family = AF_INET6; sin6->sin6_port = htons(7070); sin6->sin6_addr.s6_addr[0] = 128; tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin6, NULL); test_eq(tor_addr_family(&t1), AF_INET6); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0); test_streq(p1, "8000::"); memset(&sa_storage, 0, sizeof(sa_storage)); test_eq(sizeof(struct sockaddr_in6), tor_addr_to_sockaddr(&t1, 9999, (struct sockaddr *)&sa_storage, sizeof(sa_storage))); test_eq(AF_INET6, sin6->sin6_family); test_eq(9999, ntohs(sin6->sin6_port)); test_eq(0x80000000, ntohl(S6_ADDR32(sin6->sin6_addr)[0])); /* ==== tor_addr_lookup: static cases. (Can't test dns without knowing we * have a good resolver. */ test_eq(0, tor_addr_lookup("127.128.129.130", AF_UNSPEC, &t1)); test_eq(AF_INET, tor_addr_family(&t1)); test_eq(tor_addr_to_ipv4h(&t1), 0x7f808182); test_eq(0, tor_addr_lookup("9000::5", AF_UNSPEC, &t1)); test_eq(AF_INET6, tor_addr_family(&t1)); test_eq(0x90, tor_addr_to_in6_addr8(&t1)[0]); test_assert(tor_mem_is_zero((char*)tor_addr_to_in6_addr8(&t1)+1, 14)); test_eq(0x05, tor_addr_to_in6_addr8(&t1)[15]); /* === Test pton: valid af_inet6 */ /* Simple, valid parsing. */ r = tor_inet_pton(AF_INET6, "0102:0304:0506:0708:090A:0B0C:0D0E:0F10", &a1); test_assert(r==1); for (i=0;i<16;++i) { test_eq(i+1, (int)a1.s6_addr[i]); } /* ipv4 ending. */ test_pton6_same("0102:0304:0506:0708:090A:0B0C:0D0E:0F10", "0102:0304:0506:0708:090A:0B0C:13.14.15.16"); /* shortened words. */ test_pton6_same("0001:0099:BEEF:0000:0123:FFFF:0001:0001", "1:99:BEEF:0:0123:FFFF:1:1"); /* zeros at the beginning */ test_pton6_same("0000:0000:0000:0000:0009:C0A8:0001:0001", "::9:c0a8:1:1"); test_pton6_same("0000:0000:0000:0000:0009:C0A8:0001:0001", "::9:c0a8:0.1.0.1"); /* zeros in the middle. */ test_pton6_same("fe80:0000:0000:0000:0202:1111:0001:0001", "fe80::202:1111:1:1"); /* zeros at the end. */ test_pton6_same("1000:0001:0000:0007:0000:0000:0000:0000", "1000:1:0:7::"); /* === Test ntop: af_inet6 */ test_ntop6_reduces("0:0:0:0:0:0:0:0", "::"); test_ntop6_reduces("0001:0099:BEEF:0006:0123:FFFF:0001:0001", "1:99:beef:6:123:ffff:1:1"); //test_ntop6_reduces("0:0:0:0:0:0:c0a8:0101", "::192.168.1.1"); test_ntop6_reduces("0:0:0:0:0:ffff:c0a8:0101", "::ffff:192.168.1.1"); test_ntop6_reduces("002:0:0000:0:3::4", "2::3:0:0:4"); test_ntop6_reduces("0:0::1:0:3", "::1:0:3"); test_ntop6_reduces("008:0::0", "8::"); test_ntop6_reduces("0:0:0:0:0:ffff::1", "::ffff:0.0.0.1"); test_ntop6_reduces("abcd:0:0:0:0:0:7f00::", "abcd::7f00:0"); test_ntop6_reduces("0000:0000:0000:0000:0009:C0A8:0001:0001", "::9:c0a8:1:1"); test_ntop6_reduces("fe80:0000:0000:0000:0202:1111:0001:0001", "fe80::202:1111:1:1"); test_ntop6_reduces("1000:0001:0000:0007:0000:0000:0000:0000", "1000:1:0:7::"); /* Bad af param */ test_eq(tor_inet_pton(AF_UNSPEC, 0, 0), -1); /* === Test pton: invalid in6. */ test_pton6_bad("foobar."); test_pton6_bad("-1::"); test_pton6_bad("00001::"); test_pton6_bad("10000::"); test_pton6_bad("::10000"); test_pton6_bad("55555::"); test_pton6_bad("9:-60::"); test_pton6_bad("9:+60::"); test_pton6_bad("9|60::"); test_pton6_bad("0x60::"); test_pton6_bad("::0x60"); test_pton6_bad("9:0x60::"); test_pton6_bad("1:2:33333:4:0002:3::"); test_pton6_bad("1:2:3333:4:fish:3::"); test_pton6_bad("1:2:3:4:5:6:7:8:9"); test_pton6_bad("1:2:3:4:5:6:7"); test_pton6_bad("1:2:3:4:5:6:1.2.3.4.5"); test_pton6_bad("1:2:3:4:5:6:1.2.3"); test_pton6_bad("::1.2.3"); test_pton6_bad("::1.2.3.4.5"); test_pton6_bad("::ffff:0xff.0.0.0"); test_pton6_bad("::ffff:ff.0.0.0"); test_pton6_bad("::ffff:256.0.0.0"); test_pton6_bad("::ffff:-1.0.0.0"); test_pton6_bad("99"); test_pton6_bad(""); test_pton6_bad("."); test_pton6_bad(":"); test_pton6_bad("1::2::3:4"); test_pton6_bad("a:::b:c"); test_pton6_bad(":::a:b:c"); test_pton6_bad("a:b:c:::"); /* test internal checking */ test_external_ip("fbff:ffff::2:7", 0); test_internal_ip("fc01::2:7", 0); test_internal_ip("fc01::02:7", 0); test_internal_ip("fc01::002:7", 0); test_internal_ip("fc01::0002:7", 0); test_internal_ip("fdff:ffff::f:f", 0); test_external_ip("fe00::3:f", 0); test_external_ip("fe7f:ffff::2:7", 0); test_internal_ip("fe80::2:7", 0); test_internal_ip("febf:ffff::f:f", 0); test_internal_ip("fec0::2:7:7", 0); test_internal_ip("feff:ffff::e:7:7", 0); test_external_ip("ff00::e:7:7", 0); test_internal_ip("::", 0); test_internal_ip("::1", 0); test_internal_ip("::1", 1); test_internal_ip("::", 0); test_external_ip("::", 1); test_external_ip("::2", 0); test_external_ip("2001::", 0); test_external_ip("ffff::", 0); test_external_ip("::ffff:0.0.0.0", 1); test_internal_ip("::ffff:0.0.0.0", 0); test_internal_ip("::ffff:0.255.255.255", 0); test_external_ip("::ffff:1.0.0.0", 0); test_external_ip("::ffff:9.255.255.255", 0); test_internal_ip("::ffff:10.0.0.0", 0); test_internal_ip("::ffff:10.255.255.255", 0); test_external_ip("::ffff:11.0.0.0", 0); test_external_ip("::ffff:126.255.255.255", 0); test_internal_ip("::ffff:127.0.0.0", 0); test_internal_ip("::ffff:127.255.255.255", 0); test_external_ip("::ffff:128.0.0.0", 0); test_external_ip("::ffff:172.15.255.255", 0); test_internal_ip("::ffff:172.16.0.0", 0); test_internal_ip("::ffff:172.31.255.255", 0); test_external_ip("::ffff:172.32.0.0", 0); test_external_ip("::ffff:192.167.255.255", 0); test_internal_ip("::ffff:192.168.0.0", 0); test_internal_ip("::ffff:192.168.255.255", 0); test_external_ip("::ffff:192.169.0.0", 0); test_external_ip("::ffff:169.253.255.255", 0); test_internal_ip("::ffff:169.254.0.0", 0); test_internal_ip("::ffff:169.254.255.255", 0); test_external_ip("::ffff:169.255.0.0", 0); test_assert(is_internal_IP(0x7f000001, 0)); /* tor_addr_compare(tor_addr_t x2) */ test_addr_compare("ffff::", ==, "ffff::0"); test_addr_compare("0::3:2:1", <, "0::ffff:0.3.2.1"); test_addr_compare("0::2:2:1", <, "0::ffff:0.3.2.1"); test_addr_compare("0::ffff:0.3.2.1", >, "0::0:0:0"); test_addr_compare("0::ffff:5.2.2.1", <, "::ffff:6.0.0.0"); /* XXXX wrong. */ tor_addr_parse_mask_ports("[::ffff:2.3.4.5]", &t1, NULL, NULL, NULL); tor_addr_parse_mask_ports("2.3.4.5", &t2, NULL, NULL, NULL); test_assert(tor_addr_compare(&t1, &t2, CMP_SEMANTIC) == 0); tor_addr_parse_mask_ports("[::ffff:2.3.4.4]", &t1, NULL, NULL, NULL); tor_addr_parse_mask_ports("2.3.4.5", &t2, NULL, NULL, NULL); test_assert(tor_addr_compare(&t1, &t2, CMP_SEMANTIC) < 0); /* test compare_masked */ test_addr_compare_masked("ffff::", ==, "ffff::0", 128); test_addr_compare_masked("ffff::", ==, "ffff::0", 64); test_addr_compare_masked("0::2:2:1", <, "0::8000:2:1", 81); test_addr_compare_masked("0::2:2:1", ==, "0::8000:2:1", 80); /* Test undecorated tor_addr_to_str */ test_eq(AF_INET6, tor_addr_parse(&t1, "[123:45:6789::5005:11]")); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0); test_streq(p1, "123:45:6789::5005:11"); test_eq(AF_INET, tor_addr_parse(&t1, "18.0.0.1")); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0); test_streq(p1, "18.0.0.1"); /* Test decorated tor_addr_to_str */ test_eq(AF_INET6, tor_addr_parse(&t1, "[123:45:6789::5005:11]")); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); test_streq(p1, "[123:45:6789::5005:11]"); test_eq(AF_INET, tor_addr_parse(&t1, "18.0.0.1")); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); test_streq(p1, "18.0.0.1"); /* Test buffer bounds checking of tor_addr_to_str */ test_eq(AF_INET6, tor_addr_parse(&t1, "::")); /* 2 + \0 */ test_eq_ptr(tor_addr_to_str(buf, &t1, 2, 0), NULL); /* too short buf */ test_streq(tor_addr_to_str(buf, &t1, 3, 0), "::"); test_eq_ptr(tor_addr_to_str(buf, &t1, 4, 1), NULL); /* too short buf */ test_streq(tor_addr_to_str(buf, &t1, 5, 1), "[::]"); test_eq(AF_INET6, tor_addr_parse(&t1, "2000::1337")); /* 10 + \0 */ test_eq_ptr(tor_addr_to_str(buf, &t1, 10, 0), NULL); /* too short buf */ test_streq(tor_addr_to_str(buf, &t1, 11, 0), "2000::1337"); test_eq_ptr(tor_addr_to_str(buf, &t1, 12, 1), NULL); /* too short buf */ test_streq(tor_addr_to_str(buf, &t1, 13, 1), "[2000::1337]"); test_eq(AF_INET, tor_addr_parse(&t1, "1.2.3.4")); /* 7 + \0 */ test_eq_ptr(tor_addr_to_str(buf, &t1, 7, 0), NULL); /* too short buf */ test_streq(tor_addr_to_str(buf, &t1, 8, 0), "1.2.3.4"); test_eq(AF_INET, tor_addr_parse(&t1, "255.255.255.255")); /* 15 + \0 */ test_eq_ptr(tor_addr_to_str(buf, &t1, 15, 0), NULL); /* too short buf */ test_streq(tor_addr_to_str(buf, &t1, 16, 0), "255.255.255.255"); test_eq_ptr(tor_addr_to_str(buf, &t1, 15, 1), NULL); /* too short buf */ test_streq(tor_addr_to_str(buf, &t1, 16, 1), "255.255.255.255"); t1.family = AF_UNSPEC; test_eq_ptr(tor_addr_to_str(buf, &t1, sizeof(buf), 0), NULL); /* Test tor_addr_parse_PTR_name */ i = tor_addr_parse_PTR_name(&t1, "Foobar.baz", AF_UNSPEC, 0); test_eq(0, i); i = tor_addr_parse_PTR_name(&t1, "Foobar.baz", AF_UNSPEC, 1); test_eq(0, i); i = tor_addr_parse_PTR_name(&t1, "1.0.168.192.in-addr.arpa", AF_UNSPEC, 1); test_eq(1, i); test_eq(tor_addr_family(&t1), AF_INET); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); test_streq(p1, "192.168.0.1"); i = tor_addr_parse_PTR_name(&t1, "192.168.0.99", AF_UNSPEC, 0); test_eq(0, i); i = tor_addr_parse_PTR_name(&t1, "192.168.0.99", AF_UNSPEC, 1); test_eq(1, i); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); test_streq(p1, "192.168.0.99"); memset(&t1, 0, sizeof(t1)); i = tor_addr_parse_PTR_name(&t1, "0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_UNSPEC, 0); test_eq(1, i); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); test_streq(p1, "[9dee:effe:ebe1:beef:fedc:ba98:7654:3210]"); /* Failing cases. */ i = tor_addr_parse_PTR_name(&t1, "6.7.8.9.a.b.c.d.e.f." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_UNSPEC, 0); test_eq(i, -1); i = tor_addr_parse_PTR_name(&t1, "6.7.8.9.a.b.c.d.e.f.a.b.c.d.e.f.0." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_UNSPEC, 0); test_eq(i, -1); i = tor_addr_parse_PTR_name(&t1, "6.7.8.9.a.b.c.d.e.f.X.0.0.0.0.9." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_UNSPEC, 0); test_eq(i, -1); i = tor_addr_parse_PTR_name(&t1, "32.1.1.in-addr.arpa", AF_UNSPEC, 0); test_eq(i, -1); i = tor_addr_parse_PTR_name(&t1, ".in-addr.arpa", AF_UNSPEC, 0); test_eq(i, -1); i = tor_addr_parse_PTR_name(&t1, "1.2.3.4.5.in-addr.arpa", AF_UNSPEC, 0); test_eq(i, -1); i = tor_addr_parse_PTR_name(&t1, "1.2.3.4.5.in-addr.arpa", AF_INET6, 0); test_eq(i, -1); i = tor_addr_parse_PTR_name(&t1, "6.7.8.9.a.b.c.d.e.f.a.b.c.d.e.0." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_INET, 0); test_eq(i, -1); /* === Test tor_addr_to_PTR_name */ /* Stage IPv4 addr */ memset(&sa_storage, 0, sizeof(sa_storage)); sin = (struct sockaddr_in *)&sa_storage; sin->sin_family = AF_INET; sin->sin_addr.s_addr = htonl(0x7f010203); /* 127.1.2.3 */ tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin, NULL); /* Check IPv4 PTR - too short buffer */ test_eq(tor_addr_to_PTR_name(rbuf, 1, &t1), -1); test_eq(tor_addr_to_PTR_name(rbuf, strlen("3.2.1.127.in-addr.arpa") - 1, &t1), -1); /* Check IPv4 PTR - valid addr */ test_eq(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1), strlen("3.2.1.127.in-addr.arpa")); test_streq(rbuf, "3.2.1.127.in-addr.arpa"); /* Invalid addr family */ t1.family = AF_UNSPEC; test_eq(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1), -1); /* Stage IPv6 addr */ memset(&sa_storage, 0, sizeof(sa_storage)); sin6 = (struct sockaddr_in6 *)&sa_storage; sin6->sin6_family = AF_INET6; sin6->sin6_addr.s6_addr[0] = 0x80; /* 8000::abcd */ sin6->sin6_addr.s6_addr[14] = 0xab; sin6->sin6_addr.s6_addr[15] = 0xcd; tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin6, NULL); { const char* addr_PTR = "d.c.b.a.0.0.0.0.0.0.0.0.0.0.0.0." "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.ip6.arpa"; /* Check IPv6 PTR - too short buffer */ test_eq(tor_addr_to_PTR_name(rbuf, 0, &t1), -1); test_eq(tor_addr_to_PTR_name(rbuf, strlen(addr_PTR) - 1, &t1), -1); /* Check IPv6 PTR - valid addr */ test_eq(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1), strlen(addr_PTR)); test_streq(rbuf, addr_PTR); } /* test tor_addr_parse_mask_ports */ test_addr_mask_ports_parse("[::f]/17:47-95", AF_INET6, 0, 0, 0, 0x0000000f, 17, 47, 95); test_streq(p1, "::f"); //test_addr_parse("[::fefe:4.1.1.7/120]:999-1000"); //test_addr_parse_check("::fefe:401:107", 120, 999, 1000); test_addr_mask_ports_parse("[::ffff:4.1.1.7]/120:443", AF_INET6, 0, 0, 0x0000ffff, 0x04010107, 120, 443, 443); test_streq(p1, "::ffff:4.1.1.7"); test_addr_mask_ports_parse("[abcd:2::44a:0]:2-65000", AF_INET6, 0xabcd0002, 0, 0, 0x044a0000, 128, 2, 65000); test_streq(p1, "abcd:2::44a:0"); r=tor_addr_parse_mask_ports("[fefef::]/112", &t1, NULL, NULL, NULL); test_assert(r == -1); r=tor_addr_parse_mask_ports("efef::/112", &t1, NULL, NULL, NULL); test_assert(r == -1); r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f::]", &t1, NULL, NULL, NULL); test_assert(r == -1); r=tor_addr_parse_mask_ports("[::f:f:f:f:f:f:f:f]", &t1, NULL, NULL, NULL); test_assert(r == -1); r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f:f]", &t1, NULL, NULL, NULL); test_assert(r == -1); /* Test for V4-mapped address with mask < 96. (arguably not valid) */ r=tor_addr_parse_mask_ports("[::ffff:1.1.2.2/33]", &t1, &mask, NULL, NULL); test_assert(r == -1); r=tor_addr_parse_mask_ports("1.1.2.2/33", &t1, &mask, NULL, NULL); test_assert(r == -1); r=tor_addr_parse_mask_ports("1.1.2.2/31", &t1, &mask, NULL, NULL); test_assert(r == AF_INET); r=tor_addr_parse_mask_ports("[efef::]/112", &t1, &mask, &port1, &port2); test_assert(r == AF_INET6); test_assert(port1 == 1); test_assert(port2 == 65535); /* make sure inet address lengths >= max */ test_assert(INET_NTOA_BUF_LEN >= sizeof("255.255.255.255")); test_assert(TOR_ADDR_BUF_LEN >= sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")); test_assert(sizeof(tor_addr_t) >= sizeof(struct in6_addr)); /* get interface addresses */ r = get_interface_address6(LOG_DEBUG, AF_INET, &t1); i = get_interface_address6(LOG_DEBUG, AF_INET6, &t2); TT_BLATHER(("v4 address: %s (family=%d)", fmt_addr(&t1), tor_addr_family(&t1))); TT_BLATHER(("v6 address: %s (family=%d)", fmt_addr(&t2), tor_addr_family(&t2))); done: ; }