diff --git a/src/Application.cpp b/src/Application.cpp index 0ceef99b75..89fe9d2ddc 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -69,8 +69,6 @@ void Application::run() if (!theConfig.DEBUG_LOGFILE.empty()) Log::setLogFile(theConfig.DEBUG_LOGFILE); - mSNTPClient.init(theConfig.SNTP_SERVERS); - // // Construct databases. // @@ -149,6 +147,8 @@ void Application::run() mNetOps.setLastCloseNetTime(secondLedger->getCloseTimeNC()); } + mSNTPClient.init(theConfig.SNTP_SERVERS); + mNetOps.setStateTimer(); mIOService.run(); // This blocks diff --git a/src/Application.h b/src/Application.h index 3ba29dee22..9efbc89fc1 100644 --- a/src/Application.h +++ b/src/Application.h @@ -88,6 +88,7 @@ public: bool isNew(const uint256& s) { return mSuppressions.addSuppression(s); } bool isNew(const uint160& s) { return mSuppressions.addSuppression(s); } bool running() { return mTxnDB != NULL; } + bool getSystemTimeOffset(int& offset) { return mSNTPClient.getOffset(offset); } DatabaseCon* getRpcDB() { return mRpcDB; } DatabaseCon* getTxnDB() { return mTxnDB; } diff --git a/src/NetworkOPs.cpp b/src/NetworkOPs.cpp index 3ba931e9cd..4d243e654b 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -31,7 +31,12 @@ NetworkOPs::NetworkOPs(boost::asio::io_service& io_service, LedgerMaster* pLedge boost::posix_time::ptime NetworkOPs::getNetworkTimePT() { - return boost::posix_time::second_clock::universal_time() + boost::posix_time::seconds(mTimeOffset); + int offset; + if (theApp->getSystemTimeOffset(offset)) + offset += mTimeOffset; + else + offset = mTimeOffset; + return boost::posix_time::second_clock::universal_time() + boost::posix_time::seconds(offset); } uint32 NetworkOPs::getNetworkTimeNC() diff --git a/src/Peer.cpp b/src/Peer.cpp index ccc1b11220..3a8e385f39 100644 --- a/src/Peer.cpp +++ b/src/Peer.cpp @@ -571,15 +571,22 @@ void Peer::recvHello(newcoin::TMHello& packet) // Cancel verification timeout. (void) mVerifyTimer.cancel(); - uint32 minTime = theApp->getOPs().getNetworkTimeNC() - 20; - uint32 maxTime = minTime + 20; + uint32 ourTime = theApp->getOPs().getNetworkTimeNC(); + uint32 minTime = ourTime - 10; + uint32 maxTime = ourTime + 10; + + if (packet.has_nettime()) + { + int64 to = ourTime; + to -= packet.nettime(); + Log(lsTRACE) << "Connect: time error " << to; + } if (packet.has_nettime() && ((packet.nettime() < minTime) || (packet.nettime() > maxTime))) { Log(lsINFO) << "Recv(Hello): Disconnect: Clock is far off"; } - - if (packet.protoversionmin() < MAKE_VERSION_INT(MIN_PROTO_MAJOR, MIN_PROTO_MINOR)) + else if (packet.protoversionmin() < MAKE_VERSION_INT(MIN_PROTO_MAJOR, MIN_PROTO_MINOR)) { Log(lsINFO) << "Recv(Hello): Server requires protocol version " << GET_VERSION_MAJOR(packet.protoversion()) << "." << GET_VERSION_MINOR(packet.protoversion()) diff --git a/src/SNTPClient.cpp b/src/SNTPClient.cpp index 75226b0750..7f652fa401 100644 --- a/src/SNTPClient.cpp +++ b/src/SNTPClient.cpp @@ -40,7 +40,7 @@ void SNTPClient::resolveComplete(const boost::system::error_code& error, boost:: time_t now = time(NULL); if ((query.mLocalTimeSent == now) || ((query.mLocalTimeSent + 1) == now)) { - Log(lsINFO) << "SNTP: Redundant query suppressed"; + Log(lsTRACE) << "SNTP: Redundant query suppressed"; return; } query.mReceivedReply = false; @@ -57,20 +57,20 @@ void SNTPClient::receivePacket(const boost::system::error_code& error, std::size if (!error) { boost::mutex::scoped_lock sl(mLock); - Log(lsINFO) << "SNTP: Packet from " << mReceiveEndpoint; + Log(lsTRACE) << "SNTP: Packet from " << mReceiveEndpoint; std::map::iterator query = mQueries.find(mReceiveEndpoint); if (query == mQueries.end()) - Log(lsINFO) << "SNTP: Reply found without matching query"; + Log(lsDEBUG) << "SNTP: Reply found without matching query"; else if (query->second.mReceivedReply) - Log(lsINFO) << "SNTP: Duplicate response to query"; + Log(lsDEBUG) << "SNTP: Duplicate response to query"; else { query->second.mReceivedReply = true; if (time(NULL) > (query->second.mLocalTimeSent + 1)) - Log(lsINFO) << "SNTP: Late response"; + Log(lsWARNING) << "SNTP: Late response"; else if (bytes_xferd < 48) - Log(lsINFO) << "SNTP: Short reply (" << bytes_xferd << ") " << mReceiveBuffer.size(); + Log(lsWARNING) << "SNTP: Short reply (" << bytes_xferd << ") " << mReceiveBuffer.size(); else processReply(); } @@ -84,7 +84,7 @@ void SNTPClient::receivePacket(const boost::system::error_code& error, std::size void SNTPClient::sendComplete(const boost::system::error_code& error, std::size_t) { if (error) - Log(lsINFO) << "SNTP: Send error"; + Log(lsWARNING) << "SNTP: Send error"; } void SNTPClient::processReply() @@ -107,11 +107,17 @@ void SNTPClient::processReply() return; } - timev -= time(NULL); + time_t now = time(NULL); + timev -= now; timev -= 0x83AA7E80ULL; - Log(lsINFO) << "SNTP: Offset is " << timev; + Log(lsTRACE) << "SNTP: Offset is " << timev; - // WRITEME + if ((mLastOffsetUpdate == (time_t) -1) || (mLastOffsetUpdate < (now - 180))) + mOffset = timev; + else + mOffset = ((mOffset * 7) + timev) / 8; + mLastOffsetUpdate = now; + Log(lsTRACE) << "SNTP: Offset is " << timev << ", new system offset is " << timev; } void SNTPClient::timerEntry(const boost::system::error_code& error) @@ -150,6 +156,15 @@ void SNTPClient::queryAll() nothing(); } +bool SNTPClient::getOffset(int& offset) +{ + boost::mutex::scoped_lock sl(mLock); + if ((mLastOffsetUpdate == (time_t) -1) || ((mLastOffsetUpdate + 90) < time(NULL))) + return false; + offset = mOffset; + return true; +} + bool SNTPClient::doQuery() { boost::mutex::scoped_lock sl(mLock);