[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [tor/master] Extract the version-managing code from routerparse.c
commit 2f5dc486993b88eb23de7f06043991f08e4d0d73
Author: Nick Mathewson <nickm@xxxxxxxxxxxxxx>
Date: Sun Sep 30 18:27:23 2018 -0500
Extract the version-managing code from routerparse.c
Leave the versions.h include in routerparse.h for now; I'll remove
it later.
---
src/core/include.am | 2 +
src/core/or/versions.c | 377 +++++++++++++++++++++++++++++++++++++
src/core/or/versions.h | 40 ++++
src/feature/dirparse/routerparse.c | 364 -----------------------------------
src/feature/dirparse/routerparse.h | 25 +--
5 files changed, 421 insertions(+), 387 deletions(-)
diff --git a/src/core/include.am b/src/core/include.am
index 45f4cb5c4..c1f63c751 100644
--- a/src/core/include.am
+++ b/src/core/include.am
@@ -46,6 +46,7 @@ LIBTOR_APP_A_SOURCES = \
src/core/or/scheduler_kist.c \
src/core/or/scheduler_vanilla.c \
src/core/or/status.c \
+ src/core/or/versions.c \
src/core/proto/proto_cell.c \
src/core/proto/proto_control0.c \
src/core/proto/proto_ext_or.c \
@@ -241,6 +242,7 @@ noinst_HEADERS += \
src/core/or/status.h \
src/core/or/tor_version_st.h \
src/core/or/var_cell_st.h \
+ src/core/or/versions.h \
src/core/proto/proto_cell.h \
src/core/proto/proto_control0.h \
src/core/proto/proto_ext_or.h \
diff --git a/src/core/or/versions.c b/src/core/or/versions.c
new file mode 100644
index 000000000..2d2486298
--- /dev/null
+++ b/src/core/or/versions.c
@@ -0,0 +1,377 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file versions.c
+ * \brief Code to manipulate, parse, and compare Tor versions.
+ */
+#include "core/or/or.h"
+
+#include "core/or/versions.h"
+#include "lib/crypt_ops/crypto_util.h"
+
+#include "core/or/tor_version_st.h"
+
+/** Return VS_RECOMMENDED if <b>myversion</b> is contained in
+ * <b>versionlist</b>. Else, return VS_EMPTY if versionlist has no
+ * entries. Else, return VS_OLD if every member of
+ * <b>versionlist</b> is newer than <b>myversion</b>. Else, return
+ * VS_NEW_IN_SERIES if there is at least one member of <b>versionlist</b> in
+ * the same series (major.minor.micro) as <b>myversion</b>, but no such member
+ * is newer than <b>myversion.</b>. Else, return VS_NEW if every member of
+ * <b>versionlist</b> is older than <b>myversion</b>. Else, return
+ * VS_UNRECOMMENDED.
+ *
+ * (versionlist is a comma-separated list of version strings,
+ * optionally prefixed with "Tor". Versions that can't be parsed are
+ * ignored.)
+ */
+version_status_t
+tor_version_is_obsolete(const char *myversion, const char *versionlist)
+{
+ tor_version_t mine, other;
+ int found_newer = 0, found_older = 0, found_newer_in_series = 0,
+ found_any_in_series = 0, r, same;
+ version_status_t ret = VS_UNRECOMMENDED;
+ smartlist_t *version_sl;
+
+ log_debug(LD_CONFIG,"Checking whether version '%s' is in '%s'",
+ myversion, versionlist);
+
+ if (tor_version_parse(myversion, &mine)) {
+ log_err(LD_BUG,"I couldn't parse my own version (%s)", myversion);
+ tor_assert(0);
+ }
+ version_sl = smartlist_new();
+ smartlist_split_string(version_sl, versionlist, ",", SPLIT_SKIP_SPACE, 0);
+
+ if (!strlen(versionlist)) { /* no authorities cared or agreed */
+ ret = VS_EMPTY;
+ goto done;
+ }
+
+ SMARTLIST_FOREACH_BEGIN(version_sl, const char *, cp) {
+ if (!strcmpstart(cp, "Tor "))
+ cp += 4;
+
+ if (tor_version_parse(cp, &other)) {
+ /* Couldn't parse other; it can't be a match. */
+ } else {
+ same = tor_version_same_series(&mine, &other);
+ if (same)
+ found_any_in_series = 1;
+ r = tor_version_compare(&mine, &other);
+ if (r==0) {
+ ret = VS_RECOMMENDED;
+ goto done;
+ } else if (r<0) {
+ found_newer = 1;
+ if (same)
+ found_newer_in_series = 1;
+ } else if (r>0) {
+ found_older = 1;
+ }
+ }
+ } SMARTLIST_FOREACH_END(cp);
+
+ /* We didn't find the listed version. Is it new or old? */
+ if (found_any_in_series && !found_newer_in_series && found_newer) {
+ ret = VS_NEW_IN_SERIES;
+ } else if (found_newer && !found_older) {
+ ret = VS_OLD;
+ } else if (found_older && !found_newer) {
+ ret = VS_NEW;
+ } else {
+ ret = VS_UNRECOMMENDED;
+ }
+
+ done:
+ SMARTLIST_FOREACH(version_sl, char *, version, tor_free(version));
+ smartlist_free(version_sl);
+ return ret;
+}
+
+/** Extract a Tor version from a <b>platform</b> line from a router
+ * descriptor, and place the result in <b>router_version</b>.
+ *
+ * Return 1 on success, -1 on parsing failure, and 0 if the
+ * platform line does not indicate some version of Tor.
+ *
+ * If <b>strict</b> is non-zero, finding any weird version components
+ * (like negative numbers) counts as a parsing failure.
+ */
+int
+tor_version_parse_platform(const char *platform,
+ tor_version_t *router_version,
+ int strict)
+{
+ char tmp[128];
+ char *s, *s2, *start;
+
+ if (strcmpstart(platform,"Tor ")) /* nonstandard Tor; say 0. */
+ return 0;
+
+ start = (char *)eat_whitespace(platform+3);
+ if (!*start) return -1;
+ s = (char *)find_whitespace(start); /* also finds '\0', which is fine */
+ s2 = (char*)eat_whitespace(s);
+ if (!strcmpstart(s2, "(r") || !strcmpstart(s2, "(git-"))
+ s = (char*)find_whitespace(s2);
+
+ if ((size_t)(s-start+1) >= sizeof(tmp)) /* too big, no */
+ return -1;
+ strlcpy(tmp, start, s-start+1);
+
+ if (tor_version_parse(tmp, router_version)<0) {
+ log_info(LD_DIR,"Router version '%s' unparseable.",tmp);
+ return -1;
+ }
+
+ if (strict) {
+ if (router_version->major < 0 ||
+ router_version->minor < 0 ||
+ router_version->micro < 0 ||
+ router_version->patchlevel < 0 ||
+ router_version->svn_revision < 0) {
+ return -1;
+ }
+ }
+
+ return 1;
+}
+
+/** Parse the Tor version of the platform string <b>platform</b>,
+ * and compare it to the version in <b>cutoff</b>. Return 1 if
+ * the router is at least as new as the cutoff, else return 0.
+ */
+int
+tor_version_as_new_as(const char *platform, const char *cutoff)
+{
+ tor_version_t cutoff_version, router_version;
+ int r;
+ tor_assert(platform);
+
+ if (tor_version_parse(cutoff, &cutoff_version)<0) {
+ log_warn(LD_BUG,"cutoff version '%s' unparseable.",cutoff);
+ return 0;
+ }
+
+ r = tor_version_parse_platform(platform, &router_version, 0);
+ if (r == 0) {
+ /* nonstandard Tor; be safe and say yes */
+ return 1;
+ } else if (r < 0) {
+ /* unparseable version; be safe and say yes. */
+ return 1;
+ }
+
+ /* Here's why we don't need to do any special handling for svn revisions:
+ * - If neither has an svn revision, we're fine.
+ * - If the router doesn't have an svn revision, we can't assume that it
+ * is "at least" any svn revision, so we need to return 0.
+ * - If the target version doesn't have an svn revision, any svn revision
+ * (or none at all) is good enough, so return 1.
+ * - If both target and router have an svn revision, we compare them.
+ */
+
+ return tor_version_compare(&router_version, &cutoff_version) >= 0;
+}
+
+/** Parse a tor version from <b>s</b>, and store the result in <b>out</b>.
+ * Return 0 on success, -1 on failure. */
+int
+tor_version_parse(const char *s, tor_version_t *out)
+{
+ char *eos=NULL;
+ const char *cp=NULL;
+ int ok = 1;
+ /* Format is:
+ * "Tor " ? NUM dot NUM [ dot NUM [ ( pre | rc | dot ) NUM ] ] [ - tag ]
+ */
+ tor_assert(s);
+ tor_assert(out);
+
+ memset(out, 0, sizeof(tor_version_t));
+ out->status = VER_RELEASE;
+ if (!strcasecmpstart(s, "Tor "))
+ s += 4;
+
+ cp = s;
+
+#define NUMBER(m) \
+ do { \
+ if (!cp || *cp < '0' || *cp > '9') \
+ return -1; \
+ out->m = (int)tor_parse_uint64(cp, 10, 0, INT32_MAX, &ok, &eos); \
+ if (!ok) \
+ return -1; \
+ if (!eos || eos == cp) \
+ return -1; \
+ cp = eos; \
+ } while (0)
+
+#define DOT() \
+ do { \
+ if (*cp != '.') \
+ return -1; \
+ ++cp; \
+ } while (0)
+
+ NUMBER(major);
+ DOT();
+ NUMBER(minor);
+ if (*cp == 0)
+ return 0;
+ else if (*cp == '-')
+ goto status_tag;
+ DOT();
+ NUMBER(micro);
+
+ /* Get status */
+ if (*cp == 0) {
+ return 0;
+ } else if (*cp == '.') {
+ ++cp;
+ } else if (*cp == '-') {
+ goto status_tag;
+ } else if (0==strncmp(cp, "pre", 3)) {
+ out->status = VER_PRE;
+ cp += 3;
+ } else if (0==strncmp(cp, "rc", 2)) {
+ out->status = VER_RC;
+ cp += 2;
+ } else {
+ return -1;
+ }
+
+ NUMBER(patchlevel);
+
+ status_tag:
+ /* Get status tag. */
+ if (*cp == '-' || *cp == '.')
+ ++cp;
+ eos = (char*) find_whitespace(cp);
+ if (eos-cp >= (int)sizeof(out->status_tag))
+ strlcpy(out->status_tag, cp, sizeof(out->status_tag));
+ else {
+ memcpy(out->status_tag, cp, eos-cp);
+ out->status_tag[eos-cp] = 0;
+ }
+ cp = eat_whitespace(eos);
+
+ if (!strcmpstart(cp, "(r")) {
+ cp += 2;
+ out->svn_revision = (int) strtol(cp,&eos,10);
+ } else if (!strcmpstart(cp, "(git-")) {
+ char *close_paren = strchr(cp, ')');
+ int hexlen;
+ char digest[DIGEST_LEN];
+ if (! close_paren)
+ return -1;
+ cp += 5;
+ if (close_paren-cp > HEX_DIGEST_LEN)
+ return -1;
+ hexlen = (int)(close_paren-cp);
+ memwipe(digest, 0, sizeof(digest));
+ if ( hexlen == 0 || (hexlen % 2) == 1)
+ return -1;
+ if (base16_decode(digest, hexlen/2, cp, hexlen) != hexlen/2)
+ return -1;
+ memcpy(out->git_tag, digest, hexlen/2);
+ out->git_tag_len = hexlen/2;
+ }
+
+ return 0;
+#undef NUMBER
+#undef DOT
+}
+
+/** Compare two tor versions; Return <0 if a < b; 0 if a ==b, >0 if a >
+ * b. */
+int
+tor_version_compare(tor_version_t *a, tor_version_t *b)
+{
+ int i;
+ tor_assert(a);
+ tor_assert(b);
+
+ /* We take this approach to comparison to ensure the same (bogus!) behavior
+ * on all inputs as we would have seen before bug #21278 was fixed. The
+ * only important difference here is that this method doesn't cause
+ * a signed integer underflow.
+ */
+#define CMP(field) do { \
+ unsigned aval = (unsigned) a->field; \
+ unsigned bval = (unsigned) b->field; \
+ int result = (int) (aval - bval); \
+ if (result < 0) \
+ return -1; \
+ else if (result > 0) \
+ return 1; \
+ } while (0)
+
+ CMP(major);
+ CMP(minor);
+ CMP(micro);
+ CMP(status);
+ CMP(patchlevel);
+ if ((i = strcmp(a->status_tag, b->status_tag)))
+ return i;
+ CMP(svn_revision);
+ CMP(git_tag_len);
+ if (a->git_tag_len)
+ return fast_memcmp(a->git_tag, b->git_tag, a->git_tag_len);
+ else
+ return 0;
+
+#undef CMP
+}
+
+/** Return true iff versions <b>a</b> and <b>b</b> belong to the same series.
+ */
+int
+tor_version_same_series(tor_version_t *a, tor_version_t *b)
+{
+ tor_assert(a);
+ tor_assert(b);
+ return ((a->major == b->major) &&
+ (a->minor == b->minor) &&
+ (a->micro == b->micro));
+}
+
+/** Helper: Given pointers to two strings describing tor versions, return -1
+ * if _a precedes _b, 1 if _b precedes _a, and 0 if they are equivalent.
+ * Used to sort a list of versions. */
+static int
+compare_tor_version_str_ptr_(const void **_a, const void **_b)
+{
+ const char *a = *_a, *b = *_b;
+ int ca, cb;
+ tor_version_t va, vb;
+ ca = tor_version_parse(a, &va);
+ cb = tor_version_parse(b, &vb);
+ /* If they both parse, compare them. */
+ if (!ca && !cb)
+ return tor_version_compare(&va,&vb);
+ /* If one parses, it comes first. */
+ if (!ca && cb)
+ return -1;
+ if (ca && !cb)
+ return 1;
+ /* If neither parses, compare strings. Also, the directory server admin
+ ** needs to be smacked upside the head. But Tor is tolerant and gentle. */
+ return strcmp(a,b);
+}
+
+/** Sort a list of string-representations of versions in ascending order. */
+void
+sort_version_list(smartlist_t *versions, int remove_duplicates)
+{
+ smartlist_sort(versions, compare_tor_version_str_ptr_);
+
+ if (remove_duplicates)
+ smartlist_uniq(versions, compare_tor_version_str_ptr_, tor_free_);
+}
diff --git a/src/core/or/versions.h b/src/core/or/versions.h
new file mode 100644
index 000000000..a2353bcae
--- /dev/null
+++ b/src/core/or/versions.h
@@ -0,0 +1,40 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file versions.h
+ * \brief Header file for versions.c.
+ **/
+
+#ifndef TOR_VERSIONS_H
+#define TOR_VERSIONS_H
+
+/** Possible statuses of a version of Tor, given opinions from the directory
+ * servers. */
+typedef enum version_status_t {
+ VS_RECOMMENDED=0, /**< This version is listed as recommended. */
+ VS_OLD=1, /**< This version is older than any recommended version. */
+ VS_NEW=2, /**< This version is newer than any recommended version. */
+ VS_NEW_IN_SERIES=3, /**< This version is newer than any recommended version
+ * in its series, but later recommended versions exist.
+ */
+ VS_UNRECOMMENDED=4, /**< This version is not recommended (general case). */
+ VS_EMPTY=5, /**< The version list was empty; no agreed-on versions. */
+ VS_UNKNOWN, /**< We have no idea. */
+} version_status_t;
+
+version_status_t tor_version_is_obsolete(const char *myversion,
+ const char *versionlist);
+int tor_version_parse_platform(const char *platform,
+ tor_version_t *version_out,
+ int strict);
+int tor_version_as_new_as(const char *platform, const char *cutoff);
+int tor_version_parse(const char *s, tor_version_t *out);
+int tor_version_compare(tor_version_t *a, tor_version_t *b);
+int tor_version_same_series(tor_version_t *a, tor_version_t *b);
+void sort_version_list(smartlist_t *lst, int remove_duplicates);
+
+#endif /* !defined(TOR_VERSIONS_H) */
diff --git a/src/feature/dirparse/routerparse.c b/src/feature/dirparse/routerparse.c
index 83890cdb9..5ff5fdf23 100644
--- a/src/feature/dirparse/routerparse.c
+++ b/src/feature/dirparse/routerparse.c
@@ -108,9 +108,6 @@
#undef log
#include <math.h>
-//#ifdef HAVE_SYS_STAT_H
-//#include <sys/stat.h>
-//#endif
/****************************************************************************/
@@ -586,85 +583,6 @@ router_append_dirobj_signature(char *buf, size_t buf_len, const char *digest,
return 0;
}
-/** Return VS_RECOMMENDED if <b>myversion</b> is contained in
- * <b>versionlist</b>. Else, return VS_EMPTY if versionlist has no
- * entries. Else, return VS_OLD if every member of
- * <b>versionlist</b> is newer than <b>myversion</b>. Else, return
- * VS_NEW_IN_SERIES if there is at least one member of <b>versionlist</b> in
- * the same series (major.minor.micro) as <b>myversion</b>, but no such member
- * is newer than <b>myversion.</b>. Else, return VS_NEW if every member of
- * <b>versionlist</b> is older than <b>myversion</b>. Else, return
- * VS_UNRECOMMENDED.
- *
- * (versionlist is a comma-separated list of version strings,
- * optionally prefixed with "Tor". Versions that can't be parsed are
- * ignored.)
- */
-version_status_t
-tor_version_is_obsolete(const char *myversion, const char *versionlist)
-{
- tor_version_t mine, other;
- int found_newer = 0, found_older = 0, found_newer_in_series = 0,
- found_any_in_series = 0, r, same;
- version_status_t ret = VS_UNRECOMMENDED;
- smartlist_t *version_sl;
-
- log_debug(LD_CONFIG,"Checking whether version '%s' is in '%s'",
- myversion, versionlist);
-
- if (tor_version_parse(myversion, &mine)) {
- log_err(LD_BUG,"I couldn't parse my own version (%s)", myversion);
- tor_assert(0);
- }
- version_sl = smartlist_new();
- smartlist_split_string(version_sl, versionlist, ",", SPLIT_SKIP_SPACE, 0);
-
- if (!strlen(versionlist)) { /* no authorities cared or agreed */
- ret = VS_EMPTY;
- goto done;
- }
-
- SMARTLIST_FOREACH_BEGIN(version_sl, const char *, cp) {
- if (!strcmpstart(cp, "Tor "))
- cp += 4;
-
- if (tor_version_parse(cp, &other)) {
- /* Couldn't parse other; it can't be a match. */
- } else {
- same = tor_version_same_series(&mine, &other);
- if (same)
- found_any_in_series = 1;
- r = tor_version_compare(&mine, &other);
- if (r==0) {
- ret = VS_RECOMMENDED;
- goto done;
- } else if (r<0) {
- found_newer = 1;
- if (same)
- found_newer_in_series = 1;
- } else if (r>0) {
- found_older = 1;
- }
- }
- } SMARTLIST_FOREACH_END(cp);
-
- /* We didn't find the listed version. Is it new or old? */
- if (found_any_in_series && !found_newer_in_series && found_newer) {
- ret = VS_NEW_IN_SERIES;
- } else if (found_newer && !found_older) {
- ret = VS_OLD;
- } else if (found_older && !found_newer) {
- ret = VS_NEW;
- } else {
- ret = VS_UNRECOMMENDED;
- }
-
- done:
- SMARTLIST_FOREACH(version_sl, char *, version, tor_free(version));
- smartlist_free(version_sl);
- return ret;
-}
-
MOCK_IMPL(STATIC int,
signed_digest_equals, (const uint8_t *d1, const uint8_t *d2, size_t len))
{
@@ -4276,288 +4194,6 @@ microdescs_parse_from_string(const char *s, const char *eos,
return result;
}
-/** Extract a Tor version from a <b>platform</b> line from a router
- * descriptor, and place the result in <b>router_version</b>.
- *
- * Return 1 on success, -1 on parsing failure, and 0 if the
- * platform line does not indicate some version of Tor.
- *
- * If <b>strict</b> is non-zero, finding any weird version components
- * (like negative numbers) counts as a parsing failure.
- */
-int
-tor_version_parse_platform(const char *platform,
- tor_version_t *router_version,
- int strict)
-{
- char tmp[128];
- char *s, *s2, *start;
-
- if (strcmpstart(platform,"Tor ")) /* nonstandard Tor; say 0. */
- return 0;
-
- start = (char *)eat_whitespace(platform+3);
- if (!*start) return -1;
- s = (char *)find_whitespace(start); /* also finds '\0', which is fine */
- s2 = (char*)eat_whitespace(s);
- if (!strcmpstart(s2, "(r") || !strcmpstart(s2, "(git-"))
- s = (char*)find_whitespace(s2);
-
- if ((size_t)(s-start+1) >= sizeof(tmp)) /* too big, no */
- return -1;
- strlcpy(tmp, start, s-start+1);
-
- if (tor_version_parse(tmp, router_version)<0) {
- log_info(LD_DIR,"Router version '%s' unparseable.",tmp);
- return -1;
- }
-
- if (strict) {
- if (router_version->major < 0 ||
- router_version->minor < 0 ||
- router_version->micro < 0 ||
- router_version->patchlevel < 0 ||
- router_version->svn_revision < 0) {
- return -1;
- }
- }
-
- return 1;
-}
-
-/** Parse the Tor version of the platform string <b>platform</b>,
- * and compare it to the version in <b>cutoff</b>. Return 1 if
- * the router is at least as new as the cutoff, else return 0.
- */
-int
-tor_version_as_new_as(const char *platform, const char *cutoff)
-{
- tor_version_t cutoff_version, router_version;
- int r;
- tor_assert(platform);
-
- if (tor_version_parse(cutoff, &cutoff_version)<0) {
- log_warn(LD_BUG,"cutoff version '%s' unparseable.",cutoff);
- return 0;
- }
-
- r = tor_version_parse_platform(platform, &router_version, 0);
- if (r == 0) {
- /* nonstandard Tor; be safe and say yes */
- return 1;
- } else if (r < 0) {
- /* unparseable version; be safe and say yes. */
- return 1;
- }
-
- /* Here's why we don't need to do any special handling for svn revisions:
- * - If neither has an svn revision, we're fine.
- * - If the router doesn't have an svn revision, we can't assume that it
- * is "at least" any svn revision, so we need to return 0.
- * - If the target version doesn't have an svn revision, any svn revision
- * (or none at all) is good enough, so return 1.
- * - If both target and router have an svn revision, we compare them.
- */
-
- return tor_version_compare(&router_version, &cutoff_version) >= 0;
-}
-
-/** Parse a tor version from <b>s</b>, and store the result in <b>out</b>.
- * Return 0 on success, -1 on failure. */
-int
-tor_version_parse(const char *s, tor_version_t *out)
-{
- char *eos=NULL;
- const char *cp=NULL;
- int ok = 1;
- /* Format is:
- * "Tor " ? NUM dot NUM [ dot NUM [ ( pre | rc | dot ) NUM ] ] [ - tag ]
- */
- tor_assert(s);
- tor_assert(out);
-
- memset(out, 0, sizeof(tor_version_t));
- out->status = VER_RELEASE;
- if (!strcasecmpstart(s, "Tor "))
- s += 4;
-
- cp = s;
-
-#define NUMBER(m) \
- do { \
- if (!cp || *cp < '0' || *cp > '9') \
- return -1; \
- out->m = (int)tor_parse_uint64(cp, 10, 0, INT32_MAX, &ok, &eos); \
- if (!ok) \
- return -1; \
- if (!eos || eos == cp) \
- return -1; \
- cp = eos; \
- } while (0)
-
-#define DOT() \
- do { \
- if (*cp != '.') \
- return -1; \
- ++cp; \
- } while (0)
-
- NUMBER(major);
- DOT();
- NUMBER(minor);
- if (*cp == 0)
- return 0;
- else if (*cp == '-')
- goto status_tag;
- DOT();
- NUMBER(micro);
-
- /* Get status */
- if (*cp == 0) {
- return 0;
- } else if (*cp == '.') {
- ++cp;
- } else if (*cp == '-') {
- goto status_tag;
- } else if (0==strncmp(cp, "pre", 3)) {
- out->status = VER_PRE;
- cp += 3;
- } else if (0==strncmp(cp, "rc", 2)) {
- out->status = VER_RC;
- cp += 2;
- } else {
- return -1;
- }
-
- NUMBER(patchlevel);
-
- status_tag:
- /* Get status tag. */
- if (*cp == '-' || *cp == '.')
- ++cp;
- eos = (char*) find_whitespace(cp);
- if (eos-cp >= (int)sizeof(out->status_tag))
- strlcpy(out->status_tag, cp, sizeof(out->status_tag));
- else {
- memcpy(out->status_tag, cp, eos-cp);
- out->status_tag[eos-cp] = 0;
- }
- cp = eat_whitespace(eos);
-
- if (!strcmpstart(cp, "(r")) {
- cp += 2;
- out->svn_revision = (int) strtol(cp,&eos,10);
- } else if (!strcmpstart(cp, "(git-")) {
- char *close_paren = strchr(cp, ')');
- int hexlen;
- char digest[DIGEST_LEN];
- if (! close_paren)
- return -1;
- cp += 5;
- if (close_paren-cp > HEX_DIGEST_LEN)
- return -1;
- hexlen = (int)(close_paren-cp);
- memwipe(digest, 0, sizeof(digest));
- if ( hexlen == 0 || (hexlen % 2) == 1)
- return -1;
- if (base16_decode(digest, hexlen/2, cp, hexlen) != hexlen/2)
- return -1;
- memcpy(out->git_tag, digest, hexlen/2);
- out->git_tag_len = hexlen/2;
- }
-
- return 0;
-#undef NUMBER
-#undef DOT
-}
-
-/** Compare two tor versions; Return <0 if a < b; 0 if a ==b, >0 if a >
- * b. */
-int
-tor_version_compare(tor_version_t *a, tor_version_t *b)
-{
- int i;
- tor_assert(a);
- tor_assert(b);
-
- /* We take this approach to comparison to ensure the same (bogus!) behavior
- * on all inputs as we would have seen before bug #21278 was fixed. The
- * only important difference here is that this method doesn't cause
- * a signed integer underflow.
- */
-#define CMP(field) do { \
- unsigned aval = (unsigned) a->field; \
- unsigned bval = (unsigned) b->field; \
- int result = (int) (aval - bval); \
- if (result < 0) \
- return -1; \
- else if (result > 0) \
- return 1; \
- } while (0)
-
- CMP(major);
- CMP(minor);
- CMP(micro);
- CMP(status);
- CMP(patchlevel);
- if ((i = strcmp(a->status_tag, b->status_tag)))
- return i;
- CMP(svn_revision);
- CMP(git_tag_len);
- if (a->git_tag_len)
- return fast_memcmp(a->git_tag, b->git_tag, a->git_tag_len);
- else
- return 0;
-
-#undef CMP
-}
-
-/** Return true iff versions <b>a</b> and <b>b</b> belong to the same series.
- */
-int
-tor_version_same_series(tor_version_t *a, tor_version_t *b)
-{
- tor_assert(a);
- tor_assert(b);
- return ((a->major == b->major) &&
- (a->minor == b->minor) &&
- (a->micro == b->micro));
-}
-
-/** Helper: Given pointers to two strings describing tor versions, return -1
- * if _a precedes _b, 1 if _b precedes _a, and 0 if they are equivalent.
- * Used to sort a list of versions. */
-static int
-compare_tor_version_str_ptr_(const void **_a, const void **_b)
-{
- const char *a = *_a, *b = *_b;
- int ca, cb;
- tor_version_t va, vb;
- ca = tor_version_parse(a, &va);
- cb = tor_version_parse(b, &vb);
- /* If they both parse, compare them. */
- if (!ca && !cb)
- return tor_version_compare(&va,&vb);
- /* If one parses, it comes first. */
- if (!ca && cb)
- return -1;
- if (ca && !cb)
- return 1;
- /* If neither parses, compare strings. Also, the directory server admin
- ** needs to be smacked upside the head. But Tor is tolerant and gentle. */
- return strcmp(a,b);
-}
-
-/** Sort a list of string-representations of versions in ascending order. */
-void
-sort_version_list(smartlist_t *versions, int remove_duplicates)
-{
- smartlist_sort(versions, compare_tor_version_str_ptr_);
-
- if (remove_duplicates)
- smartlist_uniq(versions, compare_tor_version_str_ptr_, tor_free_);
-}
-
/** Parse and validate the ASCII-encoded v2 descriptor in <b>desc</b>,
* write the parsed descriptor to the newly allocated *<b>parsed_out</b>, the
* binary descriptor ID of length DIGEST_LEN to <b>desc_id_out</b>, the
diff --git a/src/feature/dirparse/routerparse.h b/src/feature/dirparse/routerparse.h
index 51d39c617..6f1af4016 100644
--- a/src/feature/dirparse/routerparse.h
+++ b/src/feature/dirparse/routerparse.h
@@ -12,19 +12,7 @@
#ifndef TOR_ROUTERPARSE_H
#define TOR_ROUTERPARSE_H
-/** Possible statuses of a version of Tor, given opinions from the directory
- * servers. */
-typedef enum version_status_t {
- VS_RECOMMENDED=0, /**< This version is listed as recommended. */
- VS_OLD=1, /**< This version is older than any recommended version. */
- VS_NEW=2, /**< This version is newer than any recommended version. */
- VS_NEW_IN_SERIES=3, /**< This version is newer than any recommended version
- * in its series, but later recommended versions exist.
- */
- VS_UNRECOMMENDED=4, /**< This version is not recommended (general case). */
- VS_EMPTY=5, /**< The version list was empty; no agreed-on versions. */
- VS_UNKNOWN, /**< We have no idea. */
-} version_status_t;
+#include "core/or/versions.h"
enum networkstatus_type_t;
@@ -65,16 +53,7 @@ extrainfo_t *extrainfo_parse_entry_from_string(const char *s, const char *end,
int *can_dl_again_out);
MOCK_DECL(addr_policy_t *, router_parse_addr_policy_item_from_string,
(const char *s, int assume_action, int *malformed_list));
-version_status_t tor_version_is_obsolete(const char *myversion,
- const char *versionlist);
-int tor_version_parse_platform(const char *platform,
- tor_version_t *version_out,
- int strict);
-int tor_version_as_new_as(const char *platform, const char *cutoff);
-int tor_version_parse(const char *s, tor_version_t *out);
-int tor_version_compare(tor_version_t *a, tor_version_t *b);
-int tor_version_same_series(tor_version_t *a, tor_version_t *b);
-void sort_version_list(smartlist_t *lst, int remove_duplicates);
+
void assert_addr_policy_ok(smartlist_t *t);
void dump_distinct_digest_count(int severity);
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits