protocol::TMHello buildHello (uint256 const& sharedValue, Application& app) { protocol::TMHello h; Blob vchSig; app.getLocalCredentials ().getNodePrivate ().signNodePrivate ( sharedValue, vchSig); h.set_protoversion (to_packed (BuildInfo::getCurrentProtocol())); h.set_protoversionmin (to_packed (BuildInfo::getMinimumProtocol())); h.set_fullversion (BuildInfo::getFullVersionString ()); h.set_nettime (app.getOPs ().getNetworkTimeNC ()); h.set_nodepublic (app.getLocalCredentials ().getNodePublic ( ).humanNodePublic ()); h.set_nodeproof (&vchSig[0], vchSig.size ()); // h.set_ipv4port (portNumber); // ignored now h.set_testnet (false); // We always advertise ourselves as private in the HELLO message. This // suppresses the old peer advertising code and allows PeerFinder to // take over the functionality. h.set_nodeprivate (true); auto const closedLedger = app.getLedgerMaster().getClosedLedger(); if (closedLedger && closedLedger->isClosed ()) { uint256 hash = closedLedger->getHash (); h.set_ledgerclosed (hash.begin (), hash.size ()); hash = closedLedger->getParentHash (); h.set_ledgerprevious (hash.begin (), hash.size ()); } return h; }
std::pair<RippleAddress, bool> verifyHello (protocol::TMHello const& h, uint256 const& sharedValue, beast::Journal journal, Application& app) { std::pair<RippleAddress, bool> result = { {}, false }; std::uint32_t const ourTime = app.getOPs().getNetworkTimeNC(); std::uint32_t const minTime = ourTime - clockToleranceDeltaSeconds; std::uint32_t const maxTime = ourTime + clockToleranceDeltaSeconds; #ifdef BEAST_DEBUG if (h.has_nettime ()) { std::int64_t to = ourTime; to -= h.nettime (); journal.debug << "Connect: time offset " << to; } #endif auto const protocol = BuildInfo::make_protocol(h.protoversion()); if (h.has_nettime () && ((h.nettime () < minTime) || (h.nettime () > maxTime))) { if (h.nettime () > maxTime) { journal.info << "Clock for is off by +" << h.nettime() - ourTime; } else if (h.nettime () < minTime) { journal.info << "Clock is off by -" << ourTime - h.nettime(); } } else if (h.protoversionmin () > to_packed ( BuildInfo::getCurrentProtocol())) { journal.info << "Hello: Disconnect: Protocol mismatch [" << "Peer expects " << to_string (protocol) << " and we run " << to_string (BuildInfo::getCurrentProtocol()) << "]"; } else if (! result.first.setNodePublic (h.nodepublic())) { journal.info << "Hello: Disconnect: Bad node public key."; } else if (! result.first.verifyNodePublic ( sharedValue, h.nodeproof (), ECDSA::not_strict)) { // Unable to verify they have private key for claimed public key. journal.info << "Hello: Disconnect: Failed to verify session."; } else { // Successful connection. result.second = true; } return result; }
void testVersionPacking () { testcase ("version packing"); expect (to_packed (from_version (0, 0)) == 0); expect (to_packed (from_version (0, 1)) == 1); expect (to_packed (from_version (0, 255)) == 255); expect (to_packed (from_version (0, 65535)) == 65535); expect (to_packed (from_version (1, 0)) == 65536); expect (to_packed (from_version (1, 1)) == 65537); expect (to_packed (from_version (1, 255)) == 65791); expect (to_packed (from_version (1, 65535)) == 131071); expect (to_packed (from_version (255, 0)) == 16711680); expect (to_packed (from_version (255, 1)) == 16711681); expect (to_packed (from_version (255, 255)) == 16711935); expect (to_packed (from_version (255, 65535)) == 16777215); expect (to_packed (from_version (65535, 0)) == 4294901760); expect (to_packed (from_version (65535, 1)) == 4294901761); expect (to_packed (from_version (65535, 255)) == 4294902015); expect (to_packed (from_version (65535, 65535)) == 4294967295); }