Watch
0
0
Fork
You've already forked hyperhive
0

swarm snapshot store: the receiver socket binds the mesh address even when wg-hive comes up after sockets.target

The socket is wanted by sockets.target and nothing orders the wireguard
unit before it, so the mesh address can be missing at bind time
(EADDRNOTAVAIL) and the receiver never listens. FreeBind lets the bind
succeed regardless, and also covers the interface coming back after a flap.

Also assert the mesh address is not a wildcard, which the comment above the
socket already claimed, and cover the rendered socket in a module-eval case.
This commit is contained in:
atlas 2026-10-15 03:15:43 +02:00 • committed by mara
commit 4285faf07c
4 changed files with 120 additions and 4 deletions

View file

@ -154,6 +154,21 @@ in
fall back to a wildcard.
'';
}
{
assertion =
!(lib.elem meshAddress [
""
"0.0.0.0"
"::"
]);
message = ''
The snapshot store refuses a wildcard listen address.
services.hyperhive.deploy.wireguard.address is "${wgCfg.address}",
which would make the receiver bind "${meshAddress}" on every
interface. Set it to this host's address on the mesh
(e.g. "10.100.0.1/24").
'';
}
];
# The store root must exist before the first connection arrives ---
@ -185,6 +200,12 @@ in
# into agent state, so the binding IS the access control and is
# asserted above rather than left to a comment.
#
# FreeBind lets the bind succeed before `wg-hive` has its address:
# sockets.target is reached before the wireguard unit, which
# nothing orders ahead of it, so without it the bind fails with
# EADDRNOTAVAIL and the receiver never listens. It also covers the
# interface coming back after a flap.
#
# Accept=yes gives one service instance per connection and sets
# $REMOTE_ADDR for the handler --- which is how the receiver knows
# which peer it is talking to.
@ -194,6 +215,7 @@ in
socketConfig = {
ListenStream = "${meshAddress}:${toString cfg.port}";
Accept = "yes";
FreeBind = true;
};
};