From 10100c28d9338a585245afd9df75ff52ae6d97be Mon Sep 17 00:00:00 2001 From: fatedier Date: Sat, 19 Feb 2022 16:49:21 +0800 Subject: [PATCH 1/6] client: add dial_server_timeout (#2805) --- client/control.go | 1 + client/proxy/proxy.go | 5 ++++- client/service.go | 1 + conf/frpc_full.ini | 3 +++ go.mod | 2 +- go.sum | 6 ++++-- pkg/config/client.go | 3 +++ pkg/config/client_test.go | 1 + test/e2e/basic/client_server.go | 1 - 9 files changed, 18 insertions(+), 5 deletions(-) diff --git a/client/control.go b/client/control.go index f9af8958eae..81aaf7bef5e 100644 --- a/client/control.go +++ b/client/control.go @@ -251,6 +251,7 @@ func (ctl *Control) connectServer() (conn net.Conn, err error) { } dialOptions = append(dialOptions, libdial.WithProtocol(protocol), + libdial.WithTimeout(time.Duration(ctl.clientCfg.DialServerTimeout)*time.Second), libdial.WithProxy(proxyType, addr), libdial.WithProxyAuth(auth), libdial.WithTLSConfig(tlsConfig), diff --git a/client/proxy/proxy.go b/client/proxy/proxy.go index 23e62e5354f..0fdececd3f4 100644 --- a/client/proxy/proxy.go +++ b/client/proxy/proxy.go @@ -787,7 +787,10 @@ func HandleTCPWorkConnection(ctx context.Context, localInfo *config.LocalSvrConf return } - localConn, err := libdial.Dial(net.JoinHostPort(localInfo.LocalIP, strconv.Itoa(localInfo.LocalPort))) + localConn, err := libdial.Dial( + net.JoinHostPort(localInfo.LocalIP, strconv.Itoa(localInfo.LocalPort)), + libdial.WithTimeout(10*time.Second), + ) if err != nil { workConn.Close() xl.Error("connect to local service [%s:%d] error: %v", localInfo.LocalIP, localInfo.LocalPort, err) diff --git a/client/service.go b/client/service.go index 815145b7b59..d0dda158fcd 100644 --- a/client/service.go +++ b/client/service.go @@ -245,6 +245,7 @@ func (svr *Service) login() (conn net.Conn, session *fmux.Session, err error) { } dialOptions = append(dialOptions, libdial.WithProtocol(protocol), + libdial.WithTimeout(time.Duration(svr.cfg.DialServerTimeout)*time.Second), libdial.WithProxy(proxyType, addr), libdial.WithProxyAuth(auth), libdial.WithTLSConfig(tlsConfig), diff --git a/conf/frpc_full.ini b/conf/frpc_full.ini index 7be2608d12d..01c040432ef 100644 --- a/conf/frpc_full.ini +++ b/conf/frpc_full.ini @@ -6,6 +6,9 @@ server_addr = 0.0.0.0 server_port = 7000 +# The maximum amount of time a dial to server will wait for a connect to complete. Default value is 10 seconds. +# dial_server_timeout = 10 + # if you want to connect frps by http proxy or socks5 proxy or ntlm proxy, you can set http_proxy here or in global environment variables # it only works when protocol is tcp # http_proxy = http://user:passwd@192.168.1.128:8080 diff --git a/go.mod b/go.mod index fd5759bf245..98398d518d9 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 github.com/coreos/go-oidc v2.2.1+incompatible github.com/fatedier/beego v0.0.0-20171024143340-6c6a4f5bd5eb - github.com/fatedier/golib v0.1.1-0.20220119075718-78e5cf8c00ee + github.com/fatedier/golib v0.1.1-0.20220218075713-264f72dfbfd9 github.com/fatedier/kcp-go v2.0.4-0.20190803094908-fe8645b0a904+incompatible github.com/go-playground/validator/v10 v10.6.1 github.com/google/uuid v1.2.0 diff --git a/go.sum b/go.sum index 95ba6744a44..a42b905f653 100644 --- a/go.sum +++ b/go.sum @@ -88,8 +88,10 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= 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.1.1-0.20220119075718-78e5cf8c00ee h1:iS0wlj2uZPxh3pciAf/HTzi88Kqu7DPh1jNKgJaFhtI= -github.com/fatedier/golib v0.1.1-0.20220119075718-78e5cf8c00ee/go.mod h1:fLV0TLwHqrnB/L3jbNl67Gn6PCLggDGHniX1wLrA2Qo= +github.com/fatedier/golib v0.1.1-0.20220218073251-9509a597216b h1:5r5/G3NFsFK+7svxvxZYA8yy8Ubs4hWIq+QYYMgEBe8= +github.com/fatedier/golib v0.1.1-0.20220218073251-9509a597216b/go.mod h1:fLV0TLwHqrnB/L3jbNl67Gn6PCLggDGHniX1wLrA2Qo= +github.com/fatedier/golib v0.1.1-0.20220218075713-264f72dfbfd9 h1:AOGf9Z1ri+3MiyGIAYXe+shEXx6/uVGJlufb6ZfnZls= +github.com/fatedier/golib v0.1.1-0.20220218075713-264f72dfbfd9/go.mod h1:fLV0TLwHqrnB/L3jbNl67Gn6PCLggDGHniX1wLrA2Qo= github.com/fatedier/kcp-go v2.0.4-0.20190803094908-fe8645b0a904+incompatible h1:ssXat9YXFvigNge/IkkZvFMn8yeYKFX+uI6wn2mLJ74= github.com/fatedier/kcp-go v2.0.4-0.20190803094908-fe8645b0a904+incompatible/go.mod h1:YpCOaxj7vvMThhIQ9AfTOPW2sfztQR5WDfs7AflSy4s= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= diff --git a/pkg/config/client.go b/pkg/config/client.go index cfc262e9ed7..9a0786fa15c 100644 --- a/pkg/config/client.go +++ b/pkg/config/client.go @@ -38,6 +38,8 @@ type ClientCommonConf struct { // ServerPort specifies the port to connect to the server on. By default, // this value is 7000. ServerPort int `ini:"server_port" json:"server_port"` + // The maximum amount of time a dial to server will wait for a connect to complete. + DialServerTimeout int64 `ini:"dial_server_timeout" json:"dial_server_timeout"` // ConnectServerLocalIP specifies the address of the client bind when it connect to server. // By default, this value is empty. // this value only use in TCP/Websocket protocol. Not support in KCP protocol. @@ -157,6 +159,7 @@ func GetDefaultClientConf() ClientCommonConf { ClientConfig: auth.GetDefaultClientConf(), ServerAddr: "0.0.0.0", ServerPort: 7000, + DialServerTimeout: 10, HTTPProxy: os.Getenv("http_proxy"), LogFile: "console", LogWay: "console", diff --git a/pkg/config/client_test.go b/pkg/config/client_test.go index c78e3294045..a64b9ee7b30 100644 --- a/pkg/config/client_test.go +++ b/pkg/config/client_test.go @@ -261,6 +261,7 @@ func Test_LoadClientCommonConf(t *testing.T) { }, ServerAddr: "0.0.0.9", ServerPort: 7009, + DialServerTimeout: 10, HTTPProxy: "http://user:passwd@192.168.1.128:8080", LogFile: "./frpc.log9", LogWay: "file", diff --git a/test/e2e/basic/client_server.go b/test/e2e/basic/client_server.go index c7faa421e44..c19077c4825 100644 --- a/test/e2e/basic/client_server.go +++ b/test/e2e/basic/client_server.go @@ -268,5 +268,4 @@ var _ = Describe("[Feature: Client-Server]", func() { }) } }) - }) From 19739ed31a26994e1e68346324f83b9544f7a4b0 Mon Sep 17 00:00:00 2001 From: fatedier Date: Thu, 24 Feb 2022 11:59:36 +0800 Subject: [PATCH 2/6] random sleep duration before reconnecting (#2816) --- client/service.go | 27 ++++++++++++--------------- pkg/util/util/util.go | 16 ++++++++++++++++ 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/client/service.go b/client/service.go index d0dda158fcd..96ddadfd882 100644 --- a/client/service.go +++ b/client/service.go @@ -17,7 +17,6 @@ package client import ( "context" "crypto/tls" - "errors" "fmt" "io" "net" @@ -34,6 +33,7 @@ import ( "github.com/fatedier/frp/pkg/transport" "github.com/fatedier/frp/pkg/util/log" frpNet "github.com/fatedier/frp/pkg/util/net" + "github.com/fatedier/frp/pkg/util/util" "github.com/fatedier/frp/pkg/util/version" "github.com/fatedier/frp/pkg/util/xlog" libdial "github.com/fatedier/golib/net/dial" @@ -109,7 +109,7 @@ func (svr *Service) Run() error { if svr.cfg.LoginFailExit { return err } - time.Sleep(10 * time.Second) + util.RandomSleep(10*time.Second, 0.9, 1.1) } else { // login success ctl := NewControl(svr.ctx, svr.runID, conn, session, svr.cfg, svr.pxyCfgs, svr.visitorCfgs, svr.serverUDPPort, svr.authSetter) @@ -158,8 +158,11 @@ func (svr *Service) keepControllerWorking() { // the first three retry with no delay if reconnectCounts > 3 { - time.Sleep(reconnectDelay) + util.RandomSleep(reconnectDelay, 0.9, 1.1) + xl.Info("wait %v to reconnect", reconnectDelay) reconnectDelay *= 2 + } else { + util.RandomSleep(time.Second, 0, 0.5) } reconnectCounts++ @@ -175,18 +178,12 @@ func (svr *Service) keepControllerWorking() { xl.Info("try to reconnect to server...") conn, session, err := svr.login() if err != nil { - xl.Warn("reconnect to server error: %v", err) - time.Sleep(delayTime) - - opErr := &net.OpError{} - // quick retry for dial error - if errors.As(err, &opErr) && opErr.Op == "dial" { - delayTime = 2 * time.Second - } else { - delayTime = delayTime * 2 - if delayTime > maxDelayTime { - delayTime = maxDelayTime - } + xl.Warn("reconnect to server error: %v, wait %v for another retry", err, delayTime) + util.RandomSleep(delayTime, 0.9, 1.1) + + delayTime = delayTime * 2 + if delayTime > maxDelayTime { + delayTime = maxDelayTime } continue } diff --git a/pkg/util/util/util.go b/pkg/util/util/util.go index eb2ae0b27ee..032675fb761 100644 --- a/pkg/util/util/util.go +++ b/pkg/util/util/util.go @@ -19,9 +19,11 @@ import ( "crypto/rand" "encoding/hex" "fmt" + mathrand "math/rand" "net" "strconv" "strings" + "time" ) // RandID return a rand string used in frp. @@ -109,3 +111,17 @@ func GenerateResponseErrorString(summary string, err error, detailed bool) strin } return summary } + +func RandomSleep(duration time.Duration, minRatio, maxRatio float64) time.Duration { + min := int64(minRatio * 1000.0) + max := int64(maxRatio * 1000.0) + var n int64 + if max <= min { + n = min + } else { + n = mathrand.Int63n(max-min) + min + } + d := duration * time.Duration(n) / time.Duration(1000) + time.Sleep(d) + return d +} From cd31359a27305ccf6eac51ea4541fa292deb9232 Mon Sep 17 00:00:00 2001 From: Blizard Date: Mon, 7 Mar 2022 14:23:49 +0800 Subject: [PATCH 3/6] feat: support add additional params for OIDC (#2814) * feat: support add additional params and test access by auth0 * fix: config name Co-authored-by: blizard863 <760076784@qq.com> --- conf/frpc_full.ini | 6 ++++++ pkg/auth/oidc.go | 28 ++++++++++++++++++++-------- pkg/config/client.go | 2 ++ 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/conf/frpc_full.ini b/conf/frpc_full.ini index 01c040432ef..58aefde8144 100644 --- a/conf/frpc_full.ini +++ b/conf/frpc_full.ini @@ -51,6 +51,12 @@ oidc_audience = # It will be used to get an OIDC token if AuthenticationMethod == "oidc". By default, this value is "". oidc_token_endpoint_url = +# oidc_additional_xxx specifies additional parameters to be sent to the OIDC Token Endpoint. +# For example, if you want to specify the "audience" parameter, you can set as follow. +# frp will add "audience=" "var1=" to the additional parameters. +# oidc_additional_audience = https://dev.auth.com/api/v2/ +# oidc_additional_var1 = foobar + # set admin address for control frpc's action by http api such as reload admin_addr = 127.0.0.1 admin_port = 7400 diff --git a/pkg/auth/oidc.go b/pkg/auth/oidc.go index 981f758933b..8a9f3404bf1 100644 --- a/pkg/auth/oidc.go +++ b/pkg/auth/oidc.go @@ -40,14 +40,20 @@ type OidcClientConfig struct { // It will be used to get an OIDC token if AuthenticationMethod == "oidc". // By default, this value is "". OidcTokenEndpointURL string `ini:"oidc_token_endpoint_url" json:"oidc_token_endpoint_url"` + + // OidcAdditionalEndpointParams specifies additional parameters to be sent + // this field will be transfer to map[string][]string in OIDC token generator + // The field will be set by prefix "oidc_additional_" + OidcAdditionalEndpointParams map[string]string `ini:"-" json:"oidc_additional_endpoint_params"` } func getDefaultOidcClientConf() OidcClientConfig { return OidcClientConfig{ - OidcClientID: "", - OidcClientSecret: "", - OidcAudience: "", - OidcTokenEndpointURL: "", + OidcClientID: "", + OidcClientSecret: "", + OidcAudience: "", + OidcTokenEndpointURL: "", + OidcAdditionalEndpointParams: make(map[string]string), } } @@ -88,11 +94,17 @@ type OidcAuthProvider struct { } func NewOidcAuthSetter(baseCfg BaseConfig, cfg OidcClientConfig) *OidcAuthProvider { + eps := make(map[string][]string) + for k, v := range cfg.OidcAdditionalEndpointParams { + eps[k] = []string{v} + } + tokenGenerator := &clientcredentials.Config{ - ClientID: cfg.OidcClientID, - ClientSecret: cfg.OidcClientSecret, - Scopes: []string{cfg.OidcAudience}, - TokenURL: cfg.OidcTokenEndpointURL, + ClientID: cfg.OidcClientID, + ClientSecret: cfg.OidcClientSecret, + Scopes: []string{cfg.OidcAudience}, + TokenURL: cfg.OidcTokenEndpointURL, + EndpointParams: eps, } return &OidcAuthProvider{ diff --git a/pkg/config/client.go b/pkg/config/client.go index 9a0786fa15c..e65e1064a06 100644 --- a/pkg/config/client.go +++ b/pkg/config/client.go @@ -261,6 +261,8 @@ func UnmarshalClientConfFromIni(source interface{}) (ClientCommonConf, error) { } common.Metas = GetMapWithoutPrefix(s.KeysHash(), "meta_") + common.ClientConfig.OidcAdditionalEndpointParams = GetMapWithoutPrefix(s.KeysHash(), "oidc_additional_") + return common, nil } From bf635c0e902c5e4b07de55440c6886d7f919dfc8 Mon Sep 17 00:00:00 2001 From: Harry Cheng Date: Tue, 8 Mar 2022 15:08:09 +0800 Subject: [PATCH 4/6] Notify server plugins when a proxy is closed (#2823) * add close proxy op * Move to actual closing routine * Fix e2e tests for CloseProxy * Add warning on resource exhaustion * Add CloseProxy to manual close * retuen errors to `CloseProxy` callers --- doc/server_plugin.md | 22 ++++++++++++++- pkg/plugin/server/manager.go | 32 ++++++++++++++++++++++ pkg/plugin/server/plugin.go | 1 + pkg/plugin/server/types.go | 5 ++++ server/control.go | 29 ++++++++++++++++++++ test/e2e/framework/process.go | 8 +++++- test/e2e/plugin/server.go | 50 +++++++++++++++++++++++++++++++++++ 7 files changed, 145 insertions(+), 2 deletions(-) diff --git a/doc/server_plugin.md b/doc/server_plugin.md index 3697053b30e..d73d2439eb7 100644 --- a/doc/server_plugin.md +++ b/doc/server_plugin.md @@ -70,7 +70,7 @@ The response can look like any of the following: ### Operation -Currently `Login`, `NewProxy`, `Ping`, `NewWorkConn` and `NewUserConn` operations are supported. +Currently `Login`, `NewProxy`, `CloseProxy`, `Ping`, `NewWorkConn` and `NewUserConn` operations are supported. #### Login @@ -136,6 +136,26 @@ Create new proxy } ``` +#### CloseProxy + +A previously created proxy is closed. + +Please note that one request will be sent for every proxy that is closed, do **NOT** use this +if you have too many proxies bound to a single client, as this may exhaust the server's resources. + +``` +{ + "content": { + "user": { + "user": , + "metas": mapstring + "run_id": + }, + "proxy_name": + } +} +``` + #### Ping Heartbeat from frpc diff --git a/pkg/plugin/server/manager.go b/pkg/plugin/server/manager.go index bc8828896f9..47d11d1c245 100644 --- a/pkg/plugin/server/manager.go +++ b/pkg/plugin/server/manager.go @@ -18,6 +18,7 @@ import ( "context" "errors" "fmt" + "strings" "github.com/fatedier/frp/pkg/util/util" "github.com/fatedier/frp/pkg/util/xlog" @@ -26,6 +27,7 @@ import ( type Manager struct { loginPlugins []Plugin newProxyPlugins []Plugin + closeProxyPlugins []Plugin pingPlugins []Plugin newWorkConnPlugins []Plugin newUserConnPlugins []Plugin @@ -35,6 +37,7 @@ func NewManager() *Manager { return &Manager{ loginPlugins: make([]Plugin, 0), newProxyPlugins: make([]Plugin, 0), + closeProxyPlugins: make([]Plugin, 0), pingPlugins: make([]Plugin, 0), newWorkConnPlugins: make([]Plugin, 0), newUserConnPlugins: make([]Plugin, 0), @@ -48,6 +51,9 @@ func (m *Manager) Register(p Plugin) { if p.IsSupport(OpNewProxy) { m.newProxyPlugins = append(m.newProxyPlugins, p) } + if p.IsSupport(OpCloseProxy) { + m.closeProxyPlugins = append(m.closeProxyPlugins, p) + } if p.IsSupport(OpPing) { m.pingPlugins = append(m.pingPlugins, p) } @@ -127,6 +133,32 @@ func (m *Manager) NewProxy(content *NewProxyContent) (*NewProxyContent, error) { return content, nil } +func (m *Manager) CloseProxy(content *CloseProxyContent) error { + if len(m.closeProxyPlugins) == 0 { + return nil + } + + errs := make([]string, 0) + reqid, _ := util.RandID() + xl := xlog.New().AppendPrefix("reqid: " + reqid) + ctx := xlog.NewContext(context.Background(), xl) + ctx = NewReqidContext(ctx, reqid) + + for _, p := range m.closeProxyPlugins { + _, _, err := p.Handle(ctx, OpCloseProxy, *content) + if err != nil { + xl.Warn("send CloseProxy request to plugin [%s] error: %v", p.Name(), err) + errs = append(errs, fmt.Sprintf("[%s]: %v", p.Name(), err)) + } + } + + if len(errs) > 0 { + return fmt.Errorf("send CloseProxy request to plugin errors: %s", strings.Join(errs, "; ")) + } else { + return nil + } +} + func (m *Manager) Ping(content *PingContent) (*PingContent, error) { if len(m.pingPlugins) == 0 { return content, nil diff --git a/pkg/plugin/server/plugin.go b/pkg/plugin/server/plugin.go index 160d12a2a7f..0d34de5467d 100644 --- a/pkg/plugin/server/plugin.go +++ b/pkg/plugin/server/plugin.go @@ -23,6 +23,7 @@ const ( OpLogin = "Login" OpNewProxy = "NewProxy" + OpCloseProxy = "CloseProxy" OpPing = "Ping" OpNewWorkConn = "NewWorkConn" OpNewUserConn = "NewUserConn" diff --git a/pkg/plugin/server/types.go b/pkg/plugin/server/types.go index 4df79f46d62..d7d98cb6535 100644 --- a/pkg/plugin/server/types.go +++ b/pkg/plugin/server/types.go @@ -48,6 +48,11 @@ type NewProxyContent struct { msg.NewProxy } +type CloseProxyContent struct { + User UserInfo `json:"user"` + msg.CloseProxy +} + type PingContent struct { User UserInfo `json:"user"` msg.Ping diff --git a/server/control.go b/server/control.go index 25adc2d2735..09740611d44 100644 --- a/server/control.go +++ b/server/control.go @@ -376,6 +376,20 @@ func (ctl *Control) stoper() { pxy.Close() ctl.pxyManager.Del(pxy.GetName()) metrics.Server.CloseProxy(pxy.GetName(), pxy.GetConf().GetBaseInfo().ProxyType) + + notifyContent := &plugin.CloseProxyContent{ + User: plugin.UserInfo{ + User: ctl.loginMsg.User, + Metas: ctl.loginMsg.Metas, + RunID: ctl.loginMsg.RunID, + }, + CloseProxy: msg.CloseProxy{ + ProxyName: pxy.GetName(), + }, + } + go func() { + ctl.pluginManager.CloseProxy(notifyContent) + }() } ctl.allShutdown.Done() @@ -564,5 +578,20 @@ func (ctl *Control) CloseProxy(closeMsg *msg.CloseProxy) (err error) { ctl.mu.Unlock() metrics.Server.CloseProxy(pxy.GetName(), pxy.GetConf().GetBaseInfo().ProxyType) + + notifyContent := &plugin.CloseProxyContent{ + User: plugin.UserInfo{ + User: ctl.loginMsg.User, + Metas: ctl.loginMsg.Metas, + RunID: ctl.loginMsg.RunID, + }, + CloseProxy: msg.CloseProxy{ + ProxyName: pxy.GetName(), + }, + } + go func() { + ctl.pluginManager.CloseProxy(notifyContent) + }() + return } diff --git a/test/e2e/framework/process.go b/test/e2e/framework/process.go index a1b15710ba2..197cb7de47e 100644 --- a/test/e2e/framework/process.go +++ b/test/e2e/framework/process.go @@ -12,7 +12,7 @@ import ( // RunProcesses run multiple processes from templates. // The first template should always be frps. -func (f *Framework) RunProcesses(serverTemplates []string, clientTemplates []string) { +func (f *Framework) RunProcesses(serverTemplates []string, clientTemplates []string) ([]*process.Process, []*process.Process) { templates := make([]string, 0, len(serverTemplates)+len(clientTemplates)) for _, t := range serverTemplates { templates = append(templates, t) @@ -28,6 +28,7 @@ func (f *Framework) RunProcesses(serverTemplates []string, clientTemplates []str f.usedPorts[name] = port } + currentServerProcesses := make([]*process.Process, 0, len(serverTemplates)) for i := range serverTemplates { path := filepath.Join(f.TempDirectory, fmt.Sprintf("frp-e2e-server-%d", i)) err = os.WriteFile(path, []byte(outs[i]), 0666) @@ -37,11 +38,13 @@ func (f *Framework) RunProcesses(serverTemplates []string, clientTemplates []str p := process.NewWithEnvs(TestContext.FRPServerPath, []string{"-c", path}, f.osEnvs) f.serverConfPaths = append(f.serverConfPaths, path) f.serverProcesses = append(f.serverProcesses, p) + currentServerProcesses = append(currentServerProcesses, p) err = p.Start() ExpectNoError(err) } time.Sleep(time.Second) + currentClientProcesses := make([]*process.Process, 0, len(clientTemplates)) for i := range clientTemplates { index := i + len(serverTemplates) path := filepath.Join(f.TempDirectory, fmt.Sprintf("frp-e2e-client-%d", i)) @@ -52,11 +55,14 @@ func (f *Framework) RunProcesses(serverTemplates []string, clientTemplates []str p := process.NewWithEnvs(TestContext.FRPClientPath, []string{"-c", path}, f.osEnvs) f.clientConfPaths = append(f.clientConfPaths, path) f.clientProcesses = append(f.clientProcesses, p) + currentClientProcesses = append(currentClientProcesses, p) err = p.Start() ExpectNoError(err) time.Sleep(500 * time.Millisecond) } time.Sleep(500 * time.Millisecond) + + return currentServerProcesses, currentClientProcesses } func (f *Framework) RunFrps(args ...string) (*process.Process, string, error) { diff --git a/test/e2e/plugin/server.go b/test/e2e/plugin/server.go index 79ecff44b04..b972f78b251 100644 --- a/test/e2e/plugin/server.go +++ b/test/e2e/plugin/server.go @@ -158,6 +158,56 @@ var _ = Describe("[Feature: Server-Plugins]", func() { }) }) + Describe("CloseProxy", func() { + newFunc := func() *plugin.Request { + var r plugin.Request + r.Content = &plugin.CloseProxyContent{} + return &r + } + + It("Validate Info", func() { + localPort := f.AllocPort() + var recordProxyName string + handler := func(req *plugin.Request) *plugin.Response { + var ret plugin.Response + content := req.Content.(*plugin.CloseProxyContent) + recordProxyName = content.ProxyName + return &ret + } + pluginServer := NewHTTPPluginServer(localPort, newFunc, handler, nil) + + f.RunServer("", pluginServer) + + serverConf := consts.DefaultServerConfig + fmt.Sprintf(` + [plugin.test] + addr = 127.0.0.1:%d + path = /handler + ops = CloseProxy + `, localPort) + clientConf := consts.DefaultClientConfig + + remotePort := f.AllocPort() + clientConf += fmt.Sprintf(` + [tcp] + type = tcp + local_port = {{ .%s }} + remote_port = %d + `, framework.TCPEchoServerPort, remotePort) + + _, clients := f.RunProcesses([]string{serverConf}, []string{clientConf}) + + framework.NewRequestExpect(f).Port(remotePort).Ensure() + + for _, c := range clients { + c.Stop() + } + + time.Sleep(1 * time.Second) + + framework.ExpectEqual(recordProxyName, "tcp") + }) + }) + Describe("Ping", func() { newFunc := func() *plugin.Request { var r plugin.Request From eeea7602d9d130f3fc953a4acaaaa8d1664a04f5 Mon Sep 17 00:00:00 2001 From: Johan Hernefeldt <3883897+presidenten@users.noreply.github.com> Date: Fri, 11 Mar 2022 07:51:47 +0100 Subject: [PATCH 5/6] bugfix: Issue #2831 - Cant connect to frps behind ingress with tls (#2832) Co-authored-by: Johan Hernefeldt --- pkg/transport/tls.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/transport/tls.go b/pkg/transport/tls.go index 4a6cd8f54ef..38201f8e900 100644 --- a/pkg/transport/tls.go +++ b/pkg/transport/tls.go @@ -100,6 +100,8 @@ func NewClientTLSConfig(certPath, keyPath, caPath, serverName string) (*tls.Conf base.Certificates = []tls.Certificate{*cert} } + base.ServerName = serverName + if caPath != "" { pool, err := newCertPool(caPath) if err != nil { @@ -107,7 +109,6 @@ func NewClientTLSConfig(certPath, keyPath, caPath, serverName string) (*tls.Conf } base.RootCAs = pool - base.ServerName = serverName base.InsecureSkipVerify = false } else { base.InsecureSkipVerify = true From 1f88a7a0b8092e1200d2a8f515d41f728d2b14b5 Mon Sep 17 00:00:00 2001 From: fatedier Date: Fri, 11 Mar 2022 19:45:34 +0800 Subject: [PATCH 6/6] bump version to v0.40.0 (#2833) --- Release.md | 12 +++++++++++- pkg/util/version/version.go | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Release.md b/Release.md index 11bd0d80805..306d8b9dd54 100644 --- a/Release.md +++ b/Release.md @@ -1,3 +1,13 @@ +### New + +* Added `dial_server_timeout` in frpc to specify connect timeout to frps. +* Additional EndpointParams can be set for OIDC. +* Added CloseProxy operation in server plugin. + +### Improve + +* Added some randomness in reconnect delay. + ### Fix -* Fixed IPv6 address parse issue. +* TLS server name is ignored when `tls_trusted_ca_file` isn’t set. diff --git a/pkg/util/version/version.go b/pkg/util/version/version.go index ede58f2980c..cb15461b4b7 100644 --- a/pkg/util/version/version.go +++ b/pkg/util/version/version.go @@ -19,7 +19,7 @@ import ( "strings" ) -var version string = "0.39.1" +var version string = "0.40.0" func Full() string { return version