Compare commits

..
Author SHA1 Message Date
RPRXandGitHub 47a10c0012 XDRIVE transport: A bunch of optimizations for Google Drive 2026-11-06 04:08:29 +00:00
5 changed files with 18 additions and 64 deletions
+1 -11
View File
@@ -51,17 +51,7 @@ func (m *Manager) AddHandler(ctx context.Context, handler inbound.Handler) error
}
if m.running {
if err := handler.Start(); err != nil {
if len(tag) > 0 {
delete(m.taggedHandlers, tag)
} else {
m.untaggedHandlers = m.untaggedHandlers[:len(m.untaggedHandlers)-1]
}
if err := handler.Close(); err != nil {
errors.LogWarningInner(ctx, err, "failed to close handler ", tag)
}
return err
}
return handler.Start()
}
return nil
+4 -4
View File
@@ -122,8 +122,8 @@ func NewHandler(ctx context.Context, config *core.OutboundHandlerConfig) (outbou
if config.Concurrency < 0 {
h.mux = &mux.ClientManager{Enabled: false}
}
if config.Concurrency >= 0 && config.Concurrency <= 128 {
config.Concurrency = 128
if config.Concurrency == 0 {
config.Concurrency = 8 // same as before
}
if config.Concurrency > 0 {
h.mux = &mux.ClientManager{
@@ -134,7 +134,7 @@ func NewHandler(ctx context.Context, config *core.OutboundHandlerConfig) (outbou
Dialer: h,
Strategy: mux.ClientStrategy{
MaxConcurrency: uint32(config.Concurrency),
MaxConnection: 1024,
MaxConnection: 128,
},
},
},
@@ -155,7 +155,7 @@ func NewHandler(ctx context.Context, config *core.OutboundHandlerConfig) (outbou
Dialer: h,
Strategy: mux.ClientStrategy{
MaxConcurrency: uint32(config.XudpConcurrency),
MaxConnection: 1024,
MaxConnection: 128,
},
},
},
-5
View File
@@ -13,7 +13,6 @@ import (
"math/big"
"runtime"
"strconv"
"sync"
"time"
"github.com/pires/go-proxyproto"
@@ -302,7 +301,6 @@ type VisionWriter struct {
// internal
writeOnceUserUUID []byte
directWriteCounter stats.Counter
access sync.Mutex
testseed []uint32
}
@@ -326,9 +324,6 @@ func NewVisionWriter(writer buf.Writer, trafficState *TrafficState, isUplink boo
}
func (w *VisionWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
w.access.Lock()
defer w.access.Unlock()
var isPadding *bool
var switchToDirectCopy *bool
var spliceReadyInbound *session.Inbound
+3 -3
View File
@@ -223,16 +223,16 @@ To make it start, wintun.dll specific for your Windows/arch must be present next
After the start network adapter with the name you chose in the config will be created in the system, and exist while Xray is running. A Wintun adapter that already has that name is reused.
With IPv6 turned off by the `DisabledComponents` registry value (0x10 set, as in 0xFF), errors setting up IPv6 for `gateway`, `dns` and `autoSystemRoutingTable`, clearing the IPv6 DNS servers when `dns` has none included, are only logged. Otherwise, they keep the TUN from starting.
With IPv6 disabled system-wide (the `DisabledComponents` registry value), the adapter has no IPv6, and the TUN starts with IPv4 only, unless `gateway`, `dns` or `autoSystemRoutingTable` has IPv6 entries, which then keep it from starting.
When `dns` is set, those servers are applied to the adapter. Windows is kept from registering the TUN's addresses in DNS, and its DNS cache is flushed when the TUN starts and stops. Xray's own lookups through the system's DNS servers, like those of the `localhost` DNS server with `autoOutboundsInterface`, skip them, unless another interface uses them as well, as they would lead back into the TUN.
Setting `autoSystemWfpBlockLeak` to at least `["dns", "misconfigtun"]` is recommended, to block DNS leaks and the traffic of an IP version without routes. It needs `autoSystemRoutingTable` (the config is rejected otherwise), and adds Windows Filtering Platform filters that let traffic of every program but Xray itself leave only through the TUN, each kind chosen by a value:
Setting `autoSystemWfpBlockLeak` to at least `["dns"]` is recommended, to block DNS leaks. It needs `autoSystemRoutingTable` (the config is rejected otherwise), and adds Windows Filtering Platform filters that let traffic of every program but Xray itself leave only through the TUN, each kind chosen by a value:
- `"dns"`: stands for `"53"`, `"853"` (DNS over TLS and QUIC) and `"windnsclient"`. Windows also queries the DNS servers of the other interfaces, through those interfaces whatever the routes say, and other programs reach a resolver on the local network (e.g. `192.168.1.1` from DHCP) through its more specific route.
- `"windnsclient"`: Windows' DNS Client service, except for name resolution on the local network (LLMNR, mDNS). Since Windows 11 and Server 2022, it may query over HTTPS or TLS, to any port; earlier versions only query port 53, so there it does nothing.
- `"tcp"`, `"udp"`: that protocol, to all ports, or with `/<port>` or `/<low>-<high>` (1 to 65535) to some, e.g. `"tcp/853"` or `"udp/10-20"`. The ports alone stand for both, e.g. `"53"` or `"10-20"`.
- `"icmp"`: ICMP and ICMPv6, e.g. `ping`.
- `"misconfigtun"`: an IP version without routes in `autoSystemRoutingTable`, which would bypass the TUN. With IPv6 turned off by `DisabledComponents`, it covers IPv6 whatever the routes, as IPv6 setup errors are then only logged, and IPv6 still works until the reboot that applies the value.
- `"misconfigtun"`: an IP version without routes in `autoSystemRoutingTable`, which would bypass the TUN.
- `"all"`: everything, in both directions. Access to the local network then breaks unless it is routed into the TUN as well, and so do incoming connections to other programs, other VPNs, and virtual machines whose NAT runs on the host.
- `"allexceptlan"`: like `"all"`, but traffic to and from the local network stays allowed, e.g. for printers or casting to a TV: private, link-local, multicast and broadcast addresses (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `169.254.0.0/16`, `224.0.0.0/4`, `255.255.255.255`, `fc00::/7`, `fe80::/10`, `ff00::/8`), not global IPv6 ones. It includes `"dns"`, and the other values apply there as well. `"all"` overrides it.
+10 -41
View File
@@ -23,7 +23,6 @@ import (
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/transport/internet"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
"golang.zx2c4.com/wintun"
"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
)
@@ -99,19 +98,6 @@ func open(name, desc string) (*wintun.Adapter, error) {
return nil, err
}
// ipv6Off tells whether DisabledComponents turns IPv6 off on the non-tunnel
// interfaces (0x10, as 0xFF does), the TUN among them. Windows applies it at
// boot only.
func ipv6Off() bool {
key, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters`, registry.QUERY_VALUE)
if err != nil {
return false
}
defer key.Close()
value, _, err := key.GetIntegerValue("DisabledComponents")
return err == nil && value&0x10 != 0
}
func (t *WindowsTun) Start() (err error) {
var address4, address6 bool
addresses := make([]netip.Prefix, 0, len(t.options.Gateway))
@@ -129,6 +115,7 @@ func (t *WindowsTun) Start() (err error) {
for _, ip := range t.options.DNS {
dns = append(dns, netip.MustParseAddr(ip))
}
dns6 := slices.ContainsFunc(dns, netip.Addr.Is6)
var route4, route6 bool
routesMap := make(map[winipcfg.RouteData]struct{})
@@ -153,17 +140,6 @@ func (t *WindowsTun) Start() (err error) {
routesData = append(routesData, &r)
}
// With IPv6 off by DisabledComponents, setting it up may fail, clearing
// its DNS servers too, which is then only logged.
off6 := ipv6Off()
ignored := func(family winipcfg.AddressFamily, err error) bool {
if family != windows.AF_INET6 || !off6 {
return false
}
errors.LogErrorInner(context.Background(), err, "[tun] ignored, as DisabledComponents turns IPv6 off")
return true
}
var retryTimes int
var firstErr error
startOver:
@@ -180,9 +156,6 @@ startOver:
err = t.luid.SetRoutesForFamily(family, routesData)
if err != nil {
firstErr = errors.New("unable to set routes").Base(err)
if ignored(family, firstErr) {
continue
}
if err == windows.ERROR_NOT_FOUND {
goto startOver
}
@@ -193,9 +166,6 @@ startOver:
err = t.luid.SetIPAddressesForFamily(family, addresses)
if err != nil {
firstErr = errors.New("unable to set ips").Base(err)
if ignored(family, firstErr) {
continue
}
if err == windows.ERROR_NOT_FOUND {
goto startOver
}
@@ -204,7 +174,9 @@ startOver:
}
ipif, err := t.luid.IPInterface(family)
if err != nil {
if ignored(family, err) {
// With IPv6 disabled system-wide (DisabledComponents), the adapter has no
// IPv6 interface at all. Skip the family unless the config asks for it.
if err == windows.ERROR_NOT_FOUND && family == windows.AF_INET6 && !address6 && !route6 && !dns6 {
continue
}
return err
@@ -223,9 +195,6 @@ startOver:
err = ipif.Set()
if err != nil {
firstErr = errors.New("unable to set metric and MTU").Base(err)
if ignored(family, firstErr) {
continue
}
if err == windows.ERROR_NOT_FOUND {
goto startOver
}
@@ -233,10 +202,13 @@ startOver:
}
err = t.luid.SetDNS(family, dns, nil)
if err != nil {
firstErr = errors.New("unable to set DNS").Base(err)
if ignored(family, firstErr) {
// Skip IPv6 the config does not ask for also when setting its DNS
// servers fails, as reported on Windows 11 24H2 with IPv6 disabled
// (Access is denied).
if family == windows.AF_INET6 && !address6 && !route6 && !dns6 {
continue
}
firstErr = errors.New("unable to set DNS").Base(err)
if err == windows.ERROR_NOT_FOUND {
goto startOver
}
@@ -293,10 +265,7 @@ startOver:
if err != nil {
return err
}
// With IPv6 off by DisabledComponents, IPv6 setup failures are only logged,
// and IPv6 still works until the reboot that applies it. So "misconfigtun"
// then blocks IPv6 outside the TUN whatever the routes.
block := newLeakFilters(leaks, route4, route6 && !off6)
block := newLeakFilters(leaks, route4, route6)
if route4 || route6 {
dnsClient := func(l leak) bool { return l.name == "windnsclient" }
if slices.ContainsFunc(block, dnsClient) && !dnsClientUsesAnyPort() {