TCP/TLS connection pooling for Eio

remove unnecessray tls_config wrapper

+3 -6
README.md
···
```ocaml
let run env =
Switch.run (fun sw ->
-
(* Create TLS configuration *)
-
let tls = Conpool.Tls_config.make
-
~authenticator:(Ca_certs.authenticator ())
-
()
-
in
+
(* Create TLS configuration - SNI servername is automatically set to the endpoint's hostname *)
+
let tls_config = Tls.Config.client ~authenticator:(Ca_certs.authenticator ()) () in
(* Create pool with TLS *)
let pool = Conpool.create
~sw
~net:(Eio.Stdenv.net env)
~clock:(Eio.Stdenv.clock env)
-
~tls
+
~tls:tls_config
()
in
+3 -3
lib/connection.ml
···
let flow t = t.flow
let endpoint t = t.endpoint
let created_at t = t.created_at
-
let last_used t = Eio.Mutex.use_ro t.mutex (fun () -> t.last_used)
-
let use_count t = Eio.Mutex.use_ro t.mutex (fun () -> t.use_count)
+
let last_used t = t.last_used
+
let use_count t = t.use_count
let update_usage t ~now =
Eio.Mutex.use_rw ~protect:true t.mutex (fun () ->
···
t.use_count <- t.use_count + 1)
let pp ppf t =
-
let uses = Eio.Mutex.use_ro t.mutex (fun () -> t.use_count) in
+
let uses = t.use_count in
Fmt.pf ppf "Connection(endpoint=%a, created_at=%.2f, uses=%d)" Endpoint.pp
t.endpoint t.created_at uses
+4 -10
lib/conpool.ml
···
(* Re-export submodules *)
module Endpoint = Endpoint
-
module Tls_config = Tls_config
module Config = Config
module Stats = Stats
module Cmd = Cmd
···
net : 'net;
clock : 'clock;
config : Config.t;
-
tls : Tls_config.t option;
+
tls : Tls.Config.client option;
endpoints : (Endpoint.t, endpoint_pool) Hashtbl.t;
endpoints_mutex : Eio.Mutex.t;
}
···
match pool.tls with
| None ->
(socket :> connection)
-
| Some tls_cfg ->
+
| Some tls_config ->
Log.debug (fun m ->
m "Initiating TLS handshake with %a" Endpoint.pp endpoint);
let host =
-
match Tls_config.servername tls_cfg with
-
| Some name -> Domain_name.(host_exn (of_string_exn name))
-
| None ->
-
Domain_name.(host_exn (of_string_exn (Endpoint.host endpoint)))
+
Domain_name.(host_exn (of_string_exn (Endpoint.host endpoint)))
in
-
let tls_flow =
-
Tls_eio.client_of_flow ~host (Tls_config.config tls_cfg) socket
-
in
+
let tls_flow = Tls_eio.client_of_flow ~host tls_config socket in
Log.info (fun m ->
m "TLS connection established to %a" Endpoint.pp endpoint);
(tls_flow :> connection)
+4 -6
lib/conpool.mli
···
Each submodule also exposes its own log source for fine-grained control:
- {!Endpoint.src} - endpoint operations
-
- {!Tls_config.src} - TLS configuration
- {!Config.src} - pool configuration *)
(** {1 Core Types} *)
module Endpoint = Endpoint
(** Network endpoint representation *)
-
-
module Tls_config = Tls_config
-
(** TLS configuration for connection pools *)
module Config = Config
(** Configuration for connection pools *)
···
sw:Eio.Switch.t ->
net:'net Eio.Net.t ->
clock:'clock Eio.Time.clock ->
-
?tls:Tls_config.t ->
+
?tls:Tls.Config.client ->
?config:Config.t ->
unit ->
t
···
@param sw Switch for resource management
@param net Network interface for creating connections
@param clock Clock for timeouts and time-based validation
-
@param tls Optional TLS configuration applied to all connections
+
@param tls
+
Optional TLS client configuration applied to all connections. SNI
+
servername is automatically set to the endpoint's hostname.
@param config
Optional pool configuration (uses Config.default if not provided) *)
-25
lib/tls_config.ml
···
-
(*---------------------------------------------------------------------------
-
Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
-
SPDX-License-Identifier: ISC
-
---------------------------------------------------------------------------*)
-
-
(** TLS configuration for connection pools *)
-
-
let src = Logs.Src.create "conpool.tls" ~doc:"Connection pool TLS configuration"
-
-
module Log = (val Logs.src_log src : Logs.LOG)
-
-
type t = { config : Tls.Config.client; servername : string option }
-
-
let make ~config ?servername () =
-
Log.debug (fun m ->
-
m "Creating TLS config with servername: %s"
-
(match servername with Some s -> s | None -> "<default>"));
-
{ config; servername }
-
-
let config t = t.config
-
let servername t = t.servername
-
-
let pp ppf t =
-
Fmt.pf ppf "TLS(servername=%s)"
-
(match t.servername with Some s -> s | None -> "<default>")
-42
lib/tls_config.mli
···
-
(*---------------------------------------------------------------------------
-
Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
-
SPDX-License-Identifier: ISC
-
---------------------------------------------------------------------------*)
-
-
(** TLS configuration for connection pools *)
-
-
(** {1 Logging} *)
-
-
val src : Logs.Src.t
-
(** Logs source for TLS configuration operations. Configure logging with:
-
{[
-
Logs.Src.set_level Conpool.Tls_config.src (Some Logs.Debug)
-
]} *)
-
-
(** {1 Type} *)
-
-
type t
-
(** TLS configuration applied to all connections in a pool *)
-
-
(** {1 Construction} *)
-
-
val make : config:Tls.Config.client -> ?servername:string -> unit -> t
-
(** Create TLS configuration.
-
-
@param config TLS client configuration for all connections
-
@param servername
-
Optional SNI server name override. If [None], uses the endpoint's hostname
-
*)
-
-
(** {1 Accessors} *)
-
-
val config : t -> Tls.Config.client
-
(** Get the TLS client configuration. *)
-
-
val servername : t -> string option
-
(** Get the SNI server name override, if any. *)
-
-
(** {1 Pretty-printing} *)
-
-
val pp : t Fmt.t
-
(** Pretty-printer for TLS configuration. *)