EbrahimTahernejad / Tun2SocksKit

Tun2Socks framework repository
50 stars 32 forks source link

Tun2Socks not starting/working properly. #10

Closed aliakhgar closed 2 weeks ago

aliakhgar commented 1 month ago

I've been using HevTun2Socks from older version, v2. And I'm migrating to this new versions RN. we have built ios xray apps using this tunnel and many users complaining about the traffic not being tunneled. We have tested and made sure that direct connection to 10808 socks port (for example via telegram proxies) is working perfectly fine but tun2socks is not tunneling perfectly. I myself have been using the apps we built using this tunnel and saw no issues but users are heavily reporting constant tunnel issues.

And also I've migrated to new 3.6.9 version but there is one problem, tun2socks not starting! and no return code. I've logged my network extension and here is logs, also xray and tun2socks both are running in net extension.

May  7 17:47:59 v2rayext(PlugInKit)[15729] <Notice>: Hello, I'm launching as euid = 501, uid = 501, personaid = 1000, type = DEFAULT, name = <private>
May  7 17:47:59 v2rayext(libxpc.dylib)[15729] <Notice>: [0x160070000] activating connection: mach=true listener=false peer=false name=com.apple.cfprefsd.daemon.system
May  7 17:47:59 v2rayext(libxpc.dylib)[15729] <Notice>: [0x160070100] activating connection: mach=true listener=false peer=false name=com.apple.cfprefsd.daemon
May  7 17:47:59 v2rayext(libxpc.dylib)[15729] <Notice>: [0x104e5b680] activating connection: mach=true listener=false peer=false name=com.apple.lsd.mapdb
May  7 17:47:59 v2rayext(RunningBoardServices)[15729] <Notice>: Initializing connection
May  7 17:47:59 v2rayext(RunningBoardServices)[15729] <Notice>: Removing all cached process handles
May  7 17:47:59 v2rayext(RunningBoardServices)[15729] <Notice>: Sending handshake request attempt #1 to server
May  7 17:47:59 v2rayext(RunningBoardServices)[15729] <Notice>: Creating connection to com.apple.runningboard
May  7 17:47:59 v2rayext(libxpc.dylib)[15729] <Notice>: [0x160070400] activating connection: mach=true listener=false peer=false name=com.apple.runningboard
May  7 17:47:59 v2rayext(RunningBoardServices)[15729] <Notice>: Handshake succeeded
May  7 17:47:59 v2rayext(RunningBoardServices)[15729] <Notice>: Identity resolved as xpcservice<com.mayaTeam.Maya-Vpn.v2rayext([osservice<com.apple.neagent-ios>:388:388])>
May  7 17:47:59 v2rayext(PlugInKit)[15729] <Notice>: Bootstrapping; Bootstrap complete. Ready for handshake from host.
May  7 17:47:59 v2rayext(libxpc.dylib)[15729] <Notice>: [0x1600e0000] activating connection: mach=false listener=true peer=false name=com.mayaTeam.Maya-Vpn.v2rayext
May  7 17:47:59 v2rayext(libxpc.dylib)[15729] <Notice>: [0x1600e0140] activating connection: mach=false listener=false peer=true name=com.mayaTeam.Maya-Vpn.v2rayext.peer[388].0x1600e0140
May  7 17:47:59 v2rayext(PlugInKit)[15729] <Notice>: [u A490FF4A-F4E1-47D0-840A-92BA904AD941] [(null)((null))] Prepare received as euid = 501, uid = 501, personaid = 1000, type = DEFAULT, name = <private>
May  7 17:47:59 v2rayext(PlugInKit)[15729] <Notice>: [u 9FAC39CE-0449-457D-ADEE-C910D68BEDE6] [<private>(<private>)] Set sole personality.
May  7 17:47:59 v2rayext(ExtensionFoundation)[15729] <Notice>: Class EXGetExtensionClass(void) returning EXConcreteExtension
May  7 17:47:59 v2rayext(ExtensionFoundation)[15729] <Notice>: Class EXGetExtensionContextVendorClass(void) returning EXConcreteExtensionContextVendor
May  7 17:47:59 v2rayext(libxpc.dylib)[15729] <Notice>: [0x1600e03c0] activating connection: mach=true listener=true peer=false name=com.mayaTeam.Maya-Vpn.v2rayext.apple-extension-service
May  7 17:47:59 v2rayext(ExtensionFoundation)[15729] <Notice>: Cecking in with launchd immediately
May  7 17:47:59 v2rayext(PlugInKit)[15729] <Notice>: [u 9FAC39CE-0449-457D-ADEE-C910D68BEDE6] [<private>(<private>)] Begin using received as euid = 501, uid = 501, personaid = 1000, type = DEFAULT, name = <private>
May  7 17:47:59 v2rayext(libxpc.dylib)[15729] <Notice>: [0x104e5f200] activating connection: mach=false listener=false peer=true name=com.mayaTeam.Maya-Vpn.v2rayext.apple-extension-service.peer[388].0x104e5f200
May  7 17:47:59 v2rayext(ExtensionFoundation)[15729] <Notice>: Class EXGetExtensionContextInternalClass(void) returning EXExtensionContextImplementation
May  7 17:47:59 v2rayext(libxpc.dylib)[15729] <Notice>: [0x1600e0500] activating connection: mach=false listener=false peer=false name=(anonymous)
May  7 17:47:59 v2rayext(Network)[15729] <Notice>: networkd_settings_read_from_file initialized networkd settings by reading plist directly
May  7 17:47:59 v2rayext(Network)[15729] <Notice>: networkd_settings_read_from_file initialized networkd settings by reading plist directly
May  7 17:47:59 v2rayext(Network)[15729] <Notice>: nw_path_evaluator_start [BDFDCE54-F249-4213-A6EE-F3736DF5CFCA <NULL> generic, attribution: developer]
    path: satisfied (Path is satisfied), interface: pdp_ip0[lte], ipv4, dns, expensive, estimated upload: 65536Bps, uses cell
May  7 17:47:59 v2rayext(ExtensionFoundation)[15729] <Notice>: in _willPerformHostCallback: block ( UUID: 225BE22C-1A7D-4FE2-A922-FDF80B64B187 error: (null) )
May  7 17:47:59 v2rayext(NetworkExtension)[15729] <Notice>: Using interface name utun37
May  7 17:47:59 v2rayext(NetworkExtension)[15729] <Notice>: Created a new NEVirtualInterface "utun37" from socket
May  7 17:47:59 v2rayext(NetworkExtension)[15729] <Notice>: [Extension com.mayaTeam.Maya-Vpn.v2rayext]: Calling startTunnelWithOptions with options 0x160084aa0
May  7 17:47:59 v2rayext(Foundation)[15729] <Notice>: Configggg {"stats":{},"log":{"loglevel":"none"},"policy":{"levels":{"8":{"handshake":4,"connIdle":300,"uplinkOnly":1,"downlinkOnly":1}},"system":{"statsOutboundUplink":true,"statsOutboundDownlink":true}...
May  7 17:47:59 v2rayext(libsystem_containermanager.dylib)[15729] <Notice>: Requesting app group container lookup; personaid = 1000, type = DEFAULT, name = DC01D3E5-F9A8-45ED-B634-89C9E519821C, origin [pid = 15701, personaid = 1000], proximate [pid = 388, personaid = 200], identifier = <private>, euid = 501, uid = 501, platform = 2
May  7 17:47:59 v2rayext(libxpc.dylib)[15729] <Notice>: [0x160070500] activating connection: mach=true listener=false peer=false name=com.apple.containermanagerd
May  7 17:47:59 v2rayext(libsystem_containermanager.dylib)[15729] <Notice>: Consumed sandbox extension; path = [<private>], handle = 1
May  7 17:47:59 v2rayext(libsystem_containermanager.dylib)[15729] <Notice>: container_create_or_lookup_app_group_path_by_app_group_identifier: success
May  7 17:47:59 v2rayext(Foundation)[15729] <Notice>: Shared Dir :: /private/var/mobile/Containers/Shared/AppGroup/A87A6BBD-E6F2-4858-8C73-F526E99DE450
May  7 17:47:59 v2rayext(Foundation)[15729] <Notice>: >>>>>>>>>>>>>>>> Network Tunnel Setting...
May  7 17:47:59 v2rayext(Foundation)[15729] <Notice>: JSON VALIDITY
May  7 17:47:59 v2rayext(Foundation)[15729] <Notice>: Running Result
May  7 17:48:00 v2rayext(Foundation)[15729] <Notice>: >>>>>>>>>>>>>>>> Starting Socks5Tunnel...
May  7 17:48:01 v2rayext(libxpc.dylib)[15729] <Notice>: [0x160070500] invalidated because the current process cancelled the connection by calling xpc_connection_cancel()

My net extension execution stops exactly at socks5 run. tunnel wont start but i can connect to 10808 port in telegram seamlessly.

Also here is my net extension code also. I've played alooot with this code, this code is on version 3.0.6 i think not 3.6.9.

  override func startTunnel(options : [String: NSObject]?) async throws {

      conf = options?["config"] as? String
      groupName = options?["groupName"] as? String
      NSLog("Configggg %@", conf)

    sharedDirectory = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: groupName)

     NSLog("Shared Dir :: %@", sharedDirectory.relativePath)

    cacheDir = sharedDirectory
          .appendingPathComponent("Library", isDirectory: true)
          .appendingPathComponent("Caches", isDirectory: true)

    assetsDirectory = sharedDirectory
          .appendingPathComponent("Library", isDirectory: true)
          .appendingPathComponent("Assets", isDirectory: true)

    var tunnelFileDescriptor: Int32? {
        var ctlInfo = ctl_info()
        withUnsafeMutablePointer(to: &ctlInfo.ctl_name) {
            $0.withMemoryRebound(to: CChar.self, capacity: MemoryLayout.size(ofValue: $0.pointee)) {
                _ = strcpy($0, "com.apple.net.utun_control")
            }
        }
        for fd: Int32 in 0...1024 {
            var addr = sockaddr_ctl()
            var ret: Int32 = -1
            var len = socklen_t(MemoryLayout.size(ofValue: addr))
            withUnsafeMutablePointer(to: &addr) {
                $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
                    ret = getpeername(fd, $0, &len)
                }
            }
            if ret != 0 || addr.sc_family != AF_SYSTEM {
                continue
            }
            if ctlInfo.ctl_id == 0 {
                ret = ioctl(fd, CTLIOCGINFO, &ctlInfo)
                if ret != 0 {
                    continue
                }
            }
            if addr.sc_id == ctlInfo.ctl_id {
                return fd
            }
        }
        return nil
    }

      let socks5Config = """
      tunnel:
        mtu: 8500

      socks5:
        port: 10808
        address: ::1
        udp: 'udp'

      misc:
        task-stack-size: 20480
        connect-timeout: 5000
        read-write-timeout: 60000
        log-file: stderr
        log-level: debug
        limit-nofile: 65535
      """

      NSLog(">>>>>>>>>>>>>>>> Network Tunnel Setting...")
      self.setTunnelNetworkSettings(getNetworkSettings(with: 8500, ipv6: true)) { [socks5Config] error in
          if let error = error {
            self.completionHandler(with: error)
              return
          }
        NSLog(">>>>>>>>>>>>>>>> Starting Socks5Tunnel...")

        let configurationFilePath = self.cacheDir.appendingPathComponent("config.yml")
        FileManager.default.createFile(atPath: configurationFilePath.relativePath, contents: socks5Config.data(using: .utf8)!)

        DispatchQueue.global(qos: .userInitiated).async { [] () in

        }

        Socks5Tunnel.run(withConfig: configurationFilePath.relativePath, using: tunnelFileDescriptor ?? 0, completionHandler: self.completionHandler)

        self.completionHandler(with: "Hi")
      }

Can you please help me with a clear test-case so that i can make sure about the code or help me find out whats wrong with tunnel starting. I can provide full OS log if you want too.

testing on ios 17.4 , iPhone 13. Thanks.

EbrahimTahernejad commented 1 month ago

this is not 3.6.9's api.

are you sure you're upgraded?

this shouldn't even compile!

aliakhgar commented 1 month ago

Yes you are right, version above is 3.0.7 and I imported Tun2SocksKitC and obtained fileDescriptor and started Hevc manually. Didn't work.

Here is my code on version 3.6.9

 override func startTunnel(options : [String: NSObject]?) async throws {

    conf = options?["config"] as? String
    groupName = options?["groupName"] as? String

    sharedDirectory = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: groupName)

    cacheDir = sharedDirectory
          .appendingPathComponent("Library", isDirectory: true)
          .appendingPathComponent("Caches", isDirectory: true)

    assetsDirectory = sharedDirectory
          .appendingPathComponent("Library", isDirectory: true)
          .appendingPathComponent("Assets", isDirectory: true)

    do {
      try self.startXray()
    } catch {
      self.completionHandler(with: error.localizedDescription)
      throw error
    }

      let socks5Config = """
      tunnel:
        mtu: 8500

      socks5:
        port: 10808
        address: 127.0.0.1
        udp: 'udp'

      misc:
        task-stack-size: 20480
        connect-timeout: 5000
        read-write-timeout: 60000
        log-file: stderr
        log-level: debug
        limit-nofile: 65535
      """

      NSLog(">>>>>>>>>>>>>>>> Network Tunnel Setting...")
      self.setTunnelNetworkSettings(getNetworkSettings(with: 8500, ipv6: false)) { [socks5Config] error in
          if let error = error {

            self.completionHandler(with: error)
              return
          }
          NSLog(">>>>>>>>>>>>>>>> Starting Socks5Tunnel...")

        let code =  Tun2SocksKit.Socks5Tunnel.run(withConfig: .string(content: socks5Config))

        NSLog(">>>>>>>>>>>>>>>> Starting Socks5Tunnel With CODE \(code)")

          self.completionHandler(with: "Hi")
      }

    }

I'm not getting any return code. I only get -1, no 0. Also tried with ipv6 ::1 and passing config as filepath but no luck. Again, my problem is tunnel not starting/not tunneling perfectly. also tun2socks stops sometimes after 10-15 secs after upgrading to v3. running it blocking/non-blocking, not working....

@EbrahimTahernejad

EbrahimTahernejad commented 1 month ago

Try using file content instead of string

On Wed, May 8, 2024 at 15:29 Ali Akhgar @.***> wrote:

Yes you are right, version above is 3.0.7 and I imported Tun2SocksKitC and obtained fileDescriptor and started Hevc manually. Didn't work.

Here is my code on version 3.6.9

override func startTunnel(options : [String: NSObject]?) async throws {

conf = options?["config"] as? String
groupName = options?["groupName"] as? String

sharedDirectory = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: groupName)

cacheDir = sharedDirectory
      .appendingPathComponent("Library", isDirectory: true)
      .appendingPathComponent("Caches", isDirectory: true)

assetsDirectory = sharedDirectory
      .appendingPathComponent("Library", isDirectory: true)
      .appendingPathComponent("Assets", isDirectory: true)

do {
  try self.startXray()
} catch {
  self.completionHandler(with: error.localizedDescription)
  throw error
}

  let socks5Config = """
  tunnel:
    mtu: 8500

  socks5:
    port: 10808
    address: 127.0.0.1
    udp: 'udp'

  misc:
    task-stack-size: 20480
    connect-timeout: 5000
    read-write-timeout: 60000
    log-file: stderr
    log-level: debug
    limit-nofile: 65535
  """

  NSLog(">>>>>>>>>>>>>>>> Network Tunnel Setting...")
  self.setTunnelNetworkSettings(getNetworkSettings(with: 8500, ipv6: false)) { [socks5Config] error in
      if let error = error {

        self.completionHandler(with: error)
          return
      }
      NSLog(">>>>>>>>>>>>>>>> Starting Socks5Tunnel...")

    let code =  Tun2SocksKit.Socks5Tunnel.run(withConfig: .string(content: socks5Config))

    NSLog(">>>>>>>>>>>>>>>> Starting Socks5Tunnel With CODE \(code)")

      self.completionHandler(with: "Hi")
  }

}

I'm not getting any return code. I only get -1, no 0. Also tried with ipv6 ::1 and passing config as filepath but no luck. Again, my problem is tunnel not starting/not tunneling perfectly. also tun2socks stops sometimes after 10-15 secs after upgrading to v3. running it blocking/non-blocking, not working....

— Reply to this email directly, view it on GitHub https://github.com/EbrahimTahernejad/Tun2SocksKit/issues/10#issuecomment-2100416573, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACDQKHDVGXMTNIJDJNBK7CTZBIHTVAVCNFSM6AAAAABHLTNSLOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMBQGQYTMNJXGM . You are receiving this because you commented.Message ID: @.***>

aliakhgar commented 1 month ago

I tried writing into file, used .standardizedFileURL and .absoluteURL , like this. again no luck no return code and also due to tun2socks stopping, my network extension closing too....

          let configurationFilePath = self.cacheDir.appendingPathComponent("config.yml")
          FileManager.default.createFile(atPath: configurationFilePath.relativePath, contents: socks5Config.data(using: .utf8)!)

        let code =  Tun2SocksKit.Socks5Tunnel.run(withConfig: .file(path:configurationFilePath.standardizedFileURL ))

rolling back to v2 does not happen to stop tun2socks but functionality is poor on v2. @EbrahimTahernejad

aliakhgar commented 1 month ago

also just to mention, there is a 10 second period before tun2socks shutdown and in that 10 seconds it seems that data is being tunneled perfectly but we encounter a sudden shut down after 10 secs.

EbrahimTahernejad commented 1 month ago

I've used 3.6.8 in production so it should work 100%

aliakhgar commented 1 month ago

version 3.6.8 seems to be working nice but im not still getting return code from socks5 run. also my config is like the above i posted.

and here is my tunnel setting, i used it from your other comments.

 func getNetworkSettings(with mtu: Int, ipv6: Bool = true) -> NEPacketTunnelNetworkSettings {
      let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "254.1.1.1")
      settings.mtu = NSNumber(integerLiteral: mtu)
      settings.ipv4Settings = {
          let settings = NEIPv4Settings(addresses: ["198.18.0.1"], subnetMasks: ["255.255.0.0"])
          settings.includedRoutes = [NEIPv4Route.default()]
          return settings
      }()
      settings.ipv6Settings = { [ipv6] () in
          guard ipv6 else {
              return nil
          }
          let settings = NEIPv6Settings(addresses: ["fd6e:a81b:704f:1211::1"], networkPrefixLengths: [64])
          settings.includedRoutes = [NEIPv6Route.default()]
          return settings
      }()
      settings.dnsSettings = NEDNSSettings(servers: ["1.1.1.1", "8.8.8.8"])
      return settings
    }

posted it just to make sure im on right track.

EbrahimTahernejad commented 1 month ago

do it like this:

try await setTunnelNetworkSettings(getNetworkSettings(with: 8500, ipv6: false))
// Run Xcode (async)
Tun2SocksKit.Socks5Tunnel.run(withConfig: ...) { [weak self] code in
    if code != 0 {
        cancelTunnelWithError(NSError(domain: "Tun2Socks exit code \(-1)", code: 0))
    }
}
// no completion needed, your function is async

The underlying c++ code is blocking so use queue/thread to run it async It'll block until an error occurs, or .stop() is called (which will return 0)

aliakhgar commented 1 month ago

ok cool to know that, thanks for sharing knowledge! I'll give it a quick test and will close this issue ASAP.

aliakhgar commented 1 month ago

Thanks for all the help ✨✌

aliakhgar commented 3 weeks ago

Dear Ebrahim Im reopening this issue due to clients claiming that xray configs not working properly in our apps but working fine in third-party apps like FoXray.

I’ll be happy to have your opinion on the issue as im using the instruction above we discussed. I really dont know what other factors impact the quality of the connection, thing like dns or etc and the proper way to set them.

Thanks again.

EbrahimTahernejad commented 3 weeks ago

Post your xray config here without the outbound

aliakhgar commented 3 weeks ago

Here it is. They are using third party apps to convert v2ray links to json config. Like npv or foxray.

{ "stats": {}, "log": { "loglevel": "none" }, "policy": { "levels": { "8": { "handshake": 4, "connIdle": 300, "uplinkOnly": 1, "downlinkOnly": 1 } }, "system": { "statsOutboundUplink": true, "statsOutboundDownlink": true } }, "inbounds": [ { "tag": "socks", "port": 10808, "protocol": "socks", "settings": { "auth": "noauth", "udp": true, "userLevel": 8 }, "sniffing": { "enabled": true, "destOverride": [ "http", "tls" ] } }, { "tag": "http", "port": 10809, "protocol": "http", "settings": { "userLevel": 8 } } ], "outbounds": [ { "tag": "proxy", "protocol": "vless", "settings": { "vnext": [ { "address": "xxx", "port": 587, "users": [ { "id": "xxx", "security": "auto", "level": 8, "encryption": "none", "flow": "" } ] } ] }, "streamSettings": { "network": "ws", "security": "none", "wsSettings": { "path": "\/", "headers": { "Host": "" } } }, "mux": { "enabled": false, "concurrency": -1, "xudpConcurrency": 8, "xudpProxyUDP443": "" } }, { "tag": "direct", "protocol": "freedom", "settings": {}, "mux": { "enabled": false, "concurrency": 8, "xudpConcurrency": 8, "xudpProxyUDP443": "" } }, { "tag": "block", "protocol": "blackhole", "settings": { "response": { "type": "http" } }, "mux": { "enabled": false, "concurrency": 8, "xudpConcurrency": 8, "xudpProxyUDP443": "" } } ], "dns": { "servers": [ "8.8.8.8" ] }, "routing": { "domainStrategy": "Asls", "rules": [] } }

EbrahimTahernejad commented 3 weeks ago

Sniff the dns, add outbound and routing for dns then try again

On Tue, May 21, 2024 at 21:04 Ali Akhgar @.***> wrote:

Here it is. They are using third party apps to convert v2ray links to json config. Like npv or foxray.

{ "stats": {}, "log": { "loglevel": "none" }, "policy": { "levels": { "8": { "handshake": 4, "connIdle": 300, "uplinkOnly": 1, "downlinkOnly": 1 } }, "system": { "statsOutboundUplink": true, "statsOutboundDownlink": true } }, "inbounds": [ { "tag": "socks", "port": 10808, "protocol": "socks", "settings": { "auth": "noauth", "udp": true, "userLevel": 8 }, "sniffing": { "enabled": true, "destOverride": [ "http", "tls" ] } }, { "tag": "http", "port": 10809, "protocol": "http", "settings": { "userLevel": 8 } } ], "outbounds": [ { "tag": "proxy", "protocol": "vless", "settings": { "vnext": [ { "address": "xxx", "port": 587, "users": [ { "id": "xxx", "security": "auto", "level": 8, "encryption": "none", "flow": "" } ] } ] }, "streamSettings": { "network": "ws", "security": "none", "wsSettings": { "path": "/", "headers": { "Host": "" } } }, "mux": { "enabled": false, "concurrency": -1, "xudpConcurrency": 8, "xudpProxyUDP443": "" } }, { "tag": "direct", "protocol": "freedom", "settings": {}, "mux": { "enabled": false, "concurrency": 8, "xudpConcurrency": 8, "xudpProxyUDP443": "" } }, { "tag": "block", "protocol": "blackhole", "settings": { "response": { "type": "http" } }, "mux": { "enabled": false, "concurrency": 8, "xudpConcurrency": 8, "xudpProxyUDP443": "" } } ], "dns": { "servers": [ "8.8.8.8" ] }, "routing": { "domainStrategy": "Asls", "rules": [] } }

— Reply to this email directly, view it on GitHub https://github.com/EbrahimTahernejad/Tun2SocksKit/issues/10#issuecomment-2123115261, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACDQKHD4QNMDFDDFKSAF2TTZDOAT5AVCNFSM6AAAAABHLTNSLOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMRTGEYTKMRWGE . You are receiving this because you were mentioned.Message ID: @.***>