feat: SDWAN data plane + UDP punch port fix + TUN reader
SDWAN: - protocol: add SDWANConfig/SDWANPeer/SDWANPacket structs, MsgTunnel type - server: sdwan.go (JSON file store), sdwan_api.go (Get/Set/broadcast/route) - server: push SDWAN config on login, announce peer online/offline events - server: RouteSDWANPacket routes TUN packets between nodes via signaling - client: TUN device setup (optun), tunReadLoop reads IP packets - client: handle SDWANConfig/SDWANPeer/SDWANDel push messages - client: apply routes (per-node /32 + broad CIDR fallback) UDP punch fix: - nat/detect: capture LocalPort from STUN UDP socket for punch binding - client: pass publicPort + localPort through login and punch config - coordinator: include PublicPort in PunchParams for both sides - protocol: add PublicPort to LoginReq and ReportBasic Other: - server: use client-reported PublicIP instead of raw r.RemoteAddr - server: update PublicIP/Port from ReportBasic if provided - client: config file loading with zero-value defaults backfill - .gitignore: exclude run/, *.pid, *.log, sdwan.json - go.mod: add golang.org/x/sys for TUN ioctl
This commit is contained in:
@@ -16,10 +16,11 @@ const (
|
||||
|
||||
// DetectResult holds the NAT detection outcome.
|
||||
type DetectResult struct {
|
||||
Type protocol.NATType
|
||||
PublicIP string
|
||||
Port1 int // external port seen on STUN server port 1
|
||||
Port2 int // external port seen on STUN server port 2
|
||||
Type protocol.NATType
|
||||
PublicIP string
|
||||
Port1 int // external port seen on STUN server port 1
|
||||
Port2 int // external port seen on STUN server port 2
|
||||
LocalPort int // local UDP port used for detection (for punch bind)
|
||||
}
|
||||
|
||||
// stunReq is sent to the STUN endpoint.
|
||||
@@ -45,6 +46,9 @@ func DetectUDP(serverIP string, port1, port2 int) DetectResult {
|
||||
return result
|
||||
}
|
||||
defer conn.Close()
|
||||
if ua, ok := conn.LocalAddr().(*net.UDPAddr); ok {
|
||||
result.LocalPort = ua.Port
|
||||
}
|
||||
|
||||
r1, err1 := probeUDP(conn, serverIP, port1, 1)
|
||||
r2, err2 := probeUDP(conn, serverIP, port2, 2)
|
||||
|
||||
@@ -61,6 +61,14 @@ const (
|
||||
SubPushEditApp // add/edit tunnel app
|
||||
SubPushDeleteApp // delete tunnel app
|
||||
SubPushReportApps // request app list
|
||||
SubPushSDWANConfig // push sdwan config to client
|
||||
SubPushSDWANPeer // push sdwan peer online/update
|
||||
SubPushSDWANDel // push sdwan peer offline/delete
|
||||
)
|
||||
|
||||
// Sub types: MsgTunnel
|
||||
const (
|
||||
SubTunnelSDWANData uint16 = iota
|
||||
)
|
||||
|
||||
// ─── Sub types: MsgRelay ───
|
||||
@@ -174,6 +182,7 @@ type LoginReq struct {
|
||||
RelayEnabled bool `json:"relayEnabled"` // --relay flag
|
||||
SuperRelay bool `json:"superRelay"` // --super flag
|
||||
PublicIP string `json:"publicIP,omitempty"`
|
||||
PublicPort int `json:"publicPort,omitempty"`
|
||||
}
|
||||
|
||||
type LoginRsp struct {
|
||||
@@ -194,6 +203,8 @@ type ReportBasic struct {
|
||||
HasIPv4 int `json:"hasIPv4"`
|
||||
HasUPNPorNATPMP int `json:"hasUPNPorNATPMP"`
|
||||
IPv6 string `json:"IPv6,omitempty"`
|
||||
PublicIP string `json:"publicIP,omitempty"`
|
||||
PublicPort int `json:"publicPort,omitempty"`
|
||||
}
|
||||
|
||||
type ReportBasicRsp struct {
|
||||
@@ -258,6 +269,37 @@ type AppConfig struct {
|
||||
RelayNode string `json:"relayNode,omitempty"` // force specific relay
|
||||
}
|
||||
|
||||
type SDWANNode struct {
|
||||
Node string `json:"node"`
|
||||
IP string `json:"ip"`
|
||||
}
|
||||
|
||||
type SDWANConfig struct {
|
||||
Enabled bool `json:"enabled,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
GatewayCIDR string `json:"gatewayCIDR"`
|
||||
Mode string `json:"mode,omitempty"` // hub | mesh | fullmesh
|
||||
IP string `json:"ip,omitempty"` // node self IP if pushed per-node
|
||||
MTU int `json:"mtu,omitempty"`
|
||||
Routes []string `json:"routes,omitempty"`
|
||||
Nodes []SDWANNode `json:"nodes"`
|
||||
UpdatedAt int64 `json:"updatedAt,omitempty"`
|
||||
}
|
||||
|
||||
type SDWANPeer struct {
|
||||
Node string `json:"node"`
|
||||
IP string `json:"ip"`
|
||||
Online bool `json:"online"`
|
||||
}
|
||||
|
||||
type SDWANPacket struct {
|
||||
FromNode string `json:"fromNode,omitempty"`
|
||||
ToNode string `json:"toNode,omitempty"`
|
||||
SrcIP string `json:"srcIP,omitempty"`
|
||||
DstIP string `json:"dstIP,omitempty"`
|
||||
Payload []byte `json:"payload"`
|
||||
}
|
||||
|
||||
// ReportConnect is the connection result reported to server.
|
||||
type ReportConnect struct {
|
||||
PeerNode string `json:"peerNode"`
|
||||
|
||||
Reference in New Issue
Block a user