selftest.c 11 KB

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