diff --git a/client/ios/PacketTunnel/PacketTunnelProvider.swift b/client/ios/PacketTunnel/PacketTunnelProvider.swift index 3de86f3..6f2c35f 100644 --- a/client/ios/PacketTunnel/PacketTunnelProvider.swift +++ b/client/ios/PacketTunnel/PacketTunnelProvider.swift @@ -206,6 +206,7 @@ final class PangolinPlatformInterface: NSObject, LibboxPlatformInterfaceProtocol let ipv4 = NEIPv4Settings(addresses: v4addrs.map(\.address), subnetMasks: v4addrs.map(\.mask)) ipv4.includedRoutes = includedRoutes4(options) + ipv4.excludedRoutes = excludedRoutes4(options) settings.ipv4Settings = ipv4 } let v6addrs = routePrefixes(options.getInet6Address()) @@ -213,6 +214,7 @@ final class PangolinPlatformInterface: NSObject, LibboxPlatformInterfaceProtocol let ipv6 = NEIPv6Settings(addresses: v6addrs.map(\.address), networkPrefixLengths: v6addrs.map { NSNumber(value: $0.prefix) }) ipv6.includedRoutes = includedRoutes6(options) + ipv6.excludedRoutes = excludedRoutes6(options) settings.ipv6Settings = ipv6 } if let dns = try? options.getDNSServerAddress(), !dns.value.isEmpty { @@ -311,6 +313,19 @@ final class PangolinPlatformInterface: NSObject, LibboxPlatformInterfaceProtocol networkPrefixLength: NSNumber(value: $0.prefix)) } } + // 排除路由:sing-box config 的 route_exclude_address(私有 LAN 网段)经 libbox + // 暴露在此。之前只设 includedRoutes、丢了 excludedRoutes → strict_route 把 LAN 也 + // 抓进隧道,VPN 开着连不上局域网/NAS/家里机器。设上 excludedRoutes 后 LAN 直连。 + private func excludedRoutes4(_ o: any LibboxTunOptionsProtocol) -> [NEIPv4Route] { + routePrefixes(o.getInet4RouteExcludeAddress()) + .map { NEIPv4Route(destinationAddress: $0.address, subnetMask: $0.mask) } + } + private func excludedRoutes6(_ o: any LibboxTunOptionsProtocol) -> [NEIPv6Route] { + routePrefixes(o.getInet6RouteExcludeAddress()) + .map { NEIPv6Route(destinationAddress: $0.address, + networkPrefixLength: NSNumber(value: $0.prefix)) } + } + // utun fd:getpeername 得 sockaddr_ctl,匹配 utun 控制 id(WireGuard 技法) private static func tunFd() -> Int32? { var ctlInfo = ctl_info() diff --git a/client/macos/PacketTunnel/PacketTunnelProvider.swift b/client/macos/PacketTunnel/PacketTunnelProvider.swift index 4ffb4c4..69d923a 100644 --- a/client/macos/PacketTunnel/PacketTunnelProvider.swift +++ b/client/macos/PacketTunnel/PacketTunnelProvider.swift @@ -201,6 +201,7 @@ final class PangolinPlatformInterface: NSObject, LibboxPlatformInterfaceProtocol let ipv4 = NEIPv4Settings(addresses: v4addrs.map(\.address), subnetMasks: v4addrs.map(\.mask)) ipv4.includedRoutes = includedRoutes4(options) + ipv4.excludedRoutes = excludedRoutes4(options) settings.ipv4Settings = ipv4 } let v6addrs = routePrefixes(options.getInet6Address()) @@ -208,6 +209,7 @@ final class PangolinPlatformInterface: NSObject, LibboxPlatformInterfaceProtocol let ipv6 = NEIPv6Settings(addresses: v6addrs.map(\.address), networkPrefixLengths: v6addrs.map { NSNumber(value: $0.prefix) }) ipv6.includedRoutes = includedRoutes6(options) + ipv6.excludedRoutes = excludedRoutes6(options) settings.ipv6Settings = ipv6 } if let dns = try? options.getDNSServerAddress(), !dns.value.isEmpty { @@ -301,6 +303,19 @@ final class PangolinPlatformInterface: NSObject, LibboxPlatformInterfaceProtocol networkPrefixLength: NSNumber(value: $0.prefix)) } } + // 排除路由:sing-box config 的 route_exclude_address(私有 LAN 网段)经 libbox + // 暴露在此。之前只设 includedRoutes、丢了 excludedRoutes → strict_route 把 LAN 也 + // 抓进隧道,VPN 开着连不上局域网/NAS/家里机器。设上 excludedRoutes 后 LAN 直连。 + private func excludedRoutes4(_ o: any LibboxTunOptionsProtocol) -> [NEIPv4Route] { + routePrefixes(o.getInet4RouteExcludeAddress()) + .map { NEIPv4Route(destinationAddress: $0.address, subnetMask: $0.mask) } + } + private func excludedRoutes6(_ o: any LibboxTunOptionsProtocol) -> [NEIPv6Route] { + routePrefixes(o.getInet6RouteExcludeAddress()) + .map { NEIPv6Route(destinationAddress: $0.address, + networkPrefixLength: NSNumber(value: $0.prefix)) } + } + // utun fd:getpeername 得 sockaddr_ctl,匹配 utun 控制 id(WireGuard 技法) private static func tunFd() -> Int32? { var ctlInfo = ctl_info()