Tor  0.4.7.0-alpha-dev
describe.c
Go to the documentation of this file.
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"
21 
22 #include "core/or/extend_info_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 *
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  size_t rv = 0;
48  bool has_ipv6 = ipv6_addr && !tor_addr_is_null(ipv6_addr);
49  bool valid_ipv4 = false;
50 
51  if (!buf)
52  return "<NULL BUFFER>";
53 
54  memset(buf, 0, NODE_DESC_BUF_LEN);
55 
56  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  rv = strlcpy(buf, "<NULL ID DIGEST>", NODE_DESC_BUF_LEN);
60  tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
61  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  rv = strlcat(buf, "$", NODE_DESC_BUF_LEN);
67  tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
68 
69  {
70  char hex_digest[HEX_DIGEST_LEN+1];
71  memset(hex_digest, 0, sizeof(hex_digest));
72 
73  base16_encode(hex_digest, sizeof(hex_digest),
74  rsa_id_digest, DIGEST_LEN);
75  rv = strlcat(buf, hex_digest, NODE_DESC_BUF_LEN);
76  tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
77  }
78 
79  if (nickname) {
80  rv = strlcat(buf, "~", NODE_DESC_BUF_LEN);
81  tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
82  rv = strlcat(buf, nickname, NODE_DESC_BUF_LEN);
83  tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
84  }
85  if (ed25519_id) {
86  char ed_base64[ED25519_BASE64_LEN+1];
87  ed25519_public_to_base64(ed_base64, ed25519_id);
88  rv = strlcat(buf, " [", NODE_DESC_BUF_LEN);
89  tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
90  rv = strlcat(buf, ed_base64, NODE_DESC_BUF_LEN);
91  tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
92  rv = strlcat(buf, "]", NODE_DESC_BUF_LEN);
93  tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
94  }
95  if (ipv4_addr || has_ipv6) {
96  rv = strlcat(buf, " at ", NODE_DESC_BUF_LEN);
97  tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
98  }
99  if (ipv4_addr) {
100  const char *str_rv = NULL;
101  char addr_str[TOR_ADDR_BUF_LEN];
102  memset(addr_str, 0, sizeof(addr_str));
103 
104  str_rv = tor_addr_to_str(addr_str, ipv4_addr, sizeof(addr_str), 0);
105  if (str_rv) {
106  rv = strlcat(buf, addr_str, NODE_DESC_BUF_LEN);
107  tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
108  valid_ipv4 = true;
109  }
110  }
111  /* Both addresses are valid */
112  if (valid_ipv4 && has_ipv6) {
113  rv = strlcat(buf, " and ", NODE_DESC_BUF_LEN);
114  tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
115  }
116  if (has_ipv6) {
117  const char *str_rv = NULL;
118  char addr_str[TOR_ADDR_BUF_LEN];
119  memset(addr_str, 0, sizeof(addr_str));
120 
121  str_rv = tor_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str), 1);
122  if (str_rv) {
123  rv = strlcat(buf, addr_str, NODE_DESC_BUF_LEN);
124  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 *
138 {
139  static char buf[NODE_DESC_BUF_LEN];
140 
141  if (!ri)
142  return "<null>";
143 
144  const ed25519_public_key_t *ed25519_id = routerinfo_get_ed25519_id(ri);
145 
146  return format_node_description(buf,
147  ri->cache_info.identity_digest,
148  ed25519_id,
149  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 node_describe(const node_t *node)
161 {
162  static char buf[NODE_DESC_BUF_LEN];
163  const char *nickname = NULL;
164  const tor_addr_t *ipv6_addr = NULL, *ipv4_addr = NULL;
165 
166  if (!node)
167  return "<null>";
168 
169  if (node->rs) {
170  nickname = node->rs->nickname;
171  ipv4_addr = &node->rs->ipv4_addr;
172  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  if (node->md && tor_addr_is_null(ipv6_addr)) {
177  ipv6_addr = &node->md->ipv6_addr;
178  }
179  } else if (node->ri) {
180  nickname = node->ri->nickname;
181  ipv4_addr = &node->ri->ipv4_addr;
182  ipv6_addr = &node->ri->ipv6_addr;
183  } else {
184  return "<null rs and ri>";
185  }
186 
187  const ed25519_public_key_t *ed25519_id = node_get_ed25519_id(node);
188 
189  return format_node_description(buf,
190  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 *
204 {
205  static char buf[NODE_DESC_BUF_LEN];
206 
207  if (!rs)
208  return "<null>";
209 
210  return format_node_description(buf,
211  rs->identity_digest,
212  NULL,
213  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 *
225 {
226  static char buf[NODE_DESC_BUF_LEN];
227 
228  if (!ei)
229  return "<null>";
230 
231  const tor_addr_port_t *ap4 = extend_info_get_orport(ei, AF_INET);
232  const tor_addr_port_t *ap6 = extend_info_get_orport(ei, AF_INET6);
233  const tor_addr_t *addr4 = ap4 ? &ap4->addr : NULL;
234  const tor_addr_t *addr6 = ap6 ? &ap6->addr : NULL;
235 
236  const ed25519_public_key_t *ed25519_id = &ei->ed_identity;
237  if (ed25519_public_key_is_zero(ed25519_id))
238  ed25519_id = NULL;
239 
240  return format_node_description(buf,
241  ei->identity_digest,
242  ed25519_id,
243  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 router_get_verbose_nickname(char *buf, const routerinfo_t *router)
257 {
258  size_t rv = 0;
259 
260  if (!buf)
261  return;
262 
263  memset(buf, 0, MAX_VERBOSE_NICKNAME_LEN+1);
264 
265  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  rv = strlcpy(buf, "<null>", MAX_VERBOSE_NICKNAME_LEN+1);
269  tor_assert_nonfatal(rv < MAX_VERBOSE_NICKNAME_LEN+1);
270  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  rv = strlcat(buf, "$", MAX_VERBOSE_NICKNAME_LEN+1);
276  tor_assert_nonfatal(rv < MAX_VERBOSE_NICKNAME_LEN+1);
277 
278  {
279  char hex_digest[HEX_DIGEST_LEN+1];
280  memset(hex_digest, 0, sizeof(hex_digest));
281 
282  base16_encode(hex_digest, sizeof(hex_digest),
283  router->cache_info.identity_digest, DIGEST_LEN);
284  rv = strlcat(buf, hex_digest, MAX_VERBOSE_NICKNAME_LEN+1);
285  tor_assert_nonfatal(rv < MAX_VERBOSE_NICKNAME_LEN+1);
286  }
287 
288  rv = strlcat(buf, "~", MAX_VERBOSE_NICKNAME_LEN+1);
289  tor_assert_nonfatal(rv < MAX_VERBOSE_NICKNAME_LEN+1);
290 
291  rv = strlcat(buf, router->nickname, MAX_VERBOSE_NICKNAME_LEN+1);
292  tor_assert_nonfatal(rv < MAX_VERBOSE_NICKNAME_LEN+1);
293 }
const char * tor_addr_to_str(char *dest, const tor_addr_t *addr, size_t len, int decorate)
Definition: address.c:328
int tor_addr_is_null(const tor_addr_t *addr)
Definition: address.c:780
#define TOR_ADDR_BUF_LEN
Definition: address.h:224
void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen)
Definition: binascii.c:478
#define HEX_DIGEST_LEN
Definition: crypto_digest.h:35
int ed25519_public_key_is_zero(const ed25519_public_key_t *pubkey)
Header for crypto_ed25519.c.
void ed25519_public_to_base64(char *output, const ed25519_public_key_t *pkey)
Header for crypto_format.c.
void router_get_verbose_nickname(char *buf, const routerinfo_t *router)
Definition: describe.c:256
const char * router_describe(const routerinfo_t *ri)
Definition: describe.c:137
const char * extend_info_describe(const extend_info_t *ei)
Definition: describe.c:224
const char * routerstatus_describe(const routerstatus_t *rs)
Definition: describe.c:203
const char * node_describe(const node_t *node)
Definition: describe.c:160
STATIC const char * format_node_description(char *buf, const char *rsa_id_digest, const ed25519_public_key_t *ed25519_id, const char *nickname, const tor_addr_t *ipv4_addr, const tor_addr_t *ipv6_addr)
Definition: describe.c:40
Header file for describe.c.
#define DIGEST_LEN
Definition: digest_sizes.h:20
Extend-info structure.
const tor_addr_port_t * extend_info_get_orport(const extend_info_t *ei, int family)
Definition: extendinfo.c:263
Header for core/or/extendinfo.c.
Microdescriptor structure.
Node information structure.
const ed25519_public_key_t * node_get_ed25519_id(const node_t *node)
Definition: nodelist.c:1150
Header file for nodelist.c.
Master header file for Tor-specific functionality.
#define MAX_VERBOSE_NICKNAME_LEN
Definition: or.h:118
const ed25519_public_key_t * routerinfo_get_ed25519_id(const routerinfo_t *ri)
Definition: routerinfo.c:82
Header file for routerinfo.c.
Router descriptor structure.
Routerstatus (consensus entry) structure.
ed25519_public_key_t ed_identity
char identity_digest[DIGEST_LEN]
char nickname[MAX_HEX_NICKNAME_LEN+1]
tor_addr_t ipv6_addr
Definition: microdesc_st.h:79
Definition: node_st.h:34
char identity[DIGEST_LEN]
Definition: node_st.h:46
tor_addr_t ipv6_addr
Definition: routerinfo_st.h:30
tor_addr_t ipv4_addr
Definition: routerinfo_st.h:25
char * nickname
Definition: routerinfo_st.h:22
tor_addr_t ipv6_addr
char identity_digest[DIGEST_LEN]
char nickname[MAX_NICKNAME_LEN+1]
char identity_digest[DIGEST_LEN]
#define STATIC
Definition: testsupport.h:32
#define ED25519_BASE64_LEN
Definition: x25519_sizes.h:43