void send (PeerFinder::Slot::ptr const& slot, std::vector <PeerFinder::Endpoint> const& endpoints) { typedef std::vector <PeerFinder::Endpoint> List; protocol::TMEndpoints tm; for (List::const_iterator iter (endpoints.begin()); iter != endpoints.end(); ++iter) { PeerFinder::Endpoint const& ep (*iter); protocol::TMEndpoint& tme (*tm.add_endpoints()); if (ep.address.is_v4()) tme.mutable_ipv4()->set_ipv4( toNetworkByteOrder (ep.address.to_v4().value)); else tme.mutable_ipv4()->set_ipv4(0); tme.mutable_ipv4()->set_ipv4port (ep.address.port()); tme.set_hops (ep.hops); } tm.set_version (1); PackedMessage::pointer msg ( boost::make_shared <PackedMessage> ( tm, protocol::mtENDPOINTS)); { std::lock_guard <decltype(m_mutex)> lock (m_mutex); PeersBySlot::iterator const iter (m_peers.find (slot)); assert (iter != m_peers.end ()); PeerImp::ptr const peer (iter->second.lock()); assert (peer != nullptr); peer->sendPacket (msg, false); } }
/** Close all peer connections. If `graceful` is true then active Requirements: Caller must hold the mutex. */ void close_all (bool graceful) { for (auto const& entry : m_peers) { PeerImp::ptr const peer (entry.second.lock()); assert (peer != nullptr); peer->close (graceful); } }
void activate (PeerFinder::Slot::ptr const& slot) { m_journal.trace << "Activate " << slot->remote_endpoint(); std::lock_guard <decltype(m_mutex)> lock (m_mutex); PeersBySlot::iterator const iter (m_peers.find (slot)); assert (iter != m_peers.end ()); PeerImp::ptr const peer (iter->second.lock()); assert (peer != nullptr); peer->activate (); }
/** Close all peer connections. If `graceful` is true then active Requirements: Caller must hold the mutex. */ void OverlayImpl::close_all (bool graceful) { for (auto const& entry : m_peers) { PeerImp::ptr const peer (entry.second.lock()); // VFALCO The only case where the weak_ptr is expired should be if // ~PeerImp is pre-empted before it calls m_peers.remove() // if (peer != nullptr) peer->close (graceful); } }
void disconnect (PeerFinder::Slot::ptr const& slot, bool graceful) { if (m_journal.trace) m_journal.trace << "Disconnect " << slot->remote_endpoint () << (graceful ? "gracefully" : ""); std::lock_guard <decltype(m_mutex)> lock (m_mutex); PeersBySlot::iterator const iter (m_peers.find (slot)); assert (iter != m_peers.end ()); PeerImp::ptr const peer (iter->second.lock()); assert (peer != nullptr); peer->close (graceful); //peer->detach ("disc", false); }
void OverlayImpl::accept (bool proxyHandshake, socket_type&& socket) { // An error getting an endpoint means the connection closed. // Just do nothing and the socket will be closed by the caller. boost::system::error_code ec; auto const local_endpoint_native (socket.local_endpoint (ec)); if (ec) return; auto const remote_endpoint_native (socket.remote_endpoint (ec)); if (ec) return; auto const local_endpoint ( beast::IPAddressConversion::from_asio (local_endpoint_native)); auto const remote_endpoint ( beast::IPAddressConversion::from_asio (remote_endpoint_native)); PeerFinder::Slot::ptr const slot (m_peerFinder->new_inbound_slot ( local_endpoint, remote_endpoint)); if (slot == nullptr) return; MultiSocket::Flag flags ( MultiSocket::Flag::server_role | MultiSocket::Flag::ssl_required); if (proxyHandshake) flags = flags.with (MultiSocket::Flag::proxy); PeerImp::ptr const peer (boost::make_shared <PeerImp> ( std::move (socket), remote_endpoint, *this, m_resourceManager, *m_peerFinder, slot, m_ssl_context, flags)); { std::lock_guard <decltype(m_mutex)> lock (m_mutex); { std::pair <PeersBySlot::iterator, bool> const result ( m_peers.emplace (slot, peer)); assert (result.second); } ++m_child_count; // This has to happen while holding the lock, // otherwise the socket might not be canceled during a stop. peer->start (); } }
void OverlayImpl::connect (beast::IP::Endpoint const& remote_endpoint) { if (isStopping()) { m_journal.debug << "Skipping " << remote_endpoint << " connect on stop"; return; } PeerFinder::Slot::ptr const slot ( m_peerFinder->new_outbound_slot (remote_endpoint)); if (slot == nullptr) return; MultiSocket::Flag const flags ( MultiSocket::Flag::client_role | MultiSocket::Flag::ssl); PeerImp::ptr const peer (std::make_shared <PeerImp> ( remote_endpoint, m_io_service, *this, m_resourceManager, *m_peerFinder, slot, m_ssl_context, flags)); { std::lock_guard <decltype(m_mutex)> lock (m_mutex); { std::pair <PeersBySlot::iterator, bool> const result ( m_peers.emplace (slot, peer)); assert (result.second); } ++m_child_count; // This has to happen while holding the lock, // otherwise the socket might not be canceled during a stop. peer->start (); } }