Licklider Transmission Protocol (CCSDS 734.1-B) for reliable DTN links
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add Eio wrappers for transport, SDLS, CFDP, and LTP

- transport-eio: CLTU/ASM over Eio flows, COP-1 service layer
- sdls-eio: file-backed keystore, SA store, OTAR, security log,
KEK management, encrypted KV store, SDLS server
- cfdp: Eio filesystem-backed filestore for segmented transfers
- ltp-eio: length-prefixed segment send/recv over TCP

Ported from borealis eio/ wrappers with dependency updates
(crypto instead of mirage-crypto, bare int for Spi/Vcid/Scid).

+172
+13
dune-project
··· 24 24 (fmt (>= 0.9)) 25 25 (alcotest :with-test) 26 26 (crowbar :with-test))) 27 + 28 + (package 29 + (name ltp-eio) 30 + (synopsis "Eio-based LTP segment transport") 31 + (description 32 + "Drives LTP segment encoding/decoding with Eio TCP connections. 33 + Provides length-prefixed framing for LTP segments over the wire.") 34 + (depends 35 + (ocaml (>= 5.1)) 36 + (ltp (= :version)) 37 + (eio (>= 1.0)) 38 + (fmt (>= 0.9)) 39 + (logs (>= 0.7))))
+4
eio/dune
··· 1 + (library 2 + (name ltp_eio) 3 + (public_name ltp-eio) 4 + (libraries ltp eio fmt logs))
+52
eio/ltp_eio.ml
··· 1 + (** LTP Eio - Effectful LTP segment transport using Eio. 2 + 3 + Provides Eio-based segment send/receive over flows with length-prefixed 4 + framing. Wraps the pure LTP segment encoding/decoding. *) 5 + 6 + let src = Logs.Src.create "ltp.eio" ~doc:"LTP Eio transport" 7 + 8 + module Log = (val Logs.src_log src : Logs.LOG) 9 + 10 + (* {1 Wire Framing} 11 + 12 + Segments are length-prefixed on the wire: 4-byte big-endian length followed 13 + by the segment data. *) 14 + 15 + let send_segment (flow : _ Eio.Flow.sink) seg = 16 + let data = Ltp.encode_segment seg in 17 + let len = String.length data in 18 + let hdr = Bytes.create 4 in 19 + Bytes.set_int32_be hdr 0 (Int32.of_int len); 20 + Eio.Flow.copy_string (Bytes.to_string hdr ^ data) flow 21 + 22 + let recv_segment (buf_r : Eio.Buf_read.t) = 23 + let hdr = Eio.Buf_read.take 4 buf_r in 24 + let len = Int32.to_int (String.get_int32_be hdr 0) in 25 + if len <= 0 || len > 1_048_576 then 26 + Error (Fmt.str "invalid segment length: %d" len) 27 + else 28 + let data = Eio.Buf_read.take len buf_r in 29 + match Ltp.decode_segment data with 30 + | Ok seg -> Ok seg 31 + | Error e -> Error (Fmt.str "%a" Ltp.pp_error e) 32 + 33 + (* {1 Connection} *) 34 + 35 + type t = { 36 + flow : [ `Generic ] Eio.Net.stream_socket_ty Eio.Resource.t; 37 + buf_r : Eio.Buf_read.t; 38 + } 39 + 40 + let connect ~sw ~net ~host ~port = 41 + Log.info (fun m -> m "Connecting to %s:%d" host port); 42 + let addr = `Tcp (Eio.Net.Ipaddr.of_raw host, port) in 43 + let flow = Eio.Net.connect ~sw net addr in 44 + let buf_r = Eio.Buf_read.of_flow ~max_size:(1024 * 1024) flow in 45 + { flow; buf_r } 46 + 47 + let close t = 48 + Log.info (fun m -> m "Closing LTP connection"); 49 + Eio.Flow.close t.flow 50 + 51 + let send t seg = send_segment t.flow seg 52 + let recv t = recv_segment t.buf_r
+67
eio/ltp_eio.mli
··· 1 + (** LTP Eio - Effectful LTP segment transport using Eio. 2 + 3 + Provides Eio-based segment send/receive over TCP with length-prefixed 4 + framing. Wraps the pure {!Ltp} segment encoding/decoding. 5 + 6 + {2 Wire Format} 7 + 8 + {v 9 + +----------+------------------+ 10 + | Length | LTP Segment | 11 + | (4B BE) | (variable) | 12 + +----------+------------------+ 13 + v} 14 + 15 + {2 Quick Start} 16 + 17 + {[ 18 + Eio_main.run @@ fun env -> 19 + Eio.Switch.run @@ fun sw -> 20 + let conn = 21 + Ltp_eio.connect ~sw ~net:env#net ~host:"127.0.0.1" ~port:1113 22 + in 23 + let seg = 24 + Ltp.data_segment ~session_id ~client_service_id:1L ~block_offset:0L 25 + "hello" 26 + in 27 + Ltp_eio.send conn seg; 28 + match Ltp_eio.recv conn with 29 + | Ok seg -> process seg 30 + | Error msg -> Fmt.epr "Error: %s@." msg 31 + ]} *) 32 + 33 + (** {1 Connection} *) 34 + 35 + type t 36 + (** An LTP transport connection. *) 37 + 38 + val connect : 39 + sw:Eio.Switch.t -> 40 + net:[> [ `Generic ] Eio.Net.ty ] Eio.Resource.t -> 41 + host:string -> 42 + port:int -> 43 + t 44 + (** [connect ~sw ~net ~host ~port] connects to a remote LTP peer over TCP. 45 + @raise Eio.Io on connection failure. *) 46 + 47 + val close : t -> unit 48 + (** [close t] closes the connection. *) 49 + 50 + (** {1 Segment I/O} *) 51 + 52 + val send : t -> Ltp.segment -> unit 53 + (** [send t seg] encodes and sends a segment with length prefix. *) 54 + 55 + val recv : t -> (Ltp.segment, string) result 56 + (** [recv t] receives and decodes a segment. 57 + 58 + Returns [Error msg] on framing or decoding errors. *) 59 + 60 + (** {1 Low-level} *) 61 + 62 + val send_segment : _ Eio.Flow.sink -> Ltp.segment -> unit 63 + (** [send_segment flow seg] sends a length-prefixed segment to any Eio sink. *) 64 + 65 + val recv_segment : Eio.Buf_read.t -> (Ltp.segment, string) result 66 + (** [recv_segment buf_r] reads a length-prefixed segment from a buffered reader. 67 + *)
+36
ltp-eio.opam
··· 1 + # This file is generated by dune, edit dune-project instead 2 + opam-version: "2.0" 3 + synopsis: "Eio-based LTP segment transport" 4 + description: """ 5 + Drives LTP segment encoding/decoding with Eio TCP connections. 6 + Provides length-prefixed framing for LTP segments over the wire.""" 7 + maintainer: ["Thomas Gazagnaire <thomas@gazagnaire.org>"] 8 + authors: ["Thomas Gazagnaire <thomas@gazagnaire.org>"] 9 + license: "ISC" 10 + homepage: "https://tangled.org/gazagnaire.org/ocaml-ltp" 11 + bug-reports: "https://tangled.org/gazagnaire.org/ocaml-ltp/issues" 12 + depends: [ 13 + "dune" {>= "3.21"} 14 + "ocaml" {>= "5.1"} 15 + "ltp" {= version} 16 + "eio" {>= "1.0"} 17 + "fmt" {>= "0.9"} 18 + "logs" {>= "0.7"} 19 + "odoc" {with-doc} 20 + ] 21 + build: [ 22 + ["dune" "subst"] {dev} 23 + [ 24 + "dune" 25 + "build" 26 + "-p" 27 + name 28 + "-j" 29 + jobs 30 + "@install" 31 + "@runtest" {with-test} 32 + "@doc" {with-doc} 33 + ] 34 + ] 35 + dev-repo: "git+https://tangled.org/gazagnaire.org/ocaml-ltp" 36 + x-maintenance-intent: ["(latest)"]