LCOV - code coverage report
Current view: top level - feature/nodelist - describe.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 117 117 100.0 %
Date: 2021-11-24 03:28:48 Functions: 6 6 100.0 %

          Line data    Source code
       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-2021, The Tor Project, Inc. */
       5             : /* See LICENSE for licensing information */
       6             : 
       7             : /**
       8             :  * \file describe.c
       9             :  * \brief Format short descriptions of relays.
      10             :  */
      11             : 
      12             : #define DESCRIBE_PRIVATE
      13             : 
      14             : #include "core/or/or.h"
      15             : #include "core/or/extendinfo.h"
      16             : #include "feature/nodelist/describe.h"
      17             : #include "feature/nodelist/nodelist.h"
      18             : #include "feature/nodelist/routerinfo.h"
      19             : #include "lib/crypt_ops/crypto_ed25519.h"
      20             : #include "lib/crypt_ops/crypto_format.h"
      21             : 
      22             : #include "core/or/extend_info_st.h"
      23             : #include "feature/nodelist/node_st.h"
      24             : #include "feature/nodelist/routerinfo_st.h"
      25             : #include "feature/nodelist/routerstatus_st.h"
      26             : #include "feature/nodelist/microdesc_st.h"
      27             : 
      28             : /** Use <b>buf</b> (which must be at least NODE_DESC_BUF_LEN bytes long) to
      29             :  * hold a human-readable description of a node with identity digest
      30             :  * <b>id_digest</b>, nickname <b>nickname</b>, and addresses <b>addr32h</b> and
      31             :  * <b>addr</b>.
      32             :  *
      33             :  * The <b>nickname</b>, <b>ipv6_addr</b> and <b>ipv4_addr</b> fields are
      34             :  * optional and may be set to NULL or the null address.
      35             :  *
      36             :  * Return a pointer to the front of <b>buf</b>.
      37             :  * If buf is NULL, return a string constant describing the error.
      38             :  */
      39             : STATIC const char *
      40        8068 : format_node_description(char *buf,
      41             :                         const char *rsa_id_digest,
      42             :                         const ed25519_public_key_t *ed25519_id,
      43             :                         const char *nickname,
      44             :                         const tor_addr_t *ipv4_addr,
      45             :                         const tor_addr_t *ipv6_addr)
      46             : {
      47        8068 :   size_t rv = 0;
      48        8068 :   bool has_ipv6 = ipv6_addr && !tor_addr_is_null(ipv6_addr);
      49        8068 :   bool valid_ipv4 = false;
      50             : 
      51        8068 :   if (!buf)
      52             :     return "<NULL BUFFER>";
      53             : 
      54        8067 :   memset(buf, 0, NODE_DESC_BUF_LEN);
      55             : 
      56        8067 :   if (!rsa_id_digest) {
      57             :     /* strlcpy() returns the length of the source string it attempted to copy,
      58             :      * ignoring any required truncation due to the buffer length. */
      59           1 :     rv = strlcpy(buf, "<NULL ID DIGEST>", NODE_DESC_BUF_LEN);
      60           1 :     tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
      61           1 :     return buf;
      62             :   }
      63             : 
      64             :   /* strlcat() returns the length of the concatenated string it attempted to
      65             :    * create, ignoring any required truncation due to the buffer length.  */
      66        8066 :   rv = strlcat(buf, "$", NODE_DESC_BUF_LEN);
      67        8066 :   tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
      68             : 
      69             :   {
      70        8066 :     char hex_digest[HEX_DIGEST_LEN+1];
      71        8066 :     memset(hex_digest, 0, sizeof(hex_digest));
      72             : 
      73        8066 :     base16_encode(hex_digest, sizeof(hex_digest),
      74             :                   rsa_id_digest, DIGEST_LEN);
      75        8066 :     rv = strlcat(buf, hex_digest, NODE_DESC_BUF_LEN);
      76        8066 :     tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
      77             :   }
      78             : 
      79        8066 :   if (nickname) {
      80        8054 :     rv = strlcat(buf, "~", NODE_DESC_BUF_LEN);
      81        8054 :     tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
      82        8054 :     rv = strlcat(buf, nickname, NODE_DESC_BUF_LEN);
      83        8054 :     tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
      84             :   }
      85        8066 :   if (ed25519_id) {
      86          33 :     char ed_base64[ED25519_BASE64_LEN+1];
      87          33 :     ed25519_public_to_base64(ed_base64, ed25519_id);
      88          33 :     rv = strlcat(buf, " [", NODE_DESC_BUF_LEN);
      89          33 :     tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
      90          33 :     rv = strlcat(buf, ed_base64, NODE_DESC_BUF_LEN);
      91          33 :     tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
      92          33 :     rv = strlcat(buf, "]", NODE_DESC_BUF_LEN);
      93          33 :     tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
      94             :   }
      95        8066 :   if (ipv4_addr || has_ipv6) {
      96        8063 :     rv = strlcat(buf, " at ", NODE_DESC_BUF_LEN);
      97        8063 :     tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
      98             :   }
      99        8066 :   if (ipv4_addr) {
     100        8061 :     const char *str_rv = NULL;
     101        8061 :     char addr_str[TOR_ADDR_BUF_LEN];
     102        8061 :     memset(addr_str, 0, sizeof(addr_str));
     103             : 
     104        8061 :     str_rv = tor_addr_to_str(addr_str, ipv4_addr, sizeof(addr_str), 0);
     105        8061 :     if (str_rv) {
     106        8029 :       rv = strlcat(buf, addr_str, NODE_DESC_BUF_LEN);
     107        8029 :       tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
     108             :       valid_ipv4 = true;
     109             :     }
     110             :   }
     111             :   /* Both addresses are valid */
     112        8066 :   if (valid_ipv4 && has_ipv6) {
     113          25 :     rv = strlcat(buf, " and ", NODE_DESC_BUF_LEN);
     114          25 :     tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
     115             :   }
     116        8066 :   if (has_ipv6) {
     117          31 :     const char *str_rv = NULL;
     118          31 :     char addr_str[TOR_ADDR_BUF_LEN];
     119          31 :     memset(addr_str, 0, sizeof(addr_str));
     120             : 
     121          31 :     str_rv = tor_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str), 1);
     122          31 :     if (str_rv) {
     123          31 :       rv = strlcat(buf, addr_str, NODE_DESC_BUF_LEN);
     124          31 :       tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
     125             :     }
     126             :   }
     127             : 
     128             :   return buf;
     129             : }
     130             : 
     131             : /** Return a human-readable description of the routerinfo_t <b>ri</b>.
     132             :  *
     133             :  * This function is not thread-safe.  Each call to this function invalidates
     134             :  * previous values returned by this function.
     135             :  */
     136             : const char *
     137          38 : router_describe(const routerinfo_t *ri)
     138             : {
     139          38 :   static char buf[NODE_DESC_BUF_LEN];
     140             : 
     141          38 :   if (!ri)
     142             :     return "<null>";
     143             : 
     144          37 :   const ed25519_public_key_t *ed25519_id = routerinfo_get_ed25519_id(ri);
     145             : 
     146          37 :   return format_node_description(buf,
     147          37 :                                  ri->cache_info.identity_digest,
     148             :                                  ed25519_id,
     149          37 :                                  ri->nickname,
     150             :                                  &ri->ipv4_addr,
     151             :                                  &ri->ipv6_addr);
     152             : }
     153             : 
     154             : /** Return a human-readable description of the node_t <b>node</b>.
     155             :  *
     156             :  * This function is not thread-safe.  Each call to this function invalidates
     157             :  * previous values returned by this function.
     158             :  */
     159             : const char *
     160        7998 : node_describe(const node_t *node)
     161             : {
     162        7998 :   static char buf[NODE_DESC_BUF_LEN];
     163        7998 :   const char *nickname = NULL;
     164        7998 :   const tor_addr_t *ipv6_addr = NULL, *ipv4_addr = NULL;
     165             : 
     166        7998 :   if (!node)
     167             :     return "<null>";
     168             : 
     169        7997 :   if (node->rs) {
     170        7988 :     nickname = node->rs->nickname;
     171        7988 :     ipv4_addr = &node->rs->ipv4_addr;
     172        7988 :     ipv6_addr = &node->rs->ipv6_addr;
     173             :     /* Support consensus versions less than 28, when IPv6 addresses were in
     174             :      * microdescs. This code can be removed when 0.2.9 is no longer supported,
     175             :      * and the MIN_METHOD_FOR_NO_A_LINES_IN_MICRODESC macro is removed. */
     176        7988 :     if (node->md && tor_addr_is_null(ipv6_addr)) {
     177        7963 :       ipv6_addr = &node->md->ipv6_addr;
     178             :     }
     179           9 :   } else if (node->ri) {
     180           8 :     nickname = node->ri->nickname;
     181           8 :     ipv4_addr = &node->ri->ipv4_addr;
     182           8 :     ipv6_addr = &node->ri->ipv6_addr;
     183             :   } else {
     184             :     return "<null rs and ri>";
     185             :   }
     186             : 
     187        7996 :   const ed25519_public_key_t *ed25519_id = node_get_ed25519_id(node);
     188             : 
     189        7996 :   return format_node_description(buf,
     190        7996 :                                  node->identity,
     191             :                                  ed25519_id,
     192             :                                  nickname,
     193             :                                  ipv4_addr,
     194             :                                  ipv6_addr);
     195             : }
     196             : 
     197             : /** Return a human-readable description of the routerstatus_t <b>rs</b>.
     198             :  *
     199             :  * This function is not thread-safe.  Each call to this function invalidates
     200             :  * previous values returned by this function.
     201             :  */
     202             : const char *
     203           4 : routerstatus_describe(const routerstatus_t *rs)
     204             : {
     205           4 :   static char buf[NODE_DESC_BUF_LEN];
     206             : 
     207           4 :   if (!rs)
     208             :     return "<null>";
     209             : 
     210           3 :   return format_node_description(buf,
     211           3 :                                  rs->identity_digest,
     212             :                                  NULL,
     213           3 :                                  rs->nickname,
     214             :                                  &rs->ipv4_addr,
     215             :                                  &rs->ipv6_addr);
     216             : }
     217             : 
     218             : /** Return a human-readable description of the extend_info_t <b>ei</b>.
     219             :  *
     220             :  * This function is not thread-safe.  Each call to this function invalidates
     221             :  * previous values returned by this function.
     222             :  */
     223             : const char *
     224          24 : extend_info_describe(const extend_info_t *ei)
     225             : {
     226          24 :   static char buf[NODE_DESC_BUF_LEN];
     227             : 
     228          24 :   if (!ei)
     229             :     return "<null>";
     230             : 
     231          23 :   const tor_addr_port_t *ap4 = extend_info_get_orport(ei, AF_INET);
     232          23 :   const tor_addr_port_t *ap6 = extend_info_get_orport(ei, AF_INET6);
     233          23 :   const tor_addr_t *addr4 = ap4 ? &ap4->addr : NULL;
     234          23 :   const tor_addr_t *addr6 = ap6 ? &ap6->addr : NULL;
     235             : 
     236          23 :   const ed25519_public_key_t *ed25519_id = &ei->ed_identity;
     237          23 :   if (ed25519_public_key_is_zero(ed25519_id))
     238          23 :     ed25519_id = NULL;
     239             : 
     240          23 :   return format_node_description(buf,
     241          23 :                                  ei->identity_digest,
     242             :                                  ed25519_id,
     243          23 :                                  ei->nickname,
     244             :                                  addr4,
     245             :                                  addr6);
     246             : }
     247             : 
     248             : /** Set <b>buf</b> (which must have MAX_VERBOSE_NICKNAME_LEN+1 bytes) to the
     249             :  * verbose representation of the identity of <b>router</b>.  The format is:
     250             :  *  A dollar sign.
     251             :  *  The upper-case hexadecimal encoding of the SHA1 hash of router's identity.
     252             :  *  A "=" if the router is named (no longer implemented); a "~" if it is not.
     253             :  *  The router's nickname.
     254             :  **/
     255             : void
     256           4 : router_get_verbose_nickname(char *buf, const routerinfo_t *router)
     257             : {
     258           4 :   size_t rv = 0;
     259             : 
     260           4 :   if (!buf)
     261             :     return;
     262             : 
     263           2 :   memset(buf, 0, MAX_VERBOSE_NICKNAME_LEN+1);
     264             : 
     265           2 :   if (!router) {
     266             :     /* strlcpy() returns the length of the source string it attempted to copy,
     267             :      * ignoring any required truncation due to the buffer length. */
     268           1 :     rv = strlcpy(buf, "<null>", MAX_VERBOSE_NICKNAME_LEN+1);
     269           1 :     tor_assert_nonfatal(rv < MAX_VERBOSE_NICKNAME_LEN+1);
     270           1 :     return;
     271             :   }
     272             : 
     273             :   /* strlcat() returns the length of the concatenated string it attempted to
     274             :    * create, ignoring any required truncation due to the buffer length.  */
     275           1 :   rv = strlcat(buf, "$", MAX_VERBOSE_NICKNAME_LEN+1);
     276           1 :   tor_assert_nonfatal(rv < MAX_VERBOSE_NICKNAME_LEN+1);
     277             : 
     278             :   {
     279           1 :     char hex_digest[HEX_DIGEST_LEN+1];
     280           1 :     memset(hex_digest, 0, sizeof(hex_digest));
     281             : 
     282           1 :     base16_encode(hex_digest, sizeof(hex_digest),
     283           1 :                   router->cache_info.identity_digest, DIGEST_LEN);
     284           1 :     rv = strlcat(buf, hex_digest, MAX_VERBOSE_NICKNAME_LEN+1);
     285           1 :     tor_assert_nonfatal(rv < MAX_VERBOSE_NICKNAME_LEN+1);
     286             :   }
     287             : 
     288           1 :   rv = strlcat(buf, "~", MAX_VERBOSE_NICKNAME_LEN+1);
     289           1 :   tor_assert_nonfatal(rv < MAX_VERBOSE_NICKNAME_LEN+1);
     290             : 
     291           1 :   rv = strlcat(buf, router->nickname, MAX_VERBOSE_NICKNAME_LEN+1);
     292           1 :   tor_assert_nonfatal(rv < MAX_VERBOSE_NICKNAME_LEN+1);
     293             : }

Generated by: LCOV version 1.14