From 3bea87e36f630842aeeda6be887f21dd899fa679 Mon Sep 17 00:00:00 2001 From: Kostas Kyrimis Date: Mon, 24 Jul 2023 15:08:24 +0300 Subject: [PATCH] fix(VersionMonitor): improper version update to older version (#1577) Add correct version comparison between VersionMonitor and the dfly server --- src/server/dfly_main.cc | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/server/dfly_main.cc b/src/server/dfly_main.cc index 1a32e69f6..94e09a748 100644 --- a/src/server/dfly_main.cc +++ b/src/server/dfly_main.cc @@ -3,6 +3,7 @@ // See LICENSE for licensing terms. // +#include "absl/strings/numbers.h" #ifdef NDEBUG #include #endif @@ -161,9 +162,41 @@ struct VersionMonitor { } private: + bool IsVersionOutdated(std::string_view remote, std::string_view current) const; void RunTask(SSL_CTX* ssl_ctx); }; +bool VersionMonitor::IsVersionOutdated(const std::string_view remote, + const std::string_view current) const { + const std::vector remote_xyz = absl::StrSplit(remote, "."); + const std::vector current_xyz = absl::StrSplit(current, "."); + if (remote_xyz.size() != current_xyz.size()) { + LOG(WARNING) << "Can't compare Dragonfly version " << current << " to latest version " + << remote; + return false; + } + const auto print_to_log = [](const std::string_view version, const absl::string_view part) { + LOG(WARNING) << "Can't parse " << version << " part of version " << part << " as a number"; + }; + for (size_t i = 0; i < remote_xyz.size(); ++i) { + size_t remote_x = 0; + if (!absl::SimpleAtoi(remote_xyz[i], &remote_x)) { + print_to_log(remote, remote_xyz[i]); + return false; + } + size_t current_x = 0; + if (!absl::SimpleAtoi(current_xyz[i], ¤t_x)) { + print_to_log(current, current_xyz[i]); + return false; + } + if (remote_x > current_x) { + return true; + } + } + + return false; +} + void VersionMonitor::Run(ProactorPool* proactor_pool) { // Avoid running dev environments. bool is_dev_env = false; @@ -205,8 +238,8 @@ void VersionMonitor::RunTask(SSL_CTX* ssl_ctx) { const std::optional remote_version = GetRemoteVersion(my_pb, ssl_ctx, host_name, port, resource, version_header); if (remote_version) { - const std::string rv = remote_version.value(); - if (rv != current_version) { + const std::string_view rv = remote_version.value(); + if (IsVersionOutdated(rv, current_version)) { LOG_FIRST_N(INFO, 1) << "Your current version '" << current_version << "' is not the latest version. A newer version '" << rv << "' is now available. Please consider an update.";