From 7ef9661fb09d2cd9356cca7476256fea2077bec9 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 23 Sep 2024 11:05:59 +0200 Subject: [PATCH] net: move-only: improve encapsulation of SockMan `SockMan` members `AcceptConnection()` `NewSockAccepted()` `GetNewId()` `m_i2p_sam_session` `m_listen` are now used only by `SockMan`, thus make them private. --- src/common/sockman.cpp | 118 ++++++++++++++++++++--------------------- src/common/sockman.h | 70 ++++++++++++------------ 2 files changed, 94 insertions(+), 94 deletions(-) diff --git a/src/common/sockman.cpp b/src/common/sockman.cpp index 4a87344a0cd..ee5389cf47c 100644 --- a/src/common/sockman.cpp +++ b/src/common/sockman.cpp @@ -222,65 +222,6 @@ SockMan::ConnectAndMakeId(const std::variant& to, return id; } -std::unique_ptr SockMan::AcceptConnection(const Sock& listen_sock, CService& addr) -{ - sockaddr_storage storage; - socklen_t len{sizeof(storage)}; - - auto sock{listen_sock.Accept(reinterpret_cast(&storage), &len)}; - - if (!sock) { - const int err{WSAGetLastError()}; - if (err != WSAEWOULDBLOCK) { - LogPrintLevel(BCLog::NET, - BCLog::Level::Error, - "Cannot accept new connection: %s\n", - NetworkErrorString(err)); - } - return {}; - } - - if (!addr.SetSockAddr(reinterpret_cast(&storage), len)) { - LogPrintLevel(BCLog::NET, BCLog::Level::Warning, "Unknown socket family\n"); - } - - return sock; -} - -void SockMan::NewSockAccepted(std::unique_ptr&& sock, const CService& me, const CService& them) -{ - AssertLockNotHeld(m_connected_mutex); - - if (!sock->IsSelectable()) { - LogPrintf("connection from %s dropped: non-selectable socket\n", them.ToStringAddrPort()); - return; - } - - // According to the internet TCP_NODELAY is not carried into accepted sockets - // on all platforms. Set it again here just to be sure. - const int on{1}; - if (sock->SetSockOpt(IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) == SOCKET_ERROR) { - LogDebug(BCLog::NET, "connection from %s: unable to set TCP_NODELAY, continuing anyway\n", - them.ToStringAddrPort()); - } - - const Id id{GetNewId()}; - - { - LOCK(m_connected_mutex); - m_connected.emplace(id, std::make_shared(std::move(sock))); - } - - if (!EventNewConnectionAccepted(id, me, them)) { - CloseConnection(id); - } -} - -SockMan::Id SockMan::GetNewId() -{ - return m_next_id.fetch_add(1, std::memory_order_relaxed); -} - bool SockMan::CloseConnection(Id id) { LOCK(m_connected_mutex); @@ -417,6 +358,65 @@ void SockMan::ThreadSocketHandler() } } +std::unique_ptr SockMan::AcceptConnection(const Sock& listen_sock, CService& addr) +{ + sockaddr_storage storage; + socklen_t len{sizeof(storage)}; + + auto sock{listen_sock.Accept(reinterpret_cast(&storage), &len)}; + + if (!sock) { + const int err{WSAGetLastError()}; + if (err != WSAEWOULDBLOCK) { + LogPrintLevel(BCLog::NET, + BCLog::Level::Error, + "Cannot accept new connection: %s\n", + NetworkErrorString(err)); + } + return {}; + } + + if (!addr.SetSockAddr(reinterpret_cast(&storage), len)) { + LogPrintLevel(BCLog::NET, BCLog::Level::Warning, "Unknown socket family\n"); + } + + return sock; +} + +void SockMan::NewSockAccepted(std::unique_ptr&& sock, const CService& me, const CService& them) +{ + AssertLockNotHeld(m_connected_mutex); + + if (!sock->IsSelectable()) { + LogPrintf("connection from %s dropped: non-selectable socket\n", them.ToStringAddrPort()); + return; + } + + // According to the internet TCP_NODELAY is not carried into accepted sockets + // on all platforms. Set it again here just to be sure. + const int on{1}; + if (sock->SetSockOpt(IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) == SOCKET_ERROR) { + LogDebug(BCLog::NET, "connection from %s: unable to set TCP_NODELAY, continuing anyway\n", + them.ToStringAddrPort()); + } + + const Id id{GetNewId()}; + + { + LOCK(m_connected_mutex); + m_connected.emplace(id, std::make_shared(std::move(sock))); + } + + if (!EventNewConnectionAccepted(id, me, them)) { + CloseConnection(id); + } +} + +SockMan::Id SockMan::GetNewId() +{ + return m_next_id.fetch_add(1, std::memory_order_relaxed); +} + SockMan::IOReadiness SockMan::GenerateWaitSockets() { AssertLockNotHeld(m_connected_mutex); diff --git a/src/common/sockman.h b/src/common/sockman.h index fcb8d9e1976..7c4a61cb779 100644 --- a/src/common/sockman.h +++ b/src/common/sockman.h @@ -128,29 +128,6 @@ public: CService& me) EXCLUSIVE_LOCKS_REQUIRED(!m_connected_mutex, !m_unused_i2p_sessions_mutex); - /** - * Accept a connection. - * @param[in] listen_sock Socket on which to accept the connection. - * @param[out] addr Address of the peer that was accepted. - * @return Newly created socket for the accepted connection. - */ - std::unique_ptr AcceptConnection(const Sock& listen_sock, CService& addr); - - /** - * After a new socket with a peer has been created, configure its flags, - * make a new connection id and call `EventNewConnectionAccepted()`. - * @param[in] sock The newly created socket. - * @param[in] me Address at our end of the connection. - * @param[in] them Address of the new peer. - */ - void NewSockAccepted(std::unique_ptr&& sock, const CService& me, const CService& them) - EXCLUSIVE_LOCKS_REQUIRED(!m_connected_mutex); - - /** - * Generate an id for a newly created connection. - */ - Id GetNewId(); - /** * Destroy a given connection by closing its socket and release resources occupied by it. * @param[in] id Connection to destroy. @@ -189,18 +166,6 @@ public: */ CThreadInterrupt interruptNet; - /** - * I2P SAM session. - * Used to accept incoming and make outgoing I2P connections from a persistent - * address. - */ - std::unique_ptr m_i2p_sam_session; - - /** - * List of listening sockets. - */ - std::vector> m_listen; - protected: /** @@ -391,6 +356,29 @@ private: void ThreadSocketHandler() EXCLUSIVE_LOCKS_REQUIRED(!m_connected_mutex); + /** + * Accept a connection. + * @param[in] listen_sock Socket on which to accept the connection. + * @param[out] addr Address of the peer that was accepted. + * @return Newly created socket for the accepted connection. + */ + std::unique_ptr AcceptConnection(const Sock& listen_sock, CService& addr); + + /** + * After a new socket with a peer has been created, configure its flags, + * make a new connection id and call `EventNewConnectionAccepted()`. + * @param[in] sock The newly created socket. + * @param[in] me Address at our end of the connection. + * @param[in] them Address of the new peer. + */ + void NewSockAccepted(std::unique_ptr&& sock, const CService& me, const CService& them) + EXCLUSIVE_LOCKS_REQUIRED(!m_connected_mutex); + + /** + * Generate an id for a newly created connection. + */ + Id GetNewId(); + /** * Generate a collection of sockets to check for IO readiness. * @return Sockets to check for readiness plus an aux map to find the @@ -450,6 +438,18 @@ private: */ std::queue> m_unused_i2p_sessions GUARDED_BY(m_unused_i2p_sessions_mutex); + /** + * I2P SAM session. + * Used to accept incoming and make outgoing I2P connections from a persistent + * address. + */ + std::unique_ptr m_i2p_sam_session; + + /** + * List of listening sockets. + */ + std::vector> m_listen; + mutable Mutex m_connected_mutex; /**