net: tweak EventNewConnectionAccepted()

Move `MaybeFlipIPv6toCJDNS()`, which is Bitcoin P2P specific from the
callers of `CConnman::EventNewConnectionAccepted()` to inside that
method.

Move the IsSelectable check, the `TCP_NODELAY` option set and the
generation of new connection id out of
`CConnman::EventNewConnectionAccepted()` because those are protocol
agnostic. Move those to a new method `SockMan::NewSockAccepted()` which
is called instead of `CConnman::EventNewConnectionAccepted()`.
This commit is contained in:
Vasil Dimov 2024-09-24 09:41:47 +02:00
parent 455185b665
commit 52106d0136
No known key found for this signature in database
GPG Key ID: 54DF06F64B55CBBF
4 changed files with 47 additions and 24 deletions

View File

@ -226,6 +226,26 @@ std::unique_ptr<Sock> SockMan::AcceptConnection(const Sock& listen_sock, CServic
return sock;
}
void SockMan::NewSockAccepted(std::unique_ptr<Sock>&& sock, const CService& me, const CService& them)
{
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()};
EventNewConnectionAccepted(id, std::move(sock), me, them);
}
SockMan::Id SockMan::GetNewId()
{
return m_next_id.fetch_add(1, std::memory_order_relaxed);
@ -276,7 +296,10 @@ void SockMan::ThreadI2PAccept()
continue;
}
EventNewConnectionAccepted(std::move(conn.sock), conn.me, conn.peer);
Assume(conn.me.IsI2P());
Assume(conn.peer.IsI2P());
NewSockAccepted(std::move(conn.sock), conn.me, conn.peer);
err_wait = err_wait_begin;
}

View File

@ -137,6 +137,15 @@ public:
*/
std::unique_ptr<Sock> 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>&& sock, const CService& me, const CService& them);
/**
* Generate an id for a newly created connection.
*/
@ -181,11 +190,13 @@ private:
/**
* Be notified when a new connection has been accepted.
* @param[in] id Id of the newly accepted connection.
* @param[in] sock Connected socket to communicate with the peer.
* @param[in] me The address and port at our side of the connection.
* @param[in] them The address and port at the peer's side of the connection.
*/
virtual void EventNewConnectionAccepted(std::unique_ptr<Sock>&& sock,
virtual void EventNewConnectionAccepted(Id id,
std::unique_ptr<Sock>&& sock,
const CService& me,
const CService& them) = 0;

View File

@ -1712,10 +1712,14 @@ bool CConnman::AttemptToEvictConnection()
return false;
}
void CConnman::EventNewConnectionAccepted(std::unique_ptr<Sock>&& sock,
const CService& addr_bind,
const CService& addr)
void CConnman::EventNewConnectionAccepted(SockMan::Id id,
std::unique_ptr<Sock>&& sock,
const CService& me,
const CService& them)
{
const CService addr_bind{MaybeFlipIPv6toCJDNS(me)};
const CService addr{MaybeFlipIPv6toCJDNS(them)};
int nInbound = 0;
NetPermissionFlags permission_flags = NetPermissionFlags::None;
@ -1738,19 +1742,6 @@ void CConnman::EventNewConnectionAccepted(std::unique_ptr<Sock>&& sock,
return;
}
if (!sock->IsSelectable()) {
LogPrintf("connection from %s dropped: non-selectable socket\n", addr.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",
addr.ToStringAddrPort());
}
// Don't accept connections from banned peers.
bool banned = m_banman && m_banman->IsBanned(addr);
if (!NetPermissions::HasFlag(permission_flags, NetPermissionFlags::NoBan) && banned)
@ -1776,7 +1767,6 @@ void CConnman::EventNewConnectionAccepted(std::unique_ptr<Sock>&& sock,
}
}
NodeId id = GetNewId();
uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
const bool inbound_onion = std::find(m_onion_binds.begin(), m_onion_binds.end(), addr_bind) != m_onion_binds.end();
@ -2278,10 +2268,7 @@ void CConnman::SocketHandlerListening(const Sock::EventsPerSock& events_per_sock
auto sock_accepted{AcceptConnection(*sock, addr_accepted)};
if (sock_accepted) {
addr_accepted = MaybeFlipIPv6toCJDNS(addr_accepted);
const CService addr_bind{MaybeFlipIPv6toCJDNS(GetBindAddress(*sock))};
EventNewConnectionAccepted(std::move(sock_accepted), addr_bind, addr_accepted);
NewSockAccepted(std::move(sock_accepted), GetBindAddress(*sock), addr_accepted);
}
}
}

View File

@ -1294,11 +1294,13 @@ private:
/**
* Create a `CNode` object and add it to the `m_nodes` member.
* @param[in] id Id of the newly accepted connection.
* @param[in] sock Connected socket to communicate with the peer.
* @param[in] me The address and port at our side of the connection.
* @param[in] them The address and port at the peer's side of the connection.
*/
virtual void EventNewConnectionAccepted(std::unique_ptr<Sock>&& sock,
virtual void EventNewConnectionAccepted(SockMan::Id id,
std::unique_ptr<Sock>&& sock,
const CService& me,
const CService& them) override;