Files
RemLink/internal/overlay/clientwg/device.go
T
qsc20001102 142e5dc7d6
ci / Go checks (ubuntu-latest) (push) Has been cancelled
ci / Go checks (windows-latest) (push) Has been cancelled
初版功能完成
2026-08-29 13:12:17 +08:00

85 lines
2.1 KiB
Go

package clientwg
import (
"errors"
"fmt"
"log/slog"
"sync"
"golang.zx2c4.com/wireguard/conn"
"golang.zx2c4.com/wireguard/device"
"golang.zx2c4.com/wireguard/tun"
)
// Device owns the MuxTun, wireguard-go engine, and transport bind.
type Device struct {
tun *MuxTun
wireguard *device.Device
closeOnce sync.Once
}
// NewDevice transfers ownership of base to a new embedded wireguard-go Device.
func NewDevice(base tun.Device, logger *slog.Logger) (*Device, error) {
if base == nil {
return nil, errors.New("base TUN device must not be nil")
}
mux := NewMuxTun(base)
wireguard := device.NewDevice(mux, conn.NewDefaultBind(), wireGuardLogger(logger))
return &Device{tun: mux, wireguard: wireguard}, nil
}
// Configure atomically replaces the single Server peer through wireguard-go UAPI.
func (d *Device) Configure(config Config) error {
uapi, err := config.uapi()
if err != nil {
return err
}
if err := d.wireguard.IpcSet(uapi); err != nil {
return fmt.Errorf("configure embedded wireguard-go: %w", err)
}
return nil
}
// Up starts the embedded WireGuard device after configuration.
func (d *Device) Up() error {
if err := d.wireguard.Up(); err != nil {
return fmt.Errorf("bring embedded wireguard-go up: %w", err)
}
return nil
}
// UAPIState returns wireguard-go's current UAPI state for diagnostics.
func (d *Device) UAPIState() (string, error) {
return d.wireguard.IpcGet()
}
// MuxTun returns the single packet boundary used by Session transport.
func (d *Device) MuxTun() *MuxTun { return d.tun }
// Close is idempotent and stops wireguard-go, MuxTun, and the base Wintun.
func (d *Device) Close() {
if d == nil || d.wireguard == nil {
return
}
d.closeOnce.Do(func() {
d.wireguard.Close()
})
}
func wireGuardLogger(logger *slog.Logger) *device.Logger {
if logger == nil {
return &device.Logger{
Verbosef: device.DiscardLogf,
Errorf: device.DiscardLogf,
}
}
return &device.Logger{
Verbosef: func(format string, args ...any) {
logger.Debug(fmt.Sprintf(format, args...))
},
Errorf: func(format string, args ...any) {
logger.Error(fmt.Sprintf(format, args...))
},
}
}