diff --git a/changes/prop297 b/changes/prop297 new file mode 100644 index 0000000000..4f93b232d2 --- /dev/null +++ b/changes/prop297 @@ -0,0 +1,7 @@ + o Minor features (required protocols): + - Tor no longer exits if it is missing a required protocol, if the + consensus that requires the protocol predates the release date of the + version of Tor. This change prevents Tor releases from exiting because + of an old cached consensus, on the theory that a newer cached + consensus might not require the protocol. Implements proposal 297; + closes ticket 27735. diff --git a/src/core/or/versions.c b/src/core/or/versions.c index 5d4effcaf8..d978935f4f 100644 --- a/src/core/or/versions.c +++ b/src/core/or/versions.c @@ -16,6 +16,25 @@ #include "core/or/tor_version_st.h" +/** + * Return the approximate date when this release came out, or was + * scheduled to come out, according to the APPROX_RELEASE_DATE set in + * configure.ac + **/ +time_t +tor_get_approx_release_date(void) +{ + char tbuf[ISO_TIME_LEN+1]; + tor_snprintf(tbuf, sizeof(tbuf), + "%s 00:00:00", APPROX_RELEASE_DATE); + time_t result = 0; + int r = parse_iso_time(tbuf, &result); + if (BUG(r < 0)) { + result = 0; + } + return result; +} + /** Return VS_RECOMMENDED if myversion is contained in * versionlist. Else, return VS_EMPTY if versionlist has no * entries. Else, return VS_OLD if every member of diff --git a/src/core/or/versions.h b/src/core/or/versions.h index 4fc50a0018..acd8998918 100644 --- a/src/core/or/versions.h +++ b/src/core/or/versions.h @@ -26,6 +26,8 @@ typedef enum version_status_t { VS_UNKNOWN, /**< We have no idea. */ } version_status_t; +time_t tor_get_approx_release_date(void); + version_status_t tor_version_is_obsolete(const char *myversion, const char *versionlist); int tor_version_parse_platform(const char *platform, diff --git a/src/feature/nodelist/networkstatus.c b/src/feature/nodelist/networkstatus.c index f1def9afb1..a25a539cd8 100644 --- a/src/feature/nodelist/networkstatus.c +++ b/src/feature/nodelist/networkstatus.c @@ -2684,6 +2684,9 @@ networkstatus_check_required_protocols(const networkstatus_t *ns, const char *required, *recommended; char *missing = NULL; + const bool consensus_postdates_this_release = + ns->valid_after >= tor_get_approx_release_date(); + tor_assert(warning_out); if (client_mode) { @@ -2701,7 +2704,7 @@ networkstatus_check_required_protocols(const networkstatus_t *ns, "%s on the Tor network. The missing protocols are: %s", func, missing); tor_free(missing); - return 1; + return consensus_postdates_this_release ? 1 : 0; } if (! protover_all_supported(recommended, &missing)) {