If we are lucky the whitespace nazis will not have noticed these things yet
[tor/rransom.git] / src / or / dirserv.c
blob3cc2c3718c3d354bb2fb5e86cffb5efb002d336f
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 /** As for dirserv_add_descriptor, but accepts multiple documents, and
568 * returns the most severe error that occurred for any one of them. */
570 dirserv_add_multiple_descriptors(const char *desc, uint8_t purpose,
571 const char *source,
572 const char **msg)
574 int r=100; /* higher than any actual return value. */
575 int r_tmp;
576 const char *msg_out;
577 smartlist_t *list;
578 const char *s;
579 int n_parsed = 0;
580 time_t now = time(NULL);
581 char annotation_buf[ROUTER_ANNOTATION_BUF_LEN];
582 char time_buf[ISO_TIME_LEN+1];
583 int general = purpose == ROUTER_PURPOSE_GENERAL;
584 tor_assert(msg);
586 format_iso_time(time_buf, now);
587 if (tor_snprintf(annotation_buf, sizeof(annotation_buf),
588 "@uploaded-at %s\n"
589 "@source %s\n"
590 "%s%s%s", time_buf, escaped(source),
591 !general ? "@purpose " : "",
592 !general ? router_purpose_to_string(purpose) : "",
593 !general ? "\n" : "")<0) {
594 *msg = "Couldn't format annotations";
595 return -1;
598 s = desc;
599 list = smartlist_create();
600 if (!router_parse_list_from_string(&s, NULL, list, SAVED_NOWHERE, 0, 0,
601 annotation_buf)) {
602 SMARTLIST_FOREACH(list, routerinfo_t *, ri, {
603 msg_out = NULL;
604 tor_assert(ri->purpose == purpose);
605 r_tmp = dirserv_add_descriptor(ri, &msg_out);
606 if (r_tmp < r) {
607 r = r_tmp;
608 *msg = msg_out;
612 n_parsed += smartlist_len(list);
613 smartlist_clear(list);
615 s = desc;
616 if (!router_parse_list_from_string(&s, NULL, list, SAVED_NOWHERE, 1, 0,
617 NULL)) {
618 SMARTLIST_FOREACH(list, extrainfo_t *, ei, {
619 msg_out = NULL;
621 r_tmp = dirserv_add_extrainfo(ei, &msg_out);
622 if (r_tmp < r) {
623 r = r_tmp;
624 *msg = msg_out;
628 n_parsed += smartlist_len(list);
629 smartlist_free(list);
631 if (! *msg) {
632 if (!n_parsed) {
633 *msg = "No descriptors found in your POST.";
634 if (r > -1)
635 r = -1;
636 } else {
637 *msg = "(no message)";
641 return r <= 2 ? r : 2;
644 /** Examine the parsed server descriptor in <b>ri</b> and maybe insert it into
645 * the list of server descriptors. Set *<b>msg</b> to a message that should be
646 * passed back to the origin of this descriptor.
648 * Return 2 if descriptor is well-formed and accepted;
649 * 1 if well-formed and accepted but origin should hear *msg;
650 * 0 if well-formed but redundant with one we already have;
651 * -1 if it is rejected and origin should hear *msg;
653 * This function is only called when fresh descriptors are posted, not when
654 * we re-load the cache.
657 dirserv_add_descriptor(routerinfo_t *ri, const char **msg)
659 int r;
660 routerinfo_t *ri_old;
661 char *desc = NULL;
662 size_t desclen = 0;
664 /* If it's too big, refuse it now. Otherwise we'll cache it all over the
665 * network and it'll clog everything up. */
666 if (ri->cache_info.signed_descriptor_len > MAX_DESCRIPTOR_UPLOAD_SIZE) {
667 log_notice(LD_DIR, "Somebody attempted to publish a router descriptor "
668 "with size %d. Either this is an attack, or the "
669 "MAX_DESCRIPTOR_UPLOAD_SIZE (%d) constant is too low.",
670 (int)ri->cache_info.signed_descriptor_len,
671 MAX_DESCRIPTOR_UPLOAD_SIZE);
672 *msg = "Router descriptor was too large";
673 control_event_or_authdir_new_descriptor("REJECTED",
674 ri->cache_info.signed_descriptor_body,
675 ri->cache_info.signed_descriptor_len, *msg);
676 routerinfo_free(ri);
677 return -1;
680 /* Check whether this descriptor is semantically identical to the last one
681 * from this server. (We do this here and not in router_add_to_routerlist
682 * because we want to be able to accept the newest router descriptor that
683 * another authority has, so we all converge on the same one.) */
684 ri_old = router_get_by_digest(ri->cache_info.identity_digest);
685 if (ri_old && ri_old->cache_info.published_on < ri->cache_info.published_on
686 && router_differences_are_cosmetic(ri_old, ri)
687 && !router_is_me(ri)) {
688 log_info(LD_DIRSERV,
689 "Not replacing descriptor from '%s'; differences are cosmetic.",
690 ri->nickname);
691 *msg = "Not replacing router descriptor; no information has changed since "
692 "the last one with this identity.";
693 control_event_or_authdir_new_descriptor("DROPPED",
694 ri->cache_info.signed_descriptor_body,
695 ri->cache_info.signed_descriptor_len, *msg);
696 routerinfo_free(ri);
697 return 0;
699 if (control_event_is_interesting(EVENT_AUTHDIR_NEWDESCS)) {
700 /* Make a copy of desc, since router_add_to_routerlist might free
701 * ri and its associated signed_descriptor_t. */
702 desclen = ri->cache_info.signed_descriptor_len;
703 desc = tor_strndup(ri->cache_info.signed_descriptor_body, desclen);
706 if ((r = router_add_to_routerlist(ri, msg, 0, 0))<0) {
707 if (r < -1 && desc) /* unless the routerinfo was fine, just out-of-date */
708 control_event_or_authdir_new_descriptor("REJECTED", desc, desclen, *msg);
709 tor_free(desc);
710 return r == -1 ? 0 : -1;
711 } else {
712 smartlist_t *changed;
713 control_event_or_authdir_new_descriptor("ACCEPTED", desc, desclen, *msg);
715 changed = smartlist_create();
716 smartlist_add(changed, ri);
717 control_event_descriptors_changed(changed);
718 smartlist_free(changed);
719 if (!*msg) {
720 *msg = ri->is_valid ? "Descriptor for valid server accepted" :
721 "Descriptor for invalid server accepted";
723 tor_free(desc);
724 return r == 0 ? 2 : 1;
728 /** As dirserv_add_descriptor, but for an extrainfo_t <b>ei</b>. */
729 static int
730 dirserv_add_extrainfo(extrainfo_t *ei, const char **msg)
732 routerinfo_t *ri;
733 int r;
734 tor_assert(msg);
735 *msg = NULL;
737 ri = router_get_by_digest(ei->cache_info.identity_digest);
738 if (!ri) {
739 *msg = "No corresponding router descriptor for extra-info descriptor";
740 extrainfo_free(ei);
741 return -1;
744 /* If it's too big, refuse it now. Otherwise we'll cache it all over the
745 * network and it'll clog everything up. */
746 if (ei->cache_info.signed_descriptor_len > MAX_EXTRAINFO_UPLOAD_SIZE) {
747 log_notice(LD_DIR, "Somebody attempted to publish an extrainfo "
748 "with size %d. Either this is an attack, or the "
749 "MAX_EXTRAINFO_UPLOAD_SIZE (%d) constant is too low.",
750 (int)ei->cache_info.signed_descriptor_len,
751 MAX_EXTRAINFO_UPLOAD_SIZE);
752 *msg = "Extrainfo document was too large";
753 extrainfo_free(ei);
754 return -1;
757 if ((r = routerinfo_incompatible_with_extrainfo(ri, ei, NULL, msg))) {
758 extrainfo_free(ei);
759 return r < 0 ? 0 : -1;
761 router_add_extrainfo_to_routerlist(ei, msg, 0, 0);
762 return 2;
765 /** Remove all descriptors whose nicknames or fingerprints no longer
766 * are allowed by our fingerprint list. (Descriptors that used to be
767 * good can become bad when we reload the fingerprint list.)
769 static void
770 directory_remove_invalid(void)
772 int i;
773 int changed = 0;
774 routerlist_t *rl = router_get_routerlist();
776 routerlist_assert_ok(rl);
778 for (i = 0; i < smartlist_len(rl->routers); ++i) {
779 const char *msg;
780 routerinfo_t *ent = smartlist_get(rl->routers, i);
781 uint32_t r = dirserv_router_get_status(ent, &msg);
782 if (r & FP_REJECT) {
783 log_info(LD_DIRSERV, "Router '%s' is now rejected: %s",
784 ent->nickname, msg?msg:"");
785 routerlist_remove(rl, ent, 0);
786 i--;
787 changed = 1;
788 continue;
790 if (bool_neq((r & FP_NAMED), ent->is_named)) {
791 log_info(LD_DIRSERV,
792 "Router '%s' is now %snamed.", ent->nickname,
793 (r&FP_NAMED)?"":"un");
794 ent->is_named = (r&FP_NAMED)?1:0;
795 changed = 1;
797 if (bool_neq((r & FP_INVALID), !ent->is_valid)) {
798 log_info(LD_DIRSERV, "Router '%s' is now %svalid.", ent->nickname,
799 (r&FP_INVALID) ? "in" : "");
800 ent->is_valid = (r&FP_INVALID)?0:1;
801 changed = 1;
803 if (bool_neq((r & FP_BADDIR), ent->is_bad_directory)) {
804 log_info(LD_DIRSERV, "Router '%s' is now a %s directory", ent->nickname,
805 (r & FP_BADDIR) ? "bad" : "good");
806 ent->is_bad_directory = (r&FP_BADDIR) ? 1: 0;
807 changed = 1;
809 if (bool_neq((r & FP_BADEXIT), ent->is_bad_exit)) {
810 log_info(LD_DIRSERV, "Router '%s' is now a %s exit", ent->nickname,
811 (r & FP_BADEXIT) ? "bad" : "good");
812 ent->is_bad_exit = (r&FP_BADEXIT) ? 1: 0;
813 changed = 1;
816 if (changed)
817 directory_set_dirty();
819 routerlist_assert_ok(rl);
822 /** Write a list of unregistered descriptors into a newly allocated
823 * string and return it. Used by dirserv operators to keep track of
824 * fast nodes that haven't registered.
827 getinfo_helper_dirserv_unregistered(control_connection_t *control_conn,
828 const char *question, char **answer_out)
830 smartlist_t *answerlist;
831 char buf[1024];
832 char *answer;
833 int min_bw = atoi(question);
834 routerlist_t *rl = router_get_routerlist();
836 (void) control_conn;
838 if (strcmpstart(question, "unregistered-servers-"))
839 return 0;
840 question += strlen("unregistered-servers-");
842 answerlist = smartlist_create();
843 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ent, {
844 uint32_t r = dirserv_router_get_status(ent, NULL);
845 if (router_get_advertised_bandwidth(ent) >= (size_t)min_bw &&
846 !(r & FP_NAMED)) {
847 /* then log this one */
848 tor_snprintf(buf, sizeof(buf),
849 "%s: BW %d on '%s'.",
850 ent->nickname, router_get_advertised_bandwidth(ent),
851 ent->platform ? ent->platform : "");
852 smartlist_add(answerlist, tor_strdup(buf));
855 answer = smartlist_join_strings(answerlist, "\r\n", 0, NULL);
856 SMARTLIST_FOREACH(answerlist, char *, cp, tor_free(cp));
857 smartlist_free(answerlist);
858 *answer_out = answer;
859 return 0;
862 /** Mark the directory as <b>dirty</b> -- when we're next asked for a
863 * directory, we will rebuild it instead of reusing the most recently
864 * generated one.
866 void
867 directory_set_dirty(void)
869 time_t now = time(NULL);
870 int set_v1_dirty=0;
872 /* Regenerate stubs only every 8 hours.
873 * XXXX021 It would be nice to generate less often. */
874 #define STUB_REGENERATE_INTERVAL (8*60*60)
875 if (!the_directory || !the_runningrouters.dir)
876 set_v1_dirty = 1;
877 else if (the_directory->published < now - STUB_REGENERATE_INTERVAL ||
878 the_runningrouters.published < now - STUB_REGENERATE_INTERVAL)
879 set_v1_dirty = 1;
881 if (set_v1_dirty) {
882 if (!the_directory_is_dirty)
883 the_directory_is_dirty = now;
884 if (!runningrouters_is_dirty)
885 runningrouters_is_dirty = now;
887 if (!the_v2_networkstatus_is_dirty)
888 the_v2_networkstatus_is_dirty = now;
892 * Allocate and return a description of the status of the server <b>desc</b>,
893 * for use in a v1-style router-status line. The server is listed
894 * as running iff <b>is_live</b> is true.
896 static char *
897 list_single_server_status(routerinfo_t *desc, int is_live)
899 char buf[MAX_NICKNAME_LEN+HEX_DIGEST_LEN+4]; /* !nickname=$hexdigest\0 */
900 char *cp;
902 tor_assert(desc);
904 cp = buf;
905 if (!is_live) {
906 *cp++ = '!';
908 if (desc->is_valid) {
909 strlcpy(cp, desc->nickname, sizeof(buf)-(cp-buf));
910 cp += strlen(cp);
911 *cp++ = '=';
913 *cp++ = '$';
914 base16_encode(cp, HEX_DIGEST_LEN+1, desc->cache_info.identity_digest,
915 DIGEST_LEN);
916 return tor_strdup(buf);
919 /** Each server needs to have passed a reachability test no more
920 * than this number of seconds ago, or he is listed as down in
921 * the directory. */
922 #define REACHABLE_TIMEOUT (45*60)
924 /** Treat a router as alive if
925 * - It's me, and I'm not hibernating.
926 * or - We've found it reachable recently. */
927 void
928 dirserv_set_router_is_running(routerinfo_t *router, time_t now)
930 int answer;
932 if (router_is_me(router) && !we_are_hibernating())
933 answer = 1;
934 else
935 answer = get_options()->AssumeReachable ||
936 now < router->last_reachable + REACHABLE_TIMEOUT;
938 if (router->is_running && !answer) {
939 /* it was running but now it's not. tell rephist. */
940 rep_hist_note_router_unreachable(router->cache_info.identity_digest, now);
943 router->is_running = answer;
946 /** Based on the routerinfo_ts in <b>routers</b>, allocate the
947 * contents of a v1-style router-status line, and store it in
948 * *<b>router_status_out</b>. Return 0 on success, -1 on failure.
950 * If for_controller is true, include the routers with very old descriptors.
951 * If for_controller is &gt;1, use the verbose nickname format.
954 list_server_status_v1(smartlist_t *routers, char **router_status_out,
955 int for_controller)
957 /* List of entries in a router-status style: An optional !, then an optional
958 * equals-suffixed nickname, then a dollar-prefixed hexdigest. */
959 smartlist_t *rs_entries;
960 time_t now = time(NULL);
961 time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
962 or_options_t *options = get_options();
963 /* We include v2 dir auths here too, because they need to answer
964 * controllers. Eventually we'll deprecate this whole function;
965 * see also networkstatus_getinfo_by_purpose(). */
966 int authdir = authdir_mode_publishes_statuses(options);
967 tor_assert(router_status_out);
969 rs_entries = smartlist_create();
971 SMARTLIST_FOREACH(routers, routerinfo_t *, ri,
973 if (authdir) {
974 /* Update router status in routerinfo_t. */
975 dirserv_set_router_is_running(ri, now);
977 if (for_controller == 1 || ri->cache_info.published_on >= cutoff)
978 smartlist_add(rs_entries, list_single_server_status(ri, ri->is_running));
979 else if (for_controller > 2) {
980 char name_buf[MAX_VERBOSE_NICKNAME_LEN+2];
981 char *cp = name_buf;
982 if (!ri->is_running)
983 *cp++ = '!';
984 router_get_verbose_nickname(cp, ri);
985 smartlist_add(rs_entries, tor_strdup(name_buf));
989 *router_status_out = smartlist_join_strings(rs_entries, " ", 0, NULL);
991 SMARTLIST_FOREACH(rs_entries, char *, cp, tor_free(cp));
992 smartlist_free(rs_entries);
994 return 0;
997 /** Given a (possibly empty) list of config_line_t, each line of which contains
998 * a list of comma-separated version numbers surrounded by optional space,
999 * allocate and return a new string containing the version numbers, in order,
1000 * separated by commas. Used to generate Recommended(Client|Server)?Versions
1002 static char *
1003 format_versions_list(config_line_t *ln)
1005 smartlist_t *versions;
1006 char *result;
1007 versions = smartlist_create();
1008 for ( ; ln; ln = ln->next) {
1009 smartlist_split_string(versions, ln->value, ",",
1010 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1012 sort_version_list(versions, 1);
1013 result = smartlist_join_strings(versions,",",0,NULL);
1014 SMARTLIST_FOREACH(versions,char *,s,tor_free(s));
1015 smartlist_free(versions);
1016 return result;
1019 /** Return 1 if <b>ri</b>'s descriptor is "active" -- running, valid,
1020 * not hibernating, and not too old. Else return 0.
1022 static int
1023 router_is_active(routerinfo_t *ri, time_t now)
1025 time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
1026 if (ri->cache_info.published_on < cutoff)
1027 return 0;
1028 if (!ri->is_running || !ri->is_valid || ri->is_hibernating)
1029 return 0;
1030 return 1;
1033 /** Generate a new v1 directory and write it into a newly allocated string.
1034 * Point *<b>dir_out</b> to the allocated string. Sign the
1035 * directory with <b>private_key</b>. Return 0 on success, -1 on
1036 * failure. If <b>complete</b> is set, give us all the descriptors;
1037 * otherwise leave out non-running and non-valid ones.
1040 dirserv_dump_directory_to_string(char **dir_out,
1041 crypto_pk_env_t *private_key)
1043 char *cp;
1044 char *identity_pkey; /* Identity key, DER64-encoded. */
1045 char *recommended_versions;
1046 char digest[DIGEST_LEN];
1047 char published[ISO_TIME_LEN+1];
1048 char *buf = NULL;
1049 size_t buf_len;
1050 size_t identity_pkey_len;
1051 time_t now = time(NULL);
1053 tor_assert(dir_out);
1054 *dir_out = NULL;
1056 if (crypto_pk_write_public_key_to_string(private_key,&identity_pkey,
1057 &identity_pkey_len)<0) {
1058 log_warn(LD_BUG,"write identity_pkey to string failed!");
1059 return -1;
1062 recommended_versions =
1063 format_versions_list(get_options()->RecommendedVersions);
1065 format_iso_time(published, now);
1067 buf_len = 2048+strlen(recommended_versions);
1069 buf = tor_malloc(buf_len);
1070 /* We'll be comparing against buf_len throughout the rest of the
1071 function, though strictly speaking we shouldn't be able to exceed
1072 it. This is C, after all, so we may as well check for buffer
1073 overruns.*/
1075 tor_snprintf(buf, buf_len,
1076 "signed-directory\n"
1077 "published %s\n"
1078 "recommended-software %s\n"
1079 "router-status %s\n"
1080 "dir-signing-key\n%s\n",
1081 published, recommended_versions, "",
1082 identity_pkey);
1084 tor_free(recommended_versions);
1085 tor_free(identity_pkey);
1087 cp = buf + strlen(buf);
1088 *cp = '\0';
1090 /* These multiple strlcat calls are inefficient, but dwarfed by the RSA
1091 signature. */
1092 if (strlcat(buf, "directory-signature ", buf_len) >= buf_len)
1093 goto truncated;
1094 if (strlcat(buf, get_options()->Nickname, buf_len) >= buf_len)
1095 goto truncated;
1096 if (strlcat(buf, "\n", buf_len) >= buf_len)
1097 goto truncated;
1099 if (router_get_dir_hash(buf,digest)) {
1100 log_warn(LD_BUG,"couldn't compute digest");
1101 tor_free(buf);
1102 return -1;
1104 note_crypto_pk_op(SIGN_DIR);
1105 if (router_append_dirobj_signature(buf,buf_len,digest,private_key)<0) {
1106 tor_free(buf);
1107 return -1;
1110 *dir_out = buf;
1111 return 0;
1112 truncated:
1113 log_warn(LD_BUG,"tried to exceed string length.");
1114 tor_free(buf);
1115 return -1;
1118 /********************************************************************/
1120 /* A set of functions to answer questions about how we'd like to behave
1121 * as a directory mirror/client. */
1123 /** Return 1 if we fetch our directory material directly from the
1124 * authorities, rather than from a mirror. */
1126 directory_fetches_from_authorities(or_options_t *options)
1128 routerinfo_t *me;
1129 uint32_t addr;
1130 if (options->FetchDirInfoEarly)
1131 return 1;
1132 if (options->BridgeRelay == 1)
1133 return 0;
1134 if (server_mode(options) && router_pick_published_address(options, &addr)<0)
1135 return 1; /* we don't know our IP address; ask an authority. */
1136 if (options->DirPort == 0)
1137 return 0;
1138 if (!server_mode(options) || !advertised_server_mode())
1139 return 0;
1140 me = router_get_my_routerinfo();
1141 if (!me || !me->dir_port)
1142 return 0; /* if dirport not advertised, return 0 too */
1143 return 1;
1146 /* Return 1 if we should fetch new networkstatuses, descriptors, etc
1147 * on the "mirror" schedule rather than the "client" schedule.
1150 directory_fetches_dir_info_early(or_options_t *options)
1152 return directory_fetches_from_authorities(options);
1155 /* Return 1 if we should fetch new networkstatuses, descriptors, etc
1156 * on a very passive schedule -- waiting long enough for ordinary clients
1157 * to probably have the info we want. These would include bridge users,
1158 * and maybe others in the future e.g. if a Tor client uses another Tor
1159 * client as a directory guard.
1162 directory_fetches_dir_info_later(or_options_t *options)
1164 return options->UseBridges != 0;
1167 /** Return 1 if we want to cache v2 dir info (each status file).
1170 directory_caches_v2_dir_info(or_options_t *options)
1172 return options->DirPort != 0;
1175 /** Return 1 if we want to keep descriptors, networkstatuses, etc around
1176 * and we're willing to serve them to others. Else return 0.
1179 directory_caches_dir_info(or_options_t *options)
1181 return options->BridgeRelay != 0 || options->DirPort != 0;
1184 /** Return 1 if we want to allow remote people to ask us directory
1185 * requests via the "begin_dir" interface, which doesn't require
1186 * having any separate port open. */
1188 directory_permits_begindir_requests(or_options_t *options)
1190 return options->BridgeRelay != 0 || options->DirPort != 0;
1193 /** Return 1 if we want to allow controllers to ask us directory
1194 * requests via the controller interface, which doesn't require
1195 * having any separate port open. */
1197 directory_permits_controller_requests(or_options_t *options)
1199 return options->DirPort != 0;
1202 /** Return 1 if we have no need to fetch new descriptors. This generally
1203 * happens when we're not a dir cache and we haven't built any circuits
1204 * lately.
1207 directory_too_idle_to_fetch_descriptors(or_options_t *options, time_t now)
1209 return !options->DirPort && !options->FetchUselessDescriptors &&
1210 rep_hist_circbuilding_dormant(now);
1213 /********************************************************************/
1215 /* Used only by non-v1-auth dirservers: The v1 directory and
1216 * runningrouters we'll serve when requested. */
1217 static cached_dir_t *cached_directory = NULL;
1218 static cached_dir_t cached_runningrouters = { NULL, NULL, 0, 0, 0, -1 };
1220 /** Used for other dirservers' v2 network statuses. Map from hexdigest to
1221 * cached_dir_t. */
1222 static digestmap_t *cached_v2_networkstatus = NULL;
1224 /** The v3 consensus network status that we're currently serving. */
1225 static cached_dir_t *cached_v3_networkstatus = NULL;
1227 /** Possibly replace the contents of <b>d</b> with the value of
1228 * <b>directory</b> published on <b>when</b>, unless <b>when</b> is older than
1229 * the last value, or too far in the future.
1231 * Does not copy <b>directory</b>; frees it if it isn't used.
1233 static void
1234 set_cached_dir(cached_dir_t *d, char *directory, time_t when)
1236 time_t now = time(NULL);
1237 if (when<=d->published) {
1238 log_info(LD_DIRSERV, "Ignoring old directory; not caching.");
1239 tor_free(directory);
1240 } else if (when>=now+ROUTER_MAX_AGE_TO_PUBLISH) {
1241 log_info(LD_DIRSERV, "Ignoring future directory; not caching.");
1242 tor_free(directory);
1243 } else {
1244 /* if (when>d->published && when<now+ROUTER_MAX_AGE) */
1245 log_debug(LD_DIRSERV, "Caching directory.");
1246 tor_free(d->dir);
1247 d->dir = directory;
1248 d->dir_len = strlen(directory);
1249 tor_free(d->dir_z);
1250 if (tor_gzip_compress(&(d->dir_z), &(d->dir_z_len), d->dir, d->dir_len,
1251 ZLIB_METHOD)) {
1252 log_warn(LD_BUG,"Error compressing cached directory");
1254 d->published = when;
1258 /** Decrement the reference count on <b>d</b>, and free it if it no longer has
1259 * any references. */
1260 void
1261 cached_dir_decref(cached_dir_t *d)
1263 if (!d || --d->refcnt > 0)
1264 return;
1265 clear_cached_dir(d);
1266 tor_free(d);
1269 /** Allocate and return a new cached_dir_t containing the string <b>s</b>,
1270 * published at <b>published</b>. */
1271 cached_dir_t *
1272 new_cached_dir(char *s, time_t published)
1274 cached_dir_t *d = tor_malloc_zero(sizeof(cached_dir_t));
1275 d->refcnt = 1;
1276 d->dir = s;
1277 d->dir_len = strlen(s);
1278 d->published = published;
1279 if (tor_gzip_compress(&(d->dir_z), &(d->dir_z_len), d->dir, d->dir_len,
1280 ZLIB_METHOD)) {
1281 log_warn(LD_BUG, "Error compressing directory");
1283 return d;
1286 /** Remove all storage held in <b>d</b>, but do not free <b>d</b> itself. */
1287 static void
1288 clear_cached_dir(cached_dir_t *d)
1290 tor_free(d->dir);
1291 tor_free(d->dir_z);
1292 memset(d, 0, sizeof(cached_dir_t));
1295 /** Free all storage held by the cached_dir_t in <b>d</b>. */
1296 static void
1297 _free_cached_dir(void *_d)
1299 cached_dir_t *d = (cached_dir_t *)_d;
1300 cached_dir_decref(d);
1303 /** If we have no cached directory, or it is older than <b>published</b>,
1304 * then replace it with <b>directory</b>, published at <b>published</b>.
1306 * If <b>published</b> is too old, do nothing.
1308 * If <b>is_running_routers</b>, this is really a v1 running_routers
1309 * document rather than a v1 directory.
1311 void
1312 dirserv_set_cached_directory(const char *directory, time_t published,
1313 int is_running_routers)
1315 time_t now = time(NULL);
1317 if (is_running_routers) {
1318 if (published >= now - MAX_V1_RR_AGE)
1319 set_cached_dir(&cached_runningrouters, tor_strdup(directory), published);
1320 } else {
1321 if (published >= now - MAX_V1_DIRECTORY_AGE) {
1322 cached_dir_decref(cached_directory);
1323 cached_directory = new_cached_dir(tor_strdup(directory), published);
1328 /** If <b>networkstatus</b> is non-NULL, we've just received a v2
1329 * network-status for an authoritative directory with identity digest
1330 * <b>identity</b> published at <b>published</b> -- store it so we can
1331 * serve it to others.
1333 * If <b>networkstatus</b> is NULL, remove the entry with the given
1334 * identity fingerprint from the v2 cache.
1336 void
1337 dirserv_set_cached_networkstatus_v2(const char *networkstatus,
1338 const char *identity,
1339 time_t published)
1341 cached_dir_t *d, *old_d;
1342 smartlist_t *trusted_dirs;
1343 if (!cached_v2_networkstatus)
1344 cached_v2_networkstatus = digestmap_new();
1346 old_d = digestmap_get(cached_v2_networkstatus, identity);
1347 if (!old_d && !networkstatus)
1348 return;
1350 if (networkstatus) {
1351 if (!old_d || published > old_d->published) {
1352 d = new_cached_dir(tor_strdup(networkstatus), published);
1353 digestmap_set(cached_v2_networkstatus, identity, d);
1354 if (old_d)
1355 cached_dir_decref(old_d);
1357 } else {
1358 if (old_d) {
1359 digestmap_remove(cached_v2_networkstatus, identity);
1360 cached_dir_decref(old_d);
1364 /* Now purge old entries. */
1365 trusted_dirs = router_get_trusted_dir_servers();
1366 if (digestmap_size(cached_v2_networkstatus) >
1367 smartlist_len(trusted_dirs) + MAX_UNTRUSTED_NETWORKSTATUSES) {
1368 /* We need to remove the oldest untrusted networkstatus. */
1369 const char *oldest = NULL;
1370 time_t oldest_published = TIME_MAX;
1371 digestmap_iter_t *iter;
1373 for (iter = digestmap_iter_init(cached_v2_networkstatus);
1374 !digestmap_iter_done(iter);
1375 iter = digestmap_iter_next(cached_v2_networkstatus, iter)) {
1376 const char *ident;
1377 void *val;
1378 digestmap_iter_get(iter, &ident, &val);
1379 d = val;
1380 if (d->published < oldest_published &&
1381 !router_digest_is_trusted_dir(ident)) {
1382 oldest = ident;
1383 oldest_published = d->published;
1386 tor_assert(oldest);
1387 d = digestmap_remove(cached_v2_networkstatus, oldest);
1388 if (d)
1389 cached_dir_decref(d);
1393 /** Replace the v3 consensus networkstatus that we're serving with
1394 * <b>networkstatus</b>, published at <b>published</b>. No validation is
1395 * performed. */
1396 void
1397 dirserv_set_cached_networkstatus_v3(const char *networkstatus,
1398 time_t published)
1400 if (cached_v3_networkstatus)
1401 cached_dir_decref(cached_v3_networkstatus);
1402 cached_v3_networkstatus = new_cached_dir(
1403 tor_strdup(networkstatus), published);
1406 /** Remove any v2 networkstatus from the directory cache that was published
1407 * before <b>cutoff</b>. */
1408 void
1409 dirserv_clear_old_networkstatuses(time_t cutoff)
1411 if (!cached_v2_networkstatus)
1412 return;
1414 DIGESTMAP_FOREACH_MODIFY(cached_v2_networkstatus, id, cached_dir_t *, dir) {
1415 if (dir->published < cutoff) {
1416 char *fname;
1417 fname = networkstatus_get_cache_filename(id);
1418 if (file_status(fname) == FN_FILE) {
1419 log_info(LD_DIR, "Removing too-old untrusted networkstatus in %s",
1420 fname);
1421 unlink(fname);
1423 tor_free(fname);
1424 cached_dir_decref(dir);
1425 MAP_DEL_CURRENT(id);
1427 } DIGESTMAP_FOREACH_END
1430 /** Remove any v1 info from the directory cache that was published
1431 * too long ago. */
1432 void
1433 dirserv_clear_old_v1_info(time_t now)
1435 if (cached_directory &&
1436 cached_directory->published < (now - MAX_V1_DIRECTORY_AGE)) {
1437 cached_dir_decref(cached_directory);
1438 cached_directory = NULL;
1440 if (cached_runningrouters.published < (now - MAX_V1_RR_AGE)) {
1441 clear_cached_dir(&cached_runningrouters);
1445 /** Helper: If we're an authority for the right directory version (v1 or v2)
1446 * (based on <b>auth_type</b>), try to regenerate
1447 * auth_src as appropriate and return it, falling back to cache_src on
1448 * failure. If we're a cache, simply return cache_src.
1450 static cached_dir_t *
1451 dirserv_pick_cached_dir_obj(cached_dir_t *cache_src,
1452 cached_dir_t *auth_src,
1453 time_t dirty, cached_dir_t *(*regenerate)(void),
1454 const char *name,
1455 authority_type_t auth_type)
1457 or_options_t *options = get_options();
1458 int authority = (auth_type == V1_AUTHORITY && authdir_mode_v1(options)) ||
1459 (auth_type == V2_AUTHORITY && authdir_mode_v2(options));
1461 if (!authority || authdir_mode_bridge(options)) {
1462 return cache_src;
1463 } else {
1464 /* We're authoritative. */
1465 if (regenerate != NULL) {
1466 if (dirty && dirty + DIR_REGEN_SLACK_TIME < time(NULL)) {
1467 if (!(auth_src = regenerate())) {
1468 log_err(LD_BUG, "Couldn't generate %s?", name);
1469 exit(1);
1471 } else {
1472 log_info(LD_DIRSERV, "The %s is still clean; reusing.", name);
1475 return auth_src ? auth_src : cache_src;
1479 /** Return the most recently generated encoded signed v1 directory,
1480 * generating a new one as necessary. If not a v1 authoritative directory
1481 * may return NULL if no directory is yet cached. */
1482 cached_dir_t *
1483 dirserv_get_directory(void)
1485 return dirserv_pick_cached_dir_obj(cached_directory, the_directory,
1486 the_directory_is_dirty,
1487 dirserv_regenerate_directory,
1488 "v1 server directory", V1_AUTHORITY);
1491 /** Only called by v1 auth dirservers.
1492 * Generate a fresh v1 directory; set the_directory and return a pointer
1493 * to the new value.
1495 static cached_dir_t *
1496 dirserv_regenerate_directory(void)
1498 char *new_directory=NULL;
1500 if (dirserv_dump_directory_to_string(&new_directory, get_identity_key())) {
1501 log_warn(LD_BUG, "Error creating directory.");
1502 tor_free(new_directory);
1503 return NULL;
1505 cached_dir_decref(the_directory);
1506 the_directory = new_cached_dir(new_directory, time(NULL));
1507 log_info(LD_DIRSERV,"New directory (size %d) has been built.",
1508 (int)the_directory->dir_len);
1509 log_debug(LD_DIRSERV,"New directory (size %d):\n%s",
1510 (int)the_directory->dir_len, the_directory->dir);
1512 the_directory_is_dirty = 0;
1514 /* Save the directory to disk so we re-load it quickly on startup.
1516 dirserv_set_cached_directory(the_directory->dir, time(NULL), 0);
1518 return the_directory;
1521 /** Only called by v1 auth dirservers.
1522 * Replace the current running-routers list with a newly generated one. */
1523 static cached_dir_t *
1524 generate_runningrouters(void)
1526 char *s=NULL;
1527 char digest[DIGEST_LEN];
1528 char published[ISO_TIME_LEN+1];
1529 size_t len;
1530 crypto_pk_env_t *private_key = get_identity_key();
1531 char *identity_pkey; /* Identity key, DER64-encoded. */
1532 size_t identity_pkey_len;
1534 if (crypto_pk_write_public_key_to_string(private_key,&identity_pkey,
1535 &identity_pkey_len)<0) {
1536 log_warn(LD_BUG,"write identity_pkey to string failed!");
1537 goto err;
1539 format_iso_time(published, time(NULL));
1541 len = 2048;
1542 s = tor_malloc_zero(len);
1543 tor_snprintf(s, len,
1544 "network-status\n"
1545 "published %s\n"
1546 "router-status %s\n"
1547 "dir-signing-key\n%s"
1548 "directory-signature %s\n",
1549 published, "", identity_pkey,
1550 get_options()->Nickname);
1551 tor_free(identity_pkey);
1552 if (router_get_runningrouters_hash(s,digest)) {
1553 log_warn(LD_BUG,"couldn't compute digest");
1554 goto err;
1556 note_crypto_pk_op(SIGN_DIR);
1557 if (router_append_dirobj_signature(s, len, digest, private_key)<0)
1558 goto err;
1560 set_cached_dir(&the_runningrouters, s, time(NULL));
1561 runningrouters_is_dirty = 0;
1563 return &the_runningrouters;
1564 err:
1565 tor_free(s);
1566 return NULL;
1569 /** Set *<b>rr</b> to the most recently generated encoded signed
1570 * running-routers list, generating a new one as necessary. Return the
1571 * size of the directory on success, and 0 on failure. */
1572 cached_dir_t *
1573 dirserv_get_runningrouters(void)
1575 return dirserv_pick_cached_dir_obj(
1576 &cached_runningrouters, &the_runningrouters,
1577 runningrouters_is_dirty,
1578 generate_runningrouters,
1579 "v1 network status list", V1_AUTHORITY);
1582 cached_dir_t *
1583 dirserv_get_consensus(void)
1585 return cached_v3_networkstatus;
1588 /** For authoritative directories: the current (v2) network status. */
1589 static cached_dir_t *the_v2_networkstatus = NULL;
1591 /** Return true iff our opinion of the routers has been stale for long
1592 * enough that we should generate a new v2 network status doc. */
1593 static int
1594 should_generate_v2_networkstatus(void)
1596 return authdir_mode_v2(get_options()) &&
1597 the_v2_networkstatus_is_dirty &&
1598 the_v2_networkstatus_is_dirty + DIR_REGEN_SLACK_TIME < time(NULL);
1601 /** If a router's uptime is at least this value, then it is always
1602 * considered stable, regardless of the rest of the network. This
1603 * way we resist attacks where an attacker doubles the size of the
1604 * network using allegedly high-uptime nodes, displacing all the
1605 * current guards. */
1606 #define UPTIME_TO_GUARANTEE_STABLE (3600*24*30)
1607 /** If a router's MTBF is at least this value, then it is always stable.
1608 * See above. (Corresponds to about 7 days for current decay rates.) */
1609 #define MTBF_TO_GUARANTEE_STABLE (60*60*24*5)
1610 /** Similarly, we protect sufficiently fast nodes from being pushed
1611 * out of the set of Fast nodes. */
1612 #define BANDWIDTH_TO_GUARANTEE_FAST (100*1024)
1613 /** Similarly, every node with sufficient bandwidth can be considered
1614 * for Guard status. */
1615 #define BANDWIDTH_TO_GUARANTEE_GUARD (250*1024)
1616 /** Similarly, every node with at least this much weighted time known can be
1617 * considered familiar enough to be a guard. Corresponds to about 20 days for
1618 * current decay rates.
1620 #define TIME_KNOWN_TO_GUARANTEE_FAMILIAR (8*24*60*60)
1621 /** Similarly, every node with sufficient WFU is around enough to be a guard.
1623 #define WFU_TO_GUARANTEE_GUARD (0.995)
1625 /* Thresholds for server performance: set by
1626 * dirserv_compute_performance_thresholds, and used by
1627 * generate_v2_networkstatus */
1628 /* XXXX stick these all in a struct. */
1629 static uint32_t stable_uptime = 0; /* start at a safe value */
1630 static double stable_mtbf = 0.0;
1631 static int enough_mtbf_info = 0;
1632 static double guard_wfu = 0.0;
1633 static long guard_tk = 0;
1634 static uint32_t fast_bandwidth = 0;
1635 static uint32_t guard_bandwidth_including_exits = 0;
1636 static uint32_t guard_bandwidth_excluding_exits = 0;
1637 static uint64_t total_bandwidth = 0;
1638 static uint64_t total_exit_bandwidth = 0;
1640 /** Helper: estimate the uptime of a router given its stated uptime and the
1641 * amount of time since it last stated its stated uptime. */
1642 static INLINE long
1643 real_uptime(routerinfo_t *router, time_t now)
1645 if (now < router->cache_info.published_on)
1646 return router->uptime;
1647 else
1648 return router->uptime + (now - router->cache_info.published_on);
1651 /** Return 1 if <b>router</b> is not suitable for these parameters, else 0.
1652 * If <b>need_uptime</b> is non-zero, we require a minimum uptime.
1653 * If <b>need_capacity</b> is non-zero, we require a minimum advertised
1654 * bandwidth.
1656 static int
1657 dirserv_thinks_router_is_unreliable(time_t now,
1658 routerinfo_t *router,
1659 int need_uptime, int need_capacity)
1661 if (need_uptime) {
1662 if (!enough_mtbf_info) {
1663 /* XXXX Once most authorities are on v3, we should change the rule from
1664 * "use uptime if we don't have mtbf data" to "don't advertise Stable on
1665 * v3 if we don't have enough mtbf data." */
1666 long uptime = real_uptime(router, now);
1667 if ((unsigned)uptime < stable_uptime &&
1668 (unsigned)uptime < UPTIME_TO_GUARANTEE_STABLE)
1669 return 1;
1670 } else {
1671 double mtbf =
1672 rep_hist_get_stability(router->cache_info.identity_digest, now);
1673 if (mtbf < stable_mtbf)
1674 return 1;
1677 if (need_capacity) {
1678 uint32_t bw = router_get_advertised_bandwidth(router);
1679 if (bw < fast_bandwidth)
1680 return 1;
1682 return 0;
1685 /** Return true iff <b>router</b> should be assigned the "HSDir" flag.
1686 * Right now this means it advertises support for it, it has a high
1687 * uptime, and it's currently considered Running.
1689 * This function needs to be called after router-\>is_running has
1690 * been set.
1692 static int
1693 dirserv_thinks_router_is_hs_dir(routerinfo_t *router, time_t now)
1695 long uptime = real_uptime(router, now);
1697 return (router->wants_to_be_hs_dir &&
1698 uptime > get_options()->MinUptimeHidServDirectoryV2 &&
1699 router->is_running);
1702 /** Look through the routerlist, the Mean Time Between Failure history, and
1703 * the Weighted Fractional Uptime history, and use them to set thresholds for
1704 * the Stable, Fast, and Guard flags. Update the fields stable_uptime,
1705 * stable_mtbf, enough_mtbf_info, guard_wfu, guard_tk, fast_bandwidth,
1706 * guard_bandwidh_including_exits, guard_bandwidth_excluding_exits,
1707 * total_bandwidth, and total_exit_bandwidth.
1709 * Also, set the is_exit flag of each router appropriately. */
1710 static void
1711 dirserv_compute_performance_thresholds(routerlist_t *rl)
1713 int n_active, n_active_nonexit, n_familiar;
1714 uint32_t *uptimes, *bandwidths, *bandwidths_excluding_exits;
1715 long *tks;
1716 double *mtbfs, *wfus;
1717 time_t now = time(NULL);
1719 /* initialize these all here, in case there are no routers */
1720 stable_uptime = 0;
1721 stable_mtbf = 0;
1722 fast_bandwidth = 0;
1723 guard_bandwidth_including_exits = 0;
1724 guard_bandwidth_excluding_exits = 0;
1725 guard_tk = 0;
1726 guard_wfu = 0;
1727 total_bandwidth = 0;
1728 total_exit_bandwidth = 0;
1730 /* Initialize arrays that will hold values for each router. We'll
1731 * sort them and use that to compute thresholds. */
1732 n_active = n_active_nonexit = 0;
1733 /* Uptime for every active router. */
1734 uptimes = tor_malloc(sizeof(uint32_t)*smartlist_len(rl->routers));
1735 /* Bandwidth for every active router. */
1736 bandwidths = tor_malloc(sizeof(uint32_t)*smartlist_len(rl->routers));
1737 /* Bandwidth for every active non-exit router. */
1738 bandwidths_excluding_exits =
1739 tor_malloc(sizeof(uint32_t)*smartlist_len(rl->routers));
1740 /* Weighted mean time between failure for each active router. */
1741 mtbfs = tor_malloc(sizeof(double)*smartlist_len(rl->routers));
1742 /* Time-known for each active router. */
1743 tks = tor_malloc(sizeof(long)*smartlist_len(rl->routers));
1744 /* Weighted fractional uptime for each active router. */
1745 wfus = tor_malloc(sizeof(double)*smartlist_len(rl->routers));
1747 /* Now, fill in the arrays. */
1748 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
1749 if (router_is_active(ri, now)) {
1750 const char *id = ri->cache_info.identity_digest;
1751 uint32_t bw;
1752 ri->is_exit = exit_policy_is_general_exit(ri->exit_policy);
1753 uptimes[n_active] = (uint32_t)real_uptime(ri, now);
1754 mtbfs[n_active] = rep_hist_get_stability(id, now);
1755 tks [n_active] = rep_hist_get_weighted_time_known(id, now);
1756 bandwidths[n_active] = bw = router_get_advertised_bandwidth(ri);
1757 total_bandwidth += bw;
1758 if (ri->is_exit && !ri->is_bad_exit) {
1759 total_exit_bandwidth += bw;
1760 } else {
1761 bandwidths_excluding_exits[n_active_nonexit] = bw;
1762 ++n_active_nonexit;
1764 ++n_active;
1768 /* Now, compute thresholds. */
1769 if (n_active) {
1770 /* The median uptime is stable. */
1771 stable_uptime = median_uint32(uptimes, n_active);
1772 /* The median mtbf is stable, if we have enough mtbf info */
1773 stable_mtbf = median_double(mtbfs, n_active);
1774 /* The 12.5th percentile bandwidth is fast. */
1775 fast_bandwidth = find_nth_uint32(bandwidths, n_active, n_active/8);
1776 /* (Now bandwidths is sorted.) */
1777 if (fast_bandwidth < ROUTER_REQUIRED_MIN_BANDWIDTH)
1778 fast_bandwidth = bandwidths[n_active/4];
1779 guard_bandwidth_including_exits = bandwidths[(n_active-1)/2];
1780 guard_tk = find_nth_long(tks, n_active, n_active/8);
1783 if (guard_tk > TIME_KNOWN_TO_GUARANTEE_FAMILIAR)
1784 guard_tk = TIME_KNOWN_TO_GUARANTEE_FAMILIAR;
1786 if (fast_bandwidth > BANDWIDTH_TO_GUARANTEE_FAST)
1787 fast_bandwidth = BANDWIDTH_TO_GUARANTEE_FAST;
1789 /* Now that we have a time-known that 7/8 routers are known longer than,
1790 * fill wfus with the wfu of every such "familiar" router. */
1791 n_familiar = 0;
1792 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
1793 if (router_is_active(ri, now)) {
1794 const char *id = ri->cache_info.identity_digest;
1795 long tk = rep_hist_get_weighted_time_known(id, now);
1796 if (tk < guard_tk)
1797 continue;
1798 wfus[n_familiar++] = rep_hist_get_weighted_fractional_uptime(id, now);
1801 if (n_familiar)
1802 guard_wfu = median_double(wfus, n_familiar);
1803 if (guard_wfu > WFU_TO_GUARANTEE_GUARD)
1804 guard_wfu = WFU_TO_GUARANTEE_GUARD;
1806 enough_mtbf_info = rep_hist_have_measured_enough_stability();
1808 if (n_active_nonexit) {
1809 guard_bandwidth_excluding_exits =
1810 median_uint32(bandwidths_excluding_exits, n_active_nonexit);
1813 log(LOG_INFO, LD_DIRSERV,
1814 "Cutoffs: For Stable, %lu sec uptime, %lu sec MTBF. "
1815 "For Fast: %lu bytes/sec. "
1816 "For Guard: WFU %.03lf%%, time-known %lu sec, "
1817 "and bandwidth %lu or %lu bytes/sec.",
1818 (unsigned long)stable_uptime,
1819 (unsigned long)stable_mtbf,
1820 (unsigned long)fast_bandwidth,
1821 guard_wfu*100,
1822 (unsigned long)guard_tk,
1823 (unsigned long)guard_bandwidth_including_exits,
1824 (unsigned long)guard_bandwidth_excluding_exits);
1826 tor_free(uptimes);
1827 tor_free(mtbfs);
1828 tor_free(bandwidths);
1829 tor_free(bandwidths_excluding_exits);
1830 tor_free(tks);
1831 tor_free(wfus);
1834 /** Given a platform string as in a routerinfo_t (possibly null), return a
1835 * newly allocated version string for a networkstatus document, or NULL if the
1836 * platform doesn't give a Tor version. */
1837 static char *
1838 version_from_platform(const char *platform)
1840 if (platform && !strcmpstart(platform, "Tor ")) {
1841 const char *eos = find_whitespace(platform+4);
1842 if (eos && !strcmpstart(eos, " (r")) {
1843 /* XXXX021 Unify this logic with the other version extraction
1844 * logic */
1845 eos = find_whitespace(eos+1);
1847 if (eos) {
1848 return tor_strndup(platform, eos-platform);
1851 return NULL;
1854 /** Helper: write the router-status information in <b>rs</b> into <b>buf</b>,
1855 * which has at least <b>buf_len</b> free characters. Do NUL-termination.
1856 * Use the same format as in network-status documents. If <b>version</b> is
1857 * non-NULL, add a "v" line for the platform. Return 0 on success, -1 on
1858 * failure. If <b>first_line_only<b> is true, don't include any flags
1859 * or version line.
1862 routerstatus_format_entry(char *buf, size_t buf_len,
1863 routerstatus_t *rs, const char *version,
1864 int first_line_only, int v2_format)
1865 /* XXX: first_line_only and v2_format should probably be be both
1866 * replaced by a single purpose parameter.
1869 int r;
1870 struct in_addr in;
1871 char *cp;
1872 char *summary;
1874 char published[ISO_TIME_LEN+1];
1875 char ipaddr[INET_NTOA_BUF_LEN];
1876 char identity64[BASE64_DIGEST_LEN+1];
1877 char digest64[BASE64_DIGEST_LEN+1];
1879 format_iso_time(published, rs->published_on);
1880 digest_to_base64(identity64, rs->identity_digest);
1881 digest_to_base64(digest64, rs->descriptor_digest);
1882 in.s_addr = htonl(rs->addr);
1883 tor_inet_ntoa(&in, ipaddr, sizeof(ipaddr));
1885 r = tor_snprintf(buf, buf_len,
1886 "r %s %s %s %s %s %d %d\n",
1887 rs->nickname,
1888 identity64,
1889 digest64,
1890 published,
1891 ipaddr,
1892 (int)rs->or_port,
1893 (int)rs->dir_port);
1894 if (r<0) {
1895 log_warn(LD_BUG, "Not enough space in buffer.");
1896 return -1;
1898 if (first_line_only)
1899 return 0;
1901 cp = buf + strlen(buf);
1902 /* NOTE: Whenever this list expands, be sure to increase MAX_FLAG_LINE_LEN*/
1903 r = tor_snprintf(cp, buf_len - (cp-buf),
1904 "s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
1905 /* These must stay in alphabetical order. */
1906 rs->is_authority?" Authority":"",
1907 rs->is_bad_directory?" BadDirectory":"",
1908 rs->is_bad_exit?" BadExit":"",
1909 rs->is_exit?" Exit":"",
1910 rs->is_fast?" Fast":"",
1911 rs->is_possible_guard?" Guard":"",
1912 rs->is_hs_dir?" HSDir":"",
1913 rs->is_named?" Named":"",
1914 rs->is_running?" Running":"",
1915 rs->is_stable?" Stable":"",
1916 rs->is_unnamed?" Unnamed":"",
1917 rs->is_v2_dir?" V2Dir":"",
1918 rs->is_valid?" Valid":"");
1919 if (r<0) {
1920 log_warn(LD_BUG, "Not enough space in buffer.");
1921 return -1;
1923 cp += strlen(cp);
1925 /* length of "opt v \n" */
1926 #define V_LINE_OVERHEAD 7
1927 if (version && strlen(version) < MAX_V_LINE_LEN - V_LINE_OVERHEAD) {
1928 if (tor_snprintf(cp, buf_len - (cp-buf), "opt v %s\n", version)<0) {
1929 log_warn(LD_BUG, "Unable to print router version.");
1930 return -1;
1932 cp += strlen(cp);
1935 if (!v2_format) {
1936 routerinfo_t* desc = router_get_by_digest(rs->identity_digest);
1938 /* Blow up more or less nicely if we didn't get anything or not the
1939 * thing we expected.
1941 if (!desc) {
1942 char id[HEX_DIGEST_LEN+1];
1943 char dd[HEX_DIGEST_LEN+1];
1945 base16_encode(id, sizeof(id), rs->identity_digest, DIGEST_LEN);
1946 base16_encode(dd, sizeof(dd), rs->descriptor_digest, DIGEST_LEN);
1947 log_warn(LD_BUG, "Cannot get the descriptor with digest %s for %s.",
1948 id, dd);
1949 return -1;
1951 if (memcmp(desc->cache_info.signed_descriptor_digest,
1952 rs->descriptor_digest,
1953 DIGEST_LEN)) {
1954 char rl_d[HEX_DIGEST_LEN+1];
1955 char rs_d[HEX_DIGEST_LEN+1];
1957 base16_encode(rl_d, sizeof(rl_d),
1958 desc->cache_info.signed_descriptor_digest, DIGEST_LEN);
1959 base16_encode(rs_d, sizeof(rs_d), rs->descriptor_digest, DIGEST_LEN);
1960 log_err(LD_BUG, "descriptor digest in routerlist does not match "
1961 "the one in routerstatus: %s vs %s\n",
1962 rl_d, rs_d);
1964 tor_assert(!memcmp(desc->cache_info.signed_descriptor_digest,
1965 rs->descriptor_digest,
1966 DIGEST_LEN));
1969 r = tor_snprintf(cp, buf_len - (cp-buf),
1970 "w Bandwidth=%d\n",
1971 router_get_advertised_bandwidth_capped(desc) / 1024);
1972 if (r<0) {
1973 log_warn(LD_BUG, "Not enough space in buffer.");
1974 return -1;
1976 cp += strlen(cp);
1978 summary = policy_summarize(desc->exit_policy);
1979 r = tor_snprintf(cp, buf_len - (cp-buf), "p %s\n", summary);
1980 if (r<0) {
1981 log_warn(LD_BUG, "Not enough space in buffer.");
1982 return -1;
1984 cp += strlen(cp);
1985 tor_free(summary);
1988 return 0;
1991 /** Helper for sorting: compares two routerinfos first by address, and then by
1992 * descending order of "usefulness". (An authority is more useful than a
1993 * non-authority; a running router is more useful than a non-running router;
1994 * and a router with more bandwidth is more useful than one with less.)
1996 static int
1997 _compare_routerinfo_by_ip_and_bw(const void **a, const void **b)
1999 routerinfo_t *first = *(routerinfo_t **)a, *second = *(routerinfo_t **)b;
2000 int first_is_auth, second_is_auth;
2001 uint32_t bw_first, bw_second;
2003 /* we return -1 if first should appear before second... that is,
2004 * if first is a better router. */
2005 if (first->addr < second->addr)
2006 return -1;
2007 else if (first->addr > second->addr)
2008 return 1;
2010 /* Potentially, this next bit could cause k n lg n memcmp calls. But in
2011 * reality, we will almost never get here, since addresses will usually be
2012 * different. */
2014 first_is_auth =
2015 router_digest_is_trusted_dir(first->cache_info.identity_digest);
2016 second_is_auth =
2017 router_digest_is_trusted_dir(second->cache_info.identity_digest);
2019 if (first_is_auth && !second_is_auth)
2020 return -1;
2021 else if (!first_is_auth && second_is_auth)
2022 return 1;
2024 else if (first->is_running && !second->is_running)
2025 return -1;
2026 else if (!first->is_running && second->is_running)
2027 return 1;
2029 bw_first = router_get_advertised_bandwidth(first);
2030 bw_second = router_get_advertised_bandwidth(second);
2032 if (bw_first > bw_second)
2033 return -1;
2034 else if (bw_first < bw_second)
2035 return 1;
2037 /* They're equal! Compare by identity digest, so there's a
2038 * deterministic order and we avoid flapping. */
2039 return memcmp(first->cache_info.identity_digest,
2040 second->cache_info.identity_digest,
2041 DIGEST_LEN);
2044 /** Given a list of routerinfo_t in <b>routers</b>, return a new digestmap_t
2045 * whose keys are the identity digests of those routers that we're going to
2046 * exclude for Sybil-like appearance. */
2047 static digestmap_t *
2048 get_possible_sybil_list(const smartlist_t *routers)
2050 or_options_t *options = get_options();
2051 digestmap_t *omit_as_sybil;
2052 smartlist_t *routers_by_ip = smartlist_create();
2053 uint32_t last_addr;
2054 int addr_count;
2055 /* Allow at most this number of Tor servers on a single IP address, ... */
2056 int max_with_same_addr = options->AuthDirMaxServersPerAddr;
2057 /* ... unless it's a directory authority, in which case allow more. */
2058 int max_with_same_addr_on_authority = options->AuthDirMaxServersPerAuthAddr;
2059 if (max_with_same_addr <= 0)
2060 max_with_same_addr = INT_MAX;
2061 if (max_with_same_addr_on_authority <= 0)
2062 max_with_same_addr_on_authority = INT_MAX;
2064 smartlist_add_all(routers_by_ip, routers);
2065 smartlist_sort(routers_by_ip, _compare_routerinfo_by_ip_and_bw);
2066 omit_as_sybil = digestmap_new();
2068 last_addr = 0;
2069 addr_count = 0;
2070 SMARTLIST_FOREACH(routers_by_ip, routerinfo_t *, ri,
2072 if (last_addr != ri->addr) {
2073 last_addr = ri->addr;
2074 addr_count = 1;
2075 } else if (++addr_count > max_with_same_addr) {
2076 if (!router_addr_is_trusted_dir(ri->addr) ||
2077 addr_count > max_with_same_addr_on_authority)
2078 digestmap_set(omit_as_sybil, ri->cache_info.identity_digest, ri);
2082 smartlist_free(routers_by_ip);
2083 return omit_as_sybil;
2086 /** Extract status information from <b>ri</b> and from other authority
2087 * functions and store it in <b>rs</b>>. If <b>naming</b>, consider setting
2088 * the named flag in <b>rs</b>. If not <b>exits_can_be_guards</b>, never mark
2089 * an exit as a guard. If <b>listbadexits</b>, consider setting the badexit
2090 * flag.
2092 * We assume that ri-\>is_running has already been set, e.g. by
2093 * dirserv_set_router_is_running(ri, now);
2095 void
2096 set_routerstatus_from_routerinfo(routerstatus_t *rs,
2097 routerinfo_t *ri, time_t now,
2098 int naming, int exits_can_be_guards,
2099 int listbadexits, int listbaddirs)
2101 int unstable_version =
2102 !tor_version_as_new_as(ri->platform,"0.1.1.16-rc-cvs");
2103 memset(rs, 0, sizeof(routerstatus_t));
2105 rs->is_authority =
2106 router_digest_is_trusted_dir(ri->cache_info.identity_digest);
2108 /* Already set by compute_performance_thresholds. */
2109 rs->is_exit = ri->is_exit;
2110 rs->is_stable = ri->is_stable =
2111 router_is_active(ri, now) &&
2112 !dirserv_thinks_router_is_unreliable(now, ri, 1, 0) &&
2113 !unstable_version;
2114 rs->is_fast = ri->is_fast =
2115 router_is_active(ri, now) &&
2116 !dirserv_thinks_router_is_unreliable(now, ri, 0, 1);
2117 rs->is_running = ri->is_running; /* computed above */
2119 if (naming) {
2120 uint32_t name_status = dirserv_get_name_status(
2121 ri->cache_info.identity_digest, ri->nickname);
2122 rs->is_named = (naming && (name_status & FP_NAMED)) ? 1 : 0;
2123 rs->is_unnamed = (naming && (name_status & FP_UNNAMED)) ? 1 : 0;
2125 rs->is_valid = ri->is_valid;
2127 if (rs->is_fast &&
2128 (!rs->is_exit || exits_can_be_guards) &&
2129 (router_get_advertised_bandwidth(ri) >= BANDWIDTH_TO_GUARANTEE_GUARD ||
2130 router_get_advertised_bandwidth(ri) >=
2131 (exits_can_be_guards ? guard_bandwidth_including_exits :
2132 guard_bandwidth_excluding_exits))) {
2133 long tk = rep_hist_get_weighted_time_known(
2134 ri->cache_info.identity_digest, now);
2135 double wfu = rep_hist_get_weighted_fractional_uptime(
2136 ri->cache_info.identity_digest, now);
2137 rs->is_possible_guard = (wfu >= guard_wfu && tk >= guard_tk) ? 1 : 0;
2138 } else {
2139 rs->is_possible_guard = 0;
2141 rs->is_bad_directory = listbaddirs && ri->is_bad_directory;
2142 rs->is_bad_exit = listbadexits && ri->is_bad_exit;
2143 ri->is_hs_dir = dirserv_thinks_router_is_hs_dir(ri, now);
2144 rs->is_hs_dir = ri->is_hs_dir;
2145 rs->is_v2_dir = ri->dir_port != 0;
2147 if (!strcasecmp(ri->nickname, UNNAMED_ROUTER_NICKNAME))
2148 rs->is_named = rs->is_unnamed = 0;
2150 rs->published_on = ri->cache_info.published_on;
2151 memcpy(rs->identity_digest, ri->cache_info.identity_digest, DIGEST_LEN);
2152 memcpy(rs->descriptor_digest, ri->cache_info.signed_descriptor_digest,
2153 DIGEST_LEN);
2154 rs->addr = ri->addr;
2155 strlcpy(rs->nickname, ri->nickname, sizeof(rs->nickname));
2156 rs->or_port = ri->or_port;
2157 rs->dir_port = ri->dir_port;
2160 /** Routerstatus <b>rs</b> is part of a group of routers that are on
2161 * too narrow an IP-space. Clear out its flags: we don't want people
2162 * using it.
2164 static void
2165 clear_status_flags_on_sybil(routerstatus_t *rs)
2167 rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
2168 rs->is_running = rs->is_named = rs->is_valid = rs->is_v2_dir =
2169 rs->is_hs_dir = rs->is_possible_guard = rs->is_bad_exit =
2170 rs->is_bad_directory = 0;
2171 /* FFFF we might want some mechanism to check later on if we
2172 * missed zeroing any flags: it's easy to add a new flag but
2173 * forget to add it to this clause. */
2176 /** Clear all the status flags in routerinfo <b>router</b>. We put this
2177 * function here because it's eerily similar to
2178 * clear_status_flags_on_sybil() above. One day we should merge them. */
2179 void
2180 router_clear_status_flags(routerinfo_t *router)
2182 router->is_valid = router->is_running = router->is_hs_dir =
2183 router->is_fast = router->is_stable =
2184 router->is_possible_guard = router->is_exit =
2185 router->is_bad_exit = router->is_bad_directory = 0;
2188 /** Return a new networkstatus_t* containing our current opinion. (For v3
2189 * authorities) */
2190 networkstatus_t *
2191 dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
2192 authority_cert_t *cert)
2194 or_options_t *options = get_options();
2195 networkstatus_t *v3_out = NULL;
2196 uint32_t addr;
2197 char *hostname = NULL, *client_versions = NULL, *server_versions = NULL;
2198 const char *contact;
2199 smartlist_t *routers, *routerstatuses;
2200 char identity_digest[DIGEST_LEN];
2201 char signing_key_digest[DIGEST_LEN];
2202 int naming = options->NamingAuthoritativeDir;
2203 int listbadexits = options->AuthDirListBadExits;
2204 int listbaddirs = options->AuthDirListBadDirs;
2205 int exits_can_be_guards;
2206 routerlist_t *rl = router_get_routerlist();
2207 time_t now = time(NULL);
2208 time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
2209 networkstatus_voter_info_t *voter = NULL;
2210 vote_timing_t timing;
2211 digestmap_t *omit_as_sybil = NULL;
2212 int vote_on_reachability = 1;
2214 tor_assert(private_key);
2215 tor_assert(cert);
2217 if (now - time_of_process_start <
2218 options->TestingAuthDirTimeToLearnReachability)
2219 vote_on_reachability = 0;
2221 if (resolve_my_address(LOG_WARN, options, &addr, &hostname)<0) {
2222 log_warn(LD_NET, "Couldn't resolve my hostname");
2223 return NULL;
2225 if (!strchr(hostname, '.')) {
2226 tor_free(hostname);
2227 hostname = tor_dup_ip(addr);
2229 if (crypto_pk_get_digest(private_key, signing_key_digest)<0) {
2230 log_err(LD_BUG, "Error computing signing key digest");
2231 return NULL;
2233 if (crypto_pk_get_digest(cert->identity_key, identity_digest)<0) {
2234 log_err(LD_BUG, "Error computing identity key digest");
2235 return NULL;
2238 if (options->VersioningAuthoritativeDir) {
2239 client_versions = format_versions_list(options->RecommendedClientVersions);
2240 server_versions = format_versions_list(options->RecommendedServerVersions);
2243 contact = get_options()->ContactInfo;
2244 if (!contact)
2245 contact = "(none)";
2247 /* precompute this part, since we need it to decide what "stable"
2248 * means. */
2249 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
2250 dirserv_set_router_is_running(ri, now);
2253 dirserv_compute_performance_thresholds(rl);
2255 /* XXXX We should take steps to keep this from oscillating if
2256 * total_exit_bandwidth is close to total_bandwidth/3. */
2257 exits_can_be_guards = total_exit_bandwidth >= (total_bandwidth / 3);
2259 routers = smartlist_create();
2260 smartlist_add_all(routers, rl->routers);
2261 routers_sort_by_identity(routers);
2262 omit_as_sybil = get_possible_sybil_list(routers);
2264 routerstatuses = smartlist_create();
2266 SMARTLIST_FOREACH(routers, routerinfo_t *, ri, {
2267 if (ri->cache_info.published_on >= cutoff) {
2268 routerstatus_t *rs;
2269 vote_routerstatus_t *vrs;
2271 vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
2272 rs = &vrs->status;
2273 set_routerstatus_from_routerinfo(rs, ri, now,
2274 naming, exits_can_be_guards,
2275 listbadexits, listbaddirs);
2277 if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest))
2278 clear_status_flags_on_sybil(rs);
2280 if (!vote_on_reachability)
2281 rs->is_running = 0;
2283 vrs->version = version_from_platform(ri->platform);
2284 smartlist_add(routerstatuses, vrs);
2287 smartlist_free(routers);
2288 digestmap_free(omit_as_sybil, NULL);
2290 v3_out = tor_malloc_zero(sizeof(networkstatus_t));
2292 v3_out->type = NS_TYPE_VOTE;
2293 dirvote_get_preferred_voting_intervals(&timing);
2294 v3_out->published = now;
2296 char tbuf[ISO_TIME_LEN+1];
2297 networkstatus_t *current_consensus =
2298 networkstatus_get_live_consensus(now);
2299 long last_consensus_interval; /* only used to pick a valid_after */
2300 if (current_consensus)
2301 last_consensus_interval = current_consensus->fresh_until -
2302 current_consensus->valid_after;
2303 else
2304 last_consensus_interval = options->TestingV3AuthInitialVotingInterval;
2305 v3_out->valid_after =
2306 dirvote_get_start_of_next_interval(now, (int)last_consensus_interval);
2307 format_iso_time(tbuf, v3_out->valid_after);
2308 log_notice(LD_DIR,"Choosing valid-after time in vote as %s: "
2309 "consensus_set=%d, last_interval=%d",
2310 tbuf, current_consensus?1:0, (int)last_consensus_interval);
2312 v3_out->fresh_until = v3_out->valid_after + timing.vote_interval;
2313 v3_out->valid_until = v3_out->valid_after +
2314 (timing.vote_interval * timing.n_intervals_valid);
2315 v3_out->vote_seconds = timing.vote_delay;
2316 v3_out->dist_seconds = timing.dist_delay;
2317 tor_assert(v3_out->vote_seconds > 0);
2318 tor_assert(v3_out->dist_seconds > 0);
2319 tor_assert(timing.n_intervals_valid > 0);
2321 v3_out->client_versions = client_versions;
2322 v3_out->server_versions = server_versions;
2323 v3_out->known_flags = smartlist_create();
2324 smartlist_split_string(v3_out->known_flags,
2325 "Authority Exit Fast Guard HSDir Stable V2Dir Valid",
2326 0, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
2327 if (vote_on_reachability)
2328 smartlist_add(v3_out->known_flags, tor_strdup("Running"));
2329 if (listbaddirs)
2330 smartlist_add(v3_out->known_flags, tor_strdup("BadDirectory"));
2331 if (listbadexits)
2332 smartlist_add(v3_out->known_flags, tor_strdup("BadExit"));
2333 if (naming) {
2334 smartlist_add(v3_out->known_flags, tor_strdup("Named"));
2335 smartlist_add(v3_out->known_flags, tor_strdup("Unnamed"));
2337 smartlist_sort_strings(v3_out->known_flags);
2339 voter = tor_malloc_zero(sizeof(networkstatus_voter_info_t));
2340 voter->nickname = tor_strdup(options->Nickname);
2341 memcpy(voter->identity_digest, identity_digest, DIGEST_LEN);
2342 voter->address = hostname;
2343 voter->addr = addr;
2344 voter->dir_port = options->DirPort;
2345 voter->or_port = options->ORPort;
2346 voter->contact = tor_strdup(contact);
2347 memcpy(voter->signing_key_digest, signing_key_digest, DIGEST_LEN);
2348 if (options->V3AuthUseLegacyKey) {
2349 authority_cert_t *c = get_my_v3_legacy_cert();
2350 if (c) {
2351 crypto_pk_get_digest(c->identity_key, voter->legacy_id_digest);
2355 v3_out->voters = smartlist_create();
2356 smartlist_add(v3_out->voters, voter);
2357 v3_out->cert = authority_cert_dup(cert);
2358 v3_out->routerstatus_list = routerstatuses;
2359 /* Note: networkstatus_digest is unset; it won't get set until we actually
2360 * format the vote. */
2362 return v3_out;
2365 /** For v2 authoritative directories only: Replace the contents of
2366 * <b>the_v2_networkstatus</b> with a newly generated network status
2367 * object. */
2368 static cached_dir_t *
2369 generate_v2_networkstatus_opinion(void)
2371 cached_dir_t *r = NULL;
2372 size_t len, identity_pkey_len;
2373 char *status = NULL, *client_versions = NULL, *server_versions = NULL,
2374 *identity_pkey = NULL, *hostname = NULL;
2375 char *outp, *endp;
2376 or_options_t *options = get_options();
2377 char fingerprint[FINGERPRINT_LEN+1];
2378 char ipaddr[INET_NTOA_BUF_LEN];
2379 char published[ISO_TIME_LEN+1];
2380 char digest[DIGEST_LEN];
2381 struct in_addr in;
2382 uint32_t addr;
2383 crypto_pk_env_t *private_key;
2384 routerlist_t *rl = router_get_routerlist();
2385 time_t now = time(NULL);
2386 time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
2387 int naming = options->NamingAuthoritativeDir;
2388 int versioning = options->VersioningAuthoritativeDir;
2389 int listbaddirs = options->AuthDirListBadDirs;
2390 int listbadexits = options->AuthDirListBadExits;
2391 int exits_can_be_guards;
2392 const char *contact;
2393 char *version_lines = NULL;
2394 smartlist_t *routers = NULL;
2395 digestmap_t *omit_as_sybil = NULL;
2397 private_key = get_identity_key();
2399 if (resolve_my_address(LOG_WARN, options, &addr, &hostname)<0) {
2400 log_warn(LD_NET, "Couldn't resolve my hostname");
2401 goto done;
2403 in.s_addr = htonl(addr);
2404 tor_inet_ntoa(&in, ipaddr, sizeof(ipaddr));
2406 format_iso_time(published, now);
2408 client_versions = format_versions_list(options->RecommendedClientVersions);
2409 server_versions = format_versions_list(options->RecommendedServerVersions);
2411 if (crypto_pk_write_public_key_to_string(private_key, &identity_pkey,
2412 &identity_pkey_len)<0) {
2413 log_warn(LD_BUG,"Writing public key to string failed.");
2414 goto done;
2417 if (crypto_pk_get_fingerprint(private_key, fingerprint, 0)<0) {
2418 log_err(LD_BUG, "Error computing fingerprint");
2419 goto done;
2422 contact = get_options()->ContactInfo;
2423 if (!contact)
2424 contact = "(none)";
2426 if (versioning) {
2427 size_t v_len = 64+strlen(client_versions)+strlen(server_versions);
2428 version_lines = tor_malloc(v_len);
2429 tor_snprintf(version_lines, v_len,
2430 "client-versions %s\nserver-versions %s\n",
2431 client_versions, server_versions);
2432 } else {
2433 version_lines = tor_strdup("");
2436 len = 4096+strlen(client_versions)+strlen(server_versions);
2437 len += identity_pkey_len*2;
2438 len += (RS_ENTRY_LEN)*smartlist_len(rl->routers);
2440 status = tor_malloc(len);
2441 tor_snprintf(status, len,
2442 "network-status-version 2\n"
2443 "dir-source %s %s %d\n"
2444 "fingerprint %s\n"
2445 "contact %s\n"
2446 "published %s\n"
2447 "dir-options%s%s%s%s\n"
2448 "%s" /* client version line, server version line. */
2449 "dir-signing-key\n%s",
2450 hostname, ipaddr, (int)options->DirPort,
2451 fingerprint,
2452 contact,
2453 published,
2454 naming ? " Names" : "",
2455 listbaddirs ? " BadDirectories" : "",
2456 listbadexits ? " BadExits" : "",
2457 versioning ? " Versions" : "",
2458 version_lines,
2459 identity_pkey);
2460 outp = status + strlen(status);
2461 endp = status + len;
2463 /* precompute this part, since we need it to decide what "stable"
2464 * means. */
2465 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
2466 dirserv_set_router_is_running(ri, now);
2469 dirserv_compute_performance_thresholds(rl);
2471 /* XXXX We should take steps to keep this from oscillating if
2472 * total_exit_bandwidth is close to total_bandwidth/3. */
2473 exits_can_be_guards = total_exit_bandwidth >= (total_bandwidth / 3);
2475 routers = smartlist_create();
2476 smartlist_add_all(routers, rl->routers);
2477 routers_sort_by_identity(routers);
2479 omit_as_sybil = get_possible_sybil_list(routers);
2481 SMARTLIST_FOREACH(routers, routerinfo_t *, ri, {
2482 if (ri->cache_info.published_on >= cutoff) {
2483 routerstatus_t rs;
2484 char *version = version_from_platform(ri->platform);
2486 set_routerstatus_from_routerinfo(&rs, ri, now,
2487 naming, exits_can_be_guards,
2488 listbadexits, listbaddirs);
2490 if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest))
2491 clear_status_flags_on_sybil(&rs);
2493 if (routerstatus_format_entry(outp, endp-outp, &rs, version, 0, 1)) {
2494 log_warn(LD_BUG, "Unable to print router status.");
2495 tor_free(version);
2496 goto done;
2498 tor_free(version);
2499 outp += strlen(outp);
2503 if (tor_snprintf(outp, endp-outp, "directory-signature %s\n",
2504 get_options()->Nickname)<0) {
2505 log_warn(LD_BUG, "Unable to write signature line.");
2506 goto done;
2508 if (router_get_networkstatus_v2_hash(status, digest)<0) {
2509 log_warn(LD_BUG, "Unable to hash network status");
2510 goto done;
2512 outp += strlen(outp);
2514 note_crypto_pk_op(SIGN_DIR);
2515 if (router_append_dirobj_signature(outp,endp-outp,digest,private_key)<0) {
2516 log_warn(LD_BUG, "Unable to sign router status.");
2517 goto done;
2521 networkstatus_v2_t *ns;
2522 if (!(ns = networkstatus_v2_parse_from_string(status))) {
2523 log_err(LD_BUG,"Generated a networkstatus we couldn't parse.");
2524 goto done;
2526 networkstatus_v2_free(ns);
2530 cached_dir_t **ns_ptr = &the_v2_networkstatus;
2531 if (*ns_ptr)
2532 cached_dir_decref(*ns_ptr);
2533 *ns_ptr = new_cached_dir(status, now);
2534 status = NULL; /* So it doesn't get double-freed. */
2535 the_v2_networkstatus_is_dirty = 0;
2536 router_set_networkstatus_v2((*ns_ptr)->dir, now, NS_GENERATED, NULL);
2537 r = *ns_ptr;
2540 done:
2541 tor_free(client_versions);
2542 tor_free(server_versions);
2543 tor_free(version_lines);
2544 tor_free(status);
2545 tor_free(hostname);
2546 tor_free(identity_pkey);
2547 if (routers)
2548 smartlist_free(routers);
2549 if (omit_as_sybil)
2550 digestmap_free(omit_as_sybil, NULL);
2551 return r;
2554 /** Given the portion of a networkstatus request URL after "tor/status/" in
2555 * <b>key</b>, append to <b>result</b> the digests of the identity keys of the
2556 * networkstatus objects that the client has requested. */
2557 void
2558 dirserv_get_networkstatus_v2_fingerprints(smartlist_t *result,
2559 const char *key)
2561 tor_assert(result);
2563 if (!cached_v2_networkstatus)
2564 cached_v2_networkstatus = digestmap_new();
2566 if (should_generate_v2_networkstatus())
2567 generate_v2_networkstatus_opinion();
2569 if (!strcmp(key,"authority")) {
2570 if (authdir_mode_v2(get_options())) {
2571 routerinfo_t *me = router_get_my_routerinfo();
2572 if (me)
2573 smartlist_add(result,
2574 tor_memdup(me->cache_info.identity_digest, DIGEST_LEN));
2576 } else if (!strcmp(key, "all")) {
2577 if (digestmap_size(cached_v2_networkstatus)) {
2578 digestmap_iter_t *iter;
2579 iter = digestmap_iter_init(cached_v2_networkstatus);
2580 while (!digestmap_iter_done(iter)) {
2581 const char *ident;
2582 void *val;
2583 digestmap_iter_get(iter, &ident, &val);
2584 smartlist_add(result, tor_memdup(ident, DIGEST_LEN));
2585 iter = digestmap_iter_next(cached_v2_networkstatus, iter);
2587 } else {
2588 SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
2589 trusted_dir_server_t *, ds,
2590 if (ds->type & V2_AUTHORITY)
2591 smartlist_add(result, tor_memdup(ds->digest, DIGEST_LEN)));
2593 smartlist_sort_digests(result);
2594 if (smartlist_len(result) == 0)
2595 log_info(LD_DIRSERV,
2596 "Client requested 'all' network status objects; we have none.");
2597 } else if (!strcmpstart(key, "fp/")) {
2598 dir_split_resource_into_fingerprints(key+3, result, NULL, 1, 1);
2602 /** Look for a network status object as specified by <b>key</b>, which should
2603 * be either "authority" (to find a network status generated by us), a hex
2604 * identity digest (to find a network status generated by given directory), or
2605 * "all" (to return all the v2 network status objects we have).
2607 void
2608 dirserv_get_networkstatus_v2(smartlist_t *result,
2609 const char *key)
2611 cached_dir_t *cached;
2612 smartlist_t *fingerprints = smartlist_create();
2613 tor_assert(result);
2615 if (!cached_v2_networkstatus)
2616 cached_v2_networkstatus = digestmap_new();
2618 dirserv_get_networkstatus_v2_fingerprints(fingerprints, key);
2619 SMARTLIST_FOREACH(fingerprints, const char *, fp,
2621 if (router_digest_is_me(fp) && should_generate_v2_networkstatus())
2622 generate_v2_networkstatus_opinion();
2623 cached = digestmap_get(cached_v2_networkstatus, fp);
2624 if (cached) {
2625 smartlist_add(result, cached);
2626 } else {
2627 char hexbuf[HEX_DIGEST_LEN+1];
2628 base16_encode(hexbuf, sizeof(hexbuf), fp, DIGEST_LEN);
2629 log_info(LD_DIRSERV, "Don't know about any network status with "
2630 "fingerprint '%s'", hexbuf);
2633 SMARTLIST_FOREACH(fingerprints, char *, cp, tor_free(cp));
2634 smartlist_free(fingerprints);
2637 /** As dirserv_get_routerdescs(), but instead of getting signed_descriptor_t
2638 * pointers, adds copies of digests to fps_out, and doesn't use the
2639 * /tor/server/ prefix. For a /d/ request, adds descriptor digests; for other
2640 * requests, adds identity digests.
2643 dirserv_get_routerdesc_fingerprints(smartlist_t *fps_out, const char *key,
2644 const char **msg, int for_unencrypted_conn)
2646 int by_id = 1;
2647 *msg = NULL;
2649 if (!strcmp(key, "all")) {
2650 routerlist_t *rl = router_get_routerlist();
2651 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, r,
2652 smartlist_add(fps_out,
2653 tor_memdup(r->cache_info.identity_digest, DIGEST_LEN)));
2654 } else if (!strcmp(key, "authority")) {
2655 routerinfo_t *ri = router_get_my_routerinfo();
2656 if (ri)
2657 smartlist_add(fps_out,
2658 tor_memdup(ri->cache_info.identity_digest, DIGEST_LEN));
2659 } else if (!strcmpstart(key, "d/")) {
2660 by_id = 0;
2661 key += strlen("d/");
2662 dir_split_resource_into_fingerprints(key, fps_out, NULL, 1, 1);
2663 } else if (!strcmpstart(key, "fp/")) {
2664 key += strlen("fp/");
2665 dir_split_resource_into_fingerprints(key, fps_out, NULL, 1, 1);
2666 } else {
2667 *msg = "Key not recognized";
2668 return -1;
2671 if (for_unencrypted_conn) {
2672 /* Remove anything whose purpose isn't general. */
2673 SMARTLIST_FOREACH(fps_out, char *, cp, {
2674 signed_descriptor_t *sd =
2675 by_id ? get_signed_descriptor_by_fp(cp,0,0) :
2676 router_get_by_descriptor_digest(cp);
2677 if (sd && !sd->send_unencrypted) {
2678 tor_free(cp);
2679 SMARTLIST_DEL_CURRENT(fps_out, cp);
2684 if (!smartlist_len(fps_out)) {
2685 *msg = "Servers unavailable";
2686 return -1;
2688 return 0;
2691 /** Add a signed_descriptor_t to <b>descs_out</b> for each router matching
2692 * <b>key</b>. The key should be either
2693 * - "/tor/server/authority" for our own routerinfo;
2694 * - "/tor/server/all" for all the routerinfos we have, concatenated;
2695 * - "/tor/server/fp/FP" where FP is a plus-separated sequence of
2696 * hex identity digests; or
2697 * - "/tor/server/d/D" where D is a plus-separated sequence
2698 * of server descriptor digests, in hex.
2700 * Return 0 if we found some matching descriptors, or -1 if we do not
2701 * have any descriptors, no matching descriptors, or if we did not
2702 * recognize the key (URL).
2703 * If -1 is returned *<b>msg</b> will be set to an appropriate error
2704 * message.
2706 * XXXX021 rename this function. It's only called from the controller.
2707 * XXXX021 in fact, refactor this function, mergeing as much as possible.
2710 dirserv_get_routerdescs(smartlist_t *descs_out, const char *key,
2711 const char **msg)
2713 *msg = NULL;
2715 if (!strcmp(key, "/tor/server/all")) {
2716 routerlist_t *rl = router_get_routerlist();
2717 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, r,
2718 smartlist_add(descs_out, &(r->cache_info)));
2719 } else if (!strcmp(key, "/tor/server/authority")) {
2720 routerinfo_t *ri = router_get_my_routerinfo();
2721 if (ri)
2722 smartlist_add(descs_out, &(ri->cache_info));
2723 } else if (!strcmpstart(key, "/tor/server/d/")) {
2724 smartlist_t *digests = smartlist_create();
2725 key += strlen("/tor/server/d/");
2726 dir_split_resource_into_fingerprints(key, digests, NULL, 1, 1);
2727 SMARTLIST_FOREACH(digests, const char *, d,
2729 signed_descriptor_t *sd = router_get_by_descriptor_digest(d);
2730 if (sd)
2731 smartlist_add(descs_out,sd);
2733 SMARTLIST_FOREACH(digests, char *, d, tor_free(d));
2734 smartlist_free(digests);
2735 } else if (!strcmpstart(key, "/tor/server/fp/")) {
2736 smartlist_t *digests = smartlist_create();
2737 time_t cutoff = time(NULL) - ROUTER_MAX_AGE_TO_PUBLISH;
2738 key += strlen("/tor/server/fp/");
2739 dir_split_resource_into_fingerprints(key, digests, NULL, 1, 1);
2740 SMARTLIST_FOREACH(digests, const char *, d,
2742 if (router_digest_is_me(d)) {
2743 /* make sure desc_routerinfo exists */
2744 routerinfo_t *ri = router_get_my_routerinfo();
2745 if (ri)
2746 smartlist_add(descs_out, &(ri->cache_info));
2747 } else {
2748 routerinfo_t *ri = router_get_by_digest(d);
2749 /* Don't actually serve a descriptor that everyone will think is
2750 * expired. This is an (ugly) workaround to keep buggy 0.1.1.10
2751 * Tors from downloading descriptors that they will throw away.
2753 if (ri && ri->cache_info.published_on > cutoff)
2754 smartlist_add(descs_out, &(ri->cache_info));
2757 SMARTLIST_FOREACH(digests, char *, d, tor_free(d));
2758 smartlist_free(digests);
2759 } else {
2760 *msg = "Key not recognized";
2761 return -1;
2764 if (!smartlist_len(descs_out)) {
2765 *msg = "Servers unavailable";
2766 return -1;
2768 return 0;
2771 /** Called when a TLS handshake has completed successfully with a
2772 * router listening at <b>address</b>:<b>or_port</b>, and has yielded
2773 * a certificate with digest <b>digest_rcvd</b>.
2775 * Also, if as_advertised is 1, then inform the reachability checker
2776 * that we could get to this guy.
2778 void
2779 dirserv_orconn_tls_done(const char *address,
2780 uint16_t or_port,
2781 const char *digest_rcvd,
2782 int as_advertised)
2784 routerlist_t *rl = router_get_routerlist();
2785 time_t now = time(NULL);
2786 int bridge_auth = authdir_mode_bridge(get_options());
2787 tor_assert(address);
2788 tor_assert(digest_rcvd);
2790 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
2791 if (!strcasecmp(address, ri->address) && or_port == ri->or_port &&
2792 as_advertised &&
2793 !memcmp(ri->cache_info.identity_digest, digest_rcvd, DIGEST_LEN)) {
2794 /* correct digest. mark this router reachable! */
2795 if (!bridge_auth || ri->purpose == ROUTER_PURPOSE_BRIDGE) {
2796 log_info(LD_DIRSERV, "Found router %s to be reachable. Yay.",
2797 ri->nickname);
2798 rep_hist_note_router_reachable(digest_rcvd, now);
2799 ri->last_reachable = now;
2803 /* FFFF Maybe we should reinstate the code that dumps routers with the same
2804 * addr/port but with nonmatching keys, but instead of dumping, we should
2805 * skip testing. */
2808 /** Auth dir server only: if <b>try_all</b> is 1, launch connections to
2809 * all known routers; else we want to load balance such that we only
2810 * try a few connections per call.
2812 * The load balancing is such that if we get called once every ten
2813 * seconds, we will cycle through all the tests in 1280 seconds (a
2814 * bit over 20 minutes).
2816 void
2817 dirserv_test_reachability(time_t now, int try_all)
2819 /* XXX decide what to do here; see or-talk thread "purging old router
2820 * information, revocation." -NM
2821 * We can't afford to mess with this in 0.1.2.x. The reason is that
2822 * if we stop doing reachability tests on some of routerlist, then
2823 * we'll for-sure think they're down, which may have unexpected
2824 * effects in other parts of the code. It doesn't hurt much to do
2825 * the testing, and directory authorities are easy to upgrade. Let's
2826 * wait til 0.2.0. -RD */
2827 // time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
2828 routerlist_t *rl = router_get_routerlist();
2829 static char ctr = 0;
2830 int bridge_auth = authdir_mode_bridge(get_options());
2832 SMARTLIST_FOREACH_BEGIN(rl->routers, routerinfo_t *, router) {
2833 const char *id_digest = router->cache_info.identity_digest;
2834 tor_addr_t router_addr;
2835 if (router_is_me(router))
2836 continue;
2837 if (bridge_auth && router->purpose != ROUTER_PURPOSE_BRIDGE)
2838 continue; /* bridge authorities only test reachability on bridges */
2839 // if (router->cache_info.published_on > cutoff)
2840 // continue;
2841 if (try_all || (((uint8_t)id_digest[0]) % 128) == ctr) {
2842 log_debug(LD_OR,"Testing reachability of %s at %s:%u.",
2843 router->nickname, router->address, router->or_port);
2844 /* Remember when we started trying to determine reachability */
2845 if (!router->testing_since)
2846 router->testing_since = now;
2847 tor_addr_from_ipv4h(&router_addr, router->addr);
2848 connection_or_connect(&router_addr, router->or_port, id_digest);
2850 } SMARTLIST_FOREACH_END(router);
2851 if (!try_all) /* increment ctr */
2852 ctr = (ctr + 1) % 128;
2855 /** Given a fingerprint <b>fp</b> which is either set if we're looking
2856 * for a v2 status, or zeroes if we're looking for a v3 status, return
2857 * a pointer to the appropriate cached dir object, or NULL if there isn't
2858 * one available. */
2859 static cached_dir_t *
2860 lookup_cached_dir_by_fp(const char *fp)
2862 cached_dir_t *d = NULL;
2863 if (tor_digest_is_zero(fp) && cached_v3_networkstatus)
2864 d = cached_v3_networkstatus;
2865 else if (router_digest_is_me(fp) && the_v2_networkstatus)
2866 d = the_v2_networkstatus;
2867 else if (cached_v2_networkstatus)
2868 d = digestmap_get(cached_v2_networkstatus, fp);
2869 return d;
2872 /** Remove from <b>fps</b> every networkstatus key where both
2873 * a) we have a networkstatus document and
2874 * b) it is not newer than <b>cutoff</b>.
2876 * Return 1 if any items were present at all; else return 0.
2879 dirserv_remove_old_statuses(smartlist_t *fps, time_t cutoff)
2881 int found_any = 0;
2882 SMARTLIST_FOREACH(fps, char *, digest,
2884 cached_dir_t *d = lookup_cached_dir_by_fp(digest);
2885 if (!d)
2886 continue;
2887 found_any = 1;
2888 if (d->published <= cutoff) {
2889 tor_free(digest);
2890 SMARTLIST_DEL_CURRENT(fps, digest);
2894 return found_any;
2897 /** Return the cache-info for identity fingerprint <b>fp</b>, or
2898 * its extra-info document if <b>extrainfo</b> is true. Return
2899 * NULL if not found or if the descriptor is older than
2900 * <b>publish_cutoff</b>. */
2901 static signed_descriptor_t *
2902 get_signed_descriptor_by_fp(const char *fp, int extrainfo,
2903 time_t publish_cutoff)
2905 if (router_digest_is_me(fp)) {
2906 if (extrainfo)
2907 return &(router_get_my_extrainfo()->cache_info);
2908 else
2909 return &(router_get_my_routerinfo()->cache_info);
2910 } else {
2911 routerinfo_t *ri = router_get_by_digest(fp);
2912 if (ri &&
2913 ri->cache_info.published_on > publish_cutoff) {
2914 if (extrainfo)
2915 return extrainfo_get_by_descriptor_digest(
2916 ri->cache_info.extra_info_digest);
2917 else
2918 return &ri->cache_info;
2921 return NULL;
2924 /** Return true iff we have any of the docments (extrainfo or routerdesc)
2925 * specified by the fingerprints in <b>fps</b> and <b>spool_src</b>. Used to
2926 * decide whether to send a 404. */
2928 dirserv_have_any_serverdesc(smartlist_t *fps, int spool_src)
2930 time_t publish_cutoff = time(NULL)-ROUTER_MAX_AGE_TO_PUBLISH;
2931 SMARTLIST_FOREACH(fps, const char *, fp, {
2932 switch (spool_src)
2934 case DIR_SPOOL_EXTRA_BY_DIGEST:
2935 if (extrainfo_get_by_descriptor_digest(fp)) return 1;
2936 break;
2937 case DIR_SPOOL_SERVER_BY_DIGEST:
2938 if (router_get_by_descriptor_digest(fp)) return 1;
2939 break;
2940 case DIR_SPOOL_EXTRA_BY_FP:
2941 case DIR_SPOOL_SERVER_BY_FP:
2942 if (get_signed_descriptor_by_fp(fp,
2943 spool_src == DIR_SPOOL_EXTRA_BY_FP, publish_cutoff))
2944 return 1;
2945 break;
2948 return 0;
2951 /** Return an approximate estimate of the number of bytes that will
2952 * be needed to transmit the server descriptors (if is_serverdescs --
2953 * they can be either d/ or fp/ queries) or networkstatus objects (if
2954 * !is_serverdescs) listed in <b>fps</b>. If <b>compressed</b> is set,
2955 * we guess how large the data will be after compression.
2957 * The return value is an estimate; it might be larger or smaller.
2959 size_t
2960 dirserv_estimate_data_size(smartlist_t *fps, int is_serverdescs,
2961 int compressed)
2963 size_t result;
2964 tor_assert(fps);
2965 if (is_serverdescs) {
2966 int n = smartlist_len(fps);
2967 routerinfo_t *me = router_get_my_routerinfo();
2968 result = (me?me->cache_info.signed_descriptor_len:2048) * n;
2969 if (compressed)
2970 result /= 2; /* observed compressability is between 35 and 55%. */
2971 } else {
2972 result = 0;
2973 SMARTLIST_FOREACH(fps, const char *, digest, {
2974 cached_dir_t *dir = lookup_cached_dir_by_fp(digest);
2975 if (dir)
2976 result += compressed ? dir->dir_z_len : dir->dir_len;
2979 return result;
2982 /** When we're spooling data onto our outbuf, add more whenever we dip
2983 * below this threshold. */
2984 #define DIRSERV_BUFFER_MIN 16384
2986 /** Spooling helper: called when we have no more data to spool to <b>conn</b>.
2987 * Flushes any remaining data to be (un)compressed, and changes the spool
2988 * source to NONE. Returns 0 on success, negative on failure. */
2989 static int
2990 connection_dirserv_finish_spooling(dir_connection_t *conn)
2992 if (conn->zlib_state) {
2993 connection_write_to_buf_zlib("", 0, conn, 1);
2994 tor_zlib_free(conn->zlib_state);
2995 conn->zlib_state = NULL;
2997 conn->dir_spool_src = DIR_SPOOL_NONE;
2998 return 0;
3001 /** Spooling helper: called when we're sending a bunch of server descriptors,
3002 * and the outbuf has become too empty. Pulls some entries from
3003 * fingerprint_stack, and writes the corresponding servers onto outbuf. If we
3004 * run out of entries, flushes the zlib state and sets the spool source to
3005 * NONE. Returns 0 on success, negative on failure.
3007 static int
3008 connection_dirserv_add_servers_to_outbuf(dir_connection_t *conn)
3010 #ifdef TRACK_SERVED_TIME
3011 time_t now = time(NULL);
3012 #endif
3013 int by_fp = (conn->dir_spool_src == DIR_SPOOL_SERVER_BY_FP ||
3014 conn->dir_spool_src == DIR_SPOOL_EXTRA_BY_FP);
3015 int extra = (conn->dir_spool_src == DIR_SPOOL_EXTRA_BY_FP ||
3016 conn->dir_spool_src == DIR_SPOOL_EXTRA_BY_DIGEST);
3017 time_t publish_cutoff = time(NULL)-ROUTER_MAX_AGE_TO_PUBLISH;
3019 while (smartlist_len(conn->fingerprint_stack) &&
3020 buf_datalen(conn->_base.outbuf) < DIRSERV_BUFFER_MIN) {
3021 const char *body;
3022 char *fp = smartlist_pop_last(conn->fingerprint_stack);
3023 signed_descriptor_t *sd = NULL;
3024 if (by_fp) {
3025 sd = get_signed_descriptor_by_fp(fp, extra, publish_cutoff);
3026 } else {
3027 sd = extra ? extrainfo_get_by_descriptor_digest(fp)
3028 : router_get_by_descriptor_digest(fp);
3030 tor_free(fp);
3031 if (!sd)
3032 continue;
3033 if (!connection_dir_is_encrypted(conn) && !sd->send_unencrypted) {
3034 /* we did this check once before (so we could have an accurate size
3035 * estimate and maybe send a 404 if somebody asked for only bridges on a
3036 * connection), but we need to do it again in case a previously
3037 * unknown bridge descriptor has shown up between then and now. */
3038 continue;
3040 #ifdef TRACK_SERVED_TIME
3041 sd->last_served_at = now;
3042 #endif
3043 body = signed_descriptor_get_body(sd);
3044 if (conn->zlib_state) {
3045 int last = ! smartlist_len(conn->fingerprint_stack);
3046 connection_write_to_buf_zlib(body, sd->signed_descriptor_len, conn,
3047 last);
3048 if (last) {
3049 tor_zlib_free(conn->zlib_state);
3050 conn->zlib_state = NULL;
3052 } else {
3053 connection_write_to_buf(body,
3054 sd->signed_descriptor_len,
3055 TO_CONN(conn));
3059 if (!smartlist_len(conn->fingerprint_stack)) {
3060 /* We just wrote the last one; finish up. */
3061 conn->dir_spool_src = DIR_SPOOL_NONE;
3062 smartlist_free(conn->fingerprint_stack);
3063 conn->fingerprint_stack = NULL;
3065 return 0;
3068 /** Spooling helper: Called when we're sending a directory or networkstatus,
3069 * and the outbuf has become too empty. Pulls some bytes from
3070 * <b>conn</b>-\>cached_dir-\>dir_z, uncompresses them if appropriate, and
3071 * puts them on the outbuf. If we run out of entries, flushes the zlib state
3072 * and sets the spool source to NONE. Returns 0 on success, negative on
3073 * failure. */
3074 static int
3075 connection_dirserv_add_dir_bytes_to_outbuf(dir_connection_t *conn)
3077 ssize_t bytes;
3078 int64_t remaining;
3080 bytes = DIRSERV_BUFFER_MIN - buf_datalen(conn->_base.outbuf);
3081 tor_assert(bytes > 0);
3082 tor_assert(conn->cached_dir);
3083 if (bytes < 8192)
3084 bytes = 8192;
3085 remaining = conn->cached_dir->dir_z_len - conn->cached_dir_offset;
3086 if (bytes > remaining)
3087 bytes = (ssize_t) remaining;
3089 if (conn->zlib_state) {
3090 connection_write_to_buf_zlib(
3091 conn->cached_dir->dir_z + conn->cached_dir_offset,
3092 bytes, conn, bytes == remaining);
3093 } else {
3094 connection_write_to_buf(conn->cached_dir->dir_z + conn->cached_dir_offset,
3095 bytes, TO_CONN(conn));
3097 conn->cached_dir_offset += bytes;
3098 if (conn->cached_dir_offset == (int)conn->cached_dir->dir_z_len) {
3099 /* We just wrote the last one; finish up. */
3100 connection_dirserv_finish_spooling(conn);
3101 cached_dir_decref(conn->cached_dir);
3102 conn->cached_dir = NULL;
3104 return 0;
3107 /** Spooling helper: Called when we're spooling networkstatus objects on
3108 * <b>conn</b>, and the outbuf has become too empty. If the current
3109 * networkstatus object (in <b>conn</b>-\>cached_dir) has more data, pull data
3110 * from there. Otherwise, pop the next fingerprint from fingerprint_stack,
3111 * and start spooling the next networkstatus. (A digest of all 0 bytes is
3112 * treated as a request for the current consensus.) If we run out of entries,
3113 * flushes the zlib state and sets the spool source to NONE. Returns 0 on
3114 * success, negative on failure. */
3115 static int
3116 connection_dirserv_add_networkstatus_bytes_to_outbuf(dir_connection_t *conn)
3119 while (buf_datalen(conn->_base.outbuf) < DIRSERV_BUFFER_MIN) {
3120 if (conn->cached_dir) {
3121 int uncompressing = (conn->zlib_state != NULL);
3122 int r = connection_dirserv_add_dir_bytes_to_outbuf(conn);
3123 if (conn->dir_spool_src == DIR_SPOOL_NONE) {
3124 /* add_dir_bytes thinks we're done with the cached_dir. But we
3125 * may have more cached_dirs! */
3126 conn->dir_spool_src = DIR_SPOOL_NETWORKSTATUS;
3127 /* This bit is tricky. If we were uncompressing the last
3128 * networkstatus, we may need to make a new zlib object to
3129 * uncompress the next one. */
3130 if (uncompressing && ! conn->zlib_state &&
3131 conn->fingerprint_stack &&
3132 smartlist_len(conn->fingerprint_stack)) {
3133 conn->zlib_state = tor_zlib_new(0, ZLIB_METHOD);
3136 if (r) return r;
3137 } else if (conn->fingerprint_stack &&
3138 smartlist_len(conn->fingerprint_stack)) {
3139 /* Add another networkstatus; start serving it. */
3140 char *fp = smartlist_pop_last(conn->fingerprint_stack);
3141 cached_dir_t *d = lookup_cached_dir_by_fp(fp);
3142 tor_free(fp);
3143 if (d) {
3144 ++d->refcnt;
3145 conn->cached_dir = d;
3146 conn->cached_dir_offset = 0;
3148 } else {
3149 connection_dirserv_finish_spooling(conn);
3150 if (conn->fingerprint_stack)
3151 smartlist_free(conn->fingerprint_stack);
3152 conn->fingerprint_stack = NULL;
3153 return 0;
3156 return 0;
3159 /** Called whenever we have flushed some directory data in state
3160 * SERVER_WRITING. */
3162 connection_dirserv_flushed_some(dir_connection_t *conn)
3164 tor_assert(conn->_base.state == DIR_CONN_STATE_SERVER_WRITING);
3166 if (buf_datalen(conn->_base.outbuf) >= DIRSERV_BUFFER_MIN)
3167 return 0;
3169 switch (conn->dir_spool_src) {
3170 case DIR_SPOOL_EXTRA_BY_DIGEST:
3171 case DIR_SPOOL_EXTRA_BY_FP:
3172 case DIR_SPOOL_SERVER_BY_DIGEST:
3173 case DIR_SPOOL_SERVER_BY_FP:
3174 return connection_dirserv_add_servers_to_outbuf(conn);
3175 case DIR_SPOOL_CACHED_DIR:
3176 return connection_dirserv_add_dir_bytes_to_outbuf(conn);
3177 case DIR_SPOOL_NETWORKSTATUS:
3178 return connection_dirserv_add_networkstatus_bytes_to_outbuf(conn);
3179 case DIR_SPOOL_NONE:
3180 default:
3181 return 0;
3185 /** Release all storage used by the directory server. */
3186 void
3187 dirserv_free_all(void)
3189 dirserv_free_fingerprint_list();
3191 cached_dir_decref(the_directory);
3192 clear_cached_dir(&the_runningrouters);
3193 cached_dir_decref(the_v2_networkstatus);
3194 cached_dir_decref(cached_directory);
3195 clear_cached_dir(&cached_runningrouters);
3196 if (cached_v2_networkstatus) {
3197 digestmap_free(cached_v2_networkstatus, _free_cached_dir);
3198 cached_v2_networkstatus = NULL;
3200 cached_dir_decref(cached_v3_networkstatus);