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 /** Do we need to regenerate the directory when someone asks for it? */
25 static int the_directory_is_dirty
= 1;
26 static int runningrouters_is_dirty
= 1;
27 static int the_v2_networkstatus_is_dirty
= 1;
29 static void directory_remove_invalid(void);
30 static cached_dir_t
*dirserv_regenerate_directory(void);
31 static char *format_versions_list(config_line_t
*ln
);
32 /* Should be static; exposed for testing */
33 struct authdir_config_t
;
34 int add_fingerprint_to_dir(const char *nickname
, const char *fp
,
35 struct authdir_config_t
*list
);
36 static uint32_t dirserv_router_get_status(const routerinfo_t
*router
,
39 dirserv_get_status_impl(const char *fp
, const char *nickname
,
41 uint32_t addr
, uint16_t or_port
,
42 const char *platform
, const char *contact
,
43 const char **msg
, int should_log
);
44 static int dirserv_thinks_router_is_reachable(routerinfo_t
*router
,
46 static void clear_cached_dir(cached_dir_t
*d
);
48 /************** Fingerprint handling code ************/
50 #define FP_NAMED 1 /**< Listed in fingerprint file. */
51 #define FP_INVALID 2 /**< Believed invalid. */
52 #define FP_REJECT 4 /**< We will not publish this router. */
53 #define FP_BADEXIT 8 /**< We'll tell clients not to use this as an exit. */
55 typedef struct router_status_t
{
56 char nickname
[MAX_NICKNAME_LEN
+1];
60 /** List of nickname-\>identity fingerprint mappings for all the routers
61 * that we name. Used to prevent router impersonation. DODDOC */
62 typedef struct authdir_config_t
{
63 strmap_t
*fp_by_name
; /* Map from lc nickname to fingerprint */
64 digestmap_t
*status_by_digest
; /* Map from digest to FP_x mask */
67 /* Should be static; exposed for testing */
68 authdir_config_t
*fingerprint_list
= NULL
;
70 static authdir_config_t
*
71 authdir_config_new(void)
73 authdir_config_t
*list
= tor_malloc_zero(sizeof(authdir_config_t
));
74 list
->fp_by_name
= strmap_new();
75 list
->status_by_digest
= digestmap_new();
79 /** Add the fingerprint <b>fp</b> for the nickname <b>nickname</b> to
80 * the smartlist of fingerprint_entry_t's <b>list</b>. Return 0 if it's
81 * new, or 1 if we replaced the old value.
83 int /* Should be static; exposed for testing */
84 add_fingerprint_to_dir(const char *nickname
, const char *fp
,
85 authdir_config_t
*list
)
89 router_status_t
*status
;
94 fingerprint
= tor_strdup(fp
);
95 tor_strstrip(fingerprint
, " ");
96 if (base16_decode(d
, DIGEST_LEN
, fingerprint
, strlen(fingerprint
))) {
97 log_warn(LD_DIRSERV
, "Couldn't decode fingerprint \"%s\"",
99 tor_free(fingerprint
);
103 if (!strcasecmp(nickname
, UNNAMED_ROUTER_NICKNAME
)) {
104 log_warn(LD_DIRSERV
, "Tried to add a mapping for reserved nickname %s",
105 UNNAMED_ROUTER_NICKNAME
);
106 tor_free(fingerprint
);
110 status
= digestmap_get(list
->status_by_digest
, d
);
112 status
= tor_malloc_zero(sizeof(router_status_t
));
113 digestmap_set(list
->status_by_digest
, d
, status
);
116 if (nickname
[0] != '!') {
117 char *old_fp
= strmap_get_lc(list
->fp_by_name
, nickname
);
118 if (old_fp
&& !strcasecmp(fingerprint
, old_fp
)) {
119 tor_free(fingerprint
);
122 strmap_set_lc(list
->fp_by_name
, nickname
, fingerprint
);
124 status
->status
|= FP_NAMED
;
125 strlcpy(status
->nickname
, nickname
, sizeof(status
->nickname
));
127 tor_free(fingerprint
);
128 if (!strcasecmp(nickname
, "!reject")) {
129 status
->status
|= FP_REJECT
;
130 } else if (!strcasecmp(nickname
, "!invalid")) {
131 status
->status
|= FP_INVALID
;
132 } else if (!strcasecmp(nickname
, "!badexit")) {
133 status
->status
|= FP_BADEXIT
;
139 /** Add the nickname and fingerprint for this OR to the
140 * global list of recognized identity key fingerprints. */
142 dirserv_add_own_fingerprint(const char *nickname
, crypto_pk_env_t
*pk
)
144 char fp
[FINGERPRINT_LEN
+1];
145 if (crypto_pk_get_fingerprint(pk
, fp
, 0)<0) {
146 log_err(LD_BUG
, "Error computing fingerprint");
149 if (!fingerprint_list
)
150 fingerprint_list
= authdir_config_new();
151 add_fingerprint_to_dir(nickname
, fp
, fingerprint_list
);
155 /** Load the nickname-\>fingerprint mappings stored in the approved-routers
156 * file. The file format is line-based, with each non-blank holding one
157 * nickname, some space, and a fingerprint for that nickname. On success,
158 * replace the current fingerprint list with the new list and return 0. On
159 * failure, leave the current fingerprint list untouched, and
162 dirserv_load_fingerprint_file(void)
166 char *nickname
, *fingerprint
;
167 authdir_config_t
*fingerprint_list_new
;
169 config_line_t
*front
=NULL
, *list
;
170 or_options_t
*options
= get_options();
172 tor_snprintf(fname
, sizeof(fname
),
173 "%s/approved-routers", options
->DataDirectory
);
175 "Reloading approved fingerprints from \"%s\"...", fname
);
177 cf
= read_file_to_str(fname
, 0, NULL
);
179 if (options
->NamingAuthoritativeDir
) {
180 log_warn(LD_FS
, "Cannot open fingerprint file '%s'. Failing.", fname
);
183 log_info(LD_FS
, "Cannot open fingerprint file '%s'. Returning.", fname
);
187 result
= config_get_lines(cf
, &front
);
190 log_warn(LD_CONFIG
, "Error reading from fingerprint file");
194 fingerprint_list_new
= authdir_config_new();
196 for (list
=front
; list
; list
=list
->next
) {
197 nickname
= list
->key
; fingerprint
= list
->value
;
198 if (strlen(nickname
) > MAX_NICKNAME_LEN
) {
199 log_notice(LD_CONFIG
,
200 "Nickname '%s' too long in fingerprint file. Skipping.",
204 if (!is_legal_nickname(nickname
) &&
205 strcasecmp(nickname
, "!reject") &&
206 strcasecmp(nickname
, "!invalid") &&
207 strcasecmp(nickname
, "!badexit")) {
208 log_notice(LD_CONFIG
,
209 "Invalid nickname '%s' in fingerprint file. Skipping.",
213 if (strlen(fingerprint
) != FINGERPRINT_LEN
||
214 !crypto_pk_check_fingerprint_syntax(fingerprint
)) {
215 log_notice(LD_CONFIG
,
216 "Invalid fingerprint (nickname '%s', "
217 "fingerprint %s). Skipping.",
218 nickname
, fingerprint
);
221 if (0==strcasecmp(nickname
, DEFAULT_CLIENT_NICKNAME
)) {
222 /* If you approved an OR called "client", then clients who use
223 * the default nickname could all be rejected. That's no good. */
224 log_notice(LD_CONFIG
,
225 "Authorizing a nickname '%s' would break "
226 "many clients; skipping.",
227 DEFAULT_CLIENT_NICKNAME
);
230 if (0==strcasecmp(nickname
, DEFAULT_CLIENT_NICKNAME
)) {
231 /* If you approved an OR called "client", then clients who use
232 * the default nickname could all be rejected. That's no good. */
233 log_notice(LD_CONFIG
,
234 "Authorizing a nickname '%s' would break "
235 "many clients; skipping.",
236 DEFAULT_CLIENT_NICKNAME
);
239 if (0==strcasecmp(nickname
, UNNAMED_ROUTER_NICKNAME
)) {
240 /* If you approved an OR called "unnamed", then clients will be
242 log_notice(LD_CONFIG
,
243 "Authorizing a nickname '%s' is not allowed; skipping.",
244 UNNAMED_ROUTER_NICKNAME
);
247 if (add_fingerprint_to_dir(nickname
, fingerprint
, fingerprint_list_new
)
249 log_notice(LD_CONFIG
, "Duplicate nickname '%s'.", nickname
);
252 config_free_lines(front
);
253 dirserv_free_fingerprint_list();
254 fingerprint_list
= fingerprint_list_new
;
255 /* Delete any routers whose fingerprints we no longer recognize */
256 directory_remove_invalid();
260 /** Check whether <b>router</b> has a nickname/identity key combination that
261 * we recognize from the fingerprint list, or an IP we automatically act on
262 * according to our configuration. Return the appropriate router status.
264 * If the status is 'FP_REJECT' and <b>msg</b> is provided, set
265 * *<b>msg</b> to an explanation of why. */
267 dirserv_router_get_status(const routerinfo_t
*router
, const char **msg
)
271 if (crypto_pk_get_digest(router
->identity_pkey
, d
)) {
272 log_warn(LD_BUG
,"Error computing fingerprint");
274 *msg
= "Bug: Error computing fingerprint";
278 return dirserv_get_status_impl(d
, router
->nickname
,
280 router
->addr
, router
->or_port
,
281 router
->platform
, router
->contact_info
,
285 /** Return true if there is no point in downloading the router described by
286 * <b>rs</b> because this directory would reject it. */
288 dirserv_would_reject_router(routerstatus_t
*rs
)
292 res
= dirserv_get_status_impl(rs
->identity_digest
, rs
->nickname
,
293 "", /* address is only used in logs */
294 rs
->addr
, rs
->or_port
,
298 return (res
& FP_REJECT
) != 0;
301 /** Helper: As dirserv_get_router_status, but takes the router fingerprint
302 * (hex, no spaces), nickname, address (used for logging only), IP address, OR
303 * port, platform (logging only) and contact info (logging only) as arguments.
305 * If should_log is false, do not log messages. (There's not much point in
306 * logging that we're rejecting servers we'll not download.)
309 dirserv_get_status_impl(const char *id_digest
, const char *nickname
,
311 uint32_t addr
, uint16_t or_port
,
312 const char *platform
, const char *contact
,
313 const char **msg
, int should_log
)
315 char fp
[HEX_DIGEST_LEN
+1];
316 int reject_unlisted
= get_options()->AuthDirRejectUnlisted
;
318 router_status_t
*status_by_digest
;
320 if (!fingerprint_list
)
321 fingerprint_list
= authdir_config_new();
323 base16_encode(fp
, sizeof(fp
), id_digest
, DIGEST_LEN
);
326 log_debug(LD_DIRSERV
, "%d fingerprints, %d digests known.",
327 strmap_size(fingerprint_list
->fp_by_name
),
328 digestmap_size(fingerprint_list
->status_by_digest
));
331 strmap_get_lc(fingerprint_list
->fp_by_name
, nickname
))) {
332 if (!strcasecmp(fp
, fp_by_name
)) {
335 log_debug(LD_DIRSERV
,"Good fingerprint for '%s'",nickname
);
338 char *esc_contact
= esc_for_log(contact
);
340 "Mismatched fingerprint for '%s': expected '%s' got '%s'. "
341 "ContactInfo '%s', platform '%s'.)",
342 nickname
, fp_by_name
, fp
,
344 platform
? escaped(platform
) : "");
345 tor_free(esc_contact
);
348 *msg
= "Rejected: There is already a named server with this nickname "
349 "and a different fingerprint.";
350 return FP_REJECT
; /* Wrong fingerprint. */
353 status_by_digest
= digestmap_get(fingerprint_list
->status_by_digest
,
355 if (status_by_digest
)
356 result
|= (status_by_digest
->status
& ~FP_NAMED
);
358 if (result
& FP_REJECT
) {
360 *msg
= "Fingerprint is marked rejected";
362 } else if (result
& FP_INVALID
) {
364 *msg
= "Fingerprint is marked invalid";
367 if (authdir_policy_badexit_address(addr
, or_port
)) {
369 log_info(LD_DIRSERV
, "Marking '%s' as bad exit because of address '%s'",
371 result
|= FP_BADEXIT
;
374 if (!(result
& FP_NAMED
)) {
375 if (!authdir_policy_permits_address(addr
, or_port
)) {
377 log_info(LD_DIRSERV
, "Rejecting '%s' because of address '%s'",
380 *msg
= "Authdir is rejecting routers in this range.";
383 if (!authdir_policy_valid_address(addr
, or_port
)) {
385 log_info(LD_DIRSERV
, "Not marking '%s' valid because of address '%s'",
387 result
|= FP_INVALID
;
389 if (reject_unlisted
) {
391 *msg
= "Authdir rejects unknown routers.";
394 /* 0.1.0.2-rc was the first version that did enough self-testing that
395 * we're willing to take its word about whether it's running. */
396 if (platform
&& !tor_version_as_new_as(platform
,"0.1.0.2-rc"))
397 result
|= FP_INVALID
;
403 /** If we are an authoritative dirserver, and the list of approved
404 * servers contains one whose identity key digest is <b>digest</b>,
405 * return that router's nickname. Otherwise return NULL. */
407 dirserv_get_nickname_by_digest(const char *digest
)
409 router_status_t
*status
;
410 if (!fingerprint_list
)
414 status
= digestmap_get(fingerprint_list
->status_by_digest
, digest
);
415 return status
? status
->nickname
: NULL
;
418 /** Clear the current fingerprint list. */
420 dirserv_free_fingerprint_list(void)
422 if (!fingerprint_list
)
425 strmap_free(fingerprint_list
->fp_by_name
, _tor_free
);
426 digestmap_free(fingerprint_list
->status_by_digest
, _tor_free
);
427 tor_free(fingerprint_list
);
434 /** Return -1 if <b>ri</b> has a private or otherwise bad address,
435 * unless we're configured to not care. Return 0 if all ok. */
437 dirserv_router_has_valid_address(routerinfo_t
*ri
)
439 struct in_addr iaddr
;
440 if (get_options()->DirAllowPrivateAddresses
)
441 return 0; /* whatever it is, we're fine with it */
442 if (!tor_inet_aton(ri
->address
, &iaddr
)) {
443 log_info(LD_DIRSERV
,"Router '%s' published non-IP address '%s'. Refusing.",
444 ri
->nickname
, ri
->address
);
447 if (is_internal_IP(ntohl(iaddr
.s_addr
), 0)) {
449 "Router '%s' published internal IP address '%s'. Refusing.",
450 ri
->nickname
, ri
->address
);
451 return -1; /* it's a private IP, we should reject it */
456 /** Check whether we, as a directory server, want to accept <b>ri</b>. If so,
457 * set its is_valid,named,running fields and return 0. Otherwise, return -1.
459 * If the router is rejected, set *<b>msg</b> to an explanation of why.
461 * If <b>complain</b> then explain at log-level 'notice' why we refused
462 * a descriptor; else explain at log-level 'info'.
465 authdir_wants_to_reject_router(routerinfo_t
*ri
, const char **msg
,
468 /* Okay. Now check whether the fingerprint is recognized. */
469 uint32_t status
= dirserv_router_get_status(ri
, msg
);
471 int severity
= complain
? LOG_NOTICE
: LOG_INFO
;
473 if (status
& FP_REJECT
)
474 return -1; /* msg is already set. */
476 /* Is there too much clock skew? */
478 if (ri
->cache_info
.published_on
> now
+ROUTER_ALLOW_SKEW
) {
479 log_fn(severity
, LD_DIRSERV
, "Publication time for nickname '%s' is too "
480 "far (%d minutes) in the future; possible clock skew. Not adding "
482 ri
->nickname
, (int)((ri
->cache_info
.published_on
-now
)/60),
483 esc_router_info(ri
));
484 *msg
= "Rejected: Your clock is set too far in the future, or your "
485 "timezone is not correct.";
488 if (ri
->cache_info
.published_on
< now
-ROUTER_MAX_AGE_TO_PUBLISH
) {
489 log_fn(severity
, LD_DIRSERV
,
490 "Publication time for router with nickname '%s' is too far "
491 "(%d minutes) in the past. Not adding (%s)",
492 ri
->nickname
, (int)((now
-ri
->cache_info
.published_on
)/60),
493 esc_router_info(ri
));
494 *msg
= "Rejected: Server is expired, or your clock is too far in the past,"
495 " or your timezone is not correct.";
498 if (dirserv_router_has_valid_address(ri
) < 0) {
499 log_fn(severity
, LD_DIRSERV
,
500 "Router with nickname '%s' has invalid address '%s'. "
502 ri
->nickname
, ri
->address
,
503 esc_router_info(ri
));
504 *msg
= "Rejected: Address is not an IP, or IP is a private address.";
507 /* Okay, looks like we're willing to accept this one. */
508 ri
->is_named
= (status
& FP_NAMED
) ? 1 : 0;
509 ri
->is_valid
= (status
& FP_INVALID
) ? 0 : 1;
510 ri
->is_bad_exit
= (status
& FP_BADEXIT
) ? 1 : 0;
515 /** Parse the server descriptor at <b>desc</b> and maybe insert it into
516 * the list of server descriptors. Set *<b>msg</b> to a message that
517 * should be passed back to the origin of this descriptor.
519 * Return 2 if descriptor is well-formed and accepted;
520 * 1 if well-formed and accepted but origin should hear *msg;
521 * 0 if well-formed but redundant with one we already have;
522 * -1 if it looks vaguely like a router descriptor but rejected;
523 * -2 if we can't find a router descriptor in <b>desc</b>.
526 dirserv_add_descriptor(const char *desc
, const char **msg
)
529 routerinfo_t
*ri
= NULL
, *ri_old
= NULL
;
533 /* Check: is the descriptor syntactically valid? */
534 ri
= router_parse_entry_from_string(desc
, NULL
, 1);
536 log_warn(LD_DIRSERV
, "Couldn't parse uploaded server descriptor");
537 *msg
= "Rejected: Couldn't parse server descriptor.";
540 /* Check whether this descriptor is semantically identical to the last one
541 * from this server. (We do this here and not in router_add_to_routerlist
542 * because we want to be able to accept the newest router descriptor that
543 * another authority has, so we all converge on the same one.) */
544 ri_old
= router_get_by_digest(ri
->cache_info
.identity_digest
);
545 if (ri_old
&& ri_old
->cache_info
.published_on
< ri
->cache_info
.published_on
546 && router_differences_are_cosmetic(ri_old
, ri
)
547 && !router_is_me(ri
)) {
549 "Not replacing descriptor from '%s'; differences are cosmetic.",
551 *msg
= "Not replacing router descriptor; no information has changed since "
552 "the last one with this identity.";
554 control_event_or_authdir_new_descriptor("DROPPED", desc
, *msg
);
557 if ((r
= router_add_to_routerlist(ri
, msg
, 0, 0))<0) {
558 if (r
< -1) /* unless the routerinfo was fine, just out-of-date */
559 control_event_or_authdir_new_descriptor("REJECTED", desc
, *msg
);
560 return r
== -1 ? 0 : -1;
562 smartlist_t
*changed
;
563 control_event_or_authdir_new_descriptor("ACCEPTED", desc
, *msg
);
565 changed
= smartlist_create();
566 smartlist_add(changed
, ri
);
567 control_event_descriptors_changed(changed
);
568 smartlist_free(changed
);
570 *msg
= ri
->is_valid
? "Descriptor for valid server accepted" :
571 "Descriptor for invalid server accepted";
573 return r
== 0 ? 2 : 1;
578 bool_neq(int a
, int b
)
580 return (a
&& !b
) || (!a
&& b
);
583 /** Remove all descriptors whose nicknames or fingerprints no longer
584 * are allowed by our fingerprint list. (Descriptors that used to be
585 * good can become bad when we reload the fingerprint list.)
588 directory_remove_invalid(void)
592 routerlist_t
*rl
= router_get_routerlist();
594 for (i
= 0; i
< smartlist_len(rl
->routers
); ++i
) {
596 routerinfo_t
*ent
= smartlist_get(rl
->routers
, i
);
597 uint32_t r
= dirserv_router_get_status(ent
, &msg
);
599 log_info(LD_DIRSERV
, "Router '%s' is now rejected: %s",
600 ent
->nickname
, msg
?msg
:"");
601 routerlist_remove(rl
, ent
, i
--, 0);
604 if (bool_neq((r
& FP_NAMED
), ent
->is_named
)) {
606 "Router '%s' is now %snamed.", ent
->nickname
,
607 (r
&FP_NAMED
)?"":"un");
608 ent
->is_named
= (r
&FP_NAMED
)?1:0;
611 if (bool_neq((r
& FP_INVALID
), !ent
->is_valid
)) {
612 log_info(LD_DIRSERV
, "Router '%s' is now %svalid.", ent
->nickname
,
613 (r
&FP_INVALID
) ? "in" : "");
614 ent
->is_valid
= (r
&FP_INVALID
)?0:1;
617 if (bool_neq((r
& FP_BADEXIT
), ent
->is_bad_exit
)) {
618 log_info(LD_DIRSERV
, "Router '%s' is now a %s exit", ent
->nickname
,
619 (r
& FP_BADEXIT
) ? "bad" : "good");
620 ent
->is_bad_exit
= (r
&FP_BADEXIT
) ? 1: 0;
625 directory_set_dirty();
628 /** Write a list of unregistered descriptors into a newly allocated
629 * string and return it. Used by dirserv operators to keep track of
630 * fast nodes that haven't registered.
633 getinfo_helper_dirserv_unregistered(control_connection_t
*control_conn
,
634 const char *question
, char **answer_out
)
636 smartlist_t
*answerlist
;
639 int min_bw
= atoi(question
);
640 routerlist_t
*rl
= router_get_routerlist();
644 if (strcmpstart(question
, "unregistered-servers-"))
646 question
+= strlen("unregistered-servers-");
648 answerlist
= smartlist_create();
649 SMARTLIST_FOREACH(rl
->routers
, routerinfo_t
*, ent
, {
650 uint32_t r
= dirserv_router_get_status(ent
, NULL
);
651 if (router_get_advertised_bandwidth(ent
) >= (size_t)min_bw
&&
653 /* then log this one */
654 tor_snprintf(buf
, sizeof(buf
),
655 "%s: BW %d on '%s'.",
656 ent
->nickname
, router_get_advertised_bandwidth(ent
),
657 ent
->platform
? ent
->platform
: "");
658 smartlist_add(answerlist
, tor_strdup(buf
));
661 answer
= smartlist_join_strings(answerlist
, "\r\n", 0, NULL
);
662 SMARTLIST_FOREACH(answerlist
, char *, cp
, tor_free(cp
));
663 smartlist_free(answerlist
);
664 *answer_out
= answer
;
668 /** Mark the directory as <b>dirty</b> -- when we're next asked for a
669 * directory, we will rebuild it instead of reusing the most recently
673 directory_set_dirty(void)
675 time_t now
= time(NULL
);
677 if (!the_directory_is_dirty
)
678 the_directory_is_dirty
= now
;
679 if (!runningrouters_is_dirty
)
680 runningrouters_is_dirty
= now
;
681 if (!the_v2_networkstatus_is_dirty
)
682 the_v2_networkstatus_is_dirty
= now
;
686 * Allocate and return a description of the status of the server <b>desc</b>,
687 * for use in a router-status line. The server is listed
688 * as running iff <b>is_live</b> is true.
691 list_single_server_status(routerinfo_t
*desc
, int is_live
)
693 char buf
[MAX_NICKNAME_LEN
+HEX_DIGEST_LEN
+4]; /* !nickname=$hexdigest\0 */
702 if (desc
->is_valid
) {
703 strlcpy(cp
, desc
->nickname
, sizeof(buf
)-(cp
-buf
));
708 base16_encode(cp
, HEX_DIGEST_LEN
+1, desc
->cache_info
.identity_digest
,
710 return tor_strdup(buf
);
713 /** Each server needs to have passed a reachability test no more
714 * than this number of seconds ago, or he is listed as down in
716 #define REACHABLE_TIMEOUT (45*60)
718 /** Treat a router as alive if
719 * - It's me, and I'm not hibernating.
720 * or - We've found it reachable recently. */
722 dirserv_thinks_router_is_reachable(routerinfo_t
*router
, time_t now
)
724 if (router_is_me(router
) && !we_are_hibernating())
726 return get_options()->AssumeReachable
||
727 now
< router
->last_reachable
+ REACHABLE_TIMEOUT
;
730 /** Return 1 if we're confident that there's a problem with
731 * <b>router</b>'s reachability and its operator should be notified.
734 dirserv_thinks_router_is_blatantly_unreachable(routerinfo_t
*router
,
737 if (router
->is_hibernating
)
739 if (now
>= router
->last_reachable
+ 5*REACHABLE_TIMEOUT
&&
740 router
->testing_since
&&
741 now
>= router
->testing_since
+ 5*REACHABLE_TIMEOUT
)
746 /** Based on the routerinfo_ts in <b>routers</b>, allocate the
747 * contents of a router-status line, and store it in
748 * *<b>router_status_out</b>. Return 0 on success, -1 on failure.
750 * If for_controller is true, include the routers with very old descriptors.
751 * If for_controller is >1, use the verbose nickname format.
754 list_server_status(smartlist_t
*routers
, char **router_status_out
,
757 /* List of entries in a router-status style: An optional !, then an optional
758 * equals-suffixed nickname, then a dollar-prefixed hexdigest. */
759 smartlist_t
*rs_entries
;
760 time_t now
= time(NULL
);
761 time_t cutoff
= now
- ROUTER_MAX_AGE_TO_PUBLISH
;
762 int authdir_mode
= get_options()->AuthoritativeDir
;
763 tor_assert(router_status_out
);
765 rs_entries
= smartlist_create();
767 SMARTLIST_FOREACH(routers
, routerinfo_t
*, ri
,
770 /* Update router status in routerinfo_t. */
771 ri
->is_running
= dirserv_thinks_router_is_reachable(ri
, now
);
773 if (for_controller
== 1 || ri
->cache_info
.published_on
>= cutoff
)
774 smartlist_add(rs_entries
, list_single_server_status(ri
, ri
->is_running
));
775 else if (for_controller
> 2) {
776 char name_buf
[MAX_VERBOSE_NICKNAME_LEN
+2];
780 router_get_verbose_nickname(cp
, ri
);
781 smartlist_add(rs_entries
, tor_strdup(name_buf
));
785 *router_status_out
= smartlist_join_strings(rs_entries
, " ", 0, NULL
);
787 SMARTLIST_FOREACH(rs_entries
, char *, cp
, tor_free(cp
));
788 smartlist_free(rs_entries
);
793 /* Given a (possibly empty) list of config_line_t, each line of which contains
794 * a list of comma-separated version numbers surrounded by optional space,
795 * allocate and return a new string containing the version numbers, in order,
796 * separated by commas. Used to generate Recommended(Client|Server)?Versions
799 format_versions_list(config_line_t
*ln
)
801 smartlist_t
*versions
;
803 versions
= smartlist_create();
804 for ( ; ln
; ln
= ln
->next
) {
805 smartlist_split_string(versions
, ln
->value
, ",",
806 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, 0);
808 sort_version_list(versions
, 1);
809 result
= smartlist_join_strings(versions
,",",0,NULL
);
810 SMARTLIST_FOREACH(versions
,char *,s
,tor_free(s
));
811 smartlist_free(versions
);
815 /** Return 1 if <b>ri</b>'s descriptor is worth including in the v1
816 * directory, else return 0.
819 live_enough_for_v1_dir(routerinfo_t
*ri
, time_t now
)
821 time_t cutoff
= now
- ROUTER_MAX_AGE_TO_PUBLISH
;
822 if (ri
->cache_info
.published_on
< cutoff
)
824 if (!ri
->is_running
|| !ri
->is_valid
)
829 /** Generate a new v1 directory and write it into a newly allocated string.
830 * Point *<b>dir_out</b> to the allocated string. Sign the
831 * directory with <b>private_key</b>. Return 0 on success, -1 on
832 * failure. If <b>complete</b> is set, give us all the descriptors;
833 * otherwise leave out non-running and non-valid ones.
836 dirserv_dump_directory_to_string(char **dir_out
,
837 crypto_pk_env_t
*private_key
, int complete
)
841 char *identity_pkey
; /* Identity key, DER64-encoded. */
842 char *recommended_versions
;
843 char digest
[DIGEST_LEN
];
844 char published
[ISO_TIME_LEN
+1];
847 size_t identity_pkey_len
;
848 routerlist_t
*rl
= router_get_routerlist();
849 time_t now
= time(NULL
);
854 if (list_server_status(rl
->routers
, &router_status
, 0))
857 if (crypto_pk_write_public_key_to_string(private_key
,&identity_pkey
,
858 &identity_pkey_len
)<0) {
859 log_warn(LD_BUG
,"write identity_pkey to string failed!");
863 recommended_versions
=
864 format_versions_list(get_options()->RecommendedVersions
);
866 format_iso_time(published
, now
);
868 buf_len
= 2048+strlen(recommended_versions
)+
869 strlen(router_status
);
870 SMARTLIST_FOREACH(rl
->routers
, routerinfo_t
*, ri
,
871 if (complete
|| live_enough_for_v1_dir(ri
, now
))
872 buf_len
+= ri
->cache_info
.signed_descriptor_len
+1);
873 buf
= tor_malloc(buf_len
);
874 /* We'll be comparing against buf_len throughout the rest of the
875 function, though strictly speaking we shouldn't be able to exceed
876 it. This is C, after all, so we may as well check for buffer
879 tor_snprintf(buf
, buf_len
,
882 "recommended-software %s\n"
884 "dir-signing-key\n%s\n",
885 published
, recommended_versions
, router_status
,
888 tor_free(recommended_versions
);
889 tor_free(router_status
);
890 tor_free(identity_pkey
);
892 cp
= buf
+ strlen(buf
);
893 SMARTLIST_FOREACH(rl
->routers
, routerinfo_t
*, ri
,
895 size_t len
= ri
->cache_info
.signed_descriptor_len
;
897 if (!complete
&& !live_enough_for_v1_dir(ri
, now
))
899 if (cp
+len
+1 >= buf
+buf_len
)
901 body
= signed_descriptor_get_body(&ri
->cache_info
);
902 memcpy(cp
, body
, len
);
904 *cp
++ = '\n'; /* add an extra newline in case somebody was depending on
909 /* These multiple strlcat calls are inefficient, but dwarfed by the RSA
911 if (strlcat(buf
, "directory-signature ", buf_len
) >= buf_len
)
913 if (strlcat(buf
, get_options()->Nickname
, buf_len
) >= buf_len
)
915 if (strlcat(buf
, "\n", buf_len
) >= buf_len
)
918 if (router_get_dir_hash(buf
,digest
)) {
919 log_warn(LD_BUG
,"couldn't compute digest");
923 note_crypto_pk_op(SIGN_DIR
);
924 if (router_append_dirobj_signature(buf
,buf_len
,digest
,private_key
)<0) {
932 log_warn(LD_BUG
,"tried to exceed string length.");
937 /** Most recently generated encoded signed directory. (auth dirservers only.)*/
938 static cached_dir_t
*the_directory
= NULL
;
940 /* Used only by non-auth dirservers: The directory and runningrouters we'll
941 * serve when requested. */
942 static cached_dir_t
*cached_directory
= NULL
;
943 static cached_dir_t cached_runningrouters
= { NULL
, NULL
, 0, 0, 0, -1 };
945 /* Used for other dirservers' v2 network statuses. Map from hexdigest to
947 static digestmap_t
*cached_v2_networkstatus
= NULL
;
949 /** Possibly replace the contents of <b>d</b> with the value of
950 * <b>directory</b> published on <b>when</b>, unless <b>when</b> is older than
951 * the last value, or too far in the future.
953 * Does not copy <b>directory</b>; frees it if it isn't used.
956 set_cached_dir(cached_dir_t
*d
, char *directory
, time_t when
)
958 time_t now
= time(NULL
);
959 if (when
<=d
->published
) {
960 log_info(LD_DIRSERV
, "Ignoring old directory; not caching.");
962 } else if (when
>=now
+ROUTER_MAX_AGE_TO_PUBLISH
) {
963 log_info(LD_DIRSERV
, "Ignoring future directory; not caching.");
966 /* if (when>d->published && when<now+ROUTER_MAX_AGE) */
967 log_debug(LD_DIRSERV
, "Caching directory.");
970 d
->dir_len
= strlen(directory
);
972 if (tor_gzip_compress(&(d
->dir_z
), &(d
->dir_z_len
), d
->dir
, d
->dir_len
,
974 log_warn(LD_BUG
,"Error compressing cached directory");
980 /** Decrement the reference count on <b>d</b>, and free it if it no longer has
983 cached_dir_decref(cached_dir_t
*d
)
985 if (!d
|| --d
->refcnt
> 0)
991 /** Allocate and return a new cached_dir_t containing the string <b>s</b>,
992 * published at <b>published</b>. */
993 static cached_dir_t
*
994 new_cached_dir(char *s
, time_t published
)
996 cached_dir_t
*d
= tor_malloc_zero(sizeof(cached_dir_t
));
999 d
->dir_len
= strlen(s
);
1000 d
->published
= published
;
1001 if (tor_gzip_compress(&(d
->dir_z
), &(d
->dir_z_len
), d
->dir
, d
->dir_len
,
1003 log_warn(LD_BUG
, "Error compressing directory");
1008 /** Remove all storage held in <b>d</b>, but do not free <b>d</b> itself. */
1010 clear_cached_dir(cached_dir_t
*d
)
1014 memset(d
, 0, sizeof(cached_dir_t
));
1017 /** Free all storage held by the cached_dir_t in <b>d</b>. */
1019 _free_cached_dir(void *_d
)
1021 cached_dir_t
*d
= (cached_dir_t
*)_d
;
1022 cached_dir_decref(d
);
1025 /** If we have no cached directory, or it is older than <b>when</b>, then
1026 * replace it with <b>directory</b>, published at <b>when</b>.
1029 dirserv_set_cached_directory(const char *directory
, time_t published
,
1030 int is_running_routers
)
1032 if (is_running_routers
) {
1033 set_cached_dir(&cached_runningrouters
, tor_strdup(directory
), published
);
1035 cached_dir_decref(cached_directory
);
1036 cached_directory
= new_cached_dir(tor_strdup(directory
), published
);
1040 /** We've just received a v2 network-status for an authoritative directory
1041 * with identity digest <b>identity</b> published at
1042 * <b>published</b>. Store it so we can serve it to others. If
1043 * <b>directory</b> is NULL, remove the entry with the given fingerprint from
1047 dirserv_set_cached_networkstatus_v2(const char *networkstatus
,
1048 const char *identity
,
1051 cached_dir_t
*d
, *old_d
;
1052 smartlist_t
*trusted_dirs
;
1053 if (!cached_v2_networkstatus
)
1054 cached_v2_networkstatus
= digestmap_new();
1056 old_d
= digestmap_get(cached_v2_networkstatus
, identity
);
1057 if (!old_d
&& !networkstatus
)
1060 if (networkstatus
) {
1061 if (!old_d
|| published
> old_d
->published
) {
1062 d
= new_cached_dir(tor_strdup(networkstatus
), published
);
1063 digestmap_set(cached_v2_networkstatus
, identity
, d
);
1065 cached_dir_decref(old_d
);
1069 digestmap_remove(cached_v2_networkstatus
, identity
);
1070 cached_dir_decref(old_d
);
1074 /* Now purge old entries. */
1075 trusted_dirs
= router_get_trusted_dir_servers();
1076 if (digestmap_size(cached_v2_networkstatus
) >
1077 smartlist_len(trusted_dirs
) + MAX_UNTRUSTED_NETWORKSTATUSES
) {
1078 /* We need to remove the oldest untrusted networkstatus. */
1079 const char *oldest
= NULL
;
1080 time_t oldest_published
= TIME_MAX
;
1081 digestmap_iter_t
*iter
;
1083 for (iter
= digestmap_iter_init(cached_v2_networkstatus
);
1084 !digestmap_iter_done(iter
);
1085 iter
= digestmap_iter_next(cached_v2_networkstatus
, iter
)) {
1088 digestmap_iter_get(iter
, &ident
, &val
);
1090 if (d
->published
< oldest_published
&&
1091 !router_digest_is_trusted_dir(ident
)) {
1093 oldest_published
= d
->published
;
1097 d
= digestmap_remove(cached_v2_networkstatus
, oldest
);
1099 cached_dir_decref(d
);
1103 /** Remove any networkstatus from the directory cache that was published
1104 * before <b>cutoff</b>. */
1106 dirserv_clear_old_networkstatuses(time_t cutoff
)
1108 digestmap_iter_t
*iter
;
1110 if (!cached_v2_networkstatus
)
1113 for (iter
= digestmap_iter_init(cached_v2_networkstatus
);
1114 !digestmap_iter_done(iter
); ) {
1118 digestmap_iter_get(iter
, &ident
, &val
);
1120 if (dir
->published
< cutoff
) {
1122 iter
= digestmap_iter_next_rmv(cached_v2_networkstatus
, iter
);
1123 fname
= networkstatus_get_cache_filename(ident
);
1124 if (file_status(fname
) == FN_FILE
) {
1125 log_info(LD_DIR
, "Removing too-old untrusted networkstatus in %s",
1130 cached_dir_decref(dir
);
1132 iter
= digestmap_iter_next(cached_v2_networkstatus
, iter
);
1138 /** Helper: If we're an authority for the right directory version (the
1139 * directory version is determined by <b>is_v1_object</b>), try to regenerate
1140 * auth_src as appropriate and return it, falling back to cache_src on
1141 * failure. If we're a cache, return cache_src.
1143 static cached_dir_t
*
1144 dirserv_pick_cached_dir_obj(cached_dir_t
*cache_src
,
1145 cached_dir_t
*auth_src
,
1146 time_t dirty
, cached_dir_t
*(*regenerate
)(void),
1150 int authority
= get_options()->AuthoritativeDir
&&
1151 (!is_v1_object
|| get_options()->V1AuthoritativeDir
);
1156 /* We're authoritative. */
1157 if (regenerate
!= NULL
) {
1158 if (dirty
&& dirty
+ DIR_REGEN_SLACK_TIME
< time(NULL
)) {
1159 if (!(auth_src
= regenerate())) {
1160 log_err(LD_BUG
, "Couldn't generate %s?", name
);
1164 log_info(LD_DIRSERV
, "The %s is still clean; reusing.", name
);
1167 return auth_src
? auth_src
: cache_src
;
1171 /** Helper: If we're authoritative and <b>auth_src</b> is set, use
1172 * <b>auth_src</b>, otherwise use <b>cache_src</b>. If we're using
1173 * <b>auth_src</b> and it's been <b>dirty</b> for at least
1174 * DIR_REGEN_SLACK_TIME seconds, call <b>regenerate</b>() to make a fresh one.
1175 * Yields the compressed version of the directory object if <b>compress</b> is
1176 * set; otherwise return the uncompressed version. (In either case, sets
1177 * *<b>out</b> and returns the size of the buffer in *<b>out</b>.)
1179 * Use <b>is_v1_object</b> to help determine whether we're authoritative for
1180 * this kind of object.
1183 dirserv_get_obj(const char **out
,
1185 cached_dir_t
*cache_src
,
1186 cached_dir_t
*auth_src
,
1187 time_t dirty
, cached_dir_t
*(*regenerate
)(void),
1191 cached_dir_t
*d
= dirserv_pick_cached_dir_obj(
1192 cache_src
, auth_src
,
1193 dirty
, regenerate
, name
, is_v1_object
);
1197 *out
= compress
? d
->dir_z
: d
->dir
;
1199 return compress
? d
->dir_z_len
: d
->dir_len
;
1201 /* not yet available. */
1206 /** Return the most recently generated encoded signed directory, generating a
1207 * new one as necessary. If not an authoritative directory may return NULL if
1208 * no directory is yet cached.*/
1210 dirserv_get_directory(void)
1212 return dirserv_pick_cached_dir_obj(cached_directory
, the_directory
,
1213 the_directory_is_dirty
,
1214 dirserv_regenerate_directory
,
1215 "server directory", 1);
1219 * Generate a fresh v1 directory (authdirservers only); set the_directory
1220 * and return a pointer to the new value.
1222 static cached_dir_t
*
1223 dirserv_regenerate_directory(void)
1225 char *new_directory
=NULL
;
1227 if (dirserv_dump_directory_to_string(&new_directory
,
1228 get_identity_key(), 0)) {
1229 log_warn(LD_BUG
, "Error creating directory.");
1230 tor_free(new_directory
);
1233 cached_dir_decref(the_directory
);
1234 the_directory
= new_cached_dir(new_directory
, time(NULL
));
1235 log_info(LD_DIRSERV
,"New directory (size %d) has been built.",
1236 (int)the_directory
->dir_len
);
1237 log_debug(LD_DIRSERV
,"New directory (size %d):\n%s",
1238 (int)the_directory
->dir_len
, the_directory
->dir
);
1240 the_directory_is_dirty
= 0;
1242 /* Save the directory to disk so we re-load it quickly on startup.
1244 dirserv_set_cached_directory(the_directory
->dir
, time(NULL
), 0);
1246 return the_directory
;
1249 /** For authoritative directories: the current (v1) network status */
1250 static cached_dir_t the_runningrouters
= { NULL
, NULL
, 0, 0, 0, -1 };
1252 /** Replace the current running-routers list with a newly generated one. */
1253 static cached_dir_t
*
1254 generate_runningrouters(void)
1257 char *router_status
=NULL
;
1258 char digest
[DIGEST_LEN
];
1259 char published
[ISO_TIME_LEN
+1];
1261 crypto_pk_env_t
*private_key
= get_identity_key();
1262 char *identity_pkey
; /* Identity key, DER64-encoded. */
1263 size_t identity_pkey_len
;
1264 routerlist_t
*rl
= router_get_routerlist();
1266 if (list_server_status(rl
->routers
, &router_status
, 0)) {
1269 if (crypto_pk_write_public_key_to_string(private_key
,&identity_pkey
,
1270 &identity_pkey_len
)<0) {
1271 log_warn(LD_BUG
,"write identity_pkey to string failed!");
1274 format_iso_time(published
, time(NULL
));
1276 len
= 2048+strlen(router_status
);
1277 s
= tor_malloc_zero(len
);
1278 tor_snprintf(s
, len
,
1281 "router-status %s\n"
1282 "dir-signing-key\n%s"
1283 "directory-signature %s\n",
1284 published
, router_status
, identity_pkey
,
1285 get_options()->Nickname
);
1286 tor_free(router_status
);
1287 tor_free(identity_pkey
);
1288 if (router_get_runningrouters_hash(s
,digest
)) {
1289 log_warn(LD_BUG
,"couldn't compute digest");
1292 note_crypto_pk_op(SIGN_DIR
);
1293 if (router_append_dirobj_signature(s
, len
, digest
, private_key
)<0)
1296 set_cached_dir(&the_runningrouters
, s
, time(NULL
));
1297 runningrouters_is_dirty
= 0;
1299 return &the_runningrouters
;
1302 tor_free(router_status
);
1306 /** Set *<b>rr</b> to the most recently generated encoded signed
1307 * running-routers list, generating a new one as necessary. Return the
1308 * size of the directory on success, and 0 on failure. */
1310 dirserv_get_runningrouters(const char **rr
, int compress
)
1312 return dirserv_get_obj(rr
, compress
,
1313 &cached_runningrouters
, &the_runningrouters
,
1314 runningrouters_is_dirty
,
1315 generate_runningrouters
,
1316 "v1 network status list", 1);
1319 /** For authoritative directories: the current (v2) network status */
1320 static cached_dir_t
*the_v2_networkstatus
= NULL
;
1323 should_generate_v2_networkstatus(void)
1325 return get_options()->AuthoritativeDir
&&
1326 the_v2_networkstatus_is_dirty
&&
1327 the_v2_networkstatus_is_dirty
+ DIR_REGEN_SLACK_TIME
< time(NULL
);
1330 /* Thresholds for server performance: set by
1331 * dirserv_compute_performance_thresholds, and used by
1332 * generate_v2_networkstatus */
1333 static uint32_t stable_uptime
= 0; /* start at a safe value */
1334 static uint32_t fast_bandwidth
= 0;
1335 static uint32_t guard_bandwidth_including_exits
= 0;
1336 static uint32_t guard_bandwidth_excluding_exits
= 0;
1337 static uint64_t total_bandwidth
= 0;
1338 static uint64_t total_exit_bandwidth
= 0;
1340 /** Helper: estimate the uptime of a router given its stated uptime and the
1341 * amount of time since it last stated its stated uptime. */
1343 real_uptime(routerinfo_t
*router
, time_t now
)
1345 if (now
< router
->cache_info
.published_on
)
1346 return router
->uptime
;
1348 return router
->uptime
+ (now
- router
->cache_info
.published_on
);
1351 /** Return 1 if <b>router</b> is not suitable for these parameters, else 0.
1352 * If <b>need_uptime</b> is non-zero, we require a minimum uptime.
1353 * If <b>need_capacity</b> is non-zero, we require a minimum advertised
1357 dirserv_thinks_router_is_unreliable(time_t now
,
1358 routerinfo_t
*router
,
1359 int need_uptime
, int need_capacity
)
1362 (unsigned)real_uptime(router
, now
) < stable_uptime
)
1364 if (need_capacity
&&
1365 router_get_advertised_bandwidth(router
) < fast_bandwidth
)
1370 /** Helper: returns a tristate based on comparing **(uint32_t**)a to
1371 * **(uint32_t**)b. */
1373 _compare_uint32(const void **a
, const void **b
)
1375 uint32_t first
= **(uint32_t **)a
, second
= **(uint32_t **)b
;
1376 if (first
< second
) return -1;
1377 if (first
> second
) return 1;
1381 /** Look through the routerlist, and assign the median uptime of running valid
1382 * servers to stable_uptime, and the relative bandwidth capacities to
1383 * fast_bandwidth and guard_bandwidth. Set total_bandwidth to the total
1384 * capacity of all running valid servers and total_exit_bandwidth to the
1385 * capacity of all running valid exits. Set the is_exit flag of each router
1388 dirserv_compute_performance_thresholds(routerlist_t
*rl
)
1390 smartlist_t
*uptimes
, *bandwidths
, *bandwidths_excluding_exits
;
1391 time_t now
= time(NULL
);
1393 /* initialize these all here, in case there are no routers */
1396 guard_bandwidth_including_exits
= 0;
1397 guard_bandwidth_excluding_exits
= 0;
1399 total_bandwidth
= 0;
1400 total_exit_bandwidth
= 0;
1402 uptimes
= smartlist_create();
1403 bandwidths
= smartlist_create();
1404 bandwidths_excluding_exits
= smartlist_create();
1406 SMARTLIST_FOREACH(rl
->routers
, routerinfo_t
*, ri
, {
1407 if (ri
->is_running
&& ri
->is_valid
) {
1408 uint32_t *up
= tor_malloc(sizeof(uint32_t));
1409 uint32_t *bw
= tor_malloc(sizeof(uint32_t));
1410 ri
->is_exit
= exit_policy_is_general_exit(ri
->exit_policy
);
1411 *up
= (uint32_t) real_uptime(ri
, now
);
1412 smartlist_add(uptimes
, up
);
1413 *bw
= router_get_advertised_bandwidth(ri
);
1414 total_bandwidth
+= *bw
;
1415 if (ri
->is_exit
&& !ri
->is_bad_exit
) {
1416 total_exit_bandwidth
+= *bw
;
1418 uint32_t *bw_not_exit
= tor_malloc(sizeof(uint32_t));
1420 smartlist_add(bandwidths_excluding_exits
, bw_not_exit
);
1422 smartlist_add(bandwidths
, bw
);
1426 smartlist_sort(uptimes
, _compare_uint32
);
1427 smartlist_sort(bandwidths
, _compare_uint32
);
1428 smartlist_sort(bandwidths_excluding_exits
, _compare_uint32
);
1430 if (smartlist_len(uptimes
))
1431 stable_uptime
= *(uint32_t*)smartlist_get(uptimes
,
1432 smartlist_len(uptimes
)/2);
1434 if (smartlist_len(bandwidths
)) {
1435 fast_bandwidth
= *(uint32_t*)smartlist_get(bandwidths
,
1436 smartlist_len(bandwidths
)/8);
1437 if (fast_bandwidth
< ROUTER_REQUIRED_MIN_BANDWIDTH
)
1438 fast_bandwidth
= *(uint32_t*)smartlist_get(bandwidths
,
1439 smartlist_len(bandwidths
)/4);
1440 guard_bandwidth_including_exits
=
1441 *(uint32_t*)smartlist_get(bandwidths
, smartlist_len(bandwidths
)/2);
1444 if (smartlist_len(bandwidths_excluding_exits
)) {
1445 guard_bandwidth_excluding_exits
=
1446 *(uint32_t*)smartlist_get(bandwidths_excluding_exits
,
1447 smartlist_len(bandwidths_excluding_exits
)/2);
1450 log(LOG_INFO
, LD_DIRSERV
,
1451 "Cutoffs: %lus uptime, %lu b/s fast, %lu or %lu b/s guard.",
1452 (unsigned long)stable_uptime
,
1453 (unsigned long)fast_bandwidth
,
1454 (unsigned long)guard_bandwidth_including_exits
,
1455 (unsigned long)guard_bandwidth_excluding_exits
);
1457 SMARTLIST_FOREACH(uptimes
, uint32_t *, up
, tor_free(up
));
1458 SMARTLIST_FOREACH(bandwidths
, uint32_t *, bw
, tor_free(bw
));
1459 SMARTLIST_FOREACH(bandwidths_excluding_exits
, uint32_t *, bw
, tor_free(bw
));
1460 smartlist_free(uptimes
);
1461 smartlist_free(bandwidths
);
1462 smartlist_free(bandwidths_excluding_exits
);
1465 /** For authoritative directories only: replace the contents of
1466 * <b>the_v2_networkstatus</b> with a newly generated network status
1468 static cached_dir_t
*
1469 generate_v2_networkstatus(void)
1471 #define LONGEST_STATUS_FLAG_NAME_LEN 9
1472 #define N_STATUS_FLAGS 9
1473 #define RS_ENTRY_LEN \
1474 ( /* first line */ \
1475 MAX_NICKNAME_LEN+BASE64_DIGEST_LEN*2+ISO_TIME_LEN+INET_NTOA_BUF_LEN+ \
1476 5*2 /* ports */ + 10 /* punctuation */ + \
1478 (LONGEST_STATUS_FLAG_NAME_LEN+1)*N_STATUS_FLAGS + 2)
1480 cached_dir_t
*r
= NULL
;
1481 size_t len
, identity_pkey_len
;
1482 char *status
= NULL
, *client_versions
= NULL
, *server_versions
= NULL
,
1483 *identity_pkey
= NULL
, *hostname
= NULL
;
1485 or_options_t
*options
= get_options();
1486 char fingerprint
[FINGERPRINT_LEN
+1];
1487 char ipaddr
[INET_NTOA_BUF_LEN
];
1488 char published
[ISO_TIME_LEN
+1];
1489 char digest
[DIGEST_LEN
];
1492 crypto_pk_env_t
*private_key
= get_identity_key();
1493 routerlist_t
*rl
= router_get_routerlist();
1494 time_t now
= time(NULL
);
1495 time_t cutoff
= now
- ROUTER_MAX_AGE_TO_PUBLISH
;
1496 int naming
= options
->NamingAuthoritativeDir
;
1497 int versioning
= options
->VersioningAuthoritativeDir
;
1498 int listbadexits
= options
->AuthDirListBadExits
;
1499 int exits_can_be_guards
;
1500 const char *contact
;
1502 if (resolve_my_address(LOG_WARN
, options
, &addr
, &hostname
)<0) {
1503 log_warn(LD_NET
, "Couldn't resolve my hostname");
1506 in
.s_addr
= htonl(addr
);
1507 tor_inet_ntoa(&in
, ipaddr
, sizeof(ipaddr
));
1509 format_iso_time(published
, time(NULL
));
1511 client_versions
= format_versions_list(options
->RecommendedClientVersions
);
1512 server_versions
= format_versions_list(options
->RecommendedServerVersions
);
1514 if (crypto_pk_write_public_key_to_string(private_key
, &identity_pkey
,
1515 &identity_pkey_len
)<0) {
1516 log_warn(LD_BUG
,"Writing public key to string failed.");
1520 if (crypto_pk_get_fingerprint(private_key
, fingerprint
, 0)<0) {
1521 log_err(LD_BUG
, "Error computing fingerprint");
1525 contact
= get_options()->ContactInfo
;
1529 len
= 2048+strlen(client_versions
)+strlen(server_versions
);
1530 len
+= identity_pkey_len
*2;
1531 len
+= (RS_ENTRY_LEN
)*smartlist_len(rl
->routers
);
1533 status
= tor_malloc(len
);
1534 tor_snprintf(status
, len
,
1535 "network-status-version 2\n"
1536 "dir-source %s %s %d\n"
1540 "dir-options%s%s%s\n"
1541 "%s%s" /* client versions %s */
1542 "%s%s%s" /* \nserver versions %s \n */
1543 "dir-signing-key\n%s\n",
1544 hostname
, ipaddr
, (int)options
->DirPort
,
1548 naming
? " Names" : "",
1549 listbadexits
? " BadExits" : "",
1550 versioning
? " Versions" : "",
1551 versioning
? "client-versions " : "",
1552 versioning
? client_versions
: "",
1553 versioning
? "\nserver-versions " : "",
1554 versioning
? server_versions
: "",
1555 versioning
? "\n" : "",
1557 outp
= status
+ strlen(status
);
1558 endp
= status
+ len
;
1560 /* precompute this part, since we need it to decide what "stable"
1562 SMARTLIST_FOREACH(rl
->routers
, routerinfo_t
*, ri
, {
1563 ri
->is_running
= dirserv_thinks_router_is_reachable(ri
, now
);
1566 dirserv_compute_performance_thresholds(rl
);
1568 /* XXXX We should take steps to keep this from oscillating if
1569 * total_exit_bandwidth is close to total_bandwidth/3. */
1570 exits_can_be_guards
= total_exit_bandwidth
>= (total_bandwidth
/ 3);
1572 SMARTLIST_FOREACH(rl
->routers
, routerinfo_t
*, ri
, {
1573 if (ri
->cache_info
.published_on
>= cutoff
) {
1574 /* Already set by compute_performance_thresholds. */
1575 int f_exit
= ri
->is_exit
;
1576 /* These versions dump connections with idle live circuits
1578 int unstable_version
=
1579 tor_version_as_new_as(ri
->platform
,"0.1.1.10-alpha") &&
1580 !tor_version_as_new_as(ri
->platform
,"0.1.1.16-rc-cvs");
1581 int f_stable
= ri
->is_stable
=
1582 !dirserv_thinks_router_is_unreliable(now
, ri
, 1, 0) &&
1584 int f_fast
= ri
->is_fast
=
1585 !dirserv_thinks_router_is_unreliable(now
, ri
, 0, 1);
1586 int f_running
= ri
->is_running
; /* computed above */
1587 int f_authority
= router_digest_is_trusted_dir(
1588 ri
->cache_info
.identity_digest
);
1589 int f_named
= naming
&& ri
->is_named
;
1590 int f_valid
= ri
->is_valid
;
1591 int f_guard
= f_fast
&& f_stable
&&
1592 (!f_exit
|| exits_can_be_guards
) &&
1593 router_get_advertised_bandwidth(ri
) >=
1594 (exits_can_be_guards
? guard_bandwidth_including_exits
:
1595 guard_bandwidth_excluding_exits
);
1596 int f_bad_exit
= listbadexits
&& ri
->is_bad_exit
;
1597 /* 0.1.1.9-alpha is the first version to support fetch by descriptor
1599 int f_v2_dir
= ri
->dir_port
&&
1600 tor_version_as_new_as(ri
->platform
,"0.1.1.9-alpha");
1601 char identity64
[BASE64_DIGEST_LEN
+1];
1602 char digest64
[BASE64_DIGEST_LEN
+1];
1604 if (!strcasecmp(ri
->nickname
, UNNAMED_ROUTER_NICKNAME
))
1607 format_iso_time(published
, ri
->cache_info
.published_on
);
1609 digest_to_base64(identity64
, ri
->cache_info
.identity_digest
);
1610 digest_to_base64(digest64
, ri
->cache_info
.signed_descriptor_digest
);
1612 in
.s_addr
= htonl(ri
->addr
);
1613 tor_inet_ntoa(&in
, ipaddr
, sizeof(ipaddr
));
1615 if (tor_snprintf(outp
, endp
-outp
,
1616 "r %s %s %s %s %s %d %d\n"
1617 "s%s%s%s%s%s%s%s%s%s%s\n",
1625 f_authority
?" Authority":"",
1626 f_bad_exit
?" BadExit":"",
1629 f_guard
?" Guard":"",
1630 f_named
?" Named":"",
1631 f_stable
?" Stable":"",
1632 f_running
?" Running":"",
1633 f_valid
?" Valid":"",
1634 f_v2_dir
?" V2Dir":"")<0) {
1635 log_warn(LD_BUG
, "Unable to print router status.");
1638 outp
+= strlen(outp
);
1639 if (ri
->platform
&& !strcmpstart(ri
->platform
, "Tor ")) {
1640 const char *eos
= find_whitespace(ri
->platform
+4);
1642 char *platform
= tor_strndup(ri
->platform
, eos
-(ri
->platform
));
1643 if (tor_snprintf(outp
, endp
-outp
,
1644 "opt v %s\n", platform
)<0) {
1645 log_warn(LD_BUG
, "Unable to print router version.");
1649 outp
+= strlen(outp
);
1655 if (tor_snprintf(outp
, endp
-outp
, "directory-signature %s\n",
1656 get_options()->Nickname
)<0) {
1657 log_warn(LD_BUG
, "Unable to write signature line.");
1661 if (router_get_networkstatus_v2_hash(status
, digest
)<0) {
1662 log_warn(LD_BUG
, "Unable to hash network status");
1666 note_crypto_pk_op(SIGN_DIR
);
1667 if (router_append_dirobj_signature(outp
,endp
-outp
,digest
,private_key
)<0) {
1668 log_warn(LD_BUG
, "Unable to sign router status.");
1672 if (the_v2_networkstatus
)
1673 cached_dir_decref(the_v2_networkstatus
);
1674 the_v2_networkstatus
= new_cached_dir(status
, time(NULL
));
1675 status
= NULL
; /* So it doesn't get double-freed. */
1676 the_v2_networkstatus_is_dirty
= 0;
1677 router_set_networkstatus(the_v2_networkstatus
->dir
,
1678 time(NULL
), NS_GENERATED
, NULL
);
1679 r
= the_v2_networkstatus
;
1681 tor_free(client_versions
);
1682 tor_free(server_versions
);
1685 tor_free(identity_pkey
);
1689 /** Given the portion of a networkstatus request URL after "tor/status/" in
1690 * <b>key</b>, append to <b>result</b> the digests of the identity keys of the
1691 * networkstatus objects that the client has requested. */
1693 dirserv_get_networkstatus_v2_fingerprints(smartlist_t
*result
,
1698 if (!cached_v2_networkstatus
)
1699 cached_v2_networkstatus
= digestmap_new();
1701 if (should_generate_v2_networkstatus())
1702 generate_v2_networkstatus();
1704 if (!strcmp(key
,"authority")) {
1705 if (get_options()->AuthoritativeDir
) {
1706 routerinfo_t
*me
= router_get_my_routerinfo();
1708 smartlist_add(result
,
1709 tor_memdup(me
->cache_info
.identity_digest
, DIGEST_LEN
));
1711 } else if (!strcmp(key
, "all")) {
1712 if (digestmap_size(cached_v2_networkstatus
)) {
1713 digestmap_iter_t
*iter
;
1714 iter
= digestmap_iter_init(cached_v2_networkstatus
);
1715 while (!digestmap_iter_done(iter
)) {
1718 digestmap_iter_get(iter
, &ident
, &val
);
1719 smartlist_add(result
, tor_memdup(ident
, DIGEST_LEN
));
1720 iter
= digestmap_iter_next(cached_v2_networkstatus
, iter
);
1723 SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
1724 trusted_dir_server_t
*, ds
,
1725 smartlist_add(result
, tor_memdup(ds
->digest
, DIGEST_LEN
)));
1727 smartlist_sort_digests(result
);
1728 if (smartlist_len(result
) == 0)
1729 log_warn(LD_DIRSERV
,
1730 "Client requested 'all' network status objects; we have none.");
1731 } else if (!strcmpstart(key
, "fp/")) {
1732 dir_split_resource_into_fingerprints(key
+3, result
, NULL
, 1, 1);
1736 /** Look for a network status object as specified by <b>key</b>, which should
1737 * be either "authority" (to find a network status generated by us), a hex
1738 * identity digest (to find a network status generated by given directory), or
1739 * "all" (to return all the v2 network status objects we have).
1742 dirserv_get_networkstatus_v2(smartlist_t
*result
,
1745 cached_dir_t
*cached
;
1746 smartlist_t
*fingerprints
= smartlist_create();
1749 if (!cached_v2_networkstatus
)
1750 cached_v2_networkstatus
= digestmap_new();
1752 dirserv_get_networkstatus_v2_fingerprints(fingerprints
, key
);
1753 SMARTLIST_FOREACH(fingerprints
, const char *, fp
,
1755 if (router_digest_is_me(fp
) && should_generate_v2_networkstatus())
1756 generate_v2_networkstatus();
1757 cached
= digestmap_get(cached_v2_networkstatus
, fp
);
1759 smartlist_add(result
, cached
);
1761 char hexbuf
[HEX_DIGEST_LEN
+1];
1762 base16_encode(hexbuf
, sizeof(hexbuf
), fp
, DIGEST_LEN
);
1763 log_info(LD_DIRSERV
, "Don't know about any network status with "
1764 "fingerprint '%s'", hexbuf
);
1767 SMARTLIST_FOREACH(fingerprints
, char *, cp
, tor_free(cp
));
1768 smartlist_free(fingerprints
);
1771 /** As dirserv_get_routerdescs(), but instead of getting signed_descriptor_t
1772 * pointers, adds copies of digests to fps_out. For a /tor/server/d/ request,
1773 * adds descriptor digests; for other requests, adds identity digests.
1776 dirserv_get_routerdesc_fingerprints(smartlist_t
*fps_out
, const char *key
,
1781 if (!strcmp(key
, "/tor/server/all")) {
1782 routerlist_t
*rl
= router_get_routerlist();
1783 SMARTLIST_FOREACH(rl
->routers
, routerinfo_t
*, r
,
1784 smartlist_add(fps_out
,
1785 tor_memdup(r
->cache_info
.identity_digest
, DIGEST_LEN
)));
1786 } else if (!strcmp(key
, "/tor/server/authority")) {
1787 routerinfo_t
*ri
= router_get_my_routerinfo();
1789 smartlist_add(fps_out
,
1790 tor_memdup(ri
->cache_info
.identity_digest
, DIGEST_LEN
));
1791 } else if (!strcmpstart(key
, "/tor/server/d/")) {
1792 key
+= strlen("/tor/server/d/");
1793 dir_split_resource_into_fingerprints(key
, fps_out
, NULL
, 1, 1);
1794 } else if (!strcmpstart(key
, "/tor/server/fp/")) {
1795 key
+= strlen("/tor/server/fp/");
1796 dir_split_resource_into_fingerprints(key
, fps_out
, NULL
, 1, 1);
1798 *msg
= "Key not recognized";
1802 if (!smartlist_len(fps_out
)) {
1803 *msg
= "Servers unavailable";
1809 /** Add a signed_descriptor_t to <b>descs_out</b> for each router matching
1810 * <b>key</b>. The key should be either
1811 * - "/tor/server/authority" for our own routerinfo;
1812 * - "/tor/server/all" for all the routerinfos we have, concatenated;
1813 * - "/tor/server/fp/FP" where FP is a plus-separated sequence of
1814 * hex identity digests; or
1815 * - "/tor/server/d/D" where D is a plus-separated sequence
1816 * of server descriptor digests, in hex.
1818 * Return 0 if we found some matching descriptors, or -1 if we do not
1819 * have any descriptors, no matching descriptors, or if we did not
1820 * recognize the key (URL).
1821 * If -1 is returned *<b>msg</b> will be set to an appropriate error
1824 * (Despite its name, this function is also called from the controller, which
1825 * exposes a similar means to fetch descriptors.)
1828 dirserv_get_routerdescs(smartlist_t
*descs_out
, const char *key
,
1833 if (!strcmp(key
, "/tor/server/all")) {
1834 routerlist_t
*rl
= router_get_routerlist();
1835 SMARTLIST_FOREACH(rl
->routers
, routerinfo_t
*, r
,
1836 smartlist_add(descs_out
, &(r
->cache_info
)));
1837 } else if (!strcmp(key
, "/tor/server/authority")) {
1838 routerinfo_t
*ri
= router_get_my_routerinfo();
1840 smartlist_add(descs_out
, &(ri
->cache_info
));
1841 } else if (!strcmpstart(key
, "/tor/server/d/")) {
1842 smartlist_t
*digests
= smartlist_create();
1843 key
+= strlen("/tor/server/d/");
1844 dir_split_resource_into_fingerprints(key
, digests
, NULL
, 1, 1);
1845 SMARTLIST_FOREACH(digests
, const char *, d
,
1847 signed_descriptor_t
*sd
= router_get_by_descriptor_digest(d
);
1849 smartlist_add(descs_out
,sd
);
1851 SMARTLIST_FOREACH(digests
, char *, d
, tor_free(d
));
1852 smartlist_free(digests
);
1853 } else if (!strcmpstart(key
, "/tor/server/fp/")) {
1854 smartlist_t
*digests
= smartlist_create();
1855 time_t cutoff
= time(NULL
) - ROUTER_MAX_AGE_TO_PUBLISH
;
1856 key
+= strlen("/tor/server/fp/");
1857 dir_split_resource_into_fingerprints(key
, digests
, NULL
, 1, 1);
1858 SMARTLIST_FOREACH(digests
, const char *, d
,
1860 if (router_digest_is_me(d
)) {
1861 smartlist_add(descs_out
, &(router_get_my_routerinfo()->cache_info
));
1863 routerinfo_t
*ri
= router_get_by_digest(d
);
1864 /* Don't actually serve a descriptor that everyone will think is
1865 * expired. This is an (ugly) workaround to keep buggy 0.1.1.10
1866 * Tors from downloading descriptors that they will throw away.
1868 if (ri
&& ri
->cache_info
.published_on
> cutoff
)
1869 smartlist_add(descs_out
, &(ri
->cache_info
));
1872 SMARTLIST_FOREACH(digests
, char *, d
, tor_free(d
));
1873 smartlist_free(digests
);
1875 *msg
= "Key not recognized";
1879 if (!smartlist_len(descs_out
)) {
1880 *msg
= "Servers unavailable";
1886 /** Called when a TLS handshake has completed successfully with a
1887 * router listening at <b>address</b>:<b>or_port</b>, and has yielded
1888 * a certificate with digest <b>digest_rcvd</b> and nickname
1889 * <b>nickname_rcvd</b>.
1891 * Also, if as_advertised is 1, then inform the reachability checker
1892 * that we could get to this guy.
1895 dirserv_orconn_tls_done(const char *address
,
1897 const char *digest_rcvd
,
1898 const char *nickname_rcvd
,
1901 routerlist_t
*rl
= router_get_routerlist();
1902 tor_assert(address
);
1903 tor_assert(digest_rcvd
);
1904 tor_assert(nickname_rcvd
);
1906 SMARTLIST_FOREACH(rl
->routers
, routerinfo_t
*, ri
, {
1907 if (!strcasecmp(address
, ri
->address
) && or_port
== ri
->or_port
&&
1909 !memcmp(ri
->cache_info
.identity_digest
, digest_rcvd
, DIGEST_LEN
) &&
1910 !strcasecmp(nickname_rcvd
, ri
->nickname
)) {
1911 /* correct nickname and digest. mark this router reachable! */
1912 log_info(LD_DIRSERV
, "Found router %s to be reachable. Yay.",
1914 ri
->last_reachable
= time(NULL
);
1915 ri
->num_unreachable_notifications
= 0;
1918 /* FFFF Maybe we should reinstate the code that dumps routers with the same
1919 * addr/port but with nonmatching keys, but instead of dumping, we should
1923 /** Auth dir server only: if <b>try_all</b> is 1, launch connections to
1924 * all known routers; else we want to load balance such that we only
1925 * try a few connections per call.
1927 * The load balancing is such that if we get called once every ten
1928 * seconds, we will cycle through all the tests in 1280 seconds (a
1929 * bit over 20 minutes).
1932 dirserv_test_reachability(int try_all
)
1934 time_t now
= time(NULL
);
1935 routerlist_t
*rl
= router_get_routerlist();
1936 static char ctr
= 0;
1938 SMARTLIST_FOREACH(rl
->routers
, routerinfo_t
*, router
, {
1939 const char *id_digest
= router
->cache_info
.identity_digest
;
1940 if (router_is_me(router
))
1942 if (try_all
|| (((uint8_t)id_digest
[0]) % 128) == ctr
) {
1943 log_debug(LD_OR
,"Testing reachability of %s at %s:%u.",
1944 router
->nickname
, router
->address
, router
->or_port
);
1945 /* Remember when we started trying to determine reachability */
1946 if (!router
->testing_since
)
1947 router
->testing_since
= now
;
1948 connection_or_connect(router
->addr
, router
->or_port
,
1952 if (!try_all
) /* increment ctr */
1953 ctr
= (ctr
+ 1) % 128;
1956 /** If <b>conn</b> is a dirserv connection tunneled over an or_connection,
1957 * return that connection. Otherwise, return NULL. */
1958 static INLINE or_connection_t
*
1959 connection_dirserv_get_target_or_conn(dir_connection_t
*conn
)
1961 if (conn
->bridge_conn
&&
1962 conn
->bridge_conn
->on_circuit
&&
1963 !CIRCUIT_IS_ORIGIN(conn
->bridge_conn
->on_circuit
)) {
1964 or_circuit_t
*circ
= TO_OR_CIRCUIT(conn
->bridge_conn
->on_circuit
);
1965 return circ
->p_conn
;
1971 /** Remove <b>dir_conn</b> from the list of bridged dirserv connections
1972 * blocking on <b>or_conn</b>, and set its status to nonblocked. */
1974 connection_dirserv_remove_from_blocked_list(or_connection_t
*or_conn
,
1975 dir_connection_t
*dir_conn
)
1977 dir_connection_t
**c
;
1978 for (c
= &or_conn
->blocked_dir_connections
; *c
;
1979 c
= &(*c
)->next_blocked_on_same_or_conn
) {
1980 if (*c
== dir_conn
) {
1981 tor_assert(dir_conn
->is_blocked_on_or_conn
== 1);
1982 *c
= dir_conn
->next_blocked_on_same_or_conn
;
1983 dir_conn
->next_blocked_on_same_or_conn
= NULL
;
1984 dir_conn
->is_blocked_on_or_conn
= 0;
1988 tor_assert(!dir_conn
->is_blocked_on_or_conn
);
1991 /* If <b>dir_conn</b> is a dirserv connection that's bridged over an edge_conn
1992 * onto an or_conn, remove it from the blocked list (if it's blocked) and
1993 * unlink it and the edge_conn from one another. */
1995 connection_dirserv_unlink_from_bridge(dir_connection_t
*dir_conn
)
1997 edge_connection_t
*edge_conn
;
1998 or_connection_t
*or_conn
;
1999 tor_assert(dir_conn
);
2000 edge_conn
= dir_conn
->bridge_conn
;
2001 or_conn
= connection_dirserv_get_target_or_conn(dir_conn
);
2003 /* XXXX Really, this is only necessary if dir_conn->is_blocked_on_or_conn.
2004 * But for now, let's leave it in, so the assert can catch */
2005 connection_dirserv_remove_from_blocked_list(or_conn
, dir_conn
);
2007 dir_conn
->is_blocked_on_or_conn
= 0; /* Probably redundant. */
2008 edge_conn
->bridge_for_conn
= NULL
;
2009 dir_conn
->bridge_conn
= NULL
;
2012 /** Stop writing on a bridged dir_conn, and remember that it's blocked because
2013 * its or_conn was too full. */
2015 connection_dirserv_mark_as_blocked(dir_connection_t
*dir_conn
)
2017 or_connection_t
*or_conn
;
2018 if (dir_conn
->is_blocked_on_or_conn
)
2020 tor_assert(! dir_conn
->next_blocked_on_same_or_conn
);
2021 or_conn
= connection_dirserv_get_target_or_conn(dir_conn
);
2024 dir_conn
->next_blocked_on_same_or_conn
= or_conn
->blocked_dir_connections
;
2025 or_conn
->blocked_dir_connections
= dir_conn
;
2026 dir_conn
->is_blocked_on_or_conn
= 1;
2027 connection_stop_writing(TO_CONN(dir_conn
));
2030 /** Tell all bridged dir_conns that were blocked because or_conn's outbuf was
2031 * too full that they can write again. */
2033 connection_dirserv_stop_blocking_all_on_or_conn(or_connection_t
*or_conn
)
2035 dir_connection_t
*dir_conn
, *next
;
2037 while (or_conn
->blocked_dir_connections
) {
2038 dir_conn
= or_conn
->blocked_dir_connections
;
2039 next
= dir_conn
->next_blocked_on_same_or_conn
;
2041 dir_conn
->is_blocked_on_or_conn
= 0;
2042 dir_conn
->next_blocked_on_same_or_conn
= NULL
;
2043 connection_start_writing(TO_CONN(dir_conn
));
2046 or_conn
->blocked_dir_connections
= NULL
;
2049 /** Return an approximate estimate of the number of bytes that will
2050 * be needed to transmit the server descriptors (if is_serverdescs --
2051 * they can be either d/ or fp/ queries) or networkstatus objects (if
2052 * !is_serverdescs) listed in <b>fps</b>. If <b>compressed</b> is set,
2053 * we guess how large the data will be after compression.
2055 * The return value is an estimate; it might be larger or smaller.
2058 dirserv_estimate_data_size(smartlist_t
*fps
, int is_serverdescs
,
2063 if (is_serverdescs
) {
2064 int n
= smartlist_len(fps
);
2065 routerinfo_t
*me
= router_get_my_routerinfo();
2066 result
= (me
?me
->cache_info
.signed_descriptor_len
:2048) * n
;
2068 result
/= 2; /* observed compressability is between 35 and 55%. */
2071 SMARTLIST_FOREACH(fps
, const char *, d
, {
2072 cached_dir_t
*dir
= digestmap_get(cached_v2_networkstatus
, d
);
2074 result
+= compressed
? dir
->dir_z_len
: dir
->dir_len
;
2080 /** When we're spooling data onto our outbuf, add more whenever we dip
2081 * below this threshold. */
2082 #define DIRSERV_BUFFER_MIN 16384
2084 /** Spooling helper: called when we have no more data to spool to <b>conn</b>.
2085 * Flushes any remaining data to be (un)compressed, and changes the spool
2086 * source to NONE. Returns 0 on success, negative on failure. */
2088 connection_dirserv_finish_spooling(dir_connection_t
*conn
)
2090 if (conn
->zlib_state
) {
2091 connection_write_to_buf_zlib("", 0, conn
, 1);
2092 tor_zlib_free(conn
->zlib_state
);
2093 conn
->zlib_state
= NULL
;
2095 conn
->dir_spool_src
= DIR_SPOOL_NONE
;
2099 /** Spooling helper: called when we're sending a bunch of server descriptors,
2100 * and the outbuf has become too empty. Pulls some entries from
2101 * fingerprint_stack, and writes the corresponding servers onto outbuf. If we
2102 * run out of entries, flushes the zlib state and sets the spool source to
2103 * NONE. Returns 0 on success, negative on failure.
2106 connection_dirserv_add_servers_to_outbuf(dir_connection_t
*conn
)
2108 int by_fp
= conn
->dir_spool_src
== DIR_SPOOL_SERVER_BY_FP
;
2110 while (smartlist_len(conn
->fingerprint_stack
) &&
2111 buf_datalen(conn
->_base
.outbuf
) < DIRSERV_BUFFER_MIN
) {
2113 char *fp
= smartlist_pop_last(conn
->fingerprint_stack
);
2114 signed_descriptor_t
*sd
= NULL
;
2116 if (router_digest_is_me(fp
)) {
2117 sd
= &(router_get_my_routerinfo()->cache_info
);
2119 routerinfo_t
*ri
= router_get_by_digest(fp
);
2121 ri
->cache_info
.published_on
> time(NULL
)-ROUTER_MAX_AGE_TO_PUBLISH
)
2122 sd
= &ri
->cache_info
;
2125 sd
= router_get_by_descriptor_digest(fp
);
2129 body
= signed_descriptor_get_body(sd
);
2130 if (conn
->zlib_state
) {
2131 int last
= ! smartlist_len(conn
->fingerprint_stack
);
2132 connection_write_to_buf_zlib(body
, sd
->signed_descriptor_len
, conn
,
2135 tor_zlib_free(conn
->zlib_state
);
2136 conn
->zlib_state
= NULL
;
2139 connection_write_to_buf(body
,
2140 sd
->signed_descriptor_len
,
2145 if (!smartlist_len(conn
->fingerprint_stack
)) {
2146 /* We just wrote the last one; finish up. */
2147 conn
->dir_spool_src
= DIR_SPOOL_NONE
;
2148 smartlist_free(conn
->fingerprint_stack
);
2149 conn
->fingerprint_stack
= NULL
;
2154 /** Spooling helper: Called when we're sending a directory or networkstatus,
2155 * and the outbuf has become too empty. Pulls some bytes from
2156 * <b>conn</b>-\>cached_dir-\>dir_z, uncompresses them if appropriate, and
2157 * puts them on the outbuf. If we run out of entries, flushes the zlib state
2158 * and sets the spool source to NONE. Returns 0 on success, negative on
2161 connection_dirserv_add_dir_bytes_to_outbuf(dir_connection_t
*conn
)
2166 bytes
= DIRSERV_BUFFER_MIN
- buf_datalen(conn
->_base
.outbuf
);
2167 tor_assert(bytes
> 0);
2168 tor_assert(conn
->cached_dir
);
2171 remaining
= conn
->cached_dir
->dir_z_len
- conn
->cached_dir_offset
;
2172 if (bytes
> remaining
)
2173 bytes
= (ssize_t
) remaining
;
2175 if (conn
->zlib_state
) {
2176 connection_write_to_buf_zlib(
2177 conn
->cached_dir
->dir_z
+ conn
->cached_dir_offset
,
2178 bytes
, conn
, bytes
== remaining
);
2180 connection_write_to_buf(conn
->cached_dir
->dir_z
+ conn
->cached_dir_offset
,
2181 bytes
, TO_CONN(conn
));
2183 conn
->cached_dir_offset
+= bytes
;
2184 if (conn
->cached_dir_offset
== (int)conn
->cached_dir
->dir_z_len
) {
2185 /* We just wrote the last one; finish up. */
2186 connection_dirserv_finish_spooling(conn
);
2187 cached_dir_decref(conn
->cached_dir
);
2188 conn
->cached_dir
= NULL
;
2193 /* Spooling helper: Called when we're spooling networkstatus objects on
2194 * <b>conn</b>, and the outbuf has become too empty. If the current
2195 * networkstatus object (in <b>conn</b>-\>cached_dir) has more data, pull data
2196 * from there. Otherwise, pop the next fingerprint from fingerprint_stack,
2197 * and start spooling the next networkstatus. If we run out of entries,
2198 * flushes the zlib state and sets the spool source to NONE. Returns 0 on
2199 * success, negative on failure. */
2201 connection_dirserv_add_networkstatus_bytes_to_outbuf(dir_connection_t
*conn
)
2204 while (buf_datalen(conn
->_base
.outbuf
) < DIRSERV_BUFFER_MIN
) {
2205 if (conn
->cached_dir
) {
2206 int uncompressing
= (conn
->zlib_state
!= NULL
);
2207 int r
= connection_dirserv_add_dir_bytes_to_outbuf(conn
);
2208 if (conn
->dir_spool_src
== DIR_SPOOL_NONE
) {
2209 /* add_dir_bytes thinks we're done with the cached_dir. But we
2210 * may have more cached_dirs! */
2211 conn
->dir_spool_src
= DIR_SPOOL_NETWORKSTATUS
;
2212 /* This bit is tricky. If we were uncompressing the last
2213 * networkstatus, we may need to make a new zlib object to
2214 * uncompress the next one. */
2215 if (uncompressing
&& ! conn
->zlib_state
&&
2216 conn
->fingerprint_stack
&&
2217 smartlist_len(conn
->fingerprint_stack
)) {
2218 conn
->zlib_state
= tor_zlib_new(0, ZLIB_METHOD
);
2222 } else if (conn
->fingerprint_stack
&&
2223 smartlist_len(conn
->fingerprint_stack
)) {
2224 /* Add another networkstatus; start serving it. */
2225 char *fp
= smartlist_pop_last(conn
->fingerprint_stack
);
2227 if (router_digest_is_me(fp
))
2228 d
= the_v2_networkstatus
;
2230 d
= digestmap_get(cached_v2_networkstatus
, fp
);
2234 conn
->cached_dir
= d
;
2235 conn
->cached_dir_offset
= 0;
2238 connection_dirserv_finish_spooling(conn
);
2239 if (conn
->fingerprint_stack
)
2240 smartlist_free(conn
->fingerprint_stack
);
2241 conn
->fingerprint_stack
= NULL
;
2248 /** Called whenever we have flushed some directory data in state
2249 * SERVER_WRITING. */
2251 connection_dirserv_flushed_some(dir_connection_t
*conn
)
2253 or_connection_t
*or_conn
;
2254 tor_assert(conn
->_base
.state
== DIR_CONN_STATE_SERVER_WRITING
);
2256 if (buf_datalen(conn
->_base
.outbuf
) >= DIRSERV_BUFFER_MIN
)
2259 if ((or_conn
= connection_dirserv_get_target_or_conn(conn
)) &&
2260 connection_or_too_full_for_dirserv_data(or_conn
)) {
2261 connection_dirserv_mark_as_blocked(conn
);
2265 switch (conn
->dir_spool_src
) {
2266 case DIR_SPOOL_SERVER_BY_DIGEST
:
2267 case DIR_SPOOL_SERVER_BY_FP
:
2268 return connection_dirserv_add_servers_to_outbuf(conn
);
2269 case DIR_SPOOL_CACHED_DIR
:
2270 return connection_dirserv_add_dir_bytes_to_outbuf(conn
);
2271 case DIR_SPOOL_NETWORKSTATUS
:
2272 return connection_dirserv_add_networkstatus_bytes_to_outbuf(conn
);
2273 case DIR_SPOOL_NONE
:
2279 /** Release all storage used by the directory server. */
2281 dirserv_free_all(void)
2283 dirserv_free_fingerprint_list();
2285 cached_dir_decref(the_directory
);
2286 clear_cached_dir(&the_runningrouters
);
2287 cached_dir_decref(the_v2_networkstatus
);
2288 cached_dir_decref(cached_directory
);
2289 clear_cached_dir(&cached_runningrouters
);
2290 if (cached_v2_networkstatus
) {
2291 digestmap_free(cached_v2_networkstatus
, _free_cached_dir
);
2292 cached_v2_networkstatus
= NULL
;