Skip to content

fix(dns): a vanished interface must not disable DNS integration forever - #21

Open
wighawag wants to merge 1 commit into
tunnetio:mainfrom
wighawag:fix/osdns-stale-journal-vanished-link
Open

fix(dns): a vanished interface must not disable DNS integration forever#21
wighawag wants to merge 1 commit into
tunnetio:mainfrom
wighawag:fix/osdns-stale-journal-vanished-link

Conversation

@wighawag

@wighawag wighawag commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

If the TUN disappears before its lease is dropped, osdns keeps a journal record naming a dead interface index. recover_stale then fails on every subsequent start, DnsController::create returns Err, cfg.dns is None, and no OS DNS is ever applied again. PeerDNS stays inactive permanently, even though the new TUN comes up fine as a different index.

Hit this for real while testing #15, by doing nothing more exotic than restarting the service:

18:17:33  PeerDNS lease applied ... ifname="tunnet0"
21:14:41  PeerDNS lease restore failed ... NoSuchLink: Link 8 not known
21:14:42  journal record was kept for later recovery ... ifindex:8
21:14:53  osdns DNS integration unavailable ... NoSuchLink: Link 8 not known

From then on tunnet dns status reports PeerDNS inactive and resolvectl status tunnet0 shows no DNS scope, on every start. Recovering needs manual removal of the record from /var/lib/osdns/journal/.

Failing closed is correct when state might be clobbered, but a resource that no longer exists has nothing to restore and nothing to protect, so the failure is permanent for no benefit. This treats that single case as recoverable and continues. Every other error still fails closed, covered by tests, so genuine conflicts are not masked.

osdns has no typed "resource gone" error at 0.1.3, so this matches the stable D-Bus error name. The better fix is upstream: recover_stale should report a vanished resource as JournalCleared rather than erroring. Happy to raise that there if you agree.

Refs #18

If the TUN disappears before its lease is dropped, osdns keeps a journal
record naming a dead interface index. `recover_stale` then fails on every
subsequent start, `DnsController::create` returns Err, `cfg.dns` is None,
and no OS DNS is ever applied again. PeerDNS stays inactive permanently,
even though the new TUN comes up fine as a different index.

Observed end to end on a restart:

    18:17:33  PeerDNS lease applied ... ifname="tunnet0"
    21:14:41  PeerDNS lease restore failed ... NoSuchLink: Link 8 not known
    21:14:42  journal record was kept for later recovery ... ifindex:8
    21:14:53  osdns DNS integration unavailable ... NoSuchLink: Link 8 not known

and `tunnet dns status` reporting `PeerDNS inactive` from then on.

Failing closed is correct when state might be clobbered, but a resource
that no longer exists has nothing to restore and nothing to protect, so
the failure is permanent for no benefit. Treat that one case as
recoverable and continue; every other error still fails closed, so real
conflicts are not masked.

osdns has no typed "resource gone" error at 0.1.3, so this matches the
stable D-Bus error name. The better fix is upstream: `recover_stale`
should report a vanished resource as `JournalCleared` rather than
erroring.
@wighawag
wighawag force-pushed the fix/osdns-stale-journal-vanished-link branch from 3e13c1f to f49468a Compare September 6, 2026 15:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant