New random transaction ID for each DHCP exchange (initial and renewal)
to avoid matching stale responses from previous transactions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add Renew() to dhcp.Client: sends REQUEST with ciaddr (RENEWING state)
- Start renewal goroutine in session at lease_time/2
- On IP change: flush TAP, reconfigure address/routes/DNS/policy routes
- On renewal failure: retry at T/4 (min 60s)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Built-in DHCP (raw Ethernet frames through tunnel), automatic reconnection,
host route management, classless static routes (option 121/249), DNS config.
Single static binary, Linux only.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>