diff --git a/.github/ISSUE_TEMPLATE b/.github/ISSUE_TEMPLATE index 858c31a..f9f7fae 100644 --- a/.github/ISSUE_TEMPLATE +++ b/.github/ISSUE_TEMPLATE @@ -1,5 +1,7 @@ Issue is only used for submiting bug report and documents typo. If there are same issues or answers can be found in documents, we will close it directly. (为了节约时间,提高处理问题的效率,不按照格式填写的 issue 将会直接关闭。) +(请不要在 issue 评论中出现无意义的 **加1**,**我也是** 等内容,将会被直接删除。) +(由于个人精力有限,和系统环境,网络环境等相关的求助问题请转至其他论坛或社交平台。) Use the commands below to provide key information from your environment: You do NOT have to include this information if this is a FEATURE REQUEST diff --git a/cmd/frpc/sub/reload.go b/cmd/frpc/sub/reload.go index 647bf1e..46118c3 100644 --- a/cmd/frpc/sub/reload.go +++ b/cmd/frpc/sub/reload.go @@ -76,17 +76,16 @@ func reload() error { resp, err := http.DefaultClient.Do(req) if err != nil { return err - } else { - if resp.StatusCode == 200 { - return nil - } - - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return err - } - return fmt.Errorf("code [%d], %s", resp.StatusCode, strings.TrimSpace(string(body))) } - return nil + defer resp.Body.Close() + + if resp.StatusCode == 200 { + return nil + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + return fmt.Errorf("code [%d], %s", resp.StatusCode, strings.TrimSpace(string(body))) } diff --git a/cmd/frpc/sub/status.go b/cmd/frpc/sub/status.go index 883c7a7..8f55ce1 100644 --- a/cmd/frpc/sub/status.go +++ b/cmd/frpc/sub/status.go @@ -78,76 +78,78 @@ func status() error { resp, err := http.DefaultClient.Do(req) if err != nil { return err - } else { - if resp.StatusCode != 200 { - return fmt.Errorf("admin api status code [%d]", resp.StatusCode) - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return err - } - res := &client.StatusResp{} - err = json.Unmarshal(body, &res) - if err != nil { - return fmt.Errorf("unmarshal http response error: %s", strings.TrimSpace(string(body))) - } - - fmt.Println("Proxy Status...") - if len(res.Tcp) > 0 { - fmt.Printf("TCP") - tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") - for _, ps := range res.Tcp { - tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) - } - tbl.Print() - fmt.Println("") - } - if len(res.Udp) > 0 { - fmt.Printf("UDP") - tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") - for _, ps := range res.Udp { - tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) - } - tbl.Print() - fmt.Println("") - } - if len(res.Http) > 0 { - fmt.Printf("HTTP") - tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") - for _, ps := range res.Http { - tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) - } - tbl.Print() - fmt.Println("") - } - if len(res.Https) > 0 { - fmt.Printf("HTTPS") - tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") - for _, ps := range res.Https { - tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) - } - tbl.Print() - fmt.Println("") - } - if len(res.Stcp) > 0 { - fmt.Printf("STCP") - tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") - for _, ps := range res.Stcp { - tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) - } - tbl.Print() - fmt.Println("") - } - if len(res.Xtcp) > 0 { - fmt.Printf("XTCP") - tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") - for _, ps := range res.Xtcp { - tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) - } - tbl.Print() - fmt.Println("") - } } + defer resp.Body.Close() + + if resp.StatusCode != 200 { + return fmt.Errorf("admin api status code [%d]", resp.StatusCode) + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + res := &client.StatusResp{} + err = json.Unmarshal(body, &res) + if err != nil { + return fmt.Errorf("unmarshal http response error: %s", strings.TrimSpace(string(body))) + } + + fmt.Println("Proxy Status...") + if len(res.Tcp) > 0 { + fmt.Printf("TCP") + tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") + for _, ps := range res.Tcp { + tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) + } + tbl.Print() + fmt.Println("") + } + if len(res.Udp) > 0 { + fmt.Printf("UDP") + tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") + for _, ps := range res.Udp { + tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) + } + tbl.Print() + fmt.Println("") + } + if len(res.Http) > 0 { + fmt.Printf("HTTP") + tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") + for _, ps := range res.Http { + tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) + } + tbl.Print() + fmt.Println("") + } + if len(res.Https) > 0 { + fmt.Printf("HTTPS") + tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") + for _, ps := range res.Https { + tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) + } + tbl.Print() + fmt.Println("") + } + if len(res.Stcp) > 0 { + fmt.Printf("STCP") + tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") + for _, ps := range res.Stcp { + tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) + } + tbl.Print() + fmt.Println("") + } + if len(res.Xtcp) > 0 { + fmt.Printf("XTCP") + tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") + for _, ps := range res.Xtcp { + tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) + } + tbl.Print() + fmt.Println("") + } + return nil } diff --git a/cmd/frps/root.go b/cmd/frps/root.go index e8def79..4dcd889 100644 --- a/cmd/frps/root.go +++ b/cmd/frps/root.go @@ -79,7 +79,7 @@ func init() { rootCmd.PersistentFlags().StringVarP(&dashboardPwd, "dashboard_pwd", "", "admin", "dashboard password") rootCmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "log file") rootCmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level") - rootCmd.PersistentFlags().Int64VarP(&logMaxDays, "log_max_days", "", 3, "log_max_days") + rootCmd.PersistentFlags().Int64VarP(&logMaxDays, "log_max_days", "", 3, "log max days") rootCmd.PersistentFlags().StringVarP(&token, "token", "t", "", "auth token") rootCmd.PersistentFlags().StringVarP(&subDomainHost, "subdomain_host", "", "", "subdomain host") rootCmd.PersistentFlags().StringVarP(&allowPorts, "allow_ports", "", "", "allow ports") diff --git a/go.sum b/go.sum index 64df382..9535e3c 100644 --- a/go.sum +++ b/go.sum @@ -1,13 +1,17 @@ +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatedier/beego v0.0.0-20171024143340-6c6a4f5bd5eb h1:wCrNShQidLmvVWn/0PikGmpdP0vtQmnvyRg3ZBEhczw= github.com/fatedier/beego v0.0.0-20171024143340-6c6a4f5bd5eb/go.mod h1:wx3gB6dbIfBRcucp94PI9Bt3I0F2c/MyNEWuhzpWiwk= github.com/fatedier/golib v0.0.0-20181107124048-ff8cd814b049 h1:teH578mf2ii42NHhIp3PhgvjU5bv+NFMq9fSQR8NaG8= github.com/fatedier/golib v0.0.0-20181107124048-ff8cd814b049/go.mod h1:DqIrnl0rp3Zybg9zbJmozTy1n8fYJoX+QoAj9slIkKM= github.com/fatedier/kcp-go v2.0.4-0.20190317085623-2063a803e6fe+incompatible h1:pNNeBKz1jtMDupiwvtEGFTujA3J86xoEXGSkwVeYFsw= github.com/fatedier/kcp-go v2.0.4-0.20190317085623-2063a803e6fe+incompatible/go.mod h1:YpCOaxj7vvMThhIQ9AfTOPW2sfztQR5WDfs7AflSy4s= +github.com/golang/snappy v0.0.0-20170215233205-553a64147049 h1:K9KHZbXKpGydfDN0aZrsoHpLJlZsBrGMFWbgLDGnPZk= github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= @@ -22,16 +26,27 @@ github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/ github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/pires/go-proxyproto v0.0.0-20190111085350-4d51b51e3bfc h1:lNOt1SMsgHXTdpuGw+RpnJtzUcCb/oRKZP65pBy9pr8= github.com/pires/go-proxyproto v0.0.0-20190111085350-4d51b51e3bfc/go.mod h1:6/gX3+E/IYGa0wMORlSMla999awQFdbaeQCHjSMKIzY= +github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rakyll/statik v0.1.1 h1:fCLHsIMajHqD5RKigbFXpvX3dN7c80Pm12+NCrI3kvg= github.com/rakyll/statik v0.1.1/go.mod h1:OEi9wJV/fMUAGx1eNjq75DKDsJVuEv1U0oYdX6GX8Zs= +github.com/rodaine/table v1.0.0 h1:UaCJG5Axc/cNXVGXqnCrffm1KxP0OfYLe1HuJLf5sFY= github.com/rodaine/table v1.0.0/go.mod h1:YAUzwPOji0DUJNEvggdxyQcUAl4g3hDRcFlyjnnR51I= +github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/pflag v1.0.1 h1:aCvUg6QPl3ibpQUxyLkrEkCHtPqYJL4x9AuhqVqFis4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/templexxx/cpufeat v0.0.0-20170927014610-3794dfbfb047 h1:K+jtWCOuZgCra7eXZ/VWn2FbJmrA/D058mTXhh2rq+8= github.com/templexxx/cpufeat v0.0.0-20170927014610-3794dfbfb047/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU= +github.com/templexxx/xor v0.0.0-20170926022130-0af8e873c554 h1:pexgSe+JCFuxG+uoMZLO+ce8KHtdHGhst4cs6rw3gmk= github.com/templexxx/xor v0.0.0-20170926022130-0af8e873c554/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4= +github.com/tjfoc/gmsm v0.0.0-20171124023159-98aa888b79d8 h1:6CNSDqI1wiE+JqyOy5Qt/yo/DoNI2/QmmOZeiCid2Nw= github.com/tjfoc/gmsm v0.0.0-20171124023159-98aa888b79d8/go.mod h1:XxO4hdhhrzAd+G4CjDqaOkd0hUzmtPR/d3EiBBMn/wc= +github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec h1:DGmKwyZwEB8dI7tbLt/I/gQuP559o/0FrAkHKlQM/Ks= github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec/go.mod h1:owBmyHYMLkxyrugmfwE/DLJyW8Ro9mkphwuVErQ0iUw= +golang.org/x/crypto v0.0.0-20180505025534-4ec37c66abab h1:w4c/LoOA2vE8SYwh8wEEQVRUwpph7TtcjH7AtZvOjy0= golang.org/x/crypto v0.0.0-20180505025534-4ec37c66abab/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20180524181706-dfa909b99c79 h1:1FDlG4HI84rVePw1/0E/crL5tt2N+1blLJpY6UZ6krs= golang.org/x/net v0.0.0-20180524181706-dfa909b99c79/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= diff --git a/server/service.go b/server/service.go index 6cd8e50..d1207f4 100644 --- a/server/service.go +++ b/server/service.go @@ -259,7 +259,16 @@ func (svr *Service) HandleListener(l frpNet.Listener) { log.Warn("Listener for incoming connections from client closed") return } - c = frpNet.CheckAndEnableTLSServerConn(c, svr.tlsConfig) + + log.Trace("start check TLS connection...") + originConn := c + c, err = frpNet.CheckAndEnableTLSServerConnWithTimeout(c, svr.tlsConfig, connReadTimeout) + if err != nil { + log.Warn("CheckAndEnableTLSServerConnWithTimeout error: %v", err) + originConn.Close() + continue + } + log.Trace("success check TLS connection") // Start a new goroutine for dealing connections. go func(frpConn frpNet.Conn) { diff --git a/tests/util/util.go b/tests/util/util.go index 2070ce3..4a4e6ff 100644 --- a/tests/util/util.go +++ b/tests/util/util.go @@ -28,51 +28,51 @@ func GetProxyStatus(statusAddr string, user string, passwd string, name string) resp, err := http.DefaultClient.Do(req) if err != nil { return status, err - } else { - if resp.StatusCode != 200 { - return status, fmt.Errorf("admin api status code [%d]", resp.StatusCode) - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return status, err - } - allStatus := &client.StatusResp{} - err = json.Unmarshal(body, &allStatus) - if err != nil { - return status, fmt.Errorf("unmarshal http response error: %s", strings.TrimSpace(string(body))) - } - for _, s := range allStatus.Tcp { - if s.Name == name { - return &s, nil - } - } - for _, s := range allStatus.Udp { - if s.Name == name { - return &s, nil - } - } - for _, s := range allStatus.Http { - if s.Name == name { - return &s, nil - } - } - for _, s := range allStatus.Https { - if s.Name == name { - return &s, nil - } - } - for _, s := range allStatus.Stcp { - if s.Name == name { - return &s, nil - } - } - for _, s := range allStatus.Xtcp { - if s.Name == name { - return &s, nil - } + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return status, fmt.Errorf("admin api status code [%d]", resp.StatusCode) + } + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return status, err + } + allStatus := &client.StatusResp{} + err = json.Unmarshal(body, &allStatus) + if err != nil { + return status, fmt.Errorf("unmarshal http response error: %s", strings.TrimSpace(string(body))) + } + for _, s := range allStatus.Tcp { + if s.Name == name { + return &s, nil } } + for _, s := range allStatus.Udp { + if s.Name == name { + return &s, nil + } + } + for _, s := range allStatus.Http { + if s.Name == name { + return &s, nil + } + } + for _, s := range allStatus.Https { + if s.Name == name { + return &s, nil + } + } + for _, s := range allStatus.Stcp { + if s.Name == name { + return &s, nil + } + } + for _, s := range allStatus.Xtcp { + if s.Name == name { + return &s, nil + } + } + return status, errors.New("no proxy status found") } @@ -87,13 +87,13 @@ func ReloadConf(reloadAddr string, user string, passwd string) error { resp, err := http.DefaultClient.Do(req) if err != nil { return err - } else { - if resp.StatusCode != 200 { - return fmt.Errorf("admin api status code [%d]", resp.StatusCode) - } - defer resp.Body.Close() - io.Copy(ioutil.Discard, resp.Body) } + defer resp.Body.Close() + + if resp.StatusCode != 200 { + return fmt.Errorf("admin api status code [%d]", resp.StatusCode) + } + io.Copy(ioutil.Discard, resp.Body) return nil } diff --git a/utils/net/tls.go b/utils/net/tls.go index ae1bfc7..4ac51d5 100644 --- a/utils/net/tls.go +++ b/utils/net/tls.go @@ -17,6 +17,7 @@ package net import ( "crypto/tls" "net" + "time" gnet "github.com/fatedier/golib/net" ) @@ -31,10 +32,17 @@ func WrapTLSClientConn(c net.Conn, tlsConfig *tls.Config) (out Conn) { return } -func CheckAndEnableTLSServerConn(c net.Conn, tlsConfig *tls.Config) (out Conn) { - sc, r := gnet.NewSharedConnSize(c, 1) +func CheckAndEnableTLSServerConnWithTimeout(c net.Conn, tlsConfig *tls.Config, timeout time.Duration) (out Conn, err error) { + sc, r := gnet.NewSharedConnSize(c, 2) buf := make([]byte, 1) - n, _ := r.Read(buf) + var n int + c.SetReadDeadline(time.Now().Add(timeout)) + n, err = r.Read(buf) + c.SetReadDeadline(time.Time{}) + if err != nil { + return + } + if n == 1 && int(buf[0]) == FRP_TLS_HEAD_BYTE { out = WrapConn(tls.Server(c, tlsConfig)) } else { diff --git a/utils/version/version.go b/utils/version/version.go index 9bc4934..da23fbe 100644 --- a/utils/version/version.go +++ b/utils/version/version.go @@ -19,7 +19,7 @@ import ( "strings" ) -var version string = "0.27.0" +var version string = "0.27.1" func Full() string { return version