10000 Egypt DPI no internet issue · Issue #83 · XTLS/libXray · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Egypt DPI no internet issue #83

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
commencementtech opened this issue Jun 2, 2025 · 8 comments
Open

Egypt DPI no internet issue #83

commencementtech opened this issue Jun 2, 2025 · 8 comments

Comments

@commencementtech
Copy link

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

@yiguodev
Copy link
Collaborator
yiguodev commented Jun 3, 2025

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

@CodeWithTamim
Copy link
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

@commencementtech
Copy link
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

@CodeWithTamim
Copy link
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 = con
8000
fig.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

@commencementtech
Copy link
Author

Sorry not getting your point @CodeWithTamim

@CodeWithTamim
Copy link
Contributor

Fix dns

@commencementtech
Copy link
Author

Okay let me check with updating it and update you

@commencementtech
Copy link
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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants
0