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