From 8a549b83a217eabfe1e068b43ec1061f718444d7 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 16 Nov 2018 12:49:04 -0500 Subject: [PATCH] NTP sync in separate thread --- daemon/Daemon.cpp | 16 +++++++-- libi2pd/Timestamp.cpp | 76 ++++++++++++++++++++++++++++++++++++++----- libi2pd/Timestamp.h | 29 ++++++++++++++++- 3 files changed, 110 insertions(+), 11 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index b1e694fd..8e0804d1 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -42,6 +42,7 @@ namespace i2p std::unique_ptr httpServer; std::unique_ptr m_I2PControlService; std::unique_ptr UPnP; + std::unique_ptr m_NTPSync; #ifdef WITH_EVENTS std::unique_ptr m_WebsocketServer; #endif @@ -284,7 +285,11 @@ namespace i2p } bool nettime; i2p::config::GetOption("nettime.enabled", nettime); - if (nettime) i2p::util::RequestNTPTimeSync (); + if (nettime) + { + d.m_NTPSync = std::unique_ptr(new i2p::util::NTPTimeSync); + d.m_NTPSync->Start (); + } bool ntcp; i2p::config::GetOption("ntcp", ntcp); bool ssu; i2p::config::GetOption("ssu", ssu); @@ -355,11 +360,18 @@ namespace i2p LogPrint(eLogInfo, "Daemon: stopping Tunnels"); i2p::tunnel::tunnels.Stop(); - if (d.UPnP) { + if (d.UPnP) + { d.UPnP->Stop (); d.UPnP = nullptr; } + if (d.m_NTPSync) + { + d.m_NTPSync->Stop (); + d.m_NTPSync = nullptr; + } + LogPrint(eLogInfo, "Daemon: stopping Transports"); i2p::transport::transports.Stop(); LogPrint(eLogInfo, "Daemon: stopping NetDB"); diff --git a/libi2pd/Timestamp.cpp b/libi2pd/Timestamp.cpp index 939e7f91..492e4559 100644 --- a/libi2pd/Timestamp.cpp +++ b/libi2pd/Timestamp.cpp @@ -1,7 +1,5 @@ #include #include -#include -#include #include #include #include @@ -92,15 +90,77 @@ namespace util LogPrint (eLogError, "Timestamp: Couldn't resove address ", address); } - void RequestNTPTimeSync () + NTPTimeSync::NTPTimeSync (): m_IsRunning (false), m_Timer (m_Service) { + i2p::config::GetOption("nettime.ntpsyncinterval", m_SyncInterval); std::string ntpservers; i2p::config::GetOption("nettime.ntpservers", ntpservers); - if (ntpservers.length () > 0) + boost::split (m_NTPServersList, ntpservers, boost::is_any_of(","), boost::token_compress_on); + } + + NTPTimeSync::~NTPTimeSync () + { + Stop (); + } + + void NTPTimeSync::Start() + { + if (m_NTPServersList.size () > 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 ()]); + m_IsRunning = true; + LogPrint(eLogInfo, "Timestamp: NTP time sync starting"); + m_Service.post (std::bind (&NTPTimeSync::Sync, this)); + m_Thread.reset (new std::thread (std::bind (&NTPTimeSync::Run, this))); + } + else + LogPrint (eLogWarning, "Timestamp: No NTP server found"); + } + + void NTPTimeSync::Stop () + { + if (m_IsRunning) + { + LogPrint(eLogInfo, "Timestamp: NTP time sync stopping"); + m_IsRunning = false; + m_Timer.cancel (); + m_Service.stop (); + if (m_Thread) + { + m_Thread->join (); + m_Thread.reset (nullptr); + } + } + } + + void NTPTimeSync::Run () + { + while (m_IsRunning) + { + try + { + m_Service.run (); + } + catch (std::exception& ex) + { + LogPrint (eLogError, "Timestamp: NTP time sync exception: ", ex.what ()); + } + } + } + + void NTPTimeSync::Sync () + { + if (m_NTPServersList.size () > 0) + SyncTimeWithNTP (m_NTPServersList[rand () % m_NTPServersList.size ()]); + else + m_IsRunning = false; + + if (m_IsRunning) + { + m_Timer.expires_from_now (boost::posix_time::hours (m_SyncInterval)); + m_Timer.async_wait ([this](const boost::system::error_code& ecode) + { + if (ecode != boost::asio::error::operation_aborted) + Sync (); + }); } } diff --git a/libi2pd/Timestamp.h b/libi2pd/Timestamp.h index d7f200b9..e859f7f6 100644 --- a/libi2pd/Timestamp.h +++ b/libi2pd/Timestamp.h @@ -2,6 +2,10 @@ #define TIMESTAMP_H__ #include +#include +#include +#include +#include namespace i2p { @@ -11,7 +15,30 @@ namespace util uint32_t GetHoursSinceEpoch (); uint64_t GetSecondsSinceEpoch (); - void RequestNTPTimeSync (); + class NTPTimeSync + { + public: + + NTPTimeSync (); + ~NTPTimeSync (); + + void Start (); + void Stop (); + + private: + + void Run (); + void Sync (); + + private: + + bool m_IsRunning; + std::unique_ptr m_Thread; + boost::asio::io_service m_Service; + boost::asio::deadline_timer m_Timer; + int m_SyncInterval; + std::vector m_NTPServersList; + }; } }