Skip to content

Egypt DPI no internet issue #83

Open

Description

@commencementtech

When connected using Xray with socket tun in iOS in that case facing no internet connection issue for Egypt country

Activity

  1. yiguodev commented on Jun 3, 2025

    @yiguodev
    Collaborator

    Try to use Wireshark to track the network traffic. I think it is NOT the problem of libXray.

  2. codewithtamim commented on Jun 3, 2025

    @codewithtamim
    Contributor

    Your setup is wrong im sure about that cause there's no reason that it will not work. Im using it on production apps and they are running smoothly

  3. commencementtech commented on Jun 6, 2025

    @commencementtech
    Author

    @codewithtamim Please find attached code which I am using

    PacketTunnelProvider.swift (Not working)

    `import LibXray
    import Network
    import NetworkExtension
    import os
    import Tun2SocksKit

    struct RunXrayRequest: Codable {
    var datDir: String?
    var configPath: String?
    var maxMemory: Int64?
    }

    private let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "PacketTunnelProvider")

    class PacketTunnelProvider: NEPacketTunnelProvider {

    let MTU = 1380
    
    override func startTunnel(options: [String: NSObject]? = nil) async throws {
        guard let sock5Port = options?["sock5Port"] as? Int else {
            throw NSError(domain: "PacketTunnel", code: -1,
                          userInfo: [NSLocalizedDescriptionKey: "SOCKS5 port configuration missing"])
        }
    
        guard let path = options?["path"] as? String else {
            throw NSError(domain: "PacketTunnel", code: -1,
                          userInfo: [NSLocalizedDescriptionKey: "Missing configuration path"])
        }
    
        do {
            try startXray(path: path)
    
            try await setTunnelNetworkSettings()
    
            try startSocks5Tunnel(serverPort: sock5Port)
    
        } catch {
            Logger().error("An error occurred while starting the service: \(error.localizedDescription)")
            throw error
        }
    }
    
    override func stopTunnel(with reason: NEProviderStopReason) async {
        Socks5Tunnel.quit()
    
        LibXrayStopXray()
    
        Logger().info("Tunnel stopped, reason: \(reason.rawValue)")
    }
    
    private func startXray(path: String) throws {
        let request = RunXrayRequest(
            datDir: Constant.assetDirectory.path,
            configPath: path,
            maxMemory: 50 * 1024 * 1024
        )
    
        do {
            let jsonData = try JSONEncoder().encode(request)
            let base64String = jsonData.base64EncodedString()
    
            LibXrayRunXray(base64String)
        } catch {
            Logger().error("Xray request encoding failed: \(error.localizedDescription)")
            throw error
        }
    }
    
    private func startSocks5Tunnel(serverPort port: Int = 10808) throws {
        let socks5Config = """
        tunnel:
          mtu: \(MTU)
    
        socks5:
          port: \(port)
          address: 127.0.0.1
          udp: true
    
        misc:
          task-stack-size: 20480
          connect-timeout: 5000
          read-write-timeout: 60000
          log-file: stderr
          log-level: debug
          limit-nofile: 65535
        """
    
        Socks5Tunnel.run(withConfig: .string(content: socks5Config)) { code in
            if code == 0 {
                Logger().info("Tun2Socks started successfully")
            } else {
                Logger().error("Tun2Socks failed to start, code: \(code)")
            }
        }
    }
    
    func setTunnelNetworkSettings() async throws {
        let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "fd00::1")
        settings.mtu = NSNumber(value: MTU)
    
        settings.ipv4Settings = {
            let ipv4 = NEIPv4Settings(
                addresses: ["198.18.0.1"],
                subnetMasks: ["255.255.255.0"]
            )
    
            let defaultV4Route = NEIPv4Route(
                destinationAddress: "0.0.0.0",
                subnetMask: "0.0.0.0"
            )
            defaultV4Route.gatewayAddress = "198.18.0.1"
    
            ipv4.includedRoutes = [defaultV4Route]
            ipv4.excludedRoutes = []
            return ipv4
        }()
    
        settings.ipv6Settings = {
            let ipv6 = NEIPv6Settings(
                addresses: ["fd6e:a81b:704f:1211::1"],
                networkPrefixLengths: [64]
            )
    
            let defaultV6Route = NEIPv6Route(
                destinationAddress: "::",
                networkPrefixLength: 0
            )
            defaultV6Route.gatewayAddress = "fd6e:a81b:704f:1211::1"
    
            ipv6.includedRoutes = [defaultV6Route]
            ipv6.excludedRoutes = []
            return ipv6
        }()
    
        let dnsSettings = NEDNSSettings(servers: [
            "1.1.1.1", // Cloudflare DNS (IPv4)
            "8.8.8.8", // Google DNS (IPv4)
            "2606:4700:4700::1111", // Cloudflare DNS (IPv6)
            "2001:4860:4860::8888", // Google DNS (IPv6)
        ])
        dnsSettings.matchDomains = [""]
    
        settings.dnsSettings = dnsSettings
    
        try await setTunnelNetworkSettings(settings)
    }
    

    }`

    Configuration.swift (Config Generation Code) (Not working)
    `import Foundation
    import LibXray
    import Network

    struct Configuration {
    func buildConfigurationData(config: String) throws -> Data {
    guard let inboundPortString = Util.loadFromUserDefaults(key: "sock5Port"),
    let trafficPortString = Util.loadFromUserDefaults(key: "trafficPort"),
    let inboundPort = NWEndpoint.Port(inboundPortString),
    let trafficPort = NWEndpoint.Port(trafficPortString)
    else {
    throw NSError(
    domain: "ConfigurationError",
    code: -1,
    userInfo: [NSLocalizedDescriptionKey: "Unable to load port from UserDefaults or port format is incorrect"]
    )
    }

        var configuration = try buildOutInbound(config: config)
        
        configuration["inbounds"] = buildInbound(inboundPort: inboundPort, trafficPort: trafficPort)
        configuration["metrics"] = buildMetrics()
        configuration["policy"] = buildPolicy()
        configuration["routing"] = try buildRoute()
        configuration["stats"] = [:]
    
        configuration = removeNullValues(from: configuration)
        configuration = removeSendThroughFromOutbounds(from: configuration)
    
        return try JSONSerialization.data(withJSONObject: configuration, options: .prettyPrinted)
    }
    
    func removeSendThroughFromOutbounds(from configuration: [String: Any]) -> [String: Any] {
        var updatedConfig = configuration
    
        if var outbounds = configuration["outbounds"] as? [[String: Any]], !outbounds.isEmpty {
            outbounds[0].removeValue(forKey: "sendThrough")
            updatedConfig["outbounds"] = outbounds
        }
    
        return updatedConfig
    }
    
    func removeNullValues(from dictionary: [String: Any]) -> [String: Any] {
        var updatedDictionary = dictionary
    
        for (key, value) in dictionary {
            if value is NSNull || "\(value)" == "<null>" {
                updatedDictionary.removeValue(forKey: key)
            } else if let nestedDictionary = value as? [String: Any] {
                updatedDictionary[key] = removeNullValues(from: nestedDictionary)
            } else if let nestedArray = value as? [[String: Any]] {
                updatedDictionary[key] = nestedArray.map { removeNullValues(from: $0) }
            }
        }
    
        return updatedDictionary
    }
    
    private func buildOutInbound(config: String) throws -> [String: Any] {
        guard let configData = config.data(using: .utf8) else {
            throw NSError(
                domain: "InvalidConfig",
                code: -1,
                userInfo: [NSLocalizedDescriptionKey: "无效的配置字符串"]
            )
        }
    
        let base64EncodedConfig = configData.base64EncodedString()
        let xrayJsonString = LibXrayConvertShareLinksToXrayJson(base64EncodedConfig)
    
        guard
            let decodedData = Data(base64Encoded: xrayJsonString),
            let decodedString = String(data: decodedData, encoding: .utf8),
            let jsonData = decodedString.data(using: .utf8),
            let jsonDict = try? JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any],
            let success = jsonDict["success"] as? Bool, success,
            var dataDict = jsonDict["data"] as? [String: Any],
            var outboundsArray = dataDict["outbounds"] as? [[String: Any]]
        else {
            throw NSError(
                domain: "InvalidXrayJson",
                code: -1,
                userInfo: [NSLocalizedDescriptionKey: "解析 Xray JSON 失败"]
            )
        }
    
        if var firstOutbound = outboundsArray.first {
            firstOutbound["tag"] = "proxy"
            outboundsArray[0] = firstOutbound
        }
    
        let newObject: [String: Any] = [
            "protocol": "freedom",
            "tag": "direct",
        ]
        outboundsArray.append(newObject)
    
        dataDict["outbounds"] = outboundsArray
    
        return dataDict
    }
    
    private func buildInbound(inboundPort: NWEndpoint.Port = Constant.sock5Port,
                              trafficPort: NWEndpoint.Port = Constant.trafficPort) -> [[String: Any]]
    {
        let socksInbound: [String: Any] = [
            "listen": "127.0.0.1",
            "port": Int(inboundPort.rawValue),
            "protocol": "socks",
            "settings": [
                "udp": true,
            ],
            "tag": "socks",
        ]
    
        let metricsInbound: [String: Any] = [
            "listen": "127.0.0.1",
            "port": Int(trafficPort.rawValue),
            "protocol": "dokodemo-door",
            "settings": [
                "address": "127.0.0.1",
            ],
            "tag": "metricsIn",
        ]
    
        return [socksInbound, metricsInbound]
    }
    
    private func buildMetrics() -> [String: Any] {
        [
            "tag": "metricsOut",
        ]
    }
    
    private func buildPolicy() -> [String: Any] {
        [
            "system": [
                "statsInboundDownlink": true,
                "statsInboundUplink": true,
                "statsOutboundDownlink": true,
                "statsOutboundUplink": true,
            ],
        ]
    }
    
    private func buildRoute() throws -> [String: Any] {
        var route: [String: Any] = [
            "domainStrategy": "AsIs",
            "rules": [
                [
                    "inboundTag": ["metricsIn"],
                    "outboundTag": "metricsOut",
                    "type": "field",
                ],
            ],
        ]
    
        var rulesArray = route["rules"] as? [[String: Any]] ?? []
    
    	rulesArray.append([
    		"type": "field",
    		"outboundTag": "direct",
    		"domain": ["geosite:cn"],
    	])
    
    	rulesArray.append([
    		"type": "field",
    		"outboundTag": "direct",
    		"ip": [
    			"223.5.5.5/32",
    			"114.114.114.114/32",
    			"geoip:private",
    			"geoip:cn",
    		],
    	])
    
    	rulesArray.append([
    		"type": "field",
    		"port": "0-65535",
    		"outboundTag": "proxy",
    	])
    
    	route["rules"] = rulesArray
    
        return route
    }
    

    }`

    Using above code having issue for no internet.

    Using below code internet working fine but whats and other some application not working
    PacketTunnelProvider.swift (Only Internet working some apps not )

    `import LibXray
    import Network
    import NetworkExtension
    import os

    struct RunXrayRequest: Codable {
    var datDir: String?
    var configPath: String?
    var maxMemory: Int64?
    }

    private let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "PacketTunnelProvider")

    class PacketTunnelProvider: NEPacketTunnelProvider {

    let MTU = 1380
    
    override func startTunnel(options: [String: NSObject]? = nil) async throws {
        guard let sock5Port = options?["sock5Port"] as? Int else {
            throw NSError(domain: "PacketTunnel", code: -1,
                          userInfo: [NSLocalizedDescriptionKey: "SOCKS5 port configuration missing"])
        }
    
        guard let path = options?["path"] as? String else {
            throw NSError(domain: "PacketTunnel", code: -1,
                          userInfo: [NSLocalizedDescriptionKey: "Missing configuration path"])
        }
    
        do {
            try startXray(path: path)
    
            try await setTunnelNetworkSettings()
    
        } catch {
            Logger().error("An error occurred while starting the service: \(error.localizedDescription)")
            throw error
        }
    }
    
    override func stopTunnel(with reason: NEProviderStopReason) async {
        LibXrayStopXray()
    
        Logger().info("Tunnel stopped, reason: \(reason.rawValue)")
    }
    
    private func startXray(path: String) throws {
        let request = RunXrayRequest(
            datDir: Constant.assetDirectory.path,
            configPath: path,
            maxMemory: 50 * 1024 * 1024
        )
    
        do {
            let jsonData = try JSONEncoder().encode(request)
            let base64String = jsonData.base64EncodedString()
    
            LibXrayRunXray(base64String)
        } catch {
            Logger().error("Xray request encoding failed: \(error.localizedDescription)")
            throw error
        }
    }
    
    func setTunnelNetworkSettings() async throws {
        let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "fd00::1")
        settings.mtu = NSNumber(value: MTU)
    
        settings.ipv4Settings = {
            let ipv4 = NEIPv4Settings(
                addresses: ["198.18.0.1"],
                subnetMasks: ["255.255.255.0"]
            )
    
            let defaultV4Route = NEIPv4Route(
                destinationAddress: "0.0.0.0",
                subnetMask: "0.0.0.0"
            )
            defaultV4Route.gatewayAddress = "198.18.0.1"
    
            ipv4.includedRoutes = [defaultV4Route]
            ipv4.excludedRoutes = []
            return ipv4
        }()
    
        settings.ipv6Settings = {
            let ipv6 = NEIPv6Settings(
                addresses: ["fd6e:a81b:704f:1211::1"],
                networkPrefixLengths: [64]
            )
    
            let defaultV6Route = NEIPv6Route(
                destinationAddress: "::",
                networkPrefixLength: 0
            )
            defaultV6Route.gatewayAddress = "fd6e:a81b:704f:1211::1"
    
            ipv6.includedRoutes = [defaultV6Route]
            ipv6.excludedRoutes = []
            return ipv6
        }()
    
        let dnsSettings = NEDNSSettings(servers: [
            "1.1.1.1", // Cloudflare DNS (IPv4)
            "8.8.8.8", // Google DNS (IPv4)
            "2606:4700:4700::1111", // Cloudflare DNS (IPv6)
            "2001:4860:4860::8888", // Google DNS (IPv6)
        ])
        dnsSettings.matchDomains = [""]
    
        settings.dnsSettings = dnsSettings
    	
    	let proxySettings: NEProxySettings = NEProxySettings()
    	proxySettings.httpServer = NEProxyServer(
    		address: "127.0.0.1",
    		port: 10808
    	)
    	proxySettings.httpsServer = NEProxyServer(
    		address: "127.0.0.1",
    		port: 10808
    	)
    	proxySettings.autoProxyConfigurationEnabled = false
    	proxySettings.httpEnabled = true
    	proxySettings.httpsEnabled = true
    	
    	settings.proxySettings = proxySettings
    
        try await setTunnelNetworkSettings(settings)
    }
    

    }`

    Configuration.swift (Generate Json Config) (Working for internet only)
    `import Foundation
    import LibXray
    import Network

    struct Configuration {
    func buildConfigurationData(config: String) throws -> Data {
    guard let inboundPortString = Util.loadFromUserDefaults(key: "sock5Port"),
    let trafficPortString = Util.loadFromUserDefaults(key: "trafficPort"),
    let inboundPort = NWEndpoint.Port(inboundPortString),
    let trafficPort = NWEndpoint.Port(trafficPortString)
    else {
    throw NSError(
    domain: "ConfigurationError",
    code: -1,
    userInfo: [NSLocalizedDescriptionKey: "Unable to load port from UserDefaults or port format is incorrect"]
    )
    }

        var configuration = try buildOutInbound(config: config)
        
        // Force all traffic through SOCKS5
        configuration["inbounds"] = buildInbound(inboundPort: inboundPort, trafficPort: trafficPort)
        configuration["dns"] = [
            "servers": [
                "https+local://1.1.1.1/dns-query",
                "1.0.0.1"
            ],
            "queryStrategy": "UseIPv4"
        ]
        configuration["stats"] = [:]
        // Apply Egypt DPI bypass enhancements
        configuration = enhanceConfigForEgyptDPI(config: configuration)
        
        configuration = removeNullValues(from: configuration)
        configuration = removeSendThroughFromOutbounds(from: configuration)
    
        return try JSONSerialization.data(withJSONObject: configuration, options: .prettyPrinted)
    }
    
    func removeSendThroughFromOutbounds(from configuration: [String: Any]) -> [String: Any] {
        var updatedConfig = configuration
    
        if var outbounds = configuration["outbounds"] as? [[String: Any]], !outbounds.isEmpty {
            outbounds[0].removeValue(forKey: "sendThrough")
            updatedConfig["outbounds"] = outbounds
        }
    
        return updatedConfig
    }
    
    func removeNullValues(from dictionary: [String: Any]) -> [String: Any] {
        var updatedDictionary = dictionary
    
        for (key, value) in dictionary {
            if value is NSNull || "\(value)" == "<null>" {
                updatedDictionary.removeValue(forKey: key)
            } else if let nestedDictionary = value as? [String: Any] {
                updatedDictionary[key] = removeNullValues(from: nestedDictionary)
            } else if let nestedArray = value as? [[String: Any]] {
                updatedDictionary[key] = nestedArray.map { removeNullValues(from: $0) }
            }
        }
    
        return updatedDictionary
    }
    
    private func buildOutInbound(config: String) throws -> [String: Any] {
        guard let configData = config.data(using: .utf8) else {
            throw NSError(
                domain: "InvalidConfig",
                code: -1,
                userInfo: [NSLocalizedDescriptionKey: "无效的配置字符串"]
            )
        }
    
        let base64EncodedConfig = configData.base64EncodedString()
        let xrayJsonString = LibXrayConvertShareLinksToXrayJson(base64EncodedConfig)
    
        guard
            let decodedData = Data(base64Encoded: xrayJsonString),
            let decodedString = String(data: decodedData, encoding: .utf8),
            let jsonData = decodedString.data(using: .utf8),
            let jsonDict = try? JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any],
            let success = jsonDict["success"] as? Bool, success,
            var dataDict = jsonDict["data"] as? [String: Any],
            var outboundsArray = dataDict["outbounds"] as? [[String: Any]]
        else {
            throw NSError(
                domain: "InvalidXrayJson",
                code: -1,
                userInfo: [NSLocalizedDescriptionKey: "解析 Xray JSON 失败"]
            )
        }
    
        if var firstOutbound = outboundsArray.first {
            firstOutbound["tag"] = "proxy"
            outboundsArray[0] = firstOutbound
        }
    
        let newObject: [String: Any] = [
            "protocol": "freedom",
            "tag": "direct",
        ]
        outboundsArray.append(newObject)
    
        dataDict["outbounds"] = outboundsArray
    
        return dataDict
    }
    
    private func buildInbound(inboundPort: NWEndpoint.Port = Constant.sock5Port,
                              trafficPort: NWEndpoint.Port = Constant.trafficPort) -> [[String: Any]]
    {
        let socksInbound: [String: Any] = [
            "tag": "socks-in",
            "port": 10808,
            "listen": "127.0.0.1",
            "protocol": "socks",
            "settings": [
                "auth": "noauth",
                "udp": true,
                "userLevel": 0,
                "ip": "127.0.0.1",
                "udpTimeout": 300
            ],
            "sniffing": [
                "enabled": true,
                "destOverride": ["http", "tls"]
            ],
            "streamSettings": [
                "sockopt": [
                    "mark": 255,
                    "tcpFastOpen": true,
                    "tproxy": "redirect"
                ]
            ]
        ]
    
        return [socksInbound]
    }
    
    private func buildMetrics() -> [String: Any] {
        [
            "tag": "metricsOut",
        ]
    }
    
    private func buildPolicy() -> [String: Any] {
        [
            "system": [
                "statsInboundDownlink": true,
                "statsInboundUplink": true,
                "statsOutboundDownlink": true,
                "statsOutboundUplink": true,
            ],
        ]
    }
    
    private func buildRoute() throws -> [String: Any] {
        var route: [String: Any] = [
            "domainStrategy": "IPIfNonMatch",
            "domainMatcher": "mph",
            "rules": [
                [
                    "type": "field",
                    "outboundTag": "proxy",
                    "port": "0-65535"  // Route all traffic through proxy
                ]
            ]
        ]
    
        return route
    }
    
    // Add this method to your Configuration class
    func enhanceConfigForEgyptDPI(config: [String: Any]) -> [String: Any] {
        var updatedConfig = config
        
        // Ensure SOCKS inbound has UDP enabled
        if var inbounds = updatedConfig["inbounds"] as? [[String: Any]] {
            for i in 0..<inbounds.count {
                if var inbound = inbounds[i] as? [String: Any],
                   let protocolType = inbound["protocol"] as? String,
                   protocolType == "socks" {
                    var settings = inbound["settings"] as? [String: Any] ?? [:]
                    settings["udp"] = true
                    inbound["settings"] = settings
                    inbounds[i] = inbound
                }
            }
            updatedConfig["inbounds"] = inbounds
        }
        
        // Add special sockopt settings for outbounds to evade DPI
        if var outbounds = updatedConfig["outbounds"] as? [[String: Any]],
           outbounds.count > 0,
           var mainOutbound = outbounds[0] as? [String: Any] {
            
            var streamSettings = mainOutbound["streamSettings"] as? [String: Any] ?? [:]
            streamSettings["sockopt"] = [
                "mark": 255,
                "tcpFastOpen": true,
                "tproxy": "redirect"
            ]
            
            mainOutbound["streamSettings"] = streamSettings
            outbounds[0] = mainOutbound
            updatedConfig["outbounds"] = outbounds
        }
        
        return updatedConfig
    }
    

    }`

    So according to last shared code it's working but half of the internet we can say where application using socket or any other communication which not via http in that case no internet. Please review and let me know where I have made wrong things.

    In advance Thanks

  4. codewithtamim commented on Jun 6, 2025

    @codewithtamim
    Contributor

    @CodeWithTamim Please find attached code which I am using

    PacketTunnelProvider.swift (Not working)

    `import LibXray import Network import NetworkExtension import os import Tun2SocksKit

    struct RunXrayRequest: Codable { var datDir: String? var configPath: String? var maxMemory: Int64? }

    private let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "PacketTunnelProvider")

    class PacketTunnelProvider: NEPacketTunnelProvider {

    let MTU = 1380
    
    override func startTunnel(options: [String: NSObject]? = nil) async throws {
        guard let sock5Port = options?["sock5Port"] as? Int else {
            throw NSError(domain: "PacketTunnel", code: -1,
                          userInfo: [NSLocalizedDescriptionKey: "SOCKS5 port configuration missing"])
        }
    
        guard let path = options?["path"] as? String else {
            throw NSError(domain: "PacketTunnel", code: -1,
                          userInfo: [NSLocalizedDescriptionKey: "Missing configuration path"])
        }
    
        do {
            try startXray(path: path)
    
            try await setTunnelNetworkSettings()
    
            try startSocks5Tunnel(serverPort: sock5Port)
    
        } catch {
            Logger().error("An error occurred while starting the service: \(error.localizedDescription)")
            throw error
        }
    }
    
    override func stopTunnel(with reason: NEProviderStopReason) async {
        Socks5Tunnel.quit()
    
        LibXrayStopXray()
    
        Logger().info("Tunnel stopped, reason: \(reason.rawValue)")
    }
    
    private func startXray(path: String) throws {
        let request = RunXrayRequest(
            datDir: Constant.assetDirectory.path,
            configPath: path,
            maxMemory: 50 * 1024 * 1024
        )
    
        do {
            let jsonData = try JSONEncoder().encode(request)
            let base64String = jsonData.base64EncodedString()
    
            LibXrayRunXray(base64String)
        } catch {
            Logger().error("Xray request encoding failed: \(error.localizedDescription)")
            throw error
        }
    }
    
    private func startSocks5Tunnel(serverPort port: Int = 10808) throws {
        let socks5Config = """
        tunnel:
          mtu: \(MTU)
    
        socks5:
          port: \(port)
          address: 127.0.0.1
          udp: true
    
        misc:
          task-stack-size: 20480
          connect-timeout: 5000
          read-write-timeout: 60000
          log-file: stderr
          log-level: debug
          limit-nofile: 65535
        """
    
        Socks5Tunnel.run(withConfig: .string(content: socks5Config)) { code in
            if code == 0 {
                Logger().info("Tun2Socks started successfully")
            } else {
                Logger().error("Tun2Socks failed to start, code: \(code)")
            }
        }
    }
    
    func setTunnelNetworkSettings() async throws {
        let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "fd00::1")
        settings.mtu = NSNumber(value: MTU)
    
        settings.ipv4Settings = {
            let ipv4 = NEIPv4Settings(
                addresses: ["198.18.0.1"],
                subnetMasks: ["255.255.255.0"]
            )
    
            let defaultV4Route = NEIPv4Route(
                destinationAddress: "0.0.0.0",
                subnetMask: "0.0.0.0"
            )
            defaultV4Route.gatewayAddress = "198.18.0.1"
    
            ipv4.includedRoutes = [defaultV4Route]
            ipv4.excludedRoutes = []
            return ipv4
        }()
    
        settings.ipv6Settings = {
            let ipv6 = NEIPv6Settings(
                addresses: ["fd6e:a81b:704f:1211::1"],
                networkPrefixLengths: [64]
            )
    
            let defaultV6Route = NEIPv6Route(
                destinationAddress: "::",
                networkPrefixLength: 0
            )
            defaultV6Route.gatewayAddress = "fd6e:a81b:704f:1211::1"
    
            ipv6.includedRoutes = [defaultV6Route]
            ipv6.excludedRoutes = []
            return ipv6
        }()
    
        let dnsSettings = NEDNSSettings(servers: [
            "1.1.1.1", // Cloudflare DNS (IPv4)
            "8.8.8.8", // Google DNS (IPv4)
            "2606:4700:4700::1111", // Cloudflare DNS (IPv6)
            "2001:4860:4860::8888", // Google DNS (IPv6)
        ])
        dnsSettings.matchDomains = [""]
    
        settings.dnsSettings = dnsSettings
    
        try await setTunnelNetworkSettings(settings)
    }
    

    }`

    Configuration.swift (Config Generation Code) (Not working) `import Foundation import LibXray import Network

    struct Configuration { func buildConfigurationData(config: String) throws -> Data { guard let inboundPortString = Util.loadFromUserDefaults(key: "sock5Port"), let trafficPortString = Util.loadFromUserDefaults(key: "trafficPort"), let inboundPort = NWEndpoint.Port(inboundPortString), let trafficPort = NWEndpoint.Port(trafficPortString) else { throw NSError( domain: "ConfigurationError", code: -1, userInfo: [NSLocalizedDescriptionKey: "Unable to load port from UserDefaults or port format is incorrect"] ) }

        var configuration = try buildOutInbound(config: config)
        
        configuration["inbounds"] = buildInbound(inboundPort: inboundPort, trafficPort: trafficPort)
        configuration["metrics"] = buildMetrics()
        configuration["policy"] = buildPolicy()
        configuration["routing"] = try buildRoute()
        configuration["stats"] = [:]
    
        configuration = removeNullValues(from: configuration)
        configuration = removeSendThroughFromOutbounds(from: configuration)
    
        return try JSONSerialization.data(withJSONObject: configuration, options: .prettyPrinted)
    }
    
    func removeSendThroughFromOutbounds(from configuration: [String: Any]) -> [String: Any] {
        var updatedConfig = configuration
    
        if var outbounds = configuration["outbounds"] as? [[String: Any]], !outbounds.isEmpty {
            outbounds[0].removeValue(forKey: "sendThrough")
            updatedConfig["outbounds"] = outbounds
        }
    
        return updatedConfig
    }
    
    func removeNullValues(from dictionary: [String: Any]) -> [String: Any] {
        var updatedDictionary = dictionary
    
        for (key, value) in dictionary {
            if value is NSNull || "\(value)" == "<null>" {
                updatedDictionary.removeValue(forKey: key)
            } else if let nestedDictionary = value as? [String: Any] {
                updatedDictionary[key] = removeNullValues(from: nestedDictionary)
            } else if let nestedArray = value as? [[String: Any]] {
                updatedDictionary[key] = nestedArray.map { removeNullValues(from: $0) }
            }
        }
    
        return updatedDictionary
    }
    
    private func buildOutInbound(config: String) throws -> [String: Any] {
        guard let configData = config.data(using: .utf8) else {
            throw NSError(
                domain: "InvalidConfig",
                code: -1,
                userInfo: [NSLocalizedDescriptionKey: "无效的配置字符串"]
            )
        }
    
        let base64EncodedConfig = configData.base64EncodedString()
        let xrayJsonString = LibXrayConvertShareLinksToXrayJson(base64EncodedConfig)
    
        guard
            let decodedData = Data(base64Encoded: xrayJsonString),
            let decodedString = String(data: decodedData, encoding: .utf8),
            let jsonData = decodedString.data(using: .utf8),
            let jsonDict = try? JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any],
            let success = jsonDict["success"] as? Bool, success,
            var dataDict = jsonDict["data"] as? [String: Any],
            var outboundsArray = dataDict["outbounds"] as? [[String: Any]]
        else {
            throw NSError(
                domain: "InvalidXrayJson",
                code: -1,
                userInfo: [NSLocalizedDescriptionKey: "解析 Xray JSON 失败"]
            )
        }
    
        if var firstOutbound = outboundsArray.first {
            firstOutbound["tag"] = "proxy"
            outboundsArray[0] = firstOutbound
        }
    
        let newObject: [String: Any] = [
            "protocol": "freedom",
            "tag": "direct",
        ]
        outboundsArray.append(newObject)
    
        dataDict["outbounds"] = outboundsArray
    
        return dataDict
    }
    
    private func buildInbound(inboundPort: NWEndpoint.Port = Constant.sock5Port,
                              trafficPort: NWEndpoint.Port = Constant.trafficPort) -> [[String: Any]]
    {
        let socksInbound: [String: Any] = [
            "listen": "127.0.0.1",
            "port": Int(inboundPort.rawValue),
            "protocol": "socks",
            "settings": [
                "udp": true,
            ],
            "tag": "socks",
        ]
    
        let metricsInbound: [String: Any] = [
            "listen": "127.0.0.1",
            "port": Int(trafficPort.rawValue),
            "protocol": "dokodemo-door",
            "settings": [
                "address": "127.0.0.1",
            ],
            "tag": "metricsIn",
        ]
    
        return [socksInbound, metricsInbound]
    }
    
    private func buildMetrics() -> [String: Any] {
        [
            "tag": "metricsOut",
        ]
    }
    
    private func buildPolicy() -> [String: Any] {
        [
            "system": [
                "statsInboundDownlink": true,
                "statsInboundUplink": true,
                "statsOutboundDownlink": true,
                "statsOutboundUplink": true,
            ],
        ]
    }
    
    private func buildRoute() throws -> [String: Any] {
        var route: [String: Any] = [
            "domainStrategy": "AsIs",
            "rules": [
                [
                    "inboundTag": ["metricsIn"],
                    "outboundTag": "metricsOut",
                    "type": "field",
                ],
            ],
        ]
    
        var rulesArray = route["rules"] as? [[String: Any]] ?? []
    
    	rulesArray.append([
    		"type": "field",
    		"outboundTag": "direct",
    		"domain": ["geosite:cn"],
    	])
    
    	rulesArray.append([
    		"type": "field",
    		"outboundTag": "direct",
    		"ip": [
    			"223.5.5.5/32",
    			"114.114.114.114/32",
    			"geoip:private",
    			"geoip:cn",
    		],
    	])
    
    	rulesArray.append([
    		"type": "field",
    		"port": "0-65535",
    		"outboundTag": "proxy",
    	])
    
    	route["rules"] = rulesArray
    
        return route
    }
    

    }`

    Using above code having issue for no internet.

    Using below code internet working fine but whats and other some application not working PacketTunnelProvider.swift (Only Internet working some apps not )

    `import LibXray import Network import NetworkExtension import os

    struct RunXrayRequest: Codable { var datDir: String? var configPath: String? var maxMemory: Int64? }

    private let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "PacketTunnelProvider")

    class PacketTunnelProvider: NEPacketTunnelProvider {

    let MTU = 1380
    
    override func startTunnel(options: [String: NSObject]? = nil) async throws {
        guard let sock5Port = options?["sock5Port"] as? Int else {
            throw NSError(domain: "PacketTunnel", code: -1,
                          userInfo: [NSLocalizedDescriptionKey: "SOCKS5 port configuration missing"])
        }
    
        guard let path = options?["path"] as? String else {
            throw NSError(domain: "PacketTunnel", code: -1,
                          userInfo: [NSLocalizedDescriptionKey: "Missing configuration path"])
        }
    
        do {
            try startXray(path: path)
    
            try await setTunnelNetworkSettings()
    
        } catch {
            Logger().error("An error occurred while starting the service: \(error.localizedDescription)")
            throw error
        }
    }
    
    override func stopTunnel(with reason: NEProviderStopReason) async {
        LibXrayStopXray()
    
        Logger().info("Tunnel stopped, reason: \(reason.rawValue)")
    }
    
    private func startXray(path: String) throws {
        let request = RunXrayRequest(
            datDir: Constant.assetDirectory.path,
            configPath: path,
            maxMemory: 50 * 1024 * 1024
        )
    
        do {
            let jsonData = try JSONEncoder().encode(request)
            let base64String = jsonData.base64EncodedString()
    
            LibXrayRunXray(base64String)
        } catch {
            Logger().error("Xray request encoding failed: \(error.localizedDescription)")
            throw error
        }
    }
    
    func setTunnelNetworkSettings() async throws {
        let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "fd00::1")
        settings.mtu = NSNumber(value: MTU)
    
        settings.ipv4Settings = {
            let ipv4 = NEIPv4Settings(
                addresses: ["198.18.0.1"],
                subnetMasks: ["255.255.255.0"]
            )
    
            let defaultV4Route = NEIPv4Route(
                destinationAddress: "0.0.0.0",
                subnetMask: "0.0.0.0"
            )
            defaultV4Route.gatewayAddress = "198.18.0.1"
    
            ipv4.includedRoutes = [defaultV4Route]
            ipv4.excludedRoutes = []
            return ipv4
        }()
    
        settings.ipv6Settings = {
            let ipv6 = NEIPv6Settings(
                addresses: ["fd6e:a81b:704f:1211::1"],
                networkPrefixLengths: [64]
            )
    
            let defaultV6Route = NEIPv6Route(
                destinationAddress: "::",
                networkPrefixLength: 0
            )
            defaultV6Route.gatewayAddress = "fd6e:a81b:704f:1211::1"
    
            ipv6.includedRoutes = [defaultV6Route]
            ipv6.excludedRoutes = []
            return ipv6
        }()
    
        let dnsSettings = NEDNSSettings(servers: [
            "1.1.1.1", // Cloudflare DNS (IPv4)
            "8.8.8.8", // Google DNS (IPv4)
            "2606:4700:4700::1111", // Cloudflare DNS (IPv6)
            "2001:4860:4860::8888", // Google DNS (IPv6)
        ])
        dnsSettings.matchDomains = [""]
    
        settings.dnsSettings = dnsSettings
    	
    	let proxySettings: NEProxySettings = NEProxySettings()
    	proxySettings.httpServer = NEProxyServer(
    		address: "127.0.0.1",
    		port: 10808
    	)
    	proxySettings.httpsServer = NEProxyServer(
    		address: "127.0.0.1",
    		port: 10808
    	)
    	proxySettings.autoProxyConfigurationEnabled = false
    	proxySettings.httpEnabled = true
    	proxySettings.httpsEnabled = true
    	
    	settings.proxySettings = proxySettings
    
        try await setTunnelNetworkSettings(settings)
    }
    

    }`

    Configuration.swift (Generate Json Config) (Working for internet only) `import Foundation import LibXray import Network

    struct Configuration { func buildConfigurationData(config: String) throws -> Data { guard let inboundPortString = Util.loadFromUserDefaults(key: "sock5Port"), let trafficPortString = Util.loadFromUserDefaults(key: "trafficPort"), let inboundPort = NWEndpoint.Port(inboundPortString), let trafficPort = NWEndpoint.Port(trafficPortString) else { throw NSError( domain: "ConfigurationError", code: -1, userInfo: [NSLocalizedDescriptionKey: "Unable to load port from UserDefaults or port format is incorrect"] ) }

        var configuration = try buildOutInbound(config: config)
        
        // Force all traffic through SOCKS5
        configuration["inbounds"] = buildInbound(inboundPort: inboundPort, trafficPort: trafficPort)
        configuration["dns"] = [
            "servers": [
                "https+local://1.1.1.1/dns-query",
                "1.0.0.1"
            ],
            "queryStrategy": "UseIPv4"
        ]
        configuration["stats"] = [:]
        // Apply Egypt DPI bypass enhancements
        configuration = enhanceConfigForEgyptDPI(config: configuration)
        
        configuration = removeNullValues(from: configuration)
        configuration = removeSendThroughFromOutbounds(from: configuration)
    
        return try JSONSerialization.data(withJSONObject: configuration, options: .prettyPrinted)
    }
    
    func removeSendThroughFromOutbounds(from configuration: [String: Any]) -> [String: Any] {
        var updatedConfig = configuration
    
        if var outbounds = configuration["outbounds"] as? [[String: Any]], !outbounds.isEmpty {
            outbounds[0].removeValue(forKey: "sendThrough")
            updatedConfig["outbounds"] = outbounds
        }
    
        return updatedConfig
    }
    
    func removeNullValues(from dictionary: [String: Any]) -> [String: Any] {
        var updatedDictionary = dictionary
    
        for (key, value) in dictionary {
            if value is NSNull || "\(value)" == "<null>" {
                updatedDictionary.removeValue(forKey: key)
            } else if let nestedDictionary = value as? [String: Any] {
                updatedDictionary[key] = removeNullValues(from: nestedDictionary)
            } else if let nestedArray = value as? [[String: Any]] {
                updatedDictionary[key] = nestedArray.map { removeNullValues(from: $0) }
            }
        }
    
        return updatedDictionary
    }
    
    private func buildOutInbound(config: String) throws -> [String: Any] {
        guard let configData = config.data(using: .utf8) else {
            throw NSError(
                domain: "InvalidConfig",
                code: -1,
                userInfo: [NSLocalizedDescriptionKey: "无效的配置字符串"]
            )
        }
    
        let base64EncodedConfig = configData.base64EncodedString()
        let xrayJsonString = LibXrayConvertShareLinksToXrayJson(base64EncodedConfig)
    
        guard
            let decodedData = Data(base64Encoded: xrayJsonString),
            let decodedString = String(data: decodedData, encoding: .utf8),
            let jsonData = decodedString.data(using: .utf8),
            let jsonDict = try? JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any],
            let success = jsonDict["success"] as? Bool, success,
            var dataDict = jsonDict["data"] as? [String: Any],
            var outboundsArray = dataDict["outbounds"] as? [[String: Any]]
        else {
            throw NSError(
                domain: "InvalidXrayJson",
                code: -1,
                userInfo: [NSLocalizedDescriptionKey: "解析 Xray JSON 失败"]
            )
        }
    
        if var firstOutbound = outboundsArray.first {
            firstOutbound["tag"] = "proxy"
            outboundsArray[0] = firstOutbound
        }
    
        let newObject: [String: Any] = [
            "protocol": "freedom",
            "tag": "direct",
        ]
        outboundsArray.append(newObject)
    
        dataDict["outbounds"] = outboundsArray
    
        return dataDict
    }
    
    private func buildInbound(inboundPort: NWEndpoint.Port = Constant.sock5Port,
                              trafficPort: NWEndpoint.Port = Constant.trafficPort) -> [[String: Any]]
    {
        let socksInbound: [String: Any] = [
            "tag": "socks-in",
            "port": 10808,
            "listen": "127.0.0.1",
            "protocol": "socks",
            "settings": [
                "auth": "noauth",
                "udp": true,
                "userLevel": 0,
                "ip": "127.0.0.1",
                "udpTimeout": 300
            ],
            "sniffing": [
                "enabled": true,
                "destOverride": ["http", "tls"]
            ],
            "streamSettings": [
                "sockopt": [
                    "mark": 255,
                    "tcpFastOpen": true,
                    "tproxy": "redirect"
                ]
            ]
        ]
    
        return [socksInbound]
    }
    
    private func buildMetrics() -> [String: Any] {
        [
            "tag": "metricsOut",
        ]
    }
    
    private func buildPolicy() -> [String: Any] {
        [
            "system": [
                "statsInboundDownlink": true,
                "statsInboundUplink": true,
                "statsOutboundDownlink": true,
                "statsOutboundUplink": true,
            ],
        ]
    }
    
    private func buildRoute() throws -> [String: Any] {
        var route: [String: Any] = [
            "domainStrategy": "IPIfNonMatch",
            "domainMatcher": "mph",
            "rules": [
                [
                    "type": "field",
                    "outboundTag": "proxy",
                    "port": "0-65535"  // Route all traffic through proxy
                ]
            ]
        ]
    
        return route
    }
    
    // Add this method to your Configuration class
    func enhanceConfigForEgyptDPI(config: [String: Any]) -> [String: Any] {
        var updatedConfig = config
        
        // Ensure SOCKS inbound has UDP enabled
        if var inbounds = updatedConfig["inbounds"] as? [[String: Any]] {
            for i in 0..<inbounds.count {
                if var inbound = inbounds[i] as? [String: Any],
                   let protocolType = inbound["protocol"] as? String,
                   protocolType == "socks" {
                    var settings = inbound["settings"] as? [String: Any] ?? [:]
                    settings["udp"] = true
                    inbound["settings"] = settings
                    inbounds[i] = inbound
                }
            }
            updatedConfig["inbounds"] = inbounds
        }
        
        // Add special sockopt settings for outbounds to evade DPI
        if var outbounds = updatedConfig["outbounds"] as? [[String: Any]],
           outbounds.count > 0,
           var mainOutbound = outbounds[0] as? [String: Any] {
            
            var streamSettings = mainOutbound["streamSettings"] as? [String: Any] ?? [:]
            streamSettings["sockopt"] = [
                "mark": 255,
                "tcpFastOpen": true,
                "tproxy": "redirect"
            ]
            
            mainOutbound["streamSettings"] = streamSettings
            outbounds[0] = mainOutbound
            updatedConfig["outbounds"] = outbounds
        }
        
        return updatedConfig
    }
    

    }`

    So according to last shared code it's working but half of the internet we can say where application using socket or any other communication which not via http in that case no internet. Please review and let me know where I have made wrong things.

    In advance Thanks

    DNS

  5. commencementtech commented on Jun 6, 2025

    @commencementtech
    Author

    Sorry not getting your point @codewithtamim

  6. codewithtamim commented on Jun 6, 2025

    @codewithtamim
    Contributor

    Fix dns

  7. commencementtech commented on Jun 6, 2025

    @commencementtech
    Author

    Okay let me check with updating it and update you

  8. commencementtech commented on Jun 7, 2025

    @commencementtech
    Author

    I’ve tried updating and removing the DNS, but the issue remains the same. The problem occurs specifically when someone located in Egypt uses the VPN—they still experience the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions