Loading src/core/or/connection_or.c +2 −9 Original line number Diff line number Diff line Loading @@ -95,13 +95,6 @@ static unsigned int connection_or_is_bad_for_new_circs(or_connection_t *or_conn); static void connection_or_mark_bad_for_new_circs(or_connection_t *or_conn); /* * Call this when changing connection state, so notifications to the owning * channel can be handled. */ static void connection_or_change_state(or_connection_t *conn, uint8_t state); static void connection_or_check_canonicity(or_connection_t *conn, int started_here); Loading Loading @@ -457,8 +450,8 @@ connection_or_state_publish(const or_connection_t *conn, uint8_t state) * be notified. */ static void connection_or_change_state(or_connection_t *conn, uint8_t state) MOCK_IMPL(STATIC void, connection_or_change_state,(or_connection_t *conn, uint8_t state)) { tor_assert(conn); Loading src/core/or/connection_or.h +7 −0 Original line number Diff line number Diff line Loading @@ -134,6 +134,13 @@ void connection_or_group_set_badness_(smartlist_t *group, int force); #ifdef CONNECTION_OR_PRIVATE STATIC int should_connect_to_relay(const or_connection_t *or_conn); STATIC void note_or_connect_failed(const or_connection_t *or_conn); /* * Call this when changing connection state, so notifications to the owning * channel can be handled. */ MOCK_DECL(STATIC void,connection_or_change_state, (or_connection_t *conn, uint8_t state)); #endif #ifdef TOR_UNIT_TESTS Loading src/test/test_connection.c +75 −2 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ #include "core/or/or.h" #include "test/test.h" #include "app/config/or_options_st.h" #include "core/mainloop/connection.h" #include "core/or/connection_edge.h" #include "feature/hs/hs_common.h" Loading Loading @@ -312,6 +313,31 @@ test_conn_download_status_teardown(const struct testcase_t *tc, void *arg) return rv; } static void * test_conn_proxy_connect_setup(const struct testcase_t *tc) { tcp_proxy_protocol_t proxy_type = (tcp_proxy_protocol_t)tc->setup_data; switch (proxy_type) { case TCP_PROXY_PROTOCOL_HAPROXY: return test_conn_get_proxy_or_connection(PROXY_HAPROXY); default: return NULL; } } static int test_conn_proxy_connect_teardown(const struct testcase_t *tc, void *arg) { (void)tc; or_connection_t *conn = arg; tt_assert(conn); assert_connection_ok(&conn->base_, time(NULL)); done: return 1; } /* Like connection_ap_make_link(), but does much less */ static connection_t * test_conn_get_linked_connection(connection_t *l_conn, uint8_t state) Loading Loading @@ -360,6 +386,10 @@ static struct testcase_setup_t test_conn_download_status_st = { test_conn_download_status_setup, test_conn_download_status_teardown }; static struct testcase_setup_t test_conn_proxy_connect_st = { test_conn_proxy_connect_setup, test_conn_proxy_connect_teardown }; static void test_conn_get_basic(void *arg) { Loading Loading @@ -788,6 +818,45 @@ test_conn_download_status(void *arg) /* the teardown function removes all the connections in the global list*/; } static int handshake_start_called = 0; static int handshake_start(or_connection_t *conn, int receiving) { (void)receiving; tor_assert(conn); handshake_start_called = 1; return 0; } static void test_conn_haproxy_proxy_connect(void *arg) { size_t sz; char *buf = NULL; or_connection_t *conn = arg; MOCK(connection_or_change_state, mock_connection_or_change_state); MOCK(connection_tls_start_handshake, handshake_start); tt_int_op(conn->base_.proxy_state, OP_EQ, PROXY_HAPROXY_WAIT_FOR_FLUSH); buf = buf_get_contents(conn->base_.outbuf, &sz); tt_str_op(buf, OP_EQ, "PROXY TCP4 0.0.0.0 127.0.0.1 0 12345\r\n"); connection_or_finished_flushing(conn); tt_int_op(conn->base_.proxy_state, OP_EQ, PROXY_CONNECTED); tt_int_op(handshake_start_called, OP_EQ, 1); done: UNMOCK(connection_or_change_state); UNMOCK(connection_tls_start_handshake); tor_free(buf); } static node_t test_node; static node_t * Loading Loading @@ -892,10 +961,14 @@ struct testcase_t connection_tests[] = { CONNECTION_TESTCASE(get_basic, TT_FORK, test_conn_get_basic_st), CONNECTION_TESTCASE(get_rend, TT_FORK, test_conn_get_rend_st), CONNECTION_TESTCASE(get_rsrc, TT_FORK, test_conn_get_rsrc_st), CONNECTION_TESTCASE_ARG(download_status, TT_FORK, test_conn_download_status_st, FLAV_MICRODESC), CONNECTION_TESTCASE_ARG(download_status, TT_FORK, test_conn_download_status_st, FLAV_NS), CONNECTION_TESTCASE_ARG(haproxy_proxy_connect, TT_FORK, test_conn_proxy_connect_st, TCP_PROXY_PROTOCOL_HAPROXY), //CONNECTION_TESTCASE(func_suffix, TT_FORK, setup_func_pair), { "failed_orconn_tracker", test_failed_orconn_tracker, TT_FORK, NULL, NULL }, END_OF_TESTCASES Loading src/test/test_connection.h +1 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ /** Some constants used by test_connection and helpers */ #define TEST_CONN_FAMILY (AF_INET) #define TEST_CONN_ADDRESS "127.0.0.1" #define TEST_CONN_ADDRESS_2 "127.0.0.2" #define TEST_CONN_PORT (12345) #define TEST_CONN_ADDRESS_PORT "127.0.0.1:12345" #define TEST_CONN_FD_INIT 50 Loading src/test/test_helpers.c +81 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #define ROUTERLIST_PRIVATE #define CONFIG_PRIVATE #define CONNECTION_PRIVATE #define CONNECTION_OR_PRIVATE #define MAINLOOP_PRIVATE #include "orconfig.h" Loading @@ -19,6 +20,7 @@ #include "lib/confmgt/confparse.h" #include "app/main/subsysmgr.h" #include "core/mainloop/connection.h" #include "core/or/connection_or.h" #include "lib/crypt_ops/crypto_rand.h" #include "core/mainloop/mainloop.h" #include "feature/nodelist/nodelist.h" Loading @@ -33,6 +35,7 @@ #include "core/or/cell_st.h" #include "core/or/connection_st.h" #include "core/or/or_connection_st.h" #include "feature/nodelist/node_st.h" #include "core/or/origin_circuit_st.h" #include "feature/nodelist/routerlist_st.h" Loading Loading @@ -194,6 +197,14 @@ fake_close_socket(tor_socket_t sock) return 0; } /* Helper for test_conn_get_proxy_or_connection() */ void mock_connection_or_change_state(or_connection_t *conn, uint8_t state) { tor_assert(conn); conn->base_.state = state; } static int mock_connection_connect_sockaddr_called = 0; static int fake_socket_number = TEST_CONN_FD_INIT; Loading Loading @@ -228,6 +239,76 @@ mock_connection_connect_sockaddr(connection_t *conn, return 1; } or_connection_t * test_conn_get_proxy_or_connection(unsigned int proxy_type) { or_connection_t *conn = NULL; tor_addr_t dst_addr; tor_addr_t proxy_addr; int socket_err = 0; int in_progress = 0; MOCK(connection_connect_sockaddr, mock_connection_connect_sockaddr); MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock); MOCK(connection_or_change_state, mock_connection_or_change_state); MOCK(tor_close_socket, fake_close_socket); tor_init_connection_lists(); conn = or_connection_new(CONN_TYPE_OR, TEST_CONN_FAMILY); tt_assert(conn); /* Set up a destination address. */ test_conn_lookup_addr_helper(TEST_CONN_ADDRESS, TEST_CONN_FAMILY, &dst_addr); tt_assert(!tor_addr_is_null(&dst_addr)); conn->proxy_type = proxy_type; conn->base_.proxy_state = PROXY_INFANT; tor_addr_copy_tight(&conn->base_.addr, &dst_addr); conn->base_.address = tor_addr_to_str_dup(&dst_addr); conn->base_.port = TEST_CONN_PORT; /* Set up a proxy address. */ test_conn_lookup_addr_helper(TEST_CONN_ADDRESS_2, TEST_CONN_FAMILY, &proxy_addr); tt_assert(!tor_addr_is_null(&proxy_addr)); conn->base_.state = OR_CONN_STATE_CONNECTING; mock_connection_connect_sockaddr_called = 0; in_progress = connection_connect(TO_CONN(conn), TEST_CONN_ADDRESS_PORT, &proxy_addr, TEST_CONN_PORT, &socket_err); tt_int_op(mock_connection_connect_sockaddr_called, OP_EQ, 1); tt_assert(!socket_err); tt_assert(in_progress == 0 || in_progress == 1); assert_connection_ok(TO_CONN(conn), time(NULL)); in_progress = connection_or_finished_connecting(conn); tt_int_op(in_progress, OP_EQ, 0); assert_connection_ok(TO_CONN(conn), time(NULL)); UNMOCK(connection_connect_sockaddr); UNMOCK(connection_write_to_buf_impl_); UNMOCK(connection_or_change_state); UNMOCK(tor_close_socket); return conn; /* On failure */ done: UNMOCK(connection_connect_sockaddr); UNMOCK(connection_write_to_buf_impl_); UNMOCK(connection_or_change_state); UNMOCK(tor_close_socket); return NULL; } /** Create and return a new connection/stream */ connection_t * test_conn_get_connection(uint8_t state, uint8_t type, uint8_t purpose) Loading Loading
src/core/or/connection_or.c +2 −9 Original line number Diff line number Diff line Loading @@ -95,13 +95,6 @@ static unsigned int connection_or_is_bad_for_new_circs(or_connection_t *or_conn); static void connection_or_mark_bad_for_new_circs(or_connection_t *or_conn); /* * Call this when changing connection state, so notifications to the owning * channel can be handled. */ static void connection_or_change_state(or_connection_t *conn, uint8_t state); static void connection_or_check_canonicity(or_connection_t *conn, int started_here); Loading Loading @@ -457,8 +450,8 @@ connection_or_state_publish(const or_connection_t *conn, uint8_t state) * be notified. */ static void connection_or_change_state(or_connection_t *conn, uint8_t state) MOCK_IMPL(STATIC void, connection_or_change_state,(or_connection_t *conn, uint8_t state)) { tor_assert(conn); Loading
src/core/or/connection_or.h +7 −0 Original line number Diff line number Diff line Loading @@ -134,6 +134,13 @@ void connection_or_group_set_badness_(smartlist_t *group, int force); #ifdef CONNECTION_OR_PRIVATE STATIC int should_connect_to_relay(const or_connection_t *or_conn); STATIC void note_or_connect_failed(const or_connection_t *or_conn); /* * Call this when changing connection state, so notifications to the owning * channel can be handled. */ MOCK_DECL(STATIC void,connection_or_change_state, (or_connection_t *conn, uint8_t state)); #endif #ifdef TOR_UNIT_TESTS Loading
src/test/test_connection.c +75 −2 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ #include "core/or/or.h" #include "test/test.h" #include "app/config/or_options_st.h" #include "core/mainloop/connection.h" #include "core/or/connection_edge.h" #include "feature/hs/hs_common.h" Loading Loading @@ -312,6 +313,31 @@ test_conn_download_status_teardown(const struct testcase_t *tc, void *arg) return rv; } static void * test_conn_proxy_connect_setup(const struct testcase_t *tc) { tcp_proxy_protocol_t proxy_type = (tcp_proxy_protocol_t)tc->setup_data; switch (proxy_type) { case TCP_PROXY_PROTOCOL_HAPROXY: return test_conn_get_proxy_or_connection(PROXY_HAPROXY); default: return NULL; } } static int test_conn_proxy_connect_teardown(const struct testcase_t *tc, void *arg) { (void)tc; or_connection_t *conn = arg; tt_assert(conn); assert_connection_ok(&conn->base_, time(NULL)); done: return 1; } /* Like connection_ap_make_link(), but does much less */ static connection_t * test_conn_get_linked_connection(connection_t *l_conn, uint8_t state) Loading Loading @@ -360,6 +386,10 @@ static struct testcase_setup_t test_conn_download_status_st = { test_conn_download_status_setup, test_conn_download_status_teardown }; static struct testcase_setup_t test_conn_proxy_connect_st = { test_conn_proxy_connect_setup, test_conn_proxy_connect_teardown }; static void test_conn_get_basic(void *arg) { Loading Loading @@ -788,6 +818,45 @@ test_conn_download_status(void *arg) /* the teardown function removes all the connections in the global list*/; } static int handshake_start_called = 0; static int handshake_start(or_connection_t *conn, int receiving) { (void)receiving; tor_assert(conn); handshake_start_called = 1; return 0; } static void test_conn_haproxy_proxy_connect(void *arg) { size_t sz; char *buf = NULL; or_connection_t *conn = arg; MOCK(connection_or_change_state, mock_connection_or_change_state); MOCK(connection_tls_start_handshake, handshake_start); tt_int_op(conn->base_.proxy_state, OP_EQ, PROXY_HAPROXY_WAIT_FOR_FLUSH); buf = buf_get_contents(conn->base_.outbuf, &sz); tt_str_op(buf, OP_EQ, "PROXY TCP4 0.0.0.0 127.0.0.1 0 12345\r\n"); connection_or_finished_flushing(conn); tt_int_op(conn->base_.proxy_state, OP_EQ, PROXY_CONNECTED); tt_int_op(handshake_start_called, OP_EQ, 1); done: UNMOCK(connection_or_change_state); UNMOCK(connection_tls_start_handshake); tor_free(buf); } static node_t test_node; static node_t * Loading Loading @@ -892,10 +961,14 @@ struct testcase_t connection_tests[] = { CONNECTION_TESTCASE(get_basic, TT_FORK, test_conn_get_basic_st), CONNECTION_TESTCASE(get_rend, TT_FORK, test_conn_get_rend_st), CONNECTION_TESTCASE(get_rsrc, TT_FORK, test_conn_get_rsrc_st), CONNECTION_TESTCASE_ARG(download_status, TT_FORK, test_conn_download_status_st, FLAV_MICRODESC), CONNECTION_TESTCASE_ARG(download_status, TT_FORK, test_conn_download_status_st, FLAV_NS), CONNECTION_TESTCASE_ARG(haproxy_proxy_connect, TT_FORK, test_conn_proxy_connect_st, TCP_PROXY_PROTOCOL_HAPROXY), //CONNECTION_TESTCASE(func_suffix, TT_FORK, setup_func_pair), { "failed_orconn_tracker", test_failed_orconn_tracker, TT_FORK, NULL, NULL }, END_OF_TESTCASES Loading
src/test/test_connection.h +1 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ /** Some constants used by test_connection and helpers */ #define TEST_CONN_FAMILY (AF_INET) #define TEST_CONN_ADDRESS "127.0.0.1" #define TEST_CONN_ADDRESS_2 "127.0.0.2" #define TEST_CONN_PORT (12345) #define TEST_CONN_ADDRESS_PORT "127.0.0.1:12345" #define TEST_CONN_FD_INIT 50 Loading
src/test/test_helpers.c +81 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #define ROUTERLIST_PRIVATE #define CONFIG_PRIVATE #define CONNECTION_PRIVATE #define CONNECTION_OR_PRIVATE #define MAINLOOP_PRIVATE #include "orconfig.h" Loading @@ -19,6 +20,7 @@ #include "lib/confmgt/confparse.h" #include "app/main/subsysmgr.h" #include "core/mainloop/connection.h" #include "core/or/connection_or.h" #include "lib/crypt_ops/crypto_rand.h" #include "core/mainloop/mainloop.h" #include "feature/nodelist/nodelist.h" Loading @@ -33,6 +35,7 @@ #include "core/or/cell_st.h" #include "core/or/connection_st.h" #include "core/or/or_connection_st.h" #include "feature/nodelist/node_st.h" #include "core/or/origin_circuit_st.h" #include "feature/nodelist/routerlist_st.h" Loading Loading @@ -194,6 +197,14 @@ fake_close_socket(tor_socket_t sock) return 0; } /* Helper for test_conn_get_proxy_or_connection() */ void mock_connection_or_change_state(or_connection_t *conn, uint8_t state) { tor_assert(conn); conn->base_.state = state; } static int mock_connection_connect_sockaddr_called = 0; static int fake_socket_number = TEST_CONN_FD_INIT; Loading Loading @@ -228,6 +239,76 @@ mock_connection_connect_sockaddr(connection_t *conn, return 1; } or_connection_t * test_conn_get_proxy_or_connection(unsigned int proxy_type) { or_connection_t *conn = NULL; tor_addr_t dst_addr; tor_addr_t proxy_addr; int socket_err = 0; int in_progress = 0; MOCK(connection_connect_sockaddr, mock_connection_connect_sockaddr); MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock); MOCK(connection_or_change_state, mock_connection_or_change_state); MOCK(tor_close_socket, fake_close_socket); tor_init_connection_lists(); conn = or_connection_new(CONN_TYPE_OR, TEST_CONN_FAMILY); tt_assert(conn); /* Set up a destination address. */ test_conn_lookup_addr_helper(TEST_CONN_ADDRESS, TEST_CONN_FAMILY, &dst_addr); tt_assert(!tor_addr_is_null(&dst_addr)); conn->proxy_type = proxy_type; conn->base_.proxy_state = PROXY_INFANT; tor_addr_copy_tight(&conn->base_.addr, &dst_addr); conn->base_.address = tor_addr_to_str_dup(&dst_addr); conn->base_.port = TEST_CONN_PORT; /* Set up a proxy address. */ test_conn_lookup_addr_helper(TEST_CONN_ADDRESS_2, TEST_CONN_FAMILY, &proxy_addr); tt_assert(!tor_addr_is_null(&proxy_addr)); conn->base_.state = OR_CONN_STATE_CONNECTING; mock_connection_connect_sockaddr_called = 0; in_progress = connection_connect(TO_CONN(conn), TEST_CONN_ADDRESS_PORT, &proxy_addr, TEST_CONN_PORT, &socket_err); tt_int_op(mock_connection_connect_sockaddr_called, OP_EQ, 1); tt_assert(!socket_err); tt_assert(in_progress == 0 || in_progress == 1); assert_connection_ok(TO_CONN(conn), time(NULL)); in_progress = connection_or_finished_connecting(conn); tt_int_op(in_progress, OP_EQ, 0); assert_connection_ok(TO_CONN(conn), time(NULL)); UNMOCK(connection_connect_sockaddr); UNMOCK(connection_write_to_buf_impl_); UNMOCK(connection_or_change_state); UNMOCK(tor_close_socket); return conn; /* On failure */ done: UNMOCK(connection_connect_sockaddr); UNMOCK(connection_write_to_buf_impl_); UNMOCK(connection_or_change_state); UNMOCK(tor_close_socket); return NULL; } /** Create and return a new connection/stream */ connection_t * test_conn_get_connection(uint8_t state, uint8_t type, uint8_t purpose) Loading