describe.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. /* Copyright (c) 2001 Matej Pfajfar.
  2. * Copyright (c) 2001-2004, Roger Dingledine.
  3. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  4. * Copyright (c) 2007-2019, The Tor Project, Inc. */
  5. /* See LICENSE for licensing information */
  6. /**
  7. * \file describe.c
  8. * \brief Format short descriptions of relays.
  9. */
  10. #define DESCRIBE_PRIVATE
  11. #include "core/or/or.h"
  12. #include "feature/nodelist/describe.h"
  13. #include "core/or/extend_info_st.h"
  14. #include "feature/nodelist/node_st.h"
  15. #include "feature/nodelist/routerinfo_st.h"
  16. #include "feature/nodelist/routerstatus_st.h"
  17. #include "feature/nodelist/microdesc_st.h"
  18. /** Use <b>buf</b> (which must be at least NODE_DESC_BUF_LEN bytes long) to
  19. * hold a human-readable description of a node with identity digest
  20. * <b>id_digest</b>, nickname <b>nickname</b>, and addresses <b>addr32h</b> and
  21. * <b>addr</b>.
  22. *
  23. * The <b>nickname</b> and <b>addr</b> fields are optional and may be set to
  24. * NULL or the null address. The <b>addr32h</b> field is optional and may be
  25. * set to 0.
  26. *
  27. * Return a pointer to the front of <b>buf</b>.
  28. * If buf is NULL, return a string constant describing the error.
  29. */
  30. STATIC const char *
  31. format_node_description(char *buf,
  32. const char *id_digest,
  33. const char *nickname,
  34. const tor_addr_t *addr,
  35. uint32_t addr32h)
  36. {
  37. size_t rv = 0;
  38. bool has_addr = addr && !tor_addr_is_null(addr);
  39. if (!buf)
  40. return "<NULL BUFFER>";
  41. memset(buf, 0, NODE_DESC_BUF_LEN);
  42. if (!id_digest) {
  43. /* strlcpy() returns the length of the source string it attempted to copy,
  44. * ignoring any required truncation due to the buffer length. */
  45. rv = strlcpy(buf, "<NULL ID DIGEST>", NODE_DESC_BUF_LEN);
  46. tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
  47. return buf;
  48. }
  49. /* strlcat() returns the length of the concatenated string it attempted to
  50. * create, ignoring any required truncation due to the buffer length. */
  51. rv = strlcat(buf, "$", NODE_DESC_BUF_LEN);
  52. tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
  53. {
  54. char hex_digest[HEX_DIGEST_LEN+1];
  55. memset(hex_digest, 0, sizeof(hex_digest));
  56. base16_encode(hex_digest, sizeof(hex_digest),
  57. id_digest, DIGEST_LEN);
  58. rv = strlcat(buf, hex_digest, NODE_DESC_BUF_LEN);
  59. tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
  60. }
  61. if (nickname) {
  62. rv = strlcat(buf, "~", NODE_DESC_BUF_LEN);
  63. tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
  64. rv = strlcat(buf, nickname, NODE_DESC_BUF_LEN);
  65. tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
  66. }
  67. if (addr32h || has_addr) {
  68. rv = strlcat(buf, " at ", NODE_DESC_BUF_LEN);
  69. tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
  70. }
  71. if (addr32h) {
  72. int ntoa_rv = 0;
  73. char ipv4_addr_str[INET_NTOA_BUF_LEN];
  74. memset(ipv4_addr_str, 0, sizeof(ipv4_addr_str));
  75. struct in_addr in;
  76. memset(&in, 0, sizeof(in));
  77. in.s_addr = htonl(addr32h);
  78. ntoa_rv = tor_inet_ntoa(&in, ipv4_addr_str, sizeof(ipv4_addr_str));
  79. tor_assert_nonfatal(ntoa_rv >= 0);
  80. rv = strlcat(buf, ipv4_addr_str, NODE_DESC_BUF_LEN);
  81. tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
  82. }
  83. /* Both addresses are valid */
  84. if (addr32h && has_addr) {
  85. rv = strlcat(buf, " and ", NODE_DESC_BUF_LEN);
  86. tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
  87. }
  88. if (has_addr) {
  89. const char *str_rv = NULL;
  90. char addr_str[TOR_ADDR_BUF_LEN];
  91. memset(addr_str, 0, sizeof(addr_str));
  92. str_rv = tor_addr_to_str(addr_str, addr, sizeof(addr_str), 1);
  93. tor_assert_nonfatal(str_rv == addr_str);
  94. rv = strlcat(buf, addr_str, NODE_DESC_BUF_LEN);
  95. tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
  96. }
  97. return buf;
  98. }
  99. /** Return a human-readable description of the routerinfo_t <b>ri</b>.
  100. *
  101. * This function is not thread-safe. Each call to this function invalidates
  102. * previous values returned by this function.
  103. */
  104. const char *
  105. router_describe(const routerinfo_t *ri)
  106. {
  107. static char buf[NODE_DESC_BUF_LEN];
  108. if (!ri)
  109. return "<null>";
  110. return format_node_description(buf,
  111. ri->cache_info.identity_digest,
  112. ri->nickname,
  113. &ri->ipv6_addr,
  114. ri->addr);
  115. }
  116. /** Return a human-readable description of the node_t <b>node</b>.
  117. *
  118. * This function is not thread-safe. Each call to this function invalidates
  119. * previous values returned by this function.
  120. */
  121. const char *
  122. node_describe(const node_t *node)
  123. {
  124. static char buf[NODE_DESC_BUF_LEN];
  125. const char *nickname = NULL;
  126. uint32_t addr32h = 0;
  127. const tor_addr_t *ipv6_addr = NULL;
  128. if (!node)
  129. return "<null>";
  130. if (node->rs) {
  131. nickname = node->rs->nickname;
  132. addr32h = node->rs->addr;
  133. ipv6_addr = &node->rs->ipv6_addr;
  134. /* Support consensus versions less than 28, when IPv6 addresses were in
  135. * microdescs. This code can be removed when 0.2.9 is no longer supported,
  136. * and the MIN_METHOD_FOR_NO_A_LINES_IN_MICRODESC macro is removed. */
  137. if (node->md && tor_addr_is_null(ipv6_addr)) {
  138. ipv6_addr = &node->md->ipv6_addr;
  139. }
  140. } else if (node->ri) {
  141. nickname = node->ri->nickname;
  142. addr32h = node->ri->addr;
  143. ipv6_addr = &node->ri->ipv6_addr;
  144. } else {
  145. return "<null rs and ri>";
  146. }
  147. return format_node_description(buf,
  148. node->identity,
  149. nickname,
  150. ipv6_addr,
  151. addr32h);
  152. }
  153. /** Return a human-readable description of the routerstatus_t <b>rs</b>.
  154. *
  155. * This function is not thread-safe. Each call to this function invalidates
  156. * previous values returned by this function.
  157. */
  158. const char *
  159. routerstatus_describe(const routerstatus_t *rs)
  160. {
  161. static char buf[NODE_DESC_BUF_LEN];
  162. if (!rs)
  163. return "<null>";
  164. return format_node_description(buf,
  165. rs->identity_digest,
  166. rs->nickname,
  167. &rs->ipv6_addr,
  168. rs->addr);
  169. }
  170. /** Return a human-readable description of the extend_info_t <b>ei</b>.
  171. *
  172. * This function is not thread-safe. Each call to this function invalidates
  173. * previous values returned by this function.
  174. */
  175. const char *
  176. extend_info_describe(const extend_info_t *ei)
  177. {
  178. static char buf[NODE_DESC_BUF_LEN];
  179. if (!ei)
  180. return "<null>";
  181. return format_node_description(buf,
  182. ei->identity_digest,
  183. ei->nickname,
  184. &ei->addr,
  185. 0);
  186. }
  187. /** Set <b>buf</b> (which must have MAX_VERBOSE_NICKNAME_LEN+1 bytes) to the
  188. * verbose representation of the identity of <b>router</b>. The format is:
  189. * A dollar sign.
  190. * The upper-case hexadecimal encoding of the SHA1 hash of router's identity.
  191. * A "=" if the router is named (no longer implemented); a "~" if it is not.
  192. * The router's nickname.
  193. **/
  194. void
  195. router_get_verbose_nickname(char *buf, const routerinfo_t *router)
  196. {
  197. size_t rv = 0;
  198. if (!buf)
  199. return;
  200. memset(buf, 0, MAX_VERBOSE_NICKNAME_LEN+1);
  201. if (!router) {
  202. /* strlcpy() returns the length of the source string it attempted to copy,
  203. * ignoring any required truncation due to the buffer length. */
  204. rv = strlcpy(buf, "<null>", MAX_VERBOSE_NICKNAME_LEN+1);
  205. tor_assert_nonfatal(rv < MAX_VERBOSE_NICKNAME_LEN+1);
  206. return;
  207. }
  208. /* strlcat() returns the length of the concatenated string it attempted to
  209. * create, ignoring any required truncation due to the buffer length. */
  210. rv = strlcat(buf, "$", MAX_VERBOSE_NICKNAME_LEN+1);
  211. tor_assert_nonfatal(rv < MAX_VERBOSE_NICKNAME_LEN+1);
  212. {
  213. char hex_digest[HEX_DIGEST_LEN+1];
  214. memset(hex_digest, 0, sizeof(hex_digest));
  215. base16_encode(hex_digest, sizeof(hex_digest),
  216. router->cache_info.identity_digest, DIGEST_LEN);
  217. rv = strlcat(buf, hex_digest, MAX_VERBOSE_NICKNAME_LEN+1);
  218. tor_assert_nonfatal(rv < MAX_VERBOSE_NICKNAME_LEN+1);
  219. }
  220. rv = strlcat(buf, "~", MAX_VERBOSE_NICKNAME_LEN+1);
  221. tor_assert_nonfatal(rv < MAX_VERBOSE_NICKNAME_LEN+1);
  222. rv = strlcat(buf, router->nickname, MAX_VERBOSE_NICKNAME_LEN+1);
  223. tor_assert_nonfatal(rv < MAX_VERBOSE_NICKNAME_LEN+1);
  224. }