Tor 0.4.9.0-alpha-dev
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"
21
22#include "core/or/circuit_st.h"
23#include "core/or/or_circuit_st.h"
28
29/**
30 * \file directory.c
31 * \brief Code to send and fetch information from directory authorities and
32 * caches via HTTP.
33 *
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
36 * them.
37 *
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.
45 *
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.
52 *
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.)
63 **/
64
65/* In-points to directory.c:
66 *
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
72 * do_hup() 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
79 */
80
81/**
82 * Cast a `connection_t *` to a `dir_connection_t *`.
83 *
84 * Exit with an assertion failure if the input is not a
85 * `dir_connection_t`.
86 **/
89{
90 tor_assert(c->magic == DIR_CONNECTION_MAGIC);
91 return DOWNCAST(dir_connection_t, c);
92}
93
94/**
95 * Cast a `const connection_t *` to a `const dir_connection_t *`.
96 *
97 * Exit with an assertion failure if the input is not a
98 * `dir_connection_t`.
99 **/
100const dir_connection_t *
102{
103 return TO_DIR_CONN((connection_t *)c);
104}
105
106/** Return false if the directory purpose <b>dir_purpose</b>
107 * does not require an anonymous (three-hop) connection.
108 *
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 */
112int
113purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose,
114 const char *resource)
115{
116 if (get_options()->AllDirActionsPrivate)
117 return 1;
118
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
123 anonymity. */
124 return 0;
125 }
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. */
129 }
130
131 switch (dir_purpose)
132 {
143 return 0;
147 return 1;
149 default:
150 log_warn(LD_BUG, "Called with dir_purpose=%d, router_purpose=%d",
151 dir_purpose, router_purpose);
153 return 1; /* Assume it needs anonymity; better safe than sorry. */
154 }
155}
156
157/** Return a newly allocated string describing <b>auth</b>. Only describes
158 * authority features. */
159char *
161{
162 char *result;
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);
170 } else {
171 result = tor_strdup("[Not an authority]");
172 }
173 smartlist_free(lst);
174 return result;
175}
176
177/** Return true iff anything we say on <b>conn</b> is being encrypted before
178 * we send it to the client/server. */
179int
181{
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.
186 */
187 return TO_CONN(conn)->linked;
188}
189
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.
193 *
194 * For client circuits via relays: true for 2-hop+ paths.
195 * For client circuits via bridges: true for 3-hop+ paths.
196 *
197 * This first test if the connection is encrypted since it is a strong
198 * requirement for anonymity. */
199bool
201{
202 const connection_t *conn, *linked_conn;
203 const edge_connection_t *edge_conn;
204 const circuit_t *circ;
205
206 tor_assert(dir_conn);
207
208 if (!connection_dir_is_encrypted(dir_conn)) {
209 return false;
210 }
211
212 /*
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.
216 *
217 * We go: dir_conn -> linked_conn -> edge_conn -> on_circuit -> p_chan.
218 */
219
220 conn = TO_CONN(dir_conn);
221 linked_conn = conn->linked_conn;
222
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 ||
227 log_debug(LD_DIR, "Directory connection is not anonymous: "
228 "not linked to edge");
229 return false;
230 }
231
232 edge_conn = CONST_TO_EDGE_CONN(linked_conn);
233 circ = edge_conn->on_circuit;
234
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");
239 return false;
240 }
241
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
245 * sure if it is. */
246 if (circ->marked_for_close) {
247 log_debug(LD_DIR, "Directory connection is not anonymous: "
248 "circuit marked for close");
249 return false;
250 }
251
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");
258 return false;
259 }
260
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);
264}
265
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
269 * return 0. */
270int
271parse_http_command(const char *headers, char **command_out, char **url_out)
272{
273 const char *command, *end_of_command;
274 char *s, *start, *tmp;
275
276 s = (char *)eat_whitespace_no_nl(headers);
277 if (!*s) return -1;
278 command = s;
279 s = (char *)find_whitespace(s); /* get past GET/POST */
280 if (!*s) return -1;
281 end_of_command = s;
282 s = (char *)eat_whitespace_no_nl(s);
283 if (!*s) return -1;
284 start = s; /* this is the URL, assuming it's valid */
285 s = (char *)find_whitespace(start);
286 if (!*s) return -1;
287
288 /* tolerate the http[s] proxy style of putting the hostname in the url */
289 if (s-start >= 4 && !strcmpstart(start,"http")) {
290 tmp = start + 4;
291 if (*tmp == 's')
292 tmp++;
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");
297 start = tmp;
298 }
299 }
300 }
301
302 /* Check if the header is well formed (next sequence
303 * should be HTTP/1.X\r\n). Assumes we're supporting 1.0? */
304 {
305 unsigned minor_ver;
306 char ch;
307 char *e = (char *)eat_whitespace_no_nl(s);
308 if (2 != tor_sscanf(e, "HTTP/1.%u%c", &minor_ver, &ch)) {
309 return -1;
310 }
311 if (ch != '\r')
312 return -1;
313 }
314
315 *url_out = tor_memdup_nulterm(start, s-start);
316 *command_out = tor_memdup_nulterm(command, end_of_command - command);
317 return 0;
318}
319
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. */
324char *
325http_get_header(const char *headers, const char *which)
326{
327 const char *cp = headers;
328 while (cp) {
329 if (!strcasecmpstart(cp, which)) {
330 char *eos;
331 cp += strlen(which);
332 if ((eos = strchr(cp,'\r')))
333 return tor_strndup(cp, eos-cp);
334 else
335 return tor_strdup(cp);
336 }
337 cp = strchr(cp, '\n');
338 if (cp)
339 ++cp;
340 }
341 return NULL;
342}
343/** Parse an HTTP response string <b>headers</b> of the form
344 * \verbatim
345 * "HTTP/1.\%d \%d\%s\r\n...".
346 * \endverbatim
347 *
348 * If it's well-formed, assign the status code to *<b>code</b> and
349 * return 0. Otherwise, return -1.
350 *
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
357 * into it.
358 */
359int
360parse_http_response(const char *headers, int *code, time_t *date,
361 compress_method_t *compression, char **reason)
362{
363 unsigned n1, n2;
364 char datestr[RFC1123_TIME_LEN+1];
365 smartlist_t *parsed_headers;
366 tor_assert(headers);
367 tor_assert(code);
368
369 while (TOR_ISSPACE(*headers)) headers++; /* tolerate leading whitespace */
370
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));
375 return -1;
376 }
377 *code = n2;
378
379 parsed_headers = smartlist_new();
380 smartlist_split_string(parsed_headers, headers, "\n",
381 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
382 if (reason) {
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 */
392 }
393 SMARTLIST_FOREACH(status_line_elements, char *, cp, tor_free(cp));
394 smartlist_free(status_line_elements);
395 }
396 if (date) {
397 *date = 0;
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);
405 break;
406 });
407 }
408 if (compression) {
409 const char *enc = NULL;
410 SMARTLIST_FOREACH(parsed_headers, const char *, s,
411 if (!strcmpstart(s, "Content-Encoding: ")) {
412 enc = s+18; break;
413 });
414
415 if (enc == NULL)
416 *compression = NO_METHOD;
417 else {
418 *compression = compression_method_get_by_name(enc);
419
420 if (*compression == UNKNOWN_METHOD)
421 log_info(LD_HTTP, "Unrecognized content encoding: %s. Trying to deal.",
422 escaped(enc));
423 }
424 }
425 SMARTLIST_FOREACH(parsed_headers, char *, s, tor_free(s));
426 smartlist_free(parsed_headers);
427
428 return 0;
429}
430
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.)
434 */
435#define MAX_DIRECTORY_OBJECT_SIZE (10*(1<<20))
436
437#define MAX_VOTE_DL_SIZE (MAX_DIRECTORY_OBJECT_SIZE * 5)
438
439/** Read handler for directory connections. (That's connections <em>to</em>
440 * directory servers and connections <em>at</em> directory servers.)
441 */
442int
444{
445 size_t max_size;
446 tor_assert(conn);
447 tor_assert(conn->base_.type == CONN_TYPE_DIR);
448
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
452 * close).
453 */
454
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));
459 return -1;
460 }
461 return 0;
462 }
463
464 max_size =
465 (TO_CONN(conn)->purpose == DIR_PURPOSE_FETCH_STATUS_VOTE) ?
466 MAX_VOTE_DL_SIZE : MAX_DIRECTORY_OBJECT_SIZE;
467
468 if (connection_get_inbuf_len(TO_CONN(conn)) > max_size) {
469 log_warn(LD_HTTP,
470 "Too much data received from %s: "
471 "denial of service attempt, or you need to upgrade?",
473 connection_mark_for_close(TO_CONN(conn));
474 return -1;
475 }
476
477 if (!conn->base_.inbuf_reached_eof)
478 log_debug(LD_HTTP,"Got data, not eof. Leaving on inbuf.");
479 return 0;
480}
481
482/** Called when we're about to finally unlink and free a directory connection:
483 * perform necessary accounting and cleanup */
484void
486{
487 connection_t *conn = TO_CONN(dir_conn);
488
490 /* It's a directory connection and connecting or fetching
491 * failed: forget about this router, and maybe try again. */
493 }
494
496}
497
498/** Write handler for directory connections; called when all data has
499 * been flushed. Close the connection or wait for a response as
500 * appropriate.
501 */
502int
504{
505 tor_assert(conn);
506 tor_assert(conn->base_.type == CONN_TYPE_DIR);
507
508 if (conn->base_.marked_for_close)
509 return 0;
510
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. */
514 if (conn->dirreq_id)
515 geoip_change_dirreq_state(conn->dirreq_id, DIRREQ_TUNNELED,
517 else
518 geoip_change_dirreq_state(TO_CONN(conn)->global_identifier,
519 DIRREQ_DIRECT,
521 switch (conn->base_.state) {
524 log_debug(LD_DIR,"client finished sending command.");
526 return 0;
528 if (conn->spool) {
529 log_warn(LD_BUG, "Emptied a dirserv buffer, but it's still spooling!");
530 connection_mark_for_close(TO_CONN(conn));
531 } else {
532 log_debug(LD_DIRSERV, "Finished writing server response. Closing.");
533 connection_mark_for_close(TO_CONN(conn));
534 }
535 return 0;
536 default:
537 log_warn(LD_BUG,"called in unexpected state %d.",
538 conn->base_.state);
540 return -1;
541 }
542 return 0;
543}
544
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. */
548int
550{
551 tor_assert(conn);
552 tor_assert(conn->base_.type == CONN_TYPE_DIR);
554
555 log_debug(LD_HTTP,"Dir connection to %s established.",
557
558 /* start flushing conn */
560 return 0;
561}
562
563/** Helper. Compare two fp_pair_t objects, and return negative, 0, or
564 * positive as appropriate. */
565static int
566compare_pairs_(const void **a, const void **b)
567{
568 const fp_pair_t *fp1 = *a, *fp2 = *b;
569 int r;
570 if ((r = fast_memcmp(fp1->first, fp2->first, DIGEST_LEN)))
571 return r;
572 else
573 return fast_memcmp(fp1->second, fp2->second, DIGEST_LEN);
574}
575
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. */
580int
582 smartlist_t *pairs_out)
583{
584 smartlist_t *pairs_tmp = smartlist_new();
585 smartlist_t *pairs_result = smartlist_new();
586
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';
593 }
594 }
595 SMARTLIST_FOREACH_BEGIN(pairs_tmp, char *, cp) {
596 if (strlen(cp) != HEX_DIGEST_LEN*2+1) {
597 log_info(LD_DIR,
598 "Skipping digest pair %s with non-standard length.", escaped(cp));
599 } else if (cp[HEX_DIGEST_LEN] != '-') {
600 log_info(LD_DIR,
601 "Skipping digest pair %s with missing dash.", escaped(cp));
602 } else {
603 fp_pair_t pair;
604 if (base16_decode(pair.first, DIGEST_LEN,
605 cp, HEX_DIGEST_LEN) != DIGEST_LEN ||
606 base16_decode(pair.second,DIGEST_LEN,
608 log_info(LD_DIR, "Skipping non-decodable digest pair %s", escaped(cp));
609 } else {
610 smartlist_add(pairs_result, tor_memdup(&pair, sizeof(pair)));
611 }
612 }
613 tor_free(cp);
614 } SMARTLIST_FOREACH_END(cp);
615 smartlist_free(pairs_tmp);
616
617 /* Uniq-and-sort */
618 smartlist_sort(pairs_result, compare_pairs_);
620
621 smartlist_add_all(pairs_out, pairs_result);
622 smartlist_free(pairs_result);
623 return 0;
624}
625
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.
630 *
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.
636 *
637 * If (flags & DSR_SORT_UNIQ), then sort the list and remove all duplicates.
638 */
639int
641 smartlist_t *fp_out, int *compressed_out,
642 int flags)
643{
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;
648
649 const int digest_len = digests_are_256 ? DIGEST256_LEN : DIGEST_LEN;
650 const int hex_digest_len = digests_are_256 ?
652 const int base64_digest_len = digests_are_256 ?
654 smartlist_t *fp_tmp = smartlist_new();
655
656 tor_assert(!(decode_hex && decode_base64));
657 tor_assert(fp_out);
658
659 smartlist_split_string(fp_tmp, resource, decode_base64?"-":"+", 0, 0);
660 if (compressed_out)
661 *compressed_out = 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';
667 if (compressed_out)
668 *compressed_out = 1;
669 }
670 }
671 if (decode_hex || decode_base64) {
672 const size_t encoded_len = decode_hex ? hex_digest_len : base64_digest_len;
673 int i;
674 char *cp, *d = NULL;
675 for (i = 0; i < smartlist_len(fp_tmp); ++i) {
676 cp = smartlist_get(fp_tmp, i);
677 if (strlen(cp) != encoded_len) {
678 log_info(LD_DIR,
679 "Skipping digest %s with non-standard length.", escaped(cp));
680 smartlist_del_keeporder(fp_tmp, i--);
681 goto again;
682 }
683 d = tor_malloc_zero(digest_len);
684 if (decode_hex ?
685 (base16_decode(d, digest_len, cp, hex_digest_len) != digest_len) :
686 (base64_decode(d, digest_len, cp, base64_digest_len)
687 != digest_len)) {
688 log_info(LD_DIR, "Skipping non-decodable digest %s", escaped(cp));
689 smartlist_del_keeporder(fp_tmp, i--);
690 goto again;
691 }
692 smartlist_set(fp_tmp, i, d);
693 d = NULL;
694 again:
695 tor_free(cp);
696 tor_free(d);
697 }
698 }
699 if (sort_uniq) {
700 if (decode_hex || decode_base64) {
701 if (digests_are_256) {
704 } else {
707 }
708 } else {
711 }
712 }
713 smartlist_add_all(fp_out, fp_tmp);
714 smartlist_free(fp_tmp);
715 return 0;
716}
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:944
tor_cmdline_mode_t command
Definition: config.c:2468
Header file for config.c.
const char * connection_describe_peer(const connection_t *conn)
Definition: connection.c:530
const char * connection_describe(const connection_t *conn)
Definition: connection.c:545
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:1726
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:2863
Header file for dirclient.c.
int connection_dir_finished_flushing(dir_connection_t *conn)
Definition: directory.c:503
int connection_dir_finished_connecting(dir_connection_t *conn)
Definition: directory.c:549
int purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose, const char *resource)
Definition: directory.c:113
int dir_split_resource_into_fingerprint_pairs(const char *res, smartlist_t *pairs_out)
Definition: directory.c:581
int parse_http_response(const char *headers, int *code, time_t *date, compress_method_t *compression, char **reason)
Definition: directory.c:360
static int compare_pairs_(const void **a, const void **b)
Definition: directory.c:566
char * authdir_type_to_string(dirinfo_type_t auth)
Definition: directory.c:160
int connection_dir_is_encrypted(const dir_connection_t *conn)
Definition: directory.c:180
const dir_connection_t * CONST_TO_DIR_CONN(const connection_t *c)
Definition: directory.c:101
dir_connection_t * TO_DIR_CONN(connection_t *c)
Definition: directory.c:88
int dir_split_resource_into_fingerprints(const char *resource, smartlist_t *fp_out, int *compressed_out, int flags)
Definition: directory.c:640
bool connection_dir_is_anonymous(const dir_connection_t *dir_conn)
Definition: directory.c:200
char * http_get_header(const char *headers, const char *which)
Definition: directory.c:325
int parse_http_command(const char *headers, char **command_out, char **url_out)
Definition: directory.c:271
void connection_dir_about_to_close(dir_connection_t *dir_conn)
Definition: directory.c:485
#define MAX_DIRECTORY_OBJECT_SIZE
Definition: directory.c:435
int connection_dir_process_inbuf(dir_connection_t *conn)
Definition: directory.c:443
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
#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:612
#define DOWNCAST(to, ptr)
Definition: or.h:109
dirinfo_type_t
Definition: or.h:787
@ V3_DIRINFO
Definition: or.h:790
@ BRIDGE_DIRINFO
Definition: or.h:792
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
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