describe.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  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>, or a string constant on error.
  28. */
  29. STATIC const char *
  30. format_node_description(char *buf,
  31. const char *id_digest,
  32. const char *nickname,
  33. const tor_addr_t *addr,
  34. uint32_t addr32h)
  35. {
  36. char *cp;
  37. bool has_addr = addr && !tor_addr_is_null(addr);
  38. if (!buf)
  39. return "<NULL BUFFER>";
  40. buf[0] = '$';
  41. base16_encode(buf+1, HEX_DIGEST_LEN+1, id_digest, DIGEST_LEN);
  42. cp = buf+1+HEX_DIGEST_LEN;
  43. if (nickname) {
  44. buf[1+HEX_DIGEST_LEN] = '~';
  45. strlcpy(buf+1+HEX_DIGEST_LEN+1, nickname, MAX_NICKNAME_LEN+1);
  46. cp += strlen(cp);
  47. }
  48. if (addr32h || has_addr) {
  49. memcpy(cp, " at ", 4);
  50. cp += 4;
  51. }
  52. if (addr32h) {
  53. struct in_addr in;
  54. in.s_addr = htonl(addr32h);
  55. tor_inet_ntoa(&in, cp, INET_NTOA_BUF_LEN);
  56. cp += strlen(cp);
  57. }
  58. if (addr32h && has_addr) {
  59. memcpy(cp, " and ", 5);
  60. cp += 5;
  61. }
  62. if (has_addr) {
  63. tor_addr_to_str(cp, addr, TOR_ADDR_BUF_LEN, 1);
  64. }
  65. return buf;
  66. }
  67. /** Return a human-readable description of the routerinfo_t <b>ri</b>.
  68. *
  69. * This function is not thread-safe. Each call to this function invalidates
  70. * previous values returned by this function.
  71. */
  72. const char *
  73. router_describe(const routerinfo_t *ri)
  74. {
  75. static char buf[NODE_DESC_BUF_LEN];
  76. if (!ri)
  77. return "<null>";
  78. return format_node_description(buf,
  79. ri->cache_info.identity_digest,
  80. ri->nickname,
  81. &ri->ipv6_addr,
  82. ri->addr);
  83. }
  84. /** Return a human-readable description of the node_t <b>node</b>.
  85. *
  86. * This function is not thread-safe. Each call to this function invalidates
  87. * previous values returned by this function.
  88. */
  89. const char *
  90. node_describe(const node_t *node)
  91. {
  92. static char buf[NODE_DESC_BUF_LEN];
  93. const char *nickname = NULL;
  94. uint32_t addr32h = 0;
  95. const tor_addr_t *ipv6_addr = NULL;
  96. if (!node)
  97. return "<null>";
  98. if (node->rs) {
  99. nickname = node->rs->nickname;
  100. addr32h = node->rs->addr;
  101. ipv6_addr = &node->rs->ipv6_addr;
  102. /* Support consensus versions less than 28, when IPv6 addresses were in
  103. * microdescs. This code can be removed when 0.2.9 is no longer supported,
  104. * and the MIN_METHOD_FOR_NO_A_LINES_IN_MICRODESC macro is removed. */
  105. if (node->md && tor_addr_is_null(ipv6_addr)) {
  106. ipv6_addr = &node->md->ipv6_addr;
  107. }
  108. } else if (node->ri) {
  109. nickname = node->ri->nickname;
  110. addr32h = node->ri->addr;
  111. ipv6_addr = &node->ri->ipv6_addr;
  112. }
  113. return format_node_description(buf,
  114. node->identity,
  115. nickname,
  116. ipv6_addr,
  117. addr32h);
  118. }
  119. /** Return a human-readable description of the routerstatus_t <b>rs</b>.
  120. *
  121. * This function is not thread-safe. Each call to this function invalidates
  122. * previous values returned by this function.
  123. */
  124. const char *
  125. routerstatus_describe(const routerstatus_t *rs)
  126. {
  127. static char buf[NODE_DESC_BUF_LEN];
  128. if (!rs)
  129. return "<null>";
  130. return format_node_description(buf,
  131. rs->identity_digest,
  132. rs->nickname,
  133. &rs->ipv6_addr,
  134. rs->addr);
  135. }
  136. /** Return a human-readable description of the extend_info_t <b>ei</b>.
  137. *
  138. * This function is not thread-safe. Each call to this function invalidates
  139. * previous values returned by this function.
  140. */
  141. const char *
  142. extend_info_describe(const extend_info_t *ei)
  143. {
  144. static char buf[NODE_DESC_BUF_LEN];
  145. if (!ei)
  146. return "<null>";
  147. return format_node_description(buf,
  148. ei->identity_digest,
  149. ei->nickname,
  150. &ei->addr,
  151. 0);
  152. }
  153. /** Set <b>buf</b> (which must have MAX_VERBOSE_NICKNAME_LEN+1 bytes) to the
  154. * verbose representation of the identity of <b>router</b>. The format is:
  155. * A dollar sign.
  156. * The upper-case hexadecimal encoding of the SHA1 hash of router's identity.
  157. * A "=" if the router is named (no longer implemented); a "~" if it is not.
  158. * The router's nickname.
  159. **/
  160. void
  161. router_get_verbose_nickname(char *buf, const routerinfo_t *router)
  162. {
  163. buf[0] = '$';
  164. base16_encode(buf+1, HEX_DIGEST_LEN+1, router->cache_info.identity_digest,
  165. DIGEST_LEN);
  166. buf[1+HEX_DIGEST_LEN] = '~';
  167. strlcpy(buf+1+HEX_DIGEST_LEN+1, router->nickname, MAX_NICKNAME_LEN+1);
  168. }