1
- module E = Eio
2
-
3
- type env = <
4
- clock : E.Time .clock ;
5
- net : E.Net .t ;
6
- fs : E.Dir .t ;
7
- secure_random : E.Flow .source ;
8
- >
1
+ type 'a env = <
2
+ clock : Eio.Time .clock ;
3
+ net : Eio.Net .t ;
4
+ fs : Eio.Fs .dir Eio.Path .t ;
5
+ secure_random : Eio.Flow .source ;
6
+ ..
7
+ > as 'a
9
8
10
9
type io_addr = Ipaddr .t * int
11
- type stack = env * E.Switch .t
10
+ type stack = {
11
+ sw : Eio.Switch .t ;
12
+ clock : Eio.Time .clock ;
13
+ net : Eio.Net .t ;
14
+ resolv_conf : Eio.Fs .dir Eio.Path .t
15
+ }
12
16
13
17
module Transport : Dns_client .S
14
18
with type io_addr = io_addr
@@ -18,7 +22,7 @@ module Transport : Dns_client.S
18
22
type nonrec io_addr = io_addr
19
23
type nonrec stack = stack
20
24
type +'a io = 'a
21
- type context = E .Net.stream_socket
25
+ type context = < Eio .Net.stream_socket ; Eio.Flow .close >
22
26
23
27
type nameservers =
24
28
| Static of io_addr Queue .t
@@ -30,17 +34,15 @@ module Transport : Dns_client.S
30
34
type t = {
31
35
nameservers : nameservers ;
32
36
timeout_ns : int64 ; (* Timeout in nano seconds *)
33
- env : env ;
34
- sw : E.Switch .t ;
35
- mutex : E.Mutex .t ;
37
+ stack : stack ;
38
+ mutex : Eio.Mutex .t ;
36
39
}
37
40
38
- let read_file env file =
39
- match E.Dir . load env#fs file with
41
+ let read_file file =
42
+ match Eio.Path . load file with
40
43
| content -> Ok content
41
- | exception e ->
42
- let err = " Error while reading file: " ^ file ^ " . " ^ (Printexc. to_string e) in
43
- Error (`Msg err)
44
+ | exception e ->
45
+ Fmt. error_msg " Error while reading file %a: %a" Eio.Path. pp file Fmt. exn e
44
46
45
47
(* Prioritises IPv6 nameservers before IPv4 nameservers so that we
46
48
are more conformant with the happy eyballs RFC when implementing it.
@@ -71,7 +73,7 @@ module Transport : Dns_client.S
71
73
|> List. map (fun ip -> ip, 53 )
72
74
|> ipv6_first_queue
73
75
74
- let create ?nameservers ~timeout ( env , sw ) =
76
+ let create ?nameservers ~timeout stack =
75
77
let nameservers =
76
78
match nameservers with
77
79
| Some (proto , ns ) -> begin
@@ -87,7 +89,7 @@ module Transport : Dns_client.S
87
89
let nameservers, digest =
88
90
match
89
91
let ( let * ) = Result. bind in
90
- let * data = read_file env " /etc/resolv.conf " in
92
+ let * data = read_file stack.resolv_conf in
91
93
let * ips = decode_resolv_conf data in
92
94
Ok (ips, Digest. string data)
93
95
with
@@ -96,8 +98,8 @@ module Transport : Dns_client.S
96
98
in
97
99
(Resolv_conf { nameservers; digest })
98
100
in
99
- let mutex = E .Mutex. create () in
100
- { nameservers; timeout_ns = timeout; env; sw; mutex }
101
+ let mutex = Eio .Mutex. create () in
102
+ { nameservers; timeout_ns = timeout; stack; mutex }
101
103
102
104
let nameservers0
103
105
{ nameservers =
@@ -130,7 +132,7 @@ module Transport : Dns_client.S
130
132
resolv_conf.digest < - None ;
131
133
resolv_conf.nameservers < - default_resolvers ()
132
134
in
133
- match read_file t.env " /etc/resolv.conf " , resolv_conf.digest with
135
+ match read_file t.stack.resolv_conf , resolv_conf.digest with
134
136
| Ok data , Some d ->
135
137
let digest = Digest. string data in
136
138
if Digest. equal digest d then () else decode_update data digest
@@ -154,17 +156,17 @@ module Transport : Dns_client.S
154
156
if n > = Queue. length ns_q then
155
157
Error (`Msg " Unable to connect to specified nameservers" )
156
158
else
157
- let (ip, port) = E .Mutex. use_ro t.mutex @@ fun () -> Queue. peek ns_q in
158
- let ip = ipaddr_octects ip |> E .Net.Ipaddr. of_raw in
159
+ let (ip, port) = Eio .Mutex. use_ro t.mutex @@ fun () -> Queue. peek ns_q in
160
+ let ip = ipaddr_octects ip |> Eio .Net.Ipaddr. of_raw in
159
161
let stream = `Tcp (ip, port) in
160
162
try
161
163
let timeout = Duration. to_f t.timeout_ns in
162
- E .Time. with_timeout_exn t.env# clock timeout @@ fun () ->
163
- let flow = E .Net. connect ~sw: t.sw t.env# net stream in
164
+ Eio .Time. with_timeout_exn t.stack. clock timeout @@ fun () ->
165
+ let flow = Eio .Net. connect ~sw: t.stack. sw t.stack. net stream in
164
166
Ok flow
165
- with E .Time.Timeout ->
167
+ with Eio .Time.Timeout ->
166
168
(* Push the non responsive nameserver to the back of the queue. *)
167
- let ns = E .Mutex. use_rw ~protect: true t.mutex @@ fun () -> Queue. pop ns_q in
169
+ let ns = Eio .Mutex. use_rw ~protect: true t.mutex @@ fun () -> Queue. pop ns_q in
168
170
Queue. push ns ns_q;
169
171
try_ns_connection t (n + 1 ) ns_q
170
172
@@ -176,23 +178,37 @@ module Transport : Dns_client.S
176
178
let send_recv ctx dns_query =
177
179
if Cstruct. length dns_query > 4 then
178
180
try
179
- let src = E .Flow. cstruct_source [dns_query] in
180
- E .Flow. copy src ctx;
181
+ let src = Eio .Flow. cstruct_source [dns_query] in
182
+ Eio .Flow. copy src ctx;
181
183
let dns_response = Cstruct. create 2048 in
182
- let got = E .Flow. read ctx dns_response in
184
+ let got = Eio .Flow. read ctx dns_response in
183
185
Ok (Cstruct. sub dns_response 0 got)
184
186
with e -> Error (`Msg (Printexc. to_string e))
185
187
else
186
188
Error (`Msg " Invalid DNS query packet (data length <= 4)" )
187
189
188
- let close flow = try E .Flow. close flow with _ -> ()
190
+ let close flow = Eio .Flow. close flow
189
191
let bind a f = f a
190
192
let lift v = v
191
193
end
192
194
193
- module Client = Dns_client. Make (Transport )
194
195
module type DNS_CLIENT = module type of Dns_client. Make (Transport )
195
196
196
- let run env (f :(module DNS_CLIENT) -> 'a ) =
197
- Mirage_crypto_rng_eio. run (module Mirage_crypto_rng. Fortuna ) env @@ fun () ->
198
- f (module Client )
197
+ module Client = Dns_client. Make (Transport )
198
+
199
+ let run (type a )
200
+ ?(resolv_conf = " /etc/resolv.conf" )
201
+ ?g
202
+ (crypto_generator : a Mirage_crypto_rng.generator )
203
+ env (f : Transport.stack -> (module DNS_CLIENT) -> 'b )
204
+ =
205
+ let module M = (val crypto_generator) in
206
+ Mirage_crypto_rng_eio. run ?g (module M ) env @@ fun () ->
207
+ Eio.Switch. run @@ fun sw ->
208
+ let stack = {
209
+ sw;
210
+ clock = env#clock;
211
+ net = env#net;
212
+ resolv_conf = Eio.Path. (env#fs / resolv_conf) }
213
+ in
214
+ f stack (module Client )
0 commit comments