Skip to content

Commit 63e66f4

Browse files
committed
chore: cleanup trojan code
1 parent bad61f9 commit 63e66f4

File tree

2 files changed

+56
-155
lines changed

2 files changed

+56
-155
lines changed

adapter/outbound/trojan.go

Lines changed: 52 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@ import (
1818
"github.com/metacubex/mihomo/transport/gun"
1919
"github.com/metacubex/mihomo/transport/shadowsocks/core"
2020
"github.com/metacubex/mihomo/transport/trojan"
21+
"github.com/metacubex/mihomo/transport/vmess"
2122
)
2223

2324
type Trojan struct {
2425
*Base
25-
instance *trojan.Trojan
26-
option *TrojanOption
26+
option *TrojanOption
27+
hexPassword [trojan.KeyLength]byte
2728

2829
// for gun mux
2930
gunTLSConfig *tls.Config
@@ -62,14 +63,20 @@ type TrojanSSOption struct {
6263
}
6364

6465
func (t *Trojan) plainStream(ctx context.Context, c net.Conn) (net.Conn, error) {
66+
var err error
67+
6568
if t.option.Network == "ws" {
6669
host, port, _ := net.SplitHostPort(t.addr)
67-
wsOpts := &trojan.WebsocketOption{
70+
71+
wsOpts := &vmess.WebsocketConfig{
6872
Host: host,
6973
Port: port,
7074
Path: t.option.WSOpts.Path,
75+
MaxEarlyData: t.option.WSOpts.MaxEarlyData,
76+
EarlyDataHeaderName: t.option.WSOpts.EarlyDataHeaderName,
7177
V2rayHttpUpgrade: t.option.WSOpts.V2rayHttpUpgrade,
7278
V2rayHttpUpgradeFastOpen: t.option.WSOpts.V2rayHttpUpgradeFastOpen,
79+
ClientFingerprint: t.option.ClientFingerprint,
7380
Headers: http.Header{},
7481
}
7582

@@ -83,10 +90,39 @@ func (t *Trojan) plainStream(ctx context.Context, c net.Conn) (net.Conn, error)
8390
}
8491
}
8592

86-
return t.instance.StreamWebsocketConn(ctx, c, wsOpts)
93+
alpn := trojan.DefaultWebsocketALPN
94+
if len(t.option.ALPN) != 0 {
95+
alpn = t.option.ALPN
96+
}
97+
98+
wsOpts.TLS = true
99+
tlsConfig := &tls.Config{
100+
NextProtos: alpn,
101+
MinVersion: tls.VersionTLS12,
102+
InsecureSkipVerify: t.option.SkipCertVerify,
103+
ServerName: t.option.SNI,
104+
}
105+
106+
wsOpts.TLSConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, t.option.Fingerprint)
107+
if err != nil {
108+
return nil, err
109+
}
110+
111+
return vmess.StreamWebsocketConn(ctx, c, wsOpts)
87112
}
88113

89-
return t.instance.StreamConn(ctx, c)
114+
alpn := trojan.DefaultALPN
115+
if len(t.option.ALPN) != 0 {
116+
alpn = t.option.ALPN
117+
}
118+
return vmess.StreamTLSConn(ctx, c, &vmess.TLSConfig{
119+
Host: t.option.SNI,
120+
SkipCertVerify: t.option.SkipCertVerify,
121+
FingerPrint: t.option.Fingerprint,
122+
ClientFingerprint: t.option.ClientFingerprint,
123+
NextProtos: alpn,
124+
Reality: t.realityConfig,
125+
})
90126
}
91127

92128
// StreamConnContext implements C.ProxyAdapter
@@ -124,7 +160,7 @@ func (t *Trojan) writeHeaderContext(ctx context.Context, c net.Conn, metadata *C
124160
if metadata.NetWork == C.UDP {
125161
command = trojan.CommandUDP
126162
}
127-
err = t.instance.WriteHeader(c, command, serializesSocksAddr(metadata))
163+
err = trojan.WriteHeader(c, t.hexPassword, command, serializesSocksAddr(metadata))
128164
return err
129165
}
130166

@@ -199,7 +235,7 @@ func (t *Trojan) ListenPacketContext(ctx context.Context, metadata *C.Metadata,
199235
return nil, err
200236
}
201237

202-
pc := t.instance.PacketConn(c)
238+
pc := trojan.NewPacketConn(c)
203239
return newPacketConn(pc, t), err
204240
}
205241
return t.ListenPacketWithDialer(ctx, dialer.NewDialer(t.Base.DialOptions(opts...)...), metadata)
@@ -234,7 +270,7 @@ func (t *Trojan) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, me
234270
return nil, err
235271
}
236272

237-
pc := t.instance.PacketConn(c)
273+
pc := trojan.NewPacketConn(c)
238274
return newPacketConn(pc, t), err
239275
}
240276

@@ -245,7 +281,7 @@ func (t *Trojan) SupportWithDialer() C.NetWork {
245281

246282
// ListenPacketOnStreamConn implements C.ProxyAdapter
247283
func (t *Trojan) ListenPacketOnStreamConn(c net.Conn, metadata *C.Metadata) (_ C.PacketConn, err error) {
248-
pc := t.instance.PacketConn(c)
284+
pc := trojan.NewPacketConn(c)
249285
return newPacketConn(pc, t), err
250286
}
251287

@@ -272,19 +308,6 @@ func (t *Trojan) Close() error {
272308
func NewTrojan(option TrojanOption) (*Trojan, error) {
273309
addr := net.JoinHostPort(option.Server, strconv.Itoa(option.Port))
274310

275-
tOption := &trojan.Option{
276-
Password: option.Password,
277-
ALPN: option.ALPN,
278-
ServerName: option.Server,
279-
SkipCertVerify: option.SkipCertVerify,
280-
Fingerprint: option.Fingerprint,
281-
ClientFingerprint: option.ClientFingerprint,
282-
}
283-
284-
if option.SNI != "" {
285-
tOption.ServerName = option.SNI
286-
}
287-
288311
t := &Trojan{
289312
Base: &Base{
290313
name: option.Name,
@@ -297,16 +320,15 @@ func NewTrojan(option TrojanOption) (*Trojan, error) {
297320
rmark: option.RoutingMark,
298321
prefer: C.NewDNSPrefer(option.IPVersion),
299322
},
300-
instance: trojan.New(tOption),
301-
option: &option,
323+
option: &option,
324+
hexPassword: trojan.Key(option.Password),
302325
}
303326

304327
var err error
305328
t.realityConfig, err = option.RealityOpts.Parse()
306329
if err != nil {
307330
return nil, err
308331
}
309-
tOption.Reality = t.realityConfig
310332

311333
if option.SSOpts.Enabled {
312334
if option.SSOpts.Password == "" {
@@ -342,8 +364,8 @@ func NewTrojan(option TrojanOption) (*Trojan, error) {
342364
tlsConfig := &tls.Config{
343365
NextProtos: option.ALPN,
344366
MinVersion: tls.VersionTLS12,
345-
InsecureSkipVerify: tOption.SkipCertVerify,
346-
ServerName: tOption.ServerName,
367+
InsecureSkipVerify: option.SkipCertVerify,
368+
ServerName: option.SNI,
347369
}
348370

349371
var err error
@@ -352,13 +374,13 @@ func NewTrojan(option TrojanOption) (*Trojan, error) {
352374
return nil, err
353375
}
354376

355-
t.transport = gun.NewHTTP2Client(dialFn, tlsConfig, tOption.ClientFingerprint, t.realityConfig)
377+
t.transport = gun.NewHTTP2Client(dialFn, tlsConfig, option.ClientFingerprint, t.realityConfig)
356378

357379
t.gunTLSConfig = tlsConfig
358380
t.gunConfig = &gun.Config{
359381
ServiceName: option.GrpcOpts.GrpcServiceName,
360-
Host: tOption.ServerName,
361-
ClientFingerprint: tOption.ClientFingerprint,
382+
Host: option.SNI,
383+
ClientFingerprint: option.ClientFingerprint,
362384
}
363385
}
364386

transport/trojan/trojan.go

Lines changed: 4 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,17 @@
11
package trojan
22

33
import (
4-
"context"
54
"crypto/sha256"
6-
"crypto/tls"
75
"encoding/binary"
86
"encoding/hex"
97
"errors"
108
"io"
119
"net"
12-
"net/http"
1310
"sync"
1411

1512
N "github.com/metacubex/mihomo/common/net"
1613
"github.com/metacubex/mihomo/common/pool"
17-
"github.com/metacubex/mihomo/component/ca"
18-
tlsC "github.com/metacubex/mihomo/component/tls"
19-
C "github.com/metacubex/mihomo/constant"
2014
"github.com/metacubex/mihomo/transport/socks5"
21-
"github.com/metacubex/mihomo/transport/vmess"
2215
)
2316

2417
const (
@@ -27,8 +20,8 @@ const (
2720
)
2821

2922
var (
30-
defaultALPN = []string{"h2", "http/1.1"}
31-
defaultWebsocketALPN = []string{"http/1.1"}
23+
DefaultALPN = []string{"h2", "http/1.1"}
24+
DefaultWebsocketALPN = []string{"http/1.1"}
3225

3326
crlf = []byte{'\r', '\n'}
3427
)
@@ -43,115 +36,11 @@ const (
4336
KeyLength = 56
4437
)
4538

46-
type Option struct {
47-
Password string
48-
ALPN []string
49-
ServerName string
50-
SkipCertVerify bool
51-
Fingerprint string
52-
ClientFingerprint string
53-
Reality *tlsC.RealityConfig
54-
}
55-
56-
type WebsocketOption struct {
57-
Host string
58-
Port string
59-
Path string
60-
Headers http.Header
61-
V2rayHttpUpgrade bool
62-
V2rayHttpUpgradeFastOpen bool
63-
}
64-
65-
type Trojan struct {
66-
option *Option
67-
hexPassword [KeyLength]byte
68-
}
69-
70-
func (t *Trojan) StreamConn(ctx context.Context, conn net.Conn) (net.Conn, error) {
71-
alpn := defaultALPN
72-
if len(t.option.ALPN) != 0 {
73-
alpn = t.option.ALPN
74-
}
75-
tlsConfig := &tls.Config{
76-
NextProtos: alpn,
77-
MinVersion: tls.VersionTLS12,
78-
InsecureSkipVerify: t.option.SkipCertVerify,
79-
ServerName: t.option.ServerName,
80-
}
81-
82-
var err error
83-
tlsConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, t.option.Fingerprint)
84-
if err != nil {
85-
return nil, err
86-
}
87-
88-
if len(t.option.ClientFingerprint) != 0 {
89-
if t.option.Reality == nil {
90-
utlsConn, valid := vmess.GetUTLSConn(conn, t.option.ClientFingerprint, tlsConfig)
91-
if valid {
92-
ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTLSTimeout)
93-
defer cancel()
94-
95-
err := utlsConn.HandshakeContext(ctx)
96-
return utlsConn, err
97-
}
98-
} else {
99-
ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTLSTimeout)
100-
defer cancel()
101-
return tlsC.GetRealityConn(ctx, conn, t.option.ClientFingerprint, tlsConfig, t.option.Reality)
102-
}
103-
}
104-
if t.option.Reality != nil {
105-
return nil, errors.New("REALITY is based on uTLS, please set a client-fingerprint")
106-
}
107-
108-
tlsConn := tls.Client(conn, tlsConfig)
109-
110-
// fix tls handshake not timeout
111-
ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTLSTimeout)
112-
defer cancel()
113-
114-
err = tlsConn.HandshakeContext(ctx)
115-
return tlsConn, err
116-
}
117-
118-
func (t *Trojan) StreamWebsocketConn(ctx context.Context, conn net.Conn, wsOptions *WebsocketOption) (net.Conn, error) {
119-
alpn := defaultWebsocketALPN
120-
if len(t.option.ALPN) != 0 {
121-
alpn = t.option.ALPN
122-
}
123-
124-
tlsConfig := &tls.Config{
125-
NextProtos: alpn,
126-
MinVersion: tls.VersionTLS12,
127-
InsecureSkipVerify: t.option.SkipCertVerify,
128-
ServerName: t.option.ServerName,
129-
}
130-
131-
var err error
132-
tlsConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, t.option.Fingerprint)
133-
if err != nil {
134-
return nil, err
135-
}
136-
137-
return vmess.StreamWebsocketConn(ctx, conn, &vmess.WebsocketConfig{
138-
Host: wsOptions.Host,
139-
Port: wsOptions.Port,
140-
Path: wsOptions.Path,
141-
Headers: wsOptions.Headers,
142-
V2rayHttpUpgrade: wsOptions.V2rayHttpUpgrade,
143-
V2rayHttpUpgradeFastOpen: wsOptions.V2rayHttpUpgradeFastOpen,
144-
TLS: true,
145-
TLSConfig: tlsConfig,
146-
ClientFingerprint: t.option.ClientFingerprint,
147-
})
148-
}
149-
150-
func (t *Trojan) WriteHeader(w io.Writer, command Command, socks5Addr []byte) error {
39+
func WriteHeader(w io.Writer, hexPassword [KeyLength]byte, command Command, socks5Addr []byte) error {
15140
buf := pool.GetBuffer()
15241
defer pool.PutBuffer(buf)
15342

154-
buf.Write(t.hexPassword[:])
43+
buf.Write(hexPassword[:])
15544
buf.Write(crlf)
15645

15746
buf.WriteByte(command)
@@ -162,12 +51,6 @@ func (t *Trojan) WriteHeader(w io.Writer, command Command, socks5Addr []byte) er
16251
return err
16352
}
16453

165-
func (t *Trojan) PacketConn(conn net.Conn) net.PacketConn {
166-
return &PacketConn{
167-
Conn: conn,
168-
}
169-
}
170-
17154
func writePacket(w io.Writer, socks5Addr, payload []byte) (int, error) {
17255
buf := pool.GetBuffer()
17356
defer pool.PutBuffer(buf)
@@ -243,10 +126,6 @@ func ReadPacket(r io.Reader, payload []byte) (net.Addr, int, int, error) {
243126
return uAddr, length, total - length, nil
244127
}
245128

246-
func New(option *Option) *Trojan {
247-
return &Trojan{option, Key(option.Password)}
248-
}
249-
250129
var _ N.EnhancePacketConn = (*PacketConn)(nil)
251130

252131
type PacketConn struct {

0 commit comments

Comments
 (0)