Skip to content

Commit 7e01a31

Browse files
committed
vpn: merge sockmark, routes and uplink packages into vpn/netstate
Pure move: files keep their names, the public API (Marker, SetupGatewayRoutes/TeardownGatewayRoutes, SetupNAT/TeardownNAT) is unchanged. Resolved on merge: one package logger, one 0x61776C constant (fwmark + policy-routing table ID, previously duplicated), uplink helpers unexported (uplinkRoute/bestUplink/bestUplinkDefault). Consumers, CI hostnet paths and docs updated. First step of the netstate manager refactoring.
1 parent 7045a25 commit 7e01a31

36 files changed

Lines changed: 179 additions & 189 deletions

.github/workflows/test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ jobs:
4444
# `if: always()` cleanup step
4545
if: matrix.os == 'ubuntu-latest'
4646
run: |
47-
go test -c -tags vpn_hostnet -o gw-hostnet.test ./vpn/routes/
47+
go test -c -tags vpn_hostnet -o gw-hostnet.test ./vpn/netstate/
4848
sudo ./gw-hostnet.test -test.run '^TestGatewayHostNet' -test.v
4949
- name: VPN gateway host-network integration test (Windows, admin)
5050
# Windows counterpart of the step above: exercises WinNAT + WFP +
@@ -58,7 +58,7 @@ jobs:
5858
shell: pwsh
5959
run: |
6060
Get-NetNat | Format-List
61-
go test -c -tags vpn_hostnet -o gw-hostnet.test.exe ./vpn/routes/
61+
go test -c -tags vpn_hostnet -o gw-hostnet.test.exe ./vpn/netstate/
6262
# Flags are quoted: pwsh splits an unquoted `-test.run` at the dot
6363
# into `-test` + `.run`, which the test binary rejects.
6464
./gw-hostnet.test.exe '-test.run' '^TestGatewayHostNet' '-test.v'

application.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ import (
3939
"github.com/anywherelan/awl/ringbuffer"
4040
"github.com/anywherelan/awl/service"
4141
"github.com/anywherelan/awl/vpn"
42-
"github.com/anywherelan/awl/vpn/sockmark"
42+
"github.com/anywherelan/awl/vpn/netstate"
4343
)
4444

4545
const (
@@ -97,9 +97,9 @@ type Application struct {
9797
// keep libp2p traffic out of the VPN tunnel when gateway mode is on.
9898
// Callers (notably cmd/gomobile-lib on Android) may set this before
9999
// Init to inject a platform-specific marker — e.g.
100-
// app.SockMarker = sockmark.NewAndroid(protectorFn)
101-
// Init falls back to sockmark.New() if SockMarker is left nil.
102-
SockMarker sockmark.Marker
100+
// app.SockMarker = netstate.NewAndroid(protectorFn)
101+
// Init falls back to netstate.New() if SockMarker is left nil.
102+
SockMarker netstate.Marker
103103
}
104104

105105
func New() *Application {
@@ -111,7 +111,7 @@ func (a *Application) Init(ctx context.Context, tunDevice tun.Device) error {
111111

112112
a.ctx, a.ctxCancel = context.WithCancel(ctx)
113113
if a.SockMarker == nil {
114-
a.SockMarker = sockmark.New()
114+
a.SockMarker = netstate.New()
115115
}
116116
// Start before InitHost so the very first libp2p sockets are already
117117
// marked (on Windows: bound to the detected uplink). An offline start is

cmd/gomobile-lib/main.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313
"github.com/anywherelan/awl"
1414
"github.com/anywherelan/awl/config"
1515
"github.com/anywherelan/awl/vpn"
16-
"github.com/anywherelan/awl/vpn/sockmark"
16+
"github.com/anywherelan/awl/vpn/netstate"
1717
)
1818

1919
const appType = config.AppTypeAwlAndroid
@@ -64,7 +64,7 @@ type SocketProtector interface {
6464

6565
// StartServerWithProtector starts the server, registering a socket protector
6666
// so that libp2p and other sockets bypass the VPN. The protector reference is held by
67-
// the Application's sockmark.Marker for the lifetime of the run; calling
67+
// the Application's netstate.Marker for the lifetime of the run; calling
6868
// StopServer drops it.
6969
//
7070
// When VPN gateway client mode is enabled in the saved config, the host app
@@ -80,7 +80,7 @@ func StartServer(tunFD int32, protector SocketProtector) (err error) {
8080

8181
globalApp = awl.New()
8282
globalApp.SetupLoggerAndConfig(appType)
83-
globalApp.SockMarker = sockmark.NewAndroid(protectorToFunc(protector))
83+
globalApp.SockMarker = netstate.NewAndroid(protectorToFunc(protector))
8484

8585
// A tunFD of 0 means the host did not establish a VPN interface (VPN
8686
// disabled in config); Init then skips the VPN device entirely. Otherwise
@@ -132,7 +132,7 @@ func UpdateTunDevice(tunFD int32) error {
132132
return globalSwapTUN.Swap(inner)
133133
}
134134

135-
func protectorToFunc(p SocketProtector) sockmark.ProtectFunc {
135+
func protectorToFunc(p SocketProtector) netstate.ProtectFunc {
136136
if p == nil {
137137
return nil
138138
}

service/socks5.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import (
1919
"github.com/anywherelan/awl/metrics"
2020
"github.com/anywherelan/awl/protocol"
2121
"github.com/anywherelan/awl/socks5"
22-
"github.com/anywherelan/awl/vpn/sockmark"
22+
"github.com/anywherelan/awl/vpn/netstate"
2323
)
2424

2525
type SOCKS5 struct {
@@ -31,7 +31,7 @@ type SOCKS5 struct {
3131
server *socks5.Server
3232
}
3333

34-
func NewSOCKS5(p2pService P2p, conf *config.Config, sockMarker sockmark.Marker) (*SOCKS5, error) {
34+
func NewSOCKS5(p2pService P2p, conf *config.Config, sockMarker netstate.Marker) (*SOCKS5, error) {
3535
logger := log.Logger("awl/service/socks5")
3636

3737
var client *socks5.Client

service/vpn_gateway.go

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ import (
1414
"github.com/anywherelan/awl/config"
1515
"github.com/anywherelan/awl/entity"
1616
"github.com/anywherelan/awl/vpn"
17-
"github.com/anywherelan/awl/vpn/routes"
18-
"github.com/anywherelan/awl/vpn/sockmark"
17+
"github.com/anywherelan/awl/vpn/netstate"
1918
)
2019

2120
// DNSReconfigurer is the narrow slice of the DNS service the gateway needs to
@@ -49,7 +48,7 @@ type VPNGateway struct {
4948
tunnel *Tunnel
5049
device *vpn.Device
5150
p2p P2p
52-
sockMarker sockmark.Marker
51+
sockMarker netstate.Marker
5352
dns DNSReconfigurer
5453
logger *log.ZapEventLogger
5554

@@ -63,14 +62,14 @@ type VPNGateway struct {
6362
// paths. Connectivity to the bound gateway peer is observed via p2p
6463
// events inside Tunnel — no background goroutine here.
6564
mu sync.Mutex
66-
clientRouteState *routes.RouteState
67-
serverNATState *routes.NATState
65+
clientRouteState *netstate.RouteState
66+
serverNATState *netstate.NATState
6867
}
6968

7069
// NewVPNGateway constructs a VPNGateway service. tunnel may be nil when the
7170
// VPN interface is disabled; the API methods still work but only update the
7271
// persisted config.
73-
func NewVPNGateway(conf *config.Config, tunnel *Tunnel, device *vpn.Device, p2p P2p, sockMarker sockmark.Marker, dns DNSReconfigurer, disableOSSetup bool) *VPNGateway {
72+
func NewVPNGateway(conf *config.Config, tunnel *Tunnel, device *vpn.Device, p2p P2p, sockMarker netstate.Marker, dns DNSReconfigurer, disableOSSetup bool) *VPNGateway {
7473
return &VPNGateway{
7574
conf: conf,
7675
tunnel: tunnel,
@@ -155,7 +154,7 @@ func (g *VPNGateway) ListAvailableVPNGateways() []entity.AvailableVPNGateway {
155154
// gateway, applying OS-level routes immediately. Atomic: rolls back the
156155
// tunnel binding on apply failure.
157156
//
158-
// On android the OS-level apply (routes.SetupGatewayRoutes / sockmark) is a
157+
// On android the OS-level apply (netstate.SetupGatewayRoutes / sockmark) is a
159158
// no-op — routing is owned by the host's VpnService.Builder. This call flips
160159
// the in-memory tunnel binding and persists config; the host then re-establishes
161160
// the VpnService with the new routes and hot-swaps the fresh tun fd into the
@@ -298,7 +297,7 @@ func (g *VPNGateway) IsServerActive() bool {
298297
// ClientRouteState returns the current route state pointer (or nil). For
299298
// tests that need pointer-identity comparisons (idempotent re-enable must
300299
// not reinstall routes).
301-
func (g *VPNGateway) ClientRouteState() *routes.RouteState {
300+
func (g *VPNGateway) ClientRouteState() *netstate.RouteState {
302301
g.mu.Lock()
303302
defer g.mu.Unlock()
304303
return g.clientRouteState
@@ -323,7 +322,7 @@ func (g *VPNGateway) applyServer() error {
323322
if g.disableOSSetup {
324323
// Keep state tracking working (so teardown is symmetric) without
325324
// touching the kernel.
326-
g.serverNATState = &routes.NATState{}
325+
g.serverNATState = &netstate.NATState{}
327326
return nil
328327
}
329328

@@ -334,7 +333,7 @@ func (g *VPNGateway) applyServer() error {
334333
localIP, netMask := g.conf.VPNLocalIPMask()
335334
awlSubnet := (&net.IPNet{IP: localIP.Mask(netMask), Mask: netMask}).String()
336335

337-
natState, err := routes.SetupNAT(awlSubnet, tunName)
336+
natState, err := netstate.SetupNAT(awlSubnet, tunName)
338337
if err != nil {
339338
return fmt.Errorf("setup NAT: %w", err)
340339
}
@@ -352,7 +351,7 @@ func (g *VPNGateway) teardownServer() {
352351
return
353352
}
354353
if !g.disableOSSetup {
355-
if err := routes.TeardownNAT(g.serverNATState); err != nil {
354+
if err := netstate.TeardownNAT(g.serverNATState); err != nil {
356355
g.logger.Errorf("teardown NAT: %v", err)
357356
}
358357
}
@@ -394,7 +393,7 @@ func (g *VPNGateway) applyClient() error {
394393
// the netstate manager in the next MR and flattens there.
395394
//nolint:nestif
396395
if g.disableOSSetup {
397-
g.clientRouteState = &routes.RouteState{}
396+
g.clientRouteState = &netstate.RouteState{}
398397
} else {
399398
// Markers that can be temporarily unable to guarantee loop-free
400399
// marking (Windows: no uplink detected right now) expose Ready.
@@ -412,7 +411,7 @@ func (g *VPNGateway) applyClient() error {
412411
if err != nil {
413412
return fmt.Errorf("get TUN name for gateway routes: %w", err)
414413
}
415-
routeState, err := routes.SetupGatewayRoutes(tunName, g.sockMarker.FWMark())
414+
routeState, err := netstate.SetupGatewayRoutes(tunName, g.sockMarker.FWMark())
416415
if err != nil {
417416
return fmt.Errorf("setup gateway routes: %w", err)
418417
}
@@ -446,7 +445,7 @@ func (g *VPNGateway) teardownClient() {
446445
return
447446
}
448447
if !g.disableOSSetup {
449-
if err := routes.TeardownGatewayRoutes(g.clientRouteState); err != nil {
448+
if err := netstate.TeardownGatewayRoutes(g.clientRouteState); err != nil {
450449
g.logger.Errorf("teardown gateway routes: %v", err)
451450
}
452451
}

test_suite_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import (
4141

4242
const TestTUNBatchSize = 100
4343

44-
// noopSockMarker is a sockmark.Marker test double that does nothing. Production
44+
// noopSockMarker is a netstate.Marker test double that does nothing. Production
4545
// wiring sets SocketControlFunc unconditionally; tests run as a non-root user
4646
// where SO_MARK fails with EPERM, which would break libp2p dials and leave
4747
// QUIC reuse goroutines hanging past the goleak window.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package sockmark
1+
package netstate
22

33
import (
44
"net"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package sockmark
1+
package netstate
22

33
import (
44
"fmt"

vpn/netstate/log.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package netstate
2+
3+
import "github.com/ipfs/go-log/v2"
4+
5+
// logger is the shared package-level logger (socket marker, gateway routes,
6+
// NAT). Used to surface stale-state recovery, uplink changes and other one-off
7+
// events that callers shouldn't have to thread through return values.
8+
var logger = log.Logger("awl/vpn/netstate")
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//go:build linux && android
22

3-
package routes
3+
package netstate
44

55
// NATState holds the state needed to teardown NAT rules.
66
type NATState struct{}

0 commit comments

Comments
 (0)