tor  0.4.2.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-2019, 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"
24 #include "core/or/edge_connection_st.h"
25 #include "core/or/or_connection_st.h"
26 #include "feature/dircommon/dir_connection_st.h"
27 #include "feature/nodelist/routerinfo_st.h"
28 
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  * rend_client_refetch_renddesc() in rendclient.c
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 
86 {
87  tor_assert(c->magic == DIR_CONNECTION_MAGIC);
88  return DOWNCAST(dir_connection_t, c);
89 }
90 
97 int
98 purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose,
99  const char *resource)
100 {
101  if (get_options()->AllDirActionsPrivate)
102  return 1;
103 
104  if (router_purpose == ROUTER_PURPOSE_BRIDGE) {
105  if (dir_purpose == DIR_PURPOSE_FETCH_SERVERDESC
106  && resource && !strcmp(resource, "authority.z")) {
107  /* We are asking a bridge for its own descriptor. That doesn't need
108  anonymity. */
109  return 0;
110  }
111  /* Assume all other bridge stuff needs anonymity. */
112  return 1; /* if no circuits yet, this might break bootstrapping, but it's
113  * needed to be safe. */
114  }
115 
116  switch (dir_purpose)
117  {
128  return 0;
135  return 1;
136  case DIR_PURPOSE_SERVER:
137  default:
138  log_warn(LD_BUG, "Called with dir_purpose=%d, router_purpose=%d",
139  dir_purpose, router_purpose);
140  tor_assert_nonfatal_unreached();
141  return 1; /* Assume it needs anonymity; better safe than sorry. */
142  }
143 }
144 
147 char *
149 {
150  char *result;
151  smartlist_t *lst = smartlist_new();
152  if (auth & V3_DIRINFO)
153  smartlist_add(lst, (void*)"V3");
154  if (auth & BRIDGE_DIRINFO)
155  smartlist_add(lst, (void*)"Bridge");
156  if (smartlist_len(lst)) {
157  result = smartlist_join_strings(lst, ", ", 0, NULL);
158  } else {
159  result = tor_strdup("[Not an authority]");
160  }
161  smartlist_free(lst);
162  return result;
163 }
164 
167 int
169 {
170  /* Right now it's sufficient to see if conn is or has been linked, since
171  * the only thing it could be linked to is an edge connection on a
172  * circuit, and the only way it could have been unlinked is at the edge
173  * connection getting closed.
174  */
175  return TO_CONN(conn)->linked;
176 }
177 
187 bool
189 {
190  const connection_t *conn, *linked_conn;
191  const edge_connection_t *edge_conn;
192  const circuit_t *circ;
193 
194  tor_assert(dir_conn);
195 
196  if (!connection_dir_is_encrypted(dir_conn)) {
197  return false;
198  }
199 
200  /*
201  * Buckle up, we'll do a deep dive into the connection in order to get the
202  * final connection channel of that connection in order to figure out if
203  * this is a client or relay link.
204  *
205  * We go: dir_conn -> linked_conn -> edge_conn -> on_circuit -> p_chan.
206  */
207 
208  conn = TO_CONN(dir_conn);
209  linked_conn = conn->linked_conn;
210 
211  /* The dir connection should be connected to an edge connection. It can not
212  * be closed or marked for close. */
213  if (linked_conn == NULL || linked_conn->magic != EDGE_CONNECTION_MAGIC ||
215  log_info(LD_DIR, "Rejected HSDir request: not linked to edge");
216  return false;
217  }
218 
219  edge_conn = TO_EDGE_CONN((connection_t *) linked_conn);
220  circ = edge_conn->on_circuit;
221 
222  /* Can't be a circuit we initiated and without a circuit, no channel. */
223  if (circ == NULL || CIRCUIT_IS_ORIGIN(circ)) {
224  log_info(LD_DIR, "Rejected HSDir request: not on OR circuit");
225  return false;
226  }
227 
228  /* Get the previous channel to learn if it is a client or relay link. */
229  if (BUG(CONST_TO_OR_CIRCUIT(circ)->p_chan == NULL)) {
230  log_info(LD_DIR, "Rejected HSDir request: no p_chan");
231  return false;
232  }
233 
234  /* Will be true if the channel is an unauthenticated peer which is only true
235  * for clients and bridges. */
236  return !channel_is_client(CONST_TO_OR_CIRCUIT(circ)->p_chan);
237 }
238 
243 int
244 parse_http_command(const char *headers, char **command_out, char **url_out)
245 {
246  const char *command, *end_of_command;
247  char *s, *start, *tmp;
248 
249  s = (char *)eat_whitespace_no_nl(headers);
250  if (!*s) return -1;
251  command = s;
252  s = (char *)find_whitespace(s); /* get past GET/POST */
253  if (!*s) return -1;
254  end_of_command = s;
255  s = (char *)eat_whitespace_no_nl(s);
256  if (!*s) return -1;
257  start = s; /* this is the URL, assuming it's valid */
258  s = (char *)find_whitespace(start);
259  if (!*s) return -1;
260 
261  /* tolerate the http[s] proxy style of putting the hostname in the url */
262  if (s-start >= 4 && !strcmpstart(start,"http")) {
263  tmp = start + 4;
264  if (*tmp == 's')
265  tmp++;
266  if (s-tmp >= 3 && !strcmpstart(tmp,"://")) {
267  tmp = strchr(tmp+3, '/');
268  if (tmp && tmp < s) {
269  log_debug(LD_DIR,"Skipping over 'http[s]://hostname/' string");
270  start = tmp;
271  }
272  }
273  }
274 
275  /* Check if the header is well formed (next sequence
276  * should be HTTP/1.X\r\n). Assumes we're supporting 1.0? */
277  {
278  unsigned minor_ver;
279  char ch;
280  char *e = (char *)eat_whitespace_no_nl(s);
281  if (2 != tor_sscanf(e, "HTTP/1.%u%c", &minor_ver, &ch)) {
282  return -1;
283  }
284  if (ch != '\r')
285  return -1;
286  }
287 
288  *url_out = tor_memdup_nulterm(start, s-start);
289  *command_out = tor_memdup_nulterm(command, end_of_command - command);
290  return 0;
291 }
292 
297 char *
298 http_get_header(const char *headers, const char *which)
299 {
300  const char *cp = headers;
301  while (cp) {
302  if (!strcasecmpstart(cp, which)) {
303  char *eos;
304  cp += strlen(which);
305  if ((eos = strchr(cp,'\r')))
306  return tor_strndup(cp, eos-cp);
307  else
308  return tor_strdup(cp);
309  }
310  cp = strchr(cp, '\n');
311  if (cp)
312  ++cp;
313  }
314  return NULL;
315 }
332 int
333 parse_http_response(const char *headers, int *code, time_t *date,
334  compress_method_t *compression, char **reason)
335 {
336  unsigned n1, n2;
337  char datestr[RFC1123_TIME_LEN+1];
338  smartlist_t *parsed_headers;
339  tor_assert(headers);
340  tor_assert(code);
341 
342  while (TOR_ISSPACE(*headers)) headers++; /* tolerate leading whitespace */
343 
344  if (tor_sscanf(headers, "HTTP/1.%u %u", &n1, &n2) < 2 ||
345  (n1 != 0 && n1 != 1) ||
346  (n2 < 100 || n2 >= 600)) {
347  log_warn(LD_HTTP,"Failed to parse header %s",escaped(headers));
348  return -1;
349  }
350  *code = n2;
351 
352  parsed_headers = smartlist_new();
353  smartlist_split_string(parsed_headers, headers, "\n",
354  SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
355  if (reason) {
356  smartlist_t *status_line_elements = smartlist_new();
357  tor_assert(smartlist_len(parsed_headers));
358  smartlist_split_string(status_line_elements,
359  smartlist_get(parsed_headers, 0),
360  " ", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 3);
361  tor_assert(smartlist_len(status_line_elements) <= 3);
362  if (smartlist_len(status_line_elements) == 3) {
363  *reason = smartlist_get(status_line_elements, 2);
364  smartlist_set(status_line_elements, 2, NULL); /* Prevent free */
365  }
366  SMARTLIST_FOREACH(status_line_elements, char *, cp, tor_free(cp));
367  smartlist_free(status_line_elements);
368  }
369  if (date) {
370  *date = 0;
371  SMARTLIST_FOREACH(parsed_headers, const char *, s,
372  if (!strcmpstart(s, "Date: ")) {
373  strlcpy(datestr, s+6, sizeof(datestr));
374  /* This will do nothing on failure, so we don't need to check
375  the result. We shouldn't warn, since there are many other valid
376  date formats besides the one we use. */
377  parse_rfc1123_time(datestr, date);
378  break;
379  });
380  }
381  if (compression) {
382  const char *enc = NULL;
383  SMARTLIST_FOREACH(parsed_headers, const char *, s,
384  if (!strcmpstart(s, "Content-Encoding: ")) {
385  enc = s+18; break;
386  });
387 
388  if (enc == NULL)
389  *compression = NO_METHOD;
390  else {
391  *compression = compression_method_get_by_name(enc);
392 
393  if (*compression == UNKNOWN_METHOD)
394  log_info(LD_HTTP, "Unrecognized content encoding: %s. Trying to deal.",
395  escaped(enc));
396  }
397  }
398  SMARTLIST_FOREACH(parsed_headers, char *, s, tor_free(s));
399  smartlist_free(parsed_headers);
400 
401  return 0;
402 }
403 
408 #define MAX_DIRECTORY_OBJECT_SIZE (10*(1<<20))
409 
410 #define MAX_VOTE_DL_SIZE (MAX_DIRECTORY_OBJECT_SIZE * 5)
411 
415 int
417 {
418  size_t max_size;
419  tor_assert(conn);
420  tor_assert(conn->base_.type == CONN_TYPE_DIR);
421 
422  /* Directory clients write, then read data until they receive EOF;
423  * directory servers read data until they get an HTTP command, then
424  * write their response (when it's finished flushing, they mark for
425  * close).
426  */
427 
428  /* If we're on the dirserver side, look for a command. */
429  if (conn->base_.state == DIR_CONN_STATE_SERVER_COMMAND_WAIT) {
430  if (directory_handle_command(conn) < 0) {
431  connection_mark_for_close(TO_CONN(conn));
432  return -1;
433  }
434  return 0;
435  }
436 
437  max_size =
438  (TO_CONN(conn)->purpose == DIR_PURPOSE_FETCH_STATUS_VOTE) ?
439  MAX_VOTE_DL_SIZE : MAX_DIRECTORY_OBJECT_SIZE;
440 
441  if (connection_get_inbuf_len(TO_CONN(conn)) > max_size) {
442  log_warn(LD_HTTP,
443  "Too much data received from directory connection (%s): "
444  "denial of service attempt, or you need to upgrade?",
445  conn->base_.address);
446  connection_mark_for_close(TO_CONN(conn));
447  return -1;
448  }
449 
450  if (!conn->base_.inbuf_reached_eof)
451  log_debug(LD_HTTP,"Got data, not eof. Leaving on inbuf.");
452  return 0;
453 }
454 
457 void
459 {
460  connection_t *conn = TO_CONN(dir_conn);
461 
463  /* It's a directory connection and connecting or fetching
464  * failed: forget about this router, and maybe try again. */
466  }
467 
469 }
470 
475 int
477 {
478  tor_assert(conn);
479  tor_assert(conn->base_.type == CONN_TYPE_DIR);
480 
481  if (conn->base_.marked_for_close)
482  return 0;
483 
484  /* Note that we have finished writing the directory response. For direct
485  * connections this means we're done; for tunneled connections it's only
486  * an intermediate step. */
487  if (conn->dirreq_id)
488  geoip_change_dirreq_state(conn->dirreq_id, DIRREQ_TUNNELED,
490  else
491  geoip_change_dirreq_state(TO_CONN(conn)->global_identifier,
492  DIRREQ_DIRECT,
494  switch (conn->base_.state) {
497  log_debug(LD_DIR,"client finished sending command.");
498  conn->base_.state = DIR_CONN_STATE_CLIENT_READING;
499  return 0;
501  if (conn->spool) {
502  log_warn(LD_BUG, "Emptied a dirserv buffer, but it's still spooling!");
503  connection_mark_for_close(TO_CONN(conn));
504  } else {
505  log_debug(LD_DIRSERV, "Finished writing server response. Closing.");
506  connection_mark_for_close(TO_CONN(conn));
507  }
508  return 0;
509  default:
510  log_warn(LD_BUG,"called in unexpected state %d.",
511  conn->base_.state);
513  return -1;
514  }
515  return 0;
516 }
517 
521 int
523 {
524  tor_assert(conn);
525  tor_assert(conn->base_.type == CONN_TYPE_DIR);
527 
528  log_debug(LD_HTTP,"Dir connection to router %s:%u established.",
529  conn->base_.address,conn->base_.port);
530 
531  /* start flushing conn */
532  conn->base_.state = DIR_CONN_STATE_CLIENT_SENDING;
533  return 0;
534 }
535 
538 static int
539 compare_pairs_(const void **a, const void **b)
540 {
541  const fp_pair_t *fp1 = *a, *fp2 = *b;
542  int r;
543  if ((r = fast_memcmp(fp1->first, fp2->first, DIGEST_LEN)))
544  return r;
545  else
546  return fast_memcmp(fp1->second, fp2->second, DIGEST_LEN);
547 }
548 
553 int
555  smartlist_t *pairs_out)
556 {
557  smartlist_t *pairs_tmp = smartlist_new();
558  smartlist_t *pairs_result = smartlist_new();
559 
560  smartlist_split_string(pairs_tmp, res, "+", 0, 0);
561  if (smartlist_len(pairs_tmp)) {
562  char *last = smartlist_get(pairs_tmp,smartlist_len(pairs_tmp)-1);
563  size_t last_len = strlen(last);
564  if (last_len > 2 && !strcmp(last+last_len-2, ".z")) {
565  last[last_len-2] = '\0';
566  }
567  }
568  SMARTLIST_FOREACH_BEGIN(pairs_tmp, char *, cp) {
569  if (strlen(cp) != HEX_DIGEST_LEN*2+1) {
570  log_info(LD_DIR,
571  "Skipping digest pair %s with non-standard length.", escaped(cp));
572  } else if (cp[HEX_DIGEST_LEN] != '-') {
573  log_info(LD_DIR,
574  "Skipping digest pair %s with missing dash.", escaped(cp));
575  } else {
576  fp_pair_t pair;
577  if (base16_decode(pair.first, DIGEST_LEN,
578  cp, HEX_DIGEST_LEN) != DIGEST_LEN ||
579  base16_decode(pair.second,DIGEST_LEN,
581  log_info(LD_DIR, "Skipping non-decodable digest pair %s", escaped(cp));
582  } else {
583  smartlist_add(pairs_result, tor_memdup(&pair, sizeof(pair)));
584  }
585  }
586  tor_free(cp);
587  } SMARTLIST_FOREACH_END(cp);
588  smartlist_free(pairs_tmp);
589 
590  /* Uniq-and-sort */
591  smartlist_sort(pairs_result, compare_pairs_);
592  smartlist_uniq(pairs_result, compare_pairs_, tor_free_);
593 
594  smartlist_add_all(pairs_out, pairs_result);
595  smartlist_free(pairs_result);
596  return 0;
597 }
598 
612 int
614  smartlist_t *fp_out, int *compressed_out,
615  int flags)
616 {
617  const int decode_hex = flags & DSR_HEX;
618  const int decode_base64 = flags & DSR_BASE64;
619  const int digests_are_256 = flags & DSR_DIGEST256;
620  const int sort_uniq = flags & DSR_SORT_UNIQ;
621 
622  const int digest_len = digests_are_256 ? DIGEST256_LEN : DIGEST_LEN;
623  const int hex_digest_len = digests_are_256 ?
625  const int base64_digest_len = digests_are_256 ?
627  smartlist_t *fp_tmp = smartlist_new();
628 
629  tor_assert(!(decode_hex && decode_base64));
630  tor_assert(fp_out);
631 
632  smartlist_split_string(fp_tmp, resource, decode_base64?"-":"+", 0, 0);
633  if (compressed_out)
634  *compressed_out = 0;
635  if (smartlist_len(fp_tmp)) {
636  char *last = smartlist_get(fp_tmp,smartlist_len(fp_tmp)-1);
637  size_t last_len = strlen(last);
638  if (last_len > 2 && !strcmp(last+last_len-2, ".z")) {
639  last[last_len-2] = '\0';
640  if (compressed_out)
641  *compressed_out = 1;
642  }
643  }
644  if (decode_hex || decode_base64) {
645  const size_t encoded_len = decode_hex ? hex_digest_len : base64_digest_len;
646  int i;
647  char *cp, *d = NULL;
648  for (i = 0; i < smartlist_len(fp_tmp); ++i) {
649  cp = smartlist_get(fp_tmp, i);
650  if (strlen(cp) != encoded_len) {
651  log_info(LD_DIR,
652  "Skipping digest %s with non-standard length.", escaped(cp));
653  smartlist_del_keeporder(fp_tmp, i--);
654  goto again;
655  }
656  d = tor_malloc_zero(digest_len);
657  if (decode_hex ?
658  (base16_decode(d, digest_len, cp, hex_digest_len) != digest_len) :
659  (base64_decode(d, digest_len, cp, base64_digest_len)
660  != digest_len)) {
661  log_info(LD_DIR, "Skipping non-decodable digest %s", escaped(cp));
662  smartlist_del_keeporder(fp_tmp, i--);
663  goto again;
664  }
665  smartlist_set(fp_tmp, i, d);
666  d = NULL;
667  again:
668  tor_free(cp);
669  tor_free(d);
670  }
671  }
672  if (sort_uniq) {
673  if (decode_hex || decode_base64) {
674  if (digests_are_256) {
677  } else {
678  smartlist_sort_digests(fp_tmp);
679  smartlist_uniq_digests(fp_tmp);
680  }
681  } else {
682  smartlist_sort_strings(fp_tmp);
683  smartlist_uniq_strings(fp_tmp);
684  }
685  }
686  smartlist_add_all(fp_out, fp_tmp);
687  smartlist_free(fp_tmp);
688  return 0;
689 }
690 
694 int
696  dir_spool_source_t source,
697  smartlist_t *spool_out,
698  int *compressed_out,
699  int flags)
700 {
701  smartlist_t *fingerprints = smartlist_new();
702 
703  tor_assert(flags & (DSR_HEX|DSR_BASE64));
704  const size_t digest_len =
705  (flags & DSR_DIGEST256) ? DIGEST256_LEN : DIGEST_LEN;
706 
707  int r = dir_split_resource_into_fingerprints(resource, fingerprints,
708  compressed_out, flags);
709  /* This is not a very efficient implementation XXXX */
710  SMARTLIST_FOREACH_BEGIN(fingerprints, uint8_t *, digest) {
711  spooled_resource_t *spooled =
712  spooled_resource_new(source, digest, digest_len);
713  if (spooled)
714  smartlist_add(spool_out, spooled);
715  tor_free(digest);
716  } SMARTLIST_FOREACH_END(digest);
717 
718  smartlist_free(fingerprints);
719  return r;
720 }
Header file for dirserv.c.
#define DIR_PURPOSE_UPLOAD_HSDESC
Definition: directory.h:72
#define DIR_PURPOSE_SERVER
Definition: directory.h:62
int channel_is_client(const channel_t *chan)
Definition: channel.c:2924
int tor_sscanf(const char *buf, const char *pattern,...)
Definition: scanf.c:309
char * authdir_type_to_string(dirinfo_type_t auth)
Definition: directory.c:148
Header file for dirclient.c.
void geoip_change_dirreq_state(uint64_t dirreq_id, dirreq_type_t type, dirreq_state_t new_state)
Definition: geoip_stats.c:550
Header file for channeltls.c.
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
#define TO_CONN(c)
Definition: or.h:735
Header file for geoip_stats.c.
Header file for dircache.c.
Header file for connection.c.
#define CIRCUIT_IS_ORIGIN(c)
Definition: circuitlist.h:145
#define DOWNCAST(to, ptr)
Definition: or.h:110
int directory_handle_command(dir_connection_t *conn)
Definition: dircache.c:1752
uint8_t state
Definition: connection_st.h:44
#define DIR_PURPOSE_FETCH_STATUS_VOTE
Definition: directory.h:50
Headers for compress.c.
int dir_split_resource_into_fingerprint_pairs(const char *res, smartlist_t *pairs_out)
Definition: directory.c:554
unsigned int inbuf_reached_eof
Definition: connection_st.h:59
Header file for directory.c.
void smartlist_add(smartlist_t *sl, void *element)
int connection_dir_finished_connecting(dir_connection_t *conn)
Definition: directory.c:522
void smartlist_sort_digests256(smartlist_t *sl)
Definition: smartlist.c:846
void smartlist_uniq_digests256(smartlist_t *sl)
Definition: smartlist.c:863
smartlist_t * spool
#define MAX_DIRECTORY_OBJECT_SIZE
Definition: directory.c:408
Header file for config.c.
#define DIR_PURPOSE_UPLOAD_DIR
Definition: directory.h:43
#define HEX_DIGEST256_LEN
Definition: crypto_digest.h:37
const char * find_whitespace(const char *s)
Definition: util_string.c:344
#define DIR_CONN_STATE_CLIENT_READING
Definition: directory.h:23
struct connection_t * linked_conn
void smartlist_uniq_strings(smartlist_t *sl)
Definition: smartlist.c:574
#define LD_HTTP
Definition: log.h:74
uint16_t port
int strcmpstart(const char *s1, const char *s2)
Definition: util_string.c:206
#define tor_free(p)
Definition: malloc.h:52
#define tor_fragile_assert()
Definition: util_bug.h:241
#define DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
Definition: directory.h:53
#define DIR_PURPOSE_FETCH_CONSENSUS
Definition: directory.h:56
dirinfo_type_t
Definition: or.h:891
void smartlist_sort_strings(smartlist_t *sl)
Definition: smartlist.c:549
#define DIR_CONN_STATE_CLIENT_SENDING
Definition: directory.h:21
#define DIR_PURPOSE_UPLOAD_SIGNATURES
Definition: directory.h:47
void connection_dir_client_request_failed(dir_connection_t *conn)
Definition: dirclient.c:719
edge_connection_t * TO_EDGE_CONN(connection_t *c)
#define DIR_PURPOSE_FETCH_EXTRAINFO
Definition: directory.h:41
void smartlist_del_keeporder(smartlist_t *sl, int idx)
int connection_dir_finished_flushing(dir_connection_t *conn)
Definition: directory.c:476
void smartlist_uniq_digests(smartlist_t *sl)
Definition: smartlist.c:832
#define DIGEST256_LEN
Definition: digest_sizes.h:23
#define DIR_CONN_STATE_CLIENT_FINISHED
Definition: directory.h:25
void smartlist_uniq(smartlist_t *sl, int(*compare)(const void **a, const void **b), void(*free_fn)(void *a))
Definition: smartlist.c:390
#define DIR_PURPOSE_FETCH_SERVERDESC
Definition: directory.h:38
tor_assert(buffer)
#define DIR_PURPOSE_UPLOAD_VOTE
Definition: directory.h:45
dir_connection_t * TO_DIR_CONN(connection_t *c)
Definition: directory.c:85
#define DIGEST_LEN
Definition: digest_sizes.h:20
dir_spool_source_t
Definition: dirserv.h:20
Master header file for Tor-specific functionality.
int purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose, const char *resource)
Definition: directory.c:98
#define LD_DIRSERV
Definition: log.h:88
#define DIR_PURPOSE_FETCH_HSDESC
Definition: directory.h:74
#define DIR_PURPOSE_FETCH_CERTIFICATE
Definition: directory.h:59
uint16_t marked_for_close
bool connection_dir_is_anonymous(const dir_connection_t *dir_conn)
Definition: directory.c:188
unsigned int type
Definition: connection_st.h:45
void tor_free_(void *mem)
Definition: malloc.c:227
int parse_http_response(const char *headers, int *code, time_t *date, compress_method_t *compression, char **reason)
Definition: directory.c:333
Header file for circuitlist.c.
int connection_dir_process_inbuf(dir_connection_t *conn)
Definition: directory.c:416
#define DIR_CONN_STATE_SERVER_COMMAND_WAIT
Definition: directory.h:27
#define HEX_DIGEST_LEN
Definition: crypto_digest.h:35
#define LD_DIR
Definition: log.h:86
char * http_get_header(const char *headers, const char *which)
Definition: directory.c:298
Header file for connection_edge.c.
Header file for fp_pair.c.
char * smartlist_join_strings(smartlist_t *sl, const char *join, int terminate, size_t *len_out)
Definition: smartlist.c:279
int base64_decode(char *dest, size_t destlen, const char *src, size_t srclen)
Definition: binascii.c:396
#define SMARTLIST_FOREACH(sl, type, var, cmd)
int connection_dir_is_encrypted(const dir_connection_t *conn)
Definition: directory.c:168
const char * escaped(const char *s)
Definition: escape.c:126
#define DIR_PURPOSE_UPLOAD_RENDDESC_V2
Definition: directory.h:65
#define BASE64_DIGEST_LEN
Definition: crypto_digest.h:26
unsigned int linked_conn_is_closed
Definition: connection_st.h:81
int dir_split_resource_into_fingerprints(const char *resource, smartlist_t *fp_out, int *compressed_out, int flags)
Definition: directory.c:613
void smartlist_add_all(smartlist_t *s1, const smartlist_t *s2)
#define DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2
Definition: directory.h:35
void smartlist_sort_digests(smartlist_t *sl)
Definition: smartlist.c:824
#define DIR_PURPOSE_FETCH_MICRODESC
Definition: directory.h:70
Definition: or.h:894
int parse_rfc1123_time(const char *buf, time_t *t)
Definition: time_fmt.c:206
#define fast_memcmp(a, b, c)
Definition: di_ops.h:26
#define DIR_PURPOSE_HAS_FETCHED_HSDESC
Definition: directory.h:77
uint32_t magic
Definition: connection_st.h:41
#define BASE64_DIGEST256_LEN
Definition: crypto_digest.h:29
int dir_split_resource_into_spoolable(const char *resource, dir_spool_source_t source, smartlist_t *spool_out, int *compressed_out, int flags)
Definition: directory.c:695
static int compare_pairs_(const void **a, const void **b)
Definition: directory.c:539
compress_method_t compression_method_get_by_name(const char *name)
Definition: compress.c:403
int base16_decode(char *dest, size_t destlen, const char *src, size_t srclen)
Definition: binascii.c:506
#define CONN_TYPE_DIR
Definition: connection.h:35
Header file for connection_or.c.
struct circuit_t * on_circuit
compress_method_t
Definition: compress.h:21
void connection_dir_client_refetch_hsdesc_if_needed(dir_connection_t *dir_conn)
Definition: dirclient.c:3009
void connection_dir_about_to_close(dir_connection_t *dir_conn)
Definition: directory.c:458
#define DIR_CONN_STATE_CONNECTING
Definition: directory.h:19
int parse_http_command(const char *headers, char **command_out, char **url_out)
Definition: directory.c:244
void smartlist_sort(smartlist_t *sl, int(*compare)(const void **a, const void **b))
Definition: smartlist.c:334
int strcasecmpstart(const char *s1, const char *s2)
Definition: util_string.c:216
#define DIR_PURPOSE_FETCH_RENDDESC_V2
Definition: directory.h:68
#define DIR_CONN_STATE_SERVER_WRITING
Definition: directory.h:29
const char * eat_whitespace_no_nl(const char *s)
Definition: util_string.c:323
#define LD_BUG
Definition: log.h:84
int smartlist_split_string(smartlist_t *sl, const char *str, const char *sep, int flags, int max)