-
Notifications
You must be signed in to change notification settings - Fork 36
/
Copy pathssr.go
125 lines (109 loc) · 3.29 KB
/
ssr.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package libcore
import (
"bytes"
"context"
"flag"
"strconv"
"github.com/Dreamacro/clash/transport/ssr/obfs"
"github.com/Dreamacro/clash/transport/ssr/protocol"
"github.com/v2fly/v2ray-core/v5/common/buf"
"github.com/v2fly/v2ray-core/v5/proxy/shadowsocks"
"github.com/v2fly/v2ray-core/v5/transport/internet"
)
var (
_ shadowsocks.SIP003Plugin = (*shadowsocksrPlugin)(nil)
_ shadowsocks.StreamPlugin = (*shadowsocksrPlugin)(nil)
_ shadowsocks.ProtocolPlugin = (*shadowsocksrPlugin)(nil)
)
func init() {
shadowsocks.RegisterPlugin("shadowsocksr", func() shadowsocks.SIP003Plugin {
return new(shadowsocksrPlugin)
})
}
type shadowsocksrPlugin struct {
host string
port int
obfs string
obfsParam string
protocol string
protocolParam string
o obfs.Obfs
p protocol.Protocol
}
func (p *shadowsocksrPlugin) Init(_ context.Context, _ string, _ string, remoteHost string, remotePort string, _ string, pluginArgs []string, account *shadowsocks.MemoryAccount) error {
fs := flag.NewFlagSet("shadowsocksr", flag.ContinueOnError)
fs.StringVar(&p.obfs, "obfs", "origin", "")
fs.StringVar(&p.obfsParam, "obfs-param", "", "")
fs.StringVar(&p.protocol, "protocol", "origin", "")
fs.StringVar(&p.protocolParam, "protocol-param", "", "")
if err := fs.Parse(pluginArgs); err != nil {
return newError("shadowsocksr: failed to parse args").Base(err)
}
p.host = remoteHost
p.port, _ = strconv.Atoi(remotePort)
obfs, obfsOverhead, err := obfs.PickObfs(p.obfs, &obfs.Base{
Host: p.host,
Port: p.port,
Key: account.Key,
IVSize: int(account.Cipher.IVSize()),
Param: p.obfsParam,
})
if err != nil {
return newError("failed to create ssr obfs").Base(err)
}
protocol, err := protocol.PickProtocol(p.protocol, &protocol.Base{
Key: account.Key,
Overhead: obfsOverhead,
Param: p.protocolParam,
})
if err != nil {
return newError("failed to create ssr protocol").Base(err)
}
p.o = obfs
p.p = protocol
return nil
}
func (p *shadowsocksrPlugin) Close() error {
return nil
}
func (p *shadowsocksrPlugin) StreamConn(conn internet.Connection) internet.Connection {
return p.o.StreamConn(conn)
}
func (p *shadowsocksrPlugin) ProtocolConn(conn *shadowsocks.ProtocolConn, iv []byte) {
upstream := buf.NewConnection(buf.ConnectionOutputMulti(conn), buf.ConnectionInputMulti(conn))
downstream := p.p.StreamConn(upstream, iv)
if upstream == downstream {
conn.ProtocolReader = conn
conn.ProtocolWriter = conn
} else {
conn.ProtocolReader = buf.NewReader(downstream)
conn.ProtocolWriter = buf.NewWriter(downstream)
}
}
func (p *shadowsocksrPlugin) EncodePacket(buffer *buf.Buffer, ivLen int32) (*buf.Buffer, error) {
defer buffer.Release()
packet := &bytes.Buffer{}
err := p.p.EncodePacket(packet, buffer.BytesFrom(ivLen))
if err != nil {
return nil, err
}
if ivLen > 0 {
newBuffer := buf.New()
newBuffer.Write(buffer.BytesTo(ivLen))
newBuffer.Write(packet.Bytes())
return newBuffer, nil
} else {
return buf.FromBytes(packet.Bytes()), nil
}
}
func (p *shadowsocksrPlugin) DecodePacket(buffer *buf.Buffer) (*buf.Buffer, error) {
defer buffer.Release()
packet, err := p.p.DecodePacket(buffer.Bytes())
if err != nil {
return nil, err
}
newBuffer := buf.New()
newBuffer.Write(packet)
newBuffer.Endpoint = buffer.Endpoint
return newBuffer, nil
}