Skip to content

v0.1.1 — five transport fixes, plus an x86-64 static build

Latest

Choose a tag to compare

@jjacke13 jjacke13 released this 01 Aug 11:03

A bug-fix release. If you are running v0.1.0, upgrade — it carries five
transport defects, one of which is a crash.

All of them live in the hyperdht-cpp dependency rather than in this port, and
all are fixed by bumping it to 81974c0. The C API surface is byte-identical
across that range, so nothing in holesail-cpp had to change to pick them up.

What was broken in v0.1.0

Symptom
Relay set was write-once Once three relay slots filled they were pinned for the life of the process. A relay that died — or that was never reachable from third parties, e.g. behind a symmetric NAT — was advertised to every client forever, and no healthier node could replace it. Restarting the server was the only cure. This is exactly the long-lived --live daemon workload.
Double stream destroy → crash A second udx_stream_destroy() inside the DESTROYING-but-not-CLOSED window ran the close path twice and tripped libuv's assert(!uv__is_closing). It only bites in Release, where libudx's guarding assert is compiled out — and Release is what ships. Seen in the field as a SIGABRT during connect-failure teardown.
No announce-relay failover The client picked one of the server's announced relays and treated its failure as terminal. One relay behind an endpoint-dependent NAT meant every connect failed -5 permanently, even with other healthy relays announced.
Local addresses were a bind-time snapshot Any interface appearing after bind — DHCP completing under an early-starting service, an interface flap, an address renewal — was never advertised for the rest of the process lifetime, and same-LAN clients failed -6 permanently. Matters most when holesail runs as a boot-time unit.
pause() / resume() left the server silent The announcer's alive_ sentinel was cleared on stop and never re-armed on start, so a suspended-then-resumed server never re-announced again. Reachable through this port's own Holesail::pause() / Holesail::resume().

Verification

  • 11/11 unit suites.
  • 6/6 live interop against the real JS holesail 2.4.1 binary on the public
    DHT: C++↔C++, C++ server↔JS client and JS server↔C++ client, each in secure
    and public mode, plus --lookup against a JS-published record. Real HTTP
    through the tunnel, 200 with the body verified in every case.

Wire compatibility with upstream holesail is unchanged: same connection
strings, same key derivation, same DHT records.

Also in this release

--version now reports the real version. All four version strings in the tree
said 0.1.0; with a known-bad v0.1.0 still downloadable, the first question
about any binary in the field is which build it is, and the CLI has to be able
to answer.

A note this repo had recorded as fact was also retracted after upstream
re-tested it: hyperdht_query_cancel() does fire on_done
(HYPERDHT_ERR_CANCELLED), possibly synchronously, and the associated leak is
~1272 B rather than the ~34 KB previously claimed. No behaviour change here —
HolesailClient::destroy() already nulled its query handle before cancelling,
which is what prevents a double free — but that ordering is now documented as
load-bearing instead of looking incidental.

Install

x86-64 Linux — new in this release. v0.1.0 shipped an aarch64 binary only,
so an ordinary server or desktop had to build from source through nix.

curl -LO https://github.com/jjacke13/holesail-cpp/releases/download/v0.1.1/holesail-v0.1.1-x86_64-linux-static
chmod +x holesail-v0.1.1-x86_64-linux-static
./holesail-v0.1.1-x86_64-linux-static --version

aarch64 Linux (Raspberry Pi class):

curl -LO https://github.com/jjacke13/holesail-cpp/releases/download/v0.1.1/holesail-v0.1.1-aarch64-linux-static
chmod +x holesail-v0.1.1-aarch64-linux-static
./holesail-v0.1.1-aarch64-linux-static --version

Both are musl, fully static, with no runtime dependencies at all — no nix, no
Node, no libuv or libsodium on the target. ~3.5 MB on disk, ~3.2 MB RSS on a
Pi 5. Verify with SHA256SUMS.txt.

The x86-64 build was validated by running the interop harness with the static
binary itself
— musl replaces glibc's resolver and threading, which is
precisely where a DHT can pass every local test and still fail on a real
network. It didn't: 6/6.

Note for hyperdht-cpp users

If you build on hyperdht-cpp's C FFI, these fixes matter to you too, and
one of them is a crash that only appears in Release builds. Separately, if you
are on anything older than 0203820, the C API firewall was inverted —
private servers admitted exactly the peers they should have rejected.


holesail-cpp is an unofficial, independent C++ port of
holesail by supersuryaansh. Use the
original unless you specifically need the smaller footprint.