Add shadowsocks uot and test
This commit is contained in:
parent
5af17f70b4
commit
a562b249a2
3 changed files with 76 additions and 0 deletions
|
@ -19,6 +19,7 @@ import (
|
|||
"github.com/sagernet/sing/common/buf"
|
||||
"github.com/sagernet/sing/common/bufio"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
"github.com/sagernet/sing/common/uot"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -29,6 +30,7 @@ type ShadowSocks struct {
|
|||
*Base
|
||||
method shadowsocks.Method
|
||||
|
||||
option *ShadowSocksOption
|
||||
// obfs
|
||||
obfsMode string
|
||||
obfsOption *simpleObfsOption
|
||||
|
@ -45,6 +47,7 @@ type ShadowSocksOption struct {
|
|||
UDP bool `proxy:"udp,omitempty"`
|
||||
Plugin string `proxy:"plugin,omitempty"`
|
||||
PluginOpts map[string]any `proxy:"plugin-opts,omitempty"`
|
||||
UDPOverTCP bool `proxy:"udp-over-tcp,omitempty"`
|
||||
}
|
||||
|
||||
type simpleObfsOption struct {
|
||||
|
@ -96,6 +99,15 @@ func (ss *ShadowSocks) DialContext(ctx context.Context, metadata *C.Metadata, op
|
|||
|
||||
// ListenPacketContext implements C.ProxyAdapter
|
||||
func (ss *ShadowSocks) ListenPacketContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.PacketConn, error) {
|
||||
if ss.option.UDPOverTCP {
|
||||
metadata.Host = uot.UOTMagicAddress
|
||||
metadata.DstPort = "443"
|
||||
tcpConn, err := ss.DialContext(ctx, metadata, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newPacketConn(uot.NewClientConn(tcpConn), ss), nil
|
||||
}
|
||||
pc, err := dialer.ListenPacket(ctx, "udp", "", ss.Base.DialOptions(opts...)...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -167,6 +179,7 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) {
|
|||
},
|
||||
method: method,
|
||||
|
||||
option: &option,
|
||||
obfsMode: obfsMode,
|
||||
v2rayOption: v2rayOption,
|
||||
obfsOption: obfsOption,
|
||||
|
|
27
test/config/xray-shadowsocks.json
Normal file
27
test/config/xray-shadowsocks.json
Normal file
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"inbounds": [
|
||||
{
|
||||
"port": 10002,
|
||||
"listen": "0.0.0.0",
|
||||
"protocol": "shadowsocks",
|
||||
"settings": {
|
||||
"network": "tcp,udp",
|
||||
"clients": [
|
||||
{
|
||||
"method": "aes-128-gcm",
|
||||
"level": 0,
|
||||
"password": "FzcLbKs2dY9mhL"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"outbounds": [
|
||||
{
|
||||
"protocol": "freedom"
|
||||
}
|
||||
],
|
||||
"log": {
|
||||
"loglevel": "debug"
|
||||
}
|
||||
}
|
|
@ -3,11 +3,13 @@ package main
|
|||
import (
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/Dreamacro/clash/adapter/outbound"
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
@ -277,3 +279,37 @@ func Benchmark_Shadowsocks(b *testing.B) {
|
|||
require.True(b, TCPing(net.JoinHostPort(localIP.String(), "10002")))
|
||||
benchmarkProxy(b, proxy)
|
||||
}
|
||||
|
||||
func TestClash_ShadowsocksUoT(t *testing.T) {
|
||||
configPath := C.Path.Resolve("xray-shadowsocks.json")
|
||||
|
||||
cfg := &container.Config{
|
||||
Image: ImageVless,
|
||||
ExposedPorts: defaultExposedPorts,
|
||||
}
|
||||
hostCfg := &container.HostConfig{
|
||||
PortBindings: defaultPortBindings,
|
||||
Binds: []string{fmt.Sprintf("%s:/etc/xray/config.json", configPath)},
|
||||
}
|
||||
|
||||
id, err := startContainer(cfg, hostCfg, "xray-ss")
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
cleanContainer(id)
|
||||
})
|
||||
|
||||
proxy, err := outbound.NewShadowSocks(outbound.ShadowSocksOption{
|
||||
Name: "ss",
|
||||
Server: localIP.String(),
|
||||
Port: 10002,
|
||||
Password: "FzcLbKs2dY9mhL",
|
||||
Cipher: "aes-128-gcm",
|
||||
UDP: true,
|
||||
UDPOverTCP: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
time.Sleep(waitTime)
|
||||
testSuit(t, proxy)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue