@@ -149,3 +149,97 @@ let setup_nameservers nameservers =
149149let setup_nameservers ?default () =
150150 let open Term in
151151 const setup_nameservers $ nameservers ?default ()
152+
153+ let error_msgf fmt = Fmt. kstr (fun msg -> Error (`Msg msg)) fmt
154+
155+ let timeout =
156+ let is_digit = function '0' .. '9' -> true | _ -> false in
157+ let parser str =
158+ let len =
159+ let len = ref 0 in
160+ while ! len < String. length str && is_digit str.[! len] do
161+ incr len
162+ done ;
163+ ! len
164+ in
165+ let meter = String. sub str len (String. length str - len) in
166+ let value = String. sub str 0 len in
167+ match meter with
168+ | "ns" -> Ok (Int64. of_string value)
169+ | "us" -> Ok (Duration. of_us (int_of_string value))
170+ | "ms" -> Ok (Duration. of_ms (int_of_string value))
171+ | "sec" | "s" -> Ok (Duration. of_sec (int_of_string value))
172+ | "min" | "m" -> Ok (Duration. of_min (int_of_string value))
173+ | "hour" | "h" -> Ok (Duration. of_hour (int_of_string value))
174+ | _ -> error_msgf " Invalid time: %S" str
175+ in
176+ let parser str =
177+ try parser str with _exn -> error_msgf " Invalid time: %S" str
178+ in
179+ Arg. conv ~docv: " TIME" (parser, Duration. pp)
180+
181+ let s_happy_eyeballs = " HAPPY EYEBALLS"
182+
183+ let aaaa_timeout =
184+ let doc = " The timeout applied to the IPv6 resolution." in
185+ let open Arg in
186+ value
187+ & opt timeout (Duration. of_ms 50 )
188+ & info [ " aaaa-timeout" ] ~doc ~docv: " TIME" ~docs: s_happy_eyeballs
189+
190+ let connect_delay =
191+ let doc =
192+ " Time to repeat another connection attempt if the others don't respond."
193+ in
194+ let open Arg in
195+ value
196+ & opt timeout (Duration. of_ms 50 )
197+ & info [ " connect-delay" ] ~doc ~docv: " TIME" ~docs: s_happy_eyeballs
198+
199+ let connect_timeout =
200+ let doc = " The timeout applied top $(b,connect())." in
201+ let open Arg in
202+ value
203+ & opt timeout (Duration. of_sec 10 )
204+ & info [ " connect-timeout" ] ~doc ~docv: " TIME" ~docs: s_happy_eyeballs
205+
206+ let resolve_timeout =
207+ let doc = " The timeout applied to the domain-name resolution." in
208+ let open Arg in
209+ value
210+ & opt timeout (Duration. of_sec 1 )
211+ & info [ " resolve-timeout" ] ~doc ~docv: " TIME" ~docs: s_happy_eyeballs
212+
213+ let resolve_retries =
214+ let doc = " The number $(i,N) of attempts to make a connection." in
215+ let open Arg in
216+ value
217+ & opt int 3
218+ & info [ " resolve-retries" ] ~doc ~docv: " NUMBER" ~docs: s_happy_eyeballs
219+
220+ type happy_eyeballs = {
221+ aaaa_timeout : int64
222+ ; connect_delay : int64
223+ ; connect_timeout : int64
224+ ; resolve_timeout : int64
225+ ; resolve_retries : int
226+ }
227+
228+ let setup_happy_eyeballs aaaa_timeout connect_delay connect_timeout
229+ resolve_timeout resolve_retries =
230+ {
231+ aaaa_timeout
232+ ; connect_delay
233+ ; connect_timeout
234+ ; resolve_timeout
235+ ; resolve_retries
236+ }
237+
238+ let setup_happy_eyeballs =
239+ let open Term in
240+ const setup_happy_eyeballs
241+ $ aaaa_timeout
242+ $ connect_delay
243+ $ connect_timeout
244+ $ resolve_timeout
245+ $ resolve_retries
0 commit comments