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