-
Notifications
You must be signed in to change notification settings - Fork 5
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
Client: Last SSL payload from server not being waited for breaks stuff #8
Comments
I've implemented a workaround, which does the trick for now: def initialize(...)
...
io_rw until @handshake_completed
io_rw(timeout: 0.2) rescue nil
... meaning: read and write to server til handshake complete, and then try to read some more just in case server has sent some, and continue otherwise. For testing purposes, it's an ok workaround, but I'd need something more robust for a client implementation. |
Weird, the callbacks all come out of openssl so the negotiation should definitely have completed. Tested against a wide range of servers and devices however I haven't done much with http2 |
I think that the fact that we are using different I/O stacks might influence the outcome. The problem is what happens "after handshake". I think (if I read about TLS correctly) that there are two additional messages exchanged between client/server, for "cipher change", and this is what's causing the weird behaviour. If I start building TLS packets on the client before the cipher coming from the server changes, I'm sending it invalid packets. It's a question of timing, but also of signalizing to the client/server when is the TLS initialization process really over. Now, if only there was a callback for that... haven't found one yet, living with the workaround for now. |
Maybe my problem here is the meaning of "handshake", and looking at my logs, I think that the handshake is considered "complete":
which seems not to be enough to start building TLS packets (for that, the last packets need to be exchanged). |
As said in the other issue, I've managed to get my tests running with
ruby-tls
. However, from time to time (and quite often if I'm running them all at once) I'm getting errors, which seems to be due to the way the handshake is processed.I've also implemented my client with
ruby-tls
, and I'm sure that the error is there (server with ruby-tls seems to work fine when ussingopenssl
as client). So, my client is only able to send requests after having an enabled ssl connection, which in my case means "handshake has been complete":I get then two different logs, for when it succeeds and when it fails (gonna copy the relevant part only):
so, in both cases, what happens is: after the handshake has been completed, it sends some payload to the server (I assume this is the change cipher message from the spec?). But after, I proceed to start building buffering tls packets without processing the last ssl handshake message coming from the server, which is (probably) invalidating my already build TLS packets, and then boom, shutdown.
I think that the handshake should only be considered complete after those last tls messages, and then my assertion
io_read_write until @handshake_completed
could be considered valid. Either that or I need a different method/variable/callback to tell me if handshake is really over.I've looked at the source code and I didn't find it. Is there a way to signal to usercode when the change-cipher dance is over?
The text was updated successfully, but these errors were encountered: