Skip to content

Commit 03a6009

Browse files
committed
rework usage of randomness in Dhcp_client
Dhcp_client.create used to call into Stdlibrandom (provided by mirage-random <=1.1.0). Dhcp_client_lwt already depends on Mirage libraries, I added the Mirage_random.C signature, and provide the random xid, if necessary, in Dhcp_client_lwt.
1 parent 01eeef8 commit 03a6009

File tree

10 files changed

+39
-28
lines changed

10 files changed

+39
-28
lines changed

charrua-client.opam

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ depends: [
2121
"jbuilder" {build & >= "1.0+beta9"}
2222
"alcotest" {test}
2323
"cstruct-unix" {test}
24+
"mirage-random-test" {test}
2425
"charrua-core" {>= "0.10"}
2526
"cstruct" {>="3.0.2"}
2627
"ipaddr"

client/dhcp_client.ml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,13 +142,9 @@ let offer t ~xid ~chaddr ~server_ip ~request_ip ~offer_options =
142142
(* make a new DHCP client. allow the user to request a specific xid, any
143143
requests, and the MAC address to use as the source for Ethernet messages and
144144
the chaddr in the fixed-length part of the message *)
145-
let create ?with_xid ?requests srcmac =
145+
let create ?requests xid srcmac =
146146
let open Constants in
147147
let open Dhcp_wire in
148-
let xid = match with_xid with
149-
| None -> Stdlibrandom.initialize (); Cstruct.BE.get_uint32 (Stdlibrandom.generate 4) 0
150-
| Some xid -> xid
151-
in
152148
let requests = match requests with
153149
| None | Some [] -> default_requests
154150
| Some requests -> requests
@@ -212,7 +208,7 @@ let input t buf =
212208
| Some DHCPACK, Renewing _
213209
| Some DHCPACK, Requesting _ -> `New_lease ({t with state = Bound incoming}, incoming)
214210
| Some DHCPNAK, Requesting _ | Some DHCPNAK, Renewing _ ->
215-
`Response (create ~with_xid:(xid t) ~requests:t.request_options t.srcmac)
211+
`Response (create ~requests:t.request_options (xid t) t.srcmac)
216212
| Some DHCPACK, Selecting _ (* too soon *)
217213
| Some DHCPACK, Bound _ -> (* too late *)
218214
`Noop

client/dhcp_client.mli

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ type buffer = Cstruct.t
44

55
val pp : Format.formatter -> t -> unit
66

7-
val create : ?with_xid : Cstruct.uint32 -> ?requests : Dhcp_wire.option_code list -> Macaddr.t -> (t * buffer)
8-
(** [create mac] returns a pair of [t, buffer]. [t] represents the current
7+
val create : ?requests : Dhcp_wire.option_code list -> Cstruct.uint32 -> Macaddr.t -> (t * buffer)
8+
(** [create xid mac] returns a pair of [t, buffer]. [t] represents the current
99
* state of the client in the lease transaction, and [buffer] is the suggested
1010
* next packet the caller should take to progress toward accepting a lease.
11-
* The optional argument [with_xid] allows the caller to specify a transaction ID
11+
* The argument [xid] allows the caller to specify a transaction ID
1212
* to use for the lease attempt.
1313
* [requests] is a list of option codes which the client should ask for in its
1414
* attempt to get a DHCP lease. If [requests] is not given, we'll make an educated

client/lwt/dhcp_client_lwt.ml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
11
let src = Logs.Src.create "dhcp_client_lwt"
22
module Log = (val Logs.src_log src : Logs.LOG)
33

4-
module Make(Time : Mirage_time_lwt.S) (Net : Mirage_net_lwt.S) = struct
4+
module Make(Random : Mirage_random.C)(Time : Mirage_time_lwt.S) (Net : Mirage_net_lwt.S) = struct
55
open Lwt.Infix
66

77
type lease = Dhcp_wire.pkt
88

99
type t = lease Lwt_stream.t
1010

1111
let connect ?(renew = true)
12-
?(with_xid)
12+
?xid
1313
?(requests : Dhcp_wire.option_code list option) net =
1414
(* listener needs to occasionally check to see whether the state has advanced,
1515
* and if not, start a new attempt at a lease transaction *)
1616
let sleep_interval = Duration.of_sec 4 in
1717

18-
let (client, dhcpdiscover) = Dhcp_client.create ?with_xid ?requests (Net.mac net) in
18+
let xid = match xid with
19+
| None -> Cstruct.BE.get_uint32 (Random.generate 4) 0
20+
| Some xid -> xid
21+
in
22+
let (client, dhcpdiscover) = Dhcp_client.create ?requests xid (Net.mac net) in
1923
let c = ref client in
2024

2125
let rec do_renew c t =
@@ -42,7 +46,8 @@ module Make(Time : Mirage_time_lwt.S) (Net : Mirage_net_lwt.S) = struct
4246
match Dhcp_client.lease !c with
4347
| Some lease -> Lwt.return_unit
4448
| None ->
45-
let (client, dhcpdiscover) = Dhcp_client.create ?requests (Net.mac net) in
49+
let xid = Cstruct.BE.get_uint32 (Random.generate 4) 0 in
50+
let (client, dhcpdiscover) = Dhcp_client.create ?requests xid (Net.mac net) in
4651
c := client;
4752
Log.info (fun f -> f "Timeout expired without a usable lease! Starting over...");
4853
Log.debug (fun f -> f "New lease attempt: %a" Dhcp_client.pp !c);

client/lwt/dhcp_client_lwt.mli

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
module Make(Time : Mirage_time_lwt.S) (Net : Mirage_net_lwt.S) : sig
1+
module Make(Random : Mirage_random.C)(Time : Mirage_time_lwt.S) (Net : Mirage_net_lwt.S) : sig
22
type lease = Dhcp_wire.pkt
33

44
type t = lease Lwt_stream.t
55

6-
val connect : ?renew:bool -> ?with_xid : Cstruct.uint32 ->
6+
val connect : ?renew:bool -> ?xid:Cstruct.uint32 ->
77
?requests:Dhcp_wire.option_code list -> Net.t -> t Lwt.t
8-
(** [connect renew with_xid requests net] starts a DHCP client communicating
8+
(** [connect renew ~xid requests net] starts a DHCP client communicating
99
over the network interface [net]. The client will attempt to get a DHCP
1010
lease at least once, and will return any leases obtained in the stream
1111
returned by [connect]. If [renew] is true, which it is by default,

client/mirage/dhcp_client_mirage.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ let config_of_lease lease : Mirage_protocols_lwt.ipv4_config option =
1919
| hd::_ ->
2020
Some Mirage_protocols_lwt.{ address; network; gateway = (Some hd) }
2121

22-
module Make(Time : Mirage_types_lwt.TIME) (Net : Mirage_types_lwt.NETWORK) = struct
22+
module Make(Random : Mirage_random.C)(Time : Mirage_types_lwt.TIME) (Net : Mirage_types_lwt.NETWORK) = struct
2323
open Lwt.Infix
2424
open Mirage_protocols_lwt
2525

2626
type t = ipv4_config Lwt_stream.t
2727

2828
let connect ?(requests : Dhcp_wire.option_code list option) net =
29-
let module Lwt_client = Dhcp_client_lwt.Make(Time)(Net) in
29+
let module Lwt_client = Dhcp_client_lwt.Make(Random)(Time)(Net) in
3030
Lwt_client.connect ~renew:false ?requests net >>= fun lease_stream ->
3131
Lwt.return @@ Lwt_stream.filter_map config_of_lease lease_stream
3232

client/mirage/dhcp_client_mirage.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module Make(Time : Mirage_types_lwt.TIME) (Network : Mirage_types_lwt.NETWORK) : sig
1+
module Make(Random : Mirage_random.C)(Time : Mirage_types_lwt.TIME) (Network : Mirage_types_lwt.NETWORK) : sig
22
type t = Mirage_protocols_lwt.ipv4_config Lwt_stream.t
33
val connect : ?requests:Dhcp_wire.option_code list
44
-> Network.t -> t Lwt.t

test/client/jbuild

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
(executables
44
((names (test_client))
5-
(libraries (cstruct-unix alcotest charrua-client charrua-core.server tcpip.unix))))
5+
(libraries (cstruct-unix alcotest charrua-client charrua-core.server tcpip.unix mirage-random-test))))
66

77
(alias
88
((name runtest)

test/client/lwt/test_client_lwt.ml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@ open Lwt.Infix
22

33
(* additional tests for time- and network-dependent code *)
44

5+
module No_random = struct
6+
type buffer = Cstruct.t
7+
type g
8+
let generate ?g n = Cstruct.create n
9+
end
10+
511
module No_time = struct
612
type 'a io = 'a Lwt.t
713
let sleep_ns n = Format.printf "Ignoring request to wait %f seconds\n" @@ Duration.to_f n;
@@ -39,7 +45,7 @@ end
3945

4046
let keep_trying () =
4147
Lwt_main.run @@ (
42-
let module Client = Dhcp_client_lwt.Make(No_time)(No_net) in
48+
let module Client = Dhcp_client_lwt.Make(No_random)(No_time)(No_net) in
4349
let net = No_net.connect ~mac:(Macaddr.of_string_exn "c0:ff:ee:c0:ff:ee") () in
4450
let test =
4551
Client.connect net >>= Lwt_stream.get >|= function

test/client/test_client.ml

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ module Defaults = struct
2424
end
2525

2626
let random_buffer () =
27-
let sz = Cstruct.BE.get_uint16 (Stdlibrandom.generate 2) 0 in
28-
Stdlibrandom.generate sz
27+
let sz = Cstruct.BE.get_uint16 (Mirage_random_test.generate 2) 0 in
28+
Mirage_random_test.generate sz
2929

3030
let rec no_result t n () =
3131
if n <= 0 then ()
@@ -39,17 +39,19 @@ let rec no_result t n () =
3939
end
4040
;;
4141

42-
let parseable buf =
42+
let parseable buf =
4343
Alcotest.(check bool) "buffer we constructed is valid dhcp" true (Dhcp_wire.is_dhcp buf (Cstruct.len buf))
4444

45+
let random_xid () = Cstruct.BE.get_uint32 (Mirage_random_test.generate 4) 0
46+
4547
let start_makes_dhcp () =
46-
let (_s, buf) = Dhcp_client.create Defaults.client_mac in
48+
let (_s, buf) = Dhcp_client.create (random_xid ()) Defaults.client_mac in
4749
(* for now, any positive result is fine *)
4850
parseable buf
4951

5052
let client_to_selecting () =
5153
let open Defaults in
52-
let (s, buf) = Dhcp_client.create client_mac in
54+
let (s, buf) = Dhcp_client.create (random_xid ()) client_mac in
5355
let answer = Dhcp_wire.pkt_of_buf buf (Cstruct.len buf) in
5456
Alcotest.(check (result pass reject)) "input succeeds" answer answer;
5557
(s, Rresult.R.get_ok answer)
@@ -136,7 +138,7 @@ Alcotest.fail "client wanted to send more packets after receiving DHCPACK"
136138
Alcotest.(check (option pass)) "lease is held" (Some dhcpack) (Dhcp_client.lease s)
137139

138140
let random_init n =
139-
let (s, _) = Dhcp_client.create Defaults.client_mac in
141+
let (s, _) = Dhcp_client.create (random_xid ()) Defaults.client_mac in
140142
"random buffer entry to INIT client", `Quick, (no_result s n)
141143

142144
let random_selecting n =
@@ -166,8 +168,9 @@ let random_bound n =
166168
a new lease"
167169
| `New_lease (s, response) ->
168170
"random buffer entry to BOUND client", `Quick, (no_result s n)
169-
171+
170172
let () =
173+
Mirage_random_test.initialize () ;
171174
let nfuzz = 100 in
172175
Alcotest.run "client tests" [
173176
(* these tests will programmatically put [Dhcp_client.t] into a particular

0 commit comments

Comments
 (0)