diff --git a/td/telegram/ConfigManager.cpp b/td/telegram/ConfigManager.cpp index da25cc06..f216e91f 100644 --- a/td/telegram/ConfigManager.cpp +++ b/td/telegram/ConfigManager.cpp @@ -455,7 +455,7 @@ class ConfigRecoverer : public Actor { VLOG(config_recoverer) << "Config has expired at " << config->expires_; } - G()->update_server_time_difference(config->date_ - Time::now()); + G()->update_dns_time_difference(config->date_ - Time::now()); simple_config_expires_at_ = get_config_expire_time(); simple_config_at_ = Time::now_cached(); for (size_t i = 1; i < simple_config_.dc_options.size(); i++) { diff --git a/td/telegram/Global.cpp b/td/telegram/Global.cpp index 0b7ae6cd..c0bf8813 100644 --- a/td/telegram/Global.cpp +++ b/td/telegram/Global.cpp @@ -71,17 +71,20 @@ Status Global::init(const TdParameters ¶meters, ActorId td, unique_ptrget_binlog_pmc()->get("server_time_difference"); + auto default_time_difference = Clocks::system() - Time::now(); if (save_diff_str.empty()) { - server_time_difference_ = Clocks::system() - Time::now(); + server_time_difference_ = default_time_difference; server_time_difference_was_updated_ = false; } else { double save_diff; unserialize(save_diff, save_diff_str).ensure(); - double diff = save_diff + Clocks::system() - Time::now(); + double diff = save_diff + default_time_difference; LOG(DEBUG) << "LOAD: " << tag("server_time_difference", diff); server_time_difference_ = diff; server_time_difference_was_updated_ = false; } + dns_time_difference_ = default_time_difference; + dns_time_difference_was_updated_ = false; return Status::OK(); } @@ -99,6 +102,27 @@ void Global::update_server_time_difference(double diff) { } } +void Global::update_dns_time_difference(double diff) { + dns_time_difference_ = diff; + dns_time_difference_was_updated_ = true; +} + +double Global::get_dns_time_difference() const { + // rely that was updated flag is monotonic. Currenly it is true. If it stops being monitonic at some point it won't + // lead to problems anyway. + bool dns_flag = dns_time_difference_was_updated_; + double dns_diff = dns_time_difference_; + bool server_flag = server_time_difference_was_updated_; + double server_diff = server_time_difference_; + if (dns_flag != server_flag) { + return dns_flag ? dns_diff : server_diff; + } + if (dns_flag) { + return std::max(dns_diff, server_diff); + } + return server_diff; +} + DcId Global::get_webfile_dc_id() const { CHECK(shared_config_ != nullptr); int32 dc_id = shared_config_->get_option_integer("webfile_dc_id"); diff --git a/td/telegram/Global.h b/td/telegram/Global.h index 5448ca28..5ce47327 100644 --- a/td/telegram/Global.h +++ b/td/telegram/Global.h @@ -137,6 +137,10 @@ class Global : public ActorContext { return server_time_difference_.load(std::memory_order_relaxed); } + void update_dns_time_difference(double diff); + + double get_dns_time_difference() const; + ActorId state_manager() const { return state_manager_; } @@ -383,6 +387,8 @@ class Global : public ActorContext { std::atomic server_time_difference_{0.0}; std::atomic server_time_difference_was_updated_{false}; + std::atomic dns_time_difference_{0.0}; + std::atomic dns_time_difference_was_updated_{false}; std::atomic close_flag_{false}; std::vector> net_stats_file_callbacks_; diff --git a/td/telegram/net/ConnectionCreator.cpp b/td/telegram/net/ConnectionCreator.cpp index 82579dbc..8d1447a4 100644 --- a/td/telegram/net/ConnectionCreator.cpp +++ b/td/telegram/net/ConnectionCreator.cpp @@ -544,7 +544,7 @@ void ConnectionCreator::ping_proxy_resolved(int32 proxy_id, IPAddress ip_address children_[token] = { false, create_actor("PingTlsInit", std::move(socket_fd), extra.mtproto_ip, "www.google.com", hex_decode(proxy.proxy().secret().substr(2)).move_as_ok(), std::move(callback), - create_reference(token), G()->get_server_time_difference())}; + create_reference(token), G()->get_dns_time_difference())}; } else { UNREACHABLE(); } @@ -1033,7 +1033,7 @@ void ConnectionCreator::client_loop(ClientInfo &client) { children_[token] = { true, create_actor("TlsInit", std::move(socket_fd), extra.mtproto_ip, "www.google.com", hex_decode(proxy.proxy().secret().substr(2)).move_as_ok(), std::move(callback), - create_reference(token), G()->get_server_time_difference())}; + create_reference(token), G()->get_dns_time_difference())}; } else { UNREACHABLE(); }