1 /* Copyright 2001-2004 Roger Dingledine.
2 * Copyright 2004-2006 Roger Dingledine, Nick Mathewson. */
3 /* See LICENSE for licensing information */
5 const char dirserv_c_id
[] =
12 * \brief Directory server core implementation. Manages directory
13 * contents and generates directories.
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 extern long stats_n_seconds_working
;
27 FP_NAMED
, /**< Listed in fingerprint file. */
28 FP_VALID
, /**< Unlisted but believed valid. */
29 FP_INVALID
, /**< Believed invalid. */
30 FP_REJECT
, /**< We will not publish this router. */
33 /** Do we need to regenerate the directory when someone asks for it? */
34 static int the_directory_is_dirty
= 1;
35 static int runningrouters_is_dirty
= 1;
36 static int the_v2_networkstatus_is_dirty
= 1;
38 static void directory_remove_invalid(void);
39 static int dirserv_regenerate_directory(void);
40 static char *format_versions_list(config_line_t
*ln
);
41 /* Should be static; exposed for testing */
42 int add_fingerprint_to_dir(const char *nickname
, const char *fp
,
44 static int router_is_general_exit(routerinfo_t
*ri
);
45 static router_status_t
dirserv_router_get_status(const routerinfo_t
*router
,
47 static router_status_t
48 dirserv_get_status_impl(const char *fp
, const char *nickname
,
50 uint32_t addr
, uint16_t or_port
,
51 const char *platform
, const char *contact
,
52 const char **msg
, int should_log
);
53 static int dirserv_thinks_router_is_reachable(routerinfo_t
*router
,
56 /************** Fingerprint handling code ************/
58 static addr_policy_t
*authdir_reject_policy
= NULL
;
59 static addr_policy_t
*authdir_invalid_policy
= NULL
;
61 /** Parse authdir policy strings from the configuration.
64 parse_authdir_policy(void)
67 if (authdir_reject_policy
) {
68 addr_policy_free(authdir_reject_policy
);
69 authdir_reject_policy
= NULL
;
71 config_parse_addr_policy(get_options()->AuthDirReject
,
72 &authdir_reject_policy
, ADDR_POLICY_REJECT
);
73 /* ports aren't used. */
74 for (n
=authdir_reject_policy
; n
; n
= n
->next
) {
79 if (authdir_invalid_policy
) {
80 addr_policy_free(authdir_invalid_policy
);
81 authdir_invalid_policy
= NULL
;
83 config_parse_addr_policy(get_options()->AuthDirInvalid
,
84 &authdir_invalid_policy
, ADDR_POLICY_REJECT
);
85 /* ports aren't used. */
86 for (n
=authdir_invalid_policy
; n
; n
= n
->next
) {
92 /** A member of fingerprint_list: maps a name to a fingerprint.
94 typedef struct fingerprint_entry_t
{
95 char *nickname
; /**< The name of a router (if this fingerprint is bound to a
96 * name); the string "!reject" (if this fingerprint should
97 * always be rejected); or the string "!invalid" (if this
98 * fingerprint should be accepted but never marked as
100 char *fingerprint
; /**< Stored as HEX_DIGEST_LEN characters, followed by a
102 } fingerprint_entry_t
;
104 /** List of nickname-\>identity fingerprint mappings for all the routers
105 * that we name. Used to prevent router impersonation. */
106 /* Should be static; exposed for testing */
107 smartlist_t
*fingerprint_list
= NULL
;
109 /** Add the fingerprint <b>fp</b> for the nickname <b>nickname</b> to
110 * the smartlist of fingerprint_entry_t's <b>list</b>. Return 0 if it's
111 * new, or 1 if we replaced the old value.
113 int /* Should be static; exposed for testing */
114 add_fingerprint_to_dir(const char *nickname
, const char *fp
, smartlist_t
*list
)
117 fingerprint_entry_t
*ent
;
119 tor_assert(nickname
);
123 fingerprint
= tor_strdup(fp
);
124 tor_strstrip(fingerprint
, " ");
126 if (nickname
[0] != '!') {
127 for (i
= 0; i
< smartlist_len(list
); ++i
) {
128 ent
= smartlist_get(list
, i
);
129 if (!strcasecmp(ent
->nickname
,nickname
)) {
130 tor_free(ent
->fingerprint
);
131 ent
->fingerprint
= fingerprint
;
136 ent
= tor_malloc(sizeof(fingerprint_entry_t
));
137 ent
->nickname
= tor_strdup(nickname
);
138 ent
->fingerprint
= fingerprint
;
139 smartlist_add(list
, ent
);
143 /** Add the nickname and fingerprint for this OR to the
144 * global list of recognized identity key fingerprints. */
146 dirserv_add_own_fingerprint(const char *nickname
, crypto_pk_env_t
*pk
)
148 char fp
[FINGERPRINT_LEN
+1];
149 if (crypto_pk_get_fingerprint(pk
, fp
, 0)<0) {
150 log_err(LD_BUG
, "Error computing fingerprint");
153 if (!fingerprint_list
)
154 fingerprint_list
= smartlist_create();
155 add_fingerprint_to_dir(nickname
, fp
, fingerprint_list
);
159 /** Parse the nickname-\>fingerprint mappings stored in the file named
160 * <b>fname</b>. The file format is line-based, with each non-blank
161 * holding one nickname, some space, and a fingerprint for that
162 * nickname. On success, replace the current fingerprint list with
163 * the contents of <b>fname</b> and return 0. On failure, leave the
164 * current fingerprint list untouched, and return -1. */
166 dirserv_parse_fingerprint_file(const char *fname
)
169 char *nickname
, *fingerprint
;
170 smartlist_t
*fingerprint_list_new
;
172 config_line_t
*front
=NULL
, *list
;
174 cf
= read_file_to_str(fname
, 0);
176 if (get_options()->NamingAuthoritativeDir
) {
177 log_warn(LD_FS
, "Cannot open fingerprint file '%s'. Failing.", fname
);
180 log_info(LD_FS
, "Cannot open fingerprint file '%s'. Returning.", fname
);
184 result
= config_get_lines(cf
, &front
);
187 log_warn(LD_CONFIG
, "Error reading from fingerprint file");
191 fingerprint_list_new
= smartlist_create();
193 for (list
=front
; list
; list
=list
->next
) {
194 nickname
= list
->key
; fingerprint
= list
->value
;
195 if (strlen(nickname
) > MAX_NICKNAME_LEN
) {
196 log_notice(LD_CONFIG
,
197 "Nickname '%s' too long in fingerprint file. Skipping.",
201 if (!is_legal_nickname(nickname
) &&
202 strcasecmp(nickname
, "!reject") &&
203 strcasecmp(nickname
, "!invalid")) {
204 log_notice(LD_CONFIG
,
205 "Invalid nickname '%s' in fingerprint file. Skipping.",
209 if (strlen(fingerprint
) != FINGERPRINT_LEN
||
210 !crypto_pk_check_fingerprint_syntax(fingerprint
)) {
211 log_notice(LD_CONFIG
,
212 "Invalid fingerprint (nickname '%s', "
213 "fingerprint %s). Skipping.",
214 nickname
, fingerprint
);
217 if (0==strcasecmp(nickname
, DEFAULT_CLIENT_NICKNAME
)) {
218 /* If you approved an OR called "client", then clients who use
219 * the default nickname could all be rejected. That's no good. */
220 log_notice(LD_CONFIG
,
221 "Authorizing a nickname '%s' would break "
222 "many clients; skipping.",
223 DEFAULT_CLIENT_NICKNAME
);
226 if (add_fingerprint_to_dir(nickname
, fingerprint
, fingerprint_list_new
)
228 log_notice(LD_CONFIG
, "Duplicate nickname '%s'.", nickname
);
231 config_free_lines(front
);
232 dirserv_free_fingerprint_list();
233 fingerprint_list
= fingerprint_list_new
;
234 /* Delete any routers whose fingerprints we no longer recognize */
235 directory_remove_invalid();
239 /** Check whether <b>router</b> has a nickname/identity key combination that
240 * we recognize from the fingerprint list, or an IP we automatically act on
241 * according to our configuration. Return the appropriate router status.
243 * If the status is 'FP_REJECT' and <b>msg</b> is provided, set
244 * *<b>msg</b> to an explanation of why. */
245 static router_status_t
246 dirserv_router_get_status(const routerinfo_t
*router
, const char **msg
)
248 char fingerprint
[FINGERPRINT_LEN
+1];
250 if (crypto_pk_get_fingerprint(router
->identity_pkey
, fingerprint
, 0)) {
251 log_warn(LD_BUG
,"Error computing fingerprint");
255 return dirserv_get_status_impl(fingerprint
, router
->nickname
,
257 router
->addr
, router
->or_port
,
258 router
->platform
, router
->contact_info
,
262 /** Return true if there is no point in downloading the router described by
263 * <b>rs</b> because this directory would reject it. */
265 dirserv_would_reject_router(routerstatus_t
*rs
)
267 char fp
[FINGERPRINT_LEN
+1];
269 base16_encode(fp
, sizeof(fp
), rs
->identity_digest
, DIGEST_LEN
);
271 res
= dirserv_get_status_impl(fp
, rs
->nickname
,
272 "", /* address is only used in logs */
273 rs
->addr
, rs
->or_port
,
277 return (res
== FP_REJECT
);
280 /** Helper: As dirserv_get_router_status, but takes the router fingerprint
281 * (hex, no spaces), nickname, address (used for logging only), IP address, OR
282 * port, platform (logging only) and contact info (logging only) as arguments.
284 * If should_log is false, do not log messages. (There's not much point in
285 * logging that we're rejecting servers we'll not download.)
287 static router_status_t
288 dirserv_get_status_impl(const char *fp
, const char *nickname
,
290 uint32_t addr
, uint16_t or_port
,
291 const char *platform
, const char *contact
,
292 const char **msg
, int should_log
)
294 fingerprint_entry_t
*nn_ent
= NULL
, *fp_ent
= NULL
;
295 int reject_unlisted
= get_options()->AuthDirRejectUnlisted
;
296 if (!fingerprint_list
)
297 fingerprint_list
= smartlist_create();
300 log_debug(LD_DIRSERV
, "%d fingerprints known.",
301 smartlist_len(fingerprint_list
));
302 SMARTLIST_FOREACH(fingerprint_list
, fingerprint_entry_t
*, ent
,
304 if (!strcasecmp(fp
,ent
->fingerprint
))
306 if (!strcasecmp(nickname
,ent
->nickname
))
311 if (!strcasecmp(fp_ent
->nickname
, "!reject")) {
313 *msg
= "Fingerprint is marked rejected";
315 } else if (!strcasecmp(fp_ent
->nickname
, "!invalid")) {
317 *msg
= "Fingerprint is marked invalid";
322 if (!nn_ent
) { /* No such server known with that nickname */
323 addr_policy_result_t rej
= router_compare_addr_to_addr_policy(
324 addr
, or_port
, authdir_reject_policy
);
325 addr_policy_result_t inv
= router_compare_addr_to_addr_policy(
326 addr
, or_port
, authdir_invalid_policy
);
328 if (rej
== ADDR_POLICY_PROBABLY_REJECTED
|| rej
== ADDR_POLICY_REJECTED
) {
330 log_info(LD_DIRSERV
, "Rejecting '%s' because of address '%s'",
333 *msg
= "Authdir is rejecting routers in this range.";
336 if (inv
== ADDR_POLICY_PROBABLY_REJECTED
|| inv
== ADDR_POLICY_REJECTED
) {
338 log_info(LD_DIRSERV
, "Not marking '%s' valid because of address '%s'",
343 log_debug(LD_DIRSERV
,"No fingerprint found for '%s'",nickname
);
344 if (!platform
|| tor_version_as_new_as(platform
,"0.1.0.2-rc"))
345 return reject_unlisted
? FP_REJECT
: FP_VALID
;
349 if (0==strcasecmp(nn_ent
->fingerprint
, fp
)) {
351 log_debug(LD_DIRSERV
,"Good fingerprint for '%s'",nickname
);
352 return FP_NAMED
; /* Right fingerprint. */
355 char *esc_contact
= esc_for_log(contact
);
357 "Mismatched fingerprint for '%s': expected '%s' got '%s'. "
358 "ContactInfo '%s', platform '%s'.)",
359 nickname
, nn_ent
->fingerprint
, fp
,
361 platform
? escaped(platform
) : "");
362 tor_free(esc_contact
);
365 *msg
= "Rejected: There is already a named server with this nickname "
366 "and a different fingerprint.";
367 return FP_REJECT
; /* Wrong fingerprint. */
371 /** If we are an authoritative dirserver, and the list of approved
372 * servers contains one whose identity key digest is <b>digest</b>,
373 * return that router's nickname. Otherwise return NULL. */
375 dirserv_get_nickname_by_digest(const char *digest
)
377 char hexdigest
[HEX_DIGEST_LEN
+1];
378 if (!fingerprint_list
)
382 base16_encode(hexdigest
, HEX_DIGEST_LEN
+1, digest
, DIGEST_LEN
);
383 SMARTLIST_FOREACH(fingerprint_list
, fingerprint_entry_t
*, ent
,
384 { if (!strcasecmp(hexdigest
, ent
->fingerprint
))
385 return ent
->nickname
; } );
389 /** Clear the current fingerprint list. */
391 dirserv_free_fingerprint_list(void)
394 fingerprint_entry_t
*ent
;
395 if (!fingerprint_list
)
398 for (i
= 0; i
< smartlist_len(fingerprint_list
); ++i
) {
399 ent
= smartlist_get(fingerprint_list
, i
);
400 tor_free(ent
->nickname
);
401 tor_free(ent
->fingerprint
);
404 smartlist_free(fingerprint_list
);
405 fingerprint_list
= NULL
;
412 /** Return -1 if <b>ri</b> has a private or otherwise bad address,
413 * unless we're configured to not care. Return 0 if all ok. */
415 dirserv_router_has_valid_address(routerinfo_t
*ri
)
417 struct in_addr iaddr
;
418 if (get_options()->DirAllowPrivateAddresses
)
419 return 0; /* whatever it is, we're fine with it */
420 if (!tor_inet_aton(ri
->address
, &iaddr
)) {
421 log_info(LD_DIRSERV
,"Router '%s' published non-IP address '%s'. Refusing.",
422 ri
->nickname
, ri
->address
);
425 if (is_internal_IP(ntohl(iaddr
.s_addr
), 0)) {
427 "Router '%s' published internal IP address '%s'. Refusing.",
428 ri
->nickname
, ri
->address
);
429 return -1; /* it's a private IP, we should reject it */
434 /** Check whether we, as a directory server, want to accept <b>ri</b>. If so,
435 * set its is_valid,named,running fields and return 0. Otherwise, return -1.
437 * If the router is rejected, set *<b>msg</b> to an explanation of why.
439 * If <b>complain</b> then explain at log-level 'notice' why we refused
440 * a descriptor; else explain at log-level 'info'.
443 authdir_wants_to_reject_router(routerinfo_t
*ri
, const char **msg
,
446 /* Okay. Now check whether the fingerprint is recognized. */
447 router_status_t status
= dirserv_router_get_status(ri
, msg
);
449 int severity
= complain
? LOG_NOTICE
: LOG_INFO
;
451 if (status
== FP_REJECT
)
452 return -1; /* msg is already set. */
454 /* Is there too much clock skew? */
456 if (ri
->cache_info
.published_on
> now
+ROUTER_ALLOW_SKEW
) {
457 log_fn(severity
, LD_DIRSERV
, "Publication time for nickname '%s' is too "
458 "far (%d minutes) in the future; possible clock skew. Not adding "
460 ri
->nickname
, (int)((ri
->cache_info
.published_on
-now
)/60),
461 esc_router_info(ri
));
462 *msg
= "Rejected: Your clock is set too far in the future, or your "
463 "timezone is not correct.";
466 if (ri
->cache_info
.published_on
< now
-ROUTER_MAX_AGE_TO_PUBLISH
) {
467 log_fn(severity
, LD_DIRSERV
,
468 "Publication time for router with nickname '%s' is too far "
469 "(%d minutes) in the past. Not adding (%s)",
470 ri
->nickname
, (int)((now
-ri
->cache_info
.published_on
)/60),
471 esc_router_info(ri
));
472 *msg
= "Rejected: Server is expired, or your clock is too far in the past,"
473 " or your timezone is not correct.";
476 if (dirserv_router_has_valid_address(ri
) < 0) {
477 log_fn(severity
, LD_DIRSERV
,
478 "Router with nickname '%s' has invalid address '%s'. "
480 ri
->nickname
, ri
->address
,
481 esc_router_info(ri
));
482 *msg
= "Rejected: Address is not an IP, or IP is a private address.";
485 /* Okay, looks like we're willing to accept this one. */
488 ri
->is_named
= ri
->is_valid
= 1;
495 ri
->is_named
= ri
->is_valid
= 0;
504 /** Parse the server descriptor at <b>desc</b> and maybe insert it into
505 * the list of server descriptors. Set *<b>msg</b> to a message that
506 * should be passed back to the origin of this descriptor.
508 * Return 2 if descriptor is well-formed and accepted;
509 * 1 if well-formed and accepted but origin should hear *msg;
510 * 0 if well-formed but redundant with one we already have;
511 * -1 if it looks vaguely like a router descriptor but rejected;
512 * -2 if we can't find a router descriptor in <b>desc</b>.
515 dirserv_add_descriptor(const char *desc
, const char **msg
)
518 routerinfo_t
*ri
= NULL
, *ri_old
= NULL
;
522 /* Check: is the descriptor syntactically valid? */
523 ri
= router_parse_entry_from_string(desc
, NULL
);
525 log_warn(LD_DIRSERV
, "Couldn't parse uploaded server descriptor");
526 *msg
= "Rejected: Couldn't parse server descriptor.";
529 /* Check whether this descriptor is semantically identical to the last one
530 * from this server. (We do this here and not in router_add_to_routerlist
531 * because we want to be able to accept the newest router descriptor that
532 * another authority has, so we all converge on the same one.) */
533 ri_old
= router_get_by_digest(ri
->cache_info
.identity_digest
);
534 if (ri_old
&& ri_old
->cache_info
.published_on
< ri
->cache_info
.published_on
535 && router_differences_are_cosmetic(ri_old
, ri
)
536 && !router_is_me(ri
)) {
538 "Not replacing descriptor from '%s'; differences are cosmetic.",
540 *msg
= "Not replacing router descriptor; no information has changed since "
541 "the last one with this identity.";
543 control_event_or_authdir_new_descriptor("DROPPED", desc
, *msg
);
546 if ((r
= router_add_to_routerlist(ri
, msg
, 0, 0))<0) {
547 if (r
< -1) /* unless the routerinfo was fine, just out-of-date */
548 control_event_or_authdir_new_descriptor("REJECTED", desc
, *msg
);
549 return r
== -1 ? 0 : -1;
551 smartlist_t
*changed
;
552 control_event_or_authdir_new_descriptor("ACCEPTED", desc
, *msg
);
554 changed
= smartlist_create();
555 smartlist_add(changed
, ri
);
556 control_event_descriptors_changed(changed
);
557 smartlist_free(changed
);
559 *msg
= ri
->is_valid
? "Descriptor for valid server accepted" :
560 "Descriptor for invalid server accepted";
562 return r
== 0 ? 2 : 1;
566 /** Remove all descriptors whose nicknames or fingerprints no longer
567 * are allowed by our fingerprint list. (Descriptors that used to be
568 * good can become bad when we reload the fingerprint list.)
571 directory_remove_invalid(void)
575 routerlist_t
*rl
= router_get_routerlist();
577 for (i
= 0; i
< smartlist_len(rl
->routers
); ++i
) {
579 routerinfo_t
*ent
= smartlist_get(rl
->routers
, i
);
580 router_status_t r
= dirserv_router_get_status(ent
, &msg
);
583 log_info(LD_DIRSERV
, "Router '%s' is now rejected: %s",
584 ent
->nickname
, msg
?msg
:"");
585 routerlist_remove(rl
, ent
, i
--, 0);
589 if (!ent
->is_valid
|| !ent
->is_named
) {
591 "Router '%s' is now valid and named.", ent
->nickname
);
592 ent
->is_valid
= ent
->is_named
= 1;
597 if (!ent
->is_valid
|| ent
->is_named
) {
598 log_info(LD_DIRSERV
, "Router '%s' is now valid.", ent
->nickname
);
605 if (ent
->is_valid
|| ent
->is_named
) {
607 "Router '%s' is no longer valid.", ent
->nickname
);
608 ent
->is_valid
= ent
->is_named
= 0;
615 directory_set_dirty();
618 /** Write a list of unregistered descriptors into a newly allocated
619 * string and return it. Used by dirserv operators to keep track of
620 * fast nodes that haven't registered.
623 dirserver_getinfo_unregistered(const char *question
)
626 smartlist_t
*answerlist
;
629 int min_bw
= atoi(question
);
630 routerlist_t
*rl
= router_get_routerlist();
632 answerlist
= smartlist_create();
633 SMARTLIST_FOREACH(rl
->routers
, routerinfo_t
*, ent
, {
634 r
= dirserv_router_get_status(ent
, NULL
);
635 if (ent
->bandwidthcapacity
>= (size_t)min_bw
&&
636 ent
->bandwidthrate
>= (size_t)min_bw
&&
638 /* then log this one */
639 tor_snprintf(buf
, sizeof(buf
),
640 "%s: BW %d on '%s'.",
641 ent
->nickname
, ent
->bandwidthcapacity
,
642 ent
->platform
? ent
->platform
: "");
643 smartlist_add(answerlist
, tor_strdup(buf
));
646 answer
= smartlist_join_strings(answerlist
, "\r\n", 0, NULL
);
647 SMARTLIST_FOREACH(answerlist
, char *, cp
, tor_free(cp
));
648 smartlist_free(answerlist
);
652 /** Mark the directory as <b>dirty</b> -- when we're next asked for a
653 * directory, we will rebuild it instead of reusing the most recently
657 directory_set_dirty(void)
659 time_t now
= time(NULL
);
661 if (!the_directory_is_dirty
)
662 the_directory_is_dirty
= now
;
663 if (!runningrouters_is_dirty
)
664 runningrouters_is_dirty
= now
;
665 if (!the_v2_networkstatus_is_dirty
)
666 the_v2_networkstatus_is_dirty
= now
;
670 * Allocate and return a description of the status of the server <b>desc</b>,
671 * for use in a router-status line. The server is listed
672 * as running iff <b>is_live</b> is true.
675 list_single_server_status(routerinfo_t
*desc
, int is_live
)
677 char buf
[MAX_NICKNAME_LEN
+HEX_DIGEST_LEN
+4]; /* !nickname=$hexdigest\0 */
686 if (desc
->is_valid
) {
687 strlcpy(cp
, desc
->nickname
, sizeof(buf
)-(cp
-buf
));
692 base16_encode(cp
, HEX_DIGEST_LEN
+1, desc
->cache_info
.identity_digest
,
694 return tor_strdup(buf
);
697 /** Each server needs to have passed a reachability test no more
698 * than this number of seconds ago, or he is listed as down in
700 #define REACHABLE_TIMEOUT (30*60)
702 /** Treat a router as alive if
703 * - It's me, and I'm not hibernating.
704 * or - We've found it reachable recently. */
706 dirserv_thinks_router_is_reachable(routerinfo_t
*router
, time_t now
)
708 if (router_is_me(router
) && !we_are_hibernating())
710 return get_options()->AssumeReachable
||
711 now
< router
->last_reachable
+ REACHABLE_TIMEOUT
;
714 /** Return 1 if we're confident that there's a problem with
715 * <b>router</b>'s reachability and its operator should be notified.
718 dirserv_thinks_router_is_blatantly_unreachable(routerinfo_t
*router
,
721 if (router
->is_hibernating
)
723 if (now
>= router
->last_reachable
+ 2*REACHABLE_TIMEOUT
&&
724 router
->testing_since
&&
725 now
>= router
->testing_since
+ 2*REACHABLE_TIMEOUT
)
730 /** Based on the routerinfo_ts in <b>routers</b>, allocate the
731 * contents of a router-status line, and store it in
732 * *<b>router_status_out</b>. Return 0 on success, -1 on failure.
735 list_server_status(smartlist_t
*routers
, char **router_status_out
)
737 /* List of entries in a router-status style: An optional !, then an optional
738 * equals-suffixed nickname, then a dollar-prefixed hexdigest. */
739 smartlist_t
*rs_entries
;
740 time_t now
= time(NULL
);
741 time_t cutoff
= now
- ROUTER_MAX_AGE_TO_PUBLISH
;
742 int authdir_mode
= get_options()->AuthoritativeDir
;
743 tor_assert(router_status_out
);
745 rs_entries
= smartlist_create();
747 SMARTLIST_FOREACH(routers
, routerinfo_t
*, ri
,
750 /* Update router status in routerinfo_t. */
751 ri
->is_running
= dirserv_thinks_router_is_reachable(ri
, now
);
753 if (ri
->cache_info
.published_on
>= cutoff
)
754 smartlist_add(rs_entries
, list_single_server_status(ri
, ri
->is_running
));
757 *router_status_out
= smartlist_join_strings(rs_entries
, " ", 0, NULL
);
759 SMARTLIST_FOREACH(rs_entries
, char *, cp
, tor_free(cp
));
760 smartlist_free(rs_entries
);
765 /* Given a (possibly empty) list of config_line_t, each line of which contains
766 * a list of comma-separated version numbers surrounded by optional space,
767 * allocate and return a new string containing the version numbers, in order,
768 * separated by commas. Used to generate Recommended(Client|Server)?Versions
771 format_versions_list(config_line_t
*ln
)
773 smartlist_t
*versions
;
775 versions
= smartlist_create();
776 for ( ; ln
; ln
= ln
->next
) {
777 smartlist_split_string(versions
, ln
->value
, ",",
778 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, 0);
780 sort_version_list(versions
);
781 result
= smartlist_join_strings(versions
,",",0,NULL
);
782 SMARTLIST_FOREACH(versions
,char *,s
,tor_free(s
));
783 smartlist_free(versions
);
787 /** Generate a new directory and write it into a newly allocated string.
788 * Point *<b>dir_out</b> to the allocated string. Sign the
789 * directory with <b>private_key</b>. Return 0 on success, -1 on
793 dirserv_dump_directory_to_string(char **dir_out
,
794 crypto_pk_env_t
*private_key
)
798 char *identity_pkey
; /* Identity key, DER64-encoded. */
799 char *recommended_versions
;
800 char digest
[DIGEST_LEN
];
801 char published
[ISO_TIME_LEN
+1];
805 size_t identity_pkey_len
;
806 routerlist_t
*rl
= router_get_routerlist();
811 if (list_server_status(rl
->routers
, &router_status
))
814 if (crypto_pk_write_public_key_to_string(private_key
,&identity_pkey
,
815 &identity_pkey_len
)<0) {
816 log_warn(LD_BUG
,"write identity_pkey to string failed!");
820 recommended_versions
=
821 format_versions_list(get_options()->RecommendedVersions
);
823 published_on
= time(NULL
);
824 format_iso_time(published
, published_on
);
826 buf_len
= 2048+strlen(recommended_versions
)+
827 strlen(router_status
);
828 SMARTLIST_FOREACH(rl
->routers
, routerinfo_t
*, ri
,
829 buf_len
+= ri
->cache_info
.signed_descriptor_len
+1);
830 buf
= tor_malloc(buf_len
);
831 /* We'll be comparing against buf_len throughout the rest of the
832 function, though strictly speaking we shouldn't be able to exceed
833 it. This is C, after all, so we may as well check for buffer
836 tor_snprintf(buf
, buf_len
,
839 "recommended-software %s\n"
841 "dir-signing-key\n%s\n",
842 published
, recommended_versions
, router_status
,
845 tor_free(recommended_versions
);
846 tor_free(router_status
);
847 tor_free(identity_pkey
);
849 cp
= buf
+ strlen(buf
);
850 SMARTLIST_FOREACH(rl
->routers
, routerinfo_t
*, ri
,
852 size_t len
= ri
->cache_info
.signed_descriptor_len
;
854 if (cp
+len
+1 >= buf
+buf_len
)
856 body
= signed_descriptor_get_body(&ri
->cache_info
);
857 memcpy(cp
, body
, len
);
859 *cp
++ = '\n'; /* add an extra newline in case somebody was depending on
864 /* These multiple strlcat calls are inefficient, but dwarfed by the RSA
866 if (strlcat(buf
, "directory-signature ", buf_len
) >= buf_len
)
868 if (strlcat(buf
, get_options()->Nickname
, buf_len
) >= buf_len
)
870 if (strlcat(buf
, "\n", buf_len
) >= buf_len
)
873 if (router_get_dir_hash(buf
,digest
)) {
874 log_warn(LD_BUG
,"couldn't compute digest");
878 if (router_append_dirobj_signature(buf
,buf_len
,digest
,private_key
)<0) {
886 log_warn(LD_BUG
,"tried to exceed string length.");
891 /** Most recently generated encoded signed directory. (auth dirservers only.)*/
892 static cached_dir_t the_directory
= { NULL
, NULL
, 0, 0, 0 };
894 /* Used only by non-auth dirservers: The directory and runningrouters we'll
895 * serve when requested. */
896 static cached_dir_t cached_directory
= { NULL
, NULL
, 0, 0, 0 };
897 static cached_dir_t cached_runningrouters
= { NULL
, NULL
, 0, 0, 0 };
899 /* Used for other dirservers' v2 network statuses. Map from hexdigest to
901 static digestmap_t
*cached_v2_networkstatus
= NULL
;
903 /** Possibly replace the contents of <b>d</b> with the value of
904 * <b>directory</b> published on <b>when</b>, unless <b>when</b> is older than
905 * the last value, or too far in the future.
907 * Does not copy <b>directory</b>; free it if it isn't used.
910 set_cached_dir(cached_dir_t
*d
, char *directory
, time_t when
)
912 time_t now
= time(NULL
);
913 if (when
<=d
->published
) {
914 log_info(LD_DIRSERV
, "Ignoring old directory; not caching.");
916 } else if (when
>=now
+ROUTER_MAX_AGE_TO_PUBLISH
) {
917 log_info(LD_DIRSERV
, "Ignoring future directory; not caching.");
920 /* if (when>d->published && when<now+ROUTER_MAX_AGE) */
921 log_debug(LD_DIRSERV
, "Caching directory.");
924 d
->dir_len
= strlen(directory
);
926 if (tor_gzip_compress(&(d
->dir_z
), &(d
->dir_z_len
), d
->dir
, d
->dir_len
,
928 log_warn(LD_BUG
,"Error compressing cached directory");
934 /** Remove all storage held in <b>d</b>, but do not free <b>d</b> itself. */
936 clear_cached_dir(cached_dir_t
*d
)
940 memset(d
, 0, sizeof(cached_dir_t
));
943 /** Free all storage held by the cached_dir_t in <b>d</b>. */
945 free_cached_dir(void *_d
)
947 cached_dir_t
*d
= (cached_dir_t
*)_d
;
952 /** If we have no cached directory, or it is older than <b>when</b>, then
953 * replace it with <b>directory</b>, published at <b>when</b>.
956 dirserv_set_cached_directory(const char *directory
, time_t published
,
957 int is_running_routers
)
960 d
= is_running_routers
? &cached_runningrouters
: &cached_directory
;
961 set_cached_dir(d
, tor_strdup(directory
), published
);
964 /** We've just received a v2 network-status for an authoritative directory
965 * with identity digest <b>identity</b> published at
966 * <b>published</b>. Store it so we can serve it to others. If
967 * <b>directory</b> is NULL, remove the entry with the given fingerprint from
971 dirserv_set_cached_networkstatus_v2(const char *networkstatus
,
972 const char *identity
,
976 smartlist_t
*trusted_dirs
;
977 if (!cached_v2_networkstatus
)
978 cached_v2_networkstatus
= digestmap_new();
980 if (!(d
= digestmap_get(cached_v2_networkstatus
, identity
))) {
983 d
= tor_malloc_zero(sizeof(cached_dir_t
));
984 digestmap_set(cached_v2_networkstatus
, identity
, d
);
989 if (published
> d
->published
) {
990 set_cached_dir(d
, tor_strdup(networkstatus
), published
);
994 digestmap_remove(cached_v2_networkstatus
, identity
);
997 router_get_trusted_dir_servers(&trusted_dirs
);
998 if (digestmap_size(cached_v2_networkstatus
) >
999 smartlist_len(trusted_dirs
) + MAX_UNTRUSTED_NETWORKSTATUSES
) {
1000 /* We need to remove the oldest untrusted networkstatus. */
1001 const char *oldest
= NULL
;
1002 time_t oldest_published
= TIME_MAX
;
1003 digestmap_iter_t
*iter
;
1005 for (iter
= digestmap_iter_init(cached_v2_networkstatus
);
1006 !digestmap_iter_done(iter
);
1007 iter
= digestmap_iter_next(cached_v2_networkstatus
, iter
)) {
1010 digestmap_iter_get(iter
, &ident
, &val
);
1012 if (d
->published
< oldest_published
&&
1013 !router_get_trusteddirserver_by_digest(ident
)) {
1015 oldest_published
= d
->published
;
1019 d
= digestmap_remove(cached_v2_networkstatus
, oldest
);
1025 /** Helper: If we're an authority for the right directory version (the
1026 * directory version is determined by <b>is_v1_object</b>), try to regenerate
1027 * auth_src as appropriate and return it, falling back to cache_src on
1028 * failure. If we're a cache, return cach_src.
1030 static cached_dir_t
*
1031 dirserv_pick_cached_dir_obj(cached_dir_t
*cache_src
,
1032 cached_dir_t
*auth_src
,
1033 time_t dirty
, int (*regenerate
)(void),
1037 int authority
= get_options()->AuthoritativeDir
&&
1038 (!is_v1_object
|| get_options()->V1AuthoritativeDir
);
1043 /* We're authoritative. */
1044 if (regenerate
!= NULL
) {
1045 if (dirty
&& dirty
+ DIR_REGEN_SLACK_TIME
< time(NULL
)) {
1047 log_err(LD_BUG
, "Couldn't generate %s?", name
);
1051 log_info(LD_DIRSERV
, "The %s is still clean; reusing.", name
);
1054 return auth_src
? auth_src
: cache_src
;
1058 /** Helper: If we're authoritative and <b>auth_src</b> is set, use
1059 * <b>auth_src</b>, otherwise use <b>cache_src</b>. If we're using
1060 * <b>auth_src</b> and it's been <b>dirty</b> for at least
1061 * DIR_REGEN_SLACK_TIME seconds, call <b>regenerate</b>() to make a fresh one.
1062 * Yields the compressed version of the directory object if <b>compress</b> is
1063 * set; otherwise return the uncompressed version. (In either case, sets
1064 * *<b>out</b> and returns the size of the buffer in *<b>out</b>.)
1066 * Use <b>is_v1_object</b> to help determine whether we're authoritative for
1067 * this kind of object.
1070 dirserv_get_obj(const char **out
, int compress
,
1071 cached_dir_t
*cache_src
,
1072 cached_dir_t
*auth_src
,
1073 time_t dirty
, int (*regenerate
)(void),
1077 cached_dir_t
*d
= dirserv_pick_cached_dir_obj(
1078 cache_src
, auth_src
,
1079 dirty
, regenerate
, name
, is_v1_object
);
1083 *out
= compress
? d
->dir_z
: d
->dir
;
1085 return compress
? d
->dir_z_len
: d
->dir_len
;
1087 /* not yet available. */
1092 /** Set *<b>directory</b> to the most recently generated encoded signed
1093 * directory, generating a new one as necessary. If not an authoritative
1094 * directory may return 0 if no directory is yet cached.*/
1096 dirserv_get_directory(const char **directory
, int compress
)
1098 return dirserv_get_obj(directory
, compress
,
1099 &cached_directory
, &the_directory
,
1100 the_directory_is_dirty
,
1101 dirserv_regenerate_directory
,
1102 "server directory", 1);
1106 * Generate a fresh directory (authdirservers only.)
1109 dirserv_regenerate_directory(void)
1111 char *new_directory
=NULL
;
1113 if (dirserv_dump_directory_to_string(&new_directory
,
1114 get_identity_key())) {
1115 log_warn(LD_BUG
, "Error creating directory.");
1116 tor_free(new_directory
);
1119 set_cached_dir(&the_directory
, new_directory
, time(NULL
));
1120 log_info(LD_DIRSERV
,"New directory (size %d) has been built.",
1121 (int)the_directory
.dir_len
);
1122 log_debug(LD_DIRSERV
,"New directory (size %d):\n%s",
1123 (int)the_directory
.dir_len
, the_directory
.dir
);
1125 the_directory_is_dirty
= 0;
1127 /* Save the directory to disk so we re-load it quickly on startup.
1129 dirserv_set_cached_directory(the_directory
.dir
, time(NULL
), 0);
1134 /** For authoritative directories: the current (v1) network status */
1135 static cached_dir_t the_runningrouters
= { NULL
, NULL
, 0, 0, 0 };
1137 /** Replace the current running-routers list with a newly generated one. */
1139 generate_runningrouters(void)
1142 char *router_status
=NULL
;
1143 char digest
[DIGEST_LEN
];
1144 char published
[ISO_TIME_LEN
+1];
1146 crypto_pk_env_t
*private_key
= get_identity_key();
1147 char *identity_pkey
; /* Identity key, DER64-encoded. */
1148 size_t identity_pkey_len
;
1149 routerlist_t
*rl
= router_get_routerlist();
1151 if (list_server_status(rl
->routers
, &router_status
)) {
1154 if (crypto_pk_write_public_key_to_string(private_key
,&identity_pkey
,
1155 &identity_pkey_len
)<0) {
1156 log_warn(LD_BUG
,"write identity_pkey to string failed!");
1159 format_iso_time(published
, time(NULL
));
1161 len
= 2048+strlen(router_status
);
1162 s
= tor_malloc_zero(len
);
1163 tor_snprintf(s
, len
,
1166 "router-status %s\n"
1167 "dir-signing-key\n%s"
1168 "directory-signature %s\n",
1169 published
, router_status
, identity_pkey
,
1170 get_options()->Nickname
);
1171 tor_free(router_status
);
1172 tor_free(identity_pkey
);
1173 if (router_get_runningrouters_hash(s
,digest
)) {
1174 log_warn(LD_BUG
,"couldn't compute digest");
1177 if (router_append_dirobj_signature(s
, len
, digest
, private_key
)<0)
1180 set_cached_dir(&the_runningrouters
, s
, time(NULL
));
1181 runningrouters_is_dirty
= 0;
1186 tor_free(router_status
);
1190 /** Set *<b>rr</b> to the most recently generated encoded signed
1191 * running-routers list, generating a new one as necessary. Return the
1192 * size of the directory on success, and 0 on failure. */
1194 dirserv_get_runningrouters(const char **rr
, int compress
)
1196 return dirserv_get_obj(rr
, compress
,
1197 &cached_runningrouters
, &the_runningrouters
,
1198 runningrouters_is_dirty
,
1199 generate_runningrouters
,
1200 "v1 network status list", 1);
1203 /** Return true iff <b>ri</b> is "useful as an exit node", meaning
1204 * it allows exit to at least one /8 address space for at least
1205 * one of ports 80, 443, and 6667. */
1207 router_is_general_exit(routerinfo_t
*ri
)
1209 static const int ports
[] = { 80, 443, 6667 };
1212 for (i
= 0; i
< 3; ++i
) {
1213 struct addr_policy_t
*policy
= ri
->exit_policy
;
1214 for ( ; policy
; policy
= policy
->next
) {
1215 if (policy
->prt_min
> ports
[i
] || policy
->prt_max
< ports
[i
])
1216 continue; /* Doesn't cover our port. */
1217 if ((policy
->msk
& 0x00fffffful
) != 0)
1218 continue; /* Narrower than a /8. */
1219 if ((policy
->addr
& 0xff000000ul
) == 0x7f000000ul
)
1220 continue; /* 127.x */
1221 /* We have a match that is at least a /8. */
1222 if (policy
->policy_type
== ADDR_POLICY_ACCEPT
)
1227 return n_allowed
> 0;
1230 /** For authoritative directories: the current (v2) network status */
1231 static cached_dir_t the_v2_networkstatus
= { NULL
, NULL
, 0, 0, 0 };
1234 should_generate_v2_networkstatus(void)
1236 return get_options()->AuthoritativeDir
&&
1237 the_v2_networkstatus_is_dirty
&&
1238 the_v2_networkstatus_is_dirty
+ DIR_REGEN_SLACK_TIME
< time(NULL
);
1241 static uint32_t stable_uptime
= 0; /* start at a safe value */
1242 static uint32_t fast_bandwidth
= 0;
1244 /** Return 1 if <b>router</b> is not suitable for these parameters, else 0.
1245 * If <b>need_uptime</b> is non-zero, we require a minimum uptime.
1246 * If <b>need_capacity</b> is non-zero, we require a minimum advertised
1250 dirserv_thinks_router_is_unreliable(routerinfo_t
*router
,
1251 int need_uptime
, int need_capacity
)
1253 if (need_uptime
&& router
->uptime
< stable_uptime
)
1255 if (need_capacity
&& router
->bandwidthcapacity
< fast_bandwidth
)
1261 _compare_uint32(const void **a
, const void **b
)
1263 uint32_t first
= **(uint32_t **)a
, second
= **(uint32_t **)b
;
1264 if (first
< second
) return -1;
1265 if (first
> second
) return 1;
1269 /** Look through the routerlist, and assign the median uptime
1270 * of running valid servers to stable_uptime, and the median bandwidth
1271 * capacity to fast_bandwidth. */
1273 dirserv_compute_performance_thresholds(routerlist_t
*rl
)
1275 smartlist_t
*uptimes
, *bandwidths
;
1277 uptimes
= smartlist_create();
1278 bandwidths
= smartlist_create();
1280 SMARTLIST_FOREACH(rl
->routers
, routerinfo_t
*, ri
, {
1281 if (ri
->is_running
&& ri
->is_valid
) {
1282 uint32_t *up
= tor_malloc(sizeof(uint32_t));
1283 *up
= (uint32_t) ri
->uptime
;
1284 smartlist_add(uptimes
, up
);
1285 uint32_t *bw
= tor_malloc(sizeof(uint32_t));
1286 *bw
= (uint32_t) ri
->bandwidthcapacity
;
1287 smartlist_add(bandwidths
, bw
);
1291 smartlist_sort(uptimes
, _compare_uint32
);
1292 smartlist_sort(bandwidths
, _compare_uint32
);
1294 if (smartlist_len(uptimes
))
1295 stable_uptime
= *(uint32_t*)smartlist_get(uptimes
,
1296 smartlist_len(uptimes
)/2);
1298 if (smartlist_len(bandwidths
))
1299 fast_bandwidth
= *(uint32_t*)smartlist_get(bandwidths
,
1300 smartlist_len(bandwidths
)/2);
1302 log_info(LD_DIRSERV
, "Uptime cutoff is %lu seconds.",
1303 (unsigned long)stable_uptime
);
1304 log_info(LD_DIRSERV
, "Bandwidth cutoff is %lu bytes.",
1305 (unsigned long)fast_bandwidth
);
1307 SMARTLIST_FOREACH(uptimes
, uint32_t *, up
, tor_free(up
));
1308 SMARTLIST_FOREACH(bandwidths
, uint32_t *, bw
, tor_free(bw
));
1309 smartlist_free(uptimes
);
1310 smartlist_free(bandwidths
);
1313 /** For authoritative directories only: replace the contents of
1314 * <b>the_v2_networkstatus</b> with a newly generated network status
1317 generate_v2_networkstatus(void)
1319 #define LONGEST_STATUS_FLAG_NAME_LEN 7
1320 #define N_STATUS_FLAGS 6
1321 #define RS_ENTRY_LEN \
1322 ( /* first line */ \
1323 MAX_NICKNAME_LEN+BASE64_DIGEST_LEN*2+ISO_TIME_LEN+INET_NTOA_BUF_LEN+ \
1324 5*2 /* ports */ + 10 /* punctuation */ + \
1326 (LONGEST_STATUS_FLAG_NAME_LEN+1)*N_STATUS_FLAGS + 2)
1329 size_t len
, identity_pkey_len
;
1330 char *status
= NULL
, *client_versions
= NULL
, *server_versions
= NULL
,
1331 *identity_pkey
= NULL
, *hostname
= NULL
;
1333 or_options_t
*options
= get_options();
1334 char fingerprint
[FINGERPRINT_LEN
+1];
1335 char ipaddr
[INET_NTOA_BUF_LEN
];
1336 char published
[ISO_TIME_LEN
+1];
1337 char digest
[DIGEST_LEN
];
1340 crypto_pk_env_t
*private_key
= get_identity_key();
1341 routerlist_t
*rl
= router_get_routerlist();
1342 time_t now
= time(NULL
);
1343 time_t cutoff
= now
- ROUTER_MAX_AGE_TO_PUBLISH
;
1344 int naming
= options
->NamingAuthoritativeDir
;
1345 int versioning
= options
->VersioningAuthoritativeDir
;
1346 const char *contact
;
1348 if (resolve_my_address(options
, &addr
, &hostname
)<0) {
1349 log_warn(LD_NET
, "Couldn't resolve my hostname");
1352 in
.s_addr
= htonl(addr
);
1353 tor_inet_ntoa(&in
, ipaddr
, sizeof(ipaddr
));
1355 format_iso_time(published
, time(NULL
));
1357 client_versions
= format_versions_list(options
->RecommendedClientVersions
);
1358 server_versions
= format_versions_list(options
->RecommendedServerVersions
);
1360 if (crypto_pk_write_public_key_to_string(private_key
, &identity_pkey
,
1361 &identity_pkey_len
)<0) {
1362 log_warn(LD_BUG
,"Writing public key to string failed.");
1366 if (crypto_pk_get_fingerprint(private_key
, fingerprint
, 0)<0) {
1367 log_err(LD_BUG
, "Error computing fingerprint");
1371 contact
= get_options()->ContactInfo
;
1375 len
= 2048+strlen(client_versions
)+strlen(server_versions
);
1376 len
+= identity_pkey_len
*2;
1377 len
+= (RS_ENTRY_LEN
)*smartlist_len(rl
->routers
);
1379 status
= tor_malloc(len
);
1380 tor_snprintf(status
, len
,
1381 "network-status-version 2\n"
1382 "dir-source %s %s %d\n"
1387 "client-versions %s\n"
1388 "server-versions %s\n"
1389 "dir-signing-key\n%s\n",
1390 hostname
, ipaddr
, (int)options
->DirPort
,
1394 naming
? " Names" : "",
1395 versioning
? " Versions" : "",
1399 outp
= status
+ strlen(status
);
1400 endp
= status
+ len
;
1402 /* precompute this part, since we need it to decide what "stable"
1404 SMARTLIST_FOREACH(rl
->routers
, routerinfo_t
*, ri
, {
1405 ri
->is_running
= dirserv_thinks_router_is_reachable(ri
, now
);
1408 dirserv_compute_performance_thresholds(rl
);
1410 SMARTLIST_FOREACH(rl
->routers
, routerinfo_t
*, ri
, {
1411 if (ri
->cache_info
.published_on
>= cutoff
) {
1412 int f_exit
= router_is_general_exit(ri
);
1413 int f_stable
= ri
->is_stable
=
1414 !dirserv_thinks_router_is_unreliable(ri
, 1, 0);
1415 int f_fast
= ri
->is_fast
=
1416 !dirserv_thinks_router_is_unreliable(ri
, 0, 1);
1417 int f_running
= ri
->is_running
; /* computed above */
1418 int f_authority
= router_digest_is_trusted_dir(
1419 ri
->cache_info
.identity_digest
);
1420 int f_named
= naming
&& ri
->is_named
;
1421 int f_valid
= ri
->is_valid
;
1422 int f_guard
= f_fast
&& f_stable
;
1423 /* 0.1.1.9-alpha is the first version to support fetch by descriptor
1425 int f_v2_dir
= ri
->dir_port
&&
1426 tor_version_as_new_as(ri
->platform
,"0.1.1.9-alpha");
1427 char identity64
[BASE64_DIGEST_LEN
+1];
1428 char digest64
[BASE64_DIGEST_LEN
+1];
1430 format_iso_time(published
, ri
->cache_info
.published_on
);
1432 digest_to_base64(identity64
, ri
->cache_info
.identity_digest
);
1433 digest_to_base64(digest64
, ri
->cache_info
.signed_descriptor_digest
);
1435 in
.s_addr
= htonl(ri
->addr
);
1436 tor_inet_ntoa(&in
, ipaddr
, sizeof(ipaddr
));
1438 if (tor_snprintf(outp
, endp
-outp
,
1439 "r %s %s %s %s %s %d %d\n"
1440 "s%s%s%s%s%s%s%s%s%s\n",
1448 f_authority
?" Authority":"",
1451 f_guard
?" Guard":"",
1452 f_named
?" Named":"",
1453 f_stable
?" Stable":"",
1454 f_running
?" Running":"",
1455 f_valid
?" Valid":"",
1456 f_v2_dir
?" V2Dir":"")<0) {
1457 log_warn(LD_BUG
, "Unable to print router status.");
1460 outp
+= strlen(outp
);
1464 if (tor_snprintf(outp
, endp
-outp
, "directory-signature %s\n",
1465 get_options()->Nickname
)<0) {
1466 log_warn(LD_BUG
, "Unable to write signature line.");
1470 if (router_get_networkstatus_v2_hash(status
, digest
)<0) {
1471 log_warn(LD_BUG
, "Unable to hash network status");
1475 if (router_append_dirobj_signature(outp
,endp
-outp
,digest
,private_key
)<0) {
1476 log_warn(LD_BUG
, "Unable to sign router status.");
1480 set_cached_dir(&the_v2_networkstatus
, status
, time(NULL
));
1481 status
= NULL
; /* So it doesn't get double-freed. */
1482 the_v2_networkstatus_is_dirty
= 0;
1483 router_set_networkstatus(the_v2_networkstatus
.dir
, time(NULL
), NS_GENERATED
,
1488 tor_free(client_versions
);
1489 tor_free(server_versions
);
1492 tor_free(identity_pkey
);
1496 /** Look for a network status object as specified by <b>key</b>, which should
1497 * be either "authority" (to find a network status generated by us), a hex
1498 * identity digest (to find a network status generated by given directory), or
1499 * "all" (to return all the v2 network status objects we have, concatenated).
1500 * If <b>compress</b>, find the version compressed with zlib. Return 0 if
1501 * nothing was found; otherwise set *<b>directory</b> to the matching network
1502 * status and return its length.
1505 dirserv_get_networkstatus_v2(smartlist_t
*result
,
1510 if (!cached_v2_networkstatus
)
1511 cached_v2_networkstatus
= digestmap_new();
1513 if (!(strcmp(key
,"authority"))) {
1514 if (get_options()->AuthoritativeDir
) {
1516 dirserv_pick_cached_dir_obj(NULL
,
1517 &the_v2_networkstatus
,
1518 the_v2_networkstatus_is_dirty
,
1519 generate_v2_networkstatus
,
1520 "network status list", 0);
1522 smartlist_add(result
, d
);
1525 "Unable to generate an authoritative network status.");
1527 } else if (!strcmp(key
, "all")) {
1528 digestmap_iter_t
*iter
;
1529 if (should_generate_v2_networkstatus())
1530 generate_v2_networkstatus();
1531 iter
= digestmap_iter_init(cached_v2_networkstatus
);
1532 while (!digestmap_iter_done(iter
)) {
1535 digestmap_iter_get(iter
, &ident
, &val
);
1536 smartlist_add(result
, val
);
1537 iter
= digestmap_iter_next(cached_v2_networkstatus
, iter
);
1539 if (smartlist_len(result
) == 0)
1540 log_warn(LD_DIRSERV
,
1541 "Client requested 'all' network status objects; we have none.");
1542 } else if (!strcmpstart(key
, "fp/")) {
1543 smartlist_t
*digests
= smartlist_create();
1544 dir_split_resource_into_fingerprints(key
+3, digests
, NULL
, 1);
1545 SMARTLIST_FOREACH(digests
, char *, cp
,
1547 cached_dir_t
*cached
;
1548 if (router_digest_is_me(cp
) && should_generate_v2_networkstatus())
1549 generate_v2_networkstatus();
1550 cached
= digestmap_get(cached_v2_networkstatus
, cp
);
1552 smartlist_add(result
, cached
);
1554 char hexbuf
[HEX_DIGEST_LEN
+1];
1555 base16_encode(hexbuf
, sizeof(hexbuf
), cp
, DIGEST_LEN
);
1556 log_info(LD_DIRSERV
, "Don't know about any network status with "
1557 "fingerprint '%s'", hexbuf
);
1561 smartlist_free(digests
);
1566 /** Add a signed_descriptor_t to <b>descs_out</b> for each router matching
1567 * <b>key</b>. The key should be either
1568 * - "/tor/server/authority" for our own routerinfo;
1569 * - "/tor/server/all" for all the routerinfos we have, concatenated;
1570 * - "/tor/server/fp/FP" where FP is a plus-separated sequence of
1571 * hex identity digests; or
1572 * - "/tor/server/d/D" where D is a plus-separated sequence
1573 * of server descriptor digests, in hex.
1575 * Return 0 if we found some matching descriptors, or -1 if we do not
1576 * have any descriptors, no matching descriptors, or if we did not
1577 * recognize the key (URL).
1578 * If -1 is returned *<b>msg</b> will be set to an appropriate error
1581 * (Despite its name, this function is also called from the controller, which
1582 * exposes a similar means to fetch descriptors.)
1585 dirserv_get_routerdescs(smartlist_t
*descs_out
, const char *key
,
1590 if (!strcmp(key
, "/tor/server/all")) {
1591 routerlist_t
*rl
= router_get_routerlist();
1592 SMARTLIST_FOREACH(rl
->routers
, routerinfo_t
*, r
,
1593 smartlist_add(descs_out
, &(r
->cache_info
)));
1594 } else if (!strcmp(key
, "/tor/server/authority")) {
1595 routerinfo_t
*ri
= router_get_my_routerinfo();
1597 smartlist_add(descs_out
, &(ri
->cache_info
));
1598 } else if (!strcmpstart(key
, "/tor/server/d/")) {
1599 smartlist_t
*digests
= smartlist_create();
1600 key
+= strlen("/tor/server/d/");
1601 dir_split_resource_into_fingerprints(key
, digests
, NULL
, 1);
1602 SMARTLIST_FOREACH(digests
, const char *, d
,
1604 signed_descriptor_t
*sd
= router_get_by_descriptor_digest(d
);
1606 smartlist_add(descs_out
,sd
);
1608 SMARTLIST_FOREACH(digests
, char *, d
, tor_free(d
));
1609 smartlist_free(digests
);
1610 } else if (!strcmpstart(key
, "/tor/server/fp/")) {
1611 smartlist_t
*digests
= smartlist_create();
1612 time_t cutoff
= time(NULL
) - ROUTER_MAX_AGE_TO_PUBLISH
;
1613 key
+= strlen("/tor/server/fp/");
1614 dir_split_resource_into_fingerprints(key
, digests
, NULL
, 1);
1615 SMARTLIST_FOREACH(digests
, const char *, d
,
1617 if (router_digest_is_me(d
)) {
1618 smartlist_add(descs_out
, &(router_get_my_routerinfo()->cache_info
));
1620 routerinfo_t
*ri
= router_get_by_digest(d
);
1621 /* Don't actually serve a descriptor that everyone will think is
1622 * expired. This is an (ugly) workaround to keep buggy 0.1.1.10
1623 * Tors from downloading descriptors that they will throw away.
1625 if (ri
&& ri
->cache_info
.published_on
> cutoff
)
1626 smartlist_add(descs_out
, &(ri
->cache_info
));
1629 SMARTLIST_FOREACH(digests
, char *, d
, tor_free(d
));
1630 smartlist_free(digests
);
1632 *msg
= "Key not recognized";
1636 if (!smartlist_len(descs_out
)) {
1637 *msg
= "Servers unavailable";
1643 /** Called when a TLS handshake has completed successfully with a
1644 * router listening at <b>address</b>:<b>or_port</b>, and has yielded
1645 * a certificate with digest <b>digest_rcvd</b> and nickname
1646 * <b>nickname_rcvd</b>. When this happens, it's clear that any other
1647 * descriptors for that address/port combination must be unusable:
1648 * delete them if they are not valid.
1650 * Also, if as_advertised is 1, then inform the reachability checker
1651 * that we could get to this guy.
1654 dirserv_orconn_tls_done(const char *address
,
1656 const char *digest_rcvd
,
1657 const char *nickname_rcvd
,
1661 routerlist_t
*rl
= router_get_routerlist();
1662 tor_assert(address
);
1663 tor_assert(digest_rcvd
);
1664 tor_assert(nickname_rcvd
);
1666 // XXXXNM We should really have a better solution here than dropping
1667 // XXXXNM whole routers; otherwise, they come back way too easily.
1668 for (i
= 0; i
< smartlist_len(rl
->routers
); ++i
) {
1669 routerinfo_t
*ri
= smartlist_get(rl
->routers
, i
);
1671 if (strcasecmp(address
, ri
->address
) || or_port
!= ri
->or_port
)
1673 if (!ri
->is_valid
) {
1674 /* We have a router at the same address! */
1675 if (strcasecmp(ri
->nickname
, nickname_rcvd
)) {
1676 log_notice(LD_DIRSERV
,
1677 "Dropping descriptor: nickname '%s' does not match "
1678 "nickname '%s' in cert from %s:%d",
1679 ri
->nickname
, nickname_rcvd
, address
, or_port
);
1681 } else if (memcmp(ri
->cache_info
.identity_digest
, digest_rcvd
,
1683 log_notice(LD_DIRSERV
,
1684 "Dropping descriptor: identity key does not match "
1685 "key in cert from %s:%d",
1691 routerlist_remove(rl
, ri
, i
--, 0);
1692 directory_set_dirty();
1693 } else { /* correct nickname and digest. mark this router reachable! */
1694 log_info(LD_DIRSERV
, "Found router %s to be reachable. Yay.",
1696 ri
->last_reachable
= time(NULL
);
1697 ri
->num_unreachable_notifications
= 0;
1702 /** Release all storage used by the directory server. */
1704 dirserv_free_all(void)
1706 if (fingerprint_list
) {
1707 SMARTLIST_FOREACH(fingerprint_list
, fingerprint_entry_t
*, fp
,
1708 { tor_free(fp
->nickname
);
1709 tor_free(fp
->fingerprint
);
1711 smartlist_free(fingerprint_list
);
1712 fingerprint_list
= NULL
;
1714 if (authdir_reject_policy
)
1715 addr_policy_free(authdir_reject_policy
);
1716 if (authdir_invalid_policy
)
1717 addr_policy_free(authdir_invalid_policy
);
1718 clear_cached_dir(&the_directory
);
1719 clear_cached_dir(&the_runningrouters
);
1720 clear_cached_dir(&the_v2_networkstatus
);
1721 clear_cached_dir(&cached_directory
);
1722 clear_cached_dir(&cached_runningrouters
);
1723 if (cached_v2_networkstatus
) {
1724 digestmap_free(cached_v2_networkstatus
, free_cached_dir
);
1725 cached_v2_networkstatus
= NULL
;