Skip to content
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

remove dependency on cstruct, use string and bytes instead #279

Merged
merged 17 commits into from
Sep 27, 2024
Merged
6 changes: 3 additions & 3 deletions .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ freebsd_instance:
freebsd_client_task:
pkg_install_script: pkg install -y ocaml-opam gmake bash
ocaml_script: opam init -a --comp=4.14.2
mirage_script: eval `opam env` && opam install --confirm-level=unsafe-yes "mirage>=4.5.0"
mirage_script: eval `opam env` && opam install --confirm-level=unsafe-yes "mirage>=4.7.0"
configure_script: eval `opam env` && cd mirage-client && mirage configure -t hvt
depend_script: eval `opam env` && cd mirage-client && gmake depend
copy_script: rm -rf mirage-client/duniverse/miragevpn/* && cp -R dune-project miragevpn.opam src mirage mirage-client/duniverse/miragevpn/
Expand All @@ -15,7 +15,7 @@ freebsd_client_task:
freebsd_router_task:
pkg_install_script: pkg install -y ocaml-opam gmake bash
ocaml_script: opam init -a --comp=4.14.2
mirage_script: eval `opam env` && opam install --confirm-level=unsafe-yes "mirage>=4.5.0"
mirage_script: eval `opam env` && opam install --confirm-level=unsafe-yes "mirage>=4.7.0"
configure_script: eval `opam env` && cd mirage-router && mirage configure -t hvt --enable-monitoring
depend_script: eval `opam env` && cd mirage-router && gmake depend
copy_script: rm -rf mirage-router/duniverse/miragevpn/* && cp -R dune-project miragevpn.opam src mirage mirage-router/duniverse/miragevpn/
Expand All @@ -26,7 +26,7 @@ freebsd_router_task:
freebsd_server_task:
pkg_install_script: pkg install -y ocaml-opam gmake bash
ocaml_script: opam init -a --comp=4.14.2
mirage_script: eval `opam env` && opam install --confirm-level=unsafe-yes "mirage>=4.5.0"
mirage_script: eval `opam env` && opam install --confirm-level=unsafe-yes "mirage>=4.7.0"
configure_script: eval `opam env` && cd mirage-server && mirage configure -t hvt
depend_script: eval `opam env` && cd mirage-server && gmake depend
copy_script: rm -rf mirage-server/duniverse/miragevpn/* && cp -R dune-project miragevpn.opam src mirage mirage-server/duniverse/miragevpn/
Expand Down
40 changes: 22 additions & 18 deletions app/common.ml
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ let safe_close fd =
Lwt.catch (fun () -> Lwt_unix.close fd) (fun _ -> Lwt.return_unit)

let write_to_fd fd data =
let rec w fd data =
if Cstruct.length data = 0 then Lwt_result.return ()
let len = String.length data in
let rec w fd data off =
if len = off then Lwt_result.return ()
else
let* len = Lwt_cstruct.write fd data in
w fd (Cstruct.shift data len)
let* len = Lwt_unix.write_string fd data off (len - off) in
w fd data (len + off)
in
Lwt.catch
(fun () -> w fd data)
(fun () -> w fd data 0)
(fun e ->
let+ () = safe_close fd in
Error (`Msg (Fmt.str "TCP write error %a" Fmt.exn e)))
Expand All @@ -25,36 +26,40 @@ let read_from_fd fd =
let buf = Bytes.create bufsize in
Lwt_unix.read fd buf 0 bufsize >>= fun count ->
if count = 0 then failwith "end of file from server"
else
let cs = Cstruct.of_bytes ~len:count buf in
Logs.debug (fun m -> m "read %d bytes" count);
Lwt.return cs)
else Logs.debug (fun m -> m "read %d bytes" count);
Lwt.return (Bytes.sub_string buf 0 count))
|> Lwt_result.map_error (fun e -> `Msg (Printexc.to_string e))

let transmit proto fd data =
match proto with
| `Tcp -> write_to_fd fd data
| `Udp -> (
let* r = Lwt_result.catch (fun () -> Lwt_cstruct.write fd data) in
let* r =
Lwt_result.catch (fun () ->
Lwt_unix.write_string fd data 0 (String.length data))
in
match r with
| Ok len when Cstruct.length data <> len ->
| Ok len when String.length data <> len ->
Lwt_result.fail (`Msg "wrote short UDP packet")
| Ok _ -> Lwt_result.return ()
| Error exn ->
let+ () = safe_close fd in
Error (`Msg (Fmt.str "UDP write error %a" Fmt.exn exn)))

let receive proto fd =
let buf = Cstruct.create_unsafe 2048 in
let* r = Lwt_result.catch (fun () -> Lwt_cstruct.recvfrom fd buf []) in
let buf = Bytes.create 2048 in
let* r =
Lwt_result.catch (fun () ->
Lwt_unix.recvfrom fd buf 0 (Bytes.length buf) [])
in
match (r, proto) with
| Ok (0, _), `Tcp ->
Logs.debug (fun m -> m "received end of file");
let* () = safe_close fd in
Lwt.return `Connection_failed
| Ok (len, _), _ ->
Logs.debug (fun m -> m "received %d bytes" len);
Lwt.return (`Data (Cstruct.sub buf 0 len))
Lwt.return (`Data (Bytes.sub_string buf 0 len))
| Error exn, _ ->
let* () = safe_close fd in
(* XXX: emit `Connection_failed?! *)
Expand All @@ -65,8 +70,8 @@ let write_udp fd data =
let open Lwt.Infix in
Lwt.catch
(fun () ->
let len = Cstruct.length data in
Lwt_unix.send fd (Cstruct.to_bytes data) 0 len [] >|= fun sent ->
let len = String.length data in
Lwt_unix.send fd (Bytes.unsafe_of_string data) 0 len [] >|= fun sent ->
if sent <> len then
Logs.warn (fun m ->
m "UDP short write (length %d, written %d)" len sent);
Expand All @@ -82,9 +87,8 @@ let read_udp =
fun fd ->
Lwt_result.catch (fun () ->
Lwt_unix.recvfrom fd buf 0 bufsize [] >>= fun (count, _sa) ->
let cs = Cstruct.of_bytes ~len:count buf in
Logs.debug (fun m -> m "read %d bytes" count);
Lwt.return (Some cs))
Lwt.return (Some (Bytes.sub_string buf 0 count)))
|> Lwt_result.map_error (fun e -> `Msg (Printexc.to_string e))

let string_of_file ~dir filename =
Expand Down
7 changes: 2 additions & 5 deletions app/dune
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
(modules common)
(libraries
lwt
cstruct-lwt
lwt.unix
fmt
logs
logs.fmt
Expand All @@ -31,8 +31,7 @@
dns-client-lwt
mirage-crypto-rng-lwt
mtime.clock.os
tuntap
cstruct-lwt))
tuntap))

(executable
(name miragevpn_client_notun)
Expand All @@ -50,7 +49,6 @@
dns-client-lwt
mirage-crypto-rng-lwt
mtime.clock.os
cstruct-lwt
tcpip
tcpip.icmpv4
tcpip.ipv4))
Expand Down Expand Up @@ -91,7 +89,6 @@
dns-client-lwt
mirage-crypto-rng-lwt
mtime.clock.os
cstruct-lwt
tcpip
tcpip.icmpv4
tcpip.ipv4))
6 changes: 3 additions & 3 deletions app/key.ml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ let error_msgf fmt = Fmt.kstr (fun msg -> Error (`Msg msg)) fmt
let catch ~exn fn = try fn () with v -> exn v

let pp_key_hum ppf key =
let cs = Tls_crypt.Key.unsafe_to_cstruct key in
let cipher_key = Cstruct.(to_string (sub cs 0 64)) in
let hmac = Cstruct.(to_string (sub cs 64 64)) in
let cs = Tls_crypt.Key.to_octets key in
let cipher_key = String.sub cs 0 64 in
let hmac = String.sub cs 64 64 in
Fmt.pf ppf "Cipher Key: @[<hov>%a@]\n%!"
(Hxd_string.pp Hxd.default)
cipher_key;
Expand Down
16 changes: 7 additions & 9 deletions app/miragevpn_client_lwt.ml
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ type conn = {
mutable peer :
[ `Udp of Lwt_unix.file_descr | `Tcp of Lwt_unix.file_descr ] option;
mutable est_switch : Lwt_switch.t;
data_mvar : Cstruct.t list Lwt_mvar.t;
data_mvar : string list Lwt_mvar.t;
est_mvar :
(Miragevpn.ip_config * int * Miragevpn.route_info, unit) result Lwt_mvar.t;
event_mvar : Miragevpn.event Lwt_mvar.t;
Expand Down Expand Up @@ -353,27 +353,25 @@ let send_recv conn config ip_config _mtu routes =
(* on FreeBSD, the tun read is prepended with a 4 byte protocol (AF_INET) *)
let pkt =
match Lazy.force platform with
| FreeBSD ->
let pre = Cstruct.create 4 in
Cstruct.set_uint8 pre 3 2;
Cstruct.append pre pkt
| FreeBSD -> "\000\000\000\002" ^ pkt
| Linux -> pkt
in
Lwt_cstruct.write tun_fd pkt >|= ignore)
Lwt_unix.write_string tun_fd pkt 0 (String.length pkt) >|= ignore)
pkts
>>= fun () -> process_incoming ()
in
let rec process_outgoing tun_fd =
let open Lwt_result.Infix in
let buf = Cstruct.create 1500 in
let buf = Bytes.create 1500 in
(* on FreeBSD, the tun read is prepended with a 4 byte protocol (AF_INET) *)
( Lwt_cstruct.read tun_fd buf |> Lwt_result.ok >|= fun len ->
( Lwt_unix.read tun_fd buf 0 (Bytes.length buf) |> Lwt_result.ok
>|= fun len ->
let start, len =
match Lazy.force platform with
| Linux -> (0, len)
| FreeBSD -> (4, len - 4)
in
Cstruct.sub buf start len )
Bytes.sub_string buf start len )
>>= fun buf ->
match Miragevpn.outgoing conn.o_client buf with
| Error `Not_ready -> failwith "tunnel not ready, dropping data"
Expand Down
15 changes: 7 additions & 8 deletions app/miragevpn_client_notun.ml
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,13 @@ let resolve (name, ip_version) =
| Ok ip -> `Resolved (Ipaddr.V6 ip))

type action =
[ Miragevpn.action
| `Suspend
| `Transmit of Cstruct.t
| `Payload of Cstruct.t ]
[ Miragevpn.action | `Suspend | `Transmit of string | `Payload of string ]

let pp_action ppf = function
| #Miragevpn.action as action -> Miragevpn.pp_action ppf action
| `Suspend -> Fmt.pf ppf "suspend"
| `Transmit data -> Fmt.pf ppf "transmit %u bytes" (Cstruct.length data)
| `Payload data -> Fmt.pf ppf "payload %u bytes" (Cstruct.length data)
| `Transmit data -> Fmt.pf ppf "transmit %u bytes" (String.length data)
| `Payload data -> Fmt.pf ppf "payload %u bytes" (String.length data)

let event k (tick : [ `Tick ] Lwt.t) client actions ev =
Logs.debug (fun m -> m "event %a" Miragevpn.pp_event ev);
Expand Down Expand Up @@ -95,9 +92,11 @@ let send_ping ({ ip_config; seq_no; mtu = _; ping = _ } as ifconfig) =
~payload_len:(Cstruct.lenv [ icmpv4_hdr; payload ])
ipv4_hdr
in
(ifconfig, Cstruct.concat [ ipv4_hdr; icmpv4_hdr; payload ])
( ifconfig,
Cstruct.to_string (Cstruct.concat [ ipv4_hdr; icmpv4_hdr; payload ]) )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it would be faster or better to do String.concat "" (List.map Cstruct.to_string [ ... ])
This may very well be premature optimization in unimportant code.


let pong { ip_config; _ } buf =
let buf = Cstruct.of_string buf in
let ( let* ) = Result.bind and ( let+ ) = Fun.flip Result.map in
let* ipv4_hdr, off = Ipv4_packet.Unmarshal.header_of_cstruct buf in
let buf = Cstruct.shift buf off in
Expand Down Expand Up @@ -231,7 +230,7 @@ and connected_action test proto fd incoming tick client actions =
let* ev =
Lwt.choose
[
(tick :> [ `Tick | `Data of Cstruct.t | `Connection_failed ] Lwt.t);
(tick :> [ `Tick | `Data of string | `Connection_failed ] Lwt.t);
incoming;
]
in
Expand Down
14 changes: 8 additions & 6 deletions app/miragevpn_server_notun.ml
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ let write t dst cs =
let _received_ping = ref 0

let handle_payload t dst source_ip data =
match Ipv4_packet.Unmarshal.of_cstruct data with
match Ipv4_packet.Unmarshal.of_cstruct (Cstruct.of_string data) with
| Error e ->
Logs.warn (fun m ->
m "%a received payload (error %s) %a" pp_dst dst e Cstruct.hexdump_pp
data);
m "%a received payload (error %s) %a" pp_dst dst e
(Ohex.pp_hexdump ()) data);
Lwt.return_unit
| Ok (ip, _) when Ipaddr.V4.compare ip.Ipv4_packet.src source_ip <> 0 ->
Logs.warn (fun m ->
Expand Down Expand Up @@ -75,7 +75,7 @@ let handle_payload t dst source_ip data =
Ipv4_packet.Marshal.make_cstruct
~payload_len:(Cstruct.length data) ip'
in
write t ip.src (Cstruct.append hdr data)
write t ip.src (Cstruct.to_string (Cstruct.append hdr data))
in
if t.test && !_received_ping > 2 then (
Logs.app (fun m ->
Expand Down Expand Up @@ -122,7 +122,9 @@ let handle_payload t dst source_ip data =
subheader = Unused;
}
and ip' = { ip with src = fst t.ip; dst = ip.src } in
let payload = Cstruct.sub data 0 (min 28 (Cstruct.length data)) in
let payload =
Cstruct.of_string data ~len:(min 28 (String.length data))
in
let data =
Cstruct.append
(Icmpv4_packet.Marshal.make_cstruct ~payload reply)
Expand All @@ -132,7 +134,7 @@ let handle_payload t dst source_ip data =
Ipv4_packet.Marshal.make_cstruct ~payload_len:(Cstruct.length data)
ip'
in
write t ip.src (Cstruct.append hdr data)
write t ip.src (Cstruct.to_string (Cstruct.append hdr data))
| Ok (ip, _) ->
Logs.warn (fun m -> m "ignoring ipv4 frame %a" Ipv4_packet.pp ip);
Lwt.return_unit
Expand Down
12 changes: 6 additions & 6 deletions bench/bench_engine.ml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ let ts () = Mtime.Span.to_uint64_ns (Mtime_clock.elapsed ())

let tls_auth =
( None,
Cstruct.create 64,
Cstruct.create 64,
Cstruct.create 64,
Cstruct.create 64 )
String.make 64 '\000',
String.make 64 '\000',
String.make 64 '\000',
String.make 64 '\000' )

let key = X509.Private_key.generate ~bits:2048 `RSA

Expand Down Expand Up @@ -174,7 +174,7 @@ let ciphers = [ `AES_256_CBC; `AES_128_GCM; `AES_256_GCM; `CHACHA20_POLY1305 ]
let test_send_data cipher =
let staged =
let established_client, _ = established cipher in
let data = Cstruct.create 1024 in
let data = String.make 1024 '\000' in
Staged.stage @@ fun () ->
match Miragevpn.outgoing established_client data with
| Ok _ -> ()
Expand All @@ -185,7 +185,7 @@ let test_send_data cipher =
let test_receive_data cipher =
let staged =
let established_client, established_server = established cipher in
let data = Cstruct.create 1024 in
let data = String.make 1024 '\000' in
let pkt =
match Miragevpn.outgoing established_server data with
| Ok (_state, pkt) -> pkt
Expand Down
2 changes: 0 additions & 2 deletions bench/dune
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,13 @@
miragevpn
fmt
logs
cstruct
ptime
decompress.lzo
mirage-crypto
tls
x509
duration
angstrom
hex
domain-name
ipaddr
gmap
Expand Down
2 changes: 1 addition & 1 deletion mirage-client/config.ml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(* mirage >= 4.4.0 & < 4.7.0 *)
(* mirage >= 4.7.0 & < 4.8.0 *)

open Mirage

Expand Down
2 changes: 1 addition & 1 deletion mirage-client/unikernel.ml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
open Lwt.Infix

module Main
(R : Mirage_random.S)
(R : Mirage_crypto_rng_mirage.S)
(M : Mirage_clock.MCLOCK)
(P : Mirage_clock.PCLOCK)
(T : Mirage_time.S)
Expand Down
2 changes: 1 addition & 1 deletion mirage-router/config.ml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(* mirage >= 4.6.0 & < 4.7.0 *)
(* mirage >= 4.7.0 & < 4.8.0 *)

open Mirage

Expand Down
Loading
Loading