networkstatus.c 58 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719
  1. /* Copyright (c) 2001 Matej Pfajfar.
  2. * Copyright (c) 2001-2004, Roger Dingledine.
  3. * Copyright (c) 2004-2007, Roger Dingledine, Nick Mathewson. */
  4. /* See LICENSE for licensing information */
  5. /* $Id$ */
  6. const char networkstatus_c_id[] =
  7. "$Id$";
  8. /**
  9. * DOCDOC
  10. */
  11. #include "or.h"
  12. /** Global list of routerstatus_t for each router, known or unknown.
  13. * Kept sorted by digest. */
  14. static smartlist_t *routerstatus_list = NULL;
  15. /** Map from descriptor digest to a member of routerstatus_list: used to
  16. * update download status when a download fails. */
  17. static digestmap_t *routerstatus_by_desc_digest_map = NULL;
  18. /** True iff any element of routerstatus_list has changed since the last
  19. * time we called routers_update_all_from_networkstatus().*/
  20. static int routerstatus_list_has_changed = 0;
  21. /** Map from lowercase nickname to digest of named server, if any. */
  22. static strmap_t *named_server_map = NULL;
  23. /** Global list of all of the current network_status documents that we know
  24. * about. This list is kept sorted by published_on. */
  25. static smartlist_t *networkstatus_list = NULL;
  26. /** Most recently received and validated v3 consensus network status. */
  27. static networkstatus_vote_t *current_consensus = NULL;
  28. /** A v3 consensus networkstatus that we've received, but which we don't
  29. * have enough certificates to be happy about. */
  30. static networkstatus_vote_t *consensus_waiting_for_certs = NULL;
  31. static char *consensus_waiting_for_certs_body = NULL;
  32. /** True iff any member of networkstatus_list has changed since the last time
  33. * we called routerstatus_list_update_from_networkstatus(). */
  34. static int networkstatus_list_has_changed = 0;
  35. /** The last time we tried to download a networkstatus, or 0 for "never". We
  36. * use this to rate-limit download attempts for directory caches (including
  37. * mirrors). Clients don't use this now. */
  38. static time_t last_networkstatus_download_attempted = 0;
  39. /**DOCDOC*/
  40. static time_t time_to_download_next_consensus = 0;
  41. /**DOCDOC*/
  42. static download_status_t consensus_dl_status = { 0, 0};
  43. /** List of strings for nicknames or fingerprints we've already warned about
  44. * and that are still conflicted. */ /*XXXX020 obsoleted by v3 dirs? */
  45. static smartlist_t *warned_conflicts = NULL;
  46. /** True iff we have logged a warning about this OR not being valid or
  47. * not being named. */
  48. static int have_warned_about_invalid_status = 0;
  49. /** True iff we have logged a warning about this OR's version being older than
  50. * listed by the authorities */
  51. static int have_warned_about_old_version = 0;
  52. /** True iff we have logged a warning about this OR's version being newer than
  53. * listed by the authorities */
  54. static int have_warned_about_new_version = 0;
  55. static int have_tried_downloading_all_statuses(int n_failures);
  56. /** DOCDOC */
  57. void
  58. networkstatus_reset_warnings(void)
  59. {
  60. if (!routerstatus_list)
  61. routerstatus_list = smartlist_create();
  62. SMARTLIST_FOREACH(routerstatus_list, routerstatus_t *, rs,
  63. rs->name_lookup_warned = 0);
  64. if (!warned_conflicts)
  65. warned_conflicts = smartlist_create();
  66. SMARTLIST_FOREACH(warned_conflicts, char *, cp, tor_free(cp));
  67. smartlist_clear(warned_conflicts); /* now the list is empty. */
  68. have_warned_about_invalid_status = 0;
  69. have_warned_about_old_version = 0;
  70. have_warned_about_new_version = 0;
  71. }
  72. /** Repopulate our list of network_status_t objects from the list cached on
  73. * disk. Return 0 on success, -1 on failure. */
  74. int
  75. router_reload_networkstatus(void)
  76. {
  77. char filename[512];
  78. smartlist_t *entries;
  79. struct stat st;
  80. char *s;
  81. tor_assert(get_options()->DataDirectory);
  82. if (!networkstatus_list)
  83. networkstatus_list = smartlist_create();
  84. tor_snprintf(filename,sizeof(filename),"%s"PATH_SEPARATOR"cached-status",
  85. get_options()->DataDirectory);
  86. entries = tor_listdir(filename);
  87. SMARTLIST_FOREACH(entries, const char *, fn, {
  88. char buf[DIGEST_LEN];
  89. if (strlen(fn) != HEX_DIGEST_LEN ||
  90. base16_decode(buf, sizeof(buf), fn, strlen(fn))) {
  91. log_info(LD_DIR,
  92. "Skipping cached-status file with unexpected name \"%s\"",fn);
  93. continue;
  94. }
  95. tor_snprintf(filename,sizeof(filename),
  96. "%s"PATH_SEPARATOR"cached-status"PATH_SEPARATOR"%s",
  97. get_options()->DataDirectory, fn);
  98. s = read_file_to_str(filename, 0, &st);
  99. if (s) {
  100. if (router_set_networkstatus(s, st.st_mtime, NS_FROM_CACHE, NULL)<0) {
  101. log_warn(LD_FS, "Couldn't load networkstatus from \"%s\"",filename);
  102. }
  103. tor_free(s);
  104. }
  105. });
  106. SMARTLIST_FOREACH(entries, char *, fn, tor_free(fn));
  107. smartlist_free(entries);
  108. networkstatus_list_clean(time(NULL));
  109. routers_update_all_from_networkstatus(time(NULL));
  110. return 0;
  111. }
  112. /** Read the cached v3 consensus networkstatus from the disk. */
  113. int
  114. router_reload_consensus_networkstatus(void)
  115. {
  116. char filename[512];
  117. char *s;
  118. /* XXXX020 Suppress warnings if cached consensus is bad. */
  119. tor_snprintf(filename,sizeof(filename),"%s"PATH_SEPARATOR"cached-consensus",
  120. get_options()->DataDirectory);
  121. s = read_file_to_str(filename, RFTS_IGNORE_MISSING, NULL);
  122. if (s) {
  123. if (networkstatus_set_current_consensus(s, 1, 0)) {
  124. log_warn(LD_FS, "Couldn't load consensus networkstatus from \"%s\"",
  125. filename);
  126. }
  127. tor_free(s);
  128. }
  129. tor_snprintf(filename,sizeof(filename),
  130. "%s"PATH_SEPARATOR"unverified-consensus",
  131. get_options()->DataDirectory);
  132. s = read_file_to_str(filename, RFTS_IGNORE_MISSING, NULL);
  133. if (s) {
  134. if (networkstatus_set_current_consensus(s, 1, 1)) {
  135. log_warn(LD_FS, "Couldn't load consensus networkstatus from \"%s\"",
  136. filename);
  137. }
  138. tor_free(s);
  139. }
  140. return 0;
  141. }
  142. /** Free all storage held by the routerstatus object <b>rs</b>. */
  143. void
  144. routerstatus_free(routerstatus_t *rs)
  145. {
  146. tor_free(rs);
  147. }
  148. /** Free all storage held by the networkstatus object <b>ns</b>. */
  149. void
  150. networkstatus_free(networkstatus_t *ns)
  151. {
  152. tor_free(ns->source_address);
  153. tor_free(ns->contact);
  154. if (ns->signing_key)
  155. crypto_free_pk_env(ns->signing_key);
  156. tor_free(ns->client_versions);
  157. tor_free(ns->server_versions);
  158. if (ns->entries) {
  159. SMARTLIST_FOREACH(ns->entries, routerstatus_t *, rs,
  160. routerstatus_free(rs));
  161. smartlist_free(ns->entries);
  162. }
  163. tor_free(ns);
  164. }
  165. /** Helper: return a newly allocated string containing the name of the filename
  166. * where we plan to cache the network status with the given identity digest. */
  167. char *
  168. networkstatus_get_cache_filename(const char *identity_digest)
  169. {
  170. const char *datadir = get_options()->DataDirectory;
  171. size_t len = strlen(datadir)+64;
  172. char fp[HEX_DIGEST_LEN+1];
  173. char *fn = tor_malloc(len+1);
  174. base16_encode(fp, HEX_DIGEST_LEN+1, identity_digest, DIGEST_LEN);
  175. tor_snprintf(fn, len, "%s"PATH_SEPARATOR"cached-status"PATH_SEPARATOR"%s",
  176. datadir,fp);
  177. return fn;
  178. }
  179. /** Helper for smartlist_sort: Compare two networkstatus objects by
  180. * publication date. */
  181. static int
  182. _compare_networkstatus_published_on(const void **_a, const void **_b)
  183. {
  184. const networkstatus_t *a = *_a, *b = *_b;
  185. if (a->published_on < b->published_on)
  186. return -1;
  187. else if (a->published_on > b->published_on)
  188. return 1;
  189. else
  190. return 0;
  191. }
  192. /** Add the parsed neworkstatus in <b>ns</b> (with original document in
  193. * <b>s</b>) to the disk cache (and the in-memory directory server cache) as
  194. * appropriate. */
  195. static int
  196. add_networkstatus_to_cache(const char *s,
  197. networkstatus_source_t source,
  198. networkstatus_t *ns)
  199. {
  200. if (source != NS_FROM_CACHE) {
  201. char *fn = networkstatus_get_cache_filename(ns->identity_digest);
  202. if (write_str_to_file(fn, s, 0)<0) {
  203. log_notice(LD_FS, "Couldn't write cached network status to \"%s\"", fn);
  204. }
  205. tor_free(fn);
  206. }
  207. if (dirserver_mode(get_options()))
  208. dirserv_set_cached_networkstatus_v2(s,
  209. ns->identity_digest,
  210. ns->published_on);
  211. return 0;
  212. }
  213. /** How far in the future do we allow a network-status to get before removing
  214. * it? (seconds) */
  215. #define NETWORKSTATUS_ALLOW_SKEW (24*60*60)
  216. /** Given a string <b>s</b> containing a network status that we received at
  217. * <b>arrived_at</b> from <b>source</b>, try to parse it, see if we want to
  218. * store it, and put it into our cache as necessary.
  219. *
  220. * If <b>source</b> is NS_FROM_DIR or NS_FROM_CACHE, do not replace our
  221. * own networkstatus_t (if we're an authoritative directory server).
  222. *
  223. * If <b>source</b> is NS_FROM_CACHE, do not write our networkstatus_t to the
  224. * cache.
  225. *
  226. * If <b>requested_fingerprints</b> is provided, it must contain a list of
  227. * uppercased identity fingerprints. Do not update any networkstatus whose
  228. * fingerprint is not on the list; after updating a networkstatus, remove its
  229. * fingerprint from the list.
  230. *
  231. * Return 0 on success, -1 on failure.
  232. *
  233. * Callers should make sure that routers_update_all_from_networkstatus() is
  234. * invoked after this function succeeds.
  235. */
  236. int
  237. router_set_networkstatus(const char *s, time_t arrived_at,
  238. networkstatus_source_t source, smartlist_t *requested_fingerprints)
  239. {
  240. networkstatus_t *ns;
  241. int i, found;
  242. time_t now;
  243. int skewed = 0;
  244. trusted_dir_server_t *trusted_dir = NULL;
  245. const char *source_desc = NULL;
  246. char fp[HEX_DIGEST_LEN+1];
  247. char published[ISO_TIME_LEN+1];
  248. ns = networkstatus_parse_from_string(s);
  249. if (!ns) {
  250. log_warn(LD_DIR, "Couldn't parse network status.");
  251. return -1;
  252. }
  253. base16_encode(fp, HEX_DIGEST_LEN+1, ns->identity_digest, DIGEST_LEN);
  254. if (!(trusted_dir =
  255. router_get_trusteddirserver_by_digest(ns->identity_digest)) ||
  256. !(trusted_dir->type & V2_AUTHORITY)) {
  257. log_info(LD_DIR, "Network status was signed, but not by an authoritative "
  258. "directory we recognize.");
  259. if (!dirserver_mode(get_options())) {
  260. networkstatus_free(ns);
  261. return 0;
  262. }
  263. source_desc = fp;
  264. } else {
  265. source_desc = trusted_dir->description;
  266. }
  267. now = time(NULL);
  268. if (arrived_at > now)
  269. arrived_at = now;
  270. ns->received_on = arrived_at;
  271. format_iso_time(published, ns->published_on);
  272. if (ns->published_on > now + NETWORKSTATUS_ALLOW_SKEW) {
  273. log_warn(LD_GENERAL, "Network status from %s was published in the future "
  274. "(%s GMT). Check your system clock! "
  275. "Not caching.",
  276. source_desc, published);
  277. control_event_general_status(LOG_WARN,
  278. "CLOCK_SKEW SOURCE=NETWORKSTATUS:%s:%d",
  279. ns->source_address, ns->source_dirport);
  280. skewed = 1;
  281. }
  282. if (!networkstatus_list)
  283. networkstatus_list = smartlist_create();
  284. if ( (source == NS_FROM_DIR_BY_FP || source == NS_FROM_DIR_ALL) &&
  285. router_digest_is_me(ns->identity_digest)) {
  286. /* Don't replace our own networkstatus when we get it from somebody else.*/
  287. networkstatus_free(ns);
  288. return 0;
  289. }
  290. if (requested_fingerprints) {
  291. if (smartlist_string_isin(requested_fingerprints, fp)) {
  292. smartlist_string_remove(requested_fingerprints, fp);
  293. } else {
  294. if (source != NS_FROM_DIR_ALL) {
  295. char *requested =
  296. smartlist_join_strings(requested_fingerprints," ",0,NULL);
  297. log_warn(LD_DIR,
  298. "We received a network status with a fingerprint (%s) that we "
  299. "never requested. (We asked for: %s.) Dropping.",
  300. fp, requested);
  301. tor_free(requested);
  302. return 0;
  303. }
  304. }
  305. }
  306. if (!trusted_dir) {
  307. if (!skewed && dirserver_mode(get_options())) {
  308. /* We got a non-trusted networkstatus, and we're a directory cache.
  309. * This means that we asked an authority, and it told us about another
  310. * authority we didn't recognize. */
  311. log_info(LD_DIR,
  312. "We do not recognize authority (%s) but we are willing "
  313. "to cache it.", fp);
  314. add_networkstatus_to_cache(s, source, ns);
  315. networkstatus_free(ns);
  316. }
  317. return 0;
  318. }
  319. found = 0;
  320. for (i=0; i < smartlist_len(networkstatus_list); ++i) {
  321. networkstatus_t *old_ns = smartlist_get(networkstatus_list, i);
  322. if (!memcmp(old_ns->identity_digest, ns->identity_digest, DIGEST_LEN)) {
  323. if (!memcmp(old_ns->networkstatus_digest,
  324. ns->networkstatus_digest, DIGEST_LEN)) {
  325. /* Same one we had before. */
  326. networkstatus_free(ns);
  327. tor_assert(trusted_dir);
  328. log_info(LD_DIR,
  329. "Not replacing network-status from %s (published %s); "
  330. "we already have it.",
  331. trusted_dir->description, published);
  332. if (old_ns->received_on < arrived_at) {
  333. if (source != NS_FROM_CACHE) {
  334. char *fn;
  335. fn = networkstatus_get_cache_filename(old_ns->identity_digest);
  336. /* We use mtime to tell when it arrived, so update that. */
  337. touch_file(fn);
  338. tor_free(fn);
  339. }
  340. old_ns->received_on = arrived_at;
  341. }
  342. download_status_failed(&trusted_dir->v2_ns_dl_status, 0);
  343. return 0;
  344. } else if (old_ns->published_on >= ns->published_on) {
  345. char old_published[ISO_TIME_LEN+1];
  346. format_iso_time(old_published, old_ns->published_on);
  347. tor_assert(trusted_dir);
  348. log_info(LD_DIR,
  349. "Not replacing network-status from %s (published %s);"
  350. " we have a newer one (published %s) for this authority.",
  351. trusted_dir->description, published,
  352. old_published);
  353. networkstatus_free(ns);
  354. download_status_failed(&trusted_dir->v2_ns_dl_status, 0);
  355. return 0;
  356. } else {
  357. networkstatus_free(old_ns);
  358. smartlist_set(networkstatus_list, i, ns);
  359. found = 1;
  360. break;
  361. }
  362. }
  363. }
  364. if (source != NS_FROM_CACHE && trusted_dir) {
  365. download_status_reset(&trusted_dir->v2_ns_dl_status);
  366. }
  367. if (!found)
  368. smartlist_add(networkstatus_list, ns);
  369. SMARTLIST_FOREACH(ns->entries, routerstatus_t *, rs,
  370. {
  371. if (!router_get_by_descriptor_digest(rs->descriptor_digest))
  372. rs->need_to_mirror = 1;
  373. });
  374. log_info(LD_DIR, "Setting networkstatus %s %s (published %s)",
  375. source == NS_FROM_CACHE?"cached from":
  376. ((source == NS_FROM_DIR_BY_FP || source == NS_FROM_DIR_ALL) ?
  377. "downloaded from":"generated for"),
  378. trusted_dir->description, published);
  379. networkstatus_list_has_changed = 1;
  380. router_dir_info_changed();
  381. smartlist_sort(networkstatus_list, _compare_networkstatus_published_on);
  382. if (!skewed)
  383. add_networkstatus_to_cache(s, source, ns);
  384. networkstatus_list_update_recent(now);
  385. return 0;
  386. }
  387. /** Remove all very-old network_status_t objects from memory and from the
  388. * disk cache. */
  389. void
  390. networkstatus_list_clean(time_t now)
  391. {
  392. int i;
  393. if (!networkstatus_list)
  394. return;
  395. for (i = 0; i < smartlist_len(networkstatus_list); ++i) {
  396. networkstatus_t *ns = smartlist_get(networkstatus_list, i);
  397. char *fname = NULL;
  398. if (ns->published_on + MAX_NETWORKSTATUS_AGE > now)
  399. continue;
  400. /* Okay, this one is too old. Remove it from the list, and delete it
  401. * from the cache. */
  402. smartlist_del(networkstatus_list, i--);
  403. fname = networkstatus_get_cache_filename(ns->identity_digest);
  404. if (file_status(fname) == FN_FILE) {
  405. log_info(LD_DIR, "Removing too-old networkstatus in %s", fname);
  406. unlink(fname);
  407. }
  408. tor_free(fname);
  409. if (dirserver_mode(get_options())) {
  410. dirserv_set_cached_networkstatus_v2(NULL, ns->identity_digest, 0);
  411. }
  412. networkstatus_free(ns);
  413. router_dir_info_changed();
  414. }
  415. /* And now go through the directory cache for any cached untrusted
  416. * networkstatuses and other network info. */
  417. dirserv_clear_old_networkstatuses(now - MAX_NETWORKSTATUS_AGE);
  418. dirserv_clear_old_v1_info(now);
  419. }
  420. /** Helper for bsearching a list of routerstatus_t pointers.*/
  421. static int
  422. _compare_digest_to_routerstatus_entry(const void *_key, const void **_member)
  423. {
  424. const char *key = _key;
  425. const routerstatus_t *rs = *_member;
  426. return memcmp(key, rs->identity_digest, DIGEST_LEN);
  427. }
  428. /** Return the entry in <b>ns</b> for the identity digest <b>digest</b>, or
  429. * NULL if none was found. */
  430. routerstatus_t *
  431. networkstatus_find_entry(networkstatus_t *ns, const char *digest)
  432. {
  433. return smartlist_bsearch(ns->entries, digest,
  434. _compare_digest_to_routerstatus_entry);
  435. }
  436. /** DOCDOC */
  437. const smartlist_t *
  438. networkstatus_get_v2_list(void)
  439. {
  440. if (!networkstatus_list)
  441. networkstatus_list = smartlist_create();
  442. return networkstatus_list;
  443. }
  444. /** DOCDOC list of routerstatus_t */
  445. const smartlist_t *
  446. networkstatus_get_all_statuses(void)
  447. {
  448. if (!routerstatus_list)
  449. routerstatus_list = smartlist_create();
  450. return routerstatus_list;
  451. }
  452. /** Return the consensus view of the status of the router whose identity
  453. * digest is <b>digest</b>, or NULL if we don't know about any such router. */
  454. routerstatus_t *
  455. router_get_combined_status_by_digest(const char *digest)
  456. {
  457. if (!routerstatus_list)
  458. return NULL;
  459. return smartlist_bsearch(routerstatus_list, digest,
  460. _compare_digest_to_routerstatus_entry);
  461. }
  462. /** Return the consensus view of the status of the router whose current
  463. * <i>descriptor</i> digest is <b>digest</b>, or NULL if no such router is
  464. * known. */
  465. routerstatus_t *
  466. router_get_combined_status_by_descriptor_digest(const char *digest)
  467. {
  468. if (!routerstatus_by_desc_digest_map)
  469. return NULL;
  470. return digestmap_get(routerstatus_by_desc_digest_map, digest);
  471. }
  472. /** Given a nickname (possibly verbose, possibly a hexadecimal digest), return
  473. * the corresponding routerstatus_t, or NULL if none exists. Warn the
  474. * user if <b>warn_if_unnamed</b> is set, and they have specified a router by
  475. * nickname, but the Named flag isn't set for that router. */
  476. routerstatus_t *
  477. router_get_combined_status_by_nickname(const char *nickname,
  478. int warn_if_unnamed)
  479. {
  480. char digest[DIGEST_LEN];
  481. routerstatus_t *best=NULL;
  482. smartlist_t *matches=NULL;
  483. if (!routerstatus_list || !nickname)
  484. return NULL;
  485. if (nickname[0] == '$') {
  486. if (base16_decode(digest, DIGEST_LEN, nickname+1, strlen(nickname))<0)
  487. return NULL;
  488. return router_get_combined_status_by_digest(digest);
  489. } else if (strlen(nickname) == HEX_DIGEST_LEN &&
  490. (base16_decode(digest, DIGEST_LEN, nickname+1, strlen(nickname))==0)) {
  491. return router_get_combined_status_by_digest(digest);
  492. }
  493. matches = smartlist_create();
  494. SMARTLIST_FOREACH(routerstatus_list, routerstatus_t *, lrs,
  495. {
  496. if (!strcasecmp(lrs->nickname, nickname)) {
  497. if (lrs->is_named) {
  498. smartlist_free(matches);
  499. return lrs;
  500. } else {
  501. smartlist_add(matches, lrs);
  502. best = lrs;
  503. }
  504. }
  505. });
  506. if (smartlist_len(matches)>1 && warn_if_unnamed) {
  507. int any_unwarned=0;
  508. SMARTLIST_FOREACH(matches, routerstatus_t *, lrs,
  509. {
  510. if (! lrs->name_lookup_warned) {
  511. lrs->name_lookup_warned=1;
  512. any_unwarned=1;
  513. }
  514. });
  515. if (any_unwarned) {
  516. log_warn(LD_CONFIG,"There are multiple matches for the nickname \"%s\","
  517. " but none is listed as named by the directory authorites. "
  518. "Choosing one arbitrarily.", nickname);
  519. }
  520. } else if (warn_if_unnamed && best && !best->name_lookup_warned) {
  521. char fp[HEX_DIGEST_LEN+1];
  522. base16_encode(fp, sizeof(fp),
  523. best->identity_digest, DIGEST_LEN);
  524. log_warn(LD_CONFIG,
  525. "When looking up a status, you specified a server \"%s\" by name, "
  526. "but the directory authorities do not have any key registered for "
  527. "this nickname -- so it could be used by any server, "
  528. "not just the one you meant. "
  529. "To make sure you get the same server in the future, refer to "
  530. "it by key, as \"$%s\".", nickname, fp);
  531. best->name_lookup_warned = 1;
  532. }
  533. smartlist_free(matches);
  534. return best;
  535. }
  536. /** DOCDOC */
  537. const char *
  538. networkstatus_get_router_digest_by_nickname(const char *nickname)
  539. {
  540. if (!named_server_map)
  541. return NULL;
  542. return strmap_get_lc(named_server_map, nickname);
  543. }
  544. #if 0
  545. /** Find a routerstatus_t that corresponds to <b>hexdigest</b>, if
  546. * any. Prefer ones that belong to authorities. */
  547. routerstatus_t *
  548. routerstatus_get_by_hexdigest(const char *hexdigest)
  549. {
  550. char digest[DIGEST_LEN];
  551. routerstatus_t *rs;
  552. trusted_dir_server_t *ds;
  553. if (strlen(hexdigest) < HEX_DIGEST_LEN ||
  554. base16_decode(digest,DIGEST_LEN,hexdigest,HEX_DIGEST_LEN) < 0)
  555. return NULL;
  556. if ((ds = router_get_trusteddirserver_by_digest(digest)))
  557. return &ds->fake_status;
  558. if ((rs = router_get_combined_status_by_digest(digest)))
  559. return rs;
  560. return NULL;
  561. }
  562. #endif
  563. /** How frequently do directory authorities re-download fresh networkstatus
  564. * documents? */
  565. #define AUTHORITY_NS_CACHE_INTERVAL (5*60)
  566. /** How frequently do non-authority directory caches re-download fresh
  567. * networkstatus documents? */
  568. #define NONAUTHORITY_NS_CACHE_INTERVAL (15*60)
  569. /** We are a directory server, and so cache network_status documents.
  570. * Initiate downloads as needed to update them. For v2 authorities,
  571. * this means asking each trusted directory for its network-status.
  572. * For caches, this means asking a random v2 authority for all
  573. * network-statuses.
  574. */
  575. static void
  576. update_v2_networkstatus_cache_downloads(time_t now)
  577. {
  578. int authority = authdir_mode_v2(get_options());
  579. int interval =
  580. authority ? AUTHORITY_NS_CACHE_INTERVAL : NONAUTHORITY_NS_CACHE_INTERVAL;
  581. const smartlist_t *trusted_dir_servers = router_get_trusted_dir_servers();
  582. if (last_networkstatus_download_attempted + interval >= now)
  583. return;
  584. last_networkstatus_download_attempted = now;
  585. if (authority) {
  586. /* An authority launches a separate connection for everybody. */
  587. SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
  588. {
  589. char resource[HEX_DIGEST_LEN+6]; /* fp/hexdigit.z\0 */
  590. if (!(ds->type & V2_AUTHORITY))
  591. continue;
  592. if (router_digest_is_me(ds->digest))
  593. continue;
  594. if (connection_get_by_type_addr_port_purpose(
  595. CONN_TYPE_DIR, ds->addr, ds->dir_port,
  596. DIR_PURPOSE_FETCH_NETWORKSTATUS)) {
  597. /* XXX020 the above dir_port won't be accurate if we're
  598. * doing a tunneled conn. In that case it should be or_port.
  599. * How to guess from here? Maybe make the function less general
  600. * and have it know that it's looking for dir conns. -RD */
  601. /* We are already fetching this one. */
  602. continue;
  603. }
  604. strlcpy(resource, "fp/", sizeof(resource));
  605. base16_encode(resource+3, sizeof(resource)-3, ds->digest, DIGEST_LEN);
  606. strlcat(resource, ".z", sizeof(resource));
  607. directory_initiate_command_routerstatus(
  608. &ds->fake_status, DIR_PURPOSE_FETCH_NETWORKSTATUS,
  609. ROUTER_PURPOSE_GENERAL,
  610. 0, /* Not private */
  611. resource,
  612. NULL, 0 /* No payload. */);
  613. });
  614. } else {
  615. /* A non-authority cache launches one connection to a random authority. */
  616. /* (Check whether we're currently fetching network-status objects.) */
  617. if (!connection_get_by_type_purpose(CONN_TYPE_DIR,
  618. DIR_PURPOSE_FETCH_NETWORKSTATUS))
  619. directory_get_from_dirserver(DIR_PURPOSE_FETCH_NETWORKSTATUS,
  620. ROUTER_PURPOSE_GENERAL, "all.z",1);
  621. }
  622. }
  623. /** How long (in seconds) does a client wait after getting a network status
  624. * before downloading the next in sequence? */
  625. #define NETWORKSTATUS_CLIENT_DL_INTERVAL (30*60)
  626. /** How many times do we allow a networkstatus download to fail before we
  627. * assume that the authority isn't publishing? */
  628. #define NETWORKSTATUS_N_ALLOWABLE_FAILURES 3
  629. /** We are not a directory cache or authority. Update our network-status list
  630. * by launching a new directory fetch for enough network-status documents "as
  631. * necessary". See function comments for implementation details.
  632. */
  633. static void
  634. update_v2_networkstatus_client_downloads(time_t now)
  635. {
  636. int n_live = 0, n_dirservers, n_running_dirservers, needed = 0;
  637. int fetch_latest = 0;
  638. int most_recent_idx = -1;
  639. trusted_dir_server_t *most_recent = NULL;
  640. time_t most_recent_received = 0;
  641. char *resource, *cp;
  642. size_t resource_len;
  643. smartlist_t *missing;
  644. const smartlist_t *trusted_dir_servers = router_get_trusted_dir_servers();
  645. if (connection_get_by_type_purpose(CONN_TYPE_DIR,
  646. DIR_PURPOSE_FETCH_NETWORKSTATUS))
  647. return;
  648. /* This is a little tricky. We want to download enough network-status
  649. * objects so that we have all of them under
  650. * NETWORKSTATUS_MAX_AGE publication time. We want to download a new
  651. * *one* if the most recent one's publication time is under
  652. * NETWORKSTATUS_CLIENT_DL_INTERVAL.
  653. */
  654. if (!get_n_authorities(V2_AUTHORITY))
  655. return;
  656. n_dirservers = n_running_dirservers = 0;
  657. missing = smartlist_create();
  658. SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
  659. {
  660. networkstatus_t *ns = networkstatus_get_by_digest(ds->digest);
  661. if (!(ds->type & V2_AUTHORITY))
  662. continue;
  663. ++n_dirservers;
  664. if (!download_status_is_ready(&ds->v2_ns_dl_status, now,
  665. NETWORKSTATUS_N_ALLOWABLE_FAILURES))
  666. continue;
  667. ++n_running_dirservers;
  668. if (ns && ns->published_on > now-NETWORKSTATUS_MAX_AGE)
  669. ++n_live;
  670. else
  671. smartlist_add(missing, ds->digest);
  672. if (ns && (!most_recent || ns->received_on > most_recent_received)) {
  673. most_recent_idx = ds_sl_idx; /* magic variable from FOREACH */
  674. most_recent = ds;
  675. most_recent_received = ns->received_on;
  676. }
  677. });
  678. /* Also, download at least 1 every NETWORKSTATUS_CLIENT_DL_INTERVAL. */
  679. if (!smartlist_len(missing) &&
  680. most_recent_received < now-NETWORKSTATUS_CLIENT_DL_INTERVAL) {
  681. log_info(LD_DIR, "Our most recent network-status document (from %s) "
  682. "is %d seconds old; downloading another.",
  683. most_recent?most_recent->description:"nobody",
  684. (int)(now-most_recent_received));
  685. fetch_latest = 1;
  686. needed = 1;
  687. } else if (smartlist_len(missing)) {
  688. log_info(LD_DIR, "For %d/%d running directory servers, we have %d live"
  689. " network-status documents. Downloading %d.",
  690. n_running_dirservers, n_dirservers, n_live,
  691. smartlist_len(missing));
  692. needed = smartlist_len(missing);
  693. } else {
  694. smartlist_free(missing);
  695. return;
  696. }
  697. /* If no networkstatus was found, choose a dirserver at random as "most
  698. * recent". */
  699. if (most_recent_idx<0)
  700. most_recent_idx = crypto_rand_int(smartlist_len(trusted_dir_servers));
  701. if (fetch_latest) {
  702. int i;
  703. int n_failed = 0;
  704. for (i = most_recent_idx + 1; 1; ++i) {
  705. trusted_dir_server_t *ds;
  706. if (i >= smartlist_len(trusted_dir_servers))
  707. i = 0;
  708. ds = smartlist_get(trusted_dir_servers, i);
  709. if (!(ds->type & V2_AUTHORITY))
  710. continue;
  711. if (n_failed >= n_dirservers) {
  712. log_info(LD_DIR, "All authorities have failed. Not trying any.");
  713. smartlist_free(missing);
  714. return;
  715. }
  716. if (ds->v2_ns_dl_status.n_download_failures >
  717. NETWORKSTATUS_N_ALLOWABLE_FAILURES) {
  718. ++n_failed;
  719. continue;
  720. }
  721. smartlist_add(missing, ds->digest);
  722. break;
  723. }
  724. }
  725. /* Build a request string for all the resources we want. */
  726. resource_len = smartlist_len(missing) * (HEX_DIGEST_LEN+1) + 6;
  727. resource = tor_malloc(resource_len);
  728. memcpy(resource, "fp/", 3);
  729. cp = resource+3;
  730. smartlist_sort_digests(missing);
  731. needed = smartlist_len(missing);
  732. SMARTLIST_FOREACH(missing, const char *, d,
  733. {
  734. base16_encode(cp, HEX_DIGEST_LEN+1, d, DIGEST_LEN);
  735. cp += HEX_DIGEST_LEN;
  736. --needed;
  737. if (needed)
  738. *cp++ = '+';
  739. });
  740. memcpy(cp, ".z", 3);
  741. directory_get_from_dirserver(DIR_PURPOSE_FETCH_NETWORKSTATUS,
  742. ROUTER_PURPOSE_GENERAL, resource, 1);
  743. tor_free(resource);
  744. smartlist_free(missing);
  745. }
  746. /** DOCDOC */
  747. static void
  748. update_consensus_networkstatus_downloads(time_t now)
  749. {
  750. or_options_t *options = get_options();
  751. if (!options->DirPort) /*XXXX020 remove this. */
  752. return;
  753. if (time_to_download_next_consensus > now)
  754. return;
  755. if (authdir_mode_v3(options))
  756. return;
  757. if (!download_status_is_ready(&consensus_dl_status, now, 8))
  758. return; /*XXXX020 magic number 8.*/
  759. if (connection_get_by_type_purpose(CONN_TYPE_DIR,
  760. DIR_PURPOSE_FETCH_CONSENSUS))
  761. return;
  762. directory_get_from_dirserver(DIR_PURPOSE_FETCH_CONSENSUS,
  763. ROUTER_PURPOSE_GENERAL, NULL, 1);
  764. }
  765. /** DOCDOC */
  766. void
  767. networkstatus_consensus_download_failed(int status_code)
  768. {
  769. download_status_failed(&consensus_dl_status, status_code);
  770. }
  771. /** DOCDOC */
  772. static void
  773. update_consensus_networkstatus_fetch_time(time_t now)
  774. {
  775. or_options_t *options = get_options();
  776. /* XXXX020 call this when DirPort switches on or off. NMNM */
  777. if (current_consensus) {
  778. const networkstatus_vote_t *c = current_consensus;
  779. time_t start;
  780. long interval;
  781. if (dirserver_mode(options)) {
  782. start = c->valid_after + 120; /*XXXX020 make this a macro. */
  783. /* XXXX020 too much magic. */
  784. interval = (c->fresh_until - c->valid_after) / 2;
  785. } else {
  786. start = c->fresh_until;
  787. /* XXXX020 too much magic. */
  788. interval = (c->valid_until - c->fresh_until) * 7 / 8;
  789. }
  790. if (interval < 1)
  791. interval = 1;
  792. tor_assert(start+interval < c->valid_until);
  793. time_to_download_next_consensus = start + crypto_rand_int(interval);
  794. } else {
  795. time_to_download_next_consensus = now;
  796. }
  797. }
  798. /** Return 1 if there's a reason we shouldn't try any directory
  799. * fetches yet (e.g. we demand bridges and none are yet known).
  800. * Else return 0. */
  801. int
  802. should_delay_dir_fetches(or_options_t *options)
  803. {
  804. if (options->UseBridges && !any_bridge_descriptors_known()) {
  805. log_info(LD_DIR, "delaying dir fetches");
  806. return 1;
  807. }
  808. return 0;
  809. }
  810. /** Launch requests for networkstatus documents and authority certificates as
  811. * appropriate. */
  812. void
  813. update_networkstatus_downloads(time_t now)
  814. {
  815. or_options_t *options = get_options();
  816. if (should_delay_dir_fetches(options))
  817. return;
  818. if (dirserver_mode(options))
  819. update_v2_networkstatus_cache_downloads(now);
  820. else
  821. update_v2_networkstatus_client_downloads(now);
  822. update_consensus_networkstatus_downloads(now);
  823. if (consensus_waiting_for_certs)
  824. authority_certs_fetch_missing(consensus_waiting_for_certs, now);
  825. else
  826. authority_certs_fetch_missing(current_consensus, now);
  827. }
  828. /** Return the network status with a given identity digest. */
  829. networkstatus_t *
  830. networkstatus_get_by_digest(const char *digest)
  831. {
  832. SMARTLIST_FOREACH(networkstatus_list, networkstatus_t *, ns,
  833. {
  834. if (!memcmp(ns->identity_digest, digest, DIGEST_LEN))
  835. return ns;
  836. });
  837. return NULL;
  838. }
  839. /** Return the most recent consensus that we have downloaded, or NULL if we
  840. * don't have one. */
  841. networkstatus_vote_t *
  842. networkstatus_get_latest_consensus(void)
  843. {
  844. return current_consensus;
  845. }
  846. /** Return the most recent consensus that we have downloaded, or NULL if it is
  847. * no longer live. */
  848. networkstatus_vote_t *
  849. networkstatus_get_live_consensus(time_t now)
  850. {
  851. if (current_consensus &&
  852. current_consensus->valid_after <= now &&
  853. now <= current_consensus->valid_until)
  854. return current_consensus;
  855. else
  856. return NULL;
  857. }
  858. /** Try to replace the current cached v3 networkstatus with the one in
  859. * <b>consensus</b>. If we don't have enough certificates to validate it,
  860. * store it in consensus_waiting_for_certs and launch a certificate fetch.
  861. *
  862. * Return 0 on success, -1 on failure. */
  863. int
  864. networkstatus_set_current_consensus(const char *consensus, int from_cache,
  865. int was_waiting_for_certs)
  866. {
  867. networkstatus_vote_t *c;
  868. int r;
  869. time_t now = time(NULL);
  870. /* Make sure it's parseable. */
  871. c = networkstatus_parse_vote_from_string(consensus, NULL, 0);
  872. if (!c) {
  873. log_warn(LD_DIR, "Unable to parse networkstatus consensus");
  874. return -1;
  875. }
  876. /* Make sure it's signed enough. */
  877. if ((r=networkstatus_check_consensus_signature(c, 1))<0) {
  878. if (r == -1 && !was_waiting_for_certs) {
  879. /* Okay, so it _might_ be signed enough if we get more certificates. */
  880. if (!was_waiting_for_certs)
  881. log_notice(LD_DIR, "Not enough certificates to check networkstatus "
  882. "consensus");
  883. if (!current_consensus ||
  884. c->valid_after > current_consensus->valid_after) {
  885. if (consensus_waiting_for_certs)
  886. networkstatus_vote_free(consensus_waiting_for_certs);
  887. tor_free(consensus_waiting_for_certs_body);
  888. consensus_waiting_for_certs = c;
  889. consensus_waiting_for_certs_body = tor_strdup(consensus);
  890. /*XXXX020 delay next update. NMNM */
  891. if (!from_cache) {
  892. or_options_t *options = get_options();
  893. char filename[512];
  894. tor_snprintf(filename, sizeof(filename),
  895. "%s"PATH_SEPARATOR"unverified-consensus",
  896. options->DataDirectory);
  897. write_str_to_file(filename, consensus, 0);
  898. }
  899. authority_certs_fetch_missing(c, now);
  900. }
  901. download_status_reset(&consensus_dl_status); /*XXXX020 not quite right.*/
  902. return 0;
  903. } else {
  904. if (!was_waiting_for_certs)
  905. log_warn(LD_DIR, "Not enough good signatures on networkstatus "
  906. "consensus");
  907. networkstatus_vote_free(c);
  908. return -1;
  909. }
  910. }
  911. download_status_reset(&consensus_dl_status); /*XXXX020 not quite right.*/
  912. /* Are we missing any certificates at all? */
  913. if (r != 1)
  914. authority_certs_fetch_missing(c, now);
  915. if (current_consensus)
  916. networkstatus_vote_free(current_consensus);
  917. if (consensus_waiting_for_certs &&
  918. consensus_waiting_for_certs->valid_after <= c->valid_after) {
  919. networkstatus_vote_free(consensus_waiting_for_certs);
  920. consensus_waiting_for_certs = NULL;
  921. if (consensus != consensus_waiting_for_certs_body)
  922. tor_free(consensus_waiting_for_certs_body);
  923. }
  924. current_consensus = c;
  925. update_consensus_networkstatus_fetch_time(now);
  926. dirvote_recalculate_timing(now);
  927. if (!from_cache) {
  928. or_options_t *options = get_options();
  929. char filename[512];
  930. tor_snprintf(filename, sizeof(filename),
  931. "%s"PATH_SEPARATOR"cached-consensus",
  932. options->DataDirectory);
  933. write_str_to_file(filename, consensus, 0);
  934. }
  935. if (dirserver_mode(get_options()))
  936. dirserv_set_cached_networkstatus_v3(consensus, c->valid_after);
  937. return 0;
  938. }
  939. /** DOCDOC */
  940. void
  941. networkstatus_note_certs_arrived(void)
  942. {
  943. if (consensus_waiting_for_certs) {
  944. if (networkstatus_check_consensus_signature(
  945. consensus_waiting_for_certs, 0)<0) {
  946. if (!networkstatus_set_current_consensus(
  947. consensus_waiting_for_certs_body, 0, 1)) {
  948. tor_free(consensus_waiting_for_certs_body);
  949. }
  950. }
  951. }
  952. }
  953. /** How many times do we have to fail at getting a networkstatus we can't find
  954. * before we're willing to believe it's okay to set up router statuses? */
  955. #define N_NS_ATTEMPTS_TO_SET_ROUTERS 4
  956. /** How many times do we have to fail at getting a networkstatus we can't find
  957. * before we're willing to believe it's okay to check our version? */
  958. #define N_NS_ATTEMPTS_TO_CHECK_VERSION 4
  959. /** We believe networkstatuses more recent than this when they tell us that
  960. * our server is broken, invalid, obsolete, etc. */
  961. #define SELF_OPINION_INTERVAL (90*60)
  962. /** If the network-status list has changed since the last time we called this
  963. * function, update the status of every routerinfo from the network-status
  964. * list.
  965. */
  966. void
  967. routers_update_all_from_networkstatus(time_t now)
  968. {
  969. routerinfo_t *me;
  970. routerlist_t *rl = router_get_routerlist();
  971. if (!networkstatus_list ||
  972. (!networkstatus_list_has_changed && !routerstatus_list_has_changed))
  973. return;
  974. router_dir_info_changed();
  975. if (networkstatus_list_has_changed)
  976. routerstatus_list_update_from_networkstatus(now);
  977. routers_update_status_from_networkstatus(rl->routers, 0);
  978. me = router_get_my_routerinfo();
  979. if (me && !have_warned_about_invalid_status &&
  980. have_tried_downloading_all_statuses(N_NS_ATTEMPTS_TO_SET_ROUTERS)) {
  981. int n_recent = 0, n_listing = 0, n_valid = 0, n_named = 0, n_naming = 0;
  982. routerstatus_t *rs;
  983. SMARTLIST_FOREACH(networkstatus_list, networkstatus_t *, ns,
  984. {
  985. if (ns->received_on + SELF_OPINION_INTERVAL < now)
  986. continue;
  987. ++n_recent;
  988. if (ns->binds_names)
  989. ++n_naming;
  990. if (!(rs = networkstatus_find_entry(ns, me->cache_info.identity_digest)))
  991. continue;
  992. ++n_listing;
  993. if (rs->is_valid)
  994. ++n_valid;
  995. if (rs->is_named)
  996. ++n_named;
  997. });
  998. if (n_listing) {
  999. if (n_valid <= n_listing/2) {
  1000. log_info(LD_GENERAL,
  1001. "%d/%d recent statements from directory authorities list us "
  1002. "as unapproved. Are you misconfigured?",
  1003. n_listing-n_valid, n_listing);
  1004. have_warned_about_invalid_status = 1;
  1005. } else if (n_naming && !n_named) {
  1006. log_info(LD_GENERAL, "0/%d name-binding directory authorities "
  1007. "recognize your nickname. Please consider sending your "
  1008. "nickname and identity fingerprint to the tor-ops.",
  1009. n_naming);
  1010. have_warned_about_invalid_status = 1;
  1011. }
  1012. }
  1013. }
  1014. entry_guards_compute_status();
  1015. if (!have_warned_about_old_version &&
  1016. have_tried_downloading_all_statuses(N_NS_ATTEMPTS_TO_CHECK_VERSION)) {
  1017. combined_version_status_t st;
  1018. int is_server = server_mode(get_options());
  1019. char *recommended;
  1020. recommended = compute_recommended_versions(now, !is_server, VERSION, &st);
  1021. if (st.n_versioning) {
  1022. if (st.consensus == VS_RECOMMENDED) {
  1023. log_info(LD_GENERAL, "%d/%d statements from version-listing "
  1024. "directory authorities say my version is ok.",
  1025. st.n_concurring, st.n_versioning);
  1026. } else if (st.consensus == VS_NEW || st.consensus == VS_NEW_IN_SERIES) {
  1027. if (!have_warned_about_new_version) {
  1028. log_notice(LD_GENERAL, "This version of Tor (%s) is newer than any "
  1029. "recommended version%s, according to %d/%d version-listing "
  1030. "network statuses. Versions recommended by more than %d "
  1031. "authorit%s are: %s",
  1032. VERSION,
  1033. st.consensus == VS_NEW_IN_SERIES ? " in its series" : "",
  1034. st.n_concurring, st.n_versioning, st.n_versioning/2,
  1035. st.n_versioning/2 > 1 ? "ies" : "y", recommended);
  1036. have_warned_about_new_version = 1;
  1037. control_event_general_status(LOG_WARN, "DANGEROUS_VERSION "
  1038. "CURRENT=%s REASON=%s RECOMMENDED=\"%s\"",
  1039. VERSION, "NEW", recommended);
  1040. }
  1041. } else {
  1042. log_warn(LD_GENERAL, "Please upgrade! "
  1043. "This version of Tor (%s) is %s, according to %d/%d version-"
  1044. "listing network statuses. Versions recommended by "
  1045. "at least %d authorit%s are: %s",
  1046. VERSION,
  1047. st.consensus == VS_OLD ? "obsolete" : "not recommended",
  1048. st.n_concurring, st.n_versioning, st.n_versioning/2,
  1049. st.n_versioning/2 > 1 ? "ies" : "y", recommended);
  1050. have_warned_about_old_version = 1;
  1051. control_event_general_status(LOG_WARN, "DANGEROUS_VERSION "
  1052. "CURRENT=%s REASON=%s RECOMMENDED=\"%s\"",
  1053. VERSION, st.consensus == VS_OLD ? "OLD" : "UNRECOMMENDED",
  1054. recommended);
  1055. }
  1056. }
  1057. tor_free(recommended);
  1058. }
  1059. routerstatus_list_has_changed = 0;
  1060. }
  1061. /** Allow any network-status newer than this to influence our view of who's
  1062. * running. */
  1063. #define DEFAULT_RUNNING_INTERVAL (60*60)
  1064. /** If possible, always allow at least this many network-statuses to influence
  1065. * our view of who's running. */
  1066. #define MIN_TO_INFLUENCE_RUNNING 3
  1067. /** Change the is_recent field of each member of networkstatus_list so that
  1068. * all members more recent than DEFAULT_RUNNING_INTERVAL are recent, and
  1069. * at least the MIN_TO_INFLUENCE_RUNNING most recent members are recent, and no
  1070. * others are recent. Set networkstatus_list_has_changed if anything happened.
  1071. */
  1072. void
  1073. networkstatus_list_update_recent(time_t now)
  1074. {
  1075. int n_statuses, n_recent, changed, i;
  1076. char published[ISO_TIME_LEN+1];
  1077. if (!networkstatus_list)
  1078. return;
  1079. n_statuses = smartlist_len(networkstatus_list);
  1080. n_recent = 0;
  1081. changed = 0;
  1082. for (i=n_statuses-1; i >= 0; --i) {
  1083. networkstatus_t *ns = smartlist_get(networkstatus_list, i);
  1084. trusted_dir_server_t *ds =
  1085. router_get_trusteddirserver_by_digest(ns->identity_digest);
  1086. const char *src = ds?ds->description:ns->source_address;
  1087. if (n_recent < MIN_TO_INFLUENCE_RUNNING ||
  1088. ns->published_on + DEFAULT_RUNNING_INTERVAL > now) {
  1089. if (!ns->is_recent) {
  1090. format_iso_time(published, ns->published_on);
  1091. log_info(LD_DIR,
  1092. "Networkstatus from %s (published %s) is now \"recent\"",
  1093. src, published);
  1094. changed = 1;
  1095. }
  1096. ns->is_recent = 1;
  1097. ++n_recent;
  1098. } else {
  1099. if (ns->is_recent) {
  1100. format_iso_time(published, ns->published_on);
  1101. log_info(LD_DIR,
  1102. "Networkstatus from %s (published %s) is "
  1103. "no longer \"recent\"",
  1104. src, published);
  1105. changed = 1;
  1106. ns->is_recent = 0;
  1107. }
  1108. }
  1109. }
  1110. if (changed) {
  1111. networkstatus_list_has_changed = 1;
  1112. router_dir_info_changed();
  1113. }
  1114. }
  1115. /** Helper for routerstatus_list_update_from_networkstatus: remember how many
  1116. * authorities recommend a given descriptor digest. */
  1117. typedef struct {
  1118. routerstatus_t *rs;
  1119. int count;
  1120. } desc_digest_count_t;
  1121. /** Update our view of router status (as stored in routerstatus_list) from the
  1122. * current set of network status documents (as stored in networkstatus_list).
  1123. * Do nothing unless the network status list has changed since the last time
  1124. * this function was called.
  1125. */
  1126. void
  1127. routerstatus_list_update_from_networkstatus(time_t now)
  1128. {
  1129. or_options_t *options = get_options();
  1130. int n_trusted, n_statuses, n_recent = 0, n_naming = 0;
  1131. int n_listing_bad_exits = 0, n_listing_bad_directories = 0;
  1132. int i, j, warned;
  1133. int *index, *size;
  1134. networkstatus_t **networkstatus;
  1135. smartlist_t *result, *changed_list;
  1136. strmap_t *name_map;
  1137. char conflict[DIGEST_LEN]; /* Sentinel value */
  1138. desc_digest_count_t *digest_counts = NULL;
  1139. /* compute which network statuses will have a vote now */
  1140. networkstatus_list_update_recent(now);
  1141. router_dir_info_changed();
  1142. if (!networkstatus_list_has_changed)
  1143. return;
  1144. if (!networkstatus_list)
  1145. networkstatus_list = smartlist_create();
  1146. if (!routerstatus_list)
  1147. routerstatus_list = smartlist_create();
  1148. if (!warned_conflicts)
  1149. warned_conflicts = smartlist_create();
  1150. n_statuses = smartlist_len(networkstatus_list);
  1151. n_trusted = get_n_authorities(V2_AUTHORITY);
  1152. if (n_statuses <= n_trusted/2) {
  1153. /* Not enough statuses to adjust status. */
  1154. log_info(LD_DIR,
  1155. "Not enough statuses to update router status list. (%d/%d)",
  1156. n_statuses, n_trusted);
  1157. return;
  1158. }
  1159. log_info(LD_DIR, "Rebuilding router status list.");
  1160. index = tor_malloc(sizeof(int)*n_statuses);
  1161. size = tor_malloc(sizeof(int)*n_statuses);
  1162. networkstatus = tor_malloc(sizeof(networkstatus_t *)*n_statuses);
  1163. for (i = 0; i < n_statuses; ++i) {
  1164. index[i] = 0;
  1165. networkstatus[i] = smartlist_get(networkstatus_list, i);
  1166. size[i] = smartlist_len(networkstatus[i]->entries);
  1167. if (networkstatus[i]->binds_names)
  1168. ++n_naming;
  1169. if (networkstatus[i]->is_recent)
  1170. ++n_recent;
  1171. if (networkstatus[i]->lists_bad_exits)
  1172. ++n_listing_bad_exits;
  1173. if (networkstatus[i]->lists_bad_directories)
  1174. ++n_listing_bad_directories;
  1175. }
  1176. /** Iterate over all entries in all networkstatuses, and build
  1177. * name_map as a map from lc nickname to identity digest. If there
  1178. * is a conflict on that nickname, map the lc nickname to conflict.
  1179. */
  1180. name_map = strmap_new();
  1181. /* Clear the global map... */
  1182. if (named_server_map)
  1183. strmap_free(named_server_map, _tor_free);
  1184. named_server_map = strmap_new();
  1185. memset(conflict, 0xff, sizeof(conflict));
  1186. for (i = 0; i < n_statuses; ++i) {
  1187. if (!networkstatus[i]->binds_names)
  1188. continue;
  1189. SMARTLIST_FOREACH(networkstatus[i]->entries, routerstatus_t *, rs,
  1190. {
  1191. const char *other_digest;
  1192. if (!rs->is_named)
  1193. continue;
  1194. other_digest = strmap_get_lc(name_map, rs->nickname);
  1195. warned = smartlist_string_isin(warned_conflicts, rs->nickname);
  1196. if (!other_digest) {
  1197. strmap_set_lc(name_map, rs->nickname, rs->identity_digest);
  1198. strmap_set_lc(named_server_map, rs->nickname,
  1199. tor_memdup(rs->identity_digest, DIGEST_LEN));
  1200. if (warned)
  1201. smartlist_string_remove(warned_conflicts, rs->nickname);
  1202. } else if (memcmp(other_digest, rs->identity_digest, DIGEST_LEN) &&
  1203. other_digest != conflict) {
  1204. if (!warned) {
  1205. char *d;
  1206. int should_warn = authdir_mode(options);
  1207. char fp1[HEX_DIGEST_LEN+1];
  1208. char fp2[HEX_DIGEST_LEN+1];
  1209. base16_encode(fp1, sizeof(fp1), other_digest, DIGEST_LEN);
  1210. base16_encode(fp2, sizeof(fp2), rs->identity_digest, DIGEST_LEN);
  1211. log_fn(should_warn ? LOG_WARN : LOG_INFO, LD_DIR,
  1212. "Naming authorities disagree about which key goes with %s. "
  1213. "($%s vs $%s)",
  1214. rs->nickname, fp1, fp2);
  1215. strmap_set_lc(name_map, rs->nickname, conflict);
  1216. d = strmap_remove_lc(named_server_map, rs->nickname);
  1217. tor_free(d);
  1218. smartlist_add(warned_conflicts, tor_strdup(rs->nickname));
  1219. }
  1220. } else {
  1221. if (warned)
  1222. smartlist_string_remove(warned_conflicts, rs->nickname);
  1223. }
  1224. });
  1225. }
  1226. result = smartlist_create();
  1227. changed_list = smartlist_create();
  1228. digest_counts = tor_malloc_zero(sizeof(desc_digest_count_t)*n_statuses);
  1229. /* Iterate through all of the sorted routerstatus lists in lockstep.
  1230. * Invariants:
  1231. * - For 0 <= i < n_statuses: index[i] is an index into
  1232. * networkstatus[i]->entries, which has size[i] elements.
  1233. * - For i1, i2, j such that 0 <= i1 < n_statuses, 0 <= i2 < n_statues, 0 <=
  1234. * j < index[i1]: networkstatus[i1]->entries[j]->identity_digest <
  1235. * networkstatus[i2]->entries[index[i2]]->identity_digest.
  1236. *
  1237. * (That is, the indices are always advanced past lower digest before
  1238. * higher.)
  1239. */
  1240. while (1) {
  1241. int n_running=0, n_named=0, n_valid=0, n_listing=0;
  1242. int n_v2_dir=0, n_fast=0, n_stable=0, n_exit=0, n_guard=0, n_bad_exit=0;
  1243. int n_bad_directory=0;
  1244. int n_version_known=0, n_supports_begindir=0;
  1245. int n_supports_extrainfo_upload=0;
  1246. int n_desc_digests=0, highest_count=0;
  1247. const char *the_name = NULL;
  1248. routerstatus_t *rs_out, *rs_old;
  1249. routerstatus_t *rs, *most_recent;
  1250. networkstatus_t *ns;
  1251. const char *lowest = NULL;
  1252. /* Find out which of the digests appears first. */
  1253. for (i = 0; i < n_statuses; ++i) {
  1254. if (index[i] < size[i]) {
  1255. rs = smartlist_get(networkstatus[i]->entries, index[i]);
  1256. if (!lowest || memcmp(rs->identity_digest, lowest, DIGEST_LEN)<0)
  1257. lowest = rs->identity_digest;
  1258. }
  1259. }
  1260. if (!lowest) {
  1261. /* We're out of routers. Great! */
  1262. break;
  1263. }
  1264. /* Okay. The routers at networkstatus[i]->entries[index[i]] whose digests
  1265. * match "lowest" are next in order. Iterate over them, incrementing those
  1266. * index[i] as we go. */
  1267. for (i = 0; i < n_statuses; ++i) {
  1268. if (index[i] >= size[i])
  1269. continue;
  1270. ns = networkstatus[i];
  1271. rs = smartlist_get(ns->entries, index[i]);
  1272. if (memcmp(rs->identity_digest, lowest, DIGEST_LEN))
  1273. continue;
  1274. /* At this point, we know that we're looking at a routersatus with
  1275. * identity "lowest".
  1276. */
  1277. ++index[i];
  1278. ++n_listing;
  1279. /* Should we name this router? Only if all the names from naming
  1280. * authorities match. */
  1281. if (rs->is_named && ns->binds_names) {
  1282. if (!the_name)
  1283. the_name = rs->nickname;
  1284. if (!strcasecmp(rs->nickname, the_name)) {
  1285. ++n_named;
  1286. } else if (strcmp(the_name,"**mismatch**")) {
  1287. char hd[HEX_DIGEST_LEN+1];
  1288. base16_encode(hd, HEX_DIGEST_LEN+1, rs->identity_digest, DIGEST_LEN);
  1289. if (! smartlist_string_isin(warned_conflicts, hd)) {
  1290. log_warn(LD_DIR,
  1291. "Naming authorities disagree about nicknames for $%s "
  1292. "(\"%s\" vs \"%s\")",
  1293. hd, the_name, rs->nickname);
  1294. smartlist_add(warned_conflicts, tor_strdup(hd));
  1295. }
  1296. the_name = "**mismatch**";
  1297. }
  1298. }
  1299. /* Keep a running count of how often which descriptor digests
  1300. * appear. */
  1301. for (j = 0; j < n_desc_digests; ++j) {
  1302. if (!memcmp(rs->descriptor_digest,
  1303. digest_counts[j].rs->descriptor_digest, DIGEST_LEN)) {
  1304. if (++digest_counts[j].count > highest_count)
  1305. highest_count = digest_counts[j].count;
  1306. goto found;
  1307. }
  1308. }
  1309. digest_counts[n_desc_digests].rs = rs;
  1310. digest_counts[n_desc_digests].count = 1;
  1311. if (!highest_count)
  1312. highest_count = 1;
  1313. ++n_desc_digests;
  1314. found:
  1315. /* Now tally up the easily-tallied flags. */
  1316. if (rs->is_valid)
  1317. ++n_valid;
  1318. if (rs->is_running && ns->is_recent)
  1319. ++n_running;
  1320. if (rs->is_exit)
  1321. ++n_exit;
  1322. if (rs->is_fast)
  1323. ++n_fast;
  1324. if (rs->is_possible_guard)
  1325. ++n_guard;
  1326. if (rs->is_stable)
  1327. ++n_stable;
  1328. if (rs->is_v2_dir)
  1329. ++n_v2_dir;
  1330. if (rs->is_bad_exit)
  1331. ++n_bad_exit;
  1332. if (rs->is_bad_directory)
  1333. ++n_bad_directory;
  1334. if (rs->version_known)
  1335. ++n_version_known;
  1336. if (rs->version_supports_begindir)
  1337. ++n_supports_begindir;
  1338. if (rs->version_supports_extrainfo_upload)
  1339. ++n_supports_extrainfo_upload;
  1340. }
  1341. /* Go over the descriptor digests and figure out which descriptor we
  1342. * want. */
  1343. most_recent = NULL;
  1344. for (i = 0; i < n_desc_digests; ++i) {
  1345. /* If any digest appears twice or more, ignore those that don't.*/
  1346. if (highest_count >= 2 && digest_counts[i].count < 2)
  1347. continue;
  1348. if (!most_recent ||
  1349. digest_counts[i].rs->published_on > most_recent->published_on)
  1350. most_recent = digest_counts[i].rs;
  1351. }
  1352. rs_out = tor_malloc_zero(sizeof(routerstatus_t));
  1353. memcpy(rs_out, most_recent, sizeof(routerstatus_t));
  1354. /* Copy status info about this router, if we had any before. */
  1355. if ((rs_old = router_get_combined_status_by_digest(lowest))) {
  1356. if (!memcmp(rs_out->descriptor_digest,
  1357. most_recent->descriptor_digest, DIGEST_LEN)) {
  1358. rs_out->dl_status.n_download_failures =
  1359. rs_old->dl_status.n_download_failures;
  1360. rs_out->dl_status.next_attempt_at = rs_old->dl_status.next_attempt_at;
  1361. }
  1362. rs_out->name_lookup_warned = rs_old->name_lookup_warned;
  1363. rs_out->last_dir_503_at = rs_old->last_dir_503_at;
  1364. }
  1365. smartlist_add(result, rs_out);
  1366. log_debug(LD_DIR, "Router '%s' is listed by %d/%d directories, "
  1367. "named by %d/%d, validated by %d/%d, and %d/%d recent "
  1368. "directories think it's running.",
  1369. rs_out->nickname,
  1370. n_listing, n_statuses, n_named, n_naming, n_valid, n_statuses,
  1371. n_running, n_recent);
  1372. rs_out->is_named = 0;
  1373. if (the_name && strcmp(the_name, "**mismatch**") && n_named > 0) {
  1374. const char *d = strmap_get_lc(name_map, the_name);
  1375. if (d && d != conflict)
  1376. rs_out->is_named = 1;
  1377. if (smartlist_string_isin(warned_conflicts, rs_out->nickname))
  1378. smartlist_string_remove(warned_conflicts, rs_out->nickname);
  1379. }
  1380. if (rs_out->is_named)
  1381. strlcpy(rs_out->nickname, the_name,
  1382. sizeof(rs_out->nickname));
  1383. rs_out->is_valid = n_valid > n_statuses/2;
  1384. rs_out->is_running = n_running > n_recent/2;
  1385. rs_out->is_exit = n_exit > n_statuses/2;
  1386. rs_out->is_fast = n_fast > n_statuses/2;
  1387. rs_out->is_possible_guard = n_guard > n_statuses/2;
  1388. rs_out->is_stable = n_stable > n_statuses/2;
  1389. rs_out->is_v2_dir = n_v2_dir > n_statuses/2;
  1390. rs_out->is_bad_exit = n_bad_exit > n_listing_bad_exits/2;
  1391. rs_out->is_bad_directory =
  1392. n_bad_directory > n_listing_bad_directories/2;
  1393. rs_out->version_known = n_version_known > 0;
  1394. rs_out->version_supports_begindir =
  1395. n_supports_begindir > n_version_known/2;
  1396. rs_out->version_supports_extrainfo_upload =
  1397. n_supports_extrainfo_upload > n_version_known/2;
  1398. if (!rs_old || memcmp(rs_old, rs_out, sizeof(routerstatus_t)))
  1399. smartlist_add(changed_list, rs_out);
  1400. }
  1401. SMARTLIST_FOREACH(routerstatus_list, routerstatus_t *, rs,
  1402. routerstatus_free(rs));
  1403. smartlist_free(routerstatus_list);
  1404. routerstatus_list = result;
  1405. if (routerstatus_by_desc_digest_map)
  1406. digestmap_free(routerstatus_by_desc_digest_map, NULL);
  1407. routerstatus_by_desc_digest_map = digestmap_new();
  1408. SMARTLIST_FOREACH(routerstatus_list, routerstatus_t *, rs,
  1409. digestmap_set(routerstatus_by_desc_digest_map,
  1410. rs->descriptor_digest,
  1411. rs));
  1412. tor_free(networkstatus);
  1413. tor_free(index);
  1414. tor_free(size);
  1415. tor_free(digest_counts);
  1416. strmap_free(name_map, NULL);
  1417. networkstatus_list_has_changed = 0;
  1418. routerstatus_list_has_changed = 1;
  1419. control_event_networkstatus_changed(changed_list);
  1420. smartlist_free(changed_list);
  1421. }
  1422. /** Given a list <b>routers</b> of routerinfo_t *, update each routers's
  1423. * is_named, is_valid, and is_running fields according to our current
  1424. * networkstatus_t documents. */ /* XXXX020 obsoleted by v3 */
  1425. void
  1426. routers_update_status_from_networkstatus(smartlist_t *routers,
  1427. int reset_failures)
  1428. {
  1429. trusted_dir_server_t *ds;
  1430. routerstatus_t *rs;
  1431. or_options_t *options = get_options();
  1432. int authdir = authdir_mode_v2(options);
  1433. int namingdir = authdir && options->NamingAuthoritativeDir;
  1434. if (!routerstatus_list)
  1435. return;
  1436. SMARTLIST_FOREACH(routers, routerinfo_t *, router,
  1437. {
  1438. const char *digest = router->cache_info.identity_digest;
  1439. rs = router_get_combined_status_by_digest(digest);
  1440. ds = router_get_trusteddirserver_by_digest(digest);
  1441. if (!rs)
  1442. continue;
  1443. if (!namingdir)
  1444. router->is_named = rs->is_named;
  1445. if (!authdir) {
  1446. /* If we're not an authdir, believe others. */
  1447. router->is_valid = rs->is_valid;
  1448. router->is_running = rs->is_running;
  1449. router->is_fast = rs->is_fast;
  1450. router->is_stable = rs->is_stable;
  1451. router->is_possible_guard = rs->is_possible_guard;
  1452. router->is_exit = rs->is_exit;
  1453. router->is_bad_exit = rs->is_bad_exit;
  1454. }
  1455. if (router->is_running && ds) {
  1456. download_status_reset(&ds->v2_ns_dl_status);
  1457. }
  1458. if (reset_failures) {
  1459. download_status_reset(&rs->dl_status);
  1460. }
  1461. });
  1462. router_dir_info_changed();
  1463. }
  1464. /** Return true iff we have downloaded, or attempted to download at least
  1465. * n_failures times, a network status for each authority. */
  1466. static int
  1467. have_tried_downloading_all_statuses(int n_failures)
  1468. {
  1469. smartlist_t *trusted_dir_servers = router_get_trusted_dir_servers();
  1470. SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
  1471. {
  1472. if (!(ds->type & V2_AUTHORITY))
  1473. continue;
  1474. /* If we don't have the status, and we haven't failed to get the status,
  1475. * we haven't tried to get the status. */
  1476. if (!networkstatus_get_by_digest(ds->digest) &&
  1477. ds->v2_ns_dl_status.n_download_failures <= n_failures)
  1478. return 0;
  1479. });
  1480. return 1;
  1481. }
  1482. /** Generate networkstatus lines for a single routerstatus_t object, and
  1483. * return the result in a newly allocated string. Used only by controller
  1484. * interface (for now.) */
  1485. char *
  1486. networkstatus_getinfo_helper_single(routerstatus_t *rs)
  1487. {
  1488. char buf[256];
  1489. routerstatus_format_entry(buf, sizeof(buf), rs, NULL, 0);
  1490. return tor_strdup(buf);
  1491. }
  1492. /** If <b>question</b> is a string beginning with "ns/" in a format the
  1493. * control interface expects for a GETINFO question, set *<b>answer</b> to a
  1494. * newly-allocated string containing networkstatus lines for the appropriate
  1495. * ORs. Return 0 on success, -1 on unrecognized question format. */
  1496. int
  1497. getinfo_helper_networkstatus(control_connection_t *conn,
  1498. const char *question, char **answer)
  1499. {
  1500. routerstatus_t *status;
  1501. (void) conn;
  1502. if (!routerstatus_list) {
  1503. *answer = tor_strdup("");
  1504. return 0;
  1505. }
  1506. if (!strcmp(question, "ns/all")) {
  1507. smartlist_t *statuses = smartlist_create();
  1508. SMARTLIST_FOREACH(routerstatus_list, routerstatus_t *, rs,
  1509. {
  1510. smartlist_add(statuses, networkstatus_getinfo_helper_single(rs));
  1511. });
  1512. *answer = smartlist_join_strings(statuses, "", 0, NULL);
  1513. SMARTLIST_FOREACH(statuses, char *, cp, tor_free(cp));
  1514. smartlist_free(statuses);
  1515. return 0;
  1516. } else if (!strcmpstart(question, "ns/id/")) {
  1517. char d[DIGEST_LEN];
  1518. if (base16_decode(d, DIGEST_LEN, question+6, strlen(question+6)))
  1519. return -1;
  1520. status = router_get_combined_status_by_digest(d);
  1521. } else if (!strcmpstart(question, "ns/name/")) {
  1522. status = router_get_combined_status_by_nickname(question+8, 0);
  1523. } else {
  1524. return -1;
  1525. }
  1526. if (status) {
  1527. *answer = networkstatus_getinfo_helper_single(status);
  1528. }
  1529. return 0;
  1530. }
  1531. /** DOCDOC */
  1532. void
  1533. networkstatus_free_all(void)
  1534. {
  1535. if (networkstatus_list) {
  1536. SMARTLIST_FOREACH(networkstatus_list, networkstatus_t *, ns,
  1537. networkstatus_free(ns));
  1538. smartlist_free(networkstatus_list);
  1539. networkstatus_list = NULL;
  1540. }
  1541. if (routerstatus_list) {
  1542. SMARTLIST_FOREACH(routerstatus_list, routerstatus_t *, rs,
  1543. routerstatus_free(rs));
  1544. smartlist_free(routerstatus_list);
  1545. routerstatus_list = NULL;
  1546. }
  1547. if (routerstatus_by_desc_digest_map) {
  1548. digestmap_free(routerstatus_by_desc_digest_map, NULL);
  1549. routerstatus_by_desc_digest_map = NULL;
  1550. }
  1551. if (current_consensus) {
  1552. networkstatus_vote_free(current_consensus);
  1553. current_consensus = NULL;
  1554. }
  1555. if (consensus_waiting_for_certs) {
  1556. networkstatus_vote_free(current_consensus);
  1557. current_consensus = NULL;
  1558. }
  1559. tor_free(consensus_waiting_for_certs_body);
  1560. if (warned_conflicts) {
  1561. SMARTLIST_FOREACH(warned_conflicts, char *, cp, tor_free(cp));
  1562. smartlist_free(warned_conflicts);
  1563. warned_conflicts = NULL;
  1564. }
  1565. if (named_server_map) {
  1566. strmap_free(named_server_map, _tor_free);
  1567. }
  1568. }