refactor: extract session/netcfg/tunnel, add mac/dhcp/policy-route flags
- Split cmd/softether-go into main.go (flags, reconnect loop) and session.go (session lifecycle, DHCP orchestration) - Extract network config to pkg/netcfg (TAP config, routing, DNS, policy routes) - Move frame bridging to pkg/client/tunnel.go as Bridge() method - Add -mac, -dhcp, -policy-route-table CLI flags - Add SetMAC() to pkg/tap for deterministic DHCP assignments - Update all docs to reflect new structure and flags Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
846ed96ff4
commit
17c1063e1f
10 changed files with 495 additions and 332 deletions
|
|
@ -98,6 +98,62 @@ func (t *Tunnel) WriteFrames(frames [][]byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// FrameHandler is called for each Ethernet frame received from the server.
|
||||
// Returning a non-nil error stops the bridge.
|
||||
type FrameHandler func(frame []byte) error
|
||||
|
||||
// Bridge runs bidirectional frame forwarding between the tunnel and a TAP device.
|
||||
// tapRead reads one Ethernet frame into buf, returning (n, err).
|
||||
// tapWrite writes one Ethernet frame.
|
||||
// onFrame is called for each server frame before writing to TAP (e.g. for DHCP).
|
||||
// Blocks until an error occurs on either direction.
|
||||
func (t *Tunnel) Bridge(tapRead func(buf []byte) (int, error), tapWrite func(buf []byte) (int, error), onFrame FrameHandler) error {
|
||||
errCh := make(chan error, 2)
|
||||
|
||||
// Server → TAP
|
||||
go func() {
|
||||
for {
|
||||
frames, err := t.ReadFrames()
|
||||
if err != nil {
|
||||
errCh <- fmt.Errorf("read from server: %w", err)
|
||||
return
|
||||
}
|
||||
for _, frame := range frames {
|
||||
if onFrame != nil {
|
||||
if err := onFrame(frame); err != nil {
|
||||
errCh <- err
|
||||
return
|
||||
}
|
||||
}
|
||||
if _, err := tapWrite(frame); err != nil {
|
||||
errCh <- fmt.Errorf("write to tap: %w", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// TAP → Server
|
||||
go func() {
|
||||
buf := make([]byte, 1600)
|
||||
for {
|
||||
n, err := tapRead(buf)
|
||||
if err != nil {
|
||||
errCh <- fmt.Errorf("read from tap: %w", err)
|
||||
return
|
||||
}
|
||||
frame := make([]byte, n)
|
||||
copy(frame, buf[:n])
|
||||
if err := t.WriteFrames([][]byte{frame}); err != nil {
|
||||
errCh <- fmt.Errorf("write to server: %w", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return <-errCh
|
||||
}
|
||||
|
||||
// StartKeepalive sends periodic keepalive packets to prevent the server from
|
||||
// timing out the connection. Must be called after the session enters tunnel mode.
|
||||
// See: https://github.com/SoftEtherVPN/SoftEtherVPN/blob/v5.02.5187/src/Cedar/Connection.c#L1779
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue