mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-29 14:59:39 -04:00
i2p: also sleep after errors in Accept()
Background: `Listen()` does: * if the session is not created yet * create the control socket and on it: * `HELLO` * `SESSION CREATE ID=sessid` * leave the control socked opened * create a new socket and on it: * `HELLO` * `STREAM ACCEPT ID=sessid` * read reply (`STREAM STATUS`) Then a wait starts, for a peer to connect. When connected, `Accept()` does: * on the socket from `STREAM ACCEPT` from `Listen()`: read the Base64 identification of the connecting peer Problem: The I2P router may be in such a state that this happens in a quick succession (many times per second, see https://github.com/bitcoin/bitcoin/issues/22759#issuecomment-1609907115): `Listen()`-succeeds, `Accept()`-fails. `Accept()` fails because the I2P router sends something that is not Base64 on the socket: STREAM STATUS RESULT=I2P_ERROR MESSAGE="Session was closed" We only sleep after failed `Listen()` because the assumption was that if `Accept()` fails then the next `Listen()` will also fail. Solution: Avoid filling the log with "Error accepting:" messages and sleep also after a failed `Accept()`. Extra changes: * Reset the error waiting time after one successful connection. Otherwise the timer will remain high due to problems that have vanished long time ago. * Increment the wait time less aggressively.
This commit is contained in:
parent
78fd3c2672
commit
762404a68c
1 changed files with 11 additions and 6 deletions
17
src/net.cpp
17
src/net.cpp
|
@ -2974,6 +2974,13 @@ void CConnman::ThreadI2PAcceptIncoming()
|
||||||
bool advertising_listen_addr = false;
|
bool advertising_listen_addr = false;
|
||||||
i2p::Connection conn;
|
i2p::Connection conn;
|
||||||
|
|
||||||
|
auto SleepOnFailure = [&]() {
|
||||||
|
interruptNet.sleep_for(err_wait);
|
||||||
|
if (err_wait < err_wait_cap) {
|
||||||
|
err_wait += 1s;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
while (!interruptNet) {
|
while (!interruptNet) {
|
||||||
|
|
||||||
if (!m_i2p_sam_session->Listen(conn)) {
|
if (!m_i2p_sam_session->Listen(conn)) {
|
||||||
|
@ -2981,12 +2988,7 @@ void CConnman::ThreadI2PAcceptIncoming()
|
||||||
RemoveLocal(conn.me);
|
RemoveLocal(conn.me);
|
||||||
advertising_listen_addr = false;
|
advertising_listen_addr = false;
|
||||||
}
|
}
|
||||||
|
SleepOnFailure();
|
||||||
interruptNet.sleep_for(err_wait);
|
|
||||||
if (err_wait < err_wait_cap) {
|
|
||||||
err_wait *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2996,11 +2998,14 @@ void CConnman::ThreadI2PAcceptIncoming()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_i2p_sam_session->Accept(conn)) {
|
if (!m_i2p_sam_session->Accept(conn)) {
|
||||||
|
SleepOnFailure();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateNodeFromAcceptedSocket(std::move(conn.sock), NetPermissionFlags::None,
|
CreateNodeFromAcceptedSocket(std::move(conn.sock), NetPermissionFlags::None,
|
||||||
CAddress{conn.me, NODE_NONE}, CAddress{conn.peer, NODE_NONE});
|
CAddress{conn.me, NODE_NONE}, CAddress{conn.peer, NODE_NONE});
|
||||||
|
|
||||||
|
err_wait = err_wait_begin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue