From 85394f2438576ac43f4fe359c4778c0e586c29d0 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 14 Nov 2018 11:06:53 -0500 Subject: [PATCH] NTP time sync --- daemon/Daemon.cpp | 4 +++ libi2pd/Config.cpp | 13 +++++++++ libi2pd/Timestamp.cpp | 61 ++++++++++++++++++++++++++++++++++++++++--- libi2pd/Timestamp.h | 21 +++------------ 4 files changed, 78 insertions(+), 21 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 0b88e983..b1e694fd 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -23,6 +23,7 @@ #include "ClientContext.h" #include "Crypto.h" #include "UPnP.h" +#include "Timestamp.h" #include "util.h" #include "Event.h" @@ -282,6 +283,9 @@ namespace i2p d.UPnP->Start (); } + bool nettime; i2p::config::GetOption("nettime.enabled", nettime); + if (nettime) i2p::util::RequestNTPTimeSync (); + bool ntcp; i2p::config::GetOption("ntcp", ntcp); bool ssu; i2p::config::GetOption("ssu", ssu); LogPrint(eLogInfo, "Daemon: starting Transports"); diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 15777968..c1fd006c 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -241,6 +241,18 @@ namespace config { ("ntcp2.port", value()->default_value(0), "Port to listen for incoming NTCP2 connections (default: auto)") ; + options_description nettime("Time sync options"); + nettime.add_options() + ("nettime.enabled", value()->default_value(false), "Disable time sync (default: disabled)") + ("nettime.ntpservers", value()->default_value( + "0.ntp.pool.org," + "1.ntp.pool.org," + "2.ntp.pool.org," + "3.ntp.pool.org" + ), "Comma separated list of NTCP servers") + ("nettime.ntpsyncinterval", value()->default_value(72), "NTP sync interval in hours (default: 72)") + ; + m_OptionsDesc .add(general) .add(limits) @@ -259,6 +271,7 @@ namespace config { .add(websocket) .add(exploratory) .add(ntcp2) + .add(nettime) ; } diff --git a/libi2pd/Timestamp.cpp b/libi2pd/Timestamp.cpp index 9e9b4e63..18314745 100644 --- a/libi2pd/Timestamp.cpp +++ b/libi2pd/Timestamp.cpp @@ -1,6 +1,12 @@ #include #include +#include +#include +#include +#include #include +#include +#include "Config.h" #include "Log.h" #include "I2PEndian.h" #include "Timestamp.h" @@ -15,10 +21,30 @@ namespace i2p { namespace util { + static uint64_t GetLocalMillisecondsSinceEpoch () + { + return std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count (); + } + + static uint32_t GetLocalHoursSinceEpoch () + { + return std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count (); + } + + static uint64_t GetLocalSecondsSinceEpoch () + { + return std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count (); + } + + static int64_t g_TimeOffset = 0; // in seconds - void SyncTimeWithNTP (const std::string& address) + static void SyncTimeWithNTP (const std::string& address) { + LogPrint (eLogInfo, "Timestamp: NTP request to ", address); boost::asio::io_service service; boost::asio::ip::udp::resolver::query query (boost::asio::ip::udp::v4 (), address, "ntp"); boost::system::error_code ec; @@ -48,19 +74,46 @@ namespace util } catch (std::exception& e) { - LogPrint (eLogError, "NTP error: ", e.what ()); + LogPrint (eLogError, "Timestamp: NTP error: ", e.what ()); } if (len >= 8) { - auto ourTs = GetSecondsSinceEpoch (); + auto ourTs = GetLocalSecondsSinceEpoch (); uint32_t ts = bufbe32toh (buf + 32); if (ts > 2208988800U) ts -= 2208988800U; // 1/1/1970 from 1/1/1900 g_TimeOffset = ts - ourTs; - LogPrint (eLogInfo, address, " time offset from system time is ", g_TimeOffset, " seconds"); + LogPrint (eLogInfo, address, "Timestamp: time offset from system time is ", g_TimeOffset, " seconds"); } } } } + + void RequestNTPTimeSync () + { + std::string ntpservers; i2p::config::GetOption("nettime.ntpservers", ntpservers); + if (ntpservers.length () > 0) + { + std::vector ntpList; + boost::split (ntpList, ntpservers, boost::is_any_of(","), boost::token_compress_on); + if (ntpList.size () > 0) + std::async (std::launch::async, SyncTimeWithNTP, ntpList[rand () % ntpList.size ()]); + } + } + + uint64_t GetMillisecondsSinceEpoch () + { + return GetLocalMillisecondsSinceEpoch () + g_TimeOffset*1000; + } + + uint32_t GetHoursSinceEpoch () + { + return GetLocalHoursSinceEpoch () + g_TimeOffset/3600; + } + + uint64_t GetSecondsSinceEpoch () + { + return GetLocalSecondsSinceEpoch () + g_TimeOffset; + } } } diff --git a/libi2pd/Timestamp.h b/libi2pd/Timestamp.h index cddc6518..d7f200b9 100644 --- a/libi2pd/Timestamp.h +++ b/libi2pd/Timestamp.h @@ -2,29 +2,16 @@ #define TIMESTAMP_H__ #include -#include namespace i2p { namespace util { - inline uint64_t GetMillisecondsSinceEpoch () - { - return std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()).count (); - } + uint64_t GetMillisecondsSinceEpoch (); + uint32_t GetHoursSinceEpoch (); + uint64_t GetSecondsSinceEpoch (); - inline uint32_t GetHoursSinceEpoch () - { - return std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()).count (); - } - - inline uint64_t GetSecondsSinceEpoch () - { - return std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()).count (); - } + void RequestNTPTimeSync (); } }