Browse Source

send multiple neighbors packets when size is over datagram size limit.

cl-refactor
subtly 10 years ago
parent
commit
d5f0679fb3
  1. 22
      libp2p/NodeTable.cpp
  2. 33
      libp2p/NodeTable.h
  3. 2
      libp2p/UDP.h

22
libp2p/NodeTable.cpp

@ -306,7 +306,7 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes
// h256 + Signature + RLP
if (_packet.size() < 100)
{
clog(NodeTableMessageSummary) << "Invalid Message size received from " << _from.address().to_string() << ":" << _from.port();
clog(NodeTableMessageSummary) << "Invalid Message size from " << _from.address().to_string() << ":" << _from.port();
return;
}
@ -314,11 +314,10 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes
h256 hashSigned(sha3(signedBytes));
if (!_packet.cropped(0, h256::size).contentsEqual(hashSigned.asBytes()))
{
clog(NodeTableMessageSummary) << "Invalid Message hash received from " << _from.address().to_string() << ":" << _from.port();
clog(NodeTableMessageSummary) << "Invalid Message hash from " << _from.address().to_string() << ":" << _from.port();
return;
}
// 3 items is PingNode, 2 items w/no lists is FindNode, 2 items w/first item as list is Neighbors, 1 item is Pong
bytesConstRef rlpBytes(signedBytes.cropped(Signature::size, signedBytes.size() - Signature::size));
RLP rlp(rlpBytes);
unsigned itemCount = rlp.itemCount();
@ -327,7 +326,7 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes
Public nodeid(dev::recover(*(Signature const*)sigBytes.data(), sha3(rlpBytes)));
if (!nodeid)
{
clog(NodeTableMessageSummary) << "Invalid Message Signature from " << _from.address().to_string() << ":" << _from.port();
clog(NodeTableMessageSummary) << "Invalid Message signature from " << _from.address().to_string() << ":" << _from.port();
return;
}
noteNode(nodeid, _from);
@ -347,7 +346,6 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes
case 2:
if (rlp[0].isList())
{
// todo: chunk neighbors packet
Neighbors in = Neighbors::fromBytesConstRef(_from, rlpBytes);
clog(NodeTableMessageSummary) << "Received " << in.nodes.size() << " Neighbors from " << _from.address().to_string() << ":" << _from.port();
for (auto n: in.nodes)
@ -359,9 +357,13 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes
FindNode in = FindNode::fromBytesConstRef(_from, rlpBytes);
std::vector<std::shared_ptr<NodeTable::NodeEntry>> nearest = findNearest(in.target);
Neighbors out(_from, nearest);
out.sign(m_secret);
m_socketPtr->send(out);
static unsigned const nlimit = (m_socketPtr->maxDatagramSize - 11) / 86;
for (unsigned offset = 0; offset < nearest.size(); offset += nlimit)
{
Neighbors out(_from, nearest, offset, nlimit);
out.sign(m_secret);
m_socketPtr->send(out);
}
}
break;
@ -384,7 +386,7 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes
}
catch (...)
{
// likely culprit is invalid rlp encoding
}
}

33
libp2p/NodeTable.h

@ -21,6 +21,7 @@
#pragma once
#include <algorithm>
#include <boost/integer/static_log2.hpp>
#include <libdevcrypto/Common.h>
#include <libp2p/UDP.h>
@ -109,15 +110,15 @@ public:
/// Constants for Kademlia, mostly derived from address space.
static constexpr unsigned s_addressByteSize = sizeof(NodeEntry::id); ///< Size of address type in bytes.
static constexpr unsigned s_bits = 8 * s_addressByteSize; ///< Denoted by n in [Kademlia].
static constexpr unsigned s_bins = s_bits - 1; ///< Size of m_state (excludes root, which is us).
static constexpr unsigned s_maxSteps = boost::static_log2<s_bits>::value; ///< Max iterations of discovery. (doFindNode)
static unsigned const s_addressByteSize = sizeof(NodeEntry::id); ///< Size of address type in bytes.
static unsigned const s_bits = 8 * s_addressByteSize; ///< Denoted by n in [Kademlia].
static unsigned const s_bins = s_bits - 1; ///< Size of m_state (excludes root, which is us).
static unsigned const s_maxSteps = boost::static_log2<s_bits>::value; ///< Max iterations of discovery. (doFindNode)
/// Chosen constants
static constexpr unsigned s_bucketSize = 16; ///< Denoted by k in [Kademlia]. Number of nodes stored in each bucket.
static constexpr unsigned s_alpha = 3; ///< Denoted by \alpha in [Kademlia]. Number of concurrent FindNode requests.
static unsigned const s_bucketSize = 16; ///< Denoted by k in [Kademlia]. Number of nodes stored in each bucket.
static unsigned const s_alpha = 3; ///< Denoted by \alpha in [Kademlia]. Number of concurrent FindNode requests.
/// Intervals
@ -312,16 +313,26 @@ struct Neighbors: RLPXDatagram<Neighbors>
};
using RLPXDatagram::RLPXDatagram;
Neighbors(bi::udp::endpoint _to, std::vector<std::shared_ptr<NodeTable::NodeEntry>> const& _nearest): RLPXDatagram(_to)
Neighbors(bi::udp::endpoint _to, std::vector<std::shared_ptr<NodeTable::NodeEntry>> const& _nearest, unsigned _offset = 0, unsigned _limit = 0): RLPXDatagram(_to)
{
for (auto& n: _nearest)
auto limit = _limit ? std::min(_nearest.size(), (size_t)(_offset + _limit)) : _nearest.size();
for (auto i = _offset; i < limit; i++)
{
Node node;
node.ipAddress = n->endpoint.udp.address().to_string();
node.port = n->endpoint.udp.port();
node.node = n->publicKey();
node.ipAddress = _nearest[i]->endpoint.udp.address().to_string();
node.port = _nearest[i]->endpoint.udp.port();
node.node = _nearest[i]->publicKey();
nodes.push_back(node);
}
// for (auto& n: _nearest)
// {
// Node node;
// node.ipAddress = n->endpoint.udp.address().to_string(); // 16
// node.port = n->endpoint.udp.port(); // 3
// node.node = n->publicKey();// 67
// nodes.push_back(node);
// }
}
std::list<Node> nodes;

2
libp2p/UDP.h

@ -110,7 +110,7 @@ template <typename Handler, unsigned MaxDatagramSize>
class UDPSocket: UDPSocketFace, public std::enable_shared_from_this<UDPSocket<Handler, MaxDatagramSize>>
{
public:
static constexpr unsigned maxDatagramSize = MaxDatagramSize;
enum { maxDatagramSize = MaxDatagramSize };
static_assert(maxDatagramSize < 65507, "UDP datagrams cannot be larger than 65507 bytes");
UDPSocket(ba::io_service& _io, UDPSocketEvents& _host, unsigned _port): m_host(_host), m_endpoint(bi::udp::v4(), _port), m_socket(_io) { m_started.store(false); m_closed.store(true); };

Loading…
Cancel
Save