Skip to content

Commit 762404a

Browse files
committed
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 bitcoin/bitcoin#22759 (comment)): `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.
1 parent 78fd3c2 commit 762404a

File tree

1 file changed

+11
-6
lines changed

1 file changed

+11
-6
lines changed

src/net.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2974,19 +2974,21 @@ void CConnman::ThreadI2PAcceptIncoming()
29742974
bool advertising_listen_addr = false;
29752975
i2p::Connection conn;
29762976

2977+
auto SleepOnFailure = [&]() {
2978+
interruptNet.sleep_for(err_wait);
2979+
if (err_wait < err_wait_cap) {
2980+
err_wait += 1s;
2981+
}
2982+
};
2983+
29772984
while (!interruptNet) {
29782985

29792986
if (!m_i2p_sam_session->Listen(conn)) {
29802987
if (advertising_listen_addr && conn.me.IsValid()) {
29812988
RemoveLocal(conn.me);
29822989
advertising_listen_addr = false;
29832990
}
2984-
2985-
interruptNet.sleep_for(err_wait);
2986-
if (err_wait < err_wait_cap) {
2987-
err_wait *= 2;
2988-
}
2989-
2991+
SleepOnFailure();
29902992
continue;
29912993
}
29922994

@@ -2996,11 +2998,14 @@ void CConnman::ThreadI2PAcceptIncoming()
29962998
}
29972999

29983000
if (!m_i2p_sam_session->Accept(conn)) {
3001+
SleepOnFailure();
29993002
continue;
30003003
}
30013004

30023005
CreateNodeFromAcceptedSocket(std::move(conn.sock), NetPermissionFlags::None,
30033006
CAddress{conn.me, NODE_NONE}, CAddress{conn.peer, NODE_NONE});
3007+
3008+
err_wait = err_wait_begin;
30043009
}
30053010
}
30063011

0 commit comments

Comments
 (0)