diff --git a/.circleci/config.yml b/.circleci/config.yml index f8623698ae3..7499579a8d9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,14 +2,16 @@ version: 2 jobs: go-version-latest: docker: - - image: cimg/go:1.18-node + - image: cimg/go:1.19-node + resource_class: large steps: - checkout - run: make - run: make alltest go-version-last: docker: - - image: cimg/go:1.17-node + - image: cimg/go:1.18-node + resource_class: large steps: - checkout - run: make diff --git a/.github/workflows/build-and-push-image.yml b/.github/workflows/build-and-push-image.yml index b7f7318b62f..99a9fa9a066 100644 --- a/.github/workflows/build-and-push-image.yml +++ b/.github/workflows/build-and-push-image.yml @@ -9,6 +9,9 @@ on: description: 'Image tag' required: true default: 'test' +permissions: + contents: read + jobs: image: name: Build Image from Dockerfile and binaries @@ -16,15 +19,15 @@ jobs: steps: # environment - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: '0' - name: Set up QEMU - uses: docker/setup-qemu-action@v1 + uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 # get image tag name - name: Get Image Tag Name @@ -35,13 +38,13 @@ jobs: echo "TAG_NAME=${{ github.event.inputs.tag }}" >> $GITHUB_ENV fi - name: Login to DockerHub - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} - name: Login to the GPR - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ github.repository_owner }} @@ -58,7 +61,7 @@ jobs: echo "TAG_FRPS_GPR=ghcr.io/fatedier/frps:${{ env.TAG_NAME }}" >> $GITHUB_ENV - name: Build and push frpc - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v3 with: context: . file: ./dockerfiles/Dockerfile-for-frpc @@ -69,7 +72,7 @@ jobs: ${{ env.TAG_FRPC_GPR }} - name: Build and push frps - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v3 with: context: . file: ./dockerfiles/Dockerfile-for-frps diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml new file mode 100644 index 00000000000..c9051f38ac6 --- /dev/null +++ b/.github/workflows/golangci-lint.yml @@ -0,0 +1,41 @@ +name: golangci-lint +on: + push: + branches: + - master + - dev + pull_request: +permissions: + contents: read + # Optional: allow read access to pull request. Use with `only-new-issues` option. + pull-requests: read +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/setup-go@v3 + with: + go-version: 1.19 + - uses: actions/checkout@v3 + - name: golangci-lint + uses: golangci/golangci-lint-action@v3 + with: + # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version + version: v1.49.0 + + # Optional: golangci-lint command line arguments. + # args: --issues-exit-code=0 + + # Optional: show only new issues if it's a pull request. The default value is `false`. + # only-new-issues: true + + # Optional: if set to true then the all caching functionality will be complete disabled, + # takes precedence over all other caching options. + # skip-cache: true + + # Optional: if set to true then the action don't cache or restore ~/go/pkg. + # skip-pkg-cache: true + + # Optional: if set to true then the action don't cache or restore ~/.cache/go-build. + # skip-build-cache: true diff --git a/.github/workflows/goreleaser.yml b/.github/workflows/goreleaser.yml index d78d2929714..d483e844267 100644 --- a/.github/workflows/goreleaser.yml +++ b/.github/workflows/goreleaser.yml @@ -10,26 +10,22 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 - name: Set up Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - - run: | - # https://github.com/actions/setup-go/issues/107 - cp -f `which go` /usr/bin/go - - name: Make All run: | sed -i 's/Token: ""/Token: "${{ secrets.FRP_TOKEN }}"/' ./pkg/auth/token.go ./package.sh - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v2 + uses: goreleaser/goreleaser-action@v3 with: version: latest args: release --rm-dist --release-notes=./Release.md diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 1a44ddf67c4..c3642d914ac 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -8,11 +8,17 @@ on: description: 'In debug mod' required: false default: 'false' +permissions: + contents: read + jobs: stale: + permissions: + issues: write # for actions/stale to close stale issues + pull-requests: write # for actions/stale to close stale PRs runs-on: ubuntu-latest steps: - - uses: actions/stale@v5 + - uses: actions/stale@v6 with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-issue-message: 'Issues go stale after 30d of inactivity. Stale issues rot after an additional 7d of inactivity and eventually close.' diff --git a/.gitignore b/.gitignore index eeccf24af01..0d8ca50d8d7 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,7 @@ test/bin/ vendor/ dist/ .idea/ +.vscode/ # Cache *.swp diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 00000000000..39c8e3f7ece --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,140 @@ +service: + # When updating this, also update the version stored in docker/build-tools/Dockerfile in the istio/tools repo. + golangci-lint-version: 1.49.x # use the fixed version to not introduce new linters unexpectedly + +run: + concurrency: 4 + # timeout for analysis, e.g. 30s, 5m, default is 1m + deadline: 20m + build-tags: + - integ + - integfuzz + # which dirs to skip: they won't be analyzed; + # can use regexp here: generated.*, regexp is applied on full path; + # default value is empty list, but next dirs are always skipped independently + # from this option's value: + # vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ + skip-dirs: + - genfiles$ + - vendor$ + - bin$ + + # which files to skip: they will be analyzed, but issues from them + # won't be reported. Default value is empty list, but there is + # no need to include all autogenerated files, we confidently recognize + # autogenerated files. If it's not please let us know. + skip-files: + - ".*\\.pb\\.go" + - ".*\\.gen\\.go" + +linters: + disable-all: true + enable: + - unused + - errcheck + - exportloopref + - gocritic + - gofumpt + - goimports + - revive + - gosimple + - govet + - ineffassign + - lll + - misspell + - staticcheck + - stylecheck + - typecheck + - unconvert + - unparam + - gci + - gosec + - asciicheck + - prealloc + - predeclared + - makezero + fast: false + +linters-settings: + errcheck: + # report about not checking of errors in type assetions: `a := b.(MyStruct)`; + # default is false: such cases aren't reported by default. + check-type-assertions: false + + # report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`; + # default is false: such cases aren't reported by default. + check-blank: false + govet: + # report about shadowed variables + check-shadowing: false + maligned: + # print struct with more effective memory layout or not, false by default + suggest-new: true + misspell: + # Correct spellings using locale preferences for US or UK. + # Default is to use a neutral variety of English. + # Setting locale to US will correct the British spelling of 'colour' to 'color'. + locale: US + ignore-words: + - cancelled + - marshalled + lll: + # max line length, lines longer will be reported. Default is 120. + # '\t' is counted as 1 character by default, and can be changed with the tab-width option + line-length: 160 + # tab width in spaces. Default to 1. + tab-width: 1 + gocritic: + disabled-checks: + - exitAfterDefer + unused: + check-exported: false + unparam: + # Inspect exported functions, default is false. Set to true if no external program/library imports your code. + # XXX: if you enable this setting, unparam will report a lot of false-positives in text editors: + # if it's called for subdir of a project it can't find external interfaces. All text editor integrations + # with golangci-lint call it on a directory with the changed file. + check-exported: false + gci: + sections: + - standard + - default + - prefix(github.com/fatedier/frp/) + gosec: + severity: "low" + confidence: "low" + excludes: + - G102 + - G112 + - G306 + - G401 + - G402 + - G404 + - G501 + +issues: + # List of regexps of issue texts to exclude, empty list by default. + # But independently from this option we use default exclude patterns, + # it can be disabled by `exclude-use-default: false`. To list all + # excluded by default patterns execute `golangci-lint run --help` + # exclude: + # - composite literal uses unkeyed fields + + exclude-rules: + # Exclude some linters from running on test files. + - path: _test\.go$|^tests/|^samples/ + linters: + - errcheck + - maligned + + # Independently from option `exclude` we use default exclude patterns, + # it can be disabled by this option. To list all + # excluded by default patterns execute `golangci-lint run --help`. + # Default value for this option is true. + exclude-use-default: true + + # Maximum issues count per one linter. Set to 0 to disable. Default is 50. + max-per-linter: 0 + + # Maximum count of issues with the same text. Set to 0 to disable. Default is 3. + max-same-issues: 0 diff --git a/Makefile.cross-compiles b/Makefile.cross-compiles index 9351924a922..06e10d7959a 100644 --- a/Makefile.cross-compiles +++ b/Makefile.cross-compiles @@ -2,7 +2,7 @@ export PATH := $(GOPATH)/bin:$(PATH) export GO111MODULE=on LDFLAGS := -s -w -os-archs=darwin:amd64 darwin:arm64 freebsd:386 freebsd:amd64 linux:386 linux:amd64 linux:arm linux:arm64 windows:386 windows:amd64 linux:mips64 linux:mips64le linux:mips:softfloat linux:mipsle:softfloat +os-archs=darwin:amd64 darwin:arm64 freebsd:386 freebsd:amd64 linux:386 linux:amd64 linux:arm linux:arm64 windows:386 windows:amd64 linux:mips64 linux:mips64le linux:mips:softfloat linux:mipsle:softfloat linux:riscv64 all: build diff --git a/README.md b/README.md index 92c14933c24..57a68949b24 100644 --- a/README.md +++ b/README.md @@ -6,17 +6,6 @@ [README](README.md) | [中文文档](README_zh.md) -

Platinum Sponsors

- - -

- - - -

- - -

Gold Sponsors

@@ -74,6 +63,7 @@ frp also has a P2P connect mode. * [For Each Proxy](#for-each-proxy) * [TCP Stream Multiplexing](#tcp-stream-multiplexing) * [Support KCP Protocol](#support-kcp-protocol) + * [Support QUIC Protocol](#support-quic-protocol) * [Connection Pooling](#connection-pooling) * [Load balancing](#load-balancing) * [Service Health Check](#service-health-check) @@ -656,7 +646,7 @@ openssl req -new -sha256 -key server.key \ -config <(cat my-openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:localhost,IP:127.0.0.1,DNS:example.server.com")) \ -out server.csr -openssl x509 -req -days 365 \ +openssl x509 -req -days 365 -sha256 \ -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \ -extfile <(printf "subjectAltName=DNS:localhost,IP:127.0.0.1,DNS:example.server.com") \ -out server.crt @@ -671,7 +661,7 @@ openssl req -new -sha256 -key client.key \ -config <(cat my-openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:client.com,DNS:example.client.com")) \ -out client.csr -openssl x509 -req -days 365 \ +openssl x509 -req -days 365 -sha256 \ -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial \ -extfile <(printf "subjectAltName=DNS:client.com,DNS:example.client.com") \ -out client.crt @@ -772,6 +762,35 @@ KCP mode uses UDP as the underlying transport. Using KCP in frp: protocol = kcp ``` +### Support QUIC Protocol + +QUIC is a new multiplexed transport built on top of UDP. + +Using QUIC in frp: + +1. Enable QUIC in frps: + + ```ini + # frps.ini + [common] + bind_port = 7000 + # Specify a UDP port for QUIC. + quic_bind_port = 7000 + ``` + + The `quic_bind_port` number can be the same number as `bind_port`, since `bind_port` field specifies a TCP port. + +2. Configure `frpc.ini` to use QUIC to connect to frps: + + ```ini + # frpc.ini + [common] + server_addr = x.x.x.x + # Same as the 'quic_bind_port' in frps.ini + server_port = 7000 + protocol = quic + ``` + ### Connection Pooling By default, frps creates a new frpc connection to the backend service upon a user request. With connection pooling, frps keeps a certain number of pre-established connections, reducing the time needed to establish a connection. @@ -883,7 +902,7 @@ custom_domains = test.example.com host_header_rewrite = dev.example.com ``` -The HTTP request will have the the `Host` header rewritten to `Host: dev.example.com` when it reaches the actual web server, although the request from the browser probably has `Host: test.example.com`. +The HTTP request will have the `Host` header rewritten to `Host: dev.example.com` when it reaches the actual web server, although the request from the browser probably has `Host: test.example.com`. ### Setting other HTTP Headers diff --git a/README_zh.md b/README_zh.md index 854ae966a46..e0612bbfbe2 100644 --- a/README_zh.md +++ b/README_zh.md @@ -7,17 +7,6 @@ frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。 -

Platinum Sponsors

- - -

- - - -

- - -

Gold Sponsors

diff --git a/Release.md b/Release.md index 35c8b12ea31..bbcb8c5c96f 100644 --- a/Release.md +++ b/Release.md @@ -1,8 +1,9 @@ ### New -* Use auto generated certificates if `plugin_key_path` and `plugin_crt_path` are empty for plugin `https2https` and `https2http`. -* Server dashboard supports TLS configs. +* Add `oidc_scope` parameter to frpc when `authentication_method = oidc`. +* Support quic protocol between frpc and frps. -### Fix -* xtcp error with IPv6 address. +### Improve + +* Upgrade oidc and oauth2 package which is forward compatible. diff --git a/client/admin.go b/client/admin.go index 6a6ceecb7c4..f96e1bc1e5a 100644 --- a/client/admin.go +++ b/client/admin.go @@ -20,10 +20,10 @@ import ( "net/http/pprof" "time" + "github.com/gorilla/mux" + "github.com/fatedier/frp/assets" frpNet "github.com/fatedier/frp/pkg/util/net" - - "github.com/gorilla/mux" ) var ( @@ -77,6 +77,8 @@ func (svr *Service) RunAdminServer(address string) (err error) { return err } - go server.Serve(ln) + go func() { + _ = server.Serve(ln) + }() return } diff --git a/client/admin_api.go b/client/admin_api.go index e434fcb19a7..545ba7fc952 100644 --- a/client/admin_api.go +++ b/client/admin_api.go @@ -49,7 +49,7 @@ func (svr *Service) apiReload(w http.ResponseWriter, r *http.Request) { log.Info("api response [/api/reload], code [%d]", res.Code) w.WriteHeader(res.Code) if len(res.Msg) > 0 { - w.Write([]byte(res.Msg)) + _, _ = w.Write([]byte(res.Msg)) } }() @@ -68,7 +68,6 @@ func (svr *Service) apiReload(w http.ResponseWriter, r *http.Request) { return } log.Info("success reload conf") - return } type StatusResp struct { @@ -173,7 +172,7 @@ func (svr *Service) apiStatus(w http.ResponseWriter, r *http.Request) { defer func() { log.Info("Http response [/api/status]") buf, _ = json.Marshal(&res) - w.Write(buf) + _, _ = w.Write(buf) }() ps := svr.ctl.pm.GetAllProxyStatus() @@ -202,7 +201,6 @@ func (svr *Service) apiStatus(w http.ResponseWriter, r *http.Request) { sort.Sort(ByProxyStatusResp(res.STCP)) sort.Sort(ByProxyStatusResp(res.XTCP)) sort.Sort(ByProxyStatusResp(res.SUDP)) - return } // GET api/config @@ -214,7 +212,7 @@ func (svr *Service) apiGetConfig(w http.ResponseWriter, r *http.Request) { log.Info("Http get response [/api/config], code [%d]", res.Code) w.WriteHeader(res.Code) if len(res.Msg) > 0 { - w.Write([]byte(res.Msg)) + _, _ = w.Write([]byte(res.Msg)) } }() @@ -254,7 +252,7 @@ func (svr *Service) apiPutConfig(w http.ResponseWriter, r *http.Request) { log.Info("Http put response [/api/config], code [%d]", res.Code) w.WriteHeader(res.Code) if len(res.Msg) > 0 { - w.Write([]byte(res.Msg)) + _, _ = w.Write([]byte(res.Msg)) } }() @@ -315,7 +313,7 @@ func (svr *Service) apiPutConfig(w http.ResponseWriter, r *http.Request) { } content = strings.Join(newRows, "\n") - err = os.WriteFile(svr.cfgFile, []byte(content), 0644) + err = os.WriteFile(svr.cfgFile, []byte(content), 0o644) if err != nil { res.Code = 500 res.Msg = fmt.Sprintf("write content to frpc config file error: %v", err) diff --git a/client/control.go b/client/control.go index ef9a766fcda..9fb15c0104f 100644 --- a/client/control.go +++ b/client/control.go @@ -16,26 +16,19 @@ package client import ( "context" - "crypto/tls" "io" "net" "runtime/debug" - "strconv" - "sync" "time" + "github.com/fatedier/golib/control/shutdown" + "github.com/fatedier/golib/crypto" + "github.com/fatedier/frp/client/proxy" "github.com/fatedier/frp/pkg/auth" "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/msg" - "github.com/fatedier/frp/pkg/transport" - frpNet "github.com/fatedier/frp/pkg/util/net" "github.com/fatedier/frp/pkg/util/xlog" - - "github.com/fatedier/golib/control/shutdown" - "github.com/fatedier/golib/crypto" - libdial "github.com/fatedier/golib/net/dial" - fmux "github.com/hashicorp/yamux" ) type Control struct { @@ -52,8 +45,7 @@ type Control struct { // control connection conn net.Conn - // tcp stream multiplexing, if enabled - session *fmux.Session + cm *ConnectionManager // put a message in this channel to send it over control connection to server sendCh chan (msg.Message) @@ -79,8 +71,6 @@ type Control struct { // The UDP port that the server is listening on serverUDPPort int - mu sync.RWMutex - xl *xlog.Logger // service context @@ -90,18 +80,19 @@ type Control struct { authSetter auth.Setter } -func NewControl(ctx context.Context, runID string, conn net.Conn, session *fmux.Session, +func NewControl( + ctx context.Context, runID string, conn net.Conn, cm *ConnectionManager, clientCfg config.ClientCommonConf, pxyCfgs map[string]config.ProxyConf, visitorCfgs map[string]config.VisitorConf, serverUDPPort int, - authSetter auth.Setter) *Control { - + authSetter auth.Setter, +) *Control { // new xlog instance ctl := &Control{ runID: runID, conn: conn, - session: session, + cm: cm, pxyCfgs: pxyCfgs, sendCh: make(chan msg.Message, 100), readCh: make(chan msg.Message, 100), @@ -131,13 +122,13 @@ func (ctl *Control) Run() { // start all visitors go ctl.vm.Run() - return } func (ctl *Control) HandleReqWorkConn(inMsg *msg.ReqWorkConn) { xl := ctl.xl workConn, err := ctl.connectServer() if err != nil { + xl.Warn("start new connection to server error: %v", err) return } @@ -156,7 +147,7 @@ func (ctl *Control) HandleReqWorkConn(inMsg *msg.ReqWorkConn) { var startMsg msg.StartWorkConn if err = msg.ReadMsgInto(workConn, &startMsg); err != nil { - xl.Error("work connection closed before response StartWorkConn message: %v", err) + xl.Trace("work connection closed before response StartWorkConn message: %v", err) workConn.Close() return } @@ -193,9 +184,7 @@ func (ctl *Control) GracefulClose(d time.Duration) error { time.Sleep(d) ctl.conn.Close() - if ctl.session != nil { - ctl.session.Close() - } + ctl.cm.Close() return nil } @@ -206,70 +195,7 @@ func (ctl *Control) ClosedDoneCh() <-chan struct{} { // connectServer return a new connection to frps func (ctl *Control) connectServer() (conn net.Conn, err error) { - xl := ctl.xl - if ctl.clientCfg.TCPMux { - stream, errRet := ctl.session.OpenStream() - if errRet != nil { - err = errRet - xl.Warn("start new connection to server error: %v", err) - return - } - conn = stream - } else { - var tlsConfig *tls.Config - sn := ctl.clientCfg.TLSServerName - if sn == "" { - sn = ctl.clientCfg.ServerAddr - } - - if ctl.clientCfg.TLSEnable { - tlsConfig, err = transport.NewClientTLSConfig( - ctl.clientCfg.TLSCertFile, - ctl.clientCfg.TLSKeyFile, - ctl.clientCfg.TLSTrustedCaFile, - sn) - - if err != nil { - xl.Warn("fail to build tls configuration when connecting to server, err: %v", err) - return - } - } - - proxyType, addr, auth, err := libdial.ParseProxyURL(ctl.clientCfg.HTTPProxy) - if err != nil { - xl.Error("fail to parse proxy url") - return nil, err - } - dialOptions := []libdial.DialOption{} - protocol := ctl.clientCfg.Protocol - if protocol == "websocket" { - protocol = "tcp" - dialOptions = append(dialOptions, libdial.WithAfterHook(libdial.AfterHook{Hook: frpNet.DialHookWebsocket()})) - } - if ctl.clientCfg.ConnectServerLocalIP != "" { - dialOptions = append(dialOptions, libdial.WithLocalAddr(ctl.clientCfg.ConnectServerLocalIP)) - } - dialOptions = append(dialOptions, - libdial.WithProtocol(protocol), - libdial.WithTimeout(time.Duration(ctl.clientCfg.DialServerTimeout)*time.Second), - libdial.WithKeepAlive(time.Duration(ctl.clientCfg.DialServerKeepAlive)*time.Second), - libdial.WithProxy(proxyType, addr), - libdial.WithProxyAuth(auth), - libdial.WithTLSConfig(tlsConfig), - libdial.WithAfterHook(libdial.AfterHook{ - Hook: frpNet.DialHookCustomTLSHeadByte(tlsConfig != nil, ctl.clientCfg.DisableCustomTLSFirstByte), - }), - ) - conn, err = libdial.Dial( - net.JoinHostPort(ctl.clientCfg.ServerAddr, strconv.Itoa(ctl.clientCfg.ServerPort)), - dialOptions..., - ) - if err != nil { - xl.Warn("start new connection to server error: %v", err) - return nil, err - } - } - return + return ctl.cm.Connect() } // reader read all messages from frps and send to readCh @@ -400,25 +326,20 @@ func (ctl *Control) worker() { go ctl.reader() go ctl.writer() - select { - case <-ctl.closedCh: - // close related channels and wait until other goroutines done - close(ctl.readCh) - ctl.readerShutdown.WaitDone() - ctl.msgHandlerShutdown.WaitDone() + <-ctl.closedCh + // close related channels and wait until other goroutines done + close(ctl.readCh) + ctl.readerShutdown.WaitDone() + ctl.msgHandlerShutdown.WaitDone() - close(ctl.sendCh) - ctl.writerShutdown.WaitDone() + close(ctl.sendCh) + ctl.writerShutdown.WaitDone() - ctl.pm.Close() - ctl.vm.Close() + ctl.pm.Close() + ctl.vm.Close() - close(ctl.closedDoneCh) - if ctl.session != nil { - ctl.session.Close() - } - return - } + close(ctl.closedDoneCh) + ctl.cm.Close() } func (ctl *Control) ReloadConf(pxyCfgs map[string]config.ProxyConf, visitorCfgs map[string]config.VisitorConf) error { diff --git a/client/event/event.go b/client/event/event.go index f9718448823..bf7090d9a30 100644 --- a/client/event/event.go +++ b/client/event/event.go @@ -6,18 +6,9 @@ import ( "github.com/fatedier/frp/pkg/msg" ) -type Type int +var ErrPayloadType = errors.New("error payload type") -const ( - EvStartProxy Type = iota - EvCloseProxy -) - -var ( - ErrPayloadType = errors.New("error payload type") -) - -type Handler func(evType Type, payload interface{}) error +type Handler func(payload interface{}) error type StartProxyPayload struct { NewProxyMsg *msg.NewProxy diff --git a/client/health/health.go b/client/health/health.go index 829bee3df9f..0ee3d04ac9c 100644 --- a/client/health/health.go +++ b/client/health/health.go @@ -26,9 +26,7 @@ import ( "github.com/fatedier/frp/pkg/util/xlog" ) -var ( - ErrHealthCheckType = errors.New("error health check type") -) +var ErrHealthCheckType = errors.New("error health check type") type Monitor struct { checkType string @@ -54,8 +52,8 @@ type Monitor struct { func NewMonitor(ctx context.Context, checkType string, intervalS int, timeoutS int, maxFailedTimes int, addr string, url string, - statusNormalFn func(), statusFailedFn func()) *Monitor { - + statusNormalFn func(), statusFailedFn func(), +) *Monitor { if intervalS <= 0 { intervalS = 10 } @@ -152,7 +150,7 @@ func (monitor *Monitor) doTCPCheck(ctx context.Context) error { } func (monitor *Monitor) doHTTPCheck(ctx context.Context) error { - req, err := http.NewRequest("GET", monitor.url, nil) + req, err := http.NewRequestWithContext(ctx, "GET", monitor.url, nil) if err != nil { return err } @@ -161,7 +159,7 @@ func (monitor *Monitor) doHTTPCheck(ctx context.Context) error { return err } defer resp.Body.Close() - io.Copy(io.Discard, resp.Body) + _, _ = io.Copy(io.Discard, resp.Body) if resp.StatusCode/100 != 2 { return fmt.Errorf("do http health check, StatusCode is [%d] not 2xx", resp.StatusCode) diff --git a/client/proxy/proxy.go b/client/proxy/proxy.go index 340da950c30..158773bc007 100644 --- a/client/proxy/proxy.go +++ b/client/proxy/proxy.go @@ -24,14 +24,6 @@ import ( "sync" "time" - "github.com/fatedier/frp/pkg/config" - "github.com/fatedier/frp/pkg/msg" - plugin "github.com/fatedier/frp/pkg/plugin/client" - "github.com/fatedier/frp/pkg/proto/udp" - "github.com/fatedier/frp/pkg/util/limit" - frpNet "github.com/fatedier/frp/pkg/util/net" - "github.com/fatedier/frp/pkg/util/xlog" - "github.com/fatedier/golib/errors" frpIo "github.com/fatedier/golib/io" libdial "github.com/fatedier/golib/net/dial" @@ -39,6 +31,14 @@ import ( fmux "github.com/hashicorp/yamux" pp "github.com/pires/go-proxyproto" "golang.org/x/time/rate" + + "github.com/fatedier/frp/pkg/config" + "github.com/fatedier/frp/pkg/msg" + plugin "github.com/fatedier/frp/pkg/plugin/client" + "github.com/fatedier/frp/pkg/proto/udp" + "github.com/fatedier/frp/pkg/util/limit" + frpNet "github.com/fatedier/frp/pkg/util/net" + "github.com/fatedier/frp/pkg/util/xlog" ) // Proxy defines how to handle work connections for different proxy type. @@ -322,7 +322,7 @@ func (pxy *XTCPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) { // Wait for client address at most 5 seconds. var natHoleRespMsg msg.NatHoleResp - clientConn.SetReadDeadline(time.Now().Add(5 * time.Second)) + _ = clientConn.SetReadDeadline(time.Now().Add(5 * time.Second)) buf := pool.GetBuf(1024) n, err := clientConn.Read(buf) @@ -335,8 +335,8 @@ func (pxy *XTCPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) { xl.Error("get natHoleRespMsg error: %v", err) return } - clientConn.SetReadDeadline(time.Time{}) - clientConn.Close() + _ = clientConn.SetReadDeadline(time.Time{}) + _ = clientConn.Close() if natHoleRespMsg.Error != "" { xl.Error("natHoleRespMsg get error info: %s", natHoleRespMsg.Error) @@ -357,10 +357,13 @@ func (pxy *XTCPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) { xl.Error("get natHoleResp visitor address error: %v", natHoleRespMsg.VisitorAddr) return } - pxy.sendDetectMsg(host, int(port), laddr, []byte(natHoleRespMsg.Sid)) + _ = pxy.sendDetectMsg(host, int(port), laddr, []byte(natHoleRespMsg.Sid)) xl.Trace("send all detect msg done") - msg.WriteMsg(conn, &msg.NatHoleClientDetectOK{}) + if err := msg.WriteMsg(conn, &msg.NatHoleClientDetectOK{}); err != nil { + xl.Error("write message error: %v", err) + return + } // Listen for clientConn's address and wait for visitor connection lConn, err := net.ListenUDP("udp", laddr) @@ -370,7 +373,7 @@ func (pxy *XTCPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) { } defer lConn.Close() - lConn.SetReadDeadline(time.Now().Add(8 * time.Second)) + _ = lConn.SetReadDeadline(time.Now().Add(8 * time.Second)) sidBuf := pool.GetBuf(1024) var uAddr *net.UDPAddr n, uAddr, err = lConn.ReadFromUDP(sidBuf) @@ -378,7 +381,7 @@ func (pxy *XTCPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) { xl.Warn("get sid from visitor error: %v", err) return } - lConn.SetReadDeadline(time.Time{}) + _ = lConn.SetReadDeadline(time.Time{}) if string(sidBuf[:n]) != natHoleRespMsg.Sid { xl.Warn("incorrect sid from visitor") return @@ -386,7 +389,10 @@ func (pxy *XTCPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) { pool.PutBuf(sidBuf) xl.Info("nat hole connection make success, sid [%s]", natHoleRespMsg.Sid) - lConn.WriteToUDP(sidBuf[:n], uAddr) + if _, err := lConn.WriteToUDP(sidBuf[:n], uAddr); err != nil { + xl.Error("write uaddr error: %v", err) + return + } kcpConn, err := frpNet.NewKCPConnFromUDP(lConn, false, uAddr.String()) if err != nil { @@ -424,12 +430,13 @@ func (pxy *XTCPProxy) sendDetectMsg(addr string, port int, laddr *net.UDPAddr, c return err } - //uConn := ipv4.NewConn(tConn) - //uConn.SetTTL(3) + // uConn := ipv4.NewConn(tConn) + // uConn.SetTTL(3) - tConn.Write(content) - tConn.Close() - return nil + if _, err := tConn.Write(content); err != nil { + return err + } + return tConn.Close() } // UDP @@ -539,7 +546,7 @@ func (pxy *UDPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) { } } } - heartbeatFn := func(conn net.Conn, sendCh chan msg.Message) { + heartbeatFn := func(sendCh chan msg.Message) { var errRet error for { time.Sleep(time.Duration(30) * time.Second) @@ -554,7 +561,7 @@ func (pxy *UDPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) { go workConnSenderFn(pxy.workConn, pxy.sendCh) go workConnReaderFn(pxy.workConn, pxy.readCh) - go heartbeatFn(pxy.workConn, pxy.sendCh) + go heartbeatFn(pxy.sendCh) udp.Forwarder(pxy.localAddr, pxy.readCh, pxy.sendCh, int(pxy.clientCfg.UDPPacketSize)) } @@ -685,7 +692,7 @@ func (pxy *SUDPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) { } } - heartbeatFn := func(conn net.Conn, sendCh chan msg.Message) { + heartbeatFn := func(sendCh chan msg.Message) { ticker := time.NewTicker(30 * time.Second) defer func() { ticker.Stop() @@ -711,14 +718,15 @@ func (pxy *SUDPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) { go workConnSenderFn(workConn, sendCh) go workConnReaderFn(workConn, readCh) - go heartbeatFn(workConn, sendCh) + go heartbeatFn(sendCh) udp.Forwarder(pxy.localAddr, readCh, sendCh, int(pxy.clientCfg.UDPPacketSize)) } // Common handler for tcp work connections. func HandleTCPWorkConnection(ctx context.Context, localInfo *config.LocalSvrConf, proxyPlugin plugin.Plugin, - baseInfo *config.BaseProxyConf, limiter *rate.Limiter, workConn net.Conn, encKey []byte, m *msg.StartWorkConn) { + baseInfo *config.BaseProxyConf, limiter *rate.Limiter, workConn net.Conn, encKey []byte, m *msg.StartWorkConn, +) { xl := xlog.FromContextSafe(ctx) var ( remote io.ReadWriteCloser @@ -773,7 +781,7 @@ func HandleTCPWorkConnection(ctx context.Context, localInfo *config.LocalSvrConf } buf := bytes.NewBuffer(nil) - h.WriteTo(buf) + _, _ = h.WriteTo(buf) extraInfo = buf.Bytes() } } @@ -800,7 +808,11 @@ func HandleTCPWorkConnection(ctx context.Context, localInfo *config.LocalSvrConf localConn.RemoteAddr().String(), workConn.LocalAddr().String(), workConn.RemoteAddr().String()) if len(extraInfo) > 0 { - localConn.Write(extraInfo) + if _, err := localConn.Write(extraInfo); err != nil { + workConn.Close() + xl.Error("write extraInfo to local conn error: %v", err) + return + } } frpIo.Join(localConn, remote) diff --git a/client/proxy/proxy_manager.go b/client/proxy/proxy_manager.go index 98c17faa984..563531e81df 100644 --- a/client/proxy/proxy_manager.go +++ b/client/proxy/proxy_manager.go @@ -6,12 +6,12 @@ import ( "net" "sync" + "github.com/fatedier/golib/errors" + "github.com/fatedier/frp/client/event" "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/msg" "github.com/fatedier/frp/pkg/util/xlog" - - "github.com/fatedier/golib/errors" ) type Manager struct { @@ -75,7 +75,7 @@ func (pm *Manager) HandleWorkConn(name string, workConn net.Conn, m *msg.StartWo } } -func (pm *Manager) HandleEvent(evType event.Type, payload interface{}) error { +func (pm *Manager) HandleEvent(payload interface{}) error { var m msg.Message switch e := payload.(type) { case *event.StartProxyPayload: @@ -113,10 +113,8 @@ func (pm *Manager) Reload(pxyCfgs map[string]config.ProxyConf) { cfg, ok := pxyCfgs[name] if !ok { del = true - } else { - if !pxy.Cfg.Compare(cfg) { - del = true - } + } else if !pxy.Cfg.Compare(cfg) { + del = true } if del { diff --git a/client/proxy/proxy_wrapper.go b/client/proxy/proxy_wrapper.go index a6f0233bd3f..af217f06d1b 100644 --- a/client/proxy/proxy_wrapper.go +++ b/client/proxy/proxy_wrapper.go @@ -8,13 +8,13 @@ import ( "sync/atomic" "time" + "github.com/fatedier/golib/errors" + "github.com/fatedier/frp/client/event" "github.com/fatedier/frp/client/health" "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/msg" "github.com/fatedier/frp/pkg/util/xlog" - - "github.com/fatedier/golib/errors" ) const ( @@ -27,9 +27,9 @@ const ( ) var ( - statusCheckInterval time.Duration = 3 * time.Second - waitResponseTimeout = 20 * time.Second - startErrTimeout = 30 * time.Second + statusCheckInterval = 3 * time.Second + waitResponseTimeout = 20 * time.Second + startErrTimeout = 30 * time.Second ) type WorkingStatus struct { @@ -145,7 +145,7 @@ func (pw *Wrapper) Stop() { } func (pw *Wrapper) close() { - pw.handler(event.EvCloseProxy, &event.CloseProxyPayload{ + _ = pw.handler(&event.CloseProxyPayload{ CloseProxyMsg: &msg.CloseProxy{ ProxyName: pw.Name, }, @@ -174,7 +174,7 @@ func (pw *Wrapper) checkWorker() { var newProxyMsg msg.NewProxy pw.Cfg.MarshalToMsg(&newProxyMsg) pw.lastSendStartMsg = now - pw.handler(event.EvStartProxy, &event.StartProxyPayload{ + _ = pw.handler(&event.StartProxyPayload{ NewProxyMsg: &newProxyMsg, }) } @@ -201,7 +201,7 @@ func (pw *Wrapper) checkWorker() { func (pw *Wrapper) statusNormalCallback() { xl := pw.xl atomic.StoreUint32(&pw.health, 0) - errors.PanicToError(func() { + _ = errors.PanicToError(func() { select { case pw.healthNotifyCh <- struct{}{}: default: @@ -213,7 +213,7 @@ func (pw *Wrapper) statusNormalCallback() { func (pw *Wrapper) statusFailedCallback() { xl := pw.xl atomic.StoreUint32(&pw.health, 1) - errors.PanicToError(func() { + _ = errors.PanicToError(func() { select { case pw.healthNotifyCh <- struct{}{}: default: diff --git a/client/service.go b/client/service.go index 30bd3f8f5bc..b72fea7731d 100644 --- a/client/service.go +++ b/client/service.go @@ -28,6 +28,11 @@ import ( "sync/atomic" "time" + "github.com/fatedier/golib/crypto" + libdial "github.com/fatedier/golib/net/dial" + fmux "github.com/hashicorp/yamux" + quic "github.com/lucas-clemente/quic-go" + "github.com/fatedier/frp/assets" "github.com/fatedier/frp/pkg/auth" "github.com/fatedier/frp/pkg/config" @@ -38,10 +43,6 @@ import ( "github.com/fatedier/frp/pkg/util/util" "github.com/fatedier/frp/pkg/util/version" "github.com/fatedier/frp/pkg/util/xlog" - "github.com/fatedier/golib/crypto" - libdial "github.com/fatedier/golib/net/dial" - - fmux "github.com/hashicorp/yamux" ) func init() { @@ -81,8 +82,12 @@ type Service struct { cancel context.CancelFunc } -func NewService(cfg config.ClientCommonConf, pxyCfgs map[string]config.ProxyConf, visitorCfgs map[string]config.VisitorConf, cfgFile string) (svr *Service, err error) { - +func NewService( + cfg config.ClientCommonConf, + pxyCfgs map[string]config.ProxyConf, + visitorCfgs map[string]config.VisitorConf, + cfgFile string, +) (svr *Service, err error) { ctx, cancel := context.WithCancel(context.Background()) svr = &Service{ authSetter: auth.NewAuthSetter(cfg.ClientConfig), @@ -123,7 +128,7 @@ func (svr *Service) Run() error { // login to frps for { - conn, session, err := svr.login() + conn, cm, err := svr.login() if err != nil { xl.Warn("login to server failed: %v", err) @@ -135,7 +140,7 @@ func (svr *Service) Run() error { 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) + ctl := NewControl(svr.ctx, svr.runID, conn, cm, svr.cfg, svr.pxyCfgs, svr.visitorCfgs, svr.serverUDPPort, svr.authSetter) ctl.Run() svr.ctlMu.Lock() svr.ctl = ctl @@ -198,13 +203,17 @@ func (svr *Service) keepControllerWorking() { } for { + if atomic.LoadUint32(&svr.exit) != 0 { + return + } + xl.Info("try to reconnect to server...") - conn, session, err := svr.login() + conn, cm, err := svr.login() if err != nil { xl.Warn("reconnect to server error: %v, wait %v for another retry", err, delayTime) util.RandomSleep(delayTime, 0.9, 1.1) - delayTime = delayTime * 2 + delayTime *= 2 if delayTime > maxDelayTime { delayTime = maxDelayTime } @@ -213,7 +222,7 @@ func (svr *Service) keepControllerWorking() { // reconnect success, init delayTime delayTime = time.Second - ctl := NewControl(svr.ctx, svr.runID, conn, session, svr.cfg, svr.pxyCfgs, svr.visitorCfgs, svr.serverUDPPort, svr.authSetter) + ctl := NewControl(svr.ctx, svr.runID, conn, cm, svr.cfg, svr.pxyCfgs, svr.visitorCfgs, svr.serverUDPPort, svr.authSetter) ctl.Run() svr.ctlMu.Lock() if svr.ctl != nil { @@ -229,83 +238,23 @@ func (svr *Service) keepControllerWorking() { // login creates a connection to frps and registers it self as a client // conn: control connection // session: if it's not nil, using tcp mux -func (svr *Service) login() (conn net.Conn, session *fmux.Session, err error) { +func (svr *Service) login() (conn net.Conn, cm *ConnectionManager, err error) { xl := xlog.FromContextSafe(svr.ctx) - var tlsConfig *tls.Config - if svr.cfg.TLSEnable { - sn := svr.cfg.TLSServerName - if sn == "" { - sn = svr.cfg.ServerAddr - } + cm = NewConnectionManager(svr.ctx, &svr.cfg) - tlsConfig, err = transport.NewClientTLSConfig( - svr.cfg.TLSCertFile, - svr.cfg.TLSKeyFile, - svr.cfg.TLSTrustedCaFile, - sn) - if err != nil { - xl.Warn("fail to build tls configuration when service login, err: %v", err) - return - } - } - - proxyType, addr, auth, err := libdial.ParseProxyURL(svr.cfg.HTTPProxy) - if err != nil { - xl.Error("fail to parse proxy url") - return - } - dialOptions := []libdial.DialOption{} - protocol := svr.cfg.Protocol - if protocol == "websocket" { - protocol = "tcp" - dialOptions = append(dialOptions, libdial.WithAfterHook(libdial.AfterHook{Hook: frpNet.DialHookWebsocket()})) - } - if svr.cfg.ConnectServerLocalIP != "" { - dialOptions = append(dialOptions, libdial.WithLocalAddr(svr.cfg.ConnectServerLocalIP)) - } - dialOptions = append(dialOptions, - libdial.WithProtocol(protocol), - libdial.WithTimeout(time.Duration(svr.cfg.DialServerTimeout)*time.Second), - libdial.WithKeepAlive(time.Duration(svr.cfg.DialServerKeepAlive)*time.Second), - libdial.WithProxy(proxyType, addr), - libdial.WithProxyAuth(auth), - libdial.WithTLSConfig(tlsConfig), - libdial.WithAfterHook(libdial.AfterHook{ - Hook: frpNet.DialHookCustomTLSHeadByte(tlsConfig != nil, svr.cfg.DisableCustomTLSFirstByte), - }), - ) - conn, err = libdial.Dial( - net.JoinHostPort(svr.cfg.ServerAddr, strconv.Itoa(svr.cfg.ServerPort)), - dialOptions..., - ) - if err != nil { - return + if err = cm.OpenConnection(); err != nil { + return nil, nil, err } defer func() { if err != nil { - conn.Close() - if session != nil { - session.Close() - } + cm.Close() } }() - if svr.cfg.TCPMux { - fmuxCfg := fmux.DefaultConfig() - fmuxCfg.KeepAliveInterval = time.Duration(svr.cfg.TCPMuxKeepaliveInterval) * time.Second - fmuxCfg.LogOutput = io.Discard - session, err = fmux.Client(conn, fmuxCfg) - if err != nil { - return - } - stream, errRet := session.OpenStream() - if errRet != nil { - session.Close() - err = errRet - return - } - conn = stream + conn, err = cm.Connect() + if err != nil { + return } loginMsg := &msg.Login{ @@ -329,11 +278,11 @@ func (svr *Service) login() (conn net.Conn, session *fmux.Session, err error) { } var loginRespMsg msg.LoginResp - conn.SetReadDeadline(time.Now().Add(10 * time.Second)) + _ = conn.SetReadDeadline(time.Now().Add(10 * time.Second)) if err = msg.ReadMsgInto(conn, &loginRespMsg); err != nil { return } - conn.SetReadDeadline(time.Time{}) + _ = conn.SetReadDeadline(time.Time{}) if loginRespMsg.Error != "" { err = fmt.Errorf("%s", loginRespMsg.Error) @@ -381,3 +330,159 @@ func (svr *Service) GracefulClose(d time.Duration) { svr.cancel() } + +type ConnectionManager struct { + ctx context.Context + cfg *config.ClientCommonConf + + muxSession *fmux.Session + quicConn quic.Connection +} + +func NewConnectionManager(ctx context.Context, cfg *config.ClientCommonConf) *ConnectionManager { + return &ConnectionManager{ + ctx: ctx, + cfg: cfg, + } +} + +func (cm *ConnectionManager) OpenConnection() error { + xl := xlog.FromContextSafe(cm.ctx) + + // special for quic + if strings.EqualFold(cm.cfg.Protocol, "quic") { + var tlsConfig *tls.Config + var err error + sn := cm.cfg.TLSServerName + if sn == "" { + sn = cm.cfg.ServerAddr + } + if cm.cfg.TLSEnable { + tlsConfig, err = transport.NewClientTLSConfig( + cm.cfg.TLSCertFile, + cm.cfg.TLSKeyFile, + cm.cfg.TLSTrustedCaFile, + sn) + } else { + tlsConfig, err = transport.NewClientTLSConfig("", "", "", sn) + } + if err != nil { + xl.Warn("fail to build tls configuration, err: %v", err) + return err + } + tlsConfig.NextProtos = []string{"frp"} + + conn, err := quic.DialAddr( + net.JoinHostPort(cm.cfg.ServerAddr, strconv.Itoa(cm.cfg.ServerPort)), + tlsConfig, &quic.Config{ + MaxIdleTimeout: time.Duration(cm.cfg.QUICMaxIdleTimeout) * time.Second, + MaxIncomingStreams: int64(cm.cfg.QUICMaxIncomingStreams), + KeepAlivePeriod: time.Duration(cm.cfg.QUICKeepalivePeriod) * time.Second, + }) + if err != nil { + return err + } + cm.quicConn = conn + return nil + } + + if !cm.cfg.TCPMux { + return nil + } + + conn, err := cm.realConnect() + if err != nil { + return err + } + + fmuxCfg := fmux.DefaultConfig() + fmuxCfg.KeepAliveInterval = time.Duration(cm.cfg.TCPMuxKeepaliveInterval) * time.Second + fmuxCfg.LogOutput = io.Discard + session, err := fmux.Client(conn, fmuxCfg) + if err != nil { + return err + } + cm.muxSession = session + return nil +} + +func (cm *ConnectionManager) Connect() (net.Conn, error) { + if cm.quicConn != nil { + stream, err := cm.quicConn.OpenStreamSync(context.Background()) + if err != nil { + return nil, err + } + return frpNet.QuicStreamToNetConn(stream, cm.quicConn), nil + } else if cm.muxSession != nil { + stream, err := cm.muxSession.OpenStream() + if err != nil { + return nil, err + } + return stream, nil + } + + return cm.realConnect() +} + +func (cm *ConnectionManager) realConnect() (net.Conn, error) { + xl := xlog.FromContextSafe(cm.ctx) + var tlsConfig *tls.Config + var err error + if cm.cfg.TLSEnable { + sn := cm.cfg.TLSServerName + if sn == "" { + sn = cm.cfg.ServerAddr + } + + tlsConfig, err = transport.NewClientTLSConfig( + cm.cfg.TLSCertFile, + cm.cfg.TLSKeyFile, + cm.cfg.TLSTrustedCaFile, + sn) + if err != nil { + xl.Warn("fail to build tls configuration, err: %v", err) + return nil, err + } + } + + proxyType, addr, auth, err := libdial.ParseProxyURL(cm.cfg.HTTPProxy) + if err != nil { + xl.Error("fail to parse proxy url") + return nil, err + } + dialOptions := []libdial.DialOption{} + protocol := cm.cfg.Protocol + if protocol == "websocket" { + protocol = "tcp" + dialOptions = append(dialOptions, libdial.WithAfterHook(libdial.AfterHook{Hook: frpNet.DialHookWebsocket()})) + } + if cm.cfg.ConnectServerLocalIP != "" { + dialOptions = append(dialOptions, libdial.WithLocalAddr(cm.cfg.ConnectServerLocalIP)) + } + dialOptions = append(dialOptions, + libdial.WithProtocol(protocol), + libdial.WithTimeout(time.Duration(cm.cfg.DialServerTimeout)*time.Second), + libdial.WithKeepAlive(time.Duration(cm.cfg.DialServerKeepAlive)*time.Second), + libdial.WithProxy(proxyType, addr), + libdial.WithProxyAuth(auth), + libdial.WithTLSConfig(tlsConfig), + libdial.WithAfterHook(libdial.AfterHook{ + Hook: frpNet.DialHookCustomTLSHeadByte(tlsConfig != nil, cm.cfg.DisableCustomTLSFirstByte), + }), + ) + conn, err := libdial.Dial( + net.JoinHostPort(cm.cfg.ServerAddr, strconv.Itoa(cm.cfg.ServerPort)), + dialOptions..., + ) + return conn, err +} + +func (cm *ConnectionManager) Close() error { + if cm.quicConn != nil { + _ = cm.quicConn.CloseWithError(0, "") + } + if cm.muxSession != nil { + _ = cm.muxSession.Close() + } + return nil +} diff --git a/client/visitor.go b/client/visitor.go index ba1cd7cb98b..1d7386f70db 100644 --- a/client/visitor.go +++ b/client/visitor.go @@ -24,17 +24,17 @@ import ( "sync" "time" + "github.com/fatedier/golib/errors" + frpIo "github.com/fatedier/golib/io" + "github.com/fatedier/golib/pool" + fmux "github.com/hashicorp/yamux" + "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/msg" "github.com/fatedier/frp/pkg/proto/udp" frpNet "github.com/fatedier/frp/pkg/util/net" "github.com/fatedier/frp/pkg/util/util" "github.com/fatedier/frp/pkg/util/xlog" - - "github.com/fatedier/golib/errors" - frpIo "github.com/fatedier/golib/io" - "github.com/fatedier/golib/pool" - fmux "github.com/hashicorp/yamux" ) // Visitor is used for forward traffics from local port tot remote service. @@ -71,9 +71,8 @@ func NewVisitor(ctx context.Context, ctl *Control, cfg config.VisitorConf) (visi } type BaseVisitor struct { - ctl *Control - l net.Listener - closed bool + ctl *Control + l net.Listener mu sync.RWMutex ctx context.Context @@ -138,13 +137,13 @@ func (sv *STCPVisitor) handleConn(userConn net.Conn) { } var newVisitorConnRespMsg msg.NewVisitorConnResp - visitorConn.SetReadDeadline(time.Now().Add(10 * time.Second)) + _ = visitorConn.SetReadDeadline(time.Now().Add(10 * time.Second)) err = msg.ReadMsgInto(visitorConn, &newVisitorConnRespMsg) if err != nil { xl.Warn("get newVisitorConnRespMsg error: %v", err) return } - visitorConn.SetReadDeadline(time.Time{}) + _ = visitorConn.SetReadDeadline(time.Time{}) if newVisitorConnRespMsg.Error != "" { xl.Warn("start new visitor connection error: %s", newVisitorConnRespMsg.Error) @@ -239,7 +238,7 @@ func (sv *XTCPVisitor) handleConn(userConn net.Conn) { // Wait for client address at most 10 seconds. var natHoleRespMsg msg.NatHoleResp - visitorConn.SetReadDeadline(time.Now().Add(10 * time.Second)) + _ = visitorConn.SetReadDeadline(time.Now().Add(10 * time.Second)) buf := pool.GetBuf(1024) n, err := visitorConn.Read(buf) if err != nil { @@ -252,7 +251,7 @@ func (sv *XTCPVisitor) handleConn(userConn net.Conn) { xl.Warn("get natHoleRespMsg error: %v", err) return } - visitorConn.SetReadDeadline(time.Time{}) + _ = visitorConn.SetReadDeadline(time.Time{}) pool.PutBuf(buf) if natHoleRespMsg.Error != "" { @@ -279,17 +278,20 @@ func (sv *XTCPVisitor) handleConn(userConn net.Conn) { } defer lConn.Close() - lConn.Write([]byte(natHoleRespMsg.Sid)) + if _, err := lConn.Write([]byte(natHoleRespMsg.Sid)); err != nil { + xl.Error("write sid error: %v", err) + return + } // read ack sid from client sidBuf := pool.GetBuf(1024) - lConn.SetReadDeadline(time.Now().Add(8 * time.Second)) + _ = lConn.SetReadDeadline(time.Now().Add(8 * time.Second)) n, err = lConn.Read(sidBuf) if err != nil { xl.Warn("get sid from client error: %v", err) return } - lConn.SetReadDeadline(time.Time{}) + _ = lConn.SetReadDeadline(time.Time{}) if string(sidBuf[:n]) != natHoleRespMsg.Sid { xl.Warn("incorrect sid from client") return @@ -411,7 +413,6 @@ func (sv *SUDPVisitor) dispatcher() { default: } } - } func (sv *SUDPVisitor) worker(workConn net.Conn, firstPacket *msg.UDPPacket) { @@ -437,13 +438,13 @@ func (sv *SUDPVisitor) worker(workConn net.Conn, firstPacket *msg.UDPPacket) { ) // frpc will send heartbeat in workConn to frpc visitor for keeping alive - conn.SetReadDeadline(time.Now().Add(60 * time.Second)) + _ = conn.SetReadDeadline(time.Now().Add(60 * time.Second)) if rawMsg, errRet = msg.ReadMsg(conn); errRet != nil { xl.Warn("read from workconn for user udp conn error: %v", errRet) return } - conn.SetReadDeadline(time.Time{}) + _ = conn.SetReadDeadline(time.Time{}) switch m := rawMsg.(type) { case *msg.Ping: xl.Debug("frpc visitor get ping message from frpc") @@ -523,12 +524,12 @@ func (sv *SUDPVisitor) getNewVisitorConn() (net.Conn, error) { } var newVisitorConnRespMsg msg.NewVisitorConnResp - visitorConn.SetReadDeadline(time.Now().Add(10 * time.Second)) + _ = visitorConn.SetReadDeadline(time.Now().Add(10 * time.Second)) err = msg.ReadMsgInto(visitorConn, &newVisitorConnRespMsg) if err != nil { return nil, fmt.Errorf("frpc read newVisitorConnRespMsg error: %v", err) } - visitorConn.SetReadDeadline(time.Time{}) + _ = visitorConn.SetReadDeadline(time.Time{}) if newVisitorConnRespMsg.Error != "" { return nil, fmt.Errorf("start new visitor connection error: %s", newVisitorConnRespMsg.Error) diff --git a/client/visitor_manager.go b/client/visitor_manager.go index 642b21e8f2f..8df47150937 100644 --- a/client/visitor_manager.go +++ b/client/visitor_manager.go @@ -65,7 +65,7 @@ func (vm *VisitorManager) Run() { name := cfg.GetBaseInfo().ProxyName if _, exist := vm.visitors[name]; !exist { xl.Info("try to start visitor [%s]", name) - vm.startVisitor(cfg) + _ = vm.startVisitor(cfg) } } vm.mu.Unlock() @@ -99,10 +99,8 @@ func (vm *VisitorManager) Reload(cfgs map[string]config.VisitorConf) { cfg, ok := cfgs[name] if !ok { del = true - } else { - if !oldCfg.Compare(cfg) { - del = true - } + } else if !oldCfg.Compare(cfg) { + del = true } if del { @@ -123,13 +121,12 @@ func (vm *VisitorManager) Reload(cfgs map[string]config.VisitorConf) { if _, ok := vm.cfgs[name]; !ok { vm.cfgs[name] = cfg addNames = append(addNames, name) - vm.startVisitor(cfg) + _ = vm.startVisitor(cfg) } } if len(addNames) > 0 { xl.Info("visitor added: %v", addNames) } - return } func (vm *VisitorManager) Close() { diff --git a/cmd/frpc/sub/http.go b/cmd/frpc/sub/http.go index 2e19fce4f67..4e193b7e2b5 100644 --- a/cmd/frpc/sub/http.go +++ b/cmd/frpc/sub/http.go @@ -19,10 +19,10 @@ import ( "os" "strings" + "github.com/spf13/cobra" + "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/consts" - - "github.com/spf13/cobra" ) func init() { diff --git a/cmd/frpc/sub/reload.go b/cmd/frpc/sub/reload.go index c625daedb43..258317e7d6a 100644 --- a/cmd/frpc/sub/reload.go +++ b/cmd/frpc/sub/reload.go @@ -22,9 +22,9 @@ import ( "os" "strings" - "github.com/fatedier/frp/pkg/config" - "github.com/spf13/cobra" + + "github.com/fatedier/frp/pkg/config" ) func init() { diff --git a/cmd/frpc/sub/root.go b/cmd/frpc/sub/root.go index f8d7eb17708..cea8ecc6876 100644 --- a/cmd/frpc/sub/root.go +++ b/cmd/frpc/sub/root.go @@ -26,13 +26,13 @@ import ( "syscall" "time" + "github.com/spf13/cobra" + "github.com/fatedier/frp/client" "github.com/fatedier/frp/pkg/auth" "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/util/log" "github.com/fatedier/frp/pkg/util/version" - - "github.com/spf13/cobra" ) const ( @@ -107,7 +107,7 @@ var rootCmd = &cobra.Command{ // Note that it's only designed for testing. It's not guaranteed to be stable. if cfgDir != "" { var wg sync.WaitGroup - filepath.WalkDir(cfgDir, func(path string, d fs.DirEntry, err error) error { + _ = filepath.WalkDir(cfgDir, func(path string, d fs.DirEntry, err error) error { if err != nil { return nil } @@ -183,7 +183,7 @@ func parseClientCommonCfgFromCmd() (cfg config.ClientCommonConf, err error) { cfg.Complete() if err = cfg.Validate(); err != nil { - err = fmt.Errorf("Parse config error: %v", err) + err = fmt.Errorf("parse config error: %v", err) return } return @@ -203,7 +203,6 @@ func startService( visitorCfgs map[string]config.VisitorConf, cfgFile string, ) (err error) { - log.InitLog(cfg.LogWay, cfg.LogFile, cfg.LogLevel, cfg.LogMaxDays, cfg.DisableLogColor) diff --git a/cmd/frpc/sub/status.go b/cmd/frpc/sub/status.go index 52c1c1954cf..c9a6a98dec5 100644 --- a/cmd/frpc/sub/status.go +++ b/cmd/frpc/sub/status.go @@ -23,11 +23,11 @@ import ( "os" "strings" - "github.com/fatedier/frp/client" - "github.com/fatedier/frp/pkg/config" - "github.com/rodaine/table" "github.com/spf13/cobra" + + "github.com/fatedier/frp/client" + "github.com/fatedier/frp/pkg/config" ) func init() { diff --git a/cmd/frpc/sub/stcp.go b/cmd/frpc/sub/stcp.go index 45f01e59872..989387bb795 100644 --- a/cmd/frpc/sub/stcp.go +++ b/cmd/frpc/sub/stcp.go @@ -18,10 +18,10 @@ import ( "fmt" "os" + "github.com/spf13/cobra" + "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/consts" - - "github.com/spf13/cobra" ) func init() { diff --git a/cmd/frpc/sub/sudp.go b/cmd/frpc/sub/sudp.go index 45c5ad61b2d..c781223ddb5 100644 --- a/cmd/frpc/sub/sudp.go +++ b/cmd/frpc/sub/sudp.go @@ -18,10 +18,10 @@ import ( "fmt" "os" + "github.com/spf13/cobra" + "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/consts" - - "github.com/spf13/cobra" ) func init() { diff --git a/cmd/frpc/sub/udp.go b/cmd/frpc/sub/udp.go index 2ce4327e4dd..984ad068d95 100644 --- a/cmd/frpc/sub/udp.go +++ b/cmd/frpc/sub/udp.go @@ -18,10 +18,10 @@ import ( "fmt" "os" + "github.com/spf13/cobra" + "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/consts" - - "github.com/spf13/cobra" ) func init() { diff --git a/cmd/frpc/sub/verify.go b/cmd/frpc/sub/verify.go index 76872b90b82..c86b1e82b9c 100644 --- a/cmd/frpc/sub/verify.go +++ b/cmd/frpc/sub/verify.go @@ -18,9 +18,9 @@ import ( "fmt" "os" - "github.com/fatedier/frp/pkg/config" - "github.com/spf13/cobra" + + "github.com/fatedier/frp/pkg/config" ) func init() { diff --git a/cmd/frpc/sub/xtcp.go b/cmd/frpc/sub/xtcp.go index 6c6c7d84bb0..069cce7e161 100644 --- a/cmd/frpc/sub/xtcp.go +++ b/cmd/frpc/sub/xtcp.go @@ -18,10 +18,10 @@ import ( "fmt" "os" + "github.com/spf13/cobra" + "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/consts" - - "github.com/spf13/cobra" ) func init() { diff --git a/cmd/frps/root.go b/cmd/frps/root.go index d31944ac409..955c90fb730 100644 --- a/cmd/frps/root.go +++ b/cmd/frps/root.go @@ -18,14 +18,14 @@ import ( "fmt" "os" + "github.com/spf13/cobra" + "github.com/fatedier/frp/pkg/auth" "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/util/log" "github.com/fatedier/frp/pkg/util/util" "github.com/fatedier/frp/pkg/util/version" "github.com/fatedier/frp/server" - - "github.com/spf13/cobra" ) const ( @@ -50,16 +50,13 @@ var ( dashboardUser string dashboardPwd string enablePrometheus bool - assetsDir string logFile string logLevel string logMaxDays int64 disableLogColor bool token string subDomainHost string - tcpMux bool allowPorts string - maxPoolCount int64 maxPortsPerClient int64 tlsOnly bool dashboardTLSMode bool @@ -151,7 +148,7 @@ func parseServerCommonCfg(fileType int, source []byte) (cfg config.ServerCommonC cfg.Complete() err = cfg.Validate() if err != nil { - err = fmt.Errorf("Parse config error: %v", err) + err = fmt.Errorf("parse config error: %v", err) return } return @@ -189,7 +186,7 @@ func parseServerCommonCfgFromCmd() (cfg config.ServerCommonConf, err error) { // e.g. 1000-2000,2001,2002,3000-4000 ports, errRet := util.ParseRangeNumbers(allowPorts) if errRet != nil { - err = fmt.Errorf("Parse conf error: allow_ports: %v", errRet) + err = fmt.Errorf("parse conf error: allow_ports: %v", errRet) return } diff --git a/cmd/frps/verify.go b/cmd/frps/verify.go index 35b2acdf181..42f2ca74b08 100644 --- a/cmd/frps/verify.go +++ b/cmd/frps/verify.go @@ -18,9 +18,9 @@ import ( "fmt" "os" - "github.com/fatedier/frp/pkg/config" - "github.com/spf13/cobra" + + "github.com/fatedier/frp/pkg/config" ) func init() { diff --git a/conf/frpc_full.ini b/conf/frpc_full.ini index 9c939678b1f..8e39de1c9f7 100644 --- a/conf/frpc_full.ini +++ b/conf/frpc_full.ini @@ -40,6 +40,8 @@ authenticate_new_work_conns = false # auth token token = 12345678 +authentication_method = + # oidc_client_id specifies the client ID to use to get a token in OIDC authentication if AuthenticationMethod == "oidc". # By default, this value is "". oidc_client_id = @@ -51,6 +53,9 @@ oidc_client_secret = # oidc_audience specifies the audience of the token in OIDC authentication if AuthenticationMethod == "oidc". By default, this value is "". oidc_audience = +# oidc_scope specifies the permisssions of the token in OIDC authentication if AuthenticationMethod == "oidc". By default, this value is "". +oidc_scope = + # oidc_token_endpoint_url specifies the URL which implements OIDC Token Endpoint. # It will be used to get an OIDC token if AuthenticationMethod == "oidc". By default, this value is "". oidc_token_endpoint_url = @@ -87,13 +92,18 @@ user = your_name login_fail_exit = true # communication protocol used to connect to server -# now it supports tcp, kcp and websocket, default is tcp +# supports tcp, kcp, quic and websocket now, default is tcp protocol = tcp # set client binding ip when connect server, default is empty. # only when protocol = tcp or websocket, the value will be used. connect_server_local_ip = 0.0.0.0 +# quic protocol options +# quic_keepalive_period = 10 +# quic_max_idle_timeout = 30 +# quic_max_incoming_streams = 100000 + # if tls_enable is true, frpc will connect frps by tls tls_enable = true diff --git a/conf/frps_full.ini b/conf/frps_full.ini index 45b222f4d6e..2d5e08e172e 100644 --- a/conf/frps_full.ini +++ b/conf/frps_full.ini @@ -9,10 +9,18 @@ bind_port = 7000 # udp port to help make udp hole to penetrate nat bind_udp_port = 7001 -# udp port used for kcp protocol, it can be same with 'bind_port' -# if not set, kcp is disabled in frps +# udp port used for kcp protocol, it can be same with 'bind_port'. +# if not set, kcp is disabled in frps. kcp_bind_port = 7000 +# udp port used for quic protocol. +# if not set, quic is disabled in frps. +# quic_bind_port = 7002 +# quic protocol options +# quic_keepalive_period = 10 +# quic_max_idle_timeout = 30 +# quic_max_incoming_streams = 100000 + # specify which address proxy will listen for, default value is same with bind_addr # proxy_bind_addr = 127.0.0.1 diff --git a/dockerfiles/Dockerfile-for-frpc b/dockerfiles/Dockerfile-for-frpc index ece950f2190..b749be0704b 100644 --- a/dockerfiles/Dockerfile-for-frpc +++ b/dockerfiles/Dockerfile-for-frpc @@ -1,4 +1,4 @@ -FROM golang:1.18 AS building +FROM golang:1.19 AS building COPY . /building WORKDIR /building diff --git a/dockerfiles/Dockerfile-for-frps b/dockerfiles/Dockerfile-for-frps index d8ab8247a3a..cd716123fb1 100644 --- a/dockerfiles/Dockerfile-for-frps +++ b/dockerfiles/Dockerfile-for-frps @@ -1,4 +1,4 @@ -FROM golang:1.18 AS building +FROM golang:1.19 AS building COPY . /building WORKDIR /building diff --git a/go.mod b/go.mod index 0a92dfb5a65..d518a612d0c 100644 --- a/go.mod +++ b/go.mod @@ -1,33 +1,76 @@ module github.com/fatedier/frp -go 1.16 +go 1.19 require ( github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 - github.com/coreos/go-oidc v2.2.1+incompatible + github.com/coreos/go-oidc/v3 v3.4.0 github.com/fatedier/beego v0.0.0-20171024143340-6c6a4f5bd5eb github.com/fatedier/golib v0.1.1-0.20220321042308-c306138b83ac 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 + github.com/go-playground/validator/v10 v10.11.0 + github.com/google/uuid v1.3.0 github.com/gorilla/mux v1.8.0 - github.com/gorilla/websocket v1.4.2 - github.com/hashicorp/yamux v0.0.0-20210707203944-259a57b3608c - github.com/leodido/go-urn v1.2.1 // indirect + github.com/gorilla/websocket v1.5.0 + github.com/hashicorp/yamux v0.1.1 + github.com/lucas-clemente/quic-go v0.31.0 github.com/onsi/ginkgo v1.16.4 - github.com/onsi/gomega v1.13.0 + github.com/onsi/gomega v1.20.2 github.com/pires/go-proxyproto v0.6.2 - github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect - github.com/prometheus/client_golang v1.11.0 + github.com/prometheus/client_golang v1.13.0 github.com/rodaine/table v1.0.1 github.com/spf13/cobra v1.1.3 github.com/stretchr/testify v1.7.0 - golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 - golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d - golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 // indirect - golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba - gopkg.in/ini.v1 v1.62.0 - gopkg.in/square/go-jose.v2 v2.4.1 // indirect - k8s.io/apimachinery v0.21.2 - k8s.io/client-go v0.21.2 + golang.org/x/net v0.4.0 + golang.org/x/oauth2 v0.3.0 + golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 + gopkg.in/ini.v1 v1.67.0 + k8s.io/apimachinery v0.25.0 + k8s.io/client-go v0.25.0 +) + +require ( + github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/fsnotify/fsnotify v1.4.9 // indirect + github.com/go-playground/locales v0.14.0 // indirect + github.com/go-playground/universal-translator v0.18.0 // indirect + github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect + github.com/golang/mock v1.6.0 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/snappy v0.0.3 // indirect + github.com/google/go-cmp v0.5.8 // indirect + github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/klauspost/cpuid/v2 v2.0.6 // indirect + github.com/klauspost/reedsolomon v1.9.15 // indirect + github.com/leodido/go-urn v1.2.1 // indirect + github.com/marten-seemann/qtls-go1-18 v0.1.3 // indirect + github.com/marten-seemann/qtls-go1-19 v0.1.1 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/nxadm/tail v1.4.8 // indirect + github.com/onsi/ginkgo/v2 v2.2.0 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.37.0 // indirect + github.com/prometheus/procfs v0.8.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // indirect + github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b // indirect + github.com/tjfoc/gmsm v1.4.1 // indirect + golang.org/x/crypto v0.4.0 // indirect + golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect + golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect + golang.org/x/sys v0.3.0 // indirect + golang.org/x/text v0.5.0 // indirect + golang.org/x/tools v0.1.12 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/square/go-jose.v2 v2.6.0 // indirect + gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed // indirect ) diff --git a/go.sum b/go.sum index 433f03e281a..3471287169a 100644 --- a/go.sum +++ b/go.sum @@ -9,45 +9,68 @@ cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6T cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= +cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= -github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= -github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28= github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= 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/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -55,19 +78,27 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk= -github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= +github.com/coreos/go-oidc/v3 v3.4.0 h1:xz7elHb/LDwm/ERpwHd+5nb7wFHL32rsr6bBOgaeu6g= +github.com/coreos/go-oidc/v3 v3.4.0/go.mod h1:eHUXhZtXPQLgEaDrOVTgwbgmz1xGOkJNye6h3zkD2Pw= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= @@ -78,14 +109,16 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= -github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -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.20220321042308-c306138b83ac h1:td1FJwN/oz8+9GldeEm3YdBX0Husc0FSPywLesZxi4w= @@ -93,7 +126,6 @@ github.com/fatedier/golib v0.1.1-0.20220321042308-c306138b83ac/go.mod h1:fLV0TLw 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= -github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -104,31 +136,25 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= -github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= -github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= -github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= -github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/validator/v10 v10.6.1 h1:W6TRDXt4WcWp4c4nf/G+6BkGdhiIo0k417gfr+V6u4I= -github.com/go-playground/validator/v10 v10.6.1/go.mod h1:xm76BBt941f7yWdGnI2DVPFFg1UK3YY04qifoXU3lOk= +github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= +github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= +github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= +github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/go-playground/validator/v10 v10.11.0 h1:0W+xRM511GY47Yy3bZUbJVitCNg2BOGlCyvTqsp/xIw= +github.com/go-playground/validator/v10 v10.11.0/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -139,11 +165,17 @@ github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -153,46 +185,71 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -213,11 +270,11 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/yamux v0.0.0-20210707203944-259a57b3608c h1:nqkErwUGfpZZMqj29WZ9U/wz2OpJVDuiokLhE/3Y7IQ= -github.com/hashicorp/yamux v0.0.0-20210707203944-259a57b3608c/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= +github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= +github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= @@ -225,14 +282,13 @@ github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/cpuid/v2 v2.0.6 h1:dQ5ueTiftKxp0gyjKSx5+8BtPWkyQbd95m8Gys/RarI= github.com/klauspost/cpuid/v2 v2.0.6/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= @@ -242,18 +298,22 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/lucas-clemente/quic-go v0.31.0 h1:MfNp3fk0wjWRajw6quMFA3ap1AVtlU+2mtwmbVogB2M= +github.com/lucas-clemente/quic-go v0.31.0/go.mod h1:0wFbizLgYzqHqtlyxyCaJKlE7bYgE6JQ+54TLd/Dq2g= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/marten-seemann/qtls-go1-18 v0.1.3 h1:R4H2Ks8P6pAtUagjFty2p7BVHn3XiwDAl7TTQf5h7TI= +github.com/marten-seemann/qtls-go1-18 v0.1.3/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4= +github.com/marten-seemann/qtls-go1-19 v0.1.1 h1:mnbxeq3oEyQxQXwI4ReCgW9DPoPR94sNlqWoDZnjRIE= +github.com/marten-seemann/qtls-go1-19 v0.1.1/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= @@ -269,39 +329,32 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4 github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI= +github.com/onsi/ginkgo/v2 v2.2.0/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.13.0 h1:7lLHu94wT9Ij0o6EWWclhu0aOh32VxhkwEJvzuWPeak= -github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= +github.com/onsi/gomega v1.20.2 h1:8uQq0zMgLEfa0vRrrBgaJF2gyW9Da9BmfGV+OyUzfkY= +github.com/onsi/gomega v1.20.2/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pires/go-proxyproto v0.6.2 h1:KAZ7UteSOt6urjme6ZldyFm4wDe/z0ZUP0Yv0Dos0d8= github.com/pires/go-proxyproto v0.6.2/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -309,14 +362,14 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU= -github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU= +github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -326,19 +379,27 @@ github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7q github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= +github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rodaine/table v1.0.1 h1:U/VwCnUxlVYxw8+NJiLIuCxA/xa6jL38MY3FYysVWWQ= github.com/rodaine/table v1.0.1/go.mod h1:UVEtfBsflpeEcD56nF4F5AocNFta0ZuolpSVdPtlmP4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= @@ -346,9 +407,7 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -358,14 +417,12 @@ github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -383,14 +440,20 @@ github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVc github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37 h1:EWU6Pktpas0n8lLQwDsRyZfmkPeRbdgPtW609es+/9E= -github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37/go.mod h1:HpMP7DB2CyokmAh4lp0EQnnWhmycP/TvwBGzvuie+H0= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= @@ -399,13 +462,12 @@ golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g= -golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= +golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -416,6 +478,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= +golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -428,6 +492,8 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= 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/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/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/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -436,6 +502,11 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -452,8 +523,8 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -461,27 +532,71 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= +golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.3.0 h1:6l90koy8/LaBLmLu8jpHeHexzMwEita0zFfYlggy2F8= +golang.org/x/oauth2 v0.3.0/go.mod h1:rQrIauxkUhJ6CuwEXwymO2/eh4xz2ZWF1nBkcxS+tGk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -496,13 +611,11 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -514,33 +627,72 @@ golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 h1:RqytpXGR1iVNX7psjB3ff8y7sNFinVFvkx1c8SjBkio= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44= +golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -553,7 +705,6 @@ golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -574,15 +725,38 @@ golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -592,13 +766,44 @@ google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -616,8 +821,67 @@ google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -626,7 +890,30 @@ google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -635,57 +922,56 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= -gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/square/go-jose.v2 v2.4.1 h1:H0TmLt7/KmzlrDOpa1F+zr0Tk90PbJYBfsVUmRLrf9Y= -gopkg.in/square/go-jose.v2 v2.4.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= +gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.21.2/go.mod h1:Lv6UGJZ1rlMI1qusN8ruAp9PUBFyBwpEHAdG24vIsiU= -k8s.io/apimachinery v0.21.2 h1:vezUc/BHqWlQDnZ+XkrpXSmnANSLbpnlpwo0Lhk0gpc= -k8s.io/apimachinery v0.21.2/go.mod h1:CdTY8fU/BlvAbJ2z/8kBwimGki5Zp8/fbVuLY8gJumM= -k8s.io/client-go v0.21.2 h1:Q1j4L/iMN4pTw6Y4DWppBoUxgKO8LbffEMVEV00MUp0= -k8s.io/client-go v0.21.2/go.mod h1:HdJ9iknWpbl3vMGtib6T2PyI/VYxiZfq936WNVHBRrA= -k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +k8s.io/apimachinery v0.25.0 h1:MlP0r6+3XbkUG2itd6vp3oxbtdQLQI94fD5gCS+gnoU= +k8s.io/apimachinery v0.25.0/go.mod h1:qMx9eAk0sZQGsXGu86fab8tZdffHbwUfsvzqKn4mfB0= +k8s.io/client-go v0.25.0 h1:CVWIaCETLMBNiTUta3d5nzRbXvY5Hy9Dpl+VvREpu5E= +k8s.io/client-go v0.25.0/go.mod h1:lxykvypVfKilxhTklov0wz1FoaUZ8X4EwbhS6rpRfN8= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= -k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= -k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= -k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed h1:jAne/RjBTyawwAy0utX5eqigAwz/lQhTmy+Hr/Cpue4= +k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/hack/run-e2e.sh b/hack/run-e2e.sh index ee396652215..d8cfb052b32 100755 --- a/hack/run-e2e.sh +++ b/hack/run-e2e.sh @@ -5,7 +5,7 @@ ROOT=$(unset CDPATH && cd $(dirname "${BASH_SOURCE[0]}")/.. && pwd) which ginkgo &> /dev/null if [ $? -ne 0 ]; then echo "ginkgo not found, try to install..." - go install github.com/onsi/ginkgo/ginkgo@latest + go install github.com/onsi/ginkgo/ginkgo@v1.16.5 fi debug=false diff --git a/package.sh b/package.sh index 2f9a0f205f4..1a63a4e8c30 100755 --- a/package.sh +++ b/package.sh @@ -15,7 +15,7 @@ rm -rf ./release/packages mkdir -p ./release/packages os_all='linux windows darwin freebsd' -arch_all='386 amd64 arm arm64 mips64 mips64le mips mipsle' +arch_all='386 amd64 arm arm64 mips64 mips64le mips mipsle riscv64' cd ./release diff --git a/pkg/auth/oidc.go b/pkg/auth/oidc.go index 8a9f3404bf1..c8ef923d3fc 100644 --- a/pkg/auth/oidc.go +++ b/pkg/auth/oidc.go @@ -18,10 +18,10 @@ import ( "context" "fmt" - "github.com/fatedier/frp/pkg/msg" - - "github.com/coreos/go-oidc" + "github.com/coreos/go-oidc/v3/oidc" "golang.org/x/oauth2/clientcredentials" + + "github.com/fatedier/frp/pkg/msg" ) type OidcClientConfig struct { @@ -34,8 +34,11 @@ type OidcClientConfig struct { // is "". OidcClientSecret string `ini:"oidc_client_secret" json:"oidc_client_secret"` // OidcAudience specifies the audience of the token in OIDC authentication - //if AuthenticationMethod == "oidc". By default, this value is "". + // if AuthenticationMethod == "oidc". By default, this value is "". OidcAudience string `ini:"oidc_audience" json:"oidc_audience"` + // OidcScope specifies the scope of the token in OIDC authentication + // if AuthenticationMethod == "oidc". By default, this value is "". + OidcScope string `ini:"oidc_scope" json:"oidc_scope"` // OidcTokenEndpointURL specifies the URL which implements OIDC Token Endpoint. // It will be used to get an OIDC token if AuthenticationMethod == "oidc". // By default, this value is "". @@ -52,6 +55,7 @@ func getDefaultOidcClientConf() OidcClientConfig { OidcClientID: "", OidcClientSecret: "", OidcAudience: "", + OidcScope: "", OidcTokenEndpointURL: "", OidcAdditionalEndpointParams: make(map[string]string), } @@ -99,10 +103,14 @@ func NewOidcAuthSetter(baseCfg BaseConfig, cfg OidcClientConfig) *OidcAuthProvid eps[k] = []string{v} } + if cfg.OidcAudience != "" { + eps["audience"] = []string{cfg.OidcAudience} + } + tokenGenerator := &clientcredentials.Config{ ClientID: cfg.OidcClientID, ClientSecret: cfg.OidcClientSecret, - Scopes: []string{cfg.OidcAudience}, + Scopes: []string{cfg.OidcScope}, TokenURL: cfg.OidcTokenEndpointURL, EndpointParams: eps, } diff --git a/pkg/config/client.go b/pkg/config/client.go index f503711b07a..906ee985ebb 100644 --- a/pkg/config/client.go +++ b/pkg/config/client.go @@ -20,10 +20,10 @@ import ( "path/filepath" "strings" + "gopkg.in/ini.v1" + "github.com/fatedier/frp/pkg/auth" "github.com/fatedier/frp/pkg/util/util" - - "gopkg.in/ini.v1" ) // ClientCommonConf contains information for a client service. It is @@ -113,11 +113,15 @@ type ClientCommonConf struct { // all supplied proxies are enabled. By default, this value is an empty // set. Start []string `ini:"start" json:"start"` - //Start map[string]struct{} `json:"start"` + // Start map[string]struct{} `json:"start"` // Protocol specifies the protocol to use when interacting with the server. - // Valid values are "tcp", "kcp" and "websocket". By default, this value + // Valid values are "tcp", "kcp", "quic" and "websocket". By default, this value // is "tcp". Protocol string `ini:"protocol" json:"protocol"` + // QUIC protocol options + QUICKeepalivePeriod int `ini:"quic_keepalive_period" json:"quic_keepalive_period" validate:"gte=0"` + QUICMaxIdleTimeout int `ini:"quic_max_idle_timeout" json:"quic_max_idle_timeout" validate:"gte=0"` + QUICMaxIncomingStreams int `ini:"quic_max_incoming_streams" json:"quic_max_incoming_streams" validate:"gte=0"` // TLSEnable specifies whether or not TLS should be used when communicating // with the server. If "tls_cert_file" and "tls_key_file" are valid, // client will load the supplied tls configuration. @@ -172,30 +176,21 @@ func GetDefaultClientConf() ClientCommonConf { LogWay: "console", LogLevel: "info", LogMaxDays: 3, - DisableLogColor: false, AdminAddr: "127.0.0.1", - AdminPort: 0, - AdminUser: "", - AdminPwd: "", - AssetsDir: "", PoolCount: 1, TCPMux: true, TCPMuxKeepaliveInterval: 60, - User: "", - DNSServer: "", LoginFailExit: true, Start: make([]string, 0), Protocol: "tcp", - TLSEnable: false, - TLSCertFile: "", - TLSKeyFile: "", - TLSTrustedCaFile: "", + QUICKeepalivePeriod: 10, + QUICMaxIdleTimeout: 30, + QUICMaxIncomingStreams: 100000, HeartbeatInterval: 30, HeartbeatTimeout: 90, Metas: make(map[string]string), UDPPacketSize: 1500, IncludeConfigFiles: make([]string, 0), - PprofEnable: false, } } @@ -214,7 +209,7 @@ func (cfg *ClientCommonConf) Validate() error { } } - if cfg.TLSEnable == false { + if !cfg.TLSEnable { if cfg.TLSCertFile != "" { fmt.Println("WARNING! tls_cert_file is invalid when tls_enable is false") } @@ -228,7 +223,7 @@ func (cfg *ClientCommonConf) Validate() error { } } - if cfg.Protocol != "tcp" && cfg.Protocol != "kcp" && cfg.Protocol != "websocket" { + if cfg.Protocol != "tcp" && cfg.Protocol != "kcp" && cfg.Protocol != "websocket" && cfg.Protocol != "quic" { return fmt.Errorf("invalid protocol") } @@ -281,7 +276,6 @@ func LoadAllProxyConfsFromIni( source interface{}, start []string, ) (map[string]ProxyConf, map[string]VisitorConf, error) { - f, err := ini.LoadSources(ini.LoadOptions{ Insensitive: false, InsensitiveSections: false, @@ -366,7 +360,6 @@ func LoadAllProxyConfsFromIni( } func renderRangeProxyTemplates(f *ini.File, section *ini.Section) error { - // Validation localPortStr := section.Key("local_port").String() remotePortStr := section.Key("remote_port").String() @@ -404,8 +397,12 @@ func renderRangeProxyTemplates(f *ini.File, section *ini.Section) error { } copySection(section, tmpsection) - tmpsection.NewKey("local_port", fmt.Sprintf("%d", localPorts[i])) - tmpsection.NewKey("remote_port", fmt.Sprintf("%d", remotePorts[i])) + if _, err := tmpsection.NewKey("local_port", fmt.Sprintf("%d", localPorts[i])); err != nil { + return fmt.Errorf("local_port new key in section error: %v", err) + } + if _, err := tmpsection.NewKey("remote_port", fmt.Sprintf("%d", remotePorts[i])); err != nil { + return fmt.Errorf("remote_port new key in section error: %v", err) + } } return nil @@ -413,6 +410,6 @@ func renderRangeProxyTemplates(f *ini.File, section *ini.Section) error { func copySection(source, target *ini.Section) { for key, value := range source.KeysHash() { - target.NewKey(key, value) + _, _ = target.NewKey(key, value) } } diff --git a/pkg/config/client_test.go b/pkg/config/client_test.go index 12f1c9e1985..9cf8c805286 100644 --- a/pkg/config/client_test.go +++ b/pkg/config/client_test.go @@ -17,18 +17,17 @@ package config import ( "testing" + "github.com/stretchr/testify/assert" + "github.com/fatedier/frp/pkg/auth" "github.com/fatedier/frp/pkg/consts" - - "github.com/stretchr/testify/assert" ) const ( testUser = "test" ) -var ( - testClientBytesWithFull = []byte(` +var testClientBytesWithFull = []byte(` # [common] is integral section [common] server_addr = 0.0.0.9 @@ -237,7 +236,6 @@ var ( use_encryption = false use_compression = false `) -) func Test_LoadClientCommonConf(t *testing.T) { assert := assert.New(t) @@ -280,6 +278,9 @@ func Test_LoadClientCommonConf(t *testing.T) { User: "your_name", LoginFailExit: true, Protocol: "tcp", + QUICKeepalivePeriod: 10, + QUICMaxIdleTimeout: 30, + QUICMaxIncomingStreams: 100000, TLSEnable: true, TLSCertFile: "client.crt", TLSKeyFile: "client.key", diff --git a/pkg/config/parse.go b/pkg/config/parse.go index 7767981e32c..9f4cdb6b74b 100644 --- a/pkg/config/parse.go +++ b/pkg/config/parse.go @@ -42,7 +42,7 @@ func ParseClientConfig(filePath string) ( } cfg.Complete() if err = cfg.Validate(); err != nil { - err = fmt.Errorf("Parse config error: %v", err) + err = fmt.Errorf("parse config error: %v", err) return } diff --git a/pkg/config/proxy.go b/pkg/config/proxy.go index e168520d377..92b499f271b 100644 --- a/pkg/config/proxy.go +++ b/pkg/config/proxy.go @@ -21,10 +21,10 @@ import ( "strconv" "strings" + "gopkg.in/ini.v1" + "github.com/fatedier/frp/pkg/consts" "github.com/fatedier/frp/pkg/msg" - - "gopkg.in/ini.v1" ) // Proxy @@ -420,10 +420,6 @@ func (cfg *BaseProxyConf) checkForCli() (err error) { return nil } -func (cfg *BaseProxyConf) checkForSvr(conf ServerCommonConf) error { - return nil -} - // DomainConf func (cfg *DomainConf) check() (err error) { if len(cfg.CustomDomains) == 0 && cfg.SubDomain == "" { diff --git a/pkg/config/proxy_test.go b/pkg/config/proxy_test.go index 68c87b95e78..c603dd7f4d2 100644 --- a/pkg/config/proxy_test.go +++ b/pkg/config/proxy_test.go @@ -17,10 +17,10 @@ package config import ( "testing" - "github.com/fatedier/frp/pkg/consts" "github.com/stretchr/testify/assert" - "gopkg.in/ini.v1" + + "github.com/fatedier/frp/pkg/consts" ) var ( @@ -49,7 +49,6 @@ func Test_Proxy_UnmarshalFromIni(t *testing.T) { source []byte expected ProxyConf }{ - { sname: "ssh", source: []byte(` @@ -457,5 +456,4 @@ func Test_RangeProxy_UnmarshalFromIni(t *testing.T) { assert.Equal(c.expected, actual) } - } diff --git a/pkg/config/server.go b/pkg/config/server.go index 50eb3054c3f..040eaf65fe0 100644 --- a/pkg/config/server.go +++ b/pkg/config/server.go @@ -18,12 +18,12 @@ import ( "fmt" "strings" + "github.com/go-playground/validator/v10" + "gopkg.in/ini.v1" + "github.com/fatedier/frp/pkg/auth" plugin "github.com/fatedier/frp/pkg/plugin/server" "github.com/fatedier/frp/pkg/util/util" - - "github.com/go-playground/validator/v10" - "gopkg.in/ini.v1" ) // ServerCommonConf contains information for a server service. It is @@ -46,6 +46,14 @@ type ServerCommonConf struct { // value is 0, the server will not listen for KCP connections. By default, // this value is 0. KCPBindPort int `ini:"kcp_bind_port" json:"kcp_bind_port" validate:"gte=0,lte=65535"` + // QUICBindPort specifies the QUIC port that the server listens on. + // Set this value to 0 will disable this feature. + // By default, the value is 0. + QUICBindPort int `ini:"quic_bind_port" json:"quic_bind_port" validate:"gte=0,lte=65535"` + // QUIC protocol options + QUICKeepalivePeriod int `ini:"quic_keepalive_period" json:"quic_keepalive_period" validate:"gte=0"` + QUICMaxIdleTimeout int `ini:"quic_max_idle_timeout" json:"quic_max_idle_timeout" validate:"gte=0"` + QUICMaxIncomingStreams int `ini:"quic_max_incoming_streams" json:"quic_max_incoming_streams" validate:"gte=0"` // ProxyBindAddr specifies the address that the proxy binds to. This value // may be the same as BindAddr. ProxyBindAddr string `ini:"proxy_bind_addr" json:"proxy_bind_addr"` @@ -195,48 +203,30 @@ func GetDefaultServerConf() ServerCommonConf { ServerConfig: auth.GetDefaultServerConf(), BindAddr: "0.0.0.0", BindPort: 7000, - BindUDPPort: 0, - KCPBindPort: 0, - ProxyBindAddr: "", - VhostHTTPPort: 0, - VhostHTTPSPort: 0, - TCPMuxHTTPConnectPort: 0, - TCPMuxPassthrough: false, + QUICKeepalivePeriod: 10, + QUICMaxIdleTimeout: 30, + QUICMaxIncomingStreams: 100000, VhostHTTPTimeout: 60, DashboardAddr: "0.0.0.0", - DashboardPort: 0, - DashboardUser: "", - DashboardPwd: "", - EnablePrometheus: false, - AssetsDir: "", LogFile: "console", LogWay: "console", LogLevel: "info", LogMaxDays: 3, - DisableLogColor: false, DetailedErrorsToClient: true, - SubDomainHost: "", TCPMux: true, TCPMuxKeepaliveInterval: 60, TCPKeepAlive: 7200, AllowPorts: make(map[int]struct{}), MaxPoolCount: 5, MaxPortsPerClient: 0, - TLSOnly: false, - TLSCertFile: "", - TLSKeyFile: "", - TLSTrustedCaFile: "", HeartbeatTimeout: 90, UserConnTimeout: 10, - Custom404Page: "", HTTPPlugins: make(map[string]plugin.HTTPPluginOptions), UDPPacketSize: 1500, - PprofEnable: false, } } func UnmarshalServerConfFromIni(source interface{}) (ServerCommonConf, error) { - f, err := ini.LoadSources(ini.LoadOptions{ Insensitive: false, InsensitiveSections: false, @@ -308,7 +298,7 @@ func (cfg *ServerCommonConf) Complete() { } func (cfg *ServerCommonConf) Validate() error { - if cfg.DashboardTLSMode == false { + if !cfg.DashboardTLSMode { if cfg.DashboardTLSCertFile != "" { fmt.Println("WARNING! dashboard_tls_cert_file is invalid when dashboard_tls_mode is false") } diff --git a/pkg/config/server_test.go b/pkg/config/server_test.go index 8646ca62038..475a86b6f3e 100644 --- a/pkg/config/server_test.go +++ b/pkg/config/server_test.go @@ -17,10 +17,10 @@ package config import ( "testing" + "github.com/stretchr/testify/assert" + "github.com/fatedier/frp/pkg/auth" plugin "github.com/fatedier/frp/pkg/plugin/server" - - "github.com/stretchr/testify/assert" ) func Test_LoadServerCommonConf(t *testing.T) { @@ -106,6 +106,9 @@ func Test_LoadServerCommonConf(t *testing.T) { BindPort: 7009, BindUDPPort: 7008, KCPBindPort: 7007, + QUICKeepalivePeriod: 10, + QUICMaxIdleTimeout: 30, + QUICMaxIncomingStreams: 100000, ProxyBindAddr: "127.0.0.9", VhostHTTPPort: 89, VhostHTTPSPort: 449, @@ -126,10 +129,10 @@ func Test_LoadServerCommonConf(t *testing.T) { HeartbeatTimeout: 99, UserConnTimeout: 9, AllowPorts: map[int]struct{}{ - 10: struct{}{}, - 11: struct{}{}, - 12: struct{}{}, - 99: struct{}{}, + 10: {}, + 11: {}, + 12: {}, + 99: {}, }, MaxPoolCount: 59, MaxPortsPerClient: 9, @@ -179,6 +182,9 @@ func Test_LoadServerCommonConf(t *testing.T) { BindAddr: "0.0.0.9", BindPort: 7009, BindUDPPort: 7008, + QUICKeepalivePeriod: 10, + QUICMaxIdleTimeout: 30, + QUICMaxIncomingStreams: 100000, ProxyBindAddr: "0.0.0.9", VhostHTTPTimeout: 60, DashboardAddr: "0.0.0.0", diff --git a/pkg/config/types.go b/pkg/config/types.go index 062cc7462cf..28a0e46d87e 100644 --- a/pkg/config/types.go +++ b/pkg/config/types.go @@ -75,21 +75,22 @@ func (q *BandwidthQuantity) UnmarshalString(s string) error { f float64 err error ) - if strings.HasSuffix(s, "MB") { + switch { + case strings.HasSuffix(s, "MB"): base = MB fstr := strings.TrimSuffix(s, "MB") f, err = strconv.ParseFloat(fstr, 64) if err != nil { return err } - } else if strings.HasSuffix(s, "KB") { + case strings.HasSuffix(s, "KB"): base = KB fstr := strings.TrimSuffix(s, "KB") f, err = strconv.ParseFloat(fstr, 64) if err != nil { return err } - } else { + default: return errors.New("unit not support") } diff --git a/pkg/config/value.go b/pkg/config/value.go index e44fbd693e1..2f228823376 100644 --- a/pkg/config/value.go +++ b/pkg/config/value.go @@ -21,9 +21,7 @@ import ( "text/template" ) -var ( - glbEnvs map[string]string -) +var glbEnvs map[string]string func init() { glbEnvs = make(map[string]string) diff --git a/pkg/config/visitor.go b/pkg/config/visitor.go index aede14d8b04..3d9440cd023 100644 --- a/pkg/config/visitor.go +++ b/pkg/config/visitor.go @@ -18,9 +18,9 @@ import ( "fmt" "reflect" - "github.com/fatedier/frp/pkg/consts" - "gopkg.in/ini.v1" + + "github.com/fatedier/frp/pkg/consts" ) // Visitor @@ -136,6 +136,7 @@ func (cfg *BaseVisitorConf) check() (err error) { } func (cfg *BaseVisitorConf) unmarshalFromIni(prefix string, name string, section *ini.Section) error { + _ = section // Custom decoration after basic unmarshal: // proxy name diff --git a/pkg/config/visitor_test.go b/pkg/config/visitor_test.go index ce200ed049b..cdfbbf4673a 100644 --- a/pkg/config/visitor_test.go +++ b/pkg/config/visitor_test.go @@ -17,10 +17,10 @@ package config import ( "testing" - "github.com/fatedier/frp/pkg/consts" - "github.com/stretchr/testify/assert" "gopkg.in/ini.v1" + + "github.com/fatedier/frp/pkg/consts" ) const testVisitorPrefix = "test." diff --git a/pkg/consts/consts.go b/pkg/consts/consts.go index 907bc73e763..9e4438349b6 100644 --- a/pkg/consts/consts.go +++ b/pkg/consts/consts.go @@ -16,26 +16,26 @@ package consts var ( // proxy status - Idle string = "idle" - Working string = "working" - Closed string = "closed" - Online string = "online" - Offline string = "offline" + Idle = "idle" + Working = "working" + Closed = "closed" + Online = "online" + Offline = "offline" // proxy type - TCPProxy string = "tcp" - UDPProxy string = "udp" - TCPMuxProxy string = "tcpmux" - HTTPProxy string = "http" - HTTPSProxy string = "https" - STCPProxy string = "stcp" - XTCPProxy string = "xtcp" - SUDPProxy string = "sudp" + TCPProxy = "tcp" + UDPProxy = "udp" + TCPMuxProxy = "tcpmux" + HTTPProxy = "http" + HTTPSProxy = "https" + STCPProxy = "stcp" + XTCPProxy = "xtcp" + SUDPProxy = "sudp" // authentication method - TokenAuthMethod string = "token" - OidcAuthMethod string = "oidc" + TokenAuthMethod = "token" + OidcAuthMethod = "oidc" // TCP multiplexer - HTTPConnectTCPMultiplexer string = "httpconnect" + HTTPConnectTCPMultiplexer = "httpconnect" ) diff --git a/pkg/metrics/aggregate/server.go b/pkg/metrics/aggregate/server.go index 1ff15e42d0e..354d85c2b68 100644 --- a/pkg/metrics/aggregate/server.go +++ b/pkg/metrics/aggregate/server.go @@ -30,7 +30,7 @@ func EnablePrometheus() { sm.Add(prometheus.ServerMetrics) } -var sm *serverMetrics = &serverMetrics{} +var sm = &serverMetrics{} func init() { metrics.Register(sm) diff --git a/pkg/metrics/mem/server.go b/pkg/metrics/mem/server.go index 55d8daf120a..38a8c68b9b4 100644 --- a/pkg/metrics/mem/server.go +++ b/pkg/metrics/mem/server.go @@ -23,9 +23,12 @@ import ( server "github.com/fatedier/frp/server/metrics" ) -var sm *serverMetrics = newServerMetrics() -var ServerMetrics server.ServerMetrics -var StatsCollector Collector +var ( + sm = newServerMetrics() + + ServerMetrics server.ServerMetrics + StatsCollector Collector +) func init() { ServerMetrics = sm diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go index 6520317d8fd..696496a2357 100644 --- a/pkg/metrics/metrics.go +++ b/pkg/metrics/metrics.go @@ -4,5 +4,7 @@ import ( "github.com/fatedier/frp/pkg/metrics/aggregate" ) -var EnableMem = aggregate.EnableMem -var EnablePrometheus = aggregate.EnablePrometheus +var ( + EnableMem = aggregate.EnableMem + EnablePrometheus = aggregate.EnablePrometheus +) diff --git a/pkg/metrics/prometheus/server.go b/pkg/metrics/prometheus/server.go index 9cfdfda65aa..19eceb72fa7 100644 --- a/pkg/metrics/prometheus/server.go +++ b/pkg/metrics/prometheus/server.go @@ -1,9 +1,9 @@ package prometheus import ( - "github.com/fatedier/frp/server/metrics" - "github.com/prometheus/client_golang/prometheus" + + "github.com/fatedier/frp/server/metrics" ) const ( diff --git a/pkg/msg/ctl.go b/pkg/msg/ctl.go index 0eafdbcc5be..bf0c71a779b 100644 --- a/pkg/msg/ctl.go +++ b/pkg/msg/ctl.go @@ -22,9 +22,7 @@ import ( type Message = jsonMsg.Message -var ( - msgCtl *jsonMsg.MsgCtl -) +var msgCtl *jsonMsg.MsgCtl func init() { msgCtl = jsonMsg.NewMsgCtl() diff --git a/pkg/msg/msg.go b/pkg/msg/msg.go index ba6dd63e450..4b2823c729b 100644 --- a/pkg/msg/msg.go +++ b/pkg/msg/msg.go @@ -37,28 +37,26 @@ const ( TypeNatHoleSid = '5' ) -var ( - msgTypeMap = map[byte]interface{}{ - TypeLogin: Login{}, - TypeLoginResp: LoginResp{}, - TypeNewProxy: NewProxy{}, - TypeNewProxyResp: NewProxyResp{}, - TypeCloseProxy: CloseProxy{}, - TypeNewWorkConn: NewWorkConn{}, - TypeReqWorkConn: ReqWorkConn{}, - TypeStartWorkConn: StartWorkConn{}, - TypeNewVisitorConn: NewVisitorConn{}, - TypeNewVisitorConnResp: NewVisitorConnResp{}, - TypePing: Ping{}, - TypePong: Pong{}, - TypeUDPPacket: UDPPacket{}, - TypeNatHoleVisitor: NatHoleVisitor{}, - TypeNatHoleClient: NatHoleClient{}, - TypeNatHoleResp: NatHoleResp{}, - TypeNatHoleClientDetectOK: NatHoleClientDetectOK{}, - TypeNatHoleSid: NatHoleSid{}, - } -) +var msgTypeMap = map[byte]interface{}{ + TypeLogin: Login{}, + TypeLoginResp: LoginResp{}, + TypeNewProxy: NewProxy{}, + TypeNewProxyResp: NewProxyResp{}, + TypeCloseProxy: CloseProxy{}, + TypeNewWorkConn: NewWorkConn{}, + TypeReqWorkConn: ReqWorkConn{}, + TypeStartWorkConn: StartWorkConn{}, + TypeNewVisitorConn: NewVisitorConn{}, + TypeNewVisitorConnResp: NewVisitorConnResp{}, + TypePing: Ping{}, + TypePong: Pong{}, + TypeUDPPacket: UDPPacket{}, + TypeNatHoleVisitor: NatHoleVisitor{}, + TypeNatHoleClient: NatHoleClient{}, + TypeNatHoleResp: NatHoleResp{}, + TypeNatHoleClientDetectOK: NatHoleClientDetectOK{}, + TypeNatHoleSid: NatHoleSid{}, +} // When frpc start, client send this message to login to server. type Login struct { @@ -129,8 +127,7 @@ type NewWorkConn struct { Timestamp int64 `json:"timestamp,omitempty"` } -type ReqWorkConn struct { -} +type ReqWorkConn struct{} type StartWorkConn struct { ProxyName string `json:"proxy_name,omitempty"` @@ -187,8 +184,7 @@ type NatHoleResp struct { Error string `json:"error,omitempty"` } -type NatHoleClientDetectOK struct { -} +type NatHoleClientDetectOK struct{} type NatHoleSid struct { Sid string `json:"sid,omitempty"` diff --git a/pkg/nathole/nathole.go b/pkg/nathole/nathole.go index 545ad7aa035..da8b49c47d9 100644 --- a/pkg/nathole/nathole.go +++ b/pkg/nathole/nathole.go @@ -7,15 +7,15 @@ import ( "sync" "time" + "github.com/fatedier/golib/errors" + "github.com/fatedier/golib/pool" + "github.com/fatedier/frp/pkg/msg" "github.com/fatedier/frp/pkg/util/log" "github.com/fatedier/frp/pkg/util/util" - - "github.com/fatedier/golib/errors" - "github.com/fatedier/golib/pool" ) -// Timeout seconds. +// NatHoleTimeout seconds. var NatHoleTimeout int64 = 10 type SidRequest struct { @@ -107,7 +107,7 @@ func (nc *Controller) HandleVisitor(m *msg.NatHoleVisitor, raddr *net.UDPAddr) { session := &Session{ Sid: sid, VisitorAddr: raddr, - NotifyCh: make(chan struct{}, 0), + NotifyCh: make(chan struct{}), } nc.mu.Lock() clientCfg, ok := nc.clientCfgs[m.ProxyName] @@ -115,14 +115,14 @@ func (nc *Controller) HandleVisitor(m *msg.NatHoleVisitor, raddr *net.UDPAddr) { nc.mu.Unlock() errInfo := fmt.Sprintf("xtcp server for [%s] doesn't exist", m.ProxyName) log.Debug(errInfo) - nc.listener.WriteToUDP(nc.GenNatHoleResponse(nil, errInfo), raddr) + _, _ = nc.listener.WriteToUDP(nc.GenNatHoleResponse(nil, errInfo), raddr) return } if m.SignKey != util.GetAuthKey(clientCfg.Sk, m.Timestamp) { nc.mu.Unlock() errInfo := fmt.Sprintf("xtcp connection of [%s] auth failed", m.ProxyName) log.Debug(errInfo) - nc.listener.WriteToUDP(nc.GenNatHoleResponse(nil, errInfo), raddr) + _, _ = nc.listener.WriteToUDP(nc.GenNatHoleResponse(nil, errInfo), raddr) return } @@ -151,7 +151,7 @@ func (nc *Controller) HandleVisitor(m *msg.NatHoleVisitor, raddr *net.UDPAddr) { case <-session.NotifyCh: resp := nc.GenNatHoleResponse(session, "") log.Trace("send nat hole response to visitor") - nc.listener.WriteToUDP(resp, raddr) + _, _ = nc.listener.WriteToUDP(resp, raddr) case <-time.After(time.Duration(NatHoleTimeout) * time.Second): return } @@ -169,7 +169,7 @@ func (nc *Controller) HandleClient(m *msg.NatHoleClient, raddr *net.UDPAddr) { resp := nc.GenNatHoleResponse(session, "") log.Trace("send nat hole response to client") - nc.listener.WriteToUDP(resp, raddr) + _, _ = nc.listener.WriteToUDP(resp, raddr) } func (nc *Controller) GenNatHoleResponse(session *Session, errInfo string) []byte { diff --git a/pkg/plugin/client/http2https.go b/pkg/plugin/client/http2https.go index 3074cddf34e..f50a6c41f7a 100644 --- a/pkg/plugin/client/http2https.go +++ b/pkg/plugin/client/http2https.go @@ -86,17 +86,20 @@ func NewHTTP2HTTPSPlugin(params map[string]string) (Plugin, error) { } p.s = &http.Server{ - Handler: rp, + Handler: rp, + ReadHeaderTimeout: 0, } - go p.s.Serve(listener) + go func() { + _ = p.s.Serve(listener) + }() return p, nil } func (p *HTTP2HTTPSPlugin) Handle(conn io.ReadWriteCloser, realConn net.Conn, extraBufToLocal []byte) { wrapConn := frpNet.WrapReadWriteCloserToConn(conn, realConn) - p.l.PutConn(wrapConn) + _ = p.l.PutConn(wrapConn) } func (p *HTTP2HTTPSPlugin) Name() string { diff --git a/pkg/plugin/client/http_proxy.go b/pkg/plugin/client/http_proxy.go index 45bd3a9a792..78930e3952e 100644 --- a/pkg/plugin/client/http_proxy.go +++ b/pkg/plugin/client/http_proxy.go @@ -22,10 +22,10 @@ import ( "net/http" "strings" - frpNet "github.com/fatedier/frp/pkg/util/net" - frpIo "github.com/fatedier/golib/io" gnet "github.com/fatedier/golib/net" + + frpNet "github.com/fatedier/frp/pkg/util/net" ) const PluginHTTPProxy = "http_proxy" @@ -56,7 +56,9 @@ func NewHTTPProxyPlugin(params map[string]string) (Plugin, error) { Handler: hp, } - go hp.s.Serve(listener) + go func() { + _ = hp.s.Serve(listener) + }() return hp, nil } @@ -86,8 +88,7 @@ func (hp *HTTPProxy) Handle(conn io.ReadWriteCloser, realConn net.Conn, extraBuf return } - hp.l.PutConn(sc) - return + _ = hp.l.PutConn(sc) } func (hp *HTTPProxy) Close() error { @@ -153,7 +154,7 @@ func (hp *HTTPProxy) ConnectHandler(rw http.ResponseWriter, req *http.Request) { client.Close() return } - client.Write([]byte("HTTP/1.1 200 OK\r\n\r\n")) + _, _ = client.Write([]byte("HTTP/1.1 200 OK\r\n\r\n")) go frpIo.Join(remote, client) } @@ -188,7 +189,10 @@ func (hp *HTTPProxy) handleConnectReq(req *http.Request, rwc io.ReadWriteCloser) defer rwc.Close() if ok := hp.Auth(req); !ok { res := getBadResponse() - res.Write(rwc) + _ = res.Write(rwc) + if res.Body != nil { + res.Body.Close() + } return } @@ -200,10 +204,10 @@ func (hp *HTTPProxy) handleConnectReq(req *http.Request, rwc io.ReadWriteCloser) ProtoMajor: 1, ProtoMinor: 1, } - res.Write(rwc) + _ = res.Write(rwc) return } - rwc.Write([]byte("HTTP/1.1 200 OK\r\n\r\n")) + _, _ = rwc.Write([]byte("HTTP/1.1 200 OK\r\n\r\n")) frpIo.Join(remote, rwc) } diff --git a/pkg/plugin/client/https2http.go b/pkg/plugin/client/https2http.go index 5aec067b17c..18138dc1c7b 100644 --- a/pkg/plugin/client/https2http.go +++ b/pkg/plugin/client/https2http.go @@ -106,7 +106,9 @@ func NewHTTPS2HTTPPlugin(params map[string]string) (Plugin, error) { } ln := tls.NewListener(listener, tlsConfig) - go p.s.Serve(ln) + go func() { + _ = p.s.Serve(ln) + }() return p, nil } @@ -122,7 +124,7 @@ func (p *HTTPS2HTTPPlugin) genTLSConfig() (*tls.Config, error) { func (p *HTTPS2HTTPPlugin) Handle(conn io.ReadWriteCloser, realConn net.Conn, extraBufToLocal []byte) { wrapConn := frpNet.WrapReadWriteCloserToConn(conn, realConn) - p.l.PutConn(wrapConn) + _ = p.l.PutConn(wrapConn) } func (p *HTTPS2HTTPPlugin) Name() string { diff --git a/pkg/plugin/client/https2https.go b/pkg/plugin/client/https2https.go index cefa203017a..596bdc138a9 100644 --- a/pkg/plugin/client/https2https.go +++ b/pkg/plugin/client/https2https.go @@ -111,7 +111,9 @@ func NewHTTPS2HTTPSPlugin(params map[string]string) (Plugin, error) { } ln := tls.NewListener(listener, tlsConfig) - go p.s.Serve(ln) + go func() { + _ = p.s.Serve(ln) + }() return p, nil } @@ -127,7 +129,7 @@ func (p *HTTPS2HTTPSPlugin) genTLSConfig() (*tls.Config, error) { func (p *HTTPS2HTTPSPlugin) Handle(conn io.ReadWriteCloser, realConn net.Conn, extraBufToLocal []byte) { wrapConn := frpNet.WrapReadWriteCloserToConn(conn, realConn) - p.l.PutConn(wrapConn) + _ = p.l.PutConn(wrapConn) } func (p *HTTPS2HTTPSPlugin) Name() string { diff --git a/pkg/plugin/client/socks5.go b/pkg/plugin/client/socks5.go index 3a543d9d2d4..f731e87da9a 100644 --- a/pkg/plugin/client/socks5.go +++ b/pkg/plugin/client/socks5.go @@ -19,9 +19,9 @@ import ( "log" "net" - frpNet "github.com/fatedier/frp/pkg/util/net" - gosocks5 "github.com/armon/go-socks5" + + frpNet "github.com/fatedier/frp/pkg/util/net" ) const PluginSocks5 = "socks5" @@ -32,9 +32,6 @@ func init() { type Socks5Plugin struct { Server *gosocks5.Server - - user string - passwd string } func NewSocks5Plugin(params map[string]string) (p Plugin, err error) { @@ -56,7 +53,7 @@ func NewSocks5Plugin(params map[string]string) (p Plugin, err error) { func (sp *Socks5Plugin) Handle(conn io.ReadWriteCloser, realConn net.Conn, extraBufToLocal []byte) { defer conn.Close() wrapConn := frpNet.WrapReadWriteCloserToConn(conn, realConn) - sp.Server.ServeConn(wrapConn) + _ = sp.Server.ServeConn(wrapConn) } func (sp *Socks5Plugin) Name() string { diff --git a/pkg/plugin/client/static_file.go b/pkg/plugin/client/static_file.go index 1eeea3ba92e..4d31ea53e8b 100644 --- a/pkg/plugin/client/static_file.go +++ b/pkg/plugin/client/static_file.go @@ -19,9 +19,9 @@ import ( "net" "net/http" - frpNet "github.com/fatedier/frp/pkg/util/net" - "github.com/gorilla/mux" + + frpNet "github.com/fatedier/frp/pkg/util/net" ) const PluginStaticFile = "static_file" @@ -69,13 +69,15 @@ func NewStaticFilePlugin(params map[string]string) (Plugin, error) { sp.s = &http.Server{ Handler: router, } - go sp.s.Serve(listener) + go func() { + _ = sp.s.Serve(listener) + }() return sp, nil } func (sp *StaticFilePlugin) Handle(conn io.ReadWriteCloser, realConn net.Conn, extraBufToLocal []byte) { wrapConn := frpNet.WrapReadWriteCloserToConn(conn, realConn) - sp.l.PutConn(wrapConn) + _ = sp.l.PutConn(wrapConn) } func (sp *StaticFilePlugin) Name() string { diff --git a/pkg/plugin/client/unix_domain_socket.go b/pkg/plugin/client/unix_domain_socket.go index a85ada702f8..68902472242 100644 --- a/pkg/plugin/client/unix_domain_socket.go +++ b/pkg/plugin/client/unix_domain_socket.go @@ -57,7 +57,9 @@ func (uds *UnixDomainSocketPlugin) Handle(conn io.ReadWriteCloser, realConn net. return } if len(extraBufToLocal) > 0 { - localConn.Write(extraBufToLocal) + if _, err := localConn.Write(extraBufToLocal); err != nil { + return + } } frpIo.Join(localConn, conn) diff --git a/pkg/plugin/server/http.go b/pkg/plugin/server/http.go index 5ca8c0635bb..b120332dcdb 100644 --- a/pkg/plugin/server/http.go +++ b/pkg/plugin/server/http.go @@ -43,12 +43,12 @@ type httpPlugin struct { } func NewHTTPPluginOptions(options HTTPPluginOptions) Plugin { - var url = fmt.Sprintf("%s%s", options.Addr, options.Path) + url := fmt.Sprintf("%s%s", options.Addr, options.Path) var client *http.Client if strings.HasPrefix(url, "https://") { tr := &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: options.TLSVerify == false}, + TLSClientConfig: &tls.Config{InsecureSkipVerify: !options.TLSVerify}, } client = &http.Client{Transport: tr} } else { diff --git a/pkg/plugin/server/manager.go b/pkg/plugin/server/manager.go index 47d11d1c245..5a8a309c61f 100644 --- a/pkg/plugin/server/manager.go +++ b/pkg/plugin/server/manager.go @@ -154,9 +154,8 @@ func (m *Manager) CloseProxy(content *CloseProxyContent) error { if len(errs) > 0 { return fmt.Errorf("send CloseProxy request to plugin errors: %s", strings.Join(errs, "; ")) - } else { - return nil } + return nil } func (m *Manager) Ping(content *PingContent) (*PingContent, error) { diff --git a/pkg/proto/udp/udp.go b/pkg/proto/udp/udp.go index 97f6ea4098f..7a11984b2e4 100644 --- a/pkg/proto/udp/udp.go +++ b/pkg/proto/udp/udp.go @@ -20,10 +20,10 @@ import ( "sync" "time" - "github.com/fatedier/frp/pkg/msg" - "github.com/fatedier/golib/errors" "github.com/fatedier/golib/pool" + + "github.com/fatedier/frp/pkg/msg" ) func NewUDPPacket(buf []byte, laddr, raddr *net.UDPAddr) *msg.UDPPacket { @@ -47,7 +47,7 @@ func ForwardUserConn(udpConn *net.UDPConn, readCh <-chan *msg.UDPPacket, sendCh if err != nil { continue } - udpConn.WriteToUDP(buf, udpMsg.RemoteAddr) + _, _ = udpConn.WriteToUDP(buf, udpMsg.RemoteAddr) } }() @@ -70,9 +70,7 @@ func ForwardUserConn(udpConn *net.UDPConn, readCh <-chan *msg.UDPPacket, sendCh } func Forwarder(dstAddr *net.UDPAddr, readCh <-chan *msg.UDPPacket, sendCh chan<- msg.Message, bufSize int) { - var ( - mu sync.RWMutex - ) + var mu sync.RWMutex udpConnMap := make(map[string]*net.UDPConn) // read from dstAddr and write to sendCh @@ -87,7 +85,7 @@ func Forwarder(dstAddr *net.UDPAddr, readCh <-chan *msg.UDPPacket, sendCh chan<- buf := pool.GetBuf(bufSize) for { - udpConn.SetReadDeadline(time.Now().Add(30 * time.Second)) + _ = udpConn.SetReadDeadline(time.Now().Add(30 * time.Second)) n, _, err := udpConn.ReadFromUDP(buf) if err != nil { return diff --git a/pkg/transport/tls.go b/pkg/transport/tls.go index 38201f8e900..02950cc546e 100644 --- a/pkg/transport/tls.go +++ b/pkg/transport/tls.go @@ -19,7 +19,7 @@ func newCustomTLSKeyPair(certfile, keyfile string) (*tls.Certificate, error) { } func newRandomTLSKeyPair() *tls.Certificate { - key, err := rsa.GenerateKey(rand.Reader, 1024) + key, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { panic(err) } @@ -58,7 +58,7 @@ func newCertPool(caPath string) (*x509.CertPool, error) { } func NewServerTLSConfig(certPath, keyPath, caPath string) (*tls.Config, error) { - var base = &tls.Config{} + base := &tls.Config{} if certPath == "" || keyPath == "" { // server will generate tls conf by itself @@ -87,7 +87,7 @@ func NewServerTLSConfig(certPath, keyPath, caPath string) (*tls.Config, error) { } func NewClientTLSConfig(certPath, keyPath, caPath, serverName string) (*tls.Config, error) { - var base = &tls.Config{} + base := &tls.Config{} if certPath == "" || keyPath == "" { // client will not generate tls conf by itself diff --git a/pkg/util/log/log.go b/pkg/util/log/log.go index 1ddf4cdc042..01a454d595d 100644 --- a/pkg/util/log/log.go +++ b/pkg/util/log/log.go @@ -40,19 +40,19 @@ func SetLogFile(logWay string, logFile string, maxdays int64, disableLogColor bo if logWay == "console" { params := "" if disableLogColor { - params = fmt.Sprintf(`{"color": false}`) + params = `{"color": false}` } - Log.SetLogger("console", params) + _ = Log.SetLogger("console", params) } else { params := fmt.Sprintf(`{"filename": "%s", "maxdays": %d}`, logFile, maxdays) - Log.SetLogger("file", params) + _ = Log.SetLogger("file", params) } } // SetLogLevel set log level, default is warning // value: error, warning, info, debug, trace func SetLogLevel(logLevel string) { - level := 4 // warning + var level int switch logLevel { case "error": level = 3 @@ -65,7 +65,7 @@ func SetLogLevel(logLevel string) { case "trace": level = 8 default: - level = 4 + level = 4 // warning } Log.SetLevel(level) } diff --git a/pkg/util/net/conn.go b/pkg/util/net/conn.go index f3d8caee400..1258ed48063 100644 --- a/pkg/util/net/conn.go +++ b/pkg/util/net/conn.go @@ -22,6 +22,8 @@ import ( "sync/atomic" "time" + quic "github.com/lucas-clemente/quic-go" + "github.com/fatedier/frp/pkg/util/xlog" ) @@ -183,3 +185,29 @@ func (statsConn *StatsConn) Close() (err error) { } return } + +type wrapQuicStream struct { + quic.Stream + c quic.Connection +} + +func QuicStreamToNetConn(s quic.Stream, c quic.Connection) net.Conn { + return &wrapQuicStream{ + Stream: s, + c: c, + } +} + +func (conn *wrapQuicStream) LocalAddr() net.Addr { + if conn.c != nil { + return conn.c.LocalAddr() + } + return (*net.TCPAddr)(nil) +} + +func (conn *wrapQuicStream) RemoteAddr() net.Addr { + if conn.c != nil { + return conn.c.RemoteAddr() + } + return (*net.TCPAddr)(nil) +} diff --git a/pkg/util/net/kcp.go b/pkg/util/net/kcp.go index e9e0b1269b6..77b6bfa76ff 100644 --- a/pkg/util/net/kcp.go +++ b/pkg/util/net/kcp.go @@ -32,8 +32,8 @@ func ListenKcp(address string) (l *KCPListener, err error) { if err != nil { return l, err } - listener.SetReadBuffer(4194304) - listener.SetWriteBuffer(4194304) + _ = listener.SetReadBuffer(4194304) + _ = listener.SetWriteBuffer(4194304) l = &KCPListener{ listener: listener, diff --git a/pkg/util/net/tls.go b/pkg/util/net/tls.go index 1bae196adb8..3aecb482f15 100644 --- a/pkg/util/net/tls.go +++ b/pkg/util/net/tls.go @@ -23,32 +23,30 @@ import ( gnet "github.com/fatedier/golib/net" ) -var ( - FRPTLSHeadByte = 0x17 -) +var FRPTLSHeadByte = 0x17 func CheckAndEnableTLSServerConnWithTimeout( c net.Conn, tlsConfig *tls.Config, tlsOnly bool, timeout time.Duration, ) (out net.Conn, isTLS bool, custom bool, err error) { - sc, r := gnet.NewSharedConnSize(c, 2) buf := make([]byte, 1) var n int - c.SetReadDeadline(time.Now().Add(timeout)) + _ = c.SetReadDeadline(time.Now().Add(timeout)) n, err = r.Read(buf) - c.SetReadDeadline(time.Time{}) + _ = c.SetReadDeadline(time.Time{}) if err != nil { return } - if n == 1 && int(buf[0]) == FRPTLSHeadByte { + switch { + case n == 1 && int(buf[0]) == FRPTLSHeadByte: out = tls.Server(c, tlsConfig) isTLS = true custom = true - } else if n == 1 && int(buf[0]) == 0x16 { + case n == 1 && int(buf[0]) == 0x16: out = tls.Server(sc, tlsConfig) isTLS = true - } else { + default: if tlsOnly { err = fmt.Errorf("non-TLS connection received on a TlsOnly server") return diff --git a/pkg/util/net/udp.go b/pkg/util/net/udp.go index 6689732e40c..82999a5f5c2 100644 --- a/pkg/util/net/udp.go +++ b/pkg/util/net/udp.go @@ -55,7 +55,7 @@ func NewFakeUDPConn(l *UDPListener, laddr, raddr net.Addr) *FakeUDPConn { for { time.Sleep(5 * time.Second) fc.mu.RLock() - if time.Now().Sub(fc.lastActive) > 10*time.Second { + if time.Since(fc.lastActive) > 10*time.Second { fc.mu.RUnlock() fc.Close() break @@ -68,8 +68,7 @@ func NewFakeUDPConn(l *UDPListener, laddr, raddr net.Addr) *FakeUDPConn { func (c *FakeUDPConn) putPacket(content []byte) { defer func() { - if err := recover(); err != nil { - } + _ = recover() }() select { @@ -109,7 +108,7 @@ func (c *FakeUDPConn) Write(b []byte) (n int, err error) { LocalAddr: c.localAddr, RemoteAddr: c.remoteAddr, } - c.l.writeUDPPacket(packet) + _ = c.l.writeUDPPacket(packet) c.mu.Lock() c.lastActive = time.Now() @@ -208,7 +207,7 @@ func ListenUDP(bindAddr string, bindPort int) (l *UDPListener, err error) { } if addr, ok := packet.RemoteAddr.(*net.UDPAddr); ok { - readConn.WriteToUDP(packet.Buf, addr) + _, _ = readConn.WriteToUDP(packet.Buf, addr) } } }() diff --git a/pkg/util/net/websocket.go b/pkg/util/net/websocket.go index 4ec5c9fe079..6a8d369c4a9 100644 --- a/pkg/util/net/websocket.go +++ b/pkg/util/net/websocket.go @@ -9,9 +9,7 @@ import ( "golang.org/x/net/websocket" ) -var ( - ErrWebsocketListenerClosed = errors.New("websocket listener closed") -) +var ErrWebsocketListenerClosed = errors.New("websocket listener closed") const ( FrpWebsocketPath = "/~!frp" @@ -21,8 +19,7 @@ type WebsocketListener struct { ln net.Listener acceptCh chan net.Conn - server *http.Server - httpMutex *http.ServeMux + server *http.Server } // NewWebsocketListener to handle websocket connections @@ -47,7 +44,9 @@ func NewWebsocketListener(ln net.Listener) (wl *WebsocketListener) { Handler: muxer, } - go wl.server.Serve(ln) + go func() { + _ = wl.server.Serve(ln) + }() return } diff --git a/pkg/util/tcpmux/httpconnect.go b/pkg/util/tcpmux/httpconnect.go index 2639c493644..e94ff4b2bb2 100644 --- a/pkg/util/tcpmux/httpconnect.go +++ b/pkg/util/tcpmux/httpconnect.go @@ -22,9 +22,10 @@ import ( "net/http" "time" + gnet "github.com/fatedier/golib/net" + "github.com/fatedier/frp/pkg/util/util" "github.com/fatedier/frp/pkg/util/vhost" - gnet "github.com/fatedier/golib/net" ) type HTTPConnectTCPMuxer struct { @@ -66,7 +67,11 @@ func (muxer *HTTPConnectTCPMuxer) sendConnectResponse(c net.Conn, reqInfo map[st if muxer.passthrough { return nil } - return util.OkResponse().Write(c) + res := util.OkResponse() + if res.Body != nil { + defer res.Body.Close() + } + return res.Write(c) } func (muxer *HTTPConnectTCPMuxer) getHostFromHTTPConnect(c net.Conn) (net.Conn, map[string]string, error) { @@ -82,11 +87,15 @@ func (muxer *HTTPConnectTCPMuxer) getHostFromHTTPConnect(c net.Conn) (net.Conn, reqInfoMap["Scheme"] = "tcp" reqInfoMap["HTTPUser"] = httpUser - var outConn net.Conn = c + outConn := c if muxer.passthrough { outConn = sc if muxer.authRequired && httpUser == "" { - util.ProxyUnauthorizedResponse().Write(c) + resp := util.ProxyUnauthorizedResponse() + if resp.Body != nil { + defer resp.Body.Close() + } + _ = resp.Write(c) outConn = c } } diff --git a/pkg/util/util/http.go b/pkg/util/util/http.go index 3b8117346f9..d89af08b76a 100644 --- a/pkg/util/util/http.go +++ b/pkg/util/util/http.go @@ -60,10 +60,8 @@ func CanonicalHost(host string) (string, error) { return "", err } } - if strings.HasSuffix(host, ".") { - // Strip trailing dot from fully qualified domain names. - host = host[:len(host)-1] - } + // Strip trailing dot from fully qualified domain names. + host = strings.TrimSuffix(host, ".") return host, nil } diff --git a/pkg/util/util/util.go b/pkg/util/util/util.go index 032675fb761..b13f9a77356 100644 --- a/pkg/util/util/util.go +++ b/pkg/util/util/util.go @@ -44,7 +44,7 @@ func RandIDWithLen(idLen int) (id string, err error) { } func GetAuthKey(token string, timestamp int64) (key string) { - token = token + fmt.Sprintf("%d", timestamp) + token += fmt.Sprintf("%d", timestamp) md5Ctx := md5.New() md5Ctx.Write([]byte(token)) data := md5Ctx.Sum(nil) @@ -70,7 +70,8 @@ func ParseRangeNumbers(rangeStr string) (numbers []int64, err error) { numArray := strings.Split(numRangeStr, "-") // length: only 1 or 2 is correct rangeType := len(numArray) - if rangeType == 1 { + switch rangeType { + case 1: // single number singleNum, errRet := strconv.ParseInt(strings.TrimSpace(numArray[0]), 10, 64) if errRet != nil { @@ -78,7 +79,7 @@ func ParseRangeNumbers(rangeStr string) (numbers []int64, err error) { return } numbers = append(numbers, singleNum) - } else if rangeType == 2 { + case 2: // range numbers min, errRet := strconv.ParseInt(strings.TrimSpace(numArray[0]), 10, 64) if errRet != nil { @@ -97,7 +98,7 @@ func ParseRangeNumbers(rangeStr string) (numbers []int64, err error) { for i := min; i <= max; i++ { numbers = append(numbers, i) } - } else { + default: err = fmt.Errorf("range number is invalid") return } diff --git a/pkg/util/version/version.go b/pkg/util/version/version.go index b5eca31735b..6228c092a58 100644 --- a/pkg/util/version/version.go +++ b/pkg/util/version/version.go @@ -19,7 +19,7 @@ import ( "strings" ) -var version string = "0.44.0" +var version = "0.46.0" func Full() string { return version diff --git a/pkg/util/vhost/http.go b/pkg/util/vhost/http.go index bfbd16ea9b6..5addb47542e 100644 --- a/pkg/util/vhost/http.go +++ b/pkg/util/vhost/http.go @@ -23,27 +23,26 @@ import ( "log" "net" "net/http" + "net/http/httputil" "net/url" "strings" "time" - frpLog "github.com/fatedier/frp/pkg/util/log" - "github.com/fatedier/frp/pkg/util/util" frpIo "github.com/fatedier/golib/io" - "github.com/fatedier/golib/pool" -) -var ( - ErrNoRouteFound = errors.New("no route found") + frpLog "github.com/fatedier/frp/pkg/util/log" + "github.com/fatedier/frp/pkg/util/util" ) +var ErrNoRouteFound = errors.New("no route found") + type HTTPReverseProxyOptions struct { ResponseHeaderTimeoutS int64 } type HTTPReverseProxy struct { - proxy *ReverseProxy + proxy *httputil.ReverseProxy vhostRouter *Routers responseHeaderTimeout time.Duration @@ -57,23 +56,32 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) * responseHeaderTimeout: time.Duration(option.ResponseHeaderTimeoutS) * time.Second, vhostRouter: vhostRouter, } - proxy := &ReverseProxy{ + proxy := &httputil.ReverseProxy{ // Modify incoming requests by route policies. Director: func(req *http.Request) { req.URL.Scheme = "http" - url := req.Context().Value(RouteInfoURL).(string) - routeByHTTPUser := req.Context().Value(RouteInfoHTTPUser).(string) - oldHost, _ := util.CanonicalHost(req.Context().Value(RouteInfoHost).(string)) - rc := rp.GetRouteConfig(oldHost, url, routeByHTTPUser) + reqRouteInfo := req.Context().Value(RouteInfoKey).(*RequestRouteInfo) + oldHost, _ := util.CanonicalHost(reqRouteInfo.Host) + + rc := rp.GetRouteConfig(oldHost, reqRouteInfo.URL, reqRouteInfo.HTTPUser) if rc != nil { if rc.RewriteHost != "" { req.Host = rc.RewriteHost } - // Set {domain}.{location}.{routeByHTTPUser} as URL host here to let http transport reuse connections. - // TODO(fatedier): use proxy name instead? + + var endpoint string + if rc.ChooseEndpointFn != nil { + // ignore error here, it will use CreateConnFn instead later + endpoint, _ = rc.ChooseEndpointFn() + reqRouteInfo.Endpoint = endpoint + frpLog.Trace("choose endpoint name [%s] for http request host [%s] path [%s] httpuser [%s]", + endpoint, oldHost, reqRouteInfo.URL, reqRouteInfo.HTTPUser) + } + // Set {domain}.{location}.{routeByHTTPUser}.{endpoint} as URL host here to let http transport reuse connections. req.URL.Host = rc.Domain + "." + base64.StdEncoding.EncodeToString([]byte(rc.Location)) + "." + - base64.StdEncoding.EncodeToString([]byte(rc.RouteByHTTPUser)) + base64.StdEncoding.EncodeToString([]byte(rc.RouteByHTTPUser)) + "." + + base64.StdEncoding.EncodeToString([]byte(endpoint)) for k, v := range rc.Headers { req.Header.Set(k, v) @@ -81,18 +89,14 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) * } else { req.URL.Host = req.Host } - }, // Create a connection to one proxy routed by route policy. Transport: &http.Transport{ ResponseHeaderTimeout: rp.responseHeaderTimeout, IdleConnTimeout: 60 * time.Second, + MaxIdleConnsPerHost: 5, DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { - url := ctx.Value(RouteInfoURL).(string) - host, _ := util.CanonicalHost(ctx.Value(RouteInfoHost).(string)) - routerByHTTPUser := ctx.Value(RouteInfoHTTPUser).(string) - remote := ctx.Value(RouteInfoRemote).(string) - return rp.CreateConnection(host, url, routerByHTTPUser, remote) + return rp.CreateConnection(ctx.Value(RouteInfoKey).(*RequestRouteInfo), true) }, Proxy: func(req *http.Request) (*url.URL, error) { // Use proxy mode if there is host in HTTP first request line. @@ -102,7 +106,7 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) * // Normal: // GET / HTTP/1.1 // Host: example.com - urlHost := req.Context().Value(RouteInfoURLHost).(string) + urlHost := req.Context().Value(RouteInfoKey).(*RequestRouteInfo).URLHost if urlHost != "" { return req.URL, nil } @@ -114,7 +118,7 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) * ErrorHandler: func(rw http.ResponseWriter, req *http.Request, err error) { frpLog.Warn("do http proxy request [host: %s] error: %v", req.Host, err) rw.WriteHeader(http.StatusNotFound) - rw.Write(getNotFoundPageContent()) + _, _ = rw.Write(getNotFoundPageContent()) }, } rp.proxy = proxy @@ -145,14 +149,6 @@ func (rp *HTTPReverseProxy) GetRouteConfig(domain, location, routeByHTTPUser str return nil } -func (rp *HTTPReverseProxy) GetRealHost(domain, location, routeByHTTPUser string) (host string) { - vr, ok := rp.getVhost(domain, location, routeByHTTPUser) - if ok { - host = vr.payload.(*RouteConfig).RewriteHost - } - return -} - func (rp *HTTPReverseProxy) GetHeaders(domain, location, routeByHTTPUser string) (headers map[string]string) { vr, ok := rp.getVhost(domain, location, routeByHTTPUser) if ok { @@ -162,15 +158,22 @@ func (rp *HTTPReverseProxy) GetHeaders(domain, location, routeByHTTPUser string) } // CreateConnection create a new connection by route config -func (rp *HTTPReverseProxy) CreateConnection(domain, location, routeByHTTPUser string, remoteAddr string) (net.Conn, error) { - vr, ok := rp.getVhost(domain, location, routeByHTTPUser) +func (rp *HTTPReverseProxy) CreateConnection(reqRouteInfo *RequestRouteInfo, byEndpoint bool) (net.Conn, error) { + host, _ := util.CanonicalHost(reqRouteInfo.Host) + vr, ok := rp.getVhost(host, reqRouteInfo.URL, reqRouteInfo.HTTPUser) if ok { + if byEndpoint { + fn := vr.payload.(*RouteConfig).CreateConnByEndpointFn + if fn != nil { + return fn(reqRouteInfo.Endpoint, reqRouteInfo.RemoteAddr) + } + } fn := vr.payload.(*RouteConfig).CreateConnFn if fn != nil { - return fn(remoteAddr) + return fn(reqRouteInfo.RemoteAddr) } } - return nil, fmt.Errorf("%v: %s %s %s", ErrNoRouteFound, domain, location, routeByHTTPUser) + return nil, fmt.Errorf("%v: %s %s %s", ErrNoRouteFound, host, reqRouteInfo.URL, reqRouteInfo.HTTPUser) } func (rp *HTTPReverseProxy) CheckAuth(domain, location, routeByHTTPUser, user, passwd string) bool { @@ -246,27 +249,35 @@ func (rp *HTTPReverseProxy) connectHandler(rw http.ResponseWriter, req *http.Req return } - url := req.Context().Value(RouteInfoURL).(string) - routeByHTTPUser := req.Context().Value(RouteInfoHTTPUser).(string) - domain, _ := util.CanonicalHost(req.Context().Value(RouteInfoHost).(string)) - remoteAddr := req.Context().Value(RouteInfoRemote).(string) - - remote, err := rp.CreateConnection(domain, url, routeByHTTPUser, remoteAddr) + remote, err := rp.CreateConnection(req.Context().Value(RouteInfoKey).(*RequestRouteInfo), false) if err != nil { - http.Error(rw, "Failed", http.StatusBadRequest) + _ = notFoundResponse().Write(client) client.Close() return } - req.Write(remote) + _ = req.Write(remote) go frpIo.Join(remote, client) } -func (rp *HTTPReverseProxy) injectRequestInfoToCtx(req *http.Request) *http.Request { - newctx := req.Context() - newctx = context.WithValue(newctx, RouteInfoURL, req.URL.Path) - newctx = context.WithValue(newctx, RouteInfoHost, req.Host) - newctx = context.WithValue(newctx, RouteInfoURLHost, req.URL.Host) +func parseBasicAuth(auth string) (username, password string, ok bool) { + const prefix = "Basic " + // Case insensitive prefix match. See Issue 22736. + if len(auth) < len(prefix) || !strings.EqualFold(auth[:len(prefix)], prefix) { + return + } + c, err := base64.StdEncoding.DecodeString(auth[len(prefix):]) + if err != nil { + return + } + cs := string(c) + s := strings.IndexByte(cs, ':') + if s < 0 { + return + } + return cs[:s], cs[s+1:], true +} +func (rp *HTTPReverseProxy) injectRequestInfoToCtx(req *http.Request) *http.Request { user := "" // If url host isn't empty, it's a proxy request. Get http user from Proxy-Authorization header. if req.URL.Host != "" { @@ -278,8 +289,16 @@ func (rp *HTTPReverseProxy) injectRequestInfoToCtx(req *http.Request) *http.Requ if user == "" { user, _, _ = req.BasicAuth() } - newctx = context.WithValue(newctx, RouteInfoHTTPUser, user) - newctx = context.WithValue(newctx, RouteInfoRemote, req.RemoteAddr) + + reqRouteInfo := &RequestRouteInfo{ + URL: req.URL.Path, + Host: req.Host, + HTTPUser: user, + RemoteAddr: req.RemoteAddr, + URLHost: req.URL.Host, + } + newctx := req.Context() + newctx = context.WithValue(newctx, RouteInfoKey, reqRouteInfo) return req.Clone(newctx) } diff --git a/pkg/util/vhost/resource.go b/pkg/util/vhost/resource.go index 446f40f91f2..65bdbcb6288 100644 --- a/pkg/util/vhost/resource.go +++ b/pkg/util/vhost/resource.go @@ -24,9 +24,7 @@ import ( "github.com/fatedier/frp/pkg/util/version" ) -var ( - NotFoundPagePath = "" -) +var NotFoundPagePath = "" const ( NotFound = ` @@ -74,14 +72,16 @@ func notFoundResponse() *http.Response { header.Set("server", "frp/"+version.Full()) header.Set("Content-Type", "text/html") + content := getNotFoundPageContent() res := &http.Response{ - Status: "Not Found", - StatusCode: 404, - Proto: "HTTP/1.0", - ProtoMajor: 1, - ProtoMinor: 0, - Header: header, - Body: io.NopCloser(bytes.NewReader(getNotFoundPageContent())), + Status: "Not Found", + StatusCode: 404, + Proto: "HTTP/1.1", + ProtoMajor: 1, + ProtoMinor: 1, + Header: header, + Body: io.NopCloser(bytes.NewReader(content)), + ContentLength: int64(len(content)), } return res } diff --git a/pkg/util/vhost/reverseproxy.go b/pkg/util/vhost/reverseproxy.go deleted file mode 100644 index 975f1d14ecf..00000000000 --- a/pkg/util/vhost/reverseproxy.go +++ /dev/null @@ -1,636 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// HTTP reverse proxy handler - -package vhost - -import ( - "context" - "encoding/base64" - "fmt" - "io" - "log" - "net" - "net/http" - "net/textproto" - "net/url" - "strings" - "sync" - "time" - - "golang.org/x/net/http/httpguts" -) - -// ReverseProxy is an HTTP Handler that takes an incoming request and -// sends it to another server, proxying the response back to the -// client. -// -// ReverseProxy by default sets the client IP as the value of the -// X-Forwarded-For header. -// -// If an X-Forwarded-For header already exists, the client IP is -// appended to the existing values. As a special case, if the header -// exists in the Request.Header map but has a nil value (such as when -// set by the Director func), the X-Forwarded-For header is -// not modified. -// -// To prevent IP spoofing, be sure to delete any pre-existing -// X-Forwarded-For header coming from the client or -// an untrusted proxy. -type ReverseProxy struct { - // Director must be a function which modifies - // the request into a new request to be sent - // using Transport. Its response is then copied - // back to the original client unmodified. - // Director must not access the provided Request - // after returning. - Director func(*http.Request) - - // The transport used to perform proxy requests. - // If nil, http.DefaultTransport is used. - Transport http.RoundTripper - - // FlushInterval specifies the flush interval - // to flush to the client while copying the - // response body. - // If zero, no periodic flushing is done. - // A negative value means to flush immediately - // after each write to the client. - // The FlushInterval is ignored when ReverseProxy - // recognizes a response as a streaming response, or - // if its ContentLength is -1; for such responses, writes - // are flushed to the client immediately. - FlushInterval time.Duration - - // ErrorLog specifies an optional logger for errors - // that occur when attempting to proxy the request. - // If nil, logging is done via the log package's standard logger. - ErrorLog *log.Logger - - // BufferPool optionally specifies a buffer pool to - // get byte slices for use by io.CopyBuffer when - // copying HTTP response bodies. - BufferPool BufferPool - - // ModifyResponse is an optional function that modifies the - // Response from the backend. It is called if the backend - // returns a response at all, with any HTTP status code. - // If the backend is unreachable, the optional ErrorHandler is - // called without any call to ModifyResponse. - // - // If ModifyResponse returns an error, ErrorHandler is called - // with its error value. If ErrorHandler is nil, its default - // implementation is used. - ModifyResponse func(*http.Response) error - - // ErrorHandler is an optional function that handles errors - // reaching the backend or errors from ModifyResponse. - // - // If nil, the default is to log the provided error and return - // a 502 Status Bad Gateway response. - ErrorHandler func(http.ResponseWriter, *http.Request, error) -} - -// A BufferPool is an interface for getting and returning temporary -// byte slices for use by io.CopyBuffer. -type BufferPool interface { - Get() []byte - Put([]byte) -} - -func singleJoiningSlash(a, b string) string { - aslash := strings.HasSuffix(a, "/") - bslash := strings.HasPrefix(b, "/") - switch { - case aslash && bslash: - return a + b[1:] - case !aslash && !bslash: - return a + "/" + b - } - return a + b -} - -func joinURLPath(a, b *url.URL) (path, rawpath string) { - if a.RawPath == "" && b.RawPath == "" { - return singleJoiningSlash(a.Path, b.Path), "" - } - // Same as singleJoiningSlash, but uses EscapedPath to determine - // whether a slash should be added - apath := a.EscapedPath() - bpath := b.EscapedPath() - - aslash := strings.HasSuffix(apath, "/") - bslash := strings.HasPrefix(bpath, "/") - - switch { - case aslash && bslash: - return a.Path + b.Path[1:], apath + bpath[1:] - case !aslash && !bslash: - return a.Path + "/" + b.Path, apath + "/" + bpath - } - return a.Path + b.Path, apath + bpath -} - -// NewSingleHostReverseProxy returns a new ReverseProxy that routes -// URLs to the scheme, host, and base path provided in target. If the -// target's path is "/base" and the incoming request was for "/dir", -// the target request will be for /base/dir. -// NewSingleHostReverseProxy does not rewrite the Host header. -// To rewrite Host headers, use ReverseProxy directly with a custom -// Director policy. -func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy { - targetQuery := target.RawQuery - director := func(req *http.Request) { - req.URL.Scheme = target.Scheme - req.URL.Host = target.Host - req.URL.Path, req.URL.RawPath = joinURLPath(target, req.URL) - if targetQuery == "" || req.URL.RawQuery == "" { - req.URL.RawQuery = targetQuery + req.URL.RawQuery - } else { - req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery - } - if _, ok := req.Header["User-Agent"]; !ok { - // explicitly disable User-Agent so it's not set to default value - req.Header.Set("User-Agent", "") - } - } - return &ReverseProxy{Director: director} -} - -func copyHeader(dst, src http.Header) { - for k, vv := range src { - for _, v := range vv { - dst.Add(k, v) - } - } -} - -// Hop-by-hop headers. These are removed when sent to the backend. -// As of RFC 7230, hop-by-hop headers are required to appear in the -// Connection header field. These are the headers defined by the -// obsoleted RFC 2616 (section 13.5.1) and are used for backward -// compatibility. -var hopHeaders = []string{ - "Connection", - "Proxy-Connection", // non-standard but still sent by libcurl and rejected by e.g. google - "Keep-Alive", - "Proxy-Authenticate", - "Proxy-Authorization", - "Te", // canonicalized version of "TE" - "Trailer", // not Trailers per URL above; https://www.rfc-editor.org/errata_search.php?eid=4522 - "Transfer-Encoding", - "Upgrade", -} - -func (p *ReverseProxy) defaultErrorHandler(rw http.ResponseWriter, req *http.Request, err error) { - p.logf("http: proxy error: %v", err) - rw.WriteHeader(http.StatusBadGateway) -} - -func (p *ReverseProxy) getErrorHandler() func(http.ResponseWriter, *http.Request, error) { - if p.ErrorHandler != nil { - return p.ErrorHandler - } - return p.defaultErrorHandler -} - -// modifyResponse conditionally runs the optional ModifyResponse hook -// and reports whether the request should proceed. -func (p *ReverseProxy) modifyResponse(rw http.ResponseWriter, res *http.Response, req *http.Request) bool { - if p.ModifyResponse == nil { - return true - } - if err := p.ModifyResponse(res); err != nil { - res.Body.Close() - p.getErrorHandler()(rw, req, err) - return false - } - return true -} - -func parseBasicAuth(auth string) (username, password string, ok bool) { - const prefix = "Basic " - // Case insensitive prefix match. See Issue 22736. - if len(auth) < len(prefix) || !strings.EqualFold(auth[:len(prefix)], prefix) { - return - } - c, err := base64.StdEncoding.DecodeString(auth[len(prefix):]) - if err != nil { - return - } - cs := string(c) - s := strings.IndexByte(cs, ':') - if s < 0 { - return - } - return cs[:s], cs[s+1:], true -} - -func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) { - transport := p.Transport - if transport == nil { - transport = http.DefaultTransport - } - - ctx := req.Context() - if cn, ok := rw.(http.CloseNotifier); ok { - var cancel context.CancelFunc - ctx, cancel = context.WithCancel(ctx) - defer cancel() - notifyChan := cn.CloseNotify() - go func() { - select { - case <-notifyChan: - cancel() - case <-ctx.Done(): - } - }() - } - - outreq := req.Clone(ctx) - if req.ContentLength == 0 { - outreq.Body = nil // Issue 16036: nil Body for http.Transport retries - } - if outreq.Header == nil { - outreq.Header = make(http.Header) // Issue 33142: historical behavior was to always allocate - } - - p.Director(outreq) - outreq.Close = false - - reqUpType := upgradeType(outreq.Header) - removeConnectionHeaders(outreq.Header) - - // Remove hop-by-hop headers to the backend. Especially - // important is "Connection" because we want a persistent - // connection, regardless of what the client sent to us. - for _, h := range hopHeaders { - hv := outreq.Header.Get(h) - if hv == "" { - continue - } - if h == "Te" && hv == "trailers" { - // Issue 21096: tell backend applications that - // care about trailer support that we support - // trailers. (We do, but we don't go out of - // our way to advertise that unless the - // incoming client request thought it was - // worth mentioning) - continue - } - outreq.Header.Del(h) - } - - // After stripping all the hop-by-hop connection headers above, add back any - // necessary for protocol upgrades, such as for websockets. - if reqUpType != "" { - outreq.Header.Set("Connection", "Upgrade") - outreq.Header.Set("Upgrade", reqUpType) - } - - if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil { - // If we aren't the first proxy retain prior - // X-Forwarded-For information as a comma+space - // separated list and fold multiple headers into one. - prior, ok := outreq.Header["X-Forwarded-For"] - omit := ok && prior == nil // Issue 38079: nil now means don't populate the header - if len(prior) > 0 { - clientIP = strings.Join(prior, ", ") + ", " + clientIP - } - if !omit { - outreq.Header.Set("X-Forwarded-For", clientIP) - } - } - - res, err := transport.RoundTrip(outreq) - if err != nil { - p.getErrorHandler()(rw, outreq, err) - return - } - - // Deal with 101 Switching Protocols responses: (WebSocket, h2c, etc) - if res.StatusCode == http.StatusSwitchingProtocols { - if !p.modifyResponse(rw, res, outreq) { - return - } - p.handleUpgradeResponse(rw, outreq, res) - return - } - - removeConnectionHeaders(res.Header) - - for _, h := range hopHeaders { - res.Header.Del(h) - } - - if !p.modifyResponse(rw, res, outreq) { - return - } - - copyHeader(rw.Header(), res.Header) - - // The "Trailer" header isn't included in the Transport's response, - // at least for *http.Transport. Build it up from Trailer. - announcedTrailers := len(res.Trailer) - if announcedTrailers > 0 { - trailerKeys := make([]string, 0, len(res.Trailer)) - for k := range res.Trailer { - trailerKeys = append(trailerKeys, k) - } - rw.Header().Add("Trailer", strings.Join(trailerKeys, ", ")) - } - - rw.WriteHeader(res.StatusCode) - - err = p.copyResponse(rw, res.Body, p.flushInterval(res)) - if err != nil { - defer res.Body.Close() - // Since we're streaming the response, if we run into an error all we can do - // is abort the request. Issue 23643: ReverseProxy should use ErrAbortHandler - // on read error while copying body. - if !shouldPanicOnCopyError(req) { - p.logf("suppressing panic for copyResponse error in test; copy error: %v", err) - return - } - panic(http.ErrAbortHandler) - } - res.Body.Close() // close now, instead of defer, to populate res.Trailer - - if len(res.Trailer) > 0 { - // Force chunking if we saw a response trailer. - // This prevents net/http from calculating the length for short - // bodies and adding a Content-Length. - if fl, ok := rw.(http.Flusher); ok { - fl.Flush() - } - } - - if len(res.Trailer) == announcedTrailers { - copyHeader(rw.Header(), res.Trailer) - return - } - - for k, vv := range res.Trailer { - k = http.TrailerPrefix + k - for _, v := range vv { - rw.Header().Add(k, v) - } - } -} - -var inOurTests bool // whether we're in our own tests - -// shouldPanicOnCopyError reports whether the reverse proxy should -// panic with http.ErrAbortHandler. This is the right thing to do by -// default, but Go 1.10 and earlier did not, so existing unit tests -// weren't expecting panics. Only panic in our own tests, or when -// running under the HTTP server. -func shouldPanicOnCopyError(req *http.Request) bool { - if inOurTests { - // Our tests know to handle this panic. - return true - } - if req.Context().Value(http.ServerContextKey) != nil { - // We seem to be running under an HTTP server, so - // it'll recover the panic. - return true - } - // Otherwise act like Go 1.10 and earlier to not break - // existing tests. - return false -} - -// removeConnectionHeaders removes hop-by-hop headers listed in the "Connection" header of h. -// See RFC 7230, section 6.1 -func removeConnectionHeaders(h http.Header) { - for _, f := range h["Connection"] { - for _, sf := range strings.Split(f, ",") { - if sf = textproto.TrimString(sf); sf != "" { - h.Del(sf) - } - } - } -} - -// flushInterval returns the p.FlushInterval value, conditionally -// overriding its value for a specific request/response. -func (p *ReverseProxy) flushInterval(res *http.Response) time.Duration { - resCT := res.Header.Get("Content-Type") - - // For Server-Sent Events responses, flush immediately. - // The MIME type is defined in https://www.w3.org/TR/eventsource/#text-event-stream - if resCT == "text/event-stream" { - return -1 // negative means immediately - } - - // We might have the case of streaming for which Content-Length might be unset. - if res.ContentLength == -1 { - return -1 - } - - return p.FlushInterval -} - -func (p *ReverseProxy) copyResponse(dst io.Writer, src io.Reader, flushInterval time.Duration) error { - if flushInterval != 0 { - if wf, ok := dst.(writeFlusher); ok { - mlw := &maxLatencyWriter{ - dst: wf, - latency: flushInterval, - } - defer mlw.stop() - - // set up initial timer so headers get flushed even if body writes are delayed - mlw.flushPending = true - mlw.t = time.AfterFunc(flushInterval, mlw.delayedFlush) - - dst = mlw - } - } - - var buf []byte - if p.BufferPool != nil { - buf = p.BufferPool.Get() - defer p.BufferPool.Put(buf) - } - _, err := p.copyBuffer(dst, src, buf) - return err -} - -// copyBuffer returns any write errors or non-EOF read errors, and the amount -// of bytes written. -func (p *ReverseProxy) copyBuffer(dst io.Writer, src io.Reader, buf []byte) (int64, error) { - if len(buf) == 0 { - buf = make([]byte, 32*1024) - } - var written int64 - for { - nr, rerr := src.Read(buf) - if rerr != nil && rerr != io.EOF && rerr != context.Canceled { - p.logf("httputil: ReverseProxy read error during body copy: %v", rerr) - } - if nr > 0 { - nw, werr := dst.Write(buf[:nr]) - if nw > 0 { - written += int64(nw) - } - if werr != nil { - return written, werr - } - if nr != nw { - return written, io.ErrShortWrite - } - } - if rerr != nil { - if rerr == io.EOF { - rerr = nil - } - return written, rerr - } - } -} - -func (p *ReverseProxy) logf(format string, args ...interface{}) { - if p.ErrorLog != nil { - p.ErrorLog.Printf(format, args...) - } else { - log.Printf(format, args...) - } -} - -type writeFlusher interface { - io.Writer - http.Flusher -} - -type maxLatencyWriter struct { - dst writeFlusher - latency time.Duration // non-zero; negative means to flush immediately - - mu sync.Mutex // protects t, flushPending, and dst.Flush - t *time.Timer - flushPending bool -} - -func (m *maxLatencyWriter) Write(p []byte) (n int, err error) { - m.mu.Lock() - defer m.mu.Unlock() - n, err = m.dst.Write(p) - if m.latency < 0 { - m.dst.Flush() - return - } - if m.flushPending { - return - } - if m.t == nil { - m.t = time.AfterFunc(m.latency, m.delayedFlush) - } else { - m.t.Reset(m.latency) - } - m.flushPending = true - return -} - -func (m *maxLatencyWriter) delayedFlush() { - m.mu.Lock() - defer m.mu.Unlock() - if !m.flushPending { // if stop was called but AfterFunc already started this goroutine - return - } - m.dst.Flush() - m.flushPending = false -} - -func (m *maxLatencyWriter) stop() { - m.mu.Lock() - defer m.mu.Unlock() - m.flushPending = false - if m.t != nil { - m.t.Stop() - } -} - -func upgradeType(h http.Header) string { - if !httpguts.HeaderValuesContainsToken(h["Connection"], "Upgrade") { - return "" - } - return strings.ToLower(h.Get("Upgrade")) -} - -func (p *ReverseProxy) handleUpgradeResponse(rw http.ResponseWriter, req *http.Request, res *http.Response) { - reqUpType := upgradeType(req.Header) - resUpType := upgradeType(res.Header) - if reqUpType != resUpType { - p.getErrorHandler()(rw, req, fmt.Errorf("backend tried to switch protocol %q when %q was requested", resUpType, reqUpType)) - return - } - - hj, ok := rw.(http.Hijacker) - if !ok { - p.getErrorHandler()(rw, req, fmt.Errorf("can't switch protocols using non-Hijacker ResponseWriter type %T", rw)) - return - } - backConn, ok := res.Body.(io.ReadWriteCloser) - if !ok { - p.getErrorHandler()(rw, req, fmt.Errorf("internal error: 101 switching protocols response with non-writable body")) - return - } - - backConnCloseCh := make(chan bool) - go func() { - // Ensure that the cancelation of a request closes the backend. - // See issue https://golang.org/issue/35559. - select { - case <-req.Context().Done(): - case <-backConnCloseCh: - } - backConn.Close() - }() - - defer close(backConnCloseCh) - - conn, brw, err := hj.Hijack() - if err != nil { - p.getErrorHandler()(rw, req, fmt.Errorf("Hijack failed on protocol switch: %v", err)) - return - } - defer conn.Close() - - copyHeader(rw.Header(), res.Header) - - res.Header = rw.Header() - res.Body = nil // so res.Write only writes the headers; we have res.Body in backConn above - if err := res.Write(brw); err != nil { - p.getErrorHandler()(rw, req, fmt.Errorf("response write: %v", err)) - return - } - if err := brw.Flush(); err != nil { - p.getErrorHandler()(rw, req, fmt.Errorf("response flush: %v", err)) - return - } - errc := make(chan error, 1) - spc := switchProtocolCopier{user: conn, backend: backConn} - go spc.copyToBackend(errc) - go spc.copyFromBackend(errc) - <-errc - return -} - -// switchProtocolCopier exists so goroutines proxying data back and -// forth have nice names in stacks. -type switchProtocolCopier struct { - user, backend io.ReadWriter -} - -func (c switchProtocolCopier) copyFromBackend(errc chan<- error) { - _, err := io.Copy(c.user, c.backend) - errc <- err -} - -func (c switchProtocolCopier) copyToBackend(errc chan<- error) { - _, err := io.Copy(c.backend, c.user) - errc <- err -} diff --git a/pkg/util/vhost/router.go b/pkg/util/vhost/router.go index 768420a47e7..281e164bdf9 100644 --- a/pkg/util/vhost/router.go +++ b/pkg/util/vhost/router.go @@ -7,9 +7,7 @@ import ( "sync" ) -var ( - ErrRouterConfigConflict = errors.New("router config conflict") -) +var ErrRouterConfigConflict = errors.New("router config conflict") type routerByHTTPUser map[string][]*Router @@ -133,9 +131,11 @@ type ByLocation []*Router func (a ByLocation) Len() int { return len(a) } + func (a ByLocation) Swap(i, j int) { a[i], a[j] = a[j], a[i] } + func (a ByLocation) Less(i, j int) bool { return strings.Compare(a[i].location, a[j].location) < 0 } diff --git a/pkg/util/vhost/vhost.go b/pkg/util/vhost/vhost.go index 2957cec4e78..651d9607221 100644 --- a/pkg/util/vhost/vhost.go +++ b/pkg/util/vhost/vhost.go @@ -19,27 +19,34 @@ import ( "strings" "time" + "github.com/fatedier/golib/errors" + "github.com/fatedier/frp/pkg/util/log" frpNet "github.com/fatedier/frp/pkg/util/net" "github.com/fatedier/frp/pkg/util/xlog" - - "github.com/fatedier/golib/errors" ) type RouteInfo string const ( - RouteInfoURL RouteInfo = "url" - RouteInfoHost RouteInfo = "host" - RouteInfoHTTPUser RouteInfo = "httpUser" - RouteInfoRemote RouteInfo = "remote" - RouteInfoURLHost RouteInfo = "urlHost" + RouteInfoKey RouteInfo = "routeInfo" ) -type muxFunc func(net.Conn) (net.Conn, map[string]string, error) -type httpAuthFunc func(net.Conn, string, string, string) (bool, error) -type hostRewriteFunc func(net.Conn, string) (net.Conn, error) -type successFunc func(net.Conn, map[string]string) error +type RequestRouteInfo struct { + URL string + Host string + HTTPUser string + RemoteAddr string + URLHost string + Endpoint string +} + +type ( + muxFunc func(net.Conn) (net.Conn, map[string]string, error) + httpAuthFunc func(net.Conn, string, string, string) (bool, error) + hostRewriteFunc func(net.Conn, string) (net.Conn, error) + successFunc func(net.Conn, map[string]string) error +) // Muxer is only used for https and tcpmux proxy. type Muxer struct { @@ -60,7 +67,6 @@ func NewMuxer( rewriteFunc hostRewriteFunc, timeout time.Duration, ) (mux *Muxer, err error) { - mux = &Muxer{ listener: listener, timeout: timeout, @@ -74,8 +80,12 @@ func NewMuxer( return mux, nil } +type ChooseEndpointFunc func() (string, error) + type CreateConnFunc func(remoteAddr string) (net.Conn, error) +type CreateConnByEndpointFunc func(endpoint, remoteAddr string) (net.Conn, error) + // RouteConfig is the params used to match HTTP requests type RouteConfig struct { Domain string @@ -86,7 +96,9 @@ type RouteConfig struct { Headers map[string]string RouteByHTTPUser string - CreateConnFn CreateConnFunc + CreateConnFn CreateConnFunc + ChooseEndpointFn ChooseEndpointFunc + CreateConnByEndpointFn CreateConnByEndpointFunc } // listen for a new domain name, if rewriteHost is not empty and rewriteFunc is not nil @@ -111,9 +123,8 @@ func (v *Muxer) Listen(ctx context.Context, cfg *RouteConfig) (l *Listener, err } func (v *Muxer) getListener(name, path, httpUser string) (*Listener, bool) { - findRouter := func(inName, inPath, inHTTPUser string) (*Listener, bool) { - vr, ok := v.registryRouter.Get(inName, inPath, httpUser) + vr, ok := v.registryRouter.Get(inName, inPath, inHTTPUser) if ok { return vr.payload.(*Listener), true } @@ -167,14 +178,14 @@ func (v *Muxer) run() { func (v *Muxer) handle(c net.Conn) { if err := c.SetDeadline(time.Now().Add(v.timeout)); err != nil { - c.Close() + _ = c.Close() return } sConn, reqInfoMap, err := v.vhostFunc(c) if err != nil { log.Debug("get hostname from http/https request error: %v", err) - c.Close() + _ = c.Close() return } @@ -184,9 +195,12 @@ func (v *Muxer) handle(c net.Conn) { l, ok := v.getListener(name, path, httpUser) if !ok { res := notFoundResponse() - res.Write(c) + if res.Body != nil { + defer res.Body.Close() + } + _ = res.Write(c) log.Debug("http request for host [%s] path [%s] httpUser [%s] not found", name, path, httpUser) - c.Close() + _ = c.Close() return } @@ -194,7 +208,7 @@ func (v *Muxer) handle(c net.Conn) { if v.successFunc != nil { if err := v.successFunc(c, reqInfoMap); err != nil { xl.Info("success func failure on vhost connection: %v", err) - c.Close() + _ = c.Close() return } } @@ -203,17 +217,20 @@ func (v *Muxer) handle(c net.Conn) { // then verify user access if l.mux.authFunc != nil && l.userName != "" && l.passWord != "" { bAccess, err := l.mux.authFunc(c, l.userName, l.passWord, reqInfoMap["Authorization"]) - if bAccess == false || err != nil { + if !bAccess || err != nil { xl.Debug("check http Authorization failed") res := noAuthResponse() - res.Write(c) - c.Close() + if res.Body != nil { + defer res.Body.Close() + } + _ = res.Write(c) + _ = c.Close() return } } if err = sConn.SetDeadline(time.Time{}); err != nil { - c.Close() + _ = c.Close() return } c = sConn diff --git a/server/control.go b/server/control.go index 197c94de968..3fcd3ae434a 100644 --- a/server/control.go +++ b/server/control.go @@ -23,6 +23,10 @@ import ( "sync" "time" + "github.com/fatedier/golib/control/shutdown" + "github.com/fatedier/golib/crypto" + "github.com/fatedier/golib/errors" + "github.com/fatedier/frp/pkg/auth" "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/consts" @@ -35,10 +39,6 @@ import ( "github.com/fatedier/frp/server/controller" "github.com/fatedier/frp/server/metrics" "github.com/fatedier/frp/server/proxy" - - "github.com/fatedier/golib/control/shutdown" - "github.com/fatedier/golib/crypto" - "github.com/fatedier/golib/errors" ) type ControlManager struct { @@ -154,7 +154,6 @@ func NewControl( loginMsg *msg.Login, serverCfg config.ServerCommonConf, ) *Control { - poolCount := loginMsg.PoolCount if poolCount > int(serverCfg.MaxPoolCount) { poolCount = int(serverCfg.MaxPoolCount) @@ -193,7 +192,7 @@ func (ctl *Control) Start() { ServerUDPPort: ctl.serverCfg.BindUDPPort, Error: "", } - msg.WriteMsg(ctl.conn, loginRespMsg) + _ = msg.WriteMsg(ctl.conn, loginRespMsg) go ctl.writer() for i := 0; i < ctl.poolCount; i++ { @@ -270,7 +269,7 @@ func (ctl *Control) GetWorkConn() (workConn net.Conn, err error) { } // When we get a work connection from pool, replace it with a new one. - errors.PanicToError(func() { + _ = errors.PanicToError(func() { ctl.sendCh <- &msg.ReqWorkConn{} }) return @@ -388,7 +387,7 @@ func (ctl *Control) stoper() { }, } go func() { - ctl.pluginManager.CloseProxy(notifyContent) + _ = ctl.pluginManager.CloseProxy(notifyContent) }() } @@ -467,7 +466,7 @@ func (ctl *Control) manager() { } ctl.sendCh <- resp case *msg.CloseProxy: - ctl.CloseProxy(m) + _ = ctl.CloseProxy(m) xl.Info("close proxy [%s] success", m.ProxyName) case *msg.Ping: content := &plugin.PingContent{ @@ -528,13 +527,13 @@ func (ctl *Control) RegisterProxy(pxyMsg *msg.NewProxy) (remoteAddr string, err err = fmt.Errorf("exceed the max_ports_per_client") return } - ctl.portsUsedNum = ctl.portsUsedNum + pxy.GetUsedPortsNum() + ctl.portsUsedNum += pxy.GetUsedPortsNum() ctl.mu.Unlock() defer func() { if err != nil { ctl.mu.Lock() - ctl.portsUsedNum = ctl.portsUsedNum - pxy.GetUsedPortsNum() + ctl.portsUsedNum -= pxy.GetUsedPortsNum() ctl.mu.Unlock() } }() @@ -570,7 +569,7 @@ func (ctl *Control) CloseProxy(closeMsg *msg.CloseProxy) (err error) { } if ctl.serverCfg.MaxPortsPerClient > 0 { - ctl.portsUsedNum = ctl.portsUsedNum - pxy.GetUsedPortsNum() + ctl.portsUsedNum -= pxy.GetUsedPortsNum() } pxy.Close() ctl.pxyManager.Del(pxy.GetName()) @@ -590,7 +589,7 @@ func (ctl *Control) CloseProxy(closeMsg *msg.CloseProxy) (err error) { }, } go func() { - ctl.pluginManager.CloseProxy(notifyContent) + _ = ctl.pluginManager.CloseProxy(notifyContent) }() return diff --git a/server/dashboard.go b/server/dashboard.go index 68e99f8a2c1..02c86325b61 100644 --- a/server/dashboard.go +++ b/server/dashboard.go @@ -21,11 +21,11 @@ import ( "net/http/pprof" "time" - "github.com/fatedier/frp/assets" - frpNet "github.com/fatedier/frp/pkg/util/net" - "github.com/gorilla/mux" "github.com/prometheus/client_golang/prometheus/promhttp" + + "github.com/fatedier/frp/assets" + frpNet "github.com/fatedier/frp/pkg/util/net" ) var ( @@ -92,6 +92,8 @@ func (svr *Service) RunDashboardServer(address string) (err error) { } ln = tls.NewListener(ln, tlsCfg) } - go server.Serve(ln) + go func() { + _ = server.Serve(ln) + }() return } diff --git a/server/dashboard_api.go b/server/dashboard_api.go index 7d159c7a89a..6f7ecfd793c 100644 --- a/server/dashboard_api.go +++ b/server/dashboard_api.go @@ -18,13 +18,13 @@ import ( "encoding/json" "net/http" + "github.com/gorilla/mux" + "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/consts" "github.com/fatedier/frp/pkg/metrics/mem" "github.com/fatedier/frp/pkg/util/log" "github.com/fatedier/frp/pkg/util/version" - - "github.com/gorilla/mux" ) type GeneralResponse struct { @@ -63,7 +63,7 @@ func (svr *Service) APIServerInfo(w http.ResponseWriter, r *http.Request) { log.Info("Http response [%s]: code [%d]", r.URL.Path, res.Code) w.WriteHeader(res.Code) if len(res.Msg) > 0 { - w.Write([]byte(res.Msg)) + _, _ = w.Write([]byte(res.Msg)) } }() @@ -179,7 +179,7 @@ func (svr *Service) APIProxyByType(w http.ResponseWriter, r *http.Request) { log.Info("Http response [%s]: code [%d]", r.URL.Path, res.Code) w.WriteHeader(res.Code) if len(res.Msg) > 0 { - w.Write([]byte(res.Msg)) + _, _ = w.Write([]byte(res.Msg)) } }() log.Info("Http request: [%s]", r.URL.Path) @@ -245,12 +245,12 @@ func (svr *Service) APIProxyByTypeAndName(w http.ResponseWriter, r *http.Request log.Info("Http response [%s]: code [%d]", r.URL.Path, res.Code) w.WriteHeader(res.Code) if len(res.Msg) > 0 { - w.Write([]byte(res.Msg)) + _, _ = w.Write([]byte(res.Msg)) } }() log.Info("Http request: [%s]", r.URL.Path) - proxyStatsResp := GetProxyStatsResp{} + var proxyStatsResp GetProxyStatsResp proxyStatsResp, res.Code, res.Msg = svr.getProxyStatsByTypeAndName(proxyType, name) if res.Code != 200 { return @@ -313,7 +313,7 @@ func (svr *Service) APIProxyTraffic(w http.ResponseWriter, r *http.Request) { log.Info("Http response [%s]: code [%d]", r.URL.Path, res.Code) w.WriteHeader(res.Code) if len(res.Msg) > 0 { - w.Write([]byte(res.Msg)) + _, _ = w.Write([]byte(res.Msg)) } }() log.Info("Http request: [%s]", r.URL.Path) diff --git a/server/group/http.go b/server/group/http.go index fb00f0c7086..640919251d3 100644 --- a/server/group/http.go +++ b/server/group/http.go @@ -10,7 +10,7 @@ import ( ) type HTTPGroupController struct { - // groups by indexKey + // groups indexed by group name groups map[string]*HTTPGroup // register createConn for each group to vhostRouter. @@ -31,7 +31,6 @@ func (ctl *HTTPGroupController) Register( proxyName, group, groupKey string, routeConfig vhost.RouteConfig, ) (err error) { - indexKey := group ctl.mu.Lock() g, ok := ctl.groups[indexKey] @@ -66,7 +65,7 @@ type HTTPGroup struct { location string routeByHTTPUser string - // CreateConnFuncs indexed by echo proxy name + // CreateConnFuncs indexed by proxy name createFuncs map[string]vhost.CreateConnFunc pxyNames []string index uint64 @@ -86,13 +85,14 @@ func (g *HTTPGroup) Register( proxyName, group, groupKey string, routeConfig vhost.RouteConfig, ) (err error) { - g.mu.Lock() defer g.mu.Unlock() if len(g.createFuncs) == 0 { // the first proxy in this group tmp := routeConfig // copy object tmp.CreateConnFn = g.createConn + tmp.ChooseEndpointFn = g.chooseEndpoint + tmp.CreateConnByEndpointFn = g.createConnByEndpoint err = g.ctl.vhostRouter.Add(routeConfig.Domain, routeConfig.Location, routeConfig.RouteByHTTPUser, &tmp) if err != nil { return @@ -152,7 +152,7 @@ func (g *HTTPGroup) createConn(remoteAddr string) (net.Conn, error) { routeByHTTPUser := g.routeByHTTPUser if len(g.pxyNames) > 0 { name := g.pxyNames[int(newIndex)%len(g.pxyNames)] - f, _ = g.createFuncs[name] + f = g.createFuncs[name] } g.mu.RUnlock() @@ -163,3 +163,36 @@ func (g *HTTPGroup) createConn(remoteAddr string) (net.Conn, error) { return f(remoteAddr) } + +func (g *HTTPGroup) chooseEndpoint() (string, error) { + newIndex := atomic.AddUint64(&g.index, 1) + name := "" + + g.mu.RLock() + group := g.group + domain := g.domain + location := g.location + routeByHTTPUser := g.routeByHTTPUser + if len(g.pxyNames) > 0 { + name = g.pxyNames[int(newIndex)%len(g.pxyNames)] + } + g.mu.RUnlock() + + if name == "" { + return "", fmt.Errorf("no healthy endpoint for http group [%s], domain [%s], location [%s], routeByHTTPUser [%s]", + group, domain, location, routeByHTTPUser) + } + return name, nil +} + +func (g *HTTPGroup) createConnByEndpoint(endpoint, remoteAddr string) (net.Conn, error) { + var f vhost.CreateConnFunc + g.mu.RLock() + f = g.createFuncs[endpoint] + g.mu.RUnlock() + + if f == nil { + return nil, fmt.Errorf("no CreateConnFunc for endpoint [%s] in group [%s]", endpoint, g.group) + } + return f(remoteAddr) +} diff --git a/server/group/tcp.go b/server/group/tcp.go index c7fd2b2799d..c0dcd5f7e3c 100644 --- a/server/group/tcp.go +++ b/server/group/tcp.go @@ -19,9 +19,9 @@ import ( "strconv" "sync" - "github.com/fatedier/frp/server/ports" - gerr "github.com/fatedier/golib/errors" + + "github.com/fatedier/frp/server/ports" ) // TCPGroupCtl manage all TCPGroups @@ -44,8 +44,8 @@ func NewTCPGroupCtl(portManager *ports.Manager) *TCPGroupCtl { // Listen is the wrapper for TCPGroup's Listen // If there are no group, we will create one here func (tgc *TCPGroupCtl) Listen(proxyName string, group string, groupKey string, - addr string, port int) (l net.Listener, realPort int, err error) { - + addr string, port int, +) (l net.Listener, realPort int, err error) { tgc.mu.Lock() tcpGroup, ok := tgc.groups[group] if !ok { @@ -73,7 +73,6 @@ type TCPGroup struct { realPort int acceptCh chan net.Conn - index uint64 tcpLn net.Listener lns []*TCPGroupListener ctl *TCPGroupCtl diff --git a/server/group/tcpmux.go b/server/group/tcpmux.go index fd805d91ebe..2da85cee4fe 100644 --- a/server/group/tcpmux.go +++ b/server/group/tcpmux.go @@ -20,11 +20,11 @@ import ( "net" "sync" + gerr "github.com/fatedier/golib/errors" + "github.com/fatedier/frp/pkg/consts" "github.com/fatedier/frp/pkg/util/tcpmux" "github.com/fatedier/frp/pkg/util/vhost" - - gerr "github.com/fatedier/golib/errors" ) // TCPMuxGroupCtl manage all TCPMuxGroups @@ -51,7 +51,6 @@ func (tmgc *TCPMuxGroupCtl) Listen( multiplexer, group, groupKey string, routeConfig vhost.RouteConfig, ) (l net.Listener, err error) { - tmgc.mu.Lock() tcpMuxGroup, ok := tmgc.groups[group] if !ok { @@ -84,7 +83,6 @@ type TCPMuxGroup struct { routeByHTTPUser string acceptCh chan net.Conn - index uint64 tcpMuxLn net.Listener lns []*TCPMuxGroupListener ctl *TCPMuxGroupCtl @@ -108,7 +106,6 @@ func (tmg *TCPMuxGroup) HTTPConnectListen( group, groupKey string, routeConfig vhost.RouteConfig, ) (ln *TCPMuxGroupListener, err error) { - tmg.mu.Lock() defer tmg.mu.Unlock() if len(tmg.lns) == 0 { diff --git a/server/proxy/http.go b/server/proxy/http.go index e0e2f23cb50..e70cb65f1c5 100644 --- a/server/proxy/http.go +++ b/server/proxy/http.go @@ -19,13 +19,13 @@ import ( "net" "strings" + frpIo "github.com/fatedier/golib/io" + "github.com/fatedier/frp/pkg/config" frpNet "github.com/fatedier/frp/pkg/util/net" "github.com/fatedier/frp/pkg/util/util" "github.com/fatedier/frp/pkg/util/vhost" "github.com/fatedier/frp/server/metrics" - - frpIo "github.com/fatedier/golib/io" ) type HTTPProxy struct { @@ -89,7 +89,7 @@ func (pxy *HTTPProxy) Run() (remoteAddr string, err error) { pxy.rc.HTTPReverseProxy.UnRegister(tmpRouteConfig) }) } - addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, int(pxy.serverCfg.VhostHTTPPort))) + addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, pxy.serverCfg.VhostHTTPPort)) xl.Info("http proxy listen for host [%s] location [%s] group [%s], routeByHTTPUser [%s]", routeConfig.Domain, routeConfig.Location, pxy.cfg.Group, pxy.cfg.RouteByHTTPUser) } diff --git a/server/proxy/https.go b/server/proxy/https.go index cd566462201..42ecf35d76f 100644 --- a/server/proxy/https.go +++ b/server/proxy/https.go @@ -62,7 +62,7 @@ func (pxy *HTTPSProxy) Run() (remoteAddr string, err error) { } xl.Info("https proxy listen for host [%s]", routeConfig.Domain) pxy.listeners = append(pxy.listeners, l) - addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, int(pxy.serverCfg.VhostHTTPSPort))) + addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, pxy.serverCfg.VhostHTTPSPort)) } pxy.startListenHandler(pxy, HandleUserTCPConnection) diff --git a/server/proxy/proxy.go b/server/proxy/proxy.go index 43c2c74e9b1..808d93161d5 100644 --- a/server/proxy/proxy.go +++ b/server/proxy/proxy.go @@ -23,6 +23,8 @@ import ( "sync" "time" + frpIo "github.com/fatedier/golib/io" + "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/msg" plugin "github.com/fatedier/frp/pkg/plugin/server" @@ -30,8 +32,6 @@ import ( "github.com/fatedier/frp/pkg/util/xlog" "github.com/fatedier/frp/server/controller" "github.com/fatedier/frp/server/metrics" - - frpIo "github.com/fatedier/golib/io" ) type GetWorkConnFn func() (net.Conn, error) @@ -184,8 +184,8 @@ func (pxy *BaseProxy) startListenHandler(p Proxy, handler func(Proxy, net.Conn, } func NewProxy(ctx context.Context, userInfo plugin.UserInfo, rc *controller.ResourceController, poolCount int, - getWorkConnFn GetWorkConnFn, pxyConf config.ProxyConf, serverCfg config.ServerCommonConf) (pxy Proxy, err error) { - + getWorkConnFn GetWorkConnFn, pxyConf config.ProxyConf, serverCfg config.ServerCommonConf, +) (pxy Proxy, err error) { xl := xlog.FromContextSafe(ctx).Spawn().AppendPrefix(pxyConf.GetBaseInfo().ProxyName) basePxy := BaseProxy{ name: pxyConf.GetBaseInfo().ProxyName, diff --git a/server/proxy/udp.go b/server/proxy/udp.go index 9e3c067509d..53865540325 100644 --- a/server/proxy/udp.go +++ b/server/proxy/udp.go @@ -22,14 +22,14 @@ import ( "strconv" "time" + "github.com/fatedier/golib/errors" + frpIo "github.com/fatedier/golib/io" + "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/msg" "github.com/fatedier/frp/pkg/proto/udp" frpNet "github.com/fatedier/frp/pkg/util/net" "github.com/fatedier/frp/server/metrics" - - "github.com/fatedier/golib/errors" - frpIo "github.com/fatedier/golib/io" ) type UDPProxy struct { @@ -98,18 +98,20 @@ func (pxy *UDPProxy) Run() (remoteAddr string, err error) { ) xl.Trace("loop waiting message from udp workConn") // client will send heartbeat in workConn for keeping alive - conn.SetReadDeadline(time.Now().Add(time.Duration(60) * time.Second)) + _ = conn.SetReadDeadline(time.Now().Add(time.Duration(60) * time.Second)) if rawMsg, errRet = msg.ReadMsg(conn); errRet != nil { xl.Warn("read from workConn for udp error: %v", errRet) - conn.Close() + _ = conn.Close() // notify proxy to start a new work connection // ignore error here, it means the proxy is closed - errors.PanicToError(func() { + _ = errors.PanicToError(func() { pxy.checkCloseCh <- 1 }) return } - conn.SetReadDeadline(time.Time{}) + if err := conn.SetReadDeadline(time.Time{}); err != nil { + xl.Warn("set read deadline error: %v", err) + } switch m := rawMsg.(type) { case *msg.Ping: xl.Trace("udp work conn get ping message") diff --git a/server/proxy/xtcp.go b/server/proxy/xtcp.go index 317a3d484c9..a1b45d5446c 100644 --- a/server/proxy/xtcp.go +++ b/server/proxy/xtcp.go @@ -17,10 +17,10 @@ package proxy import ( "fmt" + "github.com/fatedier/golib/errors" + "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/msg" - - "github.com/fatedier/golib/errors" ) type XTCPProxy struct { @@ -91,7 +91,7 @@ func (pxy *XTCPProxy) GetConf() config.ProxyConf { func (pxy *XTCPProxy) Close() { pxy.BaseProxy.Close() pxy.rc.NatHoleController.CloseClient(pxy.GetName()) - errors.PanicToError(func() { + _ = errors.PanicToError(func() { close(pxy.closeCh) }) } diff --git a/server/service.go b/server/service.go index c3d398b2749..fc59b39c64b 100644 --- a/server/service.go +++ b/server/service.go @@ -26,6 +26,10 @@ import ( "strconv" "time" + "github.com/fatedier/golib/net/mux" + fmux "github.com/hashicorp/yamux" + quic "github.com/lucas-clemente/quic-go" + "github.com/fatedier/frp/assets" "github.com/fatedier/frp/pkg/auth" "github.com/fatedier/frp/pkg/config" @@ -47,9 +51,6 @@ import ( "github.com/fatedier/frp/server/ports" "github.com/fatedier/frp/server/proxy" "github.com/fatedier/frp/server/visitor" - - "github.com/fatedier/golib/net/mux" - fmux "github.com/hashicorp/yamux" ) const ( @@ -68,6 +69,9 @@ type Service struct { // Accept connections using kcp kcpListener net.Listener + // Accept connections using quic + quicListener quic.Listener + // Accept connections using websocket websocketListener net.Listener @@ -127,26 +131,26 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) { address := net.JoinHostPort(cfg.ProxyBindAddr, strconv.Itoa(cfg.TCPMuxHTTPConnectPort)) l, err = net.Listen("tcp", address) if err != nil { - err = fmt.Errorf("Create server listener error, %v", err) + err = fmt.Errorf("create server listener error, %v", err) return } svr.rc.TCPMuxHTTPConnectMuxer, err = tcpmux.NewHTTPConnectTCPMuxer(l, cfg.TCPMuxPassthrough, vhostReadWriteTimeout) if err != nil { - err = fmt.Errorf("Create vhost tcpMuxer error, %v", err) + err = fmt.Errorf("create vhost tcpMuxer error, %v", err) return } log.Info("tcpmux httpconnect multiplexer listen on %s, passthough: %v", address, cfg.TCPMuxPassthrough) } // Init all plugins - plugin_names := make([]string, 0, len(cfg.HTTPPlugins)) + pluginNames := make([]string, 0, len(cfg.HTTPPlugins)) for n := range cfg.HTTPPlugins { - plugin_names = append(plugin_names, n) + pluginNames = append(pluginNames, n) } - sort.Strings(plugin_names) + sort.Strings(pluginNames) - for _, name := range plugin_names { + for _, name := range pluginNames { svr.pluginManager.Register(plugin.NewHTTPPluginOptions(cfg.HTTPPlugins[name])) log.Info("plugin [%s] has been registered", name) } @@ -181,13 +185,15 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) { address := net.JoinHostPort(cfg.BindAddr, strconv.Itoa(cfg.BindPort)) ln, err := net.Listen("tcp", address) if err != nil { - err = fmt.Errorf("Create server listener error, %v", err) + err = fmt.Errorf("create server listener error, %v", err) return } svr.muxer = mux.NewMux(ln) svr.muxer.SetKeepAlive(time.Duration(cfg.TCPKeepAlive) * time.Second) - go svr.muxer.Serve() + go func() { + _ = svr.muxer.Serve() + }() ln = svr.muxer.DefaultListener() svr.listener = ln @@ -198,12 +204,28 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) { address := net.JoinHostPort(cfg.BindAddr, strconv.Itoa(cfg.KCPBindPort)) svr.kcpListener, err = frpNet.ListenKcp(address) if err != nil { - err = fmt.Errorf("Listen on kcp address udp %s error: %v", address, err) + err = fmt.Errorf("listen on kcp udp address %s error: %v", address, err) return } log.Info("frps kcp listen on udp %s", address) } + if cfg.QUICBindPort > 0 { + address := net.JoinHostPort(cfg.BindAddr, strconv.Itoa(cfg.QUICBindPort)) + quicTLSCfg := tlsConfig.Clone() + quicTLSCfg.NextProtos = []string{"frp"} + svr.quicListener, err = quic.ListenAddr(address, quicTLSCfg, &quic.Config{ + MaxIdleTimeout: time.Duration(cfg.QUICMaxIdleTimeout) * time.Second, + MaxIncomingStreams: int64(cfg.QUICMaxIncomingStreams), + KeepAlivePeriod: time.Duration(cfg.QUICKeepalivePeriod) * time.Second, + }) + if err != nil { + err = fmt.Errorf("listen on quic udp address %s error: %v", address, err) + return + } + log.Info("frps quic listen on quic %s", address) + } + // Listen for accepting connections from client using websocket protocol. websocketPrefix := []byte("GET " + frpNet.FrpWebsocketPath) websocketLn := svr.muxer.Listen(0, uint32(len(websocketPrefix)), func(data []byte) bool { @@ -229,11 +251,13 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) { } else { l, err = net.Listen("tcp", address) if err != nil { - err = fmt.Errorf("Create vhost http listener error, %v", err) + err = fmt.Errorf("create vhost http listener error, %v", err) return } } - go server.Serve(l) + go func() { + _ = server.Serve(l) + }() log.Info("http service listen on %s", address) } @@ -246,7 +270,7 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) { address := net.JoinHostPort(cfg.ProxyBindAddr, strconv.Itoa(cfg.VhostHTTPSPort)) l, err = net.Listen("tcp", address) if err != nil { - err = fmt.Errorf("Create server listener error, %v", err) + err = fmt.Errorf("create server listener error, %v", err) return } log.Info("https service listen on %s", address) @@ -254,7 +278,7 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) { svr.rc.VhostHTTPSMuxer, err = vhost.NewHTTPSMuxer(l, vhostReadWriteTimeout) if err != nil { - err = fmt.Errorf("Create vhost httpsMuxer error, %v", err) + err = fmt.Errorf("create vhost httpsMuxer error, %v", err) return } } @@ -271,7 +295,7 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) { address := net.JoinHostPort(cfg.BindAddr, strconv.Itoa(cfg.BindUDPPort)) nc, err = nathole.NewController(address) if err != nil { - err = fmt.Errorf("Create nat hole controller error, %v", err) + err = fmt.Errorf("create nat hole controller error, %v", err) return } svr.rc.NatHoleController = nc @@ -287,7 +311,7 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) { address := net.JoinHostPort(cfg.DashboardAddr, strconv.Itoa(cfg.DashboardPort)) err = svr.RunDashboardServer(address) if err != nil { - err = fmt.Errorf("Create dashboard web server error, %v", err) + err = fmt.Errorf("create dashboard web server error, %v", err) return } log.Info("Dashboard listen on %s", address) @@ -306,9 +330,12 @@ func (svr *Service) Run() { if svr.rc.NatHoleController != nil { go svr.rc.NatHoleController.Run() } - if svr.cfg.KCPBindPort > 0 { + if svr.kcpListener != nil { go svr.HandleListener(svr.kcpListener) } + if svr.quicListener != nil { + go svr.HandleQUICListener(svr.quicListener) + } go svr.HandleListener(svr.websocketListener) go svr.HandleListener(svr.tlsListener) @@ -324,13 +351,13 @@ func (svr *Service) handleConnection(ctx context.Context, conn net.Conn) { err error ) - conn.SetReadDeadline(time.Now().Add(connReadTimeout)) + _ = conn.SetReadDeadline(time.Now().Add(connReadTimeout)) if rawMsg, err = msg.ReadMsg(conn); err != nil { log.Trace("Failed to read message: %v", err) conn.Close() return } - conn.SetReadDeadline(time.Time{}) + _ = conn.SetReadDeadline(time.Time{}) switch m := rawMsg.(type) { case *msg.Login: @@ -349,7 +376,7 @@ func (svr *Service) handleConnection(ctx context.Context, conn net.Conn) { // Otherwise send success message in control's work goroutine. if err != nil { xl.Warn("register control error: %v", err) - msg.WriteMsg(conn, &msg.LoginResp{ + _ = msg.WriteMsg(conn, &msg.LoginResp{ Version: version.Full(), Error: util.GenerateResponseErrorString("register control error", err, svr.cfg.DetailedErrorsToClient), }) @@ -362,13 +389,13 @@ func (svr *Service) handleConnection(ctx context.Context, conn net.Conn) { case *msg.NewVisitorConn: if err = svr.RegisterVisitorConn(conn, m); err != nil { xl.Warn("register visitor conn error: %v", err) - msg.WriteMsg(conn, &msg.NewVisitorConnResp{ + _ = msg.WriteMsg(conn, &msg.NewVisitorConnResp{ ProxyName: m.ProxyName, Error: util.GenerateResponseErrorString("register visitor conn error", err, svr.cfg.DetailedErrorsToClient), }) conn.Close() } else { - msg.WriteMsg(conn, &msg.NewVisitorConnResp{ + _ = msg.WriteMsg(conn, &msg.NewVisitorConnResp{ ProxyName: m.ProxyName, Error: "", }) @@ -433,6 +460,29 @@ func (svr *Service) HandleListener(l net.Listener) { } } +func (svr *Service) HandleQUICListener(l quic.Listener) { + // Listen for incoming connections from client. + for { + c, err := l.Accept(context.Background()) + if err != nil { + log.Warn("QUICListener for incoming connections from client closed") + return + } + // Start a new goroutine to handle connection. + go func(ctx context.Context, frpConn quic.Connection) { + for { + stream, err := frpConn.AcceptStream(context.Background()) + if err != nil { + log.Debug("Accept new quic mux stream error: %v", err) + _ = frpConn.CloseWithError(0, "") + return + } + go svr.handleConnection(ctx, frpNet.QuicStreamToNetConn(stream, frpConn)) + } + }(context.Background(), c) + } +} + func (svr *Service) RegisterControl(ctlConn net.Conn, loginMsg *msg.Login) (err error) { // If client's RunID is empty, it's a new client, we just create a new controller. // Otherwise, we check if there is one controller has the same run id. If so, we release previous controller and start new one. @@ -504,7 +554,7 @@ func (svr *Service) RegisterWorkConn(workConn net.Conn, newMsg *msg.NewWorkConn) } if err != nil { xl.Warn("invalid NewWorkConn with run id [%s]", newMsg.RunID) - msg.WriteMsg(workConn, &msg.StartWorkConn{ + _ = msg.WriteMsg(workConn, &msg.StartWorkConn{ Error: util.GenerateResponseErrorString("invalid NewWorkConn", err, ctl.serverCfg.DetailedErrorsToClient), }) return fmt.Errorf("invalid NewWorkConn with run id [%s]", newMsg.RunID) diff --git a/server/visitor/visitor.go b/server/visitor/visitor.go index 4796b416fbb..70f603b2de6 100644 --- a/server/visitor/visitor.go +++ b/server/visitor/visitor.go @@ -20,10 +20,10 @@ import ( "net" "sync" + frpIo "github.com/fatedier/golib/io" + frpNet "github.com/fatedier/frp/pkg/util/net" "github.com/fatedier/frp/pkg/util/util" - - frpIo "github.com/fatedier/golib/io" ) // Manager for visitor listeners. @@ -57,8 +57,8 @@ func (vm *Manager) Listen(name string, sk string) (l *frpNet.CustomListener, err } func (vm *Manager) NewConn(name string, conn net.Conn, timestamp int64, signKey string, - useEncryption bool, useCompression bool) (err error) { - + useEncryption bool, useCompression bool, +) (err error) { vm.mu.RLock() defer vm.mu.RUnlock() diff --git a/test/e2e/basic/basic.go b/test/e2e/basic/basic.go index 13f17168477..1f1b20072f2 100644 --- a/test/e2e/basic/basic.go +++ b/test/e2e/basic/basic.go @@ -5,6 +5,8 @@ import ( "fmt" "strings" + "github.com/onsi/ginkgo" + "github.com/fatedier/frp/pkg/transport" "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" @@ -12,18 +14,16 @@ import ( "github.com/fatedier/frp/test/e2e/mock/server/streamserver" "github.com/fatedier/frp/test/e2e/pkg/port" "github.com/fatedier/frp/test/e2e/pkg/request" - - . "github.com/onsi/ginkgo" ) -var _ = Describe("[Feature: Basic]", func() { +var _ = ginkgo.Describe("[Feature: Basic]", func() { f := framework.NewDefaultFramework() - Describe("TCP && UDP", func() { + ginkgo.Describe("TCP && UDP", func() { types := []string{"tcp", "udp"} for _, t := range types { proxyType := t - It(fmt.Sprintf("Expose a %s echo server", strings.ToUpper(proxyType)), func() { + ginkgo.It(fmt.Sprintf("Expose a %s echo server", strings.ToUpper(proxyType)), func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig @@ -93,8 +93,8 @@ var _ = Describe("[Feature: Basic]", func() { } }) - Describe("HTTP", func() { - It("proxy to HTTP server", func() { + ginkgo.Describe("HTTP", func() { + ginkgo.It("proxy to HTTP server", func() { serverConf := consts.DefaultServerConfig vhostHTTPPort := f.AllocPort() serverConf += fmt.Sprintf(` @@ -175,8 +175,8 @@ var _ = Describe("[Feature: Basic]", func() { }) }) - Describe("HTTPS", func() { - It("proxy to HTTPS server", func() { + ginkgo.Describe("HTTPS", func() { + ginkgo.It("proxy to HTTPS server", func() { serverConf := consts.DefaultServerConfig vhostHTTPSPort := f.AllocPort() serverConf += fmt.Sprintf(` @@ -237,7 +237,7 @@ var _ = Describe("[Feature: Basic]", func() { framework.ExpectNoError(err) localServer := httpserver.New( httpserver.WithBindPort(localPort), - httpserver.WithTlsConfig(tlsConfig), + httpserver.WithTLSConfig(tlsConfig), httpserver.WithResponse([]byte("test")), ) f.RunServer("", localServer) @@ -275,11 +275,11 @@ var _ = Describe("[Feature: Basic]", func() { }) }) - Describe("STCP && SUDP", func() { + ginkgo.Describe("STCP && SUDP", func() { types := []string{"stcp", "sudp"} for _, t := range types { proxyType := t - It(fmt.Sprintf("Expose echo server with %s", strings.ToUpper(proxyType)), func() { + ginkgo.It(fmt.Sprintf("Expose echo server with %s", strings.ToUpper(proxyType)), func() { serverConf := consts.DefaultServerConfig clientServerConf := consts.DefaultClientConfig clientVisitorConf := consts.DefaultClientConfig @@ -381,8 +381,8 @@ var _ = Describe("[Feature: Basic]", func() { } }) - Describe("TCPMUX", func() { - It("Type tcpmux", func() { + ginkgo.Describe("TCPMUX", func() { + ginkgo.It("Type tcpmux", func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig diff --git a/test/e2e/basic/client.go b/test/e2e/basic/client.go index 8d370928c51..10489d494d3 100644 --- a/test/e2e/basic/client.go +++ b/test/e2e/basic/client.go @@ -6,18 +6,18 @@ import ( "strings" "time" + "github.com/onsi/ginkgo" + "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" "github.com/fatedier/frp/test/e2e/pkg/request" clientsdk "github.com/fatedier/frp/test/e2e/pkg/sdk/client" - - . "github.com/onsi/ginkgo" ) -var _ = Describe("[Feature: ClientManage]", func() { +var _ = ginkgo.Describe("[Feature: ClientManage]", func() { f := framework.NewDefaultFramework() - It("Update && Reload API", func() { + ginkgo.It("Update && Reload API", func() { serverConf := consts.DefaultServerConfig adminPort := f.AllocPort() @@ -62,7 +62,9 @@ var _ = Describe("[Feature: ClientManage]", func() { // change p2 port and remove p3 proxy newClientConf := strings.ReplaceAll(conf, strconv.Itoa(p2Port), strconv.Itoa(newP2Port)) p3Index := strings.Index(newClientConf, "[p3]") - newClientConf = newClientConf[:p3Index] + if p3Index >= 0 { + newClientConf = newClientConf[:p3Index] + } err = client.UpdateConfig(newClientConf) framework.ExpectNoError(err) @@ -77,7 +79,7 @@ var _ = Describe("[Feature: ClientManage]", func() { framework.NewRequestExpect(f).Port(p3Port).Explain("p3 port").ExpectError(true).Ensure() }) - It("healthz", func() { + ginkgo.It("healthz", func() { serverConf := consts.DefaultServerConfig dashboardPort := f.AllocPort() @@ -99,5 +101,4 @@ var _ = Describe("[Feature: ClientManage]", func() { }).Port(dashboardPort). Ensure(framework.ExpectResponseCode(401)) }) - }) diff --git a/test/e2e/basic/client_server.go b/test/e2e/basic/client_server.go index c19077c4825..32a6bbe13da 100644 --- a/test/e2e/basic/client_server.go +++ b/test/e2e/basic/client_server.go @@ -4,12 +4,12 @@ import ( "fmt" "strings" + "github.com/onsi/ginkgo" + "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" "github.com/fatedier/frp/test/e2e/pkg/cert" "github.com/fatedier/frp/test/e2e/pkg/port" - - . "github.com/onsi/ginkgo" ) type generalTestConfigures struct { @@ -18,6 +18,15 @@ type generalTestConfigures struct { expectError bool } +func renderBindPortConfig(protocol string) string { + if protocol == "kcp" { + return fmt.Sprintf(`kcp_bind_port = {{ .%s }}`, consts.PortServerName) + } else if protocol == "quic" { + return fmt.Sprintf(`quic_bind_port = {{ .%s }}`, consts.PortServerName) + } + return "" +} + func runClientServerTest(f *framework.Framework, configures *generalTestConfigures) { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig @@ -54,29 +63,28 @@ func runClientServerTest(f *framework.Framework, configures *generalTestConfigur // defineClientServerTest test a normal tcp and udp proxy with specified TestConfigures. func defineClientServerTest(desc string, f *framework.Framework, configures *generalTestConfigures) { - It(desc, func() { + ginkgo.It(desc, func() { runClientServerTest(f, configures) }) } -var _ = Describe("[Feature: Client-Server]", func() { +var _ = ginkgo.Describe("[Feature: Client-Server]", func() { f := framework.NewDefaultFramework() - Describe("Protocol", func() { - supportProtocols := []string{"tcp", "kcp", "websocket"} + ginkgo.Describe("Protocol", func() { + supportProtocols := []string{"tcp", "kcp", "quic", "websocket"} for _, protocol := range supportProtocols { configures := &generalTestConfigures{ server: fmt.Sprintf(` - kcp_bind_port = {{ .%s }} - protocol = %s" - `, consts.PortServerName, protocol), + %s + `, renderBindPortConfig(protocol)), client: "protocol = " + protocol, } defineClientServerTest(protocol, f, configures) } }) - Describe("Authentication", func() { + ginkgo.Describe("Authentication", func() { defineClientServerTest("Token Correct", f, &generalTestConfigures{ server: "token = 123456", client: "token = 123456", @@ -89,15 +97,14 @@ var _ = Describe("[Feature: Client-Server]", func() { }) }) - Describe("TLS", func() { - supportProtocols := []string{"tcp", "kcp", "websocket"} + ginkgo.Describe("TLS", func() { + supportProtocols := []string{"tcp", "kcp", "quic", "websocket"} for _, protocol := range supportProtocols { tmp := protocol defineClientServerTest("TLS over "+strings.ToUpper(tmp), f, &generalTestConfigures{ server: fmt.Sprintf(` - kcp_bind_port = {{ .%s }} - protocol = %s - `, consts.PortServerName, protocol), + %s + `, renderBindPortConfig(protocol)), client: fmt.Sprintf(`tls_enable = true protocol = %s `, protocol), @@ -114,24 +121,25 @@ var _ = Describe("[Feature: Client-Server]", func() { }) }) - Describe("TLS with custom certificate", func() { - supportProtocols := []string{"tcp", "kcp", "websocket"} + ginkgo.Describe("TLS with custom certificate", func() { + supportProtocols := []string{"tcp", "kcp", "quic", "websocket"} var ( caCrtPath string serverCrtPath, serverKeyPath string clientCrtPath, clientKeyPath string ) - JustBeforeEach(func() { + ginkgo.JustBeforeEach(func() { generator := &cert.SelfSignedCertGenerator{} - artifacts, err := generator.Generate("0.0.0.0") + artifacts, err := generator.Generate("127.0.0.1") framework.ExpectNoError(err) caCrtPath = f.WriteTempFile("ca.crt", string(artifacts.CACert)) serverCrtPath = f.WriteTempFile("server.crt", string(artifacts.Cert)) serverKeyPath = f.WriteTempFile("server.key", string(artifacts.Key)) generator.SetCA(artifacts.CACert, artifacts.CAKey) - generator.Generate("0.0.0.0") + _, err = generator.Generate("127.0.0.1") + framework.ExpectNoError(err) clientCrtPath = f.WriteTempFile("client.crt", string(artifacts.Cert)) clientKeyPath = f.WriteTempFile("client.key", string(artifacts.Key)) }) @@ -139,13 +147,12 @@ var _ = Describe("[Feature: Client-Server]", func() { for _, protocol := range supportProtocols { tmp := protocol - It("one-way authentication: "+tmp, func() { + ginkgo.It("one-way authentication: "+tmp, func() { runClientServerTest(f, &generalTestConfigures{ server: fmt.Sprintf(` - protocol = %s - kcp_bind_port = {{ .%s }} + %s tls_trusted_ca_file = %s - `, tmp, consts.PortServerName, caCrtPath), + `, renderBindPortConfig(tmp), caCrtPath), client: fmt.Sprintf(` protocol = %s tls_enable = true @@ -155,15 +162,14 @@ var _ = Describe("[Feature: Client-Server]", func() { }) }) - It("mutual authentication: "+tmp, func() { + ginkgo.It("mutual authentication: "+tmp, func() { runClientServerTest(f, &generalTestConfigures{ server: fmt.Sprintf(` - protocol = %s - kcp_bind_port = {{ .%s }} + %s tls_cert_file = %s tls_key_file = %s tls_trusted_ca_file = %s - `, tmp, consts.PortServerName, serverCrtPath, serverKeyPath, caCrtPath), + `, renderBindPortConfig(tmp), serverCrtPath, serverKeyPath, caCrtPath), client: fmt.Sprintf(` protocol = %s tls_enable = true @@ -176,13 +182,13 @@ var _ = Describe("[Feature: Client-Server]", func() { } }) - Describe("TLS with custom certificate and specified server name", func() { + ginkgo.Describe("TLS with custom certificate and specified server name", func() { var ( caCrtPath string serverCrtPath, serverKeyPath string clientCrtPath, clientKeyPath string ) - JustBeforeEach(func() { + ginkgo.JustBeforeEach(func() { generator := &cert.SelfSignedCertGenerator{} artifacts, err := generator.Generate("example.com") framework.ExpectNoError(err) @@ -191,12 +197,13 @@ var _ = Describe("[Feature: Client-Server]", func() { serverCrtPath = f.WriteTempFile("server.crt", string(artifacts.Cert)) serverKeyPath = f.WriteTempFile("server.key", string(artifacts.Key)) generator.SetCA(artifacts.CACert, artifacts.CAKey) - generator.Generate("example.com") + _, err = generator.Generate("example.com") + framework.ExpectNoError(err) clientCrtPath = f.WriteTempFile("client.crt", string(artifacts.Cert)) clientKeyPath = f.WriteTempFile("client.key", string(artifacts.Key)) }) - It("mutual authentication", func() { + ginkgo.It("mutual authentication", func() { runClientServerTest(f, &generalTestConfigures{ server: fmt.Sprintf(` tls_cert_file = %s @@ -213,7 +220,7 @@ var _ = Describe("[Feature: Client-Server]", func() { }) }) - It("mutual authentication with incorrect server name", func() { + ginkgo.It("mutual authentication with incorrect server name", func() { runClientServerTest(f, &generalTestConfigures{ server: fmt.Sprintf(` tls_cert_file = %s @@ -232,15 +239,14 @@ var _ = Describe("[Feature: Client-Server]", func() { }) }) - Describe("TLS with disable_custom_tls_first_byte", func() { - supportProtocols := []string{"tcp", "kcp", "websocket"} + ginkgo.Describe("TLS with disable_custom_tls_first_byte", func() { + supportProtocols := []string{"tcp", "kcp", "quic", "websocket"} for _, protocol := range supportProtocols { tmp := protocol defineClientServerTest("TLS over "+strings.ToUpper(tmp), f, &generalTestConfigures{ server: fmt.Sprintf(` - kcp_bind_port = {{ .%s }} - protocol = %s - `, consts.PortServerName, protocol), + %s + `, renderBindPortConfig(protocol)), client: fmt.Sprintf(` tls_enable = true protocol = %s @@ -250,16 +256,15 @@ var _ = Describe("[Feature: Client-Server]", func() { } }) - Describe("IPv6 bind address", func() { - supportProtocols := []string{"tcp", "kcp", "websocket"} + ginkgo.Describe("IPv6 bind address", func() { + supportProtocols := []string{"tcp", "kcp", "quic", "websocket"} for _, protocol := range supportProtocols { tmp := protocol defineClientServerTest("IPv6 bind address: "+strings.ToUpper(tmp), f, &generalTestConfigures{ server: fmt.Sprintf(` bind_addr = :: - kcp_bind_port = {{ .%s }} - protocol = %s - `, consts.PortServerName, protocol), + %s + `, renderBindPortConfig(protocol)), client: fmt.Sprintf(` tls_enable = true protocol = %s diff --git a/test/e2e/basic/cmd.go b/test/e2e/basic/cmd.go index 562310fdf0e..bf8f2467cbe 100644 --- a/test/e2e/basic/cmd.go +++ b/test/e2e/basic/cmd.go @@ -5,21 +5,21 @@ import ( "strconv" "strings" + "github.com/onsi/ginkgo" + "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/pkg/request" - - . "github.com/onsi/ginkgo" ) const ( ConfigValidStr = "syntax is ok" ) -var _ = Describe("[Feature: Cmd]", func() { +var _ = ginkgo.Describe("[Feature: Cmd]", func() { f := framework.NewDefaultFramework() - Describe("Verify", func() { - It("frps valid", func() { + ginkgo.Describe("Verify", func() { + ginkgo.It("frps valid", func() { path := f.GenerateConfigFile(` [common] bind_addr = 0.0.0.0 @@ -29,7 +29,7 @@ var _ = Describe("[Feature: Cmd]", func() { framework.ExpectNoError(err) framework.ExpectTrue(strings.Contains(output, ConfigValidStr), "output: %s", output) }) - It("frps invalid", func() { + ginkgo.It("frps invalid", func() { path := f.GenerateConfigFile(` [common] bind_addr = 0.0.0.0 @@ -39,7 +39,7 @@ var _ = Describe("[Feature: Cmd]", func() { framework.ExpectNoError(err) framework.ExpectTrue(!strings.Contains(output, ConfigValidStr), "output: %s", output) }) - It("frpc valid", func() { + ginkgo.It("frpc valid", func() { path := f.GenerateConfigFile(` [common] server_addr = 0.0.0.0 @@ -49,7 +49,7 @@ var _ = Describe("[Feature: Cmd]", func() { framework.ExpectNoError(err) framework.ExpectTrue(strings.Contains(output, ConfigValidStr), "output: %s", output) }) - It("frpc invalid", func() { + ginkgo.It("frpc invalid", func() { path := f.GenerateConfigFile(` [common] server_addr = 0.0.0.0 @@ -62,8 +62,8 @@ var _ = Describe("[Feature: Cmd]", func() { }) }) - Describe("Single proxy", func() { - It("TCP", func() { + ginkgo.Describe("Single proxy", func() { + ginkgo.It("TCP", func() { serverPort := f.AllocPort() _, _, err := f.RunFrps("-t", "123", "-p", strconv.Itoa(serverPort)) framework.ExpectNoError(err) @@ -77,7 +77,7 @@ var _ = Describe("[Feature: Cmd]", func() { framework.NewRequestExpect(f).Port(remotePort).Ensure() }) - It("UDP", func() { + ginkgo.It("UDP", func() { serverPort := f.AllocPort() _, _, err := f.RunFrps("-t", "123", "-p", strconv.Itoa(serverPort)) framework.ExpectNoError(err) @@ -92,7 +92,7 @@ var _ = Describe("[Feature: Cmd]", func() { Port(remotePort).Ensure() }) - It("HTTP", func() { + ginkgo.It("HTTP", func() { serverPort := f.AllocPort() vhostHTTPPort := f.AllocPort() _, _, err := f.RunFrps("-t", "123", "-p", strconv.Itoa(serverPort), "--vhost_http_port", strconv.Itoa(vhostHTTPPort)) diff --git a/test/e2e/basic/config.go b/test/e2e/basic/config.go index d21bc57c9e2..3ea07b306b1 100644 --- a/test/e2e/basic/config.go +++ b/test/e2e/basic/config.go @@ -3,18 +3,18 @@ package basic import ( "fmt" + "github.com/onsi/ginkgo" + "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" "github.com/fatedier/frp/test/e2e/pkg/port" - - . "github.com/onsi/ginkgo" ) -var _ = Describe("[Feature: Config]", func() { +var _ = ginkgo.Describe("[Feature: Config]", func() { f := framework.NewDefaultFramework() - Describe("Template", func() { - It("render by env", func() { + ginkgo.Describe("Template", func() { + ginkgo.It("render by env", func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig @@ -39,8 +39,8 @@ var _ = Describe("[Feature: Config]", func() { }) }) - Describe("Includes", func() { - It("split tcp proxies into different files", func() { + ginkgo.Describe("Includes", func() { + ginkgo.It("split tcp proxies into different files", func() { serverPort := f.AllocPort() serverConfigPath := f.GenerateConfigFile(fmt.Sprintf(` [common] diff --git a/test/e2e/basic/http.go b/test/e2e/basic/http.go index 8fe73594958..0de24abb80e 100644 --- a/test/e2e/basic/http.go +++ b/test/e2e/basic/http.go @@ -6,16 +6,16 @@ import ( "net/url" "strconv" + "github.com/gorilla/websocket" + "github.com/onsi/ginkgo" + "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" "github.com/fatedier/frp/test/e2e/mock/server/httpserver" "github.com/fatedier/frp/test/e2e/pkg/request" - - "github.com/gorilla/websocket" - . "github.com/onsi/ginkgo" ) -var _ = Describe("[Feature: HTTP]", func() { +var _ = ginkgo.Describe("[Feature: HTTP]", func() { f := framework.NewDefaultFramework() getDefaultServerConf := func(vhostHTTPPort int) string { @@ -31,7 +31,7 @@ var _ = Describe("[Feature: HTTP]", func() { ) } - It("HTTP route by locations", func() { + ginkgo.It("HTTP route by locations", func() { vhostHTTPPort := f.AllocPort() serverConf := getDefaultServerConf(vhostHTTPPort) @@ -78,7 +78,7 @@ var _ = Describe("[Feature: HTTP]", func() { } }) - It("HTTP route by HTTP user", func() { + ginkgo.It("HTTP route by HTTP user", func() { vhostHTTPPort := f.AllocPort() serverConf := getDefaultServerConf(vhostHTTPPort) @@ -138,7 +138,7 @@ var _ = Describe("[Feature: HTTP]", func() { Ensure() }) - It("HTTP Basic Auth", func() { + ginkgo.It("HTTP Basic Auth", func() { vhostHTTPPort := f.AllocPort() serverConf := getDefaultServerConf(vhostHTTPPort) @@ -176,7 +176,7 @@ var _ = Describe("[Feature: HTTP]", func() { Ensure() }) - It("Wildcard domain", func() { + ginkgo.It("Wildcard domain", func() { vhostHTTPPort := f.AllocPort() serverConf := getDefaultServerConf(vhostHTTPPort) @@ -212,7 +212,7 @@ var _ = Describe("[Feature: HTTP]", func() { Ensure() }) - It("Subdomain", func() { + ginkgo.It("Subdomain", func() { vhostHTTPPort := f.AllocPort() serverConf := getDefaultServerConf(vhostHTTPPort) serverConf += ` @@ -257,7 +257,7 @@ var _ = Describe("[Feature: HTTP]", func() { Ensure() }) - It("Modify headers", func() { + ginkgo.It("Modify headers", func() { vhostHTTPPort := f.AllocPort() serverConf := getDefaultServerConf(vhostHTTPPort) @@ -265,7 +265,7 @@ var _ = Describe("[Feature: HTTP]", func() { localServer := httpserver.New( httpserver.WithBindPort(localPort), httpserver.WithHandler(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - w.Write([]byte(req.Header.Get("X-From-Where"))) + _, _ = w.Write([]byte(req.Header.Get("X-From-Where"))) })), ) f.RunServer("", localServer) @@ -290,7 +290,7 @@ var _ = Describe("[Feature: HTTP]", func() { Ensure() }) - It("Host Header Rewrite", func() { + ginkgo.It("Host Header Rewrite", func() { vhostHTTPPort := f.AllocPort() serverConf := getDefaultServerConf(vhostHTTPPort) @@ -298,7 +298,7 @@ var _ = Describe("[Feature: HTTP]", func() { localServer := httpserver.New( httpserver.WithBindPort(localPort), httpserver.WithHandler(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - w.Write([]byte(req.Host)) + _, _ = w.Write([]byte(req.Host)) })), ) f.RunServer("", localServer) @@ -322,7 +322,7 @@ var _ = Describe("[Feature: HTTP]", func() { Ensure() }) - It("Websocket protocol", func() { + ginkgo.It("Websocket protocol", func() { vhostHTTPPort := f.AllocPort() serverConf := getDefaultServerConf(vhostHTTPPort) diff --git a/test/e2e/basic/server.go b/test/e2e/basic/server.go index 74b421be5b1..a06f6d13d00 100644 --- a/test/e2e/basic/server.go +++ b/test/e2e/basic/server.go @@ -5,19 +5,19 @@ import ( "net" "strconv" + "github.com/onsi/ginkgo" + "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" "github.com/fatedier/frp/test/e2e/pkg/port" "github.com/fatedier/frp/test/e2e/pkg/request" clientsdk "github.com/fatedier/frp/test/e2e/pkg/sdk/client" - - . "github.com/onsi/ginkgo" ) -var _ = Describe("[Feature: Server Manager]", func() { +var _ = ginkgo.Describe("[Feature: Server Manager]", func() { f := framework.NewDefaultFramework() - It("Ports Whitelist", func() { + ginkgo.It("Ports Whitelist", func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig @@ -80,7 +80,7 @@ var _ = Describe("[Feature: Server Manager]", func() { }).ExpectError(true).Ensure() }) - It("Alloc Random Port", func() { + ginkgo.It("Alloc Random Port", func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig @@ -124,7 +124,7 @@ var _ = Describe("[Feature: Server Manager]", func() { framework.NewRequestExpect(f).Protocol("udp").Port(port).Ensure() }) - It("Port Reuse", func() { + ginkgo.It("Port Reuse", func() { serverConf := consts.DefaultServerConfig // Use same port as PortServer serverConf += fmt.Sprintf(` @@ -145,7 +145,7 @@ var _ = Describe("[Feature: Server Manager]", func() { }).PortName(consts.PortServerName).Ensure() }) - It("healthz", func() { + ginkgo.It("healthz", func() { serverConf := consts.DefaultServerConfig dashboardPort := f.AllocPort() diff --git a/test/e2e/e2e.go b/test/e2e/e2e.go index b392954bf09..6b0d3e01c7d 100644 --- a/test/e2e/e2e.go +++ b/test/e2e/e2e.go @@ -3,12 +3,12 @@ package e2e import ( "testing" - "github.com/fatedier/frp/pkg/util/log" - "github.com/fatedier/frp/test/e2e/framework" - "github.com/onsi/ginkgo" "github.com/onsi/ginkgo/config" "github.com/onsi/gomega" + + "github.com/fatedier/frp/pkg/util/log" + "github.com/fatedier/frp/test/e2e/framework" ) var _ = ginkgo.SynchronizedBeforeSuite(func() []byte { diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go index 2dddb95234c..d1cc6396895 100644 --- a/test/e2e/e2e_test.go +++ b/test/e2e/e2e_test.go @@ -6,15 +6,14 @@ import ( "os" "testing" - "github.com/fatedier/frp/pkg/util/log" - "github.com/fatedier/frp/test/e2e/framework" + _ "github.com/onsi/ginkgo" + "github.com/fatedier/frp/pkg/util/log" // test source _ "github.com/fatedier/frp/test/e2e/basic" _ "github.com/fatedier/frp/test/e2e/features" + "github.com/fatedier/frp/test/e2e/framework" _ "github.com/fatedier/frp/test/e2e/plugin" - - _ "github.com/onsi/ginkgo" ) // handleFlags sets up all flags and parses the command line. diff --git a/test/e2e/examples.go b/test/e2e/examples.go index 6423aec1ede..26eca20b5a9 100644 --- a/test/e2e/examples.go +++ b/test/e2e/examples.go @@ -3,17 +3,17 @@ package e2e import ( "fmt" + "github.com/onsi/ginkgo" + "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" - - . "github.com/onsi/ginkgo" ) -var _ = Describe("[Feature: Example]", func() { +var _ = ginkgo.Describe("[Feature: Example]", func() { f := framework.NewDefaultFramework() - Describe("TCP", func() { - It("Expose a TCP echo server", func() { + ginkgo.Describe("TCP", func() { + ginkgo.It("Expose a TCP echo server", func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig diff --git a/test/e2e/features/bandwidth_limit.go b/test/e2e/features/bandwidth_limit.go index f984fdb9fe3..a912b06a76e 100644 --- a/test/e2e/features/bandwidth_limit.go +++ b/test/e2e/features/bandwidth_limit.go @@ -5,18 +5,18 @@ import ( "strings" "time" + "github.com/onsi/ginkgo" + "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" "github.com/fatedier/frp/test/e2e/mock/server/streamserver" "github.com/fatedier/frp/test/e2e/pkg/request" - - . "github.com/onsi/ginkgo" ) -var _ = Describe("[Feature: Bandwidth Limit]", func() { +var _ = ginkgo.Describe("[Feature: Bandwidth Limit]", func() { f := framework.NewDefaultFramework() - It("Proxy Bandwidth Limit", func() { + ginkgo.It("Proxy Bandwidth Limit", func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig @@ -40,7 +40,7 @@ var _ = Describe("[Feature: Bandwidth Limit]", func() { framework.NewRequestExpect(f).Port(remotePort).RequestModify(func(r *request.Request) { r.Body([]byte(content)).Timeout(30 * time.Second) }).ExpectResp([]byte(content)).Ensure() - duration := time.Now().Sub(start) + duration := time.Since(start) framework.ExpectTrue(duration.Seconds() > 7, "100Kb with 10KB limit, want > 7 seconds, but got %d seconds", duration.Seconds()) }) diff --git a/test/e2e/features/chaos.go b/test/e2e/features/chaos.go index 2049fc77965..bae6eb7de44 100644 --- a/test/e2e/features/chaos.go +++ b/test/e2e/features/chaos.go @@ -4,15 +4,15 @@ import ( "fmt" "time" - "github.com/fatedier/frp/test/e2e/framework" + "github.com/onsi/ginkgo" - . "github.com/onsi/ginkgo" + "github.com/fatedier/frp/test/e2e/framework" ) -var _ = Describe("[Feature: Chaos]", func() { +var _ = ginkgo.Describe("[Feature: Chaos]", func() { f := framework.NewDefaultFramework() - It("reconnect after frps restart", func() { + ginkgo.It("reconnect after frps restart", func() { serverPort := f.AllocPort() serverConfigPath := f.GenerateConfigFile(fmt.Sprintf(` [common] @@ -41,7 +41,7 @@ var _ = Describe("[Feature: Chaos]", func() { framework.NewRequestExpect(f).Port(remotePort).Ensure() // 2. stop frps, expect request failed - ps.Stop() + _ = ps.Stop() time.Sleep(200 * time.Millisecond) framework.NewRequestExpect(f).Port(remotePort).ExpectError(true).Ensure() @@ -52,7 +52,7 @@ var _ = Describe("[Feature: Chaos]", func() { framework.NewRequestExpect(f).Port(remotePort).Ensure() // 4. stop frpc, expect request failed - pc.Stop() + _ = pc.Stop() time.Sleep(200 * time.Millisecond) framework.NewRequestExpect(f).Port(remotePort).ExpectError(true).Ensure() diff --git a/test/e2e/features/group.go b/test/e2e/features/group.go index ea6b781fd89..f36e75b26b4 100644 --- a/test/e2e/features/group.go +++ b/test/e2e/features/group.go @@ -6,16 +6,16 @@ import ( "sync" "time" + "github.com/onsi/ginkgo" + "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" "github.com/fatedier/frp/test/e2e/mock/server/httpserver" "github.com/fatedier/frp/test/e2e/mock/server/streamserver" "github.com/fatedier/frp/test/e2e/pkg/request" - - . "github.com/onsi/ginkgo" ) -var _ = Describe("[Feature: Group]", func() { +var _ = ginkgo.Describe("[Feature: Group]", func() { f := framework.NewDefaultFramework() newHTTPServer := func(port int, respContent string) *httpserver.Server { @@ -60,8 +60,8 @@ var _ = Describe("[Feature: Group]", func() { return results } - Describe("Load Balancing", func() { - It("TCP", func() { + ginkgo.Describe("Load Balancing", func() { + ginkgo.It("TCP", func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig @@ -112,8 +112,8 @@ var _ = Describe("[Feature: Group]", func() { }) }) - Describe("Health Check", func() { - It("TCP", func() { + ginkgo.Describe("Health Check", func() { + ginkgo.It("TCP", func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig @@ -178,7 +178,7 @@ var _ = Describe("[Feature: Group]", func() { framework.ExpectContainElements(results, []string{"foo", "bar"}) }) - It("HTTP", func() { + ginkgo.It("HTTP", func() { vhostPort := f.AllocPort() serverConf := consts.DefaultServerConfig + fmt.Sprintf(` vhost_http_port = %d @@ -217,6 +217,29 @@ var _ = Describe("[Feature: Group]", func() { f.RunProcesses([]string{serverConf}, []string{clientConf}) + // send first HTTP request + var contents []string + framework.NewRequestExpect(f).Port(vhostPort). + RequestModify(func(r *request.Request) { + r.HTTP().HTTPHost("example.com") + }). + Ensure(func(resp *request.Response) bool { + contents = append(contents, string(resp.Content)) + return true + }) + + // send second HTTP request, should be forwarded to another service + framework.NewRequestExpect(f).Port(vhostPort). + RequestModify(func(r *request.Request) { + r.HTTP().HTTPHost("example.com") + }). + Ensure(func(resp *request.Response) bool { + contents = append(contents, string(resp.Content)) + return true + }) + + framework.ExpectContainElements(contents, []string{"foo", "bar"}) + // check foo and bar is ok results := doFooBarHTTPRequest(vhostPort, "example.com") framework.ExpectContainElements(results, []string{"foo", "bar"}) diff --git a/test/e2e/features/heartbeat.go b/test/e2e/features/heartbeat.go index b0732c37f00..3ffbd83466b 100644 --- a/test/e2e/features/heartbeat.go +++ b/test/e2e/features/heartbeat.go @@ -4,15 +4,15 @@ import ( "fmt" "time" - "github.com/fatedier/frp/test/e2e/framework" + "github.com/onsi/ginkgo" - . "github.com/onsi/ginkgo" + "github.com/fatedier/frp/test/e2e/framework" ) -var _ = Describe("[Feature: Heartbeat]", func() { +var _ = ginkgo.Describe("[Feature: Heartbeat]", func() { f := framework.NewDefaultFramework() - It("disable application layer heartbeat", func() { + ginkgo.It("disable application layer heartbeat", func() { serverPort := f.AllocPort() serverConf := fmt.Sprintf(` [common] diff --git a/test/e2e/features/monitor.go b/test/e2e/features/monitor.go index d8b656a87d0..bf074e66041 100644 --- a/test/e2e/features/monitor.go +++ b/test/e2e/features/monitor.go @@ -5,18 +5,18 @@ import ( "strings" "time" + "github.com/onsi/ginkgo" + "github.com/fatedier/frp/pkg/util/log" "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" "github.com/fatedier/frp/test/e2e/pkg/request" - - . "github.com/onsi/ginkgo" ) -var _ = Describe("[Feature: Monitor]", func() { +var _ = ginkgo.Describe("[Feature: Monitor]", func() { f := framework.NewDefaultFramework() - It("Prometheus metrics", func() { + ginkgo.It("Prometheus metrics", func() { dashboardPort := f.AllocPort() serverConf := consts.DefaultServerConfig + fmt.Sprintf(` enable_prometheus = true diff --git a/test/e2e/features/real_ip.go b/test/e2e/features/real_ip.go index 424d4049eb1..3a2a7e40bfd 100644 --- a/test/e2e/features/real_ip.go +++ b/test/e2e/features/real_ip.go @@ -6,6 +6,9 @@ import ( "net" "net/http" + "github.com/onsi/ginkgo" + pp "github.com/pires/go-proxyproto" + "github.com/fatedier/frp/pkg/util/log" "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" @@ -13,15 +16,12 @@ import ( "github.com/fatedier/frp/test/e2e/mock/server/streamserver" "github.com/fatedier/frp/test/e2e/pkg/request" "github.com/fatedier/frp/test/e2e/pkg/rpc" - - . "github.com/onsi/ginkgo" - pp "github.com/pires/go-proxyproto" ) -var _ = Describe("[Feature: Real IP]", func() { +var _ = ginkgo.Describe("[Feature: Real IP]", func() { f := framework.NewDefaultFramework() - It("HTTP X-Forwarded-For", func() { + ginkgo.It("HTTP X-Forwarded-For", func() { vhostHTTPPort := f.AllocPort() serverConf := consts.DefaultServerConfig + fmt.Sprintf(` vhost_http_port = %d @@ -31,7 +31,7 @@ var _ = Describe("[Feature: Real IP]", func() { localServer := httpserver.New( httpserver.WithBindPort(localPort), httpserver.WithHandler(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - w.Write([]byte(req.Header.Get("X-Forwarded-For"))) + _, _ = w.Write([]byte(req.Header.Get("X-Forwarded-For"))) })), ) f.RunServer("", localServer) @@ -52,11 +52,10 @@ var _ = Describe("[Feature: Real IP]", func() { }). ExpectResp([]byte("127.0.0.1")). Ensure() - }) - Describe("Proxy Protocol", func() { - It("TCP", func() { + ginkgo.Describe("Proxy Protocol", func() { + ginkgo.It("TCP", func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig @@ -77,7 +76,7 @@ var _ = Describe("[Feature: Real IP]", func() { } buf := []byte(ppHeader.SourceAddr.String()) - rpc.WriteBytes(c, buf) + _, _ = rpc.WriteBytes(c, buf) } })) f.RunServer("", localServer) @@ -106,7 +105,7 @@ var _ = Describe("[Feature: Real IP]", func() { }) }) - It("HTTP", func() { + ginkgo.It("HTTP", func() { vhostHTTPPort := f.AllocPort() serverConf := consts.DefaultServerConfig + fmt.Sprintf(` vhost_http_port = %d diff --git a/test/e2e/framework/cleanup.go b/test/e2e/framework/cleanup.go index d2d1c5a6ce3..15e1a9dd4b9 100644 --- a/test/e2e/framework/cleanup.go +++ b/test/e2e/framework/cleanup.go @@ -6,13 +6,16 @@ import ( // CleanupActionHandle is an integer pointer type for handling cleanup action type CleanupActionHandle *int + type cleanupFuncHandle struct { actionHandle CleanupActionHandle actionHook func() } -var cleanupActionsLock sync.Mutex -var cleanupHookList = []cleanupFuncHandle{} +var ( + cleanupActionsLock sync.Mutex + cleanupHookList = []cleanupFuncHandle{} +) // AddCleanupAction installs a function that will be called in the event of the // whole test being terminated. This allows arbitrary pieces of the overall diff --git a/test/e2e/framework/consts/consts.go b/test/e2e/framework/consts/consts.go index d38e183daed..622eba924b0 100644 --- a/test/e2e/framework/consts/consts.go +++ b/test/e2e/framework/consts/consts.go @@ -25,6 +25,7 @@ var ( DefaultClientConfig = ` [common] + server_addr = 127.0.0.1 server_port = {{ .%s }} log_level = trace ` diff --git a/test/e2e/framework/framework.go b/test/e2e/framework/framework.go index 344f64c3ab9..c22c6af75f6 100644 --- a/test/e2e/framework/framework.go +++ b/test/e2e/framework/framework.go @@ -9,12 +9,12 @@ import ( "strings" "text/template" + "github.com/onsi/ginkgo" + "github.com/onsi/ginkgo/config" + "github.com/fatedier/frp/test/e2e/mock/server" "github.com/fatedier/frp/test/e2e/pkg/port" "github.com/fatedier/frp/test/e2e/pkg/process" - - "github.com/onsi/ginkgo" - "github.com/onsi/ginkgo/config" ) type Options struct { @@ -102,7 +102,8 @@ func (f *Framework) BeforeEach() { for k, v := range params { switch t := v.(type) { case int: - f.usedPorts[k] = int(t) + f.usedPorts[k] = t + default: } } } @@ -116,14 +117,14 @@ func (f *Framework) AfterEach() { // stop processor for _, p := range f.serverProcesses { - p.Stop() + _ = p.Stop() if TestContext.Debug { fmt.Println(p.ErrorOutput()) fmt.Println(p.StdOutput()) } } for _, p := range f.clientProcesses { - p.Stop() + _ = p.Stop() if TestContext.Debug { fmt.Println(p.ErrorOutput()) fmt.Println(p.StdOutput()) @@ -259,7 +260,7 @@ func (f *Framework) SetEnvs(envs []string) { func (f *Framework) WriteTempFile(name string, content string) string { filePath := filepath.Join(f.TempDirectory, name) - err := os.WriteFile(filePath, []byte(content), 0766) + err := os.WriteFile(filePath, []byte(content), 0o766) ExpectNoError(err) return filePath } diff --git a/test/e2e/framework/log.go b/test/e2e/framework/log.go index ff33f41dbe0..34ba2936b36 100644 --- a/test/e2e/framework/log.go +++ b/test/e2e/framework/log.go @@ -58,16 +58,17 @@ var codeFilterRE = regexp.MustCompile(`/github.com/onsi/ginkgo/`) // From the remaining entries it automatically filters out useless ones like // entries coming from Ginkgo. // -// This is a modified copy of PruneStack in https://github.com/onsi/ginkgo/blob/f90f37d87fa6b1dd9625e2b1e83c23ffae3de228/internal/codelocation/code_location.go#L25: -// - simplified API and thus renamed (calls debug.Stack() instead of taking a parameter) -// - source code filtering updated to be specific to Kubernetes -// - optimized to use bytes and in-place slice filtering from -// https://github.com/golang/go/wiki/SliceTricks#filter-in-place +// This is a modified copy of PruneStack in +// https://github.com/onsi/ginkgo/blob/f90f37d87fa6b1dd9625e2b1e83c23ffae3de228/internal/codelocation/code_location.go#L25: +// - simplified API and thus renamed (calls debug.Stack() instead of taking a parameter) +// - source code filtering updated to be specific to Kubernetes +// - optimized to use bytes and in-place slice filtering from +// https://github.com/golang/go/wiki/SliceTricks#filter-in-place func PrunedStack(skip int) []byte { fullStackTrace := debug.Stack() stack := bytes.Split(fullStackTrace, []byte("\n")) // Ensure that the even entries are the method names and the - // the odd entries the source code information. + // odd entries the source code information. if len(stack) > 0 && bytes.HasPrefix(stack[0], []byte("goroutine ")) { // Ignore "goroutine 29 [running]:" line. stack = stack[1:] @@ -82,7 +83,7 @@ func PrunedStack(skip int) []byte { n := 0 for i := 0; i < len(stack)/2; i++ { // We filter out based on the source code file name. - if !codeFilterRE.Match([]byte(stack[i*2+1])) { + if !codeFilterRE.Match(stack[i*2+1]) { stack[n] = stack[i*2] stack[n+1] = stack[i*2+1] n += 2 diff --git a/test/e2e/framework/mockservers.go b/test/e2e/framework/mockservers.go index af41ab90baf..32f7ac38b69 100644 --- a/test/e2e/framework/mockservers.go +++ b/test/e2e/framework/mockservers.go @@ -33,9 +33,11 @@ func NewMockServers(portAllocator *port.Allocator) *MockServers { httpPort := portAllocator.Get() s.tcpEchoServer = streamserver.New(streamserver.TCP, streamserver.WithBindPort(tcpPort)) s.udpEchoServer = streamserver.New(streamserver.UDP, streamserver.WithBindPort(udpPort)) - s.httpSimpleServer = httpserver.New(httpserver.WithBindPort(httpPort), httpserver.WithHandler(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - w.Write([]byte(consts.TestString)) - }))) + s.httpSimpleServer = httpserver.New(httpserver.WithBindPort(httpPort), + httpserver.WithHandler(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + _, _ = w.Write([]byte(consts.TestString)) + })), + ) udsIndex := portAllocator.Get() udsAddr := fmt.Sprintf("%s/frp_echo_server_%d.sock", os.TempDir(), udsIndex) diff --git a/test/e2e/framework/process.go b/test/e2e/framework/process.go index 32ef2f8424c..7c328dd4725 100644 --- a/test/e2e/framework/process.go +++ b/test/e2e/framework/process.go @@ -14,12 +14,8 @@ import ( // The first template should always be frps. 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) - } - for _, t := range clientTemplates { - templates = append(templates, t) - } + templates = append(templates, serverTemplates...) + templates = append(templates, clientTemplates...) outs, ports, err := f.RenderTemplates(templates) ExpectNoError(err) ExpectTrue(len(templates) > 0) @@ -31,7 +27,7 @@ func (f *Framework) RunProcesses(serverTemplates []string, clientTemplates []str 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) + err = os.WriteFile(path, []byte(outs[i]), 0o666) ExpectNoError(err) flog.Trace("[%s] %s", path, outs[i]) @@ -48,7 +44,7 @@ func (f *Framework) RunProcesses(serverTemplates []string, clientTemplates []str for i := range clientTemplates { index := i + len(serverTemplates) path := filepath.Join(f.TempDirectory, fmt.Sprintf("frp-e2e-client-%d", i)) - err = os.WriteFile(path, []byte(outs[index]), 0666) + err = os.WriteFile(path, []byte(outs[index]), 0o666) ExpectNoError(err) flog.Trace("[%s] %s", path, outs[index]) @@ -60,7 +56,7 @@ func (f *Framework) RunProcesses(serverTemplates []string, clientTemplates []str ExpectNoError(err) time.Sleep(500 * time.Millisecond) } - time.Sleep(time.Second) + time.Sleep(2 * time.Second) return currentServerProcesses, currentClientProcesses } @@ -91,7 +87,7 @@ func (f *Framework) RunFrpc(args ...string) (*process.Process, string, error) { func (f *Framework) GenerateConfigFile(content string) string { f.configFileIndex++ path := filepath.Join(f.TempDirectory, fmt.Sprintf("frp-e2e-config-%d", f.configFileIndex)) - err := os.WriteFile(path, []byte(content), 0666) + err := os.WriteFile(path, []byte(content), 0o666) ExpectNoError(err) return path } diff --git a/test/e2e/framework/request.go b/test/e2e/framework/request.go index 5dccd661e4c..6b75a2593ad 100644 --- a/test/e2e/framework/request.go +++ b/test/e2e/framework/request.go @@ -11,7 +11,7 @@ import ( func SpecifiedHTTPBodyHandler(body []byte) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { - w.Write(body) + _, _ = w.Write(body) } } diff --git a/test/e2e/framework/test_context.go b/test/e2e/framework/test_context.go index 958c78f8d7b..42a66445dd9 100644 --- a/test/e2e/framework/test_context.go +++ b/test/e2e/framework/test_context.go @@ -24,7 +24,6 @@ var TestContext TestContextType // The other Register*Flags methods below can be used to add more // test-specific flags. However, those settings then get added // regardless whether the test is actually in the test suite. -// func RegisterCommonFlags(flags *flag.FlagSet) { // Turn on EmitSpecProgress to get spec progress (especially on interrupt) config.GinkgoConfig.EmitSpecProgress = true diff --git a/test/e2e/mock/server/httpserver/server.go b/test/e2e/mock/server/httpserver/server.go index a811ac2700a..f9818a0db80 100644 --- a/test/e2e/mock/server/httpserver/server.go +++ b/test/e2e/mock/server/httpserver/server.go @@ -5,6 +5,7 @@ import ( "net" "net/http" "strconv" + "time" ) type Server struct { @@ -44,7 +45,7 @@ func WithBindPort(port int) Option { } } -func WithTlsConfig(tlsConfig *tls.Config) Option { +func WithTLSConfig(tlsConfig *tls.Config) Option { return func(s *Server) *Server { s.tlsConfig = tlsConfig return s @@ -61,7 +62,7 @@ func WithHandler(h http.Handler) Option { func WithResponse(resp []byte) Option { return func(s *Server) *Server { s.handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write(resp) + _, _ = w.Write(resp) }) return s } @@ -74,16 +75,21 @@ func (s *Server) Run() error { addr := net.JoinHostPort(s.bindAddr, strconv.Itoa(s.bindPort)) hs := &http.Server{ - Addr: addr, - Handler: s.handler, - TLSConfig: s.tlsConfig, + Addr: addr, + Handler: s.handler, + TLSConfig: s.tlsConfig, + ReadHeaderTimeout: time.Minute, } s.hs = hs if s.tlsConfig == nil { - go hs.Serve(s.l) + go func() { + _ = hs.Serve(s.l) + }() } else { - go hs.ServeTLS(s.l, "", "") + go func() { + _ = hs.ServeTLS(s.l, "", "") + }() } return nil } diff --git a/test/e2e/mock/server/streamserver/server.go b/test/e2e/mock/server/streamserver/server.go index 1dde353a9db..9e237d96fba 100644 --- a/test/e2e/mock/server/streamserver/server.go +++ b/test/e2e/mock/server/streamserver/server.go @@ -127,7 +127,7 @@ func (s *Server) handle(c net.Conn) { if len(s.respContent) > 0 { buf = s.respContent } - rpc.WriteBytes(c, buf) + _, _ = rpc.WriteBytes(c, buf) } } diff --git a/test/e2e/pkg/cert/generator.go b/test/e2e/pkg/cert/generator.go index 5c11b226d1e..fb22522bec0 100644 --- a/test/e2e/pkg/cert/generator.go +++ b/test/e2e/pkg/cert/generator.go @@ -22,8 +22,8 @@ type Artifacts struct { ResourceVersion string } -// CertGenerator is an interface to provision the serving certificate. -type CertGenerator interface { +// Generator is an interface to provision the serving certificate. +type Generator interface { // Generate returns a Artifacts struct. Generate(CommonName string) (*Artifacts, error) // SetCA sets the PEM-encoded CA private key and CA cert for signing the generated serving cert. diff --git a/test/e2e/pkg/cert/selfsigned.go b/test/e2e/pkg/cert/selfsigned.go index 4f9ed57378a..82762d0990c 100644 --- a/test/e2e/pkg/cert/selfsigned.go +++ b/test/e2e/pkg/cert/selfsigned.go @@ -23,7 +23,7 @@ type SelfSignedCertGenerator struct { caCert []byte } -var _ CertGenerator = &SelfSignedCertGenerator{} +var _ Generator = &SelfSignedCertGenerator{} // SetCA sets the PEM-encoded CA private key and CA cert for signing the generated serving cert. func (cp *SelfSignedCertGenerator) SetCA(caKey, caCert []byte) { diff --git a/test/e2e/pkg/port/util.go b/test/e2e/pkg/port/util.go index 9cf1204f5e7..073bf3c7787 100644 --- a/test/e2e/pkg/port/util.go +++ b/test/e2e/pkg/port/util.go @@ -26,16 +26,17 @@ func unmarshalFromName(name string) (*nameBuilder, error) { builder.name = arrs[1] case 4: builder.name = arrs[1] - if fromPort, err := strconv.Atoi(arrs[2]); err != nil { + fromPort, err := strconv.Atoi(arrs[2]) + if err != nil { return nil, fmt.Errorf("error range port from") - } else { - builder.rangePortFrom = fromPort } - if toPort, err := strconv.Atoi(arrs[3]); err != nil { + builder.rangePortFrom = fromPort + + toPort, err := strconv.Atoi(arrs[3]) + if err != nil { return nil, fmt.Errorf("error range port to") - } else { - builder.rangePortTo = toPort } + builder.rangePortTo = toPort default: return nil, fmt.Errorf("error port name format") } diff --git a/test/e2e/pkg/request/request.go b/test/e2e/pkg/request/request.go index cf6352f3828..96e714f9e26 100644 --- a/test/e2e/pkg/request/request.go +++ b/test/e2e/pkg/request/request.go @@ -12,9 +12,10 @@ import ( "strconv" "time" + libdial "github.com/fatedier/golib/net/dial" + "github.com/fatedier/frp/test/e2e/pkg/rpc" "github.com/fatedier/frp/test/e2e/pkg/utils" - libdial "github.com/fatedier/golib/net/dial" ) type Request struct { @@ -181,7 +182,7 @@ func (r *Request) Do() (*Response, error) { defer conn.Close() if r.timeout > 0 { - conn.SetDeadline(time.Now().Add(r.timeout)) + _ = conn.SetDeadline(time.Now().Add(r.timeout)) } buf, err := r.sendRequestByConn(conn, r.body) if err != nil { @@ -199,7 +200,6 @@ type Response struct { func (r *Request) sendHTTPRequest(method, urlstr string, host string, headers map[string]string, proxy string, body []byte, tlsConfig *tls.Config, ) (*Response, error) { - var inBody io.Reader if len(body) != 0 { inBody = bytes.NewReader(body) @@ -240,6 +240,7 @@ func (r *Request) sendHTTPRequest(method, urlstr string, host string, headers ma if err != nil { return nil, err } + defer resp.Body.Close() ret := &Response{Code: resp.StatusCode, Header: resp.Header} buf, err := io.ReadAll(resp.Body) diff --git a/test/e2e/pkg/rpc/rpc.go b/test/e2e/pkg/rpc/rpc.go index ee3aef56f22..d6026449d55 100644 --- a/test/e2e/pkg/rpc/rpc.go +++ b/test/e2e/pkg/rpc/rpc.go @@ -9,7 +9,10 @@ import ( func WriteBytes(w io.Writer, buf []byte) (int, error) { out := bytes.NewBuffer(nil) - binary.Write(out, binary.BigEndian, int64(len(buf))) + if err := binary.Write(out, binary.BigEndian, int64(len(buf))); err != nil { + return 0, err + } + out.Write(buf) return w.Write(out.Bytes()) } diff --git a/test/e2e/plugin/client.go b/test/e2e/plugin/client.go index afbd0a2c7fd..081c88ff541 100644 --- a/test/e2e/plugin/client.go +++ b/test/e2e/plugin/client.go @@ -5,6 +5,8 @@ import ( "fmt" "strconv" + "github.com/onsi/ginkgo" + "github.com/fatedier/frp/pkg/transport" "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" @@ -12,15 +14,13 @@ import ( "github.com/fatedier/frp/test/e2e/pkg/cert" "github.com/fatedier/frp/test/e2e/pkg/port" "github.com/fatedier/frp/test/e2e/pkg/request" - - . "github.com/onsi/ginkgo" ) -var _ = Describe("[Feature: Client-Plugins]", func() { +var _ = ginkgo.Describe("[Feature: Client-Plugins]", func() { f := framework.NewDefaultFramework() - Describe("UnixDomainSocket", func() { - It("Expose a unix domain socket echo server", func() { + ginkgo.Describe("UnixDomainSocket", func() { + ginkgo.It("Expose a unix domain socket echo server", func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig @@ -76,7 +76,7 @@ var _ = Describe("[Feature: Client-Plugins]", func() { }) }) - It("http_proxy", func() { + ginkgo.It("http_proxy", func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig @@ -108,7 +108,7 @@ var _ = Describe("[Feature: Client-Plugins]", func() { }) }) - It("socks5 proxy", func() { + ginkgo.It("socks5 proxy", func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig @@ -135,7 +135,7 @@ var _ = Describe("[Feature: Client-Plugins]", func() { }).Ensure() }) - It("static_file", func() { + ginkgo.It("static_file", func() { vhostPort := f.AllocPort() serverConf := consts.DefaultServerConfig + fmt.Sprintf(` vhost_http_port = %d @@ -184,7 +184,7 @@ var _ = Describe("[Feature: Client-Plugins]", func() { ).ExpectResp([]byte("foo")).Ensure() }) - It("http2https", func() { + ginkgo.It("http2https", func() { serverConf := consts.DefaultServerConfig vhostHTTPPort := f.AllocPort() serverConf += fmt.Sprintf(` @@ -206,7 +206,7 @@ var _ = Describe("[Feature: Client-Plugins]", func() { framework.ExpectNoError(err) localServer := httpserver.New( httpserver.WithBindPort(localPort), - httpserver.WithTlsConfig(tlsConfig), + httpserver.WithTLSConfig(tlsConfig), httpserver.WithResponse([]byte("test")), ) f.RunServer("", localServer) @@ -220,7 +220,7 @@ var _ = Describe("[Feature: Client-Plugins]", func() { Ensure() }) - It("https2http", func() { + ginkgo.It("https2http", func() { generator := &cert.SelfSignedCertGenerator{} artifacts, err := generator.Generate("example.com") framework.ExpectNoError(err) @@ -264,7 +264,7 @@ var _ = Describe("[Feature: Client-Plugins]", func() { Ensure() }) - It("https2https", func() { + ginkgo.It("https2https", func() { generator := &cert.SelfSignedCertGenerator{} artifacts, err := generator.Generate("example.com") framework.ExpectNoError(err) @@ -295,7 +295,7 @@ var _ = Describe("[Feature: Client-Plugins]", func() { localServer := httpserver.New( httpserver.WithBindPort(localPort), httpserver.WithResponse([]byte("test")), - httpserver.WithTlsConfig(tlsConfig), + httpserver.WithTLSConfig(tlsConfig), ) f.RunServer("", localServer) diff --git a/test/e2e/plugin/server.go b/test/e2e/plugin/server.go index 2af1eba8496..e4619573a7e 100644 --- a/test/e2e/plugin/server.go +++ b/test/e2e/plugin/server.go @@ -4,25 +4,25 @@ import ( "fmt" "time" + "github.com/onsi/ginkgo" + plugin "github.com/fatedier/frp/pkg/plugin/server" "github.com/fatedier/frp/pkg/transport" "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" - - . "github.com/onsi/ginkgo" ) -var _ = Describe("[Feature: Server-Plugins]", func() { +var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { f := framework.NewDefaultFramework() - Describe("Login", func() { + ginkgo.Describe("Login", func() { newFunc := func() *plugin.Request { var r plugin.Request r.Content = &plugin.LoginContent{} return &r } - It("Auth for custom meta token", func() { + ginkgo.It("Auth for custom meta token", func() { localPort := f.AllocPort() clientAddressGot := false @@ -79,14 +79,14 @@ var _ = Describe("[Feature: Server-Plugins]", func() { }) }) - Describe("NewProxy", func() { + ginkgo.Describe("NewProxy", func() { newFunc := func() *plugin.Request { var r plugin.Request r.Content = &plugin.NewProxyContent{} return &r } - It("Validate Info", func() { + ginkgo.It("Validate Info", func() { localPort := f.AllocPort() handler := func(req *plugin.Request) *plugin.Response { var ret plugin.Response @@ -123,7 +123,7 @@ var _ = Describe("[Feature: Server-Plugins]", func() { framework.NewRequestExpect(f).Port(remotePort).Ensure() }) - It("Mofify RemotePort", func() { + ginkgo.It("Mofify RemotePort", func() { localPort := f.AllocPort() remotePort := f.AllocPort() handler := func(req *plugin.Request) *plugin.Response { @@ -158,14 +158,14 @@ var _ = Describe("[Feature: Server-Plugins]", func() { }) }) - Describe("CloseProxy", func() { + ginkgo.Describe("CloseProxy", func() { newFunc := func() *plugin.Request { var r plugin.Request r.Content = &plugin.CloseProxyContent{} return &r } - It("Validate Info", func() { + ginkgo.It("Validate Info", func() { localPort := f.AllocPort() var recordProxyName string handler := func(req *plugin.Request) *plugin.Response { @@ -199,7 +199,7 @@ var _ = Describe("[Feature: Server-Plugins]", func() { framework.NewRequestExpect(f).Port(remotePort).Ensure() for _, c := range clients { - c.Stop() + _ = c.Stop() } time.Sleep(1 * time.Second) @@ -208,14 +208,14 @@ var _ = Describe("[Feature: Server-Plugins]", func() { }) }) - Describe("Ping", func() { + ginkgo.Describe("Ping", func() { newFunc := func() *plugin.Request { var r plugin.Request r.Content = &plugin.PingContent{} return &r } - It("Validate Info", func() { + ginkgo.It("Validate Info", func() { localPort := f.AllocPort() var record string @@ -258,14 +258,14 @@ var _ = Describe("[Feature: Server-Plugins]", func() { }) }) - Describe("NewWorkConn", func() { + ginkgo.Describe("NewWorkConn", func() { newFunc := func() *plugin.Request { var r plugin.Request r.Content = &plugin.NewWorkConnContent{} return &r } - It("Validate Info", func() { + ginkgo.It("Validate Info", func() { localPort := f.AllocPort() var record string @@ -304,13 +304,13 @@ var _ = Describe("[Feature: Server-Plugins]", func() { }) }) - Describe("NewUserConn", func() { + ginkgo.Describe("NewUserConn", func() { newFunc := func() *plugin.Request { var r plugin.Request r.Content = &plugin.NewUserConnContent{} return &r } - It("Validate Info", func() { + ginkgo.It("Validate Info", func() { localPort := f.AllocPort() var record string @@ -349,13 +349,13 @@ var _ = Describe("[Feature: Server-Plugins]", func() { }) }) - Describe("HTTPS Protocol", func() { + ginkgo.Describe("HTTPS Protocol", func() { newFunc := func() *plugin.Request { var r plugin.Request r.Content = &plugin.NewUserConnContent{} return &r } - It("Validate Login Info, disable tls verify", func() { + ginkgo.It("Validate Login Info, disable tls verify", func() { localPort := f.AllocPort() var record string diff --git a/test/e2e/plugin/utils.go b/test/e2e/plugin/utils.go index c0d7db3d3db..51de01d9383 100644 --- a/test/e2e/plugin/utils.go +++ b/test/e2e/plugin/utils.go @@ -11,14 +11,14 @@ import ( "github.com/fatedier/frp/test/e2e/mock/server/httpserver" ) -type PluginHandler func(req *plugin.Request) *plugin.Response +type Handler func(req *plugin.Request) *plugin.Response type NewPluginRequest func() *plugin.Request -func NewHTTPPluginServer(port int, newFunc NewPluginRequest, handler PluginHandler, tlsConfig *tls.Config) *httpserver.Server { +func NewHTTPPluginServer(port int, newFunc NewPluginRequest, handler Handler, tlsConfig *tls.Config) *httpserver.Server { return httpserver.New( httpserver.WithBindPort(port), - httpserver.WithTlsConfig(tlsConfig), + httpserver.WithTLSConfig(tlsConfig), httpserver.WithHandler(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { r := newFunc() buf, err := io.ReadAll(req.Body) @@ -35,7 +35,7 @@ func NewHTTPPluginServer(port int, newFunc NewPluginRequest, handler PluginHandl resp := handler(r) buf, _ = json.Marshal(resp) log.Trace("plugin response: %s", string(buf)) - w.Write(buf) + _, _ = w.Write(buf) })), ) }