Tor  0.4.3.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-2019, 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"
16 
17 #include "core/or/extend_info_st.h"
22 
23 /** Use <b>buf</b> (which must be at least NODE_DESC_BUF_LEN bytes long) to
24  * hold a human-readable description of a node with identity digest
25  * <b>id_digest</b>, nickname <b>nickname</b>, and addresses <b>addr32h</b> and
26  * <b>addr</b>.
27  *
28  * The <b>nickname</b> and <b>addr</b> fields are optional and may be set to
29  * NULL or the null address. The <b>addr32h</b> field is optional and may be
30  * set to 0.
31  *
32  * Return a pointer to the front of <b>buf</b>.
33  * If buf is NULL, return a string constant describing the error.
34  */
35 STATIC const char *
37  const char *id_digest,
38  const char *nickname,
39  const tor_addr_t *addr,
40  uint32_t addr32h)
41 {
42  size_t rv = 0;
43  bool has_addr = addr && !tor_addr_is_null(addr);
44 
45  if (!buf)
46  return "<NULL BUFFER>";
47 
48  memset(buf, 0, NODE_DESC_BUF_LEN);
49 
50  if (!id_digest) {
51  /* strlcpy() returns the length of the source string it attempted to copy,
52  * ignoring any required truncation due to the buffer length. */
53  rv = strlcpy(buf, "<NULL ID DIGEST>", NODE_DESC_BUF_LEN);
54  tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
55  return buf;
56  }
57 
58  /* strlcat() returns the length of the concatenated string it attempted to
59  * create, ignoring any required truncation due to the buffer length. */
60  rv = strlcat(buf, "$", NODE_DESC_BUF_LEN);
61  tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
62 
63  {
64  char hex_digest[HEX_DIGEST_LEN+1];
65  memset(hex_digest, 0, sizeof(hex_digest));
66 
67  base16_encode(hex_digest, sizeof(hex_digest),
68  id_digest, DIGEST_LEN);
69  rv = strlcat(buf, hex_digest, NODE_DESC_BUF_LEN);
70  tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
71  }
72 
73  if (nickname) {
74  rv = strlcat(buf, "~", NODE_DESC_BUF_LEN);
75  tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
76  rv = strlcat(buf, nickname, NODE_DESC_BUF_LEN);
77  tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
78  }
79  if (addr32h || has_addr) {
80  rv = strlcat(buf, " at ", NODE_DESC_BUF_LEN);
81  tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
82  }
83  if (addr32h) {
84  int ntoa_rv = 0;
85  char ipv4_addr_str[INET_NTOA_BUF_LEN];
86  memset(ipv4_addr_str, 0, sizeof(ipv4_addr_str));
87  struct in_addr in;
88  memset(&in, 0, sizeof(in));
89 
90  in.s_addr = htonl(addr32h);
91  ntoa_rv = tor_inet_ntoa(&in, ipv4_addr_str, sizeof(ipv4_addr_str));
92  tor_assert_nonfatal(ntoa_rv >= 0);
93 
94  rv = strlcat(buf, ipv4_addr_str, NODE_DESC_BUF_LEN);
95  tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
96  }
97  /* Both addresses are valid */
98  if (addr32h && has_addr) {
99  rv = strlcat(buf, " and ", NODE_DESC_BUF_LEN);
100  tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
101  }
102  if (has_addr) {
103  const char *str_rv = NULL;
104  char addr_str[TOR_ADDR_BUF_LEN];
105  memset(addr_str, 0, sizeof(addr_str));
106 
107  str_rv = tor_addr_to_str(addr_str, addr, sizeof(addr_str), 1);
108  tor_assert_nonfatal(str_rv == addr_str);
109 
110  rv = strlcat(buf, addr_str, NODE_DESC_BUF_LEN);
111  tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
112  }
113 
114  return buf;
115 }
116 
117 /** Return a human-readable description of the routerinfo_t <b>ri</b>.
118  *
119  * This function is not thread-safe. Each call to this function invalidates
120  * previous values returned by this function.
121  */
122 const char *
124 {
125  static char buf[NODE_DESC_BUF_LEN];
126 
127  if (!ri)
128  return "<null>";
129 
130  return format_node_description(buf,
131  ri->cache_info.identity_digest,
132  ri->nickname,
133  &ri->ipv6_addr,
134  ri->addr);
135 }
136 
137 /** Return a human-readable description of the node_t <b>node</b>.
138  *
139  * This function is not thread-safe. Each call to this function invalidates
140  * previous values returned by this function.
141  */
142 const char *
143 node_describe(const node_t *node)
144 {
145  static char buf[NODE_DESC_BUF_LEN];
146  const char *nickname = NULL;
147  uint32_t addr32h = 0;
148  const tor_addr_t *ipv6_addr = NULL;
149 
150  if (!node)
151  return "<null>";
152 
153  if (node->rs) {
154  nickname = node->rs->nickname;
155  addr32h = node->rs->addr;
156  ipv6_addr = &node->rs->ipv6_addr;
157  /* Support consensus versions less than 28, when IPv6 addresses were in
158  * microdescs. This code can be removed when 0.2.9 is no longer supported,
159  * and the MIN_METHOD_FOR_NO_A_LINES_IN_MICRODESC macro is removed. */
160  if (node->md && tor_addr_is_null(ipv6_addr)) {
161  ipv6_addr = &node->md->ipv6_addr;
162  }
163  } else if (node->ri) {
164  nickname = node->ri->nickname;
165  addr32h = node->ri->addr;
166  ipv6_addr = &node->ri->ipv6_addr;
167  } else {
168  return "<null rs and ri>";
169  }
170 
171  return format_node_description(buf,
172  node->identity,
173  nickname,
174  ipv6_addr,
175  addr32h);
176 }
177 
178 /** Return a human-readable description of the routerstatus_t <b>rs</b>.
179  *
180  * This function is not thread-safe. Each call to this function invalidates
181  * previous values returned by this function.
182  */
183 const char *
185 {
186  static char buf[NODE_DESC_BUF_LEN];
187 
188  if (!rs)
189  return "<null>";
190 
191  return format_node_description(buf,
192  rs->identity_digest,
193  rs->nickname,
194  &rs->ipv6_addr,
195  rs->addr);
196 }
197 
198 /** Return a human-readable description of the extend_info_t <b>ei</b>.
199  *
200  * This function is not thread-safe. Each call to this function invalidates
201  * previous values returned by this function.
202  */
203 const char *
205 {
206  static char buf[NODE_DESC_BUF_LEN];
207 
208  if (!ei)
209  return "<null>";
210 
211  return format_node_description(buf,
212  ei->identity_digest,
213  ei->nickname,
214  &ei->addr,
215  0);
216 }
217 
218 /** Set <b>buf</b> (which must have MAX_VERBOSE_NICKNAME_LEN+1 bytes) to the
219  * verbose representation of the identity of <b>router</b>. The format is:
220  * A dollar sign.
221  * The upper-case hexadecimal encoding of the SHA1 hash of router's identity.
222  * A "=" if the router is named (no longer implemented); a "~" if it is not.
223  * The router's nickname.
224  **/
225 void
226 router_get_verbose_nickname(char *buf, const routerinfo_t *router)
227 {
228  size_t rv = 0;
229 
230  if (!buf)
231  return;
232 
233  memset(buf, 0, MAX_VERBOSE_NICKNAME_LEN+1);
234 
235  if (!router) {
236  /* strlcpy() returns the length of the source string it attempted to copy,
237  * ignoring any required truncation due to the buffer length. */
238  rv = strlcpy(buf, "<null>", MAX_VERBOSE_NICKNAME_LEN+1);
239  tor_assert_nonfatal(rv < MAX_VERBOSE_NICKNAME_LEN+1);
240  return;
241  }
242 
243  /* strlcat() returns the length of the concatenated string it attempted to
244  * create, ignoring any required truncation due to the buffer length. */
245  rv = strlcat(buf, "$", MAX_VERBOSE_NICKNAME_LEN+1);
246  tor_assert_nonfatal(rv < MAX_VERBOSE_NICKNAME_LEN+1);
247 
248  {
249  char hex_digest[HEX_DIGEST_LEN+1];
250  memset(hex_digest, 0, sizeof(hex_digest));
251 
252  base16_encode(hex_digest, sizeof(hex_digest),
253  router->cache_info.identity_digest, DIGEST_LEN);
254  rv = strlcat(buf, hex_digest, MAX_VERBOSE_NICKNAME_LEN+1);
255  tor_assert_nonfatal(rv < MAX_VERBOSE_NICKNAME_LEN+1);
256  }
257 
258  rv = strlcat(buf, "~", MAX_VERBOSE_NICKNAME_LEN+1);
259  tor_assert_nonfatal(rv < MAX_VERBOSE_NICKNAME_LEN+1);
260 
261  rv = strlcat(buf, router->nickname, MAX_VERBOSE_NICKNAME_LEN+1);
262  tor_assert_nonfatal(rv < MAX_VERBOSE_NICKNAME_LEN+1);
263 }
const char * tor_addr_to_str(char *dest, const tor_addr_t *addr, size_t len, int decorate)
Definition: address.c:328
char identity_digest[DIGEST_LEN]
Router descriptor structure.
#define TOR_ADDR_BUF_LEN
Definition: address.h:205
Definition: node_st.h:33
char nickname[MAX_HEX_NICKNAME_LEN+1]
tor_addr_t addr
const char * extend_info_describe(const extend_info_t *ei)
Definition: describe.c:204
Header file for describe.c.
Microdescriptor structure.
char nickname[MAX_NICKNAME_LEN+1]
Node information structure.
char identity_digest[DIGEST_LEN]
char * nickname
Definition: routerinfo_st.h:22
#define INET_NTOA_BUF_LEN
Definition: inaddr.h:21
#define STATIC
Definition: testsupport.h:32
Routerstatus (consensus entry) structure.
void router_get_verbose_nickname(char *buf, const routerinfo_t *router)
Definition: describe.c:226
#define MAX_VERBOSE_NICKNAME_LEN
Definition: or.h:119
#define DIGEST_LEN
Definition: digest_sizes.h:20
const char * node_describe(const node_t *node)
Definition: describe.c:143
Master header file for Tor-specific functionality.
tor_addr_t ipv6_addr
Definition: microdesc_st.h:77
char identity[DIGEST_LEN]
Definition: node_st.h:45
tor_addr_t ipv6_addr
int tor_addr_is_null(const tor_addr_t *addr)
Definition: address.c:770
const char * routerstatus_describe(const routerstatus_t *rs)
Definition: describe.c:184
void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen)
Definition: binascii.c:478
Extend-info structure.
STATIC const char * format_node_description(char *buf, const char *id_digest, const char *nickname, const tor_addr_t *addr, uint32_t addr32h)
Definition: describe.c:36
#define HEX_DIGEST_LEN
Definition: crypto_digest.h:35
char identity_digest[DIGEST_LEN]
int tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len)
Definition: inaddr.c:58
tor_addr_t ipv6_addr
Definition: routerinfo_st.h:32
uint32_t addr
Definition: routerinfo_st.h:24
const char * router_describe(const routerinfo_t *ri)
Definition: describe.c:123