Fix more leaks in unit tests.
[tor/rransom.git] / src / or / dirserv.c
blob336fa7c37732166fd718efa6ead332754d054c38
1 /* Copyright (c) 2001-2004, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2008, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
5 /* $Id$ */
6 const char dirserv_c_id[] =
7 "$Id$";
9 #define DIRSERV_PRIVATE
10 #include "or.h"
12 /**
13 * \file dirserv.c
14 * \brief Directory server core implementation. Manages directory
15 * contents and generates directories.
18 /** How far in the future do we allow a router to get? (seconds) */
19 #define ROUTER_ALLOW_SKEW (60*60*12)
20 /** How many seconds do we wait before regenerating the directory? */
21 #define DIR_REGEN_SLACK_TIME 30
22 /** If we're a cache, keep this many networkstatuses around from non-trusted
23 * directory authorities. */
24 #define MAX_UNTRUSTED_NETWORKSTATUSES 16
26 /** If a v1 directory is older than this, discard it. */
27 #define MAX_V1_DIRECTORY_AGE (30*24*60*60)
28 /** If a v1 running-routers is older than this, discard it. */
29 #define MAX_V1_RR_AGE (7*24*60*60)
31 extern time_t time_of_process_start; /* from main.c */
33 /** Do we need to regenerate the directory when someone asks for it? */
34 static time_t the_directory_is_dirty = 1;
35 static time_t runningrouters_is_dirty = 1;
36 static time_t the_v2_networkstatus_is_dirty = 1;
38 /** Most recently generated encoded signed v1 directory. (v1 auth dirservers
39 * only.) */
40 static cached_dir_t *the_directory = NULL;
42 /** For authoritative directories: the current (v1) network status. */
43 static cached_dir_t the_runningrouters = { NULL, NULL, 0, 0, 0, -1 };
45 static void directory_remove_invalid(void);
46 static cached_dir_t *dirserv_regenerate_directory(void);
47 static char *format_versions_list(config_line_t *ln);
48 struct authdir_config_t;
49 static int add_fingerprint_to_dir(const char *nickname, const char *fp,
50 struct authdir_config_t *list);
51 static uint32_t dirserv_router_get_status(const routerinfo_t *router,
52 const char **msg);
53 static uint32_t
54 dirserv_get_status_impl(const char *fp, const char *nickname,
55 const char *address,
56 uint32_t addr, uint16_t or_port,
57 const char *platform, const char *contact,
58 const char **msg, int should_log);
59 static void clear_cached_dir(cached_dir_t *d);
60 static signed_descriptor_t *get_signed_descriptor_by_fp(const char *fp,
61 int extrainfo,
62 time_t publish_cutoff);
63 static int dirserv_add_extrainfo(extrainfo_t *ei, const char **msg);
65 /************** Fingerprint handling code ************/
67 #define FP_NAMED 1 /**< Listed in fingerprint file. */
68 #define FP_INVALID 2 /**< Believed invalid. */
69 #define FP_REJECT 4 /**< We will not publish this router. */
70 #define FP_BADDIR 8 /**< We'll tell clients to avoid using this as a dir. */
71 #define FP_BADEXIT 16 /**< We'll tell clients not to use this as an exit. */
72 #define FP_UNNAMED 32 /**< Another router has this name in fingerprint file. */
74 /** Encapsulate a nickname and an FP_* status; target of status_by_digest
75 * map. */
76 typedef struct router_status_t {
77 char nickname[MAX_NICKNAME_LEN+1];
78 uint32_t status;
79 } router_status_t;
81 /** List of nickname-\>identity fingerprint mappings for all the routers
82 * that we name. Used to prevent router impersonation. */
83 typedef struct authdir_config_t {
84 strmap_t *fp_by_name; /**< Map from lc nickname to fingerprint. */
85 digestmap_t *status_by_digest; /**< Map from digest to router_status_t. */
86 } authdir_config_t;
88 /** Should be static; exposed for testing. */
89 static authdir_config_t *fingerprint_list = NULL;
91 /** Allocate and return a new, empty, authdir_config_t. */
92 static authdir_config_t *
93 authdir_config_new(void)
95 authdir_config_t *list = tor_malloc_zero(sizeof(authdir_config_t));
96 list->fp_by_name = strmap_new();
97 list->status_by_digest = digestmap_new();
98 return list;
101 /** Add the fingerprint <b>fp</b> for the nickname <b>nickname</b> to
102 * the smartlist of fingerprint_entry_t's <b>list</b>. Return 0 if it's
103 * new, or 1 if we replaced the old value.
105 /* static */ int
106 add_fingerprint_to_dir(const char *nickname, const char *fp,
107 authdir_config_t *list)
109 char *fingerprint;
110 char d[DIGEST_LEN];
111 router_status_t *status;
112 tor_assert(nickname);
113 tor_assert(fp);
114 tor_assert(list);
116 fingerprint = tor_strdup(fp);
117 tor_strstrip(fingerprint, " ");
118 if (base16_decode(d, DIGEST_LEN, fingerprint, strlen(fingerprint))) {
119 log_warn(LD_DIRSERV, "Couldn't decode fingerprint \"%s\"",
120 escaped(fp));
121 tor_free(fingerprint);
122 return 0;
125 if (!strcasecmp(nickname, UNNAMED_ROUTER_NICKNAME)) {
126 log_warn(LD_DIRSERV, "Tried to add a mapping for reserved nickname %s",
127 UNNAMED_ROUTER_NICKNAME);
128 tor_free(fingerprint);
129 return 0;
132 status = digestmap_get(list->status_by_digest, d);
133 if (!status) {
134 status = tor_malloc_zero(sizeof(router_status_t));
135 digestmap_set(list->status_by_digest, d, status);
138 if (nickname[0] != '!') {
139 char *old_fp = strmap_get_lc(list->fp_by_name, nickname);
140 if (old_fp && !strcasecmp(fingerprint, old_fp)) {
141 tor_free(fingerprint);
142 } else {
143 tor_free(old_fp);
144 strmap_set_lc(list->fp_by_name, nickname, fingerprint);
146 status->status |= FP_NAMED;
147 strlcpy(status->nickname, nickname, sizeof(status->nickname));
148 } else {
149 tor_free(fingerprint);
150 if (!strcasecmp(nickname, "!reject")) {
151 status->status |= FP_REJECT;
152 } else if (!strcasecmp(nickname, "!invalid")) {
153 status->status |= FP_INVALID;
154 } else if (!strcasecmp(nickname, "!baddir")) {
155 status->status |= FP_BADDIR;
156 } else if (!strcasecmp(nickname, "!badexit")) {
157 status->status |= FP_BADEXIT;
160 return 0;
163 /** Add the nickname and fingerprint for this OR to the
164 * global list of recognized identity key fingerprints. */
166 dirserv_add_own_fingerprint(const char *nickname, crypto_pk_env_t *pk)
168 char fp[FINGERPRINT_LEN+1];
169 if (crypto_pk_get_fingerprint(pk, fp, 0)<0) {
170 log_err(LD_BUG, "Error computing fingerprint");
171 return -1;
173 if (!fingerprint_list)
174 fingerprint_list = authdir_config_new();
175 add_fingerprint_to_dir(nickname, fp, fingerprint_list);
176 return 0;
179 /** Load the nickname-\>fingerprint mappings stored in the approved-routers
180 * file. The file format is line-based, with each non-blank holding one
181 * nickname, some space, and a fingerprint for that nickname. On success,
182 * replace the current fingerprint list with the new list and return 0. On
183 * failure, leave the current fingerprint list untouched, and
184 * return -1. */
186 dirserv_load_fingerprint_file(void)
188 char *fname;
189 char *cf;
190 char *nickname, *fingerprint;
191 authdir_config_t *fingerprint_list_new;
192 int result;
193 config_line_t *front=NULL, *list;
194 or_options_t *options = get_options();
196 fname = get_datadir_fname("approved-routers");
197 log_info(LD_GENERAL,
198 "Reloading approved fingerprints from \"%s\"...", fname);
200 cf = read_file_to_str(fname, RFTS_IGNORE_MISSING, NULL);
201 if (!cf) {
202 if (options->NamingAuthoritativeDir) {
203 log_warn(LD_FS, "Cannot open fingerprint file '%s'. Failing.", fname);
204 tor_free(fname);
205 return -1;
206 } else {
207 log_info(LD_FS, "Cannot open fingerprint file '%s'. That's ok.", fname);
208 tor_free(fname);
209 return 0;
212 tor_free(fname);
214 result = config_get_lines(cf, &front);
215 tor_free(cf);
216 if (result < 0) {
217 log_warn(LD_CONFIG, "Error reading from fingerprint file");
218 return -1;
221 fingerprint_list_new = authdir_config_new();
223 for (list=front; list; list=list->next) {
224 char digest_tmp[DIGEST_LEN];
225 nickname = list->key; fingerprint = list->value;
226 if (strlen(nickname) > MAX_NICKNAME_LEN) {
227 log_notice(LD_CONFIG,
228 "Nickname '%s' too long in fingerprint file. Skipping.",
229 nickname);
230 continue;
232 if (!is_legal_nickname(nickname) &&
233 strcasecmp(nickname, "!reject") &&
234 strcasecmp(nickname, "!invalid") &&
235 strcasecmp(nickname, "!badexit")) {
236 log_notice(LD_CONFIG,
237 "Invalid nickname '%s' in fingerprint file. Skipping.",
238 nickname);
239 continue;
241 tor_strstrip(fingerprint, " "); /* remove spaces */
242 if (strlen(fingerprint) != HEX_DIGEST_LEN ||
243 base16_decode(digest_tmp, sizeof(digest_tmp),
244 fingerprint, HEX_DIGEST_LEN) < 0) {
245 log_notice(LD_CONFIG,
246 "Invalid fingerprint (nickname '%s', "
247 "fingerprint %s). Skipping.",
248 nickname, fingerprint);
249 continue;
251 if (0==strcasecmp(nickname, DEFAULT_CLIENT_NICKNAME)) {
252 /* If you approved an OR called "client", then clients who use
253 * the default nickname could all be rejected. That's no good. */
254 log_notice(LD_CONFIG,
255 "Authorizing nickname '%s' would break "
256 "many clients; skipping.",
257 DEFAULT_CLIENT_NICKNAME);
258 continue;
260 if (0==strcasecmp(nickname, UNNAMED_ROUTER_NICKNAME)) {
261 /* If you approved an OR called "unnamed", then clients will be
262 * confused. */
263 log_notice(LD_CONFIG,
264 "Authorizing nickname '%s' is not allowed; skipping.",
265 UNNAMED_ROUTER_NICKNAME);
266 continue;
268 if (add_fingerprint_to_dir(nickname, fingerprint, fingerprint_list_new)
269 != 0)
270 log_notice(LD_CONFIG, "Duplicate nickname '%s'.", nickname);
273 config_free_lines(front);
274 dirserv_free_fingerprint_list();
275 fingerprint_list = fingerprint_list_new;
276 /* Delete any routers whose fingerprints we no longer recognize */
277 directory_remove_invalid();
278 return 0;
281 /** Check whether <b>router</b> has a nickname/identity key combination that
282 * we recognize from the fingerprint list, or an IP we automatically act on
283 * according to our configuration. Return the appropriate router status.
285 * If the status is 'FP_REJECT' and <b>msg</b> is provided, set
286 * *<b>msg</b> to an explanation of why. */
287 static uint32_t
288 dirserv_router_get_status(const routerinfo_t *router, const char **msg)
290 char d[DIGEST_LEN];
292 if (crypto_pk_get_digest(router->identity_pkey, d)) {
293 log_warn(LD_BUG,"Error computing fingerprint");
294 if (msg)
295 *msg = "Bug: Error computing fingerprint";
296 return FP_REJECT;
299 return dirserv_get_status_impl(d, router->nickname,
300 router->address,
301 router->addr, router->or_port,
302 router->platform, router->contact_info,
303 msg, 1);
306 /** Return true if there is no point in downloading the router described by
307 * <b>rs</b> because this directory would reject it. */
309 dirserv_would_reject_router(routerstatus_t *rs)
311 uint32_t res;
313 res = dirserv_get_status_impl(rs->identity_digest, rs->nickname,
314 "", /* address is only used in logs */
315 rs->addr, rs->or_port,
316 NULL, NULL,
317 NULL, 0);
319 return (res & FP_REJECT) != 0;
322 /** Helper: Based only on the ID/Nickname combination,
323 * return FP_UNNAMED (unnamed), FP_NAMED (named), or 0 (neither).
325 static uint32_t
326 dirserv_get_name_status(const char *id_digest, const char *nickname)
328 char fp[HEX_DIGEST_LEN+1];
329 char *fp_by_name;
331 base16_encode(fp, sizeof(fp), id_digest, DIGEST_LEN);
333 if ((fp_by_name =
334 strmap_get_lc(fingerprint_list->fp_by_name, nickname))) {
335 if (!strcasecmp(fp, fp_by_name)) {
336 return FP_NAMED;
337 } else {
338 return FP_UNNAMED; /* Wrong fingerprint. */
341 return 0;
344 /** Helper: As dirserv_get_router_status, but takes the router fingerprint
345 * (hex, no spaces), nickname, address (used for logging only), IP address, OR
346 * port, platform (logging only) and contact info (logging only) as arguments.
348 * If should_log is false, do not log messages. (There's not much point in
349 * logging that we're rejecting servers we'll not download.)
351 static uint32_t
352 dirserv_get_status_impl(const char *id_digest, const char *nickname,
353 const char *address,
354 uint32_t addr, uint16_t or_port,
355 const char *platform, const char *contact,
356 const char **msg, int should_log)
358 int reject_unlisted = get_options()->AuthDirRejectUnlisted;
359 uint32_t result = 0;
360 router_status_t *status_by_digest;
362 if (!fingerprint_list)
363 fingerprint_list = authdir_config_new();
365 if (should_log)
366 log_debug(LD_DIRSERV, "%d fingerprints, %d digests known.",
367 strmap_size(fingerprint_list->fp_by_name),
368 digestmap_size(fingerprint_list->status_by_digest));
370 /* 0.1.1.17-rc was the first version that claimed to be stable, doesn't
371 * crash and drop circuits all the time, and is even vaguely compatible with
372 * the current network */
373 if (platform && !tor_version_as_new_as(platform,"0.1.1.17-rc")) {
374 if (msg)
375 *msg = "Tor version is far too old to work.";
376 return FP_REJECT;
379 result = dirserv_get_name_status(id_digest, nickname);
380 if (result & FP_NAMED) {
381 if (should_log)
382 log_debug(LD_DIRSERV,"Good fingerprint for '%s'",nickname);
384 if (result & FP_UNNAMED) {
385 if (should_log) {
386 char *esc_contact = esc_for_log(contact);
387 log_info(LD_DIRSERV,
388 "Mismatched fingerprint for '%s'. "
389 "ContactInfo '%s', platform '%s'.)",
390 nickname,
391 esc_contact,
392 platform ? escaped(platform) : "");
393 tor_free(esc_contact);
395 if (msg)
396 *msg = "Rejected: There is already a named server with this nickname "
397 "and a different fingerprint.";
400 status_by_digest = digestmap_get(fingerprint_list->status_by_digest,
401 id_digest);
402 if (status_by_digest)
403 result |= (status_by_digest->status & ~FP_NAMED);
405 if (result & FP_REJECT) {
406 if (msg)
407 *msg = "Fingerprint is marked rejected";
408 return FP_REJECT;
409 } else if (result & FP_INVALID) {
410 if (msg)
411 *msg = "Fingerprint is marked invalid";
414 if (authdir_policy_baddir_address(addr, or_port)) {
415 if (should_log)
416 log_info(LD_DIRSERV,
417 "Marking '%s' as bad directory because of address '%s'",
418 nickname, address);
419 result |= FP_BADDIR;
422 if (authdir_policy_badexit_address(addr, or_port)) {
423 if (should_log)
424 log_info(LD_DIRSERV, "Marking '%s' as bad exit because of address '%s'",
425 nickname, address);
426 result |= FP_BADEXIT;
429 if (!(result & FP_NAMED)) {
430 if (!authdir_policy_permits_address(addr, or_port)) {
431 if (should_log)
432 log_info(LD_DIRSERV, "Rejecting '%s' because of address '%s'",
433 nickname, address);
434 if (msg)
435 *msg = "Authdir is rejecting routers in this range.";
436 return FP_REJECT;
438 if (!authdir_policy_valid_address(addr, or_port)) {
439 if (should_log)
440 log_info(LD_DIRSERV, "Not marking '%s' valid because of address '%s'",
441 nickname, address);
442 result |= FP_INVALID;
444 if (reject_unlisted) {
445 if (msg)
446 *msg = "Authdir rejects unknown routers.";
447 return FP_REJECT;
451 return result;
454 /** If we are an authoritative dirserver, and the list of approved
455 * servers contains one whose identity key digest is <b>digest</b>,
456 * return that router's nickname. Otherwise return NULL. */
457 const char *
458 dirserv_get_nickname_by_digest(const char *digest)
460 router_status_t *status;
461 if (!fingerprint_list)
462 return NULL;
463 tor_assert(digest);
465 status = digestmap_get(fingerprint_list->status_by_digest, digest);
466 return status ? status->nickname : NULL;
469 /** Clear the current fingerprint list. */
470 void
471 dirserv_free_fingerprint_list(void)
473 if (!fingerprint_list)
474 return;
476 strmap_free(fingerprint_list->fp_by_name, _tor_free);
477 digestmap_free(fingerprint_list->status_by_digest, _tor_free);
478 tor_free(fingerprint_list);
482 * Descriptor list
485 /** Return -1 if <b>ri</b> has a private or otherwise bad address,
486 * unless we're configured to not care. Return 0 if all ok. */
487 static int
488 dirserv_router_has_valid_address(routerinfo_t *ri)
490 struct in_addr iaddr;
491 if (get_options()->DirAllowPrivateAddresses)
492 return 0; /* whatever it is, we're fine with it */
493 if (!tor_inet_aton(ri->address, &iaddr)) {
494 log_info(LD_DIRSERV,"Router '%s' published non-IP address '%s'. Refusing.",
495 ri->nickname, ri->address);
496 return -1;
498 if (is_internal_IP(ntohl(iaddr.s_addr), 0)) {
499 log_info(LD_DIRSERV,
500 "Router '%s' published internal IP address '%s'. Refusing.",
501 ri->nickname, ri->address);
502 return -1; /* it's a private IP, we should reject it */
504 return 0;
507 /** Check whether we, as a directory server, want to accept <b>ri</b>. If so,
508 * set its is_valid,named,running fields and return 0. Otherwise, return -1.
510 * If the router is rejected, set *<b>msg</b> to an explanation of why.
512 * If <b>complain</b> then explain at log-level 'notice' why we refused
513 * a descriptor; else explain at log-level 'info'.
516 authdir_wants_to_reject_router(routerinfo_t *ri, const char **msg,
517 int complain)
519 /* Okay. Now check whether the fingerprint is recognized. */
520 uint32_t status = dirserv_router_get_status(ri, msg);
521 time_t now;
522 int severity = complain ? LOG_NOTICE : LOG_INFO;
523 tor_assert(msg);
524 if (status & FP_REJECT)
525 return -1; /* msg is already set. */
527 /* Is there too much clock skew? */
528 now = time(NULL);
529 if (ri->cache_info.published_on > now+ROUTER_ALLOW_SKEW) {
530 log_fn(severity, LD_DIRSERV, "Publication time for nickname '%s' is too "
531 "far (%d minutes) in the future; possible clock skew. Not adding "
532 "(%s)",
533 ri->nickname, (int)((ri->cache_info.published_on-now)/60),
534 esc_router_info(ri));
535 *msg = "Rejected: Your clock is set too far in the future, or your "
536 "timezone is not correct.";
537 return -1;
539 if (ri->cache_info.published_on < now-ROUTER_MAX_AGE_TO_PUBLISH) {
540 log_fn(severity, LD_DIRSERV,
541 "Publication time for router with nickname '%s' is too far "
542 "(%d minutes) in the past. Not adding (%s)",
543 ri->nickname, (int)((now-ri->cache_info.published_on)/60),
544 esc_router_info(ri));
545 *msg = "Rejected: Server is expired, or your clock is too far in the past,"
546 " or your timezone is not correct.";
547 return -1;
549 if (dirserv_router_has_valid_address(ri) < 0) {
550 log_fn(severity, LD_DIRSERV,
551 "Router with nickname '%s' has invalid address '%s'. "
552 "Not adding (%s).",
553 ri->nickname, ri->address,
554 esc_router_info(ri));
555 *msg = "Rejected: Address is not an IP, or IP is a private address.";
556 return -1;
558 /* Okay, looks like we're willing to accept this one. */
559 ri->is_named = (status & FP_NAMED) ? 1 : 0;
560 ri->is_valid = (status & FP_INVALID) ? 0 : 1;
561 ri->is_bad_directory = (status & FP_BADDIR) ? 1 : 0;
562 ri->is_bad_exit = (status & FP_BADEXIT) ? 1 : 0;
564 return 0;
567 /** True iff <b>a</b> is more severe than <b>b</b>. */
568 static int
569 WRA_MORE_SEVERE(was_router_added_t a, was_router_added_t b)
571 if (b == ROUTER_ADDED_SUCCESSFULLY) {
572 return a;
573 } else if (b == ROUTER_ADDED_NOTIFY_GENERATOR) {
574 return !WRA_WAS_ADDED(a);
575 } else {
576 return a < b;
580 /** As for dirserv_add_descriptor(), but accepts multiple documents, and
581 * returns the most severe error that occurred for any one of them. */
582 was_router_added_t
583 dirserv_add_multiple_descriptors(const char *desc, uint8_t purpose,
584 const char *source,
585 const char **msg)
587 int r=ROUTER_ADDED_NOTIFY_GENERATOR; /* highest possible return value. */
588 int r_tmp;
589 const char *msg_out;
590 smartlist_t *list;
591 const char *s;
592 int n_parsed = 0;
593 time_t now = time(NULL);
594 char annotation_buf[ROUTER_ANNOTATION_BUF_LEN];
595 char time_buf[ISO_TIME_LEN+1];
596 int general = purpose == ROUTER_PURPOSE_GENERAL;
597 tor_assert(msg);
599 format_iso_time(time_buf, now);
600 if (tor_snprintf(annotation_buf, sizeof(annotation_buf),
601 "@uploaded-at %s\n"
602 "@source %s\n"
603 "%s%s%s", time_buf, escaped(source),
604 !general ? "@purpose " : "",
605 !general ? router_purpose_to_string(purpose) : "",
606 !general ? "\n" : "")<0) {
607 *msg = "Couldn't format annotations";
608 return -1;
611 s = desc;
612 list = smartlist_create();
613 if (!router_parse_list_from_string(&s, NULL, list, SAVED_NOWHERE, 0, 0,
614 annotation_buf)) {
615 SMARTLIST_FOREACH(list, routerinfo_t *, ri, {
616 msg_out = NULL;
617 tor_assert(ri->purpose == purpose);
618 r_tmp = dirserv_add_descriptor(ri, &msg_out);
619 if (WRA_MORE_SEVERE(r_tmp, r)) {
620 r = r_tmp;
621 *msg = msg_out;
625 n_parsed += smartlist_len(list);
626 smartlist_clear(list);
628 s = desc;
629 if (!router_parse_list_from_string(&s, NULL, list, SAVED_NOWHERE, 1, 0,
630 NULL)) {
631 SMARTLIST_FOREACH(list, extrainfo_t *, ei, {
632 msg_out = NULL;
634 r_tmp = dirserv_add_extrainfo(ei, &msg_out);
635 if (WRA_MORE_SEVERE(r_tmp, r)) {
636 r = r_tmp;
637 *msg = msg_out;
641 n_parsed += smartlist_len(list);
642 smartlist_free(list);
644 if (! *msg) {
645 if (!n_parsed) {
646 *msg = "No descriptors found in your POST.";
647 if (r > -1)
648 r = -1;
649 } else {
650 *msg = "(no message)";
654 return r;
657 /** Examine the parsed server descriptor in <b>ri</b> and maybe insert it into
658 * the list of server descriptors. Set *<b>msg</b> to a message that should be
659 * passed back to the origin of this descriptor.
662 * Return 2 if descriptor is well-formed and accepted;
663 * 1 if well-formed and accepted but origin should hear *msg;
664 * 0 if well-formed but redundant with one we already have;
665 * -1 if it is rejected and origin should hear *msg;
668 * This function is only called when fresh descriptors are posted, not when
669 * we re-load the cache.
671 was_router_added_t
672 dirserv_add_descriptor(routerinfo_t *ri, const char **msg)
674 was_router_added_t r;
675 routerinfo_t *ri_old;
676 char *desc = NULL;
677 size_t desclen = 0;
679 /* If it's too big, refuse it now. Otherwise we'll cache it all over the
680 * network and it'll clog everything up. */
681 if (ri->cache_info.signed_descriptor_len > MAX_DESCRIPTOR_UPLOAD_SIZE) {
682 log_notice(LD_DIR, "Somebody attempted to publish a router descriptor "
683 "with size %d. Either this is an attack, or the "
684 "MAX_DESCRIPTOR_UPLOAD_SIZE (%d) constant is too low.",
685 (int)ri->cache_info.signed_descriptor_len,
686 MAX_DESCRIPTOR_UPLOAD_SIZE);
687 *msg = "Router descriptor was too large";
688 control_event_or_authdir_new_descriptor("REJECTED",
689 ri->cache_info.signed_descriptor_body,
690 ri->cache_info.signed_descriptor_len, *msg);
691 routerinfo_free(ri);
692 return -1;
695 /* Check whether this descriptor is semantically identical to the last one
696 * from this server. (We do this here and not in router_add_to_routerlist
697 * because we want to be able to accept the newest router descriptor that
698 * another authority has, so we all converge on the same one.) */
699 ri_old = router_get_by_digest(ri->cache_info.identity_digest);
700 if (ri_old && ri_old->cache_info.published_on < ri->cache_info.published_on
701 && router_differences_are_cosmetic(ri_old, ri)
702 && !router_is_me(ri)) {
703 log_info(LD_DIRSERV,
704 "Not replacing descriptor from '%s'; differences are cosmetic.",
705 ri->nickname);
706 *msg = "Not replacing router descriptor; no information has changed since "
707 "the last one with this identity.";
708 control_event_or_authdir_new_descriptor("DROPPED",
709 ri->cache_info.signed_descriptor_body,
710 ri->cache_info.signed_descriptor_len, *msg);
711 routerinfo_free(ri);
712 return 0;
714 if (control_event_is_interesting(EVENT_AUTHDIR_NEWDESCS)) {
715 /* Make a copy of desc, since router_add_to_routerlist might free
716 * ri and its associated signed_descriptor_t. */
717 desclen = ri->cache_info.signed_descriptor_len;
718 desc = tor_strndup(ri->cache_info.signed_descriptor_body, desclen);
721 r = router_add_to_routerlist(ri, msg, 0, 0);
722 if (!WRA_WAS_ADDED(r)) {
723 /* unless the routerinfo was fine, just out-of-date */
724 if (WRA_WAS_REJECTED(r) && desc)
725 control_event_or_authdir_new_descriptor("REJECTED", desc, desclen, *msg);
726 tor_free(desc);
727 } else {
728 smartlist_t *changed;
729 if (desc)
730 control_event_or_authdir_new_descriptor("ACCEPTED", desc, desclen, *msg);
732 changed = smartlist_create();
733 smartlist_add(changed, ri);
734 control_event_descriptors_changed(changed);
735 smartlist_free(changed);
736 if (!*msg) {
737 *msg = ri->is_valid ? "Descriptor for valid server accepted" :
738 "Descriptor for invalid server accepted";
740 tor_free(desc);
742 return r;
745 /** As dirserv_add_descriptor, but for an extrainfo_t <b>ei</b>. */
746 static int
747 dirserv_add_extrainfo(extrainfo_t *ei, const char **msg)
749 routerinfo_t *ri;
750 int r;
751 tor_assert(msg);
752 *msg = NULL;
754 ri = router_get_by_digest(ei->cache_info.identity_digest);
755 if (!ri) {
756 *msg = "No corresponding router descriptor for extra-info descriptor";
757 extrainfo_free(ei);
758 return -1;
761 /* If it's too big, refuse it now. Otherwise we'll cache it all over the
762 * network and it'll clog everything up. */
763 if (ei->cache_info.signed_descriptor_len > MAX_EXTRAINFO_UPLOAD_SIZE) {
764 log_notice(LD_DIR, "Somebody attempted to publish an extrainfo "
765 "with size %d. Either this is an attack, or the "
766 "MAX_EXTRAINFO_UPLOAD_SIZE (%d) constant is too low.",
767 (int)ei->cache_info.signed_descriptor_len,
768 MAX_EXTRAINFO_UPLOAD_SIZE);
769 *msg = "Extrainfo document was too large";
770 extrainfo_free(ei);
771 return -1;
774 if ((r = routerinfo_incompatible_with_extrainfo(ri, ei, NULL, msg))) {
775 extrainfo_free(ei);
776 return r < 0 ? 0 : -1;
778 router_add_extrainfo_to_routerlist(ei, msg, 0, 0);
779 return 2;
782 /** Remove all descriptors whose nicknames or fingerprints no longer
783 * are allowed by our fingerprint list. (Descriptors that used to be
784 * good can become bad when we reload the fingerprint list.)
786 static void
787 directory_remove_invalid(void)
789 int i;
790 int changed = 0;
791 routerlist_t *rl = router_get_routerlist();
793 routerlist_assert_ok(rl);
795 for (i = 0; i < smartlist_len(rl->routers); ++i) {
796 const char *msg;
797 routerinfo_t *ent = smartlist_get(rl->routers, i);
798 uint32_t r = dirserv_router_get_status(ent, &msg);
799 if (r & FP_REJECT) {
800 log_info(LD_DIRSERV, "Router '%s' is now rejected: %s",
801 ent->nickname, msg?msg:"");
802 routerlist_remove(rl, ent, 0);
803 i--;
804 changed = 1;
805 continue;
807 if (bool_neq((r & FP_NAMED), ent->is_named)) {
808 log_info(LD_DIRSERV,
809 "Router '%s' is now %snamed.", ent->nickname,
810 (r&FP_NAMED)?"":"un");
811 ent->is_named = (r&FP_NAMED)?1:0;
812 changed = 1;
814 if (bool_neq((r & FP_INVALID), !ent->is_valid)) {
815 log_info(LD_DIRSERV, "Router '%s' is now %svalid.", ent->nickname,
816 (r&FP_INVALID) ? "in" : "");
817 ent->is_valid = (r&FP_INVALID)?0:1;
818 changed = 1;
820 if (bool_neq((r & FP_BADDIR), ent->is_bad_directory)) {
821 log_info(LD_DIRSERV, "Router '%s' is now a %s directory", ent->nickname,
822 (r & FP_BADDIR) ? "bad" : "good");
823 ent->is_bad_directory = (r&FP_BADDIR) ? 1: 0;
824 changed = 1;
826 if (bool_neq((r & FP_BADEXIT), ent->is_bad_exit)) {
827 log_info(LD_DIRSERV, "Router '%s' is now a %s exit", ent->nickname,
828 (r & FP_BADEXIT) ? "bad" : "good");
829 ent->is_bad_exit = (r&FP_BADEXIT) ? 1: 0;
830 changed = 1;
833 if (changed)
834 directory_set_dirty();
836 routerlist_assert_ok(rl);
839 /** Write a list of unregistered descriptors into a newly allocated
840 * string and return it. Used by dirserv operators to keep track of
841 * fast nodes that haven't registered.
844 getinfo_helper_dirserv_unregistered(control_connection_t *control_conn,
845 const char *question, char **answer_out)
847 smartlist_t *answerlist;
848 char buf[1024];
849 char *answer;
850 int min_bw = atoi(question);
851 routerlist_t *rl = router_get_routerlist();
853 (void) control_conn;
855 if (strcmpstart(question, "unregistered-servers-"))
856 return 0;
857 question += strlen("unregistered-servers-");
859 answerlist = smartlist_create();
860 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ent, {
861 uint32_t r = dirserv_router_get_status(ent, NULL);
862 if (router_get_advertised_bandwidth(ent) >= (size_t)min_bw &&
863 !(r & FP_NAMED)) {
864 /* then log this one */
865 tor_snprintf(buf, sizeof(buf),
866 "%s: BW %d on '%s'.",
867 ent->nickname, router_get_advertised_bandwidth(ent),
868 ent->platform ? ent->platform : "");
869 smartlist_add(answerlist, tor_strdup(buf));
872 answer = smartlist_join_strings(answerlist, "\r\n", 0, NULL);
873 SMARTLIST_FOREACH(answerlist, char *, cp, tor_free(cp));
874 smartlist_free(answerlist);
875 *answer_out = answer;
876 return 0;
879 /** Mark the directory as <b>dirty</b> -- when we're next asked for a
880 * directory, we will rebuild it instead of reusing the most recently
881 * generated one.
883 void
884 directory_set_dirty(void)
886 time_t now = time(NULL);
887 int set_v1_dirty=0;
889 /* Regenerate stubs only every 8 hours.
890 * XXXX021 It would be nice to generate less often. */
891 #define STUB_REGENERATE_INTERVAL (8*60*60)
892 if (!the_directory || !the_runningrouters.dir)
893 set_v1_dirty = 1;
894 else if (the_directory->published < now - STUB_REGENERATE_INTERVAL ||
895 the_runningrouters.published < now - STUB_REGENERATE_INTERVAL)
896 set_v1_dirty = 1;
898 if (set_v1_dirty) {
899 if (!the_directory_is_dirty)
900 the_directory_is_dirty = now;
901 if (!runningrouters_is_dirty)
902 runningrouters_is_dirty = now;
904 if (!the_v2_networkstatus_is_dirty)
905 the_v2_networkstatus_is_dirty = now;
909 * Allocate and return a description of the status of the server <b>desc</b>,
910 * for use in a v1-style router-status line. The server is listed
911 * as running iff <b>is_live</b> is true.
913 static char *
914 list_single_server_status(routerinfo_t *desc, int is_live)
916 char buf[MAX_NICKNAME_LEN+HEX_DIGEST_LEN+4]; /* !nickname=$hexdigest\0 */
917 char *cp;
919 tor_assert(desc);
921 cp = buf;
922 if (!is_live) {
923 *cp++ = '!';
925 if (desc->is_valid) {
926 strlcpy(cp, desc->nickname, sizeof(buf)-(cp-buf));
927 cp += strlen(cp);
928 *cp++ = '=';
930 *cp++ = '$';
931 base16_encode(cp, HEX_DIGEST_LEN+1, desc->cache_info.identity_digest,
932 DIGEST_LEN);
933 return tor_strdup(buf);
936 /** Each server needs to have passed a reachability test no more
937 * than this number of seconds ago, or he is listed as down in
938 * the directory. */
939 #define REACHABLE_TIMEOUT (45*60)
941 /** Treat a router as alive if
942 * - It's me, and I'm not hibernating.
943 * or - We've found it reachable recently. */
944 void
945 dirserv_set_router_is_running(routerinfo_t *router, time_t now)
947 int answer;
949 if (router_is_me(router) && !we_are_hibernating())
950 answer = 1;
951 else
952 answer = get_options()->AssumeReachable ||
953 now < router->last_reachable + REACHABLE_TIMEOUT;
955 if (router->is_running && !answer) {
956 /* it was running but now it's not. tell rephist. */
957 rep_hist_note_router_unreachable(router->cache_info.identity_digest, now);
960 router->is_running = answer;
963 /** Based on the routerinfo_ts in <b>routers</b>, allocate the
964 * contents of a v1-style router-status line, and store it in
965 * *<b>router_status_out</b>. Return 0 on success, -1 on failure.
967 * If for_controller is true, include the routers with very old descriptors.
968 * If for_controller is &gt;1, use the verbose nickname format.
971 list_server_status_v1(smartlist_t *routers, char **router_status_out,
972 int for_controller)
974 /* List of entries in a router-status style: An optional !, then an optional
975 * equals-suffixed nickname, then a dollar-prefixed hexdigest. */
976 smartlist_t *rs_entries;
977 time_t now = time(NULL);
978 time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
979 or_options_t *options = get_options();
980 /* We include v2 dir auths here too, because they need to answer
981 * controllers. Eventually we'll deprecate this whole function;
982 * see also networkstatus_getinfo_by_purpose(). */
983 int authdir = authdir_mode_publishes_statuses(options);
984 tor_assert(router_status_out);
986 rs_entries = smartlist_create();
988 SMARTLIST_FOREACH(routers, routerinfo_t *, ri,
990 if (authdir) {
991 /* Update router status in routerinfo_t. */
992 dirserv_set_router_is_running(ri, now);
994 if (for_controller == 1 || ri->cache_info.published_on >= cutoff)
995 smartlist_add(rs_entries, list_single_server_status(ri, ri->is_running));
996 else if (for_controller > 2) {
997 char name_buf[MAX_VERBOSE_NICKNAME_LEN+2];
998 char *cp = name_buf;
999 if (!ri->is_running)
1000 *cp++ = '!';
1001 router_get_verbose_nickname(cp, ri);
1002 smartlist_add(rs_entries, tor_strdup(name_buf));
1006 *router_status_out = smartlist_join_strings(rs_entries, " ", 0, NULL);
1008 SMARTLIST_FOREACH(rs_entries, char *, cp, tor_free(cp));
1009 smartlist_free(rs_entries);
1011 return 0;
1014 /** Given a (possibly empty) list of config_line_t, each line of which contains
1015 * a list of comma-separated version numbers surrounded by optional space,
1016 * allocate and return a new string containing the version numbers, in order,
1017 * separated by commas. Used to generate Recommended(Client|Server)?Versions
1019 static char *
1020 format_versions_list(config_line_t *ln)
1022 smartlist_t *versions;
1023 char *result;
1024 versions = smartlist_create();
1025 for ( ; ln; ln = ln->next) {
1026 smartlist_split_string(versions, ln->value, ",",
1027 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1029 sort_version_list(versions, 1);
1030 result = smartlist_join_strings(versions,",",0,NULL);
1031 SMARTLIST_FOREACH(versions,char *,s,tor_free(s));
1032 smartlist_free(versions);
1033 return result;
1036 /** Return 1 if <b>ri</b>'s descriptor is "active" -- running, valid,
1037 * not hibernating, and not too old. Else return 0.
1039 static int
1040 router_is_active(routerinfo_t *ri, time_t now)
1042 time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
1043 if (ri->cache_info.published_on < cutoff)
1044 return 0;
1045 if (!ri->is_running || !ri->is_valid || ri->is_hibernating)
1046 return 0;
1047 return 1;
1050 /** Generate a new v1 directory and write it into a newly allocated string.
1051 * Point *<b>dir_out</b> to the allocated string. Sign the
1052 * directory with <b>private_key</b>. Return 0 on success, -1 on
1053 * failure. If <b>complete</b> is set, give us all the descriptors;
1054 * otherwise leave out non-running and non-valid ones.
1057 dirserv_dump_directory_to_string(char **dir_out,
1058 crypto_pk_env_t *private_key)
1060 char *cp;
1061 char *identity_pkey; /* Identity key, DER64-encoded. */
1062 char *recommended_versions;
1063 char digest[DIGEST_LEN];
1064 char published[ISO_TIME_LEN+1];
1065 char *buf = NULL;
1066 size_t buf_len;
1067 size_t identity_pkey_len;
1068 time_t now = time(NULL);
1070 tor_assert(dir_out);
1071 *dir_out = NULL;
1073 if (crypto_pk_write_public_key_to_string(private_key,&identity_pkey,
1074 &identity_pkey_len)<0) {
1075 log_warn(LD_BUG,"write identity_pkey to string failed!");
1076 return -1;
1079 recommended_versions =
1080 format_versions_list(get_options()->RecommendedVersions);
1082 format_iso_time(published, now);
1084 buf_len = 2048+strlen(recommended_versions);
1086 buf = tor_malloc(buf_len);
1087 /* We'll be comparing against buf_len throughout the rest of the
1088 function, though strictly speaking we shouldn't be able to exceed
1089 it. This is C, after all, so we may as well check for buffer
1090 overruns.*/
1092 tor_snprintf(buf, buf_len,
1093 "signed-directory\n"
1094 "published %s\n"
1095 "recommended-software %s\n"
1096 "router-status %s\n"
1097 "dir-signing-key\n%s\n",
1098 published, recommended_versions, "",
1099 identity_pkey);
1101 tor_free(recommended_versions);
1102 tor_free(identity_pkey);
1104 cp = buf + strlen(buf);
1105 *cp = '\0';
1107 /* These multiple strlcat calls are inefficient, but dwarfed by the RSA
1108 signature. */
1109 if (strlcat(buf, "directory-signature ", buf_len) >= buf_len)
1110 goto truncated;
1111 if (strlcat(buf, get_options()->Nickname, buf_len) >= buf_len)
1112 goto truncated;
1113 if (strlcat(buf, "\n", buf_len) >= buf_len)
1114 goto truncated;
1116 if (router_get_dir_hash(buf,digest)) {
1117 log_warn(LD_BUG,"couldn't compute digest");
1118 tor_free(buf);
1119 return -1;
1121 note_crypto_pk_op(SIGN_DIR);
1122 if (router_append_dirobj_signature(buf,buf_len,digest,private_key)<0) {
1123 tor_free(buf);
1124 return -1;
1127 *dir_out = buf;
1128 return 0;
1129 truncated:
1130 log_warn(LD_BUG,"tried to exceed string length.");
1131 tor_free(buf);
1132 return -1;
1135 /********************************************************************/
1137 /* A set of functions to answer questions about how we'd like to behave
1138 * as a directory mirror/client. */
1140 /** Return 1 if we fetch our directory material directly from the
1141 * authorities, rather than from a mirror. */
1143 directory_fetches_from_authorities(or_options_t *options)
1145 routerinfo_t *me;
1146 uint32_t addr;
1147 if (options->FetchDirInfoEarly)
1148 return 1;
1149 if (options->BridgeRelay == 1)
1150 return 0;
1151 if (server_mode(options) && router_pick_published_address(options, &addr)<0)
1152 return 1; /* we don't know our IP address; ask an authority. */
1153 if (options->DirPort == 0)
1154 return 0;
1155 if (!server_mode(options) || !advertised_server_mode())
1156 return 0;
1157 me = router_get_my_routerinfo();
1158 if (!me || !me->dir_port)
1159 return 0; /* if dirport not advertised, return 0 too */
1160 return 1;
1163 /* Return 1 if we should fetch new networkstatuses, descriptors, etc
1164 * on the "mirror" schedule rather than the "client" schedule.
1167 directory_fetches_dir_info_early(or_options_t *options)
1169 return directory_fetches_from_authorities(options);
1172 /* Return 1 if we should fetch new networkstatuses, descriptors, etc
1173 * on a very passive schedule -- waiting long enough for ordinary clients
1174 * to probably have the info we want. These would include bridge users,
1175 * and maybe others in the future e.g. if a Tor client uses another Tor
1176 * client as a directory guard.
1179 directory_fetches_dir_info_later(or_options_t *options)
1181 return options->UseBridges != 0;
1184 /** Return 1 if we want to cache v2 dir info (each status file).
1187 directory_caches_v2_dir_info(or_options_t *options)
1189 return options->DirPort != 0;
1192 /** Return 1 if we want to keep descriptors, networkstatuses, etc around
1193 * and we're willing to serve them to others. Else return 0.
1196 directory_caches_dir_info(or_options_t *options)
1198 return options->BridgeRelay != 0 || options->DirPort != 0;
1201 /** Return 1 if we want to allow remote people to ask us directory
1202 * requests via the "begin_dir" interface, which doesn't require
1203 * having any separate port open. */
1205 directory_permits_begindir_requests(or_options_t *options)
1207 return options->BridgeRelay != 0 || options->DirPort != 0;
1210 /** Return 1 if we want to allow controllers to ask us directory
1211 * requests via the controller interface, which doesn't require
1212 * having any separate port open. */
1214 directory_permits_controller_requests(or_options_t *options)
1216 return options->DirPort != 0;
1219 /** Return 1 if we have no need to fetch new descriptors. This generally
1220 * happens when we're not a dir cache and we haven't built any circuits
1221 * lately.
1224 directory_too_idle_to_fetch_descriptors(or_options_t *options, time_t now)
1226 return !options->DirPort && !options->FetchUselessDescriptors &&
1227 rep_hist_circbuilding_dormant(now);
1230 /********************************************************************/
1232 /* Used only by non-v1-auth dirservers: The v1 directory and
1233 * runningrouters we'll serve when requested. */
1234 static cached_dir_t *cached_directory = NULL;
1235 static cached_dir_t cached_runningrouters = { NULL, NULL, 0, 0, 0, -1 };
1237 /** Used for other dirservers' v2 network statuses. Map from hexdigest to
1238 * cached_dir_t. */
1239 static digestmap_t *cached_v2_networkstatus = NULL;
1241 /** The v3 consensus network status that we're currently serving. */
1242 static cached_dir_t *cached_v3_networkstatus = NULL;
1244 /** Possibly replace the contents of <b>d</b> with the value of
1245 * <b>directory</b> published on <b>when</b>, unless <b>when</b> is older than
1246 * the last value, or too far in the future.
1248 * Does not copy <b>directory</b>; frees it if it isn't used.
1250 static void
1251 set_cached_dir(cached_dir_t *d, char *directory, time_t when)
1253 time_t now = time(NULL);
1254 if (when<=d->published) {
1255 log_info(LD_DIRSERV, "Ignoring old directory; not caching.");
1256 tor_free(directory);
1257 } else if (when>=now+ROUTER_MAX_AGE_TO_PUBLISH) {
1258 log_info(LD_DIRSERV, "Ignoring future directory; not caching.");
1259 tor_free(directory);
1260 } else {
1261 /* if (when>d->published && when<now+ROUTER_MAX_AGE) */
1262 log_debug(LD_DIRSERV, "Caching directory.");
1263 tor_free(d->dir);
1264 d->dir = directory;
1265 d->dir_len = strlen(directory);
1266 tor_free(d->dir_z);
1267 if (tor_gzip_compress(&(d->dir_z), &(d->dir_z_len), d->dir, d->dir_len,
1268 ZLIB_METHOD)) {
1269 log_warn(LD_BUG,"Error compressing cached directory");
1271 d->published = when;
1275 /** Decrement the reference count on <b>d</b>, and free it if it no longer has
1276 * any references. */
1277 void
1278 cached_dir_decref(cached_dir_t *d)
1280 if (!d || --d->refcnt > 0)
1281 return;
1282 clear_cached_dir(d);
1283 tor_free(d);
1286 /** Allocate and return a new cached_dir_t containing the string <b>s</b>,
1287 * published at <b>published</b>. */
1288 cached_dir_t *
1289 new_cached_dir(char *s, time_t published)
1291 cached_dir_t *d = tor_malloc_zero(sizeof(cached_dir_t));
1292 d->refcnt = 1;
1293 d->dir = s;
1294 d->dir_len = strlen(s);
1295 d->published = published;
1296 if (tor_gzip_compress(&(d->dir_z), &(d->dir_z_len), d->dir, d->dir_len,
1297 ZLIB_METHOD)) {
1298 log_warn(LD_BUG, "Error compressing directory");
1300 return d;
1303 /** Remove all storage held in <b>d</b>, but do not free <b>d</b> itself. */
1304 static void
1305 clear_cached_dir(cached_dir_t *d)
1307 tor_free(d->dir);
1308 tor_free(d->dir_z);
1309 memset(d, 0, sizeof(cached_dir_t));
1312 /** Free all storage held by the cached_dir_t in <b>d</b>. */
1313 static void
1314 _free_cached_dir(void *_d)
1316 cached_dir_t *d = (cached_dir_t *)_d;
1317 cached_dir_decref(d);
1320 /** If we have no cached v1 directory, or it is older than <b>published</b>,
1321 * then replace it with <b>directory</b>, published at <b>published</b>.
1323 * If <b>published</b> is too old, do nothing.
1325 * If <b>is_running_routers</b>, this is really a v1 running_routers
1326 * document rather than a v1 directory.
1328 void
1329 dirserv_set_cached_directory(const char *directory, time_t published,
1330 int is_running_routers)
1332 time_t now = time(NULL);
1334 if (is_running_routers) {
1335 if (published >= now - MAX_V1_RR_AGE)
1336 set_cached_dir(&cached_runningrouters, tor_strdup(directory), published);
1337 } else {
1338 if (published >= now - MAX_V1_DIRECTORY_AGE) {
1339 cached_dir_decref(cached_directory);
1340 cached_directory = new_cached_dir(tor_strdup(directory), published);
1345 /** If <b>networkstatus</b> is non-NULL, we've just received a v2
1346 * network-status for an authoritative directory with identity digest
1347 * <b>identity</b> published at <b>published</b> -- store it so we can
1348 * serve it to others.
1350 * If <b>networkstatus</b> is NULL, remove the entry with the given
1351 * identity fingerprint from the v2 cache.
1353 void
1354 dirserv_set_cached_networkstatus_v2(const char *networkstatus,
1355 const char *identity,
1356 time_t published)
1358 cached_dir_t *d, *old_d;
1359 smartlist_t *trusted_dirs;
1360 if (!cached_v2_networkstatus)
1361 cached_v2_networkstatus = digestmap_new();
1363 old_d = digestmap_get(cached_v2_networkstatus, identity);
1364 if (!old_d && !networkstatus)
1365 return;
1367 if (networkstatus) {
1368 if (!old_d || published > old_d->published) {
1369 d = new_cached_dir(tor_strdup(networkstatus), published);
1370 digestmap_set(cached_v2_networkstatus, identity, d);
1371 if (old_d)
1372 cached_dir_decref(old_d);
1374 } else {
1375 if (old_d) {
1376 digestmap_remove(cached_v2_networkstatus, identity);
1377 cached_dir_decref(old_d);
1381 /* Now purge old entries. */
1382 trusted_dirs = router_get_trusted_dir_servers();
1383 if (digestmap_size(cached_v2_networkstatus) >
1384 smartlist_len(trusted_dirs) + MAX_UNTRUSTED_NETWORKSTATUSES) {
1385 /* We need to remove the oldest untrusted networkstatus. */
1386 const char *oldest = NULL;
1387 time_t oldest_published = TIME_MAX;
1388 digestmap_iter_t *iter;
1390 for (iter = digestmap_iter_init(cached_v2_networkstatus);
1391 !digestmap_iter_done(iter);
1392 iter = digestmap_iter_next(cached_v2_networkstatus, iter)) {
1393 const char *ident;
1394 void *val;
1395 digestmap_iter_get(iter, &ident, &val);
1396 d = val;
1397 if (d->published < oldest_published &&
1398 !router_digest_is_trusted_dir(ident)) {
1399 oldest = ident;
1400 oldest_published = d->published;
1403 tor_assert(oldest);
1404 d = digestmap_remove(cached_v2_networkstatus, oldest);
1405 if (d)
1406 cached_dir_decref(d);
1410 /** Replace the v3 consensus networkstatus that we're serving with
1411 * <b>networkstatus</b>, published at <b>published</b>. No validation is
1412 * performed. */
1413 void
1414 dirserv_set_cached_networkstatus_v3(const char *networkstatus,
1415 time_t published)
1417 if (cached_v3_networkstatus)
1418 cached_dir_decref(cached_v3_networkstatus);
1419 cached_v3_networkstatus = new_cached_dir(
1420 tor_strdup(networkstatus), published);
1423 /** Remove any v2 networkstatus from the directory cache that was published
1424 * before <b>cutoff</b>. */
1425 void
1426 dirserv_clear_old_networkstatuses(time_t cutoff)
1428 if (!cached_v2_networkstatus)
1429 return;
1431 DIGESTMAP_FOREACH_MODIFY(cached_v2_networkstatus, id, cached_dir_t *, dir) {
1432 if (dir->published < cutoff) {
1433 char *fname;
1434 fname = networkstatus_get_cache_filename(id);
1435 if (file_status(fname) == FN_FILE) {
1436 log_info(LD_DIR, "Removing too-old untrusted networkstatus in %s",
1437 fname);
1438 unlink(fname);
1440 tor_free(fname);
1441 cached_dir_decref(dir);
1442 MAP_DEL_CURRENT(id);
1444 } DIGESTMAP_FOREACH_END
1447 /** Remove any v1 info from the directory cache that was published
1448 * too long ago. */
1449 void
1450 dirserv_clear_old_v1_info(time_t now)
1452 if (cached_directory &&
1453 cached_directory->published < (now - MAX_V1_DIRECTORY_AGE)) {
1454 cached_dir_decref(cached_directory);
1455 cached_directory = NULL;
1457 if (cached_runningrouters.published < (now - MAX_V1_RR_AGE)) {
1458 clear_cached_dir(&cached_runningrouters);
1462 /** Helper: If we're an authority for the right directory version (v1 or v2)
1463 * (based on <b>auth_type</b>), try to regenerate
1464 * auth_src as appropriate and return it, falling back to cache_src on
1465 * failure. If we're a cache, simply return cache_src.
1467 static cached_dir_t *
1468 dirserv_pick_cached_dir_obj(cached_dir_t *cache_src,
1469 cached_dir_t *auth_src,
1470 time_t dirty, cached_dir_t *(*regenerate)(void),
1471 const char *name,
1472 authority_type_t auth_type)
1474 or_options_t *options = get_options();
1475 int authority = (auth_type == V1_AUTHORITY && authdir_mode_v1(options)) ||
1476 (auth_type == V2_AUTHORITY && authdir_mode_v2(options));
1478 if (!authority || authdir_mode_bridge(options)) {
1479 return cache_src;
1480 } else {
1481 /* We're authoritative. */
1482 if (regenerate != NULL) {
1483 if (dirty && dirty + DIR_REGEN_SLACK_TIME < time(NULL)) {
1484 if (!(auth_src = regenerate())) {
1485 log_err(LD_BUG, "Couldn't generate %s?", name);
1486 exit(1);
1488 } else {
1489 log_info(LD_DIRSERV, "The %s is still clean; reusing.", name);
1492 return auth_src ? auth_src : cache_src;
1496 /** Return the most recently generated encoded signed v1 directory,
1497 * generating a new one as necessary. If not a v1 authoritative directory
1498 * may return NULL if no directory is yet cached. */
1499 cached_dir_t *
1500 dirserv_get_directory(void)
1502 return dirserv_pick_cached_dir_obj(cached_directory, the_directory,
1503 the_directory_is_dirty,
1504 dirserv_regenerate_directory,
1505 "v1 server directory", V1_AUTHORITY);
1508 /** Only called by v1 auth dirservers.
1509 * Generate a fresh v1 directory; set the_directory and return a pointer
1510 * to the new value.
1512 static cached_dir_t *
1513 dirserv_regenerate_directory(void)
1515 char *new_directory=NULL;
1517 if (dirserv_dump_directory_to_string(&new_directory, get_identity_key())) {
1518 log_warn(LD_BUG, "Error creating directory.");
1519 tor_free(new_directory);
1520 return NULL;
1522 cached_dir_decref(the_directory);
1523 the_directory = new_cached_dir(new_directory, time(NULL));
1524 log_info(LD_DIRSERV,"New directory (size %d) has been built.",
1525 (int)the_directory->dir_len);
1526 log_debug(LD_DIRSERV,"New directory (size %d):\n%s",
1527 (int)the_directory->dir_len, the_directory->dir);
1529 the_directory_is_dirty = 0;
1531 /* Save the directory to disk so we re-load it quickly on startup.
1533 dirserv_set_cached_directory(the_directory->dir, time(NULL), 0);
1535 return the_directory;
1538 /** Only called by v1 auth dirservers.
1539 * Replace the current running-routers list with a newly generated one. */
1540 static cached_dir_t *
1541 generate_runningrouters(void)
1543 char *s=NULL;
1544 char digest[DIGEST_LEN];
1545 char published[ISO_TIME_LEN+1];
1546 size_t len;
1547 crypto_pk_env_t *private_key = get_identity_key();
1548 char *identity_pkey; /* Identity key, DER64-encoded. */
1549 size_t identity_pkey_len;
1551 if (crypto_pk_write_public_key_to_string(private_key,&identity_pkey,
1552 &identity_pkey_len)<0) {
1553 log_warn(LD_BUG,"write identity_pkey to string failed!");
1554 goto err;
1556 format_iso_time(published, time(NULL));
1558 len = 2048;
1559 s = tor_malloc_zero(len);
1560 tor_snprintf(s, len,
1561 "network-status\n"
1562 "published %s\n"
1563 "router-status %s\n"
1564 "dir-signing-key\n%s"
1565 "directory-signature %s\n",
1566 published, "", identity_pkey,
1567 get_options()->Nickname);
1568 tor_free(identity_pkey);
1569 if (router_get_runningrouters_hash(s,digest)) {
1570 log_warn(LD_BUG,"couldn't compute digest");
1571 goto err;
1573 note_crypto_pk_op(SIGN_DIR);
1574 if (router_append_dirobj_signature(s, len, digest, private_key)<0)
1575 goto err;
1577 set_cached_dir(&the_runningrouters, s, time(NULL));
1578 runningrouters_is_dirty = 0;
1580 return &the_runningrouters;
1581 err:
1582 tor_free(s);
1583 return NULL;
1586 /** Set *<b>rr</b> to the most recently generated encoded signed
1587 * running-routers list, generating a new one as necessary. Return the
1588 * size of the directory on success, and 0 on failure. */
1589 cached_dir_t *
1590 dirserv_get_runningrouters(void)
1592 return dirserv_pick_cached_dir_obj(
1593 &cached_runningrouters, &the_runningrouters,
1594 runningrouters_is_dirty,
1595 generate_runningrouters,
1596 "v1 network status list", V1_AUTHORITY);
1599 cached_dir_t *
1600 dirserv_get_consensus(void)
1602 return cached_v3_networkstatus;
1605 /** For authoritative directories: the current (v2) network status. */
1606 static cached_dir_t *the_v2_networkstatus = NULL;
1608 /** Return true iff our opinion of the routers has been stale for long
1609 * enough that we should generate a new v2 network status doc. */
1610 static int
1611 should_generate_v2_networkstatus(void)
1613 return authdir_mode_v2(get_options()) &&
1614 the_v2_networkstatus_is_dirty &&
1615 the_v2_networkstatus_is_dirty + DIR_REGEN_SLACK_TIME < time(NULL);
1618 /** If a router's uptime is at least this value, then it is always
1619 * considered stable, regardless of the rest of the network. This
1620 * way we resist attacks where an attacker doubles the size of the
1621 * network using allegedly high-uptime nodes, displacing all the
1622 * current guards. */
1623 #define UPTIME_TO_GUARANTEE_STABLE (3600*24*30)
1624 /** If a router's MTBF is at least this value, then it is always stable.
1625 * See above. (Corresponds to about 7 days for current decay rates.) */
1626 /*XXXX021 Never actually used! */
1627 #define MTBF_TO_GUARANTEE_STABLE (60*60*24*5)
1628 /** Similarly, we protect sufficiently fast nodes from being pushed
1629 * out of the set of Fast nodes. */
1630 #define BANDWIDTH_TO_GUARANTEE_FAST (100*1024)
1631 /** Similarly, every node with sufficient bandwidth can be considered
1632 * for Guard status. */
1633 #define BANDWIDTH_TO_GUARANTEE_GUARD (250*1024)
1634 /** Similarly, every node with at least this much weighted time known can be
1635 * considered familiar enough to be a guard. Corresponds to about 20 days for
1636 * current decay rates.
1638 #define TIME_KNOWN_TO_GUARANTEE_FAMILIAR (8*24*60*60)
1639 /** Similarly, every node with sufficient WFU is around enough to be a guard.
1641 #define WFU_TO_GUARANTEE_GUARD (0.995)
1643 /* Thresholds for server performance: set by
1644 * dirserv_compute_performance_thresholds, and used by
1645 * generate_v2_networkstatus */
1646 /* XXXX stick these all in a struct. */
1647 static uint32_t stable_uptime = 0; /* start at a safe value */
1648 static double stable_mtbf = 0.0;
1649 static int enough_mtbf_info = 0;
1650 static double guard_wfu = 0.0;
1651 static long guard_tk = 0;
1652 static uint32_t fast_bandwidth = 0;
1653 static uint32_t guard_bandwidth_including_exits = 0;
1654 static uint32_t guard_bandwidth_excluding_exits = 0;
1655 static uint64_t total_bandwidth = 0;
1656 static uint64_t total_exit_bandwidth = 0;
1658 /** Helper: estimate the uptime of a router given its stated uptime and the
1659 * amount of time since it last stated its stated uptime. */
1660 static INLINE long
1661 real_uptime(routerinfo_t *router, time_t now)
1663 if (now < router->cache_info.published_on)
1664 return router->uptime;
1665 else
1666 return router->uptime + (now - router->cache_info.published_on);
1669 /** Return 1 if <b>router</b> is not suitable for these parameters, else 0.
1670 * If <b>need_uptime</b> is non-zero, we require a minimum uptime.
1671 * If <b>need_capacity</b> is non-zero, we require a minimum advertised
1672 * bandwidth.
1674 static int
1675 dirserv_thinks_router_is_unreliable(time_t now,
1676 routerinfo_t *router,
1677 int need_uptime, int need_capacity)
1679 if (need_uptime) {
1680 if (!enough_mtbf_info) {
1681 /* XXX021 Once most authorities are on v3, we should change the rule from
1682 * "use uptime if we don't have mtbf data" to "don't advertise Stable on
1683 * v3 if we don't have enough mtbf data." */
1684 long uptime = real_uptime(router, now);
1685 if ((unsigned)uptime < stable_uptime &&
1686 (unsigned)uptime < UPTIME_TO_GUARANTEE_STABLE)
1687 return 1;
1688 } else {
1689 double mtbf =
1690 rep_hist_get_stability(router->cache_info.identity_digest, now);
1691 if (mtbf < stable_mtbf)
1692 return 1;
1695 if (need_capacity) {
1696 uint32_t bw = router_get_advertised_bandwidth(router);
1697 if (bw < fast_bandwidth)
1698 return 1;
1700 return 0;
1703 /** Return true iff <b>router</b> should be assigned the "HSDir" flag.
1704 * Right now this means it advertises support for it, it has a high
1705 * uptime, and it's currently considered Running.
1707 * This function needs to be called after router-\>is_running has
1708 * been set.
1710 static int
1711 dirserv_thinks_router_is_hs_dir(routerinfo_t *router, time_t now)
1713 long uptime = real_uptime(router, now);
1715 return (router->wants_to_be_hs_dir &&
1716 uptime > get_options()->MinUptimeHidServDirectoryV2 &&
1717 router->is_running);
1720 /** Look through the routerlist, the Mean Time Between Failure history, and
1721 * the Weighted Fractional Uptime history, and use them to set thresholds for
1722 * the Stable, Fast, and Guard flags. Update the fields stable_uptime,
1723 * stable_mtbf, enough_mtbf_info, guard_wfu, guard_tk, fast_bandwidth,
1724 * guard_bandwidh_including_exits, guard_bandwidth_excluding_exits,
1725 * total_bandwidth, and total_exit_bandwidth.
1727 * Also, set the is_exit flag of each router appropriately. */
1728 static void
1729 dirserv_compute_performance_thresholds(routerlist_t *rl)
1731 int n_active, n_active_nonexit, n_familiar;
1732 uint32_t *uptimes, *bandwidths, *bandwidths_excluding_exits;
1733 long *tks;
1734 double *mtbfs, *wfus;
1735 time_t now = time(NULL);
1737 /* initialize these all here, in case there are no routers */
1738 stable_uptime = 0;
1739 stable_mtbf = 0;
1740 fast_bandwidth = 0;
1741 guard_bandwidth_including_exits = 0;
1742 guard_bandwidth_excluding_exits = 0;
1743 guard_tk = 0;
1744 guard_wfu = 0;
1745 total_bandwidth = 0;
1746 total_exit_bandwidth = 0;
1748 /* Initialize arrays that will hold values for each router. We'll
1749 * sort them and use that to compute thresholds. */
1750 n_active = n_active_nonexit = 0;
1751 /* Uptime for every active router. */
1752 uptimes = tor_malloc(sizeof(uint32_t)*smartlist_len(rl->routers));
1753 /* Bandwidth for every active router. */
1754 bandwidths = tor_malloc(sizeof(uint32_t)*smartlist_len(rl->routers));
1755 /* Bandwidth for every active non-exit router. */
1756 bandwidths_excluding_exits =
1757 tor_malloc(sizeof(uint32_t)*smartlist_len(rl->routers));
1758 /* Weighted mean time between failure for each active router. */
1759 mtbfs = tor_malloc(sizeof(double)*smartlist_len(rl->routers));
1760 /* Time-known for each active router. */
1761 tks = tor_malloc(sizeof(long)*smartlist_len(rl->routers));
1762 /* Weighted fractional uptime for each active router. */
1763 wfus = tor_malloc(sizeof(double)*smartlist_len(rl->routers));
1765 /* Now, fill in the arrays. */
1766 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
1767 if (router_is_active(ri, now)) {
1768 const char *id = ri->cache_info.identity_digest;
1769 uint32_t bw;
1770 ri->is_exit = exit_policy_is_general_exit(ri->exit_policy);
1771 uptimes[n_active] = (uint32_t)real_uptime(ri, now);
1772 mtbfs[n_active] = rep_hist_get_stability(id, now);
1773 tks [n_active] = rep_hist_get_weighted_time_known(id, now);
1774 bandwidths[n_active] = bw = router_get_advertised_bandwidth(ri);
1775 total_bandwidth += bw;
1776 if (ri->is_exit && !ri->is_bad_exit) {
1777 total_exit_bandwidth += bw;
1778 } else {
1779 bandwidths_excluding_exits[n_active_nonexit] = bw;
1780 ++n_active_nonexit;
1782 ++n_active;
1786 /* Now, compute thresholds. */
1787 if (n_active) {
1788 /* The median uptime is stable. */
1789 stable_uptime = median_uint32(uptimes, n_active);
1790 /* The median mtbf is stable, if we have enough mtbf info */
1791 stable_mtbf = median_double(mtbfs, n_active);
1792 /* The 12.5th percentile bandwidth is fast. */
1793 fast_bandwidth = find_nth_uint32(bandwidths, n_active, n_active/8);
1794 /* (Now bandwidths is sorted.) */
1795 if (fast_bandwidth < ROUTER_REQUIRED_MIN_BANDWIDTH)
1796 fast_bandwidth = bandwidths[n_active/4];
1797 guard_bandwidth_including_exits = bandwidths[(n_active-1)/2];
1798 guard_tk = find_nth_long(tks, n_active, n_active/8);
1801 if (guard_tk > TIME_KNOWN_TO_GUARANTEE_FAMILIAR)
1802 guard_tk = TIME_KNOWN_TO_GUARANTEE_FAMILIAR;
1804 if (fast_bandwidth > BANDWIDTH_TO_GUARANTEE_FAST)
1805 fast_bandwidth = BANDWIDTH_TO_GUARANTEE_FAST;
1807 /* Now that we have a time-known that 7/8 routers are known longer than,
1808 * fill wfus with the wfu of every such "familiar" router. */
1809 n_familiar = 0;
1810 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
1811 if (router_is_active(ri, now)) {
1812 const char *id = ri->cache_info.identity_digest;
1813 long tk = rep_hist_get_weighted_time_known(id, now);
1814 if (tk < guard_tk)
1815 continue;
1816 wfus[n_familiar++] = rep_hist_get_weighted_fractional_uptime(id, now);
1819 if (n_familiar)
1820 guard_wfu = median_double(wfus, n_familiar);
1821 if (guard_wfu > WFU_TO_GUARANTEE_GUARD)
1822 guard_wfu = WFU_TO_GUARANTEE_GUARD;
1824 enough_mtbf_info = rep_hist_have_measured_enough_stability();
1826 if (n_active_nonexit) {
1827 guard_bandwidth_excluding_exits =
1828 median_uint32(bandwidths_excluding_exits, n_active_nonexit);
1831 log(LOG_INFO, LD_DIRSERV,
1832 "Cutoffs: For Stable, %lu sec uptime, %lu sec MTBF. "
1833 "For Fast: %lu bytes/sec. "
1834 "For Guard: WFU %.03lf%%, time-known %lu sec, "
1835 "and bandwidth %lu or %lu bytes/sec. We%s have enough stability data.",
1836 (unsigned long)stable_uptime,
1837 (unsigned long)stable_mtbf,
1838 (unsigned long)fast_bandwidth,
1839 guard_wfu*100,
1840 (unsigned long)guard_tk,
1841 (unsigned long)guard_bandwidth_including_exits,
1842 (unsigned long)guard_bandwidth_excluding_exits,
1843 enough_mtbf_info ? "" : " don't ");
1845 tor_free(uptimes);
1846 tor_free(mtbfs);
1847 tor_free(bandwidths);
1848 tor_free(bandwidths_excluding_exits);
1849 tor_free(tks);
1850 tor_free(wfus);
1853 /** Given a platform string as in a routerinfo_t (possibly null), return a
1854 * newly allocated version string for a networkstatus document, or NULL if the
1855 * platform doesn't give a Tor version. */
1856 static char *
1857 version_from_platform(const char *platform)
1859 if (platform && !strcmpstart(platform, "Tor ")) {
1860 const char *eos = find_whitespace(platform+4);
1861 if (eos && !strcmpstart(eos, " (r")) {
1862 /* XXXX021 Unify this logic with the other version extraction
1863 * logic */
1864 eos = find_whitespace(eos+1);
1866 if (eos) {
1867 return tor_strndup(platform, eos-platform);
1870 return NULL;
1873 /** Helper: write the router-status information in <b>rs</b> into <b>buf</b>,
1874 * which has at least <b>buf_len</b> free characters. Do NUL-termination.
1875 * Use the same format as in network-status documents. If <b>version</b> is
1876 * non-NULL, add a "v" line for the platform. Return 0 on success, -1 on
1877 * failure. If <b>first_line_only<b> is true, don't include any flags
1878 * or version line.
1881 routerstatus_format_entry(char *buf, size_t buf_len,
1882 routerstatus_t *rs, const char *version,
1883 int first_line_only, int v2_format)
1884 /* XXX: first_line_only and v2_format should probably be be both
1885 * replaced by a single purpose parameter.
1888 int r;
1889 struct in_addr in;
1890 char *cp;
1891 char *summary;
1893 char published[ISO_TIME_LEN+1];
1894 char ipaddr[INET_NTOA_BUF_LEN];
1895 char identity64[BASE64_DIGEST_LEN+1];
1896 char digest64[BASE64_DIGEST_LEN+1];
1898 format_iso_time(published, rs->published_on);
1899 digest_to_base64(identity64, rs->identity_digest);
1900 digest_to_base64(digest64, rs->descriptor_digest);
1901 in.s_addr = htonl(rs->addr);
1902 tor_inet_ntoa(&in, ipaddr, sizeof(ipaddr));
1904 r = tor_snprintf(buf, buf_len,
1905 "r %s %s %s %s %s %d %d\n",
1906 rs->nickname,
1907 identity64,
1908 digest64,
1909 published,
1910 ipaddr,
1911 (int)rs->or_port,
1912 (int)rs->dir_port);
1913 if (r<0) {
1914 log_warn(LD_BUG, "Not enough space in buffer.");
1915 return -1;
1917 if (first_line_only)
1918 return 0;
1920 cp = buf + strlen(buf);
1921 /* NOTE: Whenever this list expands, be sure to increase MAX_FLAG_LINE_LEN*/
1922 r = tor_snprintf(cp, buf_len - (cp-buf),
1923 "s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
1924 /* These must stay in alphabetical order. */
1925 rs->is_authority?" Authority":"",
1926 rs->is_bad_directory?" BadDirectory":"",
1927 rs->is_bad_exit?" BadExit":"",
1928 rs->is_exit?" Exit":"",
1929 rs->is_fast?" Fast":"",
1930 rs->is_possible_guard?" Guard":"",
1931 rs->is_hs_dir?" HSDir":"",
1932 rs->is_named?" Named":"",
1933 rs->is_running?" Running":"",
1934 rs->is_stable?" Stable":"",
1935 rs->is_unnamed?" Unnamed":"",
1936 rs->is_v2_dir?" V2Dir":"",
1937 rs->is_valid?" Valid":"");
1938 if (r<0) {
1939 log_warn(LD_BUG, "Not enough space in buffer.");
1940 return -1;
1942 cp += strlen(cp);
1944 /* length of "opt v \n" */
1945 #define V_LINE_OVERHEAD 7
1946 if (version && strlen(version) < MAX_V_LINE_LEN - V_LINE_OVERHEAD) {
1947 if (tor_snprintf(cp, buf_len - (cp-buf), "opt v %s\n", version)<0) {
1948 log_warn(LD_BUG, "Unable to print router version.");
1949 return -1;
1951 cp += strlen(cp);
1954 if (!v2_format) {
1955 routerinfo_t* desc = router_get_by_digest(rs->identity_digest);
1957 /* Blow up more or less nicely if we didn't get anything or not the
1958 * thing we expected.
1960 if (!desc) {
1961 char id[HEX_DIGEST_LEN+1];
1962 char dd[HEX_DIGEST_LEN+1];
1964 base16_encode(id, sizeof(id), rs->identity_digest, DIGEST_LEN);
1965 base16_encode(dd, sizeof(dd), rs->descriptor_digest, DIGEST_LEN);
1966 log_warn(LD_BUG, "Cannot get any descriptor for %s "
1967 "(wanted descriptor %s).",
1968 id, dd);
1969 return -1;
1971 if (memcmp(desc->cache_info.signed_descriptor_digest,
1972 rs->descriptor_digest,
1973 DIGEST_LEN)) {
1974 char rl_d[HEX_DIGEST_LEN+1];
1975 char rs_d[HEX_DIGEST_LEN+1];
1976 char id[HEX_DIGEST_LEN+1];
1978 base16_encode(rl_d, sizeof(rl_d),
1979 desc->cache_info.signed_descriptor_digest, DIGEST_LEN);
1980 base16_encode(rs_d, sizeof(rs_d), rs->descriptor_digest, DIGEST_LEN);
1981 base16_encode(id, sizeof(id), rs->identity_digest, DIGEST_LEN);
1982 log_err(LD_BUG, "descriptor digest in routerlist does not match "
1983 "the one in routerstatus: %s vs %s "
1984 "(router %s)\n",
1985 rl_d, rs_d, id);
1987 tor_assert(!memcmp(desc->cache_info.signed_descriptor_digest,
1988 rs->descriptor_digest,
1989 DIGEST_LEN));
1992 r = tor_snprintf(cp, buf_len - (cp-buf),
1993 "w Bandwidth=%d\n",
1994 router_get_advertised_bandwidth_capped(desc) / 1024);
1995 if (r<0) {
1996 log_warn(LD_BUG, "Not enough space in buffer.");
1997 return -1;
1999 cp += strlen(cp);
2001 summary = policy_summarize(desc->exit_policy);
2002 r = tor_snprintf(cp, buf_len - (cp-buf), "p %s\n", summary);
2003 if (r<0) {
2004 log_warn(LD_BUG, "Not enough space in buffer.");
2005 tor_free(summary);
2006 return -1;
2008 cp += strlen(cp);
2009 tor_free(summary);
2012 return 0;
2015 /** Helper for sorting: compares two routerinfos first by address, and then by
2016 * descending order of "usefulness". (An authority is more useful than a
2017 * non-authority; a running router is more useful than a non-running router;
2018 * and a router with more bandwidth is more useful than one with less.)
2020 static int
2021 _compare_routerinfo_by_ip_and_bw(const void **a, const void **b)
2023 routerinfo_t *first = *(routerinfo_t **)a, *second = *(routerinfo_t **)b;
2024 int first_is_auth, second_is_auth;
2025 uint32_t bw_first, bw_second;
2027 /* we return -1 if first should appear before second... that is,
2028 * if first is a better router. */
2029 if (first->addr < second->addr)
2030 return -1;
2031 else if (first->addr > second->addr)
2032 return 1;
2034 /* Potentially, this next bit could cause k n lg n memcmp calls. But in
2035 * reality, we will almost never get here, since addresses will usually be
2036 * different. */
2038 first_is_auth =
2039 router_digest_is_trusted_dir(first->cache_info.identity_digest);
2040 second_is_auth =
2041 router_digest_is_trusted_dir(second->cache_info.identity_digest);
2043 if (first_is_auth && !second_is_auth)
2044 return -1;
2045 else if (!first_is_auth && second_is_auth)
2046 return 1;
2048 else if (first->is_running && !second->is_running)
2049 return -1;
2050 else if (!first->is_running && second->is_running)
2051 return 1;
2053 bw_first = router_get_advertised_bandwidth(first);
2054 bw_second = router_get_advertised_bandwidth(second);
2056 if (bw_first > bw_second)
2057 return -1;
2058 else if (bw_first < bw_second)
2059 return 1;
2061 /* They're equal! Compare by identity digest, so there's a
2062 * deterministic order and we avoid flapping. */
2063 return memcmp(first->cache_info.identity_digest,
2064 second->cache_info.identity_digest,
2065 DIGEST_LEN);
2068 /** Given a list of routerinfo_t in <b>routers</b>, return a new digestmap_t
2069 * whose keys are the identity digests of those routers that we're going to
2070 * exclude for Sybil-like appearance. */
2071 static digestmap_t *
2072 get_possible_sybil_list(const smartlist_t *routers)
2074 or_options_t *options = get_options();
2075 digestmap_t *omit_as_sybil;
2076 smartlist_t *routers_by_ip = smartlist_create();
2077 uint32_t last_addr;
2078 int addr_count;
2079 /* Allow at most this number of Tor servers on a single IP address, ... */
2080 int max_with_same_addr = options->AuthDirMaxServersPerAddr;
2081 /* ... unless it's a directory authority, in which case allow more. */
2082 int max_with_same_addr_on_authority = options->AuthDirMaxServersPerAuthAddr;
2083 if (max_with_same_addr <= 0)
2084 max_with_same_addr = INT_MAX;
2085 if (max_with_same_addr_on_authority <= 0)
2086 max_with_same_addr_on_authority = INT_MAX;
2088 smartlist_add_all(routers_by_ip, routers);
2089 smartlist_sort(routers_by_ip, _compare_routerinfo_by_ip_and_bw);
2090 omit_as_sybil = digestmap_new();
2092 last_addr = 0;
2093 addr_count = 0;
2094 SMARTLIST_FOREACH(routers_by_ip, routerinfo_t *, ri,
2096 if (last_addr != ri->addr) {
2097 last_addr = ri->addr;
2098 addr_count = 1;
2099 } else if (++addr_count > max_with_same_addr) {
2100 if (!router_addr_is_trusted_dir(ri->addr) ||
2101 addr_count > max_with_same_addr_on_authority)
2102 digestmap_set(omit_as_sybil, ri->cache_info.identity_digest, ri);
2106 smartlist_free(routers_by_ip);
2107 return omit_as_sybil;
2110 /** Extract status information from <b>ri</b> and from other authority
2111 * functions and store it in <b>rs</b>>. If <b>naming</b>, consider setting
2112 * the named flag in <b>rs</b>. If not <b>exits_can_be_guards</b>, never mark
2113 * an exit as a guard. If <b>listbadexits</b>, consider setting the badexit
2114 * flag.
2116 * We assume that ri-\>is_running has already been set, e.g. by
2117 * dirserv_set_router_is_running(ri, now);
2119 void
2120 set_routerstatus_from_routerinfo(routerstatus_t *rs,
2121 routerinfo_t *ri, time_t now,
2122 int naming, int exits_can_be_guards,
2123 int listbadexits, int listbaddirs)
2125 int unstable_version =
2126 !tor_version_as_new_as(ri->platform,"0.1.1.16-rc-cvs");
2127 memset(rs, 0, sizeof(routerstatus_t));
2129 rs->is_authority =
2130 router_digest_is_trusted_dir(ri->cache_info.identity_digest);
2132 /* Already set by compute_performance_thresholds. */
2133 rs->is_exit = ri->is_exit;
2134 rs->is_stable = ri->is_stable =
2135 router_is_active(ri, now) &&
2136 !dirserv_thinks_router_is_unreliable(now, ri, 1, 0) &&
2137 !unstable_version;
2138 rs->is_fast = ri->is_fast =
2139 router_is_active(ri, now) &&
2140 !dirserv_thinks_router_is_unreliable(now, ri, 0, 1);
2141 rs->is_running = ri->is_running; /* computed above */
2143 if (naming) {
2144 uint32_t name_status = dirserv_get_name_status(
2145 ri->cache_info.identity_digest, ri->nickname);
2146 rs->is_named = (naming && (name_status & FP_NAMED)) ? 1 : 0;
2147 rs->is_unnamed = (naming && (name_status & FP_UNNAMED)) ? 1 : 0;
2149 rs->is_valid = ri->is_valid;
2151 if (rs->is_fast &&
2152 (!rs->is_exit || exits_can_be_guards) &&
2153 (router_get_advertised_bandwidth(ri) >= BANDWIDTH_TO_GUARANTEE_GUARD ||
2154 router_get_advertised_bandwidth(ri) >=
2155 (exits_can_be_guards ? guard_bandwidth_including_exits :
2156 guard_bandwidth_excluding_exits))) {
2157 long tk = rep_hist_get_weighted_time_known(
2158 ri->cache_info.identity_digest, now);
2159 double wfu = rep_hist_get_weighted_fractional_uptime(
2160 ri->cache_info.identity_digest, now);
2161 rs->is_possible_guard = (wfu >= guard_wfu && tk >= guard_tk) ? 1 : 0;
2162 } else {
2163 rs->is_possible_guard = 0;
2165 rs->is_bad_directory = listbaddirs && ri->is_bad_directory;
2166 rs->is_bad_exit = listbadexits && ri->is_bad_exit;
2167 ri->is_hs_dir = dirserv_thinks_router_is_hs_dir(ri, now);
2168 rs->is_hs_dir = ri->is_hs_dir;
2169 rs->is_v2_dir = ri->dir_port != 0;
2171 if (!strcasecmp(ri->nickname, UNNAMED_ROUTER_NICKNAME))
2172 rs->is_named = rs->is_unnamed = 0;
2174 rs->published_on = ri->cache_info.published_on;
2175 memcpy(rs->identity_digest, ri->cache_info.identity_digest, DIGEST_LEN);
2176 memcpy(rs->descriptor_digest, ri->cache_info.signed_descriptor_digest,
2177 DIGEST_LEN);
2178 rs->addr = ri->addr;
2179 strlcpy(rs->nickname, ri->nickname, sizeof(rs->nickname));
2180 rs->or_port = ri->or_port;
2181 rs->dir_port = ri->dir_port;
2184 /** Routerstatus <b>rs</b> is part of a group of routers that are on
2185 * too narrow an IP-space. Clear out its flags: we don't want people
2186 * using it.
2188 static void
2189 clear_status_flags_on_sybil(routerstatus_t *rs)
2191 rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
2192 rs->is_running = rs->is_named = rs->is_valid = rs->is_v2_dir =
2193 rs->is_hs_dir = rs->is_possible_guard = rs->is_bad_exit =
2194 rs->is_bad_directory = 0;
2195 /* FFFF we might want some mechanism to check later on if we
2196 * missed zeroing any flags: it's easy to add a new flag but
2197 * forget to add it to this clause. */
2200 /** Clear all the status flags in routerinfo <b>router</b>. We put this
2201 * function here because it's eerily similar to
2202 * clear_status_flags_on_sybil() above. One day we should merge them. */
2203 void
2204 router_clear_status_flags(routerinfo_t *router)
2206 router->is_valid = router->is_running = router->is_hs_dir =
2207 router->is_fast = router->is_stable =
2208 router->is_possible_guard = router->is_exit =
2209 router->is_bad_exit = router->is_bad_directory = 0;
2212 /** Return a new networkstatus_t* containing our current opinion. (For v3
2213 * authorities) */
2214 networkstatus_t *
2215 dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
2216 authority_cert_t *cert)
2218 or_options_t *options = get_options();
2219 networkstatus_t *v3_out = NULL;
2220 uint32_t addr;
2221 char *hostname = NULL, *client_versions = NULL, *server_versions = NULL;
2222 const char *contact;
2223 smartlist_t *routers, *routerstatuses;
2224 char identity_digest[DIGEST_LEN];
2225 char signing_key_digest[DIGEST_LEN];
2226 int naming = options->NamingAuthoritativeDir;
2227 int listbadexits = options->AuthDirListBadExits;
2228 int listbaddirs = options->AuthDirListBadDirs;
2229 int exits_can_be_guards;
2230 routerlist_t *rl = router_get_routerlist();
2231 time_t now = time(NULL);
2232 time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
2233 networkstatus_voter_info_t *voter = NULL;
2234 vote_timing_t timing;
2235 digestmap_t *omit_as_sybil = NULL;
2236 int vote_on_reachability = 1;
2238 tor_assert(private_key);
2239 tor_assert(cert);
2241 if (now - time_of_process_start <
2242 options->TestingAuthDirTimeToLearnReachability)
2243 vote_on_reachability = 0;
2245 if (resolve_my_address(LOG_WARN, options, &addr, &hostname)<0) {
2246 log_warn(LD_NET, "Couldn't resolve my hostname");
2247 return NULL;
2249 if (!strchr(hostname, '.')) {
2250 tor_free(hostname);
2251 hostname = tor_dup_ip(addr);
2253 if (crypto_pk_get_digest(private_key, signing_key_digest)<0) {
2254 log_err(LD_BUG, "Error computing signing key digest");
2255 return NULL;
2257 if (crypto_pk_get_digest(cert->identity_key, identity_digest)<0) {
2258 log_err(LD_BUG, "Error computing identity key digest");
2259 return NULL;
2262 if (options->VersioningAuthoritativeDir) {
2263 client_versions = format_versions_list(options->RecommendedClientVersions);
2264 server_versions = format_versions_list(options->RecommendedServerVersions);
2267 contact = get_options()->ContactInfo;
2268 if (!contact)
2269 contact = "(none)";
2271 /* precompute this part, since we need it to decide what "stable"
2272 * means. */
2273 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
2274 dirserv_set_router_is_running(ri, now);
2277 dirserv_compute_performance_thresholds(rl);
2279 /* XXXX We should take steps to keep this from oscillating if
2280 * total_exit_bandwidth is close to total_bandwidth/3. */
2281 exits_can_be_guards = total_exit_bandwidth >= (total_bandwidth / 3);
2283 routers = smartlist_create();
2284 smartlist_add_all(routers, rl->routers);
2285 routers_sort_by_identity(routers);
2286 omit_as_sybil = get_possible_sybil_list(routers);
2288 routerstatuses = smartlist_create();
2290 SMARTLIST_FOREACH(routers, routerinfo_t *, ri, {
2291 if (ri->cache_info.published_on >= cutoff) {
2292 routerstatus_t *rs;
2293 vote_routerstatus_t *vrs;
2295 vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
2296 rs = &vrs->status;
2297 set_routerstatus_from_routerinfo(rs, ri, now,
2298 naming, exits_can_be_guards,
2299 listbadexits, listbaddirs);
2301 if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest))
2302 clear_status_flags_on_sybil(rs);
2304 if (!vote_on_reachability)
2305 rs->is_running = 0;
2307 vrs->version = version_from_platform(ri->platform);
2308 smartlist_add(routerstatuses, vrs);
2311 smartlist_free(routers);
2312 digestmap_free(omit_as_sybil, NULL);
2314 v3_out = tor_malloc_zero(sizeof(networkstatus_t));
2316 v3_out->type = NS_TYPE_VOTE;
2317 dirvote_get_preferred_voting_intervals(&timing);
2318 v3_out->published = now;
2320 char tbuf[ISO_TIME_LEN+1];
2321 networkstatus_t *current_consensus =
2322 networkstatus_get_live_consensus(now);
2323 long last_consensus_interval; /* only used to pick a valid_after */
2324 if (current_consensus)
2325 last_consensus_interval = current_consensus->fresh_until -
2326 current_consensus->valid_after;
2327 else
2328 last_consensus_interval = options->TestingV3AuthInitialVotingInterval;
2329 v3_out->valid_after =
2330 dirvote_get_start_of_next_interval(now, (int)last_consensus_interval);
2331 format_iso_time(tbuf, v3_out->valid_after);
2332 log_notice(LD_DIR,"Choosing valid-after time in vote as %s: "
2333 "consensus_set=%d, last_interval=%d",
2334 tbuf, current_consensus?1:0, (int)last_consensus_interval);
2336 v3_out->fresh_until = v3_out->valid_after + timing.vote_interval;
2337 v3_out->valid_until = v3_out->valid_after +
2338 (timing.vote_interval * timing.n_intervals_valid);
2339 v3_out->vote_seconds = timing.vote_delay;
2340 v3_out->dist_seconds = timing.dist_delay;
2341 tor_assert(v3_out->vote_seconds > 0);
2342 tor_assert(v3_out->dist_seconds > 0);
2343 tor_assert(timing.n_intervals_valid > 0);
2345 v3_out->client_versions = client_versions;
2346 v3_out->server_versions = server_versions;
2347 v3_out->known_flags = smartlist_create();
2348 smartlist_split_string(v3_out->known_flags,
2349 "Authority Exit Fast Guard HSDir Stable V2Dir Valid",
2350 0, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
2351 if (vote_on_reachability)
2352 smartlist_add(v3_out->known_flags, tor_strdup("Running"));
2353 if (listbaddirs)
2354 smartlist_add(v3_out->known_flags, tor_strdup("BadDirectory"));
2355 if (listbadexits)
2356 smartlist_add(v3_out->known_flags, tor_strdup("BadExit"));
2357 if (naming) {
2358 smartlist_add(v3_out->known_flags, tor_strdup("Named"));
2359 smartlist_add(v3_out->known_flags, tor_strdup("Unnamed"));
2361 smartlist_sort_strings(v3_out->known_flags);
2363 voter = tor_malloc_zero(sizeof(networkstatus_voter_info_t));
2364 voter->nickname = tor_strdup(options->Nickname);
2365 memcpy(voter->identity_digest, identity_digest, DIGEST_LEN);
2366 voter->address = hostname;
2367 voter->addr = addr;
2368 voter->dir_port = options->DirPort;
2369 voter->or_port = options->ORPort;
2370 voter->contact = tor_strdup(contact);
2371 memcpy(voter->signing_key_digest, signing_key_digest, DIGEST_LEN);
2372 if (options->V3AuthUseLegacyKey) {
2373 authority_cert_t *c = get_my_v3_legacy_cert();
2374 if (c) {
2375 crypto_pk_get_digest(c->identity_key, voter->legacy_id_digest);
2379 v3_out->voters = smartlist_create();
2380 smartlist_add(v3_out->voters, voter);
2381 v3_out->cert = authority_cert_dup(cert);
2382 v3_out->routerstatus_list = routerstatuses;
2383 /* Note: networkstatus_digest is unset; it won't get set until we actually
2384 * format the vote. */
2386 return v3_out;
2389 /** For v2 authoritative directories only: Replace the contents of
2390 * <b>the_v2_networkstatus</b> with a newly generated network status
2391 * object. */
2392 static cached_dir_t *
2393 generate_v2_networkstatus_opinion(void)
2395 cached_dir_t *r = NULL;
2396 size_t len, identity_pkey_len;
2397 char *status = NULL, *client_versions = NULL, *server_versions = NULL,
2398 *identity_pkey = NULL, *hostname = NULL;
2399 char *outp, *endp;
2400 or_options_t *options = get_options();
2401 char fingerprint[FINGERPRINT_LEN+1];
2402 char ipaddr[INET_NTOA_BUF_LEN];
2403 char published[ISO_TIME_LEN+1];
2404 char digest[DIGEST_LEN];
2405 struct in_addr in;
2406 uint32_t addr;
2407 crypto_pk_env_t *private_key;
2408 routerlist_t *rl = router_get_routerlist();
2409 time_t now = time(NULL);
2410 time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
2411 int naming = options->NamingAuthoritativeDir;
2412 int versioning = options->VersioningAuthoritativeDir;
2413 int listbaddirs = options->AuthDirListBadDirs;
2414 int listbadexits = options->AuthDirListBadExits;
2415 int exits_can_be_guards;
2416 const char *contact;
2417 char *version_lines = NULL;
2418 smartlist_t *routers = NULL;
2419 digestmap_t *omit_as_sybil = NULL;
2421 private_key = get_identity_key();
2423 if (resolve_my_address(LOG_WARN, options, &addr, &hostname)<0) {
2424 log_warn(LD_NET, "Couldn't resolve my hostname");
2425 goto done;
2427 in.s_addr = htonl(addr);
2428 tor_inet_ntoa(&in, ipaddr, sizeof(ipaddr));
2430 format_iso_time(published, now);
2432 client_versions = format_versions_list(options->RecommendedClientVersions);
2433 server_versions = format_versions_list(options->RecommendedServerVersions);
2435 if (crypto_pk_write_public_key_to_string(private_key, &identity_pkey,
2436 &identity_pkey_len)<0) {
2437 log_warn(LD_BUG,"Writing public key to string failed.");
2438 goto done;
2441 if (crypto_pk_get_fingerprint(private_key, fingerprint, 0)<0) {
2442 log_err(LD_BUG, "Error computing fingerprint");
2443 goto done;
2446 contact = get_options()->ContactInfo;
2447 if (!contact)
2448 contact = "(none)";
2450 if (versioning) {
2451 size_t v_len = 64+strlen(client_versions)+strlen(server_versions);
2452 version_lines = tor_malloc(v_len);
2453 tor_snprintf(version_lines, v_len,
2454 "client-versions %s\nserver-versions %s\n",
2455 client_versions, server_versions);
2456 } else {
2457 version_lines = tor_strdup("");
2460 len = 4096+strlen(client_versions)+strlen(server_versions);
2461 len += identity_pkey_len*2;
2462 len += (RS_ENTRY_LEN)*smartlist_len(rl->routers);
2464 status = tor_malloc(len);
2465 tor_snprintf(status, len,
2466 "network-status-version 2\n"
2467 "dir-source %s %s %d\n"
2468 "fingerprint %s\n"
2469 "contact %s\n"
2470 "published %s\n"
2471 "dir-options%s%s%s%s\n"
2472 "%s" /* client version line, server version line. */
2473 "dir-signing-key\n%s",
2474 hostname, ipaddr, (int)options->DirPort,
2475 fingerprint,
2476 contact,
2477 published,
2478 naming ? " Names" : "",
2479 listbaddirs ? " BadDirectories" : "",
2480 listbadexits ? " BadExits" : "",
2481 versioning ? " Versions" : "",
2482 version_lines,
2483 identity_pkey);
2484 outp = status + strlen(status);
2485 endp = status + len;
2487 /* precompute this part, since we need it to decide what "stable"
2488 * means. */
2489 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
2490 dirserv_set_router_is_running(ri, now);
2493 dirserv_compute_performance_thresholds(rl);
2495 /* XXXX We should take steps to keep this from oscillating if
2496 * total_exit_bandwidth is close to total_bandwidth/3. */
2497 exits_can_be_guards = total_exit_bandwidth >= (total_bandwidth / 3);
2499 routers = smartlist_create();
2500 smartlist_add_all(routers, rl->routers);
2501 routers_sort_by_identity(routers);
2503 omit_as_sybil = get_possible_sybil_list(routers);
2505 SMARTLIST_FOREACH(routers, routerinfo_t *, ri, {
2506 if (ri->cache_info.published_on >= cutoff) {
2507 routerstatus_t rs;
2508 char *version = version_from_platform(ri->platform);
2510 set_routerstatus_from_routerinfo(&rs, ri, now,
2511 naming, exits_can_be_guards,
2512 listbadexits, listbaddirs);
2514 if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest))
2515 clear_status_flags_on_sybil(&rs);
2517 if (routerstatus_format_entry(outp, endp-outp, &rs, version, 0, 1)) {
2518 log_warn(LD_BUG, "Unable to print router status.");
2519 tor_free(version);
2520 goto done;
2522 tor_free(version);
2523 outp += strlen(outp);
2527 if (tor_snprintf(outp, endp-outp, "directory-signature %s\n",
2528 get_options()->Nickname)<0) {
2529 log_warn(LD_BUG, "Unable to write signature line.");
2530 goto done;
2532 if (router_get_networkstatus_v2_hash(status, digest)<0) {
2533 log_warn(LD_BUG, "Unable to hash network status");
2534 goto done;
2536 outp += strlen(outp);
2538 note_crypto_pk_op(SIGN_DIR);
2539 if (router_append_dirobj_signature(outp,endp-outp,digest,private_key)<0) {
2540 log_warn(LD_BUG, "Unable to sign router status.");
2541 goto done;
2545 networkstatus_v2_t *ns;
2546 if (!(ns = networkstatus_v2_parse_from_string(status))) {
2547 log_err(LD_BUG,"Generated a networkstatus we couldn't parse.");
2548 goto done;
2550 networkstatus_v2_free(ns);
2554 cached_dir_t **ns_ptr = &the_v2_networkstatus;
2555 if (*ns_ptr)
2556 cached_dir_decref(*ns_ptr);
2557 *ns_ptr = new_cached_dir(status, now);
2558 status = NULL; /* So it doesn't get double-freed. */
2559 the_v2_networkstatus_is_dirty = 0;
2560 router_set_networkstatus_v2((*ns_ptr)->dir, now, NS_GENERATED, NULL);
2561 r = *ns_ptr;
2564 done:
2565 tor_free(client_versions);
2566 tor_free(server_versions);
2567 tor_free(version_lines);
2568 tor_free(status);
2569 tor_free(hostname);
2570 tor_free(identity_pkey);
2571 if (routers)
2572 smartlist_free(routers);
2573 if (omit_as_sybil)
2574 digestmap_free(omit_as_sybil, NULL);
2575 return r;
2578 /** Given the portion of a networkstatus request URL after "tor/status/" in
2579 * <b>key</b>, append to <b>result</b> the digests of the identity keys of the
2580 * networkstatus objects that the client has requested. */
2581 void
2582 dirserv_get_networkstatus_v2_fingerprints(smartlist_t *result,
2583 const char *key)
2585 tor_assert(result);
2587 if (!cached_v2_networkstatus)
2588 cached_v2_networkstatus = digestmap_new();
2590 if (should_generate_v2_networkstatus())
2591 generate_v2_networkstatus_opinion();
2593 if (!strcmp(key,"authority")) {
2594 if (authdir_mode_v2(get_options())) {
2595 routerinfo_t *me = router_get_my_routerinfo();
2596 if (me)
2597 smartlist_add(result,
2598 tor_memdup(me->cache_info.identity_digest, DIGEST_LEN));
2600 } else if (!strcmp(key, "all")) {
2601 if (digestmap_size(cached_v2_networkstatus)) {
2602 digestmap_iter_t *iter;
2603 iter = digestmap_iter_init(cached_v2_networkstatus);
2604 while (!digestmap_iter_done(iter)) {
2605 const char *ident;
2606 void *val;
2607 digestmap_iter_get(iter, &ident, &val);
2608 smartlist_add(result, tor_memdup(ident, DIGEST_LEN));
2609 iter = digestmap_iter_next(cached_v2_networkstatus, iter);
2611 } else {
2612 SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
2613 trusted_dir_server_t *, ds,
2614 if (ds->type & V2_AUTHORITY)
2615 smartlist_add(result, tor_memdup(ds->digest, DIGEST_LEN)));
2617 smartlist_sort_digests(result);
2618 if (smartlist_len(result) == 0)
2619 log_info(LD_DIRSERV,
2620 "Client requested 'all' network status objects; we have none.");
2621 } else if (!strcmpstart(key, "fp/")) {
2622 dir_split_resource_into_fingerprints(key+3, result, NULL, 1, 1);
2626 /** Look for a network status object as specified by <b>key</b>, which should
2627 * be either "authority" (to find a network status generated by us), a hex
2628 * identity digest (to find a network status generated by given directory), or
2629 * "all" (to return all the v2 network status objects we have).
2631 void
2632 dirserv_get_networkstatus_v2(smartlist_t *result,
2633 const char *key)
2635 cached_dir_t *cached;
2636 smartlist_t *fingerprints = smartlist_create();
2637 tor_assert(result);
2639 if (!cached_v2_networkstatus)
2640 cached_v2_networkstatus = digestmap_new();
2642 dirserv_get_networkstatus_v2_fingerprints(fingerprints, key);
2643 SMARTLIST_FOREACH(fingerprints, const char *, fp,
2645 if (router_digest_is_me(fp) && should_generate_v2_networkstatus())
2646 generate_v2_networkstatus_opinion();
2647 cached = digestmap_get(cached_v2_networkstatus, fp);
2648 if (cached) {
2649 smartlist_add(result, cached);
2650 } else {
2651 char hexbuf[HEX_DIGEST_LEN+1];
2652 base16_encode(hexbuf, sizeof(hexbuf), fp, DIGEST_LEN);
2653 log_info(LD_DIRSERV, "Don't know about any network status with "
2654 "fingerprint '%s'", hexbuf);
2657 SMARTLIST_FOREACH(fingerprints, char *, cp, tor_free(cp));
2658 smartlist_free(fingerprints);
2661 /** As dirserv_get_routerdescs(), but instead of getting signed_descriptor_t
2662 * pointers, adds copies of digests to fps_out, and doesn't use the
2663 * /tor/server/ prefix. For a /d/ request, adds descriptor digests; for other
2664 * requests, adds identity digests.
2667 dirserv_get_routerdesc_fingerprints(smartlist_t *fps_out, const char *key,
2668 const char **msg, int for_unencrypted_conn)
2670 int by_id = 1;
2671 *msg = NULL;
2673 if (!strcmp(key, "all")) {
2674 routerlist_t *rl = router_get_routerlist();
2675 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, r,
2676 smartlist_add(fps_out,
2677 tor_memdup(r->cache_info.identity_digest, DIGEST_LEN)));
2678 } else if (!strcmp(key, "authority")) {
2679 routerinfo_t *ri = router_get_my_routerinfo();
2680 if (ri)
2681 smartlist_add(fps_out,
2682 tor_memdup(ri->cache_info.identity_digest, DIGEST_LEN));
2683 } else if (!strcmpstart(key, "d/")) {
2684 by_id = 0;
2685 key += strlen("d/");
2686 dir_split_resource_into_fingerprints(key, fps_out, NULL, 1, 1);
2687 } else if (!strcmpstart(key, "fp/")) {
2688 key += strlen("fp/");
2689 dir_split_resource_into_fingerprints(key, fps_out, NULL, 1, 1);
2690 } else {
2691 *msg = "Key not recognized";
2692 return -1;
2695 if (for_unencrypted_conn) {
2696 /* Remove anything whose purpose isn't general. */
2697 SMARTLIST_FOREACH(fps_out, char *, cp, {
2698 signed_descriptor_t *sd =
2699 by_id ? get_signed_descriptor_by_fp(cp,0,0) :
2700 router_get_by_descriptor_digest(cp);
2701 if (sd && !sd->send_unencrypted) {
2702 tor_free(cp);
2703 SMARTLIST_DEL_CURRENT(fps_out, cp);
2708 if (!smartlist_len(fps_out)) {
2709 *msg = "Servers unavailable";
2710 return -1;
2712 return 0;
2715 /** Add a signed_descriptor_t to <b>descs_out</b> for each router matching
2716 * <b>key</b>. The key should be either
2717 * - "/tor/server/authority" for our own routerinfo;
2718 * - "/tor/server/all" for all the routerinfos we have, concatenated;
2719 * - "/tor/server/fp/FP" where FP is a plus-separated sequence of
2720 * hex identity digests; or
2721 * - "/tor/server/d/D" where D is a plus-separated sequence
2722 * of server descriptor digests, in hex.
2724 * Return 0 if we found some matching descriptors, or -1 if we do not
2725 * have any descriptors, no matching descriptors, or if we did not
2726 * recognize the key (URL).
2727 * If -1 is returned *<b>msg</b> will be set to an appropriate error
2728 * message.
2730 * XXXX021 rename this function. It's only called from the controller.
2731 * XXXX021 in fact, refactor this function, mergeing as much as possible.
2734 dirserv_get_routerdescs(smartlist_t *descs_out, const char *key,
2735 const char **msg)
2737 *msg = NULL;
2739 if (!strcmp(key, "/tor/server/all")) {
2740 routerlist_t *rl = router_get_routerlist();
2741 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, r,
2742 smartlist_add(descs_out, &(r->cache_info)));
2743 } else if (!strcmp(key, "/tor/server/authority")) {
2744 routerinfo_t *ri = router_get_my_routerinfo();
2745 if (ri)
2746 smartlist_add(descs_out, &(ri->cache_info));
2747 } else if (!strcmpstart(key, "/tor/server/d/")) {
2748 smartlist_t *digests = smartlist_create();
2749 key += strlen("/tor/server/d/");
2750 dir_split_resource_into_fingerprints(key, digests, NULL, 1, 1);
2751 SMARTLIST_FOREACH(digests, const char *, d,
2753 signed_descriptor_t *sd = router_get_by_descriptor_digest(d);
2754 if (sd)
2755 smartlist_add(descs_out,sd);
2757 SMARTLIST_FOREACH(digests, char *, d, tor_free(d));
2758 smartlist_free(digests);
2759 } else if (!strcmpstart(key, "/tor/server/fp/")) {
2760 smartlist_t *digests = smartlist_create();
2761 time_t cutoff = time(NULL) - ROUTER_MAX_AGE_TO_PUBLISH;
2762 key += strlen("/tor/server/fp/");
2763 dir_split_resource_into_fingerprints(key, digests, NULL, 1, 1);
2764 SMARTLIST_FOREACH(digests, const char *, d,
2766 if (router_digest_is_me(d)) {
2767 /* make sure desc_routerinfo exists */
2768 routerinfo_t *ri = router_get_my_routerinfo();
2769 if (ri)
2770 smartlist_add(descs_out, &(ri->cache_info));
2771 } else {
2772 routerinfo_t *ri = router_get_by_digest(d);
2773 /* Don't actually serve a descriptor that everyone will think is
2774 * expired. This is an (ugly) workaround to keep buggy 0.1.1.10
2775 * Tors from downloading descriptors that they will throw away.
2777 if (ri && ri->cache_info.published_on > cutoff)
2778 smartlist_add(descs_out, &(ri->cache_info));
2781 SMARTLIST_FOREACH(digests, char *, d, tor_free(d));
2782 smartlist_free(digests);
2783 } else {
2784 *msg = "Key not recognized";
2785 return -1;
2788 if (!smartlist_len(descs_out)) {
2789 *msg = "Servers unavailable";
2790 return -1;
2792 return 0;
2795 /** Called when a TLS handshake has completed successfully with a
2796 * router listening at <b>address</b>:<b>or_port</b>, and has yielded
2797 * a certificate with digest <b>digest_rcvd</b>.
2799 * Also, if as_advertised is 1, then inform the reachability checker
2800 * that we could get to this guy.
2802 void
2803 dirserv_orconn_tls_done(const char *address,
2804 uint16_t or_port,
2805 const char *digest_rcvd,
2806 int as_advertised)
2808 routerlist_t *rl = router_get_routerlist();
2809 time_t now = time(NULL);
2810 int bridge_auth = authdir_mode_bridge(get_options());
2811 tor_assert(address);
2812 tor_assert(digest_rcvd);
2814 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
2815 if (!strcasecmp(address, ri->address) && or_port == ri->or_port &&
2816 as_advertised &&
2817 !memcmp(ri->cache_info.identity_digest, digest_rcvd, DIGEST_LEN)) {
2818 /* correct digest. mark this router reachable! */
2819 if (!bridge_auth || ri->purpose == ROUTER_PURPOSE_BRIDGE) {
2820 log_info(LD_DIRSERV, "Found router %s to be reachable. Yay.",
2821 ri->nickname);
2822 rep_hist_note_router_reachable(digest_rcvd, now);
2823 ri->last_reachable = now;
2827 /* FFFF Maybe we should reinstate the code that dumps routers with the same
2828 * addr/port but with nonmatching keys, but instead of dumping, we should
2829 * skip testing. */
2832 /** Auth dir server only: if <b>try_all</b> is 1, launch connections to
2833 * all known routers; else we want to load balance such that we only
2834 * try a few connections per call.
2836 * The load balancing is such that if we get called once every ten
2837 * seconds, we will cycle through all the tests in 1280 seconds (a
2838 * bit over 20 minutes).
2840 void
2841 dirserv_test_reachability(time_t now, int try_all)
2843 /* XXX decide what to do here; see or-talk thread "purging old router
2844 * information, revocation." -NM
2845 * We can't afford to mess with this in 0.1.2.x. The reason is that
2846 * if we stop doing reachability tests on some of routerlist, then
2847 * we'll for-sure think they're down, which may have unexpected
2848 * effects in other parts of the code. It doesn't hurt much to do
2849 * the testing, and directory authorities are easy to upgrade. Let's
2850 * wait til 0.2.0. -RD */
2851 // time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
2852 routerlist_t *rl = router_get_routerlist();
2853 static char ctr = 0;
2854 int bridge_auth = authdir_mode_bridge(get_options());
2856 SMARTLIST_FOREACH_BEGIN(rl->routers, routerinfo_t *, router) {
2857 const char *id_digest = router->cache_info.identity_digest;
2858 tor_addr_t router_addr;
2859 if (router_is_me(router))
2860 continue;
2861 if (bridge_auth && router->purpose != ROUTER_PURPOSE_BRIDGE)
2862 continue; /* bridge authorities only test reachability on bridges */
2863 // if (router->cache_info.published_on > cutoff)
2864 // continue;
2865 if (try_all || (((uint8_t)id_digest[0]) % 128) == ctr) {
2866 log_debug(LD_OR,"Testing reachability of %s at %s:%u.",
2867 router->nickname, router->address, router->or_port);
2868 /* Remember when we started trying to determine reachability */
2869 if (!router->testing_since)
2870 router->testing_since = now;
2871 tor_addr_from_ipv4h(&router_addr, router->addr);
2872 connection_or_connect(&router_addr, router->or_port, id_digest);
2874 } SMARTLIST_FOREACH_END(router);
2875 if (!try_all) /* increment ctr */
2876 ctr = (ctr + 1) % 128;
2879 /** Given a fingerprint <b>fp</b> which is either set if we're looking
2880 * for a v2 status, or zeroes if we're looking for a v3 status, return
2881 * a pointer to the appropriate cached dir object, or NULL if there isn't
2882 * one available. */
2883 static cached_dir_t *
2884 lookup_cached_dir_by_fp(const char *fp)
2886 cached_dir_t *d = NULL;
2887 if (tor_digest_is_zero(fp) && cached_v3_networkstatus)
2888 d = cached_v3_networkstatus;
2889 else if (router_digest_is_me(fp) && the_v2_networkstatus)
2890 d = the_v2_networkstatus;
2891 else if (cached_v2_networkstatus)
2892 d = digestmap_get(cached_v2_networkstatus, fp);
2893 return d;
2896 /** Remove from <b>fps</b> every networkstatus key where both
2897 * a) we have a networkstatus document and
2898 * b) it is not newer than <b>cutoff</b>.
2900 * Return 1 if any items were present at all; else return 0.
2903 dirserv_remove_old_statuses(smartlist_t *fps, time_t cutoff)
2905 int found_any = 0;
2906 SMARTLIST_FOREACH(fps, char *, digest,
2908 cached_dir_t *d = lookup_cached_dir_by_fp(digest);
2909 if (!d)
2910 continue;
2911 found_any = 1;
2912 if (d->published <= cutoff) {
2913 tor_free(digest);
2914 SMARTLIST_DEL_CURRENT(fps, digest);
2918 return found_any;
2921 /** Return the cache-info for identity fingerprint <b>fp</b>, or
2922 * its extra-info document if <b>extrainfo</b> is true. Return
2923 * NULL if not found or if the descriptor is older than
2924 * <b>publish_cutoff</b>. */
2925 static signed_descriptor_t *
2926 get_signed_descriptor_by_fp(const char *fp, int extrainfo,
2927 time_t publish_cutoff)
2929 if (router_digest_is_me(fp)) {
2930 if (extrainfo)
2931 return &(router_get_my_extrainfo()->cache_info);
2932 else
2933 return &(router_get_my_routerinfo()->cache_info);
2934 } else {
2935 routerinfo_t *ri = router_get_by_digest(fp);
2936 if (ri &&
2937 ri->cache_info.published_on > publish_cutoff) {
2938 if (extrainfo)
2939 return extrainfo_get_by_descriptor_digest(
2940 ri->cache_info.extra_info_digest);
2941 else
2942 return &ri->cache_info;
2945 return NULL;
2948 /** Return true iff we have any of the docments (extrainfo or routerdesc)
2949 * specified by the fingerprints in <b>fps</b> and <b>spool_src</b>. Used to
2950 * decide whether to send a 404. */
2952 dirserv_have_any_serverdesc(smartlist_t *fps, int spool_src)
2954 time_t publish_cutoff = time(NULL)-ROUTER_MAX_AGE_TO_PUBLISH;
2955 SMARTLIST_FOREACH(fps, const char *, fp, {
2956 switch (spool_src)
2958 case DIR_SPOOL_EXTRA_BY_DIGEST:
2959 if (extrainfo_get_by_descriptor_digest(fp)) return 1;
2960 break;
2961 case DIR_SPOOL_SERVER_BY_DIGEST:
2962 if (router_get_by_descriptor_digest(fp)) return 1;
2963 break;
2964 case DIR_SPOOL_EXTRA_BY_FP:
2965 case DIR_SPOOL_SERVER_BY_FP:
2966 if (get_signed_descriptor_by_fp(fp,
2967 spool_src == DIR_SPOOL_EXTRA_BY_FP, publish_cutoff))
2968 return 1;
2969 break;
2972 return 0;
2975 /** Return an approximate estimate of the number of bytes that will
2976 * be needed to transmit the server descriptors (if is_serverdescs --
2977 * they can be either d/ or fp/ queries) or networkstatus objects (if
2978 * !is_serverdescs) listed in <b>fps</b>. If <b>compressed</b> is set,
2979 * we guess how large the data will be after compression.
2981 * The return value is an estimate; it might be larger or smaller.
2983 size_t
2984 dirserv_estimate_data_size(smartlist_t *fps, int is_serverdescs,
2985 int compressed)
2987 size_t result;
2988 tor_assert(fps);
2989 if (is_serverdescs) {
2990 int n = smartlist_len(fps);
2991 routerinfo_t *me = router_get_my_routerinfo();
2992 result = (me?me->cache_info.signed_descriptor_len:2048) * n;
2993 if (compressed)
2994 result /= 2; /* observed compressability is between 35 and 55%. */
2995 } else {
2996 result = 0;
2997 SMARTLIST_FOREACH(fps, const char *, digest, {
2998 cached_dir_t *dir = lookup_cached_dir_by_fp(digest);
2999 if (dir)
3000 result += compressed ? dir->dir_z_len : dir->dir_len;
3003 return result;
3006 /** When we're spooling data onto our outbuf, add more whenever we dip
3007 * below this threshold. */
3008 #define DIRSERV_BUFFER_MIN 16384
3010 /** Spooling helper: called when we have no more data to spool to <b>conn</b>.
3011 * Flushes any remaining data to be (un)compressed, and changes the spool
3012 * source to NONE. Returns 0 on success, negative on failure. */
3013 static int
3014 connection_dirserv_finish_spooling(dir_connection_t *conn)
3016 if (conn->zlib_state) {
3017 connection_write_to_buf_zlib("", 0, conn, 1);
3018 tor_zlib_free(conn->zlib_state);
3019 conn->zlib_state = NULL;
3021 conn->dir_spool_src = DIR_SPOOL_NONE;
3022 return 0;
3025 /** Spooling helper: called when we're sending a bunch of server descriptors,
3026 * and the outbuf has become too empty. Pulls some entries from
3027 * fingerprint_stack, and writes the corresponding servers onto outbuf. If we
3028 * run out of entries, flushes the zlib state and sets the spool source to
3029 * NONE. Returns 0 on success, negative on failure.
3031 static int
3032 connection_dirserv_add_servers_to_outbuf(dir_connection_t *conn)
3034 #ifdef TRACK_SERVED_TIME
3035 time_t now = time(NULL);
3036 #endif
3037 int by_fp = (conn->dir_spool_src == DIR_SPOOL_SERVER_BY_FP ||
3038 conn->dir_spool_src == DIR_SPOOL_EXTRA_BY_FP);
3039 int extra = (conn->dir_spool_src == DIR_SPOOL_EXTRA_BY_FP ||
3040 conn->dir_spool_src == DIR_SPOOL_EXTRA_BY_DIGEST);
3041 time_t publish_cutoff = time(NULL)-ROUTER_MAX_AGE_TO_PUBLISH;
3043 while (smartlist_len(conn->fingerprint_stack) &&
3044 buf_datalen(conn->_base.outbuf) < DIRSERV_BUFFER_MIN) {
3045 const char *body;
3046 char *fp = smartlist_pop_last(conn->fingerprint_stack);
3047 signed_descriptor_t *sd = NULL;
3048 if (by_fp) {
3049 sd = get_signed_descriptor_by_fp(fp, extra, publish_cutoff);
3050 } else {
3051 sd = extra ? extrainfo_get_by_descriptor_digest(fp)
3052 : router_get_by_descriptor_digest(fp);
3054 tor_free(fp);
3055 if (!sd)
3056 continue;
3057 if (!connection_dir_is_encrypted(conn) && !sd->send_unencrypted) {
3058 /* we did this check once before (so we could have an accurate size
3059 * estimate and maybe send a 404 if somebody asked for only bridges on a
3060 * connection), but we need to do it again in case a previously
3061 * unknown bridge descriptor has shown up between then and now. */
3062 continue;
3064 #ifdef TRACK_SERVED_TIME
3065 sd->last_served_at = now;
3066 #endif
3067 body = signed_descriptor_get_body(sd);
3068 if (conn->zlib_state) {
3069 int last = ! smartlist_len(conn->fingerprint_stack);
3070 connection_write_to_buf_zlib(body, sd->signed_descriptor_len, conn,
3071 last);
3072 if (last) {
3073 tor_zlib_free(conn->zlib_state);
3074 conn->zlib_state = NULL;
3076 } else {
3077 connection_write_to_buf(body,
3078 sd->signed_descriptor_len,
3079 TO_CONN(conn));
3083 if (!smartlist_len(conn->fingerprint_stack)) {
3084 /* We just wrote the last one; finish up. */
3085 conn->dir_spool_src = DIR_SPOOL_NONE;
3086 smartlist_free(conn->fingerprint_stack);
3087 conn->fingerprint_stack = NULL;
3089 return 0;
3092 /** Spooling helper: Called when we're sending a directory or networkstatus,
3093 * and the outbuf has become too empty. Pulls some bytes from
3094 * <b>conn</b>-\>cached_dir-\>dir_z, uncompresses them if appropriate, and
3095 * puts them on the outbuf. If we run out of entries, flushes the zlib state
3096 * and sets the spool source to NONE. Returns 0 on success, negative on
3097 * failure. */
3098 static int
3099 connection_dirserv_add_dir_bytes_to_outbuf(dir_connection_t *conn)
3101 ssize_t bytes;
3102 int64_t remaining;
3104 bytes = DIRSERV_BUFFER_MIN - buf_datalen(conn->_base.outbuf);
3105 tor_assert(bytes > 0);
3106 tor_assert(conn->cached_dir);
3107 if (bytes < 8192)
3108 bytes = 8192;
3109 remaining = conn->cached_dir->dir_z_len - conn->cached_dir_offset;
3110 if (bytes > remaining)
3111 bytes = (ssize_t) remaining;
3113 if (conn->zlib_state) {
3114 connection_write_to_buf_zlib(
3115 conn->cached_dir->dir_z + conn->cached_dir_offset,
3116 bytes, conn, bytes == remaining);
3117 } else {
3118 connection_write_to_buf(conn->cached_dir->dir_z + conn->cached_dir_offset,
3119 bytes, TO_CONN(conn));
3121 conn->cached_dir_offset += bytes;
3122 if (conn->cached_dir_offset == (int)conn->cached_dir->dir_z_len) {
3123 /* We just wrote the last one; finish up. */
3124 connection_dirserv_finish_spooling(conn);
3125 cached_dir_decref(conn->cached_dir);
3126 conn->cached_dir = NULL;
3128 return 0;
3131 /** Spooling helper: Called when we're spooling networkstatus objects on
3132 * <b>conn</b>, and the outbuf has become too empty. If the current
3133 * networkstatus object (in <b>conn</b>-\>cached_dir) has more data, pull data
3134 * from there. Otherwise, pop the next fingerprint from fingerprint_stack,
3135 * and start spooling the next networkstatus. (A digest of all 0 bytes is
3136 * treated as a request for the current consensus.) If we run out of entries,
3137 * flushes the zlib state and sets the spool source to NONE. Returns 0 on
3138 * success, negative on failure. */
3139 static int
3140 connection_dirserv_add_networkstatus_bytes_to_outbuf(dir_connection_t *conn)
3143 while (buf_datalen(conn->_base.outbuf) < DIRSERV_BUFFER_MIN) {
3144 if (conn->cached_dir) {
3145 int uncompressing = (conn->zlib_state != NULL);
3146 int r = connection_dirserv_add_dir_bytes_to_outbuf(conn);
3147 if (conn->dir_spool_src == DIR_SPOOL_NONE) {
3148 /* add_dir_bytes thinks we're done with the cached_dir. But we
3149 * may have more cached_dirs! */
3150 conn->dir_spool_src = DIR_SPOOL_NETWORKSTATUS;
3151 /* This bit is tricky. If we were uncompressing the last
3152 * networkstatus, we may need to make a new zlib object to
3153 * uncompress the next one. */
3154 if (uncompressing && ! conn->zlib_state &&
3155 conn->fingerprint_stack &&
3156 smartlist_len(conn->fingerprint_stack)) {
3157 conn->zlib_state = tor_zlib_new(0, ZLIB_METHOD);
3160 if (r) return r;
3161 } else if (conn->fingerprint_stack &&
3162 smartlist_len(conn->fingerprint_stack)) {
3163 /* Add another networkstatus; start serving it. */
3164 char *fp = smartlist_pop_last(conn->fingerprint_stack);
3165 cached_dir_t *d = lookup_cached_dir_by_fp(fp);
3166 tor_free(fp);
3167 if (d) {
3168 ++d->refcnt;
3169 conn->cached_dir = d;
3170 conn->cached_dir_offset = 0;
3172 } else {
3173 connection_dirserv_finish_spooling(conn);
3174 if (conn->fingerprint_stack)
3175 smartlist_free(conn->fingerprint_stack);
3176 conn->fingerprint_stack = NULL;
3177 return 0;
3180 return 0;
3183 /** Called whenever we have flushed some directory data in state
3184 * SERVER_WRITING. */
3186 connection_dirserv_flushed_some(dir_connection_t *conn)
3188 tor_assert(conn->_base.state == DIR_CONN_STATE_SERVER_WRITING);
3190 if (buf_datalen(conn->_base.outbuf) >= DIRSERV_BUFFER_MIN)
3191 return 0;
3193 switch (conn->dir_spool_src) {
3194 case DIR_SPOOL_EXTRA_BY_DIGEST:
3195 case DIR_SPOOL_EXTRA_BY_FP:
3196 case DIR_SPOOL_SERVER_BY_DIGEST:
3197 case DIR_SPOOL_SERVER_BY_FP:
3198 return connection_dirserv_add_servers_to_outbuf(conn);
3199 case DIR_SPOOL_CACHED_DIR:
3200 return connection_dirserv_add_dir_bytes_to_outbuf(conn);
3201 case DIR_SPOOL_NETWORKSTATUS:
3202 return connection_dirserv_add_networkstatus_bytes_to_outbuf(conn);
3203 case DIR_SPOOL_NONE:
3204 default:
3205 return 0;
3209 /** Release all storage used by the directory server. */
3210 void
3211 dirserv_free_all(void)
3213 dirserv_free_fingerprint_list();
3215 cached_dir_decref(the_directory);
3216 clear_cached_dir(&the_runningrouters);
3217 cached_dir_decref(the_v2_networkstatus);
3218 cached_dir_decref(cached_directory);
3219 clear_cached_dir(&cached_runningrouters);
3220 if (cached_v2_networkstatus) {
3221 digestmap_free(cached_v2_networkstatus, _free_cached_dir);
3222 cached_v2_networkstatus = NULL;
3224 cached_dir_decref(cached_v3_networkstatus);