tor  0.4.0.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-2018, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
5 
14 #include "core/or/or.h"
16 
17 /* #include "lib/container/buffers.h" */
18 /* #include "app/config/config.h" */
19 /* #include "app/config/confparse.h" */
20 /* #include "core/or/channel.h" */
21 /* #include "core/or/channeltls.h" */
22 /* #include "core/or/command.h" */
23 /* #include "core/mainloop/connection.h" */
24 /* #include "core/or/connection_or.h" */
25 /* #include "feature/dircache/conscache.h" */
26 /* #include "feature/dircache/consdiffmgr.h" */
27 /* #include "feature/control/control.h" */
28 /* #include "feature/dircache/directory.h" */
29 /* #include "feature/dircache/dirserv.h" */
30 /* #include "feature/hibernate/hibernate.h" */
31 /* #include "feature/dirauth/keypin.h" */
32 /* #include "core/mainloop/mainloop.h" */
33 /* #include "feature/nodelist/microdesc.h" */
34 /* #include "feature/nodelist/networkstatus.h" */
35 /* #include "feature/nodelist/nodelist.h" */
36 #include "core/or/policies.h"
37 /* #include "core/or/protover.h" */
38 /* #include "feature/stats/rephist.h" */
39 /* #include "feature/relay/router.h" */
40 /* #include "feature/nodelist/dirlist.h" */
42 
43 /* #include "feature/nodelist/routerparse.h" */
44 /* #include "feature/nodelist/routerset.h" */
45 /* #include "feature/nodelist/torcert.h" */
46 /* #include "feature/dircommon/voting_schedule.h" */
47 
49 
50 /* #include "feature/dircache/cached_dir_st.h" */
51 /* #include "feature/dircommon/dir_connection_st.h" */
52 /* #include "feature/nodelist/extrainfo_st.h" */
53 /* #include "feature/nodelist/microdesc_st.h" */
54 /* #include "feature/nodelist/node_st.h" */
55 #include "feature/nodelist/routerinfo_st.h"
56 /* #include "feature/nodelist/routerlist_st.h" */
57 /* #include "core/or/tor_version_st.h" */
58 #include "feature/nodelist/vote_routerstatus_st.h"
59 
60 /* #include "lib/compress/compress.h" */
61 /* #include "lib/container/order.h" */
63 /* #include "lib/encoding/confline.h" */
64 
65 /* #include "lib/encoding/keyval.h" */
66 
87 char *
88 routerstatus_format_entry(const routerstatus_t *rs, const char *version,
89  const char *protocols,
91  int consensus_method,
92  const vote_routerstatus_t *vrs)
93 {
94  char *summary;
95  char *result = NULL;
96 
97  char published[ISO_TIME_LEN+1];
98  char identity64[BASE64_DIGEST_LEN+1];
99  char digest64[BASE64_DIGEST_LEN+1];
100  smartlist_t *chunks = smartlist_new();
101 
102  format_iso_time(published, rs->published_on);
103  digest_to_base64(identity64, rs->identity_digest);
104  digest_to_base64(digest64, rs->descriptor_digest);
105 
106  smartlist_add_asprintf(chunks,
107  "r %s %s %s%s%s %s %d %d\n",
108  rs->nickname,
109  identity64,
110  (format==NS_V3_CONSENSUS_MICRODESC)?"":digest64,
111  (format==NS_V3_CONSENSUS_MICRODESC)?"":" ",
112  published,
113  fmt_addr32(rs->addr),
114  (int)rs->or_port,
115  (int)rs->dir_port);
116 
117  /* TODO: Maybe we want to pass in what we need to build the rest of
118  * this here, instead of in the caller. Then we could use the
119  * networkstatus_type_t values, with an additional control port value
120  * added -MP */
121 
122  /* V3 microdesc consensuses only have "a" lines in later consensus methods
123  */
124  if (format == NS_V3_CONSENSUS_MICRODESC &&
126  goto done;
127 
128  /* Possible "a" line. At most one for now. */
129  if (!tor_addr_is_null(&rs->ipv6_addr)) {
130  smartlist_add_asprintf(chunks, "a %s\n",
131  fmt_addrport(&rs->ipv6_addr, rs->ipv6_orport));
132  }
133 
134  if (format == NS_V3_CONSENSUS || format == NS_V3_CONSENSUS_MICRODESC)
135  goto done;
136 
137  smartlist_add_asprintf(chunks,
138  "s%s%s%s%s%s%s%s%s%s%s%s\n",
139  /* These must stay in alphabetical order. */
140  rs->is_authority?" Authority":"",
141  rs->is_bad_exit?" BadExit":"",
142  rs->is_exit?" Exit":"",
143  rs->is_fast?" Fast":"",
144  rs->is_possible_guard?" Guard":"",
145  rs->is_hs_dir?" HSDir":"",
146  rs->is_flagged_running?" Running":"",
147  rs->is_stable?" Stable":"",
148  rs->is_staledesc?" StaleDesc":"",
149  rs->is_v2_dir?" V2Dir":"",
150  rs->is_valid?" Valid":"");
151 
152  /* length of "opt v \n" */
153 #define V_LINE_OVERHEAD 7
154  if (version && strlen(version) < MAX_V_LINE_LEN - V_LINE_OVERHEAD) {
155  smartlist_add_asprintf(chunks, "v %s\n", version);
156  }
157  if (protocols) {
158  smartlist_add_asprintf(chunks, "pr %s\n", protocols);
159  }
160 
161  if (format != NS_V2) {
163  uint32_t bw_kb;
164 
165  if (format != NS_CONTROL_PORT) {
166  /* Blow up more or less nicely if we didn't get anything or not the
167  * thing we expected.
168  */
169  if (!desc) {
170  char id[HEX_DIGEST_LEN+1];
171  char dd[HEX_DIGEST_LEN+1];
172 
173  base16_encode(id, sizeof(id), rs->identity_digest, DIGEST_LEN);
174  base16_encode(dd, sizeof(dd), rs->descriptor_digest, DIGEST_LEN);
175  log_warn(LD_BUG, "Cannot get any descriptor for %s "
176  "(wanted descriptor %s).",
177  id, dd);
178  goto err;
179  }
180 
181  /* This assert could fire for the control port, because
182  * it can request NS documents before all descriptors
183  * have been fetched. Therefore, we only do this test when
184  * format != NS_CONTROL_PORT. */
185  if (tor_memneq(desc->cache_info.signed_descriptor_digest,
186  rs->descriptor_digest,
187  DIGEST_LEN)) {
188  char rl_d[HEX_DIGEST_LEN+1];
189  char rs_d[HEX_DIGEST_LEN+1];
190  char id[HEX_DIGEST_LEN+1];
191 
192  base16_encode(rl_d, sizeof(rl_d),
193  desc->cache_info.signed_descriptor_digest, DIGEST_LEN);
194  base16_encode(rs_d, sizeof(rs_d), rs->descriptor_digest, DIGEST_LEN);
195  base16_encode(id, sizeof(id), rs->identity_digest, DIGEST_LEN);
196  log_err(LD_BUG, "descriptor digest in routerlist does not match "
197  "the one in routerstatus: %s vs %s "
198  "(router %s)\n",
199  rl_d, rs_d, id);
200 
202  rs->descriptor_digest,
203  DIGEST_LEN));
204  }
205  }
206 
207  if (format == NS_CONTROL_PORT && rs->has_bandwidth) {
208  bw_kb = rs->bandwidth_kb;
209  } else {
210  tor_assert(desc);
211  bw_kb = router_get_advertised_bandwidth_capped(desc) / 1000;
212  }
213  smartlist_add_asprintf(chunks,
214  "w Bandwidth=%d", bw_kb);
215 
216  if (format == NS_V3_VOTE && vrs && vrs->has_measured_bw) {
217  smartlist_add_asprintf(chunks,
218  " Measured=%d", vrs->measured_bw_kb);
219  }
220  /* Write down guardfraction information if we have it. */
221  if (format == NS_V3_VOTE && vrs && vrs->status.has_guardfraction) {
222  smartlist_add_asprintf(chunks,
223  " GuardFraction=%d",
225  }
226 
227  smartlist_add_strdup(chunks, "\n");
228 
229  if (desc) {
230  summary = policy_summarize(desc->exit_policy, AF_INET);
231  smartlist_add_asprintf(chunks, "p %s\n", summary);
232  tor_free(summary);
233  }
234 
235  if (format == NS_V3_VOTE && vrs) {
236  if (tor_mem_is_zero((char*)vrs->ed25519_id, ED25519_PUBKEY_LEN)) {
237  smartlist_add_strdup(chunks, "id ed25519 none\n");
238  } else {
239  char ed_b64[BASE64_DIGEST256_LEN+1];
240  digest256_to_base64(ed_b64, (const char*)vrs->ed25519_id);
241  smartlist_add_asprintf(chunks, "id ed25519 %s\n", ed_b64);
242  }
243  }
244  }
245 
246  done:
247  result = smartlist_join_strings(chunks, "", 0, NULL);
248 
249  err:
250  SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
251  smartlist_free(chunks);
252 
253  return result;
254 }
uint32_t router_get_advertised_bandwidth_capped(const routerinfo_t *router)
Definition: routerlist.c:571
int digest256_to_base64(char *d64, const char *digest)
unsigned int is_fast
unsigned int is_valid
Format routerstatus entries for controller, vote, or consensus.
char * policy_summarize(smartlist_t *policy, sa_family_t family)
Definition: policies.c:2604
unsigned int is_hs_dir
void smartlist_add_strdup(struct smartlist_t *sl, const char *string)
int tor_mem_is_zero(const char *mem, size_t len)
Definition: util_string.c:74
char identity_digest[DIGEST_LEN]
uint32_t bandwidth_kb
char signed_descriptor_digest[DIGEST_LEN]
int digest_to_base64(char *d64, const char *digest)
#define tor_free(p)
Definition: malloc.h:52
char * routerstatus_format_entry(const routerstatus_t *rs, const char *version, const char *protocols, routerstatus_format_type_t format, int consensus_method, const vote_routerstatus_t *vrs)
unsigned int has_guardfraction
unsigned int is_authority
Header file for policies.c.
tor_assert(buffer)
Header for crypto_format.c.
int tor_memeq(const void *a, const void *b, size_t sz)
Definition: di_ops.c:107
const char * fmt_addrport(const tor_addr_t *addr, uint16_t port)
Definition: address.c:1157
unsigned int is_staledesc
smartlist_t * exit_policy
Definition: routerinfo_st.h:56
const routerinfo_t * router_get_by_id_digest(const char *digest)
Definition: routerlist.c:690
#define DIGEST_LEN
Definition: digest_sizes.h:20
void smartlist_add_asprintf(struct smartlist_t *sl, const char *pattern,...)
Definition: smartlist.c:36
Master header file for Tor-specific functionality.
const char * fmt_addr32(uint32_t addr)
Definition: address.c:1169
tor_addr_t ipv6_addr
int tor_addr_is_null(const tor_addr_t *addr)
Definition: address.c:758
char nickname[MAX_NICKNAME_LEN+1]
void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen)
Definition: binascii.c:476
unsigned int is_exit
#define MIN_METHOD_FOR_A_LINES_IN_MICRODESC_CONSENSUS
Definition: dirvote.h:76
#define MAX_V_LINE_LEN
unsigned int has_bandwidth
char descriptor_digest[DIGEST256_LEN]
#define HEX_DIGEST_LEN
Definition: crypto_digest.h:35
unsigned int is_possible_guard
uint8_t ed25519_id[ED25519_PUBKEY_LEN]
void format_iso_time(char *buf, time_t t)
Definition: time_fmt.c:291
char * smartlist_join_strings(smartlist_t *sl, const char *join, int terminate, size_t *len_out)
Definition: smartlist.c:279
Header file for dirvote.c.
#define SMARTLIST_FOREACH(sl, type, var, cmd)
routerstatus_format_type_t
#define BASE64_DIGEST_LEN
Definition: crypto_digest.h:26
unsigned int is_stable
#define BASE64_DIGEST256_LEN
Definition: crypto_digest.h:29
uint16_t ipv6_orport
unsigned int is_flagged_running
uint32_t guardfraction_percentage
unsigned int is_bad_exit
#define LD_BUG
Definition: log.h:82
Header file for routerlist.c.