diff --git a/api/client.go b/api/client.go index 115db5f10..edb275dea 100644 --- a/api/client.go +++ b/api/client.go @@ -62,7 +62,7 @@ func RunClientAPI(ctx context.Context, config *conf.GlobalConfig, auth stat.Auth if err != nil { return err } - log.Info("Client api service is running at", config.API.APIAddress) + log.Info("Trojan-Go client-side API service is listening on", config.API.APIAddress) errChan := make(chan error, 1) go func() { errChan <- server.Serve(listener) diff --git a/api/server.go b/api/server.go index 318a5749d..663d6ad2b 100644 --- a/api/server.go +++ b/api/server.go @@ -161,7 +161,7 @@ func RunServerAPI(ctx context.Context, config *conf.GlobalConfig, auth stat.Auth if err != nil { return err } - log.Info("Server api service is running at", config.API.APIAddress) + log.Info("Trojan-Go server-side API service is listening on", config.API.APIAddress) errChan := make(chan error, 1) go func() { errChan <- server.Serve(listener) diff --git a/protocol/trojan/websocket.go b/protocol/trojan/websocket.go index bb1293321..846c721f4 100644 --- a/protocol/trojan/websocket.go +++ b/protocol/trojan/websocket.go @@ -304,7 +304,7 @@ func NewInboundWebsocket(ctx context.Context, conn net.Conn, config *conf.Global if tlsErr := tlsConn.Handshake(); tlsErr != nil { rewindConn.R.Rewind() //proxy this to our own ws server - tlsErr = common.NewError("Invalid double tls handshake from" + conn.RemoteAddr().String()).Base(tlsErr) + tlsErr = common.NewError("Invalid double tls handshake from " + conn.RemoteAddr().String()).Base(tlsErr) goat, err := getWebsocketScapegoat( config, url, diff --git a/proxy/client/client.go b/proxy/client/client.go index dccb313b1..0bbb57ba6 100644 --- a/proxy/client/client.go +++ b/proxy/client/client.go @@ -307,7 +307,7 @@ func (c *Client) listenTCP(errChan chan error) { } func (c *Client) Run() error { - log.Info("Client is running at", c.config.LocalAddress.String()) + log.Info("Trojan-Go client is listening on", c.config.LocalAddress.String()) errChan := make(chan error, 3) go c.listenUDP(errChan) go c.listenTCP(errChan) diff --git a/proxy/client/forward.go b/proxy/client/forward.go index cb4d6c0ec..9335d46ee 100644 --- a/proxy/client/forward.go +++ b/proxy/client/forward.go @@ -163,7 +163,7 @@ func (f *Forward) listenTCP(errChan chan error) { } func (f *Forward) Run() error { - log.Info("Forward is running at", f.config.LocalAddress) + log.Info("Trojan-Go forward is listening on", f.config.LocalAddress) errChan := make(chan error, 2) go f.listenUDP(errChan) go f.listenTCP(errChan) diff --git a/proxy/client/nat.go b/proxy/client/nat.go index 9f7eee199..8c65d8e07 100644 --- a/proxy/client/nat.go +++ b/proxy/client/nat.go @@ -100,7 +100,7 @@ func (n *NAT) listenTCP(errChan chan error) { } func (n *NAT) Run() error { - log.Info("NAT is running at", n.config.LocalAddress) + log.Info("Trojan-Go NAT is listening on", n.config.LocalAddress) errChan := make(chan error, 2) go n.listenUDP(errChan) go n.listenTCP(errChan) diff --git a/proxy/relay/relay.go b/proxy/relay/relay.go index e4162e3c0..388719dcd 100644 --- a/proxy/relay/relay.go +++ b/proxy/relay/relay.go @@ -30,7 +30,7 @@ func (f *Relay) handleConn(conn net.Conn) { } func (f *Relay) Run() error { - log.Info("Relay is running at", f.config.LocalAddress) + log.Info("Trojan-Go relay is listening on", f.config.LocalAddress) listener, err := net.Listen("tcp", f.config.LocalAddress.String()) f.listener = listener if err != nil { diff --git a/proxy/server/server.go b/proxy/server/server.go index 257ce8c09..92556a044 100644 --- a/proxy/server/server.go +++ b/proxy/server/server.go @@ -39,6 +39,8 @@ func (s *Server) handleMuxConn(stream *smux.Stream) { log.Error(common.NewError("Failed to init inbound session").Base(err)) return } + defer stream.Close() + switch req.Command { case protocol.Connect: outboundConn, err := direct.NewOutboundConnSession(s.ctx, req, s.config) @@ -53,6 +55,7 @@ func (s *Server) handleMuxConn(stream *smux.Stream) { outboundPacket, err := direct.NewOutboundPacketSession(s.ctx) common.Must(err) inboundPacket, err := trojan.NewPacketSession(inboundConn) + defer inboundPacket.Close() proxy.ProxyPacket(s.ctx, inboundPacket, outboundPacket) default: log.Error(fmt.Sprintf("Invalid command %d", req.Command)) @@ -69,6 +72,7 @@ func (s *Server) handleConn(conn net.Conn) { return } protocol.CancelTimeout(conn) + defer conn.Close() if req.Command == protocol.Mux { muxServer, err := smux.Server(inboundConn, nil) @@ -114,7 +118,7 @@ func (s *Server) handleConn(conn net.Conn) { } func (s *Server) ListenTCP(errChan chan error) { - log.Info("Server is running at", s.config.LocalAddress) + log.Info("Trojan-Go server is listening on", s.config.LocalAddress) var listener net.Listener listener, err := net.Listen("tcp", s.config.LocalAddress.String()) @@ -168,7 +172,7 @@ func (s *Server) ListenTCP(errChan chan error) { if s.config.LogLevel == 0 { state := tlsConn.ConnectionState() - log.Trace("TLS handshaked", "cipher:", tls.CipherSuiteName(state.CipherSuite), "resume:", state.DidResume) + log.Trace("TLS handshaked", tls.CipherSuiteName(state.CipherSuite), state.DidResume, state.NegotiatedProtocol) } if err != nil { @@ -224,8 +228,7 @@ func (*Server) Build(config *conf.GlobalConfig) (common.Runnable, error) { authDriver := "memory" if config.MySQL.Enabled { authDriver = "mysql" - } - if config.Redis.Enabled { + } else if config.Redis.Enabled { authDriver = "redis" } auth, err := stat.NewAuth(ctx, authDriver, config) diff --git a/shadow/shadow.go b/shadow/shadow.go index a4742f2c1..727e54697 100644 --- a/shadow/shadow.go +++ b/shadow/shadow.go @@ -2,6 +2,7 @@ package shadow import ( "context" + "fmt" "io" "net" "time" @@ -34,6 +35,10 @@ func (m *ShadowManager) handleScapegoat() { for { select { case goat := <-m.scapegoatChan: + if goat.Conn == nil { + log.Error("Invalid inbound conn", goat.Conn) + return + } if goat.Info != "" { log.Info("Scapegoat: ", goat.Info) } @@ -52,9 +57,17 @@ func (m *ShadowManager) handleScapegoat() { continue } } - go proxy.ProxyConn(m.ctx, goat.Conn, goat.ShadowConn, m.config.BufferSize) + go func(goat *Scapegoat) { + if goat.Conn == nil || goat.ShadowConn == nil { + panic(fmt.Sprintf("Empty conn: %v %v", goat.Conn, goat.ShadowConn)) + } + proxy.ProxyConn(m.ctx, goat.Conn, goat.ShadowConn, m.config.BufferSize) + goat.Conn.Close() + goat.ShadowConn.Close() + log.Info("Scapegoat relaying done: ", goat.Info) + }(goat) case <-m.ctx.Done(): - log.Debug("shadow manager exiting..") + log.Debug("Shadow manager exiting..") return } } diff --git a/test/proxy_test.go b/test/proxy_test.go index af03ea48b..5e5310a0b 100644 --- a/test/proxy_test.go +++ b/test/proxy_test.go @@ -106,7 +106,11 @@ func getTLSConfig() conf.TLSConfig { ReuseSession: true, SessionTicket: true, FallbackAddress: common.NewAddress("127.0.0.1", 10080, "tcp"), - Fingerprint: "firefox", + ALPN: []string{ + "http/1.1", + "h2", + }, + Fingerprint: "firefox", } return c } @@ -153,6 +157,7 @@ func addWsConfig(config *conf.GlobalConfig) *conf.GlobalConfig { Path: "/websocket", ObfuscationPassword: "123456789", DoubleTLS: true, + TLS: getTLSConfig(), } hash := md5.New() hash.Write([]byte(config.Websocket.ObfuscationPassword))