diff --git a/adapter/network.go b/adapter/network.go index 00ef54b8..22816f07 100644 --- a/adapter/network.go +++ b/adapter/network.go @@ -51,4 +51,5 @@ type NetworkInterface struct { DNSServers []string Expensive bool Constrained bool + RawNetwork any } diff --git a/experimental/libbox/config.go b/experimental/libbox/config.go index 159fd8f6..b27d34ab 100644 --- a/experimental/libbox/config.go +++ b/experimental/libbox/config.go @@ -78,6 +78,10 @@ func (s *platformInterfaceStub) Interfaces() ([]adapter.NetworkInterface, error) return nil, os.ErrInvalid } +func (s *platformInterfaceStub) SetUnderlyingNetworks(networks []adapter.NetworkInterface) error { + return os.ErrInvalid +} + func (s *platformInterfaceStub) UnderNetworkExtension() bool { return false } diff --git a/experimental/libbox/platform.go b/experimental/libbox/platform.go index d5951cd3..9b7423ad 100644 --- a/experimental/libbox/platform.go +++ b/experimental/libbox/platform.go @@ -17,6 +17,7 @@ type PlatformInterface interface { StartDefaultInterfaceMonitor(listener InterfaceUpdateListener) error CloseDefaultInterfaceMonitor(listener InterfaceUpdateListener) error GetInterfaces() (NetworkInterfaceIterator, error) + SetUnderlyingNetworks(networks RawNetworkIterator) error UnderNetworkExtension() bool IncludeAllNetworks() bool ReadWIFIState() *WIFIState @@ -50,6 +51,8 @@ type NetworkInterface struct { Type int32 DNSServer StringIterator Metered bool + + RawNetwork RawNetwork } type WIFIState struct { @@ -66,6 +69,11 @@ type NetworkInterfaceIterator interface { HasNext() bool } +type RawNetworkIterator interface { + Next() RawNetwork + HasNext() bool +} + type Notification struct { Identifier string TypeName string diff --git a/experimental/libbox/platform/interface.go b/experimental/libbox/platform/interface.go index ef37daea..23849a3b 100644 --- a/experimental/libbox/platform/interface.go +++ b/experimental/libbox/platform/interface.go @@ -15,6 +15,7 @@ type Interface interface { OpenTun(options *tun.Options, platformOptions option.TunPlatformOptions) (tun.Tun, error) CreateDefaultInterfaceMonitor(logger logger.Logger) tun.DefaultInterfaceMonitor Interfaces() ([]adapter.NetworkInterface, error) + SetUnderlyingNetworks(networks []adapter.NetworkInterface) error UnderNetworkExtension() bool IncludeAllNetworks() bool ClearDNSCache() diff --git a/experimental/libbox/raw_network_android.go b/experimental/libbox/raw_network_android.go new file mode 100644 index 00000000..b8d38aaa --- /dev/null +++ b/experimental/libbox/raw_network_android.go @@ -0,0 +1,3 @@ +package libbox + +type RawNetwork interface{} diff --git a/experimental/libbox/raw_network_stub.go b/experimental/libbox/raw_network_stub.go new file mode 100644 index 00000000..6e23135c --- /dev/null +++ b/experimental/libbox/raw_network_stub.go @@ -0,0 +1,7 @@ +//go:build !android + +package libbox + +type RawNetwork interface { + stub() +} diff --git a/experimental/libbox/service.go b/experimental/libbox/service.go index 2156beef..34c3af92 100644 --- a/experimental/libbox/service.go +++ b/experimental/libbox/service.go @@ -206,11 +206,18 @@ func (w *platformInterfaceWrapper) Interfaces() ([]adapter.NetworkInterface, err DNSServers: iteratorToArray[string](netInterface.DNSServer), Expensive: netInterface.Metered || isDefault && w.isExpensive, Constrained: isDefault && w.isConstrained, + RawNetwork: netInterface.RawNetwork, }) } return interfaces, nil } +func (w *platformInterfaceWrapper) SetUnderlyingNetworks(networks []adapter.NetworkInterface) error { + return w.iif.SetUnderlyingNetworks(newIterator(common.Map(networks, func(it adapter.NetworkInterface) RawNetwork { + return it.RawNetwork.(RawNetwork) + }))) +} + func (w *platformInterfaceWrapper) UnderNetworkExtension() bool { return w.iif.UnderNetworkExtension() } diff --git a/route/network.go b/route/network.go index d82701fe..875b6e93 100644 --- a/route/network.go +++ b/route/network.go @@ -240,6 +240,9 @@ func (r *NetworkManager) UpdateInterfaces() error { newInterfaces := common.Filter(interfaces, func(it adapter.NetworkInterface) bool { return it.Flags&net.FlagUp != 0 }) + for _, networkInterface := range newInterfaces { + networkInterface.RawNetwork = nil + } r.networkInterfaces.Store(newInterfaces) if len(newInterfaces) > 0 && !slices.EqualFunc(oldInterfaces, newInterfaces, func(oldInterface adapter.NetworkInterface, newInterface adapter.NetworkInterface) bool { return oldInterface.Interface.Index == newInterface.Interface.Index && @@ -260,6 +263,15 @@ func (r *NetworkManager) UpdateInterfaces() error { } return F.ToString(it.Name, " (", strings.Join(options, ", "), ")") }), ", ")) + if C.IsAndroid { + err = r.platformInterface.SetUnderlyingNetworks(newInterfaces) + if err != nil { + r.logger.Error("set underlying networks: ", err) + } + } + } + for _, networkInterface := range interfaces { + networkInterface.RawNetwork = nil } return nil }