test_router.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. /* Copyright (c) 2017-2019, The Tor Project, Inc. */
  2. /* Copyright (c) 2017, isis agora lovecruft */
  3. /* See LICENSE for licensing information */
  4. /**
  5. * \file test_router.c
  6. * \brief Unittests for code in router.c
  7. **/
  8. #define CONFIG_PRIVATE
  9. #define ROUTER_PRIVATE
  10. #include "core/or/or.h"
  11. #include "app/config/config.h"
  12. #include "core/mainloop/mainloop.h"
  13. #include "feature/hibernate/hibernate.h"
  14. #include "feature/nodelist/networkstatus.h"
  15. #include "feature/nodelist/networkstatus_st.h"
  16. #include "feature/nodelist/node_st.h"
  17. #include "feature/nodelist/nodelist.h"
  18. #include "feature/nodelist/routerinfo_st.h"
  19. #include "feature/nodelist/routerlist.h"
  20. #include "feature/nodelist/routerstatus_st.h"
  21. #include "feature/relay/router.h"
  22. #include "feature/stats/rephist.h"
  23. #include "lib/crypt_ops/crypto_curve25519.h"
  24. #include "lib/crypt_ops/crypto_ed25519.h"
  25. #include "lib/encoding/confline.h"
  26. /* Test suite stuff */
  27. #include "test/test.h"
  28. #include "test/log_test_helpers.h"
  29. NS_DECL(const routerinfo_t *, router_get_my_routerinfo, (void));
  30. static routerinfo_t* mock_routerinfo;
  31. static const routerinfo_t*
  32. NS(router_get_my_routerinfo)(void)
  33. {
  34. crypto_pk_t* ident_key;
  35. crypto_pk_t* tap_key;
  36. time_t now;
  37. if (!mock_routerinfo) {
  38. /* Mock the published timestamp, otherwise router_dump_router_to_string()
  39. * will poop its pants. */
  40. time(&now);
  41. /* We'll need keys, or router_dump_router_to_string() would return NULL. */
  42. ident_key = pk_generate(0);
  43. tap_key = pk_generate(0);
  44. tor_assert(ident_key != NULL);
  45. tor_assert(tap_key != NULL);
  46. mock_routerinfo = tor_malloc_zero(sizeof(routerinfo_t));
  47. mock_routerinfo->nickname = tor_strdup("ConlonNancarrow");
  48. mock_routerinfo->addr = 123456789;
  49. mock_routerinfo->or_port = 443;
  50. mock_routerinfo->platform = tor_strdup("unittest");
  51. mock_routerinfo->cache_info.published_on = now;
  52. mock_routerinfo->identity_pkey = crypto_pk_dup_key(ident_key);
  53. router_set_rsa_onion_pkey(tap_key, &mock_routerinfo->onion_pkey,
  54. &mock_routerinfo->onion_pkey_len);
  55. mock_routerinfo->bandwidthrate = 9001;
  56. mock_routerinfo->bandwidthburst = 9002;
  57. crypto_pk_free(ident_key);
  58. crypto_pk_free(tap_key);
  59. }
  60. return mock_routerinfo;
  61. }
  62. /* If no distribution option was set, then check_bridge_distribution_setting()
  63. * should have set it to "any". */
  64. static void
  65. test_router_dump_router_to_string_no_bridge_distribution_method(void *arg)
  66. {
  67. const char* needle = "bridge-distribution-request any";
  68. or_options_t* options = get_options_mutable();
  69. routerinfo_t* router = NULL;
  70. curve25519_keypair_t ntor_keypair;
  71. ed25519_keypair_t signing_keypair;
  72. char* desc = NULL;
  73. char* found = NULL;
  74. (void)arg;
  75. NS_MOCK(router_get_my_routerinfo);
  76. options->ORPort_set = 1;
  77. options->BridgeRelay = 1;
  78. /* Generate keys which router_dump_router_to_string() expects to exist. */
  79. tt_int_op(0, ==, curve25519_keypair_generate(&ntor_keypair, 0));
  80. tt_int_op(0, ==, ed25519_keypair_generate(&signing_keypair, 0));
  81. /* Set up part of our routerinfo_t so that we don't trigger any other
  82. * assertions in router_dump_router_to_string(). */
  83. router = (routerinfo_t*)router_get_my_routerinfo();
  84. tt_ptr_op(router, !=, NULL);
  85. router->onion_curve25519_pkey = &ntor_keypair.pubkey;
  86. /* Generate our server descriptor and ensure that the substring
  87. * "bridge-distribution-request any" occurs somewhere within it. */
  88. crypto_pk_t *onion_pkey = router_get_rsa_onion_pkey(router->onion_pkey,
  89. router->onion_pkey_len);
  90. desc = router_dump_router_to_string(router,
  91. router->identity_pkey,
  92. onion_pkey,
  93. &ntor_keypair,
  94. &signing_keypair);
  95. crypto_pk_free(onion_pkey);
  96. tt_ptr_op(desc, !=, NULL);
  97. found = strstr(desc, needle);
  98. tt_ptr_op(found, !=, NULL);
  99. done:
  100. NS_UNMOCK(router_get_my_routerinfo);
  101. tor_free(desc);
  102. }
  103. static routerinfo_t *mock_router_get_my_routerinfo_result = NULL;
  104. static const routerinfo_t *
  105. mock_router_get_my_routerinfo(void)
  106. {
  107. return mock_router_get_my_routerinfo_result;
  108. }
  109. static long
  110. mock_get_uptime_3h(void)
  111. {
  112. return 3*60*60;
  113. }
  114. static long
  115. mock_get_uptime_1d(void)
  116. {
  117. return 24*60*60;
  118. }
  119. static int
  120. mock_rep_hist_bandwidth_assess(void)
  121. {
  122. return 20001;
  123. }
  124. static int
  125. mock_we_are_not_hibernating(void)
  126. {
  127. return 0;
  128. }
  129. static int
  130. mock_we_are_hibernating(void)
  131. {
  132. return 0;
  133. }
  134. static void
  135. test_router_check_descriptor_bandwidth_changed(void *arg)
  136. {
  137. (void)arg;
  138. routerinfo_t routerinfo;
  139. memset(&routerinfo, 0, sizeof(routerinfo));
  140. mock_router_get_my_routerinfo_result = NULL;
  141. MOCK(we_are_hibernating, mock_we_are_not_hibernating);
  142. MOCK(router_get_my_routerinfo, mock_router_get_my_routerinfo);
  143. mock_router_get_my_routerinfo_result = &routerinfo;
  144. /* When uptime is less than 24h, no previous bandwidth, no last_changed
  145. * Uptime: 10800, last_changed: 0, Previous bw: 0, Current bw: 0 */
  146. routerinfo.bandwidthcapacity = 0;
  147. MOCK(get_uptime, mock_get_uptime_3h);
  148. setup_full_capture_of_logs(LOG_INFO);
  149. check_descriptor_bandwidth_changed(time(NULL));
  150. expect_log_msg_not_containing(
  151. "Measured bandwidth has changed; rebuilding descriptor.");
  152. teardown_capture_of_logs();
  153. /* When uptime is less than 24h, previous bandwidth,
  154. * last_changed more than 3h ago
  155. * Uptime: 10800, last_changed: 0, Previous bw: 10000, Current bw: 0 */
  156. routerinfo.bandwidthcapacity = 10000;
  157. setup_full_capture_of_logs(LOG_INFO);
  158. check_descriptor_bandwidth_changed(time(NULL));
  159. expect_log_msg_containing(
  160. "Measured bandwidth has changed; rebuilding descriptor.");
  161. teardown_capture_of_logs();
  162. /* When uptime is less than 24h, previous bandwidth,
  163. * last_changed more than 3h ago, and hibernating
  164. * Uptime: 10800, last_changed: 0, Previous bw: 10000, Current bw: 0 */
  165. UNMOCK(we_are_hibernating);
  166. MOCK(we_are_hibernating, mock_we_are_hibernating);
  167. routerinfo.bandwidthcapacity = 10000;
  168. setup_full_capture_of_logs(LOG_INFO);
  169. check_descriptor_bandwidth_changed(time(NULL));
  170. expect_log_msg_not_containing(
  171. "Measured bandwidth has changed; rebuilding descriptor.");
  172. teardown_capture_of_logs();
  173. UNMOCK(we_are_hibernating);
  174. MOCK(we_are_hibernating, mock_we_are_not_hibernating);
  175. /* When uptime is less than 24h, last_changed is not more than 3h ago
  176. * Uptime: 10800, last_changed: x, Previous bw: 10000, Current bw: 0 */
  177. setup_full_capture_of_logs(LOG_INFO);
  178. check_descriptor_bandwidth_changed(time(NULL));
  179. expect_log_msg_not_containing(
  180. "Measured bandwidth has changed; rebuilding descriptor.");
  181. teardown_capture_of_logs();
  182. /* When uptime is less than 24h and bandwidthcapacity does not change
  183. * Uptime: 10800, last_changed: x, Previous bw: 10000, Current bw: 20001 */
  184. MOCK(rep_hist_bandwidth_assess, mock_rep_hist_bandwidth_assess);
  185. setup_full_capture_of_logs(LOG_INFO);
  186. check_descriptor_bandwidth_changed(time(NULL) + 6*60*60 + 1);
  187. expect_log_msg_containing(
  188. "Measured bandwidth has changed; rebuilding descriptor.");
  189. UNMOCK(get_uptime);
  190. UNMOCK(rep_hist_bandwidth_assess);
  191. teardown_capture_of_logs();
  192. /* When uptime is more than 24h */
  193. MOCK(get_uptime, mock_get_uptime_1d);
  194. setup_full_capture_of_logs(LOG_INFO);
  195. check_descriptor_bandwidth_changed(time(NULL));
  196. expect_log_msg_not_containing(
  197. "Measured bandwidth has changed; rebuilding descriptor.");
  198. teardown_capture_of_logs();
  199. done:
  200. UNMOCK(get_uptime);
  201. UNMOCK(router_get_my_routerinfo);
  202. UNMOCK(we_are_hibernating);
  203. }
  204. static networkstatus_t *mock_ns = NULL;
  205. static networkstatus_t *
  206. mock_networkstatus_get_live_consensus(time_t now)
  207. {
  208. (void)now;
  209. return mock_ns;
  210. }
  211. static routerstatus_t *mock_rs = NULL;
  212. static const routerstatus_t *
  213. mock_networkstatus_vote_find_entry(networkstatus_t *ns, const char *digest)
  214. {
  215. (void)ns;
  216. (void)digest;
  217. return mock_rs;
  218. }
  219. static void
  220. test_router_mark_if_too_old(void *arg)
  221. {
  222. (void)arg;
  223. time_t now = approx_time();
  224. MOCK(networkstatus_get_live_consensus,
  225. mock_networkstatus_get_live_consensus);
  226. MOCK(networkstatus_vote_find_entry, mock_networkstatus_vote_find_entry);
  227. routerstatus_t rs;
  228. networkstatus_t ns;
  229. memset(&rs, 0, sizeof(rs));
  230. memset(&ns, 0, sizeof(ns));
  231. mock_ns = &ns;
  232. mock_ns->valid_after = now-3600;
  233. mock_rs = &rs;
  234. mock_rs->published_on = now - 10;
  235. // no reason to mark this time.
  236. desc_clean_since = now-10;
  237. desc_dirty_reason = NULL;
  238. mark_my_descriptor_dirty_if_too_old(now);
  239. tt_i64_op(desc_clean_since, OP_EQ, now-10);
  240. // Doesn't appear in consensus? Still don't mark it.
  241. mock_ns = NULL;
  242. mark_my_descriptor_dirty_if_too_old(now);
  243. tt_i64_op(desc_clean_since, OP_EQ, now-10);
  244. mock_ns = &ns;
  245. // No new descriptor in a long time? Mark it.
  246. desc_clean_since = now - 3600 * 96;
  247. mark_my_descriptor_dirty_if_too_old(now);
  248. tt_i64_op(desc_clean_since, OP_EQ, 0);
  249. tt_str_op(desc_dirty_reason, OP_EQ, "time for new descriptor");
  250. // Version in consensus published a long time ago? We won't mark it
  251. // if it's been clean for only a short time.
  252. desc_clean_since = now - 10;
  253. desc_dirty_reason = NULL;
  254. mock_rs->published_on = now - 3600 * 96;
  255. mark_my_descriptor_dirty_if_too_old(now);
  256. tt_i64_op(desc_clean_since, OP_EQ, now - 10);
  257. // ... but if it's been clean a while, we mark.
  258. desc_clean_since = now - 2 * 3600;
  259. mark_my_descriptor_dirty_if_too_old(now);
  260. tt_i64_op(desc_clean_since, OP_EQ, 0);
  261. tt_str_op(desc_dirty_reason, OP_EQ,
  262. "version listed in consensus is quite old");
  263. // same deal if we're marked stale.
  264. desc_clean_since = now - 2 * 3600;
  265. desc_dirty_reason = NULL;
  266. mock_rs->published_on = now - 10;
  267. mock_rs->is_staledesc = 1;
  268. mark_my_descriptor_dirty_if_too_old(now);
  269. tt_i64_op(desc_clean_since, OP_EQ, 0);
  270. tt_str_op(desc_dirty_reason, OP_EQ,
  271. "listed as stale in consensus");
  272. // same deal if we're absent from the consensus.
  273. desc_clean_since = now - 2 * 3600;
  274. desc_dirty_reason = NULL;
  275. mock_rs = NULL;
  276. mark_my_descriptor_dirty_if_too_old(now);
  277. tt_i64_op(desc_clean_since, OP_EQ, 0);
  278. tt_str_op(desc_dirty_reason, OP_EQ,
  279. "not listed in consensus");
  280. done:
  281. UNMOCK(networkstatus_get_live_consensus);
  282. UNMOCK(networkstatus_vote_find_entry);
  283. }
  284. static node_t fake_node;
  285. static const node_t *
  286. mock_node_get_by_nickname(const char *name, unsigned flags)
  287. {
  288. (void)flags;
  289. if (!strcasecmp(name, "crumpet"))
  290. return &fake_node;
  291. else
  292. return NULL;
  293. }
  294. static void
  295. test_router_get_my_family(void *arg)
  296. {
  297. (void)arg;
  298. or_options_t *options = options_new();
  299. smartlist_t *sl = NULL;
  300. char *join = NULL;
  301. // Overwrite the result of router_get_my_identity_digest(). This
  302. // happens to be okay, but only for testing.
  303. set_server_identity_key_digest_testing(
  304. (const uint8_t*)"holeinthebottomofthe");
  305. setup_capture_of_logs(LOG_WARN);
  306. // No family listed -- so there's no list.
  307. sl = get_my_declared_family(options);
  308. tt_ptr_op(sl, OP_EQ, NULL);
  309. expect_no_log_entry();
  310. #define CLEAR() do { \
  311. if (sl) { \
  312. SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp)); \
  313. smartlist_free(sl); \
  314. } \
  315. tor_free(join); \
  316. mock_clean_saved_logs(); \
  317. } while (0)
  318. // Add a single nice friendly hex member. This should be enough
  319. // to have our own ID added.
  320. tt_ptr_op(options->MyFamily, OP_EQ, NULL);
  321. config_line_append(&options->MyFamily, "MyFamily",
  322. "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
  323. sl = get_my_declared_family(options);
  324. tt_ptr_op(sl, OP_NE, NULL);
  325. tt_int_op(smartlist_len(sl), OP_EQ, 2);
  326. join = smartlist_join_strings(sl, " ", 0, NULL);
  327. tt_str_op(join, OP_EQ,
  328. "$686F6C65696E746865626F74746F6D6F66746865 "
  329. "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
  330. expect_no_log_entry();
  331. CLEAR();
  332. // Add a hex member with a ~. The ~ part should get removed.
  333. config_line_append(&options->MyFamily, "MyFamily",
  334. "$0123456789abcdef0123456789abcdef01234567~Muffin");
  335. sl = get_my_declared_family(options);
  336. tt_ptr_op(sl, OP_NE, NULL);
  337. tt_int_op(smartlist_len(sl), OP_EQ, 3);
  338. join = smartlist_join_strings(sl, " ", 0, NULL);
  339. tt_str_op(join, OP_EQ,
  340. "$0123456789ABCDEF0123456789ABCDEF01234567 "
  341. "$686F6C65696E746865626F74746F6D6F66746865 "
  342. "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
  343. expect_no_log_entry();
  344. CLEAR();
  345. // Nickname lookup will fail, so a nickname will appear verbatim.
  346. config_line_append(&options->MyFamily, "MyFamily",
  347. "BAGEL");
  348. sl = get_my_declared_family(options);
  349. tt_ptr_op(sl, OP_NE, NULL);
  350. tt_int_op(smartlist_len(sl), OP_EQ, 4);
  351. join = smartlist_join_strings(sl, " ", 0, NULL);
  352. tt_str_op(join, OP_EQ,
  353. "$0123456789ABCDEF0123456789ABCDEF01234567 "
  354. "$686F6C65696E746865626F74746F6D6F66746865 "
  355. "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "
  356. "bagel");
  357. expect_single_log_msg_containing(
  358. "There is a router named \"BAGEL\" in my declared family, but "
  359. "I have no descriptor for it.");
  360. CLEAR();
  361. // A bogus digest should fail entirely.
  362. config_line_append(&options->MyFamily, "MyFamily",
  363. "$painauchocolat");
  364. sl = get_my_declared_family(options);
  365. tt_ptr_op(sl, OP_NE, NULL);
  366. tt_int_op(smartlist_len(sl), OP_EQ, 4);
  367. join = smartlist_join_strings(sl, " ", 0, NULL);
  368. tt_str_op(join, OP_EQ,
  369. "$0123456789ABCDEF0123456789ABCDEF01234567 "
  370. "$686F6C65696E746865626F74746F6D6F66746865 "
  371. "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "
  372. "bagel");
  373. // "BAGEL" is still there, but it won't make a warning, because we already
  374. // warned about it.
  375. expect_single_log_msg_containing(
  376. "There is a router named \"$painauchocolat\" in my declared "
  377. "family, but that isn't a legal digest or nickname. Skipping it.");
  378. CLEAR();
  379. // Let's introduce a node we can look up by nickname
  380. memset(&fake_node, 0, sizeof(fake_node));
  381. memcpy(fake_node.identity, "whydoyouasknonononon", DIGEST_LEN);
  382. MOCK(node_get_by_nickname, mock_node_get_by_nickname);
  383. config_line_append(&options->MyFamily, "MyFamily",
  384. "CRUmpeT");
  385. sl = get_my_declared_family(options);
  386. tt_ptr_op(sl, OP_NE, NULL);
  387. tt_int_op(smartlist_len(sl), OP_EQ, 5);
  388. join = smartlist_join_strings(sl, " ", 0, NULL);
  389. tt_str_op(join, OP_EQ,
  390. "$0123456789ABCDEF0123456789ABCDEF01234567 "
  391. "$686F6C65696E746865626F74746F6D6F66746865 "
  392. "$776879646F796F7561736B6E6F6E6F6E6F6E6F6E "
  393. "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "
  394. "bagel");
  395. // "BAGEL" is still there, but it won't make a warning, because we already
  396. // warned about it. Some with "$painauchocolat".
  397. expect_single_log_msg_containing(
  398. "There is a router named \"CRUmpeT\" in my declared "
  399. "family, but it wasn't listed by digest. Please consider saying "
  400. "$776879646F796F7561736B6E6F6E6F6E6F6E6F6E instead, if that's "
  401. "what you meant.");
  402. CLEAR();
  403. UNMOCK(node_get_by_nickname);
  404. // Try a singleton list containing only us: It should give us NULL.
  405. config_free_lines(options->MyFamily);
  406. config_line_append(&options->MyFamily, "MyFamily",
  407. "$686F6C65696E746865626F74746F6D6F66746865");
  408. sl = get_my_declared_family(options);
  409. tt_ptr_op(sl, OP_EQ, NULL);
  410. expect_no_log_entry();
  411. done:
  412. or_options_free(options);
  413. teardown_capture_of_logs();
  414. CLEAR();
  415. UNMOCK(node_get_by_nickname);
  416. #undef CLEAR
  417. }
  418. #define ROUTER_TEST(name, flags) \
  419. { #name, test_router_ ## name, flags, NULL, NULL }
  420. struct testcase_t router_tests[] = {
  421. ROUTER_TEST(check_descriptor_bandwidth_changed, TT_FORK),
  422. ROUTER_TEST(dump_router_to_string_no_bridge_distribution_method, TT_FORK),
  423. ROUTER_TEST(mark_if_too_old, TT_FORK),
  424. ROUTER_TEST(get_my_family, TT_FORK),
  425. END_OF_TESTCASES
  426. };