add sip003 plugin support

This commit is contained in:
Page Fault
2020-06-04 06:57:40 +00:00
parent 25e56371e0
commit dbe0d54d17
14 changed files with 344 additions and 146 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ import (
)
const (
Version = "v0.5.1"
Version = "v0.5.2"
)
type Runnable interface {
+11
View File
@@ -175,3 +175,14 @@ func HumanFriendlyTraffic(bytes uint64) string {
}
return fmt.Sprintf("%.2f GiB", float32(bytes)/GiB)
}
func PickPort(network string, host string) int {
l, err := net.Listen(network, host+":0")
Must(err)
defer l.Close()
_, port, err := net.SplitHostPort(l.Addr().String())
Must(err)
p, err := strconv.ParseInt(port, 10, 32)
Must(err)
return int(p)
}
+36 -24
View File
@@ -4,6 +4,7 @@ import (
"crypto/tls"
"crypto/x509"
"io"
"os/exec"
"github.com/p4gefau1t/trojan-go/common"
utls "github.com/refraction-networking/utls"
@@ -46,7 +47,6 @@ type TLSConfig struct {
ALPN []string `json:"alpn"`
Curves string `json:"curves"`
Fingerprint string `json:"fingerprint"`
ServePlainText bool `json:"serve_plain_text"`
KeyLogPath string `json:"key_log"`
ClientHelloID *utls.ClientHelloID
@@ -153,30 +153,42 @@ type APIConfig struct {
APIAddress *common.Address
}
type TransportPluginConfig struct {
Enabled bool `json:"enabled"`
Type string `json:"type"`
Command string `json:"command"`
SSOption string `json:"ss_option"`
Arg []string `json:"arg"`
Env []string `json:"env"`
Cmd *exec.Cmd
}
type GlobalConfig struct {
RunType RunType `json:"run_type"`
LogLevel int `json:"log_level"`
LogFile string `json:"log_file"`
LocalHost string `json:"local_addr"`
LocalPort int `json:"local_port"`
TargetHost string `json:"target_addr"`
TargetPort int `json:"target_port"`
RemoteHost string `json:"remote_addr"`
RemotePort int `json:"remote_port"`
BufferSize int `json:"buffer_size"`
DisableHTTPCheck bool `json:"disable_http_check"`
Passwords []string `json:"password"`
DNS []string `json:"dns"`
TLS TLSConfig `json:"ssl"`
TCP TCPConfig `json:"tcp"`
MySQL MySQLConfig `json:"mysql"`
Redis RedisConfig `json:"redis"`
Mux MuxConfig `json:"mux"`
Router RouterConfig `json:"router"`
Websocket WebsocketConfig `json:"websocket"`
API APIConfig `json:"api"`
ForwardProxy ForwardProxyConfig `json:"forward_proxy"`
Compression CompressionConfig `json:"compression"`
RunType RunType `json:"run_type"`
LogLevel int `json:"log_level"`
LogFile string `json:"log_file"`
LocalHost string `json:"local_addr"`
LocalPort int `json:"local_port"`
TargetHost string `json:"target_addr"`
TargetPort int `json:"target_port"`
RemoteHost string `json:"remote_addr"`
RemotePort int `json:"remote_port"`
BufferSize int `json:"buffer_size"`
DisableHTTPCheck bool `json:"disable_http_check"`
Passwords []string `json:"password"`
DNS []string `json:"dns"`
TLS TLSConfig `json:"ssl"`
TCP TCPConfig `json:"tcp"`
MySQL MySQLConfig `json:"mysql"`
Redis RedisConfig `json:"redis"`
Mux MuxConfig `json:"mux"`
Router RouterConfig `json:"router"`
Websocket WebsocketConfig `json:"websocket"`
API APIConfig `json:"api"`
ForwardProxy ForwardProxyConfig `json:"forward_proxy"`
Compression CompressionConfig `json:"compression"`
TransportPlugin TransportPluginConfig `json:"transport_plugin"`
LocalAddress *common.Address
RemoteAddress *common.Address
+96 -36
View File
@@ -11,6 +11,8 @@ import (
"net"
"net/http"
"os"
"os/exec"
"strconv"
"strings"
"github.com/p4gefau1t/trojan-go/common"
@@ -313,13 +315,6 @@ func loadCommonConfig(config *GlobalConfig) error {
}
func loadClientConfig(config *GlobalConfig) error {
if config.TLS.SNI == "" {
log.Warn("SNI is unspecified, using remote_addr as SNI")
config.TLS.SNI = config.RemoteHost
}
if err := loadCert(&config.TLS); err != nil {
return err
}
//forward proxy settings
if config.ForwardProxy.Enabled {
log.Info("Forward proxy enabled")
@@ -327,13 +322,50 @@ func loadClientConfig(config *GlobalConfig) error {
log.Debug("Forward proxy", config.ForwardProxy.ProxyAddress.String())
}
if config.Websocket.Enabled && config.Websocket.DoubleTLS {
if config.Websocket.TLS.CertPath == "" {
log.Warn("Empty double TLS settings, using default ssl settings")
config.Websocket.TLS = config.TLS
} else {
if err := loadCert(&config.Websocket.TLS); err != nil {
return err
if config.TransportPlugin.Enabled {
switch config.TransportPlugin.Type {
case "plaintext":
// do nothing
case "shadowsocks":
pluginHost := "127.0.0.1"
pluginPort := common.PickPort("tcp", pluginHost)
config.TransportPlugin.Env = append(
config.TransportPlugin.Env,
"SS_LOCAL_HOST="+pluginHost,
"SS_LOCAL_PORT="+strconv.FormatInt(int64(pluginPort), 10),
"SS_REMOTE_HOST="+config.RemoteHost,
"SS_REMOTE_PORT="+strconv.FormatInt(int64(config.RemotePort), 10),
)
config.RemoteHost = pluginHost
config.RemotePort = pluginPort
config.RemoteAddress = common.NewAddress(config.RemoteHost, config.RemotePort, "tcp")
log.Debug("New remote address", config.RemoteAddress.String())
log.Debug("Plugin env", config.TransportPlugin.Env)
cmd := exec.Command(config.TransportPlugin.Command, config.TransportPlugin.Arg...)
cmd.Env = append(cmd.Env, config.TransportPlugin.Env...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stdout
config.TransportPlugin.Cmd = cmd
default:
return common.NewError("Invalid plugin type: " + config.TransportPlugin.Type)
}
} else {
if config.TLS.SNI == "" {
log.Warn("SNI is unspecified, using remote_addr as SNI")
config.TLS.SNI = config.RemoteHost
}
if err := loadCert(&config.TLS); err != nil {
return err
}
if config.Websocket.Enabled && config.Websocket.DoubleTLS {
if config.Websocket.TLS.CertPath == "" {
log.Warn("Empty double TLS settings, using default ssl settings")
config.Websocket.TLS = config.TLS
} else {
if err := loadCert(&config.Websocket.TLS); err != nil {
return err
}
}
}
}
@@ -354,35 +386,63 @@ func loadServerConfig(config *GlobalConfig) error {
resp.Body.Close()
}
//tls settings
if config.TLS.ServePlainText {
log.Warn("Server will now use plain text. TLS config is ignored")
// transport plugin settings
if config.TransportPlugin.Enabled {
log.Warn("Server will use transport plugin and work in plain text mode. TLS config is ignored.")
switch config.TransportPlugin.Type {
case "shadowsocks":
trojanHost := "127.0.0.1"
trojanPort := common.PickPort("tcp", trojanHost)
config.TransportPlugin.Env = append(
config.TransportPlugin.Env,
"SS_REMOTE_HOST="+config.LocalHost,
"SS_REMOTE_PORT="+strconv.FormatInt(int64(config.LocalPort), 10),
"SS_LOCAL_HOST="+trojanHost,
"SS_LOCAL_PORT="+strconv.FormatInt(int64(trojanPort), 10),
)
config.LocalHost = trojanHost
config.LocalPort = trojanPort
config.LocalAddress = common.NewAddress(config.LocalHost, config.LocalPort, "tcp")
log.Debug("New local address", config.RemoteAddress.String())
log.Debug("Plugin env", config.TransportPlugin.Env)
cmd := exec.Command(config.TransportPlugin.Command, config.TransportPlugin.Arg...)
cmd.Env = append(cmd.Env, config.TransportPlugin.Env...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stdout
config.TransportPlugin.Cmd = cmd
case "plaintext":
// do nothing
default:
return common.NewError("Invalid plugin type: " + config.TransportPlugin.Type)
}
} else {
if err := loadCertAndKey(&config.TLS); err != nil {
return err
}
}
if config.TLS.SNI == "" {
log.Warn("Empty SNI field. Server will not verify the SNI in client hello request")
config.TLS.VerifyHostName = false
}
if config.TLS.HTTPResponseFileName != "" {
payload, err := ioutil.ReadFile(config.TLS.HTTPResponseFileName)
if err != nil {
return common.NewError("Failed to load http response file").Base(err)
// tls settings
if config.TLS.SNI == "" {
log.Warn("Empty SNI field. Server will not verify the SNI in client hello request")
config.TLS.VerifyHostName = false
}
config.TLS.HTTPResponse = payload
}
if config.Websocket.DoubleTLS {
if config.Websocket.TLS.CertPath == "" {
log.Warn("Empty double TLS settings, using global TLS settings")
config.Websocket.TLS = config.TLS
if config.TLS.HTTPResponseFileName != "" {
payload, err := ioutil.ReadFile(config.TLS.HTTPResponseFileName)
if err != nil {
return common.NewError("Failed to load http response file").Base(err)
}
config.TLS.HTTPResponse = payload
}
if err := loadCertAndKey(&config.Websocket.TLS); err != nil {
return err
if config.Websocket.DoubleTLS {
if config.Websocket.TLS.CertPath == "" {
log.Warn("Empty double TLS settings, using global TLS settings")
config.Websocket.TLS = config.TLS
}
if err := loadCertAndKey(&config.Websocket.TLS); err != nil {
return err
}
}
}
+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.5.1"
version = "0.5.2"
# Documentation repository section
# documentation repository (set edit link to documentation repository)
+9 -9
View File
@@ -11,24 +11,24 @@ require (
github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
github.com/mediocregopher/radix/v3 v3.5.1
github.com/miekg/dns v1.1.29 // indirect
github.com/onsi/ginkgo v1.10.1 // indirect
github.com/onsi/gomega v1.7.0 // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/onsi/ginkgo v1.12.3 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/proullon/ramsql v0.0.0-20181213202341-817cee58a244
github.com/refraction-networking/utls v0.0.0-20190909200633-43c36d3c1f57
github.com/refraction-networking/utls v0.0.0-20200601200209-ada0bb9b38a0
github.com/smartystreets/goconvey v1.6.4
github.com/xtaci/smux v1.5.15-0.20200523091831-637399ad4398
github.com/ziutek/mymysql v1.5.4 // indirect
go.starlark.net v0.0.0-20200519165436-0aa95694c768 // indirect
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2
golang.org/x/sys v0.0.0-20200523222454-059865788121
golang.org/x/crypto v0.0.0-20200602180216-279210d13fed
golang.org/x/net v0.0.0-20200602114024-627f9648deb9
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1
google.golang.org/grpc v1.29.1
google.golang.org/protobuf v1.24.0
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/square/go-jose.v2 v2.5.1 // indirect
v2ray.com/core v4.19.1+incompatible
v2ray.com/core v0.0.0-20190603071532-16e9d39fff74
)
replace v2ray.com/core => github.com/v2ray/v2ray-core v4.23.3+incompatible
replace v2ray.com/core => github.com/v2ray/v2ray-core v0.0.0-20200603100350-6b5d2fed91c0
+33 -34
View File
@@ -53,7 +53,6 @@ github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/cenkalti/backoff/v4 v4.0.0 h1:6VeaLF9aI+MAUQ95106HwWzYZgJJpZ4stumjj6RFYAU=
github.com/cenkalti/backoff/v4 v4.0.0/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg=
github.com/cenkalti/backoff/v4 v4.0.2 h1:JIufpQLbh4DkbQoii76ItQIUFzevQSqOLZca4eamEDs=
github.com/cenkalti/backoff/v4 v4.0.2/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg=
@@ -83,8 +82,9 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/exoscale/egoscale v0.18.1/go.mod h1:Z7OOdzzTOz1Q1PjQXumlz9Wn/CddH0zSYdCF3rnBKXE=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-acme/lego/v3 v3.5.0 h1:/0+NJQK+hNwRznhCi+19lbEa4xufhe7wJZOVd5j486s=
github.com/go-acme/lego/v3 v3.5.0/go.mod h1:TXodhTGOiWEqXDdgrzBoCtJ5R4L9lfOE68CTM0KGkT0=
@@ -124,13 +124,10 @@ github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1 h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@@ -163,7 +160,6 @@ github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df/go.mod h1:QMZY7/J/KSQEhKWFeDesPjMj+wCHReeknARU3wqlyN4=
@@ -181,7 +177,6 @@ github.com/kolo/xmlrpc v0.0.0-20190717152603-07c4ee3fd181/go.mod h1:o03bZfuBwAXH
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
@@ -202,7 +197,6 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5
github.com/mediocregopher/radix/v3 v3.5.1 h1:IOYgQUMA380N4khaL5eNT4v/P2LnHa8b0wnVdwZMFsY=
github.com/mediocregopher/radix/v3 v3.5.1/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8=
github.com/miekg/dns v1.1.4/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.27 h1:aEH/kqUzUxGJ/UHcEKdJY+ugH6WEzsEBBSPa8zuy1aM=
github.com/miekg/dns v1.1.27/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/miekg/dns v1.1.29 h1:xHBEhR+t5RzcFJjBLJlax2daXOrTYtr9z4WdKEfWFzg=
github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
@@ -216,20 +210,24 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04/go.mod h1:5sN+Lt1CaY4wsPvgQH/jsuJi4XO2ssZbdsIizr4CVC8=
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
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/nrdcg/auroradns v1.0.1/go.mod h1:y4pc0i9QXYlFCWrhWrUSIETnZgrf4KuwjDIWmmXo3JI=
github.com/nrdcg/dnspod-go v0.4.0/go.mod h1:vZSoFSFeQVm2gWLMkyX61LZ8HI3BaqtHZWgPTGKr6KQ=
github.com/nrdcg/goinwx v0.6.1/go.mod h1:XPiut7enlbEdntAqalBIqcYcTEVhpv/dKWgDCX2SwKQ=
github.com/nrdcg/namesilo v0.2.1/go.mod h1:lwMvfQTyYq+BbjJd30ylEG4GPSS6PII0Tia4rRpRiyw=
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.12.3 h1:+RYp9QczoWz9zfUyLP/5SLXQVhfr6gZOoKGfQqHuLZQ=
github.com/onsi/ginkgo v1.12.3/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
github.com/oracle/oci-go-sdk v7.0.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888=
github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014/go.mod h1:joRatxRJaZBsY3JAOEMcoOp05CnZzsx4scTxi95DHyQ=
@@ -259,8 +257,9 @@ github.com/proullon/ramsql v0.0.0-20181213202341-817cee58a244 h1:fdX2U+a2Rmc4BjR
github.com/proullon/ramsql v0.0.0-20181213202341-817cee58a244/go.mod h1:jG8oAQG0ZPHPyxg5QlMERS31airDC+ZuqiAe8DUvFVo=
github.com/rainycape/memcache v0.0.0-20150622160815-1031fa0ce2f2/go.mod h1:7tZKcyumwBO6qip7RNQ5r77yrssm9bfCowcLEBcU5IA=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/refraction-networking/utls v0.0.0-20190909200633-43c36d3c1f57 h1:SL1K0QAuC1b54KoY1pjPWe6kSlsFHwK9/oC960fKrTY=
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/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@@ -286,8 +285,8 @@ github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7/go.mod h1:imsgLp
github.com/transip/gotransip v0.0.0-20190812104329-6d8d9179b66f/go.mod h1:i0f4R4o2HM0m3DZYQWsj6/MEowD57VzoH0v3d7igeFY=
github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/v2ray/v2ray-core v4.23.3+incompatible h1:+JHDFxjxHEn7Afi6mAjvM2a6hKll4peg9q7nExmdrcA=
github.com/v2ray/v2ray-core v4.23.3+incompatible/go.mod h1:6qvbJidjCnQWxyTc9SBD/cLCtN4qLs2neS/VzwSTnTY=
github.com/v2ray/v2ray-core v0.0.0-20200603100350-6b5d2fed91c0 h1:beJRvss6cKPj/Qy8RLI/O8EKYaxaKlsXBjsXgmNqSUQ=
github.com/v2ray/v2ray-core v0.0.0-20200603100350-6b5d2fed91c0/go.mod h1:6qvbJidjCnQWxyTc9SBD/cLCtN4qLs2neS/VzwSTnTY=
github.com/vultr/govultr v0.1.4/go.mod h1:9H008Uxr/C4vFNGLqKx232C206GL0PBHzOP0809bGNA=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
@@ -302,7 +301,6 @@ go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
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=
go.starlark.net v0.0.0-20200519165436-0aa95694c768 h1:p1NBjkIS2bHXntFxS9zhyFmZ9VKtazqNnsn5r7okSTo=
go.starlark.net v0.0.0-20200519165436-0aa95694c768/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=
@@ -316,9 +314,10 @@ golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaE
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw=
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/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=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -373,8 +372,9 @@ golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2 h1:eDrdRpKgkcCqKZQwyZRyeFZgfqt37SL7Kv3tok06cKE=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM=
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -406,9 +406,12 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -418,8 +421,9 @@ golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121 h1:rITEj+UZHYC927n8GT97eC3zrpzXdb/voyeOuVKS46o=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/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.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -428,7 +432,6 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
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=
@@ -503,7 +506,6 @@ google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvx
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171 h1:xes2Q2k+d/+YNXVw0FpZkIDJiaux4OVrRKXRAzH6A0U=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
@@ -524,9 +526,7 @@ google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLY
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0 h1:cJv5/xdbk1NnMPR1VP9+HU6gupuG9MLBoH1r6RHZ2MY=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
@@ -534,12 +534,10 @@ google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEG
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE=
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
@@ -547,7 +545,6 @@ gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ns1/ns1-go.v2 v2.0.0-20190730140822-b51389932cbc/go.mod h1:VV+3haRsgDiVLxyifmMBrBIuCWFBPYKbRssXB9z67Hw=
gopkg.in/resty.v1 v1.9.1/go.mod h1:vo52Hzryw9PnPHcJfPsBiFW62XhNx5OczbV9y+IMpgc=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.3.1 h1:SK5KegNXmKmqE342YYN2qPHEnUYeoMiXXl1poUlI+o4=
gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w=
gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
@@ -555,8 +552,10 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkep
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
h12.io/socks v1.0.0/go.mod h1:MdYbo5/eB9ka7u5dzW2Qh0iSyJENwB3KI5H5ngenFGA=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+2 -1
View File
@@ -33,8 +33,9 @@ func (m *AppManager) OpenAppConn(req *protocol.Request) (protocol.ConnSession, e
outboundConn, err = trojan.NewOutboundConnSession(req, transport, m.config, m.auth)
}
if err != nil {
return nil, common.NewError("Fail to start conn session").Base(err)
return nil, common.NewError("Fail to open conn session").Base(err)
}
log.Info("Tunneling to", req)
return outboundConn, nil
}
+28 -16
View File
@@ -50,14 +50,14 @@ func (c *Client) handleSocksConn(conn io.ReadWriteCloser) {
defer inboundConn.Close()
if req.Command == protocol.Associate {
//setting up the bind address to respond
//listenUDP() will handle the incoming udp packets
// setting up the bind address to respond
// listenUDP() will handle the incoming udp packets
localIP, err := c.config.LocalAddress.ResolveIP()
if err != nil {
log.Error(common.NewError("Invalid local address").Base(err))
return
}
//bind port and IP
// bind port and IP
req.IP = localIP
req.Port = c.config.LocalAddress.Port
if localIP.To4() != nil {
@@ -66,7 +66,7 @@ func (c *Client) handleSocksConn(conn io.ReadWriteCloser) {
req.AddressType = common.IPv6
}
//notify listenUDP to get ready for relaying udp packets
// notify listenUDP to get ready for relaying udp packets
c.associated.Signal()
log.Debug("UDP associated to", req)
if err := inboundConn.(protocol.NeedRespond).Respond(); err != nil {
@@ -74,7 +74,6 @@ func (c *Client) handleSocksConn(conn io.ReadWriteCloser) {
return
}
//stop relaying UDP once TCP connection is closed
var buf [1]byte
_, err = rwc.Read(buf[:])
log.Debug(common.NewError("UDP conn ends").Base(err))
@@ -91,7 +90,6 @@ func (c *Client) handleSocksConn(conn io.ReadWriteCloser) {
log.Error(err)
return
}
log.Info("Conn tunneling to", req)
log.Debug("Policy", policy)
if policy == router.Bypass {
outboundConn, err := direct.NewOutboundConnSession(c.ctx, req, c.config)
@@ -99,11 +97,11 @@ func (c *Client) handleSocksConn(conn io.ReadWriteCloser) {
log.Error(err)
return
}
log.Info("[Bypass] conn to", req)
log.Info("[Bypass]", req)
proxy.RelayConn(c.ctx, inboundConn, outboundConn, c.config.BufferSize)
return
} else if policy == router.Block {
log.Info("[Block] conn to", req)
log.Info("[Block]", req)
return
}
outboundConn, err := c.appMan.OpenAppConn(req)
@@ -125,7 +123,7 @@ func (c *Client) handleHTTPConn(conn io.ReadWriteCloser) {
return
}
if inboundConn != nil { //CONNECT requests
if inboundConn != nil { // CONNECT requests
defer inboundConn.Close()
if err := inboundConn.(protocol.NeedRespond).Respond(); err != nil {
@@ -144,11 +142,11 @@ func (c *Client) handleHTTPConn(conn io.ReadWriteCloser) {
log.Error(err)
return
}
log.Info("[Bypass] conn to", req)
log.Info("[Bypass]", req)
proxy.RelayConn(c.ctx, inboundConn, outboundConn, c.config.BufferSize)
return
} else if policy == router.Block {
log.Info("[Block] conn to", req)
log.Info("[Block]", req)
return
}
@@ -158,7 +156,6 @@ func (c *Client) handleHTTPConn(conn io.ReadWriteCloser) {
return
}
defer outboundConn.Close()
log.Info("Conn tunneling to", req)
proxy.RelayConn(c.ctx, inboundConn, outboundConn, c.config.BufferSize)
} else { //GET/POST requests
defer inboundPacket.Close()
@@ -212,10 +209,14 @@ func (c *Client) handleHTTPConn(conn io.ReadWriteCloser) {
for {
n, err := outboundConn.Read(buf[:])
if err != nil {
log.Debug(err)
return
if err == io.ErrShortBuffer {
log.Debug("Short buffer")
} else {
log.Error(err)
return
}
}
if _, err = inboundPacket.WritePacket(nil, buf[0:n]); err != nil {
if _, err = inboundPacket.WritePacket(nil, buf[:n]); err != nil {
log.Debug(err)
return
}
@@ -308,7 +309,18 @@ func (c *Client) listenTCP(errChan chan error) {
func (c *Client) Run() error {
log.Info("Trojan-Go client is listening on", c.config.LocalAddress.String())
errChan := make(chan error, 3)
errChan := make(chan error, 4)
if c.config.TransportPlugin.Enabled && c.config.TransportPlugin.Cmd != nil {
go func() {
log.Info("Initiating plugin...")
select {
case errChan <- c.config.TransportPlugin.Cmd.Run():
case <-c.ctx.Done():
c.config.TransportPlugin.Cmd.Process.Kill()
log.Info("Plugin killed")
}
}()
}
go c.listenUDP(errChan)
go c.listenTCP(errChan)
if c.config.API.Enabled {
+14 -10
View File
@@ -2,6 +2,7 @@ package client
import (
"context"
"fmt"
"io"
"math/rand"
"sync"
@@ -49,7 +50,7 @@ stick2:
func (rwc *smuxStickyReadWriteCloser) Close() error {
const maxPaddingLength = 512
padding := [maxPaddingLength + 8]byte{0, 0, 'A', 'B', 'C', 'D', 'E', 'F'}
padding := [maxPaddingLength + 8]byte{'A', 'B', 'C', 'D', 'E', 'F'} // for debugging
buf := rwc.stickToPayload(nil)
rwc.Write(append(buf, padding[:rand.Intn(maxPaddingLength)]...))
return rwc.ReadWriteCloser.Close()
@@ -62,13 +63,13 @@ func (rwc *smuxStickyReadWriteCloser) Write(p []byte) (int, error) {
// THE CONTENT OF THE BUFFER MIGHT CHANGE
// NEVER STORE THE POINTER TO HEADER, COPY THE HEADER INSTEAD
case 0:
//cmdSYN
// cmdSYN
header := make([]byte, 8)
copy(header, p)
rwc.synQueue <- header
return 8, nil
case 1:
//cmdFIN
// cmdFIN
header := make([]byte, 8)
copy(header, p)
rwc.finQueue <- header
@@ -142,7 +143,7 @@ func (m *MuxManager) newMuxClient() (*muxClientInfo, error) {
smuxConfig.KeepAliveDisabled = true
client, err := smux.Client(smuxRWC, smuxConfig)
common.Must(err)
log.Info("Mux TLS tunnel established, client id:", id)
log.Info(fmt.Sprintf("Mux TLS tunnel established with mux client %x", id))
return &muxClientInfo{
client: client,
id: id,
@@ -157,7 +158,7 @@ func (m *MuxManager) pickMuxClient() (*muxClientInfo, error) {
for _, info := range m.muxPool {
if info.client.IsClosed() {
delete(m.muxPool, info.id)
log.Info("Mux client", info.id, "is dead")
log.Info(fmt.Sprintf("Mux client %x is closed", info.id))
continue
}
if info.client.NumStreams() < m.config.Mux.Concurrency || m.config.Mux.Concurrency <= 0 {
@@ -192,10 +193,10 @@ func (m *MuxManager) DialToServer() (io.ReadWriteCloser, error) {
defer m.Unlock()
delete(m.muxPool, info.id)
info.client.Close()
log.Warn("Somthing wrong with mux client", info.id, ", closing")
log.Warn(common.NewError(fmt.Sprintf("Somthing wrong with mux client %x, closing", info.id)).Base(err))
return nil, err
}
log.Info("New mux conn established with client", info.id)
log.Info(fmt.Sprintf("New mux stream established with mux client %x", info.id))
info.lastActiveTime = time.Now()
return stream, nil
}
@@ -217,21 +218,24 @@ func (m *MuxManager) checkAndCloseIdleMuxClient() {
for id, info := range m.muxPool {
if info.client.IsClosed() {
delete(m.muxPool, id)
log.Info("Mux", id, "is dead")
log.Info("Mux client", id, "is dead")
} else if info.client.NumStreams() == 0 && time.Now().Sub(info.lastActiveTime) > muxIdleDuration {
info.client.Close()
delete(m.muxPool, id)
log.Info("Mux", id, "is closed due to inactive")
log.Info("Mux client", id, "is closed due to inactive")
}
}
log.Debug("Current mux pool clients: ", len(m.muxPool))
for i, c := range m.muxPool {
log.Debug(fmt.Sprintf(" Client %x: %d/%d", i, c.client.NumStreams(), m.config.Mux.Concurrency))
}
m.Unlock()
case <-m.ctx.Done():
log.Debug("Shutting down mux manager..")
m.Lock()
for id, info := range m.muxPool {
info.client.Close()
log.Info("Mux client", id, "closed")
log.Debug("Mux client", id, "closed")
}
m.Unlock()
return
+11 -7
View File
@@ -342,13 +342,13 @@ func (m *TLSManager) dialTLSWithFakeFingerprint() (*utls.UConn, error) {
m.fingerprintsLock.Lock()
workingFingerprint = ""
m.fingerprintsLock.Unlock()
log.Error(common.NewError("Failed to set working fingerprint").Base(err))
log.Error(common.NewError("Failed to apply working fingerprint").Base(err))
} else {
protocol.SetRandomizedTimeout(tlsConn)
err = tlsConn.Handshake()
protocol.CancelTimeout(tlsConn)
if err != nil {
log.Debug("Working hello id failed, err:", err)
log.Error("Working hello id is no longer working, err:", err)
} else {
return tlsConn, nil
}
@@ -369,7 +369,7 @@ func (m *TLSManager) dialTLSWithFakeFingerprint() (*utls.UConn, error) {
tlsConn := utls.UClient(tcpConn, utlsConfig, utls.HelloCustom)
if err := tlsConn.ApplyPreset(spec); err != nil {
log.Error(common.NewError("Failed to set " + name + " fingerprint").Base(err))
log.Error(common.NewError("Failed to apply fingerprint:" + name).Base(err))
continue
}
@@ -377,11 +377,11 @@ func (m *TLSManager) dialTLSWithFakeFingerprint() (*utls.UConn, error) {
err = tlsConn.Handshake()
protocol.CancelTimeout(tlsConn)
if err != nil {
log.Debug("Fingerprint", name, "failed, err:", err)
log.Info("Handshaking with fingerprint:", name, "failed:", err)
continue // on tls Dial error keep trying
}
log.Debug("Avaliable hello id found:", name)
log.Info("Avaliable hello id found:", name)
m.fingerprintsLock.Lock()
m.workingFingerprint = name
m.fingerprintsLock.Unlock()
@@ -391,9 +391,13 @@ func (m *TLSManager) dialTLSWithFakeFingerprint() (*utls.UConn, error) {
}
func (m *TLSManager) DialToServer() (io.ReadWriteCloser, error) {
if m.config.TransportPlugin.Enabled {
// plain text
return m.dialTCP()
}
var transport net.Conn
if m.config.TLS.Fingerprint != "" {
//use utls fingerprints
// use utls fingerprints
tlsConn, err := m.dialTLSWithFakeFingerprint()
if err != nil {
return nil, err
@@ -401,7 +405,7 @@ func (m *TLSManager) DialToServer() (io.ReadWriteCloser, error) {
m.printConnInfo(tlsConn)
transport = tlsConn
} else {
//normal golang tls
// default golang tls library
tcpConn, err := m.dialTCP()
if err != nil {
return nil, err
+21 -5
View File
@@ -3,6 +3,7 @@ package proxy
import (
"context"
"io"
"net"
"github.com/p4gefau1t/trojan-go/common"
"github.com/p4gefau1t/trojan-go/conf"
@@ -32,6 +33,9 @@ func RelayConn(ctx context.Context, a, b io.ReadWriter, bufferSize int) {
select {
case err := <-errChan:
if err != nil {
if err == io.EOF {
return
}
log.Debug(common.NewError("Conn relaying ends").Base(err))
}
case <-ctx.Done():
@@ -63,7 +67,13 @@ func RelayPacket(ctx context.Context, a, b protocol.PacketReadWriter) {
go copyPacket(b, a)
select {
case err := <-errChan:
log.Debug(common.NewError("Packet relaying ends").Base(err))
if err, ok := err.(net.Error); ok && err.Timeout() {
return
}
if err == io.EOF {
return
}
log.Error(common.NewError("Packet relaying ends").Base(err))
case <-ctx.Done():
return
}
@@ -99,10 +109,10 @@ func RelayPacketWithRouter(ctx context.Context, from protocol.PacketReadWriter,
}
to, found := table[policy]
if !found {
log.Debug("policy not found, skiped:", policy)
log.Debug("Policy not found, skiped:", policy)
continue
}
log.Debug("udp packet ", req, "routing policy:", policy)
log.Debug("UDP packet ", req, "routing policy:", policy)
_, err = to.WritePacket(req, packet)
if err != nil {
errChan <- err
@@ -117,7 +127,13 @@ func RelayPacketWithRouter(ctx context.Context, from protocol.PacketReadWriter,
go copyToDst()
select {
case err := <-errChan:
log.Debug(common.NewError("Packet relaying with router ends").Base(err))
if err, ok := err.(net.Error); ok && err.Timeout() {
return
}
if err == io.EOF {
return
}
log.Error(common.NewError("Packet relaying with router ends").Base(err))
case <-ctx.Done():
return
}
@@ -148,7 +164,7 @@ func RegisterAPI(t conf.RunType, r APIRunner) {
func RunAPIService(t conf.RunType, ctx context.Context, config *conf.GlobalConfig, auth stat.Authenticator) error {
r, ok := apis[t]
if !ok {
return common.NewError("API module for" + string(t) + "not found")
return common.NewError("API module for type " + string(t) + " not found")
}
return r(ctx, config, auth)
}
+13 -2
View File
@@ -160,7 +160,7 @@ func (s *Server) ListenTCP(errChan chan error) {
}
log.Info("Conn accepted from", conn.RemoteAddr())
go func(conn net.Conn) {
if s.config.TLS.ServePlainText {
if s.config.TransportPlugin.Enabled {
s.handleConn(conn)
return
}
@@ -229,13 +229,24 @@ func (s *Server) ListenTCP(errChan chan error) {
}
func (s *Server) Run() error {
errChan := make(chan error, 2)
errChan := make(chan error, 3)
if s.config.API.Enabled {
log.Info("API enabled")
go func() {
errChan <- proxy.RunAPIService(conf.Server, s.ctx, s.config, s.auth)
}()
}
if s.config.TransportPlugin.Enabled && s.config.TransportPlugin.Cmd != nil {
go func() {
log.Info("Initiating plugin...")
select {
case errChan <- s.config.TransportPlugin.Cmd.Run():
case <-s.ctx.Done():
s.config.TransportPlugin.Cmd.Process.Kill()
log.Info("Plugin killed")
}
}()
}
go s.ListenTCP(errChan)
select {
case <-s.ctx.Done():
+68
View File
@@ -10,6 +10,8 @@ import (
"io/ioutil"
"net"
"os"
"os/exec"
"strconv"
"sync"
"testing"
"time"
@@ -128,6 +130,10 @@ func getPasswords(password string) []string {
func getBasicServerConfig() *conf.GlobalConfig {
config := &conf.GlobalConfig{
LocalHost: "0.0.0.0",
LocalPort: 4445,
RemoteHost: "127.0.0.1",
RemotePort: 10080,
LocalAddress: common.NewAddress("0.0.0.0", 4445, "tcp"),
RemoteAddress: common.NewAddress("127.0.0.1", 10080, "tcp"),
TLS: getTLSConfig(),
@@ -140,6 +146,10 @@ func getBasicServerConfig() *conf.GlobalConfig {
func getBasicClientConfig() *conf.GlobalConfig {
config := &conf.GlobalConfig{
LocalHost: "0.0.0.0",
LocalPort: 4444,
RemoteHost: "127.0.0.1",
RemotePort: 4445,
LocalAddress: common.NewAddress("0.0.0.0", 4444, "tcp"),
RemoteAddress: common.NewAddress("127.0.0.1", 4445, "tcp"),
TLS: getTLSConfig(),
@@ -234,6 +244,58 @@ func addDNSConfig(config *conf.GlobalConfig) *conf.GlobalConfig {
return config
}
func addServerPluginConfig(config *conf.GlobalConfig) *conf.GlobalConfig {
config.TransportPlugin.Enabled = true
config.TransportPlugin.Command = "v2ray-plugin"
config.TransportPlugin.Arg = []string{"-server"}
trojanHost := "127.0.0.1"
trojanPort := common.PickPort("tcp", trojanHost)
config.TransportPlugin.Env = append(
config.TransportPlugin.Env,
"SS_REMOTE_HOST="+config.LocalHost,
"SS_REMOTE_PORT="+strconv.FormatInt(int64(config.LocalPort), 10),
"SS_LOCAL_HOST="+trojanHost,
"SS_LOCAL_PORT="+strconv.FormatInt(int64(trojanPort), 10),
)
config.LocalHost = trojanHost
config.LocalPort = trojanPort
config.LocalAddress = common.NewAddress(config.LocalHost, config.LocalPort, "tcp")
cmd := exec.Command(config.TransportPlugin.Command, config.TransportPlugin.Arg...)
cmd.Env = append(cmd.Env, config.TransportPlugin.Env...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stdout
config.TransportPlugin.Cmd = cmd
return config
}
func addClientPluginConfig(config *conf.GlobalConfig) *conf.GlobalConfig {
config.TransportPlugin.Enabled = true
config.TransportPlugin.Command = "v2ray-plugin"
pluginHost := "127.0.0.1"
pluginPort := common.PickPort("tcp", pluginHost)
config.TransportPlugin.Env = append(
config.TransportPlugin.Env,
"SS_LOCAL_HOST="+pluginHost,
"SS_LOCAL_PORT="+strconv.FormatInt(int64(pluginPort), 10),
"SS_REMOTE_HOST="+config.RemoteHost,
"SS_REMOTE_PORT="+strconv.FormatInt(int64(config.RemotePort), 10),
)
config.RemoteHost = pluginHost
config.RemotePort = pluginPort
config.RemoteAddress = common.NewAddress(config.RemoteHost, config.RemotePort, "tcp")
cmd := exec.Command(config.TransportPlugin.Command, config.TransportPlugin.Arg...)
cmd.Env = append(cmd.Env, config.TransportPlugin.Env...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stdout
config.TransportPlugin.Cmd = cmd
return config
}
func RunClient(ctx context.Context, config *conf.GlobalConfig) {
c := client.Client{}
r, err := c.Build(config)
@@ -552,3 +614,9 @@ func TestDNS(t *testing.T) {
conn.Close()
cancel()
}
func TestPlugin(t *testing.T) {
serverConfig := addServerPluginConfig(getBasicServerConfig())
clientConfig := addClientPluginConfig(getBasicClientConfig())
CheckClientServer(t, clientConfig, serverConfig)
}