24 #define PROTOVER_PRIVATE
49 { PRT_LINKAUTH,
"LinkAuth" },
50 { PRT_RELAY,
"Relay" },
51 { PRT_DIRCACHE,
"DirCache" },
52 { PRT_HSDIR,
"HSDir" },
53 { PRT_HSINTRO,
"HSIntro" },
54 { PRT_HSREND,
"HSRend" },
56 { PRT_MICRODESC,
"Microdesc"},
57 { PRT_PADDING,
"Padding"},
59 { PRT_FLOWCTRL,
"FlowCtrl"},
62 #define N_PROTOCOL_NAMES ARRAY_LENGTH(PROTOCOL_NAMES)
67 static const unsigned MAX_PROTOCOL_NAME_LENGTH = 100;
77 for (i=0; i < N_PROTOCOL_NAMES; ++i) {
82 tor_assert_nonfatal_unreached_once();
100 #define MAX_PROTOCOL_VERSION (63)
110 uint32_t *low_out, uint32_t *high_out)
119 if (BUG(!end_of_range))
120 end_of_range = s + strlen(s);
123 if (!TOR_ISDIGIT(*s)) {
132 if (next > end_of_range)
134 if (next == end_of_range) {
144 if (!TOR_ISDIGIT(*s)) {
151 if (next != end_of_range)
167 is_valid_keyword(
const char *s,
size_t n)
169 for (
size_t i = 0; i < n; i++) {
170 if (!TOR_ISALNUM(s[i]) && s[i] !=
'-')
177 #define BIT(x) (UINT64_C(1)<<(x))
186 uint64_t mask = ~(uint64_t)0;
188 mask >>= 63 - high + low;
198 static proto_entry_t *
201 proto_entry_t *out = tor_malloc_zero(
sizeof(proto_entry_t));
204 if (BUG (!end_of_entry))
205 end_of_entry = s + strlen(s);
208 equals = memchr(s,
'=', end_of_entry - s);
217 if (equals - s > (
int)MAX_PROTOCOL_NAME_LENGTH) {
218 log_warn(
LD_NET,
"When parsing a protocol entry, I got a very large "
219 "protocol name. This is possibly an attack or a bug, unless "
220 "the Tor network truly supports protocol names larger than "
221 "%ud characters. The offending string was: %s",
222 MAX_PROTOCOL_NAME_LENGTH,
escaped(out->name));
227 if (!is_valid_keyword(s, equals-s))
230 out->name = tor_strndup(s, equals-s);
235 while (s < end_of_entry) {
236 const char *comma = memchr(s,
',', end_of_entry-s);
238 comma = end_of_entry;
240 uint32_t low=0, high=0;
249 if (s < (end_of_entry - 1))
256 proto_entry_free(out);
271 const char *end_of_entry = strchr(s,
' ');
272 proto_entry_t *entry;
274 end_of_entry = s + strlen(s);
292 smartlist_free(entries);
308 smartlist_free(list);
344 smartlist_free(protocols);
373 if (strcasecmp(proto->name, pr_name))
375 if (0 != (proto->bitmask & mask)) {
379 } SMARTLIST_FOREACH_END(proto);
383 smartlist_free(protocols);
407 #ifdef HAVE_WORKING_TOR_TLS_GET_TLSSECRETS
439 return __builtin_ctzll((
unsigned long long)x);
442 for (i = 0; i <= 64; ++i) {
460 uint64_t mask = entry->bitmask;
464 const char *comma = first ?
"" :
",";
476 shift, shift + ones - 1);
491 const char *separator =
"";
499 } SMARTLIST_FOREACH_END(ent);
504 smartlist_free(chunks);
524 tor_assert(smartlist_len(list_of_proto_strings) < 256);
526 if (smartlist_len(list_of_proto_strings) == 0) {
527 return tor_strdup(
"");
538 log_warn(
LD_NET,
"I failed with parsing a protocol list from "
539 "an authority. The offending string was: %s",
547 } SMARTLIST_FOREACH_END(ent);
549 } SMARTLIST_FOREACH_END(vote);
566 for (
int i = 0; i < 64; ++i) {
567 if ((ent->bitmask &
BIT(i)) != 0) {
571 } SMARTLIST_FOREACH_END(vote);
573 uint64_t result_bitmask = 0;
574 for (
int i = 0; i < 64; ++i) {
575 if (
counts[i] >= threshold) {
576 result_bitmask |=
BIT(i);
579 if (result_bitmask != 0) {
580 proto_entry_t *newent = tor_malloc_zero(
sizeof(proto_entry_t));
581 newent->name = tor_strdup(
name);
582 newent->bitmask = result_bitmask;
585 } SMARTLIST_FOREACH_END(
name);
590 smartlist_free(result);
591 smartlist_free(proto_names);
595 } SMARTLIST_FOREACH_END(v);
596 smartlist_free(parsed);
616 if (BUG(entries == NULL)) {
617 log_warn(
LD_NET,
"Received an unparseable protocol list %s"
618 " from the consensus",
escaped(s));
627 if (ent->bitmask != 0) {
628 proto_entry_t *m = tor_malloc_zero(
sizeof(proto_entry_t));
629 m->name = tor_strdup(ent->name);
630 m->bitmask = ent->bitmask;
636 uint64_t missing_mask = ent->bitmask & ~mine->bitmask;
637 if (missing_mask != 0) {
638 proto_entry_t *m = tor_malloc_zero(
sizeof(proto_entry_t));
639 m->name = tor_strdup(ent->name);
640 m->bitmask = missing_mask;
643 } SMARTLIST_FOREACH_END(ent);
645 const int all_supported = (smartlist_len(missing) == 0);
646 if (!all_supported && missing_out) {
651 smartlist_free(missing);
654 smartlist_free(entries);
656 return all_supported;
661 static const proto_entry_t *
668 if (!strcmp(ent->name,
name)) {
671 } SMARTLIST_FOREACH_END(ent);
682 if (BUG(protos == NULL)) {
686 if (BUG(pr_name == NULL)) {
695 return (ent->bitmask &
BIT(ver)) != 0;
710 if (version == NULL) {
712 version =
"0.2.5.15";
720 return "Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1-2 "
721 "Link=1-4 LinkAuth=1 "
722 "Microdesc=1-2 Relay=1-2";
727 return "Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 "
728 "Link=1-4 LinkAuth=1 "
729 "Microdesc=1-2 Relay=1-2";
733 return "Cons=1 Desc=1 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 "
734 "Link=1-4 LinkAuth=1 "
735 "Microdesc=1 Relay=1-2";
751 smartlist_free(entries);
static conn_counts_t counts
const char * escaped(const char *s)
Master header file for Tor-specific functionality.
unsigned long tor_parse_ulong(const char *s, int base, unsigned long min, unsigned long max, int *ok, char **next)
STATIC const char * protocol_type_to_str(protocol_type_t pr)
const char * protover_compute_for_old_tor(const char *version)
C_RUST_COUPLED: src/rust/protover/protover.rs compute_for_old_tor
static const proto_entry_t * find_entry_by_name(const smartlist_t *protos, const char *name)
static uint64_t bitmask_for_range(uint32_t low, uint32_t high)
bool protover_list_is_invalid(const char *s)
STATIC void proto_entry_free_(proto_entry_t *entry)
static smartlist_t * supported_protocol_list
static const smartlist_t * get_supported_protocol_list(void)
#define MAX_PROTOCOL_VERSION
const char * protover_get_supported_protocols(void)
C_RUST_COUPLED: src/rust/protover/protover.rs SUPPORTED_PROTOCOLS
void protover_free_all(void)
static const struct @12 PROTOCOL_NAMES[]
C_RUST_COUPLED: src/rust/protover/protover.rs PROTOCOL_NAMES
static void proto_entry_encode_into(smartlist_t *chunks, const proto_entry_t *entry)
int protover_is_supported_here(protocol_type_t pr, uint32_t ver)
static int protocol_list_contains(const smartlist_t *protos, protocol_type_t pr, uint32_t ver)
static proto_entry_t * parse_single_entry(const char *s, const char *end_of_entry)
int protocol_list_supports_protocol(const char *list, protocol_type_t tp, uint32_t version)
int protocol_list_supports_protocol_or_later(const char *list, protocol_type_t tp, uint32_t version)
char * protover_compute_vote(const smartlist_t *list_of_proto_strings, int threshold)
STATIC char * encode_protocol_list(const smartlist_t *sl)
static int parse_version_range(const char *s, const char *end_of_range, uint32_t *low_out, uint32_t *high_out)
STATIC smartlist_t * parse_protocol_list(const char *s)
static int trailing_zeros(uint64_t x)
int protover_all_supported(const char *s, char **missing_out)
Headers and type declarations for protover.c.
#define FIRST_TOR_VERSION_TO_ADVERTISE_PROTOCOLS
void smartlist_add_asprintf(struct smartlist_t *sl, const char *pattern,...)
void smartlist_sort_strings(smartlist_t *sl)
char * smartlist_join_strings(smartlist_t *sl, const char *join, int terminate, size_t *len_out)
int smartlist_contains_string(const smartlist_t *sl, const char *element)
smartlist_t * smartlist_new(void)
void smartlist_add_strdup(struct smartlist_t *sl, const char *string)
void smartlist_add(smartlist_t *sl, void *element)
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
#define SMARTLIST_FOREACH(sl, type, var, cmd)
int tor_version_as_new_as(const char *platform, const char *cutoff)
Header file for versions.c.