Convert circuituse, command, config, connection, relay, router, test to new logging...
[tor.git] / src / or / dirserv.c
blob077f06b10f69ac623459978845b568da86ef13a5
1 /* Copyright 2001-2004 Roger Dingledine.
2 * Copyright 2004-2005 Roger Dingledine, Nick Mathewson. */
3 /* See LICENSE for licensing information */
4 /* $Id$ */
5 const char dirserv_c_id[] = "$Id$";
7 #include "or.h"
9 /**
10 * \file dirserv.c
11 * \brief Directory server core implementation. Manages directory
12 * contents and generates directories.
13 **/
15 /** How far in the future do we allow a router to get? (seconds) */
16 #define ROUTER_ALLOW_SKEW (60*60*12) /* 12 hours */
17 /** How many seconds do we wait before regenerating the directory? */
18 #define DIR_REGEN_SLACK_TIME 30
20 extern long stats_n_seconds_working;
22 typedef enum {
23 FP_NAMED, /**< Listed in fingerprint file. */
24 FP_VALID, /**< Unlisted but believed valid. */
25 FP_INVALID, /**< Believed invalid. */
26 FP_REJECT, /**< We will not publish this router. */
27 } router_status_t;
29 /** Do we need to regenerate the directory when someone asks for it? */
30 static int the_directory_is_dirty = 1;
31 static int runningrouters_is_dirty = 1;
32 static int the_v2_networkstatus_is_dirty = 1;
34 static void directory_remove_invalid(void);
35 static int dirserv_regenerate_directory(void);
36 static char *format_versions_list(config_line_t *ln);
37 /* Should be static; exposed for testing */
38 int add_fingerprint_to_dir(const char *nickname, const char *fp, smartlist_t *list);
39 static int router_is_general_exit(routerinfo_t *ri);
40 static router_status_t dirserv_router_get_status(const routerinfo_t *router,
41 const char **msg);
42 static int dirserv_thinks_router_is_reachable(routerinfo_t *router,
43 time_t now);
45 /************** Fingerprint handling code ************/
47 static addr_policy_t *authdir_reject_policy = NULL;
48 static addr_policy_t *authdir_invalid_policy = NULL;
50 /** Parse authdir policy strings from the configuration.
52 void
53 parse_authdir_policy(void)
55 addr_policy_t *n;
56 if (authdir_reject_policy) {
57 addr_policy_free(authdir_reject_policy);
58 authdir_reject_policy = NULL;
60 config_parse_addr_policy(get_options()->AuthDirReject,
61 &authdir_reject_policy, ADDR_POLICY_REJECT);
62 /* ports aren't used. */
63 for (n=authdir_reject_policy; n; n = n->next) {
64 n->prt_min = 1;
65 n->prt_max = 65535;
68 if (authdir_invalid_policy) {
69 addr_policy_free(authdir_invalid_policy);
70 authdir_invalid_policy = NULL;
72 config_parse_addr_policy(get_options()->AuthDirInvalid,
73 &authdir_invalid_policy, ADDR_POLICY_REJECT);
74 /* ports aren't used. */
75 for (n=authdir_invalid_policy; n; n = n->next) {
76 n->prt_min = 1;
77 n->prt_max = 65535;
81 /** A member of fingerprint_list: maps a name to a fingerprint.
82 **/
83 typedef struct fingerprint_entry_t {
84 char *nickname; /**< The name of a router (if this fingerprint is bound to a
85 * name); the string "!reject" (if this fingerprint should
86 * always be rejected); or the string "!invalid" (if this
87 * fingerprint should be accepted but never marked as
88 * valid. */
89 char *fingerprint; /**< Stored as HEX_DIGEST_LEN characters, followed by a NUL */
90 } fingerprint_entry_t;
92 /** List of nickname-\>identity fingerprint mappings for all the routers
93 * that we name. Used to prevent router impersonation. */
94 /* Should be static; exposed for testing */
95 smartlist_t *fingerprint_list = NULL;
97 /** Add the fingerprint <b>fp</b> for the nickname <b>nickname</b> to
98 * the smartlist of fingerprint_entry_t's <b>list</b>. Return 0 if it's
99 * new, or 1 if we replaced the old value.
101 int /* Should be static; exposed for testing */
102 add_fingerprint_to_dir(const char *nickname, const char *fp, smartlist_t *list)
104 int i;
105 fingerprint_entry_t *ent;
106 char *fingerprint;
107 tor_assert(nickname);
108 tor_assert(fp);
109 tor_assert(list);
111 fingerprint = tor_strdup(fp);
112 tor_strstrip(fingerprint, " ");
114 if (nickname[0] != '!') {
115 for (i = 0; i < smartlist_len(list); ++i) {
116 ent = smartlist_get(list, i);
117 if (!strcasecmp(ent->nickname,nickname)) {
118 tor_free(ent->fingerprint);
119 ent->fingerprint = fingerprint;
120 return 1;
124 ent = tor_malloc(sizeof(fingerprint_entry_t));
125 ent->nickname = tor_strdup(nickname);
126 ent->fingerprint = fingerprint;
127 smartlist_add(list, ent);
128 return 0;
131 /** Add the nickname and fingerprint for this OR to the
132 * global list of recognized identity key fingerprints. */
134 dirserv_add_own_fingerprint(const char *nickname, crypto_pk_env_t *pk)
136 char fp[FINGERPRINT_LEN+1];
137 if (crypto_pk_get_fingerprint(pk, fp, 0)<0) {
138 log_fn(LOG_ERR, "Error computing fingerprint");
139 return -1;
141 if (!fingerprint_list)
142 fingerprint_list = smartlist_create();
143 add_fingerprint_to_dir(nickname, fp, fingerprint_list);
144 return 0;
147 /** Parse the nickname-\>fingerprint mappings stored in the file named
148 * <b>fname</b>. The file format is line-based, with each non-blank
149 * holding one nickname, some space, and a fingerprint for that
150 * nickname. On success, replace the current fingerprint list with
151 * the contents of <b>fname</b> and return 0. On failure, leave the
152 * current fingerprint list untouched, and return -1. */
154 dirserv_parse_fingerprint_file(const char *fname)
156 char *cf;
157 char *nickname, *fingerprint;
158 smartlist_t *fingerprint_list_new;
159 int result;
160 config_line_t *front=NULL, *list;
162 cf = read_file_to_str(fname, 0);
163 if (!cf) {
164 log_fn(LOG_WARN, "Cannot open fingerprint file %s", fname);
165 return -1;
167 result = config_get_lines(cf, &front);
168 tor_free(cf);
169 if (result < 0) {
170 log_fn(LOG_WARN, "Error reading from fingerprint file");
171 return -1;
174 fingerprint_list_new = smartlist_create();
176 for (list=front; list; list=list->next) {
177 nickname = list->key; fingerprint = list->value;
178 if (strlen(nickname) > MAX_NICKNAME_LEN) {
179 log(LOG_NOTICE, "Nickname '%s' too long in fingerprint file. Skipping.", nickname);
180 continue;
182 if (!is_legal_nickname(nickname) &&
183 strcasecmp(nickname, "!reject") &&
184 strcasecmp(nickname, "!invalid")) {
185 log(LOG_NOTICE, "Invalid nickname '%s' in fingerprint file. Skipping.", nickname);
186 continue;
188 if (strlen(fingerprint) != FINGERPRINT_LEN ||
189 !crypto_pk_check_fingerprint_syntax(fingerprint)) {
190 log_fn(LOG_NOTICE, "Invalid fingerprint (nickname '%s', fingerprint %s). Skipping.",
191 nickname, fingerprint);
192 continue;
194 if (0==strcasecmp(nickname, DEFAULT_CLIENT_NICKNAME)) {
195 /* If you approved an OR called "client", then clients who use
196 * the default nickname could all be rejected. That's no good. */
197 log(LOG_NOTICE,
198 "Authorizing a nickname '%s' would break many clients; skipping.",
199 DEFAULT_CLIENT_NICKNAME);
200 continue;
202 if (add_fingerprint_to_dir(nickname, fingerprint, fingerprint_list_new) != 0)
203 log(LOG_NOTICE, "Duplicate nickname '%s'.", nickname);
206 config_free_lines(front);
207 dirserv_free_fingerprint_list();
208 fingerprint_list = fingerprint_list_new;
209 /* Delete any routers whose fingerprints we no longer recognize */
210 directory_remove_invalid();
211 return 0;
214 /** Check whether <b>router</b> has a nickname/identity key combination that
215 * we recognize from the fingerprint list, or an IP we automatically act on
216 * according to our configuration. Return the appropriate router status.
218 * If the status is 'FP_REJECT' and <b>msg</b> is provided, set
219 * *<b>msg</b> to an explanation of why.
221 static router_status_t
222 dirserv_router_get_status(const routerinfo_t *router, const char **msg)
224 fingerprint_entry_t *nn_ent = NULL, *fp_ent = NULL;
225 char fp[FINGERPRINT_LEN+1];
227 if (!fingerprint_list)
228 fingerprint_list = smartlist_create();
230 if (crypto_pk_get_fingerprint(router->identity_pkey, fp, 0)) {
231 log_fn(LOG_WARN,"Error computing fingerprint");
232 return -1;
235 log_fn(LOG_DEBUG, "%d fingerprints known.", smartlist_len(fingerprint_list));
236 SMARTLIST_FOREACH(fingerprint_list, fingerprint_entry_t *, ent,
238 if (!strcasecmp(fp,ent->fingerprint))
239 fp_ent = ent;
240 if (!strcasecmp(router->nickname,ent->nickname))
241 nn_ent = ent;
244 if (fp_ent) {
245 if (!strcasecmp(fp_ent->nickname, "!reject")) {
246 if (msg)
247 *msg = "Fingerprint is marked rejected";
248 return FP_REJECT;
249 } else if (!strcasecmp(fp_ent->nickname, "!invalid")) {
250 if (msg)
251 *msg = "Fingerprint is marged invalid";
252 return FP_INVALID;
256 if (!nn_ent) { /* No such server known with that nickname */
257 addr_policy_result_t rej = router_compare_addr_to_addr_policy(
258 router->addr, router->or_port, authdir_reject_policy);
259 addr_policy_result_t inv = router_compare_addr_to_addr_policy(
260 router->addr, router->or_port, authdir_invalid_policy);
262 if (rej == ADDR_POLICY_PROBABLY_REJECTED || rej == ADDR_POLICY_REJECTED) {
263 log_fn(LOG_INFO, "Rejecting '%s' because of address %s",
264 router->nickname, router->address);
265 if (msg)
266 *msg = "Authdir is rejecting routers in this range.";
267 return FP_REJECT;
269 if (inv == ADDR_POLICY_PROBABLY_REJECTED || inv == ADDR_POLICY_REJECTED) {
270 log_fn(LOG_INFO, "Not marking '%s' valid because of address %s",
271 router->nickname, router->address);
272 return FP_INVALID;
274 if (tor_version_as_new_as(router->platform,"0.1.0.2-rc"))
275 return FP_VALID;
276 else
277 return FP_INVALID;
278 log_fn(LOG_INFO,"No fingerprint found for '%s'",router->nickname);
279 return 0;
281 if (0==strcasecmp(nn_ent->fingerprint, fp)) {
282 log_fn(LOG_DEBUG,"Good fingerprint for '%s'",router->nickname);
283 return FP_NAMED; /* Right fingerprint. */
284 } else {
285 log_fn(LOG_WARN,"Mismatched fingerprint for '%s': expected '%s' got '%s'. ContactInfo '%s', platform '%s'.)",
286 router->nickname, nn_ent->fingerprint, fp,
287 router->contact_info ? router->contact_info : "",
288 router->platform ? router->platform : "");
289 if (msg)
290 *msg = "Rejected: There is already a verified server with this nickname and a different fingerprint.";
291 return FP_REJECT; /* Wrong fingerprint. */
295 /** If we are an authoritative dirserver, and the list of approved
296 * servers contains one whose identity key digest is <b>digest</b>,
297 * return that router's nickname. Otherwise return NULL. */
298 const char *
299 dirserv_get_nickname_by_digest(const char *digest)
301 char hexdigest[HEX_DIGEST_LEN+1];
302 if (!fingerprint_list)
303 return NULL;
304 tor_assert(digest);
306 base16_encode(hexdigest, HEX_DIGEST_LEN+1, digest, DIGEST_LEN);
307 SMARTLIST_FOREACH(fingerprint_list, fingerprint_entry_t*, ent,
308 { if (!strcasecmp(hexdigest, ent->fingerprint))
309 return ent->nickname; } );
310 return NULL;
313 /** Clear the current fingerprint list. */
314 void
315 dirserv_free_fingerprint_list(void)
317 int i;
318 fingerprint_entry_t *ent;
319 if (!fingerprint_list)
320 return;
322 for (i = 0; i < smartlist_len(fingerprint_list); ++i) {
323 ent = smartlist_get(fingerprint_list, i);
324 tor_free(ent->nickname);
325 tor_free(ent->fingerprint);
326 tor_free(ent);
328 smartlist_free(fingerprint_list);
329 fingerprint_list = NULL;
333 * Descriptor list
336 /** Return -1 if <b>ri</b> has a private or otherwise bad address,
337 * unless we're configured to not care. Return 0 if all ok. */
338 static int
339 dirserv_router_has_valid_address(routerinfo_t *ri)
341 struct in_addr iaddr;
342 if (get_options()->DirAllowPrivateAddresses)
343 return 0; /* whatever it is, we're fine with it */
344 if (!tor_inet_aton(ri->address, &iaddr)) {
345 log_fn(LOG_INFO,"Router '%s' published non-IP address '%s'. Refusing.",
346 ri->nickname, ri->address);
347 return -1;
349 if (is_internal_IP(ntohl(iaddr.s_addr))) {
350 log_fn(LOG_INFO,"Router '%s' published internal IP address '%s'. Refusing.",
351 ri->nickname, ri->address);
352 return -1; /* it's a private IP, we should reject it */
354 return 0;
357 /** Check whether we, as a directory server, want to accept <b>ri</b>. If so,
358 * return 0, and set its is_valid,named,running fields. Otherwise, return -1.
360 * If the router is rejected, set *<b>msg</b> to an explanation of why.
363 authdir_wants_to_reject_router(routerinfo_t *ri,
364 const char **msg)
366 /* Okay. Now check whether the fingerprint is recognized. */
367 router_status_t status = dirserv_router_get_status(ri, msg);
368 time_t now;
369 tor_assert(msg);
370 if (status == FP_REJECT)
371 return -1; /* msg is already set. */
373 /* Is there too much clock skew? */
374 now = time(NULL);
375 if (ri->published_on > now+ROUTER_ALLOW_SKEW) {
376 log_fn(LOG_NOTICE, "Publication time for nickname '%s' is too far (%d minutes) in the future; possible clock skew. Not adding (ContactInfo '%s', platform '%s').",
377 ri->nickname, (int)((ri->published_on-now)/60),
378 ri->contact_info ? ri->contact_info : "",
379 ri->platform ? ri->platform : "");
380 *msg = "Rejected: Your clock is set too far in the future, or your timezone is not correct.";
381 return -1;
383 if (ri->published_on < now-ROUTER_MAX_AGE) {
384 log_fn(LOG_NOTICE, "Publication time for router with nickname '%s' is too far (%d minutes) in the past. Not adding (ContactInfo '%s', platform '%s').",
385 ri->nickname, (int)((now-ri->published_on)/60),
386 ri->contact_info ? ri->contact_info : "",
387 ri->platform ? ri->platform : "");
388 *msg = "Rejected: Server is expired, or your clock is too far in the past, or your timezone is not correct.";
389 return -1;
391 if (dirserv_router_has_valid_address(ri) < 0) {
392 log_fn(LOG_NOTICE, "Router with nickname '%s' has invalid address '%s'. Not adding (ContactInfo '%s', platform '%s').",
393 ri->nickname, ri->address,
394 ri->contact_info ? ri->contact_info : "",
395 ri->platform ? ri->platform : "");
396 *msg = "Rejected: Address is not an IP, or IP is a private address.";
397 return -1;
399 /* Okay, looks like we're willing to accept this one. */
400 switch (status) {
401 case FP_NAMED:
402 ri->is_named = ri->is_verified = 1;
403 break;
404 case FP_VALID:
405 ri->is_named = 0;
406 ri->is_verified = 1;
407 break;
408 case FP_INVALID:
409 ri->is_named = ri->is_verified = 0;
410 break;
411 default:
412 tor_assert(0);
415 return 0;
418 /** Parse the server descriptor at <b>desc</b> and maybe insert it into
419 * the list of server descriptors. Set *<b>msg</b> to a message that
420 * should be passed back to the origin of this descriptor.
422 * Return 2 if descriptor is well-formed and accepted;
423 * 1 if well-formed and accepted but origin should hear *msg;
424 * 0 if well-formed but redundant with one we already have;
425 * -1 if it looks vaguely like a router descriptor but rejected;
426 * -2 if we can't find a router descriptor in <b>desc</b>.
429 dirserv_add_descriptor(const char *desc, const char **msg)
431 int r;
432 routerinfo_t *ri = NULL, *ri_old = NULL;
433 tor_assert(msg);
434 *msg = NULL;
436 /* Check: is the descriptor syntactically valid? */
437 ri = router_parse_entry_from_string(desc, NULL);
438 if (!ri) {
439 log(LOG_WARN, "Couldn't parse descriptor");
440 *msg = "Rejected: Couldn't parse server descriptor.";
441 return -2;
443 /* Check whether this descriptor is semantically identical to the last one
444 * from this server. (We do this here and not in router_add_to_routerlist
445 * because we want to be able to accept the newest router descriptor that
446 * another authority has, so we all converge on the same one.) */
447 ri_old = router_get_by_digest(ri->identity_digest);
448 if (ri_old && ri_old->published_on < ri->published_on &&
449 router_differences_are_cosmetic(ri_old, ri)) {
450 log_fn(LOG_INFO,
451 "Not replacing descriptor from '%s'; differences are cosmetic.",
452 ri->nickname);
453 *msg = "Not replacing router descriptor; no information has changed since the last one with this identity.";
454 return 0;
456 if ((r = router_add_to_routerlist(ri, msg, 0))<0) {
457 return r == -1 ? 0 : -1;
458 } else {
459 smartlist_t *changed = smartlist_create();
460 smartlist_add(changed, ri);
461 control_event_descriptors_changed(changed);
462 smartlist_free(changed);
463 if (!*msg) {
464 *msg = ri->is_verified ? "Verified server descriptor accepted" :
465 "Unverified server descriptor accepted";
467 return r == 0 ? 2 : 1;
471 /** Remove all descriptors whose nicknames or fingerprints no longer
472 * are allowed by our fingerprint list. (Descriptors that used to be
473 * good can become bad when we reload the fingerprint list.)
475 static void
476 directory_remove_invalid(void)
478 int i;
479 int changed = 0;
480 routerlist_t *rl = router_get_routerlist();
482 for (i = 0; i < smartlist_len(rl->routers); ++i) {
483 const char *msg;
484 routerinfo_t *ent = smartlist_get(rl->routers, i);
485 router_status_t r = dirserv_router_get_status(ent, &msg);
486 switch (r) {
487 case FP_REJECT:
488 log(LOG_INFO, "Router '%s' is now rejected: %s",
489 ent->nickname, msg?msg:"");
490 routerlist_remove(rl, ent, i--);
491 routerinfo_free(ent);
492 changed = 1;
493 break;
494 case FP_NAMED:
495 if (!ent->is_verified || !ent->is_named) {
496 log(LOG_INFO, "Router '%s' is now verified and named.", ent->nickname);
497 ent->is_verified = ent->is_named = 1;
498 changed = 1;
500 break;
501 case FP_VALID:
502 if (!ent->is_verified || ent->is_named) {
503 log(LOG_INFO, "Router '%s' is now verified.", ent->nickname);
504 ent->is_verified = 1;
505 ent->is_named = 0;
506 changed = 1;
508 break;
509 case FP_INVALID:
510 if (ent->is_verified || ent->is_named) {
511 log(LOG_INFO, "Router '%s' is no longer verified.", ent->nickname);
512 ent->is_verified = ent->is_named = 0;
513 changed = 1;
515 break;
518 if (changed)
519 directory_set_dirty();
522 /** Write a list of unregistered descriptors into a newly allocated
523 * string and return it. Used by dirserv operators to keep track of
524 * fast nodes that haven't registered.
526 char *
527 dirserver_getinfo_unregistered(const char *question)
529 router_status_t r;
530 smartlist_t *answerlist;
531 char buf[1024];
532 char *answer;
533 int min_bw = atoi(question);
534 routerlist_t *rl = router_get_routerlist();
536 answerlist = smartlist_create();
537 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ent, {
538 r = dirserv_router_get_status(ent, NULL);
539 if (ent->bandwidthcapacity >= (size_t)min_bw &&
540 ent->bandwidthrate >= (size_t)min_bw &&
541 r != FP_NAMED) {
542 /* then log this one */
543 tor_snprintf(buf, sizeof(buf),
544 "%s: BW %d on '%s'.",
545 ent->nickname, ent->bandwidthcapacity,
546 ent->platform ? ent->platform : "");
547 smartlist_add(answerlist, tor_strdup(buf));
550 answer = smartlist_join_strings(answerlist, "\r\n", 0, NULL);
551 SMARTLIST_FOREACH(answerlist, char *, cp, tor_free(cp));
552 smartlist_free(answerlist);
553 return answer;
556 /** Mark the directory as <b>dirty</b> -- when we're next asked for a
557 * directory, we will rebuild it instead of reusing the most recently
558 * generated one.
560 void
561 directory_set_dirty(void)
563 time_t now = time(NULL);
565 if (!the_directory_is_dirty)
566 the_directory_is_dirty = now;
567 if (!runningrouters_is_dirty)
568 runningrouters_is_dirty = now;
569 if (!the_v2_networkstatus_is_dirty)
570 the_v2_networkstatus_is_dirty = now;
574 * Allocate and return a description of the status of the server <b>desc</b>,
575 * for use in a router-status line. The server is listed
576 * as running iff <b>is_live</b> is true.
578 static char *
579 list_single_server_status(routerinfo_t *desc, int is_live)
581 char buf[MAX_NICKNAME_LEN+HEX_DIGEST_LEN+4]; /* !nickname=$hexdigest\0 */
582 char *cp;
584 tor_assert(desc);
586 cp = buf;
587 if (!is_live) {
588 *cp++ = '!';
590 if (desc->is_verified) {
591 strlcpy(cp, desc->nickname, sizeof(buf)-(cp-buf));
592 cp += strlen(cp);
593 *cp++ = '=';
595 *cp++ = '$';
596 base16_encode(cp, HEX_DIGEST_LEN+1, desc->identity_digest,
597 DIGEST_LEN);
598 return tor_strdup(buf);
601 #define REACHABLE_TIMEOUT (60*60) /* an hour */
602 /* Make sure this is 3 times the value of get_dir_fetch_period() */
604 /** Treat a router as alive if
605 * - It's me, and I'm not hibernating.
606 * or - we're connected to it and we've found it reachable recently. */
607 static int
608 dirserv_thinks_router_is_reachable(routerinfo_t *router, time_t now)
610 connection_t *conn;
611 if (router_is_me(router) && !we_are_hibernating())
612 return 1;
613 conn = connection_get_by_identity_digest(router->identity_digest,
614 CONN_TYPE_OR);
615 if (conn && conn->state == OR_CONN_STATE_OPEN)
616 return get_options()->AssumeReachable ||
617 now < router->last_reachable + REACHABLE_TIMEOUT;
618 return 0;
621 /** Return 1 if we're confident that there's a problem with
622 * <b>router</b>'s reachability and its operator should be notified.
625 dirserv_thinks_router_is_blatantly_unreachable(routerinfo_t *router, time_t now)
627 connection_t *conn;
628 if (router->is_hibernating)
629 return 0;
630 conn = connection_get_by_identity_digest(router->identity_digest,
631 CONN_TYPE_OR);
632 if (conn && conn->state == OR_CONN_STATE_OPEN &&
633 now >= router->last_reachable + 2*REACHABLE_TIMEOUT &&
634 router->testing_since &&
635 now >= router->testing_since + 2*REACHABLE_TIMEOUT)
636 return 1;
637 return 0;
640 /** Based on the routerinfo_ts in <b>routers</b>, allocate the
641 * contents of a router-status line, and store it in
642 * *<b>router_status_out</b>. Return 0 on success, -1 on failure.
645 list_server_status(smartlist_t *routers, char **router_status_out)
647 /* List of entries in a router-status style: An optional !, then an optional
648 * equals-suffixed nickname, then a dollar-prefixed hexdigest. */
649 smartlist_t *rs_entries;
650 time_t now = time(NULL);
651 int authdir_mode = get_options()->AuthoritativeDir;
652 tor_assert(router_status_out);
654 rs_entries = smartlist_create();
656 SMARTLIST_FOREACH(routers, routerinfo_t *, ri,
658 if (authdir_mode) {
659 /* Update router status in routerinfo_t. */
660 ri->is_running = dirserv_thinks_router_is_reachable(ri, now);
662 smartlist_add(rs_entries, list_single_server_status(ri, ri->is_running));
665 *router_status_out = smartlist_join_strings(rs_entries, " ", 0, NULL);
667 SMARTLIST_FOREACH(rs_entries, char *, cp, tor_free(cp));
668 smartlist_free(rs_entries);
670 return 0;
673 /** Helper: Given pointers to two strings describing tor versions, return -1
674 * if _a precedes _b, 1 if _b preceeds _a, and 0 if they are equivalent.
675 * Used to sort a list of versions. */
676 static int
677 _compare_tor_version_str_ptr(const void **_a, const void **_b)
679 const char *a = *_a, *b = *_b;
680 int ca, cb;
681 tor_version_t va, vb;
682 ca = tor_version_parse(a, &va);
683 cb = tor_version_parse(b, &vb);
684 /* If they both parse, compare them. */
685 if (!ca && !cb)
686 return tor_version_compare(&va,&vb);
687 /* If one parses, it comes first. */
688 if (!ca && cb)
689 return -1;
690 if (ca && !cb)
691 return 1;
692 /* If neither parses, compare strings. Also, the directory server admin needs
693 ** to be smacked upside the head. But Tor is tolerant and gentle. */
694 return strcmp(a,b);
697 /* Given a (possibly empty) list of config_line_t, each line of which contains
698 * a list of comma-separated version numbers surrounded by optional space,
699 * allocate and return a new string containing the version numbers, in order,
700 * separated by commas. Used to generate Recommended(Client|Server)?Versions
702 static char *
703 format_versions_list(config_line_t *ln)
705 smartlist_t *versions;
706 char *result;
707 versions = smartlist_create();
708 for ( ; ln; ln = ln->next) {
709 smartlist_split_string(versions, ln->value, ",",
710 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
712 smartlist_sort(versions, _compare_tor_version_str_ptr);
713 result = smartlist_join_strings(versions,",",0,NULL);
714 SMARTLIST_FOREACH(versions,char *,s,tor_free(s));
715 smartlist_free(versions);
716 return result;
719 /** Generate a new directory and write it into a newly allocated string.
720 * Point *<b>dir_out</b> to the allocated string. Sign the
721 * directory with <b>private_key</b>. Return 0 on success, -1 on
722 * failure.
725 dirserv_dump_directory_to_string(char **dir_out,
726 crypto_pk_env_t *private_key)
728 char *cp;
729 char *router_status;
730 char *identity_pkey; /* Identity key, DER64-encoded. */
731 char *recommended_versions;
732 char digest[DIGEST_LEN];
733 char published[ISO_TIME_LEN+1];
734 time_t published_on;
735 char *buf = NULL;
736 size_t buf_len;
737 size_t identity_pkey_len;
738 routerlist_t *rl = router_get_routerlist();
740 tor_assert(dir_out);
741 *dir_out = NULL;
743 if (list_server_status(rl->routers, &router_status))
744 return -1;
746 if (crypto_pk_write_public_key_to_string(private_key,&identity_pkey,
747 &identity_pkey_len)<0) {
748 log_fn(LOG_WARN,"write identity_pkey to string failed!");
749 return -1;
752 recommended_versions = format_versions_list(get_options()->RecommendedVersions);
754 published_on = time(NULL);
755 format_iso_time(published, published_on);
757 buf_len = 2048+strlen(recommended_versions)+
758 strlen(router_status);
759 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri,
760 buf_len += ri->signed_descriptor_len+1);
761 buf = tor_malloc(buf_len);
762 /* We'll be comparing against buf_len throughout the rest of the
763 function, though strictly speaking we shouldn't be able to exceed
764 it. This is C, after all, so we may as well check for buffer
765 overruns.*/
767 tor_snprintf(buf, buf_len,
768 "signed-directory\n"
769 "published %s\n"
770 "recommended-software %s\n"
771 "router-status %s\n"
772 "dir-signing-key\n%s\n",
773 published, recommended_versions, router_status,
774 identity_pkey);
776 tor_free(recommended_versions);
777 tor_free(router_status);
778 tor_free(identity_pkey);
780 cp = buf + strlen(buf);
781 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri,
783 if (cp+ri->signed_descriptor_len+1 >= buf+buf_len)
784 goto truncated;
785 memcpy(cp, ri->signed_descriptor, ri->signed_descriptor_len);
786 cp += ri->signed_descriptor_len;
787 *cp++ = '\n'; /* add an extra newline in case somebody was depending on
788 * it. */
790 *cp = '\0';
792 /* These multiple strlcat calls are inefficient, but dwarfed by the RSA
793 signature.
795 if (strlcat(buf, "directory-signature ", buf_len) >= buf_len)
796 goto truncated;
797 if (strlcat(buf, get_options()->Nickname, buf_len) >= buf_len)
798 goto truncated;
799 if (strlcat(buf, "\n", buf_len) >= buf_len)
800 goto truncated;
802 if (router_get_dir_hash(buf,digest)) {
803 log_fn(LOG_WARN,"couldn't compute digest");
804 tor_free(buf);
805 return -1;
807 if (router_append_dirobj_signature(buf,buf_len,digest,private_key)<0) {
808 tor_free(buf);
809 return -1;
812 *dir_out = buf;
813 return 0;
814 truncated:
815 log_fn(LOG_WARN,"tried to exceed string length.");
816 tor_free(buf);
817 return -1;
820 /** Most recently generated encoded signed directory. (auth dirservers only.)*/
821 static cached_dir_t the_directory = { NULL, NULL, 0, 0, 0 };
823 /* Used only by non-auth dirservers: The directory and runningrouters we'll
824 * serve when requested. */
825 static cached_dir_t cached_directory = { NULL, NULL, 0, 0, 0 };
826 static cached_dir_t cached_runningrouters = { NULL, NULL, 0, 0, 0 };
828 /* Used for other dirservers' v2 network statuses. Map from hexdigest to
829 * cached_dir_t. */
830 static digestmap_t *cached_v2_networkstatus = NULL;
832 /** Possibly replace the contents of <b>d</b> with the value of
833 * <b>directory</b> published on <b>when</b>, unless <b>when</b> is older than
834 * the last value, or too far in the future.
836 * Does not copy <b>directory</b>; free it if it isn't used.
838 static void
839 set_cached_dir(cached_dir_t *d, char *directory, time_t when)
841 time_t now = time(NULL);
842 if (when<=d->published) {
843 log_fn(LOG_INFO, "Ignoring old directory; not caching.");
844 tor_free(directory);
845 } else if (when>=now+ROUTER_MAX_AGE) {
846 log_fn(LOG_INFO, "Ignoring future directory; not caching.");
847 tor_free(directory);
848 } else {
849 /* if (when>d->published && when<now+ROUTER_MAX_AGE) */
850 log_fn(LOG_DEBUG, "Caching directory.");
851 tor_free(d->dir);
852 d->dir = directory;
853 d->dir_len = strlen(directory);
854 tor_free(d->dir_z);
855 if (tor_gzip_compress(&(d->dir_z), &(d->dir_z_len), d->dir, d->dir_len,
856 ZLIB_METHOD)) {
857 log_fn(LOG_WARN,"Error compressing cached directory");
859 d->published = when;
863 /** Remove all storage held in <b>d</b>, but do not free <b>d</b> itself. */
864 static void
865 clear_cached_dir(cached_dir_t *d)
867 tor_free(d->dir);
868 tor_free(d->dir_z);
869 memset(d, 0, sizeof(cached_dir_t));
872 /** Free all storage held by the cached_dir_t in <b>d</b>. */
873 static void
874 free_cached_dir(void *_d)
876 cached_dir_t *d = (cached_dir_t *)_d;
877 clear_cached_dir(d);
878 tor_free(d);
881 /** If we have no cached directory, or it is older than <b>when</b>, then
882 * replace it with <b>directory</b>, published at <b>when</b>.
884 void
885 dirserv_set_cached_directory(const char *directory, time_t published,
886 int is_running_routers)
888 cached_dir_t *d;
889 d = is_running_routers ? &cached_runningrouters : &cached_directory;
890 set_cached_dir(d, tor_strdup(directory), published);
893 /** We've just received a v2 network-status for an authoritative directory
894 * with identity digest <b>identity</b> published at
895 * <b>published</b>. Store it so we can serve it to others. If
896 * <b>directory</b> is NULL, remove the entry with the given fingerprint from
897 * the cache.
899 void
900 dirserv_set_cached_networkstatus_v2(const char *directory,
901 const char *identity,
902 time_t published)
904 cached_dir_t *d;
905 if (!cached_v2_networkstatus)
906 cached_v2_networkstatus = digestmap_new();
908 if (!(d = digestmap_get(cached_v2_networkstatus, identity))) {
909 if (!directory)
910 return;
911 d = tor_malloc_zero(sizeof(cached_dir_t));
912 digestmap_set(cached_v2_networkstatus, identity, d);
915 tor_assert(d);
916 if (directory) {
917 set_cached_dir(d, tor_strdup(directory), published);
918 } else {
919 free_cached_dir(d);
920 digestmap_remove(cached_v2_networkstatus, identity);
924 /** Helper: If we're an authority for the right directory version (the
925 * directory version is determined by <b>is_v1_object</b>), try to regenerate
926 * auth_src as appropriate and return it, falling back to cache_src on
927 * failure. If we're a cache, return cach_src.
929 static cached_dir_t *
930 dirserv_pick_cached_dir_obj(cached_dir_t *cache_src,
931 cached_dir_t *auth_src,
932 time_t dirty, int (*regenerate)(void),
933 const char *name,
934 int is_v1_object)
936 int authority = get_options()->AuthoritativeDir &&
937 (!is_v1_object || get_options()->V1AuthoritativeDir);
939 if (!authority) {
940 return cache_src;
941 } else {
942 /* We're authoritative. */
943 if (regenerate != NULL) {
944 if (dirty && dirty + DIR_REGEN_SLACK_TIME < time(NULL)) {
945 if (regenerate()) {
946 log_fn(LOG_ERR, "Couldn't generate %s?", name);
947 exit(1);
949 } else {
950 log_fn(LOG_INFO, "The %s is still clean; reusing.", name);
953 return auth_src ? auth_src : cache_src;
957 /** Helper: If we're authoritative and <b>auth_src</b> is set, use
958 * <b>auth_src</b>, otherwise use <b>cache_src</b>. If we're using
959 * <b>auth_src</b> and it's been <b>dirty</b> for at least
960 * DIR_REGEN_SLACK_TIME seconds, call <b>regenerate</b>() to make a fresh one.
961 * Yields the compressed version of the directory object if <b>compress</b> is
962 * set; otherwise return the uncompressed version. (In either case, sets
963 * *<b>out</b> and returns the size of the buffer in *<b>out</b>.)
965 * Use <b>is_v1_object</b> to help determine whether we're authoritative for
966 * this kind of object.
968 static size_t
969 dirserv_get_obj(const char **out, int compress,
970 cached_dir_t *cache_src,
971 cached_dir_t *auth_src,
972 time_t dirty, int (*regenerate)(void),
973 const char *name,
974 int is_v1_object)
976 cached_dir_t *d = dirserv_pick_cached_dir_obj(
977 cache_src, auth_src,
978 dirty, regenerate, name, is_v1_object);
980 if (!d)
981 return 0;
982 *out = compress ? d->dir_z : d->dir;
983 if (*out) {
984 return compress ? d->dir_z_len : d->dir_len;
985 } else {
986 /* not yet available. */
987 return 0;
991 /** Set *<b>directory</b> to the most recently generated encoded signed
992 * directory, generating a new one as necessary. If not an authoritative
993 * directory may return 0 if no directory is yet cached.*/
994 size_t
995 dirserv_get_directory(const char **directory, int compress)
997 return dirserv_get_obj(directory, compress,
998 &cached_directory, &the_directory,
999 the_directory_is_dirty,
1000 dirserv_regenerate_directory,
1001 "server directory", 1);
1005 * Generate a fresh directory (authdirservers only.)
1007 static int
1008 dirserv_regenerate_directory(void)
1010 char *new_directory=NULL;
1012 if (dirserv_dump_directory_to_string(&new_directory,
1013 get_identity_key())) {
1014 log(LOG_WARN, "Error creating directory.");
1015 tor_free(new_directory);
1016 return -1;
1018 set_cached_dir(&the_directory, new_directory, time(NULL));
1019 log_fn(LOG_INFO,"New directory (size %d) has been built.",(int)the_directory.dir_len);
1020 log_fn(LOG_DEBUG,"New directory (size %d):\n%s",(int)the_directory.dir_len,
1021 the_directory.dir);
1023 the_directory_is_dirty = 0;
1025 /* Save the directory to disk so we re-load it quickly on startup.
1027 dirserv_set_cached_directory(the_directory.dir, time(NULL), 0);
1029 return 0;
1032 /** For authoritative directories: the current (v1) network status */
1033 static cached_dir_t the_runningrouters = { NULL, NULL, 0, 0, 0 };
1035 /** Replace the current running-routers list with a newly generated one. */
1036 static int
1037 generate_runningrouters(void)
1039 char *s=NULL;
1040 char *router_status=NULL;
1041 char digest[DIGEST_LEN];
1042 char published[ISO_TIME_LEN+1];
1043 size_t len;
1044 crypto_pk_env_t *private_key = get_identity_key();
1045 char *identity_pkey; /* Identity key, DER64-encoded. */
1046 size_t identity_pkey_len;
1047 routerlist_t *rl = router_get_routerlist();
1049 if (list_server_status(rl->routers, &router_status)) {
1050 goto err;
1052 if (crypto_pk_write_public_key_to_string(private_key,&identity_pkey,
1053 &identity_pkey_len)<0) {
1054 log_fn(LOG_WARN,"write identity_pkey to string failed!");
1055 goto err;
1057 format_iso_time(published, time(NULL));
1059 len = 2048+strlen(router_status);
1060 s = tor_malloc_zero(len);
1061 tor_snprintf(s, len,
1062 "network-status\n"
1063 "published %s\n"
1064 "router-status %s\n"
1065 "dir-signing-key\n%s"
1066 "directory-signature %s\n",
1067 published, router_status, identity_pkey, get_options()->Nickname);
1068 tor_free(router_status);
1069 tor_free(identity_pkey);
1070 if (router_get_runningrouters_hash(s,digest)) {
1071 log_fn(LOG_WARN,"couldn't compute digest");
1072 goto err;
1074 if (router_append_dirobj_signature(s, len, digest, private_key)<0)
1075 goto err;
1077 set_cached_dir(&the_runningrouters, s, time(NULL));
1078 runningrouters_is_dirty = 0;
1080 return 0;
1081 err:
1082 tor_free(s);
1083 tor_free(router_status);
1084 return -1;
1087 /** Set *<b>rr</b> to the most recently generated encoded signed
1088 * running-routers list, generating a new one as necessary. Return the
1089 * size of the directory on success, and 0 on failure. */
1090 size_t
1091 dirserv_get_runningrouters(const char **rr, int compress)
1093 return dirserv_get_obj(rr, compress,
1094 &cached_runningrouters, &the_runningrouters,
1095 runningrouters_is_dirty,
1096 generate_runningrouters,
1097 "v1 network status list", 1);
1100 /** Return true iff <b>ri</b> is "useful as an exit node", meaning
1101 * it allows exit to at least one /8 address space for at least
1102 * one of ports 80, 443, and 6667. */
1103 static int
1104 router_is_general_exit(routerinfo_t *ri)
1106 static const int ports[] = { 80, 443, 6667 };
1107 int n_allowed = 0;
1108 int i;
1109 for (i = 0; i < 3; ++i) {
1110 struct addr_policy_t *policy = ri->exit_policy;
1111 for ( ; policy; policy = policy->next) {
1112 if (policy->prt_min > ports[i] || policy->prt_max < ports[i])
1113 continue; /* Doesn't cover our port. */
1114 if ((policy->msk & 0x00fffffful) != 0)
1115 continue; /* Narrower than a /8. */
1116 if ((policy->addr & 0xff000000ul) == 0x7f000000ul)
1117 continue; /* 127.x */
1118 /* We have a match that is at least a /8. */
1119 if (policy->policy_type == ADDR_POLICY_ACCEPT)
1120 ++n_allowed;
1121 break;
1124 return n_allowed > 0;
1127 /** For authoritative directories: the current (v2) network status */
1128 static cached_dir_t the_v2_networkstatus = { NULL, NULL, 0, 0, 0 };
1130 /** For authoritative directories only: replace the contents of
1131 * <b>the_v2_networkstatus</b> with a newly generated network status
1132 * object. */
1133 static int
1134 generate_v2_networkstatus(void)
1136 #define LONGEST_STATUS_FLAG_NAME_LEN 7
1137 #define N_STATUS_FLAGS 6
1138 #define RS_ENTRY_LEN \
1139 ( /* first line */ \
1140 MAX_NICKNAME_LEN+BASE64_DIGEST_LEN*2+ISO_TIME_LEN+INET_NTOA_BUF_LEN+ \
1141 5*2 /* ports */ + 10 /* punctuation */ + \
1142 /* second line */ \
1143 (LONGEST_STATUS_FLAG_NAME_LEN+1)*N_STATUS_FLAGS + 2)
1145 int r = -1;
1146 size_t len, identity_pkey_len;
1147 char *status = NULL, *client_versions = NULL, *server_versions = NULL,
1148 *identity_pkey = NULL, *hostname = NULL;
1149 char *outp, *endp;
1150 or_options_t *options = get_options();
1151 char fingerprint[FINGERPRINT_LEN+1];
1152 char ipaddr[INET_NTOA_BUF_LEN+1];
1153 char published[ISO_TIME_LEN];
1154 char digest[DIGEST_LEN];
1155 struct in_addr in;
1156 uint32_t addr;
1157 crypto_pk_env_t *private_key = get_identity_key();
1158 routerlist_t *rl = router_get_routerlist();
1159 time_t now = time(NULL);
1160 int naming = options->NamingAuthoritativeDir;
1161 int versioning = options->VersioningAuthoritativeDir;
1162 const char *contact;
1164 if (resolve_my_address(options, &addr, &hostname)<0) {
1165 log_fn(LOG_WARN, "Couldn't resolve my hostname");
1166 goto done;
1168 in.s_addr = htonl(addr);
1169 tor_inet_ntoa(&in, ipaddr, sizeof(ipaddr));
1171 format_iso_time(published, time(NULL));
1173 client_versions = format_versions_list(options->RecommendedClientVersions);
1174 server_versions = format_versions_list(options->RecommendedServerVersions);
1176 if (crypto_pk_write_public_key_to_string(private_key, &identity_pkey,
1177 &identity_pkey_len)<0) {
1178 log_fn(LOG_WARN,"Writing public key to string failed.");
1179 goto done;
1182 if (crypto_pk_get_fingerprint(private_key, fingerprint, 0)<0) {
1183 log_fn(LOG_ERR, "Error computing fingerprint");
1184 goto done;
1187 contact = get_options()->ContactInfo;
1188 if (!contact)
1189 contact = "(none)";
1191 len = 2048+strlen(client_versions)+strlen(server_versions)+identity_pkey_len*2;
1192 len += (RS_ENTRY_LEN)*smartlist_len(rl->routers);
1194 status = tor_malloc(len);
1195 tor_snprintf(status, len,
1196 "network-status-version 2\n"
1197 "dir-source %s %s %d\n"
1198 "fingerprint %s\n"
1199 "contact %s\n"
1200 "published %s\n"
1201 "dir-options%s%s\n"
1202 "client-versions %s\n"
1203 "server-versions %s\n"
1204 "dir-signing-key\n%s\n",
1205 hostname, ipaddr, (int)options->DirPort,
1206 fingerprint,
1207 contact,
1208 published,
1209 naming ? " Names" : "",
1210 versioning ? " Versions" : "",
1211 client_versions,
1212 server_versions,
1213 identity_pkey);
1214 outp = status + strlen(status);
1215 endp = status + len;
1217 SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
1218 int f_exit = router_is_general_exit(ri);
1219 int f_stable = !router_is_unreliable(ri, 1, 0);
1220 int f_fast = !router_is_unreliable(ri, 0, 1);
1221 int f_running;
1222 int f_authority = router_digest_is_trusted_dir(ri->identity_digest);
1223 int f_named = naming && ri->is_named;
1224 int f_valid = ri->is_verified;
1225 char identity64[BASE64_DIGEST_LEN+1];
1226 char digest64[BASE64_DIGEST_LEN+1];
1227 if (options->AuthoritativeDir) {
1228 ri->is_running = dirserv_thinks_router_is_reachable(ri, now);
1230 f_running = ri->is_running;
1232 format_iso_time(published, ri->published_on);
1234 digest_to_base64(identity64, ri->identity_digest);
1235 digest_to_base64(digest64, ri->signed_descriptor_digest);
1237 in.s_addr = htonl(ri->addr);
1238 tor_inet_ntoa(&in, ipaddr, sizeof(ipaddr));
1240 if (tor_snprintf(outp, endp-outp,
1241 "r %s %s %s %s %s %d %d\n"
1242 "s%s%s%s%s%s%s%s\n",
1243 ri->nickname,
1244 identity64,
1245 digest64,
1246 published,
1247 ipaddr,
1248 ri->or_port,
1249 ri->dir_port,
1250 f_authority?" Authority":"",
1251 f_exit?" Exit":"",
1252 f_fast?" Fast":"",
1253 f_named?" Named":"",
1254 f_stable?" Stable":"",
1255 f_running?" Running":"",
1256 f_valid?" Valid":"")<0) {
1257 log_fn(LOG_WARN, "Unable to print router status.");
1258 goto done;
1260 outp += strlen(outp);
1263 if (tor_snprintf(outp, endp-outp, "directory-signature %s\n",
1264 get_options()->Nickname)<0) {
1265 log_fn(LOG_WARN, "Unable to write signature line.");
1266 goto done;
1269 if (router_get_networkstatus_v2_hash(status, digest)<0) {
1270 log_fn(LOG_WARN, "Unable to hash network status");
1271 goto done;
1274 if (router_append_dirobj_signature(outp,endp-outp,digest,private_key)<0) {
1275 log_fn(LOG_WARN, "Unable to sign router status.");
1276 goto done;
1279 set_cached_dir(&the_v2_networkstatus, status, time(NULL));
1280 status = NULL; /* So it doesn't get double-freed. */
1281 the_v2_networkstatus_is_dirty = 0;
1282 router_set_networkstatus(the_v2_networkstatus.dir, time(NULL), NS_GENERATED,
1283 NULL);
1285 r = 0;
1286 done:
1287 tor_free(client_versions);
1288 tor_free(server_versions);
1289 tor_free(status);
1290 tor_free(hostname);
1291 tor_free(identity_pkey);
1292 return r;
1295 /** Look for a network status object as specified by <b>key</b>, which should
1296 * be either "authority" (to find a network status generated by us), a hex
1297 * identity digest (to find a network status generated by given directory), or
1298 * "all" (to return all the v2 network status objects we have, concatenated).
1299 * If <b>compress</b>, find the version compressed with zlib. Return 0 if
1300 * nothing was found; otherwise set *<b>directory</b> to the matching network
1301 * status and return its length.
1304 dirserv_get_networkstatus_v2(smartlist_t *result,
1305 const char *key)
1307 tor_assert(result);
1309 if (!cached_v2_networkstatus)
1310 cached_v2_networkstatus = digestmap_new();
1312 if (!(strcmp(key,"authority"))) {
1313 if (get_options()->AuthoritativeDir) {
1314 cached_dir_t *d =
1315 dirserv_pick_cached_dir_obj(NULL,
1316 &the_v2_networkstatus,
1317 the_v2_networkstatus_is_dirty,
1318 generate_v2_networkstatus,
1319 "network status list", 0);
1320 if (d)
1321 smartlist_add(result, d);
1322 else
1323 log_fn(LOG_WARN,"Unable to generate an authoritative network status.");
1325 } else if (!strcmp(key, "all")) {
1326 digestmap_iter_t *iter = digestmap_iter_init(cached_v2_networkstatus);
1327 while (!digestmap_iter_done(iter)) {
1328 const char *ident;
1329 void *val;
1330 digestmap_iter_get(iter, &ident, &val);
1331 smartlist_add(result, val);
1332 iter = digestmap_iter_next(cached_v2_networkstatus, iter);
1334 if (smartlist_len(result) == 0)
1335 log_fn(LOG_WARN, "Client requested 'all' network status objects; we have none.");
1336 } else if (!strcmpstart(key, "fp/")) {
1337 smartlist_t *digests = smartlist_create();
1338 dir_split_resource_into_fingerprints(key+3, digests, NULL, 1);
1339 SMARTLIST_FOREACH(digests, char *, cp,
1341 cached_dir_t *cached;
1342 tor_strupper(cp);
1343 if (router_fingerprint_is_me(cp) &&
1344 get_options()->AuthoritativeDir &&
1345 the_v2_networkstatus_is_dirty &&
1346 the_v2_networkstatus_is_dirty + DIR_REGEN_SLACK_TIME < time(NULL))
1347 generate_v2_networkstatus();
1348 cached = digestmap_get(cached_v2_networkstatus, cp);
1349 if (cached) {
1350 smartlist_add(result, cached);
1351 } else {
1352 char hexbuf[HEX_DIGEST_LEN+1];
1353 base16_encode(hexbuf, sizeof(hexbuf), cp, DIGEST_LEN);
1354 log_fn(LOG_INFO, "Don't know about any network status with fingerprint '%s'", hexbuf);
1356 tor_free(cp);
1358 smartlist_free(digests);
1360 return 0;
1363 /** Add a routerinfo_t to <b>descs_out</b> for each router matching
1364 * <b>key</b>. The key should be either
1365 * - "/tor/server/authority" for our own routerinfo;
1366 * - "/tor/server/all" for all the routerinfos we have, concatenated;
1367 * - "/tor/server/fp/FP" where FP is a plus-separated sequence of
1368 * hex identity digests; or
1369 * - "/tor/server/d/D" where D is a plus-separated sequence
1370 * of server descriptor digests, in hex.
1372 * Return -1 if we do not have any descriptors, no matching descriptors,
1373 * or if we did not recognize the key (URL), 0 otherwise (i.e. we found some
1374 * matching descriptors). If -1 is returned <b>msg</b> will be set to
1375 * an appropriate error message.
1378 dirserv_get_routerdescs(smartlist_t *descs_out, const char *key,
1379 const char **msg)
1381 *msg = NULL;
1383 if (!strcmp(key, "/tor/server/all")) {
1384 routerlist_t *rl = router_get_routerlist();
1385 smartlist_add_all(descs_out, rl->routers);
1386 } else if (!strcmp(key, "/tor/server/authority")) {
1387 routerinfo_t *ri = router_get_my_routerinfo();
1388 if (ri)
1389 smartlist_add(descs_out, ri);
1390 } else if (!strcmpstart(key, "/tor/server/d/")) {
1391 smartlist_t *digests = smartlist_create();
1392 key += strlen("/tor/server/d/");
1393 dir_split_resource_into_fingerprints(key, digests, NULL, 1);
1394 SMARTLIST_FOREACH(digests, const char *, d,
1396 routerinfo_t *ri = router_get_by_descriptor_digest(d);
1397 if (ri)
1398 smartlist_add(descs_out,ri);
1400 SMARTLIST_FOREACH(digests, char *, d, tor_free(d));
1401 smartlist_free(digests);
1402 } else if (!strcmpstart(key, "/tor/server/fp/")) {
1403 smartlist_t *digests = smartlist_create();
1404 key += strlen("/tor/server/fp/");
1405 dir_split_resource_into_fingerprints(key, digests, NULL, 1);
1406 SMARTLIST_FOREACH(digests, const char *, d,
1408 if (router_digest_is_me(d)) {
1409 smartlist_add(descs_out, router_get_my_routerinfo());
1410 } else {
1411 routerinfo_t *ri = router_get_by_digest(d);
1412 if (ri)
1413 smartlist_add(descs_out,ri);
1416 SMARTLIST_FOREACH(digests, char *, d, tor_free(d));
1417 smartlist_free(digests);
1418 } else {
1419 *msg = "Key not recognized";
1420 return -1;
1423 if (!smartlist_len(descs_out)) {
1424 *msg = "Servers unavailable";
1425 return -1;
1427 return 0;
1430 /** Called when a TLS handshake has completed successfully with a
1431 * router listening at <b>address</b>:<b>or_port</b>, and has yielded
1432 * a certificate with digest <b>digest_rcvd</b> and nickname
1433 * <b>nickname_rcvd</b>. When this happens, it's clear that any other
1434 * descriptors for that address/port combination must be unusable:
1435 * delete them if they are not verified.
1437 * Also, if as_advertised is 1, then inform the reachability checker
1438 * that we could get to this guy.
1440 void
1441 dirserv_orconn_tls_done(const char *address,
1442 uint16_t or_port,
1443 const char *digest_rcvd,
1444 const char *nickname_rcvd,
1445 int as_advertised)
1447 int i;
1448 routerlist_t *rl = router_get_routerlist();
1449 tor_assert(address);
1450 tor_assert(digest_rcvd);
1451 tor_assert(nickname_rcvd);
1453 // XXXXNM We should really have a better solution here than dropping
1454 // XXXXNM whole routers; otherwise, they come back way too easily.
1455 for (i = 0; i < smartlist_len(rl->routers); ++i) {
1456 routerinfo_t *ri = smartlist_get(rl->routers, i);
1457 int drop = 0;
1458 if (strcasecmp(address, ri->address) || or_port != ri->or_port)
1459 continue;
1460 if (!ri->is_verified) {
1461 /* We have a router at the same address! */
1462 if (strcasecmp(ri->nickname, nickname_rcvd)) {
1463 log_fn(LOG_NOTICE, "Dropping descriptor: nickname '%s' does not match nickname '%s' in cert from %s:%d",
1464 ri->nickname, nickname_rcvd, address, or_port);
1465 drop = 1;
1466 } else if (memcmp(ri->identity_digest, digest_rcvd, DIGEST_LEN)) {
1467 log_fn(LOG_NOTICE, "Dropping descriptor: identity key does not match key in cert from %s:%d",
1468 address, or_port);
1469 drop = 1;
1472 if (drop) {
1473 routerlist_remove(rl, ri, i--);
1474 routerinfo_free(ri);
1475 directory_set_dirty();
1476 } else { /* correct nickname and digest. mark this router reachable! */
1477 log_fn(LOG_INFO,"Found router %s to be reachable. Yay.", ri->nickname);
1478 ri->last_reachable = time(NULL);
1479 ri->num_unreachable_notifications = 0;
1484 /** Release all storage used by the directory server. */
1485 void
1486 dirserv_free_all(void)
1488 if (fingerprint_list) {
1489 SMARTLIST_FOREACH(fingerprint_list, fingerprint_entry_t*, fp,
1490 { tor_free(fp->nickname);
1491 tor_free(fp->fingerprint);
1492 tor_free(fp); });
1493 smartlist_free(fingerprint_list);
1494 fingerprint_list = NULL;
1496 if (authdir_reject_policy)
1497 addr_policy_free(authdir_reject_policy);
1498 if (authdir_invalid_policy)
1499 addr_policy_free(authdir_invalid_policy);
1500 clear_cached_dir(&the_directory);
1501 clear_cached_dir(&the_runningrouters);
1502 clear_cached_dir(&cached_directory);
1503 clear_cached_dir(&cached_runningrouters);
1504 if (cached_v2_networkstatus) {
1505 digestmap_free(cached_v2_networkstatus, free_cached_dir);
1506 cached_v2_networkstatus = NULL;