Skip to content

Commit

Permalink
feat: add ss-opts for trojan outbound like trojan-go's `shadowsocks…
Browse files Browse the repository at this point in the history
…` config

MetaCubeX#1269
  • Loading branch information
wwqgtxx committed May 22, 2024
1 parent 71922dd commit 0b6ae6f
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 0 deletions.
43 changes: 43 additions & 0 deletions adapter/outbound/trojan.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package outbound
import (
"context"
"crypto/tls"
"errors"
"fmt"
"net"
"net/http"
Expand All @@ -15,6 +16,7 @@ import (
tlsC "github.com/metacubex/mihomo/component/tls"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/transport/gun"
"github.com/metacubex/mihomo/transport/shadowsocks/core"
"github.com/metacubex/mihomo/transport/trojan"
)

Expand All @@ -29,6 +31,8 @@ type Trojan struct {
transport *gun.TransportWrap

realityConfig *tlsC.RealityConfig

ssCipher core.Cipher
}

type TrojanOption struct {
Expand All @@ -46,9 +50,17 @@ type TrojanOption struct {
RealityOpts RealityOptions `proxy:"reality-opts,omitempty"`
GrpcOpts GrpcOptions `proxy:"grpc-opts,omitempty"`
WSOpts WSOptions `proxy:"ws-opts,omitempty"`
SSOpts TrojanSSOption `proxy:"ss-opts,omitempty"`
ClientFingerprint string `proxy:"client-fingerprint,omitempty"`
}

// TrojanSSOption from https://github.com/p4gefau1t/trojan-go/blob/v0.10.6/tunnel/shadowsocks/config.go#L5
type TrojanSSOption struct {
Enabled bool `proxy:"enabled,omitempty"`
Method string `proxy:"method,omitempty"`
Password string `proxy:"password,omitempty"`
}

func (t *Trojan) plainStream(ctx context.Context, c net.Conn) (net.Conn, error) {
if t.option.Network == "ws" {
host, port, _ := net.SplitHostPort(t.addr)
Expand Down Expand Up @@ -95,6 +107,10 @@ func (t *Trojan) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.
return nil, fmt.Errorf("%s connect error: %w", t.addr, err)
}

if t.ssCipher != nil {
c = t.ssCipher.StreamConn(c)
}

if metadata.NetWork == C.UDP {
err = t.instance.WriteHeader(c, trojan.CommandUDP, serializesSocksAddr(metadata))
return c, err
Expand All @@ -112,6 +128,10 @@ func (t *Trojan) DialContext(ctx context.Context, metadata *C.Metadata, opts ...
return nil, err
}

if t.ssCipher != nil {
c = t.ssCipher.StreamConn(c)
}

if err = t.instance.WriteHeader(c, trojan.CommandTCP, serializesSocksAddr(metadata)); err != nil {
c.Close()
return nil, err
Expand Down Expand Up @@ -161,6 +181,11 @@ func (t *Trojan) ListenPacketContext(ctx context.Context, metadata *C.Metadata,
defer func(c net.Conn) {
safeConnClose(c, err)
}(c)

if t.ssCipher != nil {
c = t.ssCipher.StreamConn(c)
}

err = t.instance.WriteHeader(c, trojan.CommandUDP, serializesSocksAddr(metadata))
if err != nil {
return nil, err
Expand Down Expand Up @@ -193,6 +218,10 @@ func (t *Trojan) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, me
return nil, fmt.Errorf("%s connect error: %w", t.addr, err)
}

if t.ssCipher != nil {
c = t.ssCipher.StreamConn(c)
}

err = t.instance.WriteHeader(c, trojan.CommandUDP, serializesSocksAddr(metadata))
if err != nil {
return nil, err
Expand Down Expand Up @@ -257,6 +286,20 @@ func NewTrojan(option TrojanOption) (*Trojan, error) {
}
tOption.Reality = t.realityConfig

if option.SSOpts.Enabled {
if option.SSOpts.Password == "" {
return nil, errors.New("empty password")
}
if option.SSOpts.Method == "" {
option.SSOpts.Method = "AES-128-GCM"
}
ciph, err := core.PickCipher(option.SSOpts.Method, nil, option.SSOpts.Password)
if err != nil {
return nil, err
}
t.ssCipher = ciph
}

if option.Network == "grpc" {
dialFn := func(network, addr string) (net.Conn, error) {
var err error
Expand Down
4 changes: 4 additions & 0 deletions docs/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,10 @@ proxies: # socks5
# - h2
# - http/1.1
# skip-cert-verify: true
# ss-opts: # like trojan-go's `shadowsocks` config
# enabled: false
# method: aes-128-gcm # aes-128-gcm/aes-256-gcm/chacha20-ietf-poly1305
# password: "example"

- name: trojan-grpc
server: server
Expand Down

0 comments on commit 0b6ae6f

Please sign in to comment.