Skip to content

Commit

Permalink
Add iperf3 example
Browse files Browse the repository at this point in the history
Co-authored-by: Dmitrii Kuvaiskii <dmitrii.kuvaiskii@intel.com>
Signed-off-by: Dimitrios Stavrakakis <dimitrios.stavrakakis@intel.com>
Signed-off-by: Dmitrii Kuvaiskii <dmitrii.kuvaiskii@intel.com>
  • Loading branch information
Dimitrios Stavrakakis and Dmitrii Kuvaiskii committed Jan 29, 2024
1 parent 1ce5dfb commit d5b0168
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 0 deletions.
3 changes: 3 additions & 0 deletions iperf/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
iperf/
install/
/*.tar.gz
68 changes: 68 additions & 0 deletions iperf/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Copyright (C) 2024 Gramine contributors
# SPDX-License-Identifier: BSD-3-Clause

ARCH_LIBDIR ?= /lib/$(shell $(CC) -dumpmachine)

IPERF_DIR = iperf
IPERF_SHA256 ?= cc740c6bbea104398cc3e466befc515a25896ec85e44a662d5f4a767b9cf713e
IPERF_SRC ?= iperf-3.16.tar.gz
IPERF_MIRRORS ?= https://github.com/esnet/iperf/releases/download/3.16

ifeq ($(DEBUG),1)
GRAMINE_LOG_LEVEL = debug
else
GRAMINE_LOG_LEVEL = error
endif

.PHONY: all
all: install/iperf3 install/libiperf.so.0 iperf3.manifest
ifeq ($(SGX),1)
all: iperf3.manifest.sgx iperf3.sig
endif

$(IPERF_DIR)/configure:
../common_tools/download --output $(IPERF_SRC) --sha256 $(IPERF_SHA256) \
$(foreach mirror,$(IPERF_MIRRORS),--url $(mirror)/$(IPERF_SRC))
mkdir $(IPERF_DIR)
tar -C $(IPERF_DIR) --strip-components=1 -xf $(IPERF_SRC)

$(IPERF_DIR)/src/.libs/iperf3: $(IPERF_DIR)/configure
cd $(IPERF_DIR) && ./configure
$(MAKE) -C $(IPERF_DIR)

iperf3.manifest: iperf3.manifest.template
gramine-manifest \
-Dlog_level=$(GRAMINE_LOG_LEVEL) \
-Darch_libdir=$(ARCH_LIBDIR) \
$< > $@

# Make on Ubuntu <= 20.04 doesn't support "Rules with Grouped Targets" (`&:`),
# see the helloworld example for details on this workaround.
iperf3.sig iperf3.manifest.sgx: sgx_sign
@:

.INTERMEDIATE: sgx_sign
sgx_sign: iperf3.manifest $(IPERF_DIR)/src/.libs/iperf3
gramine-sgx-sign \
--manifest $< \
--output $<.sgx

# for simplicity, copy iperf3 executable into our install directory
install/iperf3: $(IPERF_DIR)/src/.libs/iperf3
mkdir -p install
cp $< $@

# for simplicity, copy libiperf library into our install directory
install/libiperf.so.0: $(IPERF_DIR)/src/.libs/libiperf.so.0
mkdir -p install
cp $< $@

################################## CLEANUP ####################################

.PHONY: clean
clean:
$(RM) -r *.token *.sig *.manifest.sgx *.manifest install

.PHONY: distclean
distclean: clean
$(RM) -r $(IPERF_DIR) *.tar.gz
86 changes: 86 additions & 0 deletions iperf/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# iperf

This directory contains the Makefile and the template manifest for the most
recent version of `iperf` as of this writing (3.16).

# Prerequisites

`iperf` has no prerequisites
([source](https://github.com/esnet/iperf/tree/3.16?tab=readme-ov-file#prerequisites)).

# Building instructions

We build `iperf` from source because Ubuntu 22.04 has `iperf3` v3.9 in its
package repositories which is built with `TCP_CONGESTION` requirement (i.e.,
with `iperf3_cv_header_tcp_congestion="yes"` config option). Using the Ubuntu
package would fail with the following error:
```
iperf3: error - unable to set TCP_CONGESTION: ...
```

Thus we build `iperf` manually. In this case, it is built without
`TCP_CONGESTION`, and can successfully execute under Gramine[^1].

[^1]: Starting from version 3.10, `iperf` supports environments that do not
implement congestion control algorithm. Thus, iperf 3.10+ prebuilt packages
should work under Gramine without problems. See [release
notes](https://github.com/esnet/iperf/blob/3.16/RELNOTES.md#iperf-310-2021-05-26)
for details.


## Building for Linux

Run `make` in the current directory.

## Building for SGX

Run `make SGX=1` (non-debug) or `make SGX=1 DEBUG=1` (debug) in the current
directory.

# Execution instructions

Run `iperf` server natively:
```
LD_LIBRARY_PATH=./install ./install/iperf3 -s
```

Run `iperf` server in Gramine without SGX:
```
gramine-direct iperf3
```

Run `iperf` server in Gramine with SGX:
```
gramine-sgx iperf3
```

To get measurements with the `iperf` client, run in another terminal:
```
LD_LIBRARY_PATH=./install ./install/iperf3 -c localhost -p 5201
```

# Useful iperf options

(The options may be version-dependent. Below are the options for v3.16.)

## Generic options (both for server and client):
- `-p, --port`: server port to listen on/connect to
- `--forceflush`: force flushing output at every interval
- `-d, --debug[=#]`: emit debugging output (optional "=" and debug level: 1-4)

## Server-specific options:
- `-s, --server`: run in server mode
- `-1, --one-off`: handle one client connection then exit
- `--idle-timeout #`: restart idle server after # seconds in case it got stuck

## Client-specific options:
- `-c, --client <host>`: run in client mode, connecting to `<host>`
- `-t, --time #`: time in seconds to transmit for (default 10 secs)
- `-n, --bytes #[KMG]`: number of bytes to transmit (instead of -t)
- `-P, --parallel #`: number of parallel client streams to run
- `-N, --no-delay`: set TCP/SCTP no delay, disabling Nagle's Algorithm

# Notes
- Tested on Ubuntu 22.04.
- In the execution instructions, we use port `5201` for the client.
This is the default port used by `iperf`.
43 changes: 43 additions & 0 deletions iperf/iperf3.manifest.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Copyright (C) 2024 Gramine contributors
# SPDX-License-Identifier: BSD-3-Clause

# iperf3 manifest file example

loader.entrypoint = "file:{{ gramine.libos }}"
libos.entrypoint = "/install/iperf3"

loader.log_level = "{{ log_level }}"

# Hardcode the argument to run the iperf3 server inside Gramine
loader.argv = ["/install/iperf3", "-s"]

loader.env.LD_LIBRARY_PATH = "/install:/lib:{{ arch_libdir }}:/usr/{{ arch_libdir }}"

sys.enable_sigterm_injection = true

fs.mounts = [
{ path = "/lib", uri = "file:{{ gramine.runtimedir() }}" },
{ path = "{{ arch_libdir }}", uri = "file:{{ arch_libdir }}" },
{ path = "/usr/{{ arch_libdir }}", uri = "file:/usr/{{ arch_libdir }}" },
{ type = "tmpfs", path = "/tmp"},

# Mount iperf3 executable and libiperf (located in the install directory)
# in Gramine under the /install directory.
{ path = "/install/iperf3", uri = "file:install/iperf3" },
{ path = "/install/libiperf.so.0", uri = "file:install/libiperf.so.0" },
]

sgx.edmm_enable = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }}
# iperf3 is single threaded; we choose 4 to accommodate Gramine additional
# threads for IPC and asynchronous events/alarms.
sgx.max_threads = {{ '1' if env.get('EDMM', '0') == '1' else '4' }}
sgx.enclave_size = "1024M"

sgx.trusted_files = [
"file:install/iperf3",
"file:install/libiperf.so.0",
"file:{{ gramine.runtimedir() }}/",
"file:{{ arch_libdir }}/",
"file:/usr/{{ arch_libdir }}/",
"file:{{ gramine.libos }}",
]

0 comments on commit d5b0168

Please sign in to comment.