Repository navigation
v0.3.1
Features
Choose how progress is shown and match the terminal's colors
--progress picks the live view: panel, line (one status line that is redrawn in place, for small terminals) or plain (text lines for logs). The default, auto, uses the panel when the terminal is large enough and reports the cursor position, and the line view otherwise. It prints plain lines when stderr is not a terminal or TERM=dumb, so redirected stderr now shows each step and finished route.
--theme picks the colors. auto asks the terminal for its background color and uses RGB colors when COLORTERM announces true color. dark, light, dark-ansi and light-ansi set the colors directly.
Route tables that do not fit the terminal are printed with one short line per hop. (#21)
Fixes
Limit the size of the unpacked executable
The 64 MiB limit on release downloads now also applies to the executable unpacked from the archive, so a small, highly compressed archive can no longer make self update or the installer allocate far more memory. (#7, fixes #4)
Survive a closed stdout and print gateway text safely
When the reader of stdout goes away, as in xmtr --json host | head -1, xmtr no longer aborts; if the upload succeeded, the IPMap link is printed on stderr instead. Control characters in the trace ID, link and error text from the gateway are replaced with U+FFFD, so a gateway reply cannot send escape sequences to the terminal. (#19, fixes #12)
Keep the cursor query out of redirected output
Running xmtr in a terminal with stdout redirected, as in xmtr --json host > trace.json, wrote the escape sequence ESC [ 6 n at the start of the file, so the JSON did not parse. The panel now runs only when stdout is on the terminal. With stdout redirected, the line view shows progress on stderr. (#29, fixes #25)
Install with BusyBox wget and OpenWrt uclient-fetch
install.sh now passes --https-only to wget only when wget supports it. On Alpine, BusyBox and OpenWrt systems without curl, the script stopped with the wget usage text. (#16, fixes #9)
Upload to an IPv6 gateway address with a custom resolver
--api 'http://[::1]:8080' together with --dns failed with Label contains invalid characters, because the brackets reached the resolver. IPv6 literals now skip DNS like IPv4 literals do. (#6, fixes #3)
Accept very large time limits
A very large --time-limit, such as 18446744073709551615s, overflowed the round budget: debug builds panicked and release builds could stop after one round. The budget is now capped by --max-rounds for every accepted duration. (#5, fixes #2)
Keep route tables readable in narrow terminals
When stdout was a terminal too narrow for the route table, every column wrapped into a few characters, with Hos and t on separate lines. Now only long host names wrap. A table that still does not fit is printed as one line per hop, with the host, the average round trip and any loss. (#27, fixes #23)
Refuse release archives that do not contain an executable
xmtr self update and the installer now reject an archive whose xmtr entry is not a regular file or does not start with the executable header of the platform. Before, a directory, symlink or empty entry replaced the installed binary with an empty file and the update reported success. (#17, fixes #10)
Build release packages with the xmtr-ci project
The release workflow now runs through scripts/ci, one Python project that reads every target from a single table. The packages are the same apart from two metadata fields: <packageSourceUrl> in the Chocolatey nuspec points at scripts/ci/src/xmtr_ci/packages/chocolatey.py, and Generator in the wheel WHEEL file is xmtr-ci. (#1)
Show the short trace link in the README
Uploads return https://xmsl.dev/xmtr/<trace ID>, a short link that shows a preview when shared and opens the trace on IPMap. The README sample output and demo link now use it. (#22)
Keep parallel TCP traces running past 1024 open sockets
With about 24 or more TCP routes traced at once to targets that do not answer, xmtr aborted with fd must be in the range 0..FD_SETSIZE and printed nothing. The bundled trippy-core now waits on its sockets with poll, which has no descriptor limit. (#15, fixes #8)
Reject a time limit that fits no round
--time-limit must now be longer than --interval. A round ends after at least one interval, so shorter limits returned no hops and reported reachable targets as no probe was answered; such runs now stop with an argument error. (#18, fixes #11)