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