add shadowsocks aead

This commit is contained in:
Page Fault
2020-06-10 12:38:15 +00:00
parent 38b30b00f5
commit e81826c12f
24 changed files with 397 additions and 85 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ import (
)
const (
Version = "v0.6.1"
Version = "v0.7.0"
)
type Runnable interface {
+1 -1
View File
@@ -16,7 +16,7 @@ enableMissingTranslationPlaceholders = false
# Source Code repository section
description = "An unidentifiable mechanism that helps you bypass GFW. "
github_repository = "https://github.com/p4gefau1t/trojan-go"
version = "0.6.1"
version = "0.7.0"
# Documentation repository section
# documentation repository (set edit link to documentation repository)
+1
View File
@@ -8,6 +8,7 @@ require (
github.com/golang/protobuf v1.3.2
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/refraction-networking/utls v0.0.0-20200601200209-ada0bb9b38a0
github.com/shadowsocks/go-shadowsocks2 v0.1.0
github.com/smartystreets/goconvey v1.6.4
github.com/xtaci/smux v1.5.15-0.20200523091831-637399ad4398
golang.org/x/crypto v0.0.0-20200602180216-279210d13fed
+13
View File
@@ -2,14 +2,19 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/LiamHaworth/go-tproxy v0.0.0-20190726054950-ef7efd7f24ed h1:eqa6queieK8SvoszxCu0WwH7lSVeL4/N/f1JwOMw1G4=
github.com/LiamHaworth/go-tproxy v0.0.0-20190726054950-ef7efd7f24ed/go.mod h1:rA52xkgZwql9LRZXWb2arHEFP6qSR48KY2xOfWzEciQ=
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY=
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
@@ -20,12 +25,15 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/miekg/dns v1.1.4 h1:rCMZsU2ScVSYcAsOXgmC6+AKOK+6pmQTOcw03nfwYV0=
github.com/miekg/dns v1.1.4/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/refraction-networking/utls v0.0.0-20190909200633-43c36d3c1f57/go.mod h1:tz9gX959MEFfFN5whTIocCLUG57WiILqtdVxI8c6Wj0=
github.com/refraction-networking/utls v0.0.0-20200601200209-ada0bb9b38a0 h1:vIkvetWOJZSADSKCF9MLTsQNW2httdBmYz47dQQteP8=
github.com/refraction-networking/utls v0.0.0-20200601200209-ada0bb9b38a0/go.mod h1:tz9gX959MEFfFN5whTIocCLUG57WiILqtdVxI8c6Wj0=
github.com/shadowsocks/go-shadowsocks2 v0.1.0 h1:jQhkjAmMuOTQ7B04bnrRJ5IAoZEwoaXXkKspE7rQ6ck=
github.com/shadowsocks/go-shadowsocks2 v0.1.0/go.mod h1:/0aFGbhK8mtOX4J/6kTJsPLZlEs9KnzKoWCOCvjd7vk=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
@@ -37,6 +45,7 @@ github.com/xtaci/smux v1.5.15-0.20200523091831-637399ad4398/go.mod h1:OMlQbT5vcg
go.starlark.net v0.0.0-20190919145610-979af19b165c h1:WR7X1xgXJlXhQBdorVc9Db3RhwG+J/kp6bLuMyJjfVw=
go.starlark.net v0.0.0-20190919145610-979af19b165c/go.mod h1:c1/X6cHgvdXj6pUlmWKMkuqRnW4K8x2vwt6JAaaircg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200602180216-279210d13fed h1:g4KENRiCMEx58Q7/ecwfT0N2o8z35Fnbsjig/Alf2T4=
golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -45,11 +54,13 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 h1:OjiUf46hAmXblsZdnoSXsEUSKU8r1UEzcL5RVZ4gO9Y=
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 h1:NusfzzA6yGQ+ua51ck7E3omNUX/JuqbFSaRGqU8CcLI=
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -58,7 +69,9 @@ golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b h1:lohp5blsw53GBXtLyLNaTXPXS9pJ1tiTw61ZHUoE9Qw=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/grpc v1.24.0 h1:vb/1TCsVn3DcJlQ0Gs1yB1pKI6Do2/QNwxdKqmc/b0s=
google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
+9 -5
View File
@@ -7,6 +7,7 @@ import (
"github.com/p4gefau1t/trojan-go/tunnel"
"github.com/p4gefau1t/trojan-go/tunnel/mux"
"github.com/p4gefau1t/trojan-go/tunnel/router"
"github.com/p4gefau1t/trojan-go/tunnel/shadowsocks"
"github.com/p4gefau1t/trojan-go/tunnel/simplesocks"
"github.com/p4gefau1t/trojan-go/tunnel/socks"
"github.com/p4gefau1t/trojan-go/tunnel/transport"
@@ -17,16 +18,19 @@ import (
const Name = "CLIENT"
// GenerateClientTree generate general outbound protocol stack
func GenerateClientTree(isMux bool, isWebsocket bool, isRouter bool) []string {
func GenerateClientTree(muxEnabled bool, wsEnabled bool, ssEnabled bool, routerEnabled bool) []string {
clientStack := []string{transport.Name}
if isWebsocket {
if wsEnabled {
clientStack = append(clientStack, websocket.Name)
}
if ssEnabled {
clientStack = append(clientStack, shadowsocks.Name)
}
clientStack = append(clientStack, trojan.Name)
if isMux {
if muxEnabled {
clientStack = append(clientStack, []string{mux.Name, simplesocks.Name}...)
}
if isRouter {
if routerEnabled {
clientStack = append(clientStack, router.Name)
}
return clientStack
@@ -36,7 +40,7 @@ func init() {
proxy.RegisterProxyCreator(Name, func(ctx context.Context) (*proxy.Proxy, error) {
cfg := config.FromContext(ctx, Name).(*Config)
serverStack := []string{socks.Name}
clientStack := GenerateClientTree(cfg.Mux.Enabled, cfg.Websocket.Enabled, cfg.Router.Enabled)
clientStack := GenerateClientTree(cfg.Mux.Enabled, cfg.Websocket.Enabled, cfg.Shadowsocks.Enabled, cfg.Router.Enabled)
c, err := proxy.CreateClientStack(ctx, clientStack)
if err != nil {
return nil, err
+8 -3
View File
@@ -14,10 +14,15 @@ type RouterConfig struct {
Enabled bool `json,yaml:"enabled"`
}
type ShadowsocksConfig struct {
Enabled bool `json,yaml:"enabled"`
}
type Config struct {
Mux MuxConfig `json,yaml:"mux"`
Websocket WebsocketConfig `json,yaml:"websocket"`
Router RouterConfig `json,yaml:"router"`
Mux MuxConfig `json,yaml:"mux"`
Websocket WebsocketConfig `json,yaml:"websocket"`
Router RouterConfig `json,yaml:"router"`
Shadowsocks ShadowsocksConfig `json,yaml:"shadowsocks"`
}
func init() {
+1 -1
View File
@@ -15,7 +15,7 @@ func init() {
proxy.RegisterProxyCreator(Name, func(ctx context.Context) (*proxy.Proxy, error) {
cfg := config.FromContext(ctx, Name).(*client.Config)
serverStack := []string{dokodemo.Name}
clientStack := client.GenerateClientTree(cfg.Mux.Enabled, cfg.Websocket.Enabled, cfg.Router.Enabled)
clientStack := client.GenerateClientTree(cfg.Mux.Enabled, cfg.Websocket.Enabled, cfg.Shadowsocks.Enabled, cfg.Router.Enabled)
c, err := proxy.CreateClientStack(ctx, clientStack)
if err != nil {
return nil, err
+3 -1
View File
@@ -1,3 +1,5 @@
// +build linux darwin
package nat
import (
@@ -15,7 +17,7 @@ func init() {
proxy.RegisterProxyCreator(Name, func(ctx context.Context) (*proxy.Proxy, error) {
cfg := config.FromContext(ctx, Name).(*client.Config)
serverStack := []string{tproxy.Name}
clientStack := client.GenerateClientTree(cfg.Mux.Enabled, cfg.Websocket.Enabled, false)
clientStack := client.GenerateClientTree(cfg.Mux.Enabled, cfg.Websocket.Enabled, cfg.Shadowsocks.Enabled, false)
c, err := proxy.CreateClientStack(ctx, clientStack)
if err != nil {
return nil, err
+12 -7
View File
@@ -21,16 +21,21 @@ func (o *Option) Handle() error {
if err != nil {
log.Fatal(err)
}
isJSON := false
if strings.HasSuffix(*o.path, ".json") {
if err := RunProxy(data, true); err != nil {
log.Fatal(err)
}
isJSON = true
} else if strings.HasSuffix(*o.path, ".yaml") {
if err := RunProxy(data, false); err != nil {
log.Fatal(err)
}
isJSON = false
} else {
log.Fatal("unknown file suffix", *o.path)
log.Fatal("unsupported filename suffix", *o.path, ". use .yaml or .json instead.")
}
proxy, err := NewProxyFromConfigData(data, isJSON)
if err != nil {
log.Fatal(err)
}
err = proxy.Run()
if err != nil {
log.Fatal(err)
}
return nil
}
+5 -12
View File
@@ -154,31 +154,24 @@ func RegisterProxyCreator(name string, creator Creator) {
creators[name] = creator
}
func RunProxy(data []byte, isJSON bool) error {
func NewProxyFromConfigData(data []byte, isJSON bool) (*Proxy, error) {
ctx := context.Background()
var err error
if isJSON {
ctx, err = config.WithJSONConfig(context.Background(), data)
if err != nil {
return err
return nil, err
}
} else {
ctx, err = config.WithYAMLConfig(context.Background(), data)
if err != nil {
return err
return nil, err
}
}
cfg := config.FromContext(ctx, Name).(*Config)
create, ok := creators[strings.ToUpper(cfg.RunType)]
if !ok {
return common.NewError("unknown type " + cfg.RunType)
return nil, common.NewError("unknown proxy type: " + cfg.RunType)
}
proxy, err := create(ctx)
if err != nil {
return common.NewError("failed to create proxy instance").Base(err)
}
if err := proxy.Run(); err != nil {
log.Fatal(err)
}
return nil
return create(ctx)
}
+12
View File
@@ -0,0 +1,12 @@
package server
import (
"github.com/p4gefau1t/trojan-go/config"
"github.com/p4gefau1t/trojan-go/proxy/client"
)
func init() {
config.RegisterConfigCreator(Name, func() interface{} {
return new(client.Config)
})
}
+29 -41
View File
@@ -2,9 +2,12 @@ package server
import (
"context"
"github.com/p4gefau1t/trojan-go/config"
"github.com/p4gefau1t/trojan-go/proxy"
"github.com/p4gefau1t/trojan-go/proxy/client"
"github.com/p4gefau1t/trojan-go/tunnel/mux"
"github.com/p4gefau1t/trojan-go/tunnel/raw"
"github.com/p4gefau1t/trojan-go/tunnel/shadowsocks"
"github.com/p4gefau1t/trojan-go/tunnel/simplesocks"
"github.com/p4gefau1t/trojan-go/tunnel/transport"
"github.com/p4gefau1t/trojan-go/tunnel/trojan"
@@ -16,53 +19,38 @@ const Name = "SERVER"
func init() {
proxy.RegisterProxyCreator(Name, func(ctx context.Context) (*proxy.Proxy, error) {
clientStack := []string{raw.Name}
serverTree := &proxy.Node{
Name: transport.Name,
Next: []*proxy.Node{
{
Name: trojan.Name,
IsEndpoint: true,
Next: []*proxy.Node{
{
Name: mux.Name,
Next: []*proxy.Node{
{
Name: simplesocks.Name,
},
},
},
},
},
{
Name: websocket.Name,
Next: []*proxy.Node{
{
Name: trojan.Name,
IsEndpoint: true,
Next: []*proxy.Node{
{
Name: mux.Name,
Next: []*proxy.Node{
{
Name: simplesocks.Name,
},
},
},
},
},
},
},
},
}
c, err := proxy.CreateClientStack(ctx, clientStack)
cfg := config.FromContext(ctx, Name).(*client.Config)
s, err := transport.NewServer(ctx, nil)
if err != nil {
return nil, err
}
s, err := proxy.CreateServersStacksTree(ctx, serverTree)
root := &proxy.Node{
Name: transport.Name,
Next: make(map[string]*proxy.Node),
IsEndpoint: false,
Context: ctx,
Server: s,
}
root.BuildNext(trojan.Name).BuildNext(mux.Name).BuildNext(simplesocks.Name).IsEndpoint = true
root.BuildNext(trojan.Name).IsEndpoint = true
wsSubTree := root.BuildNext(websocket.Name)
if cfg.Shadowsocks.Enabled {
wsSubTree = wsSubTree.BuildNext(shadowsocks.Name)
}
wsSubTree.BuildNext(trojan.Name).BuildNext(mux.Name).BuildNext(simplesocks.Name).IsEndpoint = true
wsSubTree.BuildNext(trojan.Name).IsEndpoint = true
serverList := proxy.FindAllEndpoints(root)
clientList, err := proxy.CreateClientStack(ctx, clientStack)
if err != nil {
return nil, err
}
return proxy.NewProxy(ctx, s, c), nil
if err != nil {
return nil, err
}
return proxy.NewProxy(ctx, serverList, clientList), nil
})
}
+33 -1
View File
@@ -2,16 +2,48 @@ package proxy
import (
"context"
"github.com/p4gefau1t/trojan-go/log"
"github.com/p4gefau1t/trojan-go/tunnel"
)
type Node struct {
Name string
Next []*Node
Next map[string]*Node
IsEndpoint bool
context.Context
tunnel.Server
}
func (n *Node) BuildNext(name string) *Node {
if next, found := n.Next[name]; found {
return next
}
t, err := tunnel.GetTunnel(name)
if err != nil {
log.Fatal(err)
}
s, err := t.NewServer(n.Context, n.Server)
newNode := &Node{
Name: name,
Next: make(map[string]*Node),
Context: n.Context,
Server: s,
}
n.Next[name] = newNode
return newNode
}
func FindAllEndpoints(root *Node) []tunnel.Server {
list := make([]tunnel.Server, 0)
if root.IsEndpoint || len(root.Next) == 0 {
list = append(list, root.Server)
}
for _, next := range root.Next {
list = append(list, FindAllEndpoints(next)...)
}
return list
}
func buildServerStacksTree(ctx context.Context, current *Node, parent *Node) ([]tunnel.Server, error) {
t, err := tunnel.GetTunnel(current.Name)
if err != nil {
+27 -7
View File
@@ -20,7 +20,7 @@ import (
netproxy "golang.org/x/net/proxy"
)
var cert string = `
var cert = `
-----BEGIN CERTIFICATE-----
MIIDZTCCAk0CFFphZh018B5iAD9F5fV4y0AlD0LxMA0GCSqGSIb3DQEBCwUAMG8x
CzAJBgNVBAYTAlVTMQ0wCwYDVQQIDARNYXJzMRMwEQYDVQQHDAppVHJhbnN3YXJw
@@ -44,7 +44,7 @@ Haz8uKI4EciU
-----END CERTIFICATE-----
`
var key string = `
var key = `
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAml44fThYMkCcT627o7ibEs7mq2WOhImjDwYijYJ1684BatrC
sHJNcw8PJGTuP+tgGdngmALjA3l+RipjaE/UK4FJrAjruphA/hOCjZfWqk8KBR4q
@@ -98,12 +98,17 @@ websocket:
enabled: true
path: /ws
hostname: 127.0.0.1
shadowsocks:
enabled: true
method: AEAD_CHACHA20_POLY1305
password: 12345678
mux:
enabled: true
`, socksPort, serverPort)
go func() {
err := proxy.RunProxy([]byte(clientData), false)
proxy, err := proxy.NewProxyFromConfigData([]byte(clientData), false)
common.Must(err)
common.Must(proxy.Run())
}()
serverData := fmt.Sprintf(`
@@ -118,15 +123,20 @@ ssl:
verify-hostname: false
key: server.key
cert: server.crt
sni: "localhost"
sni: localhost
shadowsocks:
enabled: true
method: AEAD_CHACHA20_POLY1305
password: 12345678
websocket:
enabled: true
path: /ws
hostname: 127.0.0.1
`, serverPort, util.HTTPPort)
go func() {
err := proxy.RunProxy([]byte(serverData), false)
proxy, err := proxy.NewProxyFromConfigData([]byte(serverData), false)
common.Must(err)
common.Must(proxy.Run())
}()
time.Sleep(time.Second * 2)
@@ -168,12 +178,17 @@ websocket:
enabled: true
path: /ws
hostname: 127.0.0.1
shadowsocks:
enabled: true
method: AEAD_CHACHA20_POLY1305
password: 12345678
mux:
enabled: true
`, clientPort, serverPort, targetPort)
go func() {
err := proxy.RunProxy([]byte(clientData), false)
proxy, err := proxy.NewProxyFromConfigData([]byte(clientData), false)
common.Must(err)
common.Must(proxy.Run())
}()
serverData := fmt.Sprintf(`
@@ -193,10 +208,15 @@ websocket:
enabled: true
path: /ws
hostname: 127.0.0.1
shadowsocks:
enabled: true
method: AEAD_CHACHA20_POLY1305
password: 12345678
`, serverPort, util.HTTPPort)
go func() {
err := proxy.RunProxy([]byte(serverData), false)
proxy, err := proxy.NewProxyFromConfigData([]byte(serverData), false)
common.Must(err)
common.Must(proxy.Run())
}()
time.Sleep(time.Second * 2)
+2 -2
View File
@@ -94,7 +94,7 @@ func (c *Client) newMuxClient() (*smuxClientInfo, error) {
// The mutex should be locked when this function is called
id := generateMuxID()
if _, found := c.clientPool[id]; found {
return nil, common.NewError("Duplicated id")
return nil, common.NewError("duplicated id")
}
fakeAddr := &tunnel.Address{
@@ -129,7 +129,7 @@ func (c *Client) DialConn(addr *tunnel.Address, _ tunnel.Tunnel) (tunnel.Conn, e
rwc, err := info.client.Open()
info.lastActiveTime = time.Now()
if err != nil {
return nil, err
return nil, common.NewError("mux failed to open stream from client").Base(err)
}
return &Conn{
rwc: rwc,
+1
View File
@@ -197,6 +197,7 @@ func (c *Client) DialPacket(overlay tunnel.Tunnel) (tunnel.PacketConn, error) {
}
ctx, cancel := context.WithCancel(c.Context)
return &PacketConn{
Client: c,
PacketConn: direct,
proxy: proxy,
CancelFunc: cancel,
+57 -1
View File
@@ -6,9 +6,11 @@ import (
"github.com/p4gefau1t/trojan-go/config"
"github.com/p4gefau1t/trojan-go/test/util"
"github.com/p4gefau1t/trojan-go/tunnel"
"net"
"strconv"
"strings"
"testing"
"time"
)
type MockClient struct{}
@@ -18,13 +20,53 @@ func (m *MockClient) DialConn(address *tunnel.Address, t tunnel.Tunnel) (tunnel.
}
func (m *MockClient) DialPacket(t tunnel.Tunnel) (tunnel.PacketConn, error) {
return nil, common.NewError("mockproxy")
//return nil, common.NewError("mockproxy")
return MockPacketConn{}, nil
}
func (m MockClient) Close() error {
return nil
}
type MockPacketConn struct {
}
func (m MockPacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
panic("implement me")
}
func (m MockPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
panic("implement me")
}
func (m MockPacketConn) Close() error {
panic("implement me")
}
func (m MockPacketConn) LocalAddr() net.Addr {
panic("implement me")
}
func (m MockPacketConn) SetDeadline(t time.Time) error {
panic("implement me")
}
func (m MockPacketConn) SetReadDeadline(t time.Time) error {
panic("implement me")
}
func (m MockPacketConn) SetWriteDeadline(t time.Time) error {
panic("implement me")
}
func (m MockPacketConn) WriteWithMetadata(bytes []byte, metadata *tunnel.Metadata) (int, error) {
return 0, common.NewError("mockproxy")
}
func (m MockPacketConn) ReadWithMetadata(bytes []byte) (int, *tunnel.Metadata, error) {
return 0, nil, common.NewError("mockproxy")
}
func TestRouter(t *testing.T) {
data := `
router:
@@ -90,4 +132,18 @@ router:
if err != nil {
t.Fail()
}
packet, err := client.DialPacket(nil)
common.Must(err)
buf := [10]byte{}
_, err = packet.WriteWithMetadata(buf[:], &tunnel.Metadata{
Address: &tunnel.Address{
AddressType: tunnel.DomainName,
DomainName: "proxyfull",
Port: port,
},
})
if err.Error() != "mockproxy" {
t.Fail()
}
}
+47
View File
@@ -0,0 +1,47 @@
package shadowsocks
import (
"context"
"github.com/p4gefau1t/trojan-go/common"
"github.com/p4gefau1t/trojan-go/config"
"github.com/p4gefau1t/trojan-go/log"
"github.com/p4gefau1t/trojan-go/tunnel"
"github.com/p4gefau1t/trojan-go/tunnel/transport"
"github.com/shadowsocks/go-shadowsocks2/core"
)
type Client struct {
underlay tunnel.Client
core.Cipher
}
func (c *Client) DialConn(address *tunnel.Address, tunnel tunnel.Tunnel) (tunnel.Conn, error) {
conn, err := c.underlay.DialConn(address, tunnel)
if err != nil {
return nil, err
}
return &transport.Conn{
Conn: c.Cipher.StreamConn(conn),
}, nil
}
func (c *Client) DialPacket(tunnel tunnel.Tunnel) (tunnel.PacketConn, error) {
panic("not supported")
}
func (c *Client) Close() error {
return c.underlay.Close()
}
func NewClient(ctx context.Context, underlay tunnel.Client) (*Client, error) {
cfg := config.FromContext(ctx, Name).(*Config)
cipher, err := core.PickCipher(cfg.Shadowsocks.Method, nil, cfg.Shadowsocks.Password)
if err != nil {
return nil, common.NewError("invalid shadowsocks cipher").Base(err)
}
log.Info("shadowsocks client created")
return &Client{
underlay: underlay,
Cipher: cipher,
}, nil
}
+19
View File
@@ -0,0 +1,19 @@
package shadowsocks
import "github.com/p4gefau1t/trojan-go/config"
type ShadowsocksConfig struct {
Enabled bool `json,yaml:"enabled"`
Method string `json,yaml:"method"`
Password string `json,yaml:"password"`
}
type Config struct {
Shadowsocks ShadowsocksConfig `json,yaml:"shadowsocks"`
}
func init() {
config.RegisterConfigCreator(Name, func() interface{} {
return new(Config)
})
}
+47
View File
@@ -0,0 +1,47 @@
package shadowsocks
import (
"context"
"github.com/p4gefau1t/trojan-go/common"
"github.com/p4gefau1t/trojan-go/config"
"github.com/p4gefau1t/trojan-go/log"
"github.com/p4gefau1t/trojan-go/tunnel"
"github.com/p4gefau1t/trojan-go/tunnel/transport"
"github.com/shadowsocks/go-shadowsocks2/core"
)
type Server struct {
underlay tunnel.Server
core.Cipher
}
func (s *Server) AcceptConn(overlay tunnel.Tunnel) (tunnel.Conn, error) {
conn, err := s.underlay.AcceptConn(overlay)
if err != nil {
return nil, common.NewError("shadowsocks failed to accept connection from underlying tunnel")
}
return &transport.Conn{
Conn: s.Cipher.StreamConn(conn),
}, nil
}
func (s *Server) AcceptPacket(t tunnel.Tunnel) (tunnel.PacketConn, error) {
panic("not supported")
}
func (s *Server) Close() error {
return s.underlay.Close()
}
func NewServer(ctx context.Context, underlay tunnel.Server) (*Server, error) {
cfg := config.FromContext(ctx, Name).(*Config)
cipher, err := core.PickCipher(cfg.Shadowsocks.Method, nil, cfg.Shadowsocks.Password)
if err != nil {
return nil, common.NewError("invalid shadowsocks cipher").Base(err)
}
log.Info("shadowsocks client created")
return &Server{
underlay: underlay,
Cipher: cipher,
}, nil
}
+43
View File
@@ -0,0 +1,43 @@
package shadowsocks
import (
"context"
"github.com/p4gefau1t/trojan-go/common"
"github.com/p4gefau1t/trojan-go/config"
"github.com/p4gefau1t/trojan-go/test/util"
"github.com/p4gefau1t/trojan-go/tunnel"
"github.com/p4gefau1t/trojan-go/tunnel/raw"
"net"
"testing"
)
func TestShadowsocks(t *testing.T) {
cfg := &Config{
Shadowsocks: ShadowsocksConfig{
Enabled: true,
Method: "AES-128-GCM",
Password: "password",
},
}
ctx := config.WithConfig(context.Background(), Name, cfg)
port := common.PickPort("tcp", "127.0.0.1")
addr := &tunnel.Address{
AddressType: tunnel.IPv4,
IP: net.ParseIP("127.0.0.1"),
Port: port,
}
tcpServer, err := raw.NewServer(addr)
common.Must(err)
tcpClient := &raw.FixedClient{
FixedAddr: addr,
}
c, err := NewClient(ctx, tcpClient)
common.Must(err)
s, err := NewServer(ctx, tcpServer)
common.Must(err)
conn1, err := c.DialConn(nil, nil)
common.Must(err)
conn2, err := s.AcceptConn(nil)
common.Must(err)
util.CheckConn(conn1, conn2)
}
+25
View File
@@ -1 +1,26 @@
package shadowsocks
import (
"context"
"github.com/p4gefau1t/trojan-go/tunnel"
)
const Name = "SHADOWSOCKS"
type Tunnel struct{}
func (t *Tunnel) Name() string {
return Name
}
func (t *Tunnel) NewClient(ctx context.Context, client tunnel.Client) (tunnel.Client, error) {
return NewClient(ctx, client)
}
func (t *Tunnel) NewServer(ctx context.Context, server tunnel.Server) (tunnel.Server, error) {
return NewServer(ctx, server)
}
func init() {
tunnel.RegisterTunnel(Name, &Tunnel{})
}
+1
View File
@@ -1,4 +1,5 @@
// +build linux darwin
package tproxy
import (
-2
View File
@@ -6,12 +6,10 @@ import (
"github.com/p4gefau1t/trojan-go/tunnel"
)
// Conn is the TLS connections
type Conn struct {
net.Conn
}
// Metadata implements tunnel.Conn. We don't need and metadata here
func (c *Conn) Metadata() *tunnel.Metadata {
return nil
}