Open blaxkdevios opened 5 months ago
Make sure that the configuration you're feeding to XrayCore works on a standalone instance on a Mac or PC.
@tveerman Thanks for the answer!
If you don't mind, could you show an example configuration of XRay and Tun2SocksKit? (for vless)
@tveerman After hours of work I finally changed the config to Vless GRPC (with ws working badly) so now it works fine, no errors in logs, but crashing again when limiting memory.
Do you have any ideas why and how to fix it?
As mentioned before I'd first try the configuration on a system where you can debug it more easily. That is, where you have access to the logs so you can see what it's doing. When you know the configuration should work, then feed the exact same configuration to XrayKit. XrayKit has no debugging facilities at the moment, so you have to capture the output (on stdout and stderr) generated by XrayCore yourself and store it somewhere.
One way to do that is to redirect stdout and stderr to a pipe and create a read handler that stores the output somewhere prior to launching XrayKit. For example, to a file that resides in a directory that's shared between the app extension and the main app:
private var relayFileHandle: FileHandle? = nil // global variable in your app extension
[...]
private func relayOutput() {
var fd: [Int32] = [-1, -1]
guard pipe(&fd) == 0 else {
// handle pipe error
return
}
// capture stdout
guard dup2(fd[1], 1) != -1 else {
// handle dup error
return
}
// capture stderr
guard dup2(fd[1], 2) != -1 else {
// handle dup error
return
}
relayFileHandle = FileHandle(fileDescriptor: fd[0], closeondealloc: true)
relayFileHandle?.readabilityHandler = { fileHandle in
if fileHandle.fileDescriptor >= 0 {
let data = fileHandle.availableData
// append data to shared file
}
}
}
@tveerman Thanks for the answer! By the way, is it possible to do a soft memory limit in go lang ? https://pkg.go.dev/runtime/debug#SetMemoryLimit
as i see in other apps that support xray there is an option to control memory limit
I've dabbled with SetMemoryLimit and aggressive garbage collection, but they didn't seem to help at all. So I wonder how effective that setting is for the other apps you mention.
The only foolproof way to keep VPN working even in the face of an out-of-memory crash is to enable Connect on demand (set NETunnelProviderManager's isOnDemandEnabled to true).
i have tested the apps:
FoXray - It also drops the VPN connection if I overload the network with requests. I assume there’s a memory limit issue there as well. V2Box - There is a memory limit control in the settings, and it works well. The main screen provides statistics about memory usage.
I also thought about on-demand settings. Could you publish the changes with SetMemoryLimit?
Additionally, different libraries like libXRay (there are many such libraries) also have SetMemoryLimit (https://github.com/EbrahimTahernejad/libxray-apple).
I doubt V2Box can effectively limit the memory usage.
SetMemoryLimit sets a soft limit, so the Go runtime is allowed to go over the limit (e.g., when there's no memory to garbage collect). Also, what should the Go runtime do when more memory is necessary to perform work? It either allocates the memory anyway or it kills the process with an out-of-memory error. In both cases you're not getting what you want.
Additionally, the runtime has to consider its own memory usage but also the memory usage of other threads that are not under its control. For example, the app extension's Swift runtime and the thread that converts IP packets to HTTP or SOCKS5 connections.
Finally, even if Go can effectively keep its memory usage under a certain limit, your app extension risks being killed due to excessive CPU usage when the Go garbage collector is constantly running because you're getting very close to the limit. iOS is not forgiving.
Considering the above I decided against using SetMemoryLimit. I tested SetMemoryLimit in a local branch that I no longer have. However, you can add your own by doing the following: 1) Make a git clone of this repository 2) cd into the git clone and run make 3) modify thirdparty/Xray-core-1.8.13/main/main.go to include a call to SetMemoryLimit in libxray_main or add a new exported function so you can call it on-the-fly. 4) rm -r thirdparty/Xray-core-1.8.13/.tmp 5) run make again. The resulting Swift Package is in build/XrayKit. Add this local Swift Package to your project instead of this remote github repo.
I used Tun2SocksKit with the following code:
There are some problems:
failed to dial WebSocket > transport/internet/websocket: failed to dial to (ws://server.com/vless/): 404 Not Found > websocket: bad handshake transport/internet/websocket: failed to dial WebSocket > transport/internet/websocket: failed to dial to...
Can someone help with problems 2 and 3? Does anyone have solutions?