Repository navigation
Releases: LambdaBytes/sping
Releases · LambdaBytes/sping
Release list
v1.6.0
Immutable
release. Only release title and notes can be modified.
Added
- Static Linux binaries,
sping-vX.Y.Z-linux-x86_64-musland
sping-vX.Y.Z-linux-aarch64-musl: built against musl, they need no glibc and
run on any Linux of their architecture, Alpine and older systems included.
They resolve names without the system's NSS modules (see the README's known
limitations). - TCP connect probe,
--tcp PORT: times the TCP handshake with the port
instead of sending ICMP echoes, in every mode and view. It needs no ICMP
permission and gets through networks that filter ICMP. An open port and a
refused one both count as answers (Connected to/Refused by; the
summary counts the refusals); no answer before-Wis a loss. On Windows a
probe is a single SYN, so that a refusal answers at once (Windows otherwise
retries for about 2 s); there the wait is about 3 s at most.-t,-S
(bound on Windows too) and-I(as with ICMP) apply;-sis rejected. A
source address that cannot be used exits with code 2. JSON lines gain
probe,port,refusedandtcp_state, in TCP mode only. - The diagnosis in JSON: lines gain
diagnosis, the findings shown on the
Events line as stable codes with their evidence (intermittent_losswith
recent_loss_pct,upstream_outage,tcp_refusedwithport…), and in
single-target modegatewayandwan, the auxiliary probes' state
(online,offline,unknown) it is drawn from. Each is absent when it
has nothing to say; batch lines carry the target's diagnosis. See
JSON_CONTRACT.md.
Changed
- Quality grades have names that do not clash with the trend:
A (95) · excellent, thengood,fairandpoor(the trend keepsstable,
improving,degrading). JSON keeps"A"…"D". - The OS hint after the TTL appears only while the TTL is still an initial
value:ttl 64 (Unix-like),ttl 128 (Windows),ttl 255 (network).
Past a router the TTL no longer says what answered (8.8.8.8 was shown as
Windows), and 64 is macOS and the BSDs as much as Linux. - A loopback target (
127.0.0.0/8,::1) isloopback, notrouted internal. JSON keeps"RoutedInternal"for it. - With no source address for the target's family (an IPv6 target on a host
without IPv6) theInit:andContextlines sayno IPv6 sourceinstead
of0.0.0.0/0on the default route's interface. - A WAN outage while nothing is known about the gateway reads
WAN unreachable · gateway state unknowninstead ofupstream outage likely. - TCP: the compact and extended views say how the last connect ended at the
head of Events:TCP 443 connected · 21 ms,TCP 443 refused · host or firewall answered,TCP 443 timeout · no answer. The Status line no
longer repeats it. - Batch and table: an address given with its zone (
fe80::1%eth0) is shown
once, not followed by the same address in parentheses. - Scoring: the
high jitter with no losswarning reads the same 20 probes
and the same jitter measure as the quality grade (it read the whole
session's jitter), and appears exactly when the grade takes its largest
jitter penalty. - Scoring: changes and deviations under 0.1 ms are noise. Loopback and fast
LAN targets no longer turndegrading/improvingor lose 10-20 quality
points over tens of microseconds; a LAN going from 0.3 to 0.9 ms is still
degrading. - The trend counts losses: two or more lost probes more in the recent half
of the window than in the older one isdegrading(an outage was
unknown), as many fewerimproving. When loss and latency disagree,
degradingwins. JSONquality_scoreandtrendchange accordingly;
their types and values are the same. - README: one recording of 1.6.0 replaces the three earlier ones (the
compact view, the tour and the 1.5.5 comparison); the install methods
and the features of every version are listed.
Packaging
build.rswrites the man page and the shell completions to Cargo's
OUT_DIR(assets/man,assets/completions), no longer into the source
tree:cargo installfrom a read-only source works. A packager that wants
them at a fixed path setsSPING_ASSETS_DIRto an absolute directory (the
release builds and the Arch recipes use$PWD/target/assets).- The macOS release binary is always signed and notarized: a release build
without the signing setup fails instead of shipping it unsigned. - nixpkgs package validation: a workflow builds the nixpkgs recipe from each
release tag. sping is not in nixpkgs until that recipe is merged there. - Homebrew:
brew install LambdaBytes/tap/spingbuilds the release from
source and installs the man page and the shell completions too. A
published release goes to the tap and to crates.io on its own.
Fixes
- The interface of a loopback target:
if lo · 127.0.0.1/8(lo0on macOS,
the loopback adapter on Windows) instead of the default route's interface
with/0— on Windows its address (if 192.168.6.233 · 127.0.0.1/0).
JSONnet_ctxgets the sameinterfaceandprefix_len. - Without a source address no interface is looked up: JSON
net_ctxhas
"interface": "unknown"and"prefix_len": 0, as documented, instead of
the interface of whatever route covered0.0.0.0— with a VPN's
0.0.0.0/1that also put the target in its subnet ("SameLan"). For the
same reason a VPN's0.0.0.0/1no longer puts127.0.0.1in"SameLan". - macOS: the gateway and the interfaces were missing when sping ran with a
PATHwithout/sbin(cron runs its jobs with/usr/bin:/bin):route
andifconfignow run from/sbin.
v1.5.5
Immutable
release. Only release title and notes can be modified.
Fixes
- IPv6 link-local targets with a zone work:
sping fe80::1%eth0(interface
name, or its index:fe80::1%2; Windows takes the index). The zone given
on the command line was dropped after resolution, so the probe failed with
send failed: Invalid argumentand theInit:line showed0.0.0.0/0.
The same address in two zones counts as two targets, and a link-local
-Ssource is bound in the target's zone. Without a zone a link-local
target still cannot be reached on Linux; an unknown zone is reported as
such. - Windows: interface names, addresses and prefix lengths come from the
system's adapter list instead of the textipconfigprints. On a
non-English Windows theInit:andContextlines showed the whole
localized header (if Adaptador de Ethernet Ethernet 3) as the interface
name; they now show the adapter's name (if Ethernet 3). IPv6 addresses get
their real prefix length, so an IPv6 target in the local prefix issame LAN.ipconfigis still read if the system call fails. - macOS: ICMPv6 replies carry their hop limit in the
ttlcolumn, as on
Linux since 1.5.4. - macOS: with several IPv6 targets a reply could be counted for the wrong
one, since there every ICMPv6 socket receives every echo reply. Each probe
socket now has its own echo identifier and accepts only the replies that
carry it. - Multi-target and batch modes: each target gets its own network context.
Every target carried the context of the first one, sonet_ctxin the JSON
output (interface, source address, class) was wrong for the others. - Single target: after a DNS failover to another address, the context is
detected again for the new address instead of staying on the old one.
Release
- Every file of a GitHub release has a build provenance attestation:
gh attestation verify <file> --repo <owner>/<repo>tells which commit and
workflow run produced it. - The macOS binary is signed with a Developer ID and notarized by Apple: it
runs without removing the quarantine attribute first. - sping is on crates.io:
cargo install spingbuilds and installs the binary. - The Linux binaries and .deb packages of a GitHub release are built on
Debian 12: they need glibc 2.34 instead of 2.39, so they run on Debian 12
and Ubuntu 22.04. The release stops if a Linux binary would need a newer
glibc. - The arm64 .deb asks for libc6 2.34, what its binary needs, instead of 2.36,
so it installs on Ubuntu 22.04 too.
v1.5.4
Fixes
- Windows: ASCII output is selected automatically on the legacy console host
(cmd.exe / PowerShell outside Windows Terminal, VS Code, ConEmu), whose
fonts draw the pulse blocks and the spinner as boxes.SPING_ASCII=0forces
the Unicode charset on any terminal. - The ASCII pulse uses four marks of increasing height (
_-=")
instead of eight unrelated ones. - IPv6 targets: the
Init:andContextlines show the real source address,
interface and prefix (if lo · ::1/128) instead of0.0.0.0/0, and the
target is classified like IPv4 (::1and unique-localfc00::/7are
routed internal, an address inside the local prefix issame LAN);::1
was reported aspublic. Linux: ICMPv6 replies now carry their hop limit
in thettlcolumn; it was0.
Docs
- README: project logo. The logo and the recordings carry no provenance
manifest or tool metadata, only what the image format needs.
v1.5.3
Fixes
--ascii(and non-UTF-8 locales): the gateway/WAN indicators on the
Contextline (oup,xdown,?unknown) and thexin the batch
banner follow the charset; the output is now pure ASCII in that mode.
Docs
- README: a demo recording at the top and an 80-second tour of every view and
mode at the end; the examples are real output of this version.
v1.5.2
Fixes
- TUI views (compact, extended, table): a line wider than the terminal no
longer breaks the in-place redraw. In an 80-column terminal theLatency
line is 81 columns wide with typical RTT values; it wrapped, and every
frame left the previous header line behind. Lines are now cut short of the
terminal width and end in an ellipsis. - A probe that fails with an error (for example when the OS refuses to send)
is no longer shown as a timeout: the classic view prints
Probe error for seq=N: <reason>, and the compact and extended views put
the reason first on theEventsline. JSON output is unchanged. - Windows: the console is switched to escape-sequence processing before the
first line is printed; theInit:line showed its bold sequences as text.
v1.5.1
Fixes
- ICMPv6 on RAW sockets (the Linux fallback when
ping_group_rangedenies
DGRAM): replies are now matched against the probed address. With two or more
IPv6 targets, a reply from one target was counted for the others — every
probe shares the identifier and the sequence numbers advance together — so
an unreachable target was reported as up. - Large payloads on RAW sockets: the receive buffer now grows with
-s.
Above ~1980 bytes the reply was truncated, failed the checksum check and
every probe timed out. - Soundness (Linux): the
recvmsgcontrol buffer is aligned forcmsghdr. - Soundness (Windows): echo replies are read with unaligned loads, and the
request options no longer carry implicit padding — the bytes 64-bit Windows
reads as the options pointer are an explicit, zeroed field. - Windows IPv6: the reply buffer reserves room for the
IO_STATUS_BLOCKthat
Icmp6SendEcho2requires. - CI: a failed release creation now fails the publish job instead of being
ignored.
Packaging
- Arch
PKGBUILD/PKGBUILD-gitand a Fedora spec underpackaging/; a
dh-cargo Debian packaging draft. .debdependencies are computed automatically ($auto).- MSRV is Rust 1.88 (let-chains).
anyhow1.0.104 (RUSTSEC-2026-0190).
Internal
- Rustdoc and
SAFETY:comments acrosssrc/; clippy clean on Linux, macOS
and Windows targets. - E2E tests use a built-in watchdog instead of
timeout(1), which macOS does
not ship and Windows resolves to an unrelated tool. SECURITY.mdand GitHub CI/release workflows.