Loading src/or/connection.c +153 −77 Original line number Diff line number Diff line Loading @@ -1618,13 +1618,18 @@ connection_init_accepted_conn(connection_t *conn, return 0; } static int connection_connect_sockaddr(connection_t *conn, /** Take conn, make a nonblocking socket; try to connect to * sa, binding to bindaddr if sa is not localhost. If fail, return -1 and if * applicable put your best guess about errno into *<b>socket_error</b>. * If connected return 1, if EAGAIN return 0. */ MOCK_IMPL(STATIC int, connection_connect_sockaddr,(connection_t *conn, const struct sockaddr *sa, socklen_t sa_len, const struct sockaddr *bindaddr, socklen_t bindaddr_len, int *socket_error) int *socket_error)) { tor_socket_t s; int inprogress = 0; Loading Loading @@ -4222,6 +4227,19 @@ connection_write_to_buf_impl_,(const char *string, size_t len, } } /** Return a connection_t * from get_connection_array() that satisfies test on * var, and that is not marked for close. */ #define CONN_GET_TEMPLATE(var, test) \ STMT_BEGIN \ smartlist_t *conns = get_connection_array(); \ SMARTLIST_FOREACH(conns, connection_t *, var, \ { \ if (var && (test) && !var->marked_for_close) \ return var; \ }); \ return NULL; \ STMT_END /** Return a connection with given type, address, port, and purpose; * or NULL if no such connection exists (or if all such connections are marked * for close). */ Loading @@ -4230,17 +4248,11 @@ connection_get_by_type_addr_port_purpose(int type, const tor_addr_t *addr, uint16_t port, int purpose) { smartlist_t *conns = get_connection_array(); SMARTLIST_FOREACH(conns, connection_t *, conn, { if (conn->type == type && CONN_GET_TEMPLATE(conn, (conn->type == type && tor_addr_eq(&conn->addr, addr) && conn->port == port && conn->purpose == purpose && !conn->marked_for_close) return conn; }); return NULL; conn->purpose == purpose)); } /** Return the stream with id <b>id</b> if it is not already marked for Loading @@ -4249,13 +4261,7 @@ connection_get_by_type_addr_port_purpose(int type, connection_t * connection_get_by_global_id(uint64_t id) { smartlist_t *conns = get_connection_array(); SMARTLIST_FOREACH(conns, connection_t *, conn, { if (conn->global_identifier == id) return conn; }); return NULL; CONN_GET_TEMPLATE(conn, conn->global_identifier == id); } /** Return a connection of type <b>type</b> that is not marked for close. Loading @@ -4263,13 +4269,7 @@ connection_get_by_global_id(uint64_t id) connection_t * connection_get_by_type(int type) { smartlist_t *conns = get_connection_array(); SMARTLIST_FOREACH(conns, connection_t *, conn, { if (conn->type == type && !conn->marked_for_close) return conn; }); return NULL; CONN_GET_TEMPLATE(conn, conn->type == type); } /** Return a connection of type <b>type</b> that is in state <b>state</b>, Loading @@ -4278,13 +4278,7 @@ connection_get_by_type(int type) connection_t * connection_get_by_type_state(int type, int state) { smartlist_t *conns = get_connection_array(); SMARTLIST_FOREACH(conns, connection_t *, conn, { if (conn->type == type && conn->state == state && !conn->marked_for_close) return conn; }); return NULL; CONN_GET_TEMPLATE(conn, conn->type == type && conn->state == state); } /** Return a connection of type <b>type</b> that has rendquery equal Loading @@ -4295,55 +4289,142 @@ connection_t * connection_get_by_type_state_rendquery(int type, int state, const char *rendquery) { smartlist_t *conns = get_connection_array(); tor_assert(type == CONN_TYPE_DIR || type == CONN_TYPE_AP || type == CONN_TYPE_EXIT); tor_assert(rendquery); SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) { if (conn->type == type && !conn->marked_for_close && (!state || state == conn->state)) { if (type == CONN_TYPE_DIR && CONN_GET_TEMPLATE(conn, (conn->type == type && (!state || state == conn->state)) && ( (type == CONN_TYPE_DIR && TO_DIR_CONN(conn)->rend_data && !rend_cmp_service_ids(rendquery, TO_DIR_CONN(conn)->rend_data->onion_address)) return conn; else if (CONN_IS_EDGE(conn) && || (CONN_IS_EDGE(conn) && TO_EDGE_CONN(conn)->rend_data && !rend_cmp_service_ids(rendquery, TO_EDGE_CONN(conn)->rend_data->onion_address)) return conn; } } SMARTLIST_FOREACH_END(conn); return NULL; )); } #define CONN_FIRST_AND_FREE_TEMPLATE(sl) \ STMT_BEGIN \ if (smartlist_len(sl) > 0) { \ void *first_item = smartlist_get(sl, 0); \ smartlist_free(sl); \ return first_item; \ } else { \ smartlist_free(sl); \ return NULL; \ } \ STMT_END /** Return a directory connection (if any one exists) that is fetching * the item described by <b>state</b>/<b>resource</b> */ * the item described by <b>purpose</b>/<b>resource</b>, otherwise return NULL. */ dir_connection_t * connection_dir_get_by_purpose_and_resource(int purpose, connection_dir_get_by_purpose_and_resource( int purpose, const char *resource) { smartlist_t *conns = get_connection_array(); smartlist_t *conns = connection_dir_list_by_purpose_and_resource( purpose, resource); CONN_FIRST_AND_FREE_TEMPLATE(conns); } /** Return a new smartlist of dir_connection_t * from get_connection_array() * that satisfy conn_test on connection_t *conn_var, and dirconn_test on * dir_connection_t *dirconn_var. conn_var must be of CONN_TYPE_DIR and not * marked for close to be included in the list. */ #define DIR_CONN_LIST_TEMPLATE(conn_var, conn_test, \ dirconn_var, dirconn_test) \ STMT_BEGIN \ smartlist_t *conns = get_connection_array(); \ smartlist_t *dir_conns = smartlist_new(); \ SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn_var) { \ if (conn_var && (conn_test) \ && conn_var->type == CONN_TYPE_DIR \ && !conn_var->marked_for_close) { \ dir_connection_t *dirconn_var = TO_DIR_CONN(conn_var); \ if (dirconn_var && (dirconn_test)) { \ smartlist_add(dir_conns, dirconn_var); \ } \ } \ } SMARTLIST_FOREACH_END(conn_var); \ return dir_conns; \ STMT_END /** Return a list of directory connections that are fetching the item * described by <b>purpose</b>/<b>resource</b>. If there are none, * return an empty list. This list must be freed using smartlist_free, * but the pointers in it must not be freed. * Note that this list should not be cached, as the pointers in it can be * freed if their connections close. */ smartlist_t * connection_dir_list_by_purpose_and_resource( int purpose, const char *resource) { DIR_CONN_LIST_TEMPLATE(conn, conn->purpose == purpose, dirconn, 0 == strcmp_opt(resource, dirconn->requested_resource)); } SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) { dir_connection_t *dirconn; if (conn->type != CONN_TYPE_DIR || conn->marked_for_close || conn->purpose != purpose) continue; dirconn = TO_DIR_CONN(conn); if (dirconn->requested_resource == NULL) { if (resource == NULL) return dirconn; } else if (resource) { if (0 == strcmp(resource, dirconn->requested_resource)) return dirconn; /** Return a directory connection (if any one exists) that is fetching * the item described by <b>purpose</b>/<b>resource</b>/<b>state</b>, * otherwise return NULL. */ dir_connection_t * connection_dir_get_by_purpose_resource_and_state( int purpose, const char *resource, int state) { smartlist_t *conns = connection_dir_list_by_purpose_resource_and_state( purpose, resource, state); CONN_FIRST_AND_FREE_TEMPLATE(conns); } #undef CONN_FIRST_AND_FREE_TEMPLATE /** Return a list of directory connections that are fetching the item * described by <b>purpose</b>/<b>resource</b>/<b>state</b>. If there are * none, return an empty list. This list must be freed using smartlist_free, * but the pointers in it must not be freed. * Note that this list should not be cached, as the pointers in it can be * freed if their connections close. */ smartlist_t * connection_dir_list_by_purpose_resource_and_state( int purpose, const char *resource, int state) { DIR_CONN_LIST_TEMPLATE(conn, conn->purpose == purpose && conn->state == state, dirconn, 0 == strcmp_opt(resource, dirconn->requested_resource)); } } SMARTLIST_FOREACH_END(conn); return NULL; #undef DIR_CONN_LIST_TEMPLATE /** Return an arbitrary active OR connection that isn't <b>this_conn</b>. * * We use this to guess if we should tell the controller that we * didn't manage to connect to any of our bridges. */ static connection_t * connection_get_another_active_or_conn(const or_connection_t *this_conn) { CONN_GET_TEMPLATE(conn, conn != TO_CONN(this_conn) && conn->type == CONN_TYPE_OR); } /** Return 1 if there are any active OR connections apart from Loading @@ -4354,23 +4435,18 @@ connection_dir_get_by_purpose_and_resource(int purpose, int any_other_active_or_conns(const or_connection_t *this_conn) { smartlist_t *conns = get_connection_array(); SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) { if (conn == TO_CONN(this_conn)) { /* don't consider this conn */ continue; } if (conn->type == CONN_TYPE_OR && !conn->marked_for_close) { connection_t *conn = connection_get_another_active_or_conn(this_conn); if (conn != NULL) { log_debug(LD_DIR, "%s: Found an OR connection: %s", __func__, conn->address); return 1; } } SMARTLIST_FOREACH_END(conn); return 0; } #undef CONN_GET_TEMPLATE /** Return 1 if <b>conn</b> is a listener conn, else return 0. */ int connection_is_listener(connection_t *conn) Loading src/or/connection.h +58 −1 Original line number Diff line number Diff line Loading @@ -193,7 +193,57 @@ connection_t *connection_get_by_type_state(int type, int state); connection_t *connection_get_by_type_state_rendquery(int type, int state, const char *rendquery); dir_connection_t *connection_dir_get_by_purpose_and_resource( int state, const char *resource); int purpose, const char *resource); dir_connection_t *connection_dir_get_by_purpose_resource_and_state( int purpose, const char *resource, int state); smartlist_t *connection_dir_list_by_purpose_and_resource( int purpose, const char *resource); smartlist_t *connection_dir_list_by_purpose_resource_and_state( int purpose, const char *resource, int state); #define CONN_LEN_AND_FREE_TEMPLATE(sl) \ STMT_BEGIN \ int len = smartlist_len(sl); \ smartlist_free(sl); \ return len; \ STMT_END /** Return a count of directory connections that are fetching the item * described by <b>purpose</b>/<b>resource</b>. */ static INLINE int connection_dir_count_by_purpose_and_resource( int purpose, const char *resource) { smartlist_t *conns = connection_dir_list_by_purpose_and_resource( purpose, resource); CONN_LEN_AND_FREE_TEMPLATE(conns); } /** Return a count of directory connections that are fetching the item * described by <b>purpose</b>/<b>resource</b>/<b>state</b>. */ static INLINE int connection_dir_count_by_purpose_resource_and_state( int purpose, const char *resource, int state) { smartlist_t *conns = connection_dir_list_by_purpose_resource_and_state( purpose, resource, state); CONN_LEN_AND_FREE_TEMPLATE(conns); } #undef CONN_LEN_AND_FREE_TEMPLATE int any_other_active_or_conns(const or_connection_t *this_conn); Loading Loading @@ -239,6 +289,13 @@ void connection_buckets_note_empty_ts(uint32_t *timestamp_var, int tokens_before, size_t tokens_removed, const struct timeval *tvnow); MOCK_DECL(STATIC int,connection_connect_sockaddr, (connection_t *conn, const struct sockaddr *sa, socklen_t sa_len, const struct sockaddr *bindaddr, socklen_t bindaddr_len, int *socket_error)); #endif #endif Loading src/test/Makefile.nmake +2 −1 Original line number Diff line number Diff line Loading @@ -14,7 +14,8 @@ LIBS = ..\..\..\build-alpha\lib\libevent.lib \ TEST_OBJECTS = test.obj test_addr.obj test_channel.obj test_channeltls.obj \ test_containers.obj \ test_controller_events.obj test_crypto.obj test_data.obj test_dir.obj \ test_checkdir.obj test_microdesc.obj test_pt.obj test_util.obj test_config.obj \ test_checkdir.obj test_microdesc.obj test_pt.obj test_util.obj \ test_config.obj test_connection.obj \ test_cell_formats.obj test_relay.obj test_replay.obj \ test_scheduler.obj test_introduce.obj test_hs.obj tinytest.obj Loading src/test/include.am +1 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ src_test_test_SOURCES = \ src/test/test_circuitmux.c \ src/test/test_compat_libevent.c \ src/test/test_config.c \ src/test/test_connection.c \ src/test/test_containers.c \ src/test/test_controller.c \ src/test/test_controller_events.c \ Loading src/test/test.c +2 −0 Original line number Diff line number Diff line Loading @@ -1141,6 +1141,7 @@ extern struct testcase_t circuitlist_tests[]; extern struct testcase_t circuitmux_tests[]; extern struct testcase_t compat_libevent_tests[]; extern struct testcase_t config_tests[]; extern struct testcase_t connection_tests[]; extern struct testcase_t container_tests[]; extern struct testcase_t controller_tests[]; extern struct testcase_t controller_event_tests[]; Loading Loading @@ -1196,6 +1197,7 @@ struct testgroup_t testgroups[] = { { "circuitmux/", circuitmux_tests }, { "compat/libevent/", compat_libevent_tests }, { "config/", config_tests }, { "connection/", connection_tests }, { "container/", container_tests }, { "control/", controller_tests }, { "control/event/", controller_event_tests }, Loading Loading
src/or/connection.c +153 −77 Original line number Diff line number Diff line Loading @@ -1618,13 +1618,18 @@ connection_init_accepted_conn(connection_t *conn, return 0; } static int connection_connect_sockaddr(connection_t *conn, /** Take conn, make a nonblocking socket; try to connect to * sa, binding to bindaddr if sa is not localhost. If fail, return -1 and if * applicable put your best guess about errno into *<b>socket_error</b>. * If connected return 1, if EAGAIN return 0. */ MOCK_IMPL(STATIC int, connection_connect_sockaddr,(connection_t *conn, const struct sockaddr *sa, socklen_t sa_len, const struct sockaddr *bindaddr, socklen_t bindaddr_len, int *socket_error) int *socket_error)) { tor_socket_t s; int inprogress = 0; Loading Loading @@ -4222,6 +4227,19 @@ connection_write_to_buf_impl_,(const char *string, size_t len, } } /** Return a connection_t * from get_connection_array() that satisfies test on * var, and that is not marked for close. */ #define CONN_GET_TEMPLATE(var, test) \ STMT_BEGIN \ smartlist_t *conns = get_connection_array(); \ SMARTLIST_FOREACH(conns, connection_t *, var, \ { \ if (var && (test) && !var->marked_for_close) \ return var; \ }); \ return NULL; \ STMT_END /** Return a connection with given type, address, port, and purpose; * or NULL if no such connection exists (or if all such connections are marked * for close). */ Loading @@ -4230,17 +4248,11 @@ connection_get_by_type_addr_port_purpose(int type, const tor_addr_t *addr, uint16_t port, int purpose) { smartlist_t *conns = get_connection_array(); SMARTLIST_FOREACH(conns, connection_t *, conn, { if (conn->type == type && CONN_GET_TEMPLATE(conn, (conn->type == type && tor_addr_eq(&conn->addr, addr) && conn->port == port && conn->purpose == purpose && !conn->marked_for_close) return conn; }); return NULL; conn->purpose == purpose)); } /** Return the stream with id <b>id</b> if it is not already marked for Loading @@ -4249,13 +4261,7 @@ connection_get_by_type_addr_port_purpose(int type, connection_t * connection_get_by_global_id(uint64_t id) { smartlist_t *conns = get_connection_array(); SMARTLIST_FOREACH(conns, connection_t *, conn, { if (conn->global_identifier == id) return conn; }); return NULL; CONN_GET_TEMPLATE(conn, conn->global_identifier == id); } /** Return a connection of type <b>type</b> that is not marked for close. Loading @@ -4263,13 +4269,7 @@ connection_get_by_global_id(uint64_t id) connection_t * connection_get_by_type(int type) { smartlist_t *conns = get_connection_array(); SMARTLIST_FOREACH(conns, connection_t *, conn, { if (conn->type == type && !conn->marked_for_close) return conn; }); return NULL; CONN_GET_TEMPLATE(conn, conn->type == type); } /** Return a connection of type <b>type</b> that is in state <b>state</b>, Loading @@ -4278,13 +4278,7 @@ connection_get_by_type(int type) connection_t * connection_get_by_type_state(int type, int state) { smartlist_t *conns = get_connection_array(); SMARTLIST_FOREACH(conns, connection_t *, conn, { if (conn->type == type && conn->state == state && !conn->marked_for_close) return conn; }); return NULL; CONN_GET_TEMPLATE(conn, conn->type == type && conn->state == state); } /** Return a connection of type <b>type</b> that has rendquery equal Loading @@ -4295,55 +4289,142 @@ connection_t * connection_get_by_type_state_rendquery(int type, int state, const char *rendquery) { smartlist_t *conns = get_connection_array(); tor_assert(type == CONN_TYPE_DIR || type == CONN_TYPE_AP || type == CONN_TYPE_EXIT); tor_assert(rendquery); SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) { if (conn->type == type && !conn->marked_for_close && (!state || state == conn->state)) { if (type == CONN_TYPE_DIR && CONN_GET_TEMPLATE(conn, (conn->type == type && (!state || state == conn->state)) && ( (type == CONN_TYPE_DIR && TO_DIR_CONN(conn)->rend_data && !rend_cmp_service_ids(rendquery, TO_DIR_CONN(conn)->rend_data->onion_address)) return conn; else if (CONN_IS_EDGE(conn) && || (CONN_IS_EDGE(conn) && TO_EDGE_CONN(conn)->rend_data && !rend_cmp_service_ids(rendquery, TO_EDGE_CONN(conn)->rend_data->onion_address)) return conn; } } SMARTLIST_FOREACH_END(conn); return NULL; )); } #define CONN_FIRST_AND_FREE_TEMPLATE(sl) \ STMT_BEGIN \ if (smartlist_len(sl) > 0) { \ void *first_item = smartlist_get(sl, 0); \ smartlist_free(sl); \ return first_item; \ } else { \ smartlist_free(sl); \ return NULL; \ } \ STMT_END /** Return a directory connection (if any one exists) that is fetching * the item described by <b>state</b>/<b>resource</b> */ * the item described by <b>purpose</b>/<b>resource</b>, otherwise return NULL. */ dir_connection_t * connection_dir_get_by_purpose_and_resource(int purpose, connection_dir_get_by_purpose_and_resource( int purpose, const char *resource) { smartlist_t *conns = get_connection_array(); smartlist_t *conns = connection_dir_list_by_purpose_and_resource( purpose, resource); CONN_FIRST_AND_FREE_TEMPLATE(conns); } /** Return a new smartlist of dir_connection_t * from get_connection_array() * that satisfy conn_test on connection_t *conn_var, and dirconn_test on * dir_connection_t *dirconn_var. conn_var must be of CONN_TYPE_DIR and not * marked for close to be included in the list. */ #define DIR_CONN_LIST_TEMPLATE(conn_var, conn_test, \ dirconn_var, dirconn_test) \ STMT_BEGIN \ smartlist_t *conns = get_connection_array(); \ smartlist_t *dir_conns = smartlist_new(); \ SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn_var) { \ if (conn_var && (conn_test) \ && conn_var->type == CONN_TYPE_DIR \ && !conn_var->marked_for_close) { \ dir_connection_t *dirconn_var = TO_DIR_CONN(conn_var); \ if (dirconn_var && (dirconn_test)) { \ smartlist_add(dir_conns, dirconn_var); \ } \ } \ } SMARTLIST_FOREACH_END(conn_var); \ return dir_conns; \ STMT_END /** Return a list of directory connections that are fetching the item * described by <b>purpose</b>/<b>resource</b>. If there are none, * return an empty list. This list must be freed using smartlist_free, * but the pointers in it must not be freed. * Note that this list should not be cached, as the pointers in it can be * freed if their connections close. */ smartlist_t * connection_dir_list_by_purpose_and_resource( int purpose, const char *resource) { DIR_CONN_LIST_TEMPLATE(conn, conn->purpose == purpose, dirconn, 0 == strcmp_opt(resource, dirconn->requested_resource)); } SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) { dir_connection_t *dirconn; if (conn->type != CONN_TYPE_DIR || conn->marked_for_close || conn->purpose != purpose) continue; dirconn = TO_DIR_CONN(conn); if (dirconn->requested_resource == NULL) { if (resource == NULL) return dirconn; } else if (resource) { if (0 == strcmp(resource, dirconn->requested_resource)) return dirconn; /** Return a directory connection (if any one exists) that is fetching * the item described by <b>purpose</b>/<b>resource</b>/<b>state</b>, * otherwise return NULL. */ dir_connection_t * connection_dir_get_by_purpose_resource_and_state( int purpose, const char *resource, int state) { smartlist_t *conns = connection_dir_list_by_purpose_resource_and_state( purpose, resource, state); CONN_FIRST_AND_FREE_TEMPLATE(conns); } #undef CONN_FIRST_AND_FREE_TEMPLATE /** Return a list of directory connections that are fetching the item * described by <b>purpose</b>/<b>resource</b>/<b>state</b>. If there are * none, return an empty list. This list must be freed using smartlist_free, * but the pointers in it must not be freed. * Note that this list should not be cached, as the pointers in it can be * freed if their connections close. */ smartlist_t * connection_dir_list_by_purpose_resource_and_state( int purpose, const char *resource, int state) { DIR_CONN_LIST_TEMPLATE(conn, conn->purpose == purpose && conn->state == state, dirconn, 0 == strcmp_opt(resource, dirconn->requested_resource)); } } SMARTLIST_FOREACH_END(conn); return NULL; #undef DIR_CONN_LIST_TEMPLATE /** Return an arbitrary active OR connection that isn't <b>this_conn</b>. * * We use this to guess if we should tell the controller that we * didn't manage to connect to any of our bridges. */ static connection_t * connection_get_another_active_or_conn(const or_connection_t *this_conn) { CONN_GET_TEMPLATE(conn, conn != TO_CONN(this_conn) && conn->type == CONN_TYPE_OR); } /** Return 1 if there are any active OR connections apart from Loading @@ -4354,23 +4435,18 @@ connection_dir_get_by_purpose_and_resource(int purpose, int any_other_active_or_conns(const or_connection_t *this_conn) { smartlist_t *conns = get_connection_array(); SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) { if (conn == TO_CONN(this_conn)) { /* don't consider this conn */ continue; } if (conn->type == CONN_TYPE_OR && !conn->marked_for_close) { connection_t *conn = connection_get_another_active_or_conn(this_conn); if (conn != NULL) { log_debug(LD_DIR, "%s: Found an OR connection: %s", __func__, conn->address); return 1; } } SMARTLIST_FOREACH_END(conn); return 0; } #undef CONN_GET_TEMPLATE /** Return 1 if <b>conn</b> is a listener conn, else return 0. */ int connection_is_listener(connection_t *conn) Loading
src/or/connection.h +58 −1 Original line number Diff line number Diff line Loading @@ -193,7 +193,57 @@ connection_t *connection_get_by_type_state(int type, int state); connection_t *connection_get_by_type_state_rendquery(int type, int state, const char *rendquery); dir_connection_t *connection_dir_get_by_purpose_and_resource( int state, const char *resource); int purpose, const char *resource); dir_connection_t *connection_dir_get_by_purpose_resource_and_state( int purpose, const char *resource, int state); smartlist_t *connection_dir_list_by_purpose_and_resource( int purpose, const char *resource); smartlist_t *connection_dir_list_by_purpose_resource_and_state( int purpose, const char *resource, int state); #define CONN_LEN_AND_FREE_TEMPLATE(sl) \ STMT_BEGIN \ int len = smartlist_len(sl); \ smartlist_free(sl); \ return len; \ STMT_END /** Return a count of directory connections that are fetching the item * described by <b>purpose</b>/<b>resource</b>. */ static INLINE int connection_dir_count_by_purpose_and_resource( int purpose, const char *resource) { smartlist_t *conns = connection_dir_list_by_purpose_and_resource( purpose, resource); CONN_LEN_AND_FREE_TEMPLATE(conns); } /** Return a count of directory connections that are fetching the item * described by <b>purpose</b>/<b>resource</b>/<b>state</b>. */ static INLINE int connection_dir_count_by_purpose_resource_and_state( int purpose, const char *resource, int state) { smartlist_t *conns = connection_dir_list_by_purpose_resource_and_state( purpose, resource, state); CONN_LEN_AND_FREE_TEMPLATE(conns); } #undef CONN_LEN_AND_FREE_TEMPLATE int any_other_active_or_conns(const or_connection_t *this_conn); Loading Loading @@ -239,6 +289,13 @@ void connection_buckets_note_empty_ts(uint32_t *timestamp_var, int tokens_before, size_t tokens_removed, const struct timeval *tvnow); MOCK_DECL(STATIC int,connection_connect_sockaddr, (connection_t *conn, const struct sockaddr *sa, socklen_t sa_len, const struct sockaddr *bindaddr, socklen_t bindaddr_len, int *socket_error)); #endif #endif Loading
src/test/Makefile.nmake +2 −1 Original line number Diff line number Diff line Loading @@ -14,7 +14,8 @@ LIBS = ..\..\..\build-alpha\lib\libevent.lib \ TEST_OBJECTS = test.obj test_addr.obj test_channel.obj test_channeltls.obj \ test_containers.obj \ test_controller_events.obj test_crypto.obj test_data.obj test_dir.obj \ test_checkdir.obj test_microdesc.obj test_pt.obj test_util.obj test_config.obj \ test_checkdir.obj test_microdesc.obj test_pt.obj test_util.obj \ test_config.obj test_connection.obj \ test_cell_formats.obj test_relay.obj test_replay.obj \ test_scheduler.obj test_introduce.obj test_hs.obj tinytest.obj Loading
src/test/include.am +1 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ src_test_test_SOURCES = \ src/test/test_circuitmux.c \ src/test/test_compat_libevent.c \ src/test/test_config.c \ src/test/test_connection.c \ src/test/test_containers.c \ src/test/test_controller.c \ src/test/test_controller_events.c \ Loading
src/test/test.c +2 −0 Original line number Diff line number Diff line Loading @@ -1141,6 +1141,7 @@ extern struct testcase_t circuitlist_tests[]; extern struct testcase_t circuitmux_tests[]; extern struct testcase_t compat_libevent_tests[]; extern struct testcase_t config_tests[]; extern struct testcase_t connection_tests[]; extern struct testcase_t container_tests[]; extern struct testcase_t controller_tests[]; extern struct testcase_t controller_event_tests[]; Loading Loading @@ -1196,6 +1197,7 @@ struct testgroup_t testgroups[] = { { "circuitmux/", circuitmux_tests }, { "compat/libevent/", compat_libevent_tests }, { "config/", config_tests }, { "connection/", connection_tests }, { "container/", container_tests }, { "control/", controller_tests }, { "control/event/", controller_event_tests }, Loading