From 1d02685b4cc9da7043cd9df35e09ac08414d0255 Mon Sep 17 00:00:00 2001 From: hossinasaadi Date: Fri, 11 Oct 2024 18:02:31 +0400 Subject: [PATCH 01/11] fix gvisor implement in go 1.23 --- go.mod | 10 +++++----- go.sum | 16 ++++++++-------- proxy/wireguard/gvisortun/tun.go | 2 +- proxy/wireguard/tun.go | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index 7f3cba9f4be6..f13efa07c2dc 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/xtls/xray-core -go 1.21.4 +go 1.23.2 require ( github.com/OmarTariq612/goech v0.0.0-20240405204721-8e2e1dafd3a0 @@ -29,7 +29,7 @@ require ( golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.35.1 - gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489 + gvisor.dev/gvisor v0.0.0-20241010231727-f350fc8d7241 h12.io/socks v1.0.3 lukechampine.com/blake3 v1.3.0 ) @@ -50,10 +50,10 @@ require ( github.com/vishvananda/netns v0.0.4 // indirect go.uber.org/mock v0.4.0 // indirect golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect - golang.org/x/mod v0.18.0 // indirect + golang.org/x/mod v0.21.0 // indirect golang.org/x/text v0.19.0 // indirect - golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.22.0 // indirect + golang.org/x/time v0.7.0 // indirect + golang.org/x/tools v0.26.0 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 8fa32abd6248..9a5ea886bb59 100644 --- a/go.sum +++ b/go.sum @@ -84,8 +84,8 @@ golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7 golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc h1:O9NuF4s+E/PvMIy+9IUZB9znFwUIXEWSstNjek6VpVg= golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= -golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -111,13 +111,13 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= +golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= -golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= +golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -140,8 +140,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489 h1:ze1vwAdliUAr68RQ5NtufWaXaOg8WUO2OACzEV+TNdE= -gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489/go.mod h1:10sU+Uh5KKNv1+2x2A0Gvzt8FjD3ASIhorV3YsauXhk= +gvisor.dev/gvisor v0.0.0-20241010231727-f350fc8d7241 h1:2Gqo79I/LlzC41fZXIzVVbIkeJCOdu8Dif5/MKtFIxE= +gvisor.dev/gvisor v0.0.0-20241010231727-f350fc8d7241/go.mod h1:5DMfjtclAbTIjbXqO1qCe2K5GKKxWz2JHvCChuTcJEM= h12.io/socks v1.0.3 h1:Ka3qaQewws4j4/eDQnOdpr4wXsC//dXtWvftlIcCQUo= h12.io/socks v1.0.3/go.mod h1:AIhxy1jOId/XCz9BO+EIgNL2rQiPTBNnOfnVnQ+3Eck= lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= diff --git a/proxy/wireguard/gvisortun/tun.go b/proxy/wireguard/gvisortun/tun.go index 9e9a0b2bed47..65677c483e62 100644 --- a/proxy/wireguard/gvisortun/tun.go +++ b/proxy/wireguard/gvisortun/tun.go @@ -157,7 +157,7 @@ func (tun *netTun) Write(buf [][]byte, offset int) (int, error) { // WriteNotify implements channel.Notification func (tun *netTun) WriteNotify() { pkt := tun.ep.Read() - if pkt.IsNil() { + if pkt == nil { return } diff --git a/proxy/wireguard/tun.go b/proxy/wireguard/tun.go index 7fd8a817d6ec..74a3b71d87c8 100644 --- a/proxy/wireguard/tun.go +++ b/proxy/wireguard/tun.go @@ -194,7 +194,7 @@ func createGVisorTun(localAddresses []netip.Addr, mtu int, handler promiscuousMo Timeout: 15 * time.Second, }) - handler(xnet.UDPDestination(xnet.IPAddress(id.LocalAddress.AsSlice()), xnet.Port(id.LocalPort)), gonet.NewUDPConn(stack, &wq, ep)) + handler(xnet.UDPDestination(xnet.IPAddress(id.LocalAddress.AsSlice()), xnet.Port(id.LocalPort)), gonet.NewUDPConn(&wq, ep)) }(r) }) stack.SetTransportProtocolHandler(udp.ProtocolNumber, udpForwarder.HandlePacket) From 5331a4c72ce1b851df8dd0f305dc983192489771 Mon Sep 17 00:00:00 2001 From: hossinasaadi Date: Fri, 11 Oct 2024 22:16:33 +0400 Subject: [PATCH 02/11] fix build go 1.21.4 (win7) --- proxy/wireguard/gvisortun/tun.go | 3 + proxy/wireguard/gvisortun/tun_go121.go | 233 +++++++++++++++++++++++++ proxy/wireguard/tun.go | 3 + proxy/wireguard/tun_go121.go | 208 ++++++++++++++++++++++ 4 files changed, 447 insertions(+) create mode 100644 proxy/wireguard/gvisortun/tun_go121.go create mode 100644 proxy/wireguard/tun_go121.go diff --git a/proxy/wireguard/gvisortun/tun.go b/proxy/wireguard/gvisortun/tun.go index 65677c483e62..f809c5f82162 100644 --- a/proxy/wireguard/gvisortun/tun.go +++ b/proxy/wireguard/gvisortun/tun.go @@ -1,3 +1,6 @@ +//go:build go1.23 +// +build go1.23 + /* SPDX-License-Identifier: MIT * * Copyright (C) 2017-2022 WireGuard LLC. All Rights Reserved. diff --git a/proxy/wireguard/gvisortun/tun_go121.go b/proxy/wireguard/gvisortun/tun_go121.go new file mode 100644 index 000000000000..1fc5f10b445f --- /dev/null +++ b/proxy/wireguard/gvisortun/tun_go121.go @@ -0,0 +1,233 @@ +//go:build !go1.23 +// +build !go1.23 + +/* SPDX-License-Identifier: MIT + * + * Copyright (C) 2017-2022 WireGuard LLC. All Rights Reserved. + */ + +package gvisortun + +import ( + "context" + "fmt" + "net/netip" + "os" + "syscall" + + "golang.zx2c4.com/wireguard/tun" + "gvisor.dev/gvisor/pkg/buffer" + "gvisor.dev/gvisor/pkg/tcpip" + "gvisor.dev/gvisor/pkg/tcpip/adapters/gonet" + "gvisor.dev/gvisor/pkg/tcpip/header" + "gvisor.dev/gvisor/pkg/tcpip/link/channel" + "gvisor.dev/gvisor/pkg/tcpip/network/ipv4" + "gvisor.dev/gvisor/pkg/tcpip/network/ipv6" + "gvisor.dev/gvisor/pkg/tcpip/stack" + "gvisor.dev/gvisor/pkg/tcpip/transport/icmp" + "gvisor.dev/gvisor/pkg/tcpip/transport/tcp" + "gvisor.dev/gvisor/pkg/tcpip/transport/udp" +) + +type netTun struct { + ep *channel.Endpoint + stack *stack.Stack + events chan tun.Event + incomingPacket chan *buffer.View + mtu int + hasV4, hasV6 bool +} + +type Net netTun + +func CreateNetTUN(localAddresses []netip.Addr, mtu int, promiscuousMode bool) (tun.Device, *Net, *stack.Stack, error) { + opts := stack.Options{ + NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol}, + TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol, udp.NewProtocol, icmp.NewProtocol6, icmp.NewProtocol4}, + HandleLocal: !promiscuousMode, + } + dev := &netTun{ + ep: channel.New(1024, uint32(mtu), ""), + stack: stack.New(opts), + events: make(chan tun.Event, 1), + incomingPacket: make(chan *buffer.View), + mtu: mtu, + } + dev.ep.AddNotify(dev) + tcpipErr := dev.stack.CreateNIC(1, dev.ep) + if tcpipErr != nil { + return nil, nil, dev.stack, fmt.Errorf("CreateNIC: %v", tcpipErr) + } + for _, ip := range localAddresses { + var protoNumber tcpip.NetworkProtocolNumber + if ip.Is4() { + protoNumber = ipv4.ProtocolNumber + } else if ip.Is6() { + protoNumber = ipv6.ProtocolNumber + } + protoAddr := tcpip.ProtocolAddress{ + Protocol: protoNumber, + AddressWithPrefix: tcpip.AddrFromSlice(ip.AsSlice()).WithPrefix(), + } + tcpipErr := dev.stack.AddProtocolAddress(1, protoAddr, stack.AddressProperties{}) + if tcpipErr != nil { + return nil, nil, dev.stack, fmt.Errorf("AddProtocolAddress(%v): %v", ip, tcpipErr) + } + if ip.Is4() { + dev.hasV4 = true + } else if ip.Is6() { + dev.hasV6 = true + } + } + if dev.hasV4 { + dev.stack.AddRoute(tcpip.Route{Destination: header.IPv4EmptySubnet, NIC: 1}) + } + if dev.hasV6 { + dev.stack.AddRoute(tcpip.Route{Destination: header.IPv6EmptySubnet, NIC: 1}) + } + if promiscuousMode { + // enable promiscuous mode to handle all packets processed by netstack + dev.stack.SetPromiscuousMode(1, true) + dev.stack.SetSpoofing(1, true) + } + + opt := tcpip.CongestionControlOption("cubic") + if err := dev.stack.SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil { + return nil, nil, dev.stack, fmt.Errorf("SetTransportProtocolOption(%d, &%T(%s)): %s", tcp.ProtocolNumber, opt, opt, err) + } + + dev.events <- tun.EventUp + return dev, (*Net)(dev), dev.stack, nil +} + +// BatchSize implements tun.Device +func (tun *netTun) BatchSize() int { + return 1 +} + +// Name implements tun.Device +func (tun *netTun) Name() (string, error) { + return "go", nil +} + +// File implements tun.Device +func (tun *netTun) File() *os.File { + return nil +} + +// Events implements tun.Device +func (tun *netTun) Events() <-chan tun.Event { + return tun.events +} + +// Read implements tun.Device + +func (tun *netTun) Read(buf [][]byte, sizes []int, offset int) (int, error) { + view, ok := <-tun.incomingPacket + if !ok { + return 0, os.ErrClosed + } + + n, err := view.Read(buf[0][offset:]) + if err != nil { + return 0, err + } + sizes[0] = n + return 1, nil +} + +// Write implements tun.Device +func (tun *netTun) Write(buf [][]byte, offset int) (int, error) { + for _, buf := range buf { + packet := buf[offset:] + if len(packet) == 0 { + continue + } + + pkb := stack.NewPacketBuffer(stack.PacketBufferOptions{Payload: buffer.MakeWithData(packet)}) + switch packet[0] >> 4 { + case 4: + tun.ep.InjectInbound(header.IPv4ProtocolNumber, pkb) + case 6: + tun.ep.InjectInbound(header.IPv6ProtocolNumber, pkb) + default: + return 0, syscall.EAFNOSUPPORT + } + } + return len(buf), nil +} + +// WriteNotify implements channel.Notification +func (tun *netTun) WriteNotify() { + pkt := tun.ep.Read() + if pkt.IsNil() { + return + } + + view := pkt.ToView() + pkt.DecRef() + + tun.incomingPacket <- view +} + +// Flush implements tun.Device +func (tun *netTun) Flush() error { + return nil +} + +// Close implements tun.Device +func (tun *netTun) Close() error { + tun.stack.RemoveNIC(1) + + if tun.events != nil { + close(tun.events) + } + + tun.ep.Close() + + if tun.incomingPacket != nil { + close(tun.incomingPacket) + } + + return nil +} + +// MTU implements tun.Device +func (tun *netTun) MTU() (int, error) { + return tun.mtu, nil +} + +func convertToFullAddr(endpoint netip.AddrPort) (tcpip.FullAddress, tcpip.NetworkProtocolNumber) { + var protoNumber tcpip.NetworkProtocolNumber + if endpoint.Addr().Is4() { + protoNumber = ipv4.ProtocolNumber + } else { + protoNumber = ipv6.ProtocolNumber + } + return tcpip.FullAddress{ + NIC: 1, + Addr: tcpip.AddrFromSlice(endpoint.Addr().AsSlice()), + Port: endpoint.Port(), + }, protoNumber +} + +func (net *Net) DialContextTCPAddrPort(ctx context.Context, addr netip.AddrPort) (*gonet.TCPConn, error) { + fa, pn := convertToFullAddr(addr) + return gonet.DialContextTCP(ctx, net.stack, fa, pn) +} + +func (net *Net) DialUDPAddrPort(laddr, raddr netip.AddrPort) (*gonet.UDPConn, error) { + var lfa, rfa *tcpip.FullAddress + var pn tcpip.NetworkProtocolNumber + if laddr.IsValid() || laddr.Port() > 0 { + var addr tcpip.FullAddress + addr, pn = convertToFullAddr(laddr) + lfa = &addr + } + if raddr.IsValid() || raddr.Port() > 0 { + var addr tcpip.FullAddress + addr, pn = convertToFullAddr(raddr) + rfa = &addr + } + return gonet.DialUDP(net.stack, lfa, rfa, pn) +} diff --git a/proxy/wireguard/tun.go b/proxy/wireguard/tun.go index 74a3b71d87c8..af91d0129e38 100644 --- a/proxy/wireguard/tun.go +++ b/proxy/wireguard/tun.go @@ -1,3 +1,6 @@ +//go:build go1.23 +// +build go1.23 + package wireguard import ( diff --git a/proxy/wireguard/tun_go121.go b/proxy/wireguard/tun_go121.go new file mode 100644 index 000000000000..9c67043335a5 --- /dev/null +++ b/proxy/wireguard/tun_go121.go @@ -0,0 +1,208 @@ +//go:build !go1.23 +// +build !go1.23 + +package wireguard + +import ( + "context" + "fmt" + "net" + "net/netip" + "runtime" + "strconv" + "strings" + "sync" + "time" + + "github.com/xtls/xray-core/common/errors" + "github.com/xtls/xray-core/common/log" + xnet "github.com/xtls/xray-core/common/net" + "github.com/xtls/xray-core/proxy/wireguard/gvisortun" + "gvisor.dev/gvisor/pkg/tcpip" + "gvisor.dev/gvisor/pkg/tcpip/adapters/gonet" + "gvisor.dev/gvisor/pkg/tcpip/transport/tcp" + "gvisor.dev/gvisor/pkg/tcpip/transport/udp" + "gvisor.dev/gvisor/pkg/waiter" + + "golang.zx2c4.com/wireguard/conn" + "golang.zx2c4.com/wireguard/device" + "golang.zx2c4.com/wireguard/tun" +) + +type tunCreator func(localAddresses []netip.Addr, mtu int, handler promiscuousModeHandler) (Tunnel, error) + +type promiscuousModeHandler func(dest xnet.Destination, conn net.Conn) + +type Tunnel interface { + BuildDevice(ipc string, bind conn.Bind) error + DialContextTCPAddrPort(ctx context.Context, addr netip.AddrPort) (net.Conn, error) + DialUDPAddrPort(laddr, raddr netip.AddrPort) (net.Conn, error) + Close() error +} + +type tunnel struct { + tun tun.Device + device *device.Device + rw sync.Mutex +} + +func (t *tunnel) BuildDevice(ipc string, bind conn.Bind) (err error) { + t.rw.Lock() + defer t.rw.Unlock() + + if t.device != nil { + return errors.New("device is already initialized") + } + + logger := &device.Logger{ + Verbosef: func(format string, args ...any) { + log.Record(&log.GeneralMessage{ + Severity: log.Severity_Debug, + Content: fmt.Sprintf(format, args...), + }) + }, + Errorf: func(format string, args ...any) { + log.Record(&log.GeneralMessage{ + Severity: log.Severity_Error, + Content: fmt.Sprintf(format, args...), + }) + }, + } + + t.device = device.NewDevice(t.tun, bind, logger) + if err = t.device.IpcSet(ipc); err != nil { + return err + } + if err = t.device.Up(); err != nil { + return err + } + return nil +} + +func (t *tunnel) Close() (err error) { + t.rw.Lock() + defer t.rw.Unlock() + + if t.device == nil { + return nil + } + + t.device.Close() + t.device = nil + err = t.tun.Close() + t.tun = nil + return nil +} + +func CalculateInterfaceName(name string) (tunName string) { + if runtime.GOOS == "darwin" { + tunName = "utun" + } else if name != "" { + tunName = name + } else { + tunName = "tun" + } + interfaces, err := net.Interfaces() + if err != nil { + return + } + var tunIndex int + for _, netInterface := range interfaces { + if strings.HasPrefix(netInterface.Name, tunName) { + index, parseErr := strconv.ParseInt(netInterface.Name[len(tunName):], 10, 16) + if parseErr == nil { + tunIndex = int(index) + 1 + } + } + } + tunName = fmt.Sprintf("%s%d", tunName, tunIndex) + return +} + +var _ Tunnel = (*gvisorNet)(nil) + +type gvisorNet struct { + tunnel + net *gvisortun.Net +} + +func (g *gvisorNet) Close() error { + return g.tunnel.Close() +} + +func (g *gvisorNet) DialContextTCPAddrPort(ctx context.Context, addr netip.AddrPort) ( + net.Conn, error, +) { + return g.net.DialContextTCPAddrPort(ctx, addr) +} + +func (g *gvisorNet) DialUDPAddrPort(laddr, raddr netip.AddrPort) (net.Conn, error) { + return g.net.DialUDPAddrPort(laddr, raddr) +} + +func createGVisorTun(localAddresses []netip.Addr, mtu int, handler promiscuousModeHandler) (Tunnel, error) { + out := &gvisorNet{} + tun, n, stack, err := gvisortun.CreateNetTUN(localAddresses, mtu, handler != nil) + if err != nil { + return nil, err + } + + if handler != nil { + // handler is only used for promiscuous mode + // capture all packets and send to handler + + tcpForwarder := tcp.NewForwarder(stack, 0, 65535, func(r *tcp.ForwarderRequest) { + go func(r *tcp.ForwarderRequest) { + var ( + wq waiter.Queue + id = r.ID() + ) + + // Perform a TCP three-way handshake. + ep, err := r.CreateEndpoint(&wq) + if err != nil { + errors.LogError(context.Background(), err.String()) + r.Complete(true) + return + } + r.Complete(false) + defer ep.Close() + + // enable tcp keep-alive to prevent hanging connections + ep.SocketOptions().SetKeepAlive(true) + + // local address is actually destination + handler(xnet.TCPDestination(xnet.IPAddress(id.LocalAddress.AsSlice()), xnet.Port(id.LocalPort)), gonet.NewTCPConn(&wq, ep)) + }(r) + }) + stack.SetTransportProtocolHandler(tcp.ProtocolNumber, tcpForwarder.HandlePacket) + + udpForwarder := udp.NewForwarder(stack, func(r *udp.ForwarderRequest) { + go func(r *udp.ForwarderRequest) { + var ( + wq waiter.Queue + id = r.ID() + ) + + ep, err := r.CreateEndpoint(&wq) + if err != nil { + errors.LogError(context.Background(), err.String()) + return + } + defer ep.Close() + + // prevents hanging connections and ensure timely release + ep.SocketOptions().SetLinger(tcpip.LingerOption{ + Enabled: true, + Timeout: 15 * time.Second, + }) + + handler(xnet.UDPDestination(xnet.IPAddress(id.LocalAddress.AsSlice()), xnet.Port(id.LocalPort)), gonet.NewUDPConn(stack, &wq, ep)) + }(r) + }) + stack.SetTransportProtocolHandler(udp.ProtocolNumber, udpForwarder.HandlePacket) + } + + out.tun, out.net = tun, n + return out, nil +} From dc2c17768abea9c3a23e15504e783b0a3c15dbeb Mon Sep 17 00:00:00 2001 From: RPRX <63339210+RPRX@users.noreply.github.com> Date: Tue, 15 Oct 2024 04:34:44 +0000 Subject: [PATCH 03/11] Update go.mod --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index f13efa07c2dc..277b1563fb10 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/xtls/xray-core -go 1.23.2 +go 1.21.4 require ( github.com/OmarTariq612/goech v0.0.0-20240405204721-8e2e1dafd3a0 From 2dd3e55121ef2cf25d2216884bfb8c322ca61781 Mon Sep 17 00:00:00 2001 From: hossinasaadi Date: Thu, 17 Oct 2024 19:32:59 +0400 Subject: [PATCH 04/11] fix workflows --- .github/workflows/release.yml | 4 +++- .github/workflows/test.yml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 77e668b49c74..5d2121f24e81 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -191,7 +191,9 @@ jobs: check-latest: true - name: Get project dependencies - run: go mod download + run: | + go mod tidy + go mod download - name: Build Xray run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1e531d527a96..fcd57c115ac8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -41,4 +41,6 @@ jobs: key: xray-geodat- enableCrossOsArchive: true - name: Test - run: go test -timeout 1h -v ./... + run: | + go mod tidy + go test -timeout 1h -v ./... \ No newline at end of file From 3791118e4cae3274cbf087dc3a3995fb1aea5511 Mon Sep 17 00:00:00 2001 From: hossinasaadi Date: Wed, 1 Jan 2025 19:10:35 +0400 Subject: [PATCH 05/11] fix mods --- go.mod | 10 +++++----- go.sum | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index ac0a26f38112..7fb21a579059 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/xtls/xray-core -go 1.23 +go 1.23.2 require ( github.com/OmarTariq612/goech v0.0.0-20240405204721-8e2e1dafd3a0 @@ -29,7 +29,7 @@ require ( golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 google.golang.org/grpc v1.69.2 google.golang.org/protobuf v1.36.1 - gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489 + gvisor.dev/gvisor v0.0.0-20241010231727-f350fc8d7241 h12.io/socks v1.0.3 lukechampine.com/blake3 v1.3.0 ) @@ -50,10 +50,10 @@ require ( github.com/vishvananda/netns v0.0.4 // indirect go.uber.org/mock v0.4.0 // indirect golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect - golang.org/x/mod v0.18.0 // indirect + golang.org/x/mod v0.21.0 // indirect golang.org/x/text v0.21.0 // indirect - golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.22.0 // indirect + golang.org/x/time v0.7.0 // indirect + golang.org/x/tools v0.26.0 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 26805770a810..8ee3eaa00194 100644 --- a/go.sum +++ b/go.sum @@ -127,8 +127,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= +golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= From 9499643c1cde56d7019c1998577690bc24e74d05 Mon Sep 17 00:00:00 2001 From: hossinasaadi Date: Thu, 2 Jan 2025 16:23:19 +0400 Subject: [PATCH 06/11] revert workflow --- .github/workflows/release.yml | 4 +--- .github/workflows/test.yml | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fe19a45161b1..dc6fa6fe51a5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -168,9 +168,7 @@ jobs: check-latest: true - name: Get project dependencies - run: | - go mod tidy - go mod download + run: go mod download - name: Build Xray run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1921afb5c68a..56a4d85118f5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -29,6 +29,4 @@ jobs: key: xray-geodat- enableCrossOsArchive: true - name: Test - run: | - go mod tidy - go test -timeout 1h -v ./... \ No newline at end of file + run: go test -timeout 1h -v ./... \ No newline at end of file From db894043b0f6bee3bca37496c9552f28c46a7543 Mon Sep 17 00:00:00 2001 From: hossinasaadi Date: Thu, 2 Jan 2025 16:24:34 +0400 Subject: [PATCH 07/11] revert tun go121 --- proxy/wireguard/gvisortun/tun.go | 3 - proxy/wireguard/gvisortun/tun_go121.go | 233 ------------------------- 2 files changed, 236 deletions(-) delete mode 100644 proxy/wireguard/gvisortun/tun_go121.go diff --git a/proxy/wireguard/gvisortun/tun.go b/proxy/wireguard/gvisortun/tun.go index f809c5f82162..65677c483e62 100644 --- a/proxy/wireguard/gvisortun/tun.go +++ b/proxy/wireguard/gvisortun/tun.go @@ -1,6 +1,3 @@ -//go:build go1.23 -// +build go1.23 - /* SPDX-License-Identifier: MIT * * Copyright (C) 2017-2022 WireGuard LLC. All Rights Reserved. diff --git a/proxy/wireguard/gvisortun/tun_go121.go b/proxy/wireguard/gvisortun/tun_go121.go deleted file mode 100644 index 1fc5f10b445f..000000000000 --- a/proxy/wireguard/gvisortun/tun_go121.go +++ /dev/null @@ -1,233 +0,0 @@ -//go:build !go1.23 -// +build !go1.23 - -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2017-2022 WireGuard LLC. All Rights Reserved. - */ - -package gvisortun - -import ( - "context" - "fmt" - "net/netip" - "os" - "syscall" - - "golang.zx2c4.com/wireguard/tun" - "gvisor.dev/gvisor/pkg/buffer" - "gvisor.dev/gvisor/pkg/tcpip" - "gvisor.dev/gvisor/pkg/tcpip/adapters/gonet" - "gvisor.dev/gvisor/pkg/tcpip/header" - "gvisor.dev/gvisor/pkg/tcpip/link/channel" - "gvisor.dev/gvisor/pkg/tcpip/network/ipv4" - "gvisor.dev/gvisor/pkg/tcpip/network/ipv6" - "gvisor.dev/gvisor/pkg/tcpip/stack" - "gvisor.dev/gvisor/pkg/tcpip/transport/icmp" - "gvisor.dev/gvisor/pkg/tcpip/transport/tcp" - "gvisor.dev/gvisor/pkg/tcpip/transport/udp" -) - -type netTun struct { - ep *channel.Endpoint - stack *stack.Stack - events chan tun.Event - incomingPacket chan *buffer.View - mtu int - hasV4, hasV6 bool -} - -type Net netTun - -func CreateNetTUN(localAddresses []netip.Addr, mtu int, promiscuousMode bool) (tun.Device, *Net, *stack.Stack, error) { - opts := stack.Options{ - NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol}, - TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol, udp.NewProtocol, icmp.NewProtocol6, icmp.NewProtocol4}, - HandleLocal: !promiscuousMode, - } - dev := &netTun{ - ep: channel.New(1024, uint32(mtu), ""), - stack: stack.New(opts), - events: make(chan tun.Event, 1), - incomingPacket: make(chan *buffer.View), - mtu: mtu, - } - dev.ep.AddNotify(dev) - tcpipErr := dev.stack.CreateNIC(1, dev.ep) - if tcpipErr != nil { - return nil, nil, dev.stack, fmt.Errorf("CreateNIC: %v", tcpipErr) - } - for _, ip := range localAddresses { - var protoNumber tcpip.NetworkProtocolNumber - if ip.Is4() { - protoNumber = ipv4.ProtocolNumber - } else if ip.Is6() { - protoNumber = ipv6.ProtocolNumber - } - protoAddr := tcpip.ProtocolAddress{ - Protocol: protoNumber, - AddressWithPrefix: tcpip.AddrFromSlice(ip.AsSlice()).WithPrefix(), - } - tcpipErr := dev.stack.AddProtocolAddress(1, protoAddr, stack.AddressProperties{}) - if tcpipErr != nil { - return nil, nil, dev.stack, fmt.Errorf("AddProtocolAddress(%v): %v", ip, tcpipErr) - } - if ip.Is4() { - dev.hasV4 = true - } else if ip.Is6() { - dev.hasV6 = true - } - } - if dev.hasV4 { - dev.stack.AddRoute(tcpip.Route{Destination: header.IPv4EmptySubnet, NIC: 1}) - } - if dev.hasV6 { - dev.stack.AddRoute(tcpip.Route{Destination: header.IPv6EmptySubnet, NIC: 1}) - } - if promiscuousMode { - // enable promiscuous mode to handle all packets processed by netstack - dev.stack.SetPromiscuousMode(1, true) - dev.stack.SetSpoofing(1, true) - } - - opt := tcpip.CongestionControlOption("cubic") - if err := dev.stack.SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil { - return nil, nil, dev.stack, fmt.Errorf("SetTransportProtocolOption(%d, &%T(%s)): %s", tcp.ProtocolNumber, opt, opt, err) - } - - dev.events <- tun.EventUp - return dev, (*Net)(dev), dev.stack, nil -} - -// BatchSize implements tun.Device -func (tun *netTun) BatchSize() int { - return 1 -} - -// Name implements tun.Device -func (tun *netTun) Name() (string, error) { - return "go", nil -} - -// File implements tun.Device -func (tun *netTun) File() *os.File { - return nil -} - -// Events implements tun.Device -func (tun *netTun) Events() <-chan tun.Event { - return tun.events -} - -// Read implements tun.Device - -func (tun *netTun) Read(buf [][]byte, sizes []int, offset int) (int, error) { - view, ok := <-tun.incomingPacket - if !ok { - return 0, os.ErrClosed - } - - n, err := view.Read(buf[0][offset:]) - if err != nil { - return 0, err - } - sizes[0] = n - return 1, nil -} - -// Write implements tun.Device -func (tun *netTun) Write(buf [][]byte, offset int) (int, error) { - for _, buf := range buf { - packet := buf[offset:] - if len(packet) == 0 { - continue - } - - pkb := stack.NewPacketBuffer(stack.PacketBufferOptions{Payload: buffer.MakeWithData(packet)}) - switch packet[0] >> 4 { - case 4: - tun.ep.InjectInbound(header.IPv4ProtocolNumber, pkb) - case 6: - tun.ep.InjectInbound(header.IPv6ProtocolNumber, pkb) - default: - return 0, syscall.EAFNOSUPPORT - } - } - return len(buf), nil -} - -// WriteNotify implements channel.Notification -func (tun *netTun) WriteNotify() { - pkt := tun.ep.Read() - if pkt.IsNil() { - return - } - - view := pkt.ToView() - pkt.DecRef() - - tun.incomingPacket <- view -} - -// Flush implements tun.Device -func (tun *netTun) Flush() error { - return nil -} - -// Close implements tun.Device -func (tun *netTun) Close() error { - tun.stack.RemoveNIC(1) - - if tun.events != nil { - close(tun.events) - } - - tun.ep.Close() - - if tun.incomingPacket != nil { - close(tun.incomingPacket) - } - - return nil -} - -// MTU implements tun.Device -func (tun *netTun) MTU() (int, error) { - return tun.mtu, nil -} - -func convertToFullAddr(endpoint netip.AddrPort) (tcpip.FullAddress, tcpip.NetworkProtocolNumber) { - var protoNumber tcpip.NetworkProtocolNumber - if endpoint.Addr().Is4() { - protoNumber = ipv4.ProtocolNumber - } else { - protoNumber = ipv6.ProtocolNumber - } - return tcpip.FullAddress{ - NIC: 1, - Addr: tcpip.AddrFromSlice(endpoint.Addr().AsSlice()), - Port: endpoint.Port(), - }, protoNumber -} - -func (net *Net) DialContextTCPAddrPort(ctx context.Context, addr netip.AddrPort) (*gonet.TCPConn, error) { - fa, pn := convertToFullAddr(addr) - return gonet.DialContextTCP(ctx, net.stack, fa, pn) -} - -func (net *Net) DialUDPAddrPort(laddr, raddr netip.AddrPort) (*gonet.UDPConn, error) { - var lfa, rfa *tcpip.FullAddress - var pn tcpip.NetworkProtocolNumber - if laddr.IsValid() || laddr.Port() > 0 { - var addr tcpip.FullAddress - addr, pn = convertToFullAddr(laddr) - lfa = &addr - } - if raddr.IsValid() || raddr.Port() > 0 { - var addr tcpip.FullAddress - addr, pn = convertToFullAddr(raddr) - rfa = &addr - } - return gonet.DialUDP(net.stack, lfa, rfa, pn) -} From 5ae5fd3b32cc74246d75cd84d30148c2bf0f0648 Mon Sep 17 00:00:00 2001 From: hossinasaadi Date: Thu, 2 Jan 2025 16:25:36 +0400 Subject: [PATCH 08/11] update to latest gvisor --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 7fb21a579059..74a70f0b5fad 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 google.golang.org/grpc v1.69.2 google.golang.org/protobuf v1.36.1 - gvisor.dev/gvisor v0.0.0-20241010231727-f350fc8d7241 + gvisor.dev/gvisor v0.0.0-20241227193629-b8cde430ca0a h12.io/socks v1.0.3 lukechampine.com/blake3 v1.3.0 ) diff --git a/go.sum b/go.sum index 8ee3eaa00194..ff4686fb0e1a 100644 --- a/go.sum +++ b/go.sum @@ -156,8 +156,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gvisor.dev/gvisor v0.0.0-20241010231727-f350fc8d7241 h1:2Gqo79I/LlzC41fZXIzVVbIkeJCOdu8Dif5/MKtFIxE= -gvisor.dev/gvisor v0.0.0-20241010231727-f350fc8d7241/go.mod h1:5DMfjtclAbTIjbXqO1qCe2K5GKKxWz2JHvCChuTcJEM= +gvisor.dev/gvisor v0.0.0-20241227193629-b8cde430ca0a h1:uqyWV7OBmknOheViupl+rEAT9yzgNU9wWSI4Mu1z5n4= +gvisor.dev/gvisor v0.0.0-20241227193629-b8cde430ca0a/go.mod h1:5DMfjtclAbTIjbXqO1qCe2K5GKKxWz2JHvCChuTcJEM= h12.io/socks v1.0.3 h1:Ka3qaQewws4j4/eDQnOdpr4wXsC//dXtWvftlIcCQUo= h12.io/socks v1.0.3/go.mod h1:AIhxy1jOId/XCz9BO+EIgNL2rQiPTBNnOfnVnQ+3Eck= lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= From 37d08a387c179aa7e7060c189c025f701929ba67 Mon Sep 17 00:00:00 2001 From: hossinasaadi Date: Thu, 2 Jan 2025 16:33:24 +0400 Subject: [PATCH 09/11] remove tun_go121 --- proxy/wireguard/tun_go121.go | 208 ----------------------------------- 1 file changed, 208 deletions(-) delete mode 100644 proxy/wireguard/tun_go121.go diff --git a/proxy/wireguard/tun_go121.go b/proxy/wireguard/tun_go121.go deleted file mode 100644 index 9c67043335a5..000000000000 --- a/proxy/wireguard/tun_go121.go +++ /dev/null @@ -1,208 +0,0 @@ -//go:build !go1.23 -// +build !go1.23 - -package wireguard - -import ( - "context" - "fmt" - "net" - "net/netip" - "runtime" - "strconv" - "strings" - "sync" - "time" - - "github.com/xtls/xray-core/common/errors" - "github.com/xtls/xray-core/common/log" - xnet "github.com/xtls/xray-core/common/net" - "github.com/xtls/xray-core/proxy/wireguard/gvisortun" - "gvisor.dev/gvisor/pkg/tcpip" - "gvisor.dev/gvisor/pkg/tcpip/adapters/gonet" - "gvisor.dev/gvisor/pkg/tcpip/transport/tcp" - "gvisor.dev/gvisor/pkg/tcpip/transport/udp" - "gvisor.dev/gvisor/pkg/waiter" - - "golang.zx2c4.com/wireguard/conn" - "golang.zx2c4.com/wireguard/device" - "golang.zx2c4.com/wireguard/tun" -) - -type tunCreator func(localAddresses []netip.Addr, mtu int, handler promiscuousModeHandler) (Tunnel, error) - -type promiscuousModeHandler func(dest xnet.Destination, conn net.Conn) - -type Tunnel interface { - BuildDevice(ipc string, bind conn.Bind) error - DialContextTCPAddrPort(ctx context.Context, addr netip.AddrPort) (net.Conn, error) - DialUDPAddrPort(laddr, raddr netip.AddrPort) (net.Conn, error) - Close() error -} - -type tunnel struct { - tun tun.Device - device *device.Device - rw sync.Mutex -} - -func (t *tunnel) BuildDevice(ipc string, bind conn.Bind) (err error) { - t.rw.Lock() - defer t.rw.Unlock() - - if t.device != nil { - return errors.New("device is already initialized") - } - - logger := &device.Logger{ - Verbosef: func(format string, args ...any) { - log.Record(&log.GeneralMessage{ - Severity: log.Severity_Debug, - Content: fmt.Sprintf(format, args...), - }) - }, - Errorf: func(format string, args ...any) { - log.Record(&log.GeneralMessage{ - Severity: log.Severity_Error, - Content: fmt.Sprintf(format, args...), - }) - }, - } - - t.device = device.NewDevice(t.tun, bind, logger) - if err = t.device.IpcSet(ipc); err != nil { - return err - } - if err = t.device.Up(); err != nil { - return err - } - return nil -} - -func (t *tunnel) Close() (err error) { - t.rw.Lock() - defer t.rw.Unlock() - - if t.device == nil { - return nil - } - - t.device.Close() - t.device = nil - err = t.tun.Close() - t.tun = nil - return nil -} - -func CalculateInterfaceName(name string) (tunName string) { - if runtime.GOOS == "darwin" { - tunName = "utun" - } else if name != "" { - tunName = name - } else { - tunName = "tun" - } - interfaces, err := net.Interfaces() - if err != nil { - return - } - var tunIndex int - for _, netInterface := range interfaces { - if strings.HasPrefix(netInterface.Name, tunName) { - index, parseErr := strconv.ParseInt(netInterface.Name[len(tunName):], 10, 16) - if parseErr == nil { - tunIndex = int(index) + 1 - } - } - } - tunName = fmt.Sprintf("%s%d", tunName, tunIndex) - return -} - -var _ Tunnel = (*gvisorNet)(nil) - -type gvisorNet struct { - tunnel - net *gvisortun.Net -} - -func (g *gvisorNet) Close() error { - return g.tunnel.Close() -} - -func (g *gvisorNet) DialContextTCPAddrPort(ctx context.Context, addr netip.AddrPort) ( - net.Conn, error, -) { - return g.net.DialContextTCPAddrPort(ctx, addr) -} - -func (g *gvisorNet) DialUDPAddrPort(laddr, raddr netip.AddrPort) (net.Conn, error) { - return g.net.DialUDPAddrPort(laddr, raddr) -} - -func createGVisorTun(localAddresses []netip.Addr, mtu int, handler promiscuousModeHandler) (Tunnel, error) { - out := &gvisorNet{} - tun, n, stack, err := gvisortun.CreateNetTUN(localAddresses, mtu, handler != nil) - if err != nil { - return nil, err - } - - if handler != nil { - // handler is only used for promiscuous mode - // capture all packets and send to handler - - tcpForwarder := tcp.NewForwarder(stack, 0, 65535, func(r *tcp.ForwarderRequest) { - go func(r *tcp.ForwarderRequest) { - var ( - wq waiter.Queue - id = r.ID() - ) - - // Perform a TCP three-way handshake. - ep, err := r.CreateEndpoint(&wq) - if err != nil { - errors.LogError(context.Background(), err.String()) - r.Complete(true) - return - } - r.Complete(false) - defer ep.Close() - - // enable tcp keep-alive to prevent hanging connections - ep.SocketOptions().SetKeepAlive(true) - - // local address is actually destination - handler(xnet.TCPDestination(xnet.IPAddress(id.LocalAddress.AsSlice()), xnet.Port(id.LocalPort)), gonet.NewTCPConn(&wq, ep)) - }(r) - }) - stack.SetTransportProtocolHandler(tcp.ProtocolNumber, tcpForwarder.HandlePacket) - - udpForwarder := udp.NewForwarder(stack, func(r *udp.ForwarderRequest) { - go func(r *udp.ForwarderRequest) { - var ( - wq waiter.Queue - id = r.ID() - ) - - ep, err := r.CreateEndpoint(&wq) - if err != nil { - errors.LogError(context.Background(), err.String()) - return - } - defer ep.Close() - - // prevents hanging connections and ensure timely release - ep.SocketOptions().SetLinger(tcpip.LingerOption{ - Enabled: true, - Timeout: 15 * time.Second, - }) - - handler(xnet.UDPDestination(xnet.IPAddress(id.LocalAddress.AsSlice()), xnet.Port(id.LocalPort)), gonet.NewUDPConn(stack, &wq, ep)) - }(r) - }) - stack.SetTransportProtocolHandler(udp.ProtocolNumber, udpForwarder.HandlePacket) - } - - out.tun, out.net = tun, n - return out, nil -} From 858f1f9b09a0e9b1ce1142332377f0dc3601e2c5 Mon Sep 17 00:00:00 2001 From: hossinasaadi Date: Thu, 2 Jan 2025 17:57:00 +0400 Subject: [PATCH 10/11] remove build tag --- proxy/wireguard/tun.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/proxy/wireguard/tun.go b/proxy/wireguard/tun.go index af91d0129e38..74a3b71d87c8 100644 --- a/proxy/wireguard/tun.go +++ b/proxy/wireguard/tun.go @@ -1,6 +1,3 @@ -//go:build go1.23 -// +build go1.23 - package wireguard import ( From d63b5dc6b0416371f9ce21dcf87a8b28e6800bdb Mon Sep 17 00:00:00 2001 From: hossinasaadi Date: Fri, 3 Jan 2025 12:25:45 +0400 Subject: [PATCH 11/11] fix go version --- .github/workflows/test.yml | 2 +- go.mod | 4 ++-- go.sum | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 56a4d85118f5..9620829acefe 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -29,4 +29,4 @@ jobs: key: xray-geodat- enableCrossOsArchive: true - name: Test - run: go test -timeout 1h -v ./... \ No newline at end of file + run: go test -timeout 1h -v ./... diff --git a/go.mod b/go.mod index 74a70f0b5fad..aea10b8bd413 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/xtls/xray-core -go 1.23.2 +go 1.23 require ( github.com/OmarTariq612/goech v0.0.0-20240405204721-8e2e1dafd3a0 @@ -29,7 +29,7 @@ require ( golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 google.golang.org/grpc v1.69.2 google.golang.org/protobuf v1.36.1 - gvisor.dev/gvisor v0.0.0-20241227193629-b8cde430ca0a + gvisor.dev/gvisor v0.0.0-20240320123526-dc6abceb7ff0 h12.io/socks v1.0.3 lukechampine.com/blake3 v1.3.0 ) diff --git a/go.sum b/go.sum index ff4686fb0e1a..e29de52bce45 100644 --- a/go.sum +++ b/go.sum @@ -156,8 +156,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gvisor.dev/gvisor v0.0.0-20241227193629-b8cde430ca0a h1:uqyWV7OBmknOheViupl+rEAT9yzgNU9wWSI4Mu1z5n4= -gvisor.dev/gvisor v0.0.0-20241227193629-b8cde430ca0a/go.mod h1:5DMfjtclAbTIjbXqO1qCe2K5GKKxWz2JHvCChuTcJEM= +gvisor.dev/gvisor v0.0.0-20240320123526-dc6abceb7ff0 h1:P+U/06iIKPQ3DLcg+zBfSCia1luZ2msPZrJ8jYDFPs0= +gvisor.dev/gvisor v0.0.0-20240320123526-dc6abceb7ff0/go.mod h1:NQHVAzMwvZ+Qe3ElSiHmq9RUm1MdNHpUZ52fiEqvn+0= h12.io/socks v1.0.3 h1:Ka3qaQewws4j4/eDQnOdpr4wXsC//dXtWvftlIcCQUo= h12.io/socks v1.0.3/go.mod h1:AIhxy1jOId/XCz9BO+EIgNL2rQiPTBNnOfnVnQ+3Eck= lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE=