All writes (frames, keepalive, DHCP renewal) are queued to a buffered
channel and drained by a single writer goroutine. Eliminates mutex
contention on the data path entirely.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Assemble numBlocks + frame sizes + frame data into one buffer before
writing. Reduces TLS records and syscalls from 3 per frame to 1.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
WriteFrames and keepalive both write multi-part messages to the TLS
connection. Without synchronization, their writes could interleave
and corrupt the framing. Add writeMu to serialize all tunnel writes.
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>
The TAP→Server goroutine can't be interrupted (TAP fd doesn't support
deadlines). It exits on next TAP frame when WriteFrames fails on the
closed connection. Document this rather than add complexity.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- TAP→server: write buf[:n] directly instead of copy to new slice
- Keepalive: reuse fixed buffer instead of allocating every 3s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Rename client to "Softether Go Client"
- Fix node info int fields to use LittleEndian32 encoding matching
the C client's OutRpcNodeInfo (Admin.c:14693)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Log each step: address assignment, static routes, default route,
DNS changes, and cleanup flush.
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>