Browse Source

reenable sessions. more refactor.

cl-refactor
subtly 10 years ago
parent
commit
4ebc2f8320
  1. 21
      libp2p/Host.cpp
  2. 153
      libp2p/Host.h

21
libp2p/Host.cpp

@ -338,7 +338,7 @@ void Host::runAcceptor()
{ {
// doHandshake takes ownersihp of *s via std::move // doHandshake takes ownersihp of *s via std::move
// incoming connection; we don't yet know nodeid // incoming connection; we don't yet know nodeid
auto handshake = make_shared<PeerHandshake>(m_alias, s); auto handshake = make_shared<PeerHandshake>(this, s);
handshake->start(); handshake->start();
success = true; success = true;
} }
@ -399,10 +399,10 @@ void PeerHandshake::transition(boost::system::error_code _ech) {
bytesConstRef nonce(&auth[Signature::size + h256::size + Public::size], h256::size); bytesConstRef nonce(&auth[Signature::size + h256::size + Public::size], h256::size);
// E(remote-pubk, S(ecdhe-random, ecdh-shared-secret^nonce) || H(ecdhe-random-pubk) || pubk || nonce || 0x0) // E(remote-pubk, S(ecdhe-random, ecdh-shared-secret^nonce) || H(ecdhe-random-pubk) || pubk || nonce || 0x0)
crypto::ecdh::agree(alias.sec(), remote, ss); crypto::ecdh::agree(host->m_alias.sec(), remote, ss);
sign(ecdhe.seckey(), ss ^ this->nonce).ref().copyTo(sig); sign(ecdhe.seckey(), ss ^ this->nonce).ref().copyTo(sig);
sha3(ecdhe.pubkey().ref(), hepubk); sha3(ecdhe.pubkey().ref(), hepubk);
alias.pub().ref().copyTo(pubk); host->m_alias.pub().ref().copyTo(pubk);
this->nonce.ref().copyTo(nonce); this->nonce.ref().copyTo(nonce);
auth[auth.size() - 1] = 0x0; auth[auth.size() - 1] = 0x0;
encrypt(remote, &auth, authCipher); encrypt(remote, &auth, authCipher);
@ -423,7 +423,7 @@ void PeerHandshake::transition(boost::system::error_code _ech) {
transition(ec); transition(ec);
else else
{ {
decrypt(alias.sec(), bytesConstRef(&authCipher), auth); decrypt(host->m_alias.sec(), bytesConstRef(&authCipher), auth);
bytesConstRef sig(&auth[0], Signature::size); bytesConstRef sig(&auth[0], Signature::size);
bytesConstRef hepubk(&auth[Signature::size], h256::size); bytesConstRef hepubk(&auth[Signature::size], h256::size);
bytesConstRef pubk(&auth[Signature::size + h256::size], Public::size); bytesConstRef pubk(&auth[Signature::size + h256::size], Public::size);
@ -431,7 +431,7 @@ void PeerHandshake::transition(boost::system::error_code _ech) {
pubk.copyTo(remote.ref()); pubk.copyTo(remote.ref());
nonce.copyTo(remoteNonce.ref()); nonce.copyTo(remoteNonce.ref());
crypto::ecdh::agree(alias.sec(), remote, ss); crypto::ecdh::agree(host->m_alias.sec(), remote, ss);
remoteEphemeral = recover(*(Signature*)sig.data(), ss ^ remoteNonce); remoteEphemeral = recover(*(Signature*)sig.data(), ss ^ remoteNonce);
assert(sha3(remoteEphemeral) == *(h256*)hepubk.data()); assert(sha3(remoteEphemeral) == *(h256*)hepubk.data());
transition(); transition();
@ -451,7 +451,7 @@ void PeerHandshake::transition(boost::system::error_code _ech) {
transition(ec); transition(ec);
else else
{ {
decrypt(alias.sec(), bytesConstRef(&ackCipher), ack); decrypt(host->m_alias.sec(), bytesConstRef(&ackCipher), ack);
bytesConstRef(&ack).cropped(0, Public::size).copyTo(remoteEphemeral.ref()); bytesConstRef(&ack).cropped(0, Public::size).copyTo(remoteEphemeral.ref());
bytesConstRef(&ack).cropped(Public::size, h256::size).copyTo(remoteNonce.ref()); bytesConstRef(&ack).cropped(Public::size, h256::size).copyTo(remoteNonce.ref());
transition(); transition();
@ -551,7 +551,7 @@ void PeerHandshake::transition(boost::system::error_code _ech) {
{ {
shared_ptr<Peer> p; shared_ptr<Peer> p;
// todo: need host // todo: need host
// p = m_peers[remote]; p = host->m_peers[remote];
if (!p) if (!p)
{ {
@ -563,9 +563,8 @@ void PeerHandshake::transition(boost::system::error_code _ech) {
p->m_lastConnected = std::chrono::system_clock::now(); p->m_lastConnected = std::chrono::system_clock::now();
p->m_failedAttempts = 0; p->m_failedAttempts = 0;
// todo: need host auto ps = std::make_shared<Session>(host, move(*socket), p);
// auto ps = std::make_shared<Session>(this, move(*socket), p); ps->start();
// ps->start();
} }
// todo: PeerSession needs to take ownership of k (PeerSecrets) // todo: PeerSession needs to take ownership of k (PeerSecrets)
@ -877,7 +876,7 @@ void Host::connect(std::shared_ptr<Peer> const& _p)
else else
{ {
clog(NetConnect) << "Connected to" << _p->id.abridged() << "@" << _p->peerEndpoint(); clog(NetConnect) << "Connected to" << _p->id.abridged() << "@" << _p->peerEndpoint();
auto handshake = make_shared<PeerHandshake>(m_alias, s, _p->id); auto handshake = make_shared<PeerHandshake>(this, s, _p->id);
handshake->start(); handshake->start();
} }
Guard l(x_pendingNodeConns); Guard l(x_pendingNodeConns);

153
libp2p/Host.h

@ -64,97 +64,20 @@ private:
Host& m_host; Host& m_host;
}; };
/**
* @brief Key material and derived secrets for TCP peer connection.
*/
struct PeerSecrets
{
friend class PeerHandshake;
protected:
Secret encryptK;
Secret macK;
h256 egressMac;
h256 ingressMac;
bytes magicCipherAndMac;
bytes recvdMagicCipherAndMac;
};
struct PeerHandshake: public std::enable_shared_from_this<PeerHandshake>
{
friend class Host;
enum State
{
New, // New->AckAuth [egress: tx auth, ingress: rx auth]
AckAuth, // AckAuth->Authenticating [egress: rx ack, ingress: tx ack]
Authenticating, // Authenticating [tx caps, rx caps, authenticate]
};
/// Handshake for ingress connection. Takes ownership of socket.
PeerHandshake(KeyPair const& _alias, bi::tcp::socket* _socket): alias(_alias), socket(std::move(_socket)), originated(false) { crypto::Nonce::get().ref().copyTo(nonce.ref()); }
/// Handshake for egress connection to _remote. Takes ownership of socket.
PeerHandshake(KeyPair const& _alias, bi::tcp::socket* _socket, NodeId _remote): alias(_alias), socket(std::move(_socket)), originated(true), remote(_remote) { crypto::Nonce::get().ref().copyTo(nonce.ref()); }
~PeerHandshake() { delete socket; }
protected:
/// Returns true when the auth message is to be sent or received.
bool isNew() { return state == New; }
/// Returns true when the ack message is to be sent or received.
bool isAcking() { return state == AckAuth; }
/// Returns true when auth and ack messages have been received and caps message is to be sent, received, and authenticated.
bool isAuthenticating() { return state == Authenticating; }
void start() { transition(); }
private:
void transition(boost::system::error_code _ech = boost::system::error_code());
/// Current state of handshake.
State state = New;
KeyPair const& alias;
/// Node id of remote host for socket.
NodeId remote;
bi::tcp::socket* socket;
bool originated = false;
bytes auth;
bytes authCipher;
bytes ack;
bytes ackCipher;
Secret ss;
Secret ess;
crypto::ECDHE ecdhe;
h256 nonce;
Public remoteEphemeral;
h256 remoteNonce;
};
/** /**
* @brief The Host class * @brief The Host class
* Capabilities should be registered prior to startNetwork, since m_capabilities is not thread-safe. * Capabilities should be registered prior to startNetwork, since m_capabilities is not thread-safe.
* *
* @todo exceptions when nodeTable not set (prior to start)
* @todo onNodeTableEvent: move peer-connection logic into ensurePeers
* @todo handshake: gracefully disconnect peer if peer already connected * @todo handshake: gracefully disconnect peer if peer already connected
* @todo abstract socket -> IPConnection * @todo abstract socket -> IPConnection
* @todo determinePublic: ipv6, udp * @todo determinePublic: ipv6, udp
* @todo handle conflict if addNode/requireNode called and Node already exists w/conflicting tcp or udp port * @todo handle conflict if addNode/requireNode called and Node already exists w/conflicting tcp or udp port
* @todo write host identifier to disk w/nodes
* @todo per-session keepalive/ping instead of broadcast; set ping-timeout via median-latency * @todo per-session keepalive/ping instead of broadcast; set ping-timeout via median-latency
* @todo configuration-management (NetworkPrefs+Keys+Topology)
*/ */
class Host: public Worker class Host: public Worker
{ {
friend class HostNodeTableHandler; friend class HostNodeTableHandler;
friend struct PeerHandshake;
friend class Session; friend class Session;
friend class HostCapabilityFace; friend class HostCapabilityFace;
@ -308,5 +231,79 @@ private:
bool m_accepting = false; bool m_accepting = false;
}; };
/**
* @brief Key material and derived secrets for TCP peer connection.
*/
struct PeerSecrets
{
friend struct PeerHandshake;
protected:
Secret encryptK;
Secret macK;
h256 egressMac;
h256 ingressMac;
bytes magicCipherAndMac;
bytes recvdMagicCipherAndMac;
};
struct PeerHandshake: public std::enable_shared_from_this<PeerHandshake>
{
friend class Host;
enum State
{
New, // New->AckAuth [egress: tx auth, ingress: rx auth]
AckAuth, // AckAuth->Authenticating [egress: rx ack, ingress: tx ack]
Authenticating, // Authenticating [tx caps, rx caps, authenticate]
};
/// Handshake for ingress connection. Takes ownership of socket.
PeerHandshake(Host* _host, bi::tcp::socket* _socket): host(_host), socket(std::move(_socket)), originated(false) { crypto::Nonce::get().ref().copyTo(nonce.ref()); }
/// Handshake for egress connection to _remote. Takes ownership of socket.
PeerHandshake(Host* _host, bi::tcp::socket* _socket, NodeId _remote): host(_host), socket(std::move(_socket)), originated(true), remote(_remote) { crypto::Nonce::get().ref().copyTo(nonce.ref()); }
~PeerHandshake() { delete socket; }
protected:
/// Returns true when the auth message is to be sent or received.
bool isNew() { return state == New; }
/// Returns true when the ack message is to be sent or received.
bool isAcking() { return state == AckAuth; }
/// Returns true when auth and ack messages have been received and caps message is to be sent, received, and authenticated.
bool isAuthenticating() { return state == Authenticating; }
void start() { transition(); }
private:
void transition(boost::system::error_code _ech = boost::system::error_code());
/// Current state of handshake.
State state = New;
Host* host;
/// Node id of remote host for socket.
NodeId remote;
bi::tcp::socket* socket;
bool originated = false;
bytes auth;
bytes authCipher;
bytes ack;
bytes ackCipher;
Secret ss;
Secret ess;
crypto::ECDHE ecdhe;
h256 nonce;
Public remoteEphemeral;
h256 remoteNonce;
};
} }
} }

Loading…
Cancel
Save