mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 13:13:44 +01:00
Merge remote-tracking branch 'tor-github/pr/1864/head'
This commit is contained in:
commit
49800cf539
3
changes/bug33900
Normal file
3
changes/bug33900
Normal file
@ -0,0 +1,3 @@
|
||||
o Minor bugfixes (IPv4, relay):
|
||||
- Check for invalid zero IPv4 addresses and ports, when sending and
|
||||
receiving extend cells. Fixes bug 33900; bugfix on 0.2.4.8-alpha.
|
5
changes/bug33917
Normal file
5
changes/bug33917
Normal file
@ -0,0 +1,5 @@
|
||||
o Minor bugfixes (logging, testing):
|
||||
- Make all of tor's assertion macros support the ALL_BUGS_ARE_FATAL and
|
||||
DISABLE_ASSERTS_IN_UNIT_TESTS debugging modes. Implements these modes
|
||||
for IF_BUG_ONCE(). (It used to log a non-fatal warning, regardless of
|
||||
the debugging mode.) Fixes bug 33917; bugfix on 0.2.9.1-alpha.
|
12
changes/ticket33817
Normal file
12
changes/ticket33817
Normal file
@ -0,0 +1,12 @@
|
||||
o Major features (IPv6, relay):
|
||||
- Relays may extend circuits over IPv6, if the relay has an IPv6 ORPort,
|
||||
and the client supplies the other relay's IPv6 ORPort in the EXTEND2
|
||||
cell. IPv6 extends will be used by the relay IPv6 ORPort self-tests in
|
||||
33222. Closes ticket 33817.
|
||||
- Consider IPv6-only EXTEND2 cells valid on relays. Log a protocol warning
|
||||
if the IPv4 or IPv6 address is an internal address, and internal
|
||||
addresses are not allowed. But continue to use the other address, if it
|
||||
is valid. Closes ticket 33817.
|
||||
- If a relay can extend over IPv4 and IPv6, it chooses between them
|
||||
uniformly at random. Closes ticket 33817.
|
||||
- Re-use existing IPv6 connections for circuit extends. Closes ticket 33817.
|
4
changes/ticket33901
Normal file
4
changes/ticket33901
Normal file
@ -0,0 +1,4 @@
|
||||
o Minor features (IPv6, relay):
|
||||
- Allow clients and relays to send dual-stack and IPv6-only EXTEND2 cells.
|
||||
Parse dual-stack and IPv6-only EXTEND2 cells on relays.
|
||||
Closes ticket 33901.
|
@ -305,7 +305,7 @@ problem function-size /src/lib/encoding/confline.c:parse_config_line_from_str_ve
|
||||
problem function-size /src/lib/encoding/cstring.c:unescape_string() 108
|
||||
problem function-size /src/lib/fs/dir.c:check_private_dir() 230
|
||||
problem function-size /src/lib/math/prob_distr.c:sample_uniform_interval() 145
|
||||
problem function-size /src/lib/net/address.c:tor_addr_parse_mask_ports() 194
|
||||
problem function-size /src/lib/net/address.c:tor_addr_parse_mask_ports() 195
|
||||
problem function-size /src/lib/net/address.c:tor_addr_compare_masked() 110
|
||||
problem function-size /src/lib/net/inaddr.c:tor_inet_pton() 107
|
||||
problem function-size /src/lib/net/socketpair.c:tor_ersatz_socketpair() 102
|
||||
|
@ -83,6 +83,13 @@
|
||||
|
||||
#include "core/or/cell_queue_st.h"
|
||||
|
||||
/* Static function prototypes */
|
||||
|
||||
static bool channel_matches_target_addr_for_extend(
|
||||
channel_t *chan,
|
||||
const tor_addr_t *target_ipv4_addr,
|
||||
const tor_addr_t *target_ipv6_addr);
|
||||
|
||||
/* Global lists of channels */
|
||||
|
||||
/* All channel_t instances */
|
||||
@ -2360,9 +2367,9 @@ channel_is_better(channel_t *a, channel_t *b)
|
||||
* Get a channel to extend a circuit.
|
||||
*
|
||||
* Given the desired relay identity, pick a suitable channel to extend a
|
||||
* circuit to the target address requsted by the client. Search for an
|
||||
* existing channel for the requested endpoint. Make sure the channel is
|
||||
* usable for new circuits, and matches the target address.
|
||||
* circuit to the target IPv4 or IPv6 address requsted by the client. Search
|
||||
* for an existing channel for the requested endpoint. Make sure the channel
|
||||
* is usable for new circuits, and matches one of the target addresses.
|
||||
*
|
||||
* Try to return the best channel. But if there is no good channel, set
|
||||
* *msg_out to a message describing the channel's state and our next action,
|
||||
@ -2372,7 +2379,8 @@ channel_is_better(channel_t *a, channel_t *b)
|
||||
MOCK_IMPL(channel_t *,
|
||||
channel_get_for_extend,(const char *rsa_id_digest,
|
||||
const ed25519_public_key_t *ed_id,
|
||||
const tor_addr_t *target_addr,
|
||||
const tor_addr_t *target_ipv4_addr,
|
||||
const tor_addr_t *target_ipv6_addr,
|
||||
const char **msg_out,
|
||||
int *launch_out))
|
||||
{
|
||||
@ -2404,11 +2412,15 @@ channel_get_for_extend,(const char *rsa_id_digest,
|
||||
continue;
|
||||
}
|
||||
|
||||
const bool matches_target =
|
||||
channel_matches_target_addr_for_extend(chan,
|
||||
target_ipv4_addr,
|
||||
target_ipv6_addr);
|
||||
/* Never return a non-open connection. */
|
||||
if (!CHANNEL_IS_OPEN(chan)) {
|
||||
/* If the address matches, don't launch a new connection for this
|
||||
* circuit. */
|
||||
if (channel_matches_target_addr_for_extend(chan, target_addr))
|
||||
if (matches_target)
|
||||
++n_inprogress_goodaddr;
|
||||
continue;
|
||||
}
|
||||
@ -2419,22 +2431,21 @@ channel_get_for_extend,(const char *rsa_id_digest,
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Never return a non-canonical connection using a recent link protocol
|
||||
* if the address is not what we wanted.
|
||||
/* If the connection is using a recent link protocol, only return canonical
|
||||
* connections, when the address is one of the addresses we wanted.
|
||||
*
|
||||
* The channel_is_canonical_is_reliable() function asks the lower layer
|
||||
* if we should trust channel_is_canonical(). The below is from the
|
||||
* comments of the old circuit_or_get_for_extend() and applies when
|
||||
* if we should trust channel_is_canonical(). It only applies when
|
||||
* the lower-layer transport is channel_tls_t.
|
||||
*
|
||||
* (For old link protocols, we can't rely on is_canonical getting
|
||||
* For old link protocols, we can't rely on is_canonical getting
|
||||
* set properly if we're talking to the right address, since we might
|
||||
* have an out-of-date descriptor, and we will get no NETINFO cell to
|
||||
* tell us about the right address.)
|
||||
* tell us about the right address.
|
||||
*/
|
||||
if (!channel_is_canonical(chan) &&
|
||||
channel_is_canonical_is_reliable(chan) &&
|
||||
!channel_matches_target_addr_for_extend(chan, target_addr)) {
|
||||
!matches_target) {
|
||||
++n_noncanonical;
|
||||
continue;
|
||||
}
|
||||
@ -3297,20 +3308,33 @@ channel_matches_extend_info(channel_t *chan, extend_info_t *extend_info)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a channel matches a given target address; return true iff we do.
|
||||
* Check if a channel matches the given target IPv4 or IPv6 addresses.
|
||||
* If either address matches, return true. If neither address matches,
|
||||
* return false.
|
||||
*
|
||||
* Both addresses can't be NULL.
|
||||
*
|
||||
* This function calls into the lower layer and asks if this channel thinks
|
||||
* it matches a given target address for circuit extension purposes.
|
||||
* it matches the target addresses for circuit extension purposes.
|
||||
*/
|
||||
int
|
||||
static bool
|
||||
channel_matches_target_addr_for_extend(channel_t *chan,
|
||||
const tor_addr_t *target)
|
||||
const tor_addr_t *target_ipv4_addr,
|
||||
const tor_addr_t *target_ipv6_addr)
|
||||
{
|
||||
tor_assert(chan);
|
||||
tor_assert(chan->matches_target);
|
||||
tor_assert(target);
|
||||
|
||||
return chan->matches_target(chan, target);
|
||||
IF_BUG_ONCE(!target_ipv4_addr && !target_ipv6_addr)
|
||||
return false;
|
||||
|
||||
if (target_ipv4_addr && chan->matches_target(chan, target_ipv4_addr))
|
||||
return true;
|
||||
|
||||
if (target_ipv6_addr && chan->matches_target(chan, target_ipv6_addr))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -661,7 +661,8 @@ channel_t * channel_connect(const tor_addr_t *addr, uint16_t port,
|
||||
MOCK_DECL(channel_t *, channel_get_for_extend,(
|
||||
const char *rsa_id_digest,
|
||||
const struct ed25519_public_key_t *ed_id,
|
||||
const tor_addr_t *target_addr,
|
||||
const tor_addr_t *target_ipv4_addr,
|
||||
const tor_addr_t *target_ipv6_addr,
|
||||
const char **msg_out,
|
||||
int *launch_out));
|
||||
|
||||
@ -737,8 +738,6 @@ int channel_is_outgoing(channel_t *chan);
|
||||
void channel_mark_client(channel_t *chan);
|
||||
void channel_clear_client(channel_t *chan);
|
||||
int channel_matches_extend_info(channel_t *chan, extend_info_t *extend_info);
|
||||
int channel_matches_target_addr_for_extend(channel_t *chan,
|
||||
const tor_addr_t *target);
|
||||
unsigned int channel_num_circuits(channel_t *chan);
|
||||
MOCK_DECL(void,channel_set_circid_type,(channel_t *chan,
|
||||
crypto_pk_t *identity_rcvd,
|
||||
|
@ -1669,7 +1669,7 @@ tor_addr_from_netinfo_addr(tor_addr_t *tor_addr,
|
||||
} else if (type == NETINFO_ADDR_TYPE_IPV6 && len == 16) {
|
||||
const uint8_t *ipv6_bytes = netinfo_addr_getconstarray_addr_ipv6(
|
||||
netinfo_addr);
|
||||
tor_addr_from_ipv6_bytes(tor_addr, (const char *)ipv6_bytes);
|
||||
tor_addr_from_ipv6_bytes(tor_addr, ipv6_bytes);
|
||||
} else {
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_OR, "Cannot read address from NETINFO "
|
||||
"- wrong type/length.");
|
||||
|
@ -559,11 +559,17 @@ circuit_handle_first_hop(origin_circuit_t *circ)
|
||||
fmt_addrport(&firsthop->extend_info->addr,
|
||||
firsthop->extend_info->port));
|
||||
|
||||
n_chan = channel_get_for_extend(firsthop->extend_info->identity_digest,
|
||||
&firsthop->extend_info->ed_identity,
|
||||
&firsthop->extend_info->addr,
|
||||
&msg,
|
||||
&should_launch);
|
||||
/* We'll cleanup this code in #33220, when we add an IPv6 address to
|
||||
* extend_info_t. */
|
||||
const bool addr_is_ipv4 =
|
||||
(tor_addr_family(&firsthop->extend_info->addr) == AF_INET);
|
||||
n_chan = channel_get_for_extend(
|
||||
firsthop->extend_info->identity_digest,
|
||||
&firsthop->extend_info->ed_identity,
|
||||
addr_is_ipv4 ? &firsthop->extend_info->addr : NULL,
|
||||
addr_is_ipv4 ? NULL : &firsthop->extend_info->addr,
|
||||
&msg,
|
||||
&should_launch);
|
||||
|
||||
if (!n_chan) {
|
||||
/* not currently connected in a useful way. */
|
||||
|
@ -3531,7 +3531,7 @@ connection_ap_handshake_socks_resolved,(entry_connection_t *conn,
|
||||
}
|
||||
} else if (answer_type == RESOLVED_TYPE_IPV6 && answer_len == 16) {
|
||||
tor_addr_t a;
|
||||
tor_addr_from_ipv6_bytes(&a, (char*)answer);
|
||||
tor_addr_from_ipv6_bytes(&a, answer);
|
||||
if (! tor_addr_is_null(&a)) {
|
||||
client_dns_set_addressmap(conn,
|
||||
conn->socks_request->address, &a,
|
||||
|
@ -240,11 +240,21 @@ created_cell_parse(created_cell_t *cell_out, const cell_t *cell_in)
|
||||
static int
|
||||
check_extend_cell(const extend_cell_t *cell)
|
||||
{
|
||||
const bool is_extend2 = (cell->cell_type == RELAY_COMMAND_EXTEND2);
|
||||
|
||||
if (tor_digest_is_zero((const char*)cell->node_id))
|
||||
return -1;
|
||||
/* We don't currently allow EXTEND2 cells without an IPv4 address */
|
||||
if (tor_addr_family(&cell->orport_ipv4.addr) == AF_UNSPEC)
|
||||
return -1;
|
||||
if (!tor_addr_port_is_valid_ap(&cell->orport_ipv4, 0)) {
|
||||
/* EXTEND cells must have an IPv4 address. */
|
||||
if (!is_extend2) {
|
||||
return -1;
|
||||
}
|
||||
/* EXTEND2 cells must have at least one IP address.
|
||||
* It can be IPv4 or IPv6. */
|
||||
if (!tor_addr_port_is_valid_ap(&cell->orport_ipv6, 0)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (cell->create_cell.cell_type == CELL_CREATE) {
|
||||
if (cell->cell_type != RELAY_COMMAND_EXTEND)
|
||||
return -1;
|
||||
@ -343,7 +353,7 @@ extend_cell_from_extend2_cell_body(extend_cell_t *cell_out,
|
||||
continue;
|
||||
found_ipv6 = 1;
|
||||
tor_addr_from_ipv6_bytes(&cell_out->orport_ipv6.addr,
|
||||
(const char *)ls->un_ipv6_addr);
|
||||
ls->un_ipv6_addr);
|
||||
cell_out->orport_ipv6.port = ls->un_ipv6_port;
|
||||
break;
|
||||
case LS_LEGACY_ID:
|
||||
@ -364,7 +374,12 @@ extend_cell_from_extend2_cell_body(extend_cell_t *cell_out,
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_rsa_id || !found_ipv4) /* These are mandatory */
|
||||
/* EXTEND2 cells must have an RSA ID */
|
||||
if (!found_rsa_id)
|
||||
return -1;
|
||||
|
||||
/* EXTEND2 cells must have at least one IP address */
|
||||
if (!found_ipv4 && !found_ipv6)
|
||||
return -1;
|
||||
|
||||
return create_cell_from_create2_cell_body(&cell_out->create_cell,
|
||||
@ -620,12 +635,13 @@ extend_cell_format(uint8_t *command_out, uint16_t *len_out,
|
||||
break;
|
||||
case RELAY_COMMAND_EXTEND2:
|
||||
{
|
||||
uint8_t n_specifiers = 2;
|
||||
uint8_t n_specifiers = 1;
|
||||
*command_out = RELAY_COMMAND_EXTEND2;
|
||||
extend2_cell_body_t *cell = extend2_cell_body_new();
|
||||
link_specifier_t *ls;
|
||||
{
|
||||
/* IPv4 specifier first. */
|
||||
if (tor_addr_port_is_valid_ap(&cell_in->orport_ipv4, 0)) {
|
||||
/* Maybe IPv4 specifier first. */
|
||||
++n_specifiers;
|
||||
ls = link_specifier_new();
|
||||
extend2_cell_body_add_ls(cell, ls);
|
||||
ls->ls_type = LS_IPV4;
|
||||
@ -651,6 +667,17 @@ extend_cell_format(uint8_t *command_out, uint16_t *len_out,
|
||||
ls->ls_len = 32;
|
||||
memcpy(ls->un_ed25519_id, cell_in->ed_pubkey.pubkey, 32);
|
||||
}
|
||||
if (tor_addr_port_is_valid_ap(&cell_in->orport_ipv6, 0)) {
|
||||
/* Then maybe IPv6 specifier. */
|
||||
++n_specifiers;
|
||||
ls = link_specifier_new();
|
||||
extend2_cell_body_add_ls(cell, ls);
|
||||
ls->ls_type = LS_IPV6;
|
||||
ls->ls_len = 18;
|
||||
tor_addr_copy_ipv6_bytes(ls->un_ipv6_addr,
|
||||
&cell_in->orport_ipv6.addr);
|
||||
ls->un_ipv6_port = cell_in->orport_ipv6.port;
|
||||
}
|
||||
cell->n_spec = n_specifiers;
|
||||
|
||||
/* Now, the handshake */
|
||||
|
@ -167,7 +167,7 @@ policy_expand_unspec(smartlist_t **policy)
|
||||
}
|
||||
tor_addr_from_ipv4h(&newpolicy_ipv4.addr, 0);
|
||||
tor_addr_from_ipv6_bytes(&newpolicy_ipv6.addr,
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
|
||||
(const uint8_t *)"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
|
||||
smartlist_add(tmp, addr_policy_get_canonical_entry(&newpolicy_ipv4));
|
||||
smartlist_add(tmp, addr_policy_get_canonical_entry(&newpolicy_ipv6));
|
||||
addr_policy_free(p);
|
||||
@ -1005,7 +1005,7 @@ fascist_firewall_choose_address_ls(const smartlist_t *lspecs,
|
||||
* direct connection. */
|
||||
if (have_v6) continue;
|
||||
tor_addr_from_ipv6_bytes(&addr_v6,
|
||||
(const char *) link_specifier_getconstarray_un_ipv6_addr(ls));
|
||||
link_specifier_getconstarray_un_ipv6_addr(ls));
|
||||
port_v6 = link_specifier_get_un_ipv6_port(ls);
|
||||
have_v6 = 1;
|
||||
break;
|
||||
|
@ -867,7 +867,7 @@ connection_ap_process_end_not_open(
|
||||
ttl = (int)ntohl(get_uint32(cell->payload+RELAY_HEADER_SIZE+5));
|
||||
} else if (rh->length == 17 || rh->length == 21) {
|
||||
tor_addr_from_ipv6_bytes(&addr,
|
||||
(char*)(cell->payload+RELAY_HEADER_SIZE+1));
|
||||
(cell->payload+RELAY_HEADER_SIZE+1));
|
||||
if (rh->length == 21)
|
||||
ttl = (int)ntohl(get_uint32(cell->payload+RELAY_HEADER_SIZE+17));
|
||||
}
|
||||
@ -1092,7 +1092,7 @@ connected_cell_parse(const relay_header_t *rh, const cell_t *cell,
|
||||
return -1;
|
||||
if (get_uint8(payload + 4) != 6)
|
||||
return -1;
|
||||
tor_addr_from_ipv6_bytes(addr_out, (char*)(payload + 5));
|
||||
tor_addr_from_ipv6_bytes(addr_out, (payload + 5));
|
||||
bytes = ntohl(get_uint32(payload + 21));
|
||||
if (bytes <= INT32_MAX)
|
||||
*ttl_out = (int) bytes;
|
||||
@ -1165,7 +1165,7 @@ resolved_cell_parse(const cell_t *cell, const relay_header_t *rh,
|
||||
if (answer_len != 16)
|
||||
goto err;
|
||||
addr = tor_malloc_zero(sizeof(*addr));
|
||||
tor_addr_from_ipv6_bytes(&addr->addr, (const char*) cp);
|
||||
tor_addr_from_ipv6_bytes(&addr->addr, cp);
|
||||
cp += 16;
|
||||
addr->ttl = ntohl(get_uint32(cp));
|
||||
cp += 4;
|
||||
@ -3217,7 +3217,7 @@ decode_address_from_payload(tor_addr_t *addr_out, const uint8_t *payload,
|
||||
case RESOLVED_TYPE_IPV6:
|
||||
if (payload[1] != 16)
|
||||
return NULL;
|
||||
tor_addr_from_ipv6_bytes(addr_out, (char*)(payload+2));
|
||||
tor_addr_from_ipv6_bytes(addr_out, (payload+2));
|
||||
break;
|
||||
default:
|
||||
tor_addr_make_unspec(addr_out);
|
||||
|
@ -587,9 +587,8 @@ parse_socks5_client_request(const uint8_t *raw_data, socks_request_t *req,
|
||||
strlcpy(req->address, hostname, sizeof(req->address));
|
||||
} break;
|
||||
case 4: {
|
||||
const char *ipv6 =
|
||||
(const char *)socks5_client_request_getarray_dest_addr_ipv6(
|
||||
trunnel_req);
|
||||
const uint8_t *ipv6 =
|
||||
socks5_client_request_getarray_dest_addr_ipv6(trunnel_req);
|
||||
tor_addr_from_ipv6_bytes(&destaddr, ipv6);
|
||||
|
||||
tor_addr_to_str(req->address, &destaddr, sizeof(req->address), 1);
|
||||
|
@ -902,7 +902,7 @@ get_random_virtual_addr(const virtual_addr_conf_t *conf, tor_addr_t *addr_out)
|
||||
}
|
||||
|
||||
if (ipv6)
|
||||
tor_addr_from_ipv6_bytes(addr_out, (char*) bytes);
|
||||
tor_addr_from_ipv6_bytes(addr_out, bytes);
|
||||
else
|
||||
tor_addr_from_ipv4n(addr_out, get_uint32(bytes));
|
||||
|
||||
|
@ -18,6 +18,8 @@
|
||||
#include "orconfig.h"
|
||||
#include "feature/relay/circuitbuild_relay.h"
|
||||
|
||||
#include "lib/crypt_ops/crypto_rand.h"
|
||||
|
||||
#include "core/or/or.h"
|
||||
#include "app/config/config.h"
|
||||
|
||||
@ -36,6 +38,7 @@
|
||||
|
||||
#include "feature/nodelist/nodelist.h"
|
||||
|
||||
#include "feature/relay/router.h"
|
||||
#include "feature/relay/routermode.h"
|
||||
#include "feature/relay/selftest.h"
|
||||
|
||||
@ -119,6 +122,49 @@ circuit_extend_add_ed25519_helper(struct extend_cell_t *ec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check if the address and port in the tor_addr_port_t <b>ap</b> are valid,
|
||||
* and are allowed by the current ExtendAllowPrivateAddresses config.
|
||||
*
|
||||
* If they are valid, return true.
|
||||
* Otherwise, if they are invalid, return false.
|
||||
*
|
||||
* If <b>log_zero_addrs</b> is true, log warnings about zero addresses at
|
||||
* <b>log_level</b>. If <b>log_internal_addrs</b> is true, log warnings about
|
||||
* internal addresses at <b>log_level</b>.
|
||||
*/
|
||||
static bool
|
||||
circuit_extend_addr_port_is_valid(const struct tor_addr_port_t *ap,
|
||||
bool log_zero_addrs, bool log_internal_addrs,
|
||||
int log_level)
|
||||
{
|
||||
/* It's safe to print the family. But we don't want to print the address,
|
||||
* unless specifically configured to do so. (Zero addresses aren't sensitive,
|
||||
* But some internal addresses might be.)*/
|
||||
|
||||
if (!tor_addr_port_is_valid_ap(ap, 0)) {
|
||||
if (log_zero_addrs) {
|
||||
log_fn(log_level, LD_PROTOCOL,
|
||||
"Client asked me to extend to a zero destination port or "
|
||||
"%s address '%s'.",
|
||||
fmt_addr_family(&ap->addr), safe_str(fmt_addrport_ap(ap)));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tor_addr_is_internal(&ap->addr, 0) &&
|
||||
!get_options()->ExtendAllowPrivateAddresses) {
|
||||
if (log_internal_addrs) {
|
||||
log_fn(log_level, LD_PROTOCOL,
|
||||
"Client asked me to extend to a private %s address '%s'.",
|
||||
fmt_addr_family(&ap->addr),
|
||||
safe_str(fmt_and_decorate_addr(&ap->addr)));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Before replying to an extend cell, check the link specifiers in the extend
|
||||
* cell <b>ec</b>, which was received on the circuit <b>circ</b>.
|
||||
*
|
||||
@ -139,17 +185,28 @@ circuit_extend_lspec_valid_helper(const struct extend_cell_t *ec,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!ec->orport_ipv4.port || tor_addr_is_null(&ec->orport_ipv4.addr)) {
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
|
||||
"Client asked me to extend to zero destination port or addr.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tor_addr_is_internal(&ec->orport_ipv4.addr, 0) &&
|
||||
!get_options()->ExtendAllowPrivateAddresses) {
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
|
||||
"Client asked me to extend to a private address.");
|
||||
/* Check the addresses, without logging */
|
||||
const int ipv4_valid = circuit_extend_addr_port_is_valid(&ec->orport_ipv4,
|
||||
false, false, 0);
|
||||
const int ipv6_valid = circuit_extend_addr_port_is_valid(&ec->orport_ipv6,
|
||||
false, false, 0);
|
||||
/* We need at least one valid address */
|
||||
if (!ipv4_valid && !ipv6_valid) {
|
||||
/* Now, log the invalid addresses at protocol warning level */
|
||||
circuit_extend_addr_port_is_valid(&ec->orport_ipv4,
|
||||
true, true, LOG_PROTOCOL_WARN);
|
||||
circuit_extend_addr_port_is_valid(&ec->orport_ipv6,
|
||||
true, true, LOG_PROTOCOL_WARN);
|
||||
/* And fail */
|
||||
return -1;
|
||||
} else if (!ipv4_valid) {
|
||||
/* Always log unexpected internal addresses, but go on to use the other
|
||||
* valid address */
|
||||
circuit_extend_addr_port_is_valid(&ec->orport_ipv4,
|
||||
false, true, LOG_PROTOCOL_WARN);
|
||||
} else if (!ipv6_valid) {
|
||||
circuit_extend_addr_port_is_valid(&ec->orport_ipv6,
|
||||
false, true, LOG_PROTOCOL_WARN);
|
||||
}
|
||||
|
||||
IF_BUG_ONCE(circ->magic != OR_CIRCUIT_MAGIC) {
|
||||
@ -183,10 +240,64 @@ circuit_extend_lspec_valid_helper(const struct extend_cell_t *ec,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If possible, return a supported, non-NULL IP address.
|
||||
*
|
||||
* If both addresses are supported and non-NULL, choose one uniformly at
|
||||
* random.
|
||||
*
|
||||
* If we have an IPv6-only extend, but IPv6 is not supported, returns NULL.
|
||||
* If both addresses are NULL, also returns NULL. */
|
||||
STATIC const tor_addr_port_t *
|
||||
circuit_choose_ip_ap_for_extend(const tor_addr_port_t *ipv4_ap,
|
||||
const tor_addr_port_t *ipv6_ap)
|
||||
{
|
||||
const bool ipv6_supported = router_can_extend_over_ipv6(get_options());
|
||||
|
||||
/* If IPv6 is not supported, we can't use the IPv6 address. */
|
||||
if (!ipv6_supported) {
|
||||
ipv6_ap = NULL;
|
||||
}
|
||||
|
||||
/* If there is no IPv6 address, IPv4 is always supported.
|
||||
* Until clients include IPv6 ORPorts, and most relays support IPv6,
|
||||
* this is the most common case. */
|
||||
if (!ipv6_ap) {
|
||||
return ipv4_ap;
|
||||
}
|
||||
|
||||
/* If there is no IPv4 address, return the (possibly NULL) IPv6 address. */
|
||||
if (!ipv4_ap) {
|
||||
return ipv6_ap;
|
||||
}
|
||||
|
||||
/* Now we have an IPv4 and an IPv6 address, and IPv6 is supported.
|
||||
* So make an IPv6 connection at random, with probability 1 in N.
|
||||
* 1 means "always IPv6 (and no IPv4)"
|
||||
* 2 means "equal probability of IPv4 or IPv6"
|
||||
* ... (and so on) ...
|
||||
* (UINT_MAX - 1) means "almost always IPv4 (and almost never IPv6)"
|
||||
* To disable IPv6, set ipv6_supported to 0.
|
||||
*/
|
||||
#define IPV6_CONNECTION_ONE_IN_N 2
|
||||
|
||||
bool choose_ipv6 = crypto_fast_rng_one_in_n(get_thread_fast_rng(),
|
||||
IPV6_CONNECTION_ONE_IN_N);
|
||||
if (choose_ipv6) {
|
||||
return ipv6_ap;
|
||||
} else {
|
||||
return ipv4_ap;
|
||||
}
|
||||
}
|
||||
|
||||
/* When there is no open channel for an extend cell <b>ec</b>, set up the
|
||||
* circuit <b>circ</b> to wait for a new connection. If <b>should_launch</b>
|
||||
* is true, open a new connection. (Otherwise, we are already waiting for a
|
||||
* new connection to the same relay.)
|
||||
* circuit <b>circ</b> to wait for a new connection.
|
||||
*
|
||||
* If <b>should_launch</b> is true, open a new connection. (Otherwise, we are
|
||||
* already waiting for a new connection to the same relay.)
|
||||
*
|
||||
* Check if IPv6 extends are supported by our current configuration. If they
|
||||
* are, new connections may be made over IPv4 or IPv6. (IPv4 connections are
|
||||
* always supported.)
|
||||
*/
|
||||
STATIC void
|
||||
circuit_open_connection_for_extend(const struct extend_cell_t *ec,
|
||||
@ -205,13 +316,36 @@ circuit_open_connection_for_extend(const struct extend_cell_t *ec,
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check the addresses, without logging */
|
||||
const int ipv4_valid = circuit_extend_addr_port_is_valid(&ec->orport_ipv4,
|
||||
false, false, 0);
|
||||
const int ipv6_valid = circuit_extend_addr_port_is_valid(&ec->orport_ipv6,
|
||||
false, false, 0);
|
||||
|
||||
IF_BUG_ONCE(!ipv4_valid && !ipv6_valid) {
|
||||
/* circuit_extend_lspec_valid_helper() should have caught this */
|
||||
circuit_mark_for_close(circ, END_CIRC_REASON_CONNECTFAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
const tor_addr_port_t *chosen_ap = circuit_choose_ip_ap_for_extend(
|
||||
ipv4_valid ? &ec->orport_ipv4 : NULL,
|
||||
ipv6_valid ? &ec->orport_ipv6 : NULL);
|
||||
if (!chosen_ap) {
|
||||
/* An IPv6-only extend, but IPv6 is not supported */
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
|
||||
"Received IPv6-only extend, but we don't have an IPv6 ORPort.");
|
||||
circuit_mark_for_close(circ, END_CIRC_REASON_CONNECTFAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
circ->n_hop = extend_info_new(NULL /*nickname*/,
|
||||
(const char*)ec->node_id,
|
||||
&ec->ed_pubkey,
|
||||
NULL, /*onion_key*/
|
||||
NULL, /*curve25519_key*/
|
||||
&ec->orport_ipv4.addr,
|
||||
ec->orport_ipv4.port);
|
||||
&chosen_ap->addr,
|
||||
chosen_ap->port);
|
||||
|
||||
circ->n_chan_create_cell = tor_memdup(&ec->create_cell,
|
||||
sizeof(ec->create_cell));
|
||||
@ -220,10 +354,11 @@ circuit_open_connection_for_extend(const struct extend_cell_t *ec,
|
||||
|
||||
if (should_launch) {
|
||||
/* we should try to open a connection */
|
||||
channel_t *n_chan = channel_connect_for_circuit(&ec->orport_ipv4.addr,
|
||||
ec->orport_ipv4.port,
|
||||
(const char*)ec->node_id,
|
||||
&ec->ed_pubkey);
|
||||
channel_t *n_chan = channel_connect_for_circuit(
|
||||
&circ->n_hop->addr,
|
||||
circ->n_hop->port,
|
||||
circ->n_hop->identity_digest,
|
||||
&circ->n_hop->ed_identity);
|
||||
if (!n_chan) {
|
||||
log_info(LD_CIRC,"Launching n_chan failed. Closing circuit.");
|
||||
circuit_mark_for_close(circ, END_CIRC_REASON_CONNECTFAILED);
|
||||
@ -277,16 +412,31 @@ circuit_extend(struct cell_t *cell, struct circuit_t *circ)
|
||||
if (circuit_extend_lspec_valid_helper(&ec, circ) < 0)
|
||||
return -1;
|
||||
|
||||
/* Check the addresses, without logging */
|
||||
const int ipv4_valid = circuit_extend_addr_port_is_valid(&ec.orport_ipv4,
|
||||
false, false, 0);
|
||||
const int ipv6_valid = circuit_extend_addr_port_is_valid(&ec.orport_ipv6,
|
||||
false, false, 0);
|
||||
IF_BUG_ONCE(!ipv4_valid && !ipv6_valid) {
|
||||
/* circuit_extend_lspec_valid_helper() should have caught this */
|
||||
return -1;
|
||||
}
|
||||
|
||||
n_chan = channel_get_for_extend((const char*)ec.node_id,
|
||||
&ec.ed_pubkey,
|
||||
&ec.orport_ipv4.addr,
|
||||
ipv4_valid ? &ec.orport_ipv4.addr : NULL,
|
||||
ipv6_valid ? &ec.orport_ipv6.addr : NULL,
|
||||
&msg,
|
||||
&should_launch);
|
||||
|
||||
if (!n_chan) {
|
||||
log_debug(LD_CIRC|LD_OR,"Next router (%s): %s.",
|
||||
fmt_addrport(&ec.orport_ipv4.addr,ec.orport_ipv4.port),
|
||||
msg?msg:"????");
|
||||
/* We can't use fmt_addr*() twice in the same function call,
|
||||
* because it uses a static buffer. */
|
||||
log_debug(LD_CIRC|LD_OR, "Next router IPv4 (%s): %s.",
|
||||
fmt_addrport_ap(&ec.orport_ipv4),
|
||||
msg ? msg : "????");
|
||||
log_debug(LD_CIRC|LD_OR, "Next router IPv6 (%s).",
|
||||
fmt_addrport_ap(&ec.orport_ipv6));
|
||||
|
||||
circuit_open_connection_for_extend(&ec, circ, should_launch);
|
||||
|
||||
|
@ -75,6 +75,9 @@ STATIC int circuit_extend_state_valid_helper(const struct circuit_t *circ);
|
||||
STATIC int circuit_extend_add_ed25519_helper(struct extend_cell_t *ec);
|
||||
STATIC int circuit_extend_lspec_valid_helper(const struct extend_cell_t *ec,
|
||||
const struct circuit_t *circ);
|
||||
STATIC const tor_addr_port_t * circuit_choose_ip_ap_for_extend(
|
||||
const tor_addr_port_t *ipv4_ap,
|
||||
const tor_addr_port_t *ipv6_ap);
|
||||
STATIC void circuit_open_connection_for_extend(const struct extend_cell_t *ec,
|
||||
struct circuit_t *circ,
|
||||
int should_launch);
|
||||
|
@ -1469,7 +1469,7 @@ router_get_advertised_ipv6_or_ap(const or_options_t *options,
|
||||
AF_INET6);
|
||||
|
||||
if (!addr || port == 0) {
|
||||
log_info(LD_CONFIG, "There is no advertised IPv6 ORPort.");
|
||||
log_debug(LD_CONFIG, "There is no advertised IPv6 ORPort.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1490,6 +1490,24 @@ router_get_advertised_ipv6_or_ap(const or_options_t *options,
|
||||
ipv6_ap_out->port = port;
|
||||
}
|
||||
|
||||
/** Returns true if this router has an advertised IPv6 ORPort. */
|
||||
bool
|
||||
router_has_advertised_ipv6_orport(const or_options_t *options)
|
||||
{
|
||||
tor_addr_port_t ipv6_ap;
|
||||
router_get_advertised_ipv6_or_ap(options, &ipv6_ap);
|
||||
return tor_addr_port_is_valid_ap(&ipv6_ap, 0);
|
||||
}
|
||||
|
||||
/** Returns true if this router has an advertised IPv6 ORPort. */
|
||||
MOCK_IMPL(bool,
|
||||
router_can_extend_over_ipv6,(const or_options_t *options))
|
||||
{
|
||||
/* We might add some extra checks here, such as ExtendAllowIPv6Addresses
|
||||
* from ticket 33818. */
|
||||
return router_has_advertised_ipv6_orport(options);
|
||||
}
|
||||
|
||||
/** Return the port that we should advertise as our DirPort;
|
||||
* this is one of three possibilities:
|
||||
* The one that is passed as <b>dirport</b> if the DirPort option is 0, or
|
||||
|
@ -68,6 +68,8 @@ uint16_t router_get_active_listener_port_by_type_af(int listener_type,
|
||||
uint16_t router_get_advertised_or_port(const or_options_t *options);
|
||||
void router_get_advertised_ipv6_or_ap(const or_options_t *options,
|
||||
tor_addr_port_t *ipv6_ap_out);
|
||||
bool router_has_advertised_ipv6_orport(const or_options_t *options);
|
||||
MOCK_DECL(bool, router_can_extend_over_ipv6,(const or_options_t *options));
|
||||
uint16_t router_get_advertised_or_port_by_af(const or_options_t *options,
|
||||
sa_family_t family);
|
||||
uint16_t router_get_advertised_dir_port(const or_options_t *options,
|
||||
|
@ -142,6 +142,8 @@
|
||||
#define ALL_BUGS_ARE_FATAL
|
||||
#endif
|
||||
|
||||
/** Define ALL_BUGS_ARE_FATAL if you want Tor to crash when any problem comes
|
||||
* up, so you can get a coredump and track things down. */
|
||||
#ifdef ALL_BUGS_ARE_FATAL
|
||||
#define tor_assert_nonfatal_unreached() tor_assert(0)
|
||||
#define tor_assert_nonfatal(cond) tor_assert((cond))
|
||||
@ -154,6 +156,9 @@
|
||||
(tor_assertion_failed_(SHORT_FILE__,__LINE__,__func__,"!("#cond")",NULL), \
|
||||
tor_abort_(), 1) \
|
||||
: 0)
|
||||
#ifndef COCCI
|
||||
#define IF_BUG_ONCE(cond) if (BUG(cond))
|
||||
#endif
|
||||
#elif defined(TOR_UNIT_TESTS) && defined(DISABLE_ASSERTS_IN_UNIT_TESTS)
|
||||
#define tor_assert_nonfatal_unreached() STMT_NIL
|
||||
#define tor_assert_nonfatal(cond) ((void)(cond))
|
||||
@ -164,6 +169,9 @@
|
||||
#define tor_assert_nonfatal_unreached_once() STMT_NIL
|
||||
#define tor_assert_nonfatal_once(cond) ((void)(cond))
|
||||
#define BUG(cond) (ASSERT_PREDICT_UNLIKELY_(cond) ? 1 : 0)
|
||||
#ifndef COCCI
|
||||
#define IF_BUG_ONCE(cond) if (BUG(cond))
|
||||
#endif
|
||||
#else /* Normal case, !ALL_BUGS_ARE_FATAL, !DISABLE_ASSERTS_IN_UNIT_TESTS */
|
||||
#define tor_assert_nonfatal_unreached() STMT_BEGIN \
|
||||
tor_bug_occurred_(SHORT_FILE__, __LINE__, __func__, NULL, 0, NULL); \
|
||||
@ -200,7 +208,6 @@
|
||||
(ASSERT_PREDICT_UNLIKELY_(cond) ? \
|
||||
(tor_bug_occurred_(SHORT_FILE__,__LINE__,__func__,"!("#cond")",0,NULL),1) \
|
||||
: 0)
|
||||
#endif /* defined(ALL_BUGS_ARE_FATAL) || ... */
|
||||
|
||||
#ifndef COCCI
|
||||
#ifdef __GNUC__
|
||||
@ -232,7 +239,7 @@
|
||||
#define IF_BUG_ONCE_VARNAME__(a) \
|
||||
IF_BUG_ONCE_VARNAME_(a)
|
||||
|
||||
/** This macro behaves as 'if (bug(x))', except that it only logs its
|
||||
/** This macro behaves as 'if (BUG(x))', except that it only logs its
|
||||
* warning once, no matter how many times it triggers.
|
||||
*/
|
||||
|
||||
@ -240,9 +247,15 @@
|
||||
IF_BUG_ONCE__(ASSERT_PREDICT_UNLIKELY_(cond), \
|
||||
IF_BUG_ONCE_VARNAME__(__LINE__))
|
||||
|
||||
/** Define this if you want Tor to crash when any problem comes up,
|
||||
* so you can get a coredump and track things down. */
|
||||
// #define tor_fragile_assert() tor_assert_unreached(0)
|
||||
#endif /* defined(ALL_BUGS_ARE_FATAL) || ... */
|
||||
|
||||
/** In older code, we used tor_fragile_assert() to mark optional failure
|
||||
* points. At these points, we could make some debug builds fail.
|
||||
* (But release builds would continue.)
|
||||
*
|
||||
* To get the same behaviour in recent tor versions, define
|
||||
* ALL_BUGS_ARE_FATAL, and use any non-fatal assertion or *BUG() macro.
|
||||
*/
|
||||
#define tor_fragile_assert() tor_assert_nonfatal_unreached_once()
|
||||
|
||||
void tor_assertion_failed_(const char *fname, unsigned int line,
|
||||
|
@ -608,7 +608,8 @@ tor_addr_parse_mask_ports(const char *s,
|
||||
family = AF_INET;
|
||||
tor_addr_from_ipv4h(addr_out, 0);
|
||||
} else if (flags & TAPMP_STAR_IPV6_ONLY) {
|
||||
static char nil_bytes[16] = { [0]=0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 };
|
||||
static uint8_t nil_bytes[16] =
|
||||
{ [0]=0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 };
|
||||
family = AF_INET6;
|
||||
tor_addr_from_ipv6_bytes(addr_out, nil_bytes);
|
||||
} else {
|
||||
@ -629,7 +630,7 @@ tor_addr_parse_mask_ports(const char *s,
|
||||
tor_addr_from_ipv4h(addr_out, 0);
|
||||
any_flag = 1;
|
||||
} else if (!strcmp(address, "*6") && (flags & TAPMP_EXTENDED_STAR)) {
|
||||
static char nil_bytes[16] = { [0]=0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 };
|
||||
static uint8_t nil_bytes[16] = { [0]=0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 };
|
||||
family = AF_INET6;
|
||||
tor_addr_from_ipv6_bytes(addr_out, nil_bytes);
|
||||
any_flag = 1;
|
||||
@ -887,7 +888,7 @@ tor_addr_from_ipv4n(tor_addr_t *dest, uint32_t v4addr)
|
||||
/** Set <b>dest</b> to equal the IPv6 address in the 16 bytes at
|
||||
* <b>ipv6_bytes</b>. */
|
||||
void
|
||||
tor_addr_from_ipv6_bytes(tor_addr_t *dest, const char *ipv6_bytes)
|
||||
tor_addr_from_ipv6_bytes(tor_addr_t *dest, const uint8_t *ipv6_bytes)
|
||||
{
|
||||
tor_assert(dest);
|
||||
tor_assert(ipv6_bytes);
|
||||
@ -900,7 +901,21 @@ tor_addr_from_ipv6_bytes(tor_addr_t *dest, const char *ipv6_bytes)
|
||||
void
|
||||
tor_addr_from_in6(tor_addr_t *dest, const struct in6_addr *in6)
|
||||
{
|
||||
tor_addr_from_ipv6_bytes(dest, (const char*)in6->s6_addr);
|
||||
tor_addr_from_ipv6_bytes(dest, in6->s6_addr);
|
||||
}
|
||||
|
||||
/** Set the 16 bytes at <b>dest</b> to equal the IPv6 address <b>src</b>.
|
||||
* <b>src</b> must be an IPv6 address, if it is not, log a warning, and clear
|
||||
* <b>dest</b>. */
|
||||
void
|
||||
tor_addr_copy_ipv6_bytes(uint8_t *dest, const tor_addr_t *src)
|
||||
{
|
||||
tor_assert(dest);
|
||||
tor_assert(src);
|
||||
memset(dest, 0, 16);
|
||||
IF_BUG_ONCE(src->family != AF_INET6)
|
||||
return;
|
||||
memcpy(dest, src->addr.in6_addr.s6_addr, 16);
|
||||
}
|
||||
|
||||
/** Copy a tor_addr_t from <b>src</b> to <b>dest</b>.
|
||||
@ -1192,6 +1207,39 @@ fmt_addr32(uint32_t addr)
|
||||
return buf;
|
||||
}
|
||||
|
||||
/** Return a string representing the family of <b>addr</b>.
|
||||
*
|
||||
* This string is a string constant, and must not be freed.
|
||||
* This function is thread-safe.
|
||||
*/
|
||||
const char *
|
||||
fmt_addr_family(const tor_addr_t *addr)
|
||||
{
|
||||
static int default_bug_once = 0;
|
||||
|
||||
IF_BUG_ONCE(!addr)
|
||||
return "NULL pointer";
|
||||
|
||||
switch (tor_addr_family(addr)) {
|
||||
case AF_INET6:
|
||||
return "IPv6";
|
||||
case AF_INET:
|
||||
return "IPv4";
|
||||
case AF_UNIX:
|
||||
return "UNIX socket";
|
||||
case AF_UNSPEC:
|
||||
return "unspecified";
|
||||
default:
|
||||
if (!default_bug_once) {
|
||||
log_warn(LD_BUG, "Called with unknown address family %d",
|
||||
(int)tor_addr_family(addr));
|
||||
default_bug_once = 1;
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
//return "(unreachable code)";
|
||||
}
|
||||
|
||||
/** Convert the string in <b>src</b> to a tor_addr_t <b>addr</b>. The string
|
||||
* may be an IPv4 address, or an IPv6 address surrounded by square brackets.
|
||||
*
|
||||
@ -1416,10 +1464,10 @@ ifconf_free_ifc_buf(struct ifconf *ifc)
|
||||
* into smartlist of <b>tor_addr_t</b> structures.
|
||||
*/
|
||||
STATIC smartlist_t *
|
||||
ifreq_to_smartlist(char *buf, size_t buflen)
|
||||
ifreq_to_smartlist(const uint8_t *buf, size_t buflen)
|
||||
{
|
||||
smartlist_t *result = smartlist_new();
|
||||
char *end = buf + buflen;
|
||||
const uint8_t *end = buf + buflen;
|
||||
|
||||
/* These acrobatics are due to alignment issues which trigger
|
||||
* undefined behaviour traps on OSX. */
|
||||
@ -1493,7 +1541,7 @@ get_interface_addresses_ioctl(int severity, sa_family_t family)
|
||||
/* Ensure we have least IFREQ_SIZE bytes unused at the end. Otherwise, we
|
||||
* don't know if we got everything during ioctl. */
|
||||
} while (mult * IFREQ_SIZE - ifc.ifc_len <= IFREQ_SIZE);
|
||||
result = ifreq_to_smartlist(ifc.ifc_buf, ifc.ifc_len);
|
||||
result = ifreq_to_smartlist((const uint8_t *)ifc.ifc_buf, ifc.ifc_len);
|
||||
|
||||
done:
|
||||
if (fd >= 0)
|
||||
|
@ -104,6 +104,10 @@ int tor_addr_from_sockaddr(tor_addr_t *a, const struct sockaddr *sa,
|
||||
uint16_t *port_out);
|
||||
void tor_addr_make_unspec(tor_addr_t *a);
|
||||
void tor_addr_make_null(tor_addr_t *a, sa_family_t family);
|
||||
#define tor_addr_port_make_null(addr, port, family) \
|
||||
(void)(tor_addr_make_null(addr, family), (port) = 0)
|
||||
#define tor_addr_port_make_null_ap(ap, family) \
|
||||
tor_addr_port_make_null(&(ap)->addr, (ap)->port, family)
|
||||
char *tor_sockaddr_to_str(const struct sockaddr *sa);
|
||||
|
||||
/** Return an in6_addr* equivalent to <b>a</b>, or NULL if <b>a</b> is not
|
||||
@ -221,7 +225,9 @@ char *tor_addr_to_str_dup(const tor_addr_t *addr) ATTR_MALLOC;
|
||||
|
||||
const char *fmt_addr_impl(const tor_addr_t *addr, int decorate);
|
||||
const char *fmt_addrport(const tor_addr_t *addr, uint16_t port);
|
||||
const char * fmt_addr32(uint32_t addr);
|
||||
#define fmt_addrport_ap(ap) fmt_addrport(&(ap)->addr, (ap)->port)
|
||||
const char *fmt_addr32(uint32_t addr);
|
||||
const char *fmt_addr_family(const tor_addr_t *addr);
|
||||
|
||||
MOCK_DECL(int,get_interface_address6,(int severity, sa_family_t family,
|
||||
tor_addr_t *addr));
|
||||
@ -298,11 +304,12 @@ void tor_addr_from_ipv4n(tor_addr_t *dest, uint32_t v4addr);
|
||||
* order. */
|
||||
#define tor_addr_from_ipv4h(dest, v4addr) \
|
||||
tor_addr_from_ipv4n((dest), htonl(v4addr))
|
||||
void tor_addr_from_ipv6_bytes(tor_addr_t *dest, const char *bytes);
|
||||
void tor_addr_from_ipv6_bytes(tor_addr_t *dest, const uint8_t *bytes);
|
||||
/** Set <b>dest</b> to the IPv4 address incoded in <b>in</b>. */
|
||||
#define tor_addr_from_in(dest, in) \
|
||||
tor_addr_from_ipv4n((dest), (in)->s_addr);
|
||||
void tor_addr_from_in6(tor_addr_t *dest, const struct in6_addr *in6);
|
||||
void tor_addr_copy_ipv6_bytes(uint8_t *dest, const tor_addr_t *src);
|
||||
|
||||
int tor_addr_is_null(const tor_addr_t *addr);
|
||||
int tor_addr_is_loopback(const tor_addr_t *addr);
|
||||
@ -393,8 +400,8 @@ STATIC struct smartlist_t *get_interface_addresses_win32(int severity,
|
||||
#endif /* defined(HAVE_IP_ADAPTER_TO_SMARTLIST) */
|
||||
|
||||
#ifdef HAVE_IFCONF_TO_SMARTLIST
|
||||
STATIC struct smartlist_t *ifreq_to_smartlist(char *ifr,
|
||||
size_t buflen);
|
||||
STATIC struct smartlist_t *ifreq_to_smartlist(const uint8_t *ifr,
|
||||
size_t buflen);
|
||||
STATIC struct smartlist_t *get_interface_addresses_ioctl(int severity,
|
||||
sa_family_t family);
|
||||
#endif /* defined(HAVE_IFCONF_TO_SMARTLIST) */
|
||||
|
@ -460,7 +460,7 @@ test_address_ifreq_to_smartlist(void *arg)
|
||||
ifc->ifc_len = sizeof(struct ifreq);
|
||||
ifc->ifc_ifcu.ifcu_req = ifr;
|
||||
|
||||
results = ifreq_to_smartlist(ifc->ifc_buf,ifc->ifc_len);
|
||||
results = ifreq_to_smartlist((const uint8_t *)ifc->ifc_buf,ifc->ifc_len);
|
||||
tt_int_op(smartlist_len(results),OP_EQ,1);
|
||||
|
||||
tor_addr = smartlist_get(results, 0);
|
||||
@ -483,7 +483,7 @@ test_address_ifreq_to_smartlist(void *arg)
|
||||
SMARTLIST_FOREACH(results, tor_addr_t *, t, tor_free(t));
|
||||
smartlist_free(results);
|
||||
|
||||
results = ifreq_to_smartlist(ifc->ifc_buf,ifc->ifc_len);
|
||||
results = ifreq_to_smartlist((const uint8_t *)ifc->ifc_buf,ifc->ifc_len);
|
||||
tt_int_op(smartlist_len(results),OP_EQ,2);
|
||||
|
||||
tor_addr = smartlist_get(results, 0);
|
||||
|
@ -713,16 +713,20 @@ test_cfmt_extend_cells(void *arg)
|
||||
tt_mem_op(cc->onionskin,OP_EQ, b, 99+20);
|
||||
tt_int_op(0, OP_EQ, extend_cell_format(&p2_cmd, &p2_len, p2, &ec));
|
||||
tt_int_op(p2_cmd, OP_EQ, RELAY_COMMAND_EXTEND2);
|
||||
/* We'll generate it minus the IPv6 address and minus the konami code */
|
||||
tt_int_op(p2_len, OP_EQ, 89+99-34-20);
|
||||
/* We'll generate it minus the konami code */
|
||||
tt_int_op(p2_len, OP_EQ, 89+99-34);
|
||||
test_memeq_hex(p2,
|
||||
/* Two items: one that same darn IP address. */
|
||||
"02000612F40001F0F1"
|
||||
/* The next is a digest : anthropomorphization */
|
||||
"0214616e7468726f706f6d6f727068697a6174696f6e"
|
||||
/* Three items */
|
||||
"03"
|
||||
/* IPv4 address */
|
||||
"0006" "12F40001" "F0F1"
|
||||
/* The next is an RSA digest: anthropomorphization */
|
||||
"0214" "616e7468726f706f6d6f727068697a6174696f6e"
|
||||
/*IPv6 address */
|
||||
"0112" "20020000000000000000000000f0c51e" "1112"
|
||||
/* Now the handshake prologue */
|
||||
"01050063");
|
||||
tt_mem_op(p2+1+8+22+4,OP_EQ, b, 99+20);
|
||||
tt_mem_op(p2+1+8+22+20+4, OP_EQ, b, 99+20);
|
||||
tt_int_op(0, OP_EQ, create_cell_format_relayed(&cell, cc));
|
||||
|
||||
/* Now let's add an ed25519 key to that extend2 cell. */
|
||||
@ -732,22 +736,31 @@ test_cfmt_extend_cells(void *arg)
|
||||
/* As before, since we aren't extending by ed25519. */
|
||||
get_options_mutable()->ExtendByEd25519ID = 0;
|
||||
tt_int_op(0, OP_EQ, extend_cell_format(&p2_cmd, &p2_len, p2, &ec));
|
||||
tt_int_op(p2_len, OP_EQ, 89+99-34-20);
|
||||
tt_int_op(p2_len, OP_EQ, 89+99-34);
|
||||
test_memeq_hex(p2,
|
||||
"02000612F40001F0F1"
|
||||
"03"
|
||||
"000612F40001F0F1"
|
||||
"0214616e7468726f706f6d6f727068697a6174696f6e"
|
||||
"011220020000000000000000000000f0c51e1112"
|
||||
"01050063");
|
||||
|
||||
/* Now try with the ed25519 ID. */
|
||||
get_options_mutable()->ExtendByEd25519ID = 1;
|
||||
tt_int_op(0, OP_EQ, extend_cell_format(&p2_cmd, &p2_len, p2, &ec));
|
||||
tt_int_op(p2_len, OP_EQ, 89+99-34-20 + 34);
|
||||
tt_int_op(p2_len, OP_EQ, 89+99);
|
||||
test_memeq_hex(p2,
|
||||
"03000612F40001F0F1"
|
||||
/* Four items */
|
||||
"04"
|
||||
/* IPv4 address */
|
||||
"0006" "12F40001" "F0F1"
|
||||
/* The next is an RSA digest: anthropomorphization */
|
||||
"0214616e7468726f706f6d6f727068697a6174696f6e"
|
||||
// ed digest follows:
|
||||
/* Then an ed public key: brownshoesdontmakeit/brownshoesd */
|
||||
"0320" "62726f776e73686f6573646f6e746d616b656"
|
||||
"9742f62726f776e73686f657364"
|
||||
/*IPv6 address */
|
||||
"0112" "20020000000000000000000000f0c51e" "1112"
|
||||
/* Now the handshake prologue */
|
||||
"01050063");
|
||||
/* Can we parse that? Did the key come through right? */
|
||||
memset(&ec, 0, sizeof(ec));
|
||||
@ -756,6 +769,40 @@ test_cfmt_extend_cells(void *arg)
|
||||
tt_mem_op("brownshoesdontmakeit/brownshoesd", OP_EQ,
|
||||
ec.ed_pubkey.pubkey, 32);
|
||||
|
||||
/* Now try IPv6 without IPv4 */
|
||||
memset(p, 0, sizeof(p));
|
||||
memcpy(p, "\x02", 1);
|
||||
memcpy(p+1, "\x02\x14" "anthropomorphization", 22);
|
||||
memcpy(p+23, "\x01\x12" "xxxxxxxxxxxxxxxxYY", 20);
|
||||
memcpy(p+43, "\xff\xff\x00\x20", 4);
|
||||
tt_int_op(0, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
|
||||
p, sizeof(p)));
|
||||
tt_int_op(RELAY_COMMAND_EXTEND2, OP_EQ, ec.cell_type);
|
||||
tt_assert(fast_mem_is_zero((const char *)&ec.orport_ipv4.addr,
|
||||
sizeof(tor_addr_t)));
|
||||
tt_int_op(0, OP_EQ, ec.orport_ipv4.port);
|
||||
tt_str_op("7878:7878:7878:7878:7878:7878:7878:7878",
|
||||
OP_EQ, fmt_addr(&ec.orport_ipv6.addr));
|
||||
tt_int_op(22873, OP_EQ, ec.orport_ipv6.port);
|
||||
tt_assert(ed25519_public_key_is_zero(&ec.ed_pubkey));
|
||||
tt_mem_op(ec.node_id,OP_EQ, "anthropomorphization", 20);
|
||||
tt_int_op(cc->cell_type, OP_EQ, CELL_CREATE2);
|
||||
tt_int_op(cc->handshake_type, OP_EQ, 0xffff);
|
||||
tt_int_op(cc->handshake_len, OP_EQ, 32);
|
||||
tt_int_op(0, OP_EQ, extend_cell_format(&p2_cmd, &p2_len, p2, &ec));
|
||||
tt_int_op(p2_cmd, OP_EQ, RELAY_COMMAND_EXTEND2);
|
||||
tt_int_op(p2_len, OP_EQ, 47+32);
|
||||
test_memeq_hex(p2,
|
||||
/* Two items */
|
||||
"02"
|
||||
/* The next is an RSA digest: anthropomorphization */
|
||||
"0214" "616e7468726f706f6d6f727068697a6174696f6e"
|
||||
/*IPv6 address */
|
||||
"0112" "78787878787878787878787878787878" "5959"
|
||||
/* Now the handshake prologue */
|
||||
"ffff0020");
|
||||
tt_int_op(0, OP_EQ, create_cell_format_relayed(&cell, cc));
|
||||
|
||||
/* == Now try parsing some junk */
|
||||
|
||||
/* Try a too-long handshake */
|
||||
@ -809,13 +856,6 @@ test_cfmt_extend_cells(void *arg)
|
||||
memcpy(p+9, "\x02\x14" "anarchoindividualist", 22);
|
||||
memcpy(p+31, "\x01\x11" "xxxxxxxxxxxxxxxxY", 17);
|
||||
memcpy(p+48, "\xff\xff\x00\x20", 4);
|
||||
tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
|
||||
p, sizeof(p)));
|
||||
memset(p, 0, sizeof(p));
|
||||
memcpy(p, "\x02", 1);
|
||||
memcpy(p+1, "\x02\x14" "anarchoindividualist", 22);
|
||||
memcpy(p+23, "\x01\x12" "xxxxxxxxxxxxxxxxYY", 18);
|
||||
memcpy(p+41, "\xff\xff\x00\x20", 4);
|
||||
tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
|
||||
p, sizeof(p)));
|
||||
|
||||
|
@ -1326,7 +1326,7 @@ test_channel_for_extend(void *arg)
|
||||
channel_t *ret_chan = NULL;
|
||||
char digest[DIGEST_LEN];
|
||||
ed25519_public_key_t ed_id;
|
||||
tor_addr_t addr;
|
||||
tor_addr_t ipv4_addr, ipv6_addr;
|
||||
const char *msg;
|
||||
int launch;
|
||||
time_t now = time(NULL);
|
||||
@ -1336,6 +1336,9 @@ test_channel_for_extend(void *arg)
|
||||
memset(digest, 'A', sizeof(digest));
|
||||
memset(&ed_id, 'B', sizeof(ed_id));
|
||||
|
||||
tor_addr_make_null(&ipv4_addr, AF_INET);
|
||||
tor_addr_make_null(&ipv6_addr, AF_INET6);
|
||||
|
||||
chan1 = new_fake_channel();
|
||||
tt_assert(chan1);
|
||||
/* Need to be registered to get added to the id map. */
|
||||
@ -1366,7 +1369,8 @@ test_channel_for_extend(void *arg)
|
||||
tt_ptr_op(channel_find_by_remote_identity(digest, &ed_id), OP_EQ, chan1);
|
||||
|
||||
/* The expected result is chan2 because it is older than chan1. */
|
||||
ret_chan = channel_get_for_extend(digest, &ed_id, &addr, &msg, &launch);
|
||||
ret_chan = channel_get_for_extend(digest, &ed_id, &ipv4_addr, &ipv6_addr,
|
||||
&msg, &launch);
|
||||
tt_assert(ret_chan);
|
||||
tt_ptr_op(ret_chan, OP_EQ, chan2);
|
||||
tt_int_op(launch, OP_EQ, 0);
|
||||
@ -1374,7 +1378,8 @@ test_channel_for_extend(void *arg)
|
||||
|
||||
/* Switch that around from previous test. */
|
||||
chan2->timestamp_created = chan1->timestamp_created + 1;
|
||||
ret_chan = channel_get_for_extend(digest, &ed_id, &addr, &msg, &launch);
|
||||
ret_chan = channel_get_for_extend(digest, &ed_id, &ipv4_addr, &ipv6_addr,
|
||||
&msg, &launch);
|
||||
tt_assert(ret_chan);
|
||||
tt_ptr_op(ret_chan, OP_EQ, chan1);
|
||||
tt_int_op(launch, OP_EQ, 0);
|
||||
@ -1383,7 +1388,8 @@ test_channel_for_extend(void *arg)
|
||||
/* Same creation time, num circuits will be used and they both have 0 so the
|
||||
* channel 2 should be picked due to how channel_is_better() works. */
|
||||
chan2->timestamp_created = chan1->timestamp_created;
|
||||
ret_chan = channel_get_for_extend(digest, &ed_id, &addr, &msg, &launch);
|
||||
ret_chan = channel_get_for_extend(digest, &ed_id, &ipv4_addr, &ipv6_addr,
|
||||
&msg, &launch);
|
||||
tt_assert(ret_chan);
|
||||
tt_ptr_op(ret_chan, OP_EQ, chan1);
|
||||
tt_int_op(launch, OP_EQ, 0);
|
||||
@ -1394,7 +1400,8 @@ test_channel_for_extend(void *arg)
|
||||
|
||||
/* Condemned the older channel. */
|
||||
chan1->state = CHANNEL_STATE_CLOSING;
|
||||
ret_chan = channel_get_for_extend(digest, &ed_id, &addr, &msg, &launch);
|
||||
ret_chan = channel_get_for_extend(digest, &ed_id, &ipv4_addr, &ipv6_addr,
|
||||
&msg, &launch);
|
||||
tt_assert(ret_chan);
|
||||
tt_ptr_op(ret_chan, OP_EQ, chan2);
|
||||
tt_int_op(launch, OP_EQ, 0);
|
||||
@ -1403,7 +1410,8 @@ test_channel_for_extend(void *arg)
|
||||
|
||||
/* Make the older channel a client one. */
|
||||
channel_mark_client(chan1);
|
||||
ret_chan = channel_get_for_extend(digest, &ed_id, &addr, &msg, &launch);
|
||||
ret_chan = channel_get_for_extend(digest, &ed_id, &ipv4_addr, &ipv6_addr,
|
||||
&msg, &launch);
|
||||
tt_assert(ret_chan);
|
||||
tt_ptr_op(ret_chan, OP_EQ, chan2);
|
||||
tt_int_op(launch, OP_EQ, 0);
|
||||
@ -1413,8 +1421,9 @@ test_channel_for_extend(void *arg)
|
||||
/* Non matching ed identity with valid digest. */
|
||||
ed25519_public_key_t dumb_ed_id;
|
||||
memset(&dumb_ed_id, 0, sizeof(dumb_ed_id));
|
||||
ret_chan = channel_get_for_extend(digest, &dumb_ed_id, &addr, &msg,
|
||||
&launch);
|
||||
ret_chan = channel_get_for_extend(digest, &dumb_ed_id,
|
||||
&ipv4_addr, &ipv6_addr,
|
||||
&msg, &launch);
|
||||
tt_assert(!ret_chan);
|
||||
tt_str_op(msg, OP_EQ, "Not connected. Connecting.");
|
||||
tt_int_op(launch, OP_EQ, 1);
|
||||
@ -1423,7 +1432,8 @@ test_channel_for_extend(void *arg)
|
||||
test_chan_should_match_target = 1;
|
||||
chan1->state = CHANNEL_STATE_OPENING;
|
||||
chan2->state = CHANNEL_STATE_OPENING;
|
||||
ret_chan = channel_get_for_extend(digest, &ed_id, &addr, &msg, &launch);
|
||||
ret_chan = channel_get_for_extend(digest, &ed_id, &ipv4_addr, &ipv6_addr,
|
||||
&msg, &launch);
|
||||
tt_assert(!ret_chan);
|
||||
tt_str_op(msg, OP_EQ, "Connection in progress; waiting.");
|
||||
tt_int_op(launch, OP_EQ, 0);
|
||||
@ -1432,7 +1442,8 @@ test_channel_for_extend(void *arg)
|
||||
|
||||
/* Mark channel 1 as bad for circuits. */
|
||||
channel_mark_bad_for_new_circs(chan1);
|
||||
ret_chan = channel_get_for_extend(digest, &ed_id, &addr, &msg, &launch);
|
||||
ret_chan = channel_get_for_extend(digest, &ed_id, &ipv4_addr, &ipv6_addr,
|
||||
&msg, &launch);
|
||||
tt_assert(ret_chan);
|
||||
tt_ptr_op(ret_chan, OP_EQ, chan2);
|
||||
tt_int_op(launch, OP_EQ, 0);
|
||||
@ -1442,7 +1453,8 @@ test_channel_for_extend(void *arg)
|
||||
/* Mark both channels as unusable. */
|
||||
channel_mark_bad_for_new_circs(chan1);
|
||||
channel_mark_bad_for_new_circs(chan2);
|
||||
ret_chan = channel_get_for_extend(digest, &ed_id, &addr, &msg, &launch);
|
||||
ret_chan = channel_get_for_extend(digest, &ed_id, &ipv4_addr, &ipv6_addr,
|
||||
&msg, &launch);
|
||||
tt_assert(!ret_chan);
|
||||
tt_str_op(msg, OP_EQ, "Connections all too old, or too non-canonical. "
|
||||
" Launching a new one.");
|
||||
@ -1453,7 +1465,8 @@ test_channel_for_extend(void *arg)
|
||||
/* Non canonical channels. */
|
||||
test_chan_should_match_target = 0;
|
||||
test_chan_canonical_should_be_reliable = 1;
|
||||
ret_chan = channel_get_for_extend(digest, &ed_id, &addr, &msg, &launch);
|
||||
ret_chan = channel_get_for_extend(digest, &ed_id, &ipv4_addr, &ipv6_addr,
|
||||
&msg, &launch);
|
||||
tt_assert(!ret_chan);
|
||||
tt_str_op(msg, OP_EQ, "Connections all too old, or too non-canonical. "
|
||||
" Launching a new one.");
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "feature/client/entrynodes.h"
|
||||
#include "feature/nodelist/nodelist.h"
|
||||
#include "feature/relay/circuitbuild_relay.h"
|
||||
#include "feature/relay/router.h"
|
||||
#include "feature/relay/routermode.h"
|
||||
|
||||
#include "feature/nodelist/node_st.h"
|
||||
@ -219,6 +220,7 @@ test_circuit_extend_state_valid(void *arg)
|
||||
expect_log_msg("Got an extend cell, but running as a client. Closing.\n");
|
||||
mock_clean_saved_logs();
|
||||
|
||||
#ifndef ALL_BUGS_ARE_FATAL
|
||||
/* Circuit must be non-NULL */
|
||||
tor_capture_bugs_(1);
|
||||
server = 1;
|
||||
@ -228,6 +230,7 @@ test_circuit_extend_state_valid(void *arg)
|
||||
"!(ASSERT_PREDICT_UNLIKELY_(!circ))");
|
||||
tor_end_capture_bugs_();
|
||||
mock_clean_saved_logs();
|
||||
#endif /* !defined(ALL_BUGS_ARE_FATAL) */
|
||||
|
||||
/* n_chan and n_hop are NULL, this should succeed */
|
||||
server = 1;
|
||||
@ -314,6 +317,7 @@ test_circuit_extend_add_ed25519(void *arg)
|
||||
|
||||
setup_full_capture_of_logs(LOG_INFO);
|
||||
|
||||
#ifndef ALL_BUGS_ARE_FATAL
|
||||
/* The extend cell must be non-NULL */
|
||||
tor_capture_bugs_(1);
|
||||
tt_int_op(circuit_extend_add_ed25519_helper(NULL), OP_EQ, -1);
|
||||
@ -322,6 +326,7 @@ test_circuit_extend_add_ed25519(void *arg)
|
||||
"!(ASSERT_PREDICT_UNLIKELY_(!ec))");
|
||||
tor_end_capture_bugs_();
|
||||
mock_clean_saved_logs();
|
||||
#endif /* !defined(ALL_BUGS_ARE_FATAL) */
|
||||
|
||||
/* The node id must be non-zero */
|
||||
memcpy(old_ec, ec, sizeof(extend_cell_t));
|
||||
@ -474,6 +479,9 @@ mock_get_options(void)
|
||||
#define PUBLIC_IPV4 "1.2.3.4"
|
||||
#define INTERNAL_IPV4 "0.0.0.1"
|
||||
|
||||
#define PUBLIC_IPV6 "1234::cdef"
|
||||
#define INTERNAL_IPV6 "::1"
|
||||
|
||||
#define VALID_PORT 0x1234
|
||||
|
||||
/* Test the different cases in circuit_extend_lspec_valid_helper(). */
|
||||
@ -492,6 +500,7 @@ test_circuit_extend_lspec_valid(void *arg)
|
||||
|
||||
setup_full_capture_of_logs(LOG_INFO);
|
||||
|
||||
#ifndef ALL_BUGS_ARE_FATAL
|
||||
/* Extend cell must be non-NULL */
|
||||
tor_capture_bugs_(1);
|
||||
tt_int_op(circuit_extend_lspec_valid_helper(NULL, circ), OP_EQ, -1);
|
||||
@ -518,41 +527,114 @@ test_circuit_extend_lspec_valid(void *arg)
|
||||
tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_LE, 2);
|
||||
tor_end_capture_bugs_();
|
||||
mock_clean_saved_logs();
|
||||
#endif /* !defined(ALL_BUGS_ARE_FATAL) */
|
||||
|
||||
/* IPv4 addr or port are 0, these should fail */
|
||||
/* IPv4 and IPv6 addr and port are all zero, this should fail */
|
||||
tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
|
||||
expect_log_msg("Client asked me to extend to "
|
||||
"zero destination port or addr.\n");
|
||||
expect_log_msg("Client asked me to extend to a zero destination port "
|
||||
"or unspecified address '[scrubbed]'.\n");
|
||||
mock_clean_saved_logs();
|
||||
|
||||
/* Now ask for the actual address in the logs */
|
||||
fake_options->SafeLogging_ = SAFELOG_SCRUB_NONE;
|
||||
|
||||
/* IPv4 port is 0, IPv6 addr and port are both zero, this should fail */
|
||||
tor_addr_parse(&ec->orport_ipv4.addr, PUBLIC_IPV4);
|
||||
tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
|
||||
expect_log_msg("Client asked me to extend to "
|
||||
"zero destination port or addr.\n");
|
||||
expect_log_msg("Client asked me to extend to a zero destination port "
|
||||
"or IPv4 address '1.2.3.4:0'.\n");
|
||||
mock_clean_saved_logs();
|
||||
tor_addr_make_null(&ec->orport_ipv4.addr, AF_INET);
|
||||
tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
|
||||
tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
|
||||
|
||||
/* IPv4 addr is 0, IPv6 addr and port are both zero, this should fail */
|
||||
ec->orport_ipv4.port = VALID_PORT;
|
||||
tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
|
||||
expect_log_msg("Client asked me to extend to "
|
||||
"zero destination port or addr.\n");
|
||||
expect_log_msg("Client asked me to extend to a zero destination port "
|
||||
"or IPv4 address '0.0.0.0:4660'.\n");
|
||||
mock_clean_saved_logs();
|
||||
ec->orport_ipv4.port = 0;
|
||||
tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
|
||||
tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
|
||||
|
||||
/* IPv4 addr is internal, and port is valid.
|
||||
* (IPv6 addr and port are both zero.)
|
||||
* Result depends on ExtendAllowPrivateAddresses. */
|
||||
tor_addr_parse(&ec->orport_ipv4.addr, INTERNAL_IPV4);
|
||||
ec->orport_ipv4.port = VALID_PORT;
|
||||
|
||||
fake_options->ExtendAllowPrivateAddresses = 0;
|
||||
tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
|
||||
expect_log_msg("Client asked me to extend to a private address.\n");
|
||||
expect_log_msg("Client asked me to extend "
|
||||
"to a private IPv4 address '0.0.0.1'.\n");
|
||||
mock_clean_saved_logs();
|
||||
fake_options->ExtendAllowPrivateAddresses = 0;
|
||||
tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
|
||||
tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
|
||||
|
||||
/* Now do the same tests, but for IPv6 */
|
||||
|
||||
/* IPv6 port is 0, IPv4 addr and port are both zero, this should fail */
|
||||
tor_addr_parse(&ec->orport_ipv6.addr, PUBLIC_IPV6);
|
||||
tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
|
||||
expect_log_msg("Client asked me to extend to a zero destination port "
|
||||
"or IPv6 address '[1234::cdef]:0'.\n");
|
||||
mock_clean_saved_logs();
|
||||
tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
|
||||
tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
|
||||
|
||||
/* IPv6 addr is 0, IPv4 addr and port are both zero, this should fail */
|
||||
ec->orport_ipv6.port = VALID_PORT;
|
||||
tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
|
||||
expect_log_msg("Client asked me to extend to a zero destination port "
|
||||
"or IPv6 address '[::]:4660'.\n");
|
||||
mock_clean_saved_logs();
|
||||
ec->orport_ipv4.port = 0;
|
||||
tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
|
||||
tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
|
||||
|
||||
/* IPv6 addr is internal, and port is valid.
|
||||
* (IPv4 addr and port are both zero.)
|
||||
* Result depends on ExtendAllowPrivateAddresses. */
|
||||
tor_addr_parse(&ec->orport_ipv6.addr, INTERNAL_IPV6);
|
||||
ec->orport_ipv6.port = VALID_PORT;
|
||||
|
||||
fake_options->ExtendAllowPrivateAddresses = 0;
|
||||
tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
|
||||
expect_log_msg("Client asked me to extend "
|
||||
"to a private IPv6 address '[::1]'.\n");
|
||||
mock_clean_saved_logs();
|
||||
fake_options->ExtendAllowPrivateAddresses = 0;
|
||||
tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
|
||||
tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
|
||||
|
||||
/* Both addresses are internal.
|
||||
* Result depends on ExtendAllowPrivateAddresses. */
|
||||
tor_addr_parse(&ec->orport_ipv4.addr, INTERNAL_IPV4);
|
||||
ec->orport_ipv4.port = VALID_PORT;
|
||||
tor_addr_parse(&ec->orport_ipv6.addr, INTERNAL_IPV6);
|
||||
ec->orport_ipv6.port = VALID_PORT;
|
||||
|
||||
fake_options->ExtendAllowPrivateAddresses = 0;
|
||||
tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
|
||||
expect_log_msg("Client asked me to extend "
|
||||
"to a private IPv4 address '0.0.0.1'.\n");
|
||||
expect_log_msg("Client asked me to extend "
|
||||
"to a private IPv6 address '[::1]'.\n");
|
||||
mock_clean_saved_logs();
|
||||
fake_options->ExtendAllowPrivateAddresses = 0;
|
||||
tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
|
||||
tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
|
||||
|
||||
#ifndef ALL_BUGS_ARE_FATAL
|
||||
/* If we pass the private address check, but don't have the right
|
||||
* OR circuit magic number, we trigger another bug */
|
||||
tor_addr_parse(&ec->orport_ipv4.addr, INTERNAL_IPV4);
|
||||
ec->orport_ipv4.port = VALID_PORT;
|
||||
tor_addr_parse(&ec->orport_ipv6.addr, INTERNAL_IPV6);
|
||||
ec->orport_ipv6.port = VALID_PORT;
|
||||
fake_options->ExtendAllowPrivateAddresses = 1;
|
||||
|
||||
tor_capture_bugs_(1);
|
||||
tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
|
||||
tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
|
||||
@ -561,10 +643,27 @@ test_circuit_extend_lspec_valid(void *arg)
|
||||
tor_end_capture_bugs_();
|
||||
mock_clean_saved_logs();
|
||||
fake_options->ExtendAllowPrivateAddresses = 0;
|
||||
tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
|
||||
tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
|
||||
|
||||
/* Fail again, but this time only set an IPv4 address. */
|
||||
tor_addr_parse(&ec->orport_ipv4.addr, INTERNAL_IPV4);
|
||||
ec->orport_ipv4.port = VALID_PORT;
|
||||
fake_options->ExtendAllowPrivateAddresses = 1;
|
||||
tor_capture_bugs_(1);
|
||||
tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
|
||||
/* Since we're using IF_BUG_ONCE(), expect 0-1 bug logs */
|
||||
tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_GE, 0);
|
||||
tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_LE, 1);
|
||||
tor_end_capture_bugs_();
|
||||
mock_clean_saved_logs();
|
||||
fake_options->ExtendAllowPrivateAddresses = 0;
|
||||
#endif /* !defined(ALL_BUGS_ARE_FATAL) */
|
||||
|
||||
/* Now set the right magic */
|
||||
or_circ->base_.magic = OR_CIRCUIT_MAGIC;
|
||||
|
||||
#ifndef ALL_BUGS_ARE_FATAL
|
||||
/* If we pass the OR circuit magic check, but don't have p_chan,
|
||||
* we trigger another bug */
|
||||
fake_options->ExtendAllowPrivateAddresses = 1;
|
||||
@ -591,6 +690,7 @@ test_circuit_extend_lspec_valid(void *arg)
|
||||
|
||||
tor_addr_make_null(&ec->orport_ipv4.addr, AF_INET);
|
||||
ec->orport_ipv4.port = 0x0000;
|
||||
#endif /* !defined(ALL_BUGS_ARE_FATAL) */
|
||||
|
||||
/* Now let's fake a p_chan and the addresses */
|
||||
tor_addr_parse(&ec->orport_ipv4.addr, PUBLIC_IPV4);
|
||||
@ -622,6 +722,41 @@ test_circuit_extend_lspec_valid(void *arg)
|
||||
tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, 0);
|
||||
mock_clean_saved_logs();
|
||||
|
||||
/* Now let's check that we warn, but succeed, when only one address is
|
||||
* private */
|
||||
tor_addr_parse(&ec->orport_ipv4.addr, INTERNAL_IPV4);
|
||||
ec->orport_ipv4.port = VALID_PORT;
|
||||
tor_addr_parse(&ec->orport_ipv6.addr, PUBLIC_IPV6);
|
||||
ec->orport_ipv6.port = VALID_PORT;
|
||||
fake_options->ExtendAllowPrivateAddresses = 0;
|
||||
|
||||
tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, 0);
|
||||
expect_log_msg("Client asked me to extend "
|
||||
"to a private IPv4 address '0.0.0.1'.\n");
|
||||
mock_clean_saved_logs();
|
||||
tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
|
||||
tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
|
||||
|
||||
/* Now with private IPv6 */
|
||||
tor_addr_parse(&ec->orport_ipv4.addr, PUBLIC_IPV4);
|
||||
ec->orport_ipv4.port = VALID_PORT;
|
||||
tor_addr_parse(&ec->orport_ipv6.addr, INTERNAL_IPV6);
|
||||
ec->orport_ipv6.port = VALID_PORT;
|
||||
fake_options->ExtendAllowPrivateAddresses = 0;
|
||||
|
||||
tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, 0);
|
||||
expect_log_msg("Client asked me to extend "
|
||||
"to a private IPv6 address '[::1]'.\n");
|
||||
mock_clean_saved_logs();
|
||||
tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
|
||||
tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
|
||||
|
||||
/* Now reset to public IPv4 and IPv6 */
|
||||
tor_addr_parse(&ec->orport_ipv4.addr, PUBLIC_IPV4);
|
||||
ec->orport_ipv4.port = VALID_PORT;
|
||||
tor_addr_parse(&ec->orport_ipv6.addr, PUBLIC_IPV6);
|
||||
ec->orport_ipv6.port = VALID_PORT;
|
||||
|
||||
/* Fail on matching non-zero identities */
|
||||
memset(&ec->ed_pubkey, 0xEE, sizeof(ec->ed_pubkey));
|
||||
memset(&p_chan->ed25519_identity, 0xEE, sizeof(p_chan->ed25519_identity));
|
||||
@ -686,6 +821,97 @@ test_circuit_extend_lspec_valid(void *arg)
|
||||
tor_free(p_chan);
|
||||
}
|
||||
|
||||
static bool can_extend_over_ipv6_result = false;
|
||||
static int mock_router_can_extend_over_ipv6_calls = 0;
|
||||
static bool
|
||||
mock_router_can_extend_over_ipv6(const or_options_t *options)
|
||||
{
|
||||
(void)options;
|
||||
mock_router_can_extend_over_ipv6_calls++;
|
||||
return can_extend_over_ipv6_result;
|
||||
}
|
||||
|
||||
/* Test the different cases in circuit_choose_ip_ap_for_extend(). */
|
||||
static void
|
||||
test_circuit_choose_ip_ap_for_extend(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
tor_addr_port_t ipv4_ap;
|
||||
tor_addr_port_t ipv6_ap;
|
||||
|
||||
/* Set up valid addresses */
|
||||
tor_addr_parse(&ipv4_ap.addr, PUBLIC_IPV4);
|
||||
ipv4_ap.port = VALID_PORT;
|
||||
tor_addr_parse(&ipv6_ap.addr, PUBLIC_IPV6);
|
||||
ipv6_ap.port = VALID_PORT;
|
||||
|
||||
or_options_t *fake_options = options_new();
|
||||
MOCK(get_options, mock_get_options);
|
||||
mocked_options = fake_options;
|
||||
|
||||
MOCK(router_can_extend_over_ipv6,
|
||||
mock_router_can_extend_over_ipv6);
|
||||
can_extend_over_ipv6_result = true;
|
||||
mock_router_can_extend_over_ipv6_calls = 0;
|
||||
|
||||
/* No valid addresses */
|
||||
can_extend_over_ipv6_result = true;
|
||||
mock_router_can_extend_over_ipv6_calls = 0;
|
||||
tt_ptr_op(circuit_choose_ip_ap_for_extend(NULL, NULL), OP_EQ, NULL);
|
||||
tt_int_op(mock_router_can_extend_over_ipv6_calls, OP_EQ, 1);
|
||||
|
||||
can_extend_over_ipv6_result = false;
|
||||
mock_router_can_extend_over_ipv6_calls = 0;
|
||||
tt_ptr_op(circuit_choose_ip_ap_for_extend(NULL, NULL), OP_EQ, NULL);
|
||||
tt_int_op(mock_router_can_extend_over_ipv6_calls, OP_EQ, 1);
|
||||
|
||||
/* One valid address: IPv4 */
|
||||
can_extend_over_ipv6_result = true;
|
||||
mock_router_can_extend_over_ipv6_calls = 0;
|
||||
tt_ptr_op(circuit_choose_ip_ap_for_extend(&ipv4_ap, NULL), OP_EQ, &ipv4_ap);
|
||||
tt_int_op(mock_router_can_extend_over_ipv6_calls, OP_EQ, 1);
|
||||
|
||||
can_extend_over_ipv6_result = false;
|
||||
mock_router_can_extend_over_ipv6_calls = 0;
|
||||
tt_ptr_op(circuit_choose_ip_ap_for_extend(&ipv4_ap, NULL), OP_EQ, &ipv4_ap);
|
||||
tt_int_op(mock_router_can_extend_over_ipv6_calls, OP_EQ, 1);
|
||||
|
||||
/* One valid address: IPv6 */
|
||||
can_extend_over_ipv6_result = true;
|
||||
mock_router_can_extend_over_ipv6_calls = 0;
|
||||
tt_ptr_op(circuit_choose_ip_ap_for_extend(NULL, &ipv6_ap), OP_EQ, &ipv6_ap);
|
||||
tt_int_op(mock_router_can_extend_over_ipv6_calls, OP_EQ, 1);
|
||||
|
||||
can_extend_over_ipv6_result = false;
|
||||
mock_router_can_extend_over_ipv6_calls = 0;
|
||||
tt_ptr_op(circuit_choose_ip_ap_for_extend(NULL, &ipv6_ap), OP_EQ, NULL);
|
||||
tt_int_op(mock_router_can_extend_over_ipv6_calls, OP_EQ, 1);
|
||||
|
||||
/* Two valid addresses */
|
||||
const tor_addr_port_t *chosen_addr = NULL;
|
||||
|
||||
can_extend_over_ipv6_result = true;
|
||||
mock_router_can_extend_over_ipv6_calls = 0;
|
||||
chosen_addr = circuit_choose_ip_ap_for_extend(&ipv4_ap, &ipv6_ap);
|
||||
tt_assert(chosen_addr == &ipv4_ap || chosen_addr == &ipv6_ap);
|
||||
tt_int_op(mock_router_can_extend_over_ipv6_calls, OP_EQ, 1);
|
||||
|
||||
can_extend_over_ipv6_result = false;
|
||||
mock_router_can_extend_over_ipv6_calls = 0;
|
||||
tt_ptr_op(circuit_choose_ip_ap_for_extend(&ipv4_ap, &ipv6_ap),
|
||||
OP_EQ, &ipv4_ap);
|
||||
tt_int_op(mock_router_can_extend_over_ipv6_calls, OP_EQ, 1);
|
||||
|
||||
done:
|
||||
UNMOCK(get_options);
|
||||
or_options_free(fake_options);
|
||||
mocked_options = NULL;
|
||||
|
||||
UNMOCK(router_can_extend_over_ipv6);
|
||||
|
||||
tor_free(fake_options);
|
||||
}
|
||||
|
||||
static int mock_circuit_close_calls = 0;
|
||||
static void
|
||||
mock_circuit_mark_for_close_(circuit_t *circ, int reason,
|
||||
@ -714,23 +940,41 @@ mock_channel_connect_for_circuit(const tor_addr_t *addr,
|
||||
return mock_channel_connect_nchan;
|
||||
}
|
||||
|
||||
/* Test the different cases in circuit_open_connection_for_extend(). */
|
||||
/* Test the different cases in circuit_open_connection_for_extend().
|
||||
* Chooses different IP addresses depending on the first character in arg:
|
||||
* - 4: IPv4
|
||||
* - 6: IPv6
|
||||
* - d: IPv4 and IPv6 (dual-stack)
|
||||
*/
|
||||
static void
|
||||
test_circuit_open_connection_for_extend(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
const char ip_version = ((const char *)arg)[0];
|
||||
const bool use_ipv4 = (ip_version == '4' || ip_version == 'd');
|
||||
const bool use_ipv6 = (ip_version == '6' || ip_version == 'd');
|
||||
tor_assert(use_ipv4 || use_ipv6);
|
||||
|
||||
extend_cell_t *ec = tor_malloc_zero(sizeof(extend_cell_t));
|
||||
circuit_t *circ = tor_malloc_zero(sizeof(circuit_t));
|
||||
channel_t *fake_n_chan = tor_malloc_zero(sizeof(channel_t));
|
||||
|
||||
or_options_t *fake_options = options_new();
|
||||
MOCK(get_options, mock_get_options);
|
||||
mocked_options = fake_options;
|
||||
|
||||
MOCK(circuit_mark_for_close_, mock_circuit_mark_for_close_);
|
||||
mock_circuit_close_calls = 0;
|
||||
MOCK(channel_connect_for_circuit, mock_channel_connect_for_circuit);
|
||||
mock_channel_connect_calls = 0;
|
||||
mock_channel_connect_nchan = NULL;
|
||||
|
||||
MOCK(router_can_extend_over_ipv6,
|
||||
mock_router_can_extend_over_ipv6);
|
||||
can_extend_over_ipv6_result = true;
|
||||
|
||||
setup_full_capture_of_logs(LOG_INFO);
|
||||
|
||||
#ifndef ALL_BUGS_ARE_FATAL
|
||||
/* Circuit must be non-NULL */
|
||||
mock_circuit_close_calls = 0;
|
||||
mock_channel_connect_calls = 0;
|
||||
@ -772,6 +1016,33 @@ test_circuit_open_connection_for_extend(void *arg)
|
||||
tor_end_capture_bugs_();
|
||||
mock_clean_saved_logs();
|
||||
|
||||
/* Fail, because neither address is valid */
|
||||
mock_circuit_close_calls = 0;
|
||||
mock_channel_connect_calls = 0;
|
||||
tor_capture_bugs_(1);
|
||||
circuit_open_connection_for_extend(ec, circ, 0);
|
||||
/* Close the circuit, don't connect */
|
||||
tt_int_op(mock_circuit_close_calls, OP_EQ, 1);
|
||||
tt_int_op(mock_channel_connect_calls, OP_EQ, 0);
|
||||
/* Check state */
|
||||
tt_ptr_op(circ->n_hop, OP_EQ, NULL);
|
||||
tt_ptr_op(circ->n_chan_create_cell, OP_EQ, NULL);
|
||||
tt_int_op(circ->state, OP_EQ, 0);
|
||||
/* Cleanup */
|
||||
tor_end_capture_bugs_();
|
||||
mock_clean_saved_logs();
|
||||
#endif /* !defined(ALL_BUGS_ARE_FATAL) */
|
||||
|
||||
/* Set up valid addresses */
|
||||
if (use_ipv4) {
|
||||
tor_addr_parse(&ec->orport_ipv4.addr, PUBLIC_IPV4);
|
||||
ec->orport_ipv4.port = VALID_PORT;
|
||||
}
|
||||
if (use_ipv6) {
|
||||
tor_addr_parse(&ec->orport_ipv6.addr, PUBLIC_IPV6);
|
||||
ec->orport_ipv6.port = VALID_PORT;
|
||||
}
|
||||
|
||||
/* Succeed, but don't try to open a connection */
|
||||
mock_circuit_close_calls = 0;
|
||||
mock_channel_connect_calls = 0;
|
||||
@ -812,7 +1083,7 @@ test_circuit_open_connection_for_extend(void *arg)
|
||||
mock_circuit_close_calls = 0;
|
||||
mock_channel_connect_calls = 0;
|
||||
circuit_open_connection_for_extend(ec, circ, 1);
|
||||
/* Try to connect, and succeed, leaving the circuit open */
|
||||
/* Connection attempt succeeded, leaving the circuit open */
|
||||
tt_int_op(mock_circuit_close_calls, OP_EQ, 0);
|
||||
tt_int_op(mock_channel_connect_calls, OP_EQ, 1);
|
||||
/* Check state */
|
||||
@ -835,6 +1106,12 @@ test_circuit_open_connection_for_extend(void *arg)
|
||||
UNMOCK(channel_connect_for_circuit);
|
||||
mock_channel_connect_calls = 0;
|
||||
|
||||
UNMOCK(get_options);
|
||||
or_options_free(fake_options);
|
||||
mocked_options = NULL;
|
||||
|
||||
UNMOCK(router_can_extend_over_ipv6);
|
||||
|
||||
tor_free(ec);
|
||||
tor_free(circ->n_hop);
|
||||
tor_free(circ->n_chan_create_cell);
|
||||
@ -869,13 +1146,15 @@ static channel_t *mock_channel_get_for_extend_nchan = NULL;
|
||||
static channel_t *
|
||||
mock_channel_get_for_extend(const char *rsa_id_digest,
|
||||
const ed25519_public_key_t *ed_id,
|
||||
const tor_addr_t *target_addr,
|
||||
const tor_addr_t *target_ipv4_addr,
|
||||
const tor_addr_t *target_ipv6_addr,
|
||||
const char **msg_out,
|
||||
int *launch_out)
|
||||
{
|
||||
(void)rsa_id_digest;
|
||||
(void)ed_id;
|
||||
(void)target_addr;
|
||||
(void)target_ipv4_addr;
|
||||
(void)target_ipv6_addr;
|
||||
|
||||
/* channel_get_for_extend() requires non-NULL arguments */
|
||||
tt_ptr_op(msg_out, OP_NE, NULL);
|
||||
@ -941,6 +1220,7 @@ test_circuit_extend(void *arg)
|
||||
|
||||
setup_full_capture_of_logs(LOG_INFO);
|
||||
|
||||
#ifndef ALL_BUGS_ARE_FATAL
|
||||
/* Circuit must be non-NULL */
|
||||
tor_capture_bugs_(1);
|
||||
tt_int_op(circuit_extend(cell, NULL), OP_EQ, -1);
|
||||
@ -967,6 +1247,7 @@ test_circuit_extend(void *arg)
|
||||
tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_LE, 2);
|
||||
tor_end_capture_bugs_();
|
||||
mock_clean_saved_logs();
|
||||
#endif /* !defined(ALL_BUGS_ARE_FATAL) */
|
||||
|
||||
/* Clients can't extend */
|
||||
server = 0;
|
||||
@ -1002,8 +1283,8 @@ test_circuit_extend(void *arg)
|
||||
|
||||
tt_int_op(circuit_extend(cell, circ), OP_EQ, -1);
|
||||
tt_int_op(mock_extend_cell_parse_calls, OP_EQ, 1);
|
||||
expect_log_msg("Client asked me to extend to "
|
||||
"zero destination port or addr.\n");
|
||||
expect_log_msg("Client asked me to extend to a zero destination port "
|
||||
"or unspecified address '[scrubbed]'.\n");
|
||||
mock_clean_saved_logs();
|
||||
mock_extend_cell_parse_calls = 0;
|
||||
|
||||
@ -1012,6 +1293,7 @@ test_circuit_extend(void *arg)
|
||||
PUBLIC_IPV4);
|
||||
mock_extend_cell_parse_cell_out.orport_ipv4.port = VALID_PORT;
|
||||
|
||||
#ifndef ALL_BUGS_ARE_FATAL
|
||||
tor_capture_bugs_(1);
|
||||
tt_int_op(circuit_extend(cell, circ), OP_EQ, -1);
|
||||
tt_int_op(mock_extend_cell_parse_calls, OP_EQ, 1);
|
||||
@ -1021,6 +1303,7 @@ test_circuit_extend(void *arg)
|
||||
tor_end_capture_bugs_();
|
||||
mock_clean_saved_logs();
|
||||
mock_extend_cell_parse_calls = 0;
|
||||
#endif /* !defined(ALL_BUGS_ARE_FATAL) */
|
||||
|
||||
/* Now add the right magic and a p_chan. */
|
||||
or_circ->base_.magic = OR_CIRCUIT_MAGIC;
|
||||
@ -1166,6 +1449,7 @@ test_onionskin_answer(void *arg)
|
||||
|
||||
setup_full_capture_of_logs(LOG_INFO);
|
||||
|
||||
#ifndef ALL_BUGS_ARE_FATAL
|
||||
/* Circuit must be non-NULL */
|
||||
tor_capture_bugs_(1);
|
||||
tt_int_op(onionskin_answer(NULL, created_cell,
|
||||
@ -1209,6 +1493,7 @@ test_onionskin_answer(void *arg)
|
||||
"!(ASSERT_PREDICT_UNLIKELY_(!rend_circ_nonce))");
|
||||
tor_end_capture_bugs_();
|
||||
mock_clean_saved_logs();
|
||||
#endif /* !defined(ALL_BUGS_ARE_FATAL) */
|
||||
|
||||
/* Also, the keys length must be CPATH_KEY_MATERIAL_LEN, but we can't catch
|
||||
* asserts in unit tests. */
|
||||
@ -1240,6 +1525,12 @@ test_onionskin_answer(void *arg)
|
||||
#define TEST_CIRCUIT(name, flags) \
|
||||
{ #name, test_circuit_ ## name, flags, NULL, NULL }
|
||||
|
||||
#ifndef COCCI
|
||||
#define TEST_CIRCUIT_PASSTHROUGH(name, flags, arg) \
|
||||
{ #name "/" arg, test_circuit_ ## name, flags, \
|
||||
&passthrough_setup, (void *)(arg) }
|
||||
#endif
|
||||
|
||||
struct testcase_t circuitbuild_tests[] = {
|
||||
TEST_NEW_ROUTE_LEN(noexit, 0),
|
||||
TEST_NEW_ROUTE_LEN(safe_exit, 0),
|
||||
@ -1251,7 +1542,10 @@ struct testcase_t circuitbuild_tests[] = {
|
||||
TEST_CIRCUIT(extend_state_valid, TT_FORK),
|
||||
TEST_CIRCUIT(extend_add_ed25519, TT_FORK),
|
||||
TEST_CIRCUIT(extend_lspec_valid, TT_FORK),
|
||||
TEST_CIRCUIT(open_connection_for_extend, TT_FORK),
|
||||
TEST_CIRCUIT(choose_ip_ap_for_extend, 0),
|
||||
TEST_CIRCUIT_PASSTHROUGH(open_connection_for_extend, TT_FORK, "4"),
|
||||
TEST_CIRCUIT_PASSTHROUGH(open_connection_for_extend, TT_FORK, "6"),
|
||||
TEST_CIRCUIT_PASSTHROUGH(open_connection_for_extend, TT_FORK, "dual-stack"),
|
||||
TEST_CIRCUIT(extend, TT_FORK),
|
||||
|
||||
TEST(onionskin_answer, TT_FORK, NULL, NULL),
|
||||
|
@ -509,7 +509,7 @@ do_resolve(const char *hostname,
|
||||
} else if (atype == SOCKS5_ATYPE_IPV6) {
|
||||
/* IPv6 address */
|
||||
tor_addr_from_ipv6_bytes(result_addr,
|
||||
(const char *)socks5_server_reply_getarray_bind_addr_ipv6(reply));
|
||||
socks5_server_reply_getarray_bind_addr_ipv6(reply));
|
||||
} else if (atype == SOCKS5_ATYPE_HOSTNAME) {
|
||||
/* Domain name */
|
||||
domainname_t *dn =
|
||||
|
Loading…
Reference in New Issue
Block a user