From e606ef9a59a545a095f43ac67b7dd5c9985c1837 Mon Sep 17 00:00:00 2001 From: subtly Date: Fri, 24 Apr 2015 11:12:03 +0100 Subject: [PATCH] check node discovery timestamps. --- libp2p/NodeTable.cpp | 10 ++++++++++ libp2p/NodeTable.h | 18 +++++++++--------- libp2p/UDP.h | 5 +++-- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 3370e502b..7c30a9b03 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -498,6 +498,11 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes case FindNode::type: { FindNode in = FindNode::fromBytesConstRef(_from, rlpBytes); + if (RLPXDatagramFace::secondsSinceEpoch() - in.ts > 3) + { + clog(NodeTableTriviaSummary) << "Received expired FindNode from " << _from.address().to_string() << ":" << _from.port(); + return; + } vector> nearest = nearestNodeEntries(in.target); static unsigned const nlimit = (m_socketPointer->maxDatagramSize - 111) / 87; @@ -517,6 +522,11 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes PingNode in = PingNode::fromBytesConstRef(_from, rlpBytes); if (in.version != dev::p2p::c_protocolVersion) return; + if (RLPXDatagramFace::secondsSinceEpoch() - in.ts > 3) + { + clog(NodeTableTriviaSummary) << "Received expired PingNode from " << _from.address().to_string() << ":" << _from.port(); + return; + } if (in.source.address.is_unspecified()) in.source.address = _from.address(); diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 76cd32097..94bf81924 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -300,7 +300,7 @@ struct InvalidRLP: public Exception {}; struct PingNode: RLPXDatagram { /// Constructor used for sending PingNode. - PingNode(NodeIPEndpoint _src, NodeIPEndpoint _dest): RLPXDatagram(_dest), source(_src), destination(_dest), ts(futureFromEpoch(std::chrono::seconds(60))) {} + PingNode(NodeIPEndpoint _src, NodeIPEndpoint _dest): RLPXDatagram(_dest), source(_src), destination(_dest), ts(secondsSinceEpoch()) {} /// Constructor used to create empty PingNode for parsing inbound packets. PingNode(bi::udp::endpoint _ep): RLPXDatagram(_ep), source(UnspecifiedNodeIPEndpoint), destination(UnspecifiedNodeIPEndpoint) {} @@ -309,7 +309,7 @@ struct PingNode: RLPXDatagram unsigned version = 0; NodeIPEndpoint source; NodeIPEndpoint destination; - unsigned ts; + uint32_t ts; void streamRLP(RLPStream& _s) const override; void interpretRLP(bytesConstRef _bytes) override; @@ -321,13 +321,13 @@ struct PingNode: RLPXDatagram struct Pong: RLPXDatagram { Pong(bi::udp::endpoint const& _ep): RLPXDatagram(_ep), destination(UnspecifiedNodeIPEndpoint) {} - Pong(NodeIPEndpoint const& _dest): RLPXDatagram((bi::udp::endpoint)_dest), destination(_dest), ts(futureFromEpoch(std::chrono::seconds(60))) {} + Pong(NodeIPEndpoint const& _dest): RLPXDatagram((bi::udp::endpoint)_dest), destination(_dest), ts(secondsSinceEpoch()) {} static const uint8_t type = 2; NodeIPEndpoint destination; h256 echo; ///< MCD of PingNode - unsigned ts; + uint32_t ts; void streamRLP(RLPStream& _s) const { _s.appendList(2); _s << echo << ts; } void interpretRLP(bytesConstRef _bytes) { RLP r(_bytes); echo = (h256)r[0]; ts = r[1].toInt(); } @@ -348,12 +348,12 @@ struct Pong: RLPXDatagram struct FindNode: RLPXDatagram { FindNode(bi::udp::endpoint _ep): RLPXDatagram(_ep) {} - FindNode(bi::udp::endpoint _ep, NodeId _target, std::chrono::seconds _ts = std::chrono::seconds(60)): RLPXDatagram(_ep), target(_target), ts(futureFromEpoch(_ts)) {} + FindNode(bi::udp::endpoint _ep, NodeId _target): RLPXDatagram(_ep), target(_target), ts(secondsSinceEpoch()) {} static const uint8_t type = 3; h512 target; - unsigned ts; + uint32_t ts; void streamRLP(RLPStream& _s) const { _s.appendList(2); _s << target << ts; } void interpretRLP(bytesConstRef _bytes) { RLP r(_bytes); target = r[0].toHash(); ts = r[1].toInt(); } @@ -373,8 +373,8 @@ struct Neighbours: RLPXDatagram void streamRLP(RLPStream& _s) const { _s.appendList(4); endpoint.streamRLP(_s, NodeIPEndpoint::Inline); _s << node; } }; - Neighbours(bi::udp::endpoint _ep): RLPXDatagram(_ep), ts(futureFromEpoch(std::chrono::seconds(30))) {} - Neighbours(bi::udp::endpoint _to, std::vector> const& _nearest, unsigned _offset = 0, unsigned _limit = 0): RLPXDatagram(_to), ts(futureFromEpoch(std::chrono::seconds(30))) + Neighbours(bi::udp::endpoint _ep): RLPXDatagram(_ep), ts(secondsSinceEpoch()) {} + Neighbours(bi::udp::endpoint _to, std::vector> const& _nearest, unsigned _offset = 0, unsigned _limit = 0): RLPXDatagram(_to), ts(secondsSinceEpoch()) { auto limit = _limit ? std::min(_nearest.size(), (size_t)(_offset + _limit)) : _nearest.size(); for (auto i = _offset; i < limit; i++) @@ -383,7 +383,7 @@ struct Neighbours: RLPXDatagram static const uint8_t type = 4; std::vector neighbours; - unsigned ts = 1; + uint32_t ts = 1; void streamRLP(RLPStream& _s) const { _s.appendList(2); _s.appendList(neighbours.size()); for (auto& n: neighbours) n.streamRLP(_s); _s << ts; } void interpretRLP(bytesConstRef _bytes) { RLP r(_bytes); for (auto n: r[0]) neighbours.push_back(Neighbour(n)); ts = r[1].toInt(); } diff --git a/libp2p/UDP.h b/libp2p/UDP.h index 374f986b0..cdf241566 100644 --- a/libp2p/UDP.h +++ b/libp2p/UDP.h @@ -61,8 +61,9 @@ protected: */ struct RLPXDatagramFace: public UDPDatagram { - static uint64_t futureFromEpoch(std::chrono::milliseconds _ms) { return std::chrono::duration_cast((std::chrono::system_clock::now() + _ms).time_since_epoch()).count(); } - static uint64_t futureFromEpoch(std::chrono::seconds _sec) { return std::chrono::duration_cast((std::chrono::system_clock::now() + _sec).time_since_epoch()).count(); } + static uint32_t futureFromEpoch(std::chrono::milliseconds _ms) { return std::chrono::duration_cast((std::chrono::system_clock::now() + _ms).time_since_epoch()).count(); } + static uint32_t futureFromEpoch(std::chrono::seconds _sec) { return std::chrono::duration_cast((std::chrono::system_clock::now() + _sec).time_since_epoch()).count(); } + static uint32_t secondsSinceEpoch() { return std::chrono::duration_cast((std::chrono::system_clock::now()).time_since_epoch()).count(); } static Public authenticate(bytesConstRef _sig, bytesConstRef _rlp); virtual uint8_t packetType() = 0;