-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
epee net tcp server: properly terminate interrupted TCP connection. fixes #8685 #8731
Conversation
fix commit author (or ask them to PR the fix) |
done. |
@@ -586,8 +586,7 @@ namespace net_utils | |||
else if (ec.value()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given the change below, this else if
can be folded into the else
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Repeating my logic for this patch:
I'm thinking until someone actually writes the code to reuse an "interrupted" connection, it makes sense to simply complete the connection termination sequence (and shut down the TCP connection) after the server shuts the SSL stream down. This way the server isn't leaving a connection around in this interrupted state that can't be "un-interrupted."
Adding some more logic to support this reasoning... once a connection has entered the interrupted state, it will stop reading data received over the socket thanks to this section:
monero/contrib/epee/include/net/abstract_tcp_server2.inl
Lines 412 to 420 in c5d10a4
if (m_state.status == status_t::INTERRUPTED) | |
on_interrupted(); | |
else if (m_state.status == status_t::TERMINATING) | |
on_terminating(); | |
else if (!success) | |
interrupt(); | |
else { | |
start_read(); | |
} |
When the connection is in the interrupted state, it falls into the first if, preventing start_read
from getting called in the else. start_read
is what calls async_read_some
to read the next chunk of data received over the socket. Thus, the interrupted state prevents the server from reading more data received over the socket.
As written, I don't see why the server should keep an interrupted connection around.
What is the purpose of the state? Whoops, funky search before, I see it now. But still, what is the purpose of the state? |
From what I recall in discussions with the author, their intent behind the connection's interrupted status was to allow the server to reuse a connection that hasn't been terminated yet. But the author didn't actually implement the code to reuse an interrupted connection (I don't see a way for a connection's status to go from More behind my thinking on this patch is here: #8685 (comment) |
@j-berman its tempting to slowly remove the interrupted state completely - it seems to complicated for our use cases. |
See issue #8685
Specifically the comment/patch by @j-berman #8685 (comment)
monerod would start using 160-180% CPU after a few days of uptime.
I was consistently running into this issue for multiple months.
With this patch monerod has been running for two weeks already, without high cpu usage.
Related/Same issue #8550