Tor  0.4.3.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-2019, 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 reasonable, and estimate
12  * their own bandwidth, before publishing.
13  */
14 
15 #define SELFTEST_PRIVATE
16 
17 #include "core/or/or.h"
18 
19 #include "app/config/config.h"
21 #include "core/mainloop/mainloop.h"
23 #include "core/or/circuitbuild.h"
24 #include "core/or/circuitlist.h"
25 #include "core/or/circuituse.h"
26 #include "core/or/crypt_path_st.h"
28 #include "core/or/relay.h"
35 #include "feature/nodelist/routerlist.h" // but...
39 #include "feature/relay/router.h"
40 #include "feature/relay/selftest.h"
41 
42 /** Whether we can reach our ORPort from the outside. */
43 static int can_reach_or_port = 0;
44 /** Whether we can reach our DirPort from the outside. */
45 static int can_reach_dir_port = 0;
46 
47 /** Forget what we have learned about our reachability status. */
48 void
50 {
52 }
53 
54 /** Return 1 if we won't do reachability checks, because:
55  * - AssumeReachable is set, or
56  * - the network is disabled.
57  * Otherwise, return 0.
58  */
59 static int
61 {
62  return options->AssumeReachable ||
64 }
65 
66 /** Return 0 if we need to do an ORPort reachability check, because:
67  * - no reachability check has been done yet, or
68  * - we've initiated reachability checks, but none have succeeded.
69  * Return 1 if we don't need to do an ORPort reachability check, because:
70  * - we've seen a successful reachability check, or
71  * - AssumeReachable is set, or
72  * - the network is disabled.
73  */
74 int
76 {
77  int reach_checks_disabled = router_reachability_checks_disabled(options);
78  return reach_checks_disabled ||
80 }
81 
82 /** Return 0 if we need to do a DirPort reachability check, because:
83  * - no reachability check has been done yet, or
84  * - we've initiated reachability checks, but none have succeeded.
85  * Return 1 if we don't need to do a DirPort reachability check, because:
86  * - we've seen a successful reachability check, or
87  * - there is no DirPort set, or
88  * - AssumeReachable is set, or
89  * - the network is disabled.
90  */
91 int
93 {
94  int reach_checks_disabled = router_reachability_checks_disabled(options) ||
95  !options->DirPort_set;
96  return reach_checks_disabled ||
98 }
99 
100 /** See if we currently believe our ORPort or DirPort to be
101  * unreachable. If so, return 1 else return 0.
102  */
103 static int
104 router_should_check_reachability(int test_or, int test_dir)
105 {
107  const or_options_t *options = get_options();
108 
109  if (!me)
110  return 0;
111 
112  if (routerset_contains_router(options->ExcludeNodes, me, -1) &&
113  options->StrictNodes) {
114  /* If we've excluded ourself, and StrictNodes is set, we can't test
115  * ourself. */
116  if (test_or || test_dir) {
117 #define SELF_EXCLUDED_WARN_INTERVAL 3600
118  static ratelim_t warning_limit=RATELIM_INIT(SELF_EXCLUDED_WARN_INTERVAL);
119  log_fn_ratelim(&warning_limit, LOG_WARN, LD_CIRC,
120  "Can't peform self-tests for this relay: we have "
121  "listed ourself in ExcludeNodes, and StrictNodes is set. "
122  "We cannot learn whether we are usable, and will not "
123  "be able to advertise ourself.");
124  }
125  return 0;
126  }
127  return 1;
128 }
129 
130 /** Allocate and return a new extend_info_t that can be used to build
131  * a circuit to or through the router <b>r</b>. Uses the primary
132  * address of the router, so should only be called on a server. */
133 static extend_info_t *
135 {
136  crypto_pk_t *rsa_pubkey;
137  extend_info_t *info;
138  tor_addr_port_t ap;
139  tor_assert(r);
140 
141  /* Make sure we don't need to check address reachability */
142  tor_assert_nonfatal(router_skip_or_reachability(get_options(), 0));
143 
144  const ed25519_public_key_t *ed_id_key;
145  if (r->cache_info.signing_key_cert)
146  ed_id_key = &r->cache_info.signing_key_cert->signing_key;
147  else
148  ed_id_key = NULL;
149 
150  router_get_prim_orport(r, &ap);
151  rsa_pubkey = router_get_rsa_onion_pkey(r->onion_pkey, r->onion_pkey_len);
152  info = extend_info_new(r->nickname, r->cache_info.identity_digest,
153  ed_id_key,
154  rsa_pubkey, r->onion_curve25519_pkey,
155  &ap.addr, ap.port);
156  crypto_pk_free(rsa_pubkey);
157  return info;
158 }
159 
160 /** Some time has passed, or we just got new directory information.
161  * See if we currently believe our ORPort or DirPort to be
162  * unreachable. If so, launch a new test for it.
163  *
164  * For ORPort, we simply try making a circuit that ends at ourselves.
165  * Success is noticed in onionskin_answer().
166  *
167  * For DirPort, we make a connection via Tor to our DirPort and ask
168  * for our own server descriptor.
169  * Success is noticed in connection_dir_client_reached_eof().
170  */
171 void
172 router_do_reachability_checks(int test_or, int test_dir)
173 {
175  const or_options_t *options = get_options();
176  int orport_reachable = check_whether_orport_reachable(options);
177  tor_addr_t addr;
178 
179  if (router_should_check_reachability(test_or, test_dir)) {
180  if (test_or && (!orport_reachable || !circuit_enough_testing_circs())) {
182  /* XXX IPv6 self testing */
183  log_info(LD_CIRC, "Testing %s of my ORPort: %s:%d.",
184  !orport_reachable ? "reachability" : "bandwidth",
185  fmt_addr32(me->addr), me->or_port);
188  extend_info_free(ei);
189  }
190 
191  /* XXX IPv6 self testing */
192  tor_addr_from_ipv4h(&addr, me->addr);
193  if (test_dir && !check_whether_dirport_reachable(options) &&
195  CONN_TYPE_DIR, &addr, me->dir_port,
197  tor_addr_port_t my_orport, my_dirport;
198  memcpy(&my_orport.addr, &addr, sizeof(addr));
199  memcpy(&my_dirport.addr, &addr, sizeof(addr));
200  my_orport.port = me->or_port;
201  my_dirport.port = me->dir_port;
202  /* ask myself, via tor, for my server descriptor. */
203  directory_request_t *req =
205  directory_request_set_or_addr_port(req, &my_orport);
206  directory_request_set_dir_addr_port(req, &my_dirport);
208  me->cache_info.identity_digest);
209  // ask via an anon circuit, connecting to our dirport.
211  directory_request_set_resource(req, "authority.z");
213  directory_request_free(req);
214  }
215  }
216 }
217 
218 /** Annotate that we found our ORPort reachable. */
219 void
221 {
223  const or_options_t *options = get_options();
224  if (!can_reach_or_port && me) {
225  char *address = tor_dup_ip(me->addr);
226  log_notice(LD_OR,"Self-testing indicates your ORPort is reachable from "
227  "the outside. Excellent.%s",
228  options->PublishServerDescriptor_ != NO_DIRINFO
229  && check_whether_dirport_reachable(options) ?
230  " Publishing server descriptor." : "");
231  can_reach_or_port = 1;
232  mark_my_descriptor_dirty("ORPort found reachable");
233  /* This is a significant enough change to upload immediately,
234  * at least in a test network */
235  if (options->TestingTorNetwork == 1) {
237  }
239  "REACHABILITY_SUCCEEDED ORADDRESS=%s:%d",
240  address, me->or_port);
241  tor_free(address);
242  }
243 }
244 
245 /** Annotate that we found our DirPort reachable. */
246 void
248 {
250  const or_options_t *options = get_options();
251  if (!can_reach_dir_port && me) {
252  char *address = tor_dup_ip(me->addr);
253  log_notice(LD_DIRSERV,"Self-testing indicates your DirPort is reachable "
254  "from the outside. Excellent.%s",
255  options->PublishServerDescriptor_ != NO_DIRINFO
256  && check_whether_orport_reachable(options) ?
257  " Publishing server descriptor." : "");
258  can_reach_dir_port = 1;
259  if (router_should_advertise_dirport(options, me->dir_port)) {
260  mark_my_descriptor_dirty("DirPort found reachable");
261  /* This is a significant enough change to upload immediately,
262  * at least in a test network */
263  if (options->TestingTorNetwork == 1) {
265  }
266  }
268  "REACHABILITY_SUCCEEDED DIRADDRESS=%s:%d",
269  address, me->dir_port);
270  tor_free(address);
271  }
272 }
273 
274 /** We have enough testing circuits open. Send a bunch of "drop"
275  * cells down each of them, to exercise our bandwidth. */
276 void
277 router_perform_bandwidth_test(int num_circs, time_t now)
278 {
279  int num_cells = (int)(get_options()->BandwidthRate * 10 /
281  int max_cells = num_cells < CIRCWINDOW_START ?
282  num_cells : CIRCWINDOW_START;
283  int cells_per_circuit = max_cells / num_circs;
284  origin_circuit_t *circ = NULL;
285 
286  log_notice(LD_OR,"Performing bandwidth self-test...done.");
287  while ((circ = circuit_get_next_by_pk_and_purpose(circ, NULL,
289  /* dump cells_per_circuit drop cells onto this circ */
290  int i = cells_per_circuit;
291  if (circ->base_.state != CIRCUIT_STATE_OPEN)
292  continue;
293  circ->base_.timestamp_dirty = now;
294  while (i-- > 0) {
295  if (relay_send_command_from_edge(0, TO_CIRCUIT(circ),
296  RELAY_COMMAND_DROP,
297  NULL, 0, circ->cpath->prev)<0) {
298  return; /* stop if error */
299  }
300  }
301  }
302 }
#define CIRCLAUNCH_IS_INTERNAL
Definition: circuituse.h:46
size_t onion_pkey_len
Definition: routerinfo_st.h:41
Header file for dirclient.c.
uint16_t dir_port
Definition: routerinfo_st.h:26
Router descriptor structure.
void directory_request_set_dir_addr_port(directory_request_t *req, const tor_addr_port_t *p)
Definition: dirclient.c:997
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)
Header file for connection.c.
void router_get_prim_orport(const routerinfo_t *router, tor_addr_port_t *ap_out)
Definition: routerinfo.c:23
Path structures for origin circuits.
static int can_reach_dir_port
Definition: selftest.c:45
void reschedule_descriptor_update_check(void)
#define CIRCWINDOW_START
Definition: or.h:501
uint8_t state
Definition: circuit_st.h:109
Header file for directory.c.
static int router_reachability_checks_disabled(const or_options_t *options)
Definition: selftest.c:60
dirinfo_type_t PublishServerDescriptor_
struct directory_request_t directory_request_t
Definition: dirclient.h:52
#define TO_CIRCUIT(x)
Definition: or.h:951
Header file for config.c.
char identity_digest[DIGEST_LEN]
void router_do_reachability_checks(int test_or, int test_dir)
Definition: selftest.c:172
const or_options_t * get_options(void)
Definition: config.c:941
crypt_path_t * cpath
#define tor_assert(expr)
Definition: util_bug.h:102
struct crypt_path_t * prev
Definition: crypt_path_st.h:75
static int can_reach_or_port
Definition: selftest.c:43
void directory_request_set_directory_id_digest(directory_request_t *req, const char *digest)
Definition: dirclient.c:1007
char * nickname
Definition: routerinfo_st.h:22
#define tor_free(p)
Definition: malloc.h:52
#define LOG_NOTICE
Definition: log.h:50
Header file for mainloop.c.
void directory_request_set_resource(directory_request_t *req, const char *resource)
Definition: dirclient.c:1048
void router_perform_bandwidth_test(int num_circs, time_t now)
Definition: selftest.c:277
Header file for routerset.c.
struct curve25519_public_key_t * onion_curve25519_pkey
Definition: routerinfo_st.h:45
directory_request_t * directory_request_new(uint8_t dir_purpose)
Definition: dirclient.c:951
Header for feature/relay/relay_periodic.c.
#define DIR_PURPOSE_FETCH_SERVERDESC
Definition: directory.h:38
uint64_t BandwidthRate
#define tor_addr_from_ipv4h(dest, v4addr)
Definition: address.h:287
#define LD_CIRC
Definition: log.h:82
int router_should_advertise_dirport(const or_options_t *options, uint16_t dir_port)
Definition: router.c:1303
Origin circuit structure.
#define CIRCUIT_PURPOSE_TESTING
Definition: circuitlist.h:118
int routerset_contains_router(const routerset_t *set, const routerinfo_t *ri, country_t country)
Definition: routerset.c:306
int net_is_disabled(void)
Definition: netstatus.c:25
Master header file for Tor-specific functionality.
#define CIRCUIT_STATE_OPEN
Definition: circuitlist.h:32
#define LD_DIRSERV
Definition: log.h:90
Header file for circuitbuild.c.
const char * fmt_addr32(uint32_t addr)
Definition: address.c:1181
#define LOG_WARN
Definition: log.h:53
Header for netstatus.c.
#define log_fn_ratelim(ratelim, severity, domain, args,...)
Definition: log.h:292
Header file for circuituse.c.
#define CELL_MAX_NETWORK_SIZE
Definition: or.h:579
void mark_my_descriptor_dirty(const char *reason)
Definition: router.c:2421
Header file for circuitlist.c.
#define LD_OR
Definition: log.h:92
#define CIRCLAUNCH_NEED_CAPACITY
Definition: circuituse.h:43
static int router_should_check_reachability(int test_or, int test_dir)
Definition: selftest.c:104
static extend_info_t * extend_info_from_router(const routerinfo_t *r)
Definition: selftest.c:134
const routerinfo_t * router_get_my_routerinfo(void)
Definition: router.c:1623
void router_dirport_found_reachable(void)
Definition: selftest.c:247
origin_circuit_t * circuit_launch_by_extend_info(uint8_t purpose, extend_info_t *extend_info, int flags)
Definition: circuituse.c:2068
Header file for relay.c.
Header file for router.c.
void directory_initiate_request(directory_request_t *request)
Definition: dirclient.c:1238
char * onion_pkey
Definition: routerinfo_st.h:39
connection_t * connection_get_by_type_addr_port_purpose(int type, const tor_addr_t *addr, uint16_t port, int purpose)
Definition: connection.c:4462
time_t timestamp_dirty
Definition: circuit_st.h:186
void directory_request_set_indirection(directory_request_t *req, dir_indirection_t indirection)
Definition: dirclient.c:1035
uint16_t or_port
Definition: routerinfo_st.h:25
Header for torcert.c.
struct tor_cert_st * signing_key_cert
Header file for selftest.c.
#define CONN_TYPE_DIR
Definition: connection.h:35
uint32_t addr
Definition: routerinfo_st.h:24
int control_event_server_status(int severity, const char *format,...)
void router_reset_reachability(void)
Definition: selftest.c:49
origin_circuit_t * circuit_get_next_by_pk_and_purpose(origin_circuit_t *start, const uint8_t *digest, uint8_t purpose)
Definition: circuitlist.c:1810
Header file for routerinfo.c.
int circuit_enough_testing_circs(void)
Definition: circuituse.c:1622
Header file for control_events.c.
void router_orport_found_reachable(void)
Definition: selftest.c:220
Authority certificate structure.
int check_whether_orport_reachable(const or_options_t *options)
Definition: selftest.c:75
void directory_request_set_or_addr_port(directory_request_t *req, const tor_addr_port_t *p)
Definition: dirclient.c:986
Header file for routerlist.c.
int check_whether_dirport_reachable(const or_options_t *options)
Definition: selftest.c:92
routerset_t * ExcludeNodes
Definition: or_options_st.h:81
char * tor_dup_ip(uint32_t addr)
Definition: address.c:1948