We packaged the KEIBIDROP serving side as a container for boxes that stay on, and the first join from a laptop at home failed every time. Three connect-path bugs sat on that one topology: a joiner that waited 3 seconds for a creator that needs 15, a creator that marked its own inbound blocked after one empty window, and a bridge that keeps a room alive after the socket in it is closed. Each fix is a few lines. Each was pinned by a log line before a line of code changed.
The topology that had never been tested end to end
A KEIBIDROP session is two peers. One creates a room on the relay and accepts; the other fetches the room and dials. When both sit behind home routers, both go to the bridge at once and meet there. When both have open inbound ports, they connect directly. The container on a server has an open inbound port; the laptop at home has a blocked one. That mix, creator open and joiner blocked, is the always-on box in one sentence, and it is the case the test suites had not covered.
The joiner waited 3 seconds for a creator that needs 15
The joiner dials the creator directly, and that works: the creator's port is open. Then the joiner learns from its own relay probe that its inbound is blocked, drops the direct half, and takes the bridge for both directions. On its bridge inbound leg it waited 3 seconds for the creator's hello.
The creator meanwhile accepted the joiner's direct dial and dialed the joiner back, because a direct handshake carries no reachability verdict. That dial hits a blocked port and times out after 15 seconds. Only then does the creator take the bridge. The joiner had left 12 seconds earlier.
The 3 second bound came from the 0.4.2 security hardening, which put the accept-loop first-byte limit on every inbound handshake through one helper. The bridge leg is a socket we dialed ourselves, so the longer wait pins nothing a stranger can reach. It now waits 60 seconds, twice the creator's worst case, and a unit test fails at the old bound.
The creator marked its own inbound blocked after one empty window
After the first fix, joins still went through the bridge every time, even with a direct path available. The box's log showed why: its first 15 second accept window closed with nobody in it, because the laptop had not dialed yet, and the creator recorded that as "my inbound is blocked". From then on every round skipped the direct window, and the registration told the laptop to skip its dial too. Only an arriving dial clears that mark, and the mark itself prevents the dial.
The relay had probed the box at start and answered reachable. An empty window is weaker evidence than a fresh probe, so a fresh reachable verdict now survives an empty window. Without a verdict, or with a stale or negative one, the old mark stands.
The bridge keeps a room alive after the socket in it is closed
The third failure showed up only in the bridge's own journal. The creator's rounds alternate a 15 second accept window with a 15 second bridge wait. At the end of an empty bridge wait it closed its leg. The bridge parks an unmatched room for 20 seconds and sweeps every 10, and it does that whether or not the client is still there. A joiner arriving in that window was matched to the closed socket, its hello went to nobody, and both sides waited out their windows alone:
11:12:34 [pair 411] matched token=ff05b1a4 A=[box]:39682 B=[laptop]:57506
11:12:34 Waiting: token=fb7eb1d2 from [laptop]:53520
11:12:49 Waiting: token=ff05b1a4 from [box]:42880
11:13:00 Expired: token=fb7eb1d2
11:13:10 Expired: token=ff05b1a4
The box socket in pair 411 had been closed 5 seconds before the match. Our own knowledge base already recorded this trap for the joiner side; the creator side hit it from the other direction. The creator now keeps its leg open between rounds and reads it first in the next bridge phase. An open leg expires into nothing; a closed one expires into a corpse. An integration test against the mock bridge reproduces the race and fails with the old close.
What the numbers say after the fixes
A join started right after an empty bridge round connects in 16 seconds, the creator's doomed dial included. A join while the box waits on the bridge connects in under a second. A 1 GiB pull through the Timisoara bridge ran at 29.8 MB/s (34 s, free class, laptop in Bucharest on home WiFi with a blocked inbound, n=2), which is that bridge's egress ceiling for the free class. A 1 MiB read from the middle of that file moves one 16 MiB block. The unit and integration suites, the race lane, and the fleet lanes on Linux and Windows are green.
One open item came out of the same afternoon and stays open: a sequential read through the macFUSE mount moves one block per kernel look-ahead read, so sixteen 1 MiB reads moved sixteen blocks. That is the data path, it predates this work, and it gets its own test before its own fix.
What we would do again
Put the new topology on real machines before shipping the container. Read both peers' logs and the bridge's journal side by side; the third bug is invisible from either peer alone. Ask the knowledge base about the bridge before touching the bridge code. And keep each fix small enough that a reviewer can hold it in one hand.