bugfix on r9568: we were throwing around an uninitialized
[tor.git] / src / or / dirserv.c
blobd2b6661935488cf5050da94645bbab4b8d97c575
1 /* Copyright 2001-2004 Roger Dingledine.
2 * Copyright 2004-2007 Roger Dingledine, Nick Mathewson. */
3 /* See LICENSE for licensing information */
4 /* $Id$ */
5 const char dirserv_c_id[] =
6 "$Id$";
8 #include "or.h"
10 /**
11 * \file dirserv.c
12 * \brief Directory server core implementation. Manages directory
13 * contents and generates directories.
14 **/
16 /** How far in the future do we allow a router to get? (seconds) */
17 #define ROUTER_ALLOW_SKEW (60*60*12)
18 /** How many seconds do we wait before regenerating the directory? */
19 #define DIR_REGEN_SLACK_TIME 30
20 /** If we're a cache, keep this many networkstatuses around from non-trusted
21 * directory authorities. */
22 #define MAX_UNTRUSTED_NETWORKSTATUSES 16
24 /** Do we need to regenerate the directory when someone asks for it? */
25 static int the_directory_is_dirty = 1;
26 static int runningrouters_is_dirty = 1;
27 static int the_v2_networkstatus_is_dirty = 1;
29 static void directory_remove_invalid(void);
30 static cached_dir_t *dirserv_regenerate_directory(void);
31 static char *format_versions_list(config_line_t *ln);
32 /* Should be static; exposed for testing */
33 struct authdir_config_t;
34 int add_fingerprint_to_dir(const char *nickname, const char *fp,
35 struct authdir_config_t *list);
36 static uint32_t dirserv_router_get_status(const routerinfo_t *router,
37 const char **msg);
38 static uint32_t
39 dirserv_get_status_impl(const char *fp, const char *nickname,
40 const char *address,
41 uint32_t addr, uint16_t or_port,
42 const char *platform, const char *contact,
43 const char **msg, int should_log);
44 static int dirserv_thinks_router_is_reachable(routerinfo_t *router,
45 time_t now);
46 static void clear_cached_dir(cached_dir_t *d);
48 /************** Fingerprint handling code ************/
50 #define FP_NAMED 1 /**< Listed in fingerprint file. */
51 #define FP_INVALID 2 /**< Believed invalid. */
52 #define FP_REJECT 4 /**< We will not publish this router. */
53 #define FP_BADEXIT 8 /**< We'll tell clients not to use this as an exit. */
55 /** Encapsulate a nickname and an FP_* status; target of status_by_digest
56 * map. */
57 typedef struct router_status_t {
58 char nickname[MAX_NICKNAME_LEN+1];
59 uint32_t status;
60 } router_status_t;
62 /** List of nickname-\>identity fingerprint mappings for all the routers
63 * that we name. Used to prevent router impersonation. */
64 typedef struct authdir_config_t {
65 strmap_t *fp_by_name; /* Map from lc nickname to fingerprint */
66 digestmap_t *status_by_digest; /* Map from digest to router_status_t. */
67 } authdir_config_t;
69 /** Should be static; exposed for testing */
70 authdir_config_t *fingerprint_list = NULL;
72 /** Allocate and return a new, empty, authdir_config_t. */
73 static authdir_config_t *
74 authdir_config_new(void)
76 authdir_config_t *list = tor_malloc_zero(sizeof(authdir_config_t));
77 list->fp_by_name = strmap_new();
78 list->status_by_digest = digestmap_new();
79 return list;
82 /** Add the fingerprint <b>fp</b> for the nickname <b>nickname</b> to
83 * the smartlist of fingerprint_entry_t's <b>list</b>. Return 0 if it's
84 * new, or 1 if we replaced the old value.
86 int /* Should be static; exposed for testing */
87 add_fingerprint_to_dir(const char *nickname, const char *fp,
88 authdir_config_t *list)
90 char *fingerprint;
91 char d[DIGEST_LEN];
92 router_status_t *status;
93 tor_assert(nickname);
94 tor_assert(fp);
95 tor_assert(list);
97 fingerprint = tor_strdup(fp);
98 tor_strstrip(fingerprint, " ");
99 if (base16_decode(d, DIGEST_LEN, fingerprint, strlen(fingerprint))) {
100 log_warn(LD_DIRSERV, "Couldn't decode fingerprint \"%s\"",
101 escaped(fp));
102 tor_free(fingerprint);
103 return 0;
106 if (!strcasecmp(nickname, UNNAMED_ROUTER_NICKNAME)) {
107 log_warn(LD_DIRSERV, "Tried to add a mapping for reserved nickname %s",
108 UNNAMED_ROUTER_NICKNAME);
109 tor_free(fingerprint);
110 return 0;
113 status = digestmap_get(list->status_by_digest, d);
114 if (!status) {
115 status = tor_malloc_zero(sizeof(router_status_t));
116 digestmap_set(list->status_by_digest, d, status);
119 if (nickname[0] != '!') {
120 char *old_fp = strmap_get_lc(list->fp_by_name, nickname);
121 if (old_fp && !strcasecmp(fingerprint, old_fp)) {
122 tor_free(fingerprint);
123 } else {
124 tor_free(old_fp);
125 strmap_set_lc(list->fp_by_name, nickname, fingerprint);
127 status->status |= FP_NAMED;
128 strlcpy(status->nickname, nickname, sizeof(status->nickname));
129 } else {
130 tor_free(fingerprint);
131 if (!strcasecmp(nickname, "!reject")) {
132 status->status |= FP_REJECT;
133 } else if (!strcasecmp(nickname, "!invalid")) {
134 status->status |= FP_INVALID;
135 } else if (!strcasecmp(nickname, "!badexit")) {
136 status->status |= FP_BADEXIT;
139 return 0;
142 /** Add the nickname and fingerprint for this OR to the
143 * global list of recognized identity key fingerprints. */
145 dirserv_add_own_fingerprint(const char *nickname, crypto_pk_env_t *pk)
147 char fp[FINGERPRINT_LEN+1];
148 if (crypto_pk_get_fingerprint(pk, fp, 0)<0) {
149 log_err(LD_BUG, "Error computing fingerprint");
150 return -1;
152 if (!fingerprint_list)
153 fingerprint_list = authdir_config_new();
154 add_fingerprint_to_dir(nickname, fp, fingerprint_list);
155 return 0;
158 /** Load the nickname-\>fingerprint mappings stored in the approved-routers
159 * file. The file format is line-based, with each non-blank holding one
160 * nickname, some space, and a fingerprint for that nickname. On success,
161 * replace the current fingerprint list with the new list and return 0. On
162 * failure, leave the current fingerprint list untouched, and
163 * return -1. */
165 dirserv_load_fingerprint_file(void)
167 char fname[512];
168 char *cf;
169 char *nickname, *fingerprint;
170 authdir_config_t *fingerprint_list_new;
171 int result;
172 config_line_t *front=NULL, *list;
173 or_options_t *options = get_options();
175 tor_snprintf(fname, sizeof(fname),
176 "%s/approved-routers", options->DataDirectory);
177 log_info(LD_GENERAL,
178 "Reloading approved fingerprints from \"%s\"...", fname);
180 cf = read_file_to_str(fname, 0, NULL);
181 if (!cf) {
182 if (options->NamingAuthoritativeDir) {
183 log_warn(LD_FS, "Cannot open fingerprint file '%s'. Failing.", fname);
184 return -1;
185 } else {
186 log_info(LD_FS, "Cannot open fingerprint file '%s'. Returning.", fname);
187 return 0;
190 result = config_get_lines(cf, &front);
191 tor_free(cf);
192 if (result < 0) {
193 log_warn(LD_CONFIG, "Error reading from fingerprint file");
194 return -1;
197 fingerprint_list_new = authdir_config_new();
199 for (list=front; list; list=list->next) {
200 nickname = list->key; fingerprint = list->value;
201 if (strlen(nickname) > MAX_NICKNAME_LEN) {
202 log_notice(LD_CONFIG,
203 "Nickname '%s' too long in fingerprint file. Skipping.",
204 nickname);
205 continue;
207 if (!is_legal_nickname(nickname) &&
208 strcasecmp(nickname, "!reject") &&
209 strcasecmp(nickname, "!invalid") &&
210 strcasecmp(nickname, "!badexit")) {
211 log_notice(LD_CONFIG,
212 "Invalid nickname '%s' in fingerprint file. Skipping.",
213 nickname);
214 continue;
216 if (strlen(fingerprint) != FINGERPRINT_LEN ||
217 !crypto_pk_check_fingerprint_syntax(fingerprint)) {
218 log_notice(LD_CONFIG,
219 "Invalid fingerprint (nickname '%s', "
220 "fingerprint %s). Skipping.",
221 nickname, fingerprint);
222 continue;
224 if (0==strcasecmp(nickname, DEFAULT_CLIENT_NICKNAME)) {
225 /* If you approved an OR called "client", then clients who use
226 * the default nickname could all be rejected. That's no good. */
227 log_notice(LD_CONFIG,
228 "Authorizing a nickname '%s' would break "
229 "many clients; skipping.",
230 DEFAULT_CLIENT_NICKNAME);
231 continue;
233 if (0==strcasecmp(nickname, DEFAULT_CLIENT_NICKNAME)) {
234 /* If you approved an OR called "client", then clients who use
235 * the default nickname could all be rejected. That's no good. */
236 log_notice(LD_CONFIG,
237 "Authorizing a nickname '%s' would break "
238 "many clients; skipping.",
239 DEFAULT_CLIENT_NICKNAME);
240 continue;
242 if (0==strcasecmp(nickname, UNNAMED_ROUTER_NICKNAME)) {
243 /* If you approved an OR called "unnamed", then clients will be
244 * confused. */
245 log_notice(LD_CONFIG,
246 "Authorizing a nickname '%s' is not allowed; skipping.",
247 UNNAMED_ROUTER_NICKNAME);
248 continue;
250 if (add_fingerprint_to_dir(nickname, fingerprint, fingerprint_list_new)
251 != 0)
252 log_notice(LD_CONFIG, "Duplicate nickname '%s'.", nickname);
255 config_free_lines(front);
256 dirserv_free_fingerprint_list();
257 fingerprint_list = fingerprint_list_new;
258 /* Delete any routers whose fingerprints we no longer recognize */
259 directory_remove_invalid();
260 return 0;
263 /** Check whether <b>router</b> has a nickname/identity key combination that
264 * we recognize from the fingerprint list, or an IP we automatically act on
265 * according to our configuration. Return the appropriate router status.
267 * If the status is 'FP_REJECT' and <b>msg</b> is provided, set
268 * *<b>msg</b> to an explanation of why. */
269 static uint32_t
270 dirserv_router_get_status(const routerinfo_t *router, const char **msg)
272 char d[DIGEST_LEN];
274 if (crypto_pk_get_digest(router->identity_pkey, d)) {
275 log_warn(LD_BUG,"Error computing fingerprint");
276 if (msg)
277 *msg = "Bug: Error computing fingerprint";
278 return FP_REJECT;
281 return dirserv_get_status_impl(d, router->nickname,
282 router->address,
283 router->addr, router->or_port,
284 router->platform, router->contact_info,
285 msg, 1);
288 /** Return true if there is no point in downloading the router described by
289 * <b>rs</b> because this directory would reject it. */
291 dirserv_would_reject_router(routerstatus_t *rs)
293 uint32_t res;
295 res = dirserv_get_status_impl(rs->identity_digest, rs->nickname,
296 "", /* address is only used in logs */
297 rs->addr, rs->or_port,
298 NULL, NULL,
299 NULL, 0);
301 return (res & FP_REJECT) != 0;
304 /** Helper: As dirserv_get_router_status, but takes the router fingerprint
305 * (hex, no spaces), nickname, address (used for logging only), IP address, OR
306 * port, platform (logging only) and contact info (logging only) as arguments.
308 * If should_log is false, do not log messages. (There's not much point in
309 * logging that we're rejecting servers we'll not download.)
311 static uint32_t
312 dirserv_get_status_impl(const char *id_digest, const char *nickname,
313 const char *address,
314 uint32_t addr, uint16_t or_port,
315 const char *platform, const char *contact,
316 const char **msg, int should_log)
318 char fp[HEX_DIGEST_LEN+1];
319 int reject_unlisted = get_options()->AuthDirRejectUnlisted;
320 uint32_t result = 0;
321 router_status_t *status_by_digest;
322 char *fp_by_name;
323 if (!fingerprint_list)
324 fingerprint_list = authdir_config_new();
326 base16_encode(fp, sizeof(fp), id_digest, DIGEST_LEN);
328 if (should_log)
329 log_debug(LD_DIRSERV, "%d fingerprints, %d digests known.",
330 strmap_size(fingerprint_list->fp_by_name),
331 digestmap_size(fingerprint_list->status_by_digest));
333 if ((fp_by_name =
334 strmap_get_lc(fingerprint_list->fp_by_name, nickname))) {
335 if (!strcasecmp(fp, fp_by_name)) {
336 result |= FP_NAMED;
337 if (should_log)
338 log_debug(LD_DIRSERV,"Good fingerprint for '%s'",nickname);
339 } else {
340 if (should_log) {
341 char *esc_contact = esc_for_log(contact);
342 log_warn(LD_DIRSERV,
343 "Mismatched fingerprint for '%s': expected '%s' got '%s'. "
344 "ContactInfo '%s', platform '%s'.)",
345 nickname, fp_by_name, fp,
346 esc_contact,
347 platform ? escaped(platform) : "");
348 tor_free(esc_contact);
350 if (msg)
351 *msg = "Rejected: There is already a named server with this nickname "
352 "and a different fingerprint.";
353 return FP_REJECT; /* Wrong fingerprint. */
356 status_by_digest = digestmap_get(fingerprint_list->status_by_digest,
357 id_digest);
358 if (status_by_digest)
359 result |= (status_by_digest->status & ~FP_NAMED);
361 if (result & FP_REJECT) {
362 if (msg)
363 *msg = "Fingerprint is marked rejected";
364 return FP_REJECT;
365 } else if (result & FP_INVALID) {
366 if (msg)
367 *msg = "Fingerprint is marked invalid";
370 if (authdir_policy_badexit_address(addr, or_port)) {
371 if (should_log)
372 log_info(LD_DIRSERV, "Marking '%s' as bad exit because of address '%s'",
373 nickname, address);
374 result |= FP_BADEXIT;
377 if (!(result & FP_NAMED)) {
378 if (!authdir_policy_permits_address(addr, or_port)) {
379 if (should_log)
380 log_info(LD_DIRSERV, "Rejecting '%s' because of address '%s'",
381 nickname, address);
382 if (msg)
383 *msg = "Authdir is rejecting routers in this range.";
384 return FP_REJECT;
386 if (!authdir_policy_valid_address(addr, or_port)) {
387 if (should_log)
388 log_info(LD_DIRSERV, "Not marking '%s' valid because of address '%s'",
389 nickname, address);
390 result |= FP_INVALID;
392 if (reject_unlisted) {
393 if (msg)
394 *msg = "Authdir rejects unknown routers.";
395 return FP_REJECT;
397 /* 0.1.0.2-rc was the first version that did enough self-testing that
398 * we're willing to take its word about whether it's running. */
399 if (platform && !tor_version_as_new_as(platform,"0.1.0.2-rc"))
400 result |= FP_INVALID;
403 return result;
406 /** If we are an authoritative dirserver, and the list of approved
407 * servers contains one whose identity key digest is <b>digest</b>,
408 * return that router's nickname. Otherwise return NULL. */
409 const char *
410 dirserv_get_nickname_by_digest(const char *digest)
412 router_status_t *status;
413 if (!fingerprint_list)
414 return NULL;
415 tor_assert(digest);
417 status = digestmap_get(fingerprint_list->status_by_digest, digest);
418 return status ? status->nickname : NULL;
421 /** Clear the current fingerprint list. */
422 void
423 dirserv_free_fingerprint_list(void)
425 if (!fingerprint_list)
426 return;
428 strmap_free(fingerprint_list->fp_by_name, _tor_free);
429 digestmap_free(fingerprint_list->status_by_digest, _tor_free);
430 tor_free(fingerprint_list);
434 * Descriptor list
437 /** Return -1 if <b>ri</b> has a private or otherwise bad address,
438 * unless we're configured to not care. Return 0 if all ok. */
439 static int
440 dirserv_router_has_valid_address(routerinfo_t *ri)
442 struct in_addr iaddr;
443 if (get_options()->DirAllowPrivateAddresses)
444 return 0; /* whatever it is, we're fine with it */
445 if (!tor_inet_aton(ri->address, &iaddr)) {
446 log_info(LD_DIRSERV,"Router '%s' published non-IP address '%s'. Refusing.",
447 ri->nickname, ri->address);
448 return -1;
450 if (is_internal_IP(ntohl(iaddr.s_addr), 0)) {
451 log_info(LD_DIRSERV,
452 "Router '%s' published internal IP address '%s'. Refusing.",
453 ri->nickname, ri->address);
454 return -1; /* it's a private IP, we should reject it */
456 return 0;
459 /** Check whether we, as a directory server, want to accept <b>ri</b>. If so,
460 * set its is_valid,named,running fields and return 0. Otherwise, return -1.
462 * If the router is rejected, set *<b>msg</b> to an explanation of why.
464 * If <b>complain</b> then explain at log-level 'notice' why we refused
465 * a descriptor; else explain at log-level 'info'.
468 authdir_wants_to_reject_router(routerinfo_t *ri, const char **msg,
469 int complain)
471 /* Okay. Now check whether the fingerprint is recognized. */
472 uint32_t status = dirserv_router_get_status(ri, msg);
473 time_t now;
474 int severity = complain ? LOG_NOTICE : LOG_INFO;
475 tor_assert(msg);
476 if (status & FP_REJECT)
477 return -1; /* msg is already set. */
479 /* Is there too much clock skew? */
480 now = time(NULL);
481 if (ri->cache_info.published_on > now+ROUTER_ALLOW_SKEW) {
482 log_fn(severity, LD_DIRSERV, "Publication time for nickname '%s' is too "
483 "far (%d minutes) in the future; possible clock skew. Not adding "
484 "(%s)",
485 ri->nickname, (int)((ri->cache_info.published_on-now)/60),
486 esc_router_info(ri));
487 *msg = "Rejected: Your clock is set too far in the future, or your "
488 "timezone is not correct.";
489 return -1;
491 if (ri->cache_info.published_on < now-ROUTER_MAX_AGE_TO_PUBLISH) {
492 log_fn(severity, LD_DIRSERV,
493 "Publication time for router with nickname '%s' is too far "
494 "(%d minutes) in the past. Not adding (%s)",
495 ri->nickname, (int)((now-ri->cache_info.published_on)/60),
496 esc_router_info(ri));
497 *msg = "Rejected: Server is expired, or your clock is too far in the past,"
498 " or your timezone is not correct.";
499 return -1;
501 if (dirserv_router_has_valid_address(ri) < 0) {
502 log_fn(severity, LD_DIRSERV,
503 "Router with nickname '%s' has invalid address '%s'. "
504 "Not adding (%s).",
505 ri->nickname, ri->address,
506 esc_router_info(ri));
507 *msg = "Rejected: Address is not an IP, or IP is a private address.";
508 return -1;
510 /* Okay, looks like we're willing to accept this one. */
511 ri->is_named = (status & FP_NAMED) ? 1 : 0;
512 ri->is_valid = (status & FP_INVALID) ? 0 : 1;
513 ri->is_bad_exit = (status & FP_BADEXIT) ? 1 : 0;
515 return 0;
518 /** Parse the server descriptor at <b>desc</b> and maybe insert it into
519 * the list of server descriptors. Set *<b>msg</b> to a message that
520 * should be passed back to the origin of this descriptor.
522 * Return 2 if descriptor is well-formed and accepted;
523 * 1 if well-formed and accepted but origin should hear *msg;
524 * 0 if well-formed but redundant with one we already have;
525 * -1 if it looks vaguely like a router descriptor but rejected;
526 * -2 if we can't find a router descriptor in <b>desc</b>.
529 dirserv_add_descriptor(const char *desc, const char **msg)
531 int r;
532 routerinfo_t *ri = NULL, *ri_old = NULL;
533 tor_assert(msg);
534 *msg = NULL;
536 /* Check: is the descriptor syntactically valid? */
537 ri = router_parse_entry_from_string(desc, NULL, 1);
538 if (!ri) {
539 log_warn(LD_DIRSERV, "Couldn't parse uploaded server descriptor");
540 *msg = "Rejected: Couldn't parse server descriptor.";
541 return -2;
543 /* Check whether this descriptor is semantically identical to the last one
544 * from this server. (We do this here and not in router_add_to_routerlist
545 * because we want to be able to accept the newest router descriptor that
546 * another authority has, so we all converge on the same one.) */
547 ri_old = router_get_by_digest(ri->cache_info.identity_digest);
548 if (ri_old && ri_old->cache_info.published_on < ri->cache_info.published_on
549 && router_differences_are_cosmetic(ri_old, ri)
550 && !router_is_me(ri)) {
551 log_info(LD_DIRSERV,
552 "Not replacing descriptor from '%s'; differences are cosmetic.",
553 ri->nickname);
554 *msg = "Not replacing router descriptor; no information has changed since "
555 "the last one with this identity.";
556 routerinfo_free(ri);
557 control_event_or_authdir_new_descriptor("DROPPED", desc, *msg);
558 return 0;
560 if ((r = router_add_to_routerlist(ri, msg, 0, 0))<0) {
561 if (r < -1) /* unless the routerinfo was fine, just out-of-date */
562 control_event_or_authdir_new_descriptor("REJECTED", desc, *msg);
563 return r == -1 ? 0 : -1;
564 } else {
565 smartlist_t *changed;
566 control_event_or_authdir_new_descriptor("ACCEPTED", desc, *msg);
568 changed = smartlist_create();
569 smartlist_add(changed, ri);
570 control_event_descriptors_changed(changed);
571 smartlist_free(changed);
572 if (!*msg) {
573 *msg = ri->is_valid ? "Descriptor for valid server accepted" :
574 "Descriptor for invalid server accepted";
576 return r == 0 ? 2 : 1;
580 /** Helper: return true iff the boolean values of <b>a</b> and <b>b</b> are
581 * different. */
582 static INLINE int
583 bool_neq(int a, int b)
585 return (a) ? !b : b;
588 /** Remove all descriptors whose nicknames or fingerprints no longer
589 * are allowed by our fingerprint list. (Descriptors that used to be
590 * good can become bad when we reload the fingerprint list.)
592 static void
593 directory_remove_invalid(void)
595 int i;
596 int changed = 0;
597 routerlist_t *rl = router_get_routerlist();
599 for (i = 0; i < smartlist_len(rl->routers); ++i) {
600 const char *msg;
601 routerinfo_t *ent = smartlist_get(rl->routers, i);
602 uint32_t r = dirserv_router_get_status(ent, &msg);
603 if (r & FP_REJECT) {
604 log_info(LD_DIRSERV, "Router '%s' is now rejected: %s",
605 ent->nickname, msg?msg:"");
606 routerlist_remove(rl, ent, i--, 0);
607 changed = 1;
609 if (bool_neq((r & FP_NAMED), ent->is_named)) {
610 log_info(LD_DIRSERV,
611 "Router '%s' is now %snamed.", ent->nickname,
612 (r&FP_NAMED)?"":"un");
613 ent->is_named = (r&FP_NAMED)?1:0;
614 changed = 1;
616 if (bool_neq((r & FP_INVALID), !ent->is_valid)) {
617 log_info(LD_DIRSERV, "Router '%s' is now %svalid.", ent->nickname,
618 (r&FP_INVALID) ? "in" : "");
619 ent->is_valid = (r&FP_INVALID)?0:1;
620 changed = 1;
622 if (bool_neq((r & FP_BADEXIT), ent->is_bad_exit)) {
623 log_info(LD_DIRSERV, "Router '%s' is now a %s exit", ent->nickname,
624 (r & FP_BADEXIT) ? "bad" : "good");
625 ent->is_bad_exit = (r&FP_BADEXIT) ? 1: 0;
626 changed = 1;
629 if (changed)
630 directory_set_dirty();
633 /** Write a list of unregistered descriptors into a newly allocated
634 * string and return it. Used by dirserv operators to keep track of
635 * fast nodes that haven't registered.
638 getinfo_helper_dirserv_unregistered(control_connection_t *control_conn,
639 const char *question, char **answer_out)
641 smartlist_t *answerlist;
642 char buf[1024];
643 char *answer;
644 int min_bw = atoi(question);
645 routerlist_t *rl = router_get_routerlist();
647 (void) control_conn;
649 if (strcmpstart(question, "unregistered-servers-"))
650 return 0;
651 question += strlen("unregistered-servers-");
653 answerlist = smartlist_create();
654 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ent, {
655 uint32_t r = dirserv_router_get_status(ent, NULL);
656 if (router_get_advertised_bandwidth(ent) >= (size_t)min_bw &&
657 !(r & FP_NAMED)) {
658 /* then log this one */
659 tor_snprintf(buf, sizeof(buf),
660 "%s: BW %d on '%s'.",
661 ent->nickname, router_get_advertised_bandwidth(ent),
662 ent->platform ? ent->platform : "");
663 smartlist_add(answerlist, tor_strdup(buf));
666 answer = smartlist_join_strings(answerlist, "\r\n", 0, NULL);
667 SMARTLIST_FOREACH(answerlist, char *, cp, tor_free(cp));
668 smartlist_free(answerlist);
669 *answer_out = answer;
670 return 0;
673 /** Mark the directory as <b>dirty</b> -- when we're next asked for a
674 * directory, we will rebuild it instead of reusing the most recently
675 * generated one.
677 void
678 directory_set_dirty(void)
680 time_t now = time(NULL);
682 if (!the_directory_is_dirty)
683 the_directory_is_dirty = now;
684 if (!runningrouters_is_dirty)
685 runningrouters_is_dirty = now;
686 if (!the_v2_networkstatus_is_dirty)
687 the_v2_networkstatus_is_dirty = now;
691 * Allocate and return a description of the status of the server <b>desc</b>,
692 * for use in a router-status line. The server is listed
693 * as running iff <b>is_live</b> is true.
695 static char *
696 list_single_server_status(routerinfo_t *desc, int is_live)
698 char buf[MAX_NICKNAME_LEN+HEX_DIGEST_LEN+4]; /* !nickname=$hexdigest\0 */
699 char *cp;
701 tor_assert(desc);
703 cp = buf;
704 if (!is_live) {
705 *cp++ = '!';
707 if (desc->is_valid) {
708 strlcpy(cp, desc->nickname, sizeof(buf)-(cp-buf));
709 cp += strlen(cp);
710 *cp++ = '=';
712 *cp++ = '$';
713 base16_encode(cp, HEX_DIGEST_LEN+1, desc->cache_info.identity_digest,
714 DIGEST_LEN);
715 return tor_strdup(buf);
718 /** Each server needs to have passed a reachability test no more
719 * than this number of seconds ago, or he is listed as down in
720 * the directory. */
721 #define REACHABLE_TIMEOUT (45*60)
723 /** Treat a router as alive if
724 * - It's me, and I'm not hibernating.
725 * or - We've found it reachable recently. */
726 static int
727 dirserv_thinks_router_is_reachable(routerinfo_t *router, time_t now)
729 if (router_is_me(router) && !we_are_hibernating())
730 return 1;
731 return get_options()->AssumeReachable ||
732 now < router->last_reachable + REACHABLE_TIMEOUT;
735 /** Return 1 if we're confident that there's a problem with
736 * <b>router</b>'s reachability and its operator should be notified.
739 dirserv_thinks_router_is_blatantly_unreachable(routerinfo_t *router,
740 time_t now)
742 if (router->is_hibernating)
743 return 0;
744 if (now >= router->last_reachable + 5*REACHABLE_TIMEOUT &&
745 router->testing_since &&
746 now >= router->testing_since + 5*REACHABLE_TIMEOUT)
747 return 1;
748 return 0;
751 /** Based on the routerinfo_ts in <b>routers</b>, allocate the
752 * contents of a router-status line, and store it in
753 * *<b>router_status_out</b>. Return 0 on success, -1 on failure.
755 * If for_controller is true, include the routers with very old descriptors.
756 * If for_controller is &gt;1, use the verbose nickname format.
759 list_server_status(smartlist_t *routers, char **router_status_out,
760 int for_controller)
762 /* List of entries in a router-status style: An optional !, then an optional
763 * equals-suffixed nickname, then a dollar-prefixed hexdigest. */
764 smartlist_t *rs_entries;
765 time_t now = time(NULL);
766 time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
767 int authdir_mode = get_options()->AuthoritativeDir;
768 tor_assert(router_status_out);
770 rs_entries = smartlist_create();
772 SMARTLIST_FOREACH(routers, routerinfo_t *, ri,
774 if (authdir_mode) {
775 /* Update router status in routerinfo_t. */
776 ri->is_running = dirserv_thinks_router_is_reachable(ri, now);
778 if (for_controller == 1 || ri->cache_info.published_on >= cutoff)
779 smartlist_add(rs_entries, list_single_server_status(ri, ri->is_running));
780 else if (for_controller > 2) {
781 char name_buf[MAX_VERBOSE_NICKNAME_LEN+2];
782 char *cp = name_buf;
783 if (!ri->is_running)
784 *cp++ = '!';
785 router_get_verbose_nickname(cp, ri);
786 smartlist_add(rs_entries, tor_strdup(name_buf));
790 *router_status_out = smartlist_join_strings(rs_entries, " ", 0, NULL);
792 SMARTLIST_FOREACH(rs_entries, char *, cp, tor_free(cp));
793 smartlist_free(rs_entries);
795 return 0;
798 /** Given a (possibly empty) list of config_line_t, each line of which contains
799 * a list of comma-separated version numbers surrounded by optional space,
800 * allocate and return a new string containing the version numbers, in order,
801 * separated by commas. Used to generate Recommended(Client|Server)?Versions
803 static char *
804 format_versions_list(config_line_t *ln)
806 smartlist_t *versions;
807 char *result;
808 versions = smartlist_create();
809 for ( ; ln; ln = ln->next) {
810 smartlist_split_string(versions, ln->value, ",",
811 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
813 sort_version_list(versions, 1);
814 result = smartlist_join_strings(versions,",",0,NULL);
815 SMARTLIST_FOREACH(versions,char *,s,tor_free(s));
816 smartlist_free(versions);
817 return result;
820 /** Return 1 if <b>ri</b>'s descriptor is worth including in the v1
821 * directory, else return 0.
823 static int
824 live_enough_for_v1_dir(routerinfo_t *ri, time_t now)
826 time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
827 if (ri->cache_info.published_on < cutoff)
828 return 0;
829 if (!ri->is_running || !ri->is_valid)
830 return 0;
831 return 1;
834 /** Generate a new v1 directory and write it into a newly allocated string.
835 * Point *<b>dir_out</b> to the allocated string. Sign the
836 * directory with <b>private_key</b>. Return 0 on success, -1 on
837 * failure. If <b>complete</b> is set, give us all the descriptors;
838 * otherwise leave out non-running and non-valid ones.
841 dirserv_dump_directory_to_string(char **dir_out,
842 crypto_pk_env_t *private_key, int complete)
844 char *cp;
845 char *router_status;
846 char *identity_pkey; /* Identity key, DER64-encoded. */
847 char *recommended_versions;
848 char digest[DIGEST_LEN];
849 char published[ISO_TIME_LEN+1];
850 char *buf = NULL;
851 size_t buf_len;
852 size_t identity_pkey_len;
853 routerlist_t *rl = router_get_routerlist();
854 time_t now = time(NULL);
856 tor_assert(dir_out);
857 *dir_out = NULL;
859 if (list_server_status(rl->routers, &router_status, 0))
860 return -1;
862 if (crypto_pk_write_public_key_to_string(private_key,&identity_pkey,
863 &identity_pkey_len)<0) {
864 log_warn(LD_BUG,"write identity_pkey to string failed!");
865 return -1;
868 recommended_versions =
869 format_versions_list(get_options()->RecommendedVersions);
871 format_iso_time(published, now);
873 buf_len = 2048+strlen(recommended_versions)+
874 strlen(router_status);
875 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri,
876 if (complete || live_enough_for_v1_dir(ri, now))
877 buf_len += ri->cache_info.signed_descriptor_len+1);
878 buf = tor_malloc(buf_len);
879 /* We'll be comparing against buf_len throughout the rest of the
880 function, though strictly speaking we shouldn't be able to exceed
881 it. This is C, after all, so we may as well check for buffer
882 overruns.*/
884 tor_snprintf(buf, buf_len,
885 "signed-directory\n"
886 "published %s\n"
887 "recommended-software %s\n"
888 "router-status %s\n"
889 "dir-signing-key\n%s\n",
890 published, recommended_versions, router_status,
891 identity_pkey);
893 tor_free(recommended_versions);
894 tor_free(router_status);
895 tor_free(identity_pkey);
897 cp = buf + strlen(buf);
898 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri,
900 size_t len = ri->cache_info.signed_descriptor_len;
901 const char *body;
902 if (!complete && !live_enough_for_v1_dir(ri, now))
903 continue;
904 if (cp+len+1 >= buf+buf_len)
905 goto truncated;
906 body = signed_descriptor_get_body(&ri->cache_info);
907 memcpy(cp, body, len);
908 cp += len;
909 *cp++ = '\n'; /* add an extra newline in case somebody was depending on
910 * it. */
912 *cp = '\0';
914 /* These multiple strlcat calls are inefficient, but dwarfed by the RSA
915 signature. */
916 if (strlcat(buf, "directory-signature ", buf_len) >= buf_len)
917 goto truncated;
918 if (strlcat(buf, get_options()->Nickname, buf_len) >= buf_len)
919 goto truncated;
920 if (strlcat(buf, "\n", buf_len) >= buf_len)
921 goto truncated;
923 if (router_get_dir_hash(buf,digest)) {
924 log_warn(LD_BUG,"couldn't compute digest");
925 tor_free(buf);
926 return -1;
928 note_crypto_pk_op(SIGN_DIR);
929 if (router_append_dirobj_signature(buf,buf_len,digest,private_key)<0) {
930 tor_free(buf);
931 return -1;
934 *dir_out = buf;
935 return 0;
936 truncated:
937 log_warn(LD_BUG,"tried to exceed string length.");
938 tor_free(buf);
939 return -1;
942 /** Most recently generated encoded signed v1 directory. (auth dirservers
943 * only.)*/
944 static cached_dir_t *the_directory = NULL;
946 /* Used only by non-auth dirservers: The v1 directory and runningrouters we'll
947 * serve when requested. */
948 static cached_dir_t *cached_directory = NULL;
949 static cached_dir_t cached_runningrouters = { NULL, NULL, 0, 0, 0, -1 };
951 /** Used for other dirservers' v2 network statuses. Map from hexdigest to
952 * cached_dir_t. */
953 static digestmap_t *cached_v2_networkstatus = NULL;
955 /** Possibly replace the contents of <b>d</b> with the value of
956 * <b>directory</b> published on <b>when</b>, unless <b>when</b> is older than
957 * the last value, or too far in the future.
959 * Does not copy <b>directory</b>; frees it if it isn't used.
961 static void
962 set_cached_dir(cached_dir_t *d, char *directory, time_t when)
964 time_t now = time(NULL);
965 if (when<=d->published) {
966 log_info(LD_DIRSERV, "Ignoring old directory; not caching.");
967 tor_free(directory);
968 } else if (when>=now+ROUTER_MAX_AGE_TO_PUBLISH) {
969 log_info(LD_DIRSERV, "Ignoring future directory; not caching.");
970 tor_free(directory);
971 } else {
972 /* if (when>d->published && when<now+ROUTER_MAX_AGE) */
973 log_debug(LD_DIRSERV, "Caching directory.");
974 tor_free(d->dir);
975 d->dir = directory;
976 d->dir_len = strlen(directory);
977 tor_free(d->dir_z);
978 if (tor_gzip_compress(&(d->dir_z), &(d->dir_z_len), d->dir, d->dir_len,
979 ZLIB_METHOD)) {
980 log_warn(LD_BUG,"Error compressing cached directory");
982 d->published = when;
986 /** Decrement the reference count on <b>d</b>, and free it if it no longer has
987 * any references. */
988 void
989 cached_dir_decref(cached_dir_t *d)
991 if (!d || --d->refcnt > 0)
992 return;
993 clear_cached_dir(d);
994 tor_free(d);
997 /** Allocate and return a new cached_dir_t containing the string <b>s</b>,
998 * published at <b>published</b>. */
999 static cached_dir_t *
1000 new_cached_dir(char *s, time_t published)
1002 cached_dir_t *d = tor_malloc_zero(sizeof(cached_dir_t));
1003 d->refcnt = 1;
1004 d->dir = s;
1005 d->dir_len = strlen(s);
1006 d->published = published;
1007 if (tor_gzip_compress(&(d->dir_z), &(d->dir_z_len), d->dir, d->dir_len,
1008 ZLIB_METHOD)) {
1009 log_warn(LD_BUG, "Error compressing directory");
1011 return d;
1014 /** Remove all storage held in <b>d</b>, but do not free <b>d</b> itself. */
1015 static void
1016 clear_cached_dir(cached_dir_t *d)
1018 tor_free(d->dir);
1019 tor_free(d->dir_z);
1020 memset(d, 0, sizeof(cached_dir_t));
1023 /** Free all storage held by the cached_dir_t in <b>d</b>. */
1024 static void
1025 _free_cached_dir(void *_d)
1027 cached_dir_t *d = (cached_dir_t *)_d;
1028 cached_dir_decref(d);
1031 /** If we have no cached directory, or it is older than <b>published</b>,
1032 * then replace it with <b>directory</b>, published at <b>published</b>.
1034 * If <b>is_running_routers</b>, this is really a running_routers document
1035 * rather than a v1 directory.
1037 void
1038 dirserv_set_cached_directory(const char *directory, time_t published,
1039 int is_running_routers)
1041 if (is_running_routers) {
1042 set_cached_dir(&cached_runningrouters, tor_strdup(directory), published);
1043 } else {
1044 cached_dir_decref(cached_directory);
1045 cached_directory = new_cached_dir(tor_strdup(directory), published);
1049 /** We've just received a v2 network-status for an authoritative directory
1050 * with identity digest <b>identity</b> published at
1051 * <b>published</b>. Store it so we can serve it to others. If
1052 * <b>directory</b> is NULL, remove the entry with the given fingerprint from
1053 * the cache.
1055 void
1056 dirserv_set_cached_networkstatus_v2(const char *networkstatus,
1057 const char *identity,
1058 time_t published)
1060 cached_dir_t *d, *old_d;
1061 smartlist_t *trusted_dirs;
1062 if (!cached_v2_networkstatus)
1063 cached_v2_networkstatus = digestmap_new();
1065 old_d = digestmap_get(cached_v2_networkstatus, identity);
1066 if (!old_d && !networkstatus)
1067 return;
1069 if (networkstatus) {
1070 if (!old_d || published > old_d->published) {
1071 d = new_cached_dir(tor_strdup(networkstatus), published);
1072 digestmap_set(cached_v2_networkstatus, identity, d);
1073 if (old_d)
1074 cached_dir_decref(old_d);
1076 } else {
1077 if (old_d) {
1078 digestmap_remove(cached_v2_networkstatus, identity);
1079 cached_dir_decref(old_d);
1083 /* Now purge old entries. */
1084 trusted_dirs = router_get_trusted_dir_servers();
1085 if (digestmap_size(cached_v2_networkstatus) >
1086 smartlist_len(trusted_dirs) + MAX_UNTRUSTED_NETWORKSTATUSES) {
1087 /* We need to remove the oldest untrusted networkstatus. */
1088 const char *oldest = NULL;
1089 time_t oldest_published = TIME_MAX;
1090 digestmap_iter_t *iter;
1092 for (iter = digestmap_iter_init(cached_v2_networkstatus);
1093 !digestmap_iter_done(iter);
1094 iter = digestmap_iter_next(cached_v2_networkstatus, iter)) {
1095 const char *ident;
1096 void *val;
1097 digestmap_iter_get(iter, &ident, &val);
1098 d = val;
1099 if (d->published < oldest_published &&
1100 !router_digest_is_trusted_dir(ident)) {
1101 oldest = ident;
1102 oldest_published = d->published;
1105 tor_assert(oldest);
1106 d = digestmap_remove(cached_v2_networkstatus, oldest);
1107 if (d)
1108 cached_dir_decref(d);
1112 /** Remove any networkstatus from the directory cache that was published
1113 * before <b>cutoff</b>. */
1114 void
1115 dirserv_clear_old_networkstatuses(time_t cutoff)
1117 digestmap_iter_t *iter;
1119 if (!cached_v2_networkstatus)
1120 return;
1122 for (iter = digestmap_iter_init(cached_v2_networkstatus);
1123 !digestmap_iter_done(iter); ) {
1124 const char *ident;
1125 void *val;
1126 cached_dir_t *dir;
1127 digestmap_iter_get(iter, &ident, &val);
1128 dir = val;
1129 if (dir->published < cutoff) {
1130 char *fname;
1131 iter = digestmap_iter_next_rmv(cached_v2_networkstatus, iter);
1132 fname = networkstatus_get_cache_filename(ident);
1133 if (file_status(fname) == FN_FILE) {
1134 log_info(LD_DIR, "Removing too-old untrusted networkstatus in %s",
1135 fname);
1136 unlink(fname);
1138 tor_free(fname);
1139 cached_dir_decref(dir);
1140 } else {
1141 iter = digestmap_iter_next(cached_v2_networkstatus, iter);
1146 /** Remove any v1 info from the directory cache that was published
1147 * too long ago. */
1148 void
1149 dirserv_clear_old_v1_info(time_t now)
1151 #define MAX_V1_DIRECTORY_AGE (30*24*60*60)
1152 #define MAX_V1_RR_AGE (7*24*60*60)
1153 if (cached_directory &&
1154 cached_directory->published < (now - MAX_V1_DIRECTORY_AGE)) {
1155 cached_dir_decref(cached_directory);
1157 if (cached_runningrouters.published < (now - MAX_V1_RR_AGE)) {
1158 clear_cached_dir(&cached_runningrouters);
1162 /** Helper: If we're an authority for the right directory version (the
1163 * directory version is determined by <b>is_v1_object</b>), try to regenerate
1164 * auth_src as appropriate and return it, falling back to cache_src on
1165 * failure. If we're a cache, return cache_src.
1167 static cached_dir_t *
1168 dirserv_pick_cached_dir_obj(cached_dir_t *cache_src,
1169 cached_dir_t *auth_src,
1170 time_t dirty, cached_dir_t *(*regenerate)(void),
1171 const char *name,
1172 int is_v1_object)
1174 int authority = get_options()->AuthoritativeDir &&
1175 (!is_v1_object || get_options()->V1AuthoritativeDir);
1177 if (!authority) {
1178 return cache_src;
1179 } else {
1180 /* We're authoritative. */
1181 if (regenerate != NULL) {
1182 if (dirty && dirty + DIR_REGEN_SLACK_TIME < time(NULL)) {
1183 if (!(auth_src = regenerate())) {
1184 log_err(LD_BUG, "Couldn't generate %s?", name);
1185 exit(1);
1187 } else {
1188 log_info(LD_DIRSERV, "The %s is still clean; reusing.", name);
1191 return auth_src ? auth_src : cache_src;
1195 /** Helper: If we're authoritative and <b>auth_src</b> is set, use
1196 * <b>auth_src</b>, otherwise use <b>cache_src</b>. If we're using
1197 * <b>auth_src</b> and it's been <b>dirty</b> for at least
1198 * DIR_REGEN_SLACK_TIME seconds, call <b>regenerate</b>() to make a fresh one.
1199 * Yields the compressed version of the directory object if <b>compress</b> is
1200 * set; otherwise return the uncompressed version. (In either case, sets
1201 * *<b>out</b> and returns the size of the buffer in *<b>out</b>.)
1203 * Use <b>is_v1_object</b> to help determine whether we're authoritative for
1204 * this kind of object.
1206 static size_t
1207 dirserv_get_obj(const char **out,
1208 int compress,
1209 cached_dir_t *cache_src,
1210 cached_dir_t *auth_src,
1211 time_t dirty, cached_dir_t *(*regenerate)(void),
1212 const char *name,
1213 int is_v1_object)
1215 cached_dir_t *d = dirserv_pick_cached_dir_obj(
1216 cache_src, auth_src,
1217 dirty, regenerate, name, is_v1_object);
1219 if (!d)
1220 return 0;
1221 *out = compress ? d->dir_z : d->dir;
1222 if (*out) {
1223 return compress ? d->dir_z_len : d->dir_len;
1224 } else {
1225 /* not yet available. */
1226 return 0;
1230 /** Return the most recently generated encoded signed directory, generating a
1231 * new one as necessary. If not an authoritative directory may return NULL if
1232 * no directory is yet cached. */
1233 cached_dir_t *
1234 dirserv_get_directory(void)
1236 return dirserv_pick_cached_dir_obj(cached_directory, the_directory,
1237 the_directory_is_dirty,
1238 dirserv_regenerate_directory,
1239 "server directory", 1);
1243 * Generate a fresh v1 directory (authdirservers only); set the_directory
1244 * and return a pointer to the new value.
1246 static cached_dir_t *
1247 dirserv_regenerate_directory(void)
1249 char *new_directory=NULL;
1251 if (dirserv_dump_directory_to_string(&new_directory,
1252 get_identity_key(), 0)) {
1253 log_warn(LD_BUG, "Error creating directory.");
1254 tor_free(new_directory);
1255 return NULL;
1257 cached_dir_decref(the_directory);
1258 the_directory = new_cached_dir(new_directory, time(NULL));
1259 log_info(LD_DIRSERV,"New directory (size %d) has been built.",
1260 (int)the_directory->dir_len);
1261 log_debug(LD_DIRSERV,"New directory (size %d):\n%s",
1262 (int)the_directory->dir_len, the_directory->dir);
1264 the_directory_is_dirty = 0;
1266 /* Save the directory to disk so we re-load it quickly on startup.
1268 dirserv_set_cached_directory(the_directory->dir, time(NULL), 0);
1270 return the_directory;
1273 /** For authoritative directories: the current (v1) network status. */
1274 static cached_dir_t the_runningrouters = { NULL, NULL, 0, 0, 0, -1 };
1276 /** Replace the current running-routers list with a newly generated one. */
1277 static cached_dir_t *
1278 generate_runningrouters(void)
1280 char *s=NULL;
1281 char *router_status=NULL;
1282 char digest[DIGEST_LEN];
1283 char published[ISO_TIME_LEN+1];
1284 size_t len;
1285 crypto_pk_env_t *private_key = get_identity_key();
1286 char *identity_pkey; /* Identity key, DER64-encoded. */
1287 size_t identity_pkey_len;
1288 routerlist_t *rl = router_get_routerlist();
1290 if (list_server_status(rl->routers, &router_status, 0)) {
1291 goto err;
1293 if (crypto_pk_write_public_key_to_string(private_key,&identity_pkey,
1294 &identity_pkey_len)<0) {
1295 log_warn(LD_BUG,"write identity_pkey to string failed!");
1296 goto err;
1298 format_iso_time(published, time(NULL));
1300 len = 2048+strlen(router_status);
1301 s = tor_malloc_zero(len);
1302 tor_snprintf(s, len,
1303 "network-status\n"
1304 "published %s\n"
1305 "router-status %s\n"
1306 "dir-signing-key\n%s"
1307 "directory-signature %s\n",
1308 published, router_status, identity_pkey,
1309 get_options()->Nickname);
1310 tor_free(router_status);
1311 tor_free(identity_pkey);
1312 if (router_get_runningrouters_hash(s,digest)) {
1313 log_warn(LD_BUG,"couldn't compute digest");
1314 goto err;
1316 note_crypto_pk_op(SIGN_DIR);
1317 if (router_append_dirobj_signature(s, len, digest, private_key)<0)
1318 goto err;
1320 set_cached_dir(&the_runningrouters, s, time(NULL));
1321 runningrouters_is_dirty = 0;
1323 return &the_runningrouters;
1324 err:
1325 tor_free(s);
1326 tor_free(router_status);
1327 return NULL;
1330 /** Set *<b>rr</b> to the most recently generated encoded signed
1331 * running-routers list, generating a new one as necessary. Return the
1332 * size of the directory on success, and 0 on failure. */
1333 size_t
1334 dirserv_get_runningrouters(const char **rr, int compress)
1336 return dirserv_get_obj(rr, compress,
1337 &cached_runningrouters, &the_runningrouters,
1338 runningrouters_is_dirty,
1339 generate_runningrouters,
1340 "v1 network status list", 1);
1343 /** For authoritative directories: the current (v2) network status. */
1344 static cached_dir_t *the_v2_networkstatus = NULL;
1346 /** Return true iff our opinion of the routers has been stale for long
1347 * enough that we should generate a new network status doc. */
1348 static int
1349 should_generate_v2_networkstatus(void)
1351 return get_options()->AuthoritativeDir &&
1352 the_v2_networkstatus_is_dirty &&
1353 the_v2_networkstatus_is_dirty + DIR_REGEN_SLACK_TIME < time(NULL);
1356 /* Thresholds for server performance: set by
1357 * dirserv_compute_performance_thresholds, and used by
1358 * generate_v2_networkstatus */
1359 static uint32_t stable_uptime = 0; /* start at a safe value */
1360 static uint32_t fast_bandwidth = 0;
1361 static uint32_t guard_bandwidth_including_exits = 0;
1362 static uint32_t guard_bandwidth_excluding_exits = 0;
1363 static uint64_t total_bandwidth = 0;
1364 static uint64_t total_exit_bandwidth = 0;
1366 /** Helper: estimate the uptime of a router given its stated uptime and the
1367 * amount of time since it last stated its stated uptime. */
1368 static INLINE int
1369 real_uptime(routerinfo_t *router, time_t now)
1371 if (now < router->cache_info.published_on)
1372 return router->uptime;
1373 else
1374 return router->uptime + (now - router->cache_info.published_on);
1377 /** Return 1 if <b>router</b> is not suitable for these parameters, else 0.
1378 * If <b>need_uptime</b> is non-zero, we require a minimum uptime.
1379 * If <b>need_capacity</b> is non-zero, we require a minimum advertised
1380 * bandwidth.
1382 static int
1383 dirserv_thinks_router_is_unreliable(time_t now,
1384 routerinfo_t *router,
1385 int need_uptime, int need_capacity)
1387 if (need_uptime &&
1388 (unsigned)real_uptime(router, now) < stable_uptime)
1389 return 1;
1390 if (need_capacity &&
1391 router_get_advertised_bandwidth(router) < fast_bandwidth)
1392 return 1;
1393 return 0;
1396 /** Helper: returns a tristate based on comparing **(uint32_t**)<b>a</b>
1397 * to **(uint32_t**)<b>b</b>. */
1398 static int
1399 _compare_uint32(const void **a, const void **b)
1401 uint32_t first = **(uint32_t **)a, second = **(uint32_t **)b;
1402 if (first < second) return -1;
1403 if (first > second) return 1;
1404 return 0;
1407 /** Look through the routerlist, and assign the median uptime of running valid
1408 * servers to stable_uptime, and the relative bandwidth capacities to
1409 * fast_bandwidth and guard_bandwidth. Set total_bandwidth to the total
1410 * capacity of all running valid servers and total_exit_bandwidth to the
1411 * capacity of all running valid exits. Set the is_exit flag of each router
1412 * appropriately. */
1413 static void
1414 dirserv_compute_performance_thresholds(routerlist_t *rl)
1416 smartlist_t *uptimes, *bandwidths, *bandwidths_excluding_exits;
1417 time_t now = time(NULL);
1419 /* initialize these all here, in case there are no routers */
1420 stable_uptime = 0;
1421 fast_bandwidth = 0;
1422 guard_bandwidth_including_exits = 0;
1423 guard_bandwidth_excluding_exits = 0;
1425 total_bandwidth = 0;
1426 total_exit_bandwidth = 0;
1428 uptimes = smartlist_create();
1429 bandwidths = smartlist_create();
1430 bandwidths_excluding_exits = smartlist_create();
1432 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
1433 if (ri->is_running && ri->is_valid) {
1434 uint32_t *up = tor_malloc(sizeof(uint32_t));
1435 uint32_t *bw = tor_malloc(sizeof(uint32_t));
1436 ri->is_exit = exit_policy_is_general_exit(ri->exit_policy);
1437 *up = (uint32_t) real_uptime(ri, now);
1438 smartlist_add(uptimes, up);
1439 *bw = router_get_advertised_bandwidth(ri);
1440 total_bandwidth += *bw;
1441 if (ri->is_exit && !ri->is_bad_exit) {
1442 total_exit_bandwidth += *bw;
1443 } else {
1444 uint32_t *bw_not_exit = tor_malloc(sizeof(uint32_t));
1445 *bw_not_exit = *bw;
1446 smartlist_add(bandwidths_excluding_exits, bw_not_exit);
1448 smartlist_add(bandwidths, bw);
1452 smartlist_sort(uptimes, _compare_uint32);
1453 smartlist_sort(bandwidths, _compare_uint32);
1454 smartlist_sort(bandwidths_excluding_exits, _compare_uint32);
1456 if (smartlist_len(uptimes))
1457 stable_uptime = *(uint32_t*)smartlist_get(uptimes,
1458 smartlist_len(uptimes)/2);
1460 if (smartlist_len(bandwidths)) {
1461 fast_bandwidth = *(uint32_t*)smartlist_get(bandwidths,
1462 smartlist_len(bandwidths)/8);
1463 if (fast_bandwidth < ROUTER_REQUIRED_MIN_BANDWIDTH)
1464 fast_bandwidth = *(uint32_t*)smartlist_get(bandwidths,
1465 smartlist_len(bandwidths)/4);
1466 guard_bandwidth_including_exits =
1467 *(uint32_t*)smartlist_get(bandwidths, smartlist_len(bandwidths)/2);
1470 if (smartlist_len(bandwidths_excluding_exits)) {
1471 guard_bandwidth_excluding_exits =
1472 *(uint32_t*)smartlist_get(bandwidths_excluding_exits,
1473 smartlist_len(bandwidths_excluding_exits)/2);
1476 log(LOG_INFO, LD_DIRSERV,
1477 "Cutoffs: %lus uptime, %lu b/s fast, %lu or %lu b/s guard.",
1478 (unsigned long)stable_uptime,
1479 (unsigned long)fast_bandwidth,
1480 (unsigned long)guard_bandwidth_including_exits,
1481 (unsigned long)guard_bandwidth_excluding_exits);
1483 SMARTLIST_FOREACH(uptimes, uint32_t *, up, tor_free(up));
1484 SMARTLIST_FOREACH(bandwidths, uint32_t *, bw, tor_free(bw));
1485 SMARTLIST_FOREACH(bandwidths_excluding_exits, uint32_t *, bw, tor_free(bw));
1486 smartlist_free(uptimes);
1487 smartlist_free(bandwidths);
1488 smartlist_free(bandwidths_excluding_exits);
1491 /** For authoritative directories only: replace the contents of
1492 * <b>the_v2_networkstatus</b> with a newly generated network status
1493 * object. */
1494 static cached_dir_t *
1495 generate_v2_networkstatus(void)
1497 /** Longest status flag name that we generate. */
1498 #define LONGEST_STATUS_FLAG_NAME_LEN 9
1499 /** Maximum number of status flags we'll apply to one router. */
1500 #define N_STATUS_FLAGS 10
1501 /** Amount of space to allocate for each entry. (r line and s line.) */
1502 #define RS_ENTRY_LEN \
1503 ( /* first line */ \
1504 MAX_NICKNAME_LEN+BASE64_DIGEST_LEN*2+ISO_TIME_LEN+INET_NTOA_BUF_LEN+ \
1505 5*2 /* ports */ + 10 /* punctuation */ + \
1506 /* second line */ \
1507 (LONGEST_STATUS_FLAG_NAME_LEN+1)*N_STATUS_FLAGS + 2)
1509 cached_dir_t *r = NULL;
1510 size_t len, identity_pkey_len;
1511 char *status = NULL, *client_versions = NULL, *server_versions = NULL,
1512 *identity_pkey = NULL, *hostname = NULL;
1513 char *outp, *endp;
1514 or_options_t *options = get_options();
1515 char fingerprint[FINGERPRINT_LEN+1];
1516 char ipaddr[INET_NTOA_BUF_LEN];
1517 char published[ISO_TIME_LEN+1];
1518 char digest[DIGEST_LEN];
1519 struct in_addr in;
1520 uint32_t addr;
1521 crypto_pk_env_t *private_key = get_identity_key();
1522 routerlist_t *rl = router_get_routerlist();
1523 time_t now = time(NULL);
1524 time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
1525 int naming = options->NamingAuthoritativeDir;
1526 int versioning = options->VersioningAuthoritativeDir;
1527 int listbadexits = options->AuthDirListBadExits;
1528 int exits_can_be_guards;
1529 const char *contact;
1531 if (resolve_my_address(LOG_WARN, options, &addr, &hostname)<0) {
1532 log_warn(LD_NET, "Couldn't resolve my hostname");
1533 goto done;
1535 in.s_addr = htonl(addr);
1536 tor_inet_ntoa(&in, ipaddr, sizeof(ipaddr));
1538 format_iso_time(published, time(NULL));
1540 client_versions = format_versions_list(options->RecommendedClientVersions);
1541 server_versions = format_versions_list(options->RecommendedServerVersions);
1543 if (crypto_pk_write_public_key_to_string(private_key, &identity_pkey,
1544 &identity_pkey_len)<0) {
1545 log_warn(LD_BUG,"Writing public key to string failed.");
1546 goto done;
1549 if (crypto_pk_get_fingerprint(private_key, fingerprint, 0)<0) {
1550 log_err(LD_BUG, "Error computing fingerprint");
1551 goto done;
1554 contact = get_options()->ContactInfo;
1555 if (!contact)
1556 contact = "(none)";
1558 len = 2048+strlen(client_versions)+strlen(server_versions);
1559 len += identity_pkey_len*2;
1560 len += (RS_ENTRY_LEN)*smartlist_len(rl->routers);
1562 status = tor_malloc(len);
1563 tor_snprintf(status, len,
1564 "network-status-version 2\n"
1565 "dir-source %s %s %d\n"
1566 "fingerprint %s\n"
1567 "contact %s\n"
1568 "published %s\n"
1569 "dir-options%s%s%s\n"
1570 "%s%s" /* client versions %s */
1571 "%s%s%s" /* \nserver versions %s \n */
1572 "dir-signing-key\n%s\n",
1573 hostname, ipaddr, (int)options->DirPort,
1574 fingerprint,
1575 contact,
1576 published,
1577 naming ? " Names" : "",
1578 listbadexits ? " BadExits" : "",
1579 versioning ? " Versions" : "",
1580 versioning ? "client-versions " : "",
1581 versioning ? client_versions : "",
1582 versioning ? "\nserver-versions " : "",
1583 versioning ? server_versions : "",
1584 versioning ? "\n" : "",
1585 identity_pkey);
1586 outp = status + strlen(status);
1587 endp = status + len;
1589 /* precompute this part, since we need it to decide what "stable"
1590 * means. */
1591 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
1592 ri->is_running = dirserv_thinks_router_is_reachable(ri, now);
1595 dirserv_compute_performance_thresholds(rl);
1597 /* XXXX We should take steps to keep this from oscillating if
1598 * total_exit_bandwidth is close to total_bandwidth/3. */
1599 exits_can_be_guards = total_exit_bandwidth >= (total_bandwidth / 3);
1601 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
1602 if (ri->cache_info.published_on >= cutoff) {
1603 /* Already set by compute_performance_thresholds. */
1604 int f_exit = ri->is_exit;
1605 /* These versions dump connections with idle live circuits
1606 sometimes. D'oh!*/
1607 int unstable_version =
1608 tor_version_as_new_as(ri->platform,"0.1.1.10-alpha") &&
1609 !tor_version_as_new_as(ri->platform,"0.1.1.16-rc-cvs");
1610 int f_stable = ri->is_stable =
1611 !dirserv_thinks_router_is_unreliable(now, ri, 1, 0) &&
1612 !unstable_version;
1613 int f_fast = ri->is_fast =
1614 !dirserv_thinks_router_is_unreliable(now, ri, 0, 1);
1615 int f_running = ri->is_running; /* computed above */
1616 int f_authority = router_digest_is_trusted_dir(
1617 ri->cache_info.identity_digest);
1618 int f_named = naming && ri->is_named;
1619 int f_valid = ri->is_valid;
1620 int f_guard = f_fast && f_stable &&
1621 (!f_exit || exits_can_be_guards) &&
1622 router_get_advertised_bandwidth(ri) >=
1623 (exits_can_be_guards ? guard_bandwidth_including_exits :
1624 guard_bandwidth_excluding_exits);
1625 int f_bad_exit = listbadexits && ri->is_bad_exit;
1626 /* 0.1.1.9-alpha is the first version to support fetch by descriptor
1627 * hash. */
1628 int f_v2_dir = ri->dir_port &&
1629 tor_version_as_new_as(ri->platform,"0.1.1.9-alpha");
1630 char identity64[BASE64_DIGEST_LEN+1];
1631 char digest64[BASE64_DIGEST_LEN+1];
1633 if (!strcasecmp(ri->nickname, UNNAMED_ROUTER_NICKNAME))
1634 f_named = 0;
1636 format_iso_time(published, ri->cache_info.published_on);
1638 digest_to_base64(identity64, ri->cache_info.identity_digest);
1639 digest_to_base64(digest64, ri->cache_info.signed_descriptor_digest);
1641 in.s_addr = htonl(ri->addr);
1642 tor_inet_ntoa(&in, ipaddr, sizeof(ipaddr));
1644 if (tor_snprintf(outp, endp-outp,
1645 "r %s %s %s %s %s %d %d\n"
1646 "s%s%s%s%s%s%s%s%s%s%s\n",
1647 ri->nickname,
1648 identity64,
1649 digest64,
1650 published,
1651 ipaddr,
1652 ri->or_port,
1653 ri->dir_port,
1654 f_authority?" Authority":"",
1655 f_bad_exit?" BadExit":"",
1656 f_exit?" Exit":"",
1657 f_fast?" Fast":"",
1658 f_guard?" Guard":"",
1659 f_named?" Named":"",
1660 f_stable?" Stable":"",
1661 f_running?" Running":"",
1662 f_valid?" Valid":"",
1663 f_v2_dir?" V2Dir":"")<0) {
1664 log_warn(LD_BUG, "Unable to print router status.");
1665 goto done;
1667 outp += strlen(outp);
1668 if (ri->platform && !strcmpstart(ri->platform, "Tor ")) {
1669 const char *eos = find_whitespace(ri->platform+4);
1670 if (eos) {
1671 char *platform = tor_strndup(ri->platform, eos-(ri->platform));
1672 if (tor_snprintf(outp, endp-outp,
1673 "opt v %s\n", platform)<0) {
1674 log_warn(LD_BUG, "Unable to print router version.");
1675 goto done;
1677 tor_free(platform);
1678 outp += strlen(outp);
1684 if (tor_snprintf(outp, endp-outp, "directory-signature %s\n",
1685 get_options()->Nickname)<0) {
1686 log_warn(LD_BUG, "Unable to write signature line.");
1687 goto done;
1690 if (router_get_networkstatus_v2_hash(status, digest)<0) {
1691 log_warn(LD_BUG, "Unable to hash network status");
1692 goto done;
1695 note_crypto_pk_op(SIGN_DIR);
1696 if (router_append_dirobj_signature(outp,endp-outp,digest,private_key)<0) {
1697 log_warn(LD_BUG, "Unable to sign router status.");
1698 goto done;
1701 if (the_v2_networkstatus)
1702 cached_dir_decref(the_v2_networkstatus);
1703 the_v2_networkstatus = new_cached_dir(status, time(NULL));
1704 status = NULL; /* So it doesn't get double-freed. */
1705 the_v2_networkstatus_is_dirty = 0;
1706 router_set_networkstatus(the_v2_networkstatus->dir,
1707 time(NULL), NS_GENERATED, NULL);
1708 r = the_v2_networkstatus;
1709 done:
1710 tor_free(client_versions);
1711 tor_free(server_versions);
1712 tor_free(status);
1713 tor_free(hostname);
1714 tor_free(identity_pkey);
1715 return r;
1718 /** Given the portion of a networkstatus request URL after "tor/status/" in
1719 * <b>key</b>, append to <b>result</b> the digests of the identity keys of the
1720 * networkstatus objects that the client has requested. */
1721 void
1722 dirserv_get_networkstatus_v2_fingerprints(smartlist_t *result,
1723 const char *key)
1725 tor_assert(result);
1727 if (!cached_v2_networkstatus)
1728 cached_v2_networkstatus = digestmap_new();
1730 if (should_generate_v2_networkstatus())
1731 generate_v2_networkstatus();
1733 if (!strcmp(key,"authority")) {
1734 if (get_options()->AuthoritativeDir) {
1735 routerinfo_t *me = router_get_my_routerinfo();
1736 if (me)
1737 smartlist_add(result,
1738 tor_memdup(me->cache_info.identity_digest, DIGEST_LEN));
1740 } else if (!strcmp(key, "all")) {
1741 if (digestmap_size(cached_v2_networkstatus)) {
1742 digestmap_iter_t *iter;
1743 iter = digestmap_iter_init(cached_v2_networkstatus);
1744 while (!digestmap_iter_done(iter)) {
1745 const char *ident;
1746 void *val;
1747 digestmap_iter_get(iter, &ident, &val);
1748 smartlist_add(result, tor_memdup(ident, DIGEST_LEN));
1749 iter = digestmap_iter_next(cached_v2_networkstatus, iter);
1751 } else {
1752 SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
1753 trusted_dir_server_t *, ds,
1754 smartlist_add(result, tor_memdup(ds->digest, DIGEST_LEN)));
1756 smartlist_sort_digests(result);
1757 if (smartlist_len(result) == 0)
1758 log_warn(LD_DIRSERV,
1759 "Client requested 'all' network status objects; we have none.");
1760 } else if (!strcmpstart(key, "fp/")) {
1761 dir_split_resource_into_fingerprints(key+3, result, NULL, 1, 1);
1765 /** Look for a network status object as specified by <b>key</b>, which should
1766 * be either "authority" (to find a network status generated by us), a hex
1767 * identity digest (to find a network status generated by given directory), or
1768 * "all" (to return all the v2 network status objects we have).
1770 void
1771 dirserv_get_networkstatus_v2(smartlist_t *result,
1772 const char *key)
1774 cached_dir_t *cached;
1775 smartlist_t *fingerprints = smartlist_create();
1776 tor_assert(result);
1778 if (!cached_v2_networkstatus)
1779 cached_v2_networkstatus = digestmap_new();
1781 dirserv_get_networkstatus_v2_fingerprints(fingerprints, key);
1782 SMARTLIST_FOREACH(fingerprints, const char *, fp,
1784 if (router_digest_is_me(fp) && should_generate_v2_networkstatus())
1785 generate_v2_networkstatus();
1786 cached = digestmap_get(cached_v2_networkstatus, fp);
1787 if (cached) {
1788 smartlist_add(result, cached);
1789 } else {
1790 char hexbuf[HEX_DIGEST_LEN+1];
1791 base16_encode(hexbuf, sizeof(hexbuf), fp, DIGEST_LEN);
1792 log_info(LD_DIRSERV, "Don't know about any network status with "
1793 "fingerprint '%s'", hexbuf);
1796 SMARTLIST_FOREACH(fingerprints, char *, cp, tor_free(cp));
1797 smartlist_free(fingerprints);
1800 /** As dirserv_get_routerdescs(), but instead of getting signed_descriptor_t
1801 * pointers, adds copies of digests to fps_out. For a /tor/server/d/ request,
1802 * adds descriptor digests; for other requests, adds identity digests.
1805 dirserv_get_routerdesc_fingerprints(smartlist_t *fps_out, const char *key,
1806 const char **msg)
1808 *msg = NULL;
1810 if (!strcmp(key, "/tor/server/all")) {
1811 routerlist_t *rl = router_get_routerlist();
1812 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, r,
1813 smartlist_add(fps_out,
1814 tor_memdup(r->cache_info.identity_digest, DIGEST_LEN)));
1815 } else if (!strcmp(key, "/tor/server/authority")) {
1816 routerinfo_t *ri = router_get_my_routerinfo();
1817 if (ri)
1818 smartlist_add(fps_out,
1819 tor_memdup(ri->cache_info.identity_digest, DIGEST_LEN));
1820 } else if (!strcmpstart(key, "/tor/server/d/")) {
1821 key += strlen("/tor/server/d/");
1822 dir_split_resource_into_fingerprints(key, fps_out, NULL, 1, 1);
1823 } else if (!strcmpstart(key, "/tor/server/fp/")) {
1824 key += strlen("/tor/server/fp/");
1825 dir_split_resource_into_fingerprints(key, fps_out, NULL, 1, 1);
1826 } else {
1827 *msg = "Key not recognized";
1828 return -1;
1831 if (!smartlist_len(fps_out)) {
1832 *msg = "Servers unavailable";
1833 return -1;
1835 return 0;
1838 /** Add a signed_descriptor_t to <b>descs_out</b> for each router matching
1839 * <b>key</b>. The key should be either
1840 * - "/tor/server/authority" for our own routerinfo;
1841 * - "/tor/server/all" for all the routerinfos we have, concatenated;
1842 * - "/tor/server/fp/FP" where FP is a plus-separated sequence of
1843 * hex identity digests; or
1844 * - "/tor/server/d/D" where D is a plus-separated sequence
1845 * of server descriptor digests, in hex.
1847 * Return 0 if we found some matching descriptors, or -1 if we do not
1848 * have any descriptors, no matching descriptors, or if we did not
1849 * recognize the key (URL).
1850 * If -1 is returned *<b>msg</b> will be set to an appropriate error
1851 * message.
1853 * (Despite its name, this function is also called from the controller, which
1854 * exposes a similar means to fetch descriptors.)
1857 dirserv_get_routerdescs(smartlist_t *descs_out, const char *key,
1858 const char **msg)
1860 *msg = NULL;
1862 if (!strcmp(key, "/tor/server/all")) {
1863 routerlist_t *rl = router_get_routerlist();
1864 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, r,
1865 smartlist_add(descs_out, &(r->cache_info)));
1866 } else if (!strcmp(key, "/tor/server/authority")) {
1867 routerinfo_t *ri = router_get_my_routerinfo();
1868 if (ri)
1869 smartlist_add(descs_out, &(ri->cache_info));
1870 } else if (!strcmpstart(key, "/tor/server/d/")) {
1871 smartlist_t *digests = smartlist_create();
1872 key += strlen("/tor/server/d/");
1873 dir_split_resource_into_fingerprints(key, digests, NULL, 1, 1);
1874 SMARTLIST_FOREACH(digests, const char *, d,
1876 signed_descriptor_t *sd = router_get_by_descriptor_digest(d);
1877 if (sd)
1878 smartlist_add(descs_out,sd);
1880 SMARTLIST_FOREACH(digests, char *, d, tor_free(d));
1881 smartlist_free(digests);
1882 } else if (!strcmpstart(key, "/tor/server/fp/")) {
1883 smartlist_t *digests = smartlist_create();
1884 time_t cutoff = time(NULL) - ROUTER_MAX_AGE_TO_PUBLISH;
1885 key += strlen("/tor/server/fp/");
1886 dir_split_resource_into_fingerprints(key, digests, NULL, 1, 1);
1887 SMARTLIST_FOREACH(digests, const char *, d,
1889 if (router_digest_is_me(d)) {
1890 smartlist_add(descs_out, &(router_get_my_routerinfo()->cache_info));
1891 } else {
1892 routerinfo_t *ri = router_get_by_digest(d);
1893 /* Don't actually serve a descriptor that everyone will think is
1894 * expired. This is an (ugly) workaround to keep buggy 0.1.1.10
1895 * Tors from downloading descriptors that they will throw away.
1897 if (ri && ri->cache_info.published_on > cutoff)
1898 smartlist_add(descs_out, &(ri->cache_info));
1901 SMARTLIST_FOREACH(digests, char *, d, tor_free(d));
1902 smartlist_free(digests);
1903 } else {
1904 *msg = "Key not recognized";
1905 return -1;
1908 if (!smartlist_len(descs_out)) {
1909 *msg = "Servers unavailable";
1910 return -1;
1912 return 0;
1915 /** Called when a TLS handshake has completed successfully with a
1916 * router listening at <b>address</b>:<b>or_port</b>, and has yielded
1917 * a certificate with digest <b>digest_rcvd</b>.
1919 * Also, if as_advertised is 1, then inform the reachability checker
1920 * that we could get to this guy.
1922 void
1923 dirserv_orconn_tls_done(const char *address,
1924 uint16_t or_port,
1925 const char *digest_rcvd,
1926 int as_advertised)
1928 routerlist_t *rl = router_get_routerlist();
1929 tor_assert(address);
1930 tor_assert(digest_rcvd);
1932 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
1933 if (!strcasecmp(address, ri->address) && or_port == ri->or_port &&
1934 as_advertised &&
1935 !memcmp(ri->cache_info.identity_digest, digest_rcvd, DIGEST_LEN)) {
1936 /* correct digest. mark this router reachable! */
1937 log_info(LD_DIRSERV, "Found router %s to be reachable. Yay.",
1938 ri->nickname);
1939 ri->last_reachable = time(NULL);
1940 ri->num_unreachable_notifications = 0;
1943 /* FFFF Maybe we should reinstate the code that dumps routers with the same
1944 * addr/port but with nonmatching keys, but instead of dumping, we should
1945 * skip testing. */
1948 /** Auth dir server only: if <b>try_all</b> is 1, launch connections to
1949 * all known routers; else we want to load balance such that we only
1950 * try a few connections per call.
1952 * The load balancing is such that if we get called once every ten
1953 * seconds, we will cycle through all the tests in 1280 seconds (a
1954 * bit over 20 minutes).
1956 void
1957 dirserv_test_reachability(int try_all)
1959 time_t now = time(NULL);
1960 routerlist_t *rl = router_get_routerlist();
1961 static char ctr = 0;
1963 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, router, {
1964 const char *id_digest = router->cache_info.identity_digest;
1965 if (router_is_me(router))
1966 continue;
1967 if (try_all || (((uint8_t)id_digest[0]) % 128) == ctr) {
1968 log_debug(LD_OR,"Testing reachability of %s at %s:%u.",
1969 router->nickname, router->address, router->or_port);
1970 /* Remember when we started trying to determine reachability */
1971 if (!router->testing_since)
1972 router->testing_since = now;
1973 connection_or_connect(router->addr, router->or_port,
1974 id_digest);
1977 if (!try_all) /* increment ctr */
1978 ctr = (ctr + 1) % 128;
1981 /** If <b>conn</b> is a dirserv connection tunneled over an or_connection,
1982 * return that connection. Otherwise, return NULL. */
1983 static INLINE or_connection_t *
1984 connection_dirserv_get_target_or_conn(dir_connection_t *conn)
1986 if (conn->bridge_conn &&
1987 conn->bridge_conn->on_circuit &&
1988 !CIRCUIT_IS_ORIGIN(conn->bridge_conn->on_circuit)) {
1989 or_circuit_t *circ = TO_OR_CIRCUIT(conn->bridge_conn->on_circuit);
1990 return circ->p_conn;
1991 } else {
1992 return NULL;
1996 /** Remove <b>dir_conn</b> from the list of bridged dirserv connections
1997 * blocking on <b>or_conn</b>, and set its status to nonblocked. */
1998 static INLINE void
1999 connection_dirserv_remove_from_blocked_list(or_connection_t *or_conn,
2000 dir_connection_t *dir_conn)
2002 dir_connection_t **c;
2003 for (c = &or_conn->blocked_dir_connections; *c;
2004 c = &(*c)->next_blocked_on_same_or_conn) {
2005 if (*c == dir_conn) {
2006 tor_assert(dir_conn->is_blocked_on_or_conn == 1);
2007 *c = dir_conn->next_blocked_on_same_or_conn;
2008 dir_conn->next_blocked_on_same_or_conn = NULL;
2009 dir_conn->is_blocked_on_or_conn = 0;
2010 return;
2013 tor_assert(!dir_conn->is_blocked_on_or_conn);
2016 /** If <b>dir_conn</b> is a dirserv connection that's bridged over an edge_conn
2017 * onto an or_conn, remove it from the blocked list (if it's blocked) and
2018 * unlink it and the edge_conn from one another. */
2019 void
2020 connection_dirserv_unlink_from_bridge(dir_connection_t *dir_conn)
2022 edge_connection_t *edge_conn;
2023 or_connection_t *or_conn;
2024 tor_assert(dir_conn);
2025 edge_conn = dir_conn->bridge_conn;
2026 or_conn = connection_dirserv_get_target_or_conn(dir_conn);
2027 if (or_conn) {
2028 /* XXXX Really, this is only necessary if dir_conn->is_blocked_on_or_conn.
2029 * But for now, let's leave it in, so the assert can catch */
2030 connection_dirserv_remove_from_blocked_list(or_conn, dir_conn);
2032 dir_conn->is_blocked_on_or_conn = 0; /* Probably redundant. */
2033 edge_conn->bridge_for_conn = NULL;
2034 dir_conn->bridge_conn = NULL;
2037 /** Stop writing on a bridged dir_conn, and remember that it's blocked because
2038 * its or_conn was too full. */
2039 static void
2040 connection_dirserv_mark_as_blocked(dir_connection_t *dir_conn)
2042 or_connection_t *or_conn;
2043 if (dir_conn->is_blocked_on_or_conn)
2044 return;
2045 tor_assert(! dir_conn->next_blocked_on_same_or_conn);
2046 or_conn = connection_dirserv_get_target_or_conn(dir_conn);
2047 if (!or_conn)
2048 return;
2049 dir_conn->next_blocked_on_same_or_conn = or_conn->blocked_dir_connections;
2050 or_conn->blocked_dir_connections = dir_conn;
2051 dir_conn->is_blocked_on_or_conn = 1;
2052 connection_stop_writing(TO_CONN(dir_conn));
2055 /** Tell all bridged dir_conns that were blocked because or_conn's outbuf was
2056 * too full that they can write again. */
2057 void
2058 connection_dirserv_stop_blocking_all_on_or_conn(or_connection_t *or_conn)
2060 dir_connection_t *dir_conn, *next;
2062 while (or_conn->blocked_dir_connections) {
2063 dir_conn = or_conn->blocked_dir_connections;
2064 next = dir_conn->next_blocked_on_same_or_conn;
2066 dir_conn->is_blocked_on_or_conn = 0;
2067 dir_conn->next_blocked_on_same_or_conn = NULL;
2068 connection_start_writing(TO_CONN(dir_conn));
2069 dir_conn = next;
2071 or_conn->blocked_dir_connections = NULL;
2074 /** Return an approximate estimate of the number of bytes that will
2075 * be needed to transmit the server descriptors (if is_serverdescs --
2076 * they can be either d/ or fp/ queries) or networkstatus objects (if
2077 * !is_serverdescs) listed in <b>fps</b>. If <b>compressed</b> is set,
2078 * we guess how large the data will be after compression.
2080 * The return value is an estimate; it might be larger or smaller.
2082 size_t
2083 dirserv_estimate_data_size(smartlist_t *fps, int is_serverdescs,
2084 int compressed)
2086 size_t result;
2087 tor_assert(fps);
2088 if (is_serverdescs) {
2089 int n = smartlist_len(fps);
2090 routerinfo_t *me = router_get_my_routerinfo();
2091 result = (me?me->cache_info.signed_descriptor_len:2048) * n;
2092 if (compressed)
2093 result /= 2; /* observed compressability is between 35 and 55%. */
2094 } else {
2095 result = 0;
2096 SMARTLIST_FOREACH(fps, const char *, d, {
2097 cached_dir_t *dir = digestmap_get(cached_v2_networkstatus, d);
2098 if (dir)
2099 result += compressed ? dir->dir_z_len : dir->dir_len;
2102 return result;
2105 /** When we're spooling data onto our outbuf, add more whenever we dip
2106 * below this threshold. */
2107 #define DIRSERV_BUFFER_MIN 16384
2109 /** Spooling helper: called when we have no more data to spool to <b>conn</b>.
2110 * Flushes any remaining data to be (un)compressed, and changes the spool
2111 * source to NONE. Returns 0 on success, negative on failure. */
2112 static int
2113 connection_dirserv_finish_spooling(dir_connection_t *conn)
2115 if (conn->zlib_state) {
2116 connection_write_to_buf_zlib("", 0, conn, 1);
2117 tor_zlib_free(conn->zlib_state);
2118 conn->zlib_state = NULL;
2120 conn->dir_spool_src = DIR_SPOOL_NONE;
2121 return 0;
2124 /** Spooling helper: called when we're sending a bunch of server descriptors,
2125 * and the outbuf has become too empty. Pulls some entries from
2126 * fingerprint_stack, and writes the corresponding servers onto outbuf. If we
2127 * run out of entries, flushes the zlib state and sets the spool source to
2128 * NONE. Returns 0 on success, negative on failure.
2130 static int
2131 connection_dirserv_add_servers_to_outbuf(dir_connection_t *conn)
2133 int by_fp = conn->dir_spool_src == DIR_SPOOL_SERVER_BY_FP;
2135 while (smartlist_len(conn->fingerprint_stack) &&
2136 buf_datalen(conn->_base.outbuf) < DIRSERV_BUFFER_MIN) {
2137 const char *body;
2138 char *fp = smartlist_pop_last(conn->fingerprint_stack);
2139 signed_descriptor_t *sd = NULL;
2140 if (by_fp) {
2141 if (router_digest_is_me(fp)) {
2142 sd = &(router_get_my_routerinfo()->cache_info);
2143 } else {
2144 routerinfo_t *ri = router_get_by_digest(fp);
2145 if (ri &&
2146 ri->cache_info.published_on > time(NULL)-ROUTER_MAX_AGE_TO_PUBLISH)
2147 sd = &ri->cache_info;
2149 } else
2150 sd = router_get_by_descriptor_digest(fp);
2151 tor_free(fp);
2152 if (!sd)
2153 continue;
2154 body = signed_descriptor_get_body(sd);
2155 if (conn->zlib_state) {
2156 int last = ! smartlist_len(conn->fingerprint_stack);
2157 connection_write_to_buf_zlib(body, sd->signed_descriptor_len, conn,
2158 last);
2159 if (last) {
2160 tor_zlib_free(conn->zlib_state);
2161 conn->zlib_state = NULL;
2163 } else {
2164 connection_write_to_buf(body,
2165 sd->signed_descriptor_len,
2166 TO_CONN(conn));
2170 if (!smartlist_len(conn->fingerprint_stack)) {
2171 /* We just wrote the last one; finish up. */
2172 conn->dir_spool_src = DIR_SPOOL_NONE;
2173 smartlist_free(conn->fingerprint_stack);
2174 conn->fingerprint_stack = NULL;
2176 return 0;
2179 /** Spooling helper: Called when we're sending a directory or networkstatus,
2180 * and the outbuf has become too empty. Pulls some bytes from
2181 * <b>conn</b>-\>cached_dir-\>dir_z, uncompresses them if appropriate, and
2182 * puts them on the outbuf. If we run out of entries, flushes the zlib state
2183 * and sets the spool source to NONE. Returns 0 on success, negative on
2184 * failure. */
2185 static int
2186 connection_dirserv_add_dir_bytes_to_outbuf(dir_connection_t *conn)
2188 ssize_t bytes;
2189 int64_t remaining;
2191 bytes = DIRSERV_BUFFER_MIN - buf_datalen(conn->_base.outbuf);
2192 tor_assert(bytes > 0);
2193 tor_assert(conn->cached_dir);
2194 if (bytes < 8192)
2195 bytes = 8192;
2196 remaining = conn->cached_dir->dir_z_len - conn->cached_dir_offset;
2197 if (bytes > remaining)
2198 bytes = (ssize_t) remaining;
2200 if (conn->zlib_state) {
2201 connection_write_to_buf_zlib(
2202 conn->cached_dir->dir_z + conn->cached_dir_offset,
2203 bytes, conn, bytes == remaining);
2204 } else {
2205 connection_write_to_buf(conn->cached_dir->dir_z + conn->cached_dir_offset,
2206 bytes, TO_CONN(conn));
2208 conn->cached_dir_offset += bytes;
2209 if (conn->cached_dir_offset == (int)conn->cached_dir->dir_z_len) {
2210 /* We just wrote the last one; finish up. */
2211 connection_dirserv_finish_spooling(conn);
2212 cached_dir_decref(conn->cached_dir);
2213 conn->cached_dir = NULL;
2215 return 0;
2218 /** Spooling helper: Called when we're spooling networkstatus objects on
2219 * <b>conn</b>, and the outbuf has become too empty. If the current
2220 * networkstatus object (in <b>conn</b>-\>cached_dir) has more data, pull data
2221 * from there. Otherwise, pop the next fingerprint from fingerprint_stack,
2222 * and start spooling the next networkstatus. If we run out of entries,
2223 * flushes the zlib state and sets the spool source to NONE. Returns 0 on
2224 * success, negative on failure. */
2225 static int
2226 connection_dirserv_add_networkstatus_bytes_to_outbuf(dir_connection_t *conn)
2229 while (buf_datalen(conn->_base.outbuf) < DIRSERV_BUFFER_MIN) {
2230 if (conn->cached_dir) {
2231 int uncompressing = (conn->zlib_state != NULL);
2232 int r = connection_dirserv_add_dir_bytes_to_outbuf(conn);
2233 if (conn->dir_spool_src == DIR_SPOOL_NONE) {
2234 /* add_dir_bytes thinks we're done with the cached_dir. But we
2235 * may have more cached_dirs! */
2236 conn->dir_spool_src = DIR_SPOOL_NETWORKSTATUS;
2237 /* This bit is tricky. If we were uncompressing the last
2238 * networkstatus, we may need to make a new zlib object to
2239 * uncompress the next one. */
2240 if (uncompressing && ! conn->zlib_state &&
2241 conn->fingerprint_stack &&
2242 smartlist_len(conn->fingerprint_stack)) {
2243 conn->zlib_state = tor_zlib_new(0, ZLIB_METHOD);
2246 if (r) return r;
2247 } else if (conn->fingerprint_stack &&
2248 smartlist_len(conn->fingerprint_stack)) {
2249 /* Add another networkstatus; start serving it. */
2250 char *fp = smartlist_pop_last(conn->fingerprint_stack);
2251 cached_dir_t *d;
2252 if (router_digest_is_me(fp))
2253 d = the_v2_networkstatus;
2254 else
2255 d = digestmap_get(cached_v2_networkstatus, fp);
2256 tor_free(fp);
2257 if (d) {
2258 ++d->refcnt;
2259 conn->cached_dir = d;
2260 conn->cached_dir_offset = 0;
2262 } else {
2263 connection_dirserv_finish_spooling(conn);
2264 if (conn->fingerprint_stack)
2265 smartlist_free(conn->fingerprint_stack);
2266 conn->fingerprint_stack = NULL;
2267 return 0;
2270 return 0;
2273 /** Called whenever we have flushed some directory data in state
2274 * SERVER_WRITING. */
2276 connection_dirserv_flushed_some(dir_connection_t *conn)
2278 or_connection_t *or_conn;
2279 tor_assert(conn->_base.state == DIR_CONN_STATE_SERVER_WRITING);
2281 if (buf_datalen(conn->_base.outbuf) >= DIRSERV_BUFFER_MIN)
2282 return 0;
2284 if ((or_conn = connection_dirserv_get_target_or_conn(conn)) &&
2285 connection_or_too_full_for_dirserv_data(or_conn)) {
2286 connection_dirserv_mark_as_blocked(conn);
2287 return 0;
2290 switch (conn->dir_spool_src) {
2291 case DIR_SPOOL_SERVER_BY_DIGEST:
2292 case DIR_SPOOL_SERVER_BY_FP:
2293 return connection_dirserv_add_servers_to_outbuf(conn);
2294 case DIR_SPOOL_CACHED_DIR:
2295 return connection_dirserv_add_dir_bytes_to_outbuf(conn);
2296 case DIR_SPOOL_NETWORKSTATUS:
2297 return connection_dirserv_add_networkstatus_bytes_to_outbuf(conn);
2298 case DIR_SPOOL_NONE:
2299 default:
2300 return 0;
2304 /** Release all storage used by the directory server. */
2305 void
2306 dirserv_free_all(void)
2308 dirserv_free_fingerprint_list();
2310 cached_dir_decref(the_directory);
2311 clear_cached_dir(&the_runningrouters);
2312 cached_dir_decref(the_v2_networkstatus);
2313 cached_dir_decref(cached_directory);
2314 clear_cached_dir(&cached_runningrouters);
2315 if (cached_v2_networkstatus) {
2316 digestmap_free(cached_v2_networkstatus, _free_cached_dir);
2317 cached_v2_networkstatus = NULL;