Tor 0.4.9.0-alpha-dev
selftest.c
Go to the documentation of this file.
1/* Copyright (c) 2001 Matej Pfajfar.
2 * Copyright (c) 2001-2004, Roger Dingledine.
3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4 * Copyright (c) 2007-2021, The Tor Project, Inc. */
5/* See LICENSE for licensing information */
6
7/**
8 * \file selftest.c
9 * \brief Relay self-testing
10 *
11 * Relays need to make sure that their own ports are reachable, and estimate
12 * their own bandwidth, before publishing.
13 */
14
15#include "core/or/or.h"
16
17#include "app/config/config.h"
18
22
24#include "core/or/circuitlist.h"
25#include "core/or/circuituse.h"
27#include "core/or/extendinfo.h"
30#include "core/or/relay.h"
31
33
35
38
42#include "feature/nodelist/routerlist.h" // but...
45
49
50static bool have_orport_for_family(int family);
51static void inform_testing_reachability(const tor_addr_t *addr,
52 uint16_t port);
53
54/** Whether we can reach our IPv4 ORPort from the outside. */
55static bool can_reach_or_port_ipv4 = false;
56/** Whether we can reach our IPv6 ORPort from the outside. */
57static bool can_reach_or_port_ipv6 = false;
58
59/** Has informed_testing_reachable logged a message about testing our IPv4
60 * ORPort? */
62/** Has informed_testing_reachable logged a message about testing our IPv6
63 * ORPort? */
65
66/** Forget what we have learned about our reachability status. */
67void
69{
73}
74
75/** Return 1 if we won't do reachability checks, because:
76 * - AssumeReachable is set, or
77 * - the network is disabled.
78 * Otherwise, return 0.
79 */
80static int
82{
83 return options->AssumeReachable ||
85}
86
87/** Return 0 if we need to do an ORPort reachability check, because:
88 * - no reachability check has been done yet, or
89 * - we've initiated reachability checks, but none have succeeded.
90 * Return 1 if we don't need to do an ORPort reachability check, because:
91 * - we've seen a successful reachability check, or
92 * - AssumeReachable is set, or
93 * - the network is disabled.
94
95 * If `family'`is AF_INET or AF_INET6, return true only when we should skip
96 * the given family's orport check (Because it's been checked, or because we
97 * aren't checking it.) If `family` is 0, return true if we can skip _all_
98 * orport checks.
99 */
100int
102 int family)
103{
104 tor_assert_nonfatal(family == AF_INET || family == AF_INET6 || family == 0);
105 int reach_checks_disabled = router_reachability_checks_disabled(options);
106 if (reach_checks_disabled) {
107 return true;
108 }
109
110 // Note that we do a == 1 here, not just a boolean check. This value
111 // is also an autobool, so CFG_AUTO does not mean that we should
112 // assume IPv6 ports are reachable.
113 const bool ipv6_assume_reachable = (options->AssumeReachableIPv6 == 1);
114
115 // Which reachability flags should we look at?
116 const bool checking_ipv4 = (family == AF_INET || family == 0);
117 const bool checking_ipv6 = (family == AF_INET6 || family == 0);
118
119 if (checking_ipv4) {
121 return false;
122 }
123 }
124 if (checking_ipv6 && !ipv6_assume_reachable) {
126 return false;
127 }
128 }
129
130 return true;
131}
132
133/** Relay DirPorts are no longer used (though authorities are). In either case,
134 * reachability self test is done anymore, since network re-entry towards an
135 * authority DirPort is not allowed. Thus, consider it always reachable. */
136int
138{
139 (void) options;
140 return 1;
141}
142
143/** See if we currently believe our ORPort to be unreachable. If so, return 1
144 * else return 0. */
145static int
147{
149 const or_options_t *options = get_options();
150
151 if (!me)
152 return 0;
153
154 /* Doesn't check our IPv6 address, see #34065. */
155 if (routerset_contains_router(options->ExcludeNodes, me, -1) &&
156 options->StrictNodes) {
157 /* If we've excluded ourself, and StrictNodes is set, we can't test
158 * ourself. */
159#define SELF_EXCLUDED_WARN_INTERVAL 3600
160 static ratelim_t warning_limit=RATELIM_INIT(SELF_EXCLUDED_WARN_INTERVAL);
161 log_fn_ratelim(&warning_limit, LOG_WARN, LD_CIRC,
162 "Can't perform self-tests for this relay: we have "
163 "listed ourself in ExcludeNodes, and StrictNodes is set. "
164 "We cannot learn whether we are usable, and will not "
165 "be able to advertise ourself.");
166 return 0;
167 }
168 return 1;
169}
170
171/**
172 * Return true if we have configured an ORPort for the given family that
173 * we would like to advertise.
174 *
175 * Like other self-testing functions, this function looks at our most
176 * recently built descriptor.
177 **/
178static bool
180{
182
183 if (!me)
184 return false;
185
187 if (router_get_orport(me, &ap, family) < 0) {
188 return false;
189 }
190 return true;
191}
192
193/** Allocate and return a new extend_info_t that can be used to build
194 * a circuit to or through the router <b>r</b>, using an address from
195 * <b>family</b> (if available).
196 *
197 * Clients don't have routerinfos, so this function should only be called on a
198 * server.
199 *
200 * If the requested address is not available, returns NULL. */
201static extend_info_t *
203{
204 crypto_pk_t *rsa_pubkey;
205 extend_info_t *info;
207
208 if (BUG(!r)) {
209 return NULL;
210 }
211
212 /* Relays always assume that the first hop is reachable. They ignore
213 * ReachableAddresses. */
214 tor_assert_nonfatal(router_or_conn_should_skip_reachable_address_check(
215 get_options(), 0));
216
217 const ed25519_public_key_t *ed_id_key;
218 if (r->cache_info.signing_key_cert)
219 ed_id_key = &r->cache_info.signing_key_cert->signing_key;
220 else
221 ed_id_key = NULL;
222
223 if (router_get_orport(r, &ap, family) < 0) {
224 /* We don't have an ORPort for the requested family. */
225 return NULL;
226 }
227 rsa_pubkey = router_get_rsa_onion_pkey(r->onion_pkey, r->onion_pkey_len);
228 info = extend_info_new(r->nickname, r->cache_info.identity_digest,
229 ed_id_key,
230 rsa_pubkey, r->onion_curve25519_pkey,
231 &ap.addr, ap.port,
232 /* TODO-324: Should self-test circuits use
233 * congestion control? */
234 NULL, false);
235 crypto_pk_free(rsa_pubkey);
236 return info;
237}
238
239/** Launch a self-testing circuit to one of our ORPorts, using an address from
240 * <b>family</b> (if available). The circuit can be used to test reachability
241 * or bandwidth. <b>me</b> is our own routerinfo.
242 *
243 * Logs an info-level status message. If <b>orport_reachable</b> is false,
244 * call it a reachability circuit. Otherwise, call it a bandwidth circuit.
245 *
246 * See router_do_reachability_checks() for details. */
247static void
249 int family,
250 int orport_reachable)
251{
252 extend_info_t *ei = extend_info_from_router(me, family);
253 int ipv6_flags = (family == AF_INET6 ? CIRCLAUNCH_IS_IPV6_SELFTEST : 0);
254
255 /* If we're trying to test IPv6, but we don't have an IPv6 ORPort, ei will
256 * be NULL. */
257 if (ei) {
258 const char *family_name = fmt_af_family(family);
259 const tor_addr_port_t *ap = extend_info_get_orport(ei, family);
260 if (BUG(!ap)) {
261 /* Not much we can do here to recover apart from screaming loudly. */
262 extend_info_free(ei);
263 return;
264 }
265 log_info(LD_CIRC, "Testing %s of my %s ORPort: %s.",
266 !orport_reachable ? "reachability" : "bandwidth",
267 family_name, fmt_addrport_ap(ap));
268
269 if (!orport_reachable) {
270 /* Only log if we are actually doing a reachability test to learn if our
271 * ORPort is reachable. Else, this prints a log notice if we are simply
272 * opening a bandwidth testing circuit even though we are reachable. */
273 inform_testing_reachability(&ap->addr, ap->port);
274 }
275
279 ipv6_flags);
280 extend_info_free(ei);
281 }
282}
283
284/** Some time has passed, or we just got new directory information. See if we
285 * currently believe our ORPort to be unreachable. If so, launch a new test
286 * for it.
287 *
288 * For ORPort, we simply try making a circuit that ends at ourselves. Success
289 * is noticed in onionskin_answer().
290 */
291void
293{
295 const or_options_t *options = get_options();
296 int orport_reachable_v4 =
297 router_orport_seems_reachable(options, AF_INET);
298 int orport_reachable_v6 =
299 router_orport_seems_reachable(options, AF_INET6);
300
302 bool need_testing = !circuit_enough_testing_circs();
303 /* At the moment, tor relays believe that they are reachable when they
304 * receive any create cell on an inbound connection, if the address
305 * family is correct.
306 */
307 if (!orport_reachable_v4 || need_testing) {
308 router_do_orport_reachability_checks(me, AF_INET, orport_reachable_v4);
309 }
310 if (!orport_reachable_v6 || need_testing) {
311 router_do_orport_reachability_checks(me, AF_INET6, orport_reachable_v6);
312 }
313 }
314}
315
316/** Log a message informing the user that we are testing a port for
317 * reachability, if we have not already logged such a message.
318 *
319 * Calls to router_reset_reachability() will reset our view of whether we have
320 * logged this message for a given port. */
321static void
322inform_testing_reachability(const tor_addr_t *addr, uint16_t port)
323{
325 return;
326
327 bool *have_informed_ptr;
328 if (tor_addr_family(addr) == AF_INET) {
329 have_informed_ptr = &have_informed_testing_or_port_ipv4;
330 } else {
331 have_informed_ptr = &have_informed_testing_or_port_ipv6;
332 }
333
334 if (*have_informed_ptr) {
335 /* We already told the user that we're testing this port; no need to
336 * do it again. */
337 return;
338 }
339
340 char addr_buf[TOR_ADDRPORT_BUF_LEN];
341 strlcpy(addr_buf, fmt_addrport(addr, port), sizeof(addr_buf));
342
343 const char *afname = fmt_af_family(tor_addr_family(addr));
344
346 "CHECKING_REACHABILITY ORADDRESS=%s",
347 addr_buf);
348
349 log_notice(LD_OR, "Now checking whether %s ORPort %s is reachable... "
350 "(this may take up to %d minutes -- look for log "
351 "messages indicating success)",
352 afname, addr_buf,
354
355 *have_informed_ptr = true;
356}
357
358/**
359 * Return true if this module knows of no reason why we shouldn't publish
360 * a server descriptor.
361 **/
362static bool
364{
365 return options->PublishServerDescriptor_ != NO_DIRINFO &&
366 router_all_orports_seem_reachable(options);
367}
368
369/** Annotate that we found our ORPort reachable with a given address
370 * family. */
371void
373{
375 const or_options_t *options = get_options();
376 const char *reachable_reason = "ORPort found reachable";
377 bool *can_reach_ptr;
378 if (family == AF_INET) {
379 can_reach_ptr = &can_reach_or_port_ipv4;
380 } else if (family == AF_INET6) {
381 can_reach_ptr = &can_reach_or_port_ipv6;
382 } else {
384 return;
385 }
386 if (!*can_reach_ptr && me) {
388 if (router_get_orport(me, &ap, family) < 0) {
389 return;
390 }
391 char *address = tor_strdup(fmt_addrport_ap(&ap));
392
393 *can_reach_ptr = true;
394
395 log_notice(LD_OR,"Self-testing indicates your ORPort %s is reachable from "
396 "the outside. Excellent.%s",
397 address,
398 ready_to_publish(options) ?
399 " Publishing server descriptor." : "");
400
401 /* Make sure our descriptor is marked to publish the IPv6 if it is now
402 * reachable. This can change at runtime. */
403 if (family == AF_INET6) {
404 mark_my_descriptor_if_omit_ipv6_changes(reachable_reason, false);
405 } else {
406 mark_my_descriptor_dirty(reachable_reason);
407 }
408 /* This is a significant enough change to upload immediately,
409 * at least in a test network */
410 if (options->TestingTorNetwork == 1) {
412 }
414 "REACHABILITY_SUCCEEDED ORADDRESS=%s",
415 address);
416 tor_free(address);
417 }
418}
419
420/** We have enough testing circuits open. Send a bunch of "drop"
421 * cells down each of them, to exercise our bandwidth.
422 *
423 * May use IPv4 and IPv6 testing circuits (if available). */
424void
425router_perform_bandwidth_test(int num_circs, time_t now)
426{
427 int num_cells = (int)(get_options()->BandwidthRate * 10 /
429 int max_cells = num_cells < CIRCWINDOW_START ?
430 num_cells : CIRCWINDOW_START;
431 int cells_per_circuit = max_cells / num_circs;
432 origin_circuit_t *circ = NULL;
433
434 log_notice(LD_OR,"Performing bandwidth self-test...done.");
435 while ((circ = circuit_get_next_by_purpose(circ,
437 /* dump cells_per_circuit drop cells onto this circ */
438 int i = cells_per_circuit;
439 if (circ->base_.state != CIRCUIT_STATE_OPEN)
440 continue;
441 circ->base_.timestamp_dirty = now;
442 while (i-- > 0) {
443 if (relay_send_command_from_edge(0, TO_CIRCUIT(circ),
444 RELAY_COMMAND_DROP,
445 NULL, 0, circ->cpath->prev)<0) {
446 return; /* stop if error */
447 }
448 }
449 }
450}
const char * fmt_addrport(const tor_addr_t *addr, uint16_t port)
Definition: address.c:1199
const char * fmt_af_family(sa_family_t family)
Definition: address.c:1246
static sa_family_t tor_addr_family(const tor_addr_t *a)
Definition: address.h:187
#define TOR_ADDRPORT_BUF_LEN
Definition: address.h:233
Header file for directory authority mode.
Authority certificate structure.
Header file for circuitbuild.c.
origin_circuit_t * circuit_get_next_by_purpose(origin_circuit_t *start, uint8_t purpose)
Definition: circuitlist.c:1804
Header file for circuitlist.c.
#define CIRCUIT_STATE_OPEN
Definition: circuitlist.h:32
#define CIRCUIT_PURPOSE_TESTING
Definition: circuitlist.h:118
int circuit_enough_testing_circs(void)
Definition: circuituse.c:1592
origin_circuit_t * circuit_launch_by_extend_info(uint8_t purpose, extend_info_t *extend_info, int flags)
Definition: circuituse.c:2089
Header file for circuituse.c.
#define CIRCLAUNCH_NEED_CAPACITY
Definition: circuituse.h:43
#define CIRCLAUNCH_IS_IPV6_SELFTEST
Definition: circuituse.h:54
#define CIRCLAUNCH_IS_INTERNAL
Definition: circuituse.h:46
const or_options_t * get_options(void)
Definition: config.c:944
Header file for config.c.
Header file for connection.c.
int control_event_server_status(int severity, const char *format,...)
Header file for control_events.c.
Path structures for origin circuits.
Header file for dirclient.c.
Header file for directory.c.
Extend-info structure.
extend_info_t * extend_info_new(const char *nickname, const char *rsa_id_digest, const ed25519_public_key_t *ed_id, crypto_pk_t *onion_key, const curve25519_public_key_t *ntor_key, const tor_addr_t *addr, uint16_t port, const protover_summary_flags_t *pv, bool for_exit_use)
Definition: extendinfo.c:33
const tor_addr_port_t * extend_info_get_orport(const extend_info_t *ei, int family)
Definition: extendinfo.c:285
Header for core/or/extendinfo.c.
#define log_fn_ratelim(ratelim, severity, domain, args,...)
Definition: log.h:288
#define LD_OR
Definition: log.h:92
#define LOG_NOTICE
Definition: log.h:50
#define LD_CIRC
Definition: log.h:82
#define LOG_WARN
Definition: log.h:53
Header file for mainloop.c.
#define tor_free(p)
Definition: malloc.h:56
int net_is_disabled(void)
Definition: netstatus.c:25
Header for netstatus.c.
Master header file for Tor-specific functionality.
#define CELL_MAX_NETWORK_SIZE
Definition: or.h:468
#define TO_CIRCUIT(x)
Definition: or.h:848
#define TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT
Definition: or.h:442
#define CIRCWINDOW_START
Definition: or.h:394
Origin circuit structure.
Header file for relay.c.
void reschedule_descriptor_update_check(void)
Header for feature/relay/relay_periodic.c.
void mark_my_descriptor_if_omit_ipv6_changes(const char *reason, bool omit_ipv6)
Definition: router.c:2511
void mark_my_descriptor_dirty(const char *reason)
Definition: router.c:2572
const routerinfo_t * router_get_my_routerinfo(void)
Definition: router.c:1806
Header file for router.c.
int router_get_orport(const routerinfo_t *router, tor_addr_port_t *ap_out, int family)
Definition: routerinfo.c:27
Header file for routerinfo.c.
Router descriptor structure.
Header file for routerlist.c.
int routerset_contains_router(const routerset_t *set, const routerinfo_t *ri, country_t country)
Definition: routerset.c:328
Header file for routerset.c.
static bool can_reach_or_port_ipv6
Definition: selftest.c:57
static extend_info_t * extend_info_from_router(const routerinfo_t *r, int family)
Definition: selftest.c:202
static int router_should_check_reachability(void)
Definition: selftest.c:146
static bool ready_to_publish(const or_options_t *options)
Definition: selftest.c:363
static bool have_informed_testing_or_port_ipv4
Definition: selftest.c:61
int router_orport_seems_reachable(const or_options_t *options, int family)
Definition: selftest.c:101
static bool have_orport_for_family(int family)
Definition: selftest.c:179
static bool have_informed_testing_or_port_ipv6
Definition: selftest.c:64
static bool can_reach_or_port_ipv4
Definition: selftest.c:55
void router_do_reachability_checks(void)
Definition: selftest.c:292
void router_orport_found_reachable(int family)
Definition: selftest.c:372
void router_perform_bandwidth_test(int num_circs, time_t now)
Definition: selftest.c:425
static int router_reachability_checks_disabled(const or_options_t *options)
Definition: selftest.c:81
static void inform_testing_reachability(const tor_addr_t *addr, uint16_t port)
Definition: selftest.c:322
void router_reset_reachability(void)
Definition: selftest.c:68
int router_dirport_seems_reachable(const or_options_t *options)
Definition: selftest.c:137
static void router_do_orport_reachability_checks(const routerinfo_t *me, int family, int orport_reachable)
Definition: selftest.c:248
Header file for selftest.c.
uint8_t state
Definition: circuit_st.h:111
time_t timestamp_dirty
Definition: circuit_st.h:188
struct crypt_path_t * prev
Definition: crypt_path_st.h:80
dirinfo_type_t PublishServerDescriptor_
uint64_t BandwidthRate
struct routerset_t * ExcludeNodes
int AssumeReachableIPv6
crypt_path_t * cpath
char * onion_pkey
Definition: routerinfo_st.h:37
size_t onion_pkey_len
Definition: routerinfo_st.h:39
struct curve25519_public_key_t * onion_curve25519_pkey
Definition: routerinfo_st.h:43
char * nickname
Definition: routerinfo_st.h:22
char identity_digest[DIGEST_LEN]
struct tor_cert_st * signing_key_cert
Header for torcert.c.
#define tor_assert_nonfatal_unreached()
Definition: util_bug.h:177