iperf3 network throughput protocol in pure OCaml
0

Configure Feed

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

OCaml 93.7%
Dune 1.6%
Other 4.8%
68 1 0

Clone this repository

https://git.vm.fail/gazagnaire.org/ocaml-iperf3 https://git.vm.fail/did:plc:pzasqg73wzvo7lybfgkon7fv
ssh://git@git.recoil.org:2222/gazagnaire.org/ocaml-iperf3 ssh://git@git.recoil.org:2222/did:plc:pzasqg73wzvo7lybfgkon7fv

For self-hosted knots, clone URLs may differ based on your setup.


README.md

ocaml-iperf3#

The iperf3 network throughput protocol in pure OCaml: the control state machine and data-path codecs as I/O-free state machines (iperf3), plus an Eio client and server (iperf3-eio) that interoperate with the stock iperf3 binary in both directions.

iperf3 measures throughput between a client and a server. They negotiate over a TCP control connection -- a sequence of single-byte states, a 37-byte cookie, and length-prefixed JSON for parameters and results -- then blast payload over one or more separate data streams, in either or both directions.

Installation#

Install with opam:

$ opam install iperf3

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

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

Layout#

Package What
iperf3 Sans-IO core: Cmd, Cookie, Params, Results, Frame, and the Server / Client control state machines. No eio/unix deps; time and randomness are inputs.
iperf3-eio serve / run_client over Eio sockets, and the oiperf3 CLI.

The binary framing is built on ocaml-wire; the JSON payloads on nox-json. Frames are read non-draining from a Bytesrw.Bytes.Reader.t, so successive frames come off one live connection.

CLI#

# server
oiperf3 -s

# client: 10s forward test against a host
oiperf3 -c 10.0.0.2

# reverse (server sends), 4 parallel streams, 5 seconds
oiperf3 -c 10.0.0.2 -R -P 4 -t 5

The server interoperates with a stock iperf3 -c, and the client with a stock iperf3 -s, both forward and reverse.

Library#

The Eio adapter is a byte shuttle around the core state machines. Time is injected, so the timing policy stays with the caller:

let run_client env =
  let net = Eio.Stdenv.net env in
  let random = Eio.Stdenv.secure_random env in
  let mono = Eio.Stdenv.mono_clock env in
  let clock = Eio.Stdenv.clock env in
  let now () = Eio.Time.Mono.now mono in
  let sleep s = Eio.Time.sleep clock s in
  Eio.Switch.run @@ fun sw ->
  let params = { Iperf3.Params.default with time = 5 } in
  let r =
    Iperf3_eio.run_client ~sw ~net ~now ~sleep ~random ~host:"10.0.0.2" params
  in
  Fmt.pr "received %Ld bytes@." (Iperf3.Results.total_bytes r)

The core has no I/O at all: drive Iperf3.Server / Iperf3.Client with bytes and time and it returns the bytes to write plus structured events, so the same machine runs under any I/O model (see test/ for the in-memory roundtrip).

Status#

  • TCP data path: implemented, both directions (forward and reverse).
  • UDP / SCTP data paths, and bidirectional (--bidir) tests: not yet implemented; the UDP datagram codec is stubbed and the adapter rejects bidir.

bench/live_iperf3.ml is a live interoperability check against the stock iperf3 binary (not part of dune test):

dune exec ocaml-iperf3/bench/live_iperf3.exe