crypto/tls: Set{Read,Write}Deadline implementation is surprising/ineffective #13828
Labels
NeedsInvestigation
Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone
Bear with me, this is a little long-winded, but I'm not sure how I can explain this more succinctly..
The current implementation of these functions is to pass them directly through to c.conn. Judging by my understanding of how TLS works, I think this is wrong. Picture a TLS listener socket which has just accepted a client (which won't ever complete a handshake, say, telnet or something).
Given:
On accept of an incoming connection, an aClient instance is created (with conn populated from the TLS listener) & the server is instructed to time out the client after X seconds of not sending anything (through a goroutine, a Timer, and a channel to cancel the goroutine), something like this:
client.Write's implementation looks something like this:
authTimeout's timer will successfully fire, Write will be called, and set the Write deadline, and attempt to write. However, because the connection hasn't been read/written previously, it needs a handshake. And as handshaking requires reading from the underlying socket, this write deadline won't ever actually trigger.
This, to me, is incorrect/surprising. I'm not entirely sure what the behaviour of deadlines should be before handshake (maybe take whichever is the lowest? Maybe offer an explicit handshake deadline?) but I'm pretty sure there needs to be something done here even if that something is just a warning in the documentation. This bit me when blindly porting some code over from net/tcp to TLS.
It's worth noting, also, that net/http/transport.go tries to work around this very issue, but at least my own attempts to implement a similar pattern (handshake right after accepting, with a goroutine to time out the handshake and Close() on fail) seemed to suffer similar problems with Close() never returning unless I set both a ReadDeadline and WriteDeadline. I didn't (yet) analyze this problem, though.
The text was updated successfully, but these errors were encountered: