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 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); }
// Tests if an options with MyFamily fingerprints missing '$' normalises // them correctly and also ensure it also works with multiple fingerprints static void test_config_fix_my_family(void *arg) { char *err = NULL; const char *family = "$1111111111111111111111111111111111111111, " "1111111111111111111111111111111111111112, " "$1111111111111111111111111111111111111113"; or_options_t* options = options_new(); or_options_t* defaults = options_new(); (void) arg; options_init(options); options_init(defaults); options->MyFamily = tor_strdup(family); options_validate(NULL, options, defaults, 0, &err) ; if (err != NULL) { TT_FAIL(("options_validate failed: %s", err)); } test_streq(options->MyFamily, "$1111111111111111111111111111111111111111, " "$1111111111111111111111111111111111111112, " "$1111111111111111111111111111111111111113"); done: if (err != NULL) { tor_free(err); } or_options_free(options); or_options_free(defaults); }
/* 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_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 int handshake_start(or_connection_t *conn, int receiving) { if (!conn || !receiving) TT_FAIL(("Bad arguments to handshake_start")); handshake_start_called = 1; return 0; }
static void crypto_rand_return_tse_str(char *to, size_t n) { if (n != 32) { TT_FAIL(("Asked for %d bytes, not 32", (int)n)); return; } memcpy(to, "te road There is always another ", 32); }
static void regress_ipv4_parse(void *ptr) { int i; for (i = 0; ipv4_entries[i].addr; ++i) { char written[128]; struct ipv4_entry *ent = &ipv4_entries[i]; struct in_addr in; int r; r = evutil_inet_pton(AF_INET, ent->addr, &in); 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; } if (ntohl(in.s_addr) != ent->res) { TT_FAIL(("%s parsed to %lx, but we expected %lx", ent->addr, (unsigned long)ntohl(in.s_addr), (unsigned long)ent->res)); continue; } if (ent->status == CANONICAL) { const char *w = evutil_inet_ntop(AF_INET, &in, 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; } } } }
static void regress_sockaddr_port_parse(void *ptr) { struct sockaddr_storage ss; int i, r; for (i = 0; sa_port_ents[i].parse; ++i) { struct sa_port_ent *ent = &sa_port_ents[i]; int len = sizeof(ss); memset(&ss, 0, sizeof(ss)); r = evutil_parse_sockaddr_port(ent->parse, (struct sockaddr*)&ss, &len); if (r < 0) { if (ent->safamily) TT_FAIL(("Couldn't parse %s!", ent->parse)); continue; } else if (! ent->safamily) { TT_FAIL(("Shouldn't have been able to parse %s!", ent->parse)); continue; } if (ent->safamily == AF_INET) { struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); #ifdef EVENT__HAVE_STRUCT_SOCKADDR_IN_SIN_LEN sin.sin_len = sizeof(sin); #endif sin.sin_family = AF_INET; sin.sin_port = htons(ent->port); r = evutil_inet_pton(AF_INET, ent->addr, &sin.sin_addr); if (1 != r) { TT_FAIL(("Couldn't parse ipv4 target %s.", ent->addr)); } else if (memcmp(&sin, &ss, sizeof(sin))) { TT_FAIL(("Parse for %s was not as expected.", ent->parse)); } else if (len != sizeof(sin)) { TT_FAIL(("Length for %s not as expected.",ent->parse)); } } else { struct sockaddr_in6 sin6; memset(&sin6, 0, sizeof(sin6)); #ifdef EVENT__HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN sin6.sin6_len = sizeof(sin6); #endif sin6.sin6_family = AF_INET6; sin6.sin6_port = htons(ent->port); r = evutil_inet_pton(AF_INET6, ent->addr, &sin6.sin6_addr); if (1 != r) { TT_FAIL(("Couldn't parse ipv6 target %s.", ent->addr)); } else if (memcmp(&sin6, &ss, sizeof(sin6))) { TT_FAIL(("Parse for %s was not as expected.", ent->parse)); } else if (len != sizeof(sin6)) { TT_FAIL(("Length for %s not as expected.",ent->parse)); } } } }
/* Test helper function: Make sure that a bridge line is * unparseable. */ static void bad_bridge_line_test(const char *string) { bridge_line_t *bridge_line = parse_bridge_line(string); if (bridge_line) TT_FAIL(("%s was supposed to fail, but it didn't.", string)); test_assert(!bridge_line); done: bridge_line_free(bridge_line); }
static void test_evutil_sockaddr_predicates(void *ptr) { struct sockaddr_storage ss; int r, i; for (i=0; sa_pred_entries[i].parse; ++i) { struct sa_pred_ent *ent = &sa_pred_entries[i]; int len = sizeof(ss); r = evutil_parse_sockaddr_port(ent->parse, (struct sockaddr*)&ss, &len); if (r<0) { TT_FAIL(("Couldn't parse %s!", ent->parse)); continue; } /* sockaddr_is_loopback */ if (ent->is_loopback != evutil_sockaddr_is_loopback_((struct sockaddr*)&ss)) { TT_FAIL(("evutil_sockaddr_loopback(%s) not as expected", ent->parse)); } } }
/* small replacement mock for circuit_mark_for_close_ to avoid doing all * the other bookkeeping that comes with marking circuits. */ static void circuit_mark_for_close_dummy_(circuit_t *circ, int reason, int line, const char *file) { (void) reason; if (circ->marked_for_close) { TT_FAIL(("Circuit already marked for close at %s:%d, but we are marking " "it again at %s:%d", circ->marked_for_close_file, (int)circ->marked_for_close, file, line)); } circ->marked_for_close = line; circ->marked_for_close_file = file; }
/* 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 reader_eventcb(struct bufferevent *bev, short what, void *ctx) { struct event_base *base = ctx; if (what & BEV_EVENT_ERROR) { perror("foobar"); TT_FAIL(("got connector error %d", (int)what)); return; } if (what & BEV_EVENT_CONNECTED) { bufferevent_enable(bev, EV_READ); } if (what & BEV_EVENT_EOF) { char buf[512]; size_t n; n = bufferevent_read(bev, buf, sizeof(buf)-1); buf[n] = '\0'; tt_str_op(buf, ==, TEST_STR); if (++n_strings_read == 2) event_base_loopexit(base, NULL); }
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 sender_errorcb(struct bufferevent *bev, short what, void *ctx) { TT_FAIL(("Got sender error %d",(int)what)); }
/* Implements a DNS server for the connect_hostname test and the * getaddrinfo_async test */ static void be_getaddrinfo_server_cb(struct evdns_server_request *req, void *data) { int i; int *n_got_p=data; int added_any=0; ++*n_got_p; for (i=0;i<req->nquestions;++i) { const int qtype = req->questions[i]->type; const int qclass = req->questions[i]->dns_question_class; const char *qname = req->questions[i]->name; struct in_addr ans; struct in6_addr ans6; memset(&ans6, 0, sizeof(ans6)); if (qtype == EVDNS_TYPE_A && qclass == EVDNS_CLASS_INET && !evutil_ascii_strcasecmp(qname, "nobodaddy.example.com")) { ans.s_addr = htonl(0x7f000001); evdns_server_request_add_a_reply(req, qname, 1, &ans.s_addr, 2000); added_any = 1; } else if (!evutil_ascii_strcasecmp(qname, "nosuchplace.example.com")) { /* ok, just say notfound. */ } else if (!evutil_ascii_strcasecmp(qname, "both.example.com")) { if (qtype == EVDNS_TYPE_A) { ans.s_addr = htonl(0x50502020); evdns_server_request_add_a_reply(req, qname, 1, &ans.s_addr, 2000); added_any = 1; } else if (qtype == EVDNS_TYPE_AAAA) { ans6.s6_addr[0] = 0x80; ans6.s6_addr[1] = 0xff; ans6.s6_addr[14] = 0xbb; ans6.s6_addr[15] = 0xbb; evdns_server_request_add_aaaa_reply(req, qname, 1, &ans6.s6_addr, 2000); added_any = 1; } evdns_server_request_add_cname_reply(req, qname, "both-canonical.example.com", 1000); } else if (!evutil_ascii_strcasecmp(qname, "v4only.example.com") || !evutil_ascii_strcasecmp(qname, "v4assert.example.com")) { if (qtype == EVDNS_TYPE_A) { ans.s_addr = htonl(0x12345678); evdns_server_request_add_a_reply(req, qname, 1, &ans.s_addr, 2000); added_any = 1; } else if (!evutil_ascii_strcasecmp(qname, "v4assert.example.com")) { TT_FAIL(("Got an AAAA request for v4assert")); } } else if (!evutil_ascii_strcasecmp(qname, "v6only.example.com") || !evutil_ascii_strcasecmp(qname, "v6assert.example.com")) { if (qtype == EVDNS_TYPE_AAAA) { ans6.s6_addr[0] = 0x0b; ans6.s6_addr[1] = 0x0b; ans6.s6_addr[14] = 0xf0; ans6.s6_addr[15] = 0x0d; evdns_server_request_add_aaaa_reply(req, qname, 1, &ans6.s6_addr, 2000); added_any = 1; } else if (!evutil_ascii_strcasecmp(qname, "v6assert.example.com")) { TT_FAIL(("Got a A request for v6assert")); } } else if (!evutil_ascii_strcasecmp(qname, "v6timeout.example.com")) { if (qtype == EVDNS_TYPE_A) { ans.s_addr = htonl(0xabcdef01); evdns_server_request_add_a_reply(req, qname, 1, &ans.s_addr, 2000); added_any = 1; } else if (qtype == EVDNS_TYPE_AAAA) { /* Let the v6 request time out.*/ evdns_server_request_drop(req); return; } } else if (!evutil_ascii_strcasecmp(qname, "v4timeout.example.com")) { if (qtype == EVDNS_TYPE_AAAA) { ans6.s6_addr[0] = 0x0a; ans6.s6_addr[1] = 0x0a; ans6.s6_addr[14] = 0xff; ans6.s6_addr[15] = 0x01; evdns_server_request_add_aaaa_reply(req, qname, 1, &ans6.s6_addr, 2000); added_any = 1; } else if (qtype == EVDNS_TYPE_A) { /* Let the v4 request time out.*/ evdns_server_request_drop(req); return; } } else if (!evutil_ascii_strcasecmp(qname, "v6timeout-nonexist.example.com")) { if (qtype == EVDNS_TYPE_A) { /* Fall through, give an nexist. */ } else if (qtype == EVDNS_TYPE_AAAA) { /* Let the v6 request time out.*/ evdns_server_request_drop(req); return; } } else if (!evutil_ascii_strcasecmp(qname, "all-timeout.example.com")) { /* drop all requests */ evdns_server_request_drop(req); return; } else { TT_GRIPE(("Got weird request for %s",qname)); } } if (added_any) evdns_server_request_respond(req, 0); else evdns_server_request_respond(req, 3); }