mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
Merge branch 'ticket33236_045_01'
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
o Minor feature (relay, address discovery):
|
||||
- If Address is not found in torrc, attempt to learn our address with the
|
||||
configured ORPort address if any. Closes ticket 33236.
|
||||
|
||||
@@ -370,6 +370,63 @@ get_address_from_interface(const or_options_t *options, int warn_severity,
|
||||
return FN_RET_OK;
|
||||
}
|
||||
|
||||
/** @brief Get IP address from the ORPort (if any).
|
||||
*
|
||||
* @param options Global configuration options.
|
||||
* @param warn_severity Log level that should be used on error.
|
||||
* @param family IP address family. Only AF_INET and AF_INET6 are supported.
|
||||
* @param method_out OUT: Always "CONFIGURED_ORPORT" on success which is
|
||||
* detailed in the control-spec.txt as actions
|
||||
* for "STATUS_SERVER".
|
||||
* @param hostname_out OUT: String containing the ORPort hostname if any.
|
||||
* @param addr_out OUT: Tor address found if any.
|
||||
*
|
||||
* @return Return 0 on success that is an address has been found. Return
|
||||
* error code ERR_* found at the top of the file.
|
||||
*/
|
||||
static fn_address_ret_t
|
||||
get_address_from_orport(const or_options_t *options, int warn_severity,
|
||||
int family, const char **method_out,
|
||||
char **hostname_out, tor_addr_t *addr_out)
|
||||
{
|
||||
int ret;
|
||||
const tor_addr_t *addr;
|
||||
|
||||
tor_assert(method_out);
|
||||
tor_assert(hostname_out);
|
||||
tor_assert(addr_out);
|
||||
|
||||
log_debug(LD_CONFIG, "Attempting to get address from ORPort");
|
||||
|
||||
if (!options->ORPort_set) {
|
||||
log_info(LD_CONFIG, "No ORPort found in configuration.");
|
||||
/* No ORPort statement, inform caller to try next method. */
|
||||
return FN_RET_NEXT;
|
||||
}
|
||||
|
||||
/* Get ORPort for requested family. */
|
||||
addr = get_orport_addr(family);
|
||||
if (!addr) {
|
||||
/* No address configured for the ORPort. Ignore. */
|
||||
return FN_RET_NEXT;
|
||||
}
|
||||
|
||||
/* We found the ORPort address. Just make sure it can be used. */
|
||||
ret = address_can_be_used(addr, options, warn_severity, true);
|
||||
if (ret < 0) {
|
||||
/* Unable to use address. Inform caller to try next method. */
|
||||
return FN_RET_NEXT;
|
||||
}
|
||||
|
||||
/* Found it! */
|
||||
*method_out = "CONFIGURED_ORPORT";
|
||||
tor_addr_copy(addr_out, addr);
|
||||
|
||||
log_fn(warn_severity, LD_CONFIG, "Address found from ORPort: %s",
|
||||
fmt_addr(addr_out));
|
||||
return FN_RET_OK;
|
||||
}
|
||||
|
||||
/** @brief Update the last resolved address cache using the given address.
|
||||
*
|
||||
* A log notice is emitted if the given address has changed from before. Not
|
||||
@@ -450,6 +507,7 @@ static fn_address_ret_t
|
||||
{
|
||||
/* These functions are in order for our find address algorithm. */
|
||||
get_address_from_config,
|
||||
get_address_from_orport,
|
||||
get_address_from_interface,
|
||||
get_address_from_hostname,
|
||||
};
|
||||
|
||||
@@ -9,8 +9,14 @@
|
||||
#ifndef TOR_CONFIG_RESOLVE_ADDR_H
|
||||
#define TOR_CONFIG_RESOLVE_ADDR_H
|
||||
|
||||
#include "app/config/config.h"
|
||||
#include "core/mainloop/connection.h"
|
||||
|
||||
#include "app/config/or_options_st.h"
|
||||
|
||||
#define get_orport_addr(family) \
|
||||
(get_first_advertised_addr_by_type_af(CONN_TYPE_OR_LISTENER, family))
|
||||
|
||||
bool find_my_address(const or_options_t *options, int family,
|
||||
int warn_severity, tor_addr_t *addr_out,
|
||||
const char **method_out, char **hostname_out);
|
||||
|
||||
+81
-9
@@ -1256,13 +1256,15 @@ get_interface_address6_failure(int severity, sa_family_t family,
|
||||
/** Helper macro: Cleanup the address and variables used after a
|
||||
* find_my_address() call. */
|
||||
#undef CLEANUP_FOUND_ADDRESS
|
||||
#define CLEANUP_FOUND_ADDRESS \
|
||||
do { \
|
||||
config_free_lines(options->Address); \
|
||||
tor_free(options->DirAuthorities); \
|
||||
tor_free(hostname_out); \
|
||||
tor_addr_make_unspec(&resolved_addr); \
|
||||
tor_addr_make_unspec(&test_addr); \
|
||||
#define CLEANUP_FOUND_ADDRESS \
|
||||
do { \
|
||||
config_free_lines(options->Address); \
|
||||
config_free_lines(options->ORPort_lines); \
|
||||
options->ORPort_set = 0; \
|
||||
tor_free(options->DirAuthorities); \
|
||||
tor_free(hostname_out); \
|
||||
tor_addr_make_unspec(&resolved_addr); \
|
||||
tor_addr_make_unspec(&test_addr); \
|
||||
} while (0)
|
||||
|
||||
/** Test both IPv4 and IPv6 coexisting together in the configuration. */
|
||||
@@ -1418,6 +1420,7 @@ typedef struct find_my_address_params_t {
|
||||
int family;
|
||||
const char *public_ip;
|
||||
const char *internal_ip;
|
||||
const char *orport;
|
||||
} find_my_address_params_t;
|
||||
|
||||
static find_my_address_params_t addr_param_v4 = {
|
||||
@@ -1430,8 +1433,8 @@ static find_my_address_params_t addr_param_v4 = {
|
||||
static find_my_address_params_t addr_param_v6 = {
|
||||
.idx = 1,
|
||||
.family = AF_INET6,
|
||||
.public_ip = "4242::4242",
|
||||
.internal_ip = "::1",
|
||||
.public_ip = "[4242::4242]",
|
||||
.internal_ip = "[::1]",
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -1733,6 +1736,75 @@ test_config_find_my_address(void *arg)
|
||||
VALIDATE_FOUND_ADDRESS(false, NULL, NULL);
|
||||
CLEANUP_FOUND_ADDRESS;
|
||||
|
||||
/*
|
||||
* Case 13:
|
||||
* 1. Address is NULL.
|
||||
* 2. ORPort has a valid public address.
|
||||
*/
|
||||
{
|
||||
char *msg = NULL;
|
||||
int n, w, ret;
|
||||
char *orport_line = NULL;
|
||||
|
||||
options->Address = NULL;
|
||||
tor_asprintf(&orport_line, "%s:9001", p->public_ip);
|
||||
config_line_append(&options->ORPort_lines, "ORPort", orport_line);
|
||||
tor_free(orport_line);
|
||||
|
||||
if (p->family == AF_INET6) {
|
||||
/* XXX: Tor does _not_ allow an IPv6 only ORPort thus we need to add a
|
||||
* bogus IPv4 at the moment. */
|
||||
config_line_append(&options->ORPort_lines, "ORPort", "1.1.1.1:9001");
|
||||
}
|
||||
|
||||
ret = parse_ports(options, 0, &msg, &n, &w);
|
||||
tt_int_op(ret, OP_EQ, 0);
|
||||
tor_addr_parse(&test_addr, p->public_ip);
|
||||
}
|
||||
|
||||
retval = find_my_address(options, p->family, LOG_NOTICE, &resolved_addr,
|
||||
&method_used, &hostname_out);
|
||||
VALIDATE_FOUND_ADDRESS(true, "CONFIGURED_ORPORT", NULL);
|
||||
CLEANUP_FOUND_ADDRESS;
|
||||
|
||||
/*
|
||||
* Case 14:
|
||||
* 1. Address is NULL.
|
||||
* 2. ORPort has an internal address thus fails.
|
||||
* 3. Interface as a valid address.
|
||||
*/
|
||||
{
|
||||
char *msg = NULL;
|
||||
int n, w, ret;
|
||||
char *orport_line = NULL;
|
||||
|
||||
options->Address = NULL;
|
||||
tor_asprintf(&orport_line, "%s:9001", p->internal_ip);
|
||||
config_line_append(&options->ORPort_lines, "ORPort", orport_line);
|
||||
tor_free(orport_line);
|
||||
|
||||
if (p->family == AF_INET6) {
|
||||
/* XXX: Tor does _not_ allow an IPv6 only ORPort thus we need to add a
|
||||
* bogus IPv4 at the moment. */
|
||||
config_line_append(&options->ORPort_lines, "ORPort", "1.1.1.1:9001");
|
||||
}
|
||||
|
||||
ret = parse_ports(options, 0, &msg, &n, &w);
|
||||
tt_int_op(ret, OP_EQ, 0);
|
||||
}
|
||||
tor_addr_parse(&test_addr, ret_get_interface_address6_08080808[p->idx]);
|
||||
|
||||
MOCK(get_interface_address6, get_interface_address6_08080808);
|
||||
|
||||
prev_n_get_interface_address6 = n_get_interface_address6;
|
||||
|
||||
retval = find_my_address(options, p->family, LOG_NOTICE, &resolved_addr,
|
||||
&method_used, &hostname_out);
|
||||
|
||||
tt_int_op(n_get_interface_address6, OP_EQ, ++prev_n_get_interface_address6);
|
||||
VALIDATE_FOUND_ADDRESS(true, "INTERFACE", NULL);
|
||||
CLEANUP_FOUND_ADDRESS;
|
||||
|
||||
UNMOCK(get_interface_address6);
|
||||
UNMOCK(tor_gethostname);
|
||||
UNMOCK(tor_addr_lookup);
|
||||
|
||||
Reference in New Issue
Block a user