Tor 0.4.9.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
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 */
39STATIC 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 */
136const 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 */
159const char *
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 */
202const 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 */
223const 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 **/
255void
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}
int tor_addr_is_null(const tor_addr_t *addr)
Definition: address.c:780
const char * tor_addr_to_str(char *dest, const tor_addr_t *addr, size_t len, int decorate)
Definition: address.c:328
#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
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
const char * routerstatus_describe(const routerstatus_t *rs)
Definition: describe.c:203
const char * node_describe(const node_t *node)
Definition: describe.c:160
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:285
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