mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-30 23:53:32 +01:00
Merge branch 'ticket40071_045_01_squashed' into master
This commit is contained in:
commit
b13f32ee97
7
changes/ticket40071
Normal file
7
changes/ticket40071
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
o Minor bugfixes (relay, address):
|
||||||
|
- Don't trigger an IP change if no new valid IP can be found. Fixes bug
|
||||||
|
40071; bugfix on 0.4.5.1-alpha.
|
||||||
|
- When attempting to discover our IP, don't launch a descriptor fetch
|
||||||
|
anymore but rather a simple test circuit since the address discovery is
|
||||||
|
through the NETINFO cell now from the authorities. Fixes bug 40071; bugfix
|
||||||
|
on 0.4.5.1-alpha.
|
@ -114,7 +114,9 @@
|
|||||||
#define CIRCUIT_PURPOSE_S_HSDIR_POST 20
|
#define CIRCUIT_PURPOSE_S_HSDIR_POST 20
|
||||||
#define CIRCUIT_PURPOSE_S_HS_MAX_ 20
|
#define CIRCUIT_PURPOSE_S_HS_MAX_ 20
|
||||||
|
|
||||||
/** A testing circuit; not meant to be used for actual traffic. */
|
/** A testing circuit; not meant to be used for actual traffic. It is used for
|
||||||
|
* bandwidth measurement, reachability test and address discovery from an
|
||||||
|
* authority using the NETINFO cell. */
|
||||||
#define CIRCUIT_PURPOSE_TESTING 21
|
#define CIRCUIT_PURPOSE_TESTING 21
|
||||||
/** A controller made this circuit and Tor should not use it. */
|
/** A controller made this circuit and Tor should not use it. */
|
||||||
#define CIRCUIT_PURPOSE_CONTROLLER 22
|
#define CIRCUIT_PURPOSE_CONTROLLER 22
|
||||||
|
@ -65,6 +65,9 @@
|
|||||||
#include "app/config/config.h"
|
#include "app/config/config.h"
|
||||||
#include "core/mainloop/connection.h"
|
#include "core/mainloop/connection.h"
|
||||||
#include "core/mainloop/mainloop.h"
|
#include "core/mainloop/mainloop.h"
|
||||||
|
#include "core/or/circuitlist.h"
|
||||||
|
#include "core/or/circuituse.h"
|
||||||
|
#include "core/or/extendinfo.h"
|
||||||
#include "core/or/policies.h"
|
#include "core/or/policies.h"
|
||||||
#include "feature/client/bridges.h"
|
#include "feature/client/bridges.h"
|
||||||
#include "feature/control/control_events.h"
|
#include "feature/control/control_events.h"
|
||||||
@ -137,8 +140,6 @@ static int signed_desc_digest_is_recognized(signed_descriptor_t *desc);
|
|||||||
static const char *signed_descriptor_get_body_impl(
|
static const char *signed_descriptor_get_body_impl(
|
||||||
const signed_descriptor_t *desc,
|
const signed_descriptor_t *desc,
|
||||||
int with_annotations);
|
int with_annotations);
|
||||||
static void launch_dummy_descriptor_download_as_needed(time_t now,
|
|
||||||
const or_options_t *options);
|
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
||||||
@ -2306,7 +2307,6 @@ update_all_descriptor_downloads(time_t now)
|
|||||||
return;
|
return;
|
||||||
update_router_descriptor_downloads(now);
|
update_router_descriptor_downloads(now);
|
||||||
update_microdesc_downloads(now);
|
update_microdesc_downloads(now);
|
||||||
launch_dummy_descriptor_download_as_needed(now, get_options());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Clear all our timeouts for fetching v3 directory stuff, and then
|
/** Clear all our timeouts for fetching v3 directory stuff, and then
|
||||||
@ -2760,54 +2760,6 @@ update_consensus_router_descriptor_downloads(time_t now, int is_vote,
|
|||||||
smartlist_free(no_longer_old);
|
smartlist_free(no_longer_old);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** How often should we launch a server/authority request to be sure of getting
|
|
||||||
* a guess for our IP? */
|
|
||||||
/*XXXX+ this info should come from netinfo cells or something, or we should
|
|
||||||
* do this only when we aren't seeing incoming data. see bug 652. */
|
|
||||||
#define DUMMY_DOWNLOAD_INTERVAL (20*60)
|
|
||||||
|
|
||||||
/** As needed, launch a dummy router descriptor fetch to see if our
|
|
||||||
* address has changed. */
|
|
||||||
static void
|
|
||||||
launch_dummy_descriptor_download_as_needed(time_t now,
|
|
||||||
const or_options_t *options)
|
|
||||||
{
|
|
||||||
static time_t last_dummy_download = 0;
|
|
||||||
bool have_addr;
|
|
||||||
tor_addr_t addr_out;
|
|
||||||
|
|
||||||
/* This dummy fetch only matter for relays. */
|
|
||||||
if (!server_mode(options)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Lookup the address cache to learn if we have a good usable address. We
|
|
||||||
* still force relays to have an IPv4 so that alone is enough to learn if we
|
|
||||||
* need a lookup. In case we don't have one, we might want to attempt a
|
|
||||||
* dummy fetch to learn our address as a suggestion from an authority. */
|
|
||||||
have_addr = relay_find_addr_to_publish(options, AF_INET,
|
|
||||||
RELAY_FIND_ADDR_CACHE_ONLY,
|
|
||||||
&addr_out);
|
|
||||||
|
|
||||||
/* XXXX+ we could be smarter here; see notes on bug 652. */
|
|
||||||
/* If we're a server that doesn't have an address, we rely on directory
|
|
||||||
* fetches to learn when our address changes. So if we haven't tried to get
|
|
||||||
* any routerdescs in a long time, try a dummy fetch now. */
|
|
||||||
if (!have_addr &&
|
|
||||||
last_descriptor_download_attempted + DUMMY_DOWNLOAD_INTERVAL < now &&
|
|
||||||
last_dummy_download + DUMMY_DOWNLOAD_INTERVAL < now) {
|
|
||||||
last_dummy_download = now;
|
|
||||||
/* XX/teor - do we want an authority here, because they are less likely
|
|
||||||
* to give us the wrong address? (See #17782)
|
|
||||||
* I'm leaving the previous behaviour intact, because I don't like
|
|
||||||
* the idea of some relays contacting an authority every 20 minutes. */
|
|
||||||
directory_get_from_dirserver(DIR_PURPOSE_FETCH_SERVERDESC,
|
|
||||||
ROUTER_PURPOSE_GENERAL, "authority.z",
|
|
||||||
PDS_RETRY_IF_NO_SERVERS,
|
|
||||||
DL_WANT_ANY_DIRSERVER);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Launch downloads for router status as needed. */
|
/** Launch downloads for router status as needed. */
|
||||||
void
|
void
|
||||||
update_router_descriptor_downloads(time_t now)
|
update_router_descriptor_downloads(time_t now)
|
||||||
|
@ -12,10 +12,16 @@
|
|||||||
#include "app/config/resolve_addr.h"
|
#include "app/config/resolve_addr.h"
|
||||||
|
|
||||||
#include "core/mainloop/mainloop.h"
|
#include "core/mainloop/mainloop.h"
|
||||||
|
#include "core/or/circuitlist.h"
|
||||||
|
#include "core/or/circuituse.h"
|
||||||
|
#include "core/or/extendinfo.h"
|
||||||
|
|
||||||
#include "feature/control/control_events.h"
|
#include "feature/control/control_events.h"
|
||||||
#include "feature/dircommon/dir_connection_st.h"
|
#include "feature/dircommon/dir_connection_st.h"
|
||||||
#include "feature/nodelist/dirlist.h"
|
#include "feature/nodelist/dirlist.h"
|
||||||
|
#include "feature/nodelist/node_select.h"
|
||||||
|
#include "feature/nodelist/nodelist.h"
|
||||||
|
#include "feature/nodelist/routerstatus_st.h"
|
||||||
#include "feature/relay/relay_find_addr.h"
|
#include "feature/relay/relay_find_addr.h"
|
||||||
#include "feature/relay/router.h"
|
#include "feature/relay/router.h"
|
||||||
#include "feature/relay/routermode.h"
|
#include "feature/relay/routermode.h"
|
||||||
@ -151,3 +157,65 @@ relay_has_address_set(int family)
|
|||||||
return relay_find_addr_to_publish(get_options(), family,
|
return relay_find_addr_to_publish(get_options(), family,
|
||||||
RELAY_FIND_ADDR_CACHE_ONLY, &addr);
|
RELAY_FIND_ADDR_CACHE_ONLY, &addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** How often should we launch a circuit to an authority to be sure of getting
|
||||||
|
* a guess for our IP? */
|
||||||
|
#define DUMMY_DOWNLOAD_INTERVAL (20*60)
|
||||||
|
|
||||||
|
void
|
||||||
|
relay_addr_learn_from_dirauth(void)
|
||||||
|
{
|
||||||
|
static time_t last_dummy_circuit = 0;
|
||||||
|
const or_options_t *options = get_options();
|
||||||
|
time_t now = time(NULL);
|
||||||
|
bool have_addr;
|
||||||
|
tor_addr_t addr_out;
|
||||||
|
|
||||||
|
/* This dummy circuit only matter for relays. */
|
||||||
|
if (BUG(!server_mode(options))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lookup the address cache to learn if we have a good usable address. We
|
||||||
|
* still force relays to have an IPv4 so that alone is enough to learn if we
|
||||||
|
* need a lookup. In case we don't have one, we might want to attempt a
|
||||||
|
* dummy circuit to learn our address as a suggestion from an authority. */
|
||||||
|
have_addr = relay_find_addr_to_publish(options, AF_INET,
|
||||||
|
RELAY_FIND_ADDR_CACHE_ONLY,
|
||||||
|
&addr_out);
|
||||||
|
|
||||||
|
/* If we're a relay or bridge for which we were unable to discover our
|
||||||
|
* public address, we rely on learning our address from a directory
|
||||||
|
* authority from the NETINFO cell. */
|
||||||
|
if (!have_addr && last_dummy_circuit + DUMMY_DOWNLOAD_INTERVAL < now) {
|
||||||
|
last_dummy_circuit = now;
|
||||||
|
|
||||||
|
const routerstatus_t *rs = router_pick_trusteddirserver(V3_DIRINFO, 0);
|
||||||
|
if (BUG(!rs)) {
|
||||||
|
/* We should really always have trusted directories configured at this
|
||||||
|
* stage. They are loaded early either from default list or the one
|
||||||
|
* given in the configuration file. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const node_t *node = node_get_by_id(rs->identity_digest);
|
||||||
|
if (BUG(!node)) {
|
||||||
|
/* If there is a routerstatus_t, there is a node_t thus this should
|
||||||
|
* never fail. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
extend_info_t *ei = extend_info_from_node(node, 1);
|
||||||
|
if (BUG(!ei)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_debug(LD_GENERAL, "Attempting dummy testing circuit to an authority "
|
||||||
|
"in order to learn our address.");
|
||||||
|
|
||||||
|
/* Launch a one-hop testing circuit to a trusted authority so we can learn
|
||||||
|
* our address through the NETINFO cell. */
|
||||||
|
circuit_launch_by_extend_info(CIRCUIT_PURPOSE_TESTING, ei,
|
||||||
|
CIRCLAUNCH_IS_INTERNAL |
|
||||||
|
CIRCLAUNCH_ONEHOP_TUNNEL);
|
||||||
|
extend_info_free(ei);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -24,6 +24,8 @@ MOCK_DECL(bool, relay_find_addr_to_publish,
|
|||||||
|
|
||||||
bool relay_has_address_set(int family);
|
bool relay_has_address_set(int family);
|
||||||
|
|
||||||
|
void relay_addr_learn_from_dirauth(void);
|
||||||
|
|
||||||
#ifdef RELAY_FIND_ADDR_PRIVATE
|
#ifdef RELAY_FIND_ADDR_PRIVATE
|
||||||
|
|
||||||
#endif /* RELAY_FIND_ADDR_PRIVATE */
|
#endif /* RELAY_FIND_ADDR_PRIVATE */
|
||||||
|
@ -2071,7 +2071,9 @@ router_build_fresh_unsigned_routerinfo,(routerinfo_t **ri_out))
|
|||||||
|
|
||||||
/* Tor requires a relay to have an IPv4 so bail if we can't find it. */
|
/* Tor requires a relay to have an IPv4 so bail if we can't find it. */
|
||||||
if (!have_v4) {
|
if (!have_v4) {
|
||||||
log_warn(LD_CONFIG, "Don't know my address while generating descriptor");
|
log_info(LD_CONFIG, "Don't know my address while generating descriptor. "
|
||||||
|
"Launching circuit to authority to learn it.");
|
||||||
|
relay_addr_learn_from_dirauth();
|
||||||
result = TOR_ROUTERINFO_ERROR_NO_EXT_ADDR;
|
result = TOR_ROUTERINFO_ERROR_NO_EXT_ADDR;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@ -2679,8 +2681,21 @@ check_descriptor_ipaddress_changed(time_t now)
|
|||||||
|
|
||||||
/* Ignore returned value because we want to notice not only an address
|
/* Ignore returned value because we want to notice not only an address
|
||||||
* change but also if an address is lost (current == UNSPEC). */
|
* change but also if an address is lost (current == UNSPEC). */
|
||||||
find_my_address(get_options(), family, LOG_INFO, ¤t, &method,
|
bool found = find_my_address(get_options(), family, LOG_INFO, ¤t,
|
||||||
&hostname);
|
&method, &hostname);
|
||||||
|
if (!found) {
|
||||||
|
/* Address was possibly not found because it is simply not configured or
|
||||||
|
* discoverable. Fallback to our cache, which includes any suggestion
|
||||||
|
* sent by a trusted directory server. */
|
||||||
|
found = relay_find_addr_to_publish(get_options(), family,
|
||||||
|
RELAY_FIND_ADDR_CACHE_ONLY,
|
||||||
|
¤t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The "current" address might be UNSPEC meaning it was not discovered nor
|
||||||
|
* found in our current cache. If we had an address before and we have
|
||||||
|
* none now, we consider this an IP change since it appears the relay lost
|
||||||
|
* its address. */
|
||||||
|
|
||||||
if (!tor_addr_eq(previous, ¤t)) {
|
if (!tor_addr_eq(previous, ¤t)) {
|
||||||
char *source;
|
char *source;
|
||||||
|
Loading…
Reference in New Issue
Block a user