From fe79082008b3b408e8933e86be81e664ebd92f4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Fri, 22 Nov 2024 17:17:01 +0800 Subject: [PATCH] Make GSO adaptive --- experimental/deprecated/constants.go | 49 +++++++++++++++++++++---- experimental/deprecated/stderr.go | 2 +- option/tun.go | 3 +- option/wireguard.go | 1 - protocol/tun/inbound.go | 18 +++++---- protocol/wireguard/endpoint.go | 3 -- protocol/wireguard/outbound.go | 4 +- transport/wireguard/device.go | 1 - transport/wireguard/device_system.go | 11 ++---- transport/wireguard/endpoint.go | 1 - transport/wireguard/endpoint_options.go | 1 - 11 files changed, 61 insertions(+), 33 deletions(-) diff --git a/experimental/deprecated/constants.go b/experimental/deprecated/constants.go index f5b000a7..4271800b 100644 --- a/experimental/deprecated/constants.go +++ b/experimental/deprecated/constants.go @@ -33,17 +33,31 @@ func (n Note) Impending() bool { } func (n Note) Message() string { - return F.ToString( - n.Description, " is deprecated in sing-box ", n.DeprecatedVersion, - " and will be removed in sing-box ", n.ScheduledVersion, ", please checkout documentation for migration.", - ) + if n.MigrationLink != "" { + return F.ToString( + n.Description, " is deprecated in sing-box ", n.DeprecatedVersion, + " and will be removed in sing-box ", n.ScheduledVersion, ", please checkout documentation for migration.", + ) + } else { + return F.ToString( + n.Description, " is deprecated in sing-box ", n.DeprecatedVersion, + " and will be removed in sing-box ", n.ScheduledVersion, ".", + ) + } } func (n Note) MessageWithLink() string { - return F.ToString( - n.Description, " is deprecated in sing-box ", n.DeprecatedVersion, - " and will be removed in sing-box ", n.ScheduledVersion, ", checkout documentation for migration: ", n.MigrationLink, - ) + if n.MigrationLink != "" { + return F.ToString( + n.Description, " is deprecated in sing-box ", n.DeprecatedVersion, + " and will be removed in sing-box ", n.ScheduledVersion, ", checkout documentation for migration: ", n.MigrationLink, + ) + } else { + return F.ToString( + n.Description, " is deprecated in sing-box ", n.DeprecatedVersion, + " and will be removed in sing-box ", n.ScheduledVersion, ".", + ) + } } var OptionBadMatchSource = Note{ @@ -118,6 +132,23 @@ var OptionWireGuardOutbound = Note{ MigrationLink: "https://sing-box.sagernet.org/migration/#migrate-wireguard-outbound-to-endpoint", } +var OptionWireGuardGSO = Note{ + Name: "wireguard-gso", + Description: "GSO option in wireguard outbound", + DeprecatedVersion: "1.11.0", + ScheduledVersion: "1.13.0", + EnvName: "WIREGUARD_GSO", + MigrationLink: "https://sing-box.sagernet.org/migration/#migrate-wireguard-outbound-to-endpoint", +} + +var OptionTUNGSO = Note{ + Name: "tun-gso", + Description: "GSO option in tun", + DeprecatedVersion: "1.11.0", + ScheduledVersion: "1.12.0", + EnvName: "TUN_GSO", +} + var Options = []Note{ OptionBadMatchSource, OptionGEOIP, @@ -127,4 +158,6 @@ var Options = []Note{ OptionInboundOptions, OptionDestinationOverrideFields, OptionWireGuardOutbound, + OptionWireGuardGSO, + OptionTUNGSO, } diff --git a/experimental/deprecated/stderr.go b/experimental/deprecated/stderr.go index 0826baf9..f29b4754 100644 --- a/experimental/deprecated/stderr.go +++ b/experimental/deprecated/stderr.go @@ -34,5 +34,5 @@ func (f *stderrManager) ReportDeprecated(feature Note) { return } f.logger.Error(feature.MessageWithLink()) - f.logger.Fatal("to continuing using this feature, set ENABLE_DEPRECATED_" + feature.EnvName + "=true") + f.logger.Fatal("to continuing using this feature, set environment variable ENABLE_DEPRECATED_" + feature.EnvName + "=true") } diff --git a/option/tun.go b/option/tun.go index a7a0f6bc..1f304cc9 100644 --- a/option/tun.go +++ b/option/tun.go @@ -13,7 +13,6 @@ import ( type TunInboundOptions struct { InterfaceName string `json:"interface_name,omitempty"` MTU uint32 `json:"mtu,omitempty"` - GSO bool `json:"gso,omitempty"` Address badoption.Listable[netip.Prefix] `json:"address,omitempty"` AutoRoute bool `json:"auto_route,omitempty"` IPRoute2TableIndex int `json:"iproute2_table_index,omitempty"` @@ -41,6 +40,8 @@ type TunInboundOptions struct { Platform *TunPlatformOptions `json:"platform,omitempty"` InboundOptions + // Deprecated: removed + GSO bool `json:"gso,omitempty"` // Deprecated: merged to Address Inet4Address badoption.Listable[netip.Prefix] `json:"inet4_address,omitempty"` // Deprecated: merged to Address diff --git a/option/wireguard.go b/option/wireguard.go index 62ef332a..b9860d11 100644 --- a/option/wireguard.go +++ b/option/wireguard.go @@ -10,7 +10,6 @@ type WireGuardEndpointOptions struct { System bool `json:"system,omitempty"` Name string `json:"name,omitempty"` MTU uint32 `json:"mtu,omitempty"` - GSO bool `json:"gso,omitempty"` Address badoption.Listable[netip.Prefix] `json:"address"` PrivateKey string `json:"private_key"` ListenPort uint16 `json:"listen_port,omitempty"` diff --git a/protocol/tun/inbound.go b/protocol/tun/inbound.go index b3ada905..4d3d3f67 100644 --- a/protocol/tun/inbound.go +++ b/protocol/tun/inbound.go @@ -64,14 +64,14 @@ type Inbound struct { func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TunInboundOptions) (adapter.Inbound, error) { address := options.Address var deprecatedAddressUsed bool + //nolint:staticcheck - //goland:noinspection GoDeprecation if len(options.Inet4Address) > 0 { address = append(address, options.Inet4Address...) deprecatedAddressUsed = true } + //nolint:staticcheck - //goland:noinspection GoDeprecation if len(options.Inet6Address) > 0 { address = append(address, options.Inet6Address...) deprecatedAddressUsed = true @@ -84,14 +84,14 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo }) routeAddress := options.RouteAddress + //nolint:staticcheck - //goland:noinspection GoDeprecation if len(options.Inet4RouteAddress) > 0 { routeAddress = append(routeAddress, options.Inet4RouteAddress...) deprecatedAddressUsed = true } + //nolint:staticcheck - //goland:noinspection GoDeprecation if len(options.Inet6RouteAddress) > 0 { routeAddress = append(routeAddress, options.Inet6RouteAddress...) deprecatedAddressUsed = true @@ -104,14 +104,14 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo }) routeExcludeAddress := options.RouteExcludeAddress + //nolint:staticcheck - //goland:noinspection GoDeprecation if len(options.Inet4RouteExcludeAddress) > 0 { routeExcludeAddress = append(routeExcludeAddress, options.Inet4RouteExcludeAddress...) deprecatedAddressUsed = true } + //nolint:staticcheck - //goland:noinspection GoDeprecation if len(options.Inet6RouteExcludeAddress) > 0 { routeExcludeAddress = append(routeExcludeAddress, options.Inet6RouteExcludeAddress...) deprecatedAddressUsed = true @@ -127,6 +127,11 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo deprecated.Report(ctx, deprecated.OptionTUNAddressX) } + //nolint:staticcheck + if options.GSO { + deprecated.Report(ctx, deprecated.OptionTUNGSO) + } + tunMTU := options.MTU if tunMTU == 0 { tunMTU = 9000 @@ -180,7 +185,6 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo tunOptions: tun.Options{ Name: options.InterfaceName, MTU: tunMTU, - GSO: options.GSO, Inet4Address: inet4Address, Inet6Address: inet6Address, AutoRoute: options.AutoRoute, diff --git a/protocol/wireguard/endpoint.go b/protocol/wireguard/endpoint.go index 5465099c..dc40b613 100644 --- a/protocol/wireguard/endpoint.go +++ b/protocol/wireguard/endpoint.go @@ -51,8 +51,6 @@ func NewEndpoint(ctx context.Context, router adapter.Router, logger log.ContextL } if options.Detour == "" { options.IsWireGuardListener = true - } else if options.GSO { - return nil, E.New("gso is conflict with detour") } outboundDialer, err := dialer.New(ctx, options.DialerOptions) if err != nil { @@ -72,7 +70,6 @@ func NewEndpoint(ctx context.Context, router adapter.Router, logger log.ContextL }, Name: options.Name, MTU: options.MTU, - GSO: options.GSO, Address: options.Address, PrivateKey: options.PrivateKey, ListenPort: options.ListenPort, diff --git a/protocol/wireguard/outbound.go b/protocol/wireguard/outbound.go index c7fa15e5..b9b0f355 100644 --- a/protocol/wireguard/outbound.go +++ b/protocol/wireguard/outbound.go @@ -42,6 +42,9 @@ type Outbound struct { func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.LegacyWireGuardOutboundOptions) (adapter.Outbound, error) { deprecated.Report(ctx, deprecated.OptionWireGuardOutbound) + if options.GSO { + deprecated.Report(ctx, deprecated.OptionWireGuardGSO) + } outbound := &Outbound{ Adapter: outbound.NewAdapterWithDialerOptions(C.TypeWireGuard, tag, []string{N.NetworkTCP, N.NetworkUDP}, options.DialerOptions), ctx: ctx, @@ -70,7 +73,6 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL }, Name: options.InterfaceName, MTU: options.MTU, - GSO: options.GSO, Address: options.LocalAddress, PrivateKey: options.PrivateKey, ResolvePeer: func(domain string) (netip.Addr, error) { diff --git a/transport/wireguard/device.go b/transport/wireguard/device.go index d5d3b781..7a17b8f3 100644 --- a/transport/wireguard/device.go +++ b/transport/wireguard/device.go @@ -28,7 +28,6 @@ type DeviceOptions struct { CreateDialer func(interfaceName string) N.Dialer Name string MTU uint32 - GSO bool Address []netip.Prefix AllowedAddress []netip.Prefix } diff --git a/transport/wireguard/device_system.go b/transport/wireguard/device_system.go index 4e748fa7..4237a8a6 100644 --- a/transport/wireguard/device_system.go +++ b/transport/wireguard/device_system.go @@ -12,7 +12,6 @@ import ( "github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-tun" "github.com/sagernet/sing/common" - E "github.com/sagernet/sing/common/exceptions" M "github.com/sagernet/sing/common/metadata" N "github.com/sagernet/sing/common/network" "github.com/sagernet/sing/service" @@ -64,7 +63,7 @@ func (w *systemDevice) Start() error { return it.Addr().Is6() }), MTU: w.options.MTU, - GSO: w.options.GSO, + GSO: true, InterfaceScope: true, Inet4RouteAddress: common.Filter(w.options.AllowedAddress, func(it netip.Prefix) bool { return it.Addr().Is4() @@ -87,12 +86,8 @@ func (w *systemDevice) Start() error { } w.options.Logger.Info("started at ", w.options.Name) w.device = tunInterface - if w.options.GSO { - batchTUN, isBatchTUN := tunInterface.(tun.LinuxTUN) - if !isBatchTUN { - tunInterface.Close() - return E.New("GSO is not supported on current platform") - } + batchTUN, isBatchTUN := tunInterface.(tun.LinuxTUN) + if isBatchTUN { w.batchDevice = batchTUN } w.events <- wgTun.EventUp diff --git a/transport/wireguard/endpoint.go b/transport/wireguard/endpoint.go index ffa0b1fa..c842dfcf 100644 --- a/transport/wireguard/endpoint.go +++ b/transport/wireguard/endpoint.go @@ -104,7 +104,6 @@ func NewEndpoint(options EndpointOptions) (*Endpoint, error) { CreateDialer: options.CreateDialer, Name: options.Name, MTU: options.MTU, - GSO: options.GSO, Address: options.Address, AllowedAddress: allowedAddresses, } diff --git a/transport/wireguard/endpoint_options.go b/transport/wireguard/endpoint_options.go index d44422e3..bb9a46e6 100644 --- a/transport/wireguard/endpoint_options.go +++ b/transport/wireguard/endpoint_options.go @@ -21,7 +21,6 @@ type EndpointOptions struct { CreateDialer func(interfaceName string) N.Dialer Name string MTU uint32 - GSO bool Address []netip.Prefix PrivateKey string ListenPort uint16