From 4da7a0f4c63579169efe3b6eb67ff3d36db74556 Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 26 Mar 2015 20:14:35 +0100 Subject: [PATCH] initial requirepeer --- libp2p/Host.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++++ libp2p/Host.h | 10 ++++++++-- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 41c2fbb77..f833efbc5 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -437,6 +437,53 @@ void Host::addNode(NodeId const& _node, std::string const& _addr, unsigned short if (m_nodeTable) m_nodeTable->addNode(Node(_node, NodeIPEndpoint(bi::udp::endpoint(addr, _udpNodePort), bi::tcp::endpoint(addr, _tcpPeerPort)))); } +void Host::requirePeer(NodeId const& _n, std::string const& _addr, unsigned short _port) +{ + auto addr = bi::address::from_string(_addr); + Node node(_n, NodeIPEndpoint(bi::udp::endpoint(addr, _port), bi::tcp::endpoint(addr, _port))); + if (_n) + { + // add or replace peer + shared_ptr p; + 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(node.endpoint.udp, node.endpoint.tcp); + p->required = true; + m_peers[_n] = p; + } + p->endpoint.udp = node.endpoint.udp; + p->endpoint.tcp = node.endpoint.tcp; + } + else if (m_nodeTable) + { + shared_ptr t(new boost::asio::deadline_timer(m_ioService)); + m_timers.push_back(t); + + m_nodeTable->addNode(node); + t->expires_from_now(boost::posix_time::milliseconds(600)); + t->async_wait([this, _n](boost::system::error_code const& _ec) + { + if (!_ec && m_nodeTable) + if (auto n = m_nodeTable->node(_n)) + if (!m_peers.count(_n)) + { + shared_ptr p(new Peer()); + p->id = _n; + p->endpoint = n.endpoint; + p->required = true; + RecursiveGuard l(x_sessions); + m_peers[_n] = p; + } + }); + } +} + void Host::connect(std::shared_ptr const& _p) { if (!m_run) diff --git a/libp2p/Host.h b/libp2p/Host.h index 0feda364f..e27bc8855 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -70,9 +70,7 @@ private: * @brief The Host class * Capabilities should be registered prior to startNetwork, since m_capabilities is not thread-safe. * - * @todo cleanup startPeerSession * @todo determinePublic: ipv6, udp - * @todo handle conflict if addNode/requireNode called and Node already exists w/conflicting tcp or udp port * @todo per-session keepalive/ping instead of broadcast; set ping-timeout via median-latency */ class Host: public Worker @@ -106,7 +104,13 @@ public: /// Add node as a peer candidate. Node is added if discovery ping is successful and table has capacity. void addNode(NodeId const& _node, std::string const& _addr, unsigned short _tcpPort, unsigned short _udpPort); + + /// Create Peer and attempt keeping peer connected. + void requirePeer(NodeId const& _node, std::string const& _addr, unsigned short _port); +// /// Note peer as no longer being required. +// void relinquishPeer(NodeId const& _node); + /// Set ideal number of peers. void setIdealPeerCount(unsigned _n) { m_idealPeerCount = _n; } @@ -211,6 +215,8 @@ private: /// Shared storage of Peer objects. Peers are created or destroyed on demand by the Host. Active sessions maintain a shared_ptr to a Peer; std::map> m_peers; + + std::list> m_timers; /// The nodes to which we are currently connected. Used by host to service peer requests and keepAlivePeers and for shutdown. (see run()) /// Mutable because we flush zombie entries (null-weakptrs) as regular maintenance from a const method.