Browse Source

add packet-type. prep for node-discovery interop.

cl-refactor
subtly 10 years ago
parent
commit
a73f1fa7c5
  1. 13
      alethzero/MainWin.cpp
  2. 11
      libp2p/Host.h
  3. 25
      libp2p/NodeTable.cpp
  4. 22
      libp2p/NodeTable.h
  5. 14
      libp2p/UDP.cpp
  6. 3
      libp2p/UDP.h

13
alethzero/MainWin.cpp

@ -938,13 +938,13 @@ void Main::refreshNetwork()
if (web3()->haveNetwork())
{
map<h512, QString> clients;
map<h512, QString> sessions;
for (PeerSessionInfo const& i: ps)
ui->peers->addItem(QString("[%8 %7] %3 ms - %1:%2 - %4 %5 %6")
.arg(QString::fromStdString(i.host))
.arg(i.port)
.arg(chrono::duration_cast<chrono::milliseconds>(i.lastPing).count())
.arg(clients[i.id] = QString::fromStdString(i.clientVersion))
.arg(sessions[i.id] = QString::fromStdString(i.clientVersion))
.arg(QString::fromStdString(toString(i.caps)))
.arg(QString::fromStdString(toString(i.notes)))
.arg(i.socket)
@ -952,15 +952,12 @@ void Main::refreshNetwork()
auto ns = web3()->nodes();
for (p2p::Peer const& i: ns)
ui->nodes->insertItem(clients.count(i.id) ? 0 : ui->nodes->count(), QString("[%1 %3] %2 - ( =%5s | /%4s%6 ) - *%7 $%8")
ui->nodes->insertItem(sessions.count(i.id) ? 0 : ui->nodes->count(), QString("[%1 %3] %2 - ( =%5s | /%4s%6 ) - *%7 $%8")
.arg(QString::fromStdString(i.id.abridged()))
.arg(QString::fromStdString(toString(i.address)))
.arg(i.id == web3()->id() ? "self" : clients.count(i.id) ? clients[i.id] : i.secondsSinceLastAttempted() == -1 ? "session-fail" : i.secondsSinceLastAttempted() >= (int)i.fallbackSeconds() ? "retrying..." : "retry-" + QString::number(i.fallbackSeconds() - i.secondsSinceLastAttempted()) + "s")
.arg(i.secondsSinceLastAttempted())
.arg(i.secondsSinceLastConnected())
.arg(QString::fromStdString(i.peerEndpoint().address().to_string()))
.arg(i.id == web3()->id() ? "self" : sessions.count(i.id) ? sessions[i.id] : "disconnected")
.arg(i.isOffline() ? " | " + QString::fromStdString(reasonOf(i.lastDisconnect)) + " | " + QString::number(i.failedAttempts) + "x" : "")
.arg(i.rating)
.arg(0 /* (int)i.idOrigin */)
);
}
}

11
libp2p/Host.h

@ -69,6 +69,7 @@ class Host;
* Host of the responsibility. (&& remove save/restoreNodes)
* @todo reimplement recording of historical session information on per-transport basis
* @todo rebuild nodetable when localNetworking is enabled/disabled
* @todo move attributes into protected
*/
class Peer: public Node
{
@ -79,11 +80,6 @@ public:
bi::tcp::endpoint const& peerEndpoint() const { return endpoint.tcp; }
protected:
/// Used by isOffline() and (todo) for peer to emit session information.
std::weak_ptr<Session> m_session;
int score = 0; ///< All time cumulative.
int rating = 0; ///< Trending.
@ -93,6 +89,10 @@ protected:
std::chrono::system_clock::time_point lastAttempted;
unsigned failedAttempts = 0;
DisconnectReason lastDisconnect = NoDisconnect; ///< Reason for disconnect that happened last.
protected:
/// Used by isOffline() and (todo) for peer to emit session information.
std::weak_ptr<Session> m_session;
};
using Peers = std::vector<Peer>;
@ -260,7 +260,6 @@ private:
std::set<bi::address> m_peerAddresses; ///< Public addresses that peers (can) know us by.
// Our capabilities.
std::map<CapDesc, std::shared_ptr<HostCapabilityFace>> m_capabilities; ///< Each of the capabilities we support.
std::chrono::steady_clock::time_point m_lastPing; ///< Time we sent the last ping to all peers.

25
libp2p/NodeTable.cpp

@ -352,24 +352,24 @@ NodeTable::NodeBucket& NodeTable::bucket(NodeEntry const* _n)
void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytesConstRef _packet)
{
// h256 + Signature + RLP (smallest possible packet is empty neighbours packet which is 3 bytes)
if (_packet.size() < h256::size + Signature::size + 3)
// h256 + Signature + type + RLP (smallest possible packet is empty neighbours packet which is 3 bytes)
if (_packet.size() < h256::size + Signature::size + 1 + 3)
{
clog(NodeTableMessageSummary) << "Invalid Message size from " << _from.address().to_string() << ":" << _from.port();
return;
}
bytesConstRef signedBytes(_packet.cropped(h256::size, _packet.size() - h256::size));
h256 hashSigned(sha3(signedBytes));
bytesConstRef hashedBytes(_packet.cropped(h256::size, _packet.size() - h256::size));
h256 hashSigned(sha3(hashedBytes));
if (!_packet.cropped(0, h256::size).contentsEqual(hashSigned.asBytes()))
{
clog(NodeTableMessageSummary) << "Invalid Message hash from " << _from.address().to_string() << ":" << _from.port();
return;
}
bytesConstRef rlpBytes(hashedBytes.cropped(Signature::size, hashedBytes.size() - Signature::size));
bytesConstRef rlpBytes(signedBytes.cropped(Signature::size, signedBytes.size() - Signature::size));
RLP rlp(rlpBytes);
unsigned itemCount = rlp.itemCount();
// todo: verify sig via known-nodeid and MDC, or, do ping/pong auth if node/endpoint is unknown/untrusted
bytesConstRef sigBytes(_packet.cropped(h256::size, Signature::size));
Public nodeid(dev::recover(*(Signature const*)sigBytes.data(), sha3(rlpBytes)));
@ -378,8 +378,13 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes
clog(NodeTableMessageSummary) << "Invalid Message signature from " << _from.address().to_string() << ":" << _from.port();
return;
}
noteNode(nodeid, _from);
if (rlpBytes[0] && rlpBytes[0] < 4)
noteNode(nodeid, _from);
// todo: switch packet-type
RLP rlp(rlpBytes.cropped(1, rlpBytes.size() - 1));
unsigned itemCount = rlp.itemCount();
try {
switch (itemCount)
{
@ -435,14 +440,14 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes
PingNode in = PingNode::fromBytesConstRef(_from, rlpBytes);
Pong p(_from);
p.replyTo = sha3(rlpBytes);
p.echo = sha3(rlpBytes);
p.sign(m_secret);
m_socketPtr->send(p);
break;
}
default:
clog(NodeTableMessageSummary) << "Invalid Message received from " << _from.address().to_string() << ":" << _from.port();
clog(NodeTableMessageSummary) << "Invalid Message, " << std::hex << rlpBytes[0] << ", received from " << _from.address().to_string() << ":" << _from.port();
return;
}
}

22
libp2p/NodeTable.h

@ -122,7 +122,7 @@ public:
NodeTable(ba::io_service& _io, KeyPair _alias, uint16_t _udpPort = 30303);
~NodeTable();
/// Constants for Kademlia, mostly derived from address space.
/// Constants for Kademlia, derived from address space.
static unsigned const s_addressByteSize = sizeof(NodeId); ///< Size of address type in bytes.
static unsigned const s_bits = 8 * s_addressByteSize; ///< Denoted by n in [Kademlia].
@ -269,6 +269,9 @@ struct PingNode: RLPXDatagram<PingNode>
PingNode(bi::udp::endpoint _ep): RLPXDatagram<PingNode>(_ep) {}
PingNode(bi::udp::endpoint _ep, std::string _src, uint16_t _srcPort, std::chrono::seconds _expiration = std::chrono::seconds(60)): RLPXDatagram<PingNode>(_ep), ipAddress(_src), port(_srcPort), expiration(futureFromEpoch(_expiration)) {}
uint8_t packetType() { return 1; }
unsigned version = 1;
std::string ipAddress;
unsigned port;
unsigned expiration;
@ -283,20 +286,17 @@ struct PingNode: RLPXDatagram<PingNode>
* RLP Encoded Items: 1
* Minimum Encoded Size: 33 bytes
* Maximum Encoded Size: 33 bytes
*
* @todo expiration
* @todo value of replyTo
* @todo create from PingNode (reqs RLPXDatagram verify flag)
*/
struct Pong: RLPXDatagram<Pong>
{
Pong(bi::udp::endpoint _ep): RLPXDatagram<Pong>(_ep) {}
h256 replyTo; // hash of rlp of PingNode
uint8_t packetType() { return 2; }
h256 echo; ///< MCD of PingNode
unsigned expiration;
void streamRLP(RLPStream& _s) const { _s.appendList(1); _s << replyTo; }
void interpretRLP(bytesConstRef _bytes) { RLP r(_bytes); replyTo = (h256)r[0]; }
void streamRLP(RLPStream& _s) const { _s.appendList(1); _s << echo; }
void interpretRLP(bytesConstRef _bytes) { RLP r(_bytes); echo = (h256)r[0]; }
};
/**
@ -317,6 +317,7 @@ struct FindNode: RLPXDatagram<FindNode>
FindNode(bi::udp::endpoint _ep): RLPXDatagram<FindNode>(_ep) {}
FindNode(bi::udp::endpoint _ep, NodeId _target, std::chrono::seconds _expiration = std::chrono::seconds(30)): RLPXDatagram<FindNode>(_ep), target(_target), expiration(futureFromEpoch(_expiration)) {}
uint8_t packetType() { return 3; }
h512 target;
unsigned expiration;
@ -329,8 +330,6 @@ struct FindNode: RLPXDatagram<FindNode>
*
* RLP Encoded Items: 2 (first item is list)
* Minimum Encoded Size: 10 bytes
*
* @todo nonce: Should be replaced with expiration.
*/
struct Neighbours: RLPXDatagram<Neighbours>
{
@ -346,7 +345,7 @@ struct Neighbours: RLPXDatagram<Neighbours>
};
Neighbours(bi::udp::endpoint _ep): RLPXDatagram<Neighbours>(_ep) {}
Neighbours(bi::udp::endpoint _to, std::vector<std::shared_ptr<NodeEntry>> const& _nearest, unsigned _offset = 0, unsigned _limit = 0): RLPXDatagram<Neighbours>(_to)
Neighbours(bi::udp::endpoint _to, std::vector<std::shared_ptr<NodeEntry>> const& _nearest, unsigned _offset = 0, unsigned _limit = 0): RLPXDatagram<Neighbours>(_to), expiration(futureFromEpoch(std::chrono::seconds(30)))
{
auto limit = _limit ? std::min(_nearest.size(), (size_t)(_offset + _limit)) : _nearest.size();
for (auto i = _offset; i < limit; i++)
@ -359,6 +358,7 @@ struct Neighbours: RLPXDatagram<Neighbours>
}
}
uint8_t packetType() { return 4; }
std::list<Node> nodes;
unsigned expiration = 1;

14
libp2p/UDP.cpp

@ -25,9 +25,13 @@ using namespace dev::p2p;
h256 RLPXDatagramFace::sign(Secret const& _k)
{
RLPStream rlpstream;
streamRLP(rlpstream);
bytes rlpBytes(rlpstream.out());
assert(packetType());
RLPStream rlpxstream;
// rlpxstream.appendRaw(toPublic(_k).asBytes()); // for mdc-based signature
rlpxstream.appendRaw(bytes(1, packetType()));
streamRLP(rlpxstream);
bytes rlpBytes(rlpxstream.out());
bytesConstRef rlp(&rlpBytes);
h256 hash(dev::sha3(rlp));
@ -35,12 +39,16 @@ h256 RLPXDatagramFace::sign(Secret const& _k)
data.resize(h256::size + Signature::size + rlp.size());
bytesConstRef packetHash(&data[0], h256::size);
bytesConstRef signedPayload(&data[h256::size], Signature::size + rlp.size());
bytesConstRef payloadSig(&data[h256::size], Signature::size);
bytesConstRef payload(&data[h256::size + Signature::size], rlp.size());
sig.ref().copyTo(payloadSig);
// rlp.cropped(Public::size, rlp.size() - Public::size).copyTo(payload);
rlp.copyTo(payload);
// hash.ref().copyTo(packetHash); // for mdc-based signature
dev::sha3(signedPayload).ref().copyTo(packetHash);
return std::move(hash);

3
libp2p/UDP.h

@ -63,7 +63,8 @@ struct RLPXDatagramFace: public UDPDatagram
static uint64_t futureFromEpoch(std::chrono::milliseconds _ms) { return std::chrono::duration_cast<std::chrono::milliseconds>((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::milliseconds>((std::chrono::system_clock::now() + _sec).time_since_epoch()).count(); }
static Public authenticate(bytesConstRef _sig, bytesConstRef _rlp);
virtual uint8_t packetType() =0;
RLPXDatagramFace(bi::udp::endpoint const& _ep): UDPDatagram(_ep) {}
virtual h256 sign(Secret const& _from);

Loading…
Cancel
Save