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