Tor 0.4.9.2-alpha-dev
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
directory.c
Go to the documentation of this file.
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 */
5
6#include "core/or/or.h"
7
8#include "app/config/config.h"
10#include "core/or/circuitlist.h"
13#include "core/or/channeltls.h"
19#include "feature/hs/hs_cache.h"
22
23#include "core/or/circuit_st.h"
24#include "core/or/or_circuit_st.h"
29
30/**
31 * \file directory.c
32 * \brief Code to send and fetch information from directory authorities and
33 * caches via HTTP.
34 *
35 * Directory caches and authorities use dirserv.c to generate the results of a
36 * query and stream them to the connection; clients use routerparse.c to parse
37 * them.
38 *
39 * Every directory request has a dir_connection_t on the client side and on
40 * the server side. In most cases, the dir_connection_t object is a linked
41 * connection, tunneled through an edge_connection_t so that it can be a
42 * stream on the Tor network. The only non-tunneled connections are those
43 * that are used to upload material (descriptors and votes) to authorities.
44 * Among tunneled connections, some use one-hop circuits, and others use
45 * multi-hop circuits for anonymity.
46 *
47 * Directory requests are launched by calling
48 * directory_initiate_request(). This
49 * launch the connection, will construct an HTTP request with
50 * directory_send_command(), send the and wait for a response. The client
51 * later handles the response with connection_dir_client_reached_eof(),
52 * which passes the information received to another part of Tor.
53 *
54 * On the server side, requests are read in directory_handle_command(),
55 * which dispatches first on the request type (GET or POST), and then on
56 * the URL requested. GET requests are processed with a table-based
57 * dispatcher in url_table[]. The process of handling larger GET requests
58 * is complicated because we need to avoid allocating a copy of all the
59 * data to be sent to the client in one huge buffer. Instead, we spool the
60 * data into the buffer using logic in connection_dirserv_flushed_some() in
61 * dirserv.c. (TODO: If we extended buf.c to have a zero-copy
62 * reference-based buffer type, we could remove most of that code, at the
63 * cost of a bit more reference counting.)
64 **/
65
66/* In-points to directory.c:
67 *
68 * - directory_post_to_dirservers(), called from
69 * router_upload_dir_desc_to_dirservers() in router.c
70 * upload_service_descriptor() in rendservice.c
71 * - directory_get_from_dirserver(), called from
72 * run_scheduled_events() in main.c
73 * do_hup() in main.c
74 * - connection_dir_process_inbuf(), called from
75 * connection_process_inbuf() in connection.c
76 * - connection_dir_finished_flushing(), called from
77 * connection_finished_flushing() in connection.c
78 * - connection_dir_finished_connecting(), called from
79 * connection_finished_connecting() in connection.c
80 */
81
82/**
83 * Cast a `connection_t *` to a `dir_connection_t *`.
84 *
85 * Exit with an assertion failure if the input is not a
86 * `dir_connection_t`.
87 **/
90{
91 tor_assert(c->magic == DIR_CONNECTION_MAGIC);
92 return DOWNCAST(dir_connection_t, c);
93}
94
95/**
96 * Cast a `const connection_t *` to a `const dir_connection_t *`.
97 *
98 * Exit with an assertion failure if the input is not a
99 * `dir_connection_t`.
100 **/
101const dir_connection_t *
103{
104 return TO_DIR_CONN((connection_t *)c);
105}
106
107/** Return false if the directory purpose <b>dir_purpose</b>
108 * does not require an anonymous (three-hop) connection.
109 *
110 * Return true 1) by default, 2) if all directory actions have
111 * specifically been configured to be over an anonymous connection,
112 * or 3) if the router is a bridge */
113int
114purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose,
115 const char *resource)
116{
117 if (get_options()->AllDirActionsPrivate)
118 return 1;
119
120 if (router_purpose == ROUTER_PURPOSE_BRIDGE) {
121 if (dir_purpose == DIR_PURPOSE_FETCH_SERVERDESC
122 && resource && !strcmp(resource, "authority.z")) {
123 /* We are asking a bridge for its own descriptor. That doesn't need
124 anonymity. */
125 return 0;
126 }
127 /* Assume all other bridge stuff needs anonymity. */
128 return 1; /* if no circuits yet, this might break bootstrapping, but it's
129 * needed to be safe. */
130 }
131
132 switch (dir_purpose)
133 {
144 return 0;
148 return 1;
150 default:
151 log_warn(LD_BUG, "Called with dir_purpose=%d, router_purpose=%d",
152 dir_purpose, router_purpose);
154 return 1; /* Assume it needs anonymity; better safe than sorry. */
155 }
156}
157
158/** Return a newly allocated string describing <b>auth</b>. Only describes
159 * authority features. */
160char *
162{
163 char *result;
164 smartlist_t *lst = smartlist_new();
165 if (auth & V3_DIRINFO)
166 smartlist_add(lst, (void*)"V3");
167 if (auth & BRIDGE_DIRINFO)
168 smartlist_add(lst, (void*)"Bridge");
169 if (smartlist_len(lst)) {
170 result = smartlist_join_strings(lst, ", ", 0, NULL);
171 } else {
172 result = tor_strdup("[Not an authority]");
173 }
174 smartlist_free(lst);
175 return result;
176}
177
178/** Return true iff anything we say on <b>conn</b> is being encrypted before
179 * we send it to the client/server. */
180int
182{
183 /* Right now it's sufficient to see if conn is or has been linked, since
184 * the only thing it could be linked to is an edge connection on a
185 * circuit, and the only way it could have been unlinked is at the edge
186 * connection getting closed.
187 */
188 return TO_CONN(conn)->linked;
189}
190
191/** Return true iff the given directory connection <b>dir_conn</b> is
192 * anonymous, that is, it is on a circuit via a public relay and not directly
193 * from a client or bridge.
194 *
195 * For client circuits via relays: true for 2-hop+ paths.
196 * For client circuits via bridges: true for 3-hop+ paths.
197 *
198 * This first test if the connection is encrypted since it is a strong
199 * requirement for anonymity. */
200bool
202{
203 const connection_t *conn, *linked_conn;
204 const edge_connection_t *edge_conn;
205 const circuit_t *circ;
206
207 tor_assert(dir_conn);
208
209 if (!connection_dir_is_encrypted(dir_conn)) {
210 return false;
211 }
212
213 /*
214 * Buckle up, we'll do a deep dive into the connection in order to get the
215 * final connection channel of that connection in order to figure out if
216 * this is a client or relay link.
217 *
218 * We go: dir_conn -> linked_conn -> edge_conn -> on_circuit -> p_chan.
219 */
220
221 conn = TO_CONN(dir_conn);
222 linked_conn = conn->linked_conn;
223
224 /* The dir connection should be connected to an edge connection. It can not
225 * be closed or marked for close. */
226 if (linked_conn == NULL || linked_conn->magic != EDGE_CONNECTION_MAGIC ||
228 log_debug(LD_DIR, "Directory connection is not anonymous: "
229 "not linked to edge");
230 return false;
231 }
232
233 edge_conn = CONST_TO_EDGE_CONN(linked_conn);
234 circ = edge_conn->on_circuit;
235
236 /* Can't be a circuit we initiated and without a circuit, no channel. */
237 if (circ == NULL || CIRCUIT_IS_ORIGIN(circ)) {
238 log_debug(LD_DIR, "Directory connection is not anonymous: "
239 "not on OR circuit");
240 return false;
241 }
242
243 /* It is possible that the circuit was closed because one of the channel was
244 * closed or a DESTROY cell was received. Either way, this connection can
245 * not continue so return that it is not anonymous since we can not know for
246 * sure if it is. */
247 if (circ->marked_for_close) {
248 log_debug(LD_DIR, "Directory connection is not anonymous: "
249 "circuit marked for close");
250 return false;
251 }
252
253 /* Get the previous channel to learn if it is a client or relay link. We
254 * BUG() because if the circuit is not mark for close, we ought to have a
255 * p_chan else we have a code flow issue. */
256 if (BUG(CONST_TO_OR_CIRCUIT(circ)->p_chan == NULL)) {
257 log_debug(LD_DIR, "Directory connection is not anonymous: "
258 "no p_chan on circuit");
259 return false;
260 }
261
262 /* Will be true if the channel is an unauthenticated peer which is only true
263 * for clients and bridges. */
264 return !channel_is_client(CONST_TO_OR_CIRCUIT(circ)->p_chan);
265}
266
267/** Parse an HTTP request line at the start of a headers string. On failure,
268 * return -1. On success, set *<b>command_out</b> to a copy of the HTTP
269 * command ("get", "post", etc), set *<b>url_out</b> to a copy of the URL, and
270 * return 0. */
271int
272parse_http_command(const char *headers, char **command_out, char **url_out)
273{
274 const char *command, *end_of_command;
275 char *s, *start, *tmp;
276
277 s = (char *)eat_whitespace_no_nl(headers);
278 if (!*s) return -1;
279 command = s;
280 s = (char *)find_whitespace(s); /* get past GET/POST */
281 if (!*s) return -1;
282 end_of_command = s;
283 s = (char *)eat_whitespace_no_nl(s);
284 if (!*s) return -1;
285 start = s; /* this is the URL, assuming it's valid */
286 s = (char *)find_whitespace(start);
287 if (!*s) return -1;
288
289 /* tolerate the http[s] proxy style of putting the hostname in the url */
290 if (s-start >= 4 && !strcmpstart(start,"http")) {
291 tmp = start + 4;
292 if (*tmp == 's')
293 tmp++;
294 if (s-tmp >= 3 && !strcmpstart(tmp,"://")) {
295 tmp = strchr(tmp+3, '/');
296 if (tmp && tmp < s) {
297 log_debug(LD_DIR,"Skipping over 'http[s]://hostname/' string");
298 start = tmp;
299 }
300 }
301 }
302
303 /* Check if the header is well formed (next sequence
304 * should be HTTP/1.X\r\n). Assumes we're supporting 1.0? */
305 {
306 unsigned minor_ver;
307 char ch;
308 char *e = (char *)eat_whitespace_no_nl(s);
309 if (2 != tor_sscanf(e, "HTTP/1.%u%c", &minor_ver, &ch)) {
310 return -1;
311 }
312 if (ch != '\r')
313 return -1;
314 }
315
316 *url_out = tor_memdup_nulterm(start, s-start);
317 *command_out = tor_memdup_nulterm(command, end_of_command - command);
318 return 0;
319}
320
321/** Return a copy of the first HTTP header in <b>headers</b> whose key is
322 * <b>which</b>. The key should be given with a terminating colon and space;
323 * this function copies everything after, up to but not including the
324 * following \\r\\n. */
325char *
326http_get_header(const char *headers, const char *which)
327{
328 const char *cp = headers;
329 while (cp) {
330 if (!strcasecmpstart(cp, which)) {
331 char *eos;
332 cp += strlen(which);
333 if ((eos = strchr(cp,'\r')))
334 return tor_strndup(cp, eos-cp);
335 else
336 return tor_strdup(cp);
337 }
338 cp = strchr(cp, '\n');
339 if (cp)
340 ++cp;
341 }
342 return NULL;
343}
344/** Parse an HTTP response string <b>headers</b> of the form
345 * \verbatim
346 * "HTTP/1.\%d \%d\%s\r\n...".
347 * \endverbatim
348 *
349 * If it's well-formed, assign the status code to *<b>code</b> and
350 * return 0. Otherwise, return -1.
351 *
352 * On success: If <b>date</b> is provided, set *date to the Date
353 * header in the http headers, or 0 if no such header is found. If
354 * <b>compression</b> is provided, set *<b>compression</b> to the
355 * compression method given in the Content-Encoding header, or 0 if no
356 * such header is found, or -1 if the value of the header is not
357 * recognized. If <b>reason</b> is provided, strdup the reason string
358 * into it.
359 */
360int
361parse_http_response(const char *headers, int *code, time_t *date,
362 compress_method_t *compression, char **reason)
363{
364 unsigned n1, n2;
365 char datestr[RFC1123_TIME_LEN+1];
366 smartlist_t *parsed_headers;
367 tor_assert(headers);
368 tor_assert(code);
369
370 while (TOR_ISSPACE(*headers)) headers++; /* tolerate leading whitespace */
371
372 if (tor_sscanf(headers, "HTTP/1.%u %u", &n1, &n2) < 2 ||
373 (n1 != 0 && n1 != 1) ||
374 (n2 < 100 || n2 >= 600)) {
375 log_warn(LD_HTTP,"Failed to parse header %s",escaped(headers));
376 return -1;
377 }
378 *code = n2;
379
380 parsed_headers = smartlist_new();
381 smartlist_split_string(parsed_headers, headers, "\n",
382 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
383 if (reason) {
384 smartlist_t *status_line_elements = smartlist_new();
385 tor_assert(smartlist_len(parsed_headers));
386 smartlist_split_string(status_line_elements,
387 smartlist_get(parsed_headers, 0),
388 " ", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 3);
389 tor_assert(smartlist_len(status_line_elements) <= 3);
390 if (smartlist_len(status_line_elements) == 3) {
391 *reason = smartlist_get(status_line_elements, 2);
392 smartlist_set(status_line_elements, 2, NULL); /* Prevent free */
393 }
394 SMARTLIST_FOREACH(status_line_elements, char *, cp, tor_free(cp));
395 smartlist_free(status_line_elements);
396 }
397 if (date) {
398 *date = 0;
399 SMARTLIST_FOREACH(parsed_headers, const char *, s,
400 if (!strcmpstart(s, "Date: ")) {
401 strlcpy(datestr, s+6, sizeof(datestr));
402 /* This will do nothing on failure, so we don't need to check
403 the result. We shouldn't warn, since there are many other valid
404 date formats besides the one we use. */
405 parse_rfc1123_time(datestr, date);
406 break;
407 });
408 }
409 if (compression) {
410 const char *enc = NULL;
411 SMARTLIST_FOREACH(parsed_headers, const char *, s,
412 if (!strcmpstart(s, "Content-Encoding: ")) {
413 enc = s+18; break;
414 });
415
416 if (enc == NULL)
417 *compression = NO_METHOD;
418 else {
419 *compression = compression_method_get_by_name(enc);
420
421 if (*compression == UNKNOWN_METHOD)
422 log_info(LD_HTTP, "Unrecognized content encoding: %s. Trying to deal.",
423 escaped(enc));
424 }
425 }
426 SMARTLIST_FOREACH(parsed_headers, char *, s, tor_free(s));
427 smartlist_free(parsed_headers);
428
429 return 0;
430}
431
432/** If any directory object is arriving, and it's over 10MB large, we're
433 * getting DoS'd. (As of 0.1.2.x, raw directories are about 1MB, and we never
434 * ask for more than 96 router descriptors at a time.)
435 */
436#define MAX_DIRECTORY_OBJECT_SIZE (10*(1<<20))
437
438#define MAX_VOTE_DL_SIZE (MAX_DIRECTORY_OBJECT_SIZE * 5)
439
440/** Read handler for directory connections. (That's connections <em>to</em>
441 * directory servers and connections <em>at</em> directory servers.)
442 */
443int
445{
446 size_t max_size;
447 tor_assert(conn);
448 tor_assert(conn->base_.type == CONN_TYPE_DIR);
449
450 /* Directory clients write, then read data until they receive EOF;
451 * directory servers read data until they get an HTTP command, then
452 * write their response (when it's finished flushing, they mark for
453 * close).
454 */
455
456 /* If we're on the dirserver side, look for a command. */
457 if (conn->base_.state == DIR_CONN_STATE_SERVER_COMMAND_WAIT) {
458 if (directory_handle_command(conn) < 0) {
459 connection_mark_for_close(TO_CONN(conn));
460 return -1;
461 }
462 return 0;
463 }
464
465 max_size =
466 (TO_CONN(conn)->purpose == DIR_PURPOSE_FETCH_STATUS_VOTE) ?
467 MAX_VOTE_DL_SIZE : MAX_DIRECTORY_OBJECT_SIZE;
468
469 if (connection_get_inbuf_len(TO_CONN(conn)) > max_size) {
470 log_warn(LD_HTTP,
471 "Too much data received from %s: "
472 "denial of service attempt, or you need to upgrade?",
474 connection_mark_for_close(TO_CONN(conn));
475 return -1;
476 }
477
478 if (!conn->base_.inbuf_reached_eof)
479 log_debug(LD_HTTP,"Got data, not eof. Leaving on inbuf.");
480 return 0;
481}
482
483/** Called when we're about to finally unlink and free a directory connection:
484 * perform necessary accounting and cleanup */
485void
487{
488 connection_t *conn = TO_CONN(dir_conn);
489
491 /* It's a directory connection and connecting or fetching
492 * failed: forget about this router, and maybe try again. */
494 }
495
496 /* If we are an HSDir, mark the corresponding descriptor as downloaded. This
497 * is needed for the OOM cache cleanup.
498 *
499 * This is done when the direction connection is closed in order to raise the
500 * attack cost of filling the cache with bogus descriptors. That attacker
501 * would need to increase that downloaded counter for the attack to be
502 * successful which is expensive. */
503 if (conn->purpose == DIR_PURPOSE_SERVER && dir_conn->hs_ident) {
504 hs_cache_mark_dowloaded_as_dir(dir_conn->hs_ident);
505 }
506
508}
509
510/** Write handler for directory connections; called when all data has
511 * been flushed. Close the connection or wait for a response as
512 * appropriate.
513 */
514int
516{
517 tor_assert(conn);
518 tor_assert(conn->base_.type == CONN_TYPE_DIR);
519
520 if (conn->base_.marked_for_close)
521 return 0;
522
523 /* Note that we have finished writing the directory response. For direct
524 * connections this means we're done; for tunneled connections it's only
525 * an intermediate step. */
526 if (conn->dirreq_id)
527 geoip_change_dirreq_state(conn->dirreq_id, DIRREQ_TUNNELED,
529 else
530 geoip_change_dirreq_state(TO_CONN(conn)->global_identifier,
531 DIRREQ_DIRECT,
533 switch (conn->base_.state) {
536 log_debug(LD_DIR,"client finished sending command.");
538 return 0;
540 if (conn->spool) {
541 log_warn(LD_BUG, "Emptied a dirserv buffer, but it's still spooling!");
542 connection_mark_for_close(TO_CONN(conn));
543 } else {
544 log_debug(LD_DIRSERV, "Finished writing server response. Closing.");
545 connection_mark_for_close(TO_CONN(conn));
546 }
547 return 0;
548 default:
549 log_warn(LD_BUG,"called in unexpected state %d.",
550 conn->base_.state);
552 return -1;
553 }
554 return 0;
555}
556
557/** Connected handler for directory connections: begin sending data to the
558 * server, and return 0.
559 * Only used when connections don't immediately connect. */
560int
562{
563 tor_assert(conn);
564 tor_assert(conn->base_.type == CONN_TYPE_DIR);
566
567 log_debug(LD_HTTP,"Dir connection to %s established.",
569
570 /* start flushing conn */
572 return 0;
573}
574
575/** Helper. Compare two fp_pair_t objects, and return negative, 0, or
576 * positive as appropriate. */
577static int
578compare_pairs_(const void **a, const void **b)
579{
580 const fp_pair_t *fp1 = *a, *fp2 = *b;
581 int r;
582 if ((r = fast_memcmp(fp1->first, fp2->first, DIGEST_LEN)))
583 return r;
584 else
585 return fast_memcmp(fp1->second, fp2->second, DIGEST_LEN);
586}
587
588/** Divide a string <b>res</b> of the form FP1-FP2+FP3-FP4...[.z], where each
589 * FP is a hex-encoded fingerprint, into a sequence of distinct sorted
590 * fp_pair_t. Skip malformed pairs. On success, return 0 and add those
591 * fp_pair_t into <b>pairs_out</b>. On failure, return -1. */
592int
594 smartlist_t *pairs_out)
595{
596 smartlist_t *pairs_tmp = smartlist_new();
597 smartlist_t *pairs_result = smartlist_new();
598
599 smartlist_split_string(pairs_tmp, res, "+", 0, 0);
600 if (smartlist_len(pairs_tmp)) {
601 char *last = smartlist_get(pairs_tmp,smartlist_len(pairs_tmp)-1);
602 size_t last_len = strlen(last);
603 if (last_len > 2 && !strcmp(last+last_len-2, ".z")) {
604 last[last_len-2] = '\0';
605 }
606 }
607 SMARTLIST_FOREACH_BEGIN(pairs_tmp, char *, cp) {
608 if (strlen(cp) != HEX_DIGEST_LEN*2+1) {
609 log_info(LD_DIR,
610 "Skipping digest pair %s with non-standard length.", escaped(cp));
611 } else if (cp[HEX_DIGEST_LEN] != '-') {
612 log_info(LD_DIR,
613 "Skipping digest pair %s with missing dash.", escaped(cp));
614 } else {
615 fp_pair_t pair;
616 if (base16_decode(pair.first, DIGEST_LEN,
617 cp, HEX_DIGEST_LEN) != DIGEST_LEN ||
618 base16_decode(pair.second,DIGEST_LEN,
620 log_info(LD_DIR, "Skipping non-decodable digest pair %s", escaped(cp));
621 } else {
622 smartlist_add(pairs_result, tor_memdup(&pair, sizeof(pair)));
623 }
624 }
625 tor_free(cp);
626 } SMARTLIST_FOREACH_END(cp);
627 smartlist_free(pairs_tmp);
628
629 /* Uniq-and-sort */
630 smartlist_sort(pairs_result, compare_pairs_);
632
633 smartlist_add_all(pairs_out, pairs_result);
634 smartlist_free(pairs_result);
635 return 0;
636}
637
638/** Given a directory <b>resource</b> request, containing zero
639 * or more strings separated by plus signs, followed optionally by ".z", store
640 * the strings, in order, into <b>fp_out</b>. If <b>compressed_out</b> is
641 * non-NULL, set it to 1 if the resource ends in ".z", else set it to 0.
642 *
643 * If (flags & DSR_HEX), then delete all elements that aren't hex digests, and
644 * decode the rest. If (flags & DSR_BASE64), then use "-" rather than "+" as
645 * a separator, delete all the elements that aren't base64-encoded digests,
646 * and decode the rest. If (flags & DSR_DIGEST256), these digests should be
647 * 256 bits long; else they should be 160.
648 *
649 * If (flags & DSR_SORT_UNIQ), then sort the list and remove all duplicates.
650 */
651int
653 smartlist_t *fp_out, int *compressed_out,
654 int flags)
655{
656 const int decode_hex = flags & DSR_HEX;
657 const int decode_base64 = flags & DSR_BASE64;
658 const int digests_are_256 = flags & DSR_DIGEST256;
659 const int sort_uniq = flags & DSR_SORT_UNIQ;
660
661 const int digest_len = digests_are_256 ? DIGEST256_LEN : DIGEST_LEN;
662 const int hex_digest_len = digests_are_256 ?
664 const int base64_digest_len = digests_are_256 ?
666 smartlist_t *fp_tmp = smartlist_new();
667
668 tor_assert(!(decode_hex && decode_base64));
669 tor_assert(fp_out);
670
671 smartlist_split_string(fp_tmp, resource, decode_base64?"-":"+", 0, 0);
672 if (compressed_out)
673 *compressed_out = 0;
674 if (smartlist_len(fp_tmp)) {
675 char *last = smartlist_get(fp_tmp,smartlist_len(fp_tmp)-1);
676 size_t last_len = strlen(last);
677 if (last_len > 2 && !strcmp(last+last_len-2, ".z")) {
678 last[last_len-2] = '\0';
679 if (compressed_out)
680 *compressed_out = 1;
681 }
682 }
683 if (decode_hex || decode_base64) {
684 const size_t encoded_len = decode_hex ? hex_digest_len : base64_digest_len;
685 int i;
686 char *cp, *d = NULL;
687 for (i = 0; i < smartlist_len(fp_tmp); ++i) {
688 cp = smartlist_get(fp_tmp, i);
689 if (strlen(cp) != encoded_len) {
690 log_info(LD_DIR,
691 "Skipping digest %s with non-standard length.", escaped(cp));
692 smartlist_del_keeporder(fp_tmp, i--);
693 goto again;
694 }
695 d = tor_malloc_zero(digest_len);
696 if (decode_hex ?
697 (base16_decode(d, digest_len, cp, hex_digest_len) != digest_len) :
698 (base64_decode(d, digest_len, cp, base64_digest_len)
699 != digest_len)) {
700 log_info(LD_DIR, "Skipping non-decodable digest %s", escaped(cp));
701 smartlist_del_keeporder(fp_tmp, i--);
702 goto again;
703 }
704 smartlist_set(fp_tmp, i, d);
705 d = NULL;
706 again:
707 tor_free(cp);
708 tor_free(d);
709 }
710 }
711 if (sort_uniq) {
712 if (decode_hex || decode_base64) {
713 if (digests_are_256) {
716 } else {
719 }
720 } else {
723 }
724 }
725 smartlist_add_all(fp_out, fp_tmp);
726 smartlist_free(fp_tmp);
727 return 0;
728}
int base64_decode(char *dest, size_t destlen, const char *src, size_t srclen)
Definition: binascii.c:396
int base16_decode(char *dest, size_t destlen, const char *src, size_t srclen)
Definition: binascii.c:506
int channel_is_client(const channel_t *chan)
Definition: channel.c:2918
Header file for channeltls.c.
Base circuit structure.
Header file for circuitlist.c.
#define CIRCUIT_IS_ORIGIN(c)
Definition: circuitlist.h:154
compress_method_t compression_method_get_by_name(const char *name)
Definition: compress.c:411
Headers for compress.c.
compress_method_t
Definition: compress.h:21
const or_options_t * get_options(void)
Definition: config.c:947
tor_cmdline_mode_t command
Definition: config.c:2477
Header file for config.c.
const char * connection_describe_peer(const connection_t *conn)
Definition: connection.c:526
const char * connection_describe(const connection_t *conn)
Definition: connection.c:541
Header file for connection.c.
#define CONN_TYPE_DIR
Definition: connection.h:55
const edge_connection_t * CONST_TO_EDGE_CONN(const connection_t *c)
Header file for connection_edge.c.
Header file for connection_or.c.
#define BASE64_DIGEST256_LEN
Definition: crypto_digest.h:29
#define HEX_DIGEST256_LEN
Definition: crypto_digest.h:37
#define HEX_DIGEST_LEN
Definition: crypto_digest.h:35
#define BASE64_DIGEST_LEN
Definition: crypto_digest.h:26
#define fast_memcmp(a, b, c)
Definition: di_ops.h:28
#define DIGEST_LEN
Definition: digest_sizes.h:20
#define DIGEST256_LEN
Definition: digest_sizes.h:23
Client/server directory connection structure.
int directory_handle_command(dir_connection_t *conn)
Definition: dircache.c:1739
Header file for dircache.c.
void connection_dir_client_request_failed(dir_connection_t *conn)
Definition: dirclient.c:715
void connection_dir_client_refetch_hsdesc_if_needed(dir_connection_t *dir_conn)
Definition: dirclient.c:2868
Header file for dirclient.c.
int connection_dir_finished_flushing(dir_connection_t *conn)
Definition: directory.c:515
int connection_dir_finished_connecting(dir_connection_t *conn)
Definition: directory.c:561
int purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose, const char *resource)
Definition: directory.c:114
int dir_split_resource_into_fingerprint_pairs(const char *res, smartlist_t *pairs_out)
Definition: directory.c:593
int parse_http_response(const char *headers, int *code, time_t *date, compress_method_t *compression, char **reason)
Definition: directory.c:361
static int compare_pairs_(const void **a, const void **b)
Definition: directory.c:578
char * authdir_type_to_string(dirinfo_type_t auth)
Definition: directory.c:161
int connection_dir_is_encrypted(const dir_connection_t *conn)
Definition: directory.c:181
const dir_connection_t * CONST_TO_DIR_CONN(const connection_t *c)
Definition: directory.c:102
dir_connection_t * TO_DIR_CONN(connection_t *c)
Definition: directory.c:89
int dir_split_resource_into_fingerprints(const char *resource, smartlist_t *fp_out, int *compressed_out, int flags)
Definition: directory.c:652
bool connection_dir_is_anonymous(const dir_connection_t *dir_conn)
Definition: directory.c:201
char * http_get_header(const char *headers, const char *which)
Definition: directory.c:326
int parse_http_command(const char *headers, char **command_out, char **url_out)
Definition: directory.c:272
void connection_dir_about_to_close(dir_connection_t *dir_conn)
Definition: directory.c:486
#define MAX_DIRECTORY_OBJECT_SIZE
Definition: directory.c:436
int connection_dir_process_inbuf(dir_connection_t *conn)
Definition: directory.c:444
Header file for directory.c.
#define DIR_PURPOSE_FETCH_EXTRAINFO
Definition: directory.h:39
#define DIR_PURPOSE_FETCH_CERTIFICATE
Definition: directory.h:57
#define DIR_PURPOSE_UPLOAD_HSDESC
Definition: directory.h:67
#define DIR_PURPOSE_FETCH_MICRODESC
Definition: directory.h:65
#define DIR_CONN_STATE_CONNECTING
Definition: directory.h:20
#define DIR_CONN_STATE_CLIENT_FINISHED
Definition: directory.h:26
#define DIR_CONN_STATE_CLIENT_READING
Definition: directory.h:24
#define DIR_CONN_STATE_SERVER_WRITING
Definition: directory.h:30
#define DIR_PURPOSE_UPLOAD_VOTE
Definition: directory.h:43
#define DIR_CONN_STATE_SERVER_COMMAND_WAIT
Definition: directory.h:28
#define DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
Definition: directory.h:51
#define DIR_PURPOSE_FETCH_CONSENSUS
Definition: directory.h:54
#define DIR_PURPOSE_SERVER
Definition: directory.h:60
#define DIR_PURPOSE_FETCH_SERVERDESC
Definition: directory.h:36
#define DIR_PURPOSE_UPLOAD_SIGNATURES
Definition: directory.h:45
#define DIR_CONN_STATE_CLIENT_SENDING
Definition: directory.h:22
#define DIR_PURPOSE_FETCH_STATUS_VOTE
Definition: directory.h:48
#define DIR_PURPOSE_HAS_FETCHED_HSDESC
Definition: directory.h:72
#define DIR_PURPOSE_UPLOAD_DIR
Definition: directory.h:41
#define DIR_PURPOSE_FETCH_HSDESC
Definition: directory.h:69
Header file for dirserv.c.
Edge-connection structure.
const char * escaped(const char *s)
Definition: escape.c:126
Header file for fp_pair.c.
Header file for geoip_stats.c.
@ DIRREQ_FLUSHING_DIR_CONN_FINISHED
Definition: geoip_stats.h:64
void geoip_change_dirreq_state(uint64_t dirreq_id, dirreq_type_t type, dirreq_state_t new_state)
Definition: geoip_stats.c:552
void hs_cache_mark_dowloaded_as_dir(const hs_ident_dir_conn_t *ident)
Definition: hs_cache.c:408
Header file for hs_cache.c.
#define LD_HTTP
Definition: log.h:76
#define LD_DIRSERV
Definition: log.h:90
#define LD_BUG
Definition: log.h:86
#define LD_DIR
Definition: log.h:88
void tor_free_(void *mem)
Definition: malloc.c:227
#define tor_free(p)
Definition: malloc.h:56
Master header file for Tor-specific functionality.
#define TO_CONN(c)
Definition: or.h:700
#define DOWNCAST(to, ptr)
Definition: or.h:109
dirinfo_type_t
Definition: or.h:875
@ V3_DIRINFO
Definition: or.h:878
@ BRIDGE_DIRINFO
Definition: or.h:880
OR connection structure.
Router descriptor structure.
#define ROUTER_PURPOSE_BRIDGE
int tor_sscanf(const char *buf, const char *pattern,...)
Definition: scanf.c:309
void smartlist_sort_digests(smartlist_t *sl)
Definition: smartlist.c:824
void smartlist_sort_digests256(smartlist_t *sl)
Definition: smartlist.c:846
void smartlist_uniq_digests(smartlist_t *sl)
Definition: smartlist.c:832
void smartlist_uniq_digests256(smartlist_t *sl)
Definition: smartlist.c:863
void smartlist_uniq_strings(smartlist_t *sl)
Definition: smartlist.c:574
void smartlist_sort_strings(smartlist_t *sl)
Definition: smartlist.c:549
char * smartlist_join_strings(smartlist_t *sl, const char *join, int terminate, size_t *len_out)
Definition: smartlist.c:279
void smartlist_sort(smartlist_t *sl, int(*compare)(const void **a, const void **b))
Definition: smartlist.c:334
void smartlist_uniq(smartlist_t *sl, int(*compare)(const void **a, const void **b), void(*free_fn)(void *a))
Definition: smartlist.c:390
void smartlist_add_all(smartlist_t *s1, const smartlist_t *s2)
smartlist_t * smartlist_new(void)
void smartlist_add(smartlist_t *sl, void *element)
void smartlist_del_keeporder(smartlist_t *sl, int idx)
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
#define SMARTLIST_FOREACH(sl, type, var, cmd)
int smartlist_split_string(smartlist_t *sl, const char *str, const char *sep, int flags, int max)
uint16_t marked_for_close
Definition: circuit_st.h:190
uint8_t state
Definition: connection_st.h:49
unsigned int inbuf_reached_eof
Definition: connection_st.h:64
struct connection_t * linked_conn
unsigned int type
Definition: connection_st.h:50
uint32_t magic
Definition: connection_st.h:46
uint16_t marked_for_close
unsigned int linked_conn_is_closed
Definition: connection_st.h:89
unsigned int purpose
Definition: connection_st.h:51
smartlist_t * spool
struct circuit_t * on_circuit
int parse_rfc1123_time(const char *buf, time_t *t)
Definition: time_fmt.c:237
#define tor_assert_nonfatal_unreached()
Definition: util_bug.h:177
#define tor_assert(expr)
Definition: util_bug.h:103
#define tor_fragile_assert()
Definition: util_bug.h:278
int strcasecmpstart(const char *s1, const char *s2)
Definition: util_string.c:227
int strcmpstart(const char *s1, const char *s2)
Definition: util_string.c:217
const char * find_whitespace(const char *s)
Definition: util_string.c:355
const char * eat_whitespace_no_nl(const char *s)
Definition: util_string.c:334