From 486aaa6532e574484f98d99539badab8b6efe015 Mon Sep 17 00:00:00 2001 From: p4gefau1t Date: Sun, 5 Apr 2020 02:22:37 -0400 Subject: [PATCH 1/5] simple logger --- cert/cli.go | 40 ++++++++--------- cert/option.go | 2 +- conf/parse.go | 18 ++++---- go.sum | 1 + log/golog/golog.go | 2 +- log/log.go | 78 ++++++++++++++++++++++++++------ log/simplelog/simplelog.go | 67 ++++++++++++++++++++++++++++ main.go | 6 ++- protocol/direct/outbound.go | 4 +- protocol/mux/mux.go | 2 +- protocol/nat/inbound.go | 2 +- protocol/socks/inbound.go | 6 +-- protocol/trojan/inbound.go | 4 +- protocol/trojan/outbound.go | 12 ++--- proxy/client/client.go | 88 ++++++++++++++++++------------------- proxy/client/mux.go | 16 +++---- proxy/client/nat.go | 24 +++++----- proxy/forward/forward.go | 6 +-- proxy/option.go | 10 ++--- proxy/proxy.go | 10 ++--- proxy/server/server.go | 42 +++++++++--------- router/geo.go | 10 ++--- router/mixed.go | 8 ++-- stat/db.go | 12 ++--- test/proxy_test.go | 6 +-- test/test.go | 2 +- 26 files changed, 300 insertions(+), 178 deletions(-) create mode 100644 log/simplelog/simplelog.go diff --git a/cert/cli.go b/cert/cli.go index 1d2c00c1d..93dc2f414 100644 --- a/cert/cli.go +++ b/cert/cli.go @@ -32,7 +32,7 @@ func askForConfirmation() bool { var response string _, err := fmt.Scanln(&response) if err != nil { - log.DefaultLogger.Fatal(err) + log.Fatal(err) } okayResponses := []string{"y", "Y", "yes", "Yes", "YES"} nokayResponses := []string{"n", "N", "no", "No", "NO"} @@ -47,11 +47,11 @@ func askForConfirmation() bool { } func RequestCertGuide() { - log.DefaultLogger.Info("Guide mode: request cert") + log.Info("Guide mode: request cert") - log.DefaultLogger.Warn("To perform a ACME challenge, trojan-go need the ROOT PRIVILEGE to bind port 80 and 443") - log.DefaultLogger.Warn("Please make sure you HAVE sudo this program, and port 80/443 is NOT used by other process at this moment") - log.DefaultLogger.Info("Continue? (y/n)") + log.Warn("To perform a ACME challenge, trojan-go need the ROOT PRIVILEGE to bind port 80 and 443") + log.Warn("Please make sure you HAVE sudo this program, and port 80/443 is NOT used by other process at this moment") + log.Info("Continue? (y/n)") if !askForConfirmation() { return @@ -66,9 +66,9 @@ func RequestCertGuide() { fmt.Println("Your email:") fmt.Scanf("%s", &info.Email) } else { - log.DefaultLogger.Info("domain_info.json found") + log.Info("domain_info.json found") if err := json.Unmarshal(data, info); err != nil { - log.DefaultLogger.Error(common.NewError("failed to parse domain_info.json").Base(err)) + log.Error(common.NewError("failed to parse domain_info.json").Base(err)) return } } @@ -85,22 +85,22 @@ func RequestCertGuide() { ioutil.WriteFile("domain_info.json", data, os.ModePerm) if err := RequestCert(info.Domain, info.Email); err != nil { - log.DefaultLogger.Error(common.NewError("Failed to create cert").Base(err)) + log.Error(common.NewError("Failed to create cert").Base(err)) return } - log.DefaultLogger.Info("All done. Certificates has been saved to server.crt and server.key") - log.DefaultLogger.Warn("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") - log.DefaultLogger.Warn("BACKUP DOMAIN_INFO.JSON, SERVER.KEY, SERVER.CRT AND USER.KEY TO A SAFE PLACE") - log.DefaultLogger.Warn("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") + log.Info("All done. Certificates has been saved to server.crt and server.key") + log.Warn("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") + log.Warn("BACKUP DOMAIN_INFO.JSON, SERVER.KEY, SERVER.CRT AND USER.KEY TO A SAFE PLACE") + log.Warn("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") } func RenewCertGuide() { - log.DefaultLogger.Info("Guide mode: renew cert") + log.Info("Guide mode: renew cert") - log.DefaultLogger.Warn("To perform a ACME challenge, trojan-go need the ROOT PRIVILEGE to bind port 80 and 443") - log.DefaultLogger.Warn("Please make sure you HAVE sudo this program, and port 80/443 is NOT used by other process at this moment") - log.DefaultLogger.Info("Continue? (y/n)") + log.Warn("To perform a ACME challenge, trojan-go need the ROOT PRIVILEGE to bind port 80 and 443") + log.Warn("Please make sure you HAVE sudo this program, and port 80/443 is NOT used by other process at this moment") + log.Info("Continue? (y/n)") if !askForConfirmation() { return @@ -108,13 +108,13 @@ func RenewCertGuide() { data, err := ioutil.ReadFile("domain_info.json") if err != nil { - log.DefaultLogger.Error(err) + log.Error(err) return } info := &domainInfo{} if err := json.Unmarshal(data, info); err != nil { - log.DefaultLogger.Error(err) + log.Error(err) } fmt.Printf("Domain: %s, Email: %s\n", info.Domain, info.Email) @@ -125,8 +125,8 @@ func RenewCertGuide() { } if err := RenewCert(info.Domain, info.Email); err != nil { - log.DefaultLogger.Error(common.NewError("Failed to renew cert").Base(err)) + log.Error(common.NewError("Failed to renew cert").Base(err)) return } - log.DefaultLogger.Info("All done") + log.Info("All done") } diff --git a/cert/option.go b/cert/option.go index 4834495ea..372259fca 100644 --- a/cert/option.go +++ b/cert/option.go @@ -32,7 +32,7 @@ func (c *certOption) Handle() error { return common.NewError("not specified") default: err := common.NewError("invalid args " + *c.args) - log.DefaultLogger.Error(err) + log.Error(err) return common.NewError("invalid args") } } diff --git a/conf/parse.go b/conf/parse.go index 49bdc81e5..24ff63216 100644 --- a/conf/parse.go +++ b/conf/parse.go @@ -45,7 +45,7 @@ func ParseJSON(data []byte) (*GlobalConfig, error) { return nil, err } - log.DefaultLogger.SetLogLevel(log.LogLevel(config.LogLevel)) + log.SetLogLevel(log.LogLevel(config.LogLevel)) config.Hash = make(map[string]string) for _, password := range config.Passwords { @@ -57,7 +57,7 @@ func ParseJSON(data []byte) (*GlobalConfig, error) { return nil, common.NewError("no password found") } if config.TLS.CertPath == "" { - log.DefaultLogger.Warn("cert of the remote server is not specified. using default CA list.") + log.Warn("cert of the remote server is not specified. using default CA list.") break } serverCertBytes, err := ioutil.ReadFile(config.TLS.CertPath) @@ -149,18 +149,18 @@ func ParseJSON(data []byte) (*GlobalConfig, error) { } if !found { invalid = true - log.DefaultLogger.Warn("found invalid cipher name", specified) + log.Warn("found invalid cipher name", specified) break } } if invalid && len(supportedSuites) >= 1 { - log.DefaultLogger.Warn("cipher list contains invalid cipher name, ignored") - log.DefaultLogger.Warn("here's a list of supported ciphers:") + log.Warn("cipher list contains invalid cipher name, ignored") + log.Warn("here's a list of supported ciphers:") list := "" for _, c := range supportedSuites { list += c.Name + ":" } - log.DefaultLogger.Warn(list[0 : len(list)-1]) + log.Warn(list[0 : len(list)-1]) config.TLS.CipherSuites = nil } } @@ -168,7 +168,7 @@ func ParseJSON(data []byte) (*GlobalConfig, error) { if config.TLS.HTTPFile != "" { payload, err := ioutil.ReadFile(config.TLS.HTTPFile) if err != nil { - log.DefaultLogger.Warn("failed to load http response file", err) + log.Warn("failed to load http response file", err) } config.TLS.HTTPResponse = payload } @@ -231,12 +231,12 @@ func ParseJSON(data []byte) (*GlobalConfig, error) { config.Router.GeoIP, err = ioutil.ReadFile("geoip.dat") if err != nil { config.Router.GeoIP = []byte{} - log.DefaultLogger.Warn(err) + log.Warn(err) } config.Router.GeoSite, err = ioutil.ReadFile("geosite.dat") if err != nil { config.Router.GeoSite = []byte{} - log.DefaultLogger.Warn(err) + log.Warn(err) } return &config, nil } diff --git a/go.sum b/go.sum index 0ff202d84..19d04ae56 100644 --- a/go.sum +++ b/go.sum @@ -303,6 +303,7 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= diff --git a/log/golog/golog.go b/log/golog/golog.go index 52326f471..b9785f48e 100644 --- a/log/golog/golog.go +++ b/log/golog/golog.go @@ -18,7 +18,7 @@ import ( ) func init() { - log.DefaultLogger = New(os.Stdout) + log.RegisterLogger(New(os.Stdout)) } // FdWriter interface extends existing io.Writer with file descriptor function diff --git a/log/log.go b/log/log.go index d0a5624c2..465a796e2 100644 --- a/log/log.go +++ b/log/log.go @@ -9,12 +9,12 @@ import ( type LogLevel int const ( - All LogLevel = 0 - Info LogLevel = 1 - Warn LogLevel = 2 - Error LogLevel = 3 - Fatal LogLevel = 4 - Off LogLevel = 5 + All LogLevel = 0 + InfoLevel LogLevel = 1 + WarnLevel LogLevel = 2 + ErrorLevel LogLevel = 3 + FatalLevel LogLevel = 4 + Off LogLevel = 5 ) type Logger interface { @@ -33,19 +33,15 @@ type Logger interface { SetLogLevel(level LogLevel) } -var DefaultLogger Logger = &EmptyLogger{} +var logger Logger = &EmptyLogger{} type EmptyLogger struct{} func (l *EmptyLogger) SetLogLevel(LogLevel) {} -func (l *EmptyLogger) Fatal(v ...interface{}) { - os.Exit(1) -} +func (l *EmptyLogger) Fatal(v ...interface{}) { os.Exit(1) } -func (l *EmptyLogger) Fatalf(format string, v ...interface{}) { - os.Exit(1) -} +func (l *EmptyLogger) Fatalf(format string, v ...interface{}) { os.Exit(1) } // Error print error message to output func (l *EmptyLogger) Error(v ...interface{}) {} @@ -67,3 +63,59 @@ func (l *EmptyLogger) Debugf(format string, v ...interface{}) {} func (l *EmptyLogger) Trace(v ...interface{}) {} func (l *EmptyLogger) Tracef(format string, v ...interface{}) {} + +func Error(v ...interface{}) { + logger.Error(v...) +} + +func Errorf(format string, v ...interface{}) { + logger.Errorf(format, v...) +} + +func Warn(v ...interface{}) { + logger.Warn(v...) +} + +func Warnf(format string, v ...interface{}) { + logger.Warnf(format, v...) +} + +func Info(v ...interface{}) { + logger.Info(v...) +} + +func Infof(format string, v ...interface{}) { + logger.Warnf(format, v...) +} + +func Debug(v ...interface{}) { + logger.Debug(v...) +} + +func Debugf(format string, v ...interface{}) { + logger.Warnf(format, v...) +} + +func Trace(v ...interface{}) { + logger.Trace(v...) +} + +func Tracef(format string, v ...interface{}) { + logger.Tracef(format, v...) +} + +func Fatal(v ...interface{}) { + logger.Fatal(v...) +} + +func Fatalf(format string, v ...interface{}) { + logger.Fatalf(format, v...) +} + +func SetLogLevel(level LogLevel) { + logger.SetLogLevel(level) +} + +func RegisterLogger(l Logger) { + logger = l +} diff --git a/log/simplelog/simplelog.go b/log/simplelog/simplelog.go new file mode 100644 index 000000000..25d29af17 --- /dev/null +++ b/log/simplelog/simplelog.go @@ -0,0 +1,67 @@ +package simplelog + +import ( + golog "log" + + "github.com/p4gefau1t/trojan-go/log" +) + +func init() { + log.RegisterLogger(&SimpleLogger{}) +} + +type SimpleLogger struct { + logLevel log.LogLevel +} + +func (l *SimpleLogger) SetLogLevel(level log.LogLevel) { + l.logLevel = level +} + +func (l *SimpleLogger) Fatal(v ...interface{}) { + golog.Fatal(v...) +} + +func (l *SimpleLogger) Fatalf(format string, v ...interface{}) { + golog.Fatalf(format, v...) +} + +func (l *SimpleLogger) Error(v ...interface{}) { + golog.Println(v...) +} + +func (l *SimpleLogger) Errorf(format string, v ...interface{}) { + golog.Printf(format, v...) +} + +func (l *SimpleLogger) Warn(v ...interface{}) { + golog.Println(v...) +} + +func (l *SimpleLogger) Warnf(format string, v ...interface{}) { + golog.Printf(format, v...) +} + +func (l *SimpleLogger) Info(v ...interface{}) { + golog.Println(v...) +} + +func (l *SimpleLogger) Infof(format string, v ...interface{}) { + golog.Printf(format, v...) +} + +func (l *SimpleLogger) Debug(v ...interface{}) { + golog.Println(v...) +} + +func (l *SimpleLogger) Debugf(format string, v ...interface{}) { + golog.Printf(format, v...) +} + +func (l *SimpleLogger) Trace(v ...interface{}) { + golog.Println(v...) +} + +func (l *SimpleLogger) Tracef(format string, v ...interface{}) { + golog.Printf(format, v...) +} diff --git a/main.go b/main.go index 4a7214dae..70b67b2f6 100644 --- a/main.go +++ b/main.go @@ -11,7 +11,9 @@ import ( _ "github.com/go-sql-driver/mysql" _ "github.com/p4gefau1t/trojan-go/cert" _ "github.com/p4gefau1t/trojan-go/daemon" - _ "github.com/p4gefau1t/trojan-go/log/golog" + + //_ "github.com/p4gefau1t/trojan-go/log/golog" + _ "github.com/p4gefau1t/trojan-go/log/simplelog" _ "github.com/p4gefau1t/trojan-go/proxy/client" _ "github.com/p4gefau1t/trojan-go/proxy/forward" _ "github.com/p4gefau1t/trojan-go/proxy/server" @@ -23,7 +25,7 @@ func main() { for { h, err := common.PopOptionHandler() if err != nil { - log.DefaultLogger.Fatal("invalid options") + log.Fatal("invalid options") } err = h.Handle() if err == nil { diff --git a/protocol/direct/outbound.go b/protocol/direct/outbound.go index 280ab3c92..8aceac8da 100644 --- a/protocol/direct/outbound.go +++ b/protocol/direct/outbound.go @@ -69,7 +69,7 @@ func (o *DirectOutboundPacketSession) listenConn(req *protocol.Request, conn *ne n, addr, err := conn.ReadFromUDP(buf) conn.SetReadDeadline(time.Time{}) if err != nil { - log.DefaultLogger.Info(err) + log.Info(err) return } if addr.String() != req.String() { @@ -115,7 +115,7 @@ func (o *DirectOutboundPacketSession) WritePacket(req *protocol.Request, packet if err != nil { return 0, common.NewError("cannot dial udp").Base(err) } - log.DefaultLogger.Debug("UDP directly dialing to", remote) + log.Debug("UDP directly dialing to", remote) go o.listenConn(req, conn) n, err := conn.Write(packet) return n, err diff --git a/protocol/mux/mux.go b/protocol/mux/mux.go index f46df1bab..381f8ef1c 100644 --- a/protocol/mux/mux.go +++ b/protocol/mux/mux.go @@ -41,7 +41,7 @@ func (m *MuxConnSession) Write(p []byte) (int, error) { func (m *MuxConnSession) Close() error { m.meter.Count(m.passwordHash, m.sent, m.recv) - log.DefaultLogger.Info("mux conn to", m.request, "closed", "sent:", common.HumanFriendlyTraffic(m.sent), "recv:", common.HumanFriendlyTraffic(m.recv)) + log.Info("mux conn to", m.request, "closed", "sent:", common.HumanFriendlyTraffic(m.sent), "recv:", common.HumanFriendlyTraffic(m.recv)) return m.conn.Close() } diff --git a/protocol/nat/inbound.go b/protocol/nat/inbound.go index 39aa1c613..4dddb14a6 100644 --- a/protocol/nat/inbound.go +++ b/protocol/nat/inbound.go @@ -133,7 +133,7 @@ func (i *NATInboundPacketSession) ReadPacket() (*protocol.Request, []byte, error expire: time.Now().Add(protocol.UDPTimeout), } i.tableMutex.Unlock() - log.DefaultLogger.Debug("tproxy UDP packet from", src, "to", dst) + log.Debug("tproxy UDP packet from", src, "to", dst) req := &protocol.Request{ IP: dst.IP, Port: dst.Port, diff --git a/protocol/socks/inbound.go b/protocol/socks/inbound.go index 5bfcba1e6..6c22941cf 100644 --- a/protocol/socks/inbound.go +++ b/protocol/socks/inbound.go @@ -168,7 +168,7 @@ func (i *SocksInboundPacketSession) cleanExpiredSession() { now := time.Now() for k, v := range i.sessionTable { if now.After(v.expire) { - log.DefaultLogger.Debug("deleting expired session", v.src, "req:", v.req) + log.Debug("deleting expired session", v.src, "req:", v.req) delete(i.sessionTable, k) } } @@ -202,7 +202,7 @@ func (i *SocksInboundPacketSession) ReadPacket() (*protocol.Request, []byte, err i.tableMutex.Lock() i.sessionTable[req.String()] = session i.tableMutex.Unlock() - log.DefaultLogger.Debug("UDP read from", src, "req", req) + log.Debug("UDP read from", src, "req", req) return req, payload, err } @@ -216,7 +216,7 @@ func (i *SocksInboundPacketSession) WritePacket(req *protocol.Request, packet [] if !found { return 0, common.NewError("session not found") } - log.DefaultLogger.Debug("UDP write to", client.src, "req", req) + log.Debug("UDP write to", client.src, "req", req) return i.conn.WriteToUDP(w.Bytes(), client.src) } diff --git a/protocol/trojan/inbound.go b/protocol/trojan/inbound.go index e6b24dd87..dbd63edc7 100644 --- a/protocol/trojan/inbound.go +++ b/protocol/trojan/inbound.go @@ -42,7 +42,7 @@ func (i *TrojanInboundConnSession) Read(p []byte) (int, error) { } func (i *TrojanInboundConnSession) Close() error { - log.DefaultLogger.Info("user", i.passwordHash, "conn to", i.request, "closed", "sent:", common.HumanFriendlyTraffic(i.sent), "recv:", common.HumanFriendlyTraffic(i.recv)) + log.Info("user", i.passwordHash, "conn to", i.request, "closed", "sent:", common.HumanFriendlyTraffic(i.sent), "recv:", common.HumanFriendlyTraffic(i.recv)) i.meter.Count(i.passwordHash, i.sent, i.recv) return i.conn.Close() } @@ -66,7 +66,7 @@ func (i *TrojanInboundConnSession) parseRequest() error { Port: i.config.RemotePort, NetworkType: "tcp", } - log.DefaultLogger.Warn("remote", i.conn.RemoteAddr(), "invalid hash or other protocol:", string(userHash)) + log.Warn("remote", i.conn.RemoteAddr(), "invalid hash or other protocol:", string(userHash)) return nil } i.passwordHash = string(userHash) diff --git a/protocol/trojan/outbound.go b/protocol/trojan/outbound.go index 7738e8773..5cc4b2861 100644 --- a/protocol/trojan/outbound.go +++ b/protocol/trojan/outbound.go @@ -35,7 +35,7 @@ func (o *TrojanOutboundConnSession) Read(p []byte) (int, error) { } func (o *TrojanOutboundConnSession) Close() error { - log.DefaultLogger.Info("conn to", o.request, "closed", "sent:", common.HumanFriendlyTraffic(o.sent), "recv:", common.HumanFriendlyTraffic(o.recv)) + log.Info("conn to", o.request, "closed", "sent:", common.HumanFriendlyTraffic(o.sent), "recv:", common.HumanFriendlyTraffic(o.recv)) return o.conn.Close() } @@ -80,15 +80,15 @@ func NewOutboundConnSession(req *protocol.Request, conn io.ReadWriteCloser, conf if config.LogLevel == 0 { state := tlsConn.ConnectionState() chain := state.VerifiedChains - log.DefaultLogger.Debug("tls handshaked", "cipher", tls.CipherSuiteName(state.CipherSuite)) - log.DefaultLogger.Debug("chains:") + log.Debug("tls handshaked", "cipher", tls.CipherSuiteName(state.CipherSuite)) + log.Debug("chains:") for i := range chain { - log.DefaultLogger.Debug("--------------------------------") + log.Debug("--------------------------------") for j := range chain[i] { - log.DefaultLogger.Debug("subject:", chain[i][j].Subject, "issuer:", chain[i][j].Issuer) + log.Debug("subject:", chain[i][j].Subject, "issuer:", chain[i][j].Issuer) } } - log.DefaultLogger.Debug("--------------------------------") + log.Debug("--------------------------------") } conn = tlsConn } diff --git a/proxy/client/client.go b/proxy/client/client.go index 27fa7701f..1e4127750 100644 --- a/proxy/client/client.go +++ b/proxy/client/client.go @@ -45,9 +45,9 @@ func (c *Client) listenUDP() { common.Must(err) for { for t := <-c.associatedChan; time.Now().Sub(t) > protocol.UDPTimeout; t = <-c.associatedChan { - log.DefaultLogger.Debug("expired udp request, skipping") + log.Debug("expired udp request, skipping") } - log.DefaultLogger.Debug("associated signal") + log.Debug("associated signal") req := &protocol.Request{ DomainName: []byte("UDP_CONN"), AddressType: protocol.DomainName, @@ -55,7 +55,7 @@ func (c *Client) listenUDP() { } tunnel, err := trojan.NewOutboundConnSession(req, nil, c.config) if err != nil { - log.DefaultLogger.Error(err) + log.Error(err) continue } trojanOutbound, err := trojan.NewPacketSession(tunnel) @@ -75,7 +75,7 @@ func (c *Client) listenUDP() { func (c *Client) handleSocksConn(conn net.Conn, rw *bufio.ReadWriter) { inboundConn, err := socks.NewInboundConnSession(conn, rw) if err != nil { - log.DefaultLogger.Error(common.NewError("failed to start new inbound session").Base(err)) + log.Error(common.NewError("failed to start new inbound session").Base(err)) return } defer inboundConn.Close() @@ -93,67 +93,67 @@ func (c *Client) handleSocksConn(conn net.Conn, rw *bufio.ReadWriter) { } //notify listenUDP to get ready for relaying udp packets c.associatedChan <- time.Now() - log.DefaultLogger.Info("UDP associated to", req) + log.Info("UDP associated to", req) if err := inboundConn.(protocol.NeedRespond).Respond(); err != nil { - log.DefaultLogger.Error("failed to repsond") + log.Error("failed to repsond") } //stop relaying UDP once TCP connection is closed var buf [1]byte _, err = conn.Read(buf[:]) - log.DefaultLogger.Debug(common.NewError("UDP conn ends").Base(err)) + log.Debug(common.NewError("UDP conn ends").Base(err)) return } if err := inboundConn.(protocol.NeedRespond).Respond(); err != nil { - log.DefaultLogger.Error(common.NewError("failed to respond").Base(err)) + log.Error(common.NewError("failed to respond").Base(err)) return } policy, err := c.router.RouteRequest(req) if err != nil { - log.DefaultLogger.Error(err) + log.Error(err) return } if policy == router.Bypass { outboundConn, err := direct.NewOutboundConnSession(nil, req) if err != nil { - log.DefaultLogger.Error(err) + log.Error(err) return } - log.DefaultLogger.Info("[bypass]conn from", conn.RemoteAddr(), "to", req) + log.Info("[bypass]conn from", conn.RemoteAddr(), "to", req) proxy.ProxyConn(inboundConn, outboundConn) return } else if policy == router.Block { - log.DefaultLogger.Info("[block]conn from", conn.RemoteAddr(), "to", req) + log.Info("[block]conn from", conn.RemoteAddr(), "to", req) return } if c.config.Mux.Enabled { stream, info, err := c.mux.OpenMuxConn() if err != nil { - log.DefaultLogger.Error(common.NewError("failed to open mux stream").Base(err)) + log.Error(common.NewError("failed to open mux stream").Base(err)) return } outboundConn, err := mux.NewOutboundMuxConnSession(stream, req) if err != nil { stream.Close() - log.DefaultLogger.Error(common.NewError("fail to start trojan session over mux conn").Base(err)) + log.Error(common.NewError("fail to start trojan session over mux conn").Base(err)) return } defer outboundConn.Close() - log.DefaultLogger.Info("conn from", conn.RemoteAddr(), "mux tunneling to", req, "mux id", info.id) + log.Info("conn from", conn.RemoteAddr(), "mux tunneling to", req, "mux id", info.id) proxy.ProxyConn(inboundConn, outboundConn) } else { outboundConn, err := trojan.NewOutboundConnSession(req, nil, c.config) if err != nil { - log.DefaultLogger.Error(common.NewError("failed to start new outbound session").Base(err)) + log.Error(common.NewError("failed to start new outbound session").Base(err)) return } defer outboundConn.Close() - log.DefaultLogger.Info("conn from", conn.RemoteAddr(), "tunneling to", req) + log.Info("conn from", conn.RemoteAddr(), "tunneling to", req) proxy.ProxyConn(inboundConn, outboundConn) } } @@ -161,7 +161,7 @@ func (c *Client) handleSocksConn(conn net.Conn, rw *bufio.ReadWriter) { func (c *Client) handleHTTPConn(conn net.Conn, rw *bufio.ReadWriter) { inboundConn, inboundPacket, err := http.NewHTTPInbound(conn, rw) if err != nil { - log.DefaultLogger.Error(common.NewError("failed to start new inbound session:").Base(err)) + log.Error(common.NewError("failed to start new inbound session:").Base(err)) return } if inboundConn != nil { @@ -169,53 +169,53 @@ func (c *Client) handleHTTPConn(conn net.Conn, rw *bufio.ReadWriter) { req := inboundConn.GetRequest() if err := inboundConn.(protocol.NeedRespond).Respond(); err != nil { - log.DefaultLogger.Error(common.NewError("failed to respond").Base(err)) + log.Error(common.NewError("failed to respond").Base(err)) return } policy, err := c.router.RouteRequest(req) if err != nil { - log.DefaultLogger.Error(err) + log.Error(err) return } if policy == router.Bypass { outboundConn, err := direct.NewOutboundConnSession(nil, req) if err != nil { - log.DefaultLogger.Error(err) + log.Error(err) return } - log.DefaultLogger.Info("[bypass]conn from", conn.RemoteAddr(), "to", req) + log.Info("[bypass]conn from", conn.RemoteAddr(), "to", req) proxy.ProxyConn(inboundConn, outboundConn) return } else if policy == router.Block { - log.DefaultLogger.Info("[block]conn from", conn.RemoteAddr(), "to", req) + log.Info("[block]conn from", conn.RemoteAddr(), "to", req) return } if c.config.Mux.Enabled { stream, info, err := c.mux.OpenMuxConn() if err != nil { - log.DefaultLogger.Error(common.NewError("failed to open mux stream").Base(err)) + log.Error(common.NewError("failed to open mux stream").Base(err)) return } defer stream.Close() outboundConn, err := mux.NewOutboundMuxConnSession(stream, req) if err != nil { - log.DefaultLogger.Error(common.NewError("fail to start trojan session over mux conn").Base(err)) + log.Error(common.NewError("fail to start trojan session over mux conn").Base(err)) return } defer outboundConn.Close() - log.DefaultLogger.Info("conn from", conn.RemoteAddr(), "mux tunneling to", req, "mux id", info.id) + log.Info("conn from", conn.RemoteAddr(), "mux tunneling to", req, "mux id", info.id) proxy.ProxyConn(inboundConn, outboundConn) } else { outboundConn, err := trojan.NewOutboundConnSession(req, nil, c.config) if err != nil { - log.DefaultLogger.Error(common.NewError("failed to start new outbound session").Base(err)) + log.Error(common.NewError("failed to start new outbound session").Base(err)) return } defer outboundConn.Close() - log.DefaultLogger.Info("conn from", conn.RemoteAddr(), "tunneling to", req) + log.Info("conn from", conn.RemoteAddr(), "tunneling to", req) proxy.ProxyConn(inboundConn, outboundConn) } } else { @@ -226,7 +226,7 @@ func (c *Client) handleHTTPConn(conn net.Conn, rw *bufio.ReadWriter) { for { req, packet, err := inboundPacket.ReadPacket() if err != nil { - log.DefaultLogger.Error(err) + log.Error(err) return } packetChan <- &packetInfo{ @@ -244,25 +244,25 @@ func (c *Client) handleHTTPConn(conn net.Conn, rw *bufio.ReadWriter) { if c.config.Mux.Enabled { stream, info, err := c.mux.OpenMuxConn() if err != nil { - log.DefaultLogger.Error(common.NewError("failed to open mux stream").Base(err)) + log.Error(common.NewError("failed to open mux stream").Base(err)) continue } outboundConn, err = mux.NewOutboundMuxConnSession(stream, packet.request) if err != nil { - log.DefaultLogger.Error(common.NewError("fail to start trojan session over mux conn").Base(err)) + log.Error(common.NewError("fail to start trojan session over mux conn").Base(err)) continue } - log.DefaultLogger.Info("conn from", conn.RemoteAddr(), "mux tunneling to", packet.request, "mux id", info.id) + log.Info("conn from", conn.RemoteAddr(), "mux tunneling to", packet.request, "mux id", info.id) } else { outboundConn, err = trojan.NewOutboundConnSession(packet.request, nil, c.config) if err != nil { - log.DefaultLogger.Error(err) + log.Error(err) continue } } _, err = outboundConn.Write(packet.packet) if err != nil { - log.DefaultLogger.Error(err) + log.Error(err) continue } go func(outboundConn protocol.ConnSession) { @@ -271,11 +271,11 @@ func (c *Client) handleHTTPConn(conn net.Conn, rw *bufio.ReadWriter) { for { n, err := outboundConn.Read(buf[:]) if err != nil { - log.DefaultLogger.Debug(err) + log.Debug(err) return } if _, err = inboundPacket.WritePacket(nil, buf[0:n]); err != nil { - log.DefaultLogger.Debug(err) + log.Debug(err) return } } @@ -299,7 +299,7 @@ func (c *Client) Run() error { } defer listener.Close() - log.DefaultLogger.Info("client is running at", listener.Addr()) + log.Info("client is running at", listener.Addr()) for { conn, err := listener.Accept() if err != nil { @@ -307,13 +307,13 @@ func (c *Client) Run() error { case <-c.ctx.Done(): default: } - log.DefaultLogger.Error(common.NewError("error occured when accpeting conn").Base(err)) + log.Error(common.NewError("error occured when accpeting conn").Base(err)) continue } rw := common.NewBufReadWriter(conn) tmp, err := rw.Peek(1) if err != nil { - log.DefaultLogger.Error(common.NewError("failed to obtain proxy type").Base(err)) + log.Error(common.NewError("failed to obtain proxy type").Base(err)) conn.Close() continue } @@ -326,7 +326,7 @@ func (c *Client) Run() error { } func (c *Client) Close() error { - log.DefaultLogger.Info("shutting down client..") + log.Info("shutting down client..") c.cancel() return nil } @@ -339,17 +339,17 @@ func (c *Client) Build(config *conf.GlobalConfig) (common.Runnable, error) { c.associatedChan = make(chan time.Time, 512) var err error if config.Mux.Enabled { - log.DefaultLogger.Info("mux enabled") + log.Info("mux enabled") c.mux, err = NewMuxPoolManager(c.ctx, config) if err != nil { - log.DefaultLogger.Fatal(err) + log.Fatal(err) } } if config.Router.Enabled { - log.DefaultLogger.Info("router enabled") + log.Info("router enabled") c.router, err = router.NewMixedRouter(config) if err != nil { - log.DefaultLogger.Fatal(common.NewError("invalid router list").Base(err)) + log.Fatal(common.NewError("invalid router list").Base(err)) } } c.config = config diff --git a/proxy/client/mux.go b/proxy/client/mux.go index 21007c4a4..d5d31c5bc 100644 --- a/proxy/client/mux.go +++ b/proxy/client/mux.go @@ -45,13 +45,13 @@ func (m *muxPoolManager) newMuxClient() (*muxClientInfo, error) { } conn, err := trojan.NewOutboundConnSession(req, nil, m.config) if err != nil { - log.DefaultLogger.Error(common.NewError("failed to dial tls tunnel").Base(err)) + log.Error(common.NewError("failed to dial tls tunnel").Base(err)) return nil, err } client, err := smux.Client(conn, nil) common.Must(err) - log.DefaultLogger.Info("mux TLS tunnel established, id:", id) + log.Info("mux TLS tunnel established, id:", id) return &muxClientInfo{ client: client, id: id, @@ -66,7 +66,7 @@ func (m *muxPoolManager) pickMuxClient() (*muxClientInfo, error) { for _, info := range m.muxPool { if info.client.IsClosed() { delete(m.muxPool, info.id) - log.DefaultLogger.Info("mux", info.id, "is dead") + log.Info("mux", info.id, "is dead") continue } if info.client.NumStreams() < m.config.Mux.Concurrency || m.config.Mux.Concurrency <= 0 { @@ -102,7 +102,7 @@ func (m *muxPoolManager) checkAndCloseIdleMuxClient() { if m.config.Mux.IdleTimeout <= 0 { muxIdleDuration = 0 checkDuration = time.Second * 10 - log.DefaultLogger.Warn("invalid mux idle timeout") + log.Warn("invalid mux idle timeout") } else { muxIdleDuration = time.Duration(m.config.Mux.IdleTimeout) * time.Second checkDuration = muxIdleDuration / 4 @@ -114,22 +114,22 @@ func (m *muxPoolManager) checkAndCloseIdleMuxClient() { for id, info := range m.muxPool { if info.client.IsClosed() { delete(m.muxPool, id) - log.DefaultLogger.Info("mux", id, "is dead") + log.Info("mux", id, "is dead") } else if info.client.NumStreams() == 0 && time.Now().Sub(info.lastActiveTime) > muxIdleDuration { info.client.Close() delete(m.muxPool, id) - log.DefaultLogger.Info("mux", id, "is closed due to inactive") + log.Info("mux", id, "is closed due to inactive") } } if len(m.muxPool) != 0 { - log.DefaultLogger.Info("current mux pool conn num", len(m.muxPool)) + log.Info("current mux pool conn num", len(m.muxPool)) } m.Unlock() case <-m.ctx.Done(): m.Lock() for id, info := range m.muxPool { info.client.Close() - log.DefaultLogger.Info("mux", id, "closed") + log.Info("mux", id, "closed") } m.Unlock() return diff --git a/proxy/client/nat.go b/proxy/client/nat.go index 857c6e53f..01583ddd0 100644 --- a/proxy/client/nat.go +++ b/proxy/client/nat.go @@ -31,7 +31,7 @@ type NAT struct { func (n *NAT) handleConn(conn net.Conn) { inbound, err := nat.NewInboundConnSession(conn) if err != nil { - log.DefaultLogger.Error(common.NewError("failed to start inbound session").Base(err)) + log.Error(common.NewError("failed to start inbound session").Base(err)) return } req := inbound.GetRequest() @@ -39,34 +39,34 @@ func (n *NAT) handleConn(conn net.Conn) { if n.config.Mux.Enabled { stream, info, err := n.mux.OpenMuxConn() if err != nil { - log.DefaultLogger.Error(common.NewError("failed to open mux stream").Base(err)) + log.Error(common.NewError("failed to open mux stream").Base(err)) return } outbound, err := mux.NewOutboundMuxConnSession(stream, req) if err != nil { stream.Close() - log.DefaultLogger.Error(common.NewError("failed to start mux outbound session").Base(err)) + log.Error(common.NewError("failed to start mux outbound session").Base(err)) return } defer outbound.Close() - log.DefaultLogger.Info("[transparent]conn from", conn.RemoteAddr(), "mux tunneling to", req, "mux id", info.id) + log.Info("[transparent]conn from", conn.RemoteAddr(), "mux tunneling to", req, "mux id", info.id) proxy.ProxyConn(inbound, outbound) return } outbound, err := trojan.NewOutboundConnSession(req, nil, n.config) if err != nil { - log.DefaultLogger.Error("failed to start outbound session", err) + log.Error("failed to start outbound session", err) return } defer outbound.Close() - log.DefaultLogger.Info("[transparent]conn from", conn.RemoteAddr(), "tunneling to", req) + log.Info("[transparent]conn from", conn.RemoteAddr(), "tunneling to", req) proxy.ProxyConn(inbound, outbound) } func (n *NAT) listenUDP() { inbound, err := nat.NewInboundPacketSession(n.config) if err != nil { - log.DefaultLogger.Fatal(err) + log.Fatal(err) } n.packetInbound = inbound defer inbound.Close() @@ -83,7 +83,7 @@ func (n *NAT) listenUDP() { return default: } - log.DefaultLogger.Error(err) + log.Error(err) continue } outbound, err := trojan.NewPacketSession(tunnel) @@ -95,7 +95,7 @@ func (n *NAT) listenUDP() { func (n *NAT) Run() error { go n.listenUDP() - log.DefaultLogger.Info("nat running at", n.config.LocalAddr) + log.Info("nat running at", n.config.LocalAddr) listener, err := net.ListenTCP("tcp", &net.TCPAddr{ IP: n.config.LocalIP, Port: int(n.config.LocalPort), @@ -113,7 +113,7 @@ func (n *NAT) Run() error { return nil default: } - log.DefaultLogger.Error(err) + log.Error(err) continue } go n.handleConn(conn) @@ -121,7 +121,7 @@ func (n *NAT) Run() error { } func (n *NAT) Close() error { - log.DefaultLogger.Info("shutting down nat...") + log.Info("shutting down nat...") n.cancel() n.listener.Close() n.packetInbound.Close() @@ -134,7 +134,7 @@ func (n *NAT) Build(config *conf.GlobalConfig) (common.Runnable, error) { if config.Mux.Enabled { mux, err := NewMuxPoolManager(n.ctx, config) if err != nil { - log.DefaultLogger.Fatal(err) + log.Fatal(err) } n.mux = mux } diff --git a/proxy/forward/forward.go b/proxy/forward/forward.go index e8df0b8d2..0389d9faa 100644 --- a/proxy/forward/forward.go +++ b/proxy/forward/forward.go @@ -20,7 +20,7 @@ type Forward struct { func (f *Forward) handleConn(conn net.Conn) { newConn, err := net.Dial("tcp", f.config.RemoteAddr.String()) if err != nil { - log.DefaultLogger.Error("failed to connect to remote endpoint:", err) + log.Error("failed to connect to remote endpoint:", err) return } proxy.ProxyConn(newConn, conn) @@ -40,7 +40,7 @@ func (f *Forward) Run() error { return nil default: } - log.DefaultLogger.Error(err) + log.Error(err) continue } go f.handleConn(conn) @@ -48,7 +48,7 @@ func (f *Forward) Run() error { } func (f *Forward) Close() error { - log.DefaultLogger.Info("shutting down forward..") + log.Info("shutting down forward..") f.cancel() return nil } diff --git a/proxy/option.go b/proxy/option.go index dd605d505..cf8e2b352 100644 --- a/proxy/option.go +++ b/proxy/option.go @@ -25,18 +25,18 @@ func (*proxyOption) Priority() int { } func (c *proxyOption) Handle() error { - log.DefaultLogger.Info("Trojan-Go proxy initializing...") + log.Info("Trojan-Go proxy initializing...") data, err := ioutil.ReadFile(*c.args) if err != nil { - log.DefaultLogger.Fatal(common.NewError("Failed to read config file").Base(err)) + log.Fatal(common.NewError("Failed to read config file").Base(err)) } config, err := conf.ParseJSON(data) if err != nil { - log.DefaultLogger.Fatal(common.NewError("Failed to parse config file").Base(err)) + log.Fatal(common.NewError("Failed to parse config file").Base(err)) } proxy, err := NewProxy(config) if err != nil { - log.DefaultLogger.Fatal(err) + log.Fatal(err) } errChan := make(chan error) go func() { @@ -50,7 +50,7 @@ func (c *proxyOption) Handle() error { proxy.Close() return nil case err := <-errChan: - log.DefaultLogger.Fatal(err) + log.Fatal(err) return err } } diff --git a/proxy/proxy.go b/proxy/proxy.go index 8d141095b..9410c7ae2 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -24,7 +24,7 @@ func ProxyConn(a, b io.ReadWriteCloser) { go copyConn(b, a) err := <-errChan if err != nil { - log.DefaultLogger.Debug(common.NewError("conn proxy ends").Base(err)) + log.Debug(common.NewError("conn proxy ends").Base(err)) } } @@ -48,7 +48,7 @@ func ProxyPacket(a, b protocol.PacketReadWriter) { go copyPacket(b, a) err := <-errChan if err != nil { - log.DefaultLogger.Debug(common.NewError("packet proxy ends").Base(err)) + log.Debug(common.NewError("packet proxy ends").Base(err)) } } @@ -82,10 +82,10 @@ func ProxyPacketWithRouter(from protocol.PacketReadWriter, table map[router.Poli } to, found := table[policy] if !found { - log.DefaultLogger.Debug("policy not found, skipping:", policy) + log.Debug("policy not found, skipping:", policy) continue } - log.DefaultLogger.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 @@ -100,7 +100,7 @@ func ProxyPacketWithRouter(from protocol.PacketReadWriter, table map[router.Poli go copyToDst() err := <-errChan if err != nil { - log.DefaultLogger.Debug(common.NewError("packet proxy with routing ends").Base(err)) + log.Debug(common.NewError("packet proxy with routing ends").Base(err)) } } diff --git a/proxy/server/server.go b/proxy/server/server.go index 7b19ae3ef..3f2c986b0 100644 --- a/proxy/server/server.go +++ b/proxy/server/server.go @@ -35,22 +35,22 @@ func (s *Server) handleMuxConn(stream *smux.Stream, passwordHash string) { inboundConn, err := mux.NewInboundMuxConnSession(stream, passwordHash) if err != nil { stream.Close() - log.DefaultLogger.Error(common.NewError("cannot start inbound session").Base(err)) + log.Error(common.NewError("cannot start inbound session").Base(err)) return } inboundConn.(protocol.NeedMeter).SetMeter(s.meter) defer inboundConn.Close() req := inboundConn.GetRequest() if req.Command != protocol.Connect { - log.DefaultLogger.Error("mux only support tcp now") + log.Error("mux only support tcp now") return } outboundConn, err := direct.NewOutboundConnSession(nil, req) if err != nil { - log.DefaultLogger.Error(err) + log.Error(err) return } - log.DefaultLogger.Info("user", passwordHash, "mux tunneling to", req.String()) + log.Info("user", passwordHash, "mux tunneling to", req.String()) defer outboundConn.Close() proxy.ProxyConn(inboundConn, outboundConn) } @@ -58,7 +58,7 @@ func (s *Server) handleMuxConn(stream *smux.Stream, passwordHash string) { func (s *Server) handleConn(conn net.Conn) { inboundConn, err := trojan.NewInboundConnSession(conn, s.config, s.auth) if err != nil { - log.DefaultLogger.Error(common.NewError("failed to start inbound session, remote:" + conn.RemoteAddr().String()).Base(err)) + log.Error(common.NewError("failed to start inbound session, remote:" + conn.RemoteAddr().String()).Base(err)) return } @@ -72,7 +72,7 @@ func (s *Server) handleConn(conn net.Conn) { for { stream, err := muxServer.AcceptStream() if err != nil { - log.DefaultLogger.Debug("mux conn from", conn.RemoteAddr(), "closed: ", err) + log.Debug("mux conn from", conn.RemoteAddr(), "closed: ", err) return } go s.handleMuxConn(stream, hash) @@ -86,32 +86,32 @@ func (s *Server) handleConn(conn net.Conn) { outboundPacket, err := direct.NewOutboundPacketSession() if err != nil { - log.DefaultLogger.Error(err) + log.Error(err) return } defer outboundPacket.Close() - log.DefaultLogger.Info("UDP associated") + log.Info("UDP associated") proxy.ProxyPacket(inboundPacket, outboundPacket) - log.DefaultLogger.Info("UDP tunnel closed") + log.Info("UDP tunnel closed") return } defer inboundConn.Close() outboundConn, err := direct.NewOutboundConnSession(nil, req) if err != nil { - log.DefaultLogger.Error(err) + log.Error(err) return } defer outboundConn.Close() - log.DefaultLogger.Info("conn from", conn.RemoteAddr(), "tunneling to", req.String()) + log.Info("conn from", conn.RemoteAddr(), "tunneling to", req.String()) proxy.ProxyConn(inboundConn, outboundConn) } func (s *Server) handleInvalidConn(conn net.Conn, tlsConn *tls.Conn) { defer conn.Close() if len(s.config.TLS.HTTPResponse) > 0 { - log.DefaultLogger.Warn("trying to response with a plain http response") + log.Warn("trying to response with a plain http response") conn.Write(s.config.TLS.HTTPResponse) return } @@ -119,25 +119,25 @@ func (s *Server) handleInvalidConn(conn net.Conn, tlsConn *tls.Conn) { if s.config.TLS.FallbackAddr != nil { defer func() { if r := recover(); r != nil { - log.DefaultLogger.Error("recovered", r) + log.Error("recovered", r) } }() //HACK //obtain the bytes buffered by the tls conn v := reflect.ValueOf(*tlsConn) buf := v.FieldByName("rawInput").FieldByName("buf").Bytes() - log.DefaultLogger.Debug("payload:" + string(buf)) + log.Debug("payload:" + string(buf)) remote, err := net.Dial("tcp", s.config.TLS.FallbackAddr.String()) if err != nil { - log.DefaultLogger.Warn(common.NewError("failed to dial to tls fallback server").Base(err)) + log.Warn(common.NewError("failed to dial to tls fallback server").Base(err)) return } - log.DefaultLogger.Warn("proxying this invalid tls conn to the tls fallback server") + log.Warn("proxying this invalid tls conn to the tls fallback server") remote.Write(buf) proxy.ProxyConn(conn, remote) } else { - log.DefaultLogger.Warn("fallback port is unspecified, closing") + log.Warn("fallback port is unspecified, closing") } } @@ -175,7 +175,7 @@ func (s *Server) Run() error { } defer s.auth.Close() defer s.meter.Close() - log.DefaultLogger.Info("server is running at", s.config.LocalAddr) + log.Info("server is running at", s.config.LocalAddr) var listener net.Listener if s.config.TCP.ReusePort || s.config.TCP.FastOpen || s.config.TCP.NoDelay { @@ -212,13 +212,13 @@ func (s *Server) Run() error { return nil default: } - log.DefaultLogger.Warn(err) + log.Warn(err) continue } tlsConn := tls.Server(conn, tlsConfig) err = tlsConn.Handshake() if err != nil { - log.DefaultLogger.Warn(common.NewError("failed to perform tls handshake, remote:" + conn.RemoteAddr().String()).Base(err)) + log.Warn(common.NewError("failed to perform tls handshake, remote:" + conn.RemoteAddr().String()).Base(err)) go s.handleInvalidConn(conn, tlsConn) continue } @@ -227,7 +227,7 @@ func (s *Server) Run() error { } func (s *Server) Close() error { - log.DefaultLogger.Info("shutting down server..") + log.Info("shutting down server..") if s.listener != nil { s.listener.Close() } diff --git a/router/geo.go b/router/geo.go index cb2f38e5e..a5e1523b1 100644 --- a/router/geo.go +++ b/router/geo.go @@ -52,7 +52,7 @@ func (r *GeoRouter) matchDomain(fulldomain string) bool { //expregexp.Compile(site.GetValue()) matched, err := regexp.Match(d.GetValue(), []byte(fulldomain)) if err != nil { - log.DefaultLogger.Error("invalid regex") + log.Error("invalid regex") } if matched { return true @@ -150,9 +150,9 @@ func (r *GeoRouter) LoadGeoData(geoipData []byte, ipCode []string, geositeData [ } } if found { - log.DefaultLogger.Info("geoip tag", c, "loaded") + log.Info("geoip tag", c, "loaded") } else { - log.DefaultLogger.Warn("geoip tag", c, "not found") + log.Warn("geoip tag", c, "not found") } } @@ -173,9 +173,9 @@ func (r *GeoRouter) LoadGeoData(geoipData []byte, ipCode []string, geositeData [ } } if found { - log.DefaultLogger.Info("geosite tag", c, "loaded") + log.Info("geosite tag", c, "loaded") } else { - log.DefaultLogger.Warn("geosite tag", c, "not found") + log.Warn("geosite tag", c, "not found") } } return nil diff --git a/router/mixed.go b/router/mixed.go index 4bbd43206..f9d1b3ce2 100644 --- a/router/mixed.go +++ b/router/mixed.go @@ -20,7 +20,7 @@ type MixedRouter struct { func (r *MixedRouter) match(router Router, req *protocol.Request) bool { policy, err := router.RouteRequest(req) if err != nil { - log.DefaultLogger.Warn(common.NewError("match error").Base(err)) + log.Warn(common.NewError("match error").Base(err)) return false } if policy == match { @@ -95,15 +95,15 @@ func NewMixedRouter(config *conf.GlobalConfig) (Router, error) { if err := r.blockGeo.LoadGeoData(config.Router.GeoIP, config.Router.BlockIPCode, config.Router.GeoSite, config.Router.BlockSiteCode); err != nil { //return nil, err - log.DefaultLogger.Warn(err) + log.Warn(err) } if err := r.bypassGeo.LoadGeoData(config.Router.GeoIP, config.Router.BypassIPCode, config.Router.GeoSite, config.Router.BypassSiteCode); err != nil { //return nil, err - log.DefaultLogger.Warn(err) + log.Warn(err) } if err := r.proxyGeo.LoadGeoData(config.Router.GeoIP, config.Router.ProxyIPCode, config.Router.GeoSite, config.Router.ProxySiteCode); err != nil { //return nil, err - log.DefaultLogger.Warn(err) + log.Warn(err) } return r, nil } diff --git a/stat/db.go b/stat/db.go index 8f2e76af3..613f7dd85 100644 --- a/stat/db.go +++ b/stat/db.go @@ -69,7 +69,7 @@ func (c *DBTrafficMeter) dbDaemon() { } tx, err := c.db.Begin() if err != nil { - log.DefaultLogger.Error(common.NewError("cannot begin transactin").Base(err)) + log.Error(common.NewError("cannot begin transactin").Base(err)) continue } for _, traffic := range statBuffer { @@ -83,15 +83,15 @@ func (c *DBTrafficMeter) dbDaemon() { _, err = s.Exec(traffic.sent, traffic.passwordHash) if err != nil { - log.DefaultLogger.Error(common.NewError("failed to update data to tx").Base(err)) + log.Error(common.NewError("failed to update data to tx").Base(err)) break } } err = tx.Commit() if err != nil { - log.DefaultLogger.Error(common.NewError("failed to commit tx").Base(err)) + log.Error(common.NewError("failed to commit tx").Base(err)) } else { - log.DefaultLogger.Info("buffered data has been written into the database") + log.Info("buffered data has been written into the database") } } } @@ -136,7 +136,7 @@ func (a *DBAuthenticator) updateDaemon() { for { rows, err := a.db.Query("SELECT password,quota,download,upload FROM users") if err != nil { - log.DefaultLogger.Error(common.NewError("failed to pull data from the database").Base(err)) + log.Error(common.NewError("failed to pull data from the database").Base(err)) time.Sleep(a.updateDuration) continue } @@ -146,7 +146,7 @@ func (a *DBAuthenticator) updateDaemon() { var quota, download, upload int64 err := rows.Scan(&passwordHash, "a, &download, &upload) if err != nil { - log.DefaultLogger.Error(common.NewError("failed to obtain data from the query result").Base(err)) + log.Error(common.NewError("failed to obtain data from the query result").Base(err)) break } if download+upload < quota || quota < 0 { diff --git a/test/proxy_test.go b/test/proxy_test.go index 00d9efb4e..0bc301d16 100644 --- a/test/proxy_test.go +++ b/test/proxy_test.go @@ -228,7 +228,7 @@ func TestRouterClient(t *testing.T) { func TestClientAndServer(t *testing.T) { go func() { err := http.ListenAndServe("0.0.0.0:8000", nil) - log.DefaultLogger.Error(err) + log.Error(err) }() go TestClient(t) TestServer(t) @@ -237,7 +237,7 @@ func TestClientAndServer(t *testing.T) { func TestMuxClientAndServer(t *testing.T) { go func() { err := http.ListenAndServe("0.0.0.0:8000", nil) - log.DefaultLogger.Error(err) + log.Error(err) }() go TestMuxClient(t) TestServer(t) @@ -246,7 +246,7 @@ func TestMuxClientAndServer(t *testing.T) { func TestRouterClientAndServer(t *testing.T) { go func() { err := http.ListenAndServe("0.0.0.0:8000", nil) - log.DefaultLogger.Error(err) + log.Error(err) }() go TestRouterClient(t) TestServer(t) diff --git a/test/test.go b/test/test.go index 7672ba3a4..eda66892d 100644 --- a/test/test.go +++ b/test/test.go @@ -21,7 +21,7 @@ func RunEchoUDPServer(port int) { buf := make([]byte, protocol.MaxUDPPacketSize) n, addr, err := conn.ReadFromUDP(buf[:]) common.Must(err) - log.DefaultLogger.Info("echo from", addr) + log.Info("echo from", addr) conn.WriteToUDP(buf[0:n], addr) } } From f4f869c527a6d21ecb817866fe78d10092ee3b3d Mon Sep 17 00:00:00 2001 From: p4gefau1t Date: Sun, 5 Apr 2020 03:33:55 -0400 Subject: [PATCH 2/5] fix tiny bugs --- log/golog/golog.go | 2 +- log/log.go | 4 +- log/simplelog/simplelog.go | 48 +++++++++---- main.go | 5 +- protocol/http/http.go | 38 ----------- protocol/http/inbound.go | 134 +++++++++++++++++-------------------- 6 files changed, 101 insertions(+), 130 deletions(-) delete mode 100644 protocol/http/http.go diff --git a/log/golog/golog.go b/log/golog/golog.go index b9785f48e..4486f4034 100644 --- a/log/golog/golog.go +++ b/log/golog/golog.go @@ -206,7 +206,7 @@ func (l *Logger) Output(depth int, prefix Prefix, data string) error { var pc uintptr // Get the caller filename and line - if pc, file, line, ok = runtime.Caller(depth + 1); !ok { + if pc, file, line, ok = runtime.Caller(depth + 2); !ok { file = "" fn = "" line = 0 diff --git a/log/log.go b/log/log.go index 465a796e2..592fe191e 100644 --- a/log/log.go +++ b/log/log.go @@ -9,12 +9,12 @@ import ( type LogLevel int const ( - All LogLevel = 0 + AllLevel LogLevel = 0 InfoLevel LogLevel = 1 WarnLevel LogLevel = 2 ErrorLevel LogLevel = 3 FatalLevel LogLevel = 4 - Off LogLevel = 5 + OffLevel LogLevel = 5 ) type Logger interface { diff --git a/log/simplelog/simplelog.go b/log/simplelog/simplelog.go index 25d29af17..684c5612e 100644 --- a/log/simplelog/simplelog.go +++ b/log/simplelog/simplelog.go @@ -19,49 +19,73 @@ func (l *SimpleLogger) SetLogLevel(level log.LogLevel) { } func (l *SimpleLogger) Fatal(v ...interface{}) { - golog.Fatal(v...) + if l.logLevel <= log.FatalLevel { + golog.Fatal(v...) + } } func (l *SimpleLogger) Fatalf(format string, v ...interface{}) { - golog.Fatalf(format, v...) + if l.logLevel <= log.FatalLevel { + golog.Fatalf(format, v...) + } } func (l *SimpleLogger) Error(v ...interface{}) { - golog.Println(v...) + if l.logLevel <= log.ErrorLevel { + golog.Println(v...) + } } func (l *SimpleLogger) Errorf(format string, v ...interface{}) { - golog.Printf(format, v...) + if l.logLevel <= log.ErrorLevel { + golog.Printf(format, v...) + } } func (l *SimpleLogger) Warn(v ...interface{}) { - golog.Println(v...) + if l.logLevel <= log.WarnLevel { + golog.Println(v...) + } } func (l *SimpleLogger) Warnf(format string, v ...interface{}) { - golog.Printf(format, v...) + if l.logLevel <= log.WarnLevel { + golog.Printf(format, v...) + } } func (l *SimpleLogger) Info(v ...interface{}) { - golog.Println(v...) + if l.logLevel <= log.InfoLevel { + golog.Println(v...) + } } func (l *SimpleLogger) Infof(format string, v ...interface{}) { - golog.Printf(format, v...) + if l.logLevel <= log.InfoLevel { + golog.Printf(format, v...) + } } func (l *SimpleLogger) Debug(v ...interface{}) { - golog.Println(v...) + if l.logLevel <= log.AllLevel { + golog.Println(v...) + } } func (l *SimpleLogger) Debugf(format string, v ...interface{}) { - golog.Printf(format, v...) + if l.logLevel <= log.AllLevel { + golog.Printf(format, v...) + } } func (l *SimpleLogger) Trace(v ...interface{}) { - golog.Println(v...) + if l.logLevel <= log.AllLevel { + golog.Println(v...) + } } func (l *SimpleLogger) Tracef(format string, v ...interface{}) { - golog.Printf(format, v...) + if l.logLevel <= log.AllLevel { + golog.Printf(format, v...) + } } diff --git a/main.go b/main.go index 70b67b2f6..096583f75 100644 --- a/main.go +++ b/main.go @@ -11,13 +11,12 @@ import ( _ "github.com/go-sql-driver/mysql" _ "github.com/p4gefau1t/trojan-go/cert" _ "github.com/p4gefau1t/trojan-go/daemon" - - //_ "github.com/p4gefau1t/trojan-go/log/golog" - _ "github.com/p4gefau1t/trojan-go/log/simplelog" + _ "github.com/p4gefau1t/trojan-go/log/golog" _ "github.com/p4gefau1t/trojan-go/proxy/client" _ "github.com/p4gefau1t/trojan-go/proxy/forward" _ "github.com/p4gefau1t/trojan-go/proxy/server" _ "github.com/p4gefau1t/trojan-go/version" + //_ "github.com/p4gefau1t/trojan-go/log/simplelog" ) func main() { diff --git a/protocol/http/http.go b/protocol/http/http.go deleted file mode 100644 index c0f5cefa1..000000000 --- a/protocol/http/http.go +++ /dev/null @@ -1,38 +0,0 @@ -package http - -import ( - "bufio" - "bytes" - "io" - - "github.com/p4gefau1t/trojan-go/common" - "github.com/p4gefau1t/trojan-go/protocol" -) - -func NewHTTPInbound(conn io.ReadWriteCloser, rw *bufio.ReadWriter) (protocol.ConnSession, protocol.PacketSession, error) { - var bufReadWriter *bufio.ReadWriter - if rw == nil { - bufReadWriter = common.NewBufReadWriter(conn) - } else { - bufReadWriter = rw - } - method, err := bufReadWriter.Peek(7) - if err != nil { - return nil, nil, err - } - if bytes.Equal(method, []byte("CONNECT")) { - i := &HTTPInboundTunnelConnSession{ - bufReadWriter: bufReadWriter, - conn: conn, - } - if err := i.parseRequest(); err != nil { - return nil, nil, common.NewError("failed to parse http header").Base(err) - } - return i, nil, nil - } - i := &HTTPInboundPacketSession{ - bufReadWriter: bufReadWriter, - conn: conn, - } - return nil, i, nil -} diff --git a/protocol/http/inbound.go b/protocol/http/inbound.go index a2cd41bd2..6c32f5d31 100644 --- a/protocol/http/inbound.go +++ b/protocol/http/inbound.go @@ -7,11 +7,41 @@ import ( "io" "net" "net/http" + "strconv" "github.com/p4gefau1t/trojan-go/common" "github.com/p4gefau1t/trojan-go/protocol" ) +func parseHTTPRequest(httpRequest *http.Request) *protocol.Request { + request := &protocol.Request{ + NetworkType: "tcp", + Port: 80, + Command: protocol.Connect, + } + host, port, err := net.SplitHostPort(httpRequest.Host) + if err != nil { + if ip := net.ParseIP(httpRequest.Host); ip != nil { + request.IP = ip + if ip.To4() != nil { + request.AddressType = protocol.IPv4 + } else { + request.AddressType = protocol.IPv6 + } + } else { + request.DomainName = []byte(httpRequest.Host) + request.AddressType = protocol.DomainName + } + } else { + request.DomainName = []byte(host) + request.AddressType = protocol.DomainName + n, err := strconv.ParseInt(port, 10, 16) + common.Must(err) + request.Port = int(n) + } + return request +} + type HTTPInboundTunnelConnSession struct { protocol.ConnSession protocol.NeedRespond @@ -60,59 +90,10 @@ func (i *HTTPInboundTunnelConnSession) parseRequest() error { } i.bodyReader = httpRequest.Body i.httpRequest = httpRequest - i.request = &protocol.Request{ - NetworkType: "tcp", - Port: 80, - Command: protocol.Connect, - } - host, port, err := net.SplitHostPort(httpRequest.Host) - if err != nil { - if ip := net.ParseIP(httpRequest.Host); ip != nil { - i.request.IP = ip - if ip.To4() != nil { - i.request.AddressType = protocol.IPv4 - } else { - i.request.AddressType = protocol.IPv6 - } - } else { - i.request.DomainName = []byte(httpRequest.Host) - i.request.AddressType = protocol.DomainName - } - } else { - i.request.DomainName = []byte(host) - i.request.AddressType = protocol.DomainName - fmt.Sscanf(port, "%d", &i.request.Port) - } + i.request = parseHTTPRequest(httpRequest) return nil } -func parseHTTPRequest(httpRequest *http.Request) *protocol.Request { - request := &protocol.Request{ - NetworkType: "tcp", - Port: 80, - Command: protocol.Connect, - } - host, port, err := net.SplitHostPort(httpRequest.Host) - if err != nil { - if ip := net.ParseIP(httpRequest.Host); ip != nil { - request.IP = ip - if ip.To4() != nil { - request.AddressType = protocol.IPv4 - } else { - request.AddressType = protocol.IPv6 - } - } else { - request.DomainName = []byte(httpRequest.Host) - request.AddressType = protocol.DomainName - } - } else { - request.DomainName = []byte(host) - request.AddressType = protocol.DomainName - fmt.Sscanf(port, "%d", &request.Port) - } - return request -} - type HTTPInboundPacketSession struct { protocol.PacketSession @@ -145,30 +126,7 @@ func (i *HTTPInboundPacketSession) ReadPacket() (*protocol.Request, []byte, erro if err != nil { return nil, nil, err } - request := &protocol.Request{ - NetworkType: "tcp", - Port: 80, - Command: protocol.Connect, - } - host, port, err := net.SplitHostPort(httpRequest.Host) - if err != nil { - if ip := net.ParseIP(httpRequest.Host); ip != nil { - request.IP = ip - if ip.To4() != nil { - request.AddressType = protocol.IPv4 - } else { - request.AddressType = protocol.IPv6 - } - } else { - request.DomainName = []byte(httpRequest.Host) - request.AddressType = protocol.DomainName - } - } else { - request.DomainName = []byte(host) - request.AddressType = protocol.DomainName - fmt.Sscanf(port, "%d", &request.Port) - } - //packet, err := httputil.DumpRequest(httpRequest, true) + request := parseHTTPRequest(httpRequest) buf := bytes.NewBuffer([]byte{}) err = httpRequest.Write(buf) common.Must(err) @@ -180,3 +138,31 @@ func (i *HTTPInboundPacketSession) WritePacket(req *protocol.Request, packet []b i.bufReadWriter.Flush() return n, err } + +func NewHTTPInbound(conn io.ReadWriteCloser, rw *bufio.ReadWriter) (protocol.ConnSession, protocol.PacketSession, error) { + var bufReadWriter *bufio.ReadWriter + if rw == nil { + bufReadWriter = common.NewBufReadWriter(conn) + } else { + bufReadWriter = rw + } + method, err := bufReadWriter.Peek(7) + if err != nil { + return nil, nil, err + } + if bytes.Equal(method, []byte("CONNECT")) { + i := &HTTPInboundTunnelConnSession{ + bufReadWriter: bufReadWriter, + conn: conn, + } + if err := i.parseRequest(); err != nil { + return nil, nil, common.NewError("failed to parse http header").Base(err) + } + return i, nil, nil + } + i := &HTTPInboundPacketSession{ + bufReadWriter: bufReadWriter, + conn: conn, + } + return nil, i, nil +} From 539eb3645f40f83f613d9b804ba2adda8b11e3fe Mon Sep 17 00:00:00 2001 From: p4gefau1t Date: Sun, 5 Apr 2020 12:33:39 -0400 Subject: [PATCH 3/5] allow unlimited udp assotiate requests --- conf/conf.go | 2 ++ conf/parse.go | 13 ++++++++++--- protocol/socks/inbound.go | 3 +++ proxy/client/client.go | 11 ++++++++--- proxy/client/mux.go | 5 +++++ test/proxy_test.go | 2 +- 6 files changed, 29 insertions(+), 7 deletions(-) diff --git a/conf/conf.go b/conf/conf.go index 7355be14f..b77f7ef0d 100644 --- a/conf/conf.go +++ b/conf/conf.go @@ -79,6 +79,8 @@ type RouterConfig struct { DefaultPolicy string `json:"default_policy"` RouteByIP bool `json:"route_by_ip"` RouteByIPOnNonmatch bool `json:"route_by_ip_on_nonmatch"` + GeoIPFilename string `json:"geoip"` + GeoSiteFilename string `json:"geosite"` BypassList []byte ProxyList []byte diff --git a/conf/parse.go b/conf/parse.go index 24ff63216..86e43bb26 100644 --- a/conf/parse.go +++ b/conf/parse.go @@ -39,6 +39,8 @@ func ParseJSON(data []byte) (*GlobalConfig, error) { config.Mux.Concurrency = 8 config.MySQL.CheckRate = 60 config.Router.DefaultPolicy = "proxy" + config.Router.GeoIPFilename = "geoip.dat" + config.Router.GeoSiteFilename = "geosite.dat" err := json.Unmarshal(data, &config) if err != nil { @@ -106,7 +108,7 @@ func ParseJSON(data []byte) (*GlobalConfig, error) { } case Forward: default: - return nil, common.NewError("invalid run type") + return nil, common.NewError("invalid run type:" + string(config.RunType)) } localAddr, err := convertToAddr(config.TCP.PreferIPV4, config.LocalHost, config.LocalPort) @@ -228,15 +230,20 @@ func ParseJSON(data []byte) (*GlobalConfig, error) { config.Router.ProxyList = append(config.Router.ProxyList, byte('\n')) } - config.Router.GeoIP, err = ioutil.ReadFile("geoip.dat") + config.Router.GeoIP, err = ioutil.ReadFile(config.Router.GeoIPFilename) if err != nil { config.Router.GeoIP = []byte{} log.Warn(err) } - config.Router.GeoSite, err = ioutil.ReadFile("geosite.dat") + config.Router.GeoSite, err = ioutil.ReadFile(config.Router.GeoSiteFilename) if err != nil { config.Router.GeoSite = []byte{} log.Warn(err) } + + if config.TLS.SNI == "" { + log.Warn("SNI is unspecified, using remote_addr as SNI") + config.TLS.SNI = config.RemoteHost + } return &config, nil } diff --git a/protocol/socks/inbound.go b/protocol/socks/inbound.go index 6c22941cf..3892c299b 100644 --- a/protocol/socks/inbound.go +++ b/protocol/socks/inbound.go @@ -212,10 +212,13 @@ func (i *SocksInboundPacketSession) WritePacket(req *protocol.Request, packet [] return 0, err } w.Write(packet) + i.tableMutex.Lock() + defer i.tableMutex.Unlock() client, found := i.sessionTable[req.String()] if !found { return 0, common.NewError("session not found") } + client.expire = time.Now().Add(protocol.UDPTimeout) log.Debug("UDP write to", client.src, "req", req) return i.conn.WriteToUDP(w.Bytes(), client.src) } diff --git a/proxy/client/client.go b/proxy/client/client.go index 1e4127750..5c9d3f133 100644 --- a/proxy/client/client.go +++ b/proxy/client/client.go @@ -55,7 +55,7 @@ func (c *Client) listenUDP() { } tunnel, err := trojan.NewOutboundConnSession(req, nil, c.config) if err != nil { - log.Error(err) + log.Error(common.NewError("failed to open udp tunnel").Base(err)) continue } trojanOutbound, err := trojan.NewPacketSession(tunnel) @@ -92,8 +92,13 @@ func (c *Client) handleSocksConn(conn net.Conn, rw *bufio.ReadWriter) { req.AddressType = protocol.IPv6 } //notify listenUDP to get ready for relaying udp packets + select { + case <-c.associatedChan: + log.Debug("replacing older udp associate request..") + default: + } c.associatedChan <- time.Now() - log.Info("UDP associated to", req) + log.Info("UDP associated, req", req) if err := inboundConn.(protocol.NeedRespond).Respond(); err != nil { log.Error("failed to repsond") } @@ -336,7 +341,7 @@ func (c *Client) Build(config *conf.GlobalConfig) (common.Runnable, error) { c.router = &router.EmptyRouter{ DefaultPolicy: router.Proxy, } - c.associatedChan = make(chan time.Time, 512) + c.associatedChan = make(chan time.Time, 1) var err error if config.Mux.Enabled { log.Info("mux enabled") diff --git a/proxy/client/mux.go b/proxy/client/mux.go index d5d31c5bc..37c413b2d 100644 --- a/proxy/client/mux.go +++ b/proxy/client/mux.go @@ -91,6 +91,11 @@ func (m *muxPoolManager) OpenMuxConn() (*smux.Stream, *muxClientInfo, error) { } stream, err := info.client.OpenStream() if err != nil { + m.Lock() + defer m.Unlock() + delete(m.muxPool, info.id) + info.client.Close() + log.Info("somthing wrong with mux", info.id, ", closing") return nil, nil, err } info.lastActiveTime = time.Now() diff --git a/test/proxy_test.go b/test/proxy_test.go index 0bc301d16..bf564efd4 100644 --- a/test/proxy_test.go +++ b/test/proxy_test.go @@ -254,7 +254,7 @@ func TestRouterClientAndServer(t *testing.T) { func TestClientServerJSON(t *testing.T) { go TestServerJSON(t) - TestClient(t) + TestClientJSON(t) } func BenchmarkNormalClientToServer(b *testing.B) { From 2d8d5da64a728b999f277badf101140ac12bffdd Mon Sep 17 00:00:00 2001 From: p4gefau1t Date: Sun, 5 Apr 2020 13:47:01 -0400 Subject: [PATCH 4/5] add systemd, prepare for v0.1.0 --- common/common.go | 13 ++++++++++++- conf/parse.go | 5 +++-- data/trojan-go.service | 16 ++++++++++++++++ proxy/client/client.go | 3 +++ proxy/option.go | 8 +++++--- 5 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 data/trojan-go.service diff --git a/common/common.go b/common/common.go index c11766b86..619b3a767 100644 --- a/common/common.go +++ b/common/common.go @@ -5,10 +5,13 @@ import ( "crypto/sha256" "fmt" "io" + "log" + "os" + "path/filepath" ) const ( - Version = "v0.0.17" + Version = "v0.1.0" ) type Runnable interface { @@ -49,3 +52,11 @@ func HumanFriendlyTraffic(bytes int) string { } return fmt.Sprintf("%.2f GiB", float32(bytes)/GiB) } + +func GetProgramDir() string { + dir, err := filepath.Abs(filepath.Dir(os.Args[0])) + if err != nil { + log.Fatal(err) + } + return dir +} diff --git a/conf/parse.go b/conf/parse.go index 86e43bb26..b061cc4fb 100644 --- a/conf/parse.go +++ b/conf/parse.go @@ -39,8 +39,9 @@ func ParseJSON(data []byte) (*GlobalConfig, error) { config.Mux.Concurrency = 8 config.MySQL.CheckRate = 60 config.Router.DefaultPolicy = "proxy" - config.Router.GeoIPFilename = "geoip.dat" - config.Router.GeoSiteFilename = "geosite.dat" + + config.Router.GeoIPFilename = common.GetProgramDir() + "/geoip.dat" + config.Router.GeoSiteFilename = common.GetProgramDir() + "/geosite.dat" err := json.Unmarshal(data, &config) if err != nil { diff --git a/data/trojan-go.service b/data/trojan-go.service new file mode 100644 index 000000000..8d5df05c0 --- /dev/null +++ b/data/trojan-go.service @@ -0,0 +1,16 @@ +[Unit] +Description=Trojan-Go - An unidentifiable mechanism that helps you bypass GFW +Documentation=https://github.com/p4gefau1t/trojan-go +After=network.target nss-lookup.target +Wants=network-online.target + +[Service] +Type=simple +User=root +ExecStart=/usr/bin/trojan-go/trojan-go -config /etc/trojan-go/config.json +Restart=on-failure +RestartSec=10 +RestartPreventExitStatus=23 + +[Install] +WantedBy=multi-user.target diff --git a/proxy/client/client.go b/proxy/client/client.go index 5c9d3f133..8b600f25b 100644 --- a/proxy/client/client.go +++ b/proxy/client/client.go @@ -41,6 +41,9 @@ func (c *Client) listenUDP() { IP: c.config.LocalIP, Port: int(c.config.LocalPort), }) + if err != nil { + log.Fatal("failed to listen udp") + } inbound, err := socks.NewInboundPacketSession(listener) common.Must(err) for { diff --git a/proxy/option.go b/proxy/option.go index cf8e2b352..0ce174ac5 100644 --- a/proxy/option.go +++ b/proxy/option.go @@ -28,11 +28,13 @@ func (c *proxyOption) Handle() error { log.Info("Trojan-Go proxy initializing...") data, err := ioutil.ReadFile(*c.args) if err != nil { - log.Fatal(common.NewError("Failed to read config file").Base(err)) + log.Error(common.NewError("Failed to read config file").Base(err)) + os.Exit(23) } config, err := conf.ParseJSON(data) if err != nil { - log.Fatal(common.NewError("Failed to parse config file").Base(err)) + log.Error(common.NewError("Failed to parse config file").Base(err)) + os.Exit(23) } proxy, err := NewProxy(config) if err != nil { @@ -57,6 +59,6 @@ func (c *proxyOption) Handle() error { func init() { common.RegisterOptionHandler(&proxyOption{ - args: flag.String("config", "config.json", "Config filename"), + args: flag.String("config", common.GetProgramDir()+"/config.json", "Config filename"), }) } From 0175c20d004bc0efe1804268967cef59b8c7bf69 Mon Sep 17 00:00:00 2001 From: p4gefau1t Date: Sun, 5 Apr 2020 23:46:29 -0400 Subject: [PATCH 5/5] split client/server config parsing, detailed log --- build-all.sh | 5 +- conf/parse.go | 229 ++++++++++++++++++++++-------------- protocol/trojan/outbound.go | 12 +- proxy/option.go | 1 + router/mixed.go | 5 +- version/version.go | 2 +- 6 files changed, 146 insertions(+), 108 deletions(-) diff --git a/build-all.sh b/build-all.sh index 8e9b413b4..c55ca3fb0 100755 --- a/build-all.sh +++ b/build-all.sh @@ -126,12 +126,13 @@ done cp ../data/*.dat ./ cp ../data/*.json ./ +cp ../data/*.service ./ for name in *.zip;do - zip -ur $name ./*.dat ./*.json + zip -ur $name ./*.dat ./*.json ./*.service sha1sum $name > $name.sha1 done rm ./*.dat rm ./*.json - +rm ./*.service diff --git a/conf/parse.go b/conf/parse.go index b061cc4fb..30ccaaa09 100644 --- a/conf/parse.go +++ b/conf/parse.go @@ -28,100 +28,30 @@ func convertToAddr(preferV4 bool, host string, port int) (*net.TCPAddr, error) { return net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", host, port)) } -func ParseJSON(data []byte) (*GlobalConfig, error) { - var config GlobalConfig - - //default settings - config.TLS.Verify = true - config.TLS.VerifyHostname = true - config.TLS.SessionTicket = true - config.Mux.IdleTimeout = 60 - config.Mux.Concurrency = 8 - config.MySQL.CheckRate = 60 - config.Router.DefaultPolicy = "proxy" - - config.Router.GeoIPFilename = common.GetProgramDir() + "/geoip.dat" - config.Router.GeoSiteFilename = common.GetProgramDir() + "/geosite.dat" - - err := json.Unmarshal(data, &config) - if err != nil { - return nil, err - } - +func loadCommonConfig(config *GlobalConfig) error { + //log level log.SetLogLevel(log.LogLevel(config.LogLevel)) + //password settings + if len(config.Passwords) == 0 { + return common.NewError("no password found") + } config.Hash = make(map[string]string) for _, password := range config.Passwords { config.Hash[common.SHA224String(password)] = password } - switch config.RunType { - case Client, NAT: - if len(config.Passwords) == 0 { - return nil, common.NewError("no password found") - } - if config.TLS.CertPath == "" { - log.Warn("cert of the remote server is not specified. using default CA list.") - break - } - serverCertBytes, err := ioutil.ReadFile(config.TLS.CertPath) - if err != nil { - return nil, common.NewError("failed to load cert file").Base(err) - } - pool := x509.NewCertPool() - pool.AppendCertsFromPEM(serverCertBytes) - config.TLS.CertPool = pool - case Server: - if len(config.Passwords) == 0 { - return nil, common.NewError("no password found") - } - if config.TLS.KeyPassword != "" { - keyFile, err := ioutil.ReadFile(config.TLS.KeyPath) - if err != nil { - return nil, common.NewError("failed to load key file").Base(err) - } - keyBlock, _ := pem.Decode(keyFile) - if keyBlock == nil { - return nil, common.NewError("failed to decode key file").Base(err) - } - decryptedKey, err := x509.DecryptPEMBlock(keyBlock, []byte(config.TLS.KeyPassword)) - if err == nil { - return nil, common.NewError("failed to decrypt key").Base(err) - } - - certFile, err := ioutil.ReadFile(config.TLS.CertPath) - certBlock, _ := pem.Decode(certFile) - if certBlock == nil { - return nil, common.NewError("failed to decode cert file").Base(err) - } - - keyPair, err := tls.X509KeyPair(certBlock.Bytes, decryptedKey) - if err != nil { - return nil, err - } - - config.TLS.KeyPair = []tls.Certificate{keyPair} - } else { - keyPair, err := tls.LoadX509KeyPair(config.TLS.CertPath, config.TLS.KeyPath) - if err != nil { - return nil, common.NewError("failed to load key pair").Base(err) - } - config.TLS.KeyPair = []tls.Certificate{keyPair} - } - case Forward: - default: - return nil, common.NewError("invalid run type:" + string(config.RunType)) - } + //address settings localAddr, err := convertToAddr(config.TCP.PreferIPV4, config.LocalHost, config.LocalPort) if err != nil { - return nil, common.NewError("invalid local address").Base(err) + return common.NewError("invalid local address").Base(err) } config.LocalAddr = localAddr config.LocalIP = localAddr.IP remoteAddr, err := convertToAddr(config.TCP.PreferIPV4, config.RemoteHost, config.RemotePort) if err != nil { - return nil, common.NewError("invalid remote address").Base(err) + return common.NewError("invalid remote address").Base(err) } config.RemoteAddr = remoteAddr config.RemoteIP = remoteAddr.IP @@ -129,11 +59,12 @@ func ParseJSON(data []byte) (*GlobalConfig, error) { if config.TLS.FallbackPort != 0 { fallbackAddr, err := convertToAddr(config.TCP.PreferIPV4, config.RemoteHost, config.TLS.FallbackPort) if err != nil { - return nil, common.NewError("invalid tls fallback address").Base(err) + return common.NewError("invalid tls fallback address").Base(err) } config.TLS.FallbackAddr = fallbackAddr } + //tls settings if config.TLS.Cipher != "" || config.TLS.CipherTLS13 != "" { specifiedSuites := strings.Split(config.TLS.Cipher+":"+config.TLS.CipherTLS13, ":") supportedSuites := tls.CipherSuites() @@ -167,15 +98,13 @@ func ParseJSON(data []byte) (*GlobalConfig, error) { config.TLS.CipherSuites = nil } } + return nil +} - if config.TLS.HTTPFile != "" { - payload, err := ioutil.ReadFile(config.TLS.HTTPFile) - if err != nil { - log.Warn("failed to load http response file", err) - } - config.TLS.HTTPResponse = payload - } +func loadClientConfig(config *GlobalConfig) error { + var err error + //router settings config.Router.BlockList = []byte{} config.Router.ProxyList = []byte{} config.Router.BypassList = []byte{} @@ -191,7 +120,7 @@ func ParseJSON(data []byte) (*GlobalConfig, error) { } data, err := ioutil.ReadFile(s) if err != nil { - return nil, err + return err } config.Router.BlockList = append(config.Router.BlockList, data...) config.Router.BlockList = append(config.Router.BlockList, byte('\n')) @@ -208,7 +137,7 @@ func ParseJSON(data []byte) (*GlobalConfig, error) { } data, err := ioutil.ReadFile(s) if err != nil { - return nil, err + return err } config.Router.BypassList = append(config.Router.BypassList, data...) config.Router.BypassList = append(config.Router.BypassList, byte('\n')) @@ -225,7 +154,7 @@ func ParseJSON(data []byte) (*GlobalConfig, error) { } data, err := ioutil.ReadFile(s) if err != nil { - return nil, err + return err } config.Router.ProxyList = append(config.Router.ProxyList, data...) config.Router.ProxyList = append(config.Router.ProxyList, byte('\n')) @@ -242,9 +171,127 @@ func ParseJSON(data []byte) (*GlobalConfig, error) { log.Warn(err) } + //tls settings if config.TLS.SNI == "" { log.Warn("SNI is unspecified, using remote_addr as SNI") config.TLS.SNI = config.RemoteHost } - return &config, nil + if config.TLS.CertPath == "" { + log.Info("cert of the remote server is not specified, using default CA list") + return nil + } + + caCertByte, err := ioutil.ReadFile(config.TLS.CertPath) + if err != nil { + return common.NewError("failed to load cert file").Base(err) + } + pool := x509.NewCertPool() + ok := pool.AppendCertsFromPEM(caCertByte) + if !ok { + log.Warn("invalid CA cert list") + } + log.Info("using custom CA list") + pemCerts := caCertByte + for len(pemCerts) > 0 { + config.TLS.CertPool = pool + var block *pem.Block + block, pemCerts = pem.Decode(pemCerts) + if block == nil { + break + } + if block.Type != "CERTIFICATE" || len(block.Headers) != 0 { + continue + } + cert, err := x509.ParseCertificate(block.Bytes) + if err != nil { + continue + } + log.Debug("issuer:", cert.Issuer, ", subject:", cert.Subject) + } + + return nil +} + +func loadServerConfig(config *GlobalConfig) error { + if config.TLS.KeyPassword != "" { + keyFile, err := ioutil.ReadFile(config.TLS.KeyPath) + if err != nil { + return common.NewError("failed to load key file").Base(err) + } + keyBlock, _ := pem.Decode(keyFile) + if keyBlock == nil { + return common.NewError("failed to decode key file").Base(err) + } + decryptedKey, err := x509.DecryptPEMBlock(keyBlock, []byte(config.TLS.KeyPassword)) + if err == nil { + return common.NewError("failed to decrypt key").Base(err) + } + + certFile, err := ioutil.ReadFile(config.TLS.CertPath) + certBlock, _ := pem.Decode(certFile) + if certBlock == nil { + return common.NewError("failed to decode cert file").Base(err) + } + + keyPair, err := tls.X509KeyPair(certBlock.Bytes, decryptedKey) + if err != nil { + return err + } + + config.TLS.KeyPair = []tls.Certificate{keyPair} + } else { + keyPair, err := tls.LoadX509KeyPair(config.TLS.CertPath, config.TLS.KeyPath) + if err != nil { + return common.NewError("failed to load key pair").Base(err) + } + config.TLS.KeyPair = []tls.Certificate{keyPair} + } + if config.TLS.HTTPFile != "" { + payload, err := ioutil.ReadFile(config.TLS.HTTPFile) + if err != nil { + log.Warn("failed to load http response file", err) + } + config.TLS.HTTPResponse = payload + } + return nil +} + +func ParseJSON(data []byte) (*GlobalConfig, error) { + config := &GlobalConfig{} + + //default settings + config.TLS.Verify = true + config.TLS.VerifyHostname = true + config.TLS.SessionTicket = true + config.Mux.IdleTimeout = 60 + config.Mux.Concurrency = 8 + config.MySQL.CheckRate = 60 + config.Router.DefaultPolicy = "proxy" + config.Router.GeoIPFilename = common.GetProgramDir() + "/geoip.dat" + config.Router.GeoSiteFilename = common.GetProgramDir() + "/geosite.dat" + + err := json.Unmarshal(data, config) + if err != nil { + return nil, err + } + + if err := loadCommonConfig(config); err != nil { + return nil, err + } + + switch config.RunType { + case Client, NAT: + if err := loadClientConfig(config); err != nil { + return nil, err + } + case Server: + if err := loadServerConfig(config); err != nil { + return nil, err + } + case Forward: + default: + return nil, common.NewError("invalid run type:" + string(config.RunType)) + } + + return config, nil } diff --git a/protocol/trojan/outbound.go b/protocol/trojan/outbound.go index 5cc4b2861..b7a316ea8 100644 --- a/protocol/trojan/outbound.go +++ b/protocol/trojan/outbound.go @@ -72,23 +72,15 @@ func NewOutboundConnSession(req *protocol.Request, conn io.ReadWriteCloser, conf if err != nil { return nil, common.NewError("cannot dial to the remote server").Base(err) } - if config.TLS.VerifyHostname { - if err := tlsConn.VerifyHostname(config.TLS.SNI); err != nil { - return nil, common.NewError("failed to verify hostname").Base(err) - } - } if config.LogLevel == 0 { state := tlsConn.ConnectionState() chain := state.VerifiedChains - log.Debug("tls handshaked", "cipher", tls.CipherSuiteName(state.CipherSuite)) - log.Debug("chains:") + log.Debug("TLS handshaked", "cipher:", tls.CipherSuiteName(state.CipherSuite), "resume:", state.DidResume) for i := range chain { - log.Debug("--------------------------------") for j := range chain[i] { - log.Debug("subject:", chain[i][j].Subject, "issuer:", chain[i][j].Issuer) + log.Debug("subject:", chain[i][j].Subject, ", issuer:", chain[i][j].Issuer) } } - log.Debug("--------------------------------") } conn = tlsConn } diff --git a/proxy/option.go b/proxy/option.go index 0ce174ac5..1a2ebf558 100644 --- a/proxy/option.go +++ b/proxy/option.go @@ -26,6 +26,7 @@ func (*proxyOption) Priority() int { func (c *proxyOption) Handle() error { log.Info("Trojan-Go proxy initializing...") + log.Info("Loading config file from", *c.args) data, err := ioutil.ReadFile(*c.args) if err != nil { log.Error(common.NewError("Failed to read config file").Base(err)) diff --git a/router/mixed.go b/router/mixed.go index f9d1b3ce2..46613b646 100644 --- a/router/mixed.go +++ b/router/mixed.go @@ -89,20 +89,17 @@ func NewMixedRouter(config *conf.GlobalConfig) (Router, error) { return nil, err } - r.blockGeo, _ = NewGeoRouter(match, nonMatch, routeByIP, routeByIPOnNonmatch) + r.blockGeo, _ = NewGeoRouter(match, nonMatch, routeByIP, false) r.bypassGeo, _ = NewGeoRouter(match, nonMatch, routeByIP, routeByIPOnNonmatch) r.proxyGeo, _ = NewGeoRouter(match, nonMatch, routeByIP, routeByIPOnNonmatch) if err := r.blockGeo.LoadGeoData(config.Router.GeoIP, config.Router.BlockIPCode, config.Router.GeoSite, config.Router.BlockSiteCode); err != nil { - //return nil, err log.Warn(err) } if err := r.bypassGeo.LoadGeoData(config.Router.GeoIP, config.Router.BypassIPCode, config.Router.GeoSite, config.Router.BypassSiteCode); err != nil { - //return nil, err log.Warn(err) } if err := r.proxyGeo.LoadGeoData(config.Router.GeoIP, config.Router.ProxyIPCode, config.Router.GeoSite, config.Router.ProxySiteCode); err != nil { - //return nil, err log.Warn(err) } return r, nil diff --git a/version/version.go b/version/version.go index 531cd0e87..d5c6e5d3c 100644 --- a/version/version.go +++ b/version/version.go @@ -17,7 +17,7 @@ func (*versionOption) Name() string { } func (*versionOption) Priority() int { - return 0 + return 10 } func (c *versionOption) Handle() error {