control_fmt.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  2. * Copyright (c) 2007-2019, The Tor Project, Inc. */
  3. /* See LICENSE for licensing information */
  4. /**
  5. * \file control_fmt.c
  6. * \brief Formatting functions for controller data.
  7. */
  8. #include "core/or/or.h"
  9. #include "core/mainloop/connection.h"
  10. #include "core/or/circuitbuild.h"
  11. #include "core/or/circuitlist.h"
  12. #include "core/or/connection_edge.h"
  13. #include "feature/control/control_fmt.h"
  14. #include "feature/control/control_proto.h"
  15. #include "feature/nodelist/nodelist.h"
  16. #include "core/or/cpath_build_state_st.h"
  17. #include "core/or/entry_connection_st.h"
  18. #include "core/or/or_connection_st.h"
  19. #include "core/or/origin_circuit_st.h"
  20. #include "core/or/socks_request_st.h"
  21. #include "feature/control/control_connection_st.h"
  22. /** Given an AP connection <b>conn</b> and a <b>len</b>-character buffer
  23. * <b>buf</b>, determine the address:port combination requested on
  24. * <b>conn</b>, and write it to <b>buf</b>. Return 0 on success, -1 on
  25. * failure. */
  26. int
  27. write_stream_target_to_buf(entry_connection_t *conn, char *buf, size_t len)
  28. {
  29. char buf2[256];
  30. if (conn->chosen_exit_name)
  31. if (tor_snprintf(buf2, sizeof(buf2), ".%s.exit", conn->chosen_exit_name)<0)
  32. return -1;
  33. if (!conn->socks_request)
  34. return -1;
  35. if (tor_snprintf(buf, len, "%s%s%s:%d",
  36. conn->socks_request->address,
  37. conn->chosen_exit_name ? buf2 : "",
  38. !conn->chosen_exit_name && connection_edge_is_rendezvous_stream(
  39. ENTRY_TO_EDGE_CONN(conn)) ? ".onion" : "",
  40. conn->socks_request->port)<0)
  41. return -1;
  42. return 0;
  43. }
  44. /** Figure out the best name for the target router of an OR connection
  45. * <b>conn</b>, and write it into the <b>len</b>-character buffer
  46. * <b>name</b>. */
  47. void
  48. orconn_target_get_name(char *name, size_t len, or_connection_t *conn)
  49. {
  50. const node_t *node = node_get_by_id(conn->identity_digest);
  51. if (node) {
  52. tor_assert(len > MAX_VERBOSE_NICKNAME_LEN);
  53. node_get_verbose_nickname(node, name);
  54. } else if (! tor_digest_is_zero(conn->identity_digest)) {
  55. name[0] = '$';
  56. base16_encode(name+1, len-1, conn->identity_digest,
  57. DIGEST_LEN);
  58. } else {
  59. tor_snprintf(name, len, "%s:%d",
  60. conn->base_.address, conn->base_.port);
  61. }
  62. }
  63. /** Allocate and return a description of <b>circ</b>'s current status,
  64. * including its path (if any). */
  65. char *
  66. circuit_describe_status_for_controller(origin_circuit_t *circ)
  67. {
  68. char *rv;
  69. smartlist_t *descparts = smartlist_new();
  70. {
  71. char *vpath = circuit_list_path_for_controller(circ);
  72. if (*vpath) {
  73. smartlist_add(descparts, vpath);
  74. } else {
  75. tor_free(vpath); /* empty path; don't put an extra space in the result */
  76. }
  77. }
  78. {
  79. cpath_build_state_t *build_state = circ->build_state;
  80. smartlist_t *flaglist = smartlist_new();
  81. char *flaglist_joined;
  82. if (build_state->onehop_tunnel)
  83. smartlist_add(flaglist, (void *)"ONEHOP_TUNNEL");
  84. if (build_state->is_internal)
  85. smartlist_add(flaglist, (void *)"IS_INTERNAL");
  86. if (build_state->need_capacity)
  87. smartlist_add(flaglist, (void *)"NEED_CAPACITY");
  88. if (build_state->need_uptime)
  89. smartlist_add(flaglist, (void *)"NEED_UPTIME");
  90. /* Only emit a BUILD_FLAGS argument if it will have a non-empty value. */
  91. if (smartlist_len(flaglist)) {
  92. flaglist_joined = smartlist_join_strings(flaglist, ",", 0, NULL);
  93. smartlist_add_asprintf(descparts, "BUILD_FLAGS=%s", flaglist_joined);
  94. tor_free(flaglist_joined);
  95. }
  96. smartlist_free(flaglist);
  97. }
  98. smartlist_add_asprintf(descparts, "PURPOSE=%s",
  99. circuit_purpose_to_controller_string(circ->base_.purpose));
  100. {
  101. const char *hs_state =
  102. circuit_purpose_to_controller_hs_state_string(circ->base_.purpose);
  103. if (hs_state != NULL) {
  104. smartlist_add_asprintf(descparts, "HS_STATE=%s", hs_state);
  105. }
  106. }
  107. if (circ->rend_data != NULL || circ->hs_ident != NULL) {
  108. char addr[HS_SERVICE_ADDR_LEN_BASE32 + 1];
  109. const char *onion_address;
  110. if (circ->rend_data) {
  111. onion_address = rend_data_get_address(circ->rend_data);
  112. } else {
  113. hs_build_address(&circ->hs_ident->identity_pk, HS_VERSION_THREE, addr);
  114. onion_address = addr;
  115. }
  116. smartlist_add_asprintf(descparts, "REND_QUERY=%s", onion_address);
  117. }
  118. {
  119. char tbuf[ISO_TIME_USEC_LEN+1];
  120. format_iso_time_nospace_usec(tbuf, &circ->base_.timestamp_created);
  121. smartlist_add_asprintf(descparts, "TIME_CREATED=%s", tbuf);
  122. }
  123. // Show username and/or password if available.
  124. if (circ->socks_username_len > 0) {
  125. char* socks_username_escaped = esc_for_log_len(circ->socks_username,
  126. (size_t) circ->socks_username_len);
  127. smartlist_add_asprintf(descparts, "SOCKS_USERNAME=%s",
  128. socks_username_escaped);
  129. tor_free(socks_username_escaped);
  130. }
  131. if (circ->socks_password_len > 0) {
  132. char* socks_password_escaped = esc_for_log_len(circ->socks_password,
  133. (size_t) circ->socks_password_len);
  134. smartlist_add_asprintf(descparts, "SOCKS_PASSWORD=%s",
  135. socks_password_escaped);
  136. tor_free(socks_password_escaped);
  137. }
  138. rv = smartlist_join_strings(descparts, " ", 0, NULL);
  139. SMARTLIST_FOREACH(descparts, char *, cp, tor_free(cp));
  140. smartlist_free(descparts);
  141. return rv;
  142. }
  143. /** Return a longname the node whose identity is <b>id_digest</b>. If
  144. * node_get_by_id() returns NULL, base 16 encoding of <b>id_digest</b> is
  145. * returned instead.
  146. *
  147. * This function is not thread-safe. Each call to this function invalidates
  148. * previous values returned by this function.
  149. */
  150. MOCK_IMPL(const char *,
  151. node_describe_longname_by_id,(const char *id_digest))
  152. {
  153. static char longname[MAX_VERBOSE_NICKNAME_LEN+1];
  154. node_get_verbose_nickname_by_id(id_digest, longname);
  155. return longname;
  156. }