aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/or/protover.c107
-rw-r--r--src/core/or/protover.h4
-rw-r--r--src/feature/dirauth/dirvote.c37
3 files changed, 104 insertions, 44 deletions
diff --git a/src/core/or/protover.c b/src/core/or/protover.c
index a882d1a77d..0183704c2c 100644
--- a/src/core/or/protover.c
+++ b/src/core/or/protover.c
@@ -376,6 +376,10 @@ protocol_list_supports_protocol_or_later(const char *list,
return contains;
}
+/*
+ * XXX START OF HAZARDOUS ZONE XXX
+ */
+
/** Return the canonical string containing the list of protocols
* that we support.
**/
@@ -383,25 +387,37 @@ protocol_list_supports_protocol_or_later(const char *list,
const char *
protover_get_supported_protocols(void)
{
+
/*
- * WARNING!
+ * XXX: WARNING!
*
* Be EXTREMELY CAREFUL when *removing* versions from this list. If you
* remove an entry while it still appears as "recommended" in the consensus,
- * you'll cause all the instances without it to warn. If you remove an entry
- * while it still appears as "required" in the consensus, you'll cause
- * all the instances without it to refuse to connect to the network, and
- * shut down.
+ * you'll cause all the instances without it to warn.
+ *
+ * If you remove an entry while it still appears as "required" in the
+ * consensus, you'll cause all the instances without it to refuse to connect
+ * to the network, and shut down.
+ *
+ * If you need to remove a version from this list, you need to make sure that
+ * it is not listed in the _current consensuses_: just removing it from the
+ * required list below is NOT ENOUGH. You need to remove it from the
+ * required list, and THEN let the authorities update and vote on new
+ * consensuses without it. Only once those consensuses are out is it safe to
+ * remove from this list.
*
- * If you need to remove a version from this list, you need to make sure
- * that it is not listed in the _current consensuses_: just removing it from
- * the required list in dirvote.c is NOT ENOUGH. You need to remove it from
- * the required list dirvote.c, and THEN let the authorities update and vote
- * on new consensuses without it. Only once those consensuses are out is
- * it safe to remove from this list.
+ * One concrete example of a very dangerous race that could occur:
*
- * WARNING!
+ * If the client required protocol "HSDir=1-2" is then changed in the code
+ * and released to "HSDir=2" while the consensus stills lists "HSDir=1-2",
+ * then these clients, even very recent ones, will shutdown because they
+ * don't support "HSDir=1".
+ *
+ * And so, changes need to be done in lockstep as described above.
+ *
+ * XXX: WARNING!
*/
+
return
"Cons=1-2 "
"Desc=1-2 "
@@ -419,6 +435,73 @@ protover_get_supported_protocols(void)
"Relay=1-2";
}
+/*
+ * XXX: WARNING!
+ *
+ * The recommended and required values are hardwired, to avoid disaster. Voting
+ * on the wrong subprotocols here has the potential to take down the network.
+ *
+ * In particular, you need to be EXTREMELY CAREFUL before adding new versions
+ * to the required protocol list. Doing so will cause every relay or client
+ * that doesn't support those versions to refuse to connect to the network and
+ * shut down.
+ *
+ * Note that this applies to versions, not just protocols! If you say that
+ * Foobar=8-9 is required, and the client only has Foobar=9, it will shut down.
+ *
+ * It is okay to do this only for SUPER OLD relays that are not supported on
+ * the network anyway. For clients, we really shouldn't kick them off the
+ * network unless their presence is causing serious active harm.
+ *
+ * The following required and recommended lists MUST be changed BEFORE the
+ * supported list above is changed in order for those lists to appear in the
+ * consensus BEFORE.
+ *
+ * Please, see the warning in protocol_get_supported_versions().
+ *
+ * XXX: WARNING!
+ */
+
+/** Return the recommended client protocols list that directory authorities
+ * put in the consensus. */
+const char *
+protover_get_recommended_client_protocols(void)
+{
+ return "Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 "
+ "Link=4 Microdesc=1-2 Relay=2";
+}
+
+/** Return the recommended relay protocols list that directory authorities
+ * put in the consensus. */
+const char *
+protover_get_recommended_relay_protocols(void)
+{
+ return "Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 "
+ "Link=4 Microdesc=1-2 Relay=2";
+}
+
+/** Return the required client protocols list that directory authorities
+ * put in the consensus. */
+const char *
+protover_get_required_client_protocols(void)
+{
+ return "Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 "
+ "Link=4 Microdesc=1-2 Relay=2";
+}
+
+/** Return the required relay protocols list that directory authorities
+ * put in the consensus. */
+const char *
+protover_get_required_relay_protocols(void)
+{
+ return "Cons=1 Desc=1 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 "
+ "Link=3-4 Microdesc=1 Relay=1-2";
+}
+
+/*
+ * XXX END OF HAZARDOUS ZONE XXX
+ */
+
/** The protocols from protover_get_supported_protocols(), as parsed into a
* list of proto_entry_t values. Access this via
* get_supported_protocol_list. */
diff --git a/src/core/or/protover.h b/src/core/or/protover.h
index 7e181ba97a..c99dfe40ae 100644
--- a/src/core/or/protover.h
+++ b/src/core/or/protover.h
@@ -49,6 +49,10 @@ bool protover_contains_long_protocol_names(const char *s);
int protover_all_supported(const char *s, char **missing);
int protover_is_supported_here(protocol_type_t pr, uint32_t ver);
const char *protover_get_supported_protocols(void);
+const char *protover_get_recommended_client_protocols(void);
+const char *protover_get_recommended_relay_protocols(void);
+const char *protover_get_required_client_protocols(void);
+const char *protover_get_required_relay_protocols(void);
char *protover_compute_vote(const struct smartlist_t *list_of_proto_strings,
int threshold);
diff --git a/src/feature/dirauth/dirvote.c b/src/feature/dirauth/dirvote.c
index 5ecf680f02..d6a99d3ef8 100644
--- a/src/feature/dirauth/dirvote.c
+++ b/src/feature/dirauth/dirvote.c
@@ -180,7 +180,7 @@ format_protocols_lines_for_vote(const networkstatus_t *v3_ns)
char *required_relay_protocols_line = NULL;
char *required_client_protocols_line = NULL;
- recommended_relay_protocols_line =
+ recommended_relay_protocols_line =
format_line_if_present("recommended-relay-protocols",
v3_ns->recommended_relay_protocols);
recommended_client_protocols_line =
@@ -4577,41 +4577,14 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key,
v3_out->client_versions = client_versions;
v3_out->server_versions = server_versions;
- /*
- * WARNING!
- *
- * These values are hardwired, to avoid disaster. Voting on the wrong
- * subprotocols here has the potential to take down the network.
- *
- * In particular, you need to be EXTREMELY CAREFUL before adding new
- * versions to the required protocol list. Doing so will cause every relay
- * or client that doesn't support those versions to refuse to connect to the
- * network and shut down.
- *
- * Note that this applies to versions, not just protocols! If you say that
- * Foobar=8-9 is required, and the client only has Foobar=9, it will shut
- * down.
- *
- * It is okay to do this only for SUPER OLD relays that are not supported on
- * the network anyway. For clients, we really shouldn't kick them off the
- * network unless their presence is causing serious active harm.
- *
- * See also the warning in protocol_get_supported_versions().
- *
- * WARNING!
- */
v3_out->recommended_relay_protocols =
- tor_strdup("Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 "
- "Link=4 Microdesc=1-2 Relay=2");
+ tor_strdup(protover_get_recommended_relay_protocols());
v3_out->recommended_client_protocols =
- tor_strdup("Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 "
- "Link=4 Microdesc=1-2 Relay=2");
+ tor_strdup(protover_get_recommended_client_protocols());
v3_out->required_client_protocols =
- tor_strdup("Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 "
- "Link=4 Microdesc=1-2 Relay=2");
+ tor_strdup(protover_get_required_client_protocols());
v3_out->required_relay_protocols =
- tor_strdup("Cons=1 Desc=1 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 "
- "Link=3-4 Microdesc=1 Relay=1-2");
+ tor_strdup(protover_get_required_relay_protocols());
/* We are not allowed to vote to require anything we don't have. */
tor_assert(protover_all_supported(v3_out->required_relay_protocols, NULL));