mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-09-09 13:04:06 +08:00
ktls: Fix parse kernel version
This commit is contained in:
parent
a832c26a2f
commit
94103df562
@ -5,6 +5,8 @@ import (
|
||||
"strings"
|
||||
|
||||
F "github.com/sagernet/sing/common/format"
|
||||
|
||||
"golang.org/x/mod/semver"
|
||||
)
|
||||
|
||||
type Version struct {
|
||||
@ -16,7 +18,19 @@ type Version struct {
|
||||
PreReleaseVersion int
|
||||
}
|
||||
|
||||
func (v Version) After(anotherVersion Version) bool {
|
||||
func (v Version) LessThan(anotherVersion Version) bool {
|
||||
return !v.GreaterThanOrEqual(anotherVersion)
|
||||
}
|
||||
|
||||
func (v Version) LessThanOrEqual(anotherVersion Version) bool {
|
||||
return v == anotherVersion || anotherVersion.GreaterThan(v)
|
||||
}
|
||||
|
||||
func (v Version) GreaterThanOrEqual(anotherVersion Version) bool {
|
||||
return v == anotherVersion || v.GreaterThan(anotherVersion)
|
||||
}
|
||||
|
||||
func (v Version) GreaterThan(anotherVersion Version) bool {
|
||||
if v.Major > anotherVersion.Major {
|
||||
return true
|
||||
} else if v.Major < anotherVersion.Major {
|
||||
@ -44,19 +58,29 @@ func (v Version) After(anotherVersion Version) bool {
|
||||
} else if v.PreReleaseVersion < anotherVersion.PreReleaseVersion {
|
||||
return false
|
||||
}
|
||||
} else if v.PreReleaseIdentifier == "rc" && anotherVersion.PreReleaseIdentifier == "beta" {
|
||||
}
|
||||
preReleaseIdentifier := parsePreReleaseIdentifier(v.PreReleaseIdentifier)
|
||||
anotherPreReleaseIdentifier := parsePreReleaseIdentifier(anotherVersion.PreReleaseIdentifier)
|
||||
if preReleaseIdentifier < anotherPreReleaseIdentifier {
|
||||
return true
|
||||
} else if v.PreReleaseIdentifier == "beta" && anotherVersion.PreReleaseIdentifier == "rc" {
|
||||
return false
|
||||
} else if v.PreReleaseIdentifier == "beta" && anotherVersion.PreReleaseIdentifier == "alpha" {
|
||||
return true
|
||||
} else if v.PreReleaseIdentifier == "alpha" && anotherVersion.PreReleaseIdentifier == "beta" {
|
||||
} else if preReleaseIdentifier > anotherPreReleaseIdentifier {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func parsePreReleaseIdentifier(identifier string) int {
|
||||
if strings.HasPrefix(identifier, "rc") {
|
||||
return 1
|
||||
} else if strings.HasPrefix(identifier, "beta") {
|
||||
return 2
|
||||
} else if strings.HasPrefix(identifier, "alpha") {
|
||||
return 3
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (v Version) VersionString() string {
|
||||
return F.ToString(v.Major, ".", v.Minor, ".", v.Patch)
|
||||
}
|
||||
@ -83,6 +107,10 @@ func (v Version) BadString() string {
|
||||
return version
|
||||
}
|
||||
|
||||
func IsValid(versionName string) bool {
|
||||
return semver.IsValid("v" + versionName)
|
||||
}
|
||||
|
||||
func Parse(versionName string) (version Version) {
|
||||
if strings.HasPrefix(versionName, "v") {
|
||||
versionName = versionName[1:]
|
||||
|
@ -10,9 +10,9 @@ func TestCompareVersion(t *testing.T) {
|
||||
t.Parallel()
|
||||
require.Equal(t, "1.3.0-beta.1", Parse("v1.3.0-beta1").String())
|
||||
require.Equal(t, "1.3-beta1", Parse("v1.3.0-beta.1").BadString())
|
||||
require.True(t, Parse("1.3.0").After(Parse("1.3-beta1")))
|
||||
require.True(t, Parse("1.3.0").After(Parse("1.3.0-beta1")))
|
||||
require.True(t, Parse("1.3.0-beta1").After(Parse("1.3.0-alpha1")))
|
||||
require.True(t, Parse("1.3.1").After(Parse("1.3.0")))
|
||||
require.True(t, Parse("1.4").After(Parse("1.3")))
|
||||
require.True(t, Parse("1.3.0").GreaterThan(Parse("1.3-beta1")))
|
||||
require.True(t, Parse("1.3.0").GreaterThan(Parse("1.3.0-beta1")))
|
||||
require.True(t, Parse("1.3.0-beta1").GreaterThan(Parse("1.3.0-alpha1")))
|
||||
require.True(t, Parse("1.3.1").GreaterThan(Parse("1.3.0")))
|
||||
require.True(t, Parse("1.4").GreaterThan(Parse("1.3")))
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ func NewConn(ctx context.Context, logger logger.ContextLogger, conn aTLS.Conn, t
|
||||
for rawConn.Hand.Len() > 0 {
|
||||
err = rawConn.HandlePostHandshakeMessage()
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "ktls: failed to handle post-handshake messages")
|
||||
return nil, E.Cause(err, "handle post-handshake messages")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,11 +12,11 @@ import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/sagernet/sing-box/common/badversion"
|
||||
"github.com/sagernet/sing/common/control"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
"github.com/sagernet/sing/common/shell"
|
||||
|
||||
"github.com/blang/semver/v4"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
@ -55,46 +55,42 @@ var KernelSupport = sync.OnceValues(func() (*Support, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
kernelVersion, err := semver.Parse(strings.Trim(string(uname.Release[:]), "\x00"))
|
||||
kernelVersion := badversion.Parse(strings.Trim(string(uname.Release[:]), "\x00"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kernelVersion.Pre = nil
|
||||
kernelVersion.Build = nil
|
||||
|
||||
var support Support
|
||||
|
||||
switch {
|
||||
case kernelVersion.GTE(semver.Version{Major: 6, Minor: 14}):
|
||||
case kernelVersion.GreaterThanOrEqual(badversion.Version{Major: 6, Minor: 14}):
|
||||
support.TLS_Version13_KeyUpdate = true
|
||||
fallthrough
|
||||
case kernelVersion.GTE(semver.Version{Major: 6, Minor: 1}):
|
||||
case kernelVersion.GreaterThanOrEqual(badversion.Version{Major: 6, Minor: 1}):
|
||||
support.TLS_ARIA_GCM = true
|
||||
fallthrough
|
||||
case kernelVersion.GTE(semver.Version{Major: 6}):
|
||||
case kernelVersion.GreaterThanOrEqual(badversion.Version{Major: 6}):
|
||||
support.TLS_Version13_RX = true
|
||||
support.TLS_RX_NOPADDING = true
|
||||
fallthrough
|
||||
case kernelVersion.GTE(semver.Version{Major: 5, Minor: 19}):
|
||||
case kernelVersion.GreaterThanOrEqual(badversion.Version{Major: 5, Minor: 19}):
|
||||
support.TLS_TX_ZEROCOPY = true
|
||||
fallthrough
|
||||
case kernelVersion.GTE(semver.Version{Major: 5, Minor: 16}):
|
||||
case kernelVersion.GreaterThanOrEqual(badversion.Version{Major: 5, Minor: 16}):
|
||||
support.TLS_SM4 = true
|
||||
fallthrough
|
||||
case kernelVersion.GTE(semver.Version{Major: 5, Minor: 11}):
|
||||
case kernelVersion.GreaterThanOrEqual(badversion.Version{Major: 5, Minor: 11}):
|
||||
support.TLS_CHACHA20_POLY1305 = true
|
||||
fallthrough
|
||||
case kernelVersion.GTE(semver.Version{Major: 5, Minor: 2}):
|
||||
case kernelVersion.GreaterThanOrEqual(badversion.Version{Major: 5, Minor: 2}):
|
||||
support.TLS_AES_128_CCM = true
|
||||
fallthrough
|
||||
case kernelVersion.GTE(semver.Version{Major: 5, Minor: 1}):
|
||||
case kernelVersion.GreaterThanOrEqual(badversion.Version{Major: 5, Minor: 1}):
|
||||
support.TLS_AES_256_GCM = true
|
||||
support.TLS_Version13 = true
|
||||
fallthrough
|
||||
case kernelVersion.GTE(semver.Version{Major: 4, Minor: 17}):
|
||||
case kernelVersion.GreaterThanOrEqual(badversion.Version{Major: 4, Minor: 17}):
|
||||
support.TLS_RX = true
|
||||
fallthrough
|
||||
case kernelVersion.GTE(semver.Version{Major: 4, Minor: 13}):
|
||||
case kernelVersion.GreaterThanOrEqual(badversion.Version{Major: 4, Minor: 13}):
|
||||
support.TLS = true
|
||||
}
|
||||
|
||||
@ -118,7 +114,7 @@ var KernelSupport = sync.OnceValues(func() (*Support, error) {
|
||||
func Load() error {
|
||||
support, err := KernelSupport()
|
||||
if err != nil {
|
||||
return err
|
||||
return E.Cause(err, "ktls: check availability")
|
||||
}
|
||||
if !support.TLS || !support.TLS_Version13 {
|
||||
return E.New("ktls: kernel does not support TLS 1.3")
|
||||
@ -132,10 +128,10 @@ func (c *Conn) setupKernel(txOffload, rxOffload bool) error {
|
||||
}
|
||||
support, err := KernelSupport()
|
||||
if err != nil {
|
||||
return err
|
||||
return E.Cause(err, "check availability")
|
||||
}
|
||||
if !support.TLS || !support.TLS_Version13 {
|
||||
return E.New("ktls: kernel does not support TLS 1.3")
|
||||
return E.New("kernel does not support TLS 1.3")
|
||||
}
|
||||
c.rawConn.Out.Lock()
|
||||
defer c.rawConn.Out.Unlock()
|
||||
@ -143,13 +139,13 @@ func (c *Conn) setupKernel(txOffload, rxOffload bool) error {
|
||||
return syscall.SetsockoptString(int(fd), unix.SOL_TCP, unix.TCP_ULP, "tls")
|
||||
})
|
||||
if err != nil {
|
||||
return E.Cause(err, "initialize kernel TLS")
|
||||
return os.NewSyscallError("setsockopt", err)
|
||||
}
|
||||
|
||||
if txOffload {
|
||||
txCrypto := kernelCipher(support, c.rawConn.Out, *c.rawConn.CipherSuite, false)
|
||||
if txCrypto == nil {
|
||||
return E.New("kTLS: unsupported cipher suite")
|
||||
return E.New("unsupported cipher suite")
|
||||
}
|
||||
err = control.Raw(c.rawSyscallConn, func(fd uintptr) error {
|
||||
return syscall.SetsockoptString(int(fd), unix.SOL_TLS, TLS_TX, txCrypto.String())
|
||||
@ -172,7 +168,7 @@ func (c *Conn) setupKernel(txOffload, rxOffload bool) error {
|
||||
if rxOffload {
|
||||
rxCrypto := kernelCipher(support, c.rawConn.In, *c.rawConn.CipherSuite, true)
|
||||
if rxCrypto == nil {
|
||||
return E.New("kTLS: unsupported cipher suite")
|
||||
return E.New("unsupported cipher suite")
|
||||
}
|
||||
err = control.Raw(c.rawSyscallConn, func(fd uintptr) error {
|
||||
return syscall.SetsockoptString(int(fd), unix.SOL_TLS, TLS_RX, rxCrypto.String())
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"net"
|
||||
|
||||
"github.com/sagernet/sing-box/common/ktls"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
"github.com/sagernet/sing/common/logger"
|
||||
aTLS "github.com/sagernet/sing/common/tls"
|
||||
)
|
||||
@ -20,7 +21,12 @@ func (w *KTLSClientConfig) ClientHandshake(ctx context.Context, conn net.Conn) (
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ktls.NewConn(ctx, w.logger, tlsConn, w.kernelTx, w.kernelRx)
|
||||
kConn, err := ktls.NewConn(ctx, w.logger, tlsConn, w.kernelTx, w.kernelRx)
|
||||
if err != nil {
|
||||
tlsConn.Close()
|
||||
return nil, E.Cause(err, "initialize kernel TLS")
|
||||
}
|
||||
return kConn, nil
|
||||
}
|
||||
|
||||
func (w *KTLSClientConfig) Clone() Config {
|
||||
@ -43,7 +49,12 @@ func (w *KTlSServerConfig) ServerHandshake(ctx context.Context, conn net.Conn) (
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ktls.NewConn(ctx, w.logger, tlsConn, w.kernelTx, w.kernelRx)
|
||||
kConn, err := ktls.NewConn(ctx, w.logger, tlsConn, w.kernelTx, w.kernelRx)
|
||||
if err != nil {
|
||||
tlsConn.Close()
|
||||
return nil, E.Cause(err, "initialize kernel TLS")
|
||||
}
|
||||
return kConn, nil
|
||||
}
|
||||
|
||||
func (w *KTlSServerConfig) Clone() Config {
|
||||
|
1
go.mod
1
go.mod
@ -4,7 +4,6 @@ go 1.23.1
|
||||
|
||||
require (
|
||||
github.com/anytls/sing-anytls v0.0.8
|
||||
github.com/blang/semver/v4 v4.0.0
|
||||
github.com/caddyserver/certmagic v0.23.0
|
||||
github.com/coder/websocket v1.8.13
|
||||
github.com/cretz/bine v0.2.0
|
||||
|
2
go.sum
2
go.sum
@ -12,8 +12,6 @@ github.com/anytls/sing-anytls v0.0.8 h1:1u/fnH1HoeeMV5mX7/eUOjLBvPdkd1UJRmXiRi6V
|
||||
github.com/anytls/sing-anytls v0.0.8/go.mod h1:7rjN6IukwysmdusYsrV51Fgu1uW6vsrdd6ctjnEAln8=
|
||||
github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE=
|
||||
github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
|
||||
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
|
||||
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
|
||||
github.com/caddyserver/certmagic v0.23.0 h1:CfpZ/50jMfG4+1J/u2LV6piJq4HOfO6ppOnOf7DkFEU=
|
||||
github.com/caddyserver/certmagic v0.23.0/go.mod h1:9mEZIWqqWoI+Gf+4Trh04MOVPD0tGSxtqsxg87hAIH4=
|
||||
github.com/caddyserver/zerossl v0.1.3 h1:onS+pxp3M8HnHpN5MMbOMyNjmTheJyWRaZYwn+YTAyA=
|
||||
|
Loading…
x
Reference in New Issue
Block a user