net: move CConnman-specific parts away from ThreadI2PAcceptIncoming()

CConnman-specific or in other words, Bitcoin P2P specific. Now
the `ThreadI2PAcceptIncoming()` method is protocol agnostic and
can be moved to `SockMan`.
This commit is contained in:
Vasil Dimov 2024-08-27 16:11:35 +02:00
parent 25203720a1
commit a367d556fd
No known key found for this signature in database
GPG Key ID: 54DF06F64B55CBBF
4 changed files with 62 additions and 9 deletions

View File

@ -125,3 +125,5 @@ void SockMan::StopListening()
{
m_listen.clear();
}
void SockMan::EventI2PStatus(const CService&, I2PStatus) {}

View File

@ -28,6 +28,23 @@ public:
*/
using Id = int64_t;
/**
* Possible status changes that can be passed to `EventI2PStatus()`.
*/
enum class I2PStatus : uint8_t {
/// The listen succeeded and we are now listening for incoming I2P connections.
START_LISTENING,
/// The listen failed and now we are not listening (even if START_LISTENING was signaled before).
STOP_LISTENING,
};
virtual ~SockMan() = default;
//
// Non-virtual functions, to be reused by children classes.
//
/**
* Bind to a new address:port, start listening and add the listen socket to `m_listen`.
* @param[in] to Where to bind.
@ -62,6 +79,23 @@ public:
private:
//
// Pure virtual functions must be implemented by children classes.
//
//
// Non-pure virtual functions can be overridden by children classes or left
// alone to use the default implementation from SockMan.
//
/**
* Be notified of a change in the state of the I2P connectivity.
* The default behavior, implemented by `SockMan`, is to ignore this event.
* @param[in] addr The address we started or stopped listening on.
* @param[in] new_status New status.
*/
virtual void EventI2PStatus(const CService& addr, I2PStatus new_status);
/**
* The id to assign to the next created connection. Used to generate ids of connections.
*/

View File

@ -3054,13 +3054,30 @@ void CConnman::ThreadMessageHandler()
}
}
void CConnman::EventI2PStatus(const CService& addr, SockMan::I2PStatus new_status)
{
switch (new_status) {
case SockMan::I2PStatus::START_LISTENING:
if (!m_i2p_advertising_listen_addr) {
AddLocal(addr, LOCAL_MANUAL);
m_i2p_advertising_listen_addr = true;
}
break;
case SockMan::I2PStatus::STOP_LISTENING:
if (m_i2p_advertising_listen_addr && addr.IsValid()) {
RemoveLocal(addr);
m_i2p_advertising_listen_addr = false;
}
break;
}
}
void CConnman::ThreadI2PAcceptIncoming()
{
static constexpr auto err_wait_begin = 1s;
static constexpr auto err_wait_cap = 5min;
auto err_wait = err_wait_begin;
bool advertising_listen_addr = false;
i2p::Connection conn;
auto SleepOnFailure = [&]() {
@ -3073,18 +3090,12 @@ void CConnman::ThreadI2PAcceptIncoming()
while (!interruptNet) {
if (!m_i2p_sam_session->Listen(conn)) {
if (advertising_listen_addr && conn.me.IsValid()) {
RemoveLocal(conn.me);
advertising_listen_addr = false;
}
EventI2PStatus(conn.me, SockMan::I2PStatus::STOP_LISTENING);
SleepOnFailure();
continue;
}
if (!advertising_listen_addr) {
AddLocal(conn.me, LOCAL_MANUAL);
advertising_listen_addr = true;
}
EventI2PStatus(conn.me, SockMan::I2PStatus::START_LISTENING);
if (!m_i2p_sam_session->Accept(conn)) {
SleepOnFailure();

View File

@ -1286,6 +1286,12 @@ private:
void ProcessAddrFetch() EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex, !m_unused_i2p_sessions_mutex);
void ThreadOpenConnections(std::vector<std::string> connect, Span<const std::string> seed_nodes) EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex, !m_added_nodes_mutex, !m_nodes_mutex, !m_unused_i2p_sessions_mutex, !m_reconnections_mutex);
void ThreadMessageHandler() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc);
/// Whether we are currently advertising our I2P address (via `AddLocal()`).
bool m_i2p_advertising_listen_addr{false};
virtual void EventI2PStatus(const CService& addr, SockMan::I2PStatus new_status) override;
void ThreadI2PAcceptIncoming();
/**