1 /* Copyright (c) 2001-2004, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
6 #include "core/or/or.h"
8 #include "app/config/config.h"
9 #include "core/mainloop/connection.h"
10 #include "core/or/circuitlist.h"
11 #include "core/or/connection_edge.h"
12 #include "core/or/connection_or.h"
13 #include "core/or/channeltls.h"
14 #include "feature/dircache/dircache.h"
15 #include "feature/dircache/dirserv.h"
16 #include "feature/dirclient/dirclient.h"
17 #include "feature/dircommon/directory.h"
18 #include "feature/dircommon/fp_pair.h"
19 #include "feature/stats/geoip_stats.h"
20 #include "lib/compress/compress.h"
22 #include "core/or/circuit_st.h"
23 #include "core/or/or_circuit_st.h"
24 #include "core/or/edge_connection_st.h"
25 #include "core/or/or_connection_st.h"
26 #include "feature/dircommon/dir_connection_st.h"
27 #include "feature/nodelist/routerinfo_st.h"
31 * \brief Code to send and fetch information from directory authorities and
34 * Directory caches and authorities use dirserv.c to generate the results of a
35 * query and stream them to the connection; clients use routerparse.c to parse
38 * Every directory request has a dir_connection_t on the client side and on
39 * the server side. In most cases, the dir_connection_t object is a linked
40 * connection, tunneled through an edge_connection_t so that it can be a
41 * stream on the Tor network. The only non-tunneled connections are those
42 * that are used to upload material (descriptors and votes) to authorities.
43 * Among tunneled connections, some use one-hop circuits, and others use
44 * multi-hop circuits for anonymity.
46 * Directory requests are launched by calling
47 * directory_initiate_request(). This
48 * launch the connection, will construct an HTTP request with
49 * directory_send_command(), send the and wait for a response. The client
50 * later handles the response with connection_dir_client_reached_eof(),
51 * which passes the information received to another part of Tor.
53 * On the server side, requests are read in directory_handle_command(),
54 * which dispatches first on the request type (GET or POST), and then on
55 * the URL requested. GET requests are processed with a table-based
56 * dispatcher in url_table[]. The process of handling larger GET requests
57 * is complicated because we need to avoid allocating a copy of all the
58 * data to be sent to the client in one huge buffer. Instead, we spool the
59 * data into the buffer using logic in connection_dirserv_flushed_some() in
60 * dirserv.c. (TODO: If we extended buf.c to have a zero-copy
61 * reference-based buffer type, we could remove most of that code, at the
62 * cost of a bit more reference counting.)
65 /* In-points to directory.c:
67 * - directory_post_to_dirservers(), called from
68 * router_upload_dir_desc_to_dirservers() in router.c
69 * upload_service_descriptor() in rendservice.c
70 * - directory_get_from_dirserver(), called from
71 * run_scheduled_events() in main.c
73 * - connection_dir_process_inbuf(), called from
74 * connection_process_inbuf() in connection.c
75 * - connection_dir_finished_flushing(), called from
76 * connection_finished_flushing() in connection.c
77 * - connection_dir_finished_connecting(), called from
78 * connection_finished_connecting() in connection.c
82 * Cast a `connection_t *` to a `dir_connection_t *`.
84 * Exit with an assertion failure if the input is not a
88 TO_DIR_CONN(connection_t
*c
)
90 tor_assert(c
->magic
== DIR_CONNECTION_MAGIC
);
91 return DOWNCAST(dir_connection_t
, c
);
95 * Cast a `const connection_t *` to a `const dir_connection_t *`.
97 * Exit with an assertion failure if the input is not a
100 const dir_connection_t
*
101 CONST_TO_DIR_CONN(const connection_t
*c
)
103 return TO_DIR_CONN((connection_t
*)c
);
106 /** Return false if the directory purpose <b>dir_purpose</b>
107 * does not require an anonymous (three-hop) connection.
109 * Return true 1) by default, 2) if all directory actions have
110 * specifically been configured to be over an anonymous connection,
111 * or 3) if the router is a bridge */
113 purpose_needs_anonymity(uint8_t dir_purpose
, uint8_t router_purpose
,
114 const char *resource
)
116 if (get_options()->AllDirActionsPrivate
)
119 if (router_purpose
== ROUTER_PURPOSE_BRIDGE
) {
120 if (dir_purpose
== DIR_PURPOSE_FETCH_SERVERDESC
121 && resource
&& !strcmp(resource
, "authority.z")) {
122 /* We are asking a bridge for its own descriptor. That doesn't need
126 /* Assume all other bridge stuff needs anonymity. */
127 return 1; /* if no circuits yet, this might break bootstrapping, but it's
128 * needed to be safe. */
133 case DIR_PURPOSE_UPLOAD_DIR
:
134 case DIR_PURPOSE_UPLOAD_VOTE
:
135 case DIR_PURPOSE_UPLOAD_SIGNATURES
:
136 case DIR_PURPOSE_FETCH_STATUS_VOTE
:
137 case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
:
138 case DIR_PURPOSE_FETCH_CONSENSUS
:
139 case DIR_PURPOSE_FETCH_CERTIFICATE
:
140 case DIR_PURPOSE_FETCH_SERVERDESC
:
141 case DIR_PURPOSE_FETCH_EXTRAINFO
:
142 case DIR_PURPOSE_FETCH_MICRODESC
:
144 case DIR_PURPOSE_HAS_FETCHED_HSDESC
:
145 case DIR_PURPOSE_FETCH_HSDESC
:
146 case DIR_PURPOSE_UPLOAD_HSDESC
:
148 case DIR_PURPOSE_SERVER
:
150 log_warn(LD_BUG
, "Called with dir_purpose=%d, router_purpose=%d",
151 dir_purpose
, router_purpose
);
152 tor_assert_nonfatal_unreached();
153 return 1; /* Assume it needs anonymity; better safe than sorry. */
157 /** Return a newly allocated string describing <b>auth</b>. Only describes
158 * authority features. */
160 authdir_type_to_string(dirinfo_type_t auth
)
163 smartlist_t
*lst
= smartlist_new();
164 if (auth
& V3_DIRINFO
)
165 smartlist_add(lst
, (void*)"V3");
166 if (auth
& BRIDGE_DIRINFO
)
167 smartlist_add(lst
, (void*)"Bridge");
168 if (smartlist_len(lst
)) {
169 result
= smartlist_join_strings(lst
, ", ", 0, NULL
);
171 result
= tor_strdup("[Not an authority]");
177 /** Return true iff anything we say on <b>conn</b> is being encrypted before
178 * we send it to the client/server. */
180 connection_dir_is_encrypted(const dir_connection_t
*conn
)
182 /* Right now it's sufficient to see if conn is or has been linked, since
183 * the only thing it could be linked to is an edge connection on a
184 * circuit, and the only way it could have been unlinked is at the edge
185 * connection getting closed.
187 return TO_CONN(conn
)->linked
;
190 /** Return true iff the given directory connection <b>dir_conn</b> is
191 * anonymous, that is, it is on a circuit via a public relay and not directly
192 * from a client or bridge.
194 * For client circuits via relays: true for 2-hop+ paths.
195 * For client circuits via bridges: true for 3-hop+ paths.
197 * This first test if the connection is encrypted since it is a strong
198 * requirement for anonymity. */
200 connection_dir_is_anonymous(const dir_connection_t
*dir_conn
)
202 const connection_t
*conn
, *linked_conn
;
203 const edge_connection_t
*edge_conn
;
204 const circuit_t
*circ
;
206 tor_assert(dir_conn
);
208 if (!connection_dir_is_encrypted(dir_conn
)) {
213 * Buckle up, we'll do a deep dive into the connection in order to get the
214 * final connection channel of that connection in order to figure out if
215 * this is a client or relay link.
217 * We go: dir_conn -> linked_conn -> edge_conn -> on_circuit -> p_chan.
220 conn
= TO_CONN(dir_conn
);
221 linked_conn
= conn
->linked_conn
;
223 /* The dir connection should be connected to an edge connection. It can not
224 * be closed or marked for close. */
225 if (linked_conn
== NULL
|| linked_conn
->magic
!= EDGE_CONNECTION_MAGIC
||
226 conn
->linked_conn_is_closed
|| conn
->linked_conn
->marked_for_close
) {
227 log_debug(LD_DIR
, "Directory connection is not anonymous: "
228 "not linked to edge");
232 edge_conn
= CONST_TO_EDGE_CONN(linked_conn
);
233 circ
= edge_conn
->on_circuit
;
235 /* Can't be a circuit we initiated and without a circuit, no channel. */
236 if (circ
== NULL
|| CIRCUIT_IS_ORIGIN(circ
)) {
237 log_debug(LD_DIR
, "Directory connection is not anonymous: "
238 "not on OR circuit");
242 /* It is possible that the circuit was closed because one of the channel was
243 * closed or a DESTROY cell was received. Either way, this connection can
244 * not continue so return that it is not anonymous since we can not know for
246 if (circ
->marked_for_close
) {
247 log_debug(LD_DIR
, "Directory connection is not anonymous: "
248 "circuit marked for close");
252 /* Get the previous channel to learn if it is a client or relay link. We
253 * BUG() because if the circuit is not mark for close, we ought to have a
254 * p_chan else we have a code flow issue. */
255 if (BUG(CONST_TO_OR_CIRCUIT(circ
)->p_chan
== NULL
)) {
256 log_debug(LD_DIR
, "Directory connection is not anonymous: "
257 "no p_chan on circuit");
261 /* Will be true if the channel is an unauthenticated peer which is only true
262 * for clients and bridges. */
263 return !channel_is_client(CONST_TO_OR_CIRCUIT(circ
)->p_chan
);
266 /** Parse an HTTP request line at the start of a headers string. On failure,
267 * return -1. On success, set *<b>command_out</b> to a copy of the HTTP
268 * command ("get", "post", etc), set *<b>url_out</b> to a copy of the URL, and
271 parse_http_command(const char *headers
, char **command_out
, char **url_out
)
273 const char *command
, *end_of_command
;
274 char *s
, *start
, *tmp
;
276 s
= (char *)eat_whitespace_no_nl(headers
);
279 s
= (char *)find_whitespace(s
); /* get past GET/POST */
282 s
= (char *)eat_whitespace_no_nl(s
);
284 start
= s
; /* this is the URL, assuming it's valid */
285 s
= (char *)find_whitespace(start
);
288 /* tolerate the http[s] proxy style of putting the hostname in the url */
289 if (s
-start
>= 4 && !strcmpstart(start
,"http")) {
293 if (s
-tmp
>= 3 && !strcmpstart(tmp
,"://")) {
294 tmp
= strchr(tmp
+3, '/');
295 if (tmp
&& tmp
< s
) {
296 log_debug(LD_DIR
,"Skipping over 'http[s]://hostname/' string");
302 /* Check if the header is well formed (next sequence
303 * should be HTTP/1.X\r\n). Assumes we're supporting 1.0? */
307 char *e
= (char *)eat_whitespace_no_nl(s
);
308 if (2 != tor_sscanf(e
, "HTTP/1.%u%c", &minor_ver
, &ch
)) {
315 *url_out
= tor_memdup_nulterm(start
, s
-start
);
316 *command_out
= tor_memdup_nulterm(command
, end_of_command
- command
);
320 /** Return a copy of the first HTTP header in <b>headers</b> whose key is
321 * <b>which</b>. The key should be given with a terminating colon and space;
322 * this function copies everything after, up to but not including the
323 * following \\r\\n. */
325 http_get_header(const char *headers
, const char *which
)
327 const char *cp
= headers
;
329 if (!strcasecmpstart(cp
, which
)) {
332 if ((eos
= strchr(cp
,'\r')))
333 return tor_strndup(cp
, eos
-cp
);
335 return tor_strdup(cp
);
337 cp
= strchr(cp
, '\n');
343 /** Parse an HTTP response string <b>headers</b> of the form
345 * "HTTP/1.\%d \%d\%s\r\n...".
348 * If it's well-formed, assign the status code to *<b>code</b> and
349 * return 0. Otherwise, return -1.
351 * On success: If <b>date</b> is provided, set *date to the Date
352 * header in the http headers, or 0 if no such header is found. If
353 * <b>compression</b> is provided, set *<b>compression</b> to the
354 * compression method given in the Content-Encoding header, or 0 if no
355 * such header is found, or -1 if the value of the header is not
356 * recognized. If <b>reason</b> is provided, strdup the reason string
360 parse_http_response(const char *headers
, int *code
, time_t *date
,
361 compress_method_t
*compression
, char **reason
)
364 char datestr
[RFC1123_TIME_LEN
+1];
365 smartlist_t
*parsed_headers
;
369 while (TOR_ISSPACE(*headers
)) headers
++; /* tolerate leading whitespace */
371 if (tor_sscanf(headers
, "HTTP/1.%u %u", &n1
, &n2
) < 2 ||
372 (n1
!= 0 && n1
!= 1) ||
373 (n2
< 100 || n2
>= 600)) {
374 log_warn(LD_HTTP
,"Failed to parse header %s",escaped(headers
));
379 parsed_headers
= smartlist_new();
380 smartlist_split_string(parsed_headers
, headers
, "\n",
381 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, -1);
383 smartlist_t
*status_line_elements
= smartlist_new();
384 tor_assert(smartlist_len(parsed_headers
));
385 smartlist_split_string(status_line_elements
,
386 smartlist_get(parsed_headers
, 0),
387 " ", SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, 3);
388 tor_assert(smartlist_len(status_line_elements
) <= 3);
389 if (smartlist_len(status_line_elements
) == 3) {
390 *reason
= smartlist_get(status_line_elements
, 2);
391 smartlist_set(status_line_elements
, 2, NULL
); /* Prevent free */
393 SMARTLIST_FOREACH(status_line_elements
, char *, cp
, tor_free(cp
));
394 smartlist_free(status_line_elements
);
398 SMARTLIST_FOREACH(parsed_headers
, const char *, s
,
399 if (!strcmpstart(s
, "Date: ")) {
400 strlcpy(datestr
, s
+6, sizeof(datestr
));
401 /* This will do nothing on failure, so we don't need to check
402 the result. We shouldn't warn, since there are many other valid
403 date formats besides the one we use. */
404 parse_rfc1123_time(datestr
, date
);
409 const char *enc
= NULL
;
410 SMARTLIST_FOREACH(parsed_headers
, const char *, s
,
411 if (!strcmpstart(s
, "Content-Encoding: ")) {
416 *compression
= NO_METHOD
;
418 *compression
= compression_method_get_by_name(enc
);
420 if (*compression
== UNKNOWN_METHOD
)
421 log_info(LD_HTTP
, "Unrecognized content encoding: %s. Trying to deal.",
425 SMARTLIST_FOREACH(parsed_headers
, char *, s
, tor_free(s
));
426 smartlist_free(parsed_headers
);
431 /** If any directory object is arriving, and it's over 10MB large, we're
432 * getting DoS'd. (As of 0.1.2.x, raw directories are about 1MB, and we never
433 * ask for more than 96 router descriptors at a time.)
435 #define MAX_DIRECTORY_OBJECT_SIZE (10*(1<<20))
437 #define MAX_VOTE_DL_SIZE (MAX_DIRECTORY_OBJECT_SIZE * 5)
439 /** Read handler for directory connections. (That's connections <em>to</em>
440 * directory servers and connections <em>at</em> directory servers.)
443 connection_dir_process_inbuf(dir_connection_t
*conn
)
447 tor_assert(conn
->base_
.type
== CONN_TYPE_DIR
);
449 /* Directory clients write, then read data until they receive EOF;
450 * directory servers read data until they get an HTTP command, then
451 * write their response (when it's finished flushing, they mark for
455 /* If we're on the dirserver side, look for a command. */
456 if (conn
->base_
.state
== DIR_CONN_STATE_SERVER_COMMAND_WAIT
) {
457 if (directory_handle_command(conn
) < 0) {
458 connection_mark_for_close(TO_CONN(conn
));
465 (TO_CONN(conn
)->purpose
== DIR_PURPOSE_FETCH_STATUS_VOTE
) ?
466 MAX_VOTE_DL_SIZE
: MAX_DIRECTORY_OBJECT_SIZE
;
468 if (connection_get_inbuf_len(TO_CONN(conn
)) > max_size
) {
470 "Too much data received from %s: "
471 "denial of service attempt, or you need to upgrade?",
472 connection_describe(TO_CONN(conn
)));
473 connection_mark_for_close(TO_CONN(conn
));
477 if (!conn
->base_
.inbuf_reached_eof
)
478 log_debug(LD_HTTP
,"Got data, not eof. Leaving on inbuf.");
482 /** Called when we're about to finally unlink and free a directory connection:
483 * perform necessary accounting and cleanup */
485 connection_dir_about_to_close(dir_connection_t
*dir_conn
)
487 connection_t
*conn
= TO_CONN(dir_conn
);
489 if (conn
->state
< DIR_CONN_STATE_CLIENT_FINISHED
) {
490 /* It's a directory connection and connecting or fetching
491 * failed: forget about this router, and maybe try again. */
492 connection_dir_client_request_failed(dir_conn
);
495 connection_dir_client_refetch_hsdesc_if_needed(dir_conn
);
498 /** Write handler for directory connections; called when all data has
499 * been flushed. Close the connection or wait for a response as
503 connection_dir_finished_flushing(dir_connection_t
*conn
)
506 tor_assert(conn
->base_
.type
== CONN_TYPE_DIR
);
508 if (conn
->base_
.marked_for_close
)
511 /* Note that we have finished writing the directory response. For direct
512 * connections this means we're done; for tunneled connections it's only
513 * an intermediate step. */
515 geoip_change_dirreq_state(conn
->dirreq_id
, DIRREQ_TUNNELED
,
516 DIRREQ_FLUSHING_DIR_CONN_FINISHED
);
518 geoip_change_dirreq_state(TO_CONN(conn
)->global_identifier
,
520 DIRREQ_FLUSHING_DIR_CONN_FINISHED
);
521 switch (conn
->base_
.state
) {
522 case DIR_CONN_STATE_CONNECTING
:
523 case DIR_CONN_STATE_CLIENT_SENDING
:
524 log_debug(LD_DIR
,"client finished sending command.");
525 conn
->base_
.state
= DIR_CONN_STATE_CLIENT_READING
;
527 case DIR_CONN_STATE_SERVER_WRITING
:
529 log_warn(LD_BUG
, "Emptied a dirserv buffer, but it's still spooling!");
530 connection_mark_for_close(TO_CONN(conn
));
532 log_debug(LD_DIRSERV
, "Finished writing server response. Closing.");
533 connection_mark_for_close(TO_CONN(conn
));
537 log_warn(LD_BUG
,"called in unexpected state %d.",
539 tor_fragile_assert();
545 /** Connected handler for directory connections: begin sending data to the
546 * server, and return 0.
547 * Only used when connections don't immediately connect. */
549 connection_dir_finished_connecting(dir_connection_t
*conn
)
552 tor_assert(conn
->base_
.type
== CONN_TYPE_DIR
);
553 tor_assert(conn
->base_
.state
== DIR_CONN_STATE_CONNECTING
);
555 log_debug(LD_HTTP
,"Dir connection to %s established.",
556 connection_describe_peer(TO_CONN(conn
)));
558 /* start flushing conn */
559 conn
->base_
.state
= DIR_CONN_STATE_CLIENT_SENDING
;
563 /** Helper. Compare two fp_pair_t objects, and return negative, 0, or
564 * positive as appropriate. */
566 compare_pairs_(const void **a
, const void **b
)
568 const fp_pair_t
*fp1
= *a
, *fp2
= *b
;
570 if ((r
= fast_memcmp(fp1
->first
, fp2
->first
, DIGEST_LEN
)))
573 return fast_memcmp(fp1
->second
, fp2
->second
, DIGEST_LEN
);
576 /** Divide a string <b>res</b> of the form FP1-FP2+FP3-FP4...[.z], where each
577 * FP is a hex-encoded fingerprint, into a sequence of distinct sorted
578 * fp_pair_t. Skip malformed pairs. On success, return 0 and add those
579 * fp_pair_t into <b>pairs_out</b>. On failure, return -1. */
581 dir_split_resource_into_fingerprint_pairs(const char *res
,
582 smartlist_t
*pairs_out
)
584 smartlist_t
*pairs_tmp
= smartlist_new();
585 smartlist_t
*pairs_result
= smartlist_new();
587 smartlist_split_string(pairs_tmp
, res
, "+", 0, 0);
588 if (smartlist_len(pairs_tmp
)) {
589 char *last
= smartlist_get(pairs_tmp
,smartlist_len(pairs_tmp
)-1);
590 size_t last_len
= strlen(last
);
591 if (last_len
> 2 && !strcmp(last
+last_len
-2, ".z")) {
592 last
[last_len
-2] = '\0';
595 SMARTLIST_FOREACH_BEGIN(pairs_tmp
, char *, cp
) {
596 if (strlen(cp
) != HEX_DIGEST_LEN
*2+1) {
598 "Skipping digest pair %s with non-standard length.", escaped(cp
));
599 } else if (cp
[HEX_DIGEST_LEN
] != '-') {
601 "Skipping digest pair %s with missing dash.", escaped(cp
));
604 if (base16_decode(pair
.first
, DIGEST_LEN
,
605 cp
, HEX_DIGEST_LEN
) != DIGEST_LEN
||
606 base16_decode(pair
.second
,DIGEST_LEN
,
607 cp
+HEX_DIGEST_LEN
+1, HEX_DIGEST_LEN
) != DIGEST_LEN
) {
608 log_info(LD_DIR
, "Skipping non-decodable digest pair %s", escaped(cp
));
610 smartlist_add(pairs_result
, tor_memdup(&pair
, sizeof(pair
)));
614 } SMARTLIST_FOREACH_END(cp
);
615 smartlist_free(pairs_tmp
);
618 smartlist_sort(pairs_result
, compare_pairs_
);
619 smartlist_uniq(pairs_result
, compare_pairs_
, tor_free_
);
621 smartlist_add_all(pairs_out
, pairs_result
);
622 smartlist_free(pairs_result
);
626 /** Given a directory <b>resource</b> request, containing zero
627 * or more strings separated by plus signs, followed optionally by ".z", store
628 * the strings, in order, into <b>fp_out</b>. If <b>compressed_out</b> is
629 * non-NULL, set it to 1 if the resource ends in ".z", else set it to 0.
631 * If (flags & DSR_HEX), then delete all elements that aren't hex digests, and
632 * decode the rest. If (flags & DSR_BASE64), then use "-" rather than "+" as
633 * a separator, delete all the elements that aren't base64-encoded digests,
634 * and decode the rest. If (flags & DSR_DIGEST256), these digests should be
635 * 256 bits long; else they should be 160.
637 * If (flags & DSR_SORT_UNIQ), then sort the list and remove all duplicates.
640 dir_split_resource_into_fingerprints(const char *resource
,
641 smartlist_t
*fp_out
, int *compressed_out
,
644 const int decode_hex
= flags
& DSR_HEX
;
645 const int decode_base64
= flags
& DSR_BASE64
;
646 const int digests_are_256
= flags
& DSR_DIGEST256
;
647 const int sort_uniq
= flags
& DSR_SORT_UNIQ
;
649 const int digest_len
= digests_are_256
? DIGEST256_LEN
: DIGEST_LEN
;
650 const int hex_digest_len
= digests_are_256
?
651 HEX_DIGEST256_LEN
: HEX_DIGEST_LEN
;
652 const int base64_digest_len
= digests_are_256
?
653 BASE64_DIGEST256_LEN
: BASE64_DIGEST_LEN
;
654 smartlist_t
*fp_tmp
= smartlist_new();
656 tor_assert(!(decode_hex
&& decode_base64
));
659 smartlist_split_string(fp_tmp
, resource
, decode_base64
?"-":"+", 0, 0);
662 if (smartlist_len(fp_tmp
)) {
663 char *last
= smartlist_get(fp_tmp
,smartlist_len(fp_tmp
)-1);
664 size_t last_len
= strlen(last
);
665 if (last_len
> 2 && !strcmp(last
+last_len
-2, ".z")) {
666 last
[last_len
-2] = '\0';
671 if (decode_hex
|| decode_base64
) {
672 const size_t encoded_len
= decode_hex
? hex_digest_len
: base64_digest_len
;
675 for (i
= 0; i
< smartlist_len(fp_tmp
); ++i
) {
676 cp
= smartlist_get(fp_tmp
, i
);
677 if (strlen(cp
) != encoded_len
) {
679 "Skipping digest %s with non-standard length.", escaped(cp
));
680 smartlist_del_keeporder(fp_tmp
, i
--);
683 d
= tor_malloc_zero(digest_len
);
685 (base16_decode(d
, digest_len
, cp
, hex_digest_len
) != digest_len
) :
686 (base64_decode(d
, digest_len
, cp
, base64_digest_len
)
688 log_info(LD_DIR
, "Skipping non-decodable digest %s", escaped(cp
));
689 smartlist_del_keeporder(fp_tmp
, i
--);
692 smartlist_set(fp_tmp
, i
, d
);
700 if (decode_hex
|| decode_base64
) {
701 if (digests_are_256
) {
702 smartlist_sort_digests256(fp_tmp
);
703 smartlist_uniq_digests256(fp_tmp
);
705 smartlist_sort_digests(fp_tmp
);
706 smartlist_uniq_digests(fp_tmp
);
709 smartlist_sort_strings(fp_tmp
);
710 smartlist_uniq_strings(fp_tmp
);
713 smartlist_add_all(fp_out
, fp_tmp
);
714 smartlist_free(fp_tmp
);