From 5d2f57ac0d1f87cc417abfc9c2a85eb1e3c6e3ef Mon Sep 17 00:00:00 2001 From: Hannes Mehnert Date: Thu, 29 Aug 2024 10:36:29 +0200 Subject: [PATCH 1/3] Adapt to tls 1.0.0, mirage-crypto 1.0.0, and asn1-combinators 0.3.0 API changes --- albatross.opam | 18 +++---- client/albatross_client.ml | 83 ++++++++++++++++---------------- daemon/albatross_tls_endpoint.ml | 20 +++++--- src/dune | 4 +- src/vmm_asn.ml | 66 ++++++++++++------------- src/vmm_asn.mli | 12 ++--- src/vmm_commands.ml | 16 +++--- src/vmm_commands.mli | 8 +-- src/vmm_compress.ml | 6 --- src/vmm_compress.mli | 3 -- src/vmm_core.ml | 12 ++--- src/vmm_core.mli | 8 +-- src/vmm_lwt.ml | 18 +++---- src/vmm_unix.ml | 34 ++++++------- src/vmm_unix.mli | 14 +++--- src/vmm_vmmd.ml | 22 ++++----- test/albatross_client_gen.ml | 8 +-- test/test_asn.ml | 2 +- test/tests.ml | 34 ++++++------- tls/vmm_tls_lwt.ml | 34 ++++++++----- 20 files changed, 214 insertions(+), 208 deletions(-) diff --git a/albatross.opam b/albatross.opam index 88da1a38..ea0389cb 100644 --- a/albatross.opam +++ b/albatross.opam @@ -14,18 +14,17 @@ depends: [ "conf-libnl3" {os = "linux"} "lwt" {>= "3.0.0"} "ipaddr" {>= "5.3.0"} - "cstruct" {>= "6.0.0"} "logs" "bos" {>= "0.2.0"} "ptime" "cmdliner" {>= "1.1.0"} "fmt" {>= "0.8.7"} - "x509" {>= "0.13.0"} - "tls" {>= "0.16.0"} - "tls-lwt" {>= "0.16.0"} - "mirage-crypto" - "mirage-crypto-rng" {>= "0.11.0"} - "asn1-combinators" {>= "0.2.0"} + "x509" {>= "1.0.0"} + "tls" {>= "1.0.0"} + "tls-lwt" {>= "1.0.0"} + "mirage-crypto" {>= "1.0.0"} + "mirage-crypto-rng" {>= "1.0.0"} + "asn1-combinators" {>= "0.3.0"} "duration" "decompress" {>= "1.3.0"} "bigstringaf" {>= "0.2.0"} @@ -35,12 +34,13 @@ depends: [ "metrics-influx" {>= "0.2.0"} "metrics-rusage" "ohex" {>= "0.2.0"} - "http-lwt-client" {>= "0.2.0"} + "http-lwt-client" {>= "0.3.0"} "happy-eyeballs-lwt" "solo5-elftool" {>= "0.3"} "owee" {>= "0.4"} "fpath" {>= "0.7.3"} - "logs-syslog" {>= "0.4.0"} + "logs-syslog" {>= "0.4.1"} + "digestif" {>= "1.2.0"} "alcotest" {with-test} ] build: [ diff --git a/client/albatross_client.ml b/client/albatross_client.ml index 226c9bc3..061537aa 100644 --- a/client/albatross_client.ml +++ b/client/albatross_client.ml @@ -17,10 +17,7 @@ type exit_status = let classify_tls_error = function | Tls_lwt.Tls_alert (Tls.Packet.BAD_CERTIFICATE - | Tls.Packet.UNSUPPORTED_CERTIFICATE - | Tls.Packet.CERTIFICATE_REVOKED - | Tls.Packet.CERTIFICATE_EXPIRED - | Tls.Packet.CERTIFICATE_UNKNOWN) as exn -> + | Tls.Packet.CERTIFICATE_EXPIRED) as exn -> Logs.err (fun m -> m "local authentication failure %s" (Printexc.to_string exn)); Local_authentication_failed @@ -53,12 +50,12 @@ let output_result ((hdr, reply) as wire) = | Error (`Msg e) -> Logs.err (fun m -> m "failed to write image: %s" e) in if compressed then - match Vmm_compress.uncompress (Cstruct.to_string data) with + match Vmm_compress.uncompress data with | Ok blob -> write blob | Error `Msg msg -> Logs.err (fun m -> m "failed to uncompress image: %s" msg) else - write (Cstruct.to_string data) + write data in begin match s with | `Unikernel_image (compressed, image) -> @@ -66,7 +63,7 @@ let output_result ((hdr, reply) as wire) = write_to_file name compressed image | `Old_unikernels vms -> List.iter (fun (name, cfg) -> - if Cstruct.length cfg.Vmm_core.Unikernel.image > 0 then + if String.length cfg.Vmm_core.Unikernel.image > 0 then write_to_file name cfg.compressed cfg.image) vms | `Block_device_image (compressed, image) -> @@ -137,7 +134,7 @@ let prepare_update ~happy_eyeballs level host dryrun = function | Ok (_hdr, `Success (`Unikernel_info [ _name, Vmm_core.Unikernel.{ digest ; bridges ; block_devices ; argv ; cpuid ; memory ; fail_behaviour ; typ = `Solo5 as typ ; _ } ])) -> begin - let hash = Ohex.encode (Cstruct.to_string digest) in + let hash = Ohex.encode digest in can_update ~happy_eyeballs host hash >>= function | Error `Msg msg -> Logs.err (fun m -> m "error in HTTP interaction: %s" msg); @@ -156,8 +153,8 @@ let prepare_update ~happy_eyeballs level host dryrun = function Logs.err (fun m -> m "error in HTTP interaction: %s" msg); Lwt.return (Error Http_error) | Ok unikernel -> - let r = Vmm_unix.manifest_devices_match ~bridges ~block_devices - (Cstruct.of_string unikernel) + let r = + Vmm_unix.manifest_devices_match ~bridges ~block_devices unikernel in match r with | Error `Msg msg -> @@ -166,8 +163,8 @@ let prepare_update ~happy_eyeballs level host dryrun = function | Ok () -> let compressed, image = match level with - | 0 -> false, unikernel |> Cstruct.of_string - | _ -> true, Vmm_compress.compress ~level unikernel |> Cstruct.of_string + | 0 -> false, unikernel + | _ -> true, Vmm_compress.compress ~level unikernel in let config = { Vmm_core.Unikernel.typ ; compressed ; image ; fail_behaviour ; cpuid; memory ; block_devices ; bridges ; argv } in Lwt.return (Ok (`Unikernel_force_create config)) @@ -194,12 +191,12 @@ let create_vm force image cpuid memory argv block_devices bridges compression re in let img_file = Fpath.v image in let* image = Bos.OS.File.read img_file in - let* () = Vmm_unix.manifest_devices_match ~bridges ~block_devices (Cstruct.of_string image) in + let* () = Vmm_unix.manifest_devices_match ~bridges ~block_devices image in let image, compressed = match compression with - | 0 -> Cstruct.of_string image, false + | 0 -> image, false | level -> let img = Vmm_compress.compress ~level image in - Cstruct.of_string img, true + img, true and argv = match argv with [] -> None | xs -> Some xs and fail_behaviour = let exits = match exit_codes with [] -> None | xs -> Some (Vmm_core.IS.of_list xs) in @@ -214,10 +211,10 @@ let create_block size compression data = | None -> Ok (`Block_add (size, false, None)) | Some image -> let* size_in_mb = Vmm_unix.bytes_of_mb size in - if size_in_mb >= Cstruct.length image then + if size_in_mb >= String.length image then let compressed, img = if compression > 0 then - true, Vmm_compress.compress_cs compression image + true, Vmm_compress.compress ~level:compression image else false, image in @@ -262,8 +259,8 @@ let connect_local opt_socket name (cmd : Vmm_commands.t) = in match opt_socket with | Some "-" -> - let data = Vmm_asn.wire_to_cstruct wire in - Logs.app (fun m -> m "out: %a" Cstruct.hexdump_pp data); + let data = Vmm_asn.wire_to_str wire in + Logs.app (fun m -> m "out: %a" (Ohex.pp_hexdump ()) data); Lwt.return (Error Communication_failed) | _ -> let sockaddr = Lwt_unix.ADDR_UNIX (Option.value ~default:(Vmm_core.socket_path sock) opt_socket) in @@ -284,7 +281,7 @@ let connect_remote ?(happy_eyeballs = Happy_eyeballs_lwt.create ()) (host, port) | Tls_lwt.Tls_alert x -> Some ("TLS alert: " ^ Tls.Packet.alert_type_to_string x) | Tls_lwt.Tls_failure f -> Some ("TLS failure: " ^ Tls.Engine.string_of_failure f) | _ -> None) ; - let key_eq a b = X509.Public_key.(Cstruct.equal (encode_der a) (encode_der b)) in + let key_eq a b = X509.Public_key.(String.equal (encode_der a) (encode_der b)) in if not (key_eq (X509.Private_key.public key) (X509.Certificate.public_key cert)) then begin Logs.err (fun m -> m "Public key of certificate doesn't match private key"); Lwt.return (Error Cli_failed) @@ -303,12 +300,16 @@ let connect_remote ?(happy_eyeballs = Happy_eyeballs_lwt.create ()) (host, port) Lwt.return (Error Connect_failed) | Ok ((ip, port), fd) -> Logs.debug (fun m -> m "connected to remote host %a:%d" Ipaddr.pp ip port) ; - let client = Tls.Config.client ~certificates ~authenticator () in - Lwt.catch (fun () -> - Tls_lwt.Unix.client_of_fd client (* TODO ~host *) fd >|= fun fd -> - Logs.debug (fun m -> m "finished tls handshake") ; - Ok fd) - (fun exn -> Lwt.return (Error (classify_tls_error exn))) + match Tls.Config.client ~certificates ~authenticator () with + | Error `Msg msg -> + Logs.err (fun m -> m "tls configuration failed: %s" msg); + Lwt.return (Error Cli_failed) + | Ok client -> + Lwt.catch (fun () -> + Tls_lwt.Unix.client_of_fd client (* TODO ~host *) fd >|= fun fd -> + Logs.debug (fun m -> m "finished tls handshake") ; + Ok fd) + (fun exn -> Lwt.return (Error (classify_tls_error exn))) let timestamps validity = let now = Ptime_clock.now () in @@ -365,7 +366,7 @@ let s_exts = (singleton Ext_key_usage (true, [ `Server_auth ])))) let gen_cert (cert, certs, key) key_type name (cmd : Vmm_commands.t) = - let key_eq a b = X509.Public_key.(Cstruct.equal (encode_der a) (encode_der b)) in + let key_eq a b = X509.Public_key.(String.equal (encode_der a) (encode_der b)) in let* () = if key_eq (X509.Private_key.public key) (X509.Certificate.public_key cert) then Ok () @@ -416,11 +417,11 @@ let gen_cert (cert, certs, key) key_type name (cmd : Vmm_commands.t) = let read_cert_key cert key = let* key = let* key_data = Bos.OS.File.read (Fpath.v key) in - X509.Private_key.decode_pem (Cstruct.of_string key_data) + X509.Private_key.decode_pem key_data in let* certs = let* cert_data = Bos.OS.File.read (Fpath.v cert) in - X509.Certificate.decode_pem_multiple (Cstruct.of_string cert_data) + X509.Certificate.decode_pem_multiple cert_data in let cert, chain = match certs with | [] -> assert false @@ -476,7 +477,7 @@ let sign ?dbname ?certname ?cacert extensions issuer key csr delta = match dbname with | None -> Ok () (* no DB! *) | Some dbname -> - append dbname (Printf.sprintf "%s %s\n" (Z.to_string (X509.Certificate.serial cert)) certname) + append dbname (Printf.sprintf "%s %s\n" (Ohex.encode (X509.Certificate.serial cert)) certname) in let chain = let self_signed c = @@ -487,7 +488,7 @@ let sign ?dbname ?certname ?cacert extensions issuer key csr delta = | _ -> [ cert ] in let enc = X509.Certificate.encode_pem_multiple chain in - Bos.OS.File.write Fpath.(v certname + "pem") (Cstruct.to_string enc) + Bos.OS.File.write Fpath.(v certname + "pem") enc let priv_key typ name = let file = Fpath.(v name + "key") in @@ -497,11 +498,11 @@ let priv_key typ name = Logs.info (fun m -> m "creating new %a key %a" X509.Key_type.pp key_type Fpath.pp file); let pem = X509.Private_key.encode_pem priv in - let* () = Bos.OS.File.write ~mode:0o400 file (Cstruct.to_string pem) in + let* () = Bos.OS.File.write ~mode:0o400 file pem in Ok priv end else let* s = Bos.OS.File.read file in - X509.Private_key.decode_pem (Cstruct.of_string s) + X509.Private_key.decode_pem s let albatross_extension csr = let req_exts = @@ -564,11 +565,11 @@ let sign_csr dbname cacert key csr days = let sign_main _ db cacert cakey csrname days = (let* cacert = Bos.OS.File.read (Fpath.v cacert) in - let* cacert = X509.Certificate.decode_pem (Cstruct.of_string cacert) in + let* cacert = X509.Certificate.decode_pem cacert in let* pk = Bos.OS.File.read (Fpath.v cakey) in - let* cakey = X509.Private_key.decode_pem (Cstruct.of_string pk) in + let* cakey = X509.Private_key.decode_pem pk in let* enc = Bos.OS.File.read (Fpath.v csrname) in - let* csr = X509.Signing_request.decode_pem (Cstruct.of_string enc) in + let* csr = X509.Signing_request.decode_pem enc in sign_csr (Fpath.v db) cacert cakey csr days) |> function | Ok () -> Success @@ -646,7 +647,7 @@ let jump cmd name d cert key ca key_type tmpdir = let* priv = priv_key key_type name in let* csr = csr priv name cmd in let enc = X509.Signing_request.encode_pem csr in - Bos.OS.File.write Fpath.(v name + ".req") (Cstruct.to_string enc) + Bos.OS.File.write Fpath.(v name + ".req") enc in match r with | Ok () -> Ok Success @@ -723,7 +724,7 @@ let block_set () compression block_data name dst = let compressed, data = let level = compress_default compression dst in if level > 0 then - true, Vmm_compress.compress_cs level block_data + true, Vmm_compress.compress ~level block_data else false, block_data in @@ -813,7 +814,7 @@ let inspect_dump _ name dbdir = | Error (`Msg msg) -> Logs.err (fun m -> m "error while reading dump file: %s" msg); Cli_failed - | Ok data -> match Vmm_asn.unikernels_of_cstruct data with + | Ok data -> match Vmm_asn.unikernels_of_str data with | Error (`Msg msg) -> Logs.err (fun m -> m "couldn't parse dump file: %s" msg); Cli_failed @@ -979,9 +980,9 @@ let block_size = let data_c = let parse s = - Result.map Cstruct.of_string (Bos.OS.File.read (Fpath.v s)) + Bos.OS.File.read (Fpath.v s) and pp ppf data = - Format.fprintf ppf "file with %d bytes" (Cstruct.length data) + Format.fprintf ppf "file with %u bytes" (String.length data) in Arg.conv (parse, pp) diff --git a/daemon/albatross_tls_endpoint.ml b/daemon/albatross_tls_endpoint.ml index 36b2a947..3e2f8303 100644 --- a/daemon/albatross_tls_endpoint.ml +++ b/daemon/albatross_tls_endpoint.ml @@ -6,14 +6,20 @@ let command = ref 0L let tls_config cacert cert priv_key = X509_lwt.private_of_pems ~cert ~priv_key >>= fun cert -> - X509_lwt.certs_of_pem cacert >>= (function - | [ ca ] -> Lwt.return ca - | _ -> Lwt.fail_with "expect single ca as cacert") >|= fun ca -> + X509_lwt.certs_of_pem cacert >|= fun cas -> + let ca = match cas with + | [ ca ] -> ca + | _ -> failwith "expect single ca as cacert" + in let time () = Some (Ptime_clock.now ()) in - Tls.Config.server - ~version:(`TLS_1_3, `TLS_1_3) - ~authenticator:(X509.Authenticator.chain_of_trust ~time [ca]) - ~certificates:(`Single cert) () + match + Tls.Config.server + ~version:(`TLS_1_3, `TLS_1_3) + ~authenticator:(X509.Authenticator.chain_of_trust ~time [ca]) + ~certificates:(`Single cert) () + with + | Ok cfg -> cfg + | Error `Msg msg -> failwith msg let read version fd tls = (* now we busy read and process output *) diff --git a/src/dune b/src/dune index 67ef4d87..3fc5540e 100644 --- a/src/dune +++ b/src/dune @@ -5,7 +5,7 @@ (backend bisect_ppx)) (wrapped false) (modules vmm_core vmm_commands vmm_compress vmm_trie vmm_trie vmm_ring vmm_asn vmm_resources) - (libraries logs ipaddr ptime duration cstruct bigstringaf + (libraries logs ipaddr ptime duration bigstringaf decompress.de decompress.zl asn1-combinators fpath metrics mirage-crypto ohex)) @@ -14,4 +14,4 @@ (public_name albatross.unix) (wrapped false) (modules vmm_unix vmm_lwt vmm_vmmd) - (libraries albatross ipaddr.unix bos solo5-elftool lwt lwt.unix ptime.clock.os)) + (libraries albatross ipaddr.unix bos solo5-elftool lwt lwt.unix ptime.clock.os digestif)) diff --git a/src/vmm_asn.ml b/src/vmm_asn.ml index f4fb815b..ef782892 100644 --- a/src/vmm_asn.ml +++ b/src/vmm_asn.ml @@ -15,8 +15,8 @@ --use-version command-line flag - so new clients can talk to old servers). It should be ensured that old unikernels dumped to disk (a) can be read by - new albatross daemons. The functions unikernels_to_cstruct and - unikernels_of_cstruct are used for dump and restore, each an explicit choice. + new albatross daemons. The functions unikernels_to_str and + unikernels_of_str are used for dump and restore, each an explicit choice. They use the trie of unikernel_config, dump always uses the latest version in the explicit choice. There's no version field involved. @@ -56,15 +56,15 @@ let version = in Asn.S.map f g Asn.S.int -let decode_seq_len cs = - (* we assume a ASN.1 DER/BER encoded sequence starting in cs: +let decode_seq_len buf = + (* we assume a ASN.1 DER/BER encoded sequence starting in buf: - 0x30 - length (definite length field - not 0x80) - (of length length) *) - let* () = guard (Cstruct.length cs > 2) (`Msg "buffer too short") in - let* () = guard (Cstruct.get_uint8 cs 0 = 0x30) (`Msg "not a sequence") in - let l1 = Cstruct.get_uint8 cs 1 in + let* () = guard (String.length buf > 2) (`Msg "buffer too short") in + let* () = guard (String.get_uint8 buf 0 = 0x30) (`Msg "not a sequence") in + let l1 = String.get_uint8 buf 1 in let* (off, l) = if l1 < 0x80 then Ok (2, l1) @@ -72,27 +72,27 @@ let decode_seq_len cs = Error (`Msg "indefinite length") else let octets = l1 land 0x7F in - let* () = guard (Cstruct.length cs > octets + 2) (`Msg "data too short") in + let* () = guard (String.length buf - 2 > octets) (`Msg "data too short") in let rec go off acc = if off = octets then Ok (2 + octets, acc) else - go (succ off) (Cstruct.get_uint8 cs (off + 2) + acc lsl 8) + go (succ off) (String.get_uint8 buf (off + 2) + acc lsl 8) in go 0 0 in - let* () = guard (Cstruct.length cs >= l + off) (`Msg "buffer too small") in + let* () = guard (String.length buf - off >= l) (`Msg "buffer too small") in Ok (off, l) -let seq_hd cs = - let* (off, l) = decode_seq_len cs in - Ok (Cstruct.sub cs off l) +let seq_hd buf = + let* (off, l) = decode_seq_len buf in + Ok (String.sub buf off l) -let decode_wire_version cs = - let* cs = seq_hd cs in (* from wire, sequence2 (header, payload) *) - let* cs = seq_hd cs in (* from header, sequence3 (version ,__) *) +let decode_wire_version buf = + let* buf = seq_hd buf in (* from wire, sequence2 (header, payload) *) + let* buf = seq_hd buf in (* from header, sequence3 (version ,__) *) let c = Asn.codec Asn.der version in - match Asn.decode c cs with + match Asn.decode c buf with | Ok (a, _) -> Ok a | Error (`Parse msg) -> Error (`Msg msg) @@ -101,10 +101,10 @@ open Vmm_commands let oid = Asn.OID.(base 1 3 <| 6 <| 1 <| 4 <| 1 <| 49836 <| 42) -let decode_strict codec cs = - match Asn.decode codec cs with - | Ok (a, cs) -> - let* () = guard (Cstruct.length cs = 0) (`Msg "trailing bytes") in +let decode_strict codec buf = + match Asn.decode codec buf with + | Ok (a, rest) -> + let* () = guard (String.length rest = 0) (`Msg "trailing bytes") in Ok a | Error (`Parse msg) -> Error (`Msg msg) @@ -164,20 +164,20 @@ let console_cmd = (* TODO is this good? *) let int64 = - let f cs = Cstruct.BE.get_uint64 cs 0 + let f buf = String.get_int64_be buf 0 and g data = - let buf = Cstruct.create 8 in - Cstruct.BE.set_uint64 buf 0 data ; - buf + let buf = Bytes.create 8 in + Bytes.set_int64_be buf 0 data ; + Bytes.unsafe_to_string buf in Asn.S.map f g Asn.S.octet_string let mac_addr = let f cs = - Result.fold (Macaddr.of_octets (Cstruct.to_string cs)) + Result.fold (Macaddr.of_octets cs) ~ok:Fun.id ~error:(function `Msg e -> Asn.S.parse_error "bad mac address: %s" e) - and g mac = Cstruct.of_string (Macaddr.to_octets mac) + and g mac = Macaddr.to_octets mac in Asn.S.map f g Asn.S.octet_string @@ -792,15 +792,15 @@ let wire name = (required ~label:"header" (header name)) (required ~label:"payload" (payload name))) -let wire_of_cstruct, wire_to_cstruct = +let wire_of_str, wire_to_str = let dec, enc = projections_of (wire name) and dec_old, enc_old = projections_of (wire old_name) in - (fun cs -> - let* version = decode_wire_version cs in + (fun buf -> + let* version = decode_wire_version buf in match version with - | `AV3 | `AV4 -> dec_old cs - | `AV5 -> dec cs), + | `AV3 | `AV4 -> dec_old buf + | `AV5 -> dec buf), (fun (header, payload) -> match header.version with | `AV3 | `AV4 -> enc_old (header, payload) @@ -850,7 +850,7 @@ let unikernels = (my_explicit 2 ~label:"unikernel-OLD2" version2_unikernels) (my_explicit 3 ~label:"unikernel" version3_unikernels)) -let unikernels_of_cstruct, unikernels_to_cstruct = +let unikernels_of_str, unikernels_to_str = projections_of unikernels let cert_extension = diff --git a/src/vmm_asn.mli b/src/vmm_asn.mli index d2766730..e6a169ce 100644 --- a/src/vmm_asn.mli +++ b/src/vmm_asn.mli @@ -9,13 +9,13 @@ open Vmm_core (** OID in the Mirage namespace (enterprise arc 1.3.6.1.4.1.49836.42) *) val oid : Asn.OID.t -val wire_to_cstruct : Vmm_commands.wire -> Cstruct.t +val wire_to_str : Vmm_commands.wire -> string -val wire_of_cstruct : Cstruct.t -> (Vmm_commands.wire, [> `Msg of string ]) result +val wire_of_str : string -> (Vmm_commands.wire, [> `Msg of string ]) result val of_cert_extension : - Cstruct.t -> (Vmm_commands.version * Vmm_commands.t, [> `Msg of string ]) result -val to_cert_extension : Vmm_commands.t -> Cstruct.t + string -> (Vmm_commands.version * Vmm_commands.t, [> `Msg of string ]) result +val to_cert_extension : Vmm_commands.t -> string -val unikernels_to_cstruct : Unikernel.config Vmm_trie.t -> Cstruct.t -val unikernels_of_cstruct : Cstruct.t -> (Unikernel.config Vmm_trie.t, [> `Msg of string ]) result +val unikernels_to_str : Unikernel.config Vmm_trie.t -> string +val unikernels_of_str : string -> (Unikernel.config Vmm_trie.t, [> `Msg of string ]) result diff --git a/src/vmm_commands.ml b/src/vmm_commands.ml index 751a3f96..4f7bb399 100644 --- a/src/vmm_commands.ml +++ b/src/vmm_commands.ml @@ -97,9 +97,9 @@ let pp_policy_cmd ppf = function type block_cmd = [ | `Block_info - | `Block_add of int * bool * Cstruct.t option + | `Block_add of int * bool * string option | `Block_remove - | `Block_set of bool * Cstruct.t + | `Block_set of bool * string | `Block_dump of int ] @@ -109,10 +109,10 @@ let pp_block_cmd ppf = function | `Block_add (size, compressed, data) -> Fmt.pf ppf "block add %d (compressed %B data %a)" size compressed - Fmt.(option ~none:(any "no data") int) (Option.map Cstruct.length data) + Fmt.(option ~none:(any "no data") int) (Option.map String.length data) | `Block_set (compressed, data) -> Fmt.pf ppf "block set compressed %B %d bytes" compressed - (Cstruct.length data) + (String.length data) | `Block_dump level -> Fmt.pf ppf "block dump, compress level %d" level type t = [ @@ -158,9 +158,9 @@ type success = [ | `Old_unikernels of (Name.t * Unikernel.config) list | `Unikernel_info of (Name.t * Unikernel.info) list | `Old_unikernel_info of (Name.t * Unikernel.info) list - | `Unikernel_image of bool * Cstruct.t + | `Unikernel_image of bool * string | `Block_devices of (Name.t * int * bool) list - | `Block_device_image of bool * Cstruct.t + | `Block_device_image of bool * string ] let pp_block ppf (id, size, active) = @@ -188,11 +188,11 @@ let pp_success ~verbose ppf = function ppf infos | `Unikernel_image (compressed, image) -> Fmt.pf ppf "image (compression %B) %d bytes" - compressed (Cstruct.length image) + compressed (String.length image) | `Block_devices blocks -> my_fmt_list "no block devices" pp_block ppf blocks | `Block_device_image (compressed, data) -> Fmt.pf ppf "block device compressed %B, %d bytes" - compressed (Cstruct.length data) + compressed (String.length data) type res = [ | `Command of t diff --git a/src/vmm_commands.mli b/src/vmm_commands.mli index 2a555c99..09ff4e39 100644 --- a/src/vmm_commands.mli +++ b/src/vmm_commands.mli @@ -50,9 +50,9 @@ type policy_cmd = [ type block_cmd = [ | `Block_info - | `Block_add of int * bool * Cstruct.t option + | `Block_add of int * bool * string option | `Block_remove - | `Block_set of bool * Cstruct.t + | `Block_set of bool * string | `Block_dump of int ] @@ -89,9 +89,9 @@ type success = [ | `Old_unikernels of (Name.t * Unikernel.config) list | `Old_unikernel_info of (Name.t * Unikernel.info) list | `Unikernel_info of (Name.t * Unikernel.info) list - | `Unikernel_image of bool * Cstruct.t + | `Unikernel_image of bool * string | `Block_devices of (Name.t * int * bool) list - | `Block_device_image of bool * Cstruct.t + | `Block_device_image of bool * string ] type res = [ diff --git a/src/vmm_compress.ml b/src/vmm_compress.ml index 30478cfd..8a925d81 100644 --- a/src/vmm_compress.ml +++ b/src/vmm_compress.ml @@ -37,9 +37,3 @@ let uncompress input = match Zl.Higher.uncompress ~allocate ~refill ~flush i o with | Ok () -> Ok (Buffer.contents b) | Error _ as e -> e - -let compress_cs level data = - Cstruct.to_string data |> compress ~level |> Cstruct.of_string - -let uncompress_cs data = - Result.map Cstruct.of_string (Cstruct.to_string data |> uncompress) diff --git a/src/vmm_compress.mli b/src/vmm_compress.mli index 754e504d..33651eed 100644 --- a/src/vmm_compress.mli +++ b/src/vmm_compress.mli @@ -2,6 +2,3 @@ val compress : ?level:int -> string -> string val uncompress : string -> (string, [> `Msg of string ]) result - -val compress_cs : int -> Cstruct.t -> Cstruct.t -val uncompress_cs : Cstruct.t -> (Cstruct.t, [> `Msg of string ]) result diff --git a/src/vmm_core.ml b/src/vmm_core.ml index 953660be..380a998a 100644 --- a/src/vmm_core.ml +++ b/src/vmm_core.ml @@ -305,7 +305,7 @@ module Unikernel = struct type config = { typ : typ ; compressed : bool ; - image : Cstruct.t ; + image : string ; fail_behaviour : fail_behaviour; cpuid : int ; memory : int ; @@ -347,7 +347,7 @@ module Unikernel = struct Fmt.pf ppf "typ %a@ compression %B image %d bytes@ fail behaviour %a@ cpu %d@ %d MB memory@ block devices %a@ bridge %a" pp_typ vm.typ vm.compressed - (Cstruct.length vm.image) + (String.length vm.image) pp_fail_behaviour vm.fail_behaviour vm.cpuid vm.memory Fmt.(list ~sep:(any ", ") pp_block) vm.block_devices @@ -365,12 +365,12 @@ module Unikernel = struct cmd : string array ; pid : int ; taps : string list ; - digest : Cstruct.t ; + digest : string ; started : Ptime.t ; } let pp ppf vm = - let hex_digest = Ohex.encode (Cstruct.to_string vm.digest) in + let hex_digest = Ohex.encode vm.digest in Fmt.pf ppf "pid %d@ taps %a (block %a) cmdline %a digest %s" vm.pid Fmt.(list ~sep:(any ", ") string) vm.taps @@ -386,7 +386,7 @@ module Unikernel = struct block_devices : (string * string option * int option) list ; bridges : (string * string option * Macaddr.t option) list ; argv : string list option ; - digest : Cstruct.t ; + digest : string ; started : Ptime.t ; } @@ -397,7 +397,7 @@ module Unikernel = struct bridges = cfg.bridges ; argv = cfg.argv ; digest = t.digest ; started = t.started } let pp_info ppf (info : info) = - let hex_digest = Ohex.encode (Cstruct.to_string info.digest) in + let hex_digest = Ohex.encode info.digest in Fmt.pf ppf "typ %a@ started %a@ fail behaviour %a@ cpu %d@ %d MB memory@ block devices %a@ bridge %a@ digest %s" pp_typ info.typ (Ptime.pp_rfc3339 ()) info.started diff --git a/src/vmm_core.mli b/src/vmm_core.mli index 928652b7..ab55ca4b 100644 --- a/src/vmm_core.mli +++ b/src/vmm_core.mli @@ -104,7 +104,7 @@ module Unikernel : sig type config = { typ : typ ; compressed : bool ; - image : Cstruct.t ; + image : string ; fail_behaviour : fail_behaviour; cpuid : int ; memory : int ; @@ -128,7 +128,7 @@ module Unikernel : sig cmd : string array; pid : int; taps : string list; - digest : Cstruct.t; + digest : string; started : Ptime.t; } @@ -142,8 +142,8 @@ module Unikernel : sig block_devices : (string * string option * int option) list ; bridges : (string * string option * Macaddr.t option) list ; argv : string list option ; - digest : Cstruct.t ; - started : Ptime.t; + digest : string ; + started : Ptime.t ; } val info : t -> info diff --git a/src/vmm_lwt.ml b/src/vmm_lwt.ml index b6a1377b..2163aa1a 100644 --- a/src/vmm_lwt.ml +++ b/src/vmm_lwt.ml @@ -128,16 +128,16 @@ let read_wire s = r buf 0 4 >>= function | Error e -> Lwt.return (Error e) | Ok () -> - let len = Cstruct.BE.get_uint32 (Cstruct.of_bytes buf) 0 in + let len = Bytes.get_int32_be buf 0 in if len > 0l then begin let b = Bytes.create (Int32.to_int len) in r b 0 (Int32.to_int len) >|= function | Error e -> Error e | Ok () -> (* Logs.debug (fun m -> m "read hdr %a, body %a" - Cstruct.hexdump_pp (Cstruct.of_bytes buf) - Cstruct.hexdump_pp (Cstruct.of_bytes b)) ; *) - match Vmm_asn.wire_of_cstruct (Cstruct.of_bytes b) with + (Ohex.pp_hexdump ()) (Bytes.unsafe_to_string buf) + (Ohex.pp_hexdump ()) (Bytes.unsafe_to_string b)) ; *) + match Vmm_asn.wire_of_str (Bytes.unsafe_to_string b) with | Error (`Msg msg) -> Logs.err (fun m -> m "error %s while parsing data" msg) ; Error `Exception @@ -164,12 +164,12 @@ let write_raw s buf = safe_close s >|= fun () -> Error `Exception) in - (* Logs.debug (fun m -> m "writing %a" Cstruct.hexdump_pp (Cstruct.of_bytes buf)) ; *) + (* Logs.debug (fun m -> m "writing %a" Ohex.pp_hexdump (Bytes.unsage_to_string buf)) ; *) w 0 (Bytes.length buf) let write_wire s wire = - let data = Vmm_asn.wire_to_cstruct wire in - let dlen = Cstruct.create 4 in - Cstruct.BE.set_uint32 dlen 0 (Int32.of_int (Cstruct.length data)) ; - let buf = Cstruct.(to_bytes (append dlen data)) in + let data = Vmm_asn.wire_to_str wire in + let dlen = Bytes.create 4 in + Bytes.set_int32_be dlen 0 (Int32.of_int (String.length data)) ; + let buf = Bytes.cat dlen (Bytes.unsafe_of_string data) in write_raw s buf diff --git a/src/vmm_unix.ml b/src/vmm_unix.ml index 09ad01e9..6c9d42aa 100644 --- a/src/vmm_unix.ml +++ b/src/vmm_unix.ml @@ -124,12 +124,12 @@ let dump, restore = Bos.OS.U.(error_to_msg @@ rename state_file bak) end else Ok () in - Bos.OS.File.write state_file (Cstruct.to_string data)), + Bos.OS.File.write state_file data), (fun ?name () -> let state_file = state_file ?name () in let* exists = Bos.OS.File.exists state_file in if exists then - Result.map Cstruct.of_string (Bos.OS.File.read state_file) + Bos.OS.File.read state_file else Error `NoFile) let block_sub = "block" @@ -189,17 +189,17 @@ let destroy_tap tap = in Bos.OS.Cmd.run cmd -let owee_buf_of_cstruct cs = - let buf = Bigarray.Array1.create Bigarray.Int8_unsigned Bigarray.c_layout (Cstruct.length cs) in - for i = 0 to Cstruct.length cs - 1 do - buf.{i} <- Cstruct.get_uint8 cs i +let owee_buf_of_str b = + let buf = Bigarray.Array1.create Bigarray.Int8_unsigned Bigarray.c_layout (String.length b) in + for i = 0 to String.length b - 1 do + buf.{i} <- String.get_uint8 b i done; buf type solo5_target = Spt | Hvt let solo5_image_target image = - let* abi = Solo5_elftool.query_abi (owee_buf_of_cstruct image) in + let* abi = Solo5_elftool.query_abi (owee_buf_of_str image) in match abi.target with | Solo5_elftool.Hvt -> Ok (Hvt, Int32.to_int abi.version) | Solo5_elftool.Spt -> Ok (Spt, Int32.to_int abi.version) @@ -253,7 +253,7 @@ let check_solo5_tender target version = version (String.concat "\n" out))) let solo5_image_devices image = - let* mft = Solo5_elftool.query_manifest (owee_buf_of_cstruct image) in + let* mft = Solo5_elftool.query_manifest (owee_buf_of_str image) in Ok (List.fold_left (fun (block_devices, networks) -> function | Solo5_elftool.Dev_block_basic name -> name :: block_devices, networks @@ -305,18 +305,18 @@ let prepare name (vm : Unikernel.config) = match vm.Unikernel.typ with | `Solo5 -> if vm.Unikernel.compressed then - match Vmm_compress.uncompress (Cstruct.to_string vm.Unikernel.image) with - | Ok blob -> Ok (Cstruct.of_string blob) + match Vmm_compress.uncompress vm.Unikernel.image with + | Ok blob -> Ok blob | Error `Msg msg -> Error (`Msg ("failed to uncompress: " ^ msg)) else Ok vm.Unikernel.image in let filename = Name.image_file name in - let digest = Mirage_crypto.Hash.SHA256.digest image in + let digest = Digestif.SHA256.(to_raw_string (digest_string image)) in let* target, version = solo5_image_target image in let* _ = check_solo5_tender target version in let* () = manifest_devices_match ~bridges:vm.Unikernel.bridges ~block_devices:vm.Unikernel.block_devices image in - let* () = Bos.OS.File.write filename (Cstruct.to_string image) in + let* () = Bos.OS.File.write filename image in let* () = bridges_exist vm.Unikernel.bridges in let fifo = Name.fifo_file name in let* () = @@ -389,8 +389,8 @@ let exec name (config : Unikernel.config) bridge_taps blocks digest = let* target, version = let* image = if config.Unikernel.compressed then - match Vmm_compress.uncompress (Cstruct.to_string config.Unikernel.image) with - | Ok blob -> Ok (Cstruct.of_string blob) + match Vmm_compress.uncompress config.Unikernel.image with + | Ok blob -> Ok blob | Error `Msg msg -> Error (`Msg ("failed to uncompress: " ^ msg)) else Ok config.Unikernel.image @@ -444,8 +444,8 @@ let create_block ?data name size = let dir = block_dir () in let* dir_exists = Bos.OS.Path.exists dir in let* _ = (if dir_exists then Ok true else Bos.OS.Dir.create ~mode:0o700 dir) in - let data = Option.value ~default:Cstruct.empty data in - let* () = Bos.OS.File.write ~mode:0o600 block_name (Cstruct.to_string data) in + let data = Option.value ~default:"" data in + let* () = Bos.OS.File.write ~mode:0o600 block_name data in let* size' = bytes_of_mb size in Bos.OS.File.truncate block_name size' @@ -458,7 +458,7 @@ let dump_block name = if not block_exists then Error (`Msg "file does not exist") else - Result.map Cstruct.of_string (Bos.OS.File.read block_name) + Bos.OS.File.read block_name let mb_of_bytes size = if size = 0 || size land 0xFFFFF <> 0 then diff --git a/src/vmm_unix.mli b/src/vmm_unix.mli index da45bcce..b3cb5956 100644 --- a/src/vmm_unix.mli +++ b/src/vmm_unix.mli @@ -13,10 +13,10 @@ val set_dbdir : Fpath.t -> unit val check_commands : unit -> (unit, [> `Msg of string ]) result val prepare : Name.t -> Unikernel.config -> - ((string * string * Macaddr.t option) list * Cstruct.t, [> `Msg of string ]) result + ((string * string * Macaddr.t option) list * string, [> `Msg of string ]) result val exec : Name.t -> Unikernel.config -> (string * string * Macaddr.t option) list -> - (string * Name.t * int option) list -> Cstruct.t -> (Unikernel.t, [> `Msg of string ]) result + (string * Name.t * int option) list -> string -> (Unikernel.t, [> `Msg of string ]) result val free_system_resources : Name.t -> string list -> (unit, [> `Msg of string ]) result @@ -26,20 +26,20 @@ val bytes_of_mb : int -> (int, [> `Msg of string ]) result val close_no_err : Unix.file_descr -> unit -val create_block : ?data:Cstruct.t -> Name.t -> int -> (unit, [> `Msg of string ]) result +val create_block : ?data:string -> Name.t -> int -> (unit, [> `Msg of string ]) result val destroy_block : Name.t -> (unit, [> `Msg of string ]) result -val dump_block : Name.t -> (Cstruct.t, [> `Msg of string ]) result +val dump_block : Name.t -> (string, [> `Msg of string ]) result val find_block_devices : unit -> ((Name.t * int) list, [> `Msg of string ]) result -val dump : ?name:string -> Cstruct.t -> (unit, [> `Msg of string ]) result +val dump : ?name:string -> string -> (unit, [> `Msg of string ]) result -val restore : ?name:string -> unit -> (Cstruct.t, [> `Msg of string | `NoFile ]) result +val restore : ?name:string -> unit -> (string, [> `Msg of string | `NoFile ]) result val vm_device : Unikernel.t -> (string, [> `Msg of string ]) result val manifest_devices_match : bridges:(string * string option * Macaddr.t option) list -> - block_devices:(string * string option * int option) list -> Cstruct.t -> + block_devices:(string * string option * int option) list -> string -> (unit, [> `Msg of string]) result diff --git a/src/vmm_vmmd.ml b/src/vmm_vmmd.ml index cd744421..71eb1a57 100644 --- a/src/vmm_vmmd.ml +++ b/src/vmm_vmmd.ml @@ -44,7 +44,7 @@ let dump_unikernels t = fst @@ Vmm_trie.insert name unik.Unikernel.config t) Vmm_trie.empty unikernels in - let data = Vmm_asn.unikernels_to_cstruct trie in + let data = Vmm_asn.unikernels_to_str trie in match Vmm_unix.dump data with | Error (`Msg msg) -> Logs.err (fun m -> m "failed to dump unikernels: %s" msg) | Ok () -> Logs.info (fun m -> m "dumped current state") @@ -141,7 +141,7 @@ let restore_unikernels () = Ok Vmm_trie.empty | Error (`Msg msg) -> Error (`Msg ("while reading state: " ^ msg)) | Ok data -> - match Vmm_asn.unikernels_of_cstruct data with + match Vmm_asn.unikernels_of_str data with | Error (`Msg msg) -> Error (`Msg ("couldn't parse state: " ^ msg)) | Ok unikernels -> Logs.info (fun m -> m "restored %d unikernels" (List.length (Vmm_trie.all unikernels))) ; @@ -260,7 +260,7 @@ let handle_policy_cmd t id = let handle_unikernel_cmd t id = function | `Old_unikernel_info1 -> Logs.debug (fun m -> m "old info1 %a" Name.pp id) ; - let empty_image vm = { vm.Unikernel.config with image = Cstruct.empty } in + let empty_image vm = { vm.Unikernel.config with image = "" } in let vms = match Name.name id with | None -> @@ -314,13 +314,13 @@ let handle_unikernel_cmd t id = function if compress_level > 0 then Ok (true, img) else - let* blob = Vmm_compress.uncompress_cs img in + let* blob = Vmm_compress.uncompress img in Ok (false, blob) else if compress_level = 0 then Ok (false, img) else - Ok (true, Vmm_compress.compress_cs compress_level img) + Ok (true, Vmm_compress.compress ~level:compress_level img) in let r = `Unikernel_image (compress, img) in Ok (t, `End (`Success r)) @@ -382,7 +382,7 @@ let handle_block_cmd t id = function Logs.debug (fun m -> m "insert block %a: %dMB (data: %a)" Name.pp id size Fmt.(option ~none:(any "none provided") int) - (Option.map Cstruct.length data)); + (Option.map String.length data)); match Vmm_resources.find_block t.resources id with | Some _ -> Error (`Msg "block device with same name already exists") | None -> @@ -393,12 +393,12 @@ let handle_block_cmd t id = function | Some img -> let* img = if compressed then - Vmm_compress.uncompress_cs img + Vmm_compress.uncompress img else Ok img in let* size_in_bytes = Vmm_unix.bytes_of_mb size in - if size_in_bytes >= Cstruct.length img then + if size_in_bytes >= String.length img then Ok (Some img) else Error (`Msg "data exceeds block size") @@ -414,13 +414,13 @@ let handle_block_cmd t id = function | Some (size, false) -> let* data = if compressed then - Vmm_compress.uncompress_cs data + Vmm_compress.uncompress data else Ok data in let* size_in_bytes = Vmm_unix.bytes_of_mb size in let* () = - if size_in_bytes >= Cstruct.length data then + if size_in_bytes >= String.length data then Ok () else Error (`Msg "data exceeds block size") @@ -439,7 +439,7 @@ let handle_block_cmd t id = function if level = 0 then false, data else - true, Vmm_compress.compress_cs level data + true, Vmm_compress.compress ~level data in Ok (t, `End (`Success (`Block_device_image (compress, data)))) end diff --git a/test/albatross_client_gen.ml b/test/albatross_client_gen.ml index 3cc8465e..122b846c 100644 --- a/test/albatross_client_gen.ml +++ b/test/albatross_client_gen.ml @@ -2,7 +2,7 @@ let u1 = Vmm_core.Unikernel.{ - typ = `Solo5 ; compressed = false ; image = Cstruct.empty ; + typ = `Solo5 ; compressed = false ; image = ""; fail_behaviour = `Quit ; cpuid = 0 ; memory = 1 ; block_devices = [ "block", None, None ; "secondblock", Some "second-data", None ] ; bridges = [ "service", None, None ; "other-net", Some "second-bridge", None ] ; @@ -11,7 +11,7 @@ let u1 = let u2 = Vmm_core.Unikernel.{ - typ = `Solo5 ; compressed = false ; image = Cstruct.empty ; + typ = `Solo5 ; compressed = false ; image = ""; fail_behaviour = `Quit ; cpuid = 2 ; memory = 10 ; block_devices = [] ; bridges = [ "service", Some "bridge-interface", Some (Macaddr.of_string_exn "00:de:ad:be:ef:00") ] ; @@ -29,8 +29,8 @@ let unikernels = ins "bar:my.nice.unikernel" u2 t let jump () = - let data = Vmm_asn.unikernels_to_cstruct unikernels in - print_endline (Base64.encode_string (Cstruct.to_string data)); + let data = Vmm_asn.unikernels_to_str unikernels in + print_endline (Base64.encode_string data); Ok () open Cmdliner diff --git a/test/test_asn.ml b/test/test_asn.ml index cb6d548e..b587a48d 100644 --- a/test/test_asn.ml +++ b/test/test_asn.ml @@ -5,5 +5,5 @@ let () = Vmm_commands.header Vmm_core.Name.root, `Failure "test" in - let cs = Vmm_asn.wire_to_cstruct wire in + let cs = Vmm_asn.wire_to_str wire in ignore cs diff --git a/test/tests.ml b/test/tests.ml index 7b6175d2..d17fb69a 100644 --- a/test/tests.ml +++ b/test/tests.ml @@ -255,7 +255,7 @@ let unikernel_config_eq = in fun (a : config) (b : config) -> a.typ = b.typ && a.compressed = b.compressed && - Cstruct.equal a.image b.image && + String.equal a.image b.image && (match a.fail_behaviour, b.fail_behaviour with | `Quit, `Quit | `Restart None, `Restart None -> true @@ -268,7 +268,7 @@ let unikernel_config_eq = let unikernel_eq (a : Unikernel.t) (b : Unikernel.t) = unikernel_config_eq a.Unikernel.config b.Unikernel.config && - Cstruct.equal a.digest b.digest + String.equal a.digest b.digest let block_eq (s, a) (s', a') = s = s' && a = a' @@ -285,7 +285,7 @@ let test_resources = let u = Unikernel.{ - typ = `Solo5 ; compressed = false ; image = Cstruct.empty ; + typ = `Solo5 ; compressed = false ; image = "" ; fail_behaviour = `Quit ; cpuid = 0 ; memory = 10 ; block_devices = [] ; bridges = [ "service", None, None ] ; @@ -465,7 +465,7 @@ let resource_add_remove_vm () = cmd = Array.make 0 ""; pid = 0 ; taps = [] ; - digest = Cstruct.empty ; + digest = "" ; started = Ptime.epoch ; } in @@ -497,7 +497,7 @@ let resource_vm_with_block () = let uc3 = { uc2 with block_devices = [ "block", Some "b", None ] } in Alcotest.check ok_msg __LOC__ (Error (`Msg "block device not found")) Vmm_resources.(check_vm r1 (n_o_s "alpha:bar") uc3); - let u = Unikernel.{ config = uc2; cmd = Array.make 0 "" ; pid = 0 ; taps = [] ; digest = Cstruct.empty ; started = Ptime.epoch ; } in + let u = Unikernel.{ config = uc2; cmd = Array.make 0 "" ; pid = 0 ; taps = [] ; digest = "" ; started = Ptime.epoch ; } in let r3 = Vmm_resources.insert_vm r2 (n_o_s "alpha:bar") u in Alcotest.check ok_msg __LOC__ (Error (`Msg "block device already in use")) Vmm_resources.(check_vm r3 (n_o_s "alpha:bar2") uc2); @@ -538,12 +538,12 @@ let test_header = let console_subscribe_v4 () = (* output of "albatross-client-local console foo --socket -" *) let data = - Cstruct.of_hex {| + Ohex.decode {| 30 21 30 14 02 01 04 04 08 00 00 00 00 00 00 00 00 30 05 0c 03 66 6f 6f a0 09 a0 07 a1 05 a1 03 02 01 14|} in - match Vmm_asn.wire_of_cstruct data with + match Vmm_asn.wire_of_str data with | Error `Msg m -> Alcotest.failf "expected ok, got error %s" m | Ok ((hdr, cmd) as w) -> Alcotest.check test_header "header is equal" @@ -557,12 +557,12 @@ let console_subscribe_v4 () = let console_subscribe_v4_2 () = (* output of "albatross-client-local console foo.bar --socket -" *) let data = - Cstruct.of_hex {| + Ohex.decode {| 30 26 30 19 02 01 04 04 08 00 00 00 00 00 00 00 00 30 0a 0c 03 66 6f 6f 0c 03 62 61 72 a0 09 a0 07 a1 05 a1 03 02 01 14|} in - match Vmm_asn.wire_of_cstruct data with + match Vmm_asn.wire_of_str data with | Error `Msg m -> Alcotest.failf "expected ok, got error %s" m | Ok ((hdr, cmd) as w) -> Alcotest.check test_header "header is equal" @@ -576,12 +576,12 @@ let console_subscribe_v4_2 () = let console_subscribe_v5 () = (* output of "albatross-client-local console foo --socket -" *) let data = - Cstruct.of_hex {| + Ohex.decode {| 30 20 30 13 02 01 05 04 08 00 00 00 00 00 00 00 00 0c 04 3a 66 6f 6f a0 09 a0 07 a1 05 a1 03 02 01 14|} in - match Vmm_asn.wire_of_cstruct data with + match Vmm_asn.wire_of_str data with | Error `Msg m -> Alcotest.failf "expected ok, got error %s" m | Ok ((hdr, cmd) as w) -> Alcotest.check test_header "header is equal" @@ -595,12 +595,12 @@ let console_subscribe_v5 () = let console_subscribe_v5_2 () = (* output of "albatross-client-local console foo.bar --socket -" *) let data = - Cstruct.of_hex {| + Ohex.decode {| 30 24 30 17 02 01 05 04 08 00 00 00 00 00 00 00 00 0c 08 3a 66 6f 6f 2e 62 61 72 a0 09 a0 07 a1 05 a1 03 02 01 14|} in - match Vmm_asn.wire_of_cstruct data with + match Vmm_asn.wire_of_str data with | Error `Msg m -> Alcotest.failf "expected ok, got error %s" m | Ok ((hdr, cmd) as w) -> Alcotest.check test_header "header is equal" @@ -612,7 +612,7 @@ let console_subscribe_v5_2 () = (Vmm_commands.pp_wire ~verbose:true) w let to_cert s = - Result.get_ok (X509.Certificate.decode_pem (Cstruct.of_string s)) + Result.get_ok (X509.Certificate.decode_pem s) let bistro_console_subscribe_v4 () = (* albatross-client-bistro console foo --destination="-:1025" *) @@ -840,11 +840,11 @@ let test_unikernels = let dec_b64_unik data = let data = Base64.decode_exn data in - Result.get_ok (Vmm_asn.unikernels_of_cstruct (Cstruct.of_string data)) + Result.get_ok (Vmm_asn.unikernels_of_str data) let u1_3 = Unikernel.{ - typ = `Solo5 ; compressed = false ; image = Cstruct.empty ; + typ = `Solo5 ; compressed = false ; image = "" ; fail_behaviour = `Quit ; cpuid = 0 ; memory = 1 ; block_devices = [ "block", None, None ; "secondblock", Some "second-data", None ] ; bridges = [ "service", None, None ; "other-net", Some "second-bridge", None ] ; @@ -853,7 +853,7 @@ let u1_3 = let u2_3 = Unikernel.{ - typ = `Solo5 ; compressed = false ; image = Cstruct.empty ; + typ = `Solo5 ; compressed = false ; image = "" ; fail_behaviour = `Quit ; cpuid = 2 ; memory = 10 ; block_devices = [] ; bridges = [ "service", Some "bridge-interface", None ] ; diff --git a/tls/vmm_tls_lwt.ml b/tls/vmm_tls_lwt.ml index 163454ad..e092a3ab 100644 --- a/tls/vmm_tls_lwt.ml +++ b/tls/vmm_tls_lwt.ml @@ -8,30 +8,38 @@ let read_tls t = if l = 0 then Lwt.return (Ok ()) else - Tls_lwt.Unix.read t (Cstruct.shift buf off) >>= function + let buf' = + if off = 0 then buf else Bytes.create l + in + (* TODO Tls_lwt.Unix.read should receive an (optional) "off" parameter. *) + Tls_lwt.Unix.read t buf' >>= function | 0 -> Logs.debug (fun m -> m "TLS: end of file") ; Lwt.return (Error `Eof) - | x when x == l -> Lwt.return (Ok ()) - | x when x < l -> r_n buf (off + x) tot + | x when x == l -> + if off = 0 then () else Bytes.blit buf' 0 buf off x; + Lwt.return (Ok ()) + | x when x < l -> + if off = 0 then () else Bytes.blit buf' 0 buf off x; + r_n buf (off + x) tot | _ -> Logs.err (fun m -> m "TLS: read too much, shouldn't happen") ; Lwt.return (Error `Toomuch) in - let buf = Cstruct.create 4 in + let buf = Bytes.create 4 in r_n buf 0 4 >>= function | Error e -> Lwt.return (Error e) | Ok () -> - let len = Cstruct.BE.get_uint32 buf 0 in + let len = Bytes.get_int32_be buf 0 in if len > 0l then - let b = Cstruct.create (Int32.to_int len) in + let b = Bytes.create (Int32.to_int len) in r_n b 0 (Int32.to_int len) >|= function | Error e -> Error e | Ok () -> (* Logs.debug (fun m -> m "TLS read id %d %a tag %d data %a" hdr.Vmm_wire.id Vmm_wire.pp_version hdr.Vmm_wire.version hdr.Vmm_wire.tag - Cstruct.hexdump_pp b) ; *) - match Vmm_asn.wire_of_cstruct b with + (Ohex.pp_hexdump ()) b) ; *) + match Vmm_asn.wire_of_str (Bytes.unsafe_to_string b) with | Error (`Msg msg) -> Logs.err (fun m -> m "error %s while parsing data" msg) ; Error `Exception @@ -45,11 +53,11 @@ let read_tls t = Lwt.return (Error `Eof) let write_tls s wire = - let data = Vmm_asn.wire_to_cstruct wire in - let dlen = Cstruct.create 4 in - Cstruct.BE.set_uint32 dlen 0 (Int32.of_int (Cstruct.length data)) ; - let buf = Cstruct.(append dlen data) in - (* Logs.debug (fun m -> m "TLS write %a" Cstruct.hexdump_pp (Cstruct.of_string buf)) ; *) + let data = Vmm_asn.wire_to_str wire in + let dlen = Bytes.create 4 in + Bytes.set_int32_be dlen 0 (Int32.of_int (String.length data)) ; + let buf = Bytes.unsafe_to_string dlen ^ data in + (* Logs.debug (fun m -> m "TLS write %a" (Ohex.pp_hexdump ()) buf) ; *) Lwt.catch (fun () -> Tls_lwt.Unix.write s buf >|= fun () -> Ok ()) (function From 3a65b53db19f79c5a963cb3ff9b9d75069ef0751 Mon Sep 17 00:00:00 2001 From: Hannes Mehnert Date: Thu, 29 Aug 2024 11:20:32 +0200 Subject: [PATCH 2/3] lower bound on ocaml 4.13 --- albatross.opam | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/albatross.opam b/albatross.opam index ea0389cb..6aca17fb 100644 --- a/albatross.opam +++ b/albatross.opam @@ -7,7 +7,7 @@ bug-reports: "https://github.com/robur-coop/albatross/issues" license: "ISC" depends: [ - "ocaml" {>= "4.12.0"} + "ocaml" {>= "4.13.0"} "dune" {>= "2.7.0"} "dune-configurator" "conf-pkg-config" {build} From 8605131a24ebd49e81f2c6b41e80fb74f53a33c3 Mon Sep 17 00:00:00 2001 From: Hannes Mehnert Date: Thu, 29 Aug 2024 11:30:08 +0200 Subject: [PATCH 3/3] CI: drop 4.12 --- .cirrus.yml | 2 +- .github/workflows/build.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 18769658..b1490b88 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -13,7 +13,7 @@ regular_task_template: ®ULAR_TASK_TEMPLATE task: << : *PKG_INSTALL_TASK_TEMPLATE - ocaml_script: opam init -a --comp=4.12.1 + ocaml_script: opam init -a --comp=4.13.1 << : *REGULAR_TASK_TEMPLATE name: FreeBSD 13.3 freebsd_instance: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4da59274..c31539f1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -9,7 +9,7 @@ jobs: strategy: fail-fast: false matrix: - ocaml-version: ["4.14.0", "4.13.1", "4.12.1"] + ocaml-version: ["4.14.2", "4.13.1"] operating-system: [macos-latest, ubuntu-latest] runs-on: ${{ matrix.operating-system }}