Tor  0.4.6.0-alpha-dev
control_getinfo.c
Go to the documentation of this file.
1 /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
2  * Copyright (c) 2007-2020, The Tor Project, Inc. */
3 /* See LICENSE for licensing information */
4 
5 /**
6  * \file control_getinfo.c
7  * \brief Implementation for miscellaneous controller getinfo commands.
8  */
9 
10 #define CONTROL_EVENTS_PRIVATE
11 #define CONTROL_MODULE_PRIVATE
12 #define CONTROL_GETINFO_PRIVATE
13 
14 #include "core/or/or.h"
15 #include "app/config/config.h"
17 #include "core/mainloop/mainloop.h"
18 #include "core/or/circuitlist.h"
20 #include "core/or/connection_or.h"
21 #include "core/or/policies.h"
22 #include "core/or/versions.h"
24 #include "feature/client/bridges.h"
30 #include "feature/control/control_getinfo.h"
38 #include "feature/hs/hs_cache.h"
47 #include "feature/relay/router.h"
49 #include "feature/relay/selftest.h"
50 #include "feature/rend/rendcache.h"
53 #include "feature/stats/rephist.h"
54 #include "lib/version/torversion.h"
55 #include "lib/encoding/kvline.h"
56 
70 
71 #ifdef HAVE_UNISTD_H
72 #include <unistd.h>
73 #endif
74 
75 #ifndef _WIN32
76 #include <pwd.h>
77 #endif
78 
79 static char *list_getinfo_options(void);
80 static char *download_status_to_string(const download_status_t *dl);
81 
82 /** Implementation helper for GETINFO: knows the answers for various
83  * trivial-to-implement questions. */
84 static int
85 getinfo_helper_misc(control_connection_t *conn, const char *question,
86  char **answer, const char **errmsg)
87 {
88  (void) conn;
89  if (!strcmp(question, "version")) {
90  *answer = tor_strdup(get_version());
91  } else if (!strcmp(question, "bw-event-cache")) {
92  *answer = get_bw_samples();
93  } else if (!strcmp(question, "config-file")) {
94  const char *a = get_torrc_fname(0);
95  if (a)
96  *answer = tor_strdup(a);
97  } else if (!strcmp(question, "config-defaults-file")) {
98  const char *a = get_torrc_fname(1);
99  if (a)
100  *answer = tor_strdup(a);
101  } else if (!strcmp(question, "config-text")) {
102  *answer = options_dump(get_options(), OPTIONS_DUMP_MINIMAL);
103  } else if (!strcmp(question, "config-can-saveconf")) {
104  *answer = tor_strdup(get_options()->IncludeUsed ? "0" : "1");
105  } else if (!strcmp(question, "info/names")) {
106  *answer = list_getinfo_options();
107  } else if (!strcmp(question, "dormant")) {
108  int dormant = rep_hist_circbuilding_dormant(time(NULL));
109  *answer = tor_strdup(dormant ? "1" : "0");
110  } else if (!strcmp(question, "events/names")) {
111  int i;
112  smartlist_t *event_names = smartlist_new();
113 
114  for (i = 0; control_event_table[i].event_name != NULL; ++i) {
115  smartlist_add(event_names, (char *)control_event_table[i].event_name);
116  }
117 
118  *answer = smartlist_join_strings(event_names, " ", 0, NULL);
119 
120  smartlist_free(event_names);
121  } else if (!strcmp(question, "signal/names")) {
122  smartlist_t *signal_names = smartlist_new();
123  int j;
124  for (j = 0; signal_table[j].signal_name != NULL; ++j) {
125  smartlist_add(signal_names, (char*)signal_table[j].signal_name);
126  }
127 
128  *answer = smartlist_join_strings(signal_names, " ", 0, NULL);
129 
130  smartlist_free(signal_names);
131  } else if (!strcmp(question, "features/names")) {
132  *answer = tor_strdup("VERBOSE_NAMES EXTENDED_EVENTS");
133  } else if (!strcmp(question, "address") || !strcmp(question, "address/v4")) {
134  tor_addr_t addr;
135  if (!relay_find_addr_to_publish(get_options(), AF_INET,
136  RELAY_FIND_ADDR_CACHE_ONLY, &addr)) {
137  *errmsg = "Address unknown";
138  return -1;
139  }
140  *answer = tor_addr_to_str_dup(&addr);
141  tor_assert_nonfatal(*answer);
142  } else if (!strcmp(question, "address/v6")) {
143  tor_addr_t addr;
144  if (!relay_find_addr_to_publish(get_options(), AF_INET6,
145  RELAY_FIND_ADDR_CACHE_ONLY, &addr)) {
146  *errmsg = "Address unknown";
147  return -1;
148  }
149  *answer = tor_addr_to_str_dup(&addr);
150  tor_assert_nonfatal(*answer);
151  } else if (!strcmp(question, "traffic/read")) {
152  tor_asprintf(answer, "%"PRIu64, (get_bytes_read()));
153  } else if (!strcmp(question, "traffic/written")) {
154  tor_asprintf(answer, "%"PRIu64, (get_bytes_written()));
155  } else if (!strcmp(question, "uptime")) {
156  long uptime_secs = get_uptime();
157  tor_asprintf(answer, "%ld", uptime_secs);
158  } else if (!strcmp(question, "process/pid")) {
159  int myPid = -1;
160 
161 #ifdef _WIN32
162  myPid = _getpid();
163 #else
164  myPid = getpid();
165 #endif
166 
167  tor_asprintf(answer, "%d", myPid);
168  } else if (!strcmp(question, "process/uid")) {
169 #ifdef _WIN32
170  *answer = tor_strdup("-1");
171 #else
172  int myUid = geteuid();
173  tor_asprintf(answer, "%d", myUid);
174 #endif /* defined(_WIN32) */
175  } else if (!strcmp(question, "process/user")) {
176 #ifdef _WIN32
177  *answer = tor_strdup("");
178 #else
179  int myUid = geteuid();
180  const struct passwd *myPwEntry = tor_getpwuid(myUid);
181 
182  if (myPwEntry) {
183  *answer = tor_strdup(myPwEntry->pw_name);
184  } else {
185  *answer = tor_strdup("");
186  }
187 #endif /* defined(_WIN32) */
188  } else if (!strcmp(question, "process/descriptor-limit")) {
189  int max_fds = get_max_sockets();
190  tor_asprintf(answer, "%d", max_fds);
191  } else if (!strcmp(question, "limits/max-mem-in-queues")) {
192  tor_asprintf(answer, "%"PRIu64,
193  (get_options()->MaxMemInQueues));
194  } else if (!strcmp(question, "fingerprint")) {
195  crypto_pk_t *server_key;
196  if (!server_mode(get_options())) {
197  *errmsg = "Not running in server mode";
198  return -1;
199  }
200  server_key = get_server_identity_key();
201  *answer = tor_malloc(HEX_DIGEST_LEN+1);
202  crypto_pk_get_fingerprint(server_key, *answer, 0);
203  }
204  return 0;
205 }
206 
207 /** Awful hack: return a newly allocated string based on a routerinfo and
208  * (possibly) an extrainfo, sticking the read-history and write-history from
209  * <b>ei</b> into the resulting string. The thing you get back won't
210  * necessarily have a valid signature.
211  *
212  * New code should never use this; it's for backward compatibility.
213  *
214  * NOTE: <b>ri_body</b> is as returned by signed_descriptor_get_body: it might
215  * not be NUL-terminated. */
216 static char *
218  const signed_descriptor_t *ri,
219  const signed_descriptor_t *ei)
220 {
221  char *out = NULL, *outp;
222  int i;
223  const char *router_sig;
224  const char *ei_body = signed_descriptor_get_body(ei);
225  size_t ri_len = ri->signed_descriptor_len;
226  size_t ei_len = ei->signed_descriptor_len;
227  if (!ei_body)
228  goto bail;
229 
230  outp = out = tor_malloc(ri_len+ei_len+1);
231  if (!(router_sig = tor_memstr(ri_body, ri_len, "\nrouter-signature")))
232  goto bail;
233  ++router_sig;
234  memcpy(out, ri_body, router_sig-ri_body);
235  outp += router_sig-ri_body;
236 
237  for (i=0; i < 2; ++i) {
238  const char *kwd = i ? "\nwrite-history " : "\nread-history ";
239  const char *cp, *eol;
240  if (!(cp = tor_memstr(ei_body, ei_len, kwd)))
241  continue;
242  ++cp;
243  if (!(eol = memchr(cp, '\n', ei_len - (cp-ei_body))))
244  continue;
245  memcpy(outp, cp, eol-cp+1);
246  outp += eol-cp+1;
247  }
248  memcpy(outp, router_sig, ri_len - (router_sig-ri_body));
249  *outp++ = '\0';
250  tor_assert(outp-out < (int)(ri_len+ei_len+1));
251 
252  return out;
253  bail:
254  tor_free(out);
255  return tor_strndup(ri_body, ri->signed_descriptor_len);
256 }
257 
258 /** Implementation helper for GETINFO: answers requests for information about
259  * which ports are bound. */
260 static int
262  const char *question,
263  char **answer, const char **errmsg)
264 {
265  int type;
266  smartlist_t *res;
267 
268  (void)control_conn;
269  (void)errmsg;
270 
271  if (!strcmp(question, "net/listeners/or"))
272  type = CONN_TYPE_OR_LISTENER;
273  else if (!strcmp(question, "net/listeners/extor"))
275  else if (!strcmp(question, "net/listeners/dir"))
276  type = CONN_TYPE_DIR_LISTENER;
277  else if (!strcmp(question, "net/listeners/socks"))
278  type = CONN_TYPE_AP_LISTENER;
279  else if (!strcmp(question, "net/listeners/trans"))
281  else if (!strcmp(question, "net/listeners/natd"))
283  else if (!strcmp(question, "net/listeners/httptunnel"))
285  else if (!strcmp(question, "net/listeners/dns"))
287  else if (!strcmp(question, "net/listeners/control"))
289  else if (!strcmp(question, "net/listeners/metrics"))
291  else
292  return 0; /* unknown key */
293 
294  res = smartlist_new();
296  struct sockaddr_storage ss;
297  socklen_t ss_len = sizeof(ss);
298 
299  if (conn->type != type || conn->marked_for_close || !SOCKET_OK(conn->s))
300  continue;
301 
302  if (getsockname(conn->s, (struct sockaddr *)&ss, &ss_len) < 0) {
303  smartlist_add_asprintf(res, "%s:%d", conn->address, (int)conn->port);
304  } else {
305  char *tmp = tor_sockaddr_to_str((struct sockaddr *)&ss);
306  smartlist_add(res, esc_for_log(tmp));
307  tor_free(tmp);
308  }
309 
310  } SMARTLIST_FOREACH_END(conn);
311 
312  *answer = smartlist_join_strings(res, " ", 0, NULL);
313 
314  SMARTLIST_FOREACH(res, char *, cp, tor_free(cp));
315  smartlist_free(res);
316  return 0;
317 }
318 
319 /** Implementation helper for GETINFO: answers requests for information about
320  * the current time in both local and UTC forms. */
321 STATIC int
323  const char *question,
324  char **answer, const char **errmsg)
325 {
326  (void)control_conn;
327  (void)errmsg;
328 
329  struct timeval now;
330  tor_gettimeofday(&now);
331  char timebuf[ISO_TIME_LEN+1];
332 
333  if (!strcmp(question, "current-time/local"))
334  format_local_iso_time_nospace(timebuf, (time_t)now.tv_sec);
335  else if (!strcmp(question, "current-time/utc"))
336  format_iso_time_nospace(timebuf, (time_t)now.tv_sec);
337  else
338  return 0;
339 
340  *answer = tor_strdup(timebuf);
341  return 0;
342 }
343 
344 /** GETINFO helper for dumping different consensus flavors
345  * returns: 0 on success -1 on error. */
346 STATIC int
348  char** answer,
349  const char** errmsg)
350 {
351  const char *flavor_name = networkstatus_get_flavor_name(flavor);
352  if (BUG(!strcmp(flavor_name, "??"))) {
353  *errmsg = "Internal error: unrecognized flavor name.";
354  return -1;
355  }
356  if (we_want_to_fetch_flavor(get_options(), flavor)) {
357  /** Check from the cache */
358  const cached_dir_t *consensus = dirserv_get_consensus(flavor_name);
359  if (consensus) {
360  *answer = tor_strdup(consensus->dir);
361  }
362  }
363  if (!*answer) { /* try loading it from disk */
364 
365  tor_mmap_t *mapped = networkstatus_map_cached_consensus(flavor_name);
366  if (mapped) {
367  *answer = tor_memdup_nulterm(mapped->data, mapped->size);
368  tor_munmap_file(mapped);
369  }
370  if (!*answer) { /* generate an error */
371  *errmsg = "Could not open cached consensus. "
372  "Make sure FetchUselessDescriptors is set to 1.";
373  return -1;
374  }
375  }
376  return 0;
377 }
378 
379 /** Helper for getinfo_helper_dir.
380  *
381  * Add a signed_descriptor_t to <b>descs_out</b> for each router matching
382  * <b>key</b>. The key should be either
383  * - "/tor/server/authority" for our own routerinfo;
384  * - "/tor/server/all" for all the routerinfos we have, concatenated;
385  * - "/tor/server/fp/FP" where FP is a plus-separated sequence of
386  * hex identity digests; or
387  * - "/tor/server/d/D" where D is a plus-separated sequence
388  * of server descriptor digests, in hex.
389  *
390  * Return 0 if we found some matching descriptors, or -1 if we do not
391  * have any descriptors, no matching descriptors, or if we did not
392  * recognize the key (URL).
393  * If -1 is returned *<b>msg</b> will be set to an appropriate error
394  * message.
395  */
396 static int
397 controller_get_routerdescs(smartlist_t *descs_out, const char *key,
398  const char **msg)
399 {
400  *msg = NULL;
401 
402  if (!strcmp(key, "/tor/server/all")) {
405  smartlist_add(descs_out, &(r->cache_info)));
406  } else if (!strcmp(key, "/tor/server/authority")) {
408  if (ri)
409  smartlist_add(descs_out, (void*) &(ri->cache_info));
410  } else if (!strcmpstart(key, "/tor/server/d/")) {
411  smartlist_t *digests = smartlist_new();
412  key += strlen("/tor/server/d/");
413  dir_split_resource_into_fingerprints(key, digests, NULL,
414  DSR_HEX|DSR_SORT_UNIQ);
415  SMARTLIST_FOREACH(digests, const char *, d,
416  {
418  if (sd)
419  smartlist_add(descs_out,sd);
420  });
421  SMARTLIST_FOREACH(digests, char *, d, tor_free(d));
422  smartlist_free(digests);
423  } else if (!strcmpstart(key, "/tor/server/fp/")) {
424  smartlist_t *digests = smartlist_new();
425  time_t cutoff = time(NULL) - ROUTER_MAX_AGE_TO_PUBLISH;
426  key += strlen("/tor/server/fp/");
427  dir_split_resource_into_fingerprints(key, digests, NULL,
428  DSR_HEX|DSR_SORT_UNIQ);
429  SMARTLIST_FOREACH_BEGIN(digests, const char *, d) {
430  if (router_digest_is_me(d)) {
431  /* calling router_get_my_routerinfo() to make sure it exists */
433  if (ri)
434  smartlist_add(descs_out, (void*) &(ri->cache_info));
435  } else {
436  const routerinfo_t *ri = router_get_by_id_digest(d);
437  /* Don't actually serve a descriptor that everyone will think is
438  * expired. This is an (ugly) workaround to keep buggy 0.1.1.10
439  * Tors from downloading descriptors that they will throw away.
440  */
441  if (ri && ri->cache_info.published_on > cutoff)
442  smartlist_add(descs_out, (void*) &(ri->cache_info));
443  }
444  } SMARTLIST_FOREACH_END(d);
445  SMARTLIST_FOREACH(digests, char *, d, tor_free(d));
446  smartlist_free(digests);
447  } else {
448  *msg = "Key not recognized";
449  return -1;
450  }
451 
452  if (!smartlist_len(descs_out)) {
453  *msg = "Servers unavailable";
454  return -1;
455  }
456  return 0;
457 }
458 
459 /** Implementation helper for GETINFO: knows the answers for questions about
460  * directory information. */
461 STATIC int
463  const char *question, char **answer,
464  const char **errmsg)
465 {
466  (void) control_conn;
467  if (!strcmpstart(question, "desc/id/")) {
468  const routerinfo_t *ri = NULL;
469  const node_t *node = node_get_by_hex_id(question+strlen("desc/id/"), 0);
470  if (node)
471  ri = node->ri;
472  if (ri) {
473  const char *body = signed_descriptor_get_body(&ri->cache_info);
474  if (body)
475  *answer = tor_strndup(body, ri->cache_info.signed_descriptor_len);
476  } else if (! we_fetch_router_descriptors(get_options())) {
477  /* Descriptors won't be available, provide proper error */
478  *errmsg = "We fetch microdescriptors, not router "
479  "descriptors. You'll need to use md/id/* "
480  "instead of desc/id/*.";
481  return 0;
482  }
483  } else if (!strcmpstart(question, "desc/name/")) {
484  const routerinfo_t *ri = NULL;
485  /* XXX Setting 'warn_if_unnamed' here is a bit silly -- the
486  * warning goes to the user, not to the controller. */
487  const node_t *node =
488  node_get_by_nickname(question+strlen("desc/name/"), 0);
489  if (node)
490  ri = node->ri;
491  if (ri) {
492  const char *body = signed_descriptor_get_body(&ri->cache_info);
493  if (body)
494  *answer = tor_strndup(body, ri->cache_info.signed_descriptor_len);
495  } else if (! we_fetch_router_descriptors(get_options())) {
496  /* Descriptors won't be available, provide proper error */
497  *errmsg = "We fetch microdescriptors, not router "
498  "descriptors. You'll need to use md/name/* "
499  "instead of desc/name/*.";
500  return 0;
501  }
502  } else if (!strcmp(question, "desc/download-enabled")) {
504  tor_asprintf(answer, "%d", !!r);
505  } else if (!strcmp(question, "desc/all-recent")) {
507  smartlist_t *sl = smartlist_new();
508  if (routerlist && routerlist->routers) {
510  {
511  const char *body = signed_descriptor_get_body(&ri->cache_info);
512  if (body)
513  smartlist_add(sl,
514  tor_strndup(body, ri->cache_info.signed_descriptor_len));
515  });
516  }
517  *answer = smartlist_join_strings(sl, "", 0, NULL);
518  SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
519  smartlist_free(sl);
520  } else if (!strcmp(question, "desc/all-recent-extrainfo-hack")) {
521  /* XXXX Remove this once Torstat asks for extrainfos. */
523  smartlist_t *sl = smartlist_new();
524  if (routerlist && routerlist->routers) {
526  const char *body = signed_descriptor_get_body(&ri->cache_info);
528  ri->cache_info.extra_info_digest);
529  if (ei && body) {
531  &ri->cache_info, ei));
532  } else if (body) {
533  smartlist_add(sl,
534  tor_strndup(body, ri->cache_info.signed_descriptor_len));
535  }
536  } SMARTLIST_FOREACH_END(ri);
537  }
538  *answer = smartlist_join_strings(sl, "", 0, NULL);
539  SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
540  smartlist_free(sl);
541  } else if (!strcmpstart(question, "hs/client/desc/id/")) {
542  hostname_type_t addr_type;
543 
544  question += strlen("hs/client/desc/id/");
545  if (rend_valid_v2_service_id(question)) {
546  addr_type = ONION_V2_HOSTNAME;
547  } else if (hs_address_is_valid(question)) {
548  addr_type = ONION_V3_HOSTNAME;
549  } else {
550  *errmsg = "Invalid address";
551  return -1;
552  }
553 
554  if (addr_type == ONION_V2_HOSTNAME) {
555  rend_cache_entry_t *e = NULL;
556  if (!rend_cache_lookup_entry(question, -1, &e)) {
557  /* Descriptor found in cache */
558  *answer = tor_strdup(e->desc);
559  } else {
560  *errmsg = "Not found in cache";
561  return -1;
562  }
563  } else {
564  ed25519_public_key_t service_pk;
565  const char *desc;
566 
567  /* The check before this if/else makes sure of this. */
568  tor_assert(addr_type == ONION_V3_HOSTNAME);
569 
570  if (hs_parse_address(question, &service_pk, NULL, NULL) < 0) {
571  *errmsg = "Invalid v3 address";
572  return -1;
573  }
574 
575  desc = hs_cache_lookup_encoded_as_client(&service_pk);
576  if (desc) {
577  *answer = tor_strdup(desc);
578  } else {
579  *errmsg = "Not found in cache";
580  return -1;
581  }
582  }
583  } else if (!strcmpstart(question, "hs/service/desc/id/")) {
584  hostname_type_t addr_type;
585 
586  question += strlen("hs/service/desc/id/");
587  if (rend_valid_v2_service_id(question)) {
588  addr_type = ONION_V2_HOSTNAME;
589  } else if (hs_address_is_valid(question)) {
590  addr_type = ONION_V3_HOSTNAME;
591  } else {
592  *errmsg = "Invalid address";
593  return -1;
594  }
595  rend_cache_entry_t *e = NULL;
596 
597  if (addr_type == ONION_V2_HOSTNAME) {
598  if (!rend_cache_lookup_v2_desc_as_service(question, &e)) {
599  /* Descriptor found in cache */
600  *answer = tor_strdup(e->desc);
601  } else {
602  *errmsg = "Not found in cache";
603  return -1;
604  }
605  } else {
606  ed25519_public_key_t service_pk;
607  char *desc;
608 
609  /* The check before this if/else makes sure of this. */
610  tor_assert(addr_type == ONION_V3_HOSTNAME);
611 
612  if (hs_parse_address(question, &service_pk, NULL, NULL) < 0) {
613  *errmsg = "Invalid v3 address";
614  return -1;
615  }
616 
617  desc = hs_service_lookup_current_desc(&service_pk);
618  if (desc) {
619  /* Newly allocated string, we have ownership. */
620  *answer = desc;
621  } else {
622  *errmsg = "Not found in cache";
623  return -1;
624  }
625  }
626  } else if (!strcmp(question, "md/all")) {
627  const smartlist_t *nodes = nodelist_get_list();
628  tor_assert(nodes);
629 
630  if (smartlist_len(nodes) == 0) {
631  *answer = tor_strdup("");
632  return 0;
633  }
634 
635  smartlist_t *microdescs = smartlist_new();
636 
637  SMARTLIST_FOREACH_BEGIN(nodes, node_t *, n) {
638  if (n->md && n->md->body) {
639  char *copy = tor_strndup(n->md->body, n->md->bodylen);
640  smartlist_add(microdescs, copy);
641  }
642  } SMARTLIST_FOREACH_END(n);
643 
644  *answer = smartlist_join_strings(microdescs, "", 0, NULL);
645  SMARTLIST_FOREACH(microdescs, char *, md, tor_free(md));
646  smartlist_free(microdescs);
647  } else if (!strcmpstart(question, "md/id/")) {
648  const node_t *node = node_get_by_hex_id(question+strlen("md/id/"), 0);
649  const microdesc_t *md = NULL;
650  if (node) md = node->md;
651  if (md && md->body) {
652  *answer = tor_strndup(md->body, md->bodylen);
653  }
654  } else if (!strcmpstart(question, "md/name/")) {
655  /* XXX Setting 'warn_if_unnamed' here is a bit silly -- the
656  * warning goes to the user, not to the controller. */
657  const node_t *node = node_get_by_nickname(question+strlen("md/name/"), 0);
658  /* XXXX duplicated code */
659  const microdesc_t *md = NULL;
660  if (node) md = node->md;
661  if (md && md->body) {
662  *answer = tor_strndup(md->body, md->bodylen);
663  }
664  } else if (!strcmp(question, "md/download-enabled")) {
666  tor_asprintf(answer, "%d", !!r);
667  } else if (!strcmpstart(question, "desc-annotations/id/")) {
668  const routerinfo_t *ri = NULL;
669  const node_t *node =
670  node_get_by_hex_id(question+strlen("desc-annotations/id/"), 0);
671  if (node)
672  ri = node->ri;
673  if (ri) {
674  const char *annotations =
675  signed_descriptor_get_annotations(&ri->cache_info);
676  if (annotations)
677  *answer = tor_strndup(annotations,
678  ri->cache_info.annotations_len);
679  }
680  } else if (!strcmpstart(question, "dir/server/")) {
681  size_t answer_len = 0;
682  char *url = NULL;
683  smartlist_t *descs = smartlist_new();
684  const char *msg;
685  int res;
686  char *cp;
687  tor_asprintf(&url, "/tor/%s", question+4);
688  res = controller_get_routerdescs(descs, url, &msg);
689  if (res) {
690  log_warn(LD_CONTROL, "getinfo '%s': %s", question, msg);
691  smartlist_free(descs);
692  tor_free(url);
693  *errmsg = msg;
694  return -1;
695  }
697  answer_len += sd->signed_descriptor_len);
698  cp = *answer = tor_malloc(answer_len+1);
700  {
701  memcpy(cp, signed_descriptor_get_body(sd),
702  sd->signed_descriptor_len);
703  cp += sd->signed_descriptor_len;
704  });
705  *cp = '\0';
706  tor_free(url);
707  smartlist_free(descs);
708  } else if (!strcmpstart(question, "dir/status/")) {
709  *answer = tor_strdup("");
710  } else if (!strcmp(question, "dir/status-vote/current/consensus")) {
711  int consensus_result = getinfo_helper_current_consensus(FLAV_NS,
712  answer, errmsg);
713  if (consensus_result < 0) {
714  return -1;
715  }
716  } else if (!strcmp(question,
717  "dir/status-vote/current/consensus-microdesc")) {
718  int consensus_result = getinfo_helper_current_consensus(FLAV_MICRODESC,
719  answer, errmsg);
720  if (consensus_result < 0) {
721  return -1;
722  }
723  } else if (!strcmpstart(question, "extra-info/digest/")) {
724  question += strlen("extra-info/digest/");
725  if (strlen(question) == HEX_DIGEST_LEN) {
726  char d[DIGEST_LEN];
727  signed_descriptor_t *sd = NULL;
728  if (base16_decode(d, sizeof(d), question, strlen(question))
729  == sizeof(d)) {
730  /* XXXX this test should move into extrainfo_get_by_descriptor_digest,
731  * but I don't want to risk affecting other parts of the code,
732  * especially since the rules for using our own extrainfo (including
733  * when it might be freed) are different from those for using one
734  * we have downloaded. */
736  sd = &(router_get_my_extrainfo()->cache_info);
737  else
739  }
740  if (sd) {
741  const char *body = signed_descriptor_get_body(sd);
742  if (body)
743  *answer = tor_strndup(body, sd->signed_descriptor_len);
744  }
745  }
746  }
747 
748  return 0;
749 }
750 
751 /** Given a smartlist of 20-byte digests, return a newly allocated string
752  * containing each of those digests in order, formatted in HEX, and terminated
753  * with a newline. */
754 static char *
756 {
757  int len;
758  char *result, *s;
759 
760  /* Allow for newlines, and a \0 at the end */
761  len = smartlist_len(sl) * (HEX_DIGEST_LEN + 1) + 1;
762  result = tor_malloc_zero(len);
763 
764  s = result;
765  SMARTLIST_FOREACH_BEGIN(sl, const char *, digest) {
766  base16_encode(s, HEX_DIGEST_LEN + 1, digest, DIGEST_LEN);
767  s[HEX_DIGEST_LEN] = '\n';
768  s += HEX_DIGEST_LEN + 1;
769  } SMARTLIST_FOREACH_END(digest);
770  *s = '\0';
771 
772  return result;
773 }
774 
775 /** Turn a download_status_t into a human-readable description in a newly
776  * allocated string. The format is specified in control-spec.txt, under
777  * the documentation for "GETINFO download/..." . */
778 static char *
780 {
781  char *rv = NULL;
782  char tbuf[ISO_TIME_LEN+1];
783  const char *schedule_str, *want_authority_str;
784  const char *increment_on_str, *backoff_str;
785 
786  if (dl) {
787  /* Get some substrings of the eventual output ready */
789 
790  switch (dl->schedule) {
791  case DL_SCHED_GENERIC:
792  schedule_str = "DL_SCHED_GENERIC";
793  break;
794  case DL_SCHED_CONSENSUS:
795  schedule_str = "DL_SCHED_CONSENSUS";
796  break;
797  case DL_SCHED_BRIDGE:
798  schedule_str = "DL_SCHED_BRIDGE";
799  break;
800  default:
801  schedule_str = "unknown";
802  break;
803  }
804 
805  switch (dl->want_authority) {
806  case DL_WANT_ANY_DIRSERVER:
807  want_authority_str = "DL_WANT_ANY_DIRSERVER";
808  break;
809  case DL_WANT_AUTHORITY:
810  want_authority_str = "DL_WANT_AUTHORITY";
811  break;
812  default:
813  want_authority_str = "unknown";
814  break;
815  }
816 
817  switch (dl->increment_on) {
818  case DL_SCHED_INCREMENT_FAILURE:
819  increment_on_str = "DL_SCHED_INCREMENT_FAILURE";
820  break;
821  case DL_SCHED_INCREMENT_ATTEMPT:
822  increment_on_str = "DL_SCHED_INCREMENT_ATTEMPT";
823  break;
824  default:
825  increment_on_str = "unknown";
826  break;
827  }
828 
829  backoff_str = "DL_SCHED_RANDOM_EXPONENTIAL";
830 
831  /* Now assemble them */
832  tor_asprintf(&rv,
833  "next-attempt-at %s\n"
834  "n-download-failures %u\n"
835  "n-download-attempts %u\n"
836  "schedule %s\n"
837  "want-authority %s\n"
838  "increment-on %s\n"
839  "backoff %s\n"
840  "last-backoff-position %u\n"
841  "last-delay-used %d\n",
842  tbuf,
845  schedule_str,
846  want_authority_str,
847  increment_on_str,
848  backoff_str,
850  dl->last_delay_used);
851  }
852 
853  return rv;
854 }
855 
856 /** Handle the consensus download cases for getinfo_helper_downloads() */
857 STATIC void
859  download_status_t **dl_to_emit,
860  const char **errmsg)
861 {
862  /*
863  * We get the one for the current bootstrapped status by default, or
864  * take an extra /bootstrap or /running suffix
865  */
866  if (strcmp(flavor, "ns") == 0) {
867  *dl_to_emit = networkstatus_get_dl_status_by_flavor(FLAV_NS);
868  } else if (strcmp(flavor, "ns/bootstrap") == 0) {
870  } else if (strcmp(flavor, "ns/running") == 0 ) {
871  *dl_to_emit = networkstatus_get_dl_status_by_flavor_running(FLAV_NS);
872  } else if (strcmp(flavor, "microdesc") == 0) {
873  *dl_to_emit = networkstatus_get_dl_status_by_flavor(FLAV_MICRODESC);
874  } else if (strcmp(flavor, "microdesc/bootstrap") == 0) {
875  *dl_to_emit =
877  } else if (strcmp(flavor, "microdesc/running") == 0) {
878  *dl_to_emit =
880  } else {
881  *errmsg = "Unknown flavor";
882  }
883 }
884 
885 /** Handle the cert download cases for getinfo_helper_downloads() */
886 STATIC void
887 getinfo_helper_downloads_cert(const char *fp_sk_req,
888  download_status_t **dl_to_emit,
889  smartlist_t **digest_list,
890  const char **errmsg)
891 {
892  const char *sk_req;
893  char id_digest[DIGEST_LEN];
894  char sk_digest[DIGEST_LEN];
895 
896  /*
897  * We have to handle four cases; fp_sk_req is the request with
898  * a prefix of "downloads/cert/" snipped off.
899  *
900  * Case 1: fp_sk_req = "fps"
901  * - We should emit a digest_list with a list of all the identity
902  * fingerprints that can be queried for certificate download status;
903  * get it by calling list_authority_ids_with_downloads().
904  *
905  * Case 2: fp_sk_req = "fp/<fp>" for some fingerprint fp
906  * - We want the default certificate for this identity fingerprint's
907  * download status; this is the download we get from URLs starting
908  * in /fp/ on the directory server. We can get it with
909  * id_only_download_status_for_authority_id().
910  *
911  * Case 3: fp_sk_req = "fp/<fp>/sks" for some fingerprint fp
912  * - We want a list of all signing key digests for this identity
913  * fingerprint which can be queried for certificate download status.
914  * Get it with list_sk_digests_for_authority_id().
915  *
916  * Case 4: fp_sk_req = "fp/<fp>/<sk>" for some fingerprint fp and
917  * signing key digest sk
918  * - We want the download status for the certificate for this specific
919  * signing key and fingerprint. These correspond to the ones we get
920  * from URLs starting in /fp-sk/ on the directory server. Get it with
921  * list_sk_digests_for_authority_id().
922  */
923 
924  if (strcmp(fp_sk_req, "fps") == 0) {
925  *digest_list = list_authority_ids_with_downloads();
926  if (!(*digest_list)) {
927  *errmsg = "Failed to get list of authority identity digests (!)";
928  }
929  } else if (!strcmpstart(fp_sk_req, "fp/")) {
930  fp_sk_req += strlen("fp/");
931  /* Okay, look for another / to tell the fp from fp-sk cases */
932  sk_req = strchr(fp_sk_req, '/');
933  if (sk_req) {
934  /* okay, split it here and try to parse <fp> */
935  if (base16_decode(id_digest, DIGEST_LEN,
936  fp_sk_req, sk_req - fp_sk_req) == DIGEST_LEN) {
937  /* Skip past the '/' */
938  ++sk_req;
939  if (strcmp(sk_req, "sks") == 0) {
940  /* We're asking for the list of signing key fingerprints */
941  *digest_list = list_sk_digests_for_authority_id(id_digest);
942  if (!(*digest_list)) {
943  *errmsg = "Failed to get list of signing key digests for this "
944  "authority identity digest";
945  }
946  } else {
947  /* We've got a signing key digest */
948  if (base16_decode(sk_digest, DIGEST_LEN,
949  sk_req, strlen(sk_req)) == DIGEST_LEN) {
950  *dl_to_emit =
951  download_status_for_authority_id_and_sk(id_digest, sk_digest);
952  if (!(*dl_to_emit)) {
953  *errmsg = "Failed to get download status for this identity/"
954  "signing key digest pair";
955  }
956  } else {
957  *errmsg = "That didn't look like a signing key digest";
958  }
959  }
960  } else {
961  *errmsg = "That didn't look like an identity digest";
962  }
963  } else {
964  /* We're either in downloads/certs/fp/<fp>, or we can't parse <fp> */
965  if (strlen(fp_sk_req) == HEX_DIGEST_LEN) {
966  if (base16_decode(id_digest, DIGEST_LEN,
967  fp_sk_req, strlen(fp_sk_req)) == DIGEST_LEN) {
968  *dl_to_emit = id_only_download_status_for_authority_id(id_digest);
969  if (!(*dl_to_emit)) {
970  *errmsg = "Failed to get download status for this authority "
971  "identity digest";
972  }
973  } else {
974  *errmsg = "That didn't look like a digest";
975  }
976  } else {
977  *errmsg = "That didn't look like a digest";
978  }
979  }
980  } else {
981  *errmsg = "Unknown certificate download status query";
982  }
983 }
984 
985 /** Handle the routerdesc download cases for getinfo_helper_downloads() */
986 STATIC void
987 getinfo_helper_downloads_desc(const char *desc_req,
988  download_status_t **dl_to_emit,
989  smartlist_t **digest_list,
990  const char **errmsg)
991 {
992  char desc_digest[DIGEST_LEN];
993  /*
994  * Two cases to handle here:
995  *
996  * Case 1: desc_req = "descs"
997  * - Emit a list of all router descriptor digests, which we get by
998  * calling router_get_descriptor_digests(); this can return NULL
999  * if we have no current ns-flavor consensus.
1000  *
1001  * Case 2: desc_req = <fp>
1002  * - Check on the specified fingerprint and emit its download_status_t
1003  * using router_get_dl_status_by_descriptor_digest().
1004  */
1005 
1006  if (strcmp(desc_req, "descs") == 0) {
1007  *digest_list = router_get_descriptor_digests();
1008  if (!(*digest_list)) {
1009  *errmsg = "We don't seem to have a networkstatus-flavored consensus";
1010  }
1011  /*
1012  * Microdescs don't use the download_status_t mechanism, so we don't
1013  * answer queries about their downloads here; see microdesc.c.
1014  */
1015  } else if (strlen(desc_req) == HEX_DIGEST_LEN) {
1016  if (base16_decode(desc_digest, DIGEST_LEN,
1017  desc_req, strlen(desc_req)) == DIGEST_LEN) {
1018  /* Okay we got a digest-shaped thing; try asking for it */
1019  *dl_to_emit = router_get_dl_status_by_descriptor_digest(desc_digest);
1020  if (!(*dl_to_emit)) {
1021  *errmsg = "No such descriptor digest found";
1022  }
1023  } else {
1024  *errmsg = "That didn't look like a digest";
1025  }
1026  } else {
1027  *errmsg = "Unknown router descriptor download status query";
1028  }
1029 }
1030 
1031 /** Handle the bridge download cases for getinfo_helper_downloads() */
1032 STATIC void
1033 getinfo_helper_downloads_bridge(const char *bridge_req,
1034  download_status_t **dl_to_emit,
1035  smartlist_t **digest_list,
1036  const char **errmsg)
1037 {
1038  char bridge_digest[DIGEST_LEN];
1039  /*
1040  * Two cases to handle here:
1041  *
1042  * Case 1: bridge_req = "bridges"
1043  * - Emit a list of all bridge identity digests, which we get by
1044  * calling list_bridge_identities(); this can return NULL if we are
1045  * not using bridges.
1046  *
1047  * Case 2: bridge_req = <fp>
1048  * - Check on the specified fingerprint and emit its download_status_t
1049  * using get_bridge_dl_status_by_id().
1050  */
1051 
1052  if (strcmp(bridge_req, "bridges") == 0) {
1053  *digest_list = list_bridge_identities();
1054  if (!(*digest_list)) {
1055  *errmsg = "We don't seem to be using bridges";
1056  }
1057  } else if (strlen(bridge_req) == HEX_DIGEST_LEN) {
1058  if (base16_decode(bridge_digest, DIGEST_LEN,
1059  bridge_req, strlen(bridge_req)) == DIGEST_LEN) {
1060  /* Okay we got a digest-shaped thing; try asking for it */
1061  *dl_to_emit = get_bridge_dl_status_by_id(bridge_digest);
1062  if (!(*dl_to_emit)) {
1063  *errmsg = "No such bridge identity digest found";
1064  }
1065  } else {
1066  *errmsg = "That didn't look like a digest";
1067  }
1068  } else {
1069  *errmsg = "Unknown bridge descriptor download status query";
1070  }
1071 }
1072 
1073 /** Implementation helper for GETINFO: knows the answers for questions about
1074  * download status information. */
1075 STATIC int
1077  const char *question, char **answer,
1078  const char **errmsg)
1079 {
1080  download_status_t *dl_to_emit = NULL;
1081  smartlist_t *digest_list = NULL;
1082 
1083  /* Assert args are sane */
1084  tor_assert(control_conn != NULL);
1085  tor_assert(question != NULL);
1086  tor_assert(answer != NULL);
1087  tor_assert(errmsg != NULL);
1088 
1089  /* We check for this later to see if we should supply a default */
1090  *errmsg = NULL;
1091 
1092  /* Are we after networkstatus downloads? */
1093  if (!strcmpstart(question, "downloads/networkstatus/")) {
1095  question + strlen("downloads/networkstatus/"),
1096  &dl_to_emit, errmsg);
1097  /* Certificates? */
1098  } else if (!strcmpstart(question, "downloads/cert/")) {
1100  question + strlen("downloads/cert/"),
1101  &dl_to_emit, &digest_list, errmsg);
1102  /* Router descriptors? */
1103  } else if (!strcmpstart(question, "downloads/desc/")) {
1105  question + strlen("downloads/desc/"),
1106  &dl_to_emit, &digest_list, errmsg);
1107  /* Bridge descriptors? */
1108  } else if (!strcmpstart(question, "downloads/bridge/")) {
1110  question + strlen("downloads/bridge/"),
1111  &dl_to_emit, &digest_list, errmsg);
1112  } else {
1113  *errmsg = "Unknown download status query";
1114  }
1115 
1116  if (dl_to_emit) {
1117  *answer = download_status_to_string(dl_to_emit);
1118 
1119  return 0;
1120  } else if (digest_list) {
1121  *answer = digest_list_to_string(digest_list);
1122  SMARTLIST_FOREACH(digest_list, void *, s, tor_free(s));
1123  smartlist_free(digest_list);
1124 
1125  return 0;
1126  } else {
1127  if (!(*errmsg)) {
1128  *errmsg = "Unknown error";
1129  }
1130 
1131  return -1;
1132  }
1133 }
1134 
1135 /** Implementation helper for GETINFO: knows how to generate summaries of the
1136  * current states of things we send events about. */
1137 static int
1139  const char *question, char **answer,
1140  const char **errmsg)
1141 {
1142  const or_options_t *options = get_options();
1143  (void) control_conn;
1144  if (!strcmp(question, "circuit-status")) {
1145  smartlist_t *status = smartlist_new();
1147  origin_circuit_t *circ;
1148  char *circdesc;
1149  const char *state;
1150  if (! CIRCUIT_IS_ORIGIN(circ_) || circ_->marked_for_close)
1151  continue;
1152  circ = TO_ORIGIN_CIRCUIT(circ_);
1153 
1154  if (circ->base_.state == CIRCUIT_STATE_OPEN)
1155  state = "BUILT";
1156  else if (circ->base_.state == CIRCUIT_STATE_GUARD_WAIT)
1157  state = "GUARD_WAIT";
1158  else if (circ->cpath)
1159  state = "EXTENDED";
1160  else
1161  state = "LAUNCHED";
1162 
1163  circdesc = circuit_describe_status_for_controller(circ);
1164 
1165  smartlist_add_asprintf(status, "%lu %s%s%s",
1166  (unsigned long)circ->global_identifier,
1167  state, *circdesc ? " " : "", circdesc);
1168  tor_free(circdesc);
1169  }
1170  SMARTLIST_FOREACH_END(circ_);
1171  *answer = smartlist_join_strings(status, "\r\n", 0, NULL);
1172  SMARTLIST_FOREACH(status, char *, cp, tor_free(cp));
1173  smartlist_free(status);
1174  } else if (!strcmp(question, "stream-status")) {
1175  smartlist_t *conns = get_connection_array();
1176  smartlist_t *status = smartlist_new();
1177  char buf[256];
1178  SMARTLIST_FOREACH_BEGIN(conns, connection_t *, base_conn) {
1179  const char *state;
1180  entry_connection_t *conn;
1181  circuit_t *circ;
1182  origin_circuit_t *origin_circ = NULL;
1183  if (base_conn->type != CONN_TYPE_AP ||
1184  base_conn->marked_for_close ||
1185  base_conn->state == AP_CONN_STATE_SOCKS_WAIT ||
1186  base_conn->state == AP_CONN_STATE_NATD_WAIT)
1187  continue;
1188  conn = TO_ENTRY_CONN(base_conn);
1189  switch (base_conn->state)
1190  {
1193  if (conn->socks_request &&
1194  SOCKS_COMMAND_IS_RESOLVE(conn->socks_request->command))
1195  state = "NEWRESOLVE";
1196  else
1197  state = "NEW";
1198  break;
1201  state = "SENTCONNECT"; break;
1203  state = "SENTRESOLVE"; break;
1204  case AP_CONN_STATE_OPEN:
1205  state = "SUCCEEDED"; break;
1206  default:
1207  log_warn(LD_BUG, "Asked for stream in unknown state %d",
1208  base_conn->state);
1209  continue;
1210  }
1212  if (circ && CIRCUIT_IS_ORIGIN(circ))
1213  origin_circ = TO_ORIGIN_CIRCUIT(circ);
1214  write_stream_target_to_buf(conn, buf, sizeof(buf));
1215  smartlist_add_asprintf(status, "%lu %s %lu %s",
1216  (unsigned long) base_conn->global_identifier,state,
1217  origin_circ?
1218  (unsigned long)origin_circ->global_identifier : 0ul,
1219  buf);
1220  } SMARTLIST_FOREACH_END(base_conn);
1221  *answer = smartlist_join_strings(status, "\r\n", 0, NULL);
1222  SMARTLIST_FOREACH(status, char *, cp, tor_free(cp));
1223  smartlist_free(status);
1224  } else if (!strcmp(question, "orconn-status")) {
1225  smartlist_t *conns = get_connection_array();
1226  smartlist_t *status = smartlist_new();
1227  SMARTLIST_FOREACH_BEGIN(conns, connection_t *, base_conn) {
1228  const char *state;
1229  char name[128];
1230  or_connection_t *conn;
1231  if (base_conn->type != CONN_TYPE_OR || base_conn->marked_for_close)
1232  continue;
1233  conn = TO_OR_CONN(base_conn);
1234  if (conn->base_.state == OR_CONN_STATE_OPEN)
1235  state = "CONNECTED";
1236  else if (conn->nickname)
1237  state = "LAUNCHED";
1238  else
1239  state = "NEW";
1240  orconn_target_get_name(name, sizeof(name), conn);
1241  smartlist_add_asprintf(status, "%s %s", name, state);
1242  } SMARTLIST_FOREACH_END(base_conn);
1243  *answer = smartlist_join_strings(status, "\r\n", 0, NULL);
1244  SMARTLIST_FOREACH(status, char *, cp, tor_free(cp));
1245  smartlist_free(status);
1246  } else if (!strcmpstart(question, "address-mappings/")) {
1247  time_t min_e, max_e;
1248  smartlist_t *mappings;
1249  question += strlen("address-mappings/");
1250  if (!strcmp(question, "all")) {
1251  min_e = 0; max_e = TIME_MAX;
1252  } else if (!strcmp(question, "cache")) {
1253  min_e = 2; max_e = TIME_MAX;
1254  } else if (!strcmp(question, "config")) {
1255  min_e = 0; max_e = 0;
1256  } else if (!strcmp(question, "control")) {
1257  min_e = 1; max_e = 1;
1258  } else {
1259  return 0;
1260  }
1261  mappings = smartlist_new();
1262  addressmap_get_mappings(mappings, min_e, max_e, 1);
1263  *answer = smartlist_join_strings(mappings, "\r\n", 0, NULL);
1264  SMARTLIST_FOREACH(mappings, char *, cp, tor_free(cp));
1265  smartlist_free(mappings);
1266  } else if (!strcmpstart(question, "status/")) {
1267  /* Note that status/ is not a catch-all for events; there's only supposed
1268  * to be a status GETINFO if there's a corresponding STATUS event. */
1269  if (!strcmp(question, "status/circuit-established")) {
1270  *answer = tor_strdup(have_completed_a_circuit() ? "1" : "0");
1271  } else if (!strcmp(question, "status/enough-dir-info")) {
1272  *answer = tor_strdup(router_have_minimum_dir_info() ? "1" : "0");
1273  } else if (!strcmp(question, "status/good-server-descriptor") ||
1274  !strcmp(question, "status/accepted-server-descriptor")) {
1275  /* They're equivalent for now, until we can figure out how to make
1276  * good-server-descriptor be what we want. See comment in
1277  * control-spec.txt. */
1278  *answer = tor_strdup(directories_have_accepted_server_descriptor()
1279  ? "1" : "0");
1280  } else if (!strcmp(question, "status/reachability-succeeded/or")) {
1281  *answer = tor_strdup(
1282  router_all_orports_seem_reachable(options) ?
1283  "1" : "0");
1284  } else if (!strcmp(question, "status/reachability-succeeded/dir")) {
1285  *answer = tor_strdup(
1287  "1" : "0");
1288  } else if (!strcmp(question, "status/reachability-succeeded")) {
1289  tor_asprintf(
1290  answer, "OR=%d DIR=%d",
1291  router_all_orports_seem_reachable(options) ? 1 : 0,
1292  router_dirport_seems_reachable(options) ? 1 : 0);
1293  } else if (!strcmp(question, "status/bootstrap-phase")) {
1294  *answer = control_event_boot_last_msg();
1295  } else if (!strcmpstart(question, "status/version/")) {
1296  int is_server = server_mode(options);
1298  version_status_t status;
1299  const char *recommended;
1300  if (c) {
1301  recommended = is_server ? c->server_versions : c->client_versions;
1302  status = tor_version_is_obsolete(VERSION, recommended);
1303  } else {
1304  recommended = "?";
1305  status = VS_UNKNOWN;
1306  }
1307 
1308  if (!strcmp(question, "status/version/recommended")) {
1309  *answer = tor_strdup(recommended);
1310  return 0;
1311  }
1312  if (!strcmp(question, "status/version/current")) {
1313  switch (status)
1314  {
1315  case VS_RECOMMENDED: *answer = tor_strdup("recommended"); break;
1316  case VS_OLD: *answer = tor_strdup("obsolete"); break;
1317  case VS_NEW: *answer = tor_strdup("new"); break;
1318  case VS_NEW_IN_SERIES: *answer = tor_strdup("new in series"); break;
1319  case VS_UNRECOMMENDED: *answer = tor_strdup("unrecommended"); break;
1320  case VS_EMPTY: *answer = tor_strdup("none recommended"); break;
1321  case VS_UNKNOWN: *answer = tor_strdup("unknown"); break;
1322  default: tor_fragile_assert();
1323  }
1324  }
1325  } else if (!strcmp(question, "status/clients-seen")) {
1326  char *bridge_stats = geoip_get_bridge_stats_controller(time(NULL));
1327  if (!bridge_stats) {
1328  *errmsg = "No bridge-client stats available";
1329  return -1;
1330  }
1331  *answer = bridge_stats;
1332  } else if (!strcmp(question, "status/fresh-relay-descs")) {
1333  if (!server_mode(options)) {
1334  *errmsg = "Only relays have descriptors";
1335  return -1;
1336  }
1337  routerinfo_t *r;
1338  extrainfo_t *e;
1339  int result;
1340  if ((result = router_build_fresh_descriptor(&r, &e)) < 0) {
1341  switch (result) {
1342  case TOR_ROUTERINFO_ERROR_NO_EXT_ADDR:
1343  *errmsg = "Cannot get relay address while generating descriptor";
1344  break;
1345  case TOR_ROUTERINFO_ERROR_DIGEST_FAILED:
1346  *errmsg = "Key digest failed";
1347  break;
1348  case TOR_ROUTERINFO_ERROR_CANNOT_GENERATE:
1349  *errmsg = "Cannot generate router descriptor";
1350  break;
1351  default:
1352  *errmsg = "Error generating descriptor";
1353  break;
1354  }
1355  return -1;
1356  }
1357  size_t size = r->cache_info.signed_descriptor_len + 1;
1358  if (e) {
1359  size += e->cache_info.signed_descriptor_len + 1;
1360  }
1361  tor_assert(r->cache_info.signed_descriptor_len);
1362  char *descs = tor_malloc(size);
1363  char *cp = descs;
1364  memcpy(cp, signed_descriptor_get_body(&r->cache_info),
1365  r->cache_info.signed_descriptor_len);
1366  cp += r->cache_info.signed_descriptor_len - 1;
1367  if (e) {
1368  if (cp[0] == '\0') {
1369  cp[0] = '\n';
1370  } else if (cp[0] != '\n') {
1371  cp[1] = '\n';
1372  cp++;
1373  }
1374  memcpy(cp, signed_descriptor_get_body(&e->cache_info),
1375  e->cache_info.signed_descriptor_len);
1376  cp += e->cache_info.signed_descriptor_len - 1;
1377  }
1378  if (cp[0] == '\n') {
1379  cp[0] = '\0';
1380  } else if (cp[0] != '\0') {
1381  cp[1] = '\0';
1382  }
1383  *answer = descs;
1384  routerinfo_free(r);
1385  extrainfo_free(e);
1386  } else {
1387  return 0;
1388  }
1389  }
1390  return 0;
1391 }
1392 
1393 /** Implementation helper for GETINFO: knows how to enumerate hidden services
1394  * created via the control port. */
1395 STATIC int
1397  const char *question, char **answer,
1398  const char **errmsg)
1399 {
1400  smartlist_t *onion_list = NULL;
1401  (void) errmsg; /* no errors from this method */
1402 
1403  if (control_conn && !strcmp(question, "onions/current")) {
1404  onion_list = control_conn->ephemeral_onion_services;
1405  } else if (!strcmp(question, "onions/detached")) {
1406  onion_list = get_detached_onion_services();
1407  } else {
1408  return 0;
1409  }
1410  if (!onion_list || smartlist_len(onion_list) == 0) {
1411  if (answer) {
1412  *answer = tor_strdup("");
1413  }
1414  } else {
1415  if (answer) {
1416  *answer = smartlist_join_strings(onion_list, "\r\n", 0, NULL);
1417  }
1418  }
1419 
1420  return 0;
1421 }
1422 
1423 /** Implementation helper for GETINFO: answers queries about network
1424  * liveness. */
1425 static int
1427  const char *question, char **answer,
1428  const char **errmsg)
1429 {
1430  (void)control_conn;
1431  (void)errmsg;
1432  if (strcmp(question, "network-liveness") == 0) {
1433  if (get_cached_network_liveness()) {
1434  *answer = tor_strdup("up");
1435  } else {
1436  *answer = tor_strdup("down");
1437  }
1438  }
1439 
1440  return 0;
1441 }
1442 
1443 /** Implementation helper for GETINFO: answers queries about circuit onion
1444  * handshake rephist values */
1445 STATIC int
1447  const char *question, char **answer,
1448  const char **errmsg)
1449 {
1450  (void) control_conn;
1451  (void) errmsg;
1452  int result;
1453 
1454  if (!strcmp(question, "stats/ntor/assigned")) {
1455  result =
1456  rep_hist_get_circuit_handshake_assigned(ONION_HANDSHAKE_TYPE_NTOR);
1457  } else if (!strcmp(question, "stats/ntor/requested")) {
1458  result =
1459  rep_hist_get_circuit_handshake_requested(ONION_HANDSHAKE_TYPE_NTOR);
1460  } else if (!strcmp(question, "stats/tap/assigned")) {
1461  result =
1462  rep_hist_get_circuit_handshake_assigned(ONION_HANDSHAKE_TYPE_TAP);
1463  } else if (!strcmp(question, "stats/tap/requested")) {
1464  result =
1465  rep_hist_get_circuit_handshake_requested(ONION_HANDSHAKE_TYPE_TAP);
1466  } else {
1467  *errmsg = "Unrecognized handshake type";
1468  return -1;
1469  }
1470 
1471  tor_asprintf(answer, "%d", result);
1472 
1473  return 0;
1474 }
1475 
1476 /** Implementation helper for GETINFO: answers queries about shared random
1477  * value. */
1478 static int
1480  const char *question, char **answer,
1481  const char **errmsg)
1482 {
1483  (void) control_conn;
1484  (void) errmsg;
1485 
1486  if (!strcmp(question, "sr/current")) {
1487  *answer = sr_get_current_for_control();
1488  } else if (!strcmp(question, "sr/previous")) {
1489  *answer = sr_get_previous_for_control();
1490  }
1491  /* Else statement here is unrecognized key so do nothing. */
1492 
1493  return 0;
1494 }
1495 
1496 /** Callback function for GETINFO: on a given control connection, try to
1497  * answer the question <b>q</b> and store the newly-allocated answer in
1498  * *<b>a</b>. If an internal error occurs, return -1 and optionally set
1499  * *<b>error_out</b> to point to an error message to be delivered to the
1500  * controller. On success, _or if the key is not recognized_, return 0. Do not
1501  * set <b>a</b> if the key is not recognized but you may set <b>error_out</b>
1502  * to improve the error message.
1503  */
1505  const char *q, char **a,
1506  const char **error_out);
1507 
1508 /** A single item for the GETINFO question-to-answer-function table. */
1509 typedef struct getinfo_item_t {
1510  const char *varname; /**< The value (or prefix) of the question. */
1511  getinfo_helper_t fn; /**< The function that knows the answer: NULL if
1512  * this entry is documentation-only. */
1513  const char *desc; /**< Description of the variable. */
1514  int is_prefix; /** Must varname match exactly, or must it be a prefix? */
1515 } getinfo_item_t;
1516 
1517 #define ITEM(name, fn, desc) { name, getinfo_helper_##fn, desc, 0 }
1518 #define PREFIX(name, fn, desc) { name, getinfo_helper_##fn, desc, 1 }
1519 #define DOC(name, desc) { name, NULL, desc, 0 }
1520 
1521 /** Table mapping questions accepted by GETINFO to the functions that know how
1522  * to answer them. */
1523 static const getinfo_item_t getinfo_items[] = {
1524  ITEM("version", misc, "The current version of Tor."),
1525  ITEM("bw-event-cache", misc, "Cached BW events for a short interval."),
1526  ITEM("config-file", misc, "Current location of the \"torrc\" file."),
1527  ITEM("config-defaults-file", misc, "Current location of the defaults file."),
1528  ITEM("config-text", misc,
1529  "Return the string that would be written by a saveconf command."),
1530  ITEM("config-can-saveconf", misc,
1531  "Is it possible to save the configuration to the \"torrc\" file?"),
1532  ITEM("accounting/bytes", accounting,
1533  "Number of bytes read/written so far in the accounting interval."),
1534  ITEM("accounting/bytes-left", accounting,
1535  "Number of bytes left to write/read so far in the accounting interval."),
1536  ITEM("accounting/enabled", accounting, "Is accounting currently enabled?"),
1537  ITEM("accounting/hibernating", accounting, "Are we hibernating or awake?"),
1538  ITEM("accounting/interval-start", accounting,
1539  "Time when the accounting period starts."),
1540  ITEM("accounting/interval-end", accounting,
1541  "Time when the accounting period ends."),
1542  ITEM("accounting/interval-wake", accounting,
1543  "Time to wake up in this accounting period."),
1544  ITEM("helper-nodes", entry_guards, NULL), /* deprecated */
1545  ITEM("entry-guards", entry_guards,
1546  "Which nodes are we using as entry guards?"),
1547  ITEM("fingerprint", misc, NULL),
1548  PREFIX("config/", config, "Current configuration values."),
1549  DOC("config/names",
1550  "List of configuration options, types, and documentation."),
1551  DOC("config/defaults",
1552  "List of default values for configuration options. "
1553  "See also config/names"),
1554  PREFIX("current-time/", current_time, "Current time."),
1555  DOC("current-time/local", "Current time on the local system."),
1556  DOC("current-time/utc", "Current UTC time."),
1557  PREFIX("downloads/networkstatus/", downloads,
1558  "Download statuses for networkstatus objects"),
1559  DOC("downloads/networkstatus/ns",
1560  "Download status for current-mode networkstatus download"),
1561  DOC("downloads/networkstatus/ns/bootstrap",
1562  "Download status for bootstrap-time networkstatus download"),
1563  DOC("downloads/networkstatus/ns/running",
1564  "Download status for run-time networkstatus download"),
1565  DOC("downloads/networkstatus/microdesc",
1566  "Download status for current-mode microdesc download"),
1567  DOC("downloads/networkstatus/microdesc/bootstrap",
1568  "Download status for bootstrap-time microdesc download"),
1569  DOC("downloads/networkstatus/microdesc/running",
1570  "Download status for run-time microdesc download"),
1571  PREFIX("downloads/cert/", downloads,
1572  "Download statuses for certificates, by id fingerprint and "
1573  "signing key"),
1574  DOC("downloads/cert/fps",
1575  "List of authority fingerprints for which any download statuses "
1576  "exist"),
1577  DOC("downloads/cert/fp/<fp>",
1578  "Download status for <fp> with the default signing key; corresponds "
1579  "to /fp/ URLs on directory server."),
1580  DOC("downloads/cert/fp/<fp>/sks",
1581  "List of signing keys for which specific download statuses are "
1582  "available for this id fingerprint"),
1583  DOC("downloads/cert/fp/<fp>/<sk>",
1584  "Download status for <fp> with signing key <sk>; corresponds "
1585  "to /fp-sk/ URLs on directory server."),
1586  PREFIX("downloads/desc/", downloads,
1587  "Download statuses for router descriptors, by descriptor digest"),
1588  DOC("downloads/desc/descs",
1589  "Return a list of known router descriptor digests"),
1590  DOC("downloads/desc/<desc>",
1591  "Return a download status for a given descriptor digest"),
1592  PREFIX("downloads/bridge/", downloads,
1593  "Download statuses for bridge descriptors, by bridge identity "
1594  "digest"),
1595  DOC("downloads/bridge/bridges",
1596  "Return a list of configured bridge identity digests with download "
1597  "statuses"),
1598  DOC("downloads/bridge/<desc>",
1599  "Return a download status for a given bridge identity digest"),
1600  ITEM("info/names", misc,
1601  "List of GETINFO options, types, and documentation."),
1602  ITEM("events/names", misc,
1603  "Events that the controller can ask for with SETEVENTS."),
1604  ITEM("signal/names", misc, "Signal names recognized by the SIGNAL command"),
1605  ITEM("features/names", misc, "What arguments can USEFEATURE take?"),
1606  PREFIX("desc/id/", dir, "Router descriptors by ID."),
1607  PREFIX("desc/name/", dir, "Router descriptors by nickname."),
1608  ITEM("desc/all-recent", dir,
1609  "All non-expired, non-superseded router descriptors."),
1610  ITEM("desc/download-enabled", dir,
1611  "Do we try to download router descriptors?"),
1612  ITEM("desc/all-recent-extrainfo-hack", dir, NULL), /* Hack. */
1613  ITEM("md/all", dir, "All known microdescriptors."),
1614  PREFIX("md/id/", dir, "Microdescriptors by ID"),
1615  PREFIX("md/name/", dir, "Microdescriptors by name"),
1616  ITEM("md/download-enabled", dir,
1617  "Do we try to download microdescriptors?"),
1618  PREFIX("extra-info/digest/", dir, "Extra-info documents by digest."),
1619  PREFIX("hs/client/desc/id", dir,
1620  "Hidden Service descriptor in client's cache by onion."),
1621  PREFIX("hs/service/desc/id/", dir,
1622  "Hidden Service descriptor in services's cache by onion."),
1623  PREFIX("net/listeners/", listeners, "Bound addresses by type"),
1624  ITEM("ns/all", networkstatus,
1625  "Brief summary of router status (v2 directory format)"),
1626  PREFIX("ns/id/", networkstatus,
1627  "Brief summary of router status by ID (v2 directory format)."),
1628  PREFIX("ns/name/", networkstatus,
1629  "Brief summary of router status by nickname (v2 directory format)."),
1630  PREFIX("ns/purpose/", networkstatus,
1631  "Brief summary of router status by purpose (v2 directory format)."),
1632  PREFIX("consensus/", networkstatus,
1633  "Information about and from the ns consensus."),
1634  ITEM("network-status", dir,
1635  "Brief summary of router status (v1 directory format)"),
1636  ITEM("network-liveness", liveness,
1637  "Current opinion on whether the network is live"),
1638  ITEM("circuit-status", events, "List of current circuits originating here."),
1639  ITEM("stream-status", events,"List of current streams."),
1640  ITEM("orconn-status", events, "A list of current OR connections."),
1641  ITEM("dormant", misc,
1642  "Is Tor dormant (not building circuits because it's idle)?"),
1643  PREFIX("address-mappings/", events, NULL),
1644  DOC("address-mappings/all", "Current address mappings."),
1645  DOC("address-mappings/cache", "Current cached DNS replies."),
1646  DOC("address-mappings/config",
1647  "Current address mappings from configuration."),
1648  DOC("address-mappings/control", "Current address mappings from controller."),
1649  PREFIX("status/", events, NULL),
1650  DOC("status/circuit-established",
1651  "Whether we think client functionality is working."),
1652  DOC("status/enough-dir-info",
1653  "Whether we have enough up-to-date directory information to build "
1654  "circuits."),
1655  DOC("status/bootstrap-phase",
1656  "The last bootstrap phase status event that Tor sent."),
1657  DOC("status/clients-seen",
1658  "Breakdown of client countries seen by a bridge."),
1659  DOC("status/fresh-relay-descs",
1660  "A fresh relay/ei descriptor pair for Tor's current state. Not stored."),
1661  DOC("status/version/recommended", "List of currently recommended versions."),
1662  DOC("status/version/current", "Status of the current version."),
1663  ITEM("address", misc, "IP address of this Tor host, if we can guess it."),
1664  ITEM("address/v4", misc,
1665  "IPv4 address of this Tor host, if we can guess it."),
1666  ITEM("address/v6", misc,
1667  "IPv6 address of this Tor host, if we can guess it."),
1668  ITEM("traffic/read", misc,"Bytes read since the process was started."),
1669  ITEM("traffic/written", misc,
1670  "Bytes written since the process was started."),
1671  ITEM("uptime", misc, "Uptime of the Tor daemon in seconds."),
1672  ITEM("process/pid", misc, "Process id belonging to the main tor process."),
1673  ITEM("process/uid", misc, "User id running the tor process."),
1674  ITEM("process/user", misc,
1675  "Username under which the tor process is running."),
1676  ITEM("process/descriptor-limit", misc, "File descriptor limit."),
1677  ITEM("limits/max-mem-in-queues", misc, "Actual limit on memory in queues"),
1678  PREFIX("desc-annotations/id/", dir, "Router annotations by hexdigest."),
1679  PREFIX("dir/server/", dir,"Router descriptors as retrieved from a DirPort."),
1680  PREFIX("dir/status/", dir,
1681  "v2 networkstatus docs as retrieved from a DirPort."),
1682  ITEM("dir/status-vote/current/consensus", dir,
1683  "v3 Networkstatus consensus as retrieved from a DirPort."),
1684  ITEM("dir/status-vote/current/consensus-microdesc", dir,
1685  "v3 Microdescriptor consensus as retrieved from a DirPort."),
1686  ITEM("exit-policy/default", policies,
1687  "The default value appended to the configured exit policy."),
1688  ITEM("exit-policy/reject-private/default", policies,
1689  "The default rules appended to the configured exit policy by"
1690  " ExitPolicyRejectPrivate."),
1691  ITEM("exit-policy/reject-private/relay", policies,
1692  "The relay-specific rules appended to the configured exit policy by"
1693  " ExitPolicyRejectPrivate and/or ExitPolicyRejectLocalInterfaces."),
1694  ITEM("exit-policy/full", policies, "The entire exit policy of onion router"),
1695  ITEM("exit-policy/ipv4", policies, "IPv4 parts of exit policy"),
1696  ITEM("exit-policy/ipv6", policies, "IPv6 parts of exit policy"),
1697  PREFIX("ip-to-country/", geoip, "Perform a GEOIP lookup"),
1698  ITEM("onions/current", onions,
1699  "Onion services owned by the current control connection."),
1700  ITEM("onions/detached", onions,
1701  "Onion services detached from the control connection."),
1702  ITEM("sr/current", sr, "Get current shared random value."),
1703  ITEM("sr/previous", sr, "Get previous shared random value."),
1704  PREFIX("stats/ntor/", rephist, "NTor circuit handshake stats."),
1705  ITEM("stats/ntor/assigned", rephist,
1706  "Assigned NTor circuit handshake stats."),
1707  ITEM("stats/ntor/requested", rephist,
1708  "Requested NTor circuit handshake stats."),
1709  PREFIX("stats/tap/", rephist, "TAP circuit handshake stats."),
1710  ITEM("stats/tap/assigned", rephist,
1711  "Assigned TAP circuit handshake stats."),
1712  ITEM("stats/tap/requested", rephist,
1713  "Requested TAP circuit handshake stats."),
1714  { NULL, NULL, NULL, 0 }
1715 };
1716 
1717 /** Allocate and return a list of recognized GETINFO options. */
1718 static char *
1720 {
1721  int i;
1722  smartlist_t *lines = smartlist_new();
1723  char *ans;
1724  for (i = 0; getinfo_items[i].varname; ++i) {
1725  if (!getinfo_items[i].desc)
1726  continue;
1727 
1728  smartlist_add_asprintf(lines, "%s%s -- %s\n",
1729  getinfo_items[i].varname,
1730  getinfo_items[i].is_prefix ? "*" : "",
1731  getinfo_items[i].desc);
1732  }
1733  smartlist_sort_strings(lines);
1734 
1735  ans = smartlist_join_strings(lines, "", 0, NULL);
1736  SMARTLIST_FOREACH(lines, char *, cp, tor_free(cp));
1737  smartlist_free(lines);
1738 
1739  return ans;
1740 }
1741 
1742 /** Lookup the 'getinfo' entry <b>question</b>, and return
1743  * the answer in <b>*answer</b> (or NULL if key not recognized).
1744  * Return 0 if success or unrecognized, or -1 if recognized but
1745  * internal error. */
1746 static int
1748  const char *question, char **answer,
1749  const char **err_out)
1750 {
1751  int i;
1752  *answer = NULL; /* unrecognized key by default */
1753 
1754  for (i = 0; getinfo_items[i].varname; ++i) {
1755  int match;
1756  if (getinfo_items[i].is_prefix)
1757  match = !strcmpstart(question, getinfo_items[i].varname);
1758  else
1759  match = !strcmp(question, getinfo_items[i].varname);
1760  if (match) {
1761  tor_assert(getinfo_items[i].fn);
1762  return getinfo_items[i].fn(control_conn, question, answer, err_out);
1763  }
1764  }
1765 
1766  return 0; /* unrecognized */
1767 }
1768 
1769 const control_cmd_syntax_t getinfo_syntax = {
1770  .max_args = UINT_MAX,
1771 };
1772 
1773 /** Called when we receive a GETINFO command. Try to fetch all requested
1774  * information, and reply with information or error message. */
1775 int
1777  const control_cmd_args_t *args)
1778 {
1779  const smartlist_t *questions = args->args;
1780  smartlist_t *answers = smartlist_new();
1781  smartlist_t *unrecognized = smartlist_new();
1782  char *ans = NULL;
1783 
1784  SMARTLIST_FOREACH_BEGIN(questions, const char *, q) {
1785  const char *errmsg = NULL;
1786 
1787  if (handle_getinfo_helper(conn, q, &ans, &errmsg) < 0) {
1788  if (!errmsg)
1789  errmsg = "Internal error";
1790  control_write_endreply(conn, 551, errmsg);
1791  goto done;
1792  }
1793  if (!ans) {
1794  if (errmsg) {
1795  /* use provided error message */
1796  control_reply_add_str(unrecognized, 552, errmsg);
1797  } else {
1798  /* use default error message */
1799  control_reply_add_printf(unrecognized, 552,
1800  "Unrecognized key \"%s\"", q);
1801  }
1802  } else {
1803  control_reply_add_one_kv(answers, 250, KV_RAW, q, ans);
1804  tor_free(ans);
1805  }
1806  } SMARTLIST_FOREACH_END(q);
1807 
1808  control_reply_add_done(answers);
1809 
1810  if (smartlist_len(unrecognized)) {
1811  control_write_reply_lines(conn, unrecognized);
1812  /* If there were any unrecognized queries, don't write real answers */
1813  goto done;
1814  }
1815 
1816  control_write_reply_lines(conn, answers);
1817 
1818  done:
1819  control_reply_free(answers);
1820  control_reply_free(unrecognized);
1821 
1822  return 0;
1823 }
microdesc_t
Definition: microdesc_st.h:27
networkstatus_get_flavor_name
const char * networkstatus_get_flavor_name(consensus_flavor_t flav)
Definition: networkstatus.c:2577
selftest.h
Header file for selftest.c.
routermode.h
Header file for routermode.c.
control_reply_add_one_kv
void control_reply_add_one_kv(smartlist_t *reply, int code, int flags, const char *key, const char *val)
Definition: control_proto.c:338
tor_free
#define tor_free(p)
Definition: malloc.h:52
routerinfo_t
Definition: routerinfo_st.h:20
connection_edge.h
Header file for connection_edge.c.
versions.h
Header file for versions.c.
getinfo_item_t
Definition: control_getinfo.c:1509
CIRCUIT_STATE_OPEN
#define CIRCUIT_STATE_OPEN
Definition: circuitlist.h:32
routerinfo.h
Header file for routerinfo.c.
name
const char * name
Definition: config.c:2464
rend_cache_entry_t
Definition: rendcache.h:29
circuit_describe_status_for_controller
char * circuit_describe_status_for_controller(origin_circuit_t *circ)
Definition: control_fmt.c:73
control_cmd_args_t
Definition: control_cmd_args_st.h:24
entry_connection_st.h
Entry connection structure.
options_dump
char * options_dump(const or_options_t *options, int how_to_dump)
Definition: config.c:2929
we_want_to_fetch_flavor
int we_want_to_fetch_flavor(const or_options_t *options, int flavor)
Definition: networkstatus.c:862
tor_addr_t
Definition: address.h:69
control_connection_t::ephemeral_onion_services
smartlist_t * ephemeral_onion_services
Definition: control_connection_st.h:33
VS_NEW
@ VS_NEW
Definition: versions.h:20
extrainfo_t
Definition: extrainfo_st.h:18
circuit_get_global_list
smartlist_t * circuit_get_global_list(void)
Definition: circuitlist.c:696
tor_version_is_obsolete
version_status_t tor_version_is_obsolete(const char *myversion, const char *versionlist)
Definition: versions.c:53
get_bytes_read
uint64_t get_bytes_read(void)
Definition: mainloop.c:465
format_iso_time_nospace
void format_iso_time_nospace(char *buf, time_t t)
Definition: time_fmt.c:313
getinfo_helper_downloads
STATIC int getinfo_helper_downloads(control_connection_t *control_conn, const char *question, char **answer, const char **errmsg)
Definition: control_getinfo.c:1076
AP_CONN_STATE_CIRCUIT_WAIT
#define AP_CONN_STATE_CIRCUIT_WAIT
Definition: connection_edge.h:49
tor_assert
#define tor_assert(expr)
Definition: util_bug.h:102
control.h
Header file for control.c.
relay_find_addr.h
Header file for relay_find_addr.c.
microdesc.h
Header file for microdesc.c.
LD_BUG
#define LD_BUG
Definition: log.h:86
handle_getinfo_helper
static int handle_getinfo_helper(control_connection_t *control_conn, const char *question, char **answer, const char **err_out)
Definition: control_getinfo.c:1747
router.h
Header file for router.c.
getinfo_helper_dir
STATIC int getinfo_helper_dir(control_connection_t *control_conn, const char *question, char **answer, const char **errmsg)
Definition: control_getinfo.c:462
authcert.h
Header file for authcert.c.
format_iso_time
void format_iso_time(char *buf, time_t t)
Definition: time_fmt.c:295
router_digest_is_me
int router_digest_is_me(const char *digest)
Definition: router.c:1723
CONN_TYPE_AP_TRANS_LISTENER
#define CONN_TYPE_AP_TRANS_LISTENER
Definition: connection.h:63
AP_CONN_STATE_NATD_WAIT
#define AP_CONN_STATE_NATD_WAIT
Definition: connection_edge.h:58
router_get_descriptor_digests
smartlist_t * router_get_descriptor_digests(void)
Definition: networkstatus.c:801
base16_encode
void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen)
Definition: binascii.c:478
tor_fragile_assert
#define tor_fragile_assert()
Definition: util_bug.h:270
router_get_my_routerinfo
const routerinfo_t * router_get_my_routerinfo(void)
Definition: router.c:1785
getinfo_helper_t
int(* getinfo_helper_t)(control_connection_t *, const char *q, char **a, const char **error_out)
Definition: control_getinfo.c:1504
control_proto.h
Header file for control_proto.c.
extrainfo_get_by_descriptor_digest
signed_descriptor_t * extrainfo_get_by_descriptor_digest(const char *digest)
Definition: routerlist.c:810
signed_descriptor_t::annotations_len
size_t annotations_len
Definition: signed_descriptor_st.h:24
node_get_by_nickname
const node_t * node_get_by_nickname(const char *nickname, unsigned flags)
Definition: nodelist.c:1005
smartlist_add
void smartlist_add(smartlist_t *sl, void *element)
Definition: smartlist_core.c:117
we_fetch_microdescriptors
int we_fetch_microdescriptors(const or_options_t *options)
Definition: microdesc.c:1064
CONN_TYPE_AP_DNS_LISTENER
#define CONN_TYPE_AP_DNS_LISTENER
Definition: connection.h:68
list_sk_digests_for_authority_id
smartlist_t * list_sk_digests_for_authority_id(const char *digest)
Definition: authcert.c:247
routerlist_t::routers
smartlist_t * routers
Definition: routerlist_st.h:32
VS_EMPTY
@ VS_EMPTY
Definition: versions.h:25
tor_mmap_t::data
const char * data
Definition: mmap.h:26
addressmap_get_mappings
void addressmap_get_mappings(smartlist_t *sl, time_t min_expires, time_t max_expires, int want_expiry)
Definition: addressmap.c:1114
relay_find_addr_to_publish
bool relay_find_addr_to_publish(const or_options_t *options, int family, int flags, tor_addr_t *addr_out)
Definition: relay_find_addr.c:107
get_torrc_fname
const char * get_torrc_fname(int defaults_fname)
Definition: config.c:4749
getinfo_helper_sr
static int getinfo_helper_sr(control_connection_t *control_conn, const char *question, char **answer, const char **errmsg)
Definition: control_getinfo.c:1479
version_status_t
version_status_t
Definition: versions.h:17
control_cmd_syntax_t::max_args
unsigned int max_args
Definition: control_cmd.h:46
get_detached_onion_services
smartlist_t * get_detached_onion_services(void)
Definition: control_cmd.c:1690
hostname_type_t
hostname_type_t
Definition: connection_edge.h:79
smartlist_new
smartlist_t * smartlist_new(void)
Definition: smartlist_core.c:26
control_event_boot_last_msg
char * control_event_boot_last_msg(void)
Definition: control_bootstrap.c:384
socks_request_st.h
Client request structure.
or_connection_t
Definition: or_connection_st.h:22
CIRCUIT_IS_ORIGIN
#define CIRCUIT_IS_ORIGIN(c)
Definition: circuitlist.h:148
get_version
const char * get_version(void)
Definition: version.c:38
hs_address_is_valid
int hs_address_is_valid(const char *address)
Definition: hs_common.c:979
microdesc_t::body
char * body
Definition: microdesc_st.h:58
SMARTLIST_FOREACH
#define SMARTLIST_FOREACH(sl, type, var, cmd)
Definition: smartlist_foreach.h:112
tor_mmap_t::size
size_t size
Definition: mmap.h:27
router_extrainfo_digest_is_me
int router_extrainfo_digest_is_me(const char *digest)
Definition: router.c:1739
getinfo_helper_liveness
static int getinfo_helper_liveness(control_connection_t *control_conn, const char *question, char **answer, const char **errmsg)
Definition: control_getinfo.c:1426
dir_split_resource_into_fingerprints
int dir_split_resource_into_fingerprints(const char *resource, smartlist_t *fp_out, int *compressed_out, int flags)
Definition: directory.c:644
CONN_TYPE_EXT_OR_LISTENER
#define CONN_TYPE_EXT_OR_LISTENER
Definition: connection.h:73
list_authority_ids_with_downloads
smartlist_t * list_authority_ids_with_downloads(void)
Definition: authcert.c:196
download_status_t::schedule
download_schedule_bitfield_t schedule
Definition: download_status_st.h:49
networkstatus.h
Header file for networkstatus.c.
origin_circuit_t::global_identifier
uint32_t global_identifier
Definition: origin_circuit_st.h:240
download_status_t::last_backoff_position
uint8_t last_backoff_position
Definition: download_status_st.h:61
CONN_TYPE_OR_LISTENER
#define CONN_TYPE_OR_LISTENER
Definition: connection.h:41
geoip_stats.h
Header file for geoip_stats.c.
router_get_by_id_digest
const routerinfo_t * router_get_by_id_digest(const char *digest)
Definition: routerlist.c:776
rend_cache_lookup_entry
int rend_cache_lookup_entry(const char *query, int version, rend_cache_entry_t **e)
Definition: rendcache.c:523
getinfo_helper_downloads_desc
STATIC void getinfo_helper_downloads_desc(const char *desc_req, download_status_t **dl_to_emit, smartlist_t **digest_list, const char **errmsg)
Definition: control_getinfo.c:987
router_build_fresh_descriptor
int router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e)
Definition: router.c:2380
consensus_flavor_t
consensus_flavor_t
Definition: or.h:881
control_cmd_args_t::args
struct smartlist_t * args
Definition: control_cmd_args_st.h:33
hs_cache.h
Header file for hs_cache.c.
get_bytes_written
uint64_t get_bytes_written(void)
Definition: mainloop.c:475
base16_decode
int base16_decode(char *dest, size_t destlen, const char *src, size_t srclen)
Definition: binascii.c:506
hibernate.h
Header file for hibernate.c.
ENTRY_TO_EDGE_CONN
#define ENTRY_TO_EDGE_CONN(c)
Definition: entry_connection_st.h:102
get_bridge_dl_status_by_id
download_status_t * get_bridge_dl_status_by_id(const char *digest)
Definition: bridges.c:998
circuitlist.h
Header file for circuitlist.c.
mainloop.h
Header file for mainloop.c.
DIGEST_LEN
#define DIGEST_LEN
Definition: digest_sizes.h:20
geoip_get_bridge_stats_controller
char * geoip_get_bridge_stats_controller(time_t)
Definition: geoip_stats.c:1309
CONN_TYPE_AP
#define CONN_TYPE_AP
Definition: connection.h:51
AP_CONN_STATE_RESOLVE_WAIT
#define AP_CONN_STATE_RESOLVE_WAIT
Definition: connection_edge.h:53
OR_CONN_STATE_OPEN
#define OR_CONN_STATE_OPEN
Definition: orconn_event.h:53
CONN_TYPE_CONTROL_LISTENER
#define CONN_TYPE_CONTROL_LISTENER
Definition: connection.h:58
signed_descriptor_get_body
const char * signed_descriptor_get_body(const signed_descriptor_t *desc)
Definition: routerlist.c:880
download_status_t::want_authority
download_want_authority_bitfield_t want_authority
Definition: download_status_st.h:53
getinfo_helper_downloads_bridge
STATIC void getinfo_helper_downloads_bridge(const char *bridge_req, download_status_t **dl_to_emit, smartlist_t **digest_list, const char **errmsg)
Definition: control_getinfo.c:1033
tor_sockaddr_to_str
char * tor_sockaddr_to_str(const struct sockaddr *sa)
Definition: address.c:198
bridges.h
Header file for circuitbuild.c.
routerlist_t
Definition: routerlist_st.h:18
TO_ENTRY_CONN
entry_connection_t * TO_ENTRY_CONN(connection_t *c)
Definition: connection_edge.c:202
control_reply_free
#define control_reply_free(r)
Free and null a smartlist of control_reply_line_t.
Definition: control_proto.h:116
getinfo_helper_current_consensus
STATIC int getinfo_helper_current_consensus(consensus_flavor_t flavor, char **answer, const char **errmsg)
Definition: control_getinfo.c:347
entrynodes.h
Header file for circuitbuild.c.
networkstatus_get_latest_consensus
networkstatus_t * networkstatus_get_latest_consensus(void)
Definition: networkstatus.c:1390
getinfo_helper_listeners
static int getinfo_helper_listeners(control_connection_t *control_conn, const char *question, char **answer, const char **errmsg)
Definition: control_getinfo.c:261
control_event_table
const struct control_event_t control_event_table[]
Definition: control_events.c:80
node_t
Definition: node_st.h:34
origin_circuit_t
Definition: origin_circuit_st.h:79
getinfo_geoip.h
Header for getinfo_geoip.c.
list_bridge_identities
smartlist_t * list_bridge_identities(void)
Definition: bridges.c:978
LD_CONTROL
#define LD_CONTROL
Definition: log.h:80
AP_CONN_STATE_CONNECT_WAIT
#define AP_CONN_STATE_CONNECT_WAIT
Definition: connection_edge.h:51
networkstatus_t::client_versions
char * client_versions
Definition: networkstatus_st.h:56
router_get_dl_status_by_descriptor_digest
download_status_t * router_get_dl_status_by_descriptor_digest(const char *d)
Definition: networkstatus.c:816
list_getinfo_options
static char * list_getinfo_options(void)
Definition: control_getinfo.c:1719
CONN_TYPE_METRICS_LISTENER
#define CONN_TYPE_METRICS_LISTENER
Definition: connection.h:77
getinfo_item_t::fn
getinfo_helper_t fn
Definition: control_getinfo.c:1511
digest_list_to_string
static char * digest_list_to_string(const smartlist_t *sl)
Definition: control_getinfo.c:755
directory.h
Header file for directory.c.
CONN_TYPE_OR
#define CONN_TYPE_OR
Definition: connection.h:44
control_reply_add_done
void control_reply_add_done(smartlist_t *reply)
Definition: control_proto.c:401
cached_dir_st.h
Cached large directory object structure.
getinfo_item_t::varname
const char * varname
Definition: control_getinfo.c:1510
ed25519_public_key_t
Definition: crypto_ed25519.h:23
download_status_t::last_delay_used
int last_delay_used
Definition: download_status_st.h:65
tor_getpwuid
const struct passwd * tor_getpwuid(uid_t uid)
Definition: userdb.c:106
AP_CONN_STATE_SOCKS_WAIT
#define AP_CONN_STATE_SOCKS_WAIT
Definition: connection_edge.h:41
CONN_TYPE_AP_HTTP_CONNECT_LISTENER
#define CONN_TYPE_AP_HTTP_CONNECT_LISTENER
Definition: connection.h:75
controller_get_routerdescs
static int controller_get_routerdescs(smartlist_t *descs_out, const char *key, const char **msg)
Definition: control_getinfo.c:397
strcmpstart
int strcmpstart(const char *s1, const char *s2)
Definition: util_string.c:215
we_fetch_router_descriptors
int we_fetch_router_descriptors(const or_options_t *options)
Definition: microdesc.c:1075
control_cmd_syntax_t
Definition: control_cmd.h:36
microdesc_st.h
Microdescriptor structure.
download_status_t
Definition: download_status_st.h:41
routerlist_st.h
Router descriptor list structure.
get_connection_array
smartlist_t * get_connection_array(void)
Definition: mainloop.c:453
tor_mmap_t
Definition: mmap.h:25
AP_CONN_STATE_RENDDESC_WAIT
#define AP_CONN_STATE_RENDDESC_WAIT
Definition: connection_edge.h:44
circuit_t
Definition: circuit_st.h:61
nodelist.h
Header file for nodelist.c.
rend_valid_v2_service_id
int rend_valid_v2_service_id(const char *query)
Definition: rendcommon.c:725
routerlist.h
Header file for routerlist.c.
have_completed_a_circuit
int have_completed_a_circuit(void)
Definition: mainloop.c:220
predict_ports.h
Header file for predict_ports.c.
rep_hist_get_circuit_handshake_assigned
int rep_hist_get_circuit_handshake_assigned(uint16_t type)
Definition: rephist.c:1686
dirserv_get_consensus
cached_dir_t * dirserv_get_consensus(const char *flavor_name)
Definition: dirserv.c:201
routerinfo_st.h
Router descriptor structure.
tor_gettimeofday
void tor_gettimeofday(struct timeval *timeval)
Definition: tor_gettimeofday.c:42
ROUTER_MAX_AGE_TO_PUBLISH
#define ROUTER_MAX_AGE_TO_PUBLISH
Definition: or.h:161
tor_addr_to_str_dup
char * tor_addr_to_str_dup(const tor_addr_t *addr)
Definition: address.c:1164
cached_dir_t
Definition: cached_dir_st.h:17
getinfo_items
static const getinfo_item_t getinfo_items[]
Definition: control_getinfo.c:1523
getinfo_helper_downloads_cert
STATIC void getinfo_helper_downloads_cert(const char *fp_sk_req, download_status_t **dl_to_emit, smartlist_t **digest_list, const char **errmsg)
Definition: control_getinfo.c:887
networkstatus_get_dl_status_by_flavor
download_status_t * networkstatus_get_dl_status_by_flavor(consensus_flavor_t flavor)
Definition: networkstatus.c:1345
connection_t
Definition: connection_st.h:45
rendcache.h
Header file for rendcache.c.
rep_hist_get_circuit_handshake_requested
int rep_hist_get_circuit_handshake_requested(uint16_t type)
Definition: rephist.c:1676
router_get_by_descriptor_digest
signed_descriptor_t * router_get_by_descriptor_digest(const char *digest)
Definition: routerlist.c:784
sr_get_previous_for_control
char * sr_get_previous_for_control(void)
Definition: shared_random_client.c:131
entry_connection_t::socks_request
socks_request_t * socks_request
Definition: entry_connection_st.h:27
routerlist
static routerlist_t * routerlist
Definition: routerlist.c:147
get_max_sockets
int get_max_sockets(void)
Definition: socket.c:98
control_events.h
Header file for control_events.c.
id_only_download_status_for_authority_id
download_status_t * id_only_download_status_for_authority_id(const char *digest)
Definition: authcert.c:227
get_options
const or_options_t * get_options(void)
Definition: config.c:932
AP_CONN_STATE_OPEN
#define AP_CONN_STATE_OPEN
Definition: connection_edge.h:55
getinfo_helper_onions
STATIC int getinfo_helper_onions(control_connection_t *control_conn, const char *question, char **answer, const char **errmsg)
Definition: control_getinfo.c:1396
download_status_t::increment_on
download_schedule_increment_bitfield_t increment_on
Definition: download_status_st.h:58
addressmap.h
Header for addressmap.c.
getinfo_helper_downloads_networkstatus
STATIC void getinfo_helper_downloads_networkstatus(const char *flavor, download_status_t **dl_to_emit, const char **errmsg)
Definition: control_getinfo.c:858
download_status_t::n_download_attempts
uint8_t n_download_attempts
Definition: download_status_st.h:46
smartlist_sort_strings
void smartlist_sort_strings(smartlist_t *sl)
Definition: smartlist.c:549
origin_circuit_t::cpath
crypt_path_t * cpath
Definition: origin_circuit_st.h:129
control_write_reply_lines
void control_write_reply_lines(control_connection_t *conn, smartlist_t *lines)
Definition: control_proto.c:317
nodelist_get_list
const smartlist_t * nodelist_get_list(void)
Definition: nodelist.c:967
TO_ORIGIN_CIRCUIT
origin_circuit_t * TO_ORIGIN_CIRCUIT(circuit_t *x)
Definition: circuitlist.c:168
connection.h
Header file for connection.c.
networkstatus_get_dl_status_by_flavor_bootstrap
download_status_t * networkstatus_get_dl_status_by_flavor_bootstrap(consensus_flavor_t flavor)
Definition: networkstatus.c:1362
control_cmd.h
Header file for control_cmd.c.
signed_descriptor_get_annotations
const char * signed_descriptor_get_annotations(const signed_descriptor_t *desc)
Definition: routerlist.c:888
extrainfo_st.h
A relay's extra-info structure.
control_reply_add_printf
void control_reply_add_printf(smartlist_t *reply, int code, const char *fmt,...)
Definition: control_proto.c:387
handle_control_getinfo
int handle_control_getinfo(control_connection_t *conn, const control_cmd_args_t *args)
Definition: control_getinfo.c:1776
networkstatus_get_dl_status_by_flavor_running
download_status_t * networkstatus_get_dl_status_by_flavor_running(consensus_flavor_t flavor)
Definition: networkstatus.c:1376
dirserv.h
Header file for dirserv.c.
server_mode
int server_mode(const or_options_t *options)
Definition: routermode.c:34
crypto_pk_get_fingerprint
int crypto_pk_get_fingerprint(crypto_pk_t *pk, char *fp_out, int add_space)
Definition: crypto_rsa.c:229
timeval
Definition: compat_time.h:151
dirclient.h
Header file for dirclient.c.
tor_asprintf
int tor_asprintf(char **strp, const char *fmt,...)
Definition: printf.c:75
getinfo_helper_misc
static int getinfo_helper_misc(control_connection_t *conn, const char *question, char **answer, const char **errmsg)
Definition: control_getinfo.c:85
or_connection_st.h
OR connection structure.
kvline.h
Header for kvline.c.
download_status_get_next_attempt_at
time_t download_status_get_next_attempt_at(const download_status_t *dls)
Definition: dlstatus.c:418
SMARTLIST_FOREACH_BEGIN
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
Definition: smartlist_foreach.h:78
dlstatus.h
Header file for dlstatus.c.
sr_get_current_for_control
char * sr_get_current_for_control(void)
Definition: shared_random_client.c:115
crypto_pk_t
Definition: crypto_rsa_nss.c:37
VS_UNRECOMMENDED
@ VS_UNRECOMMENDED
Definition: versions.h:24
router_dirport_seems_reachable
int router_dirport_seems_reachable(const or_options_t *options)
Definition: selftest.c:148
router_get_routerlist
routerlist_t * router_get_routerlist(void)
Definition: routerlist.c:895
directories_have_accepted_server_descriptor
int directories_have_accepted_server_descriptor(void)
Definition: dirclient.c:206
HEX_DIGEST_LEN
#define HEX_DIGEST_LEN
Definition: crypto_digest.h:35
node_st.h
Node information structure.
router_get_my_extrainfo
extrainfo_t * router_get_my_extrainfo(void)
Definition: router.c:1838
control_connection_t
Definition: control_connection_st.h:19
VS_UNKNOWN
@ VS_UNKNOWN
Definition: versions.h:26
policies.h
Header file for policies.c.
VS_NEW_IN_SERIES
@ VS_NEW_IN_SERIES
Definition: versions.h:21
control_write_endreply
void control_write_endreply(control_connection_t *conn, int code, const char *s)
Definition: control_proto.c:214
hs_service_lookup_current_desc
char * hs_service_lookup_current_desc(const ed25519_public_key_t *pk)
Definition: hs_service.c:3822
getinfo_helper_events
static int getinfo_helper_events(control_connection_t *control_conn, const char *question, char **answer, const char **errmsg)
Definition: control_getinfo.c:1138
rend_cache_entry_t::desc
char * desc
Definition: rendcache.h:33
shared_random_client.h
Header file for shared_random_client.c.
getinfo_helper_rephist
STATIC int getinfo_helper_rephist(control_connection_t *control_conn, const char *question, char **answer, const char **errmsg)
Definition: control_getinfo.c:1446
config.h
Header file for config.c.
control_reply_add_str
void control_reply_add_str(smartlist_t *reply, int code, const char *s)
Definition: control_proto.c:375
smartlist_add_asprintf
void smartlist_add_asprintf(struct smartlist_t *sl, const char *pattern,...)
Definition: smartlist.c:36
munge_extrainfo_into_routerinfo
static char * munge_extrainfo_into_routerinfo(const char *ri_body, const signed_descriptor_t *ri, const signed_descriptor_t *ei)
Definition: control_getinfo.c:217
hs_parse_address
int hs_parse_address(const char *address, ed25519_public_key_t *key_out, uint8_t *checksum_out, uint8_t *version_out)
Definition: hs_common.c:963
esc_for_log
char * esc_for_log(const char *s)
Definition: escape.c:30
node_get_by_hex_id
const node_t * node_get_by_hex_id(const char *hex_id, unsigned flags)
Definition: nodelist.c:978
connection_t::state
uint8_t state
Definition: connection_st.h:49
signed_descriptor_t::published_on
time_t published_on
Definition: signed_descriptor_st.h:33
orconn_target_get_name
void orconn_target_get_name(char *name, size_t len, or_connection_t *conn)
Definition: control_fmt.c:54
CIRCUIT_STATE_GUARD_WAIT
#define CIRCUIT_STATE_GUARD_WAIT
Definition: circuitlist.h:30
socks_request_t::command
uint8_t command
Definition: socks_request_st.h:47
getinfo_helper_current_time
STATIC int getinfo_helper_current_time(control_connection_t *control_conn, const char *question, char **answer, const char **errmsg)
Definition: control_getinfo.c:322
networkstatus_map_cached_consensus
tor_mmap_t * networkstatus_map_cached_consensus(const char *flavorname)
Definition: networkstatus.c:262
signed_descriptor_t
Definition: signed_descriptor_st.h:18
or_options_t
Definition: or_options_st.h:64
get_uptime
long get_uptime(void)
Definition: mainloop.c:2527
download_status_to_string
static char * download_status_to_string(const download_status_t *dl)
Definition: control_getinfo.c:779
microdesc_t::bodylen
size_t bodylen
Definition: microdesc_st.h:60
STATIC
#define STATIC
Definition: testsupport.h:32
signed_descriptor_t::signed_descriptor_len
size_t signed_descriptor_len
Definition: signed_descriptor_st.h:26
AP_CONN_STATE_CONTROLLER_WAIT
#define AP_CONN_STATE_CONTROLLER_WAIT
Definition: connection_edge.h:47
router_have_minimum_dir_info
int router_have_minimum_dir_info(void)
Definition: nodelist.c:2347
CONN_TYPE_AP_LISTENER
#define CONN_TYPE_AP_LISTENER
Definition: connection.h:48
VS_RECOMMENDED
@ VS_RECOMMENDED
Definition: versions.h:18
write_stream_target_to_buf
int write_stream_target_to_buf(entry_connection_t *conn, char *buf, size_t len)
Definition: control_fmt.c:32
networkstatus_st.h
Networkstatus consensus/vote structure.
entry_connection_t
Definition: entry_connection_st.h:19
cached_dir_t::dir
char * dir
Definition: cached_dir_st.h:18
networkstatus_t
Definition: networkstatus_st.h:26
origin_circuit_st.h
Origin circuit structure.
VS_OLD
@ VS_OLD
Definition: versions.h:19
circuit_get_by_edge_conn
circuit_t * circuit_get_by_edge_conn(edge_connection_t *conn)
Definition: circuitlist.c:1588
download_status_for_authority_id_and_sk
download_status_t * download_status_for_authority_id_and_sk(const char *id_digest, const char *sk_digest)
Definition: authcert.c:282
smartlist_t
Definition: smartlist_core.h:26
getinfo_item_t::desc
const char * desc
Definition: control_getinfo.c:1513
smartlist_join_strings
char * smartlist_join_strings(smartlist_t *sl, const char *join, int terminate, size_t *len_out)
Definition: smartlist.c:279
TO_OR_CONN
or_connection_t * TO_OR_CONN(connection_t *c)
Definition: connection_or.c:108
torversion.h
Header for version.c.
control_cmd_args_st.h
Definition for control_cmd_args_t.
circuit_t::state
uint8_t state
Definition: circuit_st.h:110
download_status_t::n_download_failures
uint8_t n_download_failures
Definition: download_status_st.h:44
control_fmt.h
Header file for control_fmt.c.
format_local_iso_time_nospace
void format_local_iso_time_nospace(char *buf, time_t t)
Definition: time_fmt.c:304
CONN_TYPE_DIR_LISTENER
#define CONN_TYPE_DIR_LISTENER
Definition: connection.h:53
rephist.h
Header file for rephist.c.
CONN_TYPE_AP_NATD_LISTENER
#define CONN_TYPE_AP_NATD_LISTENER
Definition: connection.h:66
hs_cache_lookup_encoded_as_client
const char * hs_cache_lookup_encoded_as_client(const ed25519_public_key_t *key)
Definition: hs_cache.c:816
control_connection_st.h
Controller connection structure.
connection_or.h
Header file for connection_or.c.
or_connection_t::nickname
char * nickname
Definition: or_connection_st.h:42
SOCKET_OK
#define SOCKET_OK(s)
Definition: nettypes.h:39
or.h
Master header file for Tor-specific functionality.
rep_hist_circbuilding_dormant
int rep_hist_circbuilding_dormant(time_t now)
Definition: predict_ports.c:264