mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-09-15 21:00:27 +00:00
201 lines
5.0 KiB
Go
201 lines
5.0 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"net/netip"
|
|
"testing"
|
|
|
|
C "github.com/sagernet/sing-box/constant"
|
|
"github.com/sagernet/sing-box/option"
|
|
"github.com/sagernet/sing/common"
|
|
"github.com/sagernet/sing/common/json/badoption"
|
|
N "github.com/sagernet/sing/common/network"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func findFreePort(t *testing.T) uint16 {
|
|
t.Helper()
|
|
l, err := net.ListenTCP("tcp", &net.TCPAddr{IP: net.IPv4(127, 0, 0, 1)})
|
|
require.NoError(t, err)
|
|
port := uint16(l.Addr().(*net.TCPAddr).Port)
|
|
l.Close()
|
|
return port
|
|
}
|
|
|
|
// TestTrustTunnel runs e2e tests with combinations of:
|
|
// - Transport: H2, QUIC
|
|
// - Congestion controllers (QUIC only): bbr, cubic, reno
|
|
// - Multiplex: enabled/disabled
|
|
// - Network: tcp-only, tcp+udp
|
|
func TestTrustTunnel(t *testing.T) {
|
|
type combo struct {
|
|
name string
|
|
quic bool
|
|
congestionController string
|
|
multiplex bool
|
|
network option.NetworkList
|
|
testUDP bool
|
|
}
|
|
|
|
var combos []combo
|
|
|
|
// H2 transport combos
|
|
for _, mux := range []bool{false, true} {
|
|
for _, net := range []struct {
|
|
name string
|
|
list option.NetworkList
|
|
testUDP bool
|
|
}{
|
|
{"tcp", option.NetworkList(N.NetworkTCP), false},
|
|
{"tcp+udp", option.NetworkList(N.NetworkTCP + "\n" + N.NetworkUDP), true},
|
|
} {
|
|
name := fmt.Sprintf("h2/mux=%v/%s", mux, net.name)
|
|
combos = append(combos, combo{
|
|
name: name,
|
|
quic: false,
|
|
multiplex: mux,
|
|
network: net.list,
|
|
testUDP: net.testUDP,
|
|
})
|
|
}
|
|
}
|
|
|
|
// QUIC transport combos (requires UDP in network for HTTP/3 listener)
|
|
congestionControllers := []string{"bbr", "cubic", "reno"}
|
|
for _, cc := range congestionControllers {
|
|
for _, mux := range []bool{false, true} {
|
|
name := fmt.Sprintf("quic/%s/mux=%v", cc, mux)
|
|
combos = append(combos, combo{
|
|
name: name,
|
|
quic: true,
|
|
congestionController: cc,
|
|
multiplex: mux,
|
|
network: option.NetworkList(N.NetworkTCP + "\n" + N.NetworkUDP),
|
|
testUDP: true,
|
|
})
|
|
}
|
|
}
|
|
|
|
for _, c := range combos {
|
|
c := c
|
|
t.Run(c.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
testTrustTunnelCombo(t, c.quic, c.congestionController, c.multiplex, c.network, c.testUDP)
|
|
})
|
|
}
|
|
}
|
|
|
|
func testTrustTunnelCombo(t *testing.T, useQUIC bool, cc string, multiplex bool, network option.NetworkList, testUDP bool) {
|
|
t.Helper()
|
|
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
|
|
|
srvPort := findFreePort(t)
|
|
cliPort := findFreePort(t)
|
|
tstPort := findFreePort(t)
|
|
|
|
var muxOpts *option.TrustTunnelMultiplexOptions
|
|
if multiplex {
|
|
muxOpts = &option.TrustTunnelMultiplexOptions{
|
|
Enabled: true,
|
|
MaxConnections: 4,
|
|
MinStreams: 2,
|
|
}
|
|
}
|
|
|
|
startInstance(t, option.Options{
|
|
Inbounds: []option.Inbound{
|
|
{
|
|
Type: C.TypeMixed,
|
|
Tag: "mixed-in",
|
|
Options: &option.HTTPMixedInboundOptions{
|
|
ListenOptions: option.ListenOptions{
|
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
|
ListenPort: cliPort,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Type: C.TypeTrustTunnel,
|
|
Tag: "tt-in",
|
|
Options: &option.TrustTunnelInboundOptions{
|
|
ListenOptions: option.ListenOptions{
|
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
|
ListenPort: srvPort,
|
|
},
|
|
Users: []option.TrustTunnelUser{{
|
|
Name: "testuser",
|
|
Password: "testpass",
|
|
}},
|
|
Network: network,
|
|
CongestionController: cc,
|
|
CWND: 32,
|
|
InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{
|
|
TLS: &option.InboundTLSOptions{
|
|
Enabled: true,
|
|
ServerName: "example.org",
|
|
ALPN: badoption.Listable[string]{"h2", "h3"},
|
|
CertificatePath: certPem,
|
|
KeyPath: keyPem,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Outbounds: []option.Outbound{
|
|
{
|
|
Type: C.TypeDirect,
|
|
},
|
|
{
|
|
Type: C.TypeTrustTunnel,
|
|
Tag: "tt-out",
|
|
Options: &option.TrustTunnelOutboundOptions{
|
|
ServerOptions: option.ServerOptions{
|
|
Server: "127.0.0.1",
|
|
ServerPort: srvPort,
|
|
},
|
|
Username: "testuser",
|
|
Password: "testpass",
|
|
Network: network,
|
|
QUIC: useQUIC,
|
|
CongestionController: cc,
|
|
CWND: 32,
|
|
Multiplex: muxOpts,
|
|
OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
|
|
TLS: &option.OutboundTLSOptions{
|
|
Enabled: true,
|
|
ServerName: "example.org",
|
|
Insecure: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Route: &option.RouteOptions{
|
|
Rules: []option.Rule{
|
|
{
|
|
Type: C.RuleTypeDefault,
|
|
DefaultOptions: option.DefaultRule{
|
|
RawDefaultRule: option.RawDefaultRule{
|
|
Inbound: []string{"mixed-in"},
|
|
},
|
|
RuleAction: option.RuleAction{
|
|
Action: C.RuleActionTypeRoute,
|
|
RouteOptions: option.RouteActionOptions{
|
|
Outbound: "tt-out",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
if testUDP {
|
|
testSuit(t, cliPort, tstPort)
|
|
} else {
|
|
testTCP(t, cliPort, tstPort)
|
|
}
|
|
}
|