1 /* Copyright 2001-2004 Roger Dingledine.
2 * Copyright 2004-2005 Roger Dingledine, Nick Mathewson. */
3 /* See LICENSE for licensing information */
5 const char dirserv_c_id
[] = "$Id$";
11 * \brief Directory server core implementation. Manages directory
12 * contents and generates directories.
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
;
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. */
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
,
42 static int dirserv_thinks_router_is_reachable(routerinfo_t
*router
,
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.
53 parse_authdir_policy(void) {
55 if (authdir_reject_policy
) {
56 addr_policy_free(authdir_reject_policy
);
57 authdir_reject_policy
= NULL
;
59 config_parse_addr_policy(get_options()->AuthDirReject
,
60 &authdir_reject_policy
, ADDR_POLICY_ACCEPT
);
61 /* ports aren't used. */
62 for (n
=authdir_reject_policy
; n
; n
= n
->next
) {
67 if (authdir_invalid_policy
) {
68 addr_policy_free(authdir_invalid_policy
);
69 authdir_invalid_policy
= NULL
;
71 config_parse_addr_policy(get_options()->AuthDirInvalid
,
72 &authdir_invalid_policy
, ADDR_POLICY_ACCEPT
);
73 /* ports aren't used. */
74 for (n
=authdir_invalid_policy
; n
; n
= n
->next
) {
80 typedef struct fingerprint_entry_t
{
82 char *fingerprint
; /**< Stored as HEX_DIGEST_LEN characters, followed by a NUL */
83 } fingerprint_entry_t
;
85 /** List of nickname-\>identity fingerprint mappings for all the routers
86 * that we recognize. Used to prevent Sybil attacks. */
87 /* Should be static; exposed for testing */
88 smartlist_t
*fingerprint_list
= NULL
;
90 /** Add the fingerprint <b>fp</b> for the nickname <b>nickname</b> to
91 * the smartlist of fingerprint_entry_t's <b>list</b>. Return 0 if it's
92 * new, or 1 if we replaced the old value.
94 int /* Should be static; exposed for testing */
95 add_fingerprint_to_dir(const char *nickname
, const char *fp
, smartlist_t
*list
)
98 fingerprint_entry_t
*ent
;
100 tor_assert(nickname
);
104 fingerprint
= tor_strdup(fp
);
105 tor_strstrip(fingerprint
, " ");
107 for (i
= 0; i
< smartlist_len(list
); ++i
) {
108 ent
= smartlist_get(list
, i
);
109 if (!strcasecmp(ent
->nickname
,nickname
)) {
110 tor_free(ent
->fingerprint
);
111 ent
->fingerprint
= fingerprint
;
115 ent
= tor_malloc(sizeof(fingerprint_entry_t
));
116 ent
->nickname
= tor_strdup(nickname
);
117 ent
->fingerprint
= fingerprint
;
118 smartlist_add(list
, ent
);
122 /** Add the nickname and fingerprint for this OR to the
123 * global list of recognized identity key fingerprints. */
125 dirserv_add_own_fingerprint(const char *nickname
, crypto_pk_env_t
*pk
)
127 char fp
[FINGERPRINT_LEN
+1];
128 if (crypto_pk_get_fingerprint(pk
, fp
, 0)<0) {
129 log_fn(LOG_ERR
, "Error computing fingerprint");
132 if (!fingerprint_list
)
133 fingerprint_list
= smartlist_create();
134 add_fingerprint_to_dir(nickname
, fp
, fingerprint_list
);
138 /** Parse the nickname-\>fingerprint mappings stored in the file named
139 * <b>fname</b>. The file format is line-based, with each non-blank
140 * holding one nickname, some space, and a fingerprint for that
141 * nickname. On success, replace the current fingerprint list with
142 * the contents of <b>fname</b> and return 0. On failure, leave the
143 * current fingerprint list untouched, and return -1. */
145 dirserv_parse_fingerprint_file(const char *fname
)
148 char *nickname
, *fingerprint
;
149 smartlist_t
*fingerprint_list_new
;
151 config_line_t
*front
=NULL
, *list
;
153 cf
= read_file_to_str(fname
, 0);
155 log_fn(LOG_WARN
, "Cannot open fingerprint file %s", fname
);
158 result
= config_get_lines(cf
, &front
);
161 log_fn(LOG_WARN
, "Error reading from fingerprint file");
165 fingerprint_list_new
= smartlist_create();
167 for (list
=front
; list
; list
=list
->next
) {
168 nickname
= list
->key
; fingerprint
= list
->value
;
169 if (strlen(nickname
) > MAX_NICKNAME_LEN
) {
170 log(LOG_NOTICE
, "Nickname '%s' too long in fingerprint file. Skipping.", nickname
);
173 if (!is_legal_nickname(nickname
) &&
174 strcasecmp(nickname
, "!reject") &&
175 strcasecmp(nickname
, "!invalid")) {
176 log(LOG_NOTICE
, "Invalid nickname '%s' in fingerprint file. Skipping.", nickname
);
179 if (strlen(fingerprint
) != FINGERPRINT_LEN
||
180 !crypto_pk_check_fingerprint_syntax(fingerprint
)) {
181 log_fn(LOG_NOTICE
, "Invalid fingerprint (nickname '%s', fingerprint %s). Skipping.",
182 nickname
, fingerprint
);
185 if (0==strcasecmp(nickname
, DEFAULT_CLIENT_NICKNAME
)) {
186 /* If you approved an OR called "client", then clients who use
187 * the default nickname could all be rejected. That's no good. */
189 "Authorizing a nickname '%s' would break many clients; skipping.",
190 DEFAULT_CLIENT_NICKNAME
);
193 if (add_fingerprint_to_dir(nickname
, fingerprint
, fingerprint_list_new
) != 0)
194 log(LOG_NOTICE
, "Duplicate nickname '%s'.", nickname
);
197 config_free_lines(front
);
198 dirserv_free_fingerprint_list();
199 fingerprint_list
= fingerprint_list_new
;
200 /* Delete any routers whose fingerprints we no longer recognize */
201 directory_remove_invalid();
205 /** Check whether <b>router</b> has a nickname/identity key combination that
206 * we recognize from the fingerprint list, or an IP we automatically act on
207 * according to our configuration. Return the appropriate router status.
209 * If the status is 'FP_REJECT' and <b>msg</b> is provided, set
210 * *<b>msg</b> to an explanation of why.
212 static router_status_t
213 dirserv_router_get_status(const routerinfo_t
*router
, const char **msg
)
215 fingerprint_entry_t
*nn_ent
= NULL
, *fp_ent
= NULL
;
216 char fp
[FINGERPRINT_LEN
+1];
218 if (!fingerprint_list
)
219 fingerprint_list
= smartlist_create();
221 if (crypto_pk_get_fingerprint(router
->identity_pkey
, fp
, 0)) {
222 log_fn(LOG_WARN
,"Error computing fingerprint");
226 log_fn(LOG_DEBUG
, "%d fingerprints known.", smartlist_len(fingerprint_list
));
227 SMARTLIST_FOREACH(fingerprint_list
, fingerprint_entry_t
*, ent
,
229 if (!strcasecmp(fp
,ent
->fingerprint
))
231 if (!strcasecmp(router
->nickname
,ent
->nickname
))
236 if (!strcasecmp(fp_ent
->nickname
, "!reject")) {
238 *msg
= "Fingerprint is marked rejected";
240 } else if (!strcasecmp(fp_ent
->nickname
, "!invalid")) {
242 *msg
= "Fingerprint is marged invalid";
247 if (!nn_ent
) { /* No such server known with that nickname */
248 addr_policy_result_t rej
= router_compare_addr_to_addr_policy(
249 router
->addr
, router
->or_port
, authdir_reject_policy
);
250 addr_policy_result_t inv
= router_compare_addr_to_addr_policy(
251 router
->addr
, router
->or_port
, authdir_invalid_policy
);
253 if (rej
== ADDR_POLICY_PROBABLY_ACCEPTED
|| rej
== ADDR_POLICY_ACCEPTED
) {
254 log_fn(LOG_INFO
, "Rejecting '%s' because of address %s",
255 router
->nickname
, router
->address
);
257 *msg
= "Authdir is rejecting routers in this range.";
260 if (inv
== ADDR_POLICY_PROBABLY_ACCEPTED
|| inv
== ADDR_POLICY_ACCEPTED
) {
261 log_fn(LOG_INFO
, "Not marking '%s' valid because of address %s",
262 router
->nickname
, router
->address
);
265 if (tor_version_as_new_as(router
->platform
,"0.1.0.2-rc"))
269 log_fn(LOG_INFO
,"No fingerprint found for '%s'",router
->nickname
);
272 if (0==strcasecmp(nn_ent
->fingerprint
, fp
)) {
273 log_fn(LOG_DEBUG
,"Good fingerprint for '%s'",router
->nickname
);
274 return FP_NAMED
; /* Right fingerprint. */
276 log_fn(LOG_WARN
,"Mismatched fingerprint for '%s': expected '%s' got '%s'. ContactInfo '%s', platform '%s'.)",
277 router
->nickname
, nn_ent
->fingerprint
, fp
,
278 router
->contact_info
? router
->contact_info
: "",
279 router
->platform
? router
->platform
: "");
281 *msg
= "Rejected: There is already a verified server with this nickname and a different fingerprint.";
282 return FP_REJECT
; /* Wrong fingerprint. */
286 /** If we are an authoritative dirserver, and the list of approved
287 * servers contains one whose identity key digest is <b>digest</b>,
288 * return that router's nickname. Otherwise return NULL. */
290 dirserv_get_nickname_by_digest(const char *digest
)
292 char hexdigest
[HEX_DIGEST_LEN
+1];
293 if (!fingerprint_list
)
297 base16_encode(hexdigest
, HEX_DIGEST_LEN
+1, digest
, DIGEST_LEN
);
298 SMARTLIST_FOREACH(fingerprint_list
, fingerprint_entry_t
*, ent
,
299 { if (!strcasecmp(hexdigest
, ent
->fingerprint
))
300 return ent
->nickname
; } );
304 /** Clear the current fingerprint list. */
306 dirserv_free_fingerprint_list(void)
309 fingerprint_entry_t
*ent
;
310 if (!fingerprint_list
)
313 for (i
= 0; i
< smartlist_len(fingerprint_list
); ++i
) {
314 ent
= smartlist_get(fingerprint_list
, i
);
315 tor_free(ent
->nickname
);
316 tor_free(ent
->fingerprint
);
319 smartlist_free(fingerprint_list
);
320 fingerprint_list
= NULL
;
328 get_descriptor_list(void)
330 routerlist_t
*routerlist
;
331 router_get_routerlist(&routerlist
);
334 return routerlist
->routers
;
337 /** Return -1 if <b>ri</b> has a private or otherwise bad address,
338 * unless we're configured to not care. Return 0 if all ok. */
340 dirserv_router_has_valid_address(routerinfo_t
*ri
)
342 struct in_addr iaddr
;
343 if (get_options()->DirAllowPrivateAddresses
)
344 return 0; /* whatever it is, we're fine with it */
345 if (!tor_inet_aton(ri
->address
, &iaddr
)) {
346 log_fn(LOG_INFO
,"Router '%s' published non-IP address '%s'. Refusing.",
347 ri
->nickname
, ri
->address
);
350 if (is_internal_IP(ntohl(iaddr
.s_addr
))) {
351 log_fn(LOG_INFO
,"Router '%s' published internal IP address '%s'. Refusing.",
352 ri
->nickname
, ri
->address
);
353 return -1; /* it's a private IP, we should reject it */
358 /** Check whether we, as a directory server, want to accept <b>ri</b>. If so,
359 * return 0, and set its is_valid,named,running fields. Otherwise, return -1.
361 * If the router is rejected, set *<b>msg</b> to an explanation of why.
364 authdir_wants_to_reject_router(routerinfo_t
*ri
,
367 /* Okay. Now check whether the fingerprint is recognized. */
368 router_status_t status
= dirserv_router_get_status(ri
, msg
);
371 if (status
== FP_REJECT
)
372 return -1; /* msg is already set. */
374 /* Is there too much clock skew? */
376 if (ri
->published_on
> now
+ROUTER_ALLOW_SKEW
) {
377 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').",
378 ri
->nickname
, (int)((ri
->published_on
-now
)/60),
379 ri
->contact_info
? ri
->contact_info
: "",
380 ri
->platform
? ri
->platform
: "");
381 *msg
= "Rejected: Your clock is set too far in the future, or your timezone is not correct.";
384 if (ri
->published_on
< now
-ROUTER_MAX_AGE
) {
385 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').",
386 ri
->nickname
, (int)((now
-ri
->published_on
)/60),
387 ri
->contact_info
? ri
->contact_info
: "",
388 ri
->platform
? ri
->platform
: "");
389 *msg
= "Rejected: Server is expired, or your clock is too far in the past, or your timezone is not correct.";
392 if (dirserv_router_has_valid_address(ri
) < 0) {
393 log_fn(LOG_NOTICE
, "Router with nickname '%s' has invalid address '%s'. Not adding (ContactInfo '%s', platform '%s').",
394 ri
->nickname
, ri
->address
,
395 ri
->contact_info
? ri
->contact_info
: "",
396 ri
->platform
? ri
->platform
: "");
397 *msg
= "Rejected: Address is not an IP, or IP is a private address.";
400 /* Okay, looks like we're willing to accept this one. */
403 ri
->is_named
= ri
->is_verified
= 1;
410 ri
->is_named
= ri
->is_verified
= 0;
419 /** Parse the server descriptor at <b>desc</b> and maybe insert it into
420 * the list of server descriptors. Set *<b>msg</b> to a message that
421 * should be passed back to the origin of this descriptor.
423 * Return 2 if descriptor is well-formed and accepted;
424 * 1 if well-formed and accepted but origin should hear *msg;
425 * 0 if well-formed but redundant with one we already have;
426 * -1 if it looks vaguely like a router descriptor but rejected;
427 * -2 if we can't find a router descriptor in <b>desc</b>.
430 dirserv_add_descriptor(const char *desc
, const char **msg
)
433 routerinfo_t
*ri
= NULL
;
437 /* Check: is the descriptor syntactically valid? */
438 ri
= router_parse_entry_from_string(desc
, NULL
);
440 log(LOG_WARN
, "Couldn't parse descriptor");
441 *msg
= "Rejected: Couldn't parse server descriptor.";
444 if ((r
= router_add_to_routerlist(ri
, msg
, 0))<0) {
445 return r
== -1 ? 0 : -1;
447 smartlist_t
*changed
= smartlist_create();
448 smartlist_add(changed
, ri
);
449 control_event_descriptors_changed(changed
);
450 smartlist_free(changed
);
452 *msg
= ri
->is_verified
? "Verified server descriptor accepted" :
453 "Unverified server descriptor accepted";
455 return r
== 0 ? 2 : 1;
459 /** Remove all descriptors whose nicknames or fingerprints no longer
460 * are allowed by our fingerprint list. (Descriptors that used to be
461 * good can become bad when we reload the fingerprint list.)
464 directory_remove_invalid(void)
468 smartlist_t
*descriptor_list
= get_descriptor_list();
470 if (!descriptor_list
)
473 for (i
= 0; i
< smartlist_len(descriptor_list
); ++i
) {
475 routerinfo_t
*ent
= smartlist_get(descriptor_list
, i
);
476 router_status_t r
= dirserv_router_get_status(ent
, &msg
);
479 log(LOG_INFO
, "Router '%s' is now rejected: %s",
480 ent
->nickname
, msg
?msg
:"");
481 routerinfo_free(ent
);
482 smartlist_del(descriptor_list
, i
--);
486 if (!ent
->is_verified
|| !ent
->is_named
) {
487 log(LOG_INFO
, "Router '%s' is now verified and named.", ent
->nickname
);
488 ent
->is_verified
= ent
->is_named
= 1;
493 if (!ent
->is_verified
|| ent
->is_named
) {
494 log(LOG_INFO
, "Router '%s' is now verified.", ent
->nickname
);
495 ent
->is_verified
= 1;
501 if (ent
->is_verified
|| ent
->is_named
) {
502 log(LOG_INFO
, "Router '%s' is no longer verified.", ent
->nickname
);
503 ent
->is_verified
= ent
->is_named
= 0;
510 directory_set_dirty();
513 /** Write a list of unregistered descriptors into a newly allocated
514 * string and return it. Used by dirserv operators to keep track of
515 * fast nodes that haven't registered.
518 dirserver_getinfo_unregistered(const char *question
)
522 smartlist_t
*answerlist
;
526 int min_bw
= atoi(question
);
527 smartlist_t
*descriptor_list
= get_descriptor_list();
529 if (!descriptor_list
)
530 return tor_strdup("");
532 answerlist
= smartlist_create();
533 for (i
= 0; i
< smartlist_len(descriptor_list
); ++i
) {
534 ent
= smartlist_get(descriptor_list
, i
);
535 r
= dirserv_router_get_status(ent
, NULL
);
536 if (ent
->bandwidthcapacity
>= (size_t)min_bw
&&
537 ent
->bandwidthrate
>= (size_t)min_bw
&&
539 /* then log this one */
540 tor_snprintf(buf
, sizeof(buf
),
541 "%s: BW %d on '%s'.",
542 ent
->nickname
, ent
->bandwidthcapacity
,
543 ent
->platform
? ent
->platform
: "");
544 smartlist_add(answerlist
, tor_strdup(buf
));
547 answer
= smartlist_join_strings(answerlist
, "\r\n", 0, NULL
);
548 SMARTLIST_FOREACH(answerlist
, char *, cp
, tor_free(cp
));
549 smartlist_free(answerlist
);
553 /** Mark the directory as <b>dirty</b> -- when we're next asked for a
554 * directory, we will rebuild it instead of reusing the most recently
558 directory_set_dirty(void)
560 time_t now
= time(NULL
);
562 if (!the_directory_is_dirty
)
563 the_directory_is_dirty
= now
;
564 if (!runningrouters_is_dirty
)
565 runningrouters_is_dirty
= now
;
566 if (!the_v2_networkstatus_is_dirty
)
567 the_v2_networkstatus_is_dirty
= now
;
571 * Allocate and return a description of the status of the server <b>desc</b>,
572 * for use in a router-status line. The server is listed
573 * as running iff <b>is_live</b> is true.
576 list_single_server_status(routerinfo_t
*desc
, int is_live
)
578 char buf
[MAX_NICKNAME_LEN
+HEX_DIGEST_LEN
+4]; /* !nickname=$hexdigest\0 */
587 if (desc
->is_verified
) {
588 strlcpy(cp
, desc
->nickname
, sizeof(buf
)-(cp
-buf
));
593 base16_encode(cp
, HEX_DIGEST_LEN
+1, desc
->identity_digest
,
595 return tor_strdup(buf
);
598 #define REACHABLE_TIMEOUT (60*60) /* an hour */
599 /* Make sure this is 3 times the value of get_dir_fetch_period() */
601 /** Treat a router as alive if
602 * - It's me, and I'm not hibernating.
603 * or - we're connected to it and we've found it reachable recently. */
605 dirserv_thinks_router_is_reachable(routerinfo_t
*router
, time_t now
)
608 if (router_is_me(router
) && !we_are_hibernating())
610 conn
= connection_get_by_identity_digest(router
->identity_digest
,
612 if (conn
&& conn
->state
== OR_CONN_STATE_OPEN
)
613 return get_options()->AssumeReachable
||
614 now
< router
->last_reachable
+ REACHABLE_TIMEOUT
;
618 /** Return 1 if we're confident that there's a problem with
619 * <b>router</b>'s reachability and its operator should be notified.
622 dirserv_thinks_router_is_blatantly_unreachable(routerinfo_t
*router
, time_t now
)
625 if (router
->is_hibernating
)
627 conn
= connection_get_by_identity_digest(router
->identity_digest
,
629 if (conn
&& conn
->state
== OR_CONN_STATE_OPEN
&&
630 now
>= router
->last_reachable
+ 2*REACHABLE_TIMEOUT
&&
631 router
->testing_since
&&
632 now
>= router
->testing_since
+ 2*REACHABLE_TIMEOUT
)
637 /** Based on the routerinfo_ts in <b>routers</b>, allocate the
638 * contents of a router-status line, and store it in
639 * *<b>router_status_out</b>. Return 0 on success, -1 on failure.
642 list_server_status(smartlist_t
*routers
, char **router_status_out
)
644 /* List of entries in a router-status style: An optional !, then an optional
645 * equals-suffixed nickname, then a dollar-prefixed hexdigest. */
646 smartlist_t
*rs_entries
;
647 time_t now
= time(NULL
);
648 int authdir_mode
= get_options()->AuthoritativeDir
;
649 tor_assert(router_status_out
);
651 rs_entries
= smartlist_create();
653 SMARTLIST_FOREACH(routers
, routerinfo_t
*, ri
,
656 /* Update router status in routerinfo_t. */
657 ri
->is_running
= dirserv_thinks_router_is_reachable(ri
, now
);
659 smartlist_add(rs_entries
, list_single_server_status(ri
, ri
->is_running
));
662 *router_status_out
= smartlist_join_strings(rs_entries
, " ", 0, NULL
);
664 SMARTLIST_FOREACH(rs_entries
, char *, cp
, tor_free(cp
));
665 smartlist_free(rs_entries
);
670 /** Helper: Given pointers to two strings describing tor versions, return -1
671 * if _a precedes _b, 1 if _b preceeds _a, and 0 if they are equivalent.
672 * Used to sort a list of versions. */
674 _compare_tor_version_str_ptr(const void **_a
, const void **_b
)
676 const char *a
= *_a
, *b
= *_b
;
678 tor_version_t va
, vb
;
679 ca
= tor_version_parse(a
, &va
);
680 cb
= tor_version_parse(b
, &vb
);
681 /* If they both parse, compare them. */
683 return tor_version_compare(&va
,&vb
);
684 /* If one parses, it comes first. */
689 /* If neither parses, compare strings. Also, the directory server admin needs
690 ** to be smacked upside the head. But Tor is tolerant and gentle. */
694 /* Given a (possibly empty) list of config_line_t, each line of which contains
695 * a list of comma-separated version numbers surrounded by optional space,
696 * allocate and return a new string containing the version numbers, in order,
697 * separated by commas. Used to generate Recommended(Client|Server)?Versions
700 format_versions_list(config_line_t
*ln
)
702 smartlist_t
*versions
;
704 versions
= smartlist_create();
705 for ( ; ln
; ln
= ln
->next
) {
706 smartlist_split_string(versions
, ln
->value
, ",",
707 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, 0);
709 smartlist_sort(versions
, _compare_tor_version_str_ptr
);
710 result
= smartlist_join_strings(versions
,",",0,NULL
);
711 SMARTLIST_FOREACH(versions
,char *,s
,tor_free(s
));
712 smartlist_free(versions
);
716 /** Generate a new directory and write it into a newly allocated string.
717 * Point *<b>dir_out</b> to the allocated string. Sign the
718 * directory with <b>private_key</b>. Return 0 on success, -1 on
722 dirserv_dump_directory_to_string(char **dir_out
,
723 crypto_pk_env_t
*private_key
)
726 char *identity_pkey
; /* Identity key, DER64-encoded. */
727 char *recommended_versions
;
728 char digest
[DIGEST_LEN
];
729 char published
[ISO_TIME_LEN
+1];
733 size_t identity_pkey_len
;
734 smartlist_t
*descriptor_list
= get_descriptor_list();
739 if (!descriptor_list
)
742 if (list_server_status(descriptor_list
, &router_status
))
745 if (crypto_pk_write_public_key_to_string(private_key
,&identity_pkey
,
746 &identity_pkey_len
)<0) {
747 log_fn(LOG_WARN
,"write identity_pkey to string failed!");
751 recommended_versions
= format_versions_list(get_options()->RecommendedVersions
);
753 published_on
= time(NULL
);
754 format_iso_time(published
, published_on
);
756 buf_len
= 2048+strlen(recommended_versions
)+
757 strlen(router_status
);
758 SMARTLIST_FOREACH(descriptor_list
, routerinfo_t
*, ri
,
759 buf_len
+= ri
->signed_descriptor_len
);
760 buf
= tor_malloc(buf_len
);
761 /* We'll be comparing against buf_len throughout the rest of the
762 function, though strictly speaking we shouldn't be able to exceed
763 it. This is C, after all, so we may as well check for buffer
766 tor_snprintf(buf
, buf_len
,
769 "recommended-software %s\n"
771 "dir-signing-key\n%s\n",
772 published
, recommended_versions
, router_status
,
775 tor_free(recommended_versions
);
776 tor_free(router_status
);
777 tor_free(identity_pkey
);
779 SMARTLIST_FOREACH(descriptor_list
, routerinfo_t
*, ri
,
780 if (strlcat(buf
, ri
->signed_descriptor
, buf_len
) >= buf_len
)
783 /* These multiple strlcat calls are inefficient, but dwarfed by the RSA
786 if (strlcat(buf
, "directory-signature ", buf_len
) >= buf_len
)
788 if (strlcat(buf
, get_options()->Nickname
, buf_len
) >= buf_len
)
790 if (strlcat(buf
, "\n", buf_len
) >= buf_len
)
793 if (router_get_dir_hash(buf
,digest
)) {
794 log_fn(LOG_WARN
,"couldn't compute digest");
798 if (router_append_dirobj_signature(buf
,buf_len
,digest
,private_key
)<0) {
806 log_fn(LOG_WARN
,"tried to exceed string length.");
811 /** Most recently generated encoded signed directory. (auth dirservers only.)*/
812 static cached_dir_t the_directory
= { NULL
, NULL
, 0, 0, 0 };
814 /* Used only by non-auth dirservers: The directory and runningrouters we'll
815 * serve when requested. */
816 static cached_dir_t cached_directory
= { NULL
, NULL
, 0, 0, 0 };
817 static cached_dir_t cached_runningrouters
= { NULL
, NULL
, 0, 0, 0 };
819 /* Used for other dirservers' v2 network statuses. Map from hexdigest to
821 static strmap_t
*cached_v2_networkstatus
= NULL
;
823 /** Possibly replace the contents of <b>d</b> with the value of
824 * <b>directory</b> published on <b>when</b>, unless <b>when</b> is older than
825 * the last value, or too far in the future.
827 * Does not copy <b>directory</b>; free it if it isn't used.
830 set_cached_dir(cached_dir_t
*d
, char *directory
, time_t when
)
832 time_t now
= time(NULL
);
833 if (when
<=d
->published
) {
834 log_fn(LOG_INFO
, "Ignoring old directory; not caching.");
836 } else if (when
>=now
+ROUTER_MAX_AGE
) {
837 log_fn(LOG_INFO
, "Ignoring future directory; not caching.");
840 /* if (when>d->published && when<now+ROUTER_MAX_AGE) */
841 log_fn(LOG_DEBUG
, "Caching directory.");
844 d
->dir_len
= strlen(directory
);
846 if (tor_gzip_compress(&(d
->dir_z
), &(d
->dir_z_len
), d
->dir
, d
->dir_len
,
848 log_fn(LOG_WARN
,"Error compressing cached directory");
854 /** Remove all storage held in <b>d</b>, but do not free <b>d</b> itself. */
856 clear_cached_dir(cached_dir_t
*d
)
860 memset(d
, 0, sizeof(cached_dir_t
));
863 /** Free all storage held by the cached_dir_t in <b>d</b>. */
865 free_cached_dir(void *_d
)
867 cached_dir_t
*d
= (cached_dir_t
*)_d
;
872 /** If we have no cached directory, or it is older than <b>when</b>, then
873 * replace it with <b>directory</b>, published at <b>when</b>.
876 dirserv_set_cached_directory(const char *directory
, time_t published
,
877 int is_running_routers
)
880 d
= is_running_routers
? &cached_runningrouters
: &cached_directory
;
881 set_cached_dir(d
, tor_strdup(directory
), published
);
884 /** We've just received a v2 network-status for an authoritative directory
885 * with fingerprint <b>fp</b> (hex digest, no spaces), published at
886 * <b>published</b>. Store it so we can serve it to others. If
887 * <b>directory</b> is NULL, remove the entry with the given fingerprint from
891 dirserv_set_cached_networkstatus_v2(const char *directory
, const char *fp
,
895 if (!cached_v2_networkstatus
)
896 cached_v2_networkstatus
= strmap_new();
898 tor_assert(strlen(fp
) == HEX_DIGEST_LEN
);
900 if (!(d
= strmap_get(cached_v2_networkstatus
, fp
))) {
903 d
= tor_malloc_zero(sizeof(cached_dir_t
));
904 strmap_set(cached_v2_networkstatus
, fp
, d
);
909 set_cached_dir(d
, tor_strdup(directory
), published
);
912 strmap_remove(cached_v2_networkstatus
, fp
);
916 /** Helper: If we're an authority for the right directory version (the
917 * directory version is determined by <b>is_v1_object</b>), try to regenerate
918 * auth_src as appropriate and return it, falling back to cache_src on
919 * failure. If we're a cache, return cach_src.
921 static cached_dir_t
*
922 dirserv_pick_cached_dir_obj(cached_dir_t
*cache_src
,
923 cached_dir_t
*auth_src
,
924 time_t dirty
, int (*regenerate
)(void),
928 int authority
= get_options()->AuthoritativeDir
&&
929 (!is_v1_object
|| get_options()->V1AuthoritativeDir
);
934 /* We're authoritative. */
935 if (regenerate
!= NULL
) {
936 if (dirty
&& dirty
+ DIR_REGEN_SLACK_TIME
< time(NULL
)) {
938 log_fn(LOG_ERR
, "Couldn't generate %s?", name
);
942 log_fn(LOG_INFO
, "The %s is still clean; reusing.", name
);
945 return auth_src
? auth_src
: cache_src
;
949 /** Helper: If we're authoritative and <b>auth_src</b> is set, use
950 * <b>auth_src</b>, otherwise use <b>cache_src</b>. If we're using
951 * <b>auth_src</b> and it's been <b>dirty</b> for at least
952 * DIR_REGEN_SLACK_TIME seconds, call <b>regenerate</b>() to make a fresh one.
953 * Yields the compressed version of the directory object if <b>compress</b> is
954 * set; otherwise return the uncompressed version. (In either case, sets
955 * *<b>out</b> and returns the size of the buffer in *<b>out</b>.)
957 * Use <b>is_v1_object</b> to help determine whether we're authoritative for
958 * this kind of object.
961 dirserv_get_obj(const char **out
, int compress
,
962 cached_dir_t
*cache_src
,
963 cached_dir_t
*auth_src
,
964 time_t dirty
, int (*regenerate
)(void),
968 cached_dir_t
*d
= dirserv_pick_cached_dir_obj(
970 dirty
, regenerate
, name
, is_v1_object
);
974 *out
= compress
? d
->dir_z
: d
->dir
;
976 return compress
? d
->dir_z_len
: d
->dir_len
;
978 /* not yet available. */
983 /** Set *<b>directory</b> to the most recently generated encoded signed
984 * directory, generating a new one as necessary. If not an authoritative
985 * directory may return 0 if no directory is yet cached.*/
987 dirserv_get_directory(const char **directory
, int compress
)
989 return dirserv_get_obj(directory
, compress
,
990 &cached_directory
, &the_directory
,
991 the_directory_is_dirty
,
992 dirserv_regenerate_directory
,
993 "server directory", 1);
997 * Generate a fresh directory (authdirservers only.)
1000 dirserv_regenerate_directory(void)
1002 char *new_directory
=NULL
;
1004 if (dirserv_dump_directory_to_string(&new_directory
,
1005 get_identity_key())) {
1006 log(LOG_WARN
, "Error creating directory.");
1007 tor_free(new_directory
);
1010 set_cached_dir(&the_directory
, new_directory
, time(NULL
));
1011 log_fn(LOG_INFO
,"New directory (size %d):\n%s",(int)the_directory
.dir_len
,
1014 the_directory_is_dirty
= 0;
1016 /* Save the directory to disk so we re-load it quickly on startup.
1018 dirserv_set_cached_directory(the_directory
.dir
, time(NULL
), 0);
1023 /** For authoritative directories: the current (v1) network status */
1024 static cached_dir_t the_runningrouters
= { NULL
, NULL
, 0, 0, 0 };
1026 /** Replace the current running-routers list with a newly generated one. */
1028 generate_runningrouters(void)
1031 char *router_status
=NULL
;
1032 char digest
[DIGEST_LEN
];
1033 char published
[ISO_TIME_LEN
+1];
1035 crypto_pk_env_t
*private_key
= get_identity_key();
1036 char *identity_pkey
; /* Identity key, DER64-encoded. */
1037 size_t identity_pkey_len
;
1038 smartlist_t
*descriptor_list
= get_descriptor_list();
1040 if (list_server_status(descriptor_list
, &router_status
)) {
1043 if (crypto_pk_write_public_key_to_string(private_key
,&identity_pkey
,
1044 &identity_pkey_len
)<0) {
1045 log_fn(LOG_WARN
,"write identity_pkey to string failed!");
1048 format_iso_time(published
, time(NULL
));
1050 len
= 2048+strlen(router_status
);
1051 s
= tor_malloc_zero(len
);
1052 tor_snprintf(s
, len
,
1055 "router-status %s\n"
1056 "dir-signing-key\n%s"
1057 "directory-signature %s\n",
1058 published
, router_status
, identity_pkey
, get_options()->Nickname
);
1059 tor_free(router_status
);
1060 tor_free(identity_pkey
);
1061 if (router_get_runningrouters_hash(s
,digest
)) {
1062 log_fn(LOG_WARN
,"couldn't compute digest");
1065 if (router_append_dirobj_signature(s
, len
, digest
, private_key
)<0)
1068 set_cached_dir(&the_runningrouters
, s
, time(NULL
));
1069 runningrouters_is_dirty
= 0;
1074 tor_free(router_status
);
1078 /** Set *<b>rr</b> to the most recently generated encoded signed
1079 * running-routers list, generating a new one as necessary. Return the
1080 * size of the directory on success, and 0 on failure. */
1082 dirserv_get_runningrouters(const char **rr
, int compress
)
1084 return dirserv_get_obj(rr
, compress
,
1085 &cached_runningrouters
, &the_runningrouters
,
1086 runningrouters_is_dirty
,
1087 generate_runningrouters
,
1088 "v1 network status list", 1);
1091 /** Return true iff <b>ri</b> is "useful as an exit node", meaning
1092 * it allows exit to at least one /8 address space for at least
1093 * one of ports 80, 443, and 6667. */
1095 router_is_general_exit(routerinfo_t
*ri
)
1097 static const int ports
[] = { 80, 443, 6667 };
1100 for (i
= 0; i
< 3; ++i
) {
1101 struct addr_policy_t
*policy
= ri
->exit_policy
;
1102 for ( ; policy
; policy
= policy
->next
) {
1103 if (policy
->prt_min
> ports
[i
] || policy
->prt_max
< ports
[i
])
1104 continue; /* Doesn't cover our port. */
1105 if ((policy
->msk
& 0x00fffffful
) != 0)
1106 continue; /* Narrower than a /8. */
1107 if ((policy
->addr
& 0xff000000ul
) == 0x7f000000ul
)
1108 continue; /* 127.x */
1109 /* We have a match that is at least a /8. */
1110 if (policy
->policy_type
== ADDR_POLICY_ACCEPT
)
1115 return n_allowed
> 0;
1118 /** For authoritative directories: the current (v2) network status */
1119 static cached_dir_t the_v2_networkstatus
= { NULL
, NULL
, 0, 0, 0 };
1121 /** For authoritative directories only: replace the contents of
1122 * <b>the_v2_networkstatus</b> with a newly generated network status
1125 generate_v2_networkstatus(void)
1127 #define LONGEST_STATUS_FLAG_NAME_LEN 7
1128 #define N_STATUS_FLAGS 6
1129 #define RS_ENTRY_LEN \
1130 ( /* first line */ \
1131 MAX_NICKNAME_LEN+BASE64_DIGEST_LEN*2+ISO_TIME_LEN+INET_NTOA_BUF_LEN+ \
1132 5*2 /* ports */ + 10 /* punctuation */ + \
1134 (LONGEST_STATUS_FLAG_NAME_LEN+1)*N_STATUS_FLAGS + 2)
1137 size_t len
, identity_pkey_len
;
1138 char *status
= NULL
, *client_versions
= NULL
, *server_versions
= NULL
,
1139 *identity_pkey
= NULL
, *hostname
= NULL
;
1141 or_options_t
*options
= get_options();
1142 char fingerprint
[FINGERPRINT_LEN
+1];
1143 char ipaddr
[INET_NTOA_BUF_LEN
+1];
1144 char published
[ISO_TIME_LEN
];
1145 char digest
[DIGEST_LEN
];
1148 crypto_pk_env_t
*private_key
= get_identity_key();
1149 smartlist_t
*descriptor_list
= get_descriptor_list();
1150 time_t now
= time(NULL
);
1151 int naming
= options
->NamingAuthoritativeDir
;
1152 int versioning
= options
->VersioningAuthoritativeDir
;
1153 const char *contact
;
1155 if (!descriptor_list
) {
1156 log_fn(LOG_WARN
, "Couldn't get router list.");
1160 if (resolve_my_address(options
, &addr
, &hostname
)<0) {
1161 log_fn(LOG_WARN
, "Couldn't resolve my hostname");
1164 in
.s_addr
= htonl(addr
);
1165 tor_inet_ntoa(&in
, ipaddr
, sizeof(ipaddr
));
1167 format_iso_time(published
, time(NULL
));
1169 client_versions
= format_versions_list(options
->RecommendedClientVersions
);
1170 server_versions
= format_versions_list(options
->RecommendedServerVersions
);
1172 if (crypto_pk_write_public_key_to_string(private_key
, &identity_pkey
,
1173 &identity_pkey_len
)<0) {
1174 log_fn(LOG_WARN
,"Writing public key to string failed.");
1178 if (crypto_pk_get_fingerprint(private_key
, fingerprint
, 0)<0) {
1179 log_fn(LOG_ERR
, "Error computing fingerprint");
1183 contact
= get_options()->ContactInfo
;
1187 len
= 2048+strlen(client_versions
)+strlen(server_versions
)+identity_pkey_len
*2;
1188 len
+= (RS_ENTRY_LEN
)*smartlist_len(descriptor_list
) ;
1190 status
= tor_malloc(len
);
1191 tor_snprintf(status
, len
,
1192 "network-status-version 2\n"
1193 "dir-source %s %s %d\n"
1198 "client-versions %s\n"
1199 "server-versions %s\n"
1200 "dir-signing-key\n%s\n",
1201 hostname
, ipaddr
, (int)options
->DirPort
,
1205 naming
? " Names" : "",
1206 versioning
? " Versions" : "",
1210 outp
= status
+ strlen(status
);
1211 endp
= status
+ len
;
1213 SMARTLIST_FOREACH(descriptor_list
, routerinfo_t
*, ri
, {
1214 int f_exit
= router_is_general_exit(ri
);
1215 int f_stable
= !router_is_unreliable(ri
, 1, 0);
1216 int f_fast
= !router_is_unreliable(ri
, 0, 1);
1218 int f_authority
= router_digest_is_trusted_dir(ri
->identity_digest
);
1219 int f_named
= naming
&& ri
->is_named
;
1220 int f_valid
= ri
->is_verified
;
1221 char identity64
[BASE64_DIGEST_LEN
+1];
1222 char digest64
[BASE64_DIGEST_LEN
+1];
1223 if (options
->AuthoritativeDir
) {
1224 ri
->is_running
= dirserv_thinks_router_is_reachable(ri
, now
);
1226 f_running
= ri
->is_running
;
1228 format_iso_time(published
, ri
->published_on
);
1230 digest_to_base64(identity64
, ri
->identity_digest
);
1231 digest_to_base64(digest64
, ri
->signed_descriptor_digest
);
1233 in
.s_addr
= htonl(ri
->addr
);
1234 tor_inet_ntoa(&in
, ipaddr
, sizeof(ipaddr
));
1236 if (tor_snprintf(outp
, endp
-outp
,
1237 "r %s %s %s %s %s %d %d\n"
1238 "s%s%s%s%s%s%s%s\n",
1246 f_authority
?" Authority":"",
1249 f_named
?" Named":"",
1250 f_stable
?" Stable":"",
1251 f_running
?" Running":"",
1252 f_valid
?" Valid":"")<0) {
1253 log_fn(LOG_WARN
, "Unable to print router status.");
1256 outp
+= strlen(outp
);
1259 if (tor_snprintf(outp
, endp
-outp
, "directory-signature %s\n",
1260 get_options()->Nickname
)<0) {
1261 log_fn(LOG_WARN
, "Unable to write signature line.");
1265 if (router_get_networkstatus_v2_hash(status
, digest
)<0) {
1266 log_fn(LOG_WARN
, "Unable to hash network status");
1270 if (router_append_dirobj_signature(outp
,endp
-outp
,digest
,private_key
)<0) {
1271 log_fn(LOG_WARN
, "Unable to sign router status.");
1275 set_cached_dir(&the_v2_networkstatus
, status
, time(NULL
));
1276 status
= NULL
; /* So it doesn't get double-freed. */
1277 the_v2_networkstatus_is_dirty
= 0;
1278 router_set_networkstatus(the_v2_networkstatus
.dir
, time(NULL
), NS_GENERATED
,
1283 tor_free(client_versions
);
1284 tor_free(server_versions
);
1287 tor_free(identity_pkey
);
1291 /** Look for a network status object as specified by <b>key</b>, which should
1292 * be either "authority" (to find a network status generated by us), a hex
1293 * identity digest (to find a network status generated by given directory), or
1294 * "all" (to return all the v2 network status objects we have, concatenated).
1295 * If <b>compress</b>, find the version compressed with zlib. Return 0 if
1296 * nothing was found; otherwise set *<b>directory</b> to the matching network
1297 * status and return its length.
1300 dirserv_get_networkstatus_v2(smartlist_t
*result
,
1305 if (!cached_v2_networkstatus
)
1306 cached_v2_networkstatus
= strmap_new();
1308 if (!(strcmp(key
,"authority"))) {
1309 if (get_options()->AuthoritativeDir
) {
1311 dirserv_pick_cached_dir_obj(NULL
,
1312 &the_v2_networkstatus
,
1313 the_v2_networkstatus_is_dirty
,
1314 generate_v2_networkstatus
,
1315 "network status list", 0);
1316 log_fn(LOG_WARN
, "Unable to generate an authoritative network stautus.");
1318 smartlist_add(result
, d
);
1320 } else if (!strcmp(key
, "all")) {
1321 strmap_iter_t
*iter
= strmap_iter_init(cached_v2_networkstatus
);
1322 while (!strmap_iter_done(iter
)) {
1325 strmap_iter_get(iter
, &fp
, &val
);
1326 smartlist_add(result
, val
);
1327 iter
= strmap_iter_next(cached_v2_networkstatus
, iter
);
1329 if (smartlist_len(result
) == 0)
1330 log_fn(LOG_WARN
, "Client requested 'all' network status objects; we have none.");
1331 } else if (!strcmpstart(key
, "fp/")) {
1332 smartlist_t
*hexdigests
= smartlist_create();
1333 dir_split_resource_into_fingerprints(key
+3, hexdigests
, NULL
);
1334 SMARTLIST_FOREACH(hexdigests
, char *, cp
,
1336 cached_dir_t
*cached
;
1338 if (router_fingerprint_is_me(cp
) &&
1339 get_options()->AuthoritativeDir
&&
1340 the_v2_networkstatus_is_dirty
&&
1341 the_v2_networkstatus_is_dirty
+ DIR_REGEN_SLACK_TIME
< time(NULL
))
1342 generate_v2_networkstatus();
1343 cached
= strmap_get(cached_v2_networkstatus
, cp
);
1345 smartlist_add(result
, cached
);
1347 log_fn(LOG_INFO
, "Don't know about any network status with fingerprint '%s'", cp
);
1351 smartlist_free(hexdigests
);
1356 /** Add a routerinfo_t to <b>descs_out</b> for each router matching
1357 * <b>key</b>. The key should be either "/tor/server/authority" for our own
1358 * routerinfo; "/tor/server/all" for all the routerinfos we have,
1359 * concatenated; or "/tor/server/FP" where FP is a plus-separated sequence of
1360 * hex identity digests.
1363 dirserv_get_routerdescs(smartlist_t
*descs_out
, const char *key
)
1365 smartlist_t
*complete_list
= get_descriptor_list();
1369 if (!strcmp(key
, "/tor/server/all")) {
1370 smartlist_add_all(descs_out
, complete_list
);
1371 } else if (!strcmp(key
, "/tor/server/authority")) {
1372 routerinfo_t
*ri
= router_get_my_routerinfo();
1374 smartlist_add(descs_out
, ri
);
1375 } else if (!strcmpstart(key
, "/tor/server/fp/")) {
1376 smartlist_t
*hexdigests
= smartlist_create();
1377 smartlist_t
*digests
= smartlist_create();
1378 key
+= strlen("/tor/server/fp/");
1379 dir_split_resource_into_fingerprints(key
, hexdigests
, NULL
);
1380 SMARTLIST_FOREACH(hexdigests
, char *, cp
,
1383 if (strlen(cp
) != HEX_DIGEST_LEN
)
1385 d
= tor_malloc_zero(DIGEST_LEN
);
1386 base16_decode(d
, DIGEST_LEN
, cp
, HEX_DIGEST_LEN
);
1388 smartlist_add(digests
, d
);
1390 smartlist_free(hexdigests
);
1391 SMARTLIST_FOREACH(digests
, const char *, d
,
1393 if (router_digest_is_me(d
)) {
1394 smartlist_add(descs_out
, router_get_my_routerinfo());
1396 routerinfo_t
*ri
= router_get_by_digest(d
);
1398 smartlist_add(descs_out
,ri
);
1401 SMARTLIST_FOREACH(digests
, char *, d
, tor_free(d
));
1402 smartlist_free(digests
);
1406 /** Called when a TLS handshake has completed successfully with a
1407 * router listening at <b>address</b>:<b>or_port</b>, and has yielded
1408 * a certificate with digest <b>digest_rcvd</b> and nickname
1409 * <b>nickname_rcvd</b>. When this happens, it's clear that any other
1410 * descriptors for that address/port combination must be unusable:
1411 * delete them if they are not verified.
1413 * Also, if as_advertised is 1, then inform the reachability checker
1414 * that we could get to this guy.
1417 dirserv_orconn_tls_done(const char *address
,
1419 const char *digest_rcvd
,
1420 const char *nickname_rcvd
,
1424 smartlist_t
*descriptor_list
= get_descriptor_list();
1425 tor_assert(address
);
1426 tor_assert(digest_rcvd
);
1427 tor_assert(nickname_rcvd
);
1429 if (!descriptor_list
)
1432 // XXXXNM We should really have a better solution here than dropping
1433 // XXXXNM whole routers; otherwise, they come back way too easily.
1434 for (i
= 0; i
< smartlist_len(descriptor_list
); ++i
) {
1435 routerinfo_t
*ri
= smartlist_get(descriptor_list
, i
);
1437 if (strcasecmp(address
, ri
->address
) || or_port
!= ri
->or_port
)
1439 if (!ri
->is_verified
) {
1440 /* We have a router at the same address! */
1441 if (strcasecmp(ri
->nickname
, nickname_rcvd
)) {
1442 log_fn(LOG_NOTICE
, "Dropping descriptor: nickname '%s' does not match nickname '%s' in cert from %s:%d",
1443 ri
->nickname
, nickname_rcvd
, address
, or_port
);
1445 } else if (memcmp(ri
->identity_digest
, digest_rcvd
, DIGEST_LEN
)) {
1446 log_fn(LOG_NOTICE
, "Dropping descriptor: identity key does not match key in cert from %s:%d",
1452 routerinfo_free(ri
);
1453 smartlist_del(descriptor_list
, i
--);
1454 directory_set_dirty();
1455 } else { /* correct nickname and digest. mark this router reachable! */
1456 log_fn(LOG_INFO
,"Found router %s to be reachable. Yay.", ri
->nickname
);
1457 ri
->last_reachable
= time(NULL
);
1458 ri
->num_unreachable_notifications
= 0;
1463 /** Release all storage used by the directory server. */
1465 dirserv_free_all(void)
1467 if (fingerprint_list
) {
1468 SMARTLIST_FOREACH(fingerprint_list
, fingerprint_entry_t
*, fp
,
1469 { tor_free(fp
->nickname
);
1470 tor_free(fp
->fingerprint
);
1472 smartlist_free(fingerprint_list
);
1473 fingerprint_list
= NULL
;
1475 if (authdir_reject_policy
)
1476 addr_policy_free(authdir_reject_policy
);
1477 if (authdir_invalid_policy
)
1478 addr_policy_free(authdir_invalid_policy
);
1479 clear_cached_dir(&the_directory
);
1480 clear_cached_dir(&the_runningrouters
);
1481 clear_cached_dir(&cached_directory
);
1482 clear_cached_dir(&cached_runningrouters
);
1483 if (cached_v2_networkstatus
) {
1484 strmap_free(cached_v2_networkstatus
, free_cached_dir
);
1485 cached_v2_networkstatus
= NULL
;