Keep watching the tunnel after a failed look, and remember peers' names
mesh/merge-gate pass: builds netcheck → ace, g14; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
mesh/delivery delivered

This commit is contained in:
2026-10-11 23:51:40 +02:00
parent 4fc769ed29
commit c31e29f9a6
+25 -3
View File
@@ -20,6 +20,7 @@ import (
"sort"
"strconv"
"strings"
"sync"
"time"
)
@@ -109,11 +110,20 @@ func parseDump(out string, now time.Time) (Tunnel, error) {
return t, sc.Err()
}
// errNoTunnel is a machine without the interface: not a fault, a machine off the private network.
var errNoTunnel = errors.New("this machine has no " + TunnelInterface)
// names remembers the mesh's name of each peer address once found, so the watcher asks no resolver every look.
var names sync.Map
// readTunnel asks wg for the interface's state and names each peer by the mesh's names.
func readTunnel(ctx context.Context) (Tunnel, error) {
out, err := exec.CommandContext(ctx, "wg", "show", TunnelInterface, "dump").Output()
if err != nil {
var ee *exec.ExitError
if errors.As(err, &ee) && strings.Contains(string(ee.Stderr), "No such device") {
return Tunnel{}, errNoTunnel
}
if errors.As(err, &ee) && len(ee.Stderr) > 0 {
return Tunnel{}, fmt.Errorf("wg show %s: %s", TunnelInterface, strings.TrimSpace(string(ee.Stderr)))
}
@@ -124,7 +134,15 @@ func readTunnel(ctx context.Context) (Tunnel, error) {
return t, err
}
for i := range t.Peers {
t.Peers[i].Name = nameOf(ctx, t.Peers[i].AllowedIPs)
k := peerKey(t.Peers[i])
if known, ok := names.Load(k); ok {
t.Peers[i].Name = known.(string)
continue
}
if name := nameOf(ctx, t.Peers[i].AllowedIPs); name != "" {
names.Store(k, name)
t.Peers[i].Name = name
}
}
return t, nil
}
@@ -204,7 +222,7 @@ func report(err error) {
}
// watchTunnel looks every 20 seconds while this machine has the interface; a machine without it is
// looked at again every ten minutes, saying so once.
// looked at again every ten minutes. A failed look is said once and tried again at the next look.
func watchTunnel(emit emitter) {
var w tunnelWatch
said := ""
@@ -217,7 +235,11 @@ func watchTunnel(emit emitter) {
say("not watching the tunnel: %v", err)
said = err.Error()
}
time.Sleep(10 * time.Minute)
if errors.Is(err, errNoTunnel) {
time.Sleep(10 * time.Minute)
} else {
time.Sleep(20 * time.Second)
}
continue
}
said = ""