Commit a77a366b authored by Nick Mathewson's avatar Nick Mathewson 🦞
Browse files

Warn on zstd header/library version mismatch

If we're going to potentially degrade performance in this case, we
may as well tell people so.
parent f98cb5d3
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -663,3 +663,13 @@ tor_compress_init(void)
  tor_zstd_init();
}

/** Warn if we had any problems while setting up our compression libraries.
 *
 * (This isn't part of tor_compress_init, since the logs aren't set up yet.)
 */
void
tor_compress_log_init_warnings(void)
{
  tor_zstd_warn_if_version_mismatched();
}
+1 −0
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ void tor_compress_free_(tor_compress_state_t *state);
size_t tor_compress_state_size(const tor_compress_state_t *state);

void tor_compress_init(void);
void tor_compress_log_init_warnings(void);

#endif /* !defined(TOR_COMPRESS_H) */
+38 −8
Original line number Diff line number Diff line
@@ -58,21 +58,29 @@ tor_zstd_method_supported(void)
#endif
}

/** Format a zstd version number as a string in <b>buf</b>. */
static void
tor_zstd_format_version(char *buf, size_t buflen, unsigned version_number)
{
  tor_snprintf(buf, buflen,
               "%u.%u.%u",
               version_number / 10000 % 100,
               version_number / 100 % 100,
               version_number % 100);
}

#define VERSION_STR_MAX_LEN 16 /* more than enough space for 99.99.99 */

/** Return a string representation of the version of the currently running
 * version of libzstd. Returns NULL if Zstandard is unsupported. */
const char *
tor_zstd_get_version_str(void)
{
#ifdef HAVE_ZSTD
  static char version_str[16];
  size_t version_number;
  static char version_str[VERSION_STR_MAX_LEN];

  version_number = ZSTD_versionNumber();
  tor_snprintf(version_str, sizeof(version_str),
               "%d.%d.%d",
               (int) version_number / 10000 % 100,
               (int) version_number / 100 % 100,
               (int) version_number % 100);
  tor_zstd_format_version(version_str, sizeof(version_str),
                          ZSTD_versionNumber());

  return version_str;
#else /* !(defined(HAVE_ZSTD)) */
@@ -487,6 +495,27 @@ tor_zstd_init(void)
  atomic_counter_init(&total_zstd_allocation);
}

/** Warn if the header and library versions don't match. */
void
tor_zstd_warn_if_version_mismatched(void)
{
#ifdef HAVE_ZSTD
  if (! tor_zstd_can_use_static_apis()) {
    char header_version[VERSION_STR_MAX_LEN];
    char runtime_version[VERSION_STR_MAX_LEN];
    tor_zstd_format_version(header_version, sizeof(header_version),
                            ZSTD_VERSION_NUMBER);
    tor_zstd_format_version(runtime_version, sizeof(runtime_version),
                            ZSTD_versionNumber());

    log_warn(LD_GENERAL,
             "Tor was compiled with zstd %s, but is running with zstd %s. "
             "For safety, we'll avoid using advanced zstd functionality.",
             header_version, runtime_version);
  }
#endif
}

#ifdef TOR_UNIT_TESTS
/** Testing only: disable usage of static-only APIs, so we can make sure that
 * we still work without them. */
@@ -496,3 +525,4 @@ tor_zstd_set_static_apis_disabled_for_testing(int disabled)
  static_apis_disable_for_testing = disabled;
}
#endif
+1 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ size_t tor_zstd_compress_state_size(const tor_zstd_compress_state_t *state);
size_t tor_zstd_get_total_allocation(void);

void tor_zstd_init(void);
void tor_zstd_warn_if_version_mismatched(void);

#ifdef TOR_UNIT_TESTS
void tor_zstd_set_static_apis_disabled_for_testing(int disabled);
+2 −0
Original line number Diff line number Diff line
@@ -3323,6 +3323,8 @@ tor_init(int argc, char *argv[])
    if (strstr(version, "alpha") || strstr(version, "beta"))
      log_notice(LD_GENERAL, "This version is not a stable Tor release. "
                 "Expect more bugs than usual.");

    tor_compress_log_init_warnings();
  }

#ifdef HAVE_RUST