From a406402a4c9409b9c19421597f81dee8cb0158b6 Mon Sep 17 00:00:00 2001 From: subtly Date: Wed, 11 Feb 2015 01:03:13 -0500 Subject: [PATCH] Fixes for uninit. shared pointers and add const&. --- libp2p/Host.cpp | 29 ++++++++++++-------- libp2p/NodeTable.cpp | 64 ++++++++++++++++++++++++++++---------------- libp2p/NodeTable.h | 8 +++--- 3 files changed, 64 insertions(+), 37 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 25a095ae6..5ffb12c8f 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -185,15 +185,24 @@ void Host::onNodeTableEvent(NodeId const& _n, NodeTableEventType const& _e) auto n = m_nodeTable->node(_n); if (n) { - RecursiveGuard l(x_sessions); - auto p = m_peers[_n]; - if (!p) + shared_ptr p; { - m_peers[_n] = make_shared(); - p = m_peers[_n]; - p->id = _n; + RecursiveGuard l(x_sessions); + if (m_peers.count(_n)) + p = m_peers[_n]; + else + { + // TODO p2p: construct peer from node + p.reset(new Peer()); + p->id = _n; + p->endpoint = NodeIPEndpoint(n.endpoint.udp, n.endpoint.tcp); + p->required = n.required; + m_peers[_n] = p; + + clog(NetNote) << "p2p.host.peers.events.peersAdded " << _n << p->endpoint.tcp.address() << p->endpoint.udp.address(); + } + p->endpoint.tcp = n.endpoint.tcp; } - p->endpoint.tcp = n.endpoint.tcp; // TODO: Implement similar to discover. Attempt connecting to nodes // until ideal peer count is reached; if all nodes are tried, @@ -369,10 +378,8 @@ void Host::doHandshake(bi::tcp::socket* _socket, NodeId _nodeId) p = m_peers[_nodeId]; if (!p) - { - p = make_shared(); - p->endpoint.tcp.address(_socket->remote_endpoint().address()); - } + p.reset(new Peer()); + p->endpoint.tcp.address(_socket->remote_endpoint().address()); auto ps = std::make_shared(this, std::move(*_socket), p); ps->start(); diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 186ece5e2..3ccbca62d 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -70,28 +70,37 @@ shared_ptr NodeTable::addNode(Public const& _pubk, bi::udp::endpoint shared_ptr NodeTable::addNode(Node const& _node) { + // ping address if nodeid is empty + if (!_node.id) + { + PingNode p(_node.endpoint.udp, m_node.endpoint.udp.address().to_string(), m_node.endpoint.udp.port()); + p.sign(m_secret); + m_socketPointer->send(p); + shared_ptr n; + return move(n); + } + Guard l(x_nodes); - shared_ptr ret = m_nodes[_node.id]; - if (ret) + if (m_nodes.count(_node.id)) { - // TODO: p2p robust percolation of node-endpoint changes // // SECURITY: remove this in beta - it's only for lazy connections and presents an easy attack vector. // if (m_server->m_peers.count(id) && isPrivateAddress(m_server->m_peers.at(id)->address.address()) && ep.port() != 0) // // Update address if the node if we now have a public IP for it. // m_server->m_peers[id]->address = ep; + return m_nodes[_node.id]; } - else - { - clog(NodeTableNote) << "p2p.nodes.add " << _node.id.abridged(); - if (m_nodeEventHandler) - m_nodeEventHandler->appendEvent(_node.id, NodeEntryAdded); - - ret.reset(new NodeEntry(m_node, _node.id, NodeIPEndpoint(_node.endpoint.udp, _node.endpoint.tcp))); - m_nodes[_node.id] = ret; - PingNode p(_node.endpoint.udp, m_node.endpoint.udp.address().to_string(), m_node.endpoint.udp.port()); - p.sign(m_secret); - m_socketPointer->send(p); - } + + shared_ptr ret(new NodeEntry(m_node, _node.id, NodeIPEndpoint(_node.endpoint.udp, _node.endpoint.tcp))); + m_nodes[_node.id] = ret; + PingNode p(_node.endpoint.udp, m_node.endpoint.udp.address().to_string(), m_node.endpoint.udp.port()); + p.sign(m_secret); + m_socketPointer->send(p); + + // TODO p2p: rename to p2p.nodes.pending, add p2p.nodes.add event (when pong is received) + clog(NodeTableNote) << "p2p.nodes.add " << _node.id.abridged(); + if (m_nodeEventHandler) + m_nodeEventHandler->appendEvent(_node.id, NodeEntryAdded); + return move(ret); } @@ -119,18 +128,23 @@ list NodeTable::snapshot() const return move(ret); } -Node NodeTable::node(NodeId _id) +Node NodeTable::node(NodeId const& _id) { + // TODO p2p: eloquent copy operator Guard l(x_nodes); - auto n = m_nodes[_id]; - return !!n ? *n : Node(); + if (m_nodes.count(_id)) + { + auto entry = m_nodes[_id]; + Node n(_id, NodeIPEndpoint(entry->endpoint.udp, entry->endpoint.tcp), entry->required); + return move(n); + } + return move(Node()); } shared_ptr NodeTable::nodeEntry(NodeId _id) { Guard l(x_nodes); - auto n = m_nodes[_id]; - return !!n ? move(n) : move(shared_ptr()); + return m_nodes.count(_id) ? move(m_nodes[_id]) : move(shared_ptr()); } void NodeTable::discover(NodeId _node, unsigned _round, shared_ptr>> _tried) @@ -289,7 +303,9 @@ void NodeTable::noteActiveNode(Public const& _pubk, bi::udp::endpoint const& _en if (_pubk == m_node.address()) return; - shared_ptr node(addNode(_pubk, _endpoint)); + clog(NodeTableNote) << "Noting active node:" << _pubk.abridged() << _endpoint.address().to_string() << ":" << _endpoint.port(); + + shared_ptr node(addNode(_pubk, _endpoint, bi::tcp::endpoint(_endpoint.address(), _endpoint.port()))); // TODO p2p: old bug (maybe gone now) sometimes node is nullptr here if (!!node) @@ -471,8 +487,8 @@ void NodeTable::doCheckEvictions(boost::system::error_code const& _ec) Guard le(x_evictions); for (auto& e: m_evictions) if (chrono::steady_clock::now() - e.first.second > c_reqTimeout) - if (auto n = m_nodes[e.second]) - drop.push_back(n); + if (m_nodes.count(e.second)) + drop.push_back(m_nodes[e.second]); evictionsRemain = m_evictions.size() - drop.size() > 0; } @@ -498,6 +514,7 @@ void NodeTable::doRefreshBuckets(boost::system::error_code const& _ec) Guard l(x_state); for (auto& d: m_state) if (chrono::steady_clock::now() - d.modified > c_bucketRefresh) + { while (!d.nodes.empty()) { auto n = d.nodes.front(); @@ -509,6 +526,7 @@ void NodeTable::doRefreshBuckets(boost::system::error_code const& _ec) } d.nodes.pop_front(); } + } } unsigned nextRefresh = connected ? (refreshed ? 200 : c_bucketRefresh.count()*1000) : 10000; diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 72f7800f5..04e8d009c 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -115,6 +115,7 @@ inline std::ostream& operator<<(std::ostream& _out, NodeTable const& _nodeTable) * @todo cache Ping and FindSelf * * [Networking] + * @todo node-endpoint updates * @todo TCP endpoints * @todo eth/upnp/natpmp/stun/ice/etc for public-discovery * @todo firewall @@ -144,7 +145,7 @@ public: void processEvents(); /// Add node. Node will be pinged if it's not already known. - std::shared_ptr addNode(Public const& _pubk, bi::udp::endpoint const& _udp, bi::tcp::endpoint const& _tcp = bi::tcp::endpoint()); + std::shared_ptr addNode(Public const& _pubk, bi::udp::endpoint const& _udp, bi::tcp::endpoint const& _tcp); /// Add node. Node will be pinged if it's not already known. std::shared_ptr addNode(Node const& _node); @@ -162,10 +163,10 @@ public: std::list snapshot() const; /// Returns true if node id is in node table. - bool haveNode(NodeId _id) { Guard l(x_nodes); return m_nodes.count(_id); } + bool haveNode(NodeId const& _id) { Guard l(x_nodes); return m_nodes.count(_id); } /// Returns the Node to the corresponding node id or the empty Node if that id is not found. - Node node(NodeId _id); + Node node(NodeId const& _id); #ifndef BOOST_AUTO_TEST_SUITE private: @@ -197,6 +198,7 @@ protected: unsigned distance; TimePoint modified; std::list> nodes; + void touch() { modified = std::chrono::steady_clock::now(); } }; /// Used to ping endpoint.