-
Notifications
You must be signed in to change notification settings - Fork 82
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
CloseConnection considered harmful #641
base: devel
Are you sure you want to change the base?
Conversation
214fbe4
to
e4d3ff9
Compare
Hi @ghjm |
c.pc.cancel() | ||
// Close closes the connection. | ||
func (c *Conn) Close() error { | ||
if !c.fromListener { |
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.
Can you explain why this packet conn only can be cancelled this way please?
I am struggling to understand when fromListener
will be set to false
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.
If I remember right, fromListener is set based on whether a Conn object was created by the user opening it, or was created by a listener receiving a connection. If the Conn is standalone, then when we close it, we need to close the underlying PacketConn. But if the Conn came from a listener, the PacketConn is shared, and should only be closed when the listener is closed.
pkg/backends/websockets.go
Outdated
Handler: mux, | ||
Addr: b.address, | ||
Handler: mux, | ||
ReadHeaderTimeout: 10 * time.Second, |
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.
any other reason for this timeout other than tests?
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.
Yes, this is a mitigation for the Slowloris attack.
I can take a look at rebasing it later today, but I don't have time to fix non-trivial issues with it if it doesn't apply cleanly, or fails unit testing or what have you. I vaguely remember there being some problem why this didn't get merged, but I don't remember what. |
Sounds great @ghjm Let me know, happy to take over this PR if its more suitable as I think it adds a lot of value! |
@AaronH88 if you've got time to work on this then maybe you'd better take it over. I'd love to mess with it but I'm just not finding the time. |
No problem at all! |
caf8de5
to
0b473b5
Compare
SonarCloud Quality Gate failed. 0 Bugs No Coverage information Catch issues before they fail your Quality Gate with our IDE extension SonarLint |
What's wrong with this code? (Other than the lack of error checking.)
Answer: It doesn't close the connection. A PacketConn and QUIC connection, with the associated dozen-or-so goroutines, are still running, and will remain running for the life of your program.
Somehow (and I'm well aware that this is code that I probably wrote), in Receptor-land it turns out that
Close()
has the meaning we would normally associate withCloseWrite()
- it shuts down the write side of the connection and indicates an EOF to the other side, but leaves the connection open and ready to continue receiving data from the other side. If you want to actually close the Receptor connection, you have to callCloseConnection()
, which has the effect we would normally associate withClose()
.If you don't know about this and just call
Close()
, expecting Receptor to behave like any other networking library, you'll wind up leaking goroutines and memory like crazy. And given thatCloseConnection()
only appears in the Receptor code in a few places in Workceptor, I'm imagining that long-running Receptor instances probably do leak goroutines and memory like crazy.This PR renames the functions to the sensible names, and updates Workceptor to call the right functions. If other parts of the code are relying on
Close()
not really closing the connection, then this will break them, but arguably they were already broken since they were leaking connections. Also, this is a breaking change for API users, so should be in a new minor release.