From 694ee44af6f8a0708af8ff0c693eacb767542f61 Mon Sep 17 00:00:00 2001 From: fatedier Date: Fri, 13 Jan 2017 02:21:17 +0800 Subject: [PATCH 1/4] subdomain: subdomain can be configured in frps.ini, fix #220 --- src/cmd/frps/control.go | 28 +++++++++++------------ src/models/client/config.go | 44 ++++++++++++++++++++----------------- src/models/server/config.go | 44 ++++++++++++++++++++++++++++--------- src/models/server/server.go | 1 + 4 files changed, 73 insertions(+), 44 deletions(-) diff --git a/src/cmd/frps/control.go b/src/cmd/frps/control.go index a6cd6a3f..d848ccd3 100644 --- a/src/cmd/frps/control.go +++ b/src/cmd/frps/control.go @@ -268,6 +268,20 @@ func doLogin(req *msg.ControlReq, c *conn.Conn) (ret int64, info string, s *serv return } } + + if s.SubDomain != "" { + if strings.Contains(s.SubDomain, ".") || strings.Contains(s.SubDomain, "*") { + info = fmt.Sprintf("ProxyName [%s], '.' and '*' is not supported in subdomain", req.ProxyName) + log.Warn(info) + return + } + if server.SubDomainHost == "" { + info = fmt.Sprintf("ProxyName [%s], subdomain is not supported because this feature is not enabled by remote server", req.ProxyName) + log.Warn(info) + return + } + s.SubDomain = s.SubDomain + "." + server.SubDomainHost + } } err := server.CreateProxy(s) if err != nil { @@ -297,20 +311,6 @@ func doLogin(req *msg.ControlReq, c *conn.Conn) (ret int64, info string, s *serv s.HttpUserName = req.HttpUserName s.HttpPassWord = req.HttpPassWord - // package URL - if req.SubDomain != "" { - if strings.Contains(req.SubDomain, ".") || strings.Contains(req.SubDomain, "*") { - info = fmt.Sprintf("ProxyName [%s], '.' or '*' is not supported in subdomain", req.ProxyName) - log.Warn(info) - return - } - if server.SubDomainHost == "" { - info = fmt.Sprintf("ProxyName [%s], subdomain in not supported because this feature is not enabled by remote server", req.ProxyName) - log.Warn(info) - return - } - s.SubDomain = req.SubDomain + "." + server.SubDomainHost - } if req.PoolCount > server.MaxPoolCount { s.PoolCount = server.MaxPoolCount } else if req.PoolCount < 0 { diff --git a/src/models/client/config.go b/src/models/client/config.go index d04657b8..d669d764 100644 --- a/src/models/client/config.go +++ b/src/models/client/config.go @@ -243,44 +243,48 @@ func LoadConf(confFile string) (err error) { } } else if proxyClient.Type == "http" { // custom_domains - domainStr, ok := section["custom_domains"] + tmpStr, ok = section["custom_domains"] if ok { - proxyClient.CustomDomains = strings.Split(domainStr, ",") - if len(proxyClient.CustomDomains) == 0 { - ok = false - } else { - for i, domain := range proxyClient.CustomDomains { - proxyClient.CustomDomains[i] = strings.ToLower(strings.TrimSpace(domain)) - } + proxyClient.CustomDomains = strings.Split(tmpStr, ",") + for i, domain := range proxyClient.CustomDomains { + proxyClient.CustomDomains[i] = strings.ToLower(strings.TrimSpace(domain)) } } - if !ok && proxyClient.SubDomain == "" { + // subdomain + tmpStr, ok = section["subdomain"] + if ok { + proxyClient.SubDomain = tmpStr + } + + if len(proxyClient.CustomDomains) == 0 && proxyClient.SubDomain == "" { return fmt.Errorf("Parse conf error: proxy [%s] custom_domains and subdomain should set at least one of them when type is http", proxyClient.Name) } // locations - locations, ok := section["locations"] + tmpStr, ok = section["locations"] if ok { - proxyClient.Locations = strings.Split(locations, ",") + proxyClient.Locations = strings.Split(tmpStr, ",") } else { proxyClient.Locations = []string{""} } } else if proxyClient.Type == "https" { // custom_domains - domainStr, ok := section["custom_domains"] + tmpStr, ok = section["custom_domains"] if ok { - proxyClient.CustomDomains = strings.Split(domainStr, ",") - if len(proxyClient.CustomDomains) == 0 { - ok = false - } else { - for i, domain := range proxyClient.CustomDomains { - proxyClient.CustomDomains[i] = strings.ToLower(strings.TrimSpace(domain)) - } + proxyClient.CustomDomains = strings.Split(tmpStr, ",") + for i, domain := range proxyClient.CustomDomains { + proxyClient.CustomDomains[i] = strings.ToLower(strings.TrimSpace(domain)) } } - if !ok && proxyClient.SubDomain == "" { + // subdomain + tmpStr, ok = section["subdomain"] + if ok { + proxyClient.SubDomain = tmpStr + } + + if len(proxyClient.CustomDomains) == 0 && proxyClient.SubDomain == "" { return fmt.Errorf("Parse conf error: proxy [%s] custom_domains and subdomain should set at least one of them when type is https", proxyClient.Name) } } diff --git a/src/models/server/config.go b/src/models/server/config.go index e52d96c4..048e5659 100644 --- a/src/models/server/config.go +++ b/src/models/server/config.go @@ -300,9 +300,6 @@ func loadProxyConf(confFile string) (proxyServers map[string]*ProxyServer, err e domainStr, ok := section["custom_domains"] if ok { proxyServer.CustomDomains = strings.Split(domainStr, ",") - if len(proxyServer.CustomDomains) == 0 { - return proxyServers, fmt.Errorf("Parse conf error: proxy [%s] custom_domains must be set when type is http", proxyServer.Name) - } for i, domain := range proxyServer.CustomDomains { domain = strings.ToLower(strings.TrimSpace(domain)) // custom domain should not belong to subdomain_host @@ -311,8 +308,23 @@ func loadProxyConf(confFile string) (proxyServers map[string]*ProxyServer, err e } proxyServer.CustomDomains[i] = domain } - } else { - return proxyServers, fmt.Errorf("Parse conf error: proxy [%s] custom_domains must be set when type is http", proxyServer.Name) + } + + // subdomain + subdomainStr, ok := section["subdomain"] + if ok { + if strings.Contains(subdomainStr, ".") || strings.Contains(subdomainStr, "*") { + return proxyServers, fmt.Errorf("Parse conf error: proxy [%s] '.' and '*' is not supported in subdomain", proxyServer.Name) + } + + if SubDomainHost == "" { + return proxyServers, fmt.Errorf("Parse conf error: proxy [%s] subdomain is not supported because subdomain_host is empty", proxyServer.Name) + } + proxyServer.SubDomain = subdomainStr + "." + SubDomainHost + } + + if len(proxyServer.CustomDomains) == 0 && proxyServer.SubDomain == "" { + return proxyServers, fmt.Errorf("Parse conf error: proxy [%s] custom_domains and subdomain should set at least one of them when type is http", proxyServer.Name) } // locations @@ -329,9 +341,6 @@ func loadProxyConf(confFile string) (proxyServers map[string]*ProxyServer, err e domainStr, ok := section["custom_domains"] if ok { proxyServer.CustomDomains = strings.Split(domainStr, ",") - if len(proxyServer.CustomDomains) == 0 { - return proxyServers, fmt.Errorf("Parse conf error: proxy [%s] custom_domains must be set when type is https", proxyServer.Name) - } for i, domain := range proxyServer.CustomDomains { domain = strings.ToLower(strings.TrimSpace(domain)) if SubDomainHost != "" && strings.Contains(domain, SubDomainHost) { @@ -339,8 +348,23 @@ func loadProxyConf(confFile string) (proxyServers map[string]*ProxyServer, err e } proxyServer.CustomDomains[i] = domain } - } else { - return proxyServers, fmt.Errorf("Parse conf error: proxy [%s] custom_domains must be set when type is https", proxyServer.Name) + } + + // subdomain + subdomainStr, ok := section["subdomain"] + if ok { + if strings.Contains(subdomainStr, ".") || strings.Contains(subdomainStr, "*") { + return proxyServers, fmt.Errorf("Parse conf error: proxy [%s] '.' and '*' is not supported in subdomain", proxyServer.Name) + } + + if SubDomainHost == "" { + return proxyServers, fmt.Errorf("Parse conf error: proxy [%s] subdomain is not supported because subdomain_host is empty", proxyServer.Name) + } + proxyServer.SubDomain = subdomainStr + "." + SubDomainHost + } + + if len(proxyServer.CustomDomains) == 0 && proxyServer.SubDomain == "" { + return proxyServers, fmt.Errorf("Parse conf error: proxy [%s] custom_domains and subdomain should set at least one of them when type is https", proxyServer.Name) } } proxyServers[proxyServer.Name] = proxyServer diff --git a/src/models/server/server.go b/src/models/server/server.go index 27590bff..bcd552f5 100644 --- a/src/models/server/server.go +++ b/src/models/server/server.go @@ -79,6 +79,7 @@ func NewProxyServerFromCtlMsg(req *msg.ControlReq) (p *ProxyServer) { p.ListenPort = VhostHttpsPort } p.CustomDomains = req.CustomDomains + p.SubDomain = req.SubDomain p.Locations = req.Locations p.HostHeaderRewrite = req.HostHeaderRewrite p.HttpUserName = req.HttpUserName From 63be94c611ae77549ac42711bdb712768ff773e3 Mon Sep 17 00:00:00 2001 From: Tsao Date: Fri, 13 Jan 2017 13:18:22 +0800 Subject: [PATCH 2/4] Fix Bug for closing an exist ProxyServer when another ProxyServer with same name comes. --- src/models/server/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/server/server.go b/src/models/server/server.go index 27590bff..055f1fa6 100644 --- a/src/models/server/server.go +++ b/src/models/server/server.go @@ -285,7 +285,7 @@ func (p *ProxyServer) Close() { p.Release() // if the proxy created by PrivilegeMode, delete it when closed - if p.PrivilegeMode && oldStatus != consts.Closed { + if p.PrivilegeMode && oldStatus == consts.Working { // NOTE: this will take the global ProxyServerMap's lock // if we only want to release resources, use Release() instead DeleteProxy(p.Name) From 92daa45b6888fb93ce275a669b5c9608cc1fb62e Mon Sep 17 00:00:00 2001 From: fatedier Date: Sat, 14 Jan 2017 00:48:56 +0800 Subject: [PATCH 3/4] change version to 0.9.3 --- README.md | 1 + README_zh.md | 1 + src/utils/version/version.go | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d32aa32b..f6062cd8 100644 --- a/README.md +++ b/README.md @@ -497,3 +497,4 @@ Donate money by [paypal](https://www.paypal.me/fatedier) to my account **fatedie * [Manfred Touron](https://github.com/moul) * [xuebing1110](https://github.com/xuebing1110) * [Anbitioner](https://github.com/bingtianbaihua) +* [LitleCarl](https://github.com/LitleCarl) diff --git a/README_zh.md b/README_zh.md index 279e491f..95f9381f 100644 --- a/README_zh.md +++ b/README_zh.md @@ -516,3 +516,4 @@ frp 交流群:606194980 (QQ 群号) * [Manfred Touron](https://github.com/moul) * [xuebing1110](https://github.com/xuebing1110) * [Anbitioner](https://github.com/bingtianbaihua) +* [LitleCarl](https://github.com/LitleCarl) diff --git a/src/utils/version/version.go b/src/utils/version/version.go index 97b1dc11..18ba4acf 100644 --- a/src/utils/version/version.go +++ b/src/utils/version/version.go @@ -19,7 +19,7 @@ import ( "strings" ) -var version string = "0.9.2" +var version string = "0.9.3" func Full() string { return version From f9a0d891a1635b69788ca31035728098d5f24997 Mon Sep 17 00:00:00 2001 From: fatedier Date: Tue, 17 Jan 2017 22:48:21 +0800 Subject: [PATCH 4/4] pool: fix panic caused by sending to closed channel, fix #237 --- src/models/server/server.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/models/server/server.go b/src/models/server/server.go index 978a5096..364e6241 100644 --- a/src/models/server/server.go +++ b/src/models/server/server.go @@ -445,6 +445,12 @@ func (p *ProxyServer) getWorkConn() (workConn *conn.Conn, err error) { } func (p *ProxyServer) connectionPoolManager(closeCh <-chan struct{}) { + defer func() { + if r := recover(); r != nil { + log.Warn("ProxyName [%s], connectionPoolManager panic %v", p.Name, r) + } + }() + for { // check if we need more work connections and send messages to frpc to get more time.Sleep(time.Duration(2) * time.Second)