mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-30 15:43:32 +01:00
Merge branch 'tor-gitlab/mr/285' into ticket2667_044_01
This commit is contained in:
commit
b2434d30d2
4
changes/ticket2667
Normal file
4
changes/ticket2667
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
o Major feature (exit):
|
||||||
|
- Re-entry into the network is now denied at the Exit level to all relays'
|
||||||
|
ORPort and authorities' ORPort+DirPort. This is to help mitigate a series
|
||||||
|
of attacks. See ticket for more information. Closes ticket 2667.
|
@ -69,3 +69,77 @@ address_set_probably_contains(const address_set_t *set,
|
|||||||
{
|
{
|
||||||
return bloomfilt_probably_contains(set, addr);
|
return bloomfilt_probably_contains(set, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Length of the item is an address (IPv4 or IPv6) and a 2 byte port. We use
|
||||||
|
* 16 bytes for the address here (IPv6) since we do not know which family
|
||||||
|
* the given address in the item thus in the case of IPv4, the extra bytes
|
||||||
|
* are simply zeroes to accomodate. */
|
||||||
|
#define BLOOMFILT_ADDR_PORT_ITEM_LEN (16 + sizeof(uint16_t))
|
||||||
|
|
||||||
|
/** Build an item for the bloomfilter consisting of an address and port pair.
|
||||||
|
*
|
||||||
|
* If the given address is _not_ AF_INET or AF_INET6, then the item is an
|
||||||
|
* array of 0s.
|
||||||
|
*
|
||||||
|
* Return a pointer to a static buffer containing the item. Next call to this
|
||||||
|
* function invalidates its previous content. */
|
||||||
|
static const uint8_t *
|
||||||
|
build_addr_port_item(const tor_addr_t *addr, const uint16_t port)
|
||||||
|
{
|
||||||
|
static uint8_t data[BLOOMFILT_ADDR_PORT_ITEM_LEN];
|
||||||
|
|
||||||
|
memset(data, 0, sizeof(data));
|
||||||
|
switch (tor_addr_family(addr)) {
|
||||||
|
case AF_INET:
|
||||||
|
memcpy(data, &addr->addr.in_addr.s_addr, 4);
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
memcpy(data, &addr->addr.in6_addr.s6_addr, 16);
|
||||||
|
break;
|
||||||
|
case AF_UNSPEC:
|
||||||
|
/* Leave the 0. */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* LCOV_EXCL_START */
|
||||||
|
tor_fragile_assert();
|
||||||
|
/* LCOV_EXCL_STOP */
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(data + 16, &port, sizeof(port));
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return a hash value for the given item that the bloomfilter will use. */
|
||||||
|
static uint64_t
|
||||||
|
bloomfilt_addr_port_hash(const struct sipkey *key,
|
||||||
|
const void *item)
|
||||||
|
{
|
||||||
|
return siphash24(item, BLOOMFILT_ADDR_PORT_ITEM_LEN, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Allocate and return an addr_port_set_t, suitable for holding up to
|
||||||
|
* max_address_guess distinct values. */
|
||||||
|
addr_port_set_t *
|
||||||
|
addr_port_set_new(int max_addresses_guess)
|
||||||
|
{
|
||||||
|
uint8_t k[BLOOMFILT_KEY_LEN];
|
||||||
|
crypto_rand((void*)k, sizeof(k));
|
||||||
|
return bloomfilt_new(max_addresses_guess, bloomfilt_addr_port_hash, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Add an address and port pair to the given set. */
|
||||||
|
void
|
||||||
|
addr_port_set_add(addr_port_set_t *set, const tor_addr_t *addr, uint16_t port)
|
||||||
|
{
|
||||||
|
bloomfilt_add(set, build_addr_port_item(addr, port));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return true if the given address and port pair are in the set. Of course,
|
||||||
|
* this is a bloomfilter and thus in rare occasion, a false positive happens
|
||||||
|
* thus the "probably". */
|
||||||
|
bool
|
||||||
|
addr_port_set_probably_contains(const addr_port_set_t *set,
|
||||||
|
const tor_addr_t *addr, uint16_t port)
|
||||||
|
{
|
||||||
|
return !!bloomfilt_probably_contains(set, build_addr_port_item(addr, port));
|
||||||
|
}
|
||||||
|
@ -13,13 +13,14 @@
|
|||||||
#include "lib/cc/torint.h"
|
#include "lib/cc/torint.h"
|
||||||
#include "lib/container/bloomfilt.h"
|
#include "lib/container/bloomfilt.h"
|
||||||
|
|
||||||
|
struct tor_addr_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An address_set_t represents a set of tor_addr_t values. The implementation
|
* An address_set_t represents a set of tor_addr_t values. The implementation
|
||||||
* is probabilistic: false negatives cannot occur but false positives are
|
* is probabilistic: false negatives cannot occur but false positives are
|
||||||
* possible.
|
* possible.
|
||||||
*/
|
*/
|
||||||
typedef struct bloomfilt_t address_set_t;
|
typedef struct bloomfilt_t address_set_t;
|
||||||
struct tor_addr_t;
|
|
||||||
|
|
||||||
address_set_t *address_set_new(int max_addresses_guess);
|
address_set_t *address_set_new(int max_addresses_guess);
|
||||||
#define address_set_free(set) bloomfilt_free(set)
|
#define address_set_free(set) bloomfilt_free(set)
|
||||||
@ -28,4 +29,19 @@ void address_set_add_ipv4h(address_set_t *set, uint32_t addr);
|
|||||||
int address_set_probably_contains(const address_set_t *set,
|
int address_set_probably_contains(const address_set_t *set,
|
||||||
const struct tor_addr_t *addr);
|
const struct tor_addr_t *addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An addr_port_set_t represents a set of tor_addr_t values with a uint16_t
|
||||||
|
* port value. The implementation is probabilistic: false negatives cannot
|
||||||
|
* occur but false positives are possible.
|
||||||
|
*/
|
||||||
|
typedef struct bloomfilt_t addr_port_set_t;
|
||||||
|
|
||||||
|
addr_port_set_t *addr_port_set_new(int max_addresses_guess);
|
||||||
|
#define addr_port_set_free(s) bloomfilt_free(s)
|
||||||
|
void addr_port_set_add(addr_port_set_t *set,
|
||||||
|
const struct tor_addr_t *addr, uint16_t port);
|
||||||
|
bool addr_port_set_probably_contains(const addr_port_set_t *set,
|
||||||
|
const struct tor_addr_t *addr,
|
||||||
|
uint16_t port);
|
||||||
|
|
||||||
#endif /* !defined(TOR_ADDRESS_SET_H) */
|
#endif /* !defined(TOR_ADDRESS_SET_H) */
|
||||||
|
@ -4200,6 +4200,31 @@ connection_exit_connect(edge_connection_t *edge_conn)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Next, check for attempts to connect back into the Tor network. We don't
|
||||||
|
* want to allow these for the same reason we don't want to allow
|
||||||
|
* infinite-length circuits (see "A Practical Congestion Attack on Tor Using
|
||||||
|
* Long Paths", Usenix Security 2009). See also ticket 2667.
|
||||||
|
*
|
||||||
|
* The TORPROTOCOL reason is used instead of EXITPOLICY so client do NOT
|
||||||
|
* attempt to retry connecting onto another circuit that will also fail
|
||||||
|
* bringing considerable more load on the network if so.
|
||||||
|
*
|
||||||
|
* Since the address+port set here is a bloomfilter, in very rare cases, the
|
||||||
|
* check will create a false positive meaning that the destination could
|
||||||
|
* actually be legit and thus being denied exit. However, sending back a
|
||||||
|
* reason that makes the client retry results in much worst consequences in
|
||||||
|
* case of an attack so this is a small price to pay. */
|
||||||
|
if (!connection_edge_is_rendezvous_stream(edge_conn) &&
|
||||||
|
nodelist_reentry_probably_contains(&conn->addr, conn->port)) {
|
||||||
|
log_info(LD_EXIT, "%s:%d tried to connect back to a known relay address. "
|
||||||
|
"Closing.", escaped_safe_str_client(conn->address),
|
||||||
|
conn->port);
|
||||||
|
connection_edge_end(edge_conn, END_STREAM_REASON_TORPROTOCOL);
|
||||||
|
circuit_detach_stream(circuit_get_by_edge_conn(edge_conn), edge_conn);
|
||||||
|
connection_free(conn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_SYS_UN_H
|
#ifdef HAVE_SYS_UN_H
|
||||||
if (conn->socket_family != AF_UNIX) {
|
if (conn->socket_family != AF_UNIX) {
|
||||||
#else
|
#else
|
||||||
|
@ -55,13 +55,18 @@ static smartlist_t *fallback_dir_servers = NULL;
|
|||||||
static void
|
static void
|
||||||
add_trusted_dir_to_nodelist_addr_set(const dir_server_t *dir)
|
add_trusted_dir_to_nodelist_addr_set(const dir_server_t *dir)
|
||||||
{
|
{
|
||||||
|
tor_addr_t tmp_addr;
|
||||||
|
|
||||||
tor_assert(dir);
|
tor_assert(dir);
|
||||||
tor_assert(dir->is_authority);
|
tor_assert(dir->is_authority);
|
||||||
|
|
||||||
/* Add IPv4 and then IPv6 if applicable. */
|
/* Add IPv4 and then IPv6 if applicable. For authorities, we add the ORPort
|
||||||
nodelist_add_addr4_to_address_set(dir->addr);
|
* and DirPort so re-entry into the network back to them is not possible. */
|
||||||
|
tor_addr_from_ipv4h(&tmp_addr, dir->addr);
|
||||||
|
nodelist_add_addr_to_address_set(&tmp_addr, dir->or_port, dir->dir_port);
|
||||||
if (!tor_addr_is_null(&dir->ipv6_addr)) {
|
if (!tor_addr_is_null(&dir->ipv6_addr)) {
|
||||||
nodelist_add_addr6_to_address_set(&dir->ipv6_addr);
|
/* IPv6 DirPort is not a thing yet for authorities. */
|
||||||
|
nodelist_add_addr_to_address_set(&dir->ipv6_addr, dir->ipv6_orport, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,6 +135,10 @@ typedef struct nodelist_t {
|
|||||||
/* Set of addresses that belong to nodes we believe in. */
|
/* Set of addresses that belong to nodes we believe in. */
|
||||||
address_set_t *node_addrs;
|
address_set_t *node_addrs;
|
||||||
|
|
||||||
|
/* Set of addresses + port that belong to nodes we know and that we don't
|
||||||
|
* allow network re-entry towards them. */
|
||||||
|
addr_port_set_t *reentry_set;
|
||||||
|
|
||||||
/* The valid-after time of the last live consensus that initialized the
|
/* The valid-after time of the last live consensus that initialized the
|
||||||
* nodelist. We use this to detect outdated nodelists that need to be
|
* nodelist. We use this to detect outdated nodelists that need to be
|
||||||
* rebuilt using a newer consensus. */
|
* rebuilt using a newer consensus. */
|
||||||
@ -447,49 +451,62 @@ node_addrs_changed(node_t *node)
|
|||||||
static void
|
static void
|
||||||
node_add_to_address_set(const node_t *node)
|
node_add_to_address_set(const node_t *node)
|
||||||
{
|
{
|
||||||
if (!the_nodelist || !the_nodelist->node_addrs)
|
tor_addr_t tmp_addr;
|
||||||
|
|
||||||
|
if (!the_nodelist ||
|
||||||
|
!the_nodelist->node_addrs || !the_nodelist->reentry_set)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* These various address sources can be redundant, but it's likely faster
|
/* These various address sources can be redundant, but it's likely faster to
|
||||||
* to add them all than to compare them all for equality. */
|
* add them all than to compare them all for equality.
|
||||||
|
*
|
||||||
|
* For relays, we only add the ORPort in the addr+port set since we want to
|
||||||
|
* allow re-entry into the network to the DirPort so the self reachability
|
||||||
|
* test succeeds and thus the 0 value for the DirPort. */
|
||||||
|
|
||||||
if (node->rs) {
|
if (node->rs) {
|
||||||
if (node->rs->addr)
|
if (node->rs->addr) {
|
||||||
nodelist_add_addr4_to_address_set(node->rs->addr);
|
tor_addr_from_ipv4h(&tmp_addr, node->rs->addr);
|
||||||
|
nodelist_add_addr_to_address_set(&tmp_addr, node->rs->or_port, 0);
|
||||||
|
}
|
||||||
if (!tor_addr_is_null(&node->rs->ipv6_addr))
|
if (!tor_addr_is_null(&node->rs->ipv6_addr))
|
||||||
nodelist_add_addr6_to_address_set(&node->rs->ipv6_addr);
|
nodelist_add_addr_to_address_set(&node->rs->ipv6_addr,
|
||||||
|
node->rs->ipv6_orport, 0);
|
||||||
}
|
}
|
||||||
if (node->ri) {
|
if (node->ri) {
|
||||||
if (node->ri->addr)
|
if (node->ri->addr) {
|
||||||
nodelist_add_addr4_to_address_set(node->ri->addr);
|
tor_addr_from_ipv4h(&tmp_addr, node->ri->addr);
|
||||||
|
nodelist_add_addr_to_address_set(&tmp_addr, node->ri->or_port, 0);
|
||||||
|
}
|
||||||
if (!tor_addr_is_null(&node->ri->ipv6_addr))
|
if (!tor_addr_is_null(&node->ri->ipv6_addr))
|
||||||
nodelist_add_addr6_to_address_set(&node->ri->ipv6_addr);
|
nodelist_add_addr_to_address_set(&node->ri->ipv6_addr,
|
||||||
|
node->ri->ipv6_orport, 0);
|
||||||
}
|
}
|
||||||
if (node->md) {
|
if (node->md) {
|
||||||
if (!tor_addr_is_null(&node->md->ipv6_addr))
|
if (!tor_addr_is_null(&node->md->ipv6_addr))
|
||||||
nodelist_add_addr6_to_address_set(&node->md->ipv6_addr);
|
nodelist_add_addr_to_address_set(&node->md->ipv6_addr,
|
||||||
|
node->md->ipv6_orport, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Add the given v4 address into the nodelist address set. */
|
/** Add the given address into the nodelist address set. */
|
||||||
void
|
void
|
||||||
nodelist_add_addr4_to_address_set(const uint32_t addr)
|
nodelist_add_addr_to_address_set(const tor_addr_t *addr,
|
||||||
|
uint16_t or_port, uint16_t dir_port)
|
||||||
{
|
{
|
||||||
if (!the_nodelist || !the_nodelist->node_addrs || addr == 0) {
|
if (BUG(!addr) || tor_addr_is_null(addr) ||
|
||||||
return;
|
(!tor_addr_is_v4(addr) && tor_addr_family(addr) != AF_INET6) ||
|
||||||
}
|
!the_nodelist || !the_nodelist->node_addrs ||
|
||||||
address_set_add_ipv4h(the_nodelist->node_addrs, addr);
|
!the_nodelist->reentry_set) {
|
||||||
}
|
|
||||||
|
|
||||||
/** Add the given v6 address into the nodelist address set. */
|
|
||||||
void
|
|
||||||
nodelist_add_addr6_to_address_set(const tor_addr_t *addr)
|
|
||||||
{
|
|
||||||
if (BUG(!addr) || tor_addr_is_null(addr) || tor_addr_is_v4(addr) ||
|
|
||||||
!the_nodelist || !the_nodelist->node_addrs) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
address_set_add(the_nodelist->node_addrs, addr);
|
address_set_add(the_nodelist->node_addrs, addr);
|
||||||
|
if (or_port != 0) {
|
||||||
|
addr_port_set_add(the_nodelist->reentry_set, addr, or_port);
|
||||||
|
}
|
||||||
|
if (dir_port != 0) {
|
||||||
|
addr_port_set_add(the_nodelist->reentry_set, addr, dir_port);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return true if <b>addr</b> is the address of some node in the nodelist.
|
/** Return true if <b>addr</b> is the address of some node in the nodelist.
|
||||||
@ -506,6 +523,21 @@ nodelist_probably_contains_address(const tor_addr_t *addr)
|
|||||||
return address_set_probably_contains(the_nodelist->node_addrs, addr);
|
return address_set_probably_contains(the_nodelist->node_addrs, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return true if <b>addr</b> is the address of some node in the nodelist and
|
||||||
|
* corresponds also to the given port. If not, probably return false. */
|
||||||
|
bool
|
||||||
|
nodelist_reentry_probably_contains(const tor_addr_t *addr, uint16_t port)
|
||||||
|
{
|
||||||
|
if (BUG(!addr) || BUG(!port))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!the_nodelist || !the_nodelist->reentry_set)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return addr_port_set_probably_contains(the_nodelist->reentry_set,
|
||||||
|
addr, port);
|
||||||
|
}
|
||||||
|
|
||||||
/** Add <b>ri</b> to an appropriate node in the nodelist. If we replace an
|
/** Add <b>ri</b> to an appropriate node in the nodelist. If we replace an
|
||||||
* old routerinfo, and <b>ri_old_out</b> is not NULL, set *<b>ri_old_out</b>
|
* old routerinfo, and <b>ri_old_out</b> is not NULL, set *<b>ri_old_out</b>
|
||||||
* to the previous routerinfo.
|
* to the previous routerinfo.
|
||||||
@ -637,10 +669,13 @@ nodelist_set_consensus(networkstatus_t *ns)
|
|||||||
* v6). Then we add the number of configured trusted authorities we have. */
|
* v6). Then we add the number of configured trusted authorities we have. */
|
||||||
int estimated_addresses = smartlist_len(ns->routerstatus_list) *
|
int estimated_addresses = smartlist_len(ns->routerstatus_list) *
|
||||||
get_estimated_address_per_node();
|
get_estimated_address_per_node();
|
||||||
estimated_addresses += (get_n_authorities(V3_DIRINFO & BRIDGE_DIRINFO) *
|
estimated_addresses += (get_n_authorities(V3_DIRINFO | BRIDGE_DIRINFO) *
|
||||||
get_estimated_address_per_node());
|
get_estimated_address_per_node());
|
||||||
address_set_free(the_nodelist->node_addrs);
|
address_set_free(the_nodelist->node_addrs);
|
||||||
|
addr_port_set_free(the_nodelist->reentry_set);
|
||||||
the_nodelist->node_addrs = address_set_new(estimated_addresses);
|
the_nodelist->node_addrs = address_set_new(estimated_addresses);
|
||||||
|
/* Times two here is for both the ORPort and DirPort. */
|
||||||
|
the_nodelist->reentry_set = addr_port_set_new(estimated_addresses * 2);
|
||||||
|
|
||||||
SMARTLIST_FOREACH_BEGIN(ns->routerstatus_list, routerstatus_t *, rs) {
|
SMARTLIST_FOREACH_BEGIN(ns->routerstatus_list, routerstatus_t *, rs) {
|
||||||
node_t *node = node_get_or_create(rs->identity_digest);
|
node_t *node = node_get_or_create(rs->identity_digest);
|
||||||
@ -867,6 +902,8 @@ nodelist_free_all(void)
|
|||||||
|
|
||||||
address_set_free(the_nodelist->node_addrs);
|
address_set_free(the_nodelist->node_addrs);
|
||||||
the_nodelist->node_addrs = NULL;
|
the_nodelist->node_addrs = NULL;
|
||||||
|
addr_port_set_free(the_nodelist->reentry_set);
|
||||||
|
the_nodelist->reentry_set = NULL;
|
||||||
|
|
||||||
tor_free(the_nodelist);
|
tor_free(the_nodelist);
|
||||||
}
|
}
|
||||||
|
@ -35,8 +35,10 @@ node_t *nodelist_add_microdesc(microdesc_t *md);
|
|||||||
void nodelist_set_consensus(networkstatus_t *ns);
|
void nodelist_set_consensus(networkstatus_t *ns);
|
||||||
void nodelist_ensure_freshness(networkstatus_t *ns);
|
void nodelist_ensure_freshness(networkstatus_t *ns);
|
||||||
int nodelist_probably_contains_address(const tor_addr_t *addr);
|
int nodelist_probably_contains_address(const tor_addr_t *addr);
|
||||||
void nodelist_add_addr4_to_address_set(const uint32_t addr);
|
bool nodelist_reentry_probably_contains(const tor_addr_t *addr,
|
||||||
void nodelist_add_addr6_to_address_set(const tor_addr_t *addr);
|
uint16_t port);
|
||||||
|
void nodelist_add_addr_to_address_set(const tor_addr_t *addr,
|
||||||
|
uint16_t or_port, uint16_t dir_port);
|
||||||
|
|
||||||
void nodelist_remove_microdesc(const char *identity_digest, microdesc_t *md);
|
void nodelist_remove_microdesc(const char *identity_digest, microdesc_t *md);
|
||||||
void nodelist_remove_routerinfo(routerinfo_t *ri);
|
void nodelist_remove_routerinfo(routerinfo_t *ri);
|
||||||
|
@ -182,11 +182,91 @@ test_nodelist(void *arg)
|
|||||||
UNMOCK(dirlist_add_trusted_dir_addresses);
|
UNMOCK(dirlist_add_trusted_dir_addresses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Test that the no-reentry exit filter works as intended */
|
||||||
|
static void
|
||||||
|
test_exit_no_reentry(void *arg)
|
||||||
|
{
|
||||||
|
routerstatus_t *rs = NULL; microdesc_t *md = NULL; routerinfo_t *ri = NULL;
|
||||||
|
(void) arg;
|
||||||
|
|
||||||
|
MOCK(networkstatus_get_latest_consensus,
|
||||||
|
mock_networkstatus_get_latest_consensus);
|
||||||
|
MOCK(networkstatus_get_latest_consensus_by_flavor,
|
||||||
|
mock_networkstatus_get_latest_consensus_by_flavor);
|
||||||
|
MOCK(get_estimated_address_per_node,
|
||||||
|
mock_get_estimated_address_per_node);
|
||||||
|
MOCK(dirlist_add_trusted_dir_addresses,
|
||||||
|
mock_dirlist_add_trusted_dir_addresses);
|
||||||
|
|
||||||
|
dummy_ns = tor_malloc_zero(sizeof(*dummy_ns));
|
||||||
|
dummy_ns->flavor = FLAV_MICRODESC;
|
||||||
|
dummy_ns->routerstatus_list = smartlist_new();
|
||||||
|
|
||||||
|
tor_addr_t addr_v4, addr_v6, dummy_addr;
|
||||||
|
tor_addr_parse(&addr_v4, "42.42.42.42");
|
||||||
|
tor_addr_parse(&addr_v6, "1:2:3:4::");
|
||||||
|
memset(&dummy_addr, 'A', sizeof(dummy_addr));
|
||||||
|
|
||||||
|
/* This will make the nodelist bloom filter very large
|
||||||
|
* (the_nodelist->node_addrs) so we will fail the contain test rarely. */
|
||||||
|
addr_per_node = 1024;
|
||||||
|
|
||||||
|
/* After this point the nodelist is populated with the directory authorities
|
||||||
|
* address and ports */
|
||||||
|
nodelist_set_consensus(dummy_ns);
|
||||||
|
|
||||||
|
/* The address set is empty. Try it anyway */
|
||||||
|
tt_assert(!nodelist_reentry_probably_contains(&addr_v4, 244));
|
||||||
|
tt_assert(!nodelist_reentry_probably_contains(&addr_v6, 244));
|
||||||
|
|
||||||
|
/* Now let's populate the network */
|
||||||
|
md = tor_malloc_zero(sizeof(*md));
|
||||||
|
ri = tor_malloc_zero(sizeof(*ri));
|
||||||
|
rs = tor_malloc_zero(sizeof(*rs));
|
||||||
|
crypto_rand(rs->identity_digest, sizeof(rs->identity_digest));
|
||||||
|
crypto_rand(md->digest, sizeof(md->digest));
|
||||||
|
memcpy(rs->descriptor_digest, md->digest, DIGEST256_LEN);
|
||||||
|
|
||||||
|
/* Setup the rs, ri and md addresses. */
|
||||||
|
rs->addr = tor_addr_to_ipv4h(&addr_v4);
|
||||||
|
rs->or_port = 444;
|
||||||
|
tor_addr_parse(&rs->ipv6_addr, "1:2:3:4::");
|
||||||
|
rs->ipv6_orport = 666;
|
||||||
|
ri->addr = tor_addr_to_ipv4h(&addr_v4);
|
||||||
|
tor_addr_parse(&ri->ipv6_addr, "1:2:3:4::");
|
||||||
|
tor_addr_parse(&md->ipv6_addr, "1:2:3:4::");
|
||||||
|
|
||||||
|
/* Add the rs to the consensus becoming a node_t. */
|
||||||
|
smartlist_add(dummy_ns->routerstatus_list, rs);
|
||||||
|
nodelist_set_consensus(dummy_ns);
|
||||||
|
|
||||||
|
/* Now that the nodelist is populated let's do some retry attempts */
|
||||||
|
|
||||||
|
/* First let's try an address that is on the no-reentry list, but with a
|
||||||
|
different port */
|
||||||
|
tt_assert(!nodelist_reentry_probably_contains(&addr_v4, 666));
|
||||||
|
tt_assert(!nodelist_reentry_probably_contains(&addr_v6, 444));
|
||||||
|
|
||||||
|
/* OK now let's try with the right address and right port */
|
||||||
|
tt_assert(nodelist_reentry_probably_contains(&addr_v4, 444));
|
||||||
|
tt_assert(nodelist_reentry_probably_contains(&addr_v6, 666));
|
||||||
|
|
||||||
|
done:
|
||||||
|
routerstatus_free(rs); routerinfo_free(ri); microdesc_free(md);
|
||||||
|
smartlist_clear(dummy_ns->routerstatus_list);
|
||||||
|
networkstatus_vote_free(dummy_ns);
|
||||||
|
UNMOCK(networkstatus_get_latest_consensus);
|
||||||
|
UNMOCK(networkstatus_get_latest_consensus_by_flavor);
|
||||||
|
UNMOCK(get_estimated_address_per_node);
|
||||||
|
UNMOCK(dirlist_add_trusted_dir_addresses);
|
||||||
|
}
|
||||||
|
|
||||||
struct testcase_t address_set_tests[] = {
|
struct testcase_t address_set_tests[] = {
|
||||||
{ "contains", test_contains, TT_FORK,
|
{ "contains", test_contains, TT_FORK,
|
||||||
NULL, NULL },
|
NULL, NULL },
|
||||||
{ "nodelist", test_nodelist, TT_FORK,
|
{ "nodelist", test_nodelist, TT_FORK,
|
||||||
NULL, NULL },
|
NULL, NULL },
|
||||||
|
{ "exit_no_reentry", test_exit_no_reentry, TT_FORK, NULL, NULL },
|
||||||
|
|
||||||
END_OF_TESTCASES
|
END_OF_TESTCASES
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user