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.

ltp#

Pure OCaml implementation of Licklider Transmission Protocol (RFC 5326) for reliable data delivery over high-delay and disruption-prone links.

Overview#

LTP is designed for deep-space communications where round-trip times can be minutes to hours. It provides selective acknowledgment and retransmission with support for both reliable and unreliable data segments.

Packages#

  • ltp -- Core protocol: segment types, SDNV codecs, session management
  • ltp-eio -- Eio-based LTP segment transport

Installation#

Install with opam:

$ opam install ltp ltp-eio

If opam cannot find the packages, they may not yet be released in the public opam-repository. Add the overlay repository, then install them:

$ opam repo add samoht https://tangled.org/gazagnaire.org/opam-overlay.git
$ opam update
$ opam install ltp ltp-eio

Usage#

Send a block#

A block is delivered as a chain of data segments on a shared session, ending with is_eob:true:

let send_block ~host ~port ~block =
  Eio_main.run @@ fun env ->
  Eio.Switch.run @@ fun sw ->
  let net = (env#net :> [`Generic] Eio.Net.ty Eio.Resource.t) in
  let conn = Ltp_eio.connect ~sw ~net ~host ~port in
  let session = { Ltp.originator = 1L; number = 42L } in
  let chunk_size = 1024 in
  let len = String.length block in
  let rec send offset =
    if offset >= len then ()
    else
      let size = min chunk_size (len - offset) in
      let data = String.sub block offset size in
      let last = offset + size = len in
      let seg =
        Ltp.data_segment
          ~session_id:session
          ~client_service_id:1L
          ~block_offset:(Int64.of_int offset)
          ~is_eob:last
          data
      in
      Ltp_eio.send conn seg;
      send (offset + size)
  in
  send 0;
  Ltp_eio.close conn

Receive a block#

Read segments until one with is_eob seg and concatenate their payloads:

let recv_block ~host ~port =
  Eio_main.run @@ fun env ->
  Eio.Switch.run @@ fun sw ->
  let net = (env#net :> [`Generic] Eio.Net.ty Eio.Resource.t) in
  let conn = Ltp_eio.connect ~sw ~net ~host ~port in
  let buf = Buffer.create 4096 in
  let rec loop () =
    match Ltp_eio.recv conn with
    | Ok seg ->
        (match seg.Ltp.content with
         | Ltp.Data d -> Buffer.add_string buf d.Ltp.data
         | _ -> ());
        if Ltp.is_eob seg then () else loop ()
    | Error msg -> Fmt.epr "Error: %s@." msg
  in
  loop ();
  Ltp_eio.close conn;
  Fmt.pr "received %d bytes@." (Buffer.length buf)

Features#

  • SDNV (Self-Delimiting Numeric Value) encoding/decoding
  • Session management with engine/session IDs
  • Data segment types:
    • Red segments - reliable with acknowledgment
    • Green segments - best-effort delivery
  • Control segments:
    • Report segments (acknowledge received ranges)
    • Report-ack segments
    • Cancel segments
  • Checkpoint and report-based flow control

Segment-level API#

For protocol-level work (checkpoints, reports, cancel flow), construct and inspect segments directly.

Build and encode#

open Ltp

let session = { originator = 1L; number = 42L }

let segment =
  data_segment
    ~session_id:session
    ~client_service_id:1L
    ~block_offset:0L
    "hello"

let wire = encode_segment segment

SDNV#

let encoded = Ltp.encode_sdnv 127L

let () =
  match Ltp.decode_sdnv encoded 0 with
  | Ok (value, _offset) -> Fmt.pr "Value: %Ld@." value
  | Error msg -> Fmt.pr "Error: %s@." msg

Predicates#

  • is_data_segment, is_red_segment, is_green_segment
  • is_checkpoint, is_eorp, is_eob

Report and cancel#

  • Ltp.report_segment ~session_id ~report_serial ~checkpoint_serial ~upper_bound claims
  • Ltp.report_ack ~session_id ~report_serial
  • Ltp.cancel ~session_id ~from_sender reason
  • Ltp.cancel_ack ~session_id ~to_sender
  • ION - NASA/JPL DTN with LTP
  • µD3TN - Lightweight DTN with LTP support

References#

Licence#

ISC License. See LICENSE.md for details.