]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
protover: Move all hardcoded lists in one place
authorDavid Goulet <dgoulet@torproject.org>
Fri, 5 Nov 2021 14:10:24 +0000 (10:10 -0400)
committerDavid Goulet <dgoulet@torproject.org>
Fri, 5 Nov 2021 14:13:47 +0000 (10:13 -0400)
This also moves the warnings and add some theatrical effect around the
code so anyone modifying those list should notice the warnings signs and
read the comment accordingly.

Signed-off-by: David Goulet <dgoulet@torproject.org>
src/core/or/protover.c
src/core/or/protover.h
src/feature/dirauth/dirvote.c

index a882d1a77d785decaa980252c746c00bc43486d7..0183704c2ca4e78c8b6b723d0f5cba97e0ebf055 100644 (file)
@@ -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. */
index 7e181ba97a3e266b85fb390d066151f8a25ccf12..c99dfe40ae026d5b0332c7d76f35351132fda4af 100644 (file)
@@ -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);
index 5ecf680f02f00f8d2d420ed100f1ad1e2efbc5ae..d6a99d3ef89c3c496257c1038e41ada2546e2dd1 100644 (file)
@@ -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));