6 Commits
Author SHA1 Message Date
Anthony Wong 8ae09ac98e feat(cli): put the network state of the host in the log journal
The journal records the network state of the host and each change of
that state. The support team reads one file to see the interfaces, the
routes, the resolvers, and the recoveries around an incident. The same
file shows the health of the query path. A change that touches only
AirDrop or virtual interfaces runs no DNS work.
2026-09-28 16:49:05 +07:00
Dev Scribe 799f14e639 macOS: repair network recovery and improve diagnostics 2026-09-28 16:45:33 +07:00
Dev Scribe 779fe015f0 fix: validate pf state before stabilization 2026-08-21 14:45:56 +07:00
Codescribe 3f59cdad1a fix: block IPv6 DNS in intercept mode, remove raw socket approach
IPv6 DNS interception on macOS is not feasible with current pf capabilities.
The kernel rejects sendmsg from [::1] to global unicast (EINVAL), nat on lo0
doesn't fire for route-to'd packets, raw sockets bypass routing but pf doesn't
match them against rdr state, and DIOCNATLOOK can't be used because bind()
fails for non-local addresses.

Replace all IPv6 interception code with a simple pf block rule:
  block out quick on ! lo0 inet6 proto { udp, tcp } from any to any port 53

macOS automatically retries DNS over IPv4 when IPv6 is blocked.

Changes:
- Remove rawipv6_darwin.go and rawipv6_other.go
- Remove [::1] listener spawn on macOS (needLocalIPv6Listener returns false)
- Remove IPv6 rdr, route-to, pass, and reply-to pf rules
- Add block rule for all outbound IPv6 DNS
- Update docs/pf-dns-intercept.md with what was tried and why it failed
2026-04-01 17:35:08 +07:00
Codescribe 22a796f673 fix: use raw IPv6 socket for DNS responses in macOS intercept mode
macOS rejects sendmsg from [::1] to global unicast IPv6 (EINVAL), and
nat on lo0 doesn't fire for route-to'd packets (pf skips translation
on the second interface pass). ULA addresses on lo0 also fail (EHOSTUNREACH
- kernel segregates lo0 routing).

Solution: wrap the [::1] UDP listener's ResponseWriter with rawIPv6Writer
that sends responses via SOCK_RAW (IPPROTO_UDP) on lo0, bypassing the
kernel's routing validation. pf's rdr state reverses the address
translation on the response path.

Changes:
- Add rawipv6_darwin.go: rawIPv6Writer wraps dns.ResponseWriter, sends
  UDP responses via raw IPv6 socket with proper checksum calculation
- Add rawipv6_other.go: no-op wrapIPv6Handler for non-darwin platforms
- Remove nat rules from pf anchor (no longer needed)
- Block IPv6 TCP DNS (block return) - falls back to IPv4 (~1s, rare)
- Remove IPv6 TCP rdr/route-to/pass rules (only UDP intercepted)
2026-04-01 17:24:17 +07:00
Codescribe 289a46dc2c feat: add macOS pf DNS interception
Implement DNS interception on macOS using pf (packet filter):
- Anchor injection into running ruleset (not /etc/pf.conf)
- route-to lo0 + rdr rules for locally-originated DNS capture
- _ctrld group exemption so ctrld's own queries bypass interception
- Watchdog to detect and restore wiped anchor rules
- Probe-based auto-heal for Parallels VM pf corruption
- IPv6 DNS blocking and block-return for clean timeouts
- Interface-specific tunnel detection for VPN coexistence
- Port 5354 fallback in intercept mode

Includes pf technical reference docs and test scripts.

Squashed from intercept mode development on v1.0 branch (#497).
2026-03-03 14:27:43 +07:00