Giter VIP home page Giter VIP logo

irtt's Introduction

IRTT (Isochronous Round-Trip Tester)

IRTT measures round-trip time, one-way delay and other metrics using UDP packets sent on a fixed period, and produces both user and machine parseable output.

IRTT has reached version 0.9.1. I would appreciate any feedback, which you can send under Issues. However, it could be useful to first review the Roadmap section of the documentation before submitting a new bug or feature request.

Table of Contents

  1. Motivation
  2. Goals
  3. Features
  4. Limitations
  5. Installation
  6. Documentation
  7. Frequently Asked Questions
  8. Roadmap
  9. Changes
  10. Thanks

Motivation

Latency is an under-appreciated metric in network and application performance. As of this writing, many broadband connections are well past the point of diminishing returns when it comes to throughput, yet that’s what we continue to take as the primary measure of Internet performance. This is analogous to ordinary car buyers making top speed their first priority.

There is a certain hard to quantify but visceral “latency stress” that comes from waiting in expectation after a web page click, straining through a delayed and garbled VoIP conversation, or losing at your favorite online game (unless you like “lag” as an excuse). Those who work on reducing latency and improving network performance characteristics beyond just throughput may be driven by the idea of helping relieve this stress for others.

IRTT was originally written to improve the latency and packet loss measurements for the excellent Flent tool, but should be useful as a standalone tool as well. Flent was developed by and for the Bufferbloat project, which aims to reduce "chaotic and laggy network performance," making this project valuable to anyone who values their time and sanity while using the Internet.

Goals

The goals of this project are to:

  • Accurately measure latency and other relevant metrics of network behavior
  • Produce statistics via both human and machine parseable output
  • Provide for reasonably secure use on both public and private servers
  • Support small enough packet sizes for VoIP simulation
  • Support relevant socket options, including DSCP
  • Use a single UDP port for deployment simplicity
  • Keep the executable size small enough for use on embedded devices
  • Provide an API for embedding and extensibility

Features:

  • Measurement of:
  • Statistics: min, max, mean, median (for most quantities) and standard deviation
  • One nanosecond time precision on Linux and OS/X, and 100ns on Windows
  • Robustness in the face of clock drift and NTP corrections through the use of both wall and monotonic clocks
  • Binary protocol with negotiated format for test packet lengths down to 16 bytes (without timestamps)
  • HMAC support for private servers, preventing unauthorized discovery and use
  • Support for a wide range of Go supported platforms
  • Timer compensation to improve sleep send schedule accuracy
  • Support for IPv4 and IPv6
  • Public server protections, including:
    • Three-way handshake with returned 64-bit connection token, preventing reply redirection to spoofed source addresses
    • Limits on maximum test duration, minimum interval and maximum packet length, both advertised in the negotiation and enforced with hard limits to protect against rogue clients
    • Packet payload filling to prevent relaying of arbitrary traffic
  • Output to JSON
  • An available SmokePing probe (code)

Limitations

See the LIMITATIONS section of the irtt(1) man page.

Installation

To install IRTT manually or build from source, you must:

  1. Install Go
  2. Install irtt: go install github.com/heistp/irtt/cmd/irtt@latest
  3. For convenience, copy the irtt executable, which should be in $HOME/go/bin, or $GOPATH/bin if you have $GOPATH defined, to somewhere on your PATH.

If you want to build the source for development, you must also:

  1. Install the pandoc utility for generating man pages and HTML documentation from their markdown source files. This can be done with apt-get install pandoc on Debian flavors of Linux or brew install pandoc on OS/X. See the Pandoc site for more information.
  2. Install the stringer utility by doing go install golang.org/x/tools/cmd/stringer@latest. This is only necessary if you need to re-generate the *_string.go files that are generated by this tool, otherwise the checked in versions may also be used.
  3. Use build.sh to build during development, which helps with development related tasks, such as generating source files and docs, and cross-compiling for testing. For example, build.sh min linux-amd64 would compile a minimized binary for Linux on AMD64. See build.sh for more info and a "source-documented" list of platforms that the script supports. See this page for a full list of valid GOOS GOARCH combinations. build.sh install runs Go's install command, which puts the resulting executable in $GOPATH/bin.

If you want to build from a branch, you should first follow the steps above, then from the github.com/heistp/irtt directory, do:

  1. git checkout branch
  2. go get ./...
  3. go install ./cmd/irtt or ./build.sh and move resulting irtt executable to install location

Building for iOS:

I have no way to verify this, but I received a report that the following is "close to but not quite the right command" to cross-compile for iOS:

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

Please file an issue if you get this working so I can update the doc.

Documentation

After installing IRTT, see the man pages and their corresponding EXAMPLES sections to get started quickly:

Frequently Asked Questions

  1. Why not just use ping?

    Ping may be the preferred tool when measuring minimum latency, or for other reasons. IRTT's reported mean RTT is likely to be a bit higher (on the order of a couple hundred microseconds) and a bit more variable than the results reported by ping, due to the overhead of entering userspace, together with Go's system call overhead and scheduling variability. That said, this overhead should be negligible at most Internet RTTs, and there are advantages that IRTT has over ping when minimum RTT is not what you're measuring:

    • In addition to round-trip time, IRTT also measures OWD, IPDV and upstream vs downstream packet loss.
    • Some device vendors prioritize ICMP, so ping may not be an accurate measure of user-perceived latency.
    • IRTT can use HMACs to protect private servers from unauthorized discovery and use.
    • IRTT has a three-way handshake to prevent test traffic redirection from spoofed source IPs.
    • IRTT can fill the payload (if included) with random or arbitrary data.
    • On Windows, ping has a precision of 0.5ms, while IRTT uses high resolution timer functions for a precision of 100ns (high resolution wall clock only available on Windows 8 or Windows 2012 Server and later).

    Also note the following behavioral differences between ping and IRTT:

    • IRTT makes a stateful connection to the server, whereas ping is stateless.
    • By default, ping waits for a reply before sending its next request, while IRTT keeps sending requests on the specified interval regardless of whether or not replies are received. The effect of this, for example, is that a fixed-length pause in server packet processing (with packets buffered during the pause) will look like a single high RTT in ping, and multiple high then descending RTTs in IRTT for the duration of the maximum RTT.
  2. Is there a public server I can use?

    There is a test server running at irtt.heistp.net with an HMAC key of irttuser. Please do not abuse it. To restrict bandwidth, the minimum interval is set to 100ms, the max length to 256 bytes, and the max duration to 60 seconds. Example usage:

    irtt client --hmac=irttuser irtt.heistp.net

  3. How do I run the IRTT server at startup?

    This depends on your OS and init system, but see:

    • the irtt.service file for systemd, used in Debian and Ubuntu
    • the irtt.openrc file for OpenRC, used in Gentoo and Alpine
  4. Why can't the client connect to the server, and instead I get Error: no reply from server?

    There are a number of possible reasons for this:

    1. You've specified an incorrect hostname or IP address for the server.
    2. There is a firewall blocking packets from the client to the server. Traffic must be allowed on the chosen UDP port (default 2112).
    3. There is high packet loss. By default, up to four packets are sent when the client tries to connect to the server, using timeouts of 1, 2, 4 and 8 seconds. If all of these are lost, the client won't connect to the server. In environments with known high packet loss, the --timeouts flag may be used to send more packets with the chosen timeouts before abandoning the connection.
    4. The server has an HMAC key set with --hmac and the client either has not specified a key or it's incorrect. Make sure the client has the correct HMAC key, also specified with the --hmac flag.
    5. You're trying to connect to a listener that's listening on an unspecified IP address, but reply packets are coming back on a different route from the requests, or not coming back at all. This can happen in network environments with [asymmetric routing and a firewall or NAT] (https://www.cisco.com/web/services/news/ts_newsletter/tech/chalktalk/archives/200903.html). There are several possible solutions to this:
      • Change your network configuration to avoid the problem.
      • Have the IRTT server listen on specific addresses with the -b flag.
      • Use the --set-src-ip flag on the server, which explicitly sets the source address on all reply packets from listeners on unspecified IP addresses to the destination address that the request was received on. The only reason this is not done by default is to avoid the extra per-packet heap allocations required by the golang.org/x/net packege to do so.
  5. Why is the send (or receive) delay negative or much larger than I expect?

    The client and server clocks must be synchronized for one-way delay values to be meaningful (although, the relative change of send and receive delay may be useful to look at even without clock synchronization). Well-configured NTP hosts may be able to synchronize to within a few milliseconds. PTP (Linux implementation here) is capable of much higher precision. For example, using two PCEngines APU2 boards (which support PTP hardware timestamps) connected directly by Ethernet, the clocks may be synchronized within a few microseconds.

    Note that client and server synchronization is not needed for either RTT or IPDV (even send and receive IPDV) values to be correct. RTT is measured with client times only, and since IPDV is measuring differences between successive packets, it's not affected by time synchronization.

  6. Why is the receive rate 0 when a single packet is sent?

    Receive rate is measured from the time the first packet is received to the time the last packet is received. For a single packet, those times are the same.

  7. Why does a test with a one second duration and 200ms interval run for around 800ms and not one second?

    The test duration is exclusive, meaning requests will not be sent exactly at or after the test duration has elapsed. In this case, the interval is 200ms, and the fifth and final request is sent at around 800ms from the start of the test. The test ends when all replies have been received from the server, so it may end shortly after 800ms. If there are any outstanding packets, the wait time is observed, which by default is a multiple of the maximum RTT.

  8. Why is IPDV not reported when only one packet is received?

    IPDV is the difference in delay between successfully returned replies, so at least two reply packets are required to make this calculation.

  9. Why does wait fall back to fixed duration when duration is less than RTT?

    If a full RTT has not elapsed, there is no way to know how long an appropriate wait time would be, so the wait falls back to a default fixed time (default is 4 seconds, same as ping).

  10. Why can't the client connect to the server, and I either see [Drop] [UnknownParam] unknown negotiation param (0x8 = 0) on the server, or a strange message on the client like [InvalidServerRestriction] server tried to reduce interval to < 1s, from 1s to 92ns?

    You're using a 0.1 development version of the server with a newer client. Make sure both client and server are up to date. Going forward, the protocol is versioned (independently from IRTT in general), and is checked when the client connects to the server. For now, the protocol versions must match exactly.

  11. Why don't you include median values for send call time, timer error and server processing time?

    Those values aren't stored for each round trip, and it's difficult to do a running calculation of the median, although this method of using skip lists appears to have promise. It's a possibility for the future, but so far it isn't a high priority. If it is for you, file an Issue.

  12. I see you use MD5 for the HMAC. Isn't that insecure?

    MD5 should not have practical vulnerabilities when used in a message authenticate code. See this page for more info.

  13. Are there any plans for translation to other languages?

    While some parts of the API were designed to keep i18n possible, there is no support for i18n built in to the Go standard libraries. It should be possible, but could be a challenge, and is not something I'm likely to undertake myself.

  14. Why do I get Error: failed to allocate results buffer for X round trips (runtime error: makeslice: cap out of range)?

    Your test interval and duration probably require a results buffer that's larger than Go can allocate on your platform. Lower either your test interval or duration. See the following additional documentation for reference: In-memory results storage, maxSliceCap in slice.go and _MaxMem in malloc.go.

  15. Why is little endian byte order used in the packet format?

    As for Google's protobufs, this was chosen because the vast majority of modern processors use little-endian byte order. In the future, packet manipulation may be optimized for little-endian architecutures by doing conversions with Go's unsafe package, but so far this optimization has not been shown to be necessary.

  16. Why does irtt client use -l for packet length instead of following ping and using -s for size?

    I felt it more appropriate to follow the RFC 768 term length for UDP packets, since IRTT uses UDP.

  17. Why is the virt size (vsz) memory usage for the server so high in Linux?

    This has to do with the way Go allocates memory, but should not cause a problem. See this article for more information. File an Issue if your resident usage (rss/res) is high or you feel that memory consumption is somehow a problem.

  18. Why doesn't the server start on Linux when the kernel parameter ipv6.disable=1 is set?

    By default, IRTT tries to listen on both IPv4 and IPv6 addresses, and for safety, the server shuts down if there are failures on any of the listeners for any of the addresses. In this case, the server may be started with the -4 flag.

  19. Why don't you make use of x library?

    We need to keep the executable size as small as possible for embedded devices, and most external libaries are not compatible with this.

Changes

See CHANGES.md.

Roadmap

v0.9.2

Planned for v0.9.2...

  • Refactor lconn, and make the srcSrcIP/ecn flag stuff independent.
  • Solidify TimeSource, Time and new Windows timer support:
    • Add --timesrc to client and server
    • Fall back to Go functions as necessary for older Windows versions
    • Make sure all calls to TimeSource.Now pass in only needed clocks
    • Find a better way to log warnings than fmt.Fprintf(os.Stderr) in timesrc_win.go
    • Rename Time.Mono to Monotonic, or others from Monotonic to Mono for consistency
    • Document 100ns resolution for Windows
  • Improve diagnostic commands:
    • Change bench command to output in columns
    • Rename sleep command to timer and add --timesrc, --sleep, --timer and --tcomp
    • Rename timer command to resolution and add --timesrc
    • Rename clock command to drift and add --timesrc
  • Add a late flag to RoundTrip
  • Measure and document local differences between ping and irtt response times
  • Sync Debian package to history re-write and create backports version for Debian stable
  • Add report command, or similar, to print results from an existing JSON file

v1.0.0

Planned for v1.0.0...

  • Refactor handshake params to use signed values and straight bytes as appropriate.
  • Improve client output flexibility:
    • Allow specifying a format string for text output with optional units for times
    • Add format abbreviations for CSV, space delimited, etc.
    • Add a subcommand to the CLI to convert JSON to CSV
    • Add a way to disable per-packet results in JSON
    • Add a way to keep out "internal" info from JSON, like IP and hostname, and a subcommand to strip these out after the JSON is created
    • Add more info on outliers and possibly a textual histogram
  • Refactor packet manipulation to improve readability, prevent multiple validations and support unit tests
  • Add DSCP text values and return an error when ECN bits are passed to --dscp
  • Improve open/close process:
    • Do Happy Eyeballs (RFC 8305) to better handle multiple address families and addresses
    • Make timeout support automatic exponential backoff, like 4x15s
    • Repeat close packets until acknowledgement, like open
    • Include final stats in the close acknowledgement from the server
  • Improve robustness and security of public servers:
    • Add bitrate limiting
    • Limit open requests rate and coordinate with sconn cleanup
    • Add separate, shorter timeout for open
    • Specify close timeout as param from client, which may be restricted
      • Add per-IP limiting
  • Add a more secure way than cmdline flag to specify --hmac
  • Stabilize API:
    • Minimize exposed functions (remove timer, timer comp, etc)
    • Always return instance of irtt.Error? If so, look at exitOnError.
    • Use error code (if available) as exit code
  • Improve induced latency and jitter:
    • Use Go profiling, scheduler tracing, strace and sar
    • Do more thorough tests of chrt -r 99, --thread and --gc
    • Find or file issue with Go team over scheduler performance, if needed
    • Prototype doing thread scheduling or socket i/o for Linux in C
  • Show actual size of header in text and json, and add calculation to doc

Inbox

Collection area...

  • Add ping-pair-like functionality
  • Add UDP-lite support to allow partially damaged packets to be received
  • Add different server authentication modes:
    • none (no conn token in header, for minimum packet sizes during local use)
    • token (what we have today, 64-bit token in header)
    • nacl-hmac (hmac key negotiated with public/private key encryption)
  • Implement graceful server shutdown with sconn close
  • Implement zero-downtime restarts
  • Add a Scheduler interface to allow non-isochronous send schedules and variable packet lengths
    • Find some way to determine packet interval and length distributions for captured traffic
    • Determine if asymmetric send schedules (between client and server) required
  • Add an overhead test mode to compare ping vs irtt
  • Add client flag to skip sleep and catch up after timer misses
  • Add seqno to the Max and maybe Min columns in the text output
  • Prototype TCP throughput test and compare straight Go vs iperf/netperf
  • Support a range of server ports to improve concurrency and maybe defeat latency "slotting" on multi-queue interfaces
  • Add more unit tests
  • Add support for load balanced conns (multiple source addresses for same conn)
  • Use unsafe package to speed up packet buffer manipulation
  • Add encryption
  • Add estimate for HMAC calculation time and correct send timestamp by this time
  • Implement web interface for client and server
  • Set DSCP per-packet, at least for IPv6
  • Add NAT hole punching
  • Use a larger, internal received window on the server to increase up/down loss accuracy
  • Allow specifying two out of three of interval, bitrate and packet size
  • Calculate per-packet arrival order during results generation using timestamps
  • Make it possible to add custom per-round-trip statistics programmatically
  • Allow Server to listen on multiple IPs for a hostname
  • Prompt to write JSON file on cancellation
  • Open questions:
    • What do I do for IPDV when there are out of order packets?
    • Does exposing both monotonic and wall clock values, as well as dual timestamps, open the server to any timing attacks?
    • Is there any way to make the server concurrent without inducing latency?
    • Should I request a reserved IANA port?

Thanks

Many thanks to both Toke Høiland-Jørgensen and Dave Täht from the Bufferbloat project for their valuable advice. Any problems in design or implementation are entirely my own.

irtt's People

Contributors

eric-s-raymond avatar heistp avatar mmlb avatar tohojo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

irtt's Issues

Support for continuous use for connection monitoring?

A speculative question.. Is there any interest in a mode for IRTT where it operates continuously, for monitoring? The tool right now wants to run for N seconds and then print summary stats at the end. I want something that runs continuously, indefinitely, and occasionally emits data suitable for collection in a monitoring system like Grafana.

Right now I'm running the tool for 58 seconds every minute from telegraf, like a cron job. This works OK but it's kind of awkward, it creates discontinuities at the restarts. (And because of telegraf limitations a run has to exit before the next can start.) I'd also appreciate being able to get stats during the 60 second run, like a rolling moving average of median RTT or packet loss. (possibly exponentially weighted.)

Macosx 10.12.6 irtt clock

bash-3.2$ uname -a
Darwin hms-beagle2.local 16.7.0 Darwin Kernel Version 16.7.0: Wed Oct 4 00:17:00 PDT 2017; root:xnu-3789.71.6~1/RELEASE_X86_64 x86_64
bash-3.2$ irtt clock
Testing wall vs monotonic clocks...

     Monotonic              Wall   Wall-Monotonic   Wall Drift / Second	
          31ns              31ns               0s                    0s
  1.004843916s      1.004843916s               0s                    0s
   2.00859407s       2.00854707s            -47µs             -23.399µs
  3.011850648s      3.011803648s            -47µs             -15.605µs
  4.012266459s      4.012172459s            -94µs             -23.428µs
  5.012448021s      5.012354021s            -94µs             -18.753µs
  6.017632952s      6.017490952s           -142µs             -23.597µs
  7.022266934s      7.022124934s           -142µs             -20.221µs
  8.027482605s      8.027293605s           -189µs             -23.544µs
  9.029592262s      9.029403262s           -189µs             -20.931µs

     Monotonic              Wall   Wall-Monotonic   Wall Drift / Second	
 10.034701027s     10.034465027s           -236µs             -23.518µs
 11.038663312s     11.038427312s           -236µs             -21.379µs
 12.040153662s     12.039870662s           -283µs             -23.504µs
 13.041516939s     13.041233939s           -283µs             -21.699µs
 14.042727691s     14.042397691s           -330µs             -23.499µs
  15.04444393s      15.04411393s           -330µs             -21.935µs
 16.046998999s     16.046621999s           -377µs             -23.493µs
 17.050234553s     17.049857553s           -377µs             -22.111µs
 18.054029129s     18.053605129s           -424µs             -23.485µs
 19.059090807s     19.058666807s           -424µs             -22.246µs

     Monotonic              Wall   Wall-Monotonic   Wall Drift / Second	
 20.061734558s     20.061263558s           -471µs             -23.477µs

^C
bash-3.2$ sudo irtt clock

Testing wall vs monotonic clocks...

         Monotonic              Wall   Wall-Monotonic   Wall Drift / Second	
              27ns              27ns               0s                    0s
      1.004612908s      1.004565908s            -47µs             -46.784µs
      2.007071209s      2.007024209s            -47µs             -23.417µs
      3.010969943s      3.010875943s            -94µs             -31.219µs
      4.013890093s      4.013796093s            -94µs             -23.418µs
      5.015685871s      5.015544871s           -141µs             -28.111µs
      6.019656637s      6.019515637s           -141µs             -23.423µs
      7.024592735s      7.024404735s           -188µs             -26.763µs
      8.025272681s      8.025084681s           -188µs             -23.425µs
       9.02959961s       9.02936461s           -235µs             -26.025µs

         Monotonic              Wall   Wall-Monotonic   Wall Drift / Second	
     10.032041975s     10.031806975s           -235µs             -23.424µs
     11.037099453s     11.036817453s           -282µs              -25.55µs
     12.042050044s     12.041768044s           -282µs             -23.417µs
     13.044367277s     13.044037277s           -330µs             -25.298µs
     14.046980878s     14.046650878s           -330µs             -23.492µs
     15.051992904s     15.051615904s           -377µs             -25.046µs
     16.056293646s     16.055916646s           -377µs             -23.479µs
     17.060556787s     17.060132787s           -424µs             -24.852µs
     18.063871466s     18.063447466s           -424µs             -23.472µs
     19.068772835s     19.068301835s           -471µs               -24.7µs

         Monotonic              Wall   Wall-Monotonic   Wall Drift / Second	
     20.073744461s     20.073273461s           -471µs             -23.463µs
^C
bash-3.2$ 

use irtt as a library

Hello,

I am working on a project where I need to implement system that will run multiple scheduled IRTT jobs (clients). I started with cron jobs that run bunch of irtt every min, than moved to exec plugin for telegraf, and now I am thinking to (learn golang and) write "simple" scheduler in golang that will use IRTT as library and run jobs in more controlled way (so i can distribute client test sessions to different CPUs)

Is it something that can(should) be done ? Do you have documentation/examples for API ?

Thank you!

Suprious DropBadMagic errors?

I've had the irtt server running for a while now, but had not gotten around to opening up the firewall to the public internet. Looking at the logs, I get a bunch of DropBadMagic errors:

Nov 24 19:57:12 irtt[18073]: [DropBadMagic] bad magic: 265083 != 14a75b
Nov 24 19:57:17 irtt[18073]: [DropBadMagic] bad magic: 265083 != 14a75b
Nov 25 11:56:22 irtt[18073]: [DropBadMagic] bad magic: 84e783 != 14a75b
Nov 25 11:56:27 irtt[18073]: [DropBadMagic] bad magic: 84e783 != 14a75b
Nov 25 13:34:13 irtt[18073]: [DropBadMagic] bad magic: 6c0481 != 14a75b
Nov 26 01:00:10 irtt[18073]: [DropBadMagic] bad magic: eb4d83 != 14a75b
Nov 26 01:00:15 irtt[18073]: [DropBadMagic] bad magic: eb4d83 != 14a75b
Nov 26 08:12:12 irtt[18073]: [DropBadMagic] bad magic: dd7781 != 14a75b
Nov 26 08:12:17 irtt[18073]: [DropBadMagic] bad magic: dd7781 != 14a75b
Nov 26 18:01:26 irtt[18073]: [DropBadMagic] bad magic: c85d83 != 14a75b
Nov 26 18:01:31 irtt[18073]: [DropBadMagic] bad magic: c85d83 != 14a75b
Nov 27 15:23:20 irtt[18073]: [DropBadMagic] bad magic: bffb81 != 14a75b
Nov 27 15:23:25 irtt[18073]: [DropBadMagic] bad magic: bffb81 != 14a75b
Nov 28 02:33:05 irtt[18073]: [DropBadMagic] bad magic: f3db83 != 14a75b
Nov 28 02:33:10 irtt[18073]: [DropBadMagic] bad magic: f3db83 != 14a75b
Nov 28 04:24:19 irtt[18073]: [DropBadMagic] bad magic: 338383 != 14a75b
Nov 28 04:24:24 irtt[18073]: [DropBadMagic] bad magic: 338383 != 14a75b
Nov 29 04:22:56 irtt[18073]: [DropBadMagic] bad magic: 599483 != 14a75b
Nov 29 14:23:29 irtt[18073]: [DropBadMagic] bad magic: aae681 != 14a75b
Nov 29 14:23:34 irtt[18073]: [DropBadMagic] bad magic: aae681 != 14a75b
Nov 29 17:19:01 irtt[18073]: [DropBadMagic] bad magic: 355381 != 14a75b
Nov 29 17:19:06 irtt[18073]: [DropBadMagic] bad magic: 355381 != 14a75b

The odd thing is that no tests have been run at any of these times; so is there something else going on related to a long-running server?

The VmSize of the long-running process is 1196928 kB while a newly started server shows 383376 kB - but I don't know if it is growing over time or if its just because there have been a couple of tests run against the long-running server.

Client Port

The port on the client side seems to be random. Could a feature be added to set the client side port?

switch to Lookup* methods for name resolution

We use ResolveUDPAddr to convert host names to IP addresses, for but "historical reasons", this prefers IPv4 over IPv6, despite the ordering that the local resolver uses (sort of related: golang/go#20911). This isn't the correct behavior. If we switch to one of the Lookup* methods (LookupIP?), that should give us addresses in the order returned by the local resolver.

There are multiple places this is called, there's listen addresses to worry about, and whether or not this works with and without cgo, etc, so this may take some care to get right.

Allow specifying bind interfaces in addition to addresses

When deploying irtt to my testbed, I have several boxes with the same interface names but with diffent IPs assigned to each interface. It would be useful to be able to specify the interface name to -b instead of the address, since I can then just reuse the same systemd unit file.

smokeping probe configuration

Trying to setup the smokeping probe for irtt, but I'm running into some odd behavior. In the graph, it implies I'm losing about 50% of packets all the time. While my internet is indeed quite bad, it's not that bad. The confusing part is on the lower bit of the graph, it will say only like 1% loss at a period where the graph shows the 50% loss. ie. 300/600 packets dropped. I'm certain I've messed up some configuration here, but don't quite understand where I've gone wrong.

My configuration and an example of what I'm seeing are attached.

smokeping

smokeping-irtt.txt

allow IPv6 addresses without brackets

Currently, we require brackets around IPv6 addresses to distinguish them from the port. This comes from Go's net.Dial(), but external tools might not expect this, and we could be more "liberal with what we accept". If the address looks like an IPv6 address, we should surround it with brackets automatically.

"ShortReply" error when running on Windows

Not sure Windows is a supported platform or not but compiles without issues. When running I always get from the client:

Terminated due to receive error: [ShortReply] received short reply (44 bytes)

Server doesn't have much information other than "NewConn" and "CloseConn" logs. Enabling HMAC increases the packet size in the error from 44 to 60 bytes but still has the same error.

Packet capture shows (bytes refers to UDP payload not the entire packet):
Client->Server: 25 bytes
Server->Client: 33 bytes
Client->Server: 60 bytes
Server->Client: 44 bytes
Client->Server: 12 bytes

Roadmap suggestion: Prometheus integration

First thank you for your work on this great project which I have only discovered today !

Could I put the idea in your minds to add Prometheus integration to irtt.

To be more specific:

  • irtt-client support for Prometheus text-based exposition. This would enable irtt-client to publish output in a directory for collection by node_exporterwhen running with the --collector.textfile.directory flag; and/or
  • irtt-server publish a http metrics page for Prometheus to scrape

Given that both irtt and prometheus are written in Go and prometheus publish Go libraries, I think this should be relatively straightforward to implement. I'm a noob to Go programming but even I managed to hack together something (for my own personal unrelated project) that exports to text file using the following calls from the Prometheus go library:

import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/expfmt"
)

# Create registry
reg := prometheus.NewRegistry()
var collectors []prometheus.Collector

# Gauge / Counters (Repeated as required)
gauge := prometheus.NewGauge(prometheus.GaugeOpts{}) 
gauge.Set(value)
collectors = append(
  collectors,
  gauge,
  )

# Collect and export to text file
reg.MustRegister(collectors...)
gathered, err := reg.Gather()
for _, item := range gathered {
  _, err := expfmt.MetricFamilyToText(
  tmp,
  item,
  )

RTTs can be highly inaccurate on Windows

The Windows client can show round-trip times that are zero or even negative, regardless of whether the wall or monotonic clock values are used (tested on VMWare Win 10 32-bit, Go 1.10.2).

Thanks for irtt

Hi, This library is a great work and this issue is mostly here to thank you for it.

I would also want to discuss if you would welcome a PR to simplify a few bits?
For example, we could make use of viper/cobra for the CLI, define custom types in structs, etc.

Would you be open to this idea?

being able to plot cleanly from the command line

from this thread over here:

https://forum.openwrt.org/t/validating-nss-fq-codels-correctness/111123/33

I've longed to plot dynamically the output of a high resolution irtt sample, but the output has two problems in that it uses mixed units (us, ms, s), and the one way delay measurements require a sync'd clock. the rtt measurement does not. (ok, that's three problems).

The json output doesn't use mixed units but requires the test complete before plotting. four problems. A command line option to always use ns would help.

a typical test I do is:

irtt client -i3ms -d1m --dscp=0xfe

and then I parse that with tr, awk and gnuplot. There isn't a way to send the json output (-o whatever.json) to a stream either. I have some really cool plots of how starlink works but haven't twiddled it enough to do one way delay yet (five problems).

ios version?

I was under the impression that irtt had been ported to ios, but I don't see it. It looks straightforward to cross compile from osx, but haven't tried it. Does there exist an irtt version for ios already?

README.md `go get` is deprecated

Step 2 of:
https://github.com/heistp/irtt#installation

recommends the use of go get -u github.com/heistp/irtt/cmd/irtt to install irtt

this command fails for me, with a message that go get is no longer supported outside a module. Apparently this method is deprecated as of go 1.17 (see https://go.dev/doc/go-get-install-deprecation). The error message helpfully suggests using a go install command, which worked:

go install github.com/heistp/irtt/cmd/irtt@latest

I suggest updating README.md to reference this command instead of go get

Default server mode doesn't discover new addresses and interfaces

Since the default for the server now is to explicitly listen on each active address, irtt will no longer automatically listen on new interfaces or even new addresses on existing ones. This makes it a bit harder to run a long-running irtt server instance on a machine that changes addresses (and can even lead to problems if irtt is started at boot before all interfaces are fully configured).

Unfortunately, I don't believe the Go standard library has an interface for discovering new addresses. It's not a huge amount of code to subscribe to updates via netlink (I implemented this in a tool of mine: https://github.com/tohojo/nsregd/blob/master/nsregc.go#L281), but it does require pulling in a netlink library, and it's obviously not portable.

Macosx 10.12.6 irtt sleep results

bash-3.2$ irtt sleep
Testing sleep accuracy...

Sleep Duration        Mean Error       % Error
           1ns             319ns       31920.4
          10ns             309ns        3094.7
         100ns             218ns         218.6
           1µs           5.515µs         551.5
          10µs           8.759µs          87.6
         100µs          32.912µs          32.9
           1ms         329.167µs          32.9
          10ms        1.792291ms          17.9
         100ms         2.73035ms           2.7
         200ms        3.271282ms           1.6
         500ms        1.748611ms           0.3


bash-3.2$ sudo irtt sleep
Password:
Testing sleep accuracy...

Sleep Duration        Mean Error       % Error
           1ns             316ns       31669.5
          10ns             308ns        3081.6
         100ns             218ns         218.5
           1µs           5.612µs         561.2
          10µs           8.878µs          88.8
         100µs          33.061µs          33.1
           1ms         326.339µs          32.6
          10ms         1.95625ms          19.6
         100ms        2.811226ms           2.8
         200ms        2.738883ms           1.4
         500ms         3.74202ms           0.7
bash-3.2$ uname -a
Darwin hms-beagle2.local 16.7.0 Darwin Kernel Version 16.7.0: Wed Oct  4 00:17:00 PDT 2017; root:xnu-3789.71.6~1/RELEASE_X86_64 x86_64
bash-3.2$ 

Out of order command line parameters are silently ignored

I've been bitten by this a couple of times now, and got annoyed enough to open a bug.

Basically, this will work:

irtt client -d 5s localhost

whereas this will appear to work but will silently ignore the parameter and keep running for an hour:

irtt client localhost -d 5s

Ideally, the order of parameters shouldn't matter. But if the switches are required to be at the beginning,
at least an error should be raised if they are not...

IRTT and Cloudflare tunneling support/setup?

I am trying to getting IRTT Server to work with Cloudflare(d) Tunneling Access service. Explanation and documentation here https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/

I have done the following:
Using the WARP client which allows UDP packets, which this documentation has said it uses - it cannot connect to the host server from the client terminal over the domain using my own domain and tunneling settings with the port of 2112.
Using the basic tunneling option over HTTP, HTTPS, SMD, SSH and TCP service with localhost as the address, also the server in the terminal irtt server -b irtt.XXXXX.com:2112 -d 0 -i 0 --hmac=XXXXX --fill=rand and irtt server -b localhost:2112 -d 0 -i 0 --hmac=XXXXX --fill=rand - same story, it cannot connect to the host server from the client terminal over the domain using my own domain and tunneling settings with the port of 2112 or any other one.

It works only in the local internet environment and perfectly without any hiccups.

I do not have any option to open up the ports through my own home ISP nor the university laboratories due to security concerns, which is why I use and force to use tunneling. Tunneling has been successful before and the reason why I am trying to get it to work with hosting a smokeping service and website to do my research in internet load latency measurement and networking. Currently relegating to use fping and DNS's dig probes instead as a replacement to get data from my satellite connected smokeping's child's packet to the parent.

Consider switching to crypto/Rand

Given that crypto/Rand uses /dev/urandom or its equivalent on on other platforms, are there any good reasons not to switch away from math/Rand to crypto/Rand.

Indeed, your own documentation seems to suggest this would be a good idea, because you state (in irtt-server man page) that:

Allowing non-random fills insecure on public servers

But then you're not really doing much to help secure public servers if you then go and use math/Rand.

At least if you are not willing to replace it, you should provide crypto/Rand as a config option, e.g. --fill=crypto.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.