tor  0.4.0.1-alpha
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 
15 #define SELFTEST_PRIVATE
16 
17 #include "core/or/or.h"
18 
19 #include "app/config/config.h"
21 #include "core/mainloop/mainloop.h"
22 #include "core/mainloop/netstatus.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"
27 #include "core/or/origin_circuit_st.h"
28 #include "core/or/relay.h"
32 #include "feature/nodelist/authority_cert_st.h"
34 #include "feature/nodelist/routerinfo_st.h"
35 #include "feature/nodelist/routerlist.h" // but...
36 #include "feature/nodelist/routerset.h"
37 #include "feature/nodelist/torcert.h"
38 #include "feature/relay/router.h"
39 #include "feature/relay/selftest.h"
40 
42 static int can_reach_or_port = 0;
44 static int can_reach_dir_port = 0;
45 
47 void
49 {
51 }
52 
58 static int
60 {
61  return options->AssumeReachable ||
62  net_is_disabled();
63 }
64 
73 int
75 {
76  int reach_checks_disabled = router_reachability_checks_disabled(options);
77  return reach_checks_disabled ||
79 }
80 
90 int
92 {
93  int reach_checks_disabled = router_reachability_checks_disabled(options) ||
94  !options->DirPort_set;
95  return reach_checks_disabled ||
97 }
98 
102 static int
103 router_should_check_reachability(int test_or, int test_dir)
104 {
105  const routerinfo_t *me = router_get_my_routerinfo();
106  const or_options_t *options = get_options();
107 
108  if (!me)
109  return 0;
110 
111  if (routerset_contains_router(options->ExcludeNodes, me, -1) &&
112  options->StrictNodes) {
113  /* If we've excluded ourself, and StrictNodes is set, we can't test
114  * ourself. */
115  if (test_or || test_dir) {
116 #define SELF_EXCLUDED_WARN_INTERVAL 3600
117  static ratelim_t warning_limit=RATELIM_INIT(SELF_EXCLUDED_WARN_INTERVAL);
118  log_fn_ratelim(&warning_limit, LOG_WARN, LD_CIRC,
119  "Can't peform self-tests for this relay: we have "
120  "listed ourself in ExcludeNodes, and StrictNodes is set. "
121  "We cannot learn whether we are usable, and will not "
122  "be able to advertise ourself.");
123  }
124  return 0;
125  }
126  return 1;
127 }
128 
132 static extend_info_t *
134 {
135  crypto_pk_t *rsa_pubkey;
136  extend_info_t *info;
137  tor_addr_port_t ap;
138  tor_assert(r);
139 
140  /* Make sure we don't need to check address reachability */
141  tor_assert_nonfatal(router_skip_or_reachability(get_options(), 0));
142 
143  const ed25519_public_key_t *ed_id_key;
144  if (r->cache_info.signing_key_cert)
145  ed_id_key = &r->cache_info.signing_key_cert->signing_key;
146  else
147  ed_id_key = NULL;
148 
149  router_get_prim_orport(r, &ap);
150  rsa_pubkey = router_get_rsa_onion_pkey(r->onion_pkey, r->onion_pkey_len);
151  info = extend_info_new(r->nickname, r->cache_info.identity_digest,
152  ed_id_key,
153  rsa_pubkey, r->onion_curve25519_pkey,
154  &ap.addr, ap.port);
155  crypto_pk_free(rsa_pubkey);
156  return info;
157 }
158 
170 void
171 router_do_reachability_checks(int test_or, int test_dir)
172 {
173  const routerinfo_t *me = router_get_my_routerinfo();
174  const or_options_t *options = get_options();
175  int orport_reachable = check_whether_orport_reachable(options);
176  tor_addr_t addr;
177 
178  if (router_should_check_reachability(test_or, test_dir)) {
179  if (test_or && (!orport_reachable || !circuit_enough_testing_circs())) {
181  /* XXX IPv6 self testing */
182  log_info(LD_CIRC, "Testing %s of my ORPort: %s:%d.",
183  !orport_reachable ? "reachability" : "bandwidth",
184  fmt_addr32(me->addr), me->or_port);
187  extend_info_free(ei);
188  }
189 
190  /* XXX IPv6 self testing */
191  tor_addr_from_ipv4h(&addr, me->addr);
192  if (test_dir && !check_whether_dirport_reachable(options) &&
193  !connection_get_by_type_addr_port_purpose(
194  CONN_TYPE_DIR, &addr, me->dir_port,
196  tor_addr_port_t my_orport, my_dirport;
197  memcpy(&my_orport.addr, &addr, sizeof(addr));
198  memcpy(&my_dirport.addr, &addr, sizeof(addr));
199  my_orport.port = me->or_port;
200  my_dirport.port = me->dir_port;
201  /* ask myself, via tor, for my server descriptor. */
202  directory_request_t *req =
204  directory_request_set_or_addr_port(req, &my_orport);
205  directory_request_set_dir_addr_port(req, &my_dirport);
207  me->cache_info.identity_digest);
208  // ask via an anon circuit, connecting to our dirport.
210  directory_request_set_resource(req, "authority.z");
211  directory_initiate_request(req);
212  directory_request_free(req);
213  }
214  }
215 }
216 
218 void
220 {
221  const routerinfo_t *me = router_get_my_routerinfo();
222  const or_options_t *options = get_options();
223  if (!can_reach_or_port && me) {
224  char *address = tor_dup_ip(me->addr);
225  log_notice(LD_OR,"Self-testing indicates your ORPort is reachable from "
226  "the outside. Excellent.%s",
227  options->PublishServerDescriptor_ != NO_DIRINFO
228  && check_whether_dirport_reachable(options) ?
229  " Publishing server descriptor." : "");
230  can_reach_or_port = 1;
231  mark_my_descriptor_dirty("ORPort found reachable");
232  /* This is a significant enough change to upload immediately,
233  * at least in a test network */
234  if (options->TestingTorNetwork == 1) {
236  }
238  "REACHABILITY_SUCCEEDED ORADDRESS=%s:%d",
239  address, me->or_port);
240  tor_free(address);
241  }
242 }
243 
245 void
247 {
248  const routerinfo_t *me = router_get_my_routerinfo();
249  const or_options_t *options = get_options();
250  if (!can_reach_dir_port && me) {
251  char *address = tor_dup_ip(me->addr);
252  log_notice(LD_DIRSERV,"Self-testing indicates your DirPort is reachable "
253  "from the outside. Excellent.%s",
254  options->PublishServerDescriptor_ != NO_DIRINFO
255  && check_whether_orport_reachable(options) ?
256  " Publishing server descriptor." : "");
257  can_reach_dir_port = 1;
258  if (router_should_advertise_dirport(options, me->dir_port)) {
259  mark_my_descriptor_dirty("DirPort found reachable");
260  /* This is a significant enough change to upload immediately,
261  * at least in a test network */
262  if (options->TestingTorNetwork == 1) {
264  }
265  }
267  "REACHABILITY_SUCCEEDED DIRADDRESS=%s:%d",
268  address, me->dir_port);
269  tor_free(address);
270  }
271 }
272 
275 void
276 router_perform_bandwidth_test(int num_circs, time_t now)
277 {
278  int num_cells = (int)(get_options()->BandwidthRate * 10 /
280  int max_cells = num_cells < CIRCWINDOW_START ?
281  num_cells : CIRCWINDOW_START;
282  int cells_per_circuit = max_cells / num_circs;
283  origin_circuit_t *circ = NULL;
284 
285  log_notice(LD_OR,"Performing bandwidth self-test...done.");
286  while ((circ = circuit_get_next_by_pk_and_purpose(circ, NULL,
288  /* dump cells_per_circuit drop cells onto this circ */
289  int i = cells_per_circuit;
290  if (circ->base_.state != CIRCUIT_STATE_OPEN)
291  continue;
292  circ->base_.timestamp_dirty = now;
293  while (i-- > 0) {
294  if (relay_send_command_from_edge(0, TO_CIRCUIT(circ),
295  RELAY_COMMAND_DROP,
296  NULL, 0, circ->cpath->prev)<0) {
297  return; /* stop if error */
298  }
299  }
300  }
301 }
struct curve25519_public_key_t * onion_curve25519_pkey
Definition: routerinfo_st.h:40
#define CIRCLAUNCH_IS_INTERNAL
Definition: circuituse.h:46
void directory_request_set_dir_addr_port(directory_request_t *req, const tor_addr_port_t *p)
Definition: dirclient.c:992
Header file for dirclient.c.
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.
static int can_reach_dir_port
Definition: selftest.c:44
#define CIRCWINDOW_START
Definition: or.h:501
crypt_path_t * cpath
Header file for directory.c.
static int router_reachability_checks_disabled(const or_options_t *options)
Definition: selftest.c:59
struct directory_request_t directory_request_t
Definition: dirclient.h:52
#define TO_CIRCUIT(x)
Definition: or.h:947
Header file for config.c.
void router_do_reachability_checks(int test_or, int test_dir)
Definition: selftest.c:171
ed25519_public_key_t signing_key
Definition: torcert.h:28
static int can_reach_or_port
Definition: selftest.c:42
#define tor_free(p)
Definition: malloc.h:52
#define LOG_NOTICE
Definition: log.h:46
struct tor_cert_st * signing_key_cert
Header file for mainloop.c.
void router_perform_bandwidth_test(int num_circs, time_t now)
Definition: selftest.c:276
void directory_request_set_indirection(directory_request_t *req, dir_indirection_t indirection)
Definition: dirclient.c:1030
#define DIR_PURPOSE_FETCH_SERVERDESC
Definition: directory.h:38
tor_assert(buffer)
directory_request_t * directory_request_new(uint8_t dir_purpose)
Definition: dirclient.c:946
void reschedule_descriptor_update_check(void)
Definition: mainloop.c:1698
#define tor_addr_from_ipv4h(dest, v4addr)
Definition: address.h:287
time_t timestamp_dirty
Definition: circuit_st.h:152
#define LD_CIRC
Definition: log.h:78
uint8_t state
Definition: circuit_st.h:101
routerset_t * ExcludeNodes
Definition: or_options_st.h:84
int router_should_advertise_dirport(const or_options_t *options, uint16_t dir_port)
Definition: router.c:1306
#define CIRCUIT_PURPOSE_TESTING
Definition: circuitlist.h:115
int routerset_contains_router(const routerset_t *set, const routerinfo_t *ri, country_t country)
Definition: routerset.c:302
Master header file for Tor-specific functionality.
#define CIRCUIT_STATE_OPEN
Definition: circuitlist.h:31
#define LD_DIRSERV
Definition: log.h:86
size_t onion_pkey_len
Definition: routerinfo_st.h:36
Header file for circuitbuild.c.
const char * fmt_addr32(uint32_t addr)
Definition: address.c:1169
#define LOG_WARN
Definition: log.h:49
#define log_fn_ratelim(ratelim, severity, domain, args,...)
Definition: log.h:260
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:2244
Header file for circuitlist.c.
char * onion_pkey
Definition: routerinfo_st.h:34
#define LD_OR
Definition: log.h:88
#define CIRCLAUNCH_NEED_CAPACITY
Definition: circuituse.h:43
static int router_should_check_reachability(int test_or, int test_dir)
Definition: selftest.c:103
struct crypt_path_t * prev
Definition: crypt_path_st.h:61
char identity_digest[DIGEST_LEN]
int control_event_server_status(int severity, const char *format,...)
Definition: control.c:6847
static extend_info_t * extend_info_from_router(const routerinfo_t *r)
Definition: selftest.c:133
void router_dirport_found_reachable(void)
Definition: selftest.c:246
origin_circuit_t * circuit_launch_by_extend_info(uint8_t purpose, extend_info_t *extend_info, int flags)
Definition: circuituse.c:2053
Header file for relay.c.
Header file for router.c.
void directory_request_set_or_addr_port(directory_request_t *req, const tor_addr_port_t *p)
Definition: dirclient.c:981
char * nickname
Definition: routerinfo_st.h:17
uint16_t dir_port
Definition: routerinfo_st.h:21
void router_get_prim_orport(const routerinfo_t *router, tor_addr_port_t *addr_port_out)
Definition: routerinfo.c:18
dirinfo_type_t PublishServerDescriptor_
Header file for control.c.
uint32_t addr
Definition: routerinfo_st.h:19
Header file for selftest.c.
#define CONN_TYPE_DIR
Definition: connection.h:35
void directory_request_set_directory_id_digest(directory_request_t *req, const char *digest)
Definition: dirclient.c:1002
void router_reset_reachability(void)
Definition: selftest.c:48
origin_circuit_t * circuit_get_next_by_pk_and_purpose(origin_circuit_t *start, const uint8_t *digest, uint8_t purpose)
Definition: circuitlist.c:1808
void directory_request_set_resource(directory_request_t *req, const char *resource)
Definition: dirclient.c:1043
Header file for routerinfo.c.
int circuit_enough_testing_circs(void)
Definition: circuituse.c:1607
void router_orport_found_reachable(void)
Definition: selftest.c:219
int check_whether_orport_reachable(const or_options_t *options)
Definition: selftest.c:74
Header file for routerlist.c.
uint16_t or_port
Definition: routerinfo_st.h:20
int check_whether_dirport_reachable(const or_options_t *options)
Definition: selftest.c:91
char * tor_dup_ip(uint32_t addr)
Definition: address.c:1879