{"id":13582366,"url":"https://github.com/heistp/irtt","last_synced_at":"2025-10-21T13:03:19.553Z","repository":{"id":49974375,"uuid":"106883225","full_name":"heistp/irtt","owner":"heistp","description":"Isochronous Round-Trip Tester","archived":false,"fork":false,"pushed_at":"2024-05-18T06:41:12.000Z","size":507,"stargazers_count":191,"open_issues_count":16,"forks_count":23,"subscribers_count":14,"default_branch":"master","last_synced_at":"2024-11-05T22:40:57.018Z","etag":null,"topics":["go","jitter","packet-loss","ping","rtt"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/heistp.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-10-13T23:47:31.000Z","updated_at":"2024-10-29T13:13:41.000Z","dependencies_parsed_at":"2024-01-19T08:14:15.584Z","dependency_job_id":"0effa650-589c-4dd8-9caf-3829b8d90ed6","html_url":"https://github.com/heistp/irtt","commit_stats":{"total_commits":242,"total_committers":4,"mean_commits":60.5,"dds":0.02066115702479343,"last_synced_commit":"de1991d4770e211253223db7b5c015acf08af839"},"previous_names":["peteheist/irtt"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/heistp%2Firtt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/heistp%2Firtt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/heistp%2Firtt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/heistp%2Firtt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/heistp","download_url":"https://codeload.github.com/heistp/irtt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247495711,"owners_count":20948100,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","jitter","packet-loss","ping","rtt"],"created_at":"2024-08-01T15:02:38.975Z","updated_at":"2025-10-21T13:03:19.481Z","avatar_url":"https://github.com/heistp.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# IRTT (Isochronous Round-Trip Tester)\n\nIRTT measures round-trip time, one-way delay and other metrics using UDP\npackets sent on a fixed period, and produces both user and machine parseable\noutput.\n\nIRTT has reached version 0.9.1. I would appreciate any feedback, which you can\nsend under Issues. However, it could be useful to first review the\n[Roadmap](#roadmap) section of the documentation before submitting a new bug or\nfeature request.\n\n## Table of Contents\n\n1. [Motivation](#motivation)\n2. [Goals](#goals)\n3. [Features](#features)\n4. [Limitations](#limitations)\n5. [Installation](#installation)\n6. [Documentation](#documentation)\n7. [Frequently Asked Questions](#frequently-asked-questions)\n8. [Roadmap](#roadmap)\n9. [Changes](#changes)\n10. [Thanks](#thanks)\n\n## Motivation\n\nLatency is an under-appreciated metric in network and application performance.\nAs of this writing, many broadband connections are well past the point of\ndiminishing returns when it comes to throughput, yet that’s what we continue to\ntake as the primary measure of Internet performance. This is analogous to\nordinary car buyers making top speed their first priority.\n\nThere is a certain hard to quantify but visceral “latency stress” that comes\nfrom waiting in expectation after a web page click, straining through a delayed\nand garbled VoIP conversation, or losing at your favorite online game (unless\nyou like “lag” as an excuse). Those who work on reducing latency and improving\nnetwork performance characteristics beyond just throughput may be driven by the\nidea of helping relieve this stress for others.\n\nIRTT was originally written to improve the latency and packet loss measurements\nfor the excellent [Flent](https://flent.org) tool, but should be useful as a\nstandalone tool as well. Flent was developed by and for the\n[Bufferbloat](https://www.bufferbloat.net/projects/) project, which aims to\nreduce \"chaotic and laggy network performance,\" making this project valuable to\nanyone who values their time and sanity while using the Internet.\n\n## Goals\n\nThe goals of this project are to:\n\n- Accurately measure latency and other relevant metrics of network behavior\n- Produce statistics via both human and machine parseable output\n- Provide for reasonably secure use on both public and private servers\n- Support small enough packet sizes for [VoIP](https://www.cisco.com/c/en/us/support/docs/voice/voice-quality/7934-bwidth-consume.html) simulation\n- Support relevant socket options, including DSCP\n- Use a single UDP port for deployment simplicity\n- Keep the executable size small enough for use on embedded devices\n- Provide an API for embedding and extensibility\n\n## Features:\n\n- Measurement of:\n\t- [RTT (round-trip time)](https://en.wikipedia.org/wiki/Round-trip_delay_time)\n\t- [OWD (one-way delay)](https://en.wikipedia.org/wiki/End-to-end_delay), given\n\t\texternal clock synchronization\n\t- [IPDV (instantaneous packet delay variation)](https://en.wikipedia.org/wiki/Packet_delay_variation), usually referred to as jitter\n\t- [Packet loss](https://en.wikipedia.org/wiki/Packet_loss), with upstream and downstream differentiation\n\t- [Out-of-order](https://en.wikipedia.org/wiki/Out-of-order_delivery)\n\t\t(measured using late packets metric) and [duplicate](https://wiki.wireshark.org/DuplicatePackets) packets\n\t- [Bitrate](https://en.wikipedia.org/wiki/Bit_rate)\n\t- Timer error, send call time and server processing time\n- Statistics: min, max, mean, median (for most quantities) and standard deviation\n- One nanosecond time precision on Linux and OS/X, and 100ns on Windows\n- Robustness in the face of clock drift and NTP corrections through the use of\n  both wall and monotonic clocks\n- Binary protocol with negotiated format for test packet lengths down to 16 bytes (without timestamps)\n- HMAC support for private servers, preventing unauthorized discovery and use\n- Support for a wide range of Go supported [platforms](https://github.com/golang/go/wiki/MinimumRequirements)\n- Timer compensation to improve sleep send schedule accuracy\n- Support for IPv4 and IPv6\n- Public server protections, including:\n\t- Three-way handshake with returned 64-bit connection token, preventing reply\n\t\tredirection to spoofed source addresses\n\t- Limits on maximum test duration, minimum interval and maximum packet length,\n\t\tboth advertised in the negotiation and enforced with hard limits to protect\n\t\tagainst rogue clients\n\t- Packet payload filling to prevent relaying of arbitrary traffic\n- Output to JSON\n- An available [SmokePing](https://oss.oetiker.ch/smokeping/) probe\n  ([code](https://github.com/oetiker/SmokePing/blob/master/lib/Smokeping/probes/IRTT.pm))\n\n## Limitations\n\nSee the\n[LIMITATIONS](http://htmlpreview.github.io/?https://github.com/heistp/irtt/blob/master/doc/irtt.html#limitations)\nsection of the irtt(1) man page.\n\n## Installation\n\nTo install IRTT manually or build from source, you must:\n\n1. [Install Go](https://golang.org/dl/)\n2. Install irtt: `go install github.com/heistp/irtt/cmd/irtt@latest`\n3. For convenience, copy the `irtt` executable, which should be in\n   `$HOME/go/bin`, or `$GOPATH/bin` if you have `$GOPATH` defined, to somewhere\n   on your `PATH`.\n\nIf you want to build the source for development, you must also:\n\n1. Install the `pandoc` utility for generating man pages and HTML documentation\n   from their markdown source files. This can be done with `apt-get install\n   pandoc` on Debian flavors of Linux or `brew install pandoc` on OS/X. See the\n   [Pandoc](http://pandoc.org/) site for more information.\n2. Install the `stringer` utility by doing\n   `go install golang.org/x/tools/cmd/stringer@latest`.\n   This is only necessary if you need to re-generate the `*_string.go` files that\n   are generated by this tool, otherwise the checked in versions may also be\n   used.\n3. Use `build.sh` to build during development, which helps with development\n   related tasks, such as generating source files and docs, and cross-compiling\n   for testing. For example, `build.sh min linux-amd64` would compile a\n   minimized binary for Linux on AMD64. See `build.sh` for more info and a\n   \"source-documented\" list of platforms that the script supports. See [this\n   page](http://golang.org/doc/install/source#environment) for a full list of\n   valid GOOS GOARCH combinations. `build.sh install` runs Go's install command,\n   which puts the resulting executable in `$GOPATH/bin`.\n\nIf you want to build from a branch, you should first follow the steps above,\nthen from the `github.com/heistp/irtt` directory, do:\n1. `git checkout branch`\n2. `go get ./...`\n3. `go install ./cmd/irtt` or `./build.sh` and move resulting `irtt` executable\n   to install location\n\nBuilding for iOS:\n\nI have no way to verify this, but I received a report that the following is\n\"close to but not quite the right command\" to cross-compile for iOS:\n\n``GOOS=ios GOARCH=arm64  IPHONEOS_DEPLOYMENT_TARGET=14.0 CGO_ENABLED=1 CGO_CFLAGS=\"-arch arm64 -isysroot `xcrun --sdk iphoneos --show-sdk-path` -mios-version-min=10.0\" CGO_LDFLAGS=\"-arch arm64 -isysroot `xcrun --sdk iphoneos --show-sdk-path`\" go build -o irtt cmd/irtt/main.go``\n\nPlease file an issue if you get this working so I can update the doc.\n\n## Documentation\n\nAfter installing IRTT, see the man pages and their corresponding EXAMPLES\nsections to get started quickly:\n- [irtt(1)](http://htmlpreview.github.io/?https://github.com/heistp/irtt/blob/master/doc/irtt.html) | [EXAMPLES](http://htmlpreview.github.io/?https://github.com/heistp/irtt/blob/master/doc/irtt.html#examples)\n- [irtt-client(1)](http://htmlpreview.github.io/?https://github.com/heistp/irtt/blob/master/doc/irtt-client.html) | [EXAMPLES](http://htmlpreview.github.io/?https://github.com/heistp/irtt/blob/master/doc/irtt-client.html#examples)\n- [irtt-server(1)](http://htmlpreview.github.io/?https://github.com/heistp/irtt/blob/master/doc/irtt-server.html) | [EXAMPLES](http://htmlpreview.github.io/?https://github.com/heistp/irtt/blob/master/doc/irtt-server.html#examples)\n\n## Frequently Asked Questions\n\n1) Why not just use ping?\n\n   Ping may be the preferred tool when measuring minimum latency, or for other\n   reasons. IRTT's reported mean RTT is likely to be a bit higher (on the order\n   of a couple hundred microseconds) and a bit more variable than the results\n   reported by ping, due to the overhead of entering userspace, together with\n   Go's system call overhead and scheduling variability. That said, this\n   overhead should be negligible at most Internet RTTs, and there are advantages\n   that IRTT has over ping when minimum RTT is not what you're measuring:\n\n\t - In addition to round-trip time, IRTT also measures OWD, IPDV and upstream\n\t   vs downstream packet loss.\n\t - Some device vendors prioritize ICMP, so ping may not be an accurate measure\n\t\t of user-perceived latency.\n\t - IRTT can use HMACs to protect private servers from unauthorized discovery\n\t\t and use.\n\t - IRTT has a three-way handshake to prevent test traffic redirection from\n\t\t spoofed source IPs.\n\t - IRTT can fill the payload (if included) with random or arbitrary data.\n   - On Windows, ping has a precision of 0.5ms, while IRTT uses high resolution\n     timer functions for a precision of 100ns (high resolution wall clock only\n     available on Windows 8 or Windows 2012 Server and later).\n\n   Also note the following behavioral differences between ping and IRTT:\n\n   - IRTT makes a stateful connection to the server, whereas ping is stateless.\n   - By default, ping waits for a reply before sending its next request, while\n     IRTT keeps sending requests on the specified interval regardless of whether\n     or not replies are received. The effect of this, for example, is that a\n     fixed-length pause in server packet processing (with packets buffered\n     during the pause) will look like a single high RTT in ping, and multiple\n     high then descending RTTs in IRTT for the duration of the maximum RTT.\n\n2) Is there a public server I can use?\n\n   There is a test server running at `irtt.heistp.net` with an HMAC key of\n   `irttuser`. Please do not abuse it. To restrict bandwidth, the minimum\n   interval is set to 100ms, the max length to 256 bytes, and the max duration\n   to 60 seconds. Example usage:\n   \n   `irtt client --hmac=irttuser irtt.heistp.net`\n\n3) How do I run the IRTT server at startup?\n\n   This depends on your OS and init system, but see:\n   \n   - the `irtt.service` file for\n     [systemd](https://www.freedesktop.org/wiki/Software/systemd/), used in Debian\n   and Ubuntu\n   - the `irtt.openrc` file for [OpenRC](https://wiki.gentoo.org/wiki/OpenRC),\n     used in Gentoo and Alpine\n\n4) Why can't the client connect to the server, and instead I get\n   `Error: no reply from server`?\n\n   There are a number of possible reasons for this:\n\n   1) You've specified an incorrect hostname or IP address for the server.\n   2) There is a firewall blocking packets from the client to the server.\n      Traffic must be allowed on the chosen UDP port (default 2112).\n   3) There is high packet loss. By default, up to four packets are sent when\n      the client tries to connect to the server, using timeouts of 1, 2, 4 and 8\n      seconds. If all of these are lost, the client won't connect to the server.\n      In environments with known high packet loss, the `--timeouts` flag may\n      be used to send more packets with the chosen timeouts before abandoning\n      the connection.\n   4) The server has an HMAC key set with `--hmac` and the client either has\n      not specified a key or it's incorrect. Make sure the client has the\n      correct HMAC key, also specified with the `--hmac` flag.\n   5) You're trying to connect to a listener that's listening on an unspecified\n      IP address, but reply packets are coming back on a different route from the\n      requests, or not coming back at all. This can happen in network\n      environments with [asymmetric routing and a firewall or NAT]\n      (https://www.cisco.com/web/services/news/ts_newsletter/tech/chalktalk/archives/200903.html).\n      There are several possible solutions to this:\n      - Change your network configuration to avoid the problem.\n      - Have the IRTT server listen on specific addresses with the `-b` flag.\n      - Use the `--set-src-ip` flag on the server, which explicitly sets the\n        source address on all reply packets from listeners on unspecified IP\n        addresses to the destination address that the request was received on.\n        The only reason this is not done by default is to avoid the extra\n        per-packet heap allocations required by the `golang.org/x/net` packege\n        to do so.\n\n5) Why is the send (or receive) delay negative or much larger than I expect?\n\n\t The client and server clocks must be synchronized for one-way delay values to\n\t be meaningful (although, the relative change of send and receive delay may be\n   useful to look at even without clock synchronization). Well-configured NTP\n   hosts may be able to synchronize to within a few milliseconds.\n\t [PTP](https://en.wikipedia.org/wiki/Precision_Time_Protocol)\n\t ([Linux](http://linuxptp.sourceforge.net) implementation here) is capable of\n   much higher precision. For example, using two\n   [PCEngines APU2](http://pcengines.ch/apu2.htm) boards (which support PTP\n   hardware timestamps) connected directly by Ethernet, the clocks\n   may be synchronized within a few microseconds.\n   \n\t Note that client and server synchronization is not needed for either RTT or\n\t IPDV (even send and receive IPDV) values to be correct. RTT is measured with\n\t client times only, and since IPDV is measuring differences between successive\n\t packets, it's not affected by time synchronization.\n\n6) Why is the receive rate 0 when a single packet is sent?\n\n   Receive rate is measured from the time the first packet is received to the time\n   the last packet is received. For a single packet, those times are the same.\n\n7) Why does a test with a one second duration and 200ms interval run for around\n   800ms and not one second?\n\n   The test duration is exclusive, meaning requests will not be sent exactly at\n   or after the test duration has elapsed. In this case, the interval is 200ms, and\n   the fifth and final request is sent at around 800ms from the start of the test.\n   The test ends when all replies have been received from the server, so it may\n\t end shortly after 800ms. If there are any outstanding packets, the wait time\n\t is observed, which by default is a multiple of the maximum RTT.\n\n8) Why is IPDV not reported when only one packet is received?\n\n   [IPDV](https://en.wikipedia.org/wiki/Packet_delay_variation) is the\n   difference in delay between successfully returned replies, so at least two\n   reply packets are required to make this calculation.\n\n9) Why does wait fall back to fixed duration when duration is less than RTT?\n\n   If a full RTT has not elapsed, there is no way to know how long an\n\t appropriate wait time would be, so the wait falls back to a default fixed\n\t time (default is 4 seconds, same as ping).\n\n10) Why can't the client connect to the server, and I either see `[Drop]\n    [UnknownParam] unknown negotiation param (0x8 = 0)` on the server, or a strange\n    message on the client like `[InvalidServerRestriction] server tried to reduce\n    interval to \u003c 1s, from 1s to 92ns`?\n \n    You're using a 0.1 development version of the server with a newer client.\n    Make sure both client and server are up to date. Going forward, the protocol\n    is versioned (independently from IRTT in general), and is checked when the\n    client connects to the server. For now, the protocol versions must match\n    exactly.\n\n11) Why don't you include median values for send call time, timer error and\n    server processing time?\n\n    Those values aren't stored for each round trip, and it's difficult to do a\n    running calculation of the median, although\n    [this method](https://rhettinger.wordpress.com/2010/02/06/lost-knowledge/) of\n    using skip lists appears to have promise. It's a possibility for the future,\n    but so far it isn't a high priority. If it is for you, file an\n    [Issue](https://github.com/heistp/irtt/issues).\n\n12) I see you use MD5 for the HMAC. Isn't that insecure?\n\n    MD5 should not have practical vulnerabilities when used in a message authenticate\n    code. See\n    [this page](https://en.wikipedia.org/wiki/Hash-based_message_authentication_code#Security)\n    for more info.\n\n13) Are there any plans for translation to other languages?\n\n    While some parts of the API were designed to keep i18n possible, there is no\n    support for i18n built in to the Go standard libraries. It should be possible,\n    but could be a challenge, and is not something I'm likely to undertake myself.\n\n14) Why do I get `Error: failed to allocate results buffer for X round trips\n    (runtime error: makeslice: cap out of range)`?\n\n    Your test interval and duration probably require a results buffer that's\n    larger than Go can allocate on your platform. Lower either your test\n    interval or duration. See the following additional documentation for\n    reference: [In-memory results storage](#in-memory-results-storage),\n    `maxSliceCap` in [slice.go](https://golang.org/src/runtime/slice.go) and\n    `_MaxMem` in [malloc.go](https://golang.org/src/runtime/malloc.go).\n\n15) Why is little endian byte order used in the packet format?\n\n    As for Google's [protobufs](https://github.com/google/protobuf), this was\n    chosen because the vast majority of modern processors use little-endian byte\n    order. In the future, packet manipulation may be optimized for little-endian\n    architecutures by doing conversions with Go's\n    [unsafe](https://golang.org/pkg/unsafe/) package, but so far this\n    optimization has not been shown to be necessary.\n\n16) Why does `irtt client` use `-l` for packet length instead of following ping\n    and using `-s` for size?\n\n    I felt it more appropriate to follow the\n    [RFC 768](https://tools.ietf.org/html/rfc768) term _length_ for UDP packets,\n    since IRTT uses UDP.\n\n17) Why is the virt size (vsz) memory usage for the server so high in Linux?\n\n    This has to do with the way Go allocates memory, but should not cause a\n    problem. See [this\n    article](https://deferpanic.com/blog/understanding-golang-memory-usage/) for\n    more information. File an Issue if your resident usage (rss/res) is high or\n    you feel that memory consumption is somehow a problem.\n\n18) Why doesn't the server start on Linux when the kernel parameter\n    `ipv6.disable=1` is set?\n\n    By default, IRTT tries to listen on both IPv4 and IPv6 addresses, and for\n    safety, the server shuts down if there are failures on any of the\n    listeners for any of the addresses. In this case, the server may be\n    started with the `-4` flag.\n\n19) Why don't you make use of `x` library?\n\n    We need to keep the executable size as small as possible for embedded\n    devices, and most external libaries are not compatible with this.\n\n## Changes\n\nSee [CHANGES.md](CHANGES.md).\n\n## Roadmap\n\n### v0.9.2\n\n_Planned for v0.9.2..._\n\n- Refactor lconn, and make the srcSrcIP/ecn flag stuff independent.\n- Solidify TimeSource, Time and new Windows timer support:\n  - Add --timesrc to client and server\n  - Fall back to Go functions as necessary for older Windows versions\n  - Make sure all calls to TimeSource.Now pass in only needed clocks\n  - Find a better way to log warnings than fmt.Fprintf(os.Stderr) in timesrc_win.go\n  - Rename Time.Mono to Monotonic, or others from Monotonic to Mono for\n    consistency\n  - Document 100ns resolution for Windows\n- Improve diagnostic commands:\n  - Change bench command to output in columns\n  - Rename sleep command to timer and add --timesrc, --sleep, --timer and --tcomp\n  - Rename timer command to resolution and add --timesrc\n  - Rename clock command to drift and add --timesrc\n- Add a `late` flag to RoundTrip\n- Measure and document local differences between ping and irtt response times\n- Sync Debian package to history re-write and create backports version for Debian stable\n- Add `report` command, or similar, to print results from an existing JSON file\n\n### v1.0.0\n\n_Planned for v1.0.0..._\n\n- Refactor handshake params to use signed values and straight bytes as\n  appropriate.\n- Improve client output flexibility:\n  - Allow specifying a format string for text output with optional units for times\n  - Add format abbreviations for CSV, space delimited, etc.\n  - Add a subcommand to the CLI to convert JSON to CSV\n  - Add a way to disable per-packet results in JSON\n  - Add a way to keep out \"internal\" info from JSON, like IP and hostname, and a\n\t  subcommand to strip these out after the JSON is created\n  - Add more info on outliers and possibly a textual histogram\n- Refactor packet manipulation to improve readability, prevent multiple validations\n  and support unit tests\n- Add DSCP text values and return an error when ECN bits are passed to --dscp\n- Improve open/close process:\n  - Do Happy Eyeballs (RFC 8305) to better handle multiple address families and\n    addresses\n  - Make timeout support automatic exponential backoff, like 4x15s\n  - Repeat close packets until acknowledgement, like open\n  - Include final stats in the close acknowledgement from the server\n- Improve robustness and security of public servers:\n\t- Add bitrate limiting\n\t- Limit open requests rate and coordinate with sconn cleanup\n  - Add separate, shorter timeout for open\n  - Specify close timeout as param from client, which may be restricted\n\t- Add per-IP limiting\n- Add a more secure way than cmdline flag to specify --hmac\n- Stabilize API:\n  - Minimize exposed functions (remove timer, timer comp, etc)\n  - Always return instance of irtt.Error? If so, look at exitOnError.\n  - Use error code (if available) as exit code\n- Improve induced latency and jitter:\n  - Use Go profiling, scheduler tracing, strace and sar\n  - Do more thorough tests of `chrt -r 99`, `--thread` and `--gc`\n  - Find or file issue with Go team over scheduler performance, if needed\n  - Prototype doing thread scheduling or socket i/o for Linux in C\n- Show actual size of header in text and json, and add calculation to doc\n\n### Inbox\n\n_Collection area..._\n\n- Add [ping-pair](https://www.microsoft.com/en-us/research/wp-content/uploads/2017/09/PingPair-CoNEXT2017.pdf)-like functionality\n- Add UDP-lite support to allow partially damaged packets to be received\n- Add different server authentication modes:\n\t- none (no conn token in header, for minimum packet sizes during local use)\n\t- token (what we have today, 64-bit token in header)\n\t- nacl-hmac (hmac key negotiated with public/private key encryption)\n- Implement graceful server shutdown with sconn close\n- Implement zero-downtime restarts\n- Add a Scheduler interface to allow non-isochronous send schedules and variable\n  packet lengths\n  - Find some way to determine packet interval and length distributions for\n    captured traffic\n  - Determine if asymmetric send schedules (between client and server) required\n- Add an overhead test mode to compare ping vs irtt\n- Add client flag to skip sleep and catch up after timer misses\n- Add seqno to the Max and maybe Min columns in the text output\n- Prototype TCP throughput test and compare straight Go vs iperf/netperf\n- Support a range of server ports to improve concurrency and maybe defeat\n  latency \"slotting\" on multi-queue interfaces\n- Add more unit tests\n- Add support for load balanced conns (multiple source addresses for same conn)\n- Use unsafe package to speed up packet buffer manipulation\n- Add encryption\n- Add estimate for HMAC calculation time and correct send timestamp by this time\n- Implement web interface for client and server\n- Set DSCP per-packet, at least for IPv6\n- Add NAT hole punching\n- Use a larger, internal received window on the server to increase up/down loss accuracy\n- Allow specifying two out of three of interval, bitrate and packet size\n- Calculate per-packet arrival order during results generation using timestamps\n- Make it possible to add custom per-round-trip statistics programmatically\n- Allow Server to listen on multiple IPs for a hostname\n- Prompt to write JSON file on cancellation\n- Open questions:\n  - What do I do for IPDV when there are out of order packets?\n  - Does exposing both monotonic and wall clock values, as well as dual\n    timestamps, open the server to any timing attacks?\n  - Is there any way to make the server concurrent without inducing latency?\n  - Should I request a reserved IANA port?\n\n## Thanks\n\nMany thanks to both Toke Høiland-Jørgensen and Dave Täht from the\n[Bufferbloat project](https://www.bufferbloat.net/) for their valuable\nadvice. Any problems in design or implementation are entirely my own.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fheistp%2Firtt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fheistp%2Firtt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fheistp%2Firtt/lists"}