A performance measurement tool for QUIC similar to iperf. This forked version of the original qperf offers a proxy
mode, where qperf acts as a Performance Enhancing Proxy (PEP) by splitting the incoming connection: The proxy receives incoming connections, establishes a new connection to a predefined destination, and forwards data between both connections while directly mapping the stream IDs.
This simplistic design breaks the end-to-end encryption and gives the proxy access to the decrypted user data; we therefore explicitly note that the implementation of QUIC PEP is a proof-of-concept in order to evaluate if QUIC could benefit from transport layer optimizations.
qperf
is based on quicly, and uses a forked submodule of quicly in order to enable the parametrization of the QUIC Acknowledgement Frequency extension.
Usage: ./qperf [-s|-P target|-c target] [options]
./qperf [-h|--help] [-v|--version]
Global options:
--cc [reno|cubic] congestion control algorithm to use (default reno)
-g enable UDP generic segmentation offload (linux only)
-h, --help print this help message
-i, --report-interval # seconds between each statistics report (default 1.0)
-l, --log-tls <file> file to log tls secrets
--print-raw output raw statistics, don't calculate metric prefixes
-q, --quicly-buffer #[k...E] set quicly buffer in qperf to this size (default 1MB)
-u, --udp-buffer #[k...E] set udp buffer in qperf to this size (default 1MB)
-w, --iw # initial window to use (default 10)
--max-ack-delay max. time for sending of ACK (in milliseconds, Set to UINT64_MAX to turn off ack frequency extension)
--first-ack-freq-packet-number the packet number after which the first ACK frequency frame will be sent
--ack-freq-cwnd-fraction the fraction of CWND that will be set to packet tolerance in ACK frequency frames (e.g. 8 -> 1/8)
-v, --version print version and exit
Server:
-s run in server mode
Proxy:
-P <host> run in proxy mode and connect to target server
-b, --qperf-buffer #[k...E] set transfer buffer in qperf to this size (default 1MB)
--alpn protocol name to be used for both proxy connections
--wait-for-svr wait for connection to server to be established before completing client connection
Client:
-c <host> run in client mode and connect to target server
-e measure time for connection establishment and first byte only
-t # run for this many seconds (default 10)
Server/Proxy:
--listen-addr <addr> address to listen on in server/proxy mode (default 0.0.0.0)
--listen-port # port to listen on in server/proxy mode (default 18080)
--tls-cert <file> certificate file to use (default 'server.crt')
--tls-key <file> key file to use (default 'server.key')
--session-cache <file> file to cache a single session across restarts for 0-RTT handshakes
Proxy/Client:
-p, --port # port to connect to (default 18080)
--session <file> file to load and store the session information for 0-RTT handshakes
--quic-version quic version (rfc-1, draft-27, draft-29) to be used and enforced with version negotiation (only as proxy) (default: rfc-1 w/o version negotiation)
Client/Server:
--events <file> file to log quicly events
[k...E] Indicates options that support a k,m,g,t,p,e,K,M,G,T,P or E suffix
Lowercase format characters are 10^3 based and uppercase are 2^10 based
(e.g. 1k = 1000, 1K = 1024, 1m = 1,000,000 and 1M = 1,048,576)
./qperf -s
starting server with pid 3143, port 18080, cc reno, iw 10
got new connection from 127.0.0.1:58350
new server binding 0
binding 0 src connected to 127.0.0.1:58350
connection 0 connection establishment time: 1ms
binding 0 stream 0 opened
binding 0 request received, sending data
connection 0 second 1: 1.63 Gbit/s, send window: 207055230, bytes sent: 203943026, packets sent: 162694, packets lost: 0
connection 0 second 2: 1.528 Gbit/s, send window: 402490630, bytes sent: 191425151, packets sent: 152670, packets lost: 0
connection 0 second 3: 1.514 Gbit/s, send window: 595481199, bytes sent: 189213079, packets sent: 150944, packets lost: 0
connection 0 second 4: 1.58 Gbit/s, send window: 796512603, bytes sent: 196919713, packets sent: 157095, packets lost: 0
connection 0 second 5: 1.493 Gbit/s, send window: 986410809, bytes sent: 186641332, packets sent: 148910, packets lost: 0
connection 0 second 6: 1.557 Gbit/s, send window: 1185382645, bytes sent: 194759155, packets sent: 155620, packets lost: 0
connection 0 second 7: 1.572 Gbit/s, send window: 1386913696, bytes sent: 196934176, packets sent: 157646, packets lost: 0
connection 0 second 8: 1.526 Gbit/s, send window: 1582037031, bytes sent: 190630711, packets sent: 152600, packets lost: 0
connection 0 second 9: 1.548 Gbit/s, send window: 1779833647, bytes sent: 193287020, packets sent: 154727, packets lost: 0
connection 0 second 10: 1.583 Gbit/s, send window: 1982226314, bytes sent: 197737555, packets sent: 158289, packets lost: 0
binding 0 closed by remote: transport close: code=0x0; frame=0; reason=runtime_reached
binding 0 closed
connection 0 total: bytes sent: 1942290348, packets sent: 1551835, packets lost: 0
binding 0 disconnected, cleaning up
binding 0 removed
Note: The server looks for a TLS certificate and key in the current working dir named "server.crt" and "server.key" respectively. You can use a self signed certificate; the client doesn't validate it.
./qperf -c 127.0.0.1
starting client with host 127.0.0.1, port 18080, runtime 10s, cc reno, iw 10
establishing connection to 127.0.0.1:18080
connection establishment time: 11ms
time to first byte: 13ms
second 1: 1.635 Gbit/s, bytes received: 204384774, packets received: 163046
second 2: 1.527 Gbit/s, bytes received: 190983395, packets received: 152318
second 3: 1.514 Gbit/s, bytes received: 189213079, packets received: 150944
second 4: 1.579 Gbit/s, bytes received: 197427297, packets received: 157500
second 5: 1.493 Gbit/s, bytes received: 186679724, packets received: 148941
second 6: 1.559 Gbit/s, bytes received: 194633507, packets received: 155520
second 7: 1.571 Gbit/s, bytes received: 196513848, packets received: 157310
second 8: 1.526 Gbit/s, bytes received: 190630711, packets received: 152600
second 9: 1.548 Gbit/s, bytes received: 193527212, packets received: 154919
second 10: 1.585 Gbit/s, bytes received: 198076576, packets received: 158560
total: bytes received: 1942165199, packets received: 1551734
Ensure that build-essentials
, libssl-dev
, libev-dev
and cmake
are installed.
git clone --recurse-submodules git@gitlab.lrz.de:kosekmike/qperf.git
mkdir build-qperf
cd build-qperf
cmake ../qperf
make
not supported in proxy mode
qperf cannot output qlog itself, but it can be generated from the event trace.
- use
--events
option to specify output file- e.g.
qperf --events -c 127.0.0.0 events.ndjson
- e.g.
- run qlog-adapter.py to generate qlog trace
- e.g.
quicly/misc/qlog-adapter.py events.ndjson > events.qlog
- e.g.