Tor  0.4.6.0-alpha-dev
fmt_routerstatus.c
1 /* Copyright (c) 2001-2004, Roger Dingledine.
2  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3  * Copyright (c) 2007-2020, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
5 
6 /**
7  * \file fmt_routerstatus.h
8  * \brief Format routerstatus entries for controller, vote, or consensus.
9  *
10  * (Because controllers consume this format, we can't make this
11  * code dirauth-only.)
12  **/
13 
14 #include "core/or/or.h"
16 
17 #include "core/or/policies.h"
20 
23 
25 
26 /** Helper: write the router-status information in <b>rs</b> into a newly
27  * allocated character buffer. Use the same format as in network-status
28  * documents. If <b>version</b> is non-NULL, add a "v" line for the platform.
29  *
30  * Return 0 on success, -1 on failure.
31  *
32  * The format argument has one of the following values:
33  * NS_V2 - Output an entry suitable for a V2 NS opinion document
34  * NS_V3_CONSENSUS - Output the first portion of a V3 NS consensus entry
35  * for consensus_method.
36  * NS_V3_CONSENSUS_MICRODESC - Output the first portion of a V3 microdesc
37  * consensus entry for consensus_method.
38  * NS_V3_VOTE - Output a complete V3 NS vote. If <b>vrs</b> is present,
39  * it contains additional information for the vote.
40  * NS_CONTROL_PORT - Output a NS document for the control port.
41  */
42 char *
43 routerstatus_format_entry(const routerstatus_t *rs, const char *version,
44  const char *protocols,
46  const vote_routerstatus_t *vrs)
47 {
48  char *summary;
49  char *result = NULL;
50 
51  char published[ISO_TIME_LEN+1];
52  char identity64[BASE64_DIGEST_LEN+1];
53  char digest64[BASE64_DIGEST_LEN+1];
54  smartlist_t *chunks = smartlist_new();
55 
56  const char *ip_str = fmt_addr(&rs->ipv4_addr);
57  if (ip_str[0] == '\0')
58  goto err;
59 
60  format_iso_time(published, rs->published_on);
61  digest_to_base64(identity64, rs->identity_digest);
62  digest_to_base64(digest64, rs->descriptor_digest);
63 
65  "r %s %s %s%s%s %s %" PRIu16 " %" PRIu16 "\n",
66  rs->nickname,
67  identity64,
68  (format==NS_V3_CONSENSUS_MICRODESC)?"":digest64,
69  (format==NS_V3_CONSENSUS_MICRODESC)?"":" ",
70  published,
71  ip_str,
72  rs->ipv4_orport,
73  rs->ipv4_dirport);
74 
75  /* TODO: Maybe we want to pass in what we need to build the rest of
76  * this here, instead of in the caller. Then we could use the
77  * networkstatus_type_t values, with an additional control port value
78  * added -MP */
79 
80  /* Possible "a" line. At most one for now. */
81  if (!tor_addr_is_null(&rs->ipv6_addr)) {
82  smartlist_add_asprintf(chunks, "a %s\n",
84  }
85 
86  if (format == NS_V3_CONSENSUS || format == NS_V3_CONSENSUS_MICRODESC)
87  goto done;
88 
90  "s%s%s%s%s%s%s%s%s%s%s%s\n",
91  /* These must stay in alphabetical order. */
92  rs->is_authority?" Authority":"",
93  rs->is_bad_exit?" BadExit":"",
94  rs->is_exit?" Exit":"",
95  rs->is_fast?" Fast":"",
96  rs->is_possible_guard?" Guard":"",
97  rs->is_hs_dir?" HSDir":"",
98  rs->is_flagged_running?" Running":"",
99  rs->is_stable?" Stable":"",
100  rs->is_staledesc?" StaleDesc":"",
101  rs->is_v2_dir?" V2Dir":"",
102  rs->is_valid?" Valid":"");
103 
104  /* length of "opt v \n" */
105 #define V_LINE_OVERHEAD 7
106  if (version && strlen(version) < MAX_V_LINE_LEN - V_LINE_OVERHEAD) {
107  smartlist_add_asprintf(chunks, "v %s\n", version);
108  }
109  if (protocols) {
110  smartlist_add_asprintf(chunks, "pr %s\n", protocols);
111  }
112 
113  if (format != NS_V2) {
115  uint32_t bw_kb;
116 
117  if (format != NS_CONTROL_PORT) {
118  /* Blow up more or less nicely if we didn't get anything or not the
119  * thing we expected.
120  * This should be kept in sync with the function
121  * routerstatus_has_visibly_changed and the struct routerstatus_t
122  */
123  if (!desc) {
124  char id[HEX_DIGEST_LEN+1];
125  char dd[HEX_DIGEST_LEN+1];
126 
127  base16_encode(id, sizeof(id), rs->identity_digest, DIGEST_LEN);
128  base16_encode(dd, sizeof(dd), rs->descriptor_digest, DIGEST_LEN);
129  log_warn(LD_BUG, "Cannot get any descriptor for %s "
130  "(wanted descriptor %s).",
131  id, dd);
132  goto err;
133  }
134 
135  /* This assert could fire for the control port, because
136  * it can request NS documents before all descriptors
137  * have been fetched. Therefore, we only do this test when
138  * format != NS_CONTROL_PORT. */
139  if (tor_memneq(desc->cache_info.signed_descriptor_digest,
140  rs->descriptor_digest,
141  DIGEST_LEN)) {
142  char rl_d[HEX_DIGEST_LEN+1];
143  char rs_d[HEX_DIGEST_LEN+1];
144  char id[HEX_DIGEST_LEN+1];
145 
146  base16_encode(rl_d, sizeof(rl_d),
147  desc->cache_info.signed_descriptor_digest, DIGEST_LEN);
148  base16_encode(rs_d, sizeof(rs_d), rs->descriptor_digest, DIGEST_LEN);
149  base16_encode(id, sizeof(id), rs->identity_digest, DIGEST_LEN);
150  log_err(LD_BUG, "descriptor digest in routerlist does not match "
151  "the one in routerstatus: %s vs %s "
152  "(router %s)\n",
153  rl_d, rs_d, id);
154 
156  rs->descriptor_digest,
157  DIGEST_LEN));
158  }
159  }
160 
161  if (format == NS_CONTROL_PORT && rs->has_bandwidth) {
162  bw_kb = rs->bandwidth_kb;
163  } else {
164  tor_assert(desc);
165  bw_kb = router_get_advertised_bandwidth_capped(desc) / 1000;
166  }
167  smartlist_add_asprintf(chunks,
168  "w Bandwidth=%d", bw_kb);
169 
170  if (format == NS_V3_VOTE && vrs && vrs->has_measured_bw) {
171  smartlist_add_asprintf(chunks,
172  " Measured=%d", vrs->measured_bw_kb);
173  }
174  /* Write down guardfraction information if we have it. */
175  if (format == NS_V3_VOTE && vrs && vrs->status.has_guardfraction) {
176  smartlist_add_asprintf(chunks,
177  " GuardFraction=%d",
179  }
180 
181  smartlist_add_strdup(chunks, "\n");
182 
183  if (desc) {
184  summary = policy_summarize(desc->exit_policy, AF_INET);
185  smartlist_add_asprintf(chunks, "p %s\n", summary);
186  tor_free(summary);
187  }
188 
189  if (format == NS_V3_VOTE && vrs) {
190  if (fast_mem_is_zero((char*)vrs->ed25519_id, ED25519_PUBKEY_LEN)) {
191  smartlist_add_strdup(chunks, "id ed25519 none\n");
192  } else {
193  char ed_b64[BASE64_DIGEST256_LEN+1];
194  digest256_to_base64(ed_b64, (const char*)vrs->ed25519_id);
195  smartlist_add_asprintf(chunks, "id ed25519 %s\n", ed_b64);
196  }
197  }
198  }
199 
200  done:
201  result = smartlist_join_strings(chunks, "", 0, NULL);
202 
203  err:
204  SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
205  smartlist_free(chunks);
206 
207  return result;
208 }
routerstatus_t::ipv4_dirport
uint16_t ipv4_dirport
Definition: routerstatus_st.h:34
tor_free
#define tor_free(p)
Definition: malloc.h:52
routerinfo_t
Definition: routerinfo_st.h:20
routerstatus_t::is_authority
unsigned int is_authority
Definition: routerstatus_st.h:37
routerstatus_t::is_staledesc
unsigned int is_staledesc
Definition: routerstatus_st.h:59
smartlist_add_strdup
void smartlist_add_strdup(struct smartlist_t *sl, const char *string)
Definition: smartlist_core.c:137
BASE64_DIGEST256_LEN
#define BASE64_DIGEST256_LEN
Definition: crypto_digest.h:29
routerstatus_t::is_flagged_running
unsigned int is_flagged_running
Definition: routerstatus_st.h:45
tor_assert
#define tor_assert(expr)
Definition: util_bug.h:102
LD_BUG
#define LD_BUG
Definition: log.h:86
format_iso_time
void format_iso_time(char *buf, time_t t)
Definition: time_fmt.c:295
fast_mem_is_zero
int fast_mem_is_zero(const char *mem, size_t len)
Definition: util_string.c:74
routerstatus_t::is_valid
unsigned int is_valid
Definition: routerstatus_st.h:49
base16_encode
void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen)
Definition: binascii.c:478
routerstatus_t::has_guardfraction
unsigned int has_guardfraction
Definition: routerstatus_st.h:74
routerstatus_t
Definition: routerstatus_st.h:19
routerstatus_t::nickname
char nickname[MAX_NICKNAME_LEN+1]
Definition: routerstatus_st.h:25
ED25519_PUBKEY_LEN
#define ED25519_PUBKEY_LEN
Definition: x25519_sizes.h:27
smartlist_new
smartlist_t * smartlist_new(void)
Definition: smartlist_core.c:26
SMARTLIST_FOREACH
#define SMARTLIST_FOREACH(sl, type, var, cmd)
Definition: smartlist_foreach.h:112
routerstatus_t::is_fast
unsigned int is_fast
Definition: routerstatus_st.h:40
routerstatus_t::has_bandwidth
unsigned int has_bandwidth
Definition: routerstatus_st.h:62
fmt_routerstatus.h
Format routerstatus entries for controller, vote, or consensus.
router_get_by_id_digest
const routerinfo_t * router_get_by_id_digest(const char *digest)
Definition: routerlist.c:776
digest256_to_base64
void digest256_to_base64(char *d64, const char *digest)
Definition: crypto_format.c:304
tor_memeq
int tor_memeq(const void *a, const void *b, size_t sz)
Definition: di_ops.c:107
routerstatus_format_entry
char * routerstatus_format_entry(const routerstatus_t *rs, const char *version, const char *protocols, routerstatus_format_type_t format, const vote_routerstatus_t *vrs)
Definition: fmt_routerstatus.c:43
DIGEST_LEN
#define DIGEST_LEN
Definition: digest_sizes.h:20
routerstatus_t::is_possible_guard
unsigned int is_possible_guard
Definition: routerstatus_st.h:50
crypto_format.h
Header for crypto_format.c.
routerstatus_t::ipv4_orport
uint16_t ipv4_orport
Definition: routerstatus_st.h:33
tor_memneq
#define tor_memneq(a, b, sz)
Definition: di_ops.h:21
dirvote.h
Header file for dirvote.c.
vote_routerstatus_st.h
Routerstatus (vote entry) structure.
vote_routerstatus_t::ed25519_id
uint8_t ed25519_id[ED25519_PUBKEY_LEN]
Definition: vote_routerstatus_st.h:42
vote_routerstatus_t
Definition: vote_routerstatus_st.h:18
routerstatus_t::published_on
time_t published_on
Definition: routerstatus_st.h:24
signed_descriptor_t::signed_descriptor_digest
char signed_descriptor_digest[DIGEST_LEN]
Definition: signed_descriptor_st.h:29
NS_V2
@ NS_V2
Definition: fmt_routerstatus.h:19
routerinfo_t::exit_policy
smartlist_t * exit_policy
Definition: routerinfo_st.h:59
routerlist.h
Header file for routerlist.c.
vote_routerstatus_t::has_measured_bw
unsigned int has_measured_bw
Definition: vote_routerstatus_st.h:30
policy_summarize
char * policy_summarize(smartlist_t *policy, sa_family_t family)
Definition: policies.c:2573
routerinfo_st.h
Router descriptor structure.
BASE64_DIGEST_LEN
#define BASE64_DIGEST_LEN
Definition: crypto_digest.h:26
routerstatus_t::is_stable
unsigned int is_stable
Definition: routerstatus_st.h:39
fmt_addr
#define fmt_addr(a)
Definition: address.h:239
routerstatus_t::is_exit
unsigned int is_exit
Definition: routerstatus_st.h:38
routerstatus_t::descriptor_digest
char descriptor_digest[DIGEST256_LEN]
Definition: routerstatus_st.h:31
fmt_addrport
const char * fmt_addrport(const tor_addr_t *addr, uint16_t port)
Definition: address.c:1199
routerstatus_t::guardfraction_percentage
uint32_t guardfraction_percentage
Definition: routerstatus_st.h:76
NS_V3_CONSENSUS
@ NS_V3_CONSENSUS
Definition: fmt_routerstatus.h:21
routerstatus_t::is_bad_exit
unsigned int is_bad_exit
Definition: routerstatus_st.h:52
tor_addr_is_null
int tor_addr_is_null(const tor_addr_t *addr)
Definition: address.c:780
routerstatus_t::bandwidth_kb
uint32_t bandwidth_kb
Definition: routerstatus_st.h:70
NS_CONTROL_PORT
@ NS_CONTROL_PORT
Definition: fmt_routerstatus.h:25
HEX_DIGEST_LEN
#define HEX_DIGEST_LEN
Definition: crypto_digest.h:35
routerstatus_t::ipv6_addr
tor_addr_t ipv6_addr
Definition: routerstatus_st.h:35
MAX_V_LINE_LEN
#define MAX_V_LINE_LEN
Definition: fmt_routerstatus.h:31
vote_routerstatus_t::status
routerstatus_t status
Definition: vote_routerstatus_st.h:19
policies.h
Header file for policies.c.
NS_V3_CONSENSUS_MICRODESC
@ NS_V3_CONSENSUS_MICRODESC
Definition: fmt_routerstatus.h:27
router_get_advertised_bandwidth_capped
uint32_t router_get_advertised_bandwidth_capped(const routerinfo_t *router)
Definition: routerlist.c:657
smartlist_add_asprintf
void smartlist_add_asprintf(struct smartlist_t *sl, const char *pattern,...)
Definition: smartlist.c:36
digest_to_base64
void digest_to_base64(char *d64, const char *digest)
Definition: crypto_format.c:275
routerstatus_t::is_hs_dir
unsigned int is_hs_dir
Definition: routerstatus_st.h:54
routerstatus_t::ipv6_orport
uint16_t ipv6_orport
Definition: routerstatus_st.h:36
routerstatus_format_type_t
routerstatus_format_type_t
Definition: fmt_routerstatus.h:17
routerstatus_t::identity_digest
char identity_digest[DIGEST_LEN]
Definition: routerstatus_st.h:27
smartlist_t
Definition: smartlist_core.h:26
smartlist_join_strings
char * smartlist_join_strings(smartlist_t *sl, const char *join, int terminate, size_t *len_out)
Definition: smartlist.c:279
vote_routerstatus_t::measured_bw_kb
uint32_t measured_bw_kb
Definition: vote_routerstatus_st.h:38
NS_V3_VOTE
@ NS_V3_VOTE
Definition: fmt_routerstatus.h:23
or.h
Master header file for Tor-specific functionality.