mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2025-12-20 00:50:06 +08:00
fix: alpn apply on shadowtls
Some checks failed
Test / test (1.20, macos-13) (push) Waiting to run
Test / test (1.20, macos-latest) (push) Waiting to run
Test / test (1.20, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.20, windows-latest) (push) Waiting to run
Test / test (1.21, macos-13) (push) Waiting to run
Test / test (1.21, macos-latest) (push) Waiting to run
Test / test (1.21, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.21, windows-latest) (push) Waiting to run
Test / test (1.22, macos-13) (push) Waiting to run
Test / test (1.22, macos-latest) (push) Waiting to run
Test / test (1.22, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.22, windows-latest) (push) Waiting to run
Test / test (1.23, macos-13) (push) Waiting to run
Test / test (1.23, macos-latest) (push) Waiting to run
Test / test (1.23, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.23, windows-latest) (push) Waiting to run
Test / test (1.24, macos-13) (push) Waiting to run
Test / test (1.24, macos-latest) (push) Waiting to run
Test / test (1.24, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.24, windows-latest) (push) Waiting to run
Test / test (1.20, ubuntu-latest) (push) Failing after 1s
Test / test (1.21, ubuntu-latest) (push) Failing after 1s
Test / test (1.22, ubuntu-latest) (push) Failing after 1s
Test / test (1.23, ubuntu-latest) (push) Failing after 1s
Test / test (1.24, ubuntu-latest) (push) Failing after 1s
Trigger CMFA Update / trigger-CMFA-update (push) Failing after 1s
Some checks failed
Test / test (1.20, macos-13) (push) Waiting to run
Test / test (1.20, macos-latest) (push) Waiting to run
Test / test (1.20, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.20, windows-latest) (push) Waiting to run
Test / test (1.21, macos-13) (push) Waiting to run
Test / test (1.21, macos-latest) (push) Waiting to run
Test / test (1.21, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.21, windows-latest) (push) Waiting to run
Test / test (1.22, macos-13) (push) Waiting to run
Test / test (1.22, macos-latest) (push) Waiting to run
Test / test (1.22, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.22, windows-latest) (push) Waiting to run
Test / test (1.23, macos-13) (push) Waiting to run
Test / test (1.23, macos-latest) (push) Waiting to run
Test / test (1.23, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.23, windows-latest) (push) Waiting to run
Test / test (1.24, macos-13) (push) Waiting to run
Test / test (1.24, macos-latest) (push) Waiting to run
Test / test (1.24, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.24, windows-latest) (push) Waiting to run
Test / test (1.20, ubuntu-latest) (push) Failing after 1s
Test / test (1.21, ubuntu-latest) (push) Failing after 1s
Test / test (1.22, ubuntu-latest) (push) Failing after 1s
Test / test (1.23, ubuntu-latest) (push) Failing after 1s
Test / test (1.24, ubuntu-latest) (push) Failing after 1s
Trigger CMFA Update / trigger-CMFA-update (push) Failing after 1s
This commit is contained in:
parent
99aa1b0de1
commit
e6e7aa5ae2
@ -19,37 +19,36 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
var shadowsocksCipherList = []string{shadowsocks.MethodNone}
|
var noneList = []string{shadowsocks.MethodNone}
|
||||||
var shadowsocksCipherListShort = []string{shadowsocks.MethodNone}
|
var shadowsocksCipherLists = [][]string{noneList, shadowaead.List, shadowaead_2022.List, shadowstream.List}
|
||||||
|
var shadowsocksCipherShortLists = [][]string{noneList, shadowaead.List[:1], shadowaead_2022.List[:1]}
|
||||||
var shadowsocksPassword32 string
|
var shadowsocksPassword32 string
|
||||||
var shadowsocksPassword16 string
|
var shadowsocksPassword16 string
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
shadowsocksCipherList = append(shadowsocksCipherList, shadowaead.List...)
|
|
||||||
shadowsocksCipherList = append(shadowsocksCipherList, shadowaead_2022.List...)
|
|
||||||
shadowsocksCipherList = append(shadowsocksCipherList, shadowstream.List...)
|
|
||||||
shadowsocksCipherListShort = append(shadowsocksCipherListShort, shadowaead.List[0])
|
|
||||||
shadowsocksCipherListShort = append(shadowsocksCipherListShort, shadowaead_2022.List[0])
|
|
||||||
passwordBytes := make([]byte, 32)
|
passwordBytes := make([]byte, 32)
|
||||||
rand.Read(passwordBytes)
|
rand.Read(passwordBytes)
|
||||||
shadowsocksPassword32 = base64.StdEncoding.EncodeToString(passwordBytes)
|
shadowsocksPassword32 = base64.StdEncoding.EncodeToString(passwordBytes)
|
||||||
shadowsocksPassword16 = base64.StdEncoding.EncodeToString(passwordBytes[:16])
|
shadowsocksPassword16 = base64.StdEncoding.EncodeToString(passwordBytes[:16])
|
||||||
}
|
}
|
||||||
|
|
||||||
func testInboundShadowSocks(t *testing.T, inboundOptions inbound.ShadowSocksOption, outboundOptions outbound.ShadowSocksOption, cipherList []string) {
|
func testInboundShadowSocks(t *testing.T, inboundOptions inbound.ShadowSocksOption, outboundOptions outbound.ShadowSocksOption, cipherLists [][]string) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
for _, cipher := range cipherList {
|
for _, cipherList := range cipherLists {
|
||||||
|
for i, cipher := range cipherList {
|
||||||
|
enableSingMux := i == 0
|
||||||
cipher := cipher
|
cipher := cipher
|
||||||
t.Run(cipher, func(t *testing.T) {
|
t.Run(cipher, func(t *testing.T) {
|
||||||
inboundOptions, outboundOptions := inboundOptions, outboundOptions // don't modify outside options value
|
inboundOptions, outboundOptions := inboundOptions, outboundOptions // don't modify outside options value
|
||||||
inboundOptions.Cipher = cipher
|
inboundOptions.Cipher = cipher
|
||||||
outboundOptions.Cipher = cipher
|
outboundOptions.Cipher = cipher
|
||||||
testInboundShadowSocks0(t, inboundOptions, outboundOptions)
|
testInboundShadowSocks0(t, inboundOptions, outboundOptions, enableSingMux)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func testInboundShadowSocks0(t *testing.T, inboundOptions inbound.ShadowSocksOption, outboundOptions outbound.ShadowSocksOption) {
|
func testInboundShadowSocks0(t *testing.T, inboundOptions inbound.ShadowSocksOption, outboundOptions outbound.ShadowSocksOption, enableSingMux bool) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
password := shadowsocksPassword32
|
password := shadowsocksPassword32
|
||||||
if strings.Contains(inboundOptions.Cipher, "-128-") {
|
if strings.Contains(inboundOptions.Cipher, "-128-") {
|
||||||
@ -93,13 +92,28 @@ func testInboundShadowSocks0(t *testing.T, inboundOptions inbound.ShadowSocksOpt
|
|||||||
|
|
||||||
tunnel.DoTest(t, out)
|
tunnel.DoTest(t, out)
|
||||||
|
|
||||||
|
if enableSingMux {
|
||||||
testSingMux(t, tunnel, out)
|
testSingMux(t, tunnel, out)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestInboundShadowSocks_Basic(t *testing.T) {
|
func TestInboundShadowSocks_Basic(t *testing.T) {
|
||||||
inboundOptions := inbound.ShadowSocksOption{}
|
inboundOptions := inbound.ShadowSocksOption{}
|
||||||
outboundOptions := outbound.ShadowSocksOption{}
|
outboundOptions := outbound.ShadowSocksOption{}
|
||||||
testInboundShadowSocks(t, inboundOptions, outboundOptions, shadowsocksCipherList)
|
testInboundShadowSocks(t, inboundOptions, outboundOptions, shadowsocksCipherLists)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testInboundShadowSocksShadowTls(t *testing.T, inboundOptions inbound.ShadowSocksOption, outboundOptions outbound.ShadowSocksOption) {
|
||||||
|
t.Parallel()
|
||||||
|
t.Run("Conn", func(t *testing.T) {
|
||||||
|
inboundOptions, outboundOptions := inboundOptions, outboundOptions // don't modify outside options value
|
||||||
|
testInboundShadowSocks(t, inboundOptions, outboundOptions, shadowsocksCipherShortLists)
|
||||||
|
})
|
||||||
|
t.Run("UConn", func(t *testing.T) {
|
||||||
|
inboundOptions, outboundOptions := inboundOptions, outboundOptions // don't modify outside options value
|
||||||
|
outboundOptions.ClientFingerprint = "chrome"
|
||||||
|
testInboundShadowSocks(t, inboundOptions, outboundOptions, shadowsocksCipherShortLists)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInboundShadowSocks_ShadowTlsv1(t *testing.T) {
|
func TestInboundShadowSocks_ShadowTlsv1(t *testing.T) {
|
||||||
@ -114,7 +128,7 @@ func TestInboundShadowSocks_ShadowTlsv1(t *testing.T) {
|
|||||||
Plugin: shadowtls.Mode,
|
Plugin: shadowtls.Mode,
|
||||||
PluginOpts: map[string]any{"host": realityDest, "fingerprint": tlsFingerprint, "version": 1},
|
PluginOpts: map[string]any{"host": realityDest, "fingerprint": tlsFingerprint, "version": 1},
|
||||||
}
|
}
|
||||||
testInboundShadowSocks(t, inboundOptions, outboundOptions, shadowsocksCipherListShort)
|
testInboundShadowSocksShadowTls(t, inboundOptions, outboundOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInboundShadowSocks_ShadowTlsv2(t *testing.T) {
|
func TestInboundShadowSocks_ShadowTlsv2(t *testing.T) {
|
||||||
@ -131,7 +145,7 @@ func TestInboundShadowSocks_ShadowTlsv2(t *testing.T) {
|
|||||||
PluginOpts: map[string]any{"host": realityDest, "password": shadowsocksPassword16, "fingerprint": tlsFingerprint, "version": 2},
|
PluginOpts: map[string]any{"host": realityDest, "password": shadowsocksPassword16, "fingerprint": tlsFingerprint, "version": 2},
|
||||||
}
|
}
|
||||||
outboundOptions.PluginOpts["alpn"] = []string{"http/1.1"} // shadowtls v2 work confuse with http/2 server, so we set alpn to http/1.1 to pass the test
|
outboundOptions.PluginOpts["alpn"] = []string{"http/1.1"} // shadowtls v2 work confuse with http/2 server, so we set alpn to http/1.1 to pass the test
|
||||||
testInboundShadowSocks(t, inboundOptions, outboundOptions, shadowsocksCipherListShort)
|
testInboundShadowSocksShadowTls(t, inboundOptions, outboundOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInboundShadowSocks_ShadowTlsv3(t *testing.T) {
|
func TestInboundShadowSocks_ShadowTlsv3(t *testing.T) {
|
||||||
@ -147,5 +161,5 @@ func TestInboundShadowSocks_ShadowTlsv3(t *testing.T) {
|
|||||||
Plugin: shadowtls.Mode,
|
Plugin: shadowtls.Mode,
|
||||||
PluginOpts: map[string]any{"host": realityDest, "password": shadowsocksPassword16, "fingerprint": tlsFingerprint, "version": 3},
|
PluginOpts: map[string]any{"host": realityDest, "password": shadowsocksPassword16, "fingerprint": tlsFingerprint, "version": 3},
|
||||||
}
|
}
|
||||||
testInboundShadowSocks(t, inboundOptions, outboundOptions, shadowsocksCipherListShort)
|
testInboundShadowSocksShadowTls(t, inboundOptions, outboundOptions)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import (
|
|||||||
|
|
||||||
"github.com/metacubex/sing-shadowtls"
|
"github.com/metacubex/sing-shadowtls"
|
||||||
utls "github.com/metacubex/utls"
|
utls "github.com/metacubex/utls"
|
||||||
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -19,6 +20,7 @@ const (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
DefaultALPN = []string{"h2", "http/1.1"}
|
DefaultALPN = []string{"h2", "http/1.1"}
|
||||||
|
WsALPN = []string{"http/1.1"}
|
||||||
)
|
)
|
||||||
|
|
||||||
type ShadowTLSOption struct {
|
type ShadowTLSOption struct {
|
||||||
@ -69,9 +71,18 @@ func uTLSHandshakeFunc(config *tls.Config, clientFingerprint string) shadowtls.T
|
|||||||
if tlsC.HaveGlobalFingerprint() && len(clientFingerprint) == 0 {
|
if tlsC.HaveGlobalFingerprint() && len(clientFingerprint) == 0 {
|
||||||
clientFingerprint = tlsC.GetGlobalFingerprint()
|
clientFingerprint = tlsC.GetGlobalFingerprint()
|
||||||
}
|
}
|
||||||
|
if config.MaxVersion == tls.VersionTLS12 { // for ShadowTLS v1
|
||||||
|
clientFingerprint = ""
|
||||||
|
}
|
||||||
if len(clientFingerprint) != 0 {
|
if len(clientFingerprint) != 0 {
|
||||||
if fingerprint, exists := tlsC.GetFingerprint(clientFingerprint); exists {
|
if fingerprint, exists := tlsC.GetFingerprint(clientFingerprint); exists {
|
||||||
tlsConn := tlsC.UClient(conn, tlsConfig, fingerprint)
|
tlsConn := tlsC.UClient(conn, tlsConfig, fingerprint)
|
||||||
|
if slices.Equal(tlsConfig.NextProtos, WsALPN) {
|
||||||
|
err := tlsC.BuildWebsocketHandshakeState(tlsConn)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
return tlsConn.HandshakeContext(ctx)
|
return tlsConn.HandshakeContext(ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user