- Notifications
You must be signed in to change notification settings - Fork12
rperf is a Rust-based iperf alternative developed by 3D-P
License
opensource-3d-p/rperf
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
rperf is a Rust-basediperf alternativedeveloped by3D-P, aiming to avoid some reliability andconsistency issues found iniperf3, while simultaneously providing richermetrics data, with a focus on operation in a loss-tolerant, more IoT-likeenvironment. While it can be used as a near-drop-in replacement foriperf, andthere may be benefits to doing so, its focus is on periodic data-collection in amonitoring capacity in a closed network, meaning it is not suitable for alldomains thatiperf can serve.
rperf is an independent implementation, referencing the algorithms ofiperf3andzapwireless to assesscorrectness and derive suitable corrections, but copying no code from either.
In particular, the most significant issues addressed fromiperf3 follow:
Multiple concurrent clients are supported by any given server.
rperf's implementation ofRFC 1889 for streamingjitter calculation starts by assuming a delta between the first and secondpackets in a sequence and gaps in a sequence trigger a reset of the count.Comparatively,iperf3 begins with 0, which creates artificially low values,and in case of a gap, it just continues naively, which creates artificiallyhigh values.
Duplicate packets are accounted for in UDP exchanges and out-of-order packetsare counted as independent events.
All traffic can be emitted proportionally at regular sub-second intervals,allowing for configurations that more accurately reflect real datatransmission and sending algorithms.
- This addresses a commonly seen case in embedded-like systems where a pieceof equipment has a very small send- or receive-buffer that the OS does notknow about and it will just drop packets when receiving a huge mass ofdata in a single burst, incorrectly under-reporting network capacity.
Stream-configuration and results are exchanged via a dedicated connection andevery data-path has clearly defined timeout, completion and failure semantics,so execution doesn't hang indefinitely on either side of a test when keypackets are lost.
rperf's JSON output is structurally legal. No unquoted strings, repeatedkeys, or dangling commas, all of which require pre-processing beforeconsumption or cause unexpected errors.
In contrast tozapwireless, the following improvements are realised:
rperf uses a classic client-server architecture, so there's no need tomaintain a running process on devices that waits for a test-execution request.
Jitter is calculated.
IPv6 is supported.
Multiple streams may be run in parallel as part of a test.
An
omitoption is available to discard TCP ramp-up time from results.Output is available in JSON for easier telemetry-harvesting.
rperf should build and work on all major platforms, though its development andusage focus is on Linux-based systems, so that is where it will be mostfeature-complete.
Pull-requests for implementations of equivalent features for other systems arewelcome.
Everything is outlined in the output of--help and most users familiar with similar tools should feel comfortable immediately.
rperf works much likeiperf3, sharing a lot of concepts and even command-line flags. One key area where it differs is that the client drives all of the configuration process while the server just complies to the best of its ability and provides a stream of results. This means that the server will not present test-results directly via its interface and also that TCP and UDP tests can be run against the same instance, potentially by many clients simultaneously.
In its normal mode of operation, the client will upload data to the server; when thereverse flag is set, the client will receive data.
Unlikeiperf3,rperf does not make use of a reserved port-range by default. This is so it can support an arbitrary number of clients in parallel without resource contention on what can only practically be a small number of contiguous ports. In its intended capacity, this shouldn't be a problem, but where non-permissive firewalls and NAT setups are concerned, the--tcp[6]-port-pool and--udp[6]-port-pool options may be used to allocate non-continguous ports to the set that will be used to receive traffic.
There also isn't a concept of testing throughput relative to a fixed quantity of data. Rather, the sole focus is on measuring throughput over a roughly known period of time.
Also of relevance is that, if the server is running in IPv6 mode and its host supports IPv4-mapping in a dual-stack configuration, both IPv4 and IPv6 clients can connect to the same instance.
rperf usescargo.The typical process will simply becargo build --release.
cargo-deb is also supported and willproduce a usable Debian package that installs a disabled-by-defaultrperfsystemd service. When started, it runs asnobody:nogroup, assuming IPv6support by default.
Like its contemporaries,rperf's core concept is firing a stream of TCP orUDP data at an IP target at a pre-arranged target speed. The amount of dataactually received is observed and used to gauge the capacity of a network link.
Within those domains, additional data about the quality of the exchange isgathered and made available for review.
Architecturally,rperf has clients establish a TCP connection to the server,after which the client sends details about the test to be performed and theserver obliges, reporting observation results to the client during the entiretesting process.
The client may request that multiple parallel streams be used for testing, whichis facilitated by establishing multiple TCP connections or UDP sockets withtheir own dedicated thread on either side, which may be further pinned to asingle logical CPU core to reduce the impact of page-faults on thedata-exchange.
The client-server relationship is treated as a very central aspect of thisdesign, in contrast toiperf3, where they're more like peers, andzapwireless, where each participant runs its own daemon and a third processorchestrates communication.
Notably, all data-gathering, calculation, and display happens client-side, withthe server simply returning what it observed. This can lead to some drift inrecordings, particularly where time is concerned (server intervals being ahandful of milliseconds longer than their corresponding client values is notat all uncommon). Assuming the connection wasn't lost, however, totals for dataobserved will match up in all modes of operation.
The server uses three layers of threading: one for the main thread, one for eachclient being served, and one more for each stream that communicates with theclient. On the client side, the main thread is used to communicate with theserver and it spawns an additional thread for each stream that communicates withthe server.
When the server receives a request from a client, it spawns a thread thathandles that client's specific request; internally, each stream for the testproduces an iterator-like handler on either side. Both the client and server runthese iterator-analogues against each other asynchronously until the test periodends, at which point the sender indicates completion within its stream.
To reliably handle the possibility of disconnects at the stream level, akeepalive mechanism in the client-server stream, over which test-results aresent from the server at regular intervals, will terminate outstandingconnections after a few seconds of inactivity.
The host OS's TCP and UDP mechanisms are used for all actual traffic exchanged,with some tuning parameters exposed. This approach was chosen over a userspaceimplementation on top of layer-2 or layer-3 because it most accuratelyrepresents the way real-world applications will behave.
The "timestamp" values visible in JSON-serialised interval data arehost-relative, so unless your environment has very high system-clock accuracy,send-timestamps should only be compared to other send-timestamps and likewisefor receive-timestamps. In general, this data is not useful outside ofcorrectness-validation, however.
During each exchange interval, an attempt is made to sendlength bytes at atime, until the amount written to the stream meets or exceeds the bandwdithtarget, at which point the sender goes silent until the start of the nextinterval; the data sent within an interval should be uniformly distributed overthe period.
Stream indexes start at0, not1. This probably won't surprise anyone, butseeing "stream 0" in a report is not cause for concern.
rperf is distributed by Evtech Solutions, Ltd., dba 3D-P, under theGNU GPL version 3, the text ofwhich may be found inCOPYING.
Authorship details, copyright specifics, and transferability notes are presentwithin the source code itself.
About
rperf is a Rust-based iperf alternative developed by 3D-P
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Uh oh!
There was an error while loading.Please reload this page.