-
Notifications
You must be signed in to change notification settings - Fork 67
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
Implement Eio.Resource.Close #489
Conversation
It's up to tls-eio to decide whether closing a TLS flow also closes the underlying flow. For tls-lwt, we have: (** [of_t t] is [ic, oc], the input and output channel. [close]
defaults to [!Unix.close]. *)
val of_t : ?close:(unit -> unit Lwt.t) -> Unix.t -> ic * oc So, tls-lwt closes by default but you can override it. tls-mirage closes in all cases. I find it a bit ugly that this PR uses runtime introspection to find out whether it can close the underlying flow. Since it's probably only useful in rare cases, we could just default to not closing. |
@talex5 Thanks for the input, I'm new to EIO and still learning, as well. I agree the runtime introspection is ugly, and I changed my mind about the PR in the current form. I think that the best solution is to require that the underlying flow implements the Would it not also be best to close by default in consistency with tls-lwt? I can't think of cases where it would be relevant to re-use the underlying flow after the TLS session is complete. Of course, when using switches either way works, but releasing resources as soon as possible is a good thing. |
Sounds good to me! (it would also be possible to use a polymorphic type to remember whether the underlying flow is closable, but I suspect that would be more trouble than it's worth and would certainly break existing code) |
I've updated the PR to require close from the socket. If we want to make it optional, I could add either a boolean parameter or a function like for tls-lwt. |
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.
Looks good to me. CI is failing for an unrelated reason:
File "lwt/examples/resume_echo_server.ml", line 55, characters 35-61:
55 | obfuscation = Randomconv.int32 Mirage_crypto_rng.generate ;
^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: This expression has type int -> HT.key
but an expression was expected of type int -> string
Type HT.key is not compatible with type string
Ooops sorry, I forgot about this PR. If you could rebase to the main branch, and @talex5 approval still stands, I can merge and cut a release for tls-eio. |
No problem, I pushed a branch rebased on main. Let me know if you prefer it squashed too. |
CHANGES: * tls: handle half-closed connection properly: a received CLOSE_NOTIFY does not lead to a CLOSE_NOTIFY to be sent (a `send_close_notify` sends it explicitly) (mirleft/ocaml-tls#488 @hannesm) * tls: modify return type of `handle_tls` - the Alert is now in the right hand side, and `` `Eof `` is explicit in the second part of the tuple (mirleft/ocaml-tls#488 @hannesm) * tls: remove `can_handle_appdata`, the function `handshake_in_progress` is available (mirleft/ocaml-tls#488 @hannesm) * tls-mirage: avoid exceptions in reneg and rekey (mirleft/ocaml-tls#487 @hannesm) * tls: remove HEARTBEAT decoding - HEARTBEAT was never supported in this library, the decoder was superfluous (mirleft/ocaml-tls#487 @hannesm) * tls-mirage: provide `underlying : flow -> FLOW.flow` (mirleft/ocaml-tls#487 @hannesm, fixes mirleft/ocaml-tls#425 @dinosaure) * tls-mirage: implement mirage-flow 4 API (`val shutdown`) (mirleft/ocaml-tls#488 @hannesm) * tls-eio: adapt to half-closed connections (mirleft/ocaml-tls#488 @talex5) * tls-eio: implement Eio.Resource.Close (mirleft/ocaml-tls#489 @paurkedal, reviewed by @talex5)
thanks @paurkedal, merged and I re-did the 0.17.4 release to include this PR. ocaml/opam-repository#25587 |
CHANGES: * tls: handle half-closed connection properly: a received CLOSE_NOTIFY does not lead to a CLOSE_NOTIFY to be sent (a `send_close_notify` sends it explicitly) (mirleft/ocaml-tls#488 @hannesm) * tls: modify return type of `handle_tls` - the Alert is now in the right hand side, and `` `Eof `` is explicit in the second part of the tuple (mirleft/ocaml-tls#488 @hannesm) * tls: remove `can_handle_appdata`, the function `handshake_in_progress` is available (mirleft/ocaml-tls#488 @hannesm) * tls-mirage: avoid exceptions in reneg and rekey (mirleft/ocaml-tls#487 @hannesm) * tls: remove HEARTBEAT decoding - HEARTBEAT was never supported in this library, the decoder was superfluous (mirleft/ocaml-tls#487 @hannesm) * tls-mirage: provide `underlying : flow -> FLOW.flow` (mirleft/ocaml-tls#487 @hannesm, fixes mirleft/ocaml-tls#425 @dinosaure) * tls-mirage: implement mirage-flow 4 API (`val shutdown`) (mirleft/ocaml-tls#488 @hannesm) * tls-eio: adapt to half-closed connections (mirleft/ocaml-tls#488 @talex5) * tls-eio: implement Eio.Resource.Close (mirleft/ocaml-tls#489 @paurkedal, reviewed by @talex5)
After shutting down the TLS flow, I would like to close the underlying TCP socket. This is of course handled by the switch, but since I'm using resource pooling, I would like to do this before leaving the scope of the switch. I could pass around the TCP flow along with the TLS flow, but this breaks the flow-abstraction which is very useful when dealing with TLS.
My proposal here is the the TLS flow implements the close interface but falls back to no-op if the underlying flow does not implement it. We could consider making close a requirement for the underlying flow, since it should be possible to amend a no-op close operation to an existing flow in the (unlikely?) event that a non-TCP flow is used.
(I made a hack around the issue, but I prefer a more proper solution.)