diff --git a/build.sh b/build.sh index cd089f6..09cfad3 100755 --- a/build.sh +++ b/build.sh @@ -8,4 +8,4 @@ VAR_SETTING="" VAR_SETTING="$VAR_SETTING -X $PACKAGE_NAME/constant.Version=$VERSION" VAR_SETTING="$VAR_SETTING -X $PACKAGE_NAME/constant.Commit=$COMMIT" -CGO_ENABLE=0 go build -tags "full" -ldflags="-s -w $VAR_SETTING" +CGO_ENABLED=0 go build -tags "full" -ldflags="-s -w $VAR_SETTING" diff --git a/docs/content/developer/overview.md b/docs/content/developer/overview.md index 57cf13d..c57c9b3 100644 --- a/docs/content/developer/overview.md +++ b/docs/content/developer/overview.md @@ -114,10 +114,10 @@ Trojan-Go将所有协议(包括路由功能等)抽象为隧道(tunnel.Tunnel - websocket - trojan(终端节点) - mux - - simplesocks (终端节点) + - simplesocks (终端节点) - trojan 能够识别mux和普通trojan流量并分发(终端节点) - mux - - simplesocks (终端节点) + - simplesocks (终端节点) - 出站(列表) - freedom diff --git a/example/trojan-go.service b/example/trojan-go.service index bf70dd0..19380a2 100644 --- a/example/trojan-go.service +++ b/example/trojan-go.service @@ -1,6 +1,6 @@ [Unit] Description=Trojan-Go - An unidentifiable mechanism that helps you bypass GFW -Documentation=https://github.com/p4gefau1t/trojan-go +Documentation=https://p4gefau1t.github.io/trojan-go/ After=network.target network-online.target nss-lookup.target mysql.service mariadb.service mysqld.service Wants=network-online.target diff --git a/example/trojan-go@.service b/example/trojan-go@.service index 01789b0..91a8d46 100644 --- a/example/trojan-go@.service +++ b/example/trojan-go@.service @@ -6,7 +6,7 @@ After=network.target network-online.target nss-lookup.target mysql.service maria [Service] Type=simple StandardError=journal -User=nobody +User=root AmbientCapabilities=CAP_NET_BIND_SERVICE ExecStart=/usr/bin/trojan-go -config /etc/trojan-go/%i.json ExecReload=/bin/kill -HUP $MAINPID diff --git a/option/option.go b/option/option.go index 3e39356..cc867c2 100644 --- a/option/option.go +++ b/option/option.go @@ -22,7 +22,7 @@ func PopOptionHandler() (Handler, error) { } } if maxHandler == nil { - return nil, common.NewError("No option left") + return nil, common.NewError("no option left") } delete(handlers, maxHandler.Name()) return maxHandler, nil diff --git a/proxy/custom/custom.go b/proxy/custom/custom.go index 559e61e..200a1a3 100644 --- a/proxy/custom/custom.go +++ b/proxy/custom/custom.go @@ -45,26 +45,27 @@ func init() { var root *proxy.Node // build server tree for _, path := range cfg.Inbound.Path { - lastNode := root + var lastNode *proxy.Node for _, tag := range path { if _, found := nodes[tag]; !found { return nil, common.NewError("invalid node tag: " + tag) } if lastNode == nil { - if root != nil { - panic("root != nil") + if root == nil { + lastNode = nodes[tag] + root = lastNode + t, err := tunnel.GetTunnel(root.Name) + if err != nil { + return nil, common.NewError("failed to find root tunnel").Base(err) + } + s, err := t.NewServer(root.Context, nil) + if err != nil { + return nil, common.NewError("failed to init root server").Base(err) + } + root.Server = s + } else { + lastNode = root } - lastNode = nodes[tag] - root = lastNode - t, err := tunnel.GetTunnel(root.Name) - if err != nil { - return nil, common.NewError("failed to find root tunnel").Base(err) - } - s, err := t.NewServer(root.Context, nil) - if err != nil { - return nil, common.NewError("failed to init root server").Base(err) - } - root.Server = s } else { lastNode = lastNode.LinkNextNode(nodes[tag]) } diff --git a/test/scenario/custom_test.go b/test/scenario/custom_test.go index 8075689..a4f41cd 100644 --- a/test/scenario/custom_test.go +++ b/test/scenario/custom_test.go @@ -85,11 +85,24 @@ inbound: password: - 12345678 + - protocol: mux + tag: mux + + - protocol: simplesocks + tag: simplesocks + + path: - - transport - tls - trojan + - + - transport + - tls + - trojan + - mux + - simplesocks outbound: node: diff --git a/tunnel/freedom/client.go b/tunnel/freedom/client.go index 4bc08b7..606e2e6 100644 --- a/tunnel/freedom/client.go +++ b/tunnel/freedom/client.go @@ -20,6 +20,7 @@ type Client struct { keepAlive bool dns []string ctx context.Context + cancel context.CancelFunc forwardProxy bool proxyAddr *tunnel.Address username string @@ -116,8 +117,8 @@ func (c *Client) DialConn(addr *tunnel.Address, t tunnel.Tunnel) (tunnel.Conn, e Conn: socksConn, }, nil } - - tcpConn, err := net.Dial(network, addr.String()) + dialer := new(net.Dialer) + tcpConn, err := dialer.DialContext(c.ctx, network, addr.String()) if err != nil { return nil, err } @@ -144,15 +145,19 @@ func (c *Client) DialPacket(tunnel.Tunnel) (tunnel.PacketConn, error) { } func (c *Client) Close() error { + c.cancel() return nil } -func NewClient(ctx context.Context, client tunnel.Client) (*Client, error) { +func NewClient(ctx context.Context, _ tunnel.Client) (*Client, error) { // TODO implement dns // TODO socks5 udp cfg := config.FromContext(ctx, Name).(*Config) addr := tunnel.NewAddressFromHostPort("tcp", cfg.ForwardProxy.ProxyHost, cfg.ForwardProxy.ProxyPort) + ctx, cancel := context.WithCancel(ctx) return &Client{ + ctx: ctx, + cancel: cancel, dns: cfg.DNS, noDelay: cfg.TCP.NoDelay, keepAlive: cfg.TCP.KeepAlive, diff --git a/tunnel/freedom/freedom_test.go b/tunnel/freedom/freedom_test.go index 1139117..38d08f3 100644 --- a/tunnel/freedom/freedom_test.go +++ b/tunnel/freedom/freedom_test.go @@ -2,6 +2,7 @@ package freedom import ( "bytes" + "context" "testing" "github.com/p4gefau1t/trojan-go/test/util" @@ -11,7 +12,11 @@ import ( ) func TestConn(t *testing.T) { - client := &Client{} + ctx, cancel := context.WithCancel(context.Background()) + client := &Client{ + ctx: ctx, + cancel: cancel, + } addr, err := tunnel.NewAddressFromAddr("tcp", util.EchoAddr) common.Must(err) conn1, err := client.DialConn(addr, nil) @@ -26,10 +31,15 @@ func TestConn(t *testing.T) { if !bytes.Equal(sendBuf, recvBuf[:]) { t.Fail() } + client.Close() } func TestPacket(t *testing.T) { - client := &Client{} + ctx, cancel := context.WithCancel(context.Background()) + client := &Client{ + ctx: ctx, + cancel: cancel, + } addr, err := tunnel.NewAddressFromAddr("udp", util.EchoAddr) common.Must(err) conn1, err := client.DialPacket(nil) diff --git a/tunnel/transport/client.go b/tunnel/transport/client.go index 7e3f688..0e2edb7 100644 --- a/tunnel/transport/client.go +++ b/tunnel/transport/client.go @@ -16,9 +16,12 @@ import ( type Client struct { serverAddress *tunnel.Address cmd *exec.Cmd + ctx context.Context + cancel context.CancelFunc } func (c *Client) Close() error { + c.cancel() if c.cmd != nil { c.cmd.Process.Kill() } @@ -31,7 +34,8 @@ func (c *Client) DialPacket(tunnel.Tunnel) (tunnel.PacketConn, error) { // DialConn implements tunnel.Client. It will ignore the params and directly dial to the remote server func (c *Client) DialConn(*tunnel.Address, tunnel.Tunnel) (tunnel.Conn, error) { - conn, err := net.Dial("tcp", c.serverAddress.String()) + dialer := new(net.Dialer) + conn, err := dialer.DialContext(c.ctx, "tcp", c.serverAddress.String()) if err != nil { return nil, common.NewError("transport failed to connect to remote server") } @@ -41,9 +45,11 @@ func (c *Client) DialConn(*tunnel.Address, tunnel.Tunnel) (tunnel.Conn, error) { } // NewClient creates a transport layer client -func NewClient(ctx context.Context, c tunnel.Client) (*Client, error) { +func NewClient(ctx context.Context, _ tunnel.Client) (*Client, error) { cfg := config.FromContext(ctx, Name).(*Config) + ctx, cancel := context.WithCancel(ctx) + var cmd *exec.Cmd serverAddress := tunnel.NewAddressFromHostPort("tcp", cfg.RemoteHost, cfg.RemotePort) @@ -87,6 +93,8 @@ func NewClient(ctx context.Context, c tunnel.Client) (*Client, error) { client := &Client{ serverAddress: serverAddress, cmd: cmd, + ctx: ctx, + cancel: cancel, } return client, nil } diff --git a/version/version.go b/version/version.go index 9232fb9..51bcbab 100644 --- a/version/version.go +++ b/version/version.go @@ -15,7 +15,7 @@ type versionOption struct { } func (*versionOption) Name() string { - return "help" + return "version" } func (*versionOption) Priority() int {