Xray-core icon indicating copy to clipboard operation
Xray-core copied to clipboard

[ BUG ] Wireguard Chain speed problem

Open X-Oracle opened this issue 1 year ago • 15 comments

unlike sing-box, speed is very slow when chaing wireguard-outbound (using dialerProxy) to another outboundin xray-core, unlike sing-box (using detour).

X-Oracle avatar Dec 24 '23 11:12 X-Oracle

I have the same problem. Wireguard over Vmes works very slowly (dialerProxy or proxySettings tag). Xray Wireguard client - 16 Mbit/s Xray Vmes client - 30 Mbit/s Xray Wireguard via Vmes - 50 Kbit/s and lag. Sing-box Wireguard via Vmes (detour) - 25 Mbit/s

OS Windows 10 x64 Xray-core v1.8.6

AlexeySa avatar Jan 04 '24 01:01 AlexeySa

unlike sing-box, speed is very slow when chaing wireguard-outbound (using dialerProxy) to another outboundin xray-core, unlike sing-box (using detour).

how did you chain wireguard to other outbound ? how do you specify the dialerProxy?

XRaySup avatar Apr 06 '24 00:04 XRaySup

unlike sing-box, speed is very slow when chaing wireguard-outbound (using dialerProxy) to another outboundin xray-core, unlike sing-box (using detour).

how did you chain wireguard to other outbound ? how do you specify the dialerProxy?

https://xtls.github.io/config/transport.html#sockoptobject

chise0713 avatar Apr 17 '24 09:04 chise0713

@chise0713 That would be streamSettings -> sockopt ->dialerProxy. When I open official docs it says

Currently, the Wireguard protocol outbound does not support setting streamSettings

Is this simply outdated?

uuonda avatar May 16 '24 14:05 uuonda

@chise0713 That would be streamSettings -> sockopt ->dialerProxy. When I open official docs it says

Currently, the Wireguard protocol outbound does not support setting streamSettings

Is this simply outdated?

I don't know. I stopped using it When I saw poor performance.

I just opened this issue to tell devs that sing-box is doing chains with better performance.

The doc statement is probably for when we use kernel wireguard.

X-Oracle avatar May 16 '24 20:05 X-Oracle

@X-Oracle did you move completely to sing-box or switch just the client?

uuonda avatar May 16 '24 21:05 uuonda

@X-Oracle did you move completely to sing-box or switch just the client?

I use sing-box for Wireguard but only when chaining it.

I use both of them wherever suited, but I prefer Xray as I'm more experienced in it. I don't like the idea of using Xray server and sing-box client but in this case, I don't have much choice.

X-Oracle avatar May 16 '24 21:05 X-Oracle

using sockopt even with direct tag, degrade speed to ~50KBps

"streamSettings": {          
          "sockopt": {            
             "dialerProxy": "direct"        
          }
 },

i enable error log and find that only when sockopt is used , some "unknown type packet" generated

wireguard-go/device/receive.go#L207 device.log.Verbosef("Received message with unknown type") https://github.com/WireGuard/wireguard-go/blob/12269c2761734b15625017d8565745096325392f/device/receive.go#L207

and also speed is sensitive to mtu i guess it may related to udp/tcp conversion on dialer

do you have any idea ? wireguard chain is very important for us.

GFW-knocker avatar Jul 14 '24 14:07 GFW-knocker

@GFW-knocker Have u tried using sing wiregurad instead of wireguard-go for ur customized core?sing handles wireguard chain a lot better,not sure if there is somthing wrong with *ray or wireguard-go https://github.com/SagerNet/wireguard-go

Mfire2001 avatar Jul 15 '24 14:07 Mfire2001

As I said before. It has better performance in the sing-box.

In theory, there could be a fix if somebody who understands both cores could investigate this.

Wireguard chain is a rare situation and I don't think anybody with knowledge is interested in it.

X-Oracle avatar Jul 15 '24 15:07 X-Oracle

@Mfire2001 sagernet/wireguard-go is not compatible to xray
i looked at commits and play around it (adding workers,...) no difference. our issue is related to chain dialer in xray (maybe converting udp to tcp ???) whereas sing use detour

GFW-knocker avatar Jul 16 '24 16:07 GFW-knocker

no difference. our issue is related to chain dialer in xray (maybe converting udp to tcp ???) whereas sing use detour

It is not a wireguard issue. If it was then a normal wireguard would be affected too.

We must see how both detour and dialerProxy do traffic routing to different outbound.

For UDP, we can test with VLESS-quick and see if it behaves like wireguard as both are udp based protocol.

X-Oracle avatar Jul 17 '24 21:07 X-Oracle

It seems this issue can be worked around by setting the internal buffer size of dialerProxy to nothing, at top-level policy object:

  "policy": {
    "levels": {
      "0": {
        "bufferSize": 0
      }
    }
  },

the effect seems to be the same as:

diff --git a/transport/internet/dialer.go b/transport/internet/dialer.go
index 989bfa0..5de136a 100644
--- a/transport/internet/dialer.go
+++ b/transport/internet/dialer.go
@@ -120,8 +120,8 @@ func redirect(ctx context.Context, dst net.Destination, obt string) net.Conn {
                Tag:     obt,
        })) // add another outbound in session ctx
        if h != nil {
-               ur, uw := pipe.New(pipe.OptionsFromContext(ctx)...)
-               dr, dw := pipe.New(pipe.OptionsFromContext(ctx)...)
+               ur, uw := pipe.New(pipe.WithSizeLimit(0))
+               dr, dw := pipe.New(pipe.WithSizeLimit(0))

                go h.Dispatch(ctx, &transport.Link{Reader: ur, Writer: dw})
                nc := cnc.NewConnection(

please confirm. I don't think it's an appropriate fix though. ~~though maybe it makes sense to be able to set these buffer sizes per-dialerproxy instead of globally~~

mmmray avatar Jul 19 '24 23:07 mmmray

@mmmray hey you are brilliant! i confirm that chain speed problem solved when using pipe.New(pipe.WithSizeLimit(0)) and error of device.log.Verbosef("Received message with unknown type") disappeared.

although "policy" object does not work for me but pipe.WithSizeLimit(0) do the job.

i guess dialer proxy accumulate multiple udp packet into buffer when resending them , some unknown type packet generated.

is it safe to use pipe.WithSizeLimit(0) in production ? or it may hurt other parts in core?

GFW-knocker avatar Jul 20 '24 21:07 GFW-knocker

is it safe to use pipe.WithSizeLimit(0) in production ?

I think it may hurt other configs that use dialerProxy, I haven't looked into a proper fix yet. It's probably a good idea to test it a bit with things like fragment and other common scenarios that may use dialerProxy.

mmmray avatar Jul 20 '24 21:07 mmmray

@mmmray Is it good to have a key in sockopt which allow us to change the internal buffer size for specific outbound?

I see you at least mentioned policy but I don't see any key for wireguard configuration which allow us to set policy level.

X-Oracle avatar Aug 03 '24 14:08 X-Oracle

@X-Oracle @GFW-knocker please test https://github.com/XTLS/Xray-core/pull/3570, I think it fixes this issue but I have not done a thorough speedtest.

mmmray avatar Aug 09 '24 22:08 mmmray

@X-Oracle @GFW-knocker please test #3570, I think it fixes this issue but I have not done a thorough speedtest.

@mmmray Bravo! i confirm that #3570 works great. using ConnectionOutputMultiUDP(dr) for udp in dialer.go solve wireguard chain DL speed. it also improve overall web loading experience. thank you so much.

GFW-knocker avatar Aug 11 '24 11:08 GFW-knocker

https://github.com/XTLS/Xray-core/pull/3570 has been merged so this should also be fixed now

mmmray avatar Aug 11 '24 17:08 mmmray