adjust clock from SSU SessionCreated is time difference exceeds 15 seconds

This commit is contained in:
orignal 2022-02-01 18:43:11 -05:00
parent 03bcdceb9b
commit 19cc1c3b3f
7 changed files with 43 additions and 21 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@ -272,8 +272,9 @@ namespace config {
"1.pool.ntp.org,"
"2.pool.ntp.org,"
"3.pool.ntp.org"
), "Comma separated list of NTCP servers")
), "Comma separated list of NTP servers")
("nettime.ntpsyncinterval", value<int>()->default_value(72), "NTP sync interval in hours (default: 72)")
("nettime.frompeers", value<bool>()->default_value(true), "Sync clock from transport peers (default: enabled)")
;
options_description persist("Network information persisting options");

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2021, The PurpleI2P Project
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@ -11,8 +11,9 @@
#include "Timestamp.h"
#include "RouterContext.h"
#include "NetDb.hpp"
#include "SSU.h"
#include "Config.h"
#include "util.h"
#include "SSU.h"
#ifdef __linux__
#include <linux/in6.h>
@ -33,7 +34,8 @@ namespace transport
m_Endpoint (boost::asio::ip::udp::v4 (), port), m_EndpointV6 (boost::asio::ip::udp::v6 (), port),
m_Socket (m_ReceiversService), m_SocketV6 (m_ReceiversServiceV6),
m_IntroducersUpdateTimer (m_Service), m_IntroducersUpdateTimerV6 (m_Service),
m_PeerTestsCleanupTimer (m_Service), m_TerminationTimer (m_Service), m_TerminationTimerV6 (m_Service)
m_PeerTestsCleanupTimer (m_Service), m_TerminationTimer (m_Service), m_TerminationTimerV6 (m_Service),
m_IsSyncClockFromPeers (true)
{
}
@ -90,6 +92,7 @@ namespace transport
void SSUServer::Start ()
{
i2p::config::GetOption("nettime.frompeers", m_IsSyncClockFromPeers);
m_IsRunning = true;
m_Thread = new std::thread (std::bind (&SSUServer::Run, this));
if (context.SupportsV4 ())

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2021, The PurpleI2P Project
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@ -69,6 +69,7 @@ namespace transport
i2p::util::MemoryPool<SentMessage>& GetSentMessagesPool () { return m_SentMessagesPool; };
uint16_t GetPort () const { return m_Endpoint.port (); };
bool IsSyncClockFromPeers () const { return m_IsSyncClockFromPeers; };
void SetLocalAddress (const boost::asio::ip::address& localAddress);
void Send (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& to);
@ -136,6 +137,7 @@ namespace transport
boost::asio::ip::udp::socket m_Socket, m_SocketV6;
boost::asio::deadline_timer m_IntroducersUpdateTimer, m_IntroducersUpdateTimerV6,
m_PeerTestsCleanupTimer, m_TerminationTimer, m_TerminationTimerV6;
bool m_IsSyncClockFromPeers;
std::list<boost::asio::ip::udp::endpoint> m_Introducers, m_IntroducersV6; // introducers we are connected to
std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<SSUSession> > m_Sessions, m_SessionsV6;
std::map<uint32_t, std::shared_ptr<SSUSession> > m_Relays; // we are introducer

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2021, The PurpleI2P Project
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@ -274,16 +274,7 @@ namespace transport
s.Insert (payload, 8); // relayTag and signed on time
m_RelayTag = bufbe32toh (payload);
payload += 4; // relayTag
if (ourIP.is_v4 () && i2p::context.GetStatus () == eRouterStatusTesting)
{
auto ts = i2p::util::GetSecondsSinceEpoch ();
uint32_t signedOnTime = bufbe32toh(payload);
if (signedOnTime < ts - SSU_CLOCK_SKEW || signedOnTime > ts + SSU_CLOCK_SKEW)
{
LogPrint (eLogError, "SSU: Clock skew detected ", (int)ts - signedOnTime, ". Check your clock");
i2p::context.SetError (eRouterErrorClockSkew);
}
}
payload += 4; // signed on time
// decrypt signature
size_t signatureLen = m_RemoteIdentity->GetSignatureLen ();
@ -295,6 +286,24 @@ namespace transport
// verify signature
if (s.Verify (m_RemoteIdentity, payload))
{
if (ourIP.is_v4 () && i2p::context.GetStatus () == eRouterStatusTesting)
{
auto ts = i2p::util::GetSecondsSinceEpoch ();
int offset = (int)ts - signedOnTime;
if (m_Server.IsSyncClockFromPeers ())
{
if (std::abs (offset) > SSU_CLOCK_THRESHOLD)
{
LogPrint (eLogWarning, "SSU: Clock adjusted by ", -offset, " seconds");
i2p::util::AdjustTimeOffset (-offset);
}
}
else if (std::abs (offset) > SSU_CLOCK_SKEW)
{
LogPrint (eLogError, "SSU: Clock skew detected ", offset, ". Check your clock");
i2p::context.SetError (eRouterErrorClockSkew);
}
}
LogPrint (eLogInfo, "SSU: Our external address is ", ourIP.to_string (), ":", ourPort);
if (!i2p::util::net::IsInReservedRange (ourIP))
{

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2021, The PurpleI2P Project
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@ -36,6 +36,7 @@ namespace transport
const int SSU_CONNECT_TIMEOUT = 5; // 5 seconds
const int SSU_TERMINATION_TIMEOUT = 330; // 5.5 minutes
const int SSU_CLOCK_SKEW = 60; // in seconds
const int SSU_CLOCK_THRESHOLD = 15; // in seconds, if more we should adjust
const size_t SSU_MAX_I2NP_MESSAGE_SIZE = 32768;
// payload types (4 bits)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2021, The PurpleI2P Project
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@ -250,5 +250,10 @@ namespace util
sprintf(date, "%04i%02i%02i", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
#endif
}
void AdjustTimeOffset (int64_t offset)
{
g_TimeOffset += offset;
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@ -26,6 +26,7 @@ namespace util
void GetCurrentDate (char * date); // returns date as YYYYMMDD string, 9 bytes
void GetDateString (uint64_t timestamp, char * date); // timestap is seconds since epoch, returns date as YYYYMMDD string, 9 bytes
void AdjustTimeOffset (int64_t offset); // in seconds from current
class NTPTimeSync
{