diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 61f30b548..d7546bb11 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -157,13 +157,15 @@ unsigned Host::protocolVersion() const void Host::registerPeer(std::shared_ptr _s, CapDescs const& _caps) { - assert(!!_s->m_peer); - assert(!!_s->m_peer->id); + asserts(!!_s->m_peer->id); { RecursiveGuard l(x_sessions); + if (!m_peers.count(_s->m_peer->id)) + m_peers[_s->m_peer->id] = _s->m_peer; m_sessions[_s->m_peer->id] = _s; } + unsigned o = (unsigned)UserPacket; for (auto const& i: _caps) if (haveCapability(i)) @@ -298,16 +300,7 @@ void Host::runAcceptor() { try { -// RecursiveGuard l(x_sessions); -// auto p = m_peers[_n]; -// if (!p) -// { -// m_peers[_n] = make_shared(); -// p = m_peers[_n]; -// p->id = _n; -// } -// p->address = n.endpoint.tcp; - + // incoming connection so we don't yet know nodeid doHandshake(s, NodeId()); success = true; } @@ -343,9 +336,18 @@ void Host::doHandshake(bi::tcp::socket* _socket, NodeId _nodeId) clog(NetConnect) << "Accepting connection for " << _socket->remote_endpoint(); } catch (...){} - // - auto p = std::make_shared(this, std::move(*_socket), m_peers[_nodeId]); - p->start(); + shared_ptr p; + if (_nodeId) + p = m_peers[_nodeId]; + + if (!p) + { + p = make_shared(); + p->address.address(_socket->remote_endpoint().address()); + } + + auto ps = std::make_shared(this, std::move(*_socket), p); + ps->start(); } string Host::pocHost() @@ -426,8 +428,8 @@ void Host::connect(std::shared_ptr const& _n) clog(NetConnect) << "Connected to" << _n->id.abridged() << "@" << _n->address; _n->lastConnected = std::chrono::system_clock::now(); - auto p = make_shared(this, std::move(*s), _n); - p->start(); + auto ps = make_shared(this, std::move(*s), _n); + ps->start(); } delete s; diff --git a/libp2p/Host.h b/libp2p/Host.h index 3d386fe8c..0e86710ec 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -212,8 +212,8 @@ private: /// Called only from startedWorking(). void runAcceptor(); - /// Handler for verifying handshake siganture before creating session. _egressNodeId is passed for outbound connections. - void doHandshake(bi::tcp::socket* _socket, NodeId _nodeId); + /// Handler for verifying handshake siganture before creating session. _nodeId is passed for outbound connections. + void doHandshake(bi::tcp::socket* _socket, NodeId _nodeId = NodeId()); void seal(bytes& _b); @@ -261,11 +261,10 @@ private: std::map> m_peers; - mutable RecursiveMutex x_sessions; - /// The nodes to which we are currently connected. /// Mutable because we flush zombie entries (null-weakptrs) as regular maintenance from a const method. mutable std::map> m_sessions; + mutable RecursiveMutex x_sessions; unsigned m_idealPeerCount = 5; ///< Ideal number of peers to be connected to. diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index 80c538b24..bafaed7e3 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -86,22 +86,6 @@ int Session::rating() const return m_peer->rating; } -//// TODO: P2P integration: session->? should be unavailable when socket isn't open -//bi::tcp::endpoint Session::endpoint() const -//{ -// if (m_socket.is_open() && m_peer) -// try -// { -// return bi::tcp::endpoint(m_socket.remote_endpoint().address(), m_peer->address.port()); -// } -// catch (...) {} -// -// if (m_peer) -// return m_peer->address; -// -// return m_manualEndpoint; -//} - template vector randomSelection(vector const& _t, unsigned _n) { if (_t.size() <= _n) @@ -172,6 +156,11 @@ bool Session::interpret(RLP const& _r) { case HelloPacket: { + // TODO: P2P first pass, implement signatures. if signature fails, drop connection. if egress, flag node's endpoint as stale. + // Move auth to Host so we consolidate authentication logic and eschew peer deduplication logic. + // Move all node-lifecycle information into Host. + // Finalize peer-lifecycle properties vs node lifecycle. + m_protocolVersion = _r[1].toInt(); auto clientVersion = _r[2].toString(); auto caps = _r[3].toVector(); @@ -194,7 +183,7 @@ bool Session::interpret(RLP const& _r) return true; } - // TODO: P2P ensure disabled logic is covered + // TODO: P2P ensure disabled logic is considered if (false /* m_server->havePeer(id) */) { // Already connected. @@ -203,27 +192,28 @@ bool Session::interpret(RLP const& _r) return true; } + // if peer and connection have id, check for UnexpectedIdentity if (!id) { disconnect(NullIdentity); return true; } - - // TODO: P2P first pass, implement signatures. if signature fails, drop connection. if egress, flag node's endpoint as stale. - // Discussion: Most this to Host so we consolidate authentication logic and eschew peer deduplication logic. - // TODO: P2P Move all node-lifecycle information into Host. Determine best way to handle peer-lifecycle properties vs node lifecycle. - // TODO: P2P remove oldid - // TODO: P2P with encrypted transport the handshake will fail and we won't get here - - // if peer is missing this is incoming connection and we need to tell host about new potential peer - + else if (!m_peer->id) + { + m_peer->id = id; + m_peer->address.port(listenPort); + } + else if (m_peer->id != id) + { + disconnect(UnexpectedIdentity); + return true; + } -// m_peer = m_server->noteNode(m_peer->id, bi::tcp::endpoint(m_socket.remote_endpoint().address(), listenPort)); assert(!!m_peer); assert(!!m_peer->id); if (m_peer->isOffline()) m_peer->lastConnected = chrono::system_clock::now(); -// + // // TODO: P2P introduce map of nodes we've given to this node (if GetPeers/Peers stays in TCP) m_knownNodes.extendAll(m_peer->index); m_knownNodes.unionWith(m_peer->index); @@ -234,7 +224,6 @@ bool Session::interpret(RLP const& _r) return true; } - // TODO: P2P migrate auth to Host and Handshake to constructor m_info.clientVersion = clientVersion; m_info.host = m_socket.remote_endpoint().address().to_string(); m_info.port = listenPort; @@ -347,7 +336,7 @@ bool Session::interpret(RLP const& _r) // OK passed all our checks. Assume it's good. addRating(1000); - // TODO: P2P change to addNode() + // TODO: P2P test m_server->addNode(Node(id, NodeIPEndpoint(bi::udp::endpoint(ep.address(), 30303), ep))); clogS(NetTriviaDetail) << "New peer: " << ep << "(" << id .abridged()<< ")";