Tor  0.4.7.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"
12 #include "core/or/connection_or.h"
13 #include "core/or/channeltls.h"
20 #include "lib/compress/compress.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  **/
100 const 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 */
112 int
113 purpose_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;
148  case DIR_PURPOSE_SERVER:
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. */
159 char *
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. */
179 int
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. */
199 bool
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. */
270 int
271 parse_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. */
324 char *
325 http_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  */
359 int
360 parse_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  */
442 int
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 */
484 void
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  */
502 int
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.");
525  conn->base_.state = DIR_CONN_STATE_CLIENT_READING;
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. */
548 int
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 */
559  conn->base_.state = DIR_CONN_STATE_CLIENT_SENDING;
560  return 0;
561 }
562 
563 /** Helper. Compare two fp_pair_t objects, and return negative, 0, or
564  * positive as appropriate. */
565 static int
566 compare_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. */
580 int
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_);
619  smartlist_uniq(pairs_result, compare_pairs_, tor_free_);
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  */
639 int
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 {
705  smartlist_sort_digests(fp_tmp);
706  smartlist_uniq_digests(fp_tmp);
707  }
708  } else {
709  smartlist_sort_strings(fp_tmp);
710  smartlist_uniq_strings(fp_tmp);
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:2893
Header file for channeltls.c.
Base circuit structure.
Header file for circuitlist.c.
#define CIRCUIT_IS_ORIGIN(c)
Definition: circuitlist.h:147
compress_method_t compression_method_get_by_name(const char *name)
Definition: compress.c:403
Headers for compress.c.
compress_method_t
Definition: compress.h:21
const or_options_t * get_options(void)
Definition: config.c:919
tor_cmdline_mode_t command
Definition: config.c:2440
Header file for config.c.
const char * connection_describe(const connection_t *conn)
Definition: connection.c:543
const char * connection_describe_peer(const connection_t *conn)
Definition: connection.c:528
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:1724
Header file for dircache.c.
void connection_dir_client_request_failed(dir_connection_t *conn)
Definition: dirclient.c:704
void connection_dir_client_refetch_hsdesc_if_needed(dir_connection_t *dir_conn)
Definition: dirclient.c:2831
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
dir_connection_t * TO_DIR_CONN(connection_t *c)
Definition: directory.c:88
char * authdir_type_to_string(dirinfo_type_t auth)
Definition: directory.c:160
int dir_split_resource_into_fingerprint_pairs(const char *res, smartlist_t *pairs_out)
Definition: directory.c:581
const dir_connection_t * CONST_TO_DIR_CONN(const connection_t *c)
Definition: directory.c:101
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
int connection_dir_is_encrypted(const dir_connection_t *conn)
Definition: directory.c:180
char * http_get_header(const char *headers, const char *which)
Definition: directory.c:325
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
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:52
Master header file for Tor-specific functionality.
#define TO_CONN(c)
Definition: or.h:616
#define DOWNCAST(to, ptr)
Definition: or.h:109
dirinfo_type_t
Definition: or.h:785
@ V3_DIRINFO
Definition: or.h:788
@ BRIDGE_DIRINFO
Definition: or.h:790
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:189
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:206
#define tor_assert_nonfatal_unreached()
Definition: util_bug.h:176
#define tor_assert(expr)
Definition: util_bug.h:102
#define tor_fragile_assert()
Definition: util_bug.h:270
int strcasecmpstart(const char *s1, const char *s2)
Definition: util_string.c:225
int strcmpstart(const char *s1, const char *s2)
Definition: util_string.c:215
const char * find_whitespace(const char *s)
Definition: util_string.c:353
const char * eat_whitespace_no_nl(const char *s)
Definition: util_string.c:332