|
|
@ -63,98 +63,21 @@ private: |
|
|
|
|
|
|
|
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 |
|
|
|
* 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 abstract socket -> IPConnection |
|
|
|
* @todo determinePublic: ipv6, udp |
|
|
|
* @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 configuration-management (NetworkPrefs+Keys+Topology) |
|
|
|
*/ |
|
|
|
class Host: public Worker |
|
|
|
{ |
|
|
|
friend class HostNodeTableHandler; |
|
|
|
friend struct PeerHandshake; |
|
|
|
friend class Session; |
|
|
|
friend class HostCapabilityFace; |
|
|
|
|
|
|
@ -308,5 +231,79 @@ private: |
|
|
|
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; |
|
|
|
}; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|