mirror of
https://github.com/fatedier/frp.git
synced 2025-05-09 16:18:27 +00:00
commit
1e650ea9a7
.circleci
.github/workflows
.golangci.ymlMakefileREADME.mdREADME_zh.mdRelease.mdassets/frps/static
client
cmd
conf
doc/pic
dockerfiles
go.modgo.sumpkg
auth
config
legacy
types
v1
metrics/mem
msg
nathole
plugin
ssh
util
server
test/e2e
@ -2,24 +2,15 @@ version: 2
|
||||
jobs:
|
||||
go-version-latest:
|
||||
docker:
|
||||
- image: cimg/go:1.21-node
|
||||
- image: cimg/go:1.22-node
|
||||
resource_class: large
|
||||
steps:
|
||||
- checkout
|
||||
- run: make
|
||||
- run: make alltest
|
||||
go-version-last:
|
||||
docker:
|
||||
- image: cimg/go:1.20-node
|
||||
resource_class: large
|
||||
steps:
|
||||
- checkout
|
||||
- run: make
|
||||
- run: make alltest
|
||||
- checkout
|
||||
- run: make
|
||||
- run: make alltest
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
build_and_test:
|
||||
jobs:
|
||||
- go-version-latest
|
||||
- go-version-last
|
||||
- go-version-latest
|
||||
|
12
.github/workflows/build-and-push-image.yml
vendored
12
.github/workflows/build-and-push-image.yml
vendored
@ -19,15 +19,15 @@ jobs:
|
||||
steps:
|
||||
# environment
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: '0'
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
# get image tag name
|
||||
- name: Get Image Tag Name
|
||||
@ -38,13 +38,13 @@ jobs:
|
||||
echo "TAG_NAME=${{ github.event.inputs.tag }}" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v2
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Login to the GPR
|
||||
uses: docker/login-action@v2
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
@ -72,7 +72,7 @@ jobs:
|
||||
${{ env.TAG_FRPC_GPR }}
|
||||
|
||||
- name: Build and push frps
|
||||
uses: docker/build-push-action@v4
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: ./dockerfiles/Dockerfile-for-frps
|
||||
|
41
.github/workflows/golangci-lint.yml
vendored
41
.github/workflows/golangci-lint.yml
vendored
@ -14,28 +14,29 @@ jobs:
|
||||
name: lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.21'
|
||||
- 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.55
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22'
|
||||
cache: false
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v4
|
||||
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.56
|
||||
|
||||
# Optional: golangci-lint command line arguments.
|
||||
# args: --issues-exit-code=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: 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 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 ~/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
|
||||
# Optional: if set to true then the action don't cache or restore ~/.cache/go-build.
|
||||
# skip-build-cache: true
|
||||
|
8
.github/workflows/goreleaser.yml
vendored
8
.github/workflows/goreleaser.yml
vendored
@ -8,21 +8,21 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v4
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.21'
|
||||
go-version: '1.22'
|
||||
|
||||
- name: Make All
|
||||
run: |
|
||||
./package.sh
|
||||
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v4
|
||||
uses: goreleaser/goreleaser-action@v5
|
||||
with:
|
||||
version: latest
|
||||
args: release --clean --release-notes=./Release.md
|
||||
|
@ -1,5 +1,5 @@
|
||||
service:
|
||||
golangci-lint-version: 1.55.x # use the fixed version to not introduce new linters unexpectedly
|
||||
golangci-lint-version: 1.56.x # use the fixed version to not introduce new linters unexpectedly
|
||||
|
||||
run:
|
||||
concurrency: 4
|
||||
|
7
Makefile
7
Makefile
@ -1,11 +1,14 @@
|
||||
export PATH := $(GOPATH)/bin:$(PATH)
|
||||
export PATH := $(PATH):`go env GOPATH`/bin
|
||||
export GO111MODULE=on
|
||||
LDFLAGS := -s -w
|
||||
|
||||
all: fmt build
|
||||
all: env fmt build
|
||||
|
||||
build: frps frpc
|
||||
|
||||
env:
|
||||
@go version
|
||||
|
||||
# compile assets into binary file
|
||||
file:
|
||||
rm -rf ./assets/frps/static/*
|
||||
|
12
README.md
12
README.md
@ -2,6 +2,8 @@
|
||||
|
||||
[](https://circleci.com/gh/fatedier/frp)
|
||||
[](https://github.com/fatedier/frp/releases)
|
||||
[](https://goreportcard.com/report/github.com/fatedier/frp)
|
||||
[](https://somsubhra.github.io/github-release-stats/?username=fatedier&repository=frp)
|
||||
|
||||
[README](README.md) | [中文文档](README_zh.md)
|
||||
|
||||
@ -12,8 +14,8 @@
|
||||
<img width="350px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_workos.png">
|
||||
</a>
|
||||
<a> </a>
|
||||
<a href="https://www.nango.dev?utm_source=github&utm_medium=oss-banner&utm_campaign=fatedier-frp" target="_blank">
|
||||
<img width="400px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_nango.png">
|
||||
<a href="https://github.com/daytonaio/daytona" target="_blank">
|
||||
<img width="360px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_daytona.png">
|
||||
</a>
|
||||
</p>
|
||||
<!--gold sponsors end-->
|
||||
@ -201,11 +203,11 @@ This example implements multiple SSH services exposed through the same port usin
|
||||
|
||||
4. To access internal machine A using SSH ProxyCommand, assuming the username is "test":
|
||||
|
||||
`ssh -o 'proxycommand socat - PROXY:x.x.x.x:machine-a.example.com:22,proxyport=5002' test@machine-a`
|
||||
`ssh -o 'proxycommand socat - PROXY:x.x.x.x:%h:%p,proxyport=5002' test@machine-a.example.com`
|
||||
|
||||
5. To access internal machine B, the only difference is the domain name, assuming the username is "test":
|
||||
|
||||
`ssh -o 'proxycommand socat - PROXY:x.x.x.x:machine-b.example.com:22,proxyport=5002' test@machine-b`
|
||||
`ssh -o 'proxycommand socat - PROXY:x.x.x.x:%h:%p,proxyport=5002' test@machine-b.example.com`
|
||||
|
||||
### Accessing Internal Web Services with Custom Domains in LAN
|
||||
|
||||
@ -526,6 +528,8 @@ Check frp's status and proxies' statistics information by Dashboard.
|
||||
Configure a port for dashboard to enable this feature:
|
||||
|
||||
```toml
|
||||
# The default value is 127.0.0.1. Change it to 0.0.0.0 when you want to access it from a public network.
|
||||
webServer.addr = "0.0.0.0"
|
||||
webServer.port = 7500
|
||||
# dashboard's username and password are both optional
|
||||
webServer.user = "admin"
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
[](https://circleci.com/gh/fatedier/frp)
|
||||
[](https://github.com/fatedier/frp/releases)
|
||||
[](https://goreportcard.com/report/github.com/fatedier/frp)
|
||||
[](https://somsubhra.github.io/github-release-stats/?username=fatedier&repository=frp)
|
||||
|
||||
[README](README.md) | [中文文档](README_zh.md)
|
||||
|
||||
@ -14,8 +16,8 @@ frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP
|
||||
<img width="350px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_workos.png">
|
||||
</a>
|
||||
<a> </a>
|
||||
<a href="https://www.nango.dev?utm_source=github&utm_medium=oss-banner&utm_campaign=fatedier-frp" target="_blank">
|
||||
<img width="400px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_nango.png">
|
||||
<a href="https://github.com/daytonaio/daytona" target="_blank">
|
||||
<img width="360px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_daytona.png">
|
||||
</a>
|
||||
</p>
|
||||
<!--gold sponsors end-->
|
||||
|
11
Release.md
11
Release.md
@ -1,11 +1,12 @@
|
||||
### Deprecation Notices
|
||||
### Notable Changes
|
||||
|
||||
* Using an underscore in a flag name is deprecated and has been replaced by a hyphen. The underscore format will remain compatible for some time, until it is completely removed in a future version. For example, `--remote_port` is replaced with `--remote-port`.
|
||||
* The minimum supported Go version has been updated to `1.22`. In the new version of Go, the default minimum supported TLS version has been changed to `TLS 1.2`.
|
||||
* The default value of `--strict-config` has been changed from `false` to `true`. If your configuration file uses a non-existent configuration item or has a spelling error, the application will throw an error. This startup parameter was introduced in version `v0.53.0`. If you wish to continue using the old behavior, you need to explicitly set `--strict-config=false`.
|
||||
|
||||
### Features
|
||||
|
||||
* The `Refresh` and `ClearOfflineProxies` buttons have been added to the Dashboard of frps.
|
||||
* Proxy supports configuring annotations, which will be displayed in the frps dashboard.
|
||||
|
||||
### Fixes
|
||||
### Changes
|
||||
|
||||
* The host/domain matching in the routing rules has been changed to be case-insensitive.
|
||||
* Removed dependencies on the forked version of kcp-go and beego log, kcp-go now uses the upstream version, and golib/log replaces beego log.
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
84
assets/frps/static/index-Q42Pu2_S.js
Normal file
84
assets/frps/static/index-Q42Pu2_S.js
Normal file
File diff suppressed because one or more lines are too long
1
assets/frps/static/index-rzPDshRD.css
Normal file
1
assets/frps/static/index-rzPDshRD.css
Normal file
File diff suppressed because one or more lines are too long
@ -4,8 +4,8 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>frps dashboard</title>
|
||||
<script type="module" crossorigin src="./index-1gecbKzv.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./index-Lf6B06jY.css">
|
||||
<script type="module" crossorigin src="./index-Q42Pu2_S.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./index-rzPDshRD.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -15,19 +15,17 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"sort"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/samber/lo"
|
||||
|
||||
"github.com/fatedier/frp/client/proxy"
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
"github.com/fatedier/frp/pkg/config/v1/validation"
|
||||
@ -78,9 +76,9 @@ func (svr *Service) apiReload(w http.ResponseWriter, r *http.Request) {
|
||||
strictConfigMode, _ = strconv.ParseBool(strictStr)
|
||||
}
|
||||
|
||||
log.Info("api request [/api/reload]")
|
||||
log.Infof("api request [/api/reload]")
|
||||
defer func() {
|
||||
log.Info("api response [/api/reload], code [%d]", res.Code)
|
||||
log.Infof("api response [/api/reload], code [%d]", res.Code)
|
||||
w.WriteHeader(res.Code)
|
||||
if len(res.Msg) > 0 {
|
||||
_, _ = w.Write([]byte(res.Msg))
|
||||
@ -91,32 +89,32 @@ func (svr *Service) apiReload(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
res.Code = 400
|
||||
res.Msg = err.Error()
|
||||
log.Warn("reload frpc proxy config error: %s", res.Msg)
|
||||
log.Warnf("reload frpc proxy config error: %s", res.Msg)
|
||||
return
|
||||
}
|
||||
if _, err := validation.ValidateAllClientConfig(cliCfg, proxyCfgs, visitorCfgs); err != nil {
|
||||
res.Code = 400
|
||||
res.Msg = err.Error()
|
||||
log.Warn("reload frpc proxy config error: %s", res.Msg)
|
||||
log.Warnf("reload frpc proxy config error: %s", res.Msg)
|
||||
return
|
||||
}
|
||||
|
||||
if err := svr.UpdateAllConfigurer(proxyCfgs, visitorCfgs); err != nil {
|
||||
res.Code = 500
|
||||
res.Msg = err.Error()
|
||||
log.Warn("reload frpc proxy config error: %s", res.Msg)
|
||||
log.Warnf("reload frpc proxy config error: %s", res.Msg)
|
||||
return
|
||||
}
|
||||
log.Info("success reload conf")
|
||||
log.Infof("success reload conf")
|
||||
}
|
||||
|
||||
// POST /api/stop
|
||||
func (svr *Service) apiStop(w http.ResponseWriter, _ *http.Request) {
|
||||
res := GeneralResponse{Code: 200}
|
||||
|
||||
log.Info("api request [/api/stop]")
|
||||
log.Infof("api request [/api/stop]")
|
||||
defer func() {
|
||||
log.Info("api response [/api/stop], code [%d]", res.Code)
|
||||
log.Infof("api response [/api/stop], code [%d]", res.Code)
|
||||
w.WriteHeader(res.Code)
|
||||
if len(res.Msg) > 0 {
|
||||
_, _ = w.Write([]byte(res.Msg))
|
||||
@ -153,7 +151,7 @@ func NewProxyStatusResp(status *proxy.WorkingStatus, serverAddr string) ProxySta
|
||||
|
||||
if status.Err == "" {
|
||||
psr.RemoteAddr = status.RemoteAddr
|
||||
if lo.Contains([]string{"tcp", "udp"}, status.Type) {
|
||||
if slices.Contains([]string{"tcp", "udp"}, status.Type) {
|
||||
psr.RemoteAddr = serverAddr + psr.RemoteAddr
|
||||
}
|
||||
}
|
||||
@ -167,9 +165,9 @@ func (svr *Service) apiStatus(w http.ResponseWriter, _ *http.Request) {
|
||||
res StatusResp = make(map[string][]ProxyStatusResp)
|
||||
)
|
||||
|
||||
log.Info("Http request [/api/status]")
|
||||
log.Infof("Http request [/api/status]")
|
||||
defer func() {
|
||||
log.Info("Http response [/api/status]")
|
||||
log.Infof("Http response [/api/status]")
|
||||
buf, _ = json.Marshal(&res)
|
||||
_, _ = w.Write(buf)
|
||||
}()
|
||||
@ -190,8 +188,8 @@ func (svr *Service) apiStatus(w http.ResponseWriter, _ *http.Request) {
|
||||
if len(arrs) <= 1 {
|
||||
continue
|
||||
}
|
||||
sort.Slice(arrs, func(i, j int) bool {
|
||||
return strings.Compare(arrs[i].Name, arrs[j].Name) < 0
|
||||
slices.SortFunc(arrs, func(a, b ProxyStatusResp) int {
|
||||
return cmp.Compare(a.Name, b.Name)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -200,9 +198,9 @@ func (svr *Service) apiStatus(w http.ResponseWriter, _ *http.Request) {
|
||||
func (svr *Service) apiGetConfig(w http.ResponseWriter, _ *http.Request) {
|
||||
res := GeneralResponse{Code: 200}
|
||||
|
||||
log.Info("Http get request [/api/config]")
|
||||
log.Infof("Http get request [/api/config]")
|
||||
defer func() {
|
||||
log.Info("Http get response [/api/config], code [%d]", res.Code)
|
||||
log.Infof("Http get response [/api/config], code [%d]", res.Code)
|
||||
w.WriteHeader(res.Code)
|
||||
if len(res.Msg) > 0 {
|
||||
_, _ = w.Write([]byte(res.Msg))
|
||||
@ -212,7 +210,7 @@ func (svr *Service) apiGetConfig(w http.ResponseWriter, _ *http.Request) {
|
||||
if svr.configFilePath == "" {
|
||||
res.Code = 400
|
||||
res.Msg = "frpc has no config file path"
|
||||
log.Warn("%s", res.Msg)
|
||||
log.Warnf("%s", res.Msg)
|
||||
return
|
||||
}
|
||||
|
||||
@ -220,7 +218,7 @@ func (svr *Service) apiGetConfig(w http.ResponseWriter, _ *http.Request) {
|
||||
if err != nil {
|
||||
res.Code = 400
|
||||
res.Msg = err.Error()
|
||||
log.Warn("load frpc config file error: %s", res.Msg)
|
||||
log.Warnf("load frpc config file error: %s", res.Msg)
|
||||
return
|
||||
}
|
||||
res.Msg = string(content)
|
||||
@ -230,9 +228,9 @@ func (svr *Service) apiGetConfig(w http.ResponseWriter, _ *http.Request) {
|
||||
func (svr *Service) apiPutConfig(w http.ResponseWriter, r *http.Request) {
|
||||
res := GeneralResponse{Code: 200}
|
||||
|
||||
log.Info("Http put request [/api/config]")
|
||||
log.Infof("Http put request [/api/config]")
|
||||
defer func() {
|
||||
log.Info("Http put response [/api/config], code [%d]", res.Code)
|
||||
log.Infof("Http put response [/api/config], code [%d]", res.Code)
|
||||
w.WriteHeader(res.Code)
|
||||
if len(res.Msg) > 0 {
|
||||
_, _ = w.Write([]byte(res.Msg))
|
||||
@ -244,21 +242,21 @@ func (svr *Service) apiPutConfig(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
res.Code = 400
|
||||
res.Msg = fmt.Sprintf("read request body error: %v", err)
|
||||
log.Warn("%s", res.Msg)
|
||||
log.Warnf("%s", res.Msg)
|
||||
return
|
||||
}
|
||||
|
||||
if len(body) == 0 {
|
||||
res.Code = 400
|
||||
res.Msg = "body can't be empty"
|
||||
log.Warn("%s", res.Msg)
|
||||
log.Warnf("%s", res.Msg)
|
||||
return
|
||||
}
|
||||
|
||||
if err := os.WriteFile(svr.configFilePath, body, 0o644); err != nil {
|
||||
res.Code = 500
|
||||
res.Msg = fmt.Sprintf("write content to frpc config file error: %v", err)
|
||||
log.Warn("%s", res.Msg)
|
||||
log.Warnf("%s", res.Msg)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ func (c *defaultConnectorImpl) Open() error {
|
||||
tlsConfig, err = transport.NewClientTLSConfig("", "", "", sn)
|
||||
}
|
||||
if err != nil {
|
||||
xl.Warn("fail to build tls configuration, err: %v", err)
|
||||
xl.Warnf("fail to build tls configuration, err: %v", err)
|
||||
return err
|
||||
}
|
||||
tlsConfig.NextProtos = []string{"frp"}
|
||||
@ -164,14 +164,14 @@ func (c *defaultConnectorImpl) realConnect() (net.Conn, error) {
|
||||
c.cfg.Transport.TLS.TrustedCaFile,
|
||||
sn)
|
||||
if err != nil {
|
||||
xl.Warn("fail to build tls configuration, err: %v", err)
|
||||
xl.Warnf("fail to build tls configuration, err: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
proxyType, addr, auth, err := libdial.ParseProxyURL(c.cfg.Transport.ProxyURL)
|
||||
if err != nil {
|
||||
xl.Error("fail to parse proxy url")
|
||||
xl.Errorf("fail to parse proxy url")
|
||||
return nil, err
|
||||
}
|
||||
dialOptions := []libdial.DialOption{}
|
||||
|
@ -124,7 +124,7 @@ func (ctl *Control) handleReqWorkConn(_ msg.Message) {
|
||||
xl := ctl.xl
|
||||
workConn, err := ctl.connectServer()
|
||||
if err != nil {
|
||||
xl.Warn("start new connection to server error: %v", err)
|
||||
xl.Warnf("start new connection to server error: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -132,24 +132,24 @@ func (ctl *Control) handleReqWorkConn(_ msg.Message) {
|
||||
RunID: ctl.sessionCtx.RunID,
|
||||
}
|
||||
if err = ctl.sessionCtx.AuthSetter.SetNewWorkConn(m); err != nil {
|
||||
xl.Warn("error during NewWorkConn authentication: %v", err)
|
||||
xl.Warnf("error during NewWorkConn authentication: %v", err)
|
||||
workConn.Close()
|
||||
return
|
||||
}
|
||||
if err = msg.WriteMsg(workConn, m); err != nil {
|
||||
xl.Warn("work connection write to server error: %v", err)
|
||||
xl.Warnf("work connection write to server error: %v", err)
|
||||
workConn.Close()
|
||||
return
|
||||
}
|
||||
|
||||
var startMsg msg.StartWorkConn
|
||||
if err = msg.ReadMsgInto(workConn, &startMsg); err != nil {
|
||||
xl.Trace("work connection closed before response StartWorkConn message: %v", err)
|
||||
xl.Tracef("work connection closed before response StartWorkConn message: %v", err)
|
||||
workConn.Close()
|
||||
return
|
||||
}
|
||||
if startMsg.Error != "" {
|
||||
xl.Error("StartWorkConn contains error: %s", startMsg.Error)
|
||||
xl.Errorf("StartWorkConn contains error: %s", startMsg.Error)
|
||||
workConn.Close()
|
||||
return
|
||||
}
|
||||
@ -165,9 +165,9 @@ func (ctl *Control) handleNewProxyResp(m msg.Message) {
|
||||
// Start a new proxy handler if no error got
|
||||
err := ctl.pm.StartProxy(inMsg.ProxyName, inMsg.RemoteAddr, inMsg.Error)
|
||||
if err != nil {
|
||||
xl.Warn("[%s] start error: %v", inMsg.ProxyName, err)
|
||||
xl.Warnf("[%s] start error: %v", inMsg.ProxyName, err)
|
||||
} else {
|
||||
xl.Info("[%s] start proxy success", inMsg.ProxyName)
|
||||
xl.Infof("[%s] start proxy success", inMsg.ProxyName)
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,7 +178,7 @@ func (ctl *Control) handleNatHoleResp(m msg.Message) {
|
||||
// Dispatch the NatHoleResp message to the related proxy.
|
||||
ok := ctl.msgTransporter.DispatchWithType(inMsg, msg.TypeNameNatHoleResp, inMsg.TransactionID)
|
||||
if !ok {
|
||||
xl.Trace("dispatch NatHoleResp message to related proxy error")
|
||||
xl.Tracef("dispatch NatHoleResp message to related proxy error")
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,12 +187,12 @@ func (ctl *Control) handlePong(m msg.Message) {
|
||||
inMsg := m.(*msg.Pong)
|
||||
|
||||
if inMsg.Error != "" {
|
||||
xl.Error("Pong message contains error: %s", inMsg.Error)
|
||||
xl.Errorf("Pong message contains error: %s", inMsg.Error)
|
||||
ctl.closeSession()
|
||||
return
|
||||
}
|
||||
ctl.lastPong.Store(time.Now())
|
||||
xl.Debug("receive heartbeat from server")
|
||||
xl.Debugf("receive heartbeat from server")
|
||||
}
|
||||
|
||||
// closeSession closes the control connection.
|
||||
@ -241,10 +241,10 @@ func (ctl *Control) heartbeatWorker() {
|
||||
if ctl.sessionCtx.Common.Transport.HeartbeatInterval > 0 {
|
||||
// send heartbeat to server
|
||||
sendHeartBeat := func() (bool, error) {
|
||||
xl.Debug("send heartbeat to server")
|
||||
xl.Debugf("send heartbeat to server")
|
||||
pingMsg := &msg.Ping{}
|
||||
if err := ctl.sessionCtx.AuthSetter.SetPing(pingMsg); err != nil {
|
||||
xl.Warn("error during ping authentication: %v, skip sending ping message", err)
|
||||
xl.Warnf("error during ping authentication: %v, skip sending ping message", err)
|
||||
return false, err
|
||||
}
|
||||
_ = ctl.msgDispatcher.Send(pingMsg)
|
||||
@ -269,7 +269,7 @@ func (ctl *Control) heartbeatWorker() {
|
||||
|
||||
go wait.Until(func() {
|
||||
if time.Since(ctl.lastPong.Load().(time.Time)) > time.Duration(ctl.sessionCtx.Common.Transport.HeartbeatTimeout)*time.Second {
|
||||
xl.Warn("heartbeat timeout")
|
||||
xl.Warnf("heartbeat timeout")
|
||||
ctl.closeSession()
|
||||
return
|
||||
}
|
||||
|
@ -112,17 +112,17 @@ func (monitor *Monitor) checkWorker() {
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
xl.Trace("do one health check success")
|
||||
xl.Tracef("do one health check success")
|
||||
if !monitor.statusOK && monitor.statusNormalFn != nil {
|
||||
xl.Info("health check status change to success")
|
||||
xl.Infof("health check status change to success")
|
||||
monitor.statusOK = true
|
||||
monitor.statusNormalFn()
|
||||
}
|
||||
} else {
|
||||
xl.Warn("do one health check failed: %v", err)
|
||||
xl.Warnf("do one health check failed: %v", err)
|
||||
monitor.failedTimes++
|
||||
if monitor.statusOK && int(monitor.failedTimes) >= monitor.maxFailedTimes && monitor.statusFailedFn != nil {
|
||||
xl.Warn("health check status change to failed")
|
||||
xl.Warnf("health check status change to failed")
|
||||
monitor.statusOK = false
|
||||
monitor.statusFailedFn()
|
||||
}
|
||||
|
@ -141,13 +141,13 @@ func (pxy *BaseProxy) HandleTCPWorkConnection(workConn net.Conn, m *msg.StartWor
|
||||
})
|
||||
}
|
||||
|
||||
xl.Trace("handle tcp work connection, useEncryption: %t, useCompression: %t",
|
||||
xl.Tracef("handle tcp work connection, useEncryption: %t, useCompression: %t",
|
||||
baseCfg.Transport.UseEncryption, baseCfg.Transport.UseCompression)
|
||||
if baseCfg.Transport.UseEncryption {
|
||||
remote, err = libio.WithEncryption(remote, encKey)
|
||||
if err != nil {
|
||||
workConn.Close()
|
||||
xl.Error("create encryption stream error: %v", err)
|
||||
xl.Errorf("create encryption stream error: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -189,9 +189,9 @@ func (pxy *BaseProxy) HandleTCPWorkConnection(workConn net.Conn, m *msg.StartWor
|
||||
|
||||
if pxy.proxyPlugin != nil {
|
||||
// if plugin is set, let plugin handle connection first
|
||||
xl.Debug("handle by plugin: %s", pxy.proxyPlugin.Name())
|
||||
xl.Debugf("handle by plugin: %s", pxy.proxyPlugin.Name())
|
||||
pxy.proxyPlugin.Handle(remote, workConn, &extraInfo)
|
||||
xl.Debug("handle by plugin finished")
|
||||
xl.Debugf("handle by plugin finished")
|
||||
return
|
||||
}
|
||||
|
||||
@ -201,25 +201,25 @@ func (pxy *BaseProxy) HandleTCPWorkConnection(workConn net.Conn, m *msg.StartWor
|
||||
)
|
||||
if err != nil {
|
||||
workConn.Close()
|
||||
xl.Error("connect to local service [%s:%d] error: %v", baseCfg.LocalIP, baseCfg.LocalPort, err)
|
||||
xl.Errorf("connect to local service [%s:%d] error: %v", baseCfg.LocalIP, baseCfg.LocalPort, err)
|
||||
return
|
||||
}
|
||||
|
||||
xl.Debug("join connections, localConn(l[%s] r[%s]) workConn(l[%s] r[%s])", localConn.LocalAddr().String(),
|
||||
xl.Debugf("join connections, localConn(l[%s] r[%s]) workConn(l[%s] r[%s])", localConn.LocalAddr().String(),
|
||||
localConn.RemoteAddr().String(), workConn.LocalAddr().String(), workConn.RemoteAddr().String())
|
||||
|
||||
if extraInfo.ProxyProtocolHeader != nil {
|
||||
if _, err := extraInfo.ProxyProtocolHeader.WriteTo(localConn); err != nil {
|
||||
workConn.Close()
|
||||
xl.Error("write proxy protocol header to local conn error: %v", err)
|
||||
xl.Errorf("write proxy protocol header to local conn error: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
_, _, errs := libio.Join(localConn, remote)
|
||||
xl.Debug("join connections closed")
|
||||
xl.Debugf("join connections closed")
|
||||
if len(errs) > 0 {
|
||||
xl.Trace("join connections errors: %v", errs)
|
||||
xl.Tracef("join connections errors: %v", errs)
|
||||
}
|
||||
if compressionResourceRecycleFn != nil {
|
||||
compressionResourceRecycleFn()
|
||||
|
@ -152,7 +152,7 @@ func (pm *Manager) UpdateAll(proxyCfgs []v1.ProxyConfigurer) {
|
||||
}
|
||||
}
|
||||
if len(delPxyNames) > 0 {
|
||||
xl.Info("proxy removed: %s", delPxyNames)
|
||||
xl.Infof("proxy removed: %s", delPxyNames)
|
||||
}
|
||||
|
||||
addPxyNames := make([]string, 0)
|
||||
@ -170,6 +170,6 @@ func (pm *Manager) UpdateAll(proxyCfgs []v1.ProxyConfigurer) {
|
||||
}
|
||||
}
|
||||
if len(addPxyNames) > 0 {
|
||||
xl.Info("proxy added: %s", addPxyNames)
|
||||
xl.Infof("proxy added: %s", addPxyNames)
|
||||
}
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ func NewWrapper(
|
||||
addr := net.JoinHostPort(baseInfo.LocalIP, strconv.Itoa(baseInfo.LocalPort))
|
||||
pw.monitor = health.NewMonitor(pw.ctx, baseInfo.HealthCheck, addr,
|
||||
pw.statusNormalCallback, pw.statusFailedCallback)
|
||||
xl.Trace("enable health check monitor")
|
||||
xl.Tracef("enable health check monitor")
|
||||
}
|
||||
|
||||
pw.pxy = NewProxy(pw.ctx, pw.Cfg, clientCfg, pw.msgTransporter)
|
||||
@ -197,7 +197,7 @@ func (pw *Wrapper) checkWorker() {
|
||||
(pw.Phase == ProxyPhaseWaitStart && now.After(pw.lastSendStartMsg.Add(waitResponseTimeout))) ||
|
||||
(pw.Phase == ProxyPhaseStartErr && now.After(pw.lastStartErr.Add(startErrTimeout))) {
|
||||
|
||||
xl.Trace("change status from [%s] to [%s]", pw.Phase, ProxyPhaseWaitStart)
|
||||
xl.Tracef("change status from [%s] to [%s]", pw.Phase, ProxyPhaseWaitStart)
|
||||
pw.Phase = ProxyPhaseWaitStart
|
||||
|
||||
var newProxyMsg msg.NewProxy
|
||||
@ -212,7 +212,7 @@ func (pw *Wrapper) checkWorker() {
|
||||
pw.mu.Lock()
|
||||
if pw.Phase == ProxyPhaseRunning || pw.Phase == ProxyPhaseWaitStart {
|
||||
pw.close()
|
||||
xl.Trace("change status from [%s] to [%s]", pw.Phase, ProxyPhaseCheckFailed)
|
||||
xl.Tracef("change status from [%s] to [%s]", pw.Phase, ProxyPhaseCheckFailed)
|
||||
pw.Phase = ProxyPhaseCheckFailed
|
||||
}
|
||||
pw.mu.Unlock()
|
||||
@ -236,7 +236,7 @@ func (pw *Wrapper) statusNormalCallback() {
|
||||
default:
|
||||
}
|
||||
})
|
||||
xl.Info("health check success")
|
||||
xl.Infof("health check success")
|
||||
}
|
||||
|
||||
func (pw *Wrapper) statusFailedCallback() {
|
||||
@ -248,7 +248,7 @@ func (pw *Wrapper) statusFailedCallback() {
|
||||
default:
|
||||
}
|
||||
})
|
||||
xl.Info("health check failed")
|
||||
xl.Infof("health check failed")
|
||||
}
|
||||
|
||||
func (pw *Wrapper) InWorkConn(workConn net.Conn, m *msg.StartWorkConn) {
|
||||
@ -257,7 +257,7 @@ func (pw *Wrapper) InWorkConn(workConn net.Conn, m *msg.StartWorkConn) {
|
||||
pxy := pw.pxy
|
||||
pw.mu.RUnlock()
|
||||
if pxy != nil && pw.Phase == ProxyPhaseRunning {
|
||||
xl.Debug("start a new work connection, localAddr: %s remoteAddr: %s", workConn.LocalAddr().String(), workConn.RemoteAddr().String())
|
||||
xl.Debugf("start a new work connection, localAddr: %s remoteAddr: %s", workConn.LocalAddr().String(), workConn.RemoteAddr().String())
|
||||
go pxy.InWorkConn(workConn, m)
|
||||
} else {
|
||||
workConn.Close()
|
||||
|
@ -81,7 +81,7 @@ func (pxy *SUDPProxy) Close() {
|
||||
|
||||
func (pxy *SUDPProxy) InWorkConn(conn net.Conn, _ *msg.StartWorkConn) {
|
||||
xl := pxy.xl
|
||||
xl.Info("incoming a new work connection for sudp proxy, %s", conn.RemoteAddr().String())
|
||||
xl.Infof("incoming a new work connection for sudp proxy, %s", conn.RemoteAddr().String())
|
||||
|
||||
var rwc io.ReadWriteCloser = conn
|
||||
var err error
|
||||
@ -94,7 +94,7 @@ func (pxy *SUDPProxy) InWorkConn(conn net.Conn, _ *msg.StartWorkConn) {
|
||||
rwc, err = libio.WithEncryption(rwc, []byte(pxy.clientCfg.Auth.Token))
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
xl.Error("create encryption stream error: %v", err)
|
||||
xl.Errorf("create encryption stream error: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -133,21 +133,21 @@ func (pxy *SUDPProxy) InWorkConn(conn net.Conn, _ *msg.StartWorkConn) {
|
||||
// first to check sudp proxy is closed or not
|
||||
select {
|
||||
case <-pxy.closeCh:
|
||||
xl.Trace("frpc sudp proxy is closed")
|
||||
xl.Tracef("frpc sudp proxy is closed")
|
||||
return
|
||||
default:
|
||||
}
|
||||
|
||||
var udpMsg msg.UDPPacket
|
||||
if errRet := msg.ReadMsgInto(conn, &udpMsg); errRet != nil {
|
||||
xl.Warn("read from workConn for sudp error: %v", errRet)
|
||||
xl.Warnf("read from workConn for sudp error: %v", errRet)
|
||||
return
|
||||
}
|
||||
|
||||
if errRet := errors.PanicToError(func() {
|
||||
readCh <- &udpMsg
|
||||
}); errRet != nil {
|
||||
xl.Warn("reader goroutine for sudp work connection closed: %v", errRet)
|
||||
xl.Warnf("reader goroutine for sudp work connection closed: %v", errRet)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -157,21 +157,21 @@ func (pxy *SUDPProxy) InWorkConn(conn net.Conn, _ *msg.StartWorkConn) {
|
||||
workConnSenderFn := func(conn net.Conn, sendCh chan msg.Message) {
|
||||
defer func() {
|
||||
closeFn()
|
||||
xl.Info("writer goroutine for sudp work connection closed")
|
||||
xl.Infof("writer goroutine for sudp work connection closed")
|
||||
}()
|
||||
|
||||
var errRet error
|
||||
for rawMsg := range sendCh {
|
||||
switch m := rawMsg.(type) {
|
||||
case *msg.UDPPacket:
|
||||
xl.Trace("frpc send udp package to frpc visitor, [udp local: %v, remote: %v], [tcp work conn local: %v, remote: %v]",
|
||||
xl.Tracef("frpc send udp package to frpc visitor, [udp local: %v, remote: %v], [tcp work conn local: %v, remote: %v]",
|
||||
m.LocalAddr.String(), m.RemoteAddr.String(), conn.LocalAddr().String(), conn.RemoteAddr().String())
|
||||
case *msg.Ping:
|
||||
xl.Trace("frpc send ping message to frpc visitor")
|
||||
xl.Tracef("frpc send ping message to frpc visitor")
|
||||
}
|
||||
|
||||
if errRet = msg.WriteMsg(conn, rawMsg); errRet != nil {
|
||||
xl.Error("sudp work write error: %v", errRet)
|
||||
xl.Errorf("sudp work write error: %v", errRet)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -191,11 +191,11 @@ func (pxy *SUDPProxy) InWorkConn(conn net.Conn, _ *msg.StartWorkConn) {
|
||||
if errRet = errors.PanicToError(func() {
|
||||
sendCh <- &msg.Ping{}
|
||||
}); errRet != nil {
|
||||
xl.Warn("heartbeat goroutine for sudp work connection closed")
|
||||
xl.Warnf("heartbeat goroutine for sudp work connection closed")
|
||||
return
|
||||
}
|
||||
case <-pxy.closeCh:
|
||||
xl.Trace("frpc sudp proxy is closed")
|
||||
xl.Tracef("frpc sudp proxy is closed")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ func (pxy *UDPProxy) Close() {
|
||||
|
||||
func (pxy *UDPProxy) InWorkConn(conn net.Conn, _ *msg.StartWorkConn) {
|
||||
xl := pxy.xl
|
||||
xl.Info("incoming a new work connection for udp proxy, %s", conn.RemoteAddr().String())
|
||||
xl.Infof("incoming a new work connection for udp proxy, %s", conn.RemoteAddr().String())
|
||||
// close resources related with old workConn
|
||||
pxy.Close()
|
||||
|
||||
@ -105,7 +105,7 @@ func (pxy *UDPProxy) InWorkConn(conn net.Conn, _ *msg.StartWorkConn) {
|
||||
rwc, err = libio.WithEncryption(rwc, []byte(pxy.clientCfg.Auth.Token))
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
xl.Error("create encryption stream error: %v", err)
|
||||
xl.Errorf("create encryption stream error: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -125,32 +125,32 @@ func (pxy *UDPProxy) InWorkConn(conn net.Conn, _ *msg.StartWorkConn) {
|
||||
for {
|
||||
var udpMsg msg.UDPPacket
|
||||
if errRet := msg.ReadMsgInto(conn, &udpMsg); errRet != nil {
|
||||
xl.Warn("read from workConn for udp error: %v", errRet)
|
||||
xl.Warnf("read from workConn for udp error: %v", errRet)
|
||||
return
|
||||
}
|
||||
if errRet := errors.PanicToError(func() {
|
||||
xl.Trace("get udp package from workConn: %s", udpMsg.Content)
|
||||
xl.Tracef("get udp package from workConn: %s", udpMsg.Content)
|
||||
readCh <- &udpMsg
|
||||
}); errRet != nil {
|
||||
xl.Info("reader goroutine for udp work connection closed: %v", errRet)
|
||||
xl.Infof("reader goroutine for udp work connection closed: %v", errRet)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
workConnSenderFn := func(conn net.Conn, sendCh chan msg.Message) {
|
||||
defer func() {
|
||||
xl.Info("writer goroutine for udp work connection closed")
|
||||
xl.Infof("writer goroutine for udp work connection closed")
|
||||
}()
|
||||
var errRet error
|
||||
for rawMsg := range sendCh {
|
||||
switch m := rawMsg.(type) {
|
||||
case *msg.UDPPacket:
|
||||
xl.Trace("send udp package to workConn: %s", m.Content)
|
||||
xl.Tracef("send udp package to workConn: %s", m.Content)
|
||||
case *msg.Ping:
|
||||
xl.Trace("send ping message to udp workConn")
|
||||
xl.Tracef("send ping message to udp workConn")
|
||||
}
|
||||
if errRet = msg.WriteMsg(conn, rawMsg); errRet != nil {
|
||||
xl.Error("udp work write error: %v", errRet)
|
||||
xl.Errorf("udp work write error: %v", errRet)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -162,7 +162,7 @@ func (pxy *UDPProxy) InWorkConn(conn net.Conn, _ *msg.StartWorkConn) {
|
||||
if errRet = errors.PanicToError(func() {
|
||||
sendCh <- &msg.Ping{}
|
||||
}); errRet != nil {
|
||||
xl.Trace("heartbeat goroutine for udp work connection closed")
|
||||
xl.Tracef("heartbeat goroutine for udp work connection closed")
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -59,17 +59,17 @@ func (pxy *XTCPProxy) InWorkConn(conn net.Conn, startWorkConnMsg *msg.StartWorkC
|
||||
var natHoleSidMsg msg.NatHoleSid
|
||||
err := msg.ReadMsgInto(conn, &natHoleSidMsg)
|
||||
if err != nil {
|
||||
xl.Error("xtcp read from workConn error: %v", err)
|
||||
xl.Errorf("xtcp read from workConn error: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
xl.Trace("nathole prepare start")
|
||||
xl.Tracef("nathole prepare start")
|
||||
prepareResult, err := nathole.Prepare([]string{pxy.clientCfg.NatHoleSTUNServer})
|
||||
if err != nil {
|
||||
xl.Warn("nathole prepare error: %v", err)
|
||||
xl.Warnf("nathole prepare error: %v", err)
|
||||
return
|
||||
}
|
||||
xl.Info("nathole prepare success, nat type: %s, behavior: %s, addresses: %v, assistedAddresses: %v",
|
||||
xl.Infof("nathole prepare success, nat type: %s, behavior: %s, addresses: %v, assistedAddresses: %v",
|
||||
prepareResult.NatType, prepareResult.Behavior, prepareResult.Addrs, prepareResult.AssistedAddrs)
|
||||
defer prepareResult.ListenConn.Close()
|
||||
|
||||
@ -83,14 +83,14 @@ func (pxy *XTCPProxy) InWorkConn(conn net.Conn, startWorkConnMsg *msg.StartWorkC
|
||||
AssistedAddrs: prepareResult.AssistedAddrs,
|
||||
}
|
||||
|
||||
xl.Trace("nathole exchange info start")
|
||||
xl.Tracef("nathole exchange info start")
|
||||
natHoleRespMsg, err := nathole.ExchangeInfo(pxy.ctx, pxy.msgTransporter, transactionID, natHoleClientMsg, 5*time.Second)
|
||||
if err != nil {
|
||||
xl.Warn("nathole exchange info error: %v", err)
|
||||
xl.Warnf("nathole exchange info error: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
xl.Info("get natHoleRespMsg, sid [%s], protocol [%s], candidate address %v, assisted address %v, detectBehavior: %+v",
|
||||
xl.Infof("get natHoleRespMsg, sid [%s], protocol [%s], candidate address %v, assisted address %v, detectBehavior: %+v",
|
||||
natHoleRespMsg.Sid, natHoleRespMsg.Protocol, natHoleRespMsg.CandidateAddrs,
|
||||
natHoleRespMsg.AssistedAddrs, natHoleRespMsg.DetectBehavior)
|
||||
|
||||
@ -98,7 +98,7 @@ func (pxy *XTCPProxy) InWorkConn(conn net.Conn, startWorkConnMsg *msg.StartWorkC
|
||||
newListenConn, raddr, err := nathole.MakeHole(pxy.ctx, listenConn, natHoleRespMsg, []byte(pxy.cfg.Secretkey))
|
||||
if err != nil {
|
||||
listenConn.Close()
|
||||
xl.Warn("make hole error: %v", err)
|
||||
xl.Warnf("make hole error: %v", err)
|
||||
_ = pxy.msgTransporter.Send(&msg.NatHoleReport{
|
||||
Sid: natHoleRespMsg.Sid,
|
||||
Success: false,
|
||||
@ -106,7 +106,7 @@ func (pxy *XTCPProxy) InWorkConn(conn net.Conn, startWorkConnMsg *msg.StartWorkC
|
||||
return
|
||||
}
|
||||
listenConn = newListenConn
|
||||
xl.Info("establishing nat hole connection successful, sid [%s], remoteAddr [%s]", natHoleRespMsg.Sid, raddr)
|
||||
xl.Infof("establishing nat hole connection successful, sid [%s], remoteAddr [%s]", natHoleRespMsg.Sid, raddr)
|
||||
|
||||
_ = pxy.msgTransporter.Send(&msg.NatHoleReport{
|
||||
Sid: natHoleRespMsg.Sid,
|
||||
@ -128,14 +128,14 @@ func (pxy *XTCPProxy) listenByKCP(listenConn *net.UDPConn, raddr *net.UDPAddr, s
|
||||
laddr, _ := net.ResolveUDPAddr("udp", listenConn.LocalAddr().String())
|
||||
lConn, err := net.DialUDP("udp", laddr, raddr)
|
||||
if err != nil {
|
||||
xl.Warn("dial udp error: %v", err)
|
||||
xl.Warnf("dial udp error: %v", err)
|
||||
return
|
||||
}
|
||||
defer lConn.Close()
|
||||
|
||||
remote, err := netpkg.NewKCPConnFromUDP(lConn, true, raddr.String())
|
||||
if err != nil {
|
||||
xl.Warn("create kcp connection from udp connection error: %v", err)
|
||||
xl.Warnf("create kcp connection from udp connection error: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -145,7 +145,7 @@ func (pxy *XTCPProxy) listenByKCP(listenConn *net.UDPConn, raddr *net.UDPAddr, s
|
||||
fmuxCfg.LogOutput = io.Discard
|
||||
session, err := fmux.Server(remote, fmuxCfg)
|
||||
if err != nil {
|
||||
xl.Error("create mux session error: %v", err)
|
||||
xl.Errorf("create mux session error: %v", err)
|
||||
return
|
||||
}
|
||||
defer session.Close()
|
||||
@ -153,7 +153,7 @@ func (pxy *XTCPProxy) listenByKCP(listenConn *net.UDPConn, raddr *net.UDPAddr, s
|
||||
for {
|
||||
muxConn, err := session.Accept()
|
||||
if err != nil {
|
||||
xl.Error("accept connection error: %v", err)
|
||||
xl.Errorf("accept connection error: %v", err)
|
||||
return
|
||||
}
|
||||
go pxy.HandleTCPWorkConnection(muxConn, startWorkConnMsg, []byte(pxy.cfg.Secretkey))
|
||||
@ -166,7 +166,7 @@ func (pxy *XTCPProxy) listenByQUIC(listenConn *net.UDPConn, _ *net.UDPAddr, star
|
||||
|
||||
tlsConfig, err := transport.NewServerTLSConfig("", "", "")
|
||||
if err != nil {
|
||||
xl.Warn("create tls config error: %v", err)
|
||||
xl.Warnf("create tls config error: %v", err)
|
||||
return
|
||||
}
|
||||
tlsConfig.NextProtos = []string{"frp"}
|
||||
@ -178,19 +178,19 @@ func (pxy *XTCPProxy) listenByQUIC(listenConn *net.UDPConn, _ *net.UDPAddr, star
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
xl.Warn("dial quic error: %v", err)
|
||||
xl.Warnf("dial quic error: %v", err)
|
||||
return
|
||||
}
|
||||
// only accept one connection from raddr
|
||||
c, err := quicListener.Accept(pxy.ctx)
|
||||
if err != nil {
|
||||
xl.Error("quic accept connection error: %v", err)
|
||||
xl.Errorf("quic accept connection error: %v", err)
|
||||
return
|
||||
}
|
||||
for {
|
||||
stream, err := c.AcceptStream(pxy.ctx)
|
||||
if err != nil {
|
||||
xl.Debug("quic accept stream error: %v", err)
|
||||
xl.Debugf("quic accept stream error: %v", err)
|
||||
_ = c.CloseWithError(0, "")
|
||||
return
|
||||
}
|
||||
|
@ -174,9 +174,9 @@ func (svr *Service) Run(ctx context.Context) error {
|
||||
|
||||
if svr.webServer != nil {
|
||||
go func() {
|
||||
log.Info("admin server listen on %s", svr.webServer.Address())
|
||||
log.Infof("admin server listen on %s", svr.webServer.Address())
|
||||
if err := svr.webServer.Run(); err != nil {
|
||||
log.Warn("admin server exit with error: %v", err)
|
||||
log.Warnf("admin server exit with error: %v", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
@ -269,14 +269,14 @@ func (svr *Service) login() (conn net.Conn, connector Connector, err error) {
|
||||
|
||||
if loginRespMsg.Error != "" {
|
||||
err = fmt.Errorf("%s", loginRespMsg.Error)
|
||||
xl.Error("%s", loginRespMsg.Error)
|
||||
xl.Errorf("%s", loginRespMsg.Error)
|
||||
return
|
||||
}
|
||||
|
||||
svr.runID = loginRespMsg.RunID
|
||||
xl.AddPrefix(xlog.LogPrefix{Name: "runID", Value: svr.runID})
|
||||
|
||||
xl.Info("login to server success, get run id [%s]", loginRespMsg.RunID)
|
||||
xl.Infof("login to server success, get run id [%s]", loginRespMsg.RunID)
|
||||
return
|
||||
}
|
||||
|
||||
@ -284,10 +284,10 @@ func (svr *Service) loopLoginUntilSuccess(maxInterval time.Duration, firstLoginE
|
||||
xl := xlog.FromContextSafe(svr.ctx)
|
||||
|
||||
loginFunc := func() (bool, error) {
|
||||
xl.Info("try to connect to server...")
|
||||
xl.Infof("try to connect to server...")
|
||||
conn, connector, err := svr.login()
|
||||
if err != nil {
|
||||
xl.Warn("connect to server error: %v", err)
|
||||
xl.Warnf("connect to server error: %v", err)
|
||||
if firstLoginExit {
|
||||
svr.cancel(cancelErr{Err: err})
|
||||
}
|
||||
@ -313,7 +313,7 @@ func (svr *Service) loopLoginUntilSuccess(maxInterval time.Duration, firstLoginE
|
||||
ctl, err := NewControl(svr.ctx, sessionCtx)
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
xl.Error("NewControl error: %v", err)
|
||||
xl.Errorf("NewControl error: %v", err)
|
||||
return false, err
|
||||
}
|
||||
ctl.SetInWorkConnCallback(svr.handleWorkConnCb)
|
||||
|
@ -56,7 +56,7 @@ func (sv *STCPVisitor) worker() {
|
||||
for {
|
||||
conn, err := sv.l.Accept()
|
||||
if err != nil {
|
||||
xl.Warn("stcp local listener closed")
|
||||
xl.Warnf("stcp local listener closed")
|
||||
return
|
||||
}
|
||||
go sv.handleConn(conn)
|
||||
@ -68,7 +68,7 @@ func (sv *STCPVisitor) internalConnWorker() {
|
||||
for {
|
||||
conn, err := sv.internalLn.Accept()
|
||||
if err != nil {
|
||||
xl.Warn("stcp internal listener closed")
|
||||
xl.Warnf("stcp internal listener closed")
|
||||
return
|
||||
}
|
||||
go sv.handleConn(conn)
|
||||
@ -79,7 +79,7 @@ func (sv *STCPVisitor) handleConn(userConn net.Conn) {
|
||||
xl := xlog.FromContextSafe(sv.ctx)
|
||||
defer userConn.Close()
|
||||
|
||||
xl.Debug("get a new stcp user connection")
|
||||
xl.Debugf("get a new stcp user connection")
|
||||
visitorConn, err := sv.helper.ConnectServer()
|
||||
if err != nil {
|
||||
return
|
||||
@ -97,7 +97,7 @@ func (sv *STCPVisitor) handleConn(userConn net.Conn) {
|
||||
}
|
||||
err = msg.WriteMsg(visitorConn, newVisitorConnMsg)
|
||||
if err != nil {
|
||||
xl.Warn("send newVisitorConnMsg to server error: %v", err)
|
||||
xl.Warnf("send newVisitorConnMsg to server error: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -105,13 +105,13 @@ func (sv *STCPVisitor) handleConn(userConn net.Conn) {
|
||||
_ = visitorConn.SetReadDeadline(time.Now().Add(10 * time.Second))
|
||||
err = msg.ReadMsgInto(visitorConn, &newVisitorConnRespMsg)
|
||||
if err != nil {
|
||||
xl.Warn("get newVisitorConnRespMsg error: %v", err)
|
||||
xl.Warnf("get newVisitorConnRespMsg error: %v", err)
|
||||
return
|
||||
}
|
||||
_ = visitorConn.SetReadDeadline(time.Time{})
|
||||
|
||||
if newVisitorConnRespMsg.Error != "" {
|
||||
xl.Warn("start new visitor connection error: %s", newVisitorConnRespMsg.Error)
|
||||
xl.Warnf("start new visitor connection error: %s", newVisitorConnRespMsg.Error)
|
||||
return
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ func (sv *STCPVisitor) handleConn(userConn net.Conn) {
|
||||
if sv.cfg.Transport.UseEncryption {
|
||||
remote, err = libio.WithEncryption(remote, []byte(sv.cfg.SecretKey))
|
||||
if err != nil {
|
||||
xl.Error("create encryption stream error: %v", err)
|
||||
xl.Errorf("create encryption stream error: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ func (sv *SUDPVisitor) Run() (err error) {
|
||||
sv.sendCh = make(chan *msg.UDPPacket, 1024)
|
||||
sv.readCh = make(chan *msg.UDPPacket, 1024)
|
||||
|
||||
xl.Info("sudp start to work, listen on %s", addr)
|
||||
xl.Infof("sudp start to work, listen on %s", addr)
|
||||
|
||||
go sv.dispatcher()
|
||||
go udp.ForwardUserConn(sv.udpConn, sv.readCh, sv.sendCh, int(sv.clientCfg.UDPPacketSize))
|
||||
@ -84,17 +84,17 @@ func (sv *SUDPVisitor) dispatcher() {
|
||||
select {
|
||||
case firstPacket = <-sv.sendCh:
|
||||
if firstPacket == nil {
|
||||
xl.Info("frpc sudp visitor proxy is closed")
|
||||
xl.Infof("frpc sudp visitor proxy is closed")
|
||||
return
|
||||
}
|
||||
case <-sv.checkCloseCh:
|
||||
xl.Info("frpc sudp visitor proxy is closed")
|
||||
xl.Infof("frpc sudp visitor proxy is closed")
|
||||
return
|
||||
}
|
||||
|
||||
visitorConn, err = sv.getNewVisitorConn()
|
||||
if err != nil {
|
||||
xl.Warn("newVisitorConn to frps error: %v, try to reconnect", err)
|
||||
xl.Warnf("newVisitorConn to frps error: %v, try to reconnect", err)
|
||||
continue
|
||||
}
|
||||
|
||||
@ -111,7 +111,7 @@ func (sv *SUDPVisitor) dispatcher() {
|
||||
|
||||
func (sv *SUDPVisitor) worker(workConn net.Conn, firstPacket *msg.UDPPacket) {
|
||||
xl := xlog.FromContextSafe(sv.ctx)
|
||||
xl.Debug("starting sudp proxy worker")
|
||||
xl.Debugf("starting sudp proxy worker")
|
||||
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(2)
|
||||
@ -134,21 +134,21 @@ 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))
|
||||
if rawMsg, errRet = msg.ReadMsg(conn); errRet != nil {
|
||||
xl.Warn("read from workconn for user udp conn error: %v", errRet)
|
||||
xl.Warnf("read from workconn for user udp conn error: %v", errRet)
|
||||
return
|
||||
}
|
||||
|
||||
_ = conn.SetReadDeadline(time.Time{})
|
||||
switch m := rawMsg.(type) {
|
||||
case *msg.Ping:
|
||||
xl.Debug("frpc visitor get ping message from frpc")
|
||||
xl.Debugf("frpc visitor get ping message from frpc")
|
||||
continue
|
||||
case *msg.UDPPacket:
|
||||
if errRet := errors.PanicToError(func() {
|
||||
sv.readCh <- m
|
||||
xl.Trace("frpc visitor get udp packet from workConn: %s", m.Content)
|
||||
xl.Tracef("frpc visitor get udp packet from workConn: %s", m.Content)
|
||||
}); errRet != nil {
|
||||
xl.Info("reader goroutine for udp work connection closed")
|
||||
xl.Infof("reader goroutine for udp work connection closed")
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -165,25 +165,25 @@ func (sv *SUDPVisitor) worker(workConn net.Conn, firstPacket *msg.UDPPacket) {
|
||||
var errRet error
|
||||
if firstPacket != nil {
|
||||
if errRet = msg.WriteMsg(conn, firstPacket); errRet != nil {
|
||||
xl.Warn("sender goroutine for udp work connection closed: %v", errRet)
|
||||
xl.Warnf("sender goroutine for udp work connection closed: %v", errRet)
|
||||
return
|
||||
}
|
||||
xl.Trace("send udp package to workConn: %s", firstPacket.Content)
|
||||
xl.Tracef("send udp package to workConn: %s", firstPacket.Content)
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case udpMsg, ok := <-sv.sendCh:
|
||||
if !ok {
|
||||
xl.Info("sender goroutine for udp work connection closed")
|
||||
xl.Infof("sender goroutine for udp work connection closed")
|
||||
return
|
||||
}
|
||||
|
||||
if errRet = msg.WriteMsg(conn, udpMsg); errRet != nil {
|
||||
xl.Warn("sender goroutine for udp work connection closed: %v", errRet)
|
||||
xl.Warnf("sender goroutine for udp work connection closed: %v", errRet)
|
||||
return
|
||||
}
|
||||
xl.Trace("send udp package to workConn: %s", udpMsg.Content)
|
||||
xl.Tracef("send udp package to workConn: %s", udpMsg.Content)
|
||||
case <-closeCh:
|
||||
return
|
||||
}
|
||||
@ -194,7 +194,7 @@ func (sv *SUDPVisitor) worker(workConn net.Conn, firstPacket *msg.UDPPacket) {
|
||||
go workConnSenderFn(workConn)
|
||||
|
||||
wg.Wait()
|
||||
xl.Info("sudp worker is closed")
|
||||
xl.Infof("sudp worker is closed")
|
||||
}
|
||||
|
||||
func (sv *SUDPVisitor) getNewVisitorConn() (net.Conn, error) {
|
||||
@ -235,7 +235,7 @@ func (sv *SUDPVisitor) getNewVisitorConn() (net.Conn, error) {
|
||||
if sv.cfg.Transport.UseEncryption {
|
||||
remote, err = libio.WithEncryption(remote, []byte(sv.cfg.SecretKey))
|
||||
if err != nil {
|
||||
xl.Error("create encryption stream error: %v", err)
|
||||
xl.Errorf("create encryption stream error: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
@ -79,14 +79,14 @@ func (vm *Manager) keepVisitorsRunning() {
|
||||
for {
|
||||
select {
|
||||
case <-vm.stopCh:
|
||||
xl.Trace("gracefully shutdown visitor manager")
|
||||
xl.Tracef("gracefully shutdown visitor manager")
|
||||
return
|
||||
case <-ticker.C:
|
||||
vm.mu.Lock()
|
||||
for _, cfg := range vm.cfgs {
|
||||
name := cfg.GetBaseConfig().Name
|
||||
if _, exist := vm.visitors[name]; !exist {
|
||||
xl.Info("try to start visitor [%s]", name)
|
||||
xl.Infof("try to start visitor [%s]", name)
|
||||
_ = vm.startVisitor(cfg)
|
||||
}
|
||||
}
|
||||
@ -115,10 +115,10 @@ func (vm *Manager) startVisitor(cfg v1.VisitorConfigurer) (err error) {
|
||||
visitor := NewVisitor(vm.ctx, cfg, vm.clientCfg, vm.helper)
|
||||
err = visitor.Run()
|
||||
if err != nil {
|
||||
xl.Warn("start error: %v", err)
|
||||
xl.Warnf("start error: %v", err)
|
||||
} else {
|
||||
vm.visitors[name] = visitor
|
||||
xl.Info("start visitor success")
|
||||
xl.Infof("start visitor success")
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -156,7 +156,7 @@ func (vm *Manager) UpdateAll(cfgs []v1.VisitorConfigurer) {
|
||||
}
|
||||
}
|
||||
if len(delNames) > 0 {
|
||||
xl.Info("visitor removed: %v", delNames)
|
||||
xl.Infof("visitor removed: %v", delNames)
|
||||
}
|
||||
|
||||
addNames := make([]string, 0)
|
||||
@ -169,7 +169,7 @@ func (vm *Manager) UpdateAll(cfgs []v1.VisitorConfigurer) {
|
||||
}
|
||||
}
|
||||
if len(addNames) > 0 {
|
||||
xl.Info("visitor added: %v", addNames)
|
||||
xl.Infof("visitor added: %v", addNames)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ func (sv *XTCPVisitor) worker() {
|
||||
for {
|
||||
conn, err := sv.l.Accept()
|
||||
if err != nil {
|
||||
xl.Warn("xtcp local listener closed")
|
||||
xl.Warnf("xtcp local listener closed")
|
||||
return
|
||||
}
|
||||
go sv.handleConn(conn)
|
||||
@ -105,7 +105,7 @@ func (sv *XTCPVisitor) internalConnWorker() {
|
||||
for {
|
||||
conn, err := sv.internalLn.Accept()
|
||||
if err != nil {
|
||||
xl.Warn("xtcp internal listener closed")
|
||||
xl.Warnf("xtcp internal listener closed")
|
||||
return
|
||||
}
|
||||
go sv.handleConn(conn)
|
||||
@ -140,14 +140,14 @@ func (sv *XTCPVisitor) keepTunnelOpenWorker() {
|
||||
case <-sv.ctx.Done():
|
||||
return
|
||||
case <-ticker.C:
|
||||
xl.Debug("keepTunnelOpenWorker try to check tunnel...")
|
||||
xl.Debugf("keepTunnelOpenWorker try to check tunnel...")
|
||||
conn, err := sv.getTunnelConn()
|
||||
if err != nil {
|
||||
xl.Warn("keepTunnelOpenWorker get tunnel connection error: %v", err)
|
||||
xl.Warnf("keepTunnelOpenWorker get tunnel connection error: %v", err)
|
||||
_ = sv.retryLimiter.Wait(sv.ctx)
|
||||
continue
|
||||
}
|
||||
xl.Debug("keepTunnelOpenWorker check success")
|
||||
xl.Debugf("keepTunnelOpenWorker check success")
|
||||
if conn != nil {
|
||||
conn.Close()
|
||||
}
|
||||
@ -164,7 +164,7 @@ func (sv *XTCPVisitor) handleConn(userConn net.Conn) {
|
||||
}
|
||||
}()
|
||||
|
||||
xl.Debug("get a new xtcp user connection")
|
||||
xl.Debugf("get a new xtcp user connection")
|
||||
|
||||
// Open a tunnel connection to the server. If there is already a successful hole-punching connection,
|
||||
// it will be reused. Otherwise, it will block and wait for a successful hole-punching connection until timeout.
|
||||
@ -176,15 +176,15 @@ func (sv *XTCPVisitor) handleConn(userConn net.Conn) {
|
||||
}
|
||||
tunnelConn, err := sv.openTunnel(ctx)
|
||||
if err != nil {
|
||||
xl.Error("open tunnel error: %v", err)
|
||||
xl.Errorf("open tunnel error: %v", err)
|
||||
// no fallback, just return
|
||||
if sv.cfg.FallbackTo == "" {
|
||||
return
|
||||
}
|
||||
|
||||
xl.Debug("try to transfer connection to visitor: %s", sv.cfg.FallbackTo)
|
||||
xl.Debugf("try to transfer connection to visitor: %s", sv.cfg.FallbackTo)
|
||||
if err := sv.helper.TransferConn(sv.cfg.FallbackTo, userConn); err != nil {
|
||||
xl.Error("transfer connection to visitor %s error: %v", sv.cfg.FallbackTo, err)
|
||||
xl.Errorf("transfer connection to visitor %s error: %v", sv.cfg.FallbackTo, err)
|
||||
return
|
||||
}
|
||||
isConnTrasfered = true
|
||||
@ -195,7 +195,7 @@ func (sv *XTCPVisitor) handleConn(userConn net.Conn) {
|
||||
if sv.cfg.Transport.UseEncryption {
|
||||
muxConnRWCloser, err = libio.WithEncryption(muxConnRWCloser, []byte(sv.cfg.SecretKey))
|
||||
if err != nil {
|
||||
xl.Error("create encryption stream error: %v", err)
|
||||
xl.Errorf("create encryption stream error: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -206,9 +206,9 @@ func (sv *XTCPVisitor) handleConn(userConn net.Conn) {
|
||||
}
|
||||
|
||||
_, _, errs := libio.Join(userConn, muxConnRWCloser)
|
||||
xl.Debug("join connections closed")
|
||||
xl.Debugf("join connections closed")
|
||||
if len(errs) > 0 {
|
||||
xl.Trace("join connections errors: %v", errs)
|
||||
xl.Tracef("join connections errors: %v", errs)
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,7 +239,7 @@ func (sv *XTCPVisitor) openTunnel(ctx context.Context) (conn net.Conn, err error
|
||||
|
||||
if err != nil {
|
||||
if err != ErrNoTunnelSession {
|
||||
xl.Warn("get tunnel connection error: %v", err)
|
||||
xl.Warnf("get tunnel connection error: %v", err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
@ -268,19 +268,19 @@ func (sv *XTCPVisitor) getTunnelConn() (net.Conn, error) {
|
||||
// 4. Create a tunnel session using an underlying UDP connection.
|
||||
func (sv *XTCPVisitor) makeNatHole() {
|
||||
xl := xlog.FromContextSafe(sv.ctx)
|
||||
xl.Trace("makeNatHole start")
|
||||
xl.Tracef("makeNatHole start")
|
||||
if err := nathole.PreCheck(sv.ctx, sv.helper.MsgTransporter(), sv.cfg.ServerName, 5*time.Second); err != nil {
|
||||
xl.Warn("nathole precheck error: %v", err)
|
||||
xl.Warnf("nathole precheck error: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
xl.Trace("nathole prepare start")
|
||||
xl.Tracef("nathole prepare start")
|
||||
prepareResult, err := nathole.Prepare([]string{sv.clientCfg.NatHoleSTUNServer})
|
||||
if err != nil {
|
||||
xl.Warn("nathole prepare error: %v", err)
|
||||
xl.Warnf("nathole prepare error: %v", err)
|
||||
return
|
||||
}
|
||||
xl.Info("nathole prepare success, nat type: %s, behavior: %s, addresses: %v, assistedAddresses: %v",
|
||||
xl.Infof("nathole prepare success, nat type: %s, behavior: %s, addresses: %v, assistedAddresses: %v",
|
||||
prepareResult.NatType, prepareResult.Behavior, prepareResult.Addrs, prepareResult.AssistedAddrs)
|
||||
|
||||
listenConn := prepareResult.ListenConn
|
||||
@ -298,30 +298,30 @@ func (sv *XTCPVisitor) makeNatHole() {
|
||||
AssistedAddrs: prepareResult.AssistedAddrs,
|
||||
}
|
||||
|
||||
xl.Trace("nathole exchange info start")
|
||||
xl.Tracef("nathole exchange info start")
|
||||
natHoleRespMsg, err := nathole.ExchangeInfo(sv.ctx, sv.helper.MsgTransporter(), transactionID, natHoleVisitorMsg, 5*time.Second)
|
||||
if err != nil {
|
||||
listenConn.Close()
|
||||
xl.Warn("nathole exchange info error: %v", err)
|
||||
xl.Warnf("nathole exchange info error: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
xl.Info("get natHoleRespMsg, sid [%s], protocol [%s], candidate address %v, assisted address %v, detectBehavior: %+v",
|
||||
xl.Infof("get natHoleRespMsg, sid [%s], protocol [%s], candidate address %v, assisted address %v, detectBehavior: %+v",
|
||||
natHoleRespMsg.Sid, natHoleRespMsg.Protocol, natHoleRespMsg.CandidateAddrs,
|
||||
natHoleRespMsg.AssistedAddrs, natHoleRespMsg.DetectBehavior)
|
||||
|
||||
newListenConn, raddr, err := nathole.MakeHole(sv.ctx, listenConn, natHoleRespMsg, []byte(sv.cfg.SecretKey))
|
||||
if err != nil {
|
||||
listenConn.Close()
|
||||
xl.Warn("make hole error: %v", err)
|
||||
xl.Warnf("make hole error: %v", err)
|
||||
return
|
||||
}
|
||||
listenConn = newListenConn
|
||||
xl.Info("establishing nat hole connection successful, sid [%s], remoteAddr [%s]", natHoleRespMsg.Sid, raddr)
|
||||
xl.Infof("establishing nat hole connection successful, sid [%s], remoteAddr [%s]", natHoleRespMsg.Sid, raddr)
|
||||
|
||||
if err := sv.session.Init(listenConn, raddr); err != nil {
|
||||
listenConn.Close()
|
||||
xl.Warn("init tunnel session error: %v", err)
|
||||
xl.Warnf("init tunnel session error: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -17,8 +17,8 @@ package sub
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"slices"
|
||||
|
||||
"github.com/samber/lo"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
@ -55,7 +55,7 @@ func init() {
|
||||
config.RegisterProxyFlags(cmd, c)
|
||||
|
||||
// add sub command for visitor
|
||||
if lo.Contains(visitorTypes, v1.VisitorType(typ)) {
|
||||
if slices.Contains(visitorTypes, v1.VisitorType(typ)) {
|
||||
vc := v1.NewVisitorConfigurerByType(v1.VisitorType(typ))
|
||||
if vc == nil {
|
||||
panic("visitor type: " + typ + " not support")
|
||||
|
@ -46,7 +46,7 @@ func init() {
|
||||
rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "./frpc.ini", "config file of frpc")
|
||||
rootCmd.PersistentFlags().StringVarP(&cfgDir, "config_dir", "", "", "config directory, run one frpc service for each file in config directory")
|
||||
rootCmd.PersistentFlags().BoolVarP(&showVersion, "version", "v", false, "version of frpc")
|
||||
rootCmd.PersistentFlags().BoolVarP(&strictConfigMode, "strict_config", "", false, "strict config parsing mode, unknown fields will cause an error")
|
||||
rootCmd.PersistentFlags().BoolVarP(&strictConfigMode, "strict_config", "", true, "strict config parsing mode, unknown fields will cause an errors")
|
||||
}
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
@ -136,11 +136,11 @@ func startService(
|
||||
visitorCfgs []v1.VisitorConfigurer,
|
||||
cfgFile string,
|
||||
) error {
|
||||
log.InitLog(cfg.Log.To, cfg.Log.Level, cfg.Log.MaxDays, cfg.Log.DisablePrintColor)
|
||||
log.InitLogger(cfg.Log.To, cfg.Log.Level, int(cfg.Log.MaxDays), cfg.Log.DisablePrintColor)
|
||||
|
||||
if cfgFile != "" {
|
||||
log.Info("start frpc service for config file [%s]", cfgFile)
|
||||
defer log.Info("frpc service for config file [%s] stopped", cfgFile)
|
||||
log.Infof("start frpc service for config file [%s]", cfgFile)
|
||||
defer log.Infof("frpc service for config file [%s] stopped", cfgFile)
|
||||
}
|
||||
svr, err := client.NewService(client.ServiceOptions{
|
||||
Common: cfg,
|
||||
|
@ -40,7 +40,7 @@ var (
|
||||
func init() {
|
||||
rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file of frps")
|
||||
rootCmd.PersistentFlags().BoolVarP(&showVersion, "version", "v", false, "version of frps")
|
||||
rootCmd.PersistentFlags().BoolVarP(&strictConfigMode, "strict_config", "", false, "strict config parsing mode, unknown fields will cause error")
|
||||
rootCmd.PersistentFlags().BoolVarP(&strictConfigMode, "strict_config", "", true, "strict config parsing mode, unknown fields will cause errors")
|
||||
|
||||
config.RegisterServerConfigFlags(rootCmd, &serverCfg)
|
||||
}
|
||||
@ -99,19 +99,19 @@ func Execute() {
|
||||
}
|
||||
|
||||
func runServer(cfg *v1.ServerConfig) (err error) {
|
||||
log.InitLog(cfg.Log.To, cfg.Log.Level, cfg.Log.MaxDays, cfg.Log.DisablePrintColor)
|
||||
log.InitLogger(cfg.Log.To, cfg.Log.Level, int(cfg.Log.MaxDays), cfg.Log.DisablePrintColor)
|
||||
|
||||
if cfgFile != "" {
|
||||
log.Info("frps uses config file: %s", cfgFile)
|
||||
log.Infof("frps uses config file: %s", cfgFile)
|
||||
} else {
|
||||
log.Info("frps uses command line arguments for config")
|
||||
log.Infof("frps uses command line arguments for config")
|
||||
}
|
||||
|
||||
svr, err := server.NewService(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Info("frps started successfully")
|
||||
log.Infof("frps started successfully")
|
||||
svr.Run(context.Background())
|
||||
return
|
||||
}
|
||||
|
@ -164,11 +164,16 @@ healthCheck.type = "tcp"
|
||||
healthCheck.timeoutSeconds = 3
|
||||
# If continuous failed in 3 times, the proxy will be removed from frps
|
||||
healthCheck.maxFailed = 3
|
||||
# every 10 seconds will do a health check
|
||||
# Every 10 seconds will do a health check
|
||||
healthCheck.intervalSeconds = 10
|
||||
# additional meta info for each proxy
|
||||
# Additional meta info for each proxy. It will be passed to the server-side plugin for use.
|
||||
metadatas.var1 = "abc"
|
||||
metadatas.var2 = "123"
|
||||
# You can add some extra information to the proxy through annotations.
|
||||
# These annotations will be displayed on the frps dashboard.
|
||||
[proxies.annotations]
|
||||
key1 = "value1"
|
||||
"prefix/key2" = "value2"
|
||||
|
||||
[[proxies]]
|
||||
name = "ssh_random"
|
||||
|
BIN
doc/pic/sponsor_daytona.png
Normal file
BIN
doc/pic/sponsor_daytona.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 56 KiB |
@ -1,4 +1,4 @@
|
||||
FROM golang:1.21 AS building
|
||||
FROM golang:1.22 AS building
|
||||
|
||||
COPY . /building
|
||||
WORKDIR /building
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM golang:1.21 AS building
|
||||
FROM golang:1.22 AS building
|
||||
|
||||
COPY . /building
|
||||
WORKDIR /building
|
||||
|
36
go.mod
36
go.mod
@ -1,13 +1,11 @@
|
||||
module github.com/fatedier/frp
|
||||
|
||||
go 1.20
|
||||
go 1.22
|
||||
|
||||
require (
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5
|
||||
github.com/coreos/go-oidc/v3 v3.6.0
|
||||
github.com/fatedier/beego v0.0.0-20171024143340-6c6a4f5bd5eb
|
||||
github.com/fatedier/golib v0.1.1-0.20230725122706-dcbaee8eef40
|
||||
github.com/fatedier/kcp-go v2.0.4-0.20190803094908-fe8645b0a904+incompatible
|
||||
github.com/fatedier/golib v0.4.0
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
@ -15,17 +13,19 @@ require (
|
||||
github.com/onsi/ginkgo/v2 v2.11.0
|
||||
github.com/onsi/gomega v1.27.8
|
||||
github.com/pelletier/go-toml/v2 v2.1.0
|
||||
github.com/pion/stun v0.6.1
|
||||
github.com/pion/stun/v2 v2.0.0
|
||||
github.com/pires/go-proxyproto v0.7.0
|
||||
github.com/prometheus/client_golang v1.16.0
|
||||
github.com/quic-go/quic-go v0.37.7
|
||||
github.com/quic-go/quic-go v0.41.0
|
||||
github.com/rodaine/table v1.1.0
|
||||
github.com/samber/lo v1.38.1
|
||||
github.com/samber/lo v1.39.0
|
||||
github.com/spf13/cobra v1.8.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.8.4
|
||||
golang.org/x/crypto v0.17.0
|
||||
golang.org/x/net v0.17.0
|
||||
github.com/tidwall/gjson v1.17.1
|
||||
github.com/xtaci/kcp-go/v5 v5.6.7
|
||||
golang.org/x/crypto v0.18.0
|
||||
golang.org/x/net v0.19.0
|
||||
golang.org/x/oauth2 v0.10.0
|
||||
golang.org/x/sync v0.3.0
|
||||
golang.org/x/time v0.3.0
|
||||
@ -42,32 +42,34 @@ require (
|
||||
github.com/go-jose/go-jose/v3 v3.0.1 // indirect
|
||||
github.com/go-logr/logr v1.2.4 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.0.6 // indirect
|
||||
github.com/klauspost/reedsolomon v1.9.15 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
|
||||
github.com/klauspost/reedsolomon v1.12.0 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/pion/dtls/v2 v2.2.7 // indirect
|
||||
github.com/pion/logging v0.2.2 // indirect
|
||||
github.com/pion/transport/v2 v2.2.1 // indirect
|
||||
github.com/pion/transport/v3 v3.0.1 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_model v0.3.0 // indirect
|
||||
github.com/prometheus/common v0.42.0 // indirect
|
||||
github.com/prometheus/procfs v0.10.1 // indirect
|
||||
github.com/quic-go/qtls-go1-20 v0.3.1 // indirect
|
||||
github.com/rogpeppe/go-internal v1.11.0 // indirect
|
||||
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // indirect
|
||||
github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b // indirect
|
||||
github.com/templexxx/cpu v0.1.0 // indirect
|
||||
github.com/templexxx/xorsimd v0.4.2 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
github.com/tjfoc/gmsm v1.4.1 // indirect
|
||||
go.uber.org/mock v0.3.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect
|
||||
golang.org/x/mod v0.10.0 // indirect
|
||||
golang.org/x/sys v0.15.0 // indirect
|
||||
golang.org/x/mod v0.11.0 // indirect
|
||||
golang.org/x/sys v0.16.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/tools v0.9.3 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
|
92
go.sum
92
go.sum
@ -24,12 +24,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
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.20230725122706-dcbaee8eef40 h1:BVdpWT6viE/mpuRa6txNyRNjtHa1Efrii9Du6/gHfJ0=
|
||||
github.com/fatedier/golib v0.1.1-0.20230725122706-dcbaee8eef40/go.mod h1:Lmi9U4VfvdRvonSMh1FgXVy1hCXycVyJk4E9ktokknE=
|
||||
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/fatedier/golib v0.4.0 h1:lafvYRMhFmqrfIUChKy/f5AXqs1eDSk+GAUtLexN5bU=
|
||||
github.com/fatedier/golib v0.4.0/go.mod h1:gpu+1vXxtJ072NYaNsn/YWgojDL8Ap2kFZQtbzT2qkg=
|
||||
github.com/fatedier/yamux v0.0.0-20230628132301-7aca4898904d h1:ynk1ra0RUqDWQfvFi5KtMiSobkVQ3cNc0ODb8CfIETo=
|
||||
github.com/fatedier/yamux v0.0.0-20230628132301-7aca4898904d/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
|
||||
github.com/go-jose/go-jose/v3 v3.0.1 h1:pWmKFVtt+Jl0vBZTIpz/eAKwsm6LkIxDVVbFHKkchhA=
|
||||
@ -40,8 +36,6 @@ github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEe
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
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=
|
||||
@ -77,11 +71,12 @@ github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
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=
|
||||
github.com/klauspost/reedsolomon v1.9.15 h1:g2erWKD2M6rgnPf89fCji6jNlhMKMdXcuNHMW1SYCIo=
|
||||
github.com/klauspost/reedsolomon v1.9.15/go.mod h1:eqPAcE7xar5CIzcdfwydOEdcmchAKAP/qs14y4GCBOk=
|
||||
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
|
||||
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/klauspost/reedsolomon v1.12.0 h1:I5FEp3xSwVCcEh3F5A7dofEfhXdF/bWhQWPH+XwBFno=
|
||||
github.com/klauspost/reedsolomon v1.12.0/go.mod h1:EPLZJeh4l27pUGC3aXOjheaoh1I9yut7xTURiW3LQ9Y=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
@ -98,10 +93,12 @@ github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8=
|
||||
github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s=
|
||||
github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
|
||||
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
|
||||
github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4=
|
||||
github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8=
|
||||
github.com/pion/stun/v2 v2.0.0 h1:A5+wXKLAypxQri59+tmQKVs7+l6mMM+3d+eER9ifRU0=
|
||||
github.com/pion/stun/v2 v2.0.0/go.mod h1:22qRSh08fSEttYUmJZGlriq9+03jtVmXNODgLccj8GQ=
|
||||
github.com/pion/transport/v2 v2.2.1 h1:7qYnCBlpgSJNYMbLCKuSY9KbQdBFoETvPNETv0y4N7c=
|
||||
github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g=
|
||||
github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM=
|
||||
github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0=
|
||||
github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs=
|
||||
github.com/pires/go-proxyproto v0.7.0/go.mod h1:Vz/1JPY/OACxWGQNIRY2BeyDmpoaWmEP40O9LbuiFR4=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
@ -117,17 +114,15 @@ github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI
|
||||
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
|
||||
github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg=
|
||||
github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.1 h1:O4BLOM3hwfVF3AcktIylQXyl7Yi2iBNVy5QsV+ySxbg=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
|
||||
github.com/quic-go/quic-go v0.37.7 h1:AgKsQLZ1+YCwZd2GYhBUsJDYZwEkA5gENtAjb+MxONU=
|
||||
github.com/quic-go/quic-go v0.37.7/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU=
|
||||
github.com/quic-go/quic-go v0.41.0 h1:aD8MmHfgqTURWNJy48IYFg2OnxwHT3JL7ahGs73lb4k=
|
||||
github.com/quic-go/quic-go v0.41.0/go.mod h1:qCkNjqczPEvgsOnxZ0eCD14lv+B2LHlFAB++CNOh9hA=
|
||||
github.com/rodaine/table v1.1.0 h1:/fUlCSdjamMY8VifdQRIu3VWZXYLY7QHFkVorS8NTr4=
|
||||
github.com/rodaine/table v1.1.0/go.mod h1:Qu3q5wi1jTQD6B6HsP6szie/S4w1QUQ8pq22pz9iL8g=
|
||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM=
|
||||
github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
|
||||
github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA=
|
||||
github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
|
||||
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
|
||||
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
@ -141,35 +136,44 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
|
||||
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 h1:89CEmDvlq/F7SJEOqkIdNDGJXrQIhuIx9D2DBXjavSU=
|
||||
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU=
|
||||
github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b h1:fj5tQ8acgNUr6O8LEplsxDhUIe2573iLkJc+PqnzZTI=
|
||||
github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4=
|
||||
github.com/templexxx/cpu v0.1.0 h1:wVM+WIJP2nYaxVxqgHPD4wGA2aJ9rvrQRV8CvFzNb40=
|
||||
github.com/templexxx/cpu v0.1.0/go.mod h1:w7Tb+7qgcAlIyX4NhLuDKt78AHA5SzPmq0Wj6HiEnnk=
|
||||
github.com/templexxx/xorsimd v0.4.2 h1:ocZZ+Nvu65LGHmCLZ7OoCtg8Fx8jnHKK37SjvngUoVI=
|
||||
github.com/templexxx/xorsimd v0.4.2/go.mod h1:HgwaPoDREdi6OnULpSfxhzaiiSUY4Fi3JPn1wpt28NI=
|
||||
github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U=
|
||||
github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
|
||||
github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
|
||||
github.com/xtaci/kcp-go/v5 v5.6.7 h1:7+rnxNFIsjEwTXQk4cSZpXM4pO0hqtpwE1UFFoJBffA=
|
||||
github.com/xtaci/kcp-go/v5 v5.6.7/go.mod h1:oE9j2NVqAkuKO5o8ByKGch3vgVX3BNf8zqP8JiGq0bM=
|
||||
github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37 h1:EWU6Pktpas0n8lLQwDsRyZfmkPeRbdgPtW609es+/9E=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37/go.mod h1:HpMP7DB2CyokmAh4lp0EQnnWhmycP/TvwBGzvuie+H0=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo=
|
||||
go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/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-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
|
||||
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
|
||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o=
|
||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
|
||||
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
|
||||
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
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-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -179,12 +183,13 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
|
||||
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8=
|
||||
golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI=
|
||||
@ -192,7 +197,6 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
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-20190423024810-112230192c58/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-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
||||
@ -203,26 +207,30 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/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-20210330210617-4fbd30eecc44/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-20210615035016-665e8c7367d1/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-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
|
||||
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
|
||||
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
|
||||
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
|
||||
golang.org/x/text v0.3.0/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.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
@ -233,15 +241,12 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM=
|
||||
golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
|
||||
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/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
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.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
@ -264,6 +269,7 @@ google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
|
@ -17,9 +17,9 @@ package auth
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"slices"
|
||||
|
||||
"github.com/coreos/go-oidc/v3/oidc"
|
||||
"github.com/samber/lo"
|
||||
"golang.org/x/oauth2/clientcredentials"
|
||||
|
||||
v1 "github.com/fatedier/frp/pkg/config/v1"
|
||||
@ -70,7 +70,7 @@ func (auth *OidcAuthProvider) SetLogin(loginMsg *msg.Login) (err error) {
|
||||
}
|
||||
|
||||
func (auth *OidcAuthProvider) SetPing(pingMsg *msg.Ping) (err error) {
|
||||
if !lo.Contains(auth.additionalAuthScopes, v1.AuthScopeHeartBeats) {
|
||||
if !slices.Contains(auth.additionalAuthScopes, v1.AuthScopeHeartBeats) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ func (auth *OidcAuthProvider) SetPing(pingMsg *msg.Ping) (err error) {
|
||||
}
|
||||
|
||||
func (auth *OidcAuthProvider) SetNewWorkConn(newWorkConnMsg *msg.NewWorkConn) (err error) {
|
||||
if !lo.Contains(auth.additionalAuthScopes, v1.AuthScopeNewWorkConns) {
|
||||
if !slices.Contains(auth.additionalAuthScopes, v1.AuthScopeNewWorkConns) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -135,7 +135,7 @@ func (auth *OidcAuthConsumer) verifyPostLoginToken(privilegeKey string) (err err
|
||||
}
|
||||
|
||||
func (auth *OidcAuthConsumer) VerifyPing(pingMsg *msg.Ping) (err error) {
|
||||
if !lo.Contains(auth.additionalAuthScopes, v1.AuthScopeHeartBeats) {
|
||||
if !slices.Contains(auth.additionalAuthScopes, v1.AuthScopeHeartBeats) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -143,7 +143,7 @@ func (auth *OidcAuthConsumer) VerifyPing(pingMsg *msg.Ping) (err error) {
|
||||
}
|
||||
|
||||
func (auth *OidcAuthConsumer) VerifyNewWorkConn(newWorkConnMsg *msg.NewWorkConn) (err error) {
|
||||
if !lo.Contains(auth.additionalAuthScopes, v1.AuthScopeNewWorkConns) {
|
||||
if !slices.Contains(auth.additionalAuthScopes, v1.AuthScopeNewWorkConns) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -16,10 +16,9 @@ package auth
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
"github.com/samber/lo"
|
||||
|
||||
v1 "github.com/fatedier/frp/pkg/config/v1"
|
||||
"github.com/fatedier/frp/pkg/msg"
|
||||
"github.com/fatedier/frp/pkg/util/util"
|
||||
@ -43,7 +42,7 @@ func (auth *TokenAuthSetterVerifier) SetLogin(loginMsg *msg.Login) error {
|
||||
}
|
||||
|
||||
func (auth *TokenAuthSetterVerifier) SetPing(pingMsg *msg.Ping) error {
|
||||
if !lo.Contains(auth.additionalAuthScopes, v1.AuthScopeHeartBeats) {
|
||||
if !slices.Contains(auth.additionalAuthScopes, v1.AuthScopeHeartBeats) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -53,7 +52,7 @@ func (auth *TokenAuthSetterVerifier) SetPing(pingMsg *msg.Ping) error {
|
||||
}
|
||||
|
||||
func (auth *TokenAuthSetterVerifier) SetNewWorkConn(newWorkConnMsg *msg.NewWorkConn) error {
|
||||
if !lo.Contains(auth.additionalAuthScopes, v1.AuthScopeNewWorkConns) {
|
||||
if !slices.Contains(auth.additionalAuthScopes, v1.AuthScopeNewWorkConns) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -70,7 +69,7 @@ func (auth *TokenAuthSetterVerifier) VerifyLogin(m *msg.Login) error {
|
||||
}
|
||||
|
||||
func (auth *TokenAuthSetterVerifier) VerifyPing(m *msg.Ping) error {
|
||||
if !lo.Contains(auth.additionalAuthScopes, v1.AuthScopeHeartBeats) {
|
||||
if !slices.Contains(auth.additionalAuthScopes, v1.AuthScopeHeartBeats) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -81,7 +80,7 @@ func (auth *TokenAuthSetterVerifier) VerifyPing(m *msg.Ping) error {
|
||||
}
|
||||
|
||||
func (auth *TokenAuthSetterVerifier) VerifyNewWorkConn(m *msg.NewWorkConn) error {
|
||||
if !lo.Contains(auth.additionalAuthScopes, v1.AuthScopeNewWorkConns) {
|
||||
if !slices.Contains(auth.additionalAuthScopes, v1.AuthScopeNewWorkConns) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -18,9 +18,9 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/samber/lo"
|
||||
"gopkg.in/ini.v1"
|
||||
|
||||
legacyauth "github.com/fatedier/frp/pkg/auth/legacy"
|
||||
@ -399,7 +399,7 @@ func (cfg *ClientCommonConf) Validate() error {
|
||||
}
|
||||
}
|
||||
|
||||
if !lo.Contains([]string{"tcp", "kcp", "quic", "websocket", "wss"}, cfg.Protocol) {
|
||||
if !slices.Contains([]string{"tcp", "kcp", "quic", "websocket", "wss"}, cfg.Protocol) {
|
||||
return fmt.Errorf("invalid protocol")
|
||||
}
|
||||
|
||||
|
@ -175,6 +175,9 @@ func transformHeadersFromPluginParams(params map[string]string) v1.HeaderOperati
|
||||
continue
|
||||
}
|
||||
if k = strings.TrimPrefix(k, "plugin_header_"); k != "" {
|
||||
if out.Set == nil {
|
||||
out.Set = make(map[string]string)
|
||||
}
|
||||
out.Set[k] = v
|
||||
}
|
||||
}
|
||||
|
@ -45,15 +45,6 @@ func NewBandwidthQuantity(s string) (BandwidthQuantity, error) {
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func MustBandwidthQuantity(s string) BandwidthQuantity {
|
||||
q := BandwidthQuantity{}
|
||||
err := q.UnmarshalString(s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return q
|
||||
}
|
||||
|
||||
func (q *BandwidthQuantity) Equal(u *BandwidthQuantity) bool {
|
||||
if q == nil && u == nil {
|
||||
return true
|
||||
|
@ -57,7 +57,7 @@ func (c *TypedClientPluginOptions) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
|
||||
if err := decoder.Decode(options); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("unmarshal ClientPluginOptions error: %v", err)
|
||||
}
|
||||
c.ClientPluginOptions = options
|
||||
return nil
|
||||
|
@ -105,9 +105,10 @@ type DomainConfig struct {
|
||||
}
|
||||
|
||||
type ProxyBaseConfig struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Transport ProxyTransport `json:"transport,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
Transport ProxyTransport `json:"transport,omitempty"`
|
||||
// metadata info for each proxy
|
||||
Metadatas map[string]string `json:"metadatas,omitempty"`
|
||||
LoadBalancer LoadBalancerConfig `json:"loadBalancer,omitempty"`
|
||||
@ -138,6 +139,7 @@ func (c *ProxyBaseConfig) MarshalToMsg(m *msg.NewProxy) {
|
||||
m.Group = c.LoadBalancer.Group
|
||||
m.GroupKey = c.LoadBalancer.GroupKey
|
||||
m.Metas = c.Metadatas
|
||||
m.Annotations = c.Annotations
|
||||
}
|
||||
|
||||
func (c *ProxyBaseConfig) UnmarshalFromMsg(m *msg.NewProxy) {
|
||||
@ -154,6 +156,7 @@ func (c *ProxyBaseConfig) UnmarshalFromMsg(m *msg.NewProxy) {
|
||||
c.LoadBalancer.Group = m.Group
|
||||
c.LoadBalancer.GroupKey = m.GroupKey
|
||||
c.Metadatas = m.Metas
|
||||
c.Annotations = m.Annotations
|
||||
}
|
||||
|
||||
type TypedProxyConfig struct {
|
||||
@ -183,7 +186,7 @@ func (c *TypedProxyConfig) UnmarshalJSON(b []byte) error {
|
||||
decoder.DisallowUnknownFields()
|
||||
}
|
||||
if err := decoder.Decode(configurer); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("unmarshal ProxyConfig error: %v", err)
|
||||
}
|
||||
c.ProxyConfigurer = configurer
|
||||
return nil
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
|
||||
"github.com/samber/lo"
|
||||
|
||||
@ -29,7 +30,7 @@ func ValidateClientCommonConfig(c *v1.ClientCommonConfig) (Warning, error) {
|
||||
warnings Warning
|
||||
errs error
|
||||
)
|
||||
if !lo.Contains(SupportedAuthMethods, c.Auth.Method) {
|
||||
if !slices.Contains(SupportedAuthMethods, c.Auth.Method) {
|
||||
errs = AppendError(errs, fmt.Errorf("invalid auth method, optional values are %v", SupportedAuthMethods))
|
||||
}
|
||||
if !lo.Every(SupportedAuthAdditionalScopes, c.Auth.AdditionalScopes) {
|
||||
@ -63,7 +64,7 @@ func ValidateClientCommonConfig(c *v1.ClientCommonConfig) (Warning, error) {
|
||||
warnings = AppendError(warnings, checkTLSConfig("transport.tls.trustedCaFile", c.Transport.TLS.TrustedCaFile))
|
||||
}
|
||||
|
||||
if !lo.Contains(SupportedTransportProtocols, c.Transport.Protocol) {
|
||||
if !slices.Contains(SupportedTransportProtocols, c.Transport.Protocol) {
|
||||
errs = AppendError(errs, fmt.Errorf("invalid transport.protocol, optional values are %v", SupportedTransportProtocols))
|
||||
}
|
||||
|
||||
|
@ -16,8 +16,7 @@ package validation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/samber/lo"
|
||||
"slices"
|
||||
|
||||
v1 "github.com/fatedier/frp/pkg/config/v1"
|
||||
)
|
||||
@ -44,7 +43,7 @@ func ValidatePort(port int, fieldPath string) error {
|
||||
}
|
||||
|
||||
func validateLogConfig(c *v1.LogConfig) error {
|
||||
if !lo.Contains(SupportedLogLevels, c.Level) {
|
||||
if !slices.Contains(SupportedLogLevels, c.Level) {
|
||||
return fmt.Errorf("invalid log level, optional values are %v", SupportedLogLevels)
|
||||
}
|
||||
return nil
|
||||
|
@ -17,9 +17,10 @@ package validation
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/samber/lo"
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
|
||||
v1 "github.com/fatedier/frp/pkg/config/v1"
|
||||
)
|
||||
@ -29,11 +30,13 @@ func validateProxyBaseConfigForClient(c *v1.ProxyBaseConfig) error {
|
||||
return errors.New("name should not be empty")
|
||||
}
|
||||
|
||||
if !lo.Contains([]string{"", "v1", "v2"}, c.Transport.ProxyProtocolVersion) {
|
||||
if err := ValidateAnnotations(c.Annotations); err != nil {
|
||||
return err
|
||||
}
|
||||
if !slices.Contains([]string{"", "v1", "v2"}, c.Transport.ProxyProtocolVersion) {
|
||||
return fmt.Errorf("not support proxy protocol version: %s", c.Transport.ProxyProtocolVersion)
|
||||
}
|
||||
|
||||
if !lo.Contains([]string{"client", "server"}, c.Transport.BandwidthLimitMode) {
|
||||
if !slices.Contains([]string{"client", "server"}, c.Transport.BandwidthLimitMode) {
|
||||
return fmt.Errorf("bandwidth limit mode should be client or server")
|
||||
}
|
||||
|
||||
@ -43,7 +46,7 @@ func validateProxyBaseConfigForClient(c *v1.ProxyBaseConfig) error {
|
||||
}
|
||||
}
|
||||
|
||||
if !lo.Contains([]string{"", "tcp", "http"}, c.HealthCheck.Type) {
|
||||
if !slices.Contains([]string{"", "tcp", "http"}, c.HealthCheck.Type) {
|
||||
return fmt.Errorf("not support health check type: %s", c.HealthCheck.Type)
|
||||
}
|
||||
if c.HealthCheck.Type != "" {
|
||||
@ -61,7 +64,10 @@ func validateProxyBaseConfigForClient(c *v1.ProxyBaseConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateProxyBaseConfigForServer(c *v1.ProxyBaseConfig, s *v1.ServerConfig) error {
|
||||
func validateProxyBaseConfigForServer(c *v1.ProxyBaseConfig) error {
|
||||
if err := ValidateAnnotations(c.Annotations); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -133,7 +139,7 @@ func validateTCPMuxProxyConfigForClient(c *v1.TCPMuxProxyConfig) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if !lo.Contains([]string{string(v1.TCPMultiplexerHTTPConnect)}, c.Multiplexer) {
|
||||
if !slices.Contains([]string{string(v1.TCPMultiplexerHTTPConnect)}, c.Multiplexer) {
|
||||
return fmt.Errorf("not support multiplexer: %s", c.Multiplexer)
|
||||
}
|
||||
return nil
|
||||
@ -161,7 +167,7 @@ func validateSUDPProxyConfigForClient(c *v1.SUDPProxyConfig) error {
|
||||
|
||||
func ValidateProxyConfigurerForServer(c v1.ProxyConfigurer, s *v1.ServerConfig) error {
|
||||
base := c.GetBaseConfig()
|
||||
if err := validateProxyBaseConfigForServer(base, s); err != nil {
|
||||
if err := validateProxyBaseConfigForServer(base); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -231,3 +237,34 @@ func validateXTCPProxyConfigForServer(c *v1.XTCPProxyConfig, s *v1.ServerConfig)
|
||||
func validateSUDPProxyConfigForServer(c *v1.SUDPProxyConfig, s *v1.ServerConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValidateAnnotations validates that a set of annotations are correctly defined.
|
||||
func ValidateAnnotations(annotations map[string]string) error {
|
||||
if len(annotations) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var errs error
|
||||
for k := range annotations {
|
||||
for _, msg := range validation.IsQualifiedName(strings.ToLower(k)) {
|
||||
errs = AppendError(errs, fmt.Errorf("annotation key %s is invalid: %s", k, msg))
|
||||
}
|
||||
}
|
||||
if err := ValidateAnnotationsSize(annotations); err != nil {
|
||||
errs = AppendError(errs, err)
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
const TotalAnnotationSizeLimitB int = 256 * (1 << 10) // 256 kB
|
||||
|
||||
func ValidateAnnotationsSize(annotations map[string]string) error {
|
||||
var totalSize int64
|
||||
for k, v := range annotations {
|
||||
totalSize += (int64)(len(k)) + (int64)(len(v))
|
||||
}
|
||||
if totalSize > (int64)(TotalAnnotationSizeLimitB) {
|
||||
return fmt.Errorf("annotations size %d is larger than limit %d", totalSize, TotalAnnotationSizeLimitB)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ package validation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
|
||||
"github.com/samber/lo"
|
||||
|
||||
@ -27,7 +28,7 @@ func ValidateServerConfig(c *v1.ServerConfig) (Warning, error) {
|
||||
warnings Warning
|
||||
errs error
|
||||
)
|
||||
if !lo.Contains(SupportedAuthMethods, c.Auth.Method) {
|
||||
if !slices.Contains(SupportedAuthMethods, c.Auth.Method) {
|
||||
errs = AppendError(errs, fmt.Errorf("invalid auth method, optional values are %v", SupportedAuthMethods))
|
||||
}
|
||||
if !lo.Every(SupportedAuthAdditionalScopes, c.Auth.AdditionalScopes) {
|
||||
|
@ -17,8 +17,7 @@ package validation
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/samber/lo"
|
||||
"slices"
|
||||
|
||||
v1 "github.com/fatedier/frp/pkg/config/v1"
|
||||
)
|
||||
@ -56,7 +55,7 @@ func validateVisitorBaseConfig(c *v1.VisitorBaseConfig) error {
|
||||
}
|
||||
|
||||
func validateXTCPVisitorConfig(c *v1.XTCPVisitorConfig) error {
|
||||
if !lo.Contains([]string{"kcp", "quic"}, c.Protocol) {
|
||||
if !slices.Contains([]string{"kcp", "quic"}, c.Protocol) {
|
||||
return fmt.Errorf("protocol should be kcp or quic")
|
||||
}
|
||||
return nil
|
||||
|
@ -114,7 +114,7 @@ func (c *TypedVisitorConfig) UnmarshalJSON(b []byte) error {
|
||||
decoder.DisallowUnknownFields()
|
||||
}
|
||||
if err := decoder.Decode(configurer); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("unmarshal VisitorConfig error: %v", err)
|
||||
}
|
||||
c.VisitorConfigurer = configurer
|
||||
return nil
|
||||
|
@ -62,7 +62,7 @@ func (m *serverMetrics) run() {
|
||||
time.Sleep(12 * time.Hour)
|
||||
start := time.Now()
|
||||
count, total := m.clearUselessInfo(time.Duration(7*24) * time.Hour)
|
||||
log.Debug("clear useless proxy statistics data count %d/%d, cost %v", count, total, time.Since(start))
|
||||
log.Debugf("clear useless proxy statistics data count %d/%d, cost %v", count, total, time.Since(start))
|
||||
}
|
||||
}()
|
||||
}
|
||||
@ -80,7 +80,7 @@ func (m *serverMetrics) clearUselessInfo(continuousOfflineDuration time.Duration
|
||||
time.Since(data.LastCloseTime) > continuousOfflineDuration {
|
||||
delete(m.info.ProxyStatistics, name)
|
||||
count++
|
||||
log.Trace("clear proxy [%s]'s statistics data, lastCloseTime: [%s]", name, data.LastCloseTime.String())
|
||||
log.Tracef("clear proxy [%s]'s statistics data, lastCloseTime: [%s]", name, data.LastCloseTime.String())
|
||||
}
|
||||
}
|
||||
return count, total
|
||||
|
@ -42,7 +42,3 @@ func ReadMsgInto(c io.Reader, msg Message) (err error) {
|
||||
func WriteMsg(c io.Writer, msg interface{}) (err error) {
|
||||
return msgCtl.WriteMsg(c, msg)
|
||||
}
|
||||
|
||||
func Pack(msg interface{}) (data []byte, err error) {
|
||||
return msgCtl.Pack(msg)
|
||||
}
|
||||
|
@ -108,6 +108,7 @@ type NewProxy struct {
|
||||
Group string `json:"group,omitempty"`
|
||||
GroupKey string `json:"group_key,omitempty"`
|
||||
Metas map[string]string `json:"metas,omitempty"`
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
|
||||
// tcp and udp only
|
||||
RemotePort int `json:"remote_port,omitempty"`
|
||||
|
@ -15,6 +15,8 @@
|
||||
package nathole
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"slices"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@ -224,7 +226,7 @@ func (mhr *MakeHoleRecords) ReportSuccess(mode int, index int) {
|
||||
}
|
||||
|
||||
score.Score += 2
|
||||
score.Score = lo.Min([]int{score.Score, 10})
|
||||
score.Score = min(score.Score, 10)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -233,12 +235,12 @@ func (mhr *MakeHoleRecords) Recommand() (mode, index int) {
|
||||
mhr.mu.Lock()
|
||||
defer mhr.mu.Unlock()
|
||||
|
||||
maxScore := lo.MaxBy(mhr.scores, func(item, max *BehaviorScore) bool {
|
||||
return item.Score > max.Score
|
||||
})
|
||||
if maxScore == nil {
|
||||
if len(mhr.scores) == 0 {
|
||||
return 0, 0
|
||||
}
|
||||
maxScore := slices.MaxFunc(mhr.scores, func(a, b *BehaviorScore) int {
|
||||
return cmp.Compare(a.Score, b.Score)
|
||||
})
|
||||
maxScore.Score--
|
||||
mhr.LastUpdateTime = time.Now()
|
||||
return maxScore.Mode, maxScore.Index
|
||||
|
@ -17,9 +17,8 @@ package nathole
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"slices"
|
||||
"strconv"
|
||||
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -59,7 +58,7 @@ func ClassifyNATFeature(addresses []string, localIPs []string) (*NatFeature, err
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if lo.Contains(localIPs, ip) {
|
||||
if slices.Contains(localIPs, ip) {
|
||||
natFeature.PublicNetwork = true
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net"
|
||||
"slices"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
@ -72,7 +73,7 @@ type Session struct {
|
||||
|
||||
func (s *Session) genAnalysisKey() {
|
||||
hash := md5.New()
|
||||
vIPs := lo.Uniq(parseIPs(s.visitorMsg.MappedAddrs))
|
||||
vIPs := slices.Compact(parseIPs(s.visitorMsg.MappedAddrs))
|
||||
if len(vIPs) > 0 {
|
||||
hash.Write([]byte(vIPs[0]))
|
||||
}
|
||||
@ -80,7 +81,7 @@ func (s *Session) genAnalysisKey() {
|
||||
hash.Write([]byte(s.vNatFeature.Behavior))
|
||||
hash.Write([]byte(strconv.FormatBool(s.vNatFeature.RegularPortsChange)))
|
||||
|
||||
cIPs := lo.Uniq(parseIPs(s.clientMsg.MappedAddrs))
|
||||
cIPs := slices.Compact(parseIPs(s.clientMsg.MappedAddrs))
|
||||
if len(cIPs) > 0 {
|
||||
hash.Write([]byte(cIPs[0]))
|
||||
}
|
||||
@ -114,7 +115,7 @@ func (c *Controller) CleanWorker(ctx context.Context) {
|
||||
case <-ticker.C:
|
||||
start := time.Now()
|
||||
count, total := c.analyzer.Clean()
|
||||
log.Trace("clean %d/%d nathole analysis data, cost %v", count, total, time.Since(start))
|
||||
log.Tracef("clean %d/%d nathole analysis data, cost %v", count, total, time.Since(start))
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
@ -156,7 +157,7 @@ func (c *Controller) HandleVisitor(m *msg.NatHoleVisitor, transporter transport.
|
||||
_ = transporter.Send(c.GenNatHoleResponse(m.TransactionID, nil, fmt.Sprintf("xtcp server for [%s] doesn't exist", m.ProxyName)))
|
||||
return
|
||||
}
|
||||
if !lo.Contains(cfg.allowUsers, visitorUser) && !lo.Contains(cfg.allowUsers, "*") {
|
||||
if !slices.Contains(cfg.allowUsers, visitorUser) && !slices.Contains(cfg.allowUsers, "*") {
|
||||
_ = transporter.Send(c.GenNatHoleResponse(m.TransactionID, nil, fmt.Sprintf("xtcp visitor user [%s] not allowed for [%s]", visitorUser, m.ProxyName)))
|
||||
return
|
||||
}
|
||||
@ -190,11 +191,11 @@ func (c *Controller) HandleVisitor(m *msg.NatHoleVisitor, transporter transport.
|
||||
return nil
|
||||
}()
|
||||
if err != nil {
|
||||
log.Warn("handle visitorMsg error: %v", err)
|
||||
log.Warnf("handle visitorMsg error: %v", err)
|
||||
_ = transporter.Send(c.GenNatHoleResponse(m.TransactionID, nil, err.Error()))
|
||||
return
|
||||
}
|
||||
log.Trace("handle visitor message, sid [%s], server name: %s", sid, m.ProxyName)
|
||||
log.Tracef("handle visitor message, sid [%s], server name: %s", sid, m.ProxyName)
|
||||
|
||||
defer func() {
|
||||
c.mu.Lock()
|
||||
@ -212,14 +213,14 @@ func (c *Controller) HandleVisitor(m *msg.NatHoleVisitor, transporter transport.
|
||||
select {
|
||||
case <-session.notifyCh:
|
||||
case <-time.After(time.Duration(NatHoleTimeout) * time.Second):
|
||||
log.Debug("wait for NatHoleClient message timeout, sid [%s]", sid)
|
||||
log.Debugf("wait for NatHoleClient message timeout, sid [%s]", sid)
|
||||
return
|
||||
}
|
||||
|
||||
// Make hole-punching decisions based on the NAT information of the client and visitor.
|
||||
vResp, cResp, err := c.analysis(session)
|
||||
if err != nil {
|
||||
log.Debug("sid [%s] analysis error: %v", err)
|
||||
log.Debugf("sid [%s] analysis error: %v", err)
|
||||
vResp = c.GenNatHoleResponse(session.visitorMsg.TransactionID, nil, err.Error())
|
||||
cResp = c.GenNatHoleResponse(session.clientMsg.TransactionID, nil, err.Error())
|
||||
}
|
||||
@ -256,7 +257,7 @@ func (c *Controller) HandleClient(m *msg.NatHoleClient, transporter transport.Me
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
log.Trace("handle client message, sid [%s], server name: %s", session.sid, m.ProxyName)
|
||||
log.Tracef("handle client message, sid [%s], server name: %s", session.sid, m.ProxyName)
|
||||
session.clientMsg = m
|
||||
session.clientTransporter = transporter
|
||||
select {
|
||||
@ -270,13 +271,13 @@ func (c *Controller) HandleReport(m *msg.NatHoleReport) {
|
||||
session, ok := c.sessions[m.Sid]
|
||||
c.mu.RUnlock()
|
||||
if !ok {
|
||||
log.Trace("sid [%s] report make hole success: %v, but session not found", m.Sid, m.Success)
|
||||
log.Tracef("sid [%s] report make hole success: %v, but session not found", m.Sid, m.Success)
|
||||
return
|
||||
}
|
||||
if m.Success {
|
||||
c.analyzer.ReportSuccess(session.analysisKey, session.recommandMode, session.recommandIndex)
|
||||
}
|
||||
log.Info("sid [%s] report make hole success: %v, mode %v, index %v",
|
||||
log.Infof("sid [%s] report make hole success: %v, mode %v, index %v",
|
||||
m.Sid, m.Success, session.recommandMode, session.recommandIndex)
|
||||
}
|
||||
|
||||
@ -317,7 +318,7 @@ func (c *Controller) analysis(session *Session) (*msg.NatHoleResp, *msg.NatHoleR
|
||||
session.cBehavior = cBehavior
|
||||
session.vBehavior = vBehavior
|
||||
|
||||
timeoutMs := lo.Max([]int{cBehavior.SendDelayMs, vBehavior.SendDelayMs}) + 5000
|
||||
timeoutMs := max(cBehavior.SendDelayMs, vBehavior.SendDelayMs) + 5000
|
||||
if cBehavior.ListenRandomPorts > 0 || vBehavior.ListenRandomPorts > 0 {
|
||||
timeoutMs += 30000
|
||||
}
|
||||
@ -327,8 +328,8 @@ func (c *Controller) analysis(session *Session) (*msg.NatHoleResp, *msg.NatHoleR
|
||||
TransactionID: vm.TransactionID,
|
||||
Sid: session.sid,
|
||||
Protocol: protocol,
|
||||
CandidateAddrs: lo.Uniq(cm.MappedAddrs),
|
||||
AssistedAddrs: lo.Uniq(cm.AssistedAddrs),
|
||||
CandidateAddrs: slices.Compact(cm.MappedAddrs),
|
||||
AssistedAddrs: slices.Compact(cm.AssistedAddrs),
|
||||
DetectBehavior: msg.NatHoleDetectBehavior{
|
||||
Mode: mode,
|
||||
Role: vBehavior.Role,
|
||||
@ -344,8 +345,8 @@ func (c *Controller) analysis(session *Session) (*msg.NatHoleResp, *msg.NatHoleR
|
||||
TransactionID: cm.TransactionID,
|
||||
Sid: session.sid,
|
||||
Protocol: protocol,
|
||||
CandidateAddrs: lo.Uniq(vm.MappedAddrs),
|
||||
AssistedAddrs: lo.Uniq(vm.AssistedAddrs),
|
||||
CandidateAddrs: slices.Compact(vm.MappedAddrs),
|
||||
AssistedAddrs: slices.Compact(vm.AssistedAddrs),
|
||||
DetectBehavior: msg.NatHoleDetectBehavior{
|
||||
Mode: mode,
|
||||
Role: cBehavior.Role,
|
||||
@ -358,10 +359,10 @@ func (c *Controller) analysis(session *Session) (*msg.NatHoleResp, *msg.NatHoleR
|
||||
},
|
||||
}
|
||||
|
||||
log.Debug("sid [%s] visitor nat: %+v, candidateAddrs: %v; client nat: %+v, candidateAddrs: %v, protocol: %s",
|
||||
log.Debugf("sid [%s] visitor nat: %+v, candidateAddrs: %v; client nat: %+v, candidateAddrs: %v, protocol: %s",
|
||||
session.sid, *vNatFeature, vm.MappedAddrs, *cNatFeature, cm.MappedAddrs, protocol)
|
||||
log.Debug("sid [%s] visitor detect behavior: %+v", session.sid, vResp.DetectBehavior)
|
||||
log.Debug("sid [%s] client detect behavior: %+v", session.sid, cResp.DetectBehavior)
|
||||
log.Debugf("sid [%s] visitor detect behavior: %+v", session.sid, vResp.DetectBehavior)
|
||||
log.Debugf("sid [%s] client detect behavior: %+v", session.sid, cResp.DetectBehavior)
|
||||
return vResp, cResp, nil
|
||||
}
|
||||
|
||||
@ -384,8 +385,8 @@ func getRangePorts(addrs []string, difference, maxNumber int) []msg.PortsRange {
|
||||
return nil
|
||||
}
|
||||
ports = append(ports, msg.PortsRange{
|
||||
From: lo.Max([]int{port - difference - 5, port - maxNumber, 1}),
|
||||
To: lo.Min([]int{port + difference + 5, port + maxNumber, 65535}),
|
||||
From: max(port-difference-5, port-maxNumber, 1),
|
||||
To: min(port+difference+5, port+maxNumber, 65535),
|
||||
})
|
||||
return ports
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/pion/stun"
|
||||
"github.com/pion/stun/v2"
|
||||
)
|
||||
|
||||
var responseTimeout = 3 * time.Second
|
||||
|
@ -19,12 +19,12 @@ import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fatedier/golib/pool"
|
||||
"github.com/samber/lo"
|
||||
"golang.org/x/net/ipv4"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
|
||||
@ -204,7 +204,7 @@ func MakeHole(ctx context.Context, listenConn *net.UDPConn, m *msg.NatHoleResp,
|
||||
for i := 0; i < m.DetectBehavior.ListenRandomPorts; i++ {
|
||||
tmpConn, err := net.ListenUDP("udp4", nil)
|
||||
if err != nil {
|
||||
xl.Warn("listen random udp addr error: %v", err)
|
||||
xl.Warnf("listen random udp addr error: %v", err)
|
||||
continue
|
||||
}
|
||||
listenConns = append(listenConns, tmpConn)
|
||||
@ -212,11 +212,11 @@ func MakeHole(ctx context.Context, listenConn *net.UDPConn, m *msg.NatHoleResp,
|
||||
}
|
||||
}
|
||||
|
||||
detectAddrs = lo.Uniq(detectAddrs)
|
||||
detectAddrs = slices.Compact(detectAddrs)
|
||||
for _, detectAddr := range detectAddrs {
|
||||
for _, conn := range listenConns {
|
||||
if err := sendSidMessage(ctx, conn, m.Sid, transactionID, detectAddr, key, m.DetectBehavior.TTL); err != nil {
|
||||
xl.Trace("send sid message from %s to %s error: %v", conn.LocalAddr(), detectAddr, err)
|
||||
xl.Tracef("send sid message from %s to %s error: %v", conn.LocalAddr(), detectAddr, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -289,16 +289,16 @@ func waitDetectMessage(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
xl.Debug("get udp message local %s, from %s", conn.LocalAddr(), raddr)
|
||||
xl.Debugf("get udp message local %s, from %s", conn.LocalAddr(), raddr)
|
||||
var m msg.NatHoleSid
|
||||
if err := DecodeMessageInto(buf[:n], key, &m); err != nil {
|
||||
xl.Warn("decode sid message error: %v", err)
|
||||
xl.Warnf("decode sid message error: %v", err)
|
||||
continue
|
||||
}
|
||||
pool.PutBuf(buf)
|
||||
|
||||
if m.Sid != sid {
|
||||
xl.Warn("get sid message with wrong sid: %s, expect: %s", m.Sid, sid)
|
||||
xl.Warnf("get sid message with wrong sid: %s, expect: %s", m.Sid, sid)
|
||||
continue
|
||||
}
|
||||
|
||||
@ -311,7 +311,7 @@ func waitDetectMessage(
|
||||
m.Response = true
|
||||
buf2, err := EncodeMessage(&m, key)
|
||||
if err != nil {
|
||||
xl.Warn("encode sid message error: %v", err)
|
||||
xl.Warnf("encode sid message error: %v", err)
|
||||
continue
|
||||
}
|
||||
_, _ = conn.WriteToUDP(buf2, raddr)
|
||||
@ -329,7 +329,7 @@ func sendSidMessage(
|
||||
if ttl > 0 {
|
||||
ttlStr = fmt.Sprintf(" with ttl %d", ttl)
|
||||
}
|
||||
xl.Trace("send sid message from %s to %s%s", conn.LocalAddr(), addr, ttlStr)
|
||||
xl.Tracef("send sid message from %s to %s%s", conn.LocalAddr(), addr, ttlStr)
|
||||
raddr, err := net.ResolveUDPAddr("udp4", addr)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -351,14 +351,14 @@ func sendSidMessage(
|
||||
uConn := ipv4.NewConn(conn)
|
||||
original, err := uConn.TTL()
|
||||
if err != nil {
|
||||
xl.Trace("get ttl error %v", err)
|
||||
xl.Tracef("get ttl error %v", err)
|
||||
return err
|
||||
}
|
||||
xl.Trace("original ttl %d", original)
|
||||
xl.Tracef("original ttl %d", original)
|
||||
|
||||
err = uConn.SetTTL(ttl)
|
||||
if err != nil {
|
||||
xl.Trace("set ttl error %v", err)
|
||||
xl.Tracef("set ttl error %v", err)
|
||||
} else {
|
||||
defer func() {
|
||||
_ = uConn.SetTTL(original)
|
||||
@ -377,12 +377,12 @@ func sendSidMessageToRangePorts(
|
||||
sendFunc func(*net.UDPConn, string) error,
|
||||
) {
|
||||
xl := xlog.FromContextSafe(ctx)
|
||||
for _, ip := range lo.Uniq(parseIPs(addrs)) {
|
||||
for _, ip := range slices.Compact(parseIPs(addrs)) {
|
||||
for _, portsRange := range ports {
|
||||
for i := portsRange.From; i <= portsRange.To; i++ {
|
||||
detectAddr := net.JoinHostPort(ip, strconv.Itoa(i))
|
||||
if err := sendFunc(conn, detectAddr); err != nil {
|
||||
xl.Trace("send sid message from %s to %s error: %v", conn.LocalAddr(), detectAddr, err)
|
||||
xl.Tracef("send sid message from %s to %s error: %v", conn.LocalAddr(), detectAddr, err)
|
||||
}
|
||||
time.Sleep(2 * time.Millisecond)
|
||||
}
|
||||
@ -419,10 +419,10 @@ func sendSidMessageToRandomPorts(
|
||||
continue
|
||||
}
|
||||
|
||||
for _, ip := range lo.Uniq(parseIPs(addrs)) {
|
||||
for _, ip := range slices.Compact(parseIPs(addrs)) {
|
||||
detectAddr := net.JoinHostPort(ip, strconv.Itoa(port))
|
||||
if err := sendFunc(conn, detectAddr); err != nil {
|
||||
xl.Trace("send sid message from %s to %s error: %v", conn.LocalAddr(), detectAddr, err)
|
||||
xl.Tracef("send sid message from %s to %s error: %v", conn.LocalAddr(), detectAddr, err)
|
||||
}
|
||||
time.Sleep(time.Millisecond * 15)
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/fatedier/golib/crypto"
|
||||
"github.com/pion/stun"
|
||||
"github.com/pion/stun/v2"
|
||||
|
||||
"github.com/fatedier/frp/pkg/msg"
|
||||
)
|
||||
|
@ -53,7 +53,8 @@ func NewHTTP2HTTPSPlugin(options v1.ClientPluginOptions) (Plugin, error) {
|
||||
}
|
||||
|
||||
rp := &httputil.ReverseProxy{
|
||||
Director: func(req *http.Request) {
|
||||
Rewrite: func(r *httputil.ProxyRequest) {
|
||||
req := r.Out
|
||||
req.URL.Scheme = "https"
|
||||
req.URL.Host = p.opts.LocalAddr
|
||||
if p.opts.HostHeaderRewrite != "" {
|
||||
|
@ -50,7 +50,8 @@ func NewHTTPS2HTTPPlugin(options v1.ClientPluginOptions) (Plugin, error) {
|
||||
}
|
||||
|
||||
rp := &httputil.ReverseProxy{
|
||||
Director: func(req *http.Request) {
|
||||
Rewrite: func(r *httputil.ProxyRequest) {
|
||||
req := r.Out
|
||||
req.URL.Scheme = "http"
|
||||
req.URL.Host = p.opts.LocalAddr
|
||||
if p.opts.HostHeaderRewrite != "" {
|
||||
|
@ -55,7 +55,8 @@ func NewHTTPS2HTTPSPlugin(options v1.ClientPluginOptions) (Plugin, error) {
|
||||
}
|
||||
|
||||
rp := &httputil.ReverseProxy{
|
||||
Director: func(req *http.Request) {
|
||||
Rewrite: func(r *httputil.ProxyRequest) {
|
||||
req := r.Out
|
||||
req.URL.Scheme = "https"
|
||||
req.URL.Host = p.opts.LocalAddr
|
||||
if p.opts.HostHeaderRewrite != "" {
|
||||
|
@ -86,7 +86,7 @@ func (m *Manager) Login(content *LoginContent) (*LoginContent, error) {
|
||||
for _, p := range m.loginPlugins {
|
||||
res, retContent, err = p.Handle(ctx, OpLogin, *content)
|
||||
if err != nil {
|
||||
xl.Warn("send Login request to plugin [%s] error: %v", p.Name(), err)
|
||||
xl.Warnf("send Login request to plugin [%s] error: %v", p.Name(), err)
|
||||
return nil, errors.New("send Login request to plugin error")
|
||||
}
|
||||
if res.Reject {
|
||||
@ -120,7 +120,7 @@ func (m *Manager) NewProxy(content *NewProxyContent) (*NewProxyContent, error) {
|
||||
for _, p := range m.newProxyPlugins {
|
||||
res, retContent, err = p.Handle(ctx, OpNewProxy, *content)
|
||||
if err != nil {
|
||||
xl.Warn("send NewProxy request to plugin [%s] error: %v", p.Name(), err)
|
||||
xl.Warnf("send NewProxy request to plugin [%s] error: %v", p.Name(), err)
|
||||
return nil, errors.New("send NewProxy request to plugin error")
|
||||
}
|
||||
if res.Reject {
|
||||
@ -147,7 +147,7 @@ func (m *Manager) CloseProxy(content *CloseProxyContent) error {
|
||||
for _, p := range m.closeProxyPlugins {
|
||||
_, _, err := p.Handle(ctx, OpCloseProxy, *content)
|
||||
if err != nil {
|
||||
xl.Warn("send CloseProxy request to plugin [%s] error: %v", p.Name(), err)
|
||||
xl.Warnf("send CloseProxy request to plugin [%s] error: %v", p.Name(), err)
|
||||
errs = append(errs, fmt.Sprintf("[%s]: %v", p.Name(), err))
|
||||
}
|
||||
}
|
||||
@ -179,7 +179,7 @@ func (m *Manager) Ping(content *PingContent) (*PingContent, error) {
|
||||
for _, p := range m.pingPlugins {
|
||||
res, retContent, err = p.Handle(ctx, OpPing, *content)
|
||||
if err != nil {
|
||||
xl.Warn("send Ping request to plugin [%s] error: %v", p.Name(), err)
|
||||
xl.Warnf("send Ping request to plugin [%s] error: %v", p.Name(), err)
|
||||
return nil, errors.New("send Ping request to plugin error")
|
||||
}
|
||||
if res.Reject {
|
||||
@ -213,7 +213,7 @@ func (m *Manager) NewWorkConn(content *NewWorkConnContent) (*NewWorkConnContent,
|
||||
for _, p := range m.newWorkConnPlugins {
|
||||
res, retContent, err = p.Handle(ctx, OpNewWorkConn, *content)
|
||||
if err != nil {
|
||||
xl.Warn("send NewWorkConn request to plugin [%s] error: %v", p.Name(), err)
|
||||
xl.Warnf("send NewWorkConn request to plugin [%s] error: %v", p.Name(), err)
|
||||
return nil, errors.New("send NewWorkConn request to plugin error")
|
||||
}
|
||||
if res.Reject {
|
||||
@ -247,7 +247,7 @@ func (m *Manager) NewUserConn(content *NewUserConnContent) (*NewUserConnContent,
|
||||
for _, p := range m.newUserConnPlugins {
|
||||
res, retContent, err = p.Handle(ctx, OpNewUserConn, *content)
|
||||
if err != nil {
|
||||
xl.Info("send NewUserConn request to plugin [%s] error: %v", p.Name(), err)
|
||||
xl.Infof("send NewUserConn request to plugin [%s] error: %v", p.Name(), err)
|
||||
return nil, errors.New("send NewUserConn request to plugin error")
|
||||
}
|
||||
if res.Reject {
|
||||
|
@ -75,7 +75,7 @@ func NewGateway(
|
||||
sshConfig.PublicKeyCallback = func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) {
|
||||
authorizedKeysMap, err := loadAuthorizedKeysFromFile(cfg.AuthorizedKeysFile)
|
||||
if err != nil {
|
||||
log.Error("load authorized keys file error: %v", err)
|
||||
log.Errorf("load authorized keys file error: %v", err)
|
||||
return nil, fmt.Errorf("internal error")
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ func (g *Gateway) handleConn(conn net.Conn) {
|
||||
return
|
||||
}
|
||||
if err := ts.Run(); err != nil {
|
||||
log.Error("ssh tunnel server run error: %v", err)
|
||||
log.Errorf("ssh tunnel server run error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,12 +20,12 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
libio "github.com/fatedier/golib/io"
|
||||
"github.com/samber/lo"
|
||||
"github.com/spf13/cobra"
|
||||
flag "github.com/spf13/pflag"
|
||||
"golang.org/x/crypto/ssh"
|
||||
@ -123,7 +123,7 @@ func (s *TunnelServer) Run() error {
|
||||
// join workConn and ssh channel
|
||||
c, err := s.openConn(addr)
|
||||
if err != nil {
|
||||
log.Trace("open conn error: %v", err)
|
||||
log.Tracef("open conn error: %v", err)
|
||||
workConn.Close()
|
||||
return false
|
||||
}
|
||||
@ -167,7 +167,7 @@ func (s *TunnelServer) Run() error {
|
||||
|
||||
if ps, err := s.waitProxyStatusReady(pc.GetBaseConfig().Name, time.Second); err != nil {
|
||||
s.writeToClient(err.Error())
|
||||
log.Warn("wait proxy status ready error: %v", err)
|
||||
log.Warnf("wait proxy status ready error: %v", err)
|
||||
} else {
|
||||
// success
|
||||
s.writeToClient(createSuccessInfo(clientCfg.User, pc, ps))
|
||||
@ -175,7 +175,7 @@ func (s *TunnelServer) Run() error {
|
||||
}
|
||||
|
||||
s.vc.Close()
|
||||
log.Trace("ssh tunnel connection from %v closed", sshConn.RemoteAddr())
|
||||
log.Tracef("ssh tunnel connection from %v closed", sshConn.RemoteAddr())
|
||||
s.closeDoneChOnce.Do(func() {
|
||||
_ = sshConn.Close()
|
||||
close(s.doneCh)
|
||||
@ -262,7 +262,7 @@ func (s *TunnelServer) parseClientAndProxyConfigurer(_ *tcpipForward, extraPaylo
|
||||
}
|
||||
proxyType := strings.TrimSpace(args[0])
|
||||
supportTypes := []string{"tcp", "http", "https", "tcpmux", "stcp"}
|
||||
if !lo.Contains(supportTypes, proxyType) {
|
||||
if !slices.Contains(supportTypes, proxyType) {
|
||||
return nil, nil, helpMessage, fmt.Errorf("invalid proxy type: %s, support types: %v", proxyType, supportTypes)
|
||||
}
|
||||
pc := v1.NewProxyConfigurerByType(v1.ProxyType(proxyType))
|
||||
|
@ -15,78 +15,65 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/fatedier/beego/logs"
|
||||
"github.com/fatedier/golib/log"
|
||||
)
|
||||
|
||||
// Log is the under log object
|
||||
var Log *logs.BeeLogger
|
||||
var Logger *log.Logger
|
||||
|
||||
func init() {
|
||||
Log = logs.NewLogger(200)
|
||||
Log.EnableFuncCallDepth(true)
|
||||
Log.SetLogFuncCallDepth(Log.GetLogFuncCallDepth() + 1)
|
||||
Logger = log.New(
|
||||
log.WithCaller(true),
|
||||
log.AddCallerSkip(1),
|
||||
log.WithLevel(log.InfoLevel),
|
||||
)
|
||||
}
|
||||
|
||||
func InitLog(logFile string, logLevel string, maxdays int64, disableLogColor bool) {
|
||||
SetLogFile(logFile, maxdays, disableLogColor)
|
||||
SetLogLevel(logLevel)
|
||||
}
|
||||
|
||||
// SetLogFile to configure log params
|
||||
func SetLogFile(logFile string, maxdays int64, disableLogColor bool) {
|
||||
if logFile == "console" {
|
||||
params := ""
|
||||
if disableLogColor {
|
||||
params = `{"color": false}`
|
||||
func InitLogger(logPath string, levelStr string, maxDays int, disableLogColor bool) {
|
||||
options := []log.Option{}
|
||||
if logPath == "console" {
|
||||
if !disableLogColor {
|
||||
options = append(options,
|
||||
log.WithOutput(log.NewConsoleWriter(log.ConsoleConfig{
|
||||
Colorful: true,
|
||||
}, os.Stdout)),
|
||||
)
|
||||
}
|
||||
_ = Log.SetLogger("console", params)
|
||||
} else {
|
||||
params := fmt.Sprintf(`{"filename": "%s", "maxdays": %d}`, logFile, maxdays)
|
||||
_ = Log.SetLogger("file", params)
|
||||
writer := log.NewRotateFileWriter(log.RotateFileConfig{
|
||||
FileName: logPath,
|
||||
Mode: log.RotateFileModeDaily,
|
||||
MaxDays: maxDays,
|
||||
})
|
||||
writer.Init()
|
||||
options = append(options, log.WithOutput(writer))
|
||||
}
|
||||
}
|
||||
|
||||
// SetLogLevel set log level, default is warning
|
||||
// value: error, warning, info, debug, trace
|
||||
func SetLogLevel(logLevel string) {
|
||||
var level int
|
||||
switch logLevel {
|
||||
case "error":
|
||||
level = 3
|
||||
case "warn":
|
||||
level = 4
|
||||
case "info":
|
||||
level = 6
|
||||
case "debug":
|
||||
level = 7
|
||||
case "trace":
|
||||
level = 8
|
||||
default:
|
||||
level = 4 // warning
|
||||
level, err := log.ParseLevel(levelStr)
|
||||
if err != nil {
|
||||
level = log.InfoLevel
|
||||
}
|
||||
Log.SetLevel(level)
|
||||
options = append(options, log.WithLevel(level))
|
||||
Logger = Logger.WithOptions(options...)
|
||||
}
|
||||
|
||||
// wrap log
|
||||
|
||||
func Error(format string, v ...interface{}) {
|
||||
Log.Error(format, v...)
|
||||
func Errorf(format string, v ...interface{}) {
|
||||
Logger.Errorf(format, v...)
|
||||
}
|
||||
|
||||
func Warn(format string, v ...interface{}) {
|
||||
Log.Warn(format, v...)
|
||||
func Warnf(format string, v ...interface{}) {
|
||||
Logger.Warnf(format, v...)
|
||||
}
|
||||
|
||||
func Info(format string, v ...interface{}) {
|
||||
Log.Info(format, v...)
|
||||
func Infof(format string, v ...interface{}) {
|
||||
Logger.Infof(format, v...)
|
||||
}
|
||||
|
||||
func Debug(format string, v ...interface{}) {
|
||||
Log.Debug(format, v...)
|
||||
func Debugf(format string, v ...interface{}) {
|
||||
Logger.Debugf(format, v...)
|
||||
}
|
||||
|
||||
func Trace(format string, v ...interface{}) {
|
||||
Log.Trace(format, v...)
|
||||
func Tracef(format string, v ...interface{}) {
|
||||
Logger.Tracef(format, v...)
|
||||
}
|
||||
|
@ -24,30 +24,6 @@ import (
|
||||
"github.com/fatedier/frp/pkg/util/util"
|
||||
)
|
||||
|
||||
type HTTPAuthWrapper struct {
|
||||
h http.Handler
|
||||
user string
|
||||
passwd string
|
||||
}
|
||||
|
||||
func NewHTTPBasicAuthWrapper(h http.Handler, user, passwd string) http.Handler {
|
||||
return &HTTPAuthWrapper{
|
||||
h: h,
|
||||
user: user,
|
||||
passwd: passwd,
|
||||
}
|
||||
}
|
||||
|
||||
func (aw *HTTPAuthWrapper) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
user, passwd, hasAuth := r.BasicAuth()
|
||||
if (aw.user == "" && aw.passwd == "") || (hasAuth && user == aw.user && passwd == aw.passwd) {
|
||||
aw.h.ServeHTTP(w, r)
|
||||
} else {
|
||||
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
|
||||
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
|
||||
}
|
||||
}
|
||||
|
||||
type HTTPAuthMiddleware struct {
|
||||
user string
|
||||
passwd string
|
||||
|
@ -18,7 +18,7 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
kcp "github.com/fatedier/kcp-go"
|
||||
kcp "github.com/xtaci/kcp-go/v5"
|
||||
)
|
||||
|
||||
type KCPListener struct {
|
||||
@ -85,7 +85,15 @@ func (l *KCPListener) Addr() net.Addr {
|
||||
}
|
||||
|
||||
func NewKCPConnFromUDP(conn *net.UDPConn, connected bool, raddr string) (net.Conn, error) {
|
||||
kcpConn, err := kcp.NewConnEx(1, connected, raddr, nil, 10, 3, conn)
|
||||
udpAddr, err := net.ResolveUDPAddr("udp", raddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var pConn net.PacketConn = conn
|
||||
if connected {
|
||||
pConn = &ConnectedUDPConn{conn}
|
||||
}
|
||||
kcpConn, err := kcp.NewConn3(1, udpAddr, nil, 10, 3, pConn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"errors"
|
||||
"net"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"golang.org/x/net/websocket"
|
||||
)
|
||||
@ -50,15 +49,6 @@ func NewWebsocketListener(ln net.Listener) (wl *WebsocketListener) {
|
||||
return
|
||||
}
|
||||
|
||||
func ListenWebsocket(bindAddr string, bindPort int) (*WebsocketListener, error) {
|
||||
tcpLn, err := net.Listen("tcp", net.JoinHostPort(bindAddr, strconv.Itoa(bindPort)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
l := NewWebsocketListener(tcpLn)
|
||||
return l, nil
|
||||
}
|
||||
|
||||
func (p *WebsocketListener) Accept() (net.Conn, error) {
|
||||
c, ok := <-p.acceptCh
|
||||
if !ok {
|
||||
|
@ -47,16 +47,6 @@ func RandIDWithLen(idLen int) (id string, err error) {
|
||||
return id[:idLen], nil
|
||||
}
|
||||
|
||||
// RandIDWithRandLen return a rand string with length between [start, end).
|
||||
func RandIDWithRandLen(start, end int) (id string, err error) {
|
||||
if start >= end {
|
||||
err = fmt.Errorf("start should be less than end")
|
||||
return
|
||||
}
|
||||
idLen := mathrand.Intn(end-start) + start
|
||||
return RandIDWithLen(idLen)
|
||||
}
|
||||
|
||||
func GetAuthKey(token string, timestamp int64) (key string) {
|
||||
md5Ctx := md5.New()
|
||||
md5Ctx.Write([]byte(token))
|
||||
|
@ -14,48 +14,6 @@ func TestRandId(t *testing.T) {
|
||||
assert.Equal(16, len(id))
|
||||
}
|
||||
|
||||
func TestRandIDWithRandLen(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
start int
|
||||
end int
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
name: "start and end are equal",
|
||||
start: 5,
|
||||
end: 5,
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
name: "start is less than end",
|
||||
start: 5,
|
||||
end: 10,
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
name: "start is greater than end",
|
||||
start: 10,
|
||||
end: 5,
|
||||
expectErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
id, err := RandIDWithRandLen(tt.start, tt.end)
|
||||
if tt.expectErr {
|
||||
assert.Error(err)
|
||||
} else {
|
||||
assert.NoError(err)
|
||||
assert.GreaterOrEqual(len(id), tt.start)
|
||||
assert.Less(len(id), tt.end)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAuthKey(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
key := GetAuthKey("1234", 1488720000)
|
||||
|
@ -14,34 +14,8 @@
|
||||
|
||||
package version
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var version = "0.54.0"
|
||||
var version = "0.55.0"
|
||||
|
||||
func Full() string {
|
||||
return version
|
||||
}
|
||||
|
||||
func getSubVersion(v string, position int) int64 {
|
||||
arr := strings.Split(v, ".")
|
||||
if len(arr) < 3 {
|
||||
return 0
|
||||
}
|
||||
res, _ := strconv.ParseInt(arr[position], 10, 64)
|
||||
return res
|
||||
}
|
||||
|
||||
func Proto(v string) int64 {
|
||||
return getSubVersion(v, 0)
|
||||
}
|
||||
|
||||
func Major(v string) int64 {
|
||||
return getSubVersion(v, 1)
|
||||
}
|
||||
|
||||
func Minor(v string) int64 {
|
||||
return getSubVersion(v, 2)
|
||||
}
|
||||
|
@ -1,53 +0,0 @@
|
||||
// Copyright 2016 fatedier, fatedier@gmail.com
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package version
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestFull(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
version := Full()
|
||||
arr := strings.Split(version, ".")
|
||||
assert.Equal(3, len(arr))
|
||||
|
||||
proto, err := strconv.ParseInt(arr[0], 10, 64)
|
||||
assert.NoError(err)
|
||||
assert.True(proto >= 0)
|
||||
|
||||
major, err := strconv.ParseInt(arr[1], 10, 64)
|
||||
assert.NoError(err)
|
||||
assert.True(major >= 0)
|
||||
|
||||
minor, err := strconv.ParseInt(arr[2], 10, 64)
|
||||
assert.NoError(err)
|
||||
assert.True(minor >= 0)
|
||||
}
|
||||
|
||||
func TestVersion(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
proto := Proto(Full())
|
||||
major := Major(Full())
|
||||
minor := Minor(Full())
|
||||
parseVersion := fmt.Sprintf("%d.%d.%d", proto, major, minor)
|
||||
version := Full()
|
||||
assert.Equal(parseVersion, version)
|
||||
}
|
@ -20,7 +20,7 @@ import (
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
stdlog "log"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
@ -32,7 +32,7 @@ import (
|
||||
"github.com/fatedier/golib/pool"
|
||||
|
||||
httppkg "github.com/fatedier/frp/pkg/util/http"
|
||||
logpkg "github.com/fatedier/frp/pkg/util/log"
|
||||
"github.com/fatedier/frp/pkg/util/log"
|
||||
)
|
||||
|
||||
var ErrNoRouteFound = errors.New("no route found")
|
||||
@ -58,7 +58,9 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) *
|
||||
}
|
||||
proxy := &httputil.ReverseProxy{
|
||||
// Modify incoming requests by route policies.
|
||||
Director: func(req *http.Request) {
|
||||
Rewrite: func(r *httputil.ProxyRequest) {
|
||||
r.SetXForwarded()
|
||||
req := r.Out
|
||||
req.URL.Scheme = "http"
|
||||
reqRouteInfo := req.Context().Value(RouteInfoKey).(*RequestRouteInfo)
|
||||
oldHost, _ := httppkg.CanonicalHost(reqRouteInfo.Host)
|
||||
@ -74,7 +76,7 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) *
|
||||
// ignore error here, it will use CreateConnFn instead later
|
||||
endpoint, _ = rc.ChooseEndpointFn()
|
||||
reqRouteInfo.Endpoint = endpoint
|
||||
logpkg.Trace("choose endpoint name [%s] for http request host [%s] path [%s] httpuser [%s]",
|
||||
log.Tracef("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.
|
||||
@ -114,9 +116,9 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) *
|
||||
},
|
||||
},
|
||||
BufferPool: newWrapPool(),
|
||||
ErrorLog: log.New(newWrapLogger(), "", 0),
|
||||
ErrorLog: stdlog.New(newWrapLogger(), "", 0),
|
||||
ErrorHandler: func(rw http.ResponseWriter, req *http.Request, err error) {
|
||||
logpkg.Warn("do http proxy request [host: %s] error: %v", req.Host, err)
|
||||
log.Warnf("do http proxy request [host: %s] error: %v", req.Host, err)
|
||||
rw.WriteHeader(http.StatusNotFound)
|
||||
_, _ = rw.Write(getNotFoundPageContent())
|
||||
},
|
||||
@ -143,7 +145,7 @@ func (rp *HTTPReverseProxy) UnRegister(routeCfg RouteConfig) {
|
||||
func (rp *HTTPReverseProxy) GetRouteConfig(domain, location, routeByHTTPUser string) *RouteConfig {
|
||||
vr, ok := rp.getVhost(domain, location, routeByHTTPUser)
|
||||
if ok {
|
||||
logpkg.Debug("get new HTTP request host [%s] path [%s] httpuser [%s]", domain, location, routeByHTTPUser)
|
||||
log.Debugf("get new HTTP request host [%s] path [%s] httpuser [%s]", domain, location, routeByHTTPUser)
|
||||
return vr.payload.(*RouteConfig)
|
||||
}
|
||||
return nil
|
||||
@ -333,6 +335,6 @@ type wrapLogger struct{}
|
||||
func newWrapLogger() *wrapLogger { return &wrapLogger{} }
|
||||
|
||||
func (l *wrapLogger) Write(p []byte) (n int, err error) {
|
||||
logpkg.Warn("%s", string(bytes.TrimRight(p, "\n")))
|
||||
log.Warnf("%s", string(bytes.TrimRight(p, "\n")))
|
||||
return len(p), nil
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
logpkg "github.com/fatedier/frp/pkg/util/log"
|
||||
"github.com/fatedier/frp/pkg/util/log"
|
||||
"github.com/fatedier/frp/pkg/util/version"
|
||||
)
|
||||
|
||||
@ -58,7 +58,7 @@ func getNotFoundPageContent() []byte {
|
||||
if NotFoundPagePath != "" {
|
||||
buf, err = os.ReadFile(NotFoundPagePath)
|
||||
if err != nil {
|
||||
logpkg.Warn("read custom 404 page error: %v", err)
|
||||
log.Warnf("read custom 404 page error: %v", err)
|
||||
buf = []byte(NotFound)
|
||||
}
|
||||
} else {
|
||||
|
@ -1,8 +1,9 @@
|
||||
package vhost
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"errors"
|
||||
"sort"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
@ -58,7 +59,10 @@ func (r *Routers) Add(domain, location, httpUser string, payload interface{}) er
|
||||
payload: payload,
|
||||
}
|
||||
vrs = append(vrs, vr)
|
||||
sort.Sort(sort.Reverse(ByLocation(vrs)))
|
||||
|
||||
slices.SortFunc(vrs, func(a, b *Router) int {
|
||||
return -cmp.Compare(a.location, b.location)
|
||||
})
|
||||
|
||||
routersByHTTPUser[httpUser] = vrs
|
||||
r.indexByDomain[domain] = routersByHTTPUser
|
||||
@ -130,18 +134,3 @@ func (r *Routers) exist(host, path, httpUser string) (route *Router, exist bool)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// sort by location
|
||||
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
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ func (v *Muxer) handle(c net.Conn) {
|
||||
|
||||
sConn, reqInfoMap, err := v.vhostFunc(c)
|
||||
if err != nil {
|
||||
log.Debug("get hostname from http/https request error: %v", err)
|
||||
log.Debugf("get hostname from http/https request error: %v", err)
|
||||
_ = c.Close()
|
||||
return
|
||||
}
|
||||
@ -213,7 +213,7 @@ func (v *Muxer) handle(c net.Conn) {
|
||||
httpUser := reqInfoMap["HTTPUser"]
|
||||
l, ok := v.getListener(name, path, httpUser)
|
||||
if !ok {
|
||||
log.Debug("http request for host [%s] path [%s] httpUser [%s] not found", name, path, httpUser)
|
||||
log.Debugf("http request for host [%s] path [%s] httpUser [%s] not found", name, path, httpUser)
|
||||
v.failHook(sConn)
|
||||
return
|
||||
}
|
||||
@ -221,7 +221,7 @@ func (v *Muxer) handle(c net.Conn) {
|
||||
xl := xlog.FromContextSafe(l.ctx)
|
||||
if v.successHook != nil {
|
||||
if err := v.successHook(c, reqInfoMap); err != nil {
|
||||
xl.Info("success func failure on vhost connection: %v", err)
|
||||
xl.Infof("success func failure on vhost connection: %v", err)
|
||||
_ = c.Close()
|
||||
return
|
||||
}
|
||||
@ -232,7 +232,7 @@ func (v *Muxer) handle(c net.Conn) {
|
||||
if l.mux.checkAuth != nil && l.username != "" {
|
||||
ok, err := l.mux.checkAuth(c, l.username, l.password, reqInfoMap)
|
||||
if !ok || err != nil {
|
||||
xl.Debug("auth failed for user: %s", l.username)
|
||||
xl.Debugf("auth failed for user: %s", l.username)
|
||||
_ = c.Close()
|
||||
return
|
||||
}
|
||||
@ -244,12 +244,12 @@ func (v *Muxer) handle(c net.Conn) {
|
||||
}
|
||||
c = sConn
|
||||
|
||||
xl.Debug("new request host [%s] path [%s] httpUser [%s]", name, path, httpUser)
|
||||
xl.Debugf("new request host [%s] path [%s] httpUser [%s]", name, path, httpUser)
|
||||
err = errors.PanicToError(func() {
|
||||
l.accept <- c
|
||||
})
|
||||
if err != nil {
|
||||
xl.Warn("listener is already closed, ignore this request")
|
||||
xl.Warnf("listener is already closed, ignore this request")
|
||||
}
|
||||
}
|
||||
|
||||
@ -278,10 +278,10 @@ func (l *Listener) Accept() (net.Conn, error) {
|
||||
if l.mux.rewriteHost != nil {
|
||||
sConn, err := l.mux.rewriteHost(conn, l.rewriteHost)
|
||||
if err != nil {
|
||||
xl.Warn("host header rewrite failed: %v", err)
|
||||
xl.Warnf("host header rewrite failed: %v", err)
|
||||
return nil, fmt.Errorf("host header rewrite failed")
|
||||
}
|
||||
xl.Debug("rewrite host to [%s] success", l.rewriteHost)
|
||||
xl.Debugf("rewrite host to [%s] success", l.rewriteHost)
|
||||
conn = sConn
|
||||
}
|
||||
return netpkg.NewContextConn(l.ctx, conn), nil
|
||||
|
@ -16,7 +16,6 @@ package wait
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/fatedier/frp/pkg/util/util"
|
||||
@ -174,21 +173,3 @@ func Until(f func(), period time.Duration, stopCh <-chan struct{}) {
|
||||
return period
|
||||
}), true, stopCh)
|
||||
}
|
||||
|
||||
func MergeAndCloseOnAnyStopChannel[T any](upstreams ...<-chan T) <-chan T {
|
||||
out := make(chan T)
|
||||
closeOnce := sync.Once{}
|
||||
for _, upstream := range upstreams {
|
||||
ch := upstream
|
||||
go func() {
|
||||
select {
|
||||
case <-ch:
|
||||
closeOnce.Do(func() {
|
||||
close(out)
|
||||
})
|
||||
case <-out:
|
||||
}
|
||||
}()
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
@ -15,7 +15,8 @@
|
||||
package xlog
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"cmp"
|
||||
"slices"
|
||||
|
||||
"github.com/fatedier/frp/pkg/util/log"
|
||||
)
|
||||
@ -77,8 +78,8 @@ func (l *Logger) AddPrefix(prefix LogPrefix) *Logger {
|
||||
}
|
||||
|
||||
func (l *Logger) renderPrefixString() {
|
||||
sort.SliceStable(l.prefixes, func(i, j int) bool {
|
||||
return l.prefixes[i].Priority < l.prefixes[j].Priority
|
||||
slices.SortStableFunc(l.prefixes, func(a, b LogPrefix) int {
|
||||
return cmp.Compare(a.Priority, b.Priority)
|
||||
})
|
||||
l.prefixString = ""
|
||||
for _, v := range l.prefixes {
|
||||
@ -93,22 +94,22 @@ func (l *Logger) Spawn() *Logger {
|
||||
return nl
|
||||
}
|
||||
|
||||
func (l *Logger) Error(format string, v ...interface{}) {
|
||||
log.Log.Error(l.prefixString+format, v...)
|
||||
func (l *Logger) Errorf(format string, v ...interface{}) {
|
||||
log.Logger.Errorf(l.prefixString+format, v...)
|
||||
}
|
||||
|
||||
func (l *Logger) Warn(format string, v ...interface{}) {
|
||||
log.Log.Warn(l.prefixString+format, v...)
|
||||
func (l *Logger) Warnf(format string, v ...interface{}) {
|
||||
log.Logger.Warnf(l.prefixString+format, v...)
|
||||
}
|
||||
|
||||
func (l *Logger) Info(format string, v ...interface{}) {
|
||||
log.Log.Info(l.prefixString+format, v...)
|
||||
func (l *Logger) Infof(format string, v ...interface{}) {
|
||||
log.Logger.Infof(l.prefixString+format, v...)
|
||||
}
|
||||
|
||||
func (l *Logger) Debug(format string, v ...interface{}) {
|
||||
log.Log.Debug(l.prefixString+format, v...)
|
||||
func (l *Logger) Debugf(format string, v ...interface{}) {
|
||||
log.Logger.Debugf(l.prefixString+format, v...)
|
||||
}
|
||||
|
||||
func (l *Logger) Trace(format string, v ...interface{}) {
|
||||
log.Log.Trace(l.prefixString+format, v...)
|
||||
func (l *Logger) Tracef(format string, v ...interface{}) {
|
||||
log.Logger.Tracef(l.prefixString+format, v...)
|
||||
}
|
||||
|
@ -224,7 +224,7 @@ func (ctl *Control) Close() error {
|
||||
|
||||
func (ctl *Control) Replaced(newCtl *Control) {
|
||||
xl := ctl.xl
|
||||
xl.Info("Replaced by client [%s]", newCtl.runID)
|
||||
xl.Infof("Replaced by client [%s]", newCtl.runID)
|
||||
ctl.runID = ""
|
||||
ctl.conn.Close()
|
||||
}
|
||||
@ -233,17 +233,17 @@ func (ctl *Control) RegisterWorkConn(conn net.Conn) error {
|
||||
xl := ctl.xl
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
xl.Error("panic error: %v", err)
|
||||
xl.Error(string(debug.Stack()))
|
||||
xl.Errorf("panic error: %v", err)
|
||||
xl.Errorf(string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
|
||||
select {
|
||||
case ctl.workConnCh <- conn:
|
||||
xl.Debug("new work connection registered")
|
||||
xl.Debugf("new work connection registered")
|
||||
return nil
|
||||
default:
|
||||
xl.Debug("work connection pool is full, discarding")
|
||||
xl.Debugf("work connection pool is full, discarding")
|
||||
return fmt.Errorf("work connection pool is full, discarding")
|
||||
}
|
||||
}
|
||||
@ -256,8 +256,8 @@ func (ctl *Control) GetWorkConn() (workConn net.Conn, err error) {
|
||||
xl := ctl.xl
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
xl.Error("panic error: %v", err)
|
||||
xl.Error(string(debug.Stack()))
|
||||
xl.Errorf("panic error: %v", err)
|
||||
xl.Errorf(string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
|
||||
@ -269,7 +269,7 @@ func (ctl *Control) GetWorkConn() (workConn net.Conn, err error) {
|
||||
err = pkgerr.ErrCtlClosed
|
||||
return
|
||||
}
|
||||
xl.Debug("get work connection from pool")
|
||||
xl.Debugf("get work connection from pool")
|
||||
default:
|
||||
// no work connections available in the poll, send message to frpc to get more
|
||||
if err := ctl.msgDispatcher.Send(&msg.ReqWorkConn{}); err != nil {
|
||||
@ -280,13 +280,13 @@ func (ctl *Control) GetWorkConn() (workConn net.Conn, err error) {
|
||||
case workConn, ok = <-ctl.workConnCh:
|
||||
if !ok {
|
||||
err = pkgerr.ErrCtlClosed
|
||||
xl.Warn("no work connections available, %v", err)
|
||||
xl.Warnf("no work connections available, %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
case <-time.After(time.Duration(ctl.serverCfg.UserConnTimeout) * time.Second):
|
||||
err = fmt.Errorf("timeout trying to get work connection")
|
||||
xl.Warn("%v", err)
|
||||
xl.Warnf("%v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -305,7 +305,7 @@ func (ctl *Control) heartbeatWorker() {
|
||||
if !lo.FromPtr(ctl.serverCfg.Transport.TCPMux) && ctl.serverCfg.Transport.HeartbeatTimeout > 0 {
|
||||
go wait.Until(func() {
|
||||
if time.Since(ctl.lastPing.Load().(time.Time)) > time.Duration(ctl.serverCfg.Transport.HeartbeatTimeout)*time.Second {
|
||||
xl.Warn("heartbeat timeout")
|
||||
xl.Warnf("heartbeat timeout")
|
||||
ctl.conn.Close()
|
||||
return
|
||||
}
|
||||
@ -356,7 +356,7 @@ func (ctl *Control) worker() {
|
||||
}
|
||||
|
||||
metrics.Server.CloseClient()
|
||||
xl.Info("client exit success")
|
||||
xl.Infof("client exit success")
|
||||
close(ctl.doneCh)
|
||||
}
|
||||
|
||||
@ -393,12 +393,12 @@ func (ctl *Control) handleNewProxy(m msg.Message) {
|
||||
ProxyName: inMsg.ProxyName,
|
||||
}
|
||||
if err != nil {
|
||||
xl.Warn("new proxy [%s] type [%s] error: %v", inMsg.ProxyName, inMsg.ProxyType, err)
|
||||
xl.Warnf("new proxy [%s] type [%s] error: %v", inMsg.ProxyName, inMsg.ProxyType, err)
|
||||
resp.Error = util.GenerateResponseErrorString(fmt.Sprintf("new proxy [%s] error", inMsg.ProxyName),
|
||||
err, lo.FromPtr(ctl.serverCfg.DetailedErrorsToClient))
|
||||
} else {
|
||||
resp.RemoteAddr = remoteAddr
|
||||
xl.Info("new proxy [%s] type [%s] success", inMsg.ProxyName, inMsg.ProxyType)
|
||||
xl.Infof("new proxy [%s] type [%s] success", inMsg.ProxyName, inMsg.ProxyType)
|
||||
metrics.Server.NewProxy(inMsg.ProxyName, inMsg.ProxyType)
|
||||
}
|
||||
_ = ctl.msgDispatcher.Send(resp)
|
||||
@ -422,14 +422,14 @@ func (ctl *Control) handlePing(m msg.Message) {
|
||||
err = ctl.authVerifier.VerifyPing(inMsg)
|
||||
}
|
||||
if err != nil {
|
||||
xl.Warn("received invalid ping: %v", err)
|
||||
xl.Warnf("received invalid ping: %v", err)
|
||||
_ = ctl.msgDispatcher.Send(&msg.Pong{
|
||||
Error: util.GenerateResponseErrorString("invalid ping", err, lo.FromPtr(ctl.serverCfg.DetailedErrorsToClient)),
|
||||
})
|
||||
return
|
||||
}
|
||||
ctl.lastPing.Store(time.Now())
|
||||
xl.Debug("receive heartbeat")
|
||||
xl.Debugf("receive heartbeat")
|
||||
_ = ctl.msgDispatcher.Send(&msg.Pong{})
|
||||
}
|
||||
|
||||
@ -452,7 +452,7 @@ func (ctl *Control) handleCloseProxy(m msg.Message) {
|
||||
xl := ctl.xl
|
||||
inMsg := m.(*msg.CloseProxy)
|
||||
_ = ctl.CloseProxy(inMsg)
|
||||
xl.Info("close proxy [%s] success", inMsg.ProxyName)
|
||||
xl.Infof("close proxy [%s] success", inMsg.ProxyName)
|
||||
}
|
||||
|
||||
func (ctl *Control) RegisterProxy(pxyMsg *msg.NewProxy) (remoteAddr string, err error) {
|
||||
|
@ -15,9 +15,10 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"sort"
|
||||
"slices"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
@ -98,14 +99,14 @@ func (svr *Service) healthz(w http.ResponseWriter, _ *http.Request) {
|
||||
func (svr *Service) apiServerInfo(w http.ResponseWriter, r *http.Request) {
|
||||
res := GeneralResponse{Code: 200}
|
||||
defer func() {
|
||||
log.Info("Http response [%s]: code [%d]", r.URL.Path, res.Code)
|
||||
log.Infof("Http response [%s]: code [%d]", r.URL.Path, res.Code)
|
||||
w.WriteHeader(res.Code)
|
||||
if len(res.Msg) > 0 {
|
||||
_, _ = w.Write([]byte(res.Msg))
|
||||
}
|
||||
}()
|
||||
|
||||
log.Info("Http request: [%s]", r.URL.Path)
|
||||
log.Infof("Http request: [%s]", r.URL.Path)
|
||||
serverStats := mem.StatsCollector.GetServer()
|
||||
svrResp := serverInfoResp{
|
||||
Version: version.Full(),
|
||||
@ -218,18 +219,18 @@ func (svr *Service) apiProxyByType(w http.ResponseWriter, r *http.Request) {
|
||||
proxyType := params["type"]
|
||||
|
||||
defer func() {
|
||||
log.Info("Http response [%s]: code [%d]", r.URL.Path, res.Code)
|
||||
log.Infof("Http response [%s]: code [%d]", r.URL.Path, res.Code)
|
||||
w.WriteHeader(res.Code)
|
||||
if len(res.Msg) > 0 {
|
||||
_, _ = w.Write([]byte(res.Msg))
|
||||
}
|
||||
}()
|
||||
log.Info("Http request: [%s]", r.URL.Path)
|
||||
log.Infof("Http request: [%s]", r.URL.Path)
|
||||
|
||||
proxyInfoResp := GetProxyInfoResp{}
|
||||
proxyInfoResp.Proxies = svr.getProxyStatsByType(proxyType)
|
||||
sort.Slice(proxyInfoResp.Proxies, func(i, j int) bool {
|
||||
return proxyInfoResp.Proxies[i].Name < proxyInfoResp.Proxies[j].Name
|
||||
slices.SortFunc(proxyInfoResp.Proxies, func(a, b *ProxyStatsInfo) int {
|
||||
return cmp.Compare(a.Name, b.Name)
|
||||
})
|
||||
|
||||
buf, _ := json.Marshal(&proxyInfoResp)
|
||||
@ -244,12 +245,12 @@ func (svr *Service) getProxyStatsByType(proxyType string) (proxyInfos []*ProxySt
|
||||
if pxy, ok := svr.pxyManager.GetByName(ps.Name); ok {
|
||||
content, err := json.Marshal(pxy.GetConfigurer())
|
||||
if err != nil {
|
||||
log.Warn("marshal proxy [%s] conf info error: %v", ps.Name, err)
|
||||
log.Warnf("marshal proxy [%s] conf info error: %v", ps.Name, err)
|
||||
continue
|
||||
}
|
||||
proxyInfo.Conf = getConfByType(ps.Type)
|
||||
if err = json.Unmarshal(content, &proxyInfo.Conf); err != nil {
|
||||
log.Warn("unmarshal proxy [%s] conf info error: %v", ps.Name, err)
|
||||
log.Warnf("unmarshal proxy [%s] conf info error: %v", ps.Name, err)
|
||||
continue
|
||||
}
|
||||
proxyInfo.Status = "online"
|
||||
@ -290,13 +291,13 @@ func (svr *Service) apiProxyByTypeAndName(w http.ResponseWriter, r *http.Request
|
||||
name := params["name"]
|
||||
|
||||
defer func() {
|
||||
log.Info("Http response [%s]: code [%d]", r.URL.Path, res.Code)
|
||||
log.Infof("Http response [%s]: code [%d]", r.URL.Path, res.Code)
|
||||
w.WriteHeader(res.Code)
|
||||
if len(res.Msg) > 0 {
|
||||
_, _ = w.Write([]byte(res.Msg))
|
||||
}
|
||||
}()
|
||||
log.Info("Http request: [%s]", r.URL.Path)
|
||||
log.Infof("Http request: [%s]", r.URL.Path)
|
||||
|
||||
var proxyStatsResp GetProxyStatsResp
|
||||
proxyStatsResp, res.Code, res.Msg = svr.getProxyStatsByTypeAndName(proxyType, name)
|
||||
@ -318,14 +319,14 @@ func (svr *Service) getProxyStatsByTypeAndName(proxyType string, proxyName strin
|
||||
if pxy, ok := svr.pxyManager.GetByName(proxyName); ok {
|
||||
content, err := json.Marshal(pxy.GetConfigurer())
|
||||
if err != nil {
|
||||
log.Warn("marshal proxy [%s] conf info error: %v", ps.Name, err)
|
||||
log.Warnf("marshal proxy [%s] conf info error: %v", ps.Name, err)
|
||||
code = 400
|
||||
msg = "parse conf error"
|
||||
return
|
||||
}
|
||||
proxyInfo.Conf = getConfByType(ps.Type)
|
||||
if err = json.Unmarshal(content, &proxyInfo.Conf); err != nil {
|
||||
log.Warn("unmarshal proxy [%s] conf info error: %v", ps.Name, err)
|
||||
log.Warnf("unmarshal proxy [%s] conf info error: %v", ps.Name, err)
|
||||
code = 400
|
||||
msg = "parse conf error"
|
||||
return
|
||||
@ -358,13 +359,13 @@ func (svr *Service) apiProxyTraffic(w http.ResponseWriter, r *http.Request) {
|
||||
name := params["name"]
|
||||
|
||||
defer func() {
|
||||
log.Info("Http response [%s]: code [%d]", r.URL.Path, res.Code)
|
||||
log.Infof("Http response [%s]: code [%d]", r.URL.Path, res.Code)
|
||||
w.WriteHeader(res.Code)
|
||||
if len(res.Msg) > 0 {
|
||||
_, _ = w.Write([]byte(res.Msg))
|
||||
}
|
||||
}()
|
||||
log.Info("Http request: [%s]", r.URL.Path)
|
||||
log.Infof("Http request: [%s]", r.URL.Path)
|
||||
|
||||
trafficResp := GetProxyTrafficResp{}
|
||||
trafficResp.Name = name
|
||||
@ -386,9 +387,9 @@ func (svr *Service) apiProxyTraffic(w http.ResponseWriter, r *http.Request) {
|
||||
func (svr *Service) deleteProxies(w http.ResponseWriter, r *http.Request) {
|
||||
res := GeneralResponse{Code: 200}
|
||||
|
||||
log.Info("Http request: [%s]", r.URL.Path)
|
||||
log.Infof("Http request: [%s]", r.URL.Path)
|
||||
defer func() {
|
||||
log.Info("Http response [%s]: code [%d]", r.URL.Path, res.Code)
|
||||
log.Infof("Http response [%s]: code [%d]", r.URL.Path, res.Code)
|
||||
w.WriteHeader(res.Code)
|
||||
if len(res.Msg) > 0 {
|
||||
_, _ = w.Write([]byte(res.Msg))
|
||||
@ -402,5 +403,5 @@ func (svr *Service) deleteProxies(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
cleared, total := mem.StatsCollector.ClearOfflineProxies()
|
||||
log.Info("cleared [%d] offline proxies, total [%d] proxies", cleared, total)
|
||||
log.Infof("cleared [%d] offline proxies, total [%d] proxies", cleared, total)
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ func (pxy *HTTPProxy) Run() (remoteAddr string, err error) {
|
||||
})
|
||||
}
|
||||
addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, pxy.serverCfg.VhostHTTPPort))
|
||||
xl.Info("http proxy listen for host [%s] location [%s] group [%s], routeByHTTPUser [%s]",
|
||||
xl.Infof("http proxy listen for host [%s] location [%s] group [%s], routeByHTTPUser [%s]",
|
||||
routeConfig.Domain, routeConfig.Location, pxy.cfg.LoadBalancer.Group, pxy.cfg.RouteByHTTPUser)
|
||||
}
|
||||
}
|
||||
@ -140,7 +140,7 @@ func (pxy *HTTPProxy) Run() (remoteAddr string, err error) {
|
||||
}
|
||||
addrs = append(addrs, util.CanonicalAddr(tmpRouteConfig.Domain, pxy.serverCfg.VhostHTTPPort))
|
||||
|
||||
xl.Info("http proxy listen for host [%s] location [%s] group [%s], routeByHTTPUser [%s]",
|
||||
xl.Infof("http proxy listen for host [%s] location [%s] group [%s], routeByHTTPUser [%s]",
|
||||
routeConfig.Domain, routeConfig.Location, pxy.cfg.LoadBalancer.Group, pxy.cfg.RouteByHTTPUser)
|
||||
}
|
||||
}
|
||||
@ -152,7 +152,7 @@ func (pxy *HTTPProxy) GetRealConn(remoteAddr string) (workConn net.Conn, err err
|
||||
xl := pxy.xl
|
||||
rAddr, errRet := net.ResolveTCPAddr("tcp", remoteAddr)
|
||||
if errRet != nil {
|
||||
xl.Warn("resolve TCP addr [%s] error: %v", remoteAddr, errRet)
|
||||
xl.Warnf("resolve TCP addr [%s] error: %v", remoteAddr, errRet)
|
||||
// we do not return error here since remoteAddr is not necessary for proxies without proxy protocol enabled
|
||||
}
|
||||
|
||||
@ -166,7 +166,7 @@ func (pxy *HTTPProxy) GetRealConn(remoteAddr string) (workConn net.Conn, err err
|
||||
if pxy.cfg.Transport.UseEncryption {
|
||||
rwc, err = libio.WithEncryption(rwc, []byte(pxy.serverCfg.Auth.Token))
|
||||
if err != nil {
|
||||
xl.Error("create encryption stream error: %v", err)
|
||||
xl.Errorf("create encryption stream error: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ func (pxy *HTTPSProxy) Run() (remoteAddr string, err error) {
|
||||
err = errRet
|
||||
return
|
||||
}
|
||||
xl.Info("https proxy listen for host [%s]", routeConfig.Domain)
|
||||
xl.Infof("https proxy listen for host [%s]", routeConfig.Domain)
|
||||
pxy.listeners = append(pxy.listeners, l)
|
||||
addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, pxy.serverCfg.VhostHTTPSPort))
|
||||
}
|
||||
@ -76,7 +76,7 @@ func (pxy *HTTPSProxy) Run() (remoteAddr string, err error) {
|
||||
err = errRet
|
||||
return
|
||||
}
|
||||
xl.Info("https proxy listen for host [%s]", routeConfig.Domain)
|
||||
xl.Infof("https proxy listen for host [%s]", routeConfig.Domain)
|
||||
pxy.listeners = append(pxy.listeners, l)
|
||||
addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, pxy.serverCfg.VhostHTTPSPort))
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ func (pxy *BaseProxy) GetConfigurer() v1.ProxyConfigurer {
|
||||
|
||||
func (pxy *BaseProxy) Close() {
|
||||
xl := xlog.FromContextSafe(pxy.ctx)
|
||||
xl.Info("proxy closing")
|
||||
xl.Infof("proxy closing")
|
||||
for _, l := range pxy.listeners {
|
||||
l.Close()
|
||||
}
|
||||
@ -125,10 +125,10 @@ func (pxy *BaseProxy) GetWorkConnFromPool(src, dst net.Addr) (workConn net.Conn,
|
||||
// try all connections from the pool
|
||||
for i := 0; i < pxy.poolCount+1; i++ {
|
||||
if workConn, err = pxy.getWorkConnFn(); err != nil {
|
||||
xl.Warn("failed to get work connection: %v", err)
|
||||
xl.Warnf("failed to get work connection: %v", err)
|
||||
return
|
||||
}
|
||||
xl.Debug("get a new work connection: [%s]", workConn.RemoteAddr().String())
|
||||
xl.Debugf("get a new work connection: [%s]", workConn.RemoteAddr().String())
|
||||
xl.Spawn().AppendPrefix(pxy.GetName())
|
||||
workConn = netpkg.NewContextConn(pxy.ctx, workConn)
|
||||
|
||||
@ -158,7 +158,7 @@ func (pxy *BaseProxy) GetWorkConnFromPool(src, dst net.Addr) (workConn net.Conn,
|
||||
Error: "",
|
||||
})
|
||||
if err != nil {
|
||||
xl.Warn("failed to send message to work connection from pool: %v, times: %d", err, i)
|
||||
xl.Warnf("failed to send message to work connection from pool: %v, times: %d", err, i)
|
||||
workConn.Close()
|
||||
} else {
|
||||
break
|
||||
@ -166,7 +166,7 @@ func (pxy *BaseProxy) GetWorkConnFromPool(src, dst net.Addr) (workConn net.Conn,
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
xl.Error("try to get work connection failed in the end")
|
||||
xl.Errorf("try to get work connection failed in the end")
|
||||
return
|
||||
}
|
||||
return
|
||||
@ -193,15 +193,15 @@ func (pxy *BaseProxy) startCommonTCPListenersHandler() {
|
||||
if max := 1 * time.Second; tempDelay > max {
|
||||
tempDelay = max
|
||||
}
|
||||
xl.Info("met temporary error: %s, sleep for %s ...", err, tempDelay)
|
||||
xl.Infof("met temporary error: %s, sleep for %s ...", err, tempDelay)
|
||||
time.Sleep(tempDelay)
|
||||
continue
|
||||
}
|
||||
|
||||
xl.Warn("listener is closed: %s", err)
|
||||
xl.Warnf("listener is closed: %s", err)
|
||||
return
|
||||
}
|
||||
xl.Info("get a user connection [%s]", c.RemoteAddr().String())
|
||||
xl.Infof("get a user connection [%s]", c.RemoteAddr().String())
|
||||
go pxy.handleUserTCPConnection(c)
|
||||
}
|
||||
}(listener)
|
||||
@ -225,7 +225,7 @@ func (pxy *BaseProxy) handleUserTCPConnection(userConn net.Conn) {
|
||||
}
|
||||
_, err := rc.PluginManager.NewUserConn(content)
|
||||
if err != nil {
|
||||
xl.Warn("the user conn [%s] was rejected, err:%v", content.RemoteAddr, err)
|
||||
xl.Warnf("the user conn [%s] was rejected, err:%v", content.RemoteAddr, err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -237,12 +237,12 @@ func (pxy *BaseProxy) handleUserTCPConnection(userConn net.Conn) {
|
||||
defer workConn.Close()
|
||||
|
||||
var local io.ReadWriteCloser = workConn
|
||||
xl.Trace("handler user tcp connection, use_encryption: %t, use_compression: %t",
|
||||
xl.Tracef("handler user tcp connection, use_encryption: %t, use_compression: %t",
|
||||
cfg.Transport.UseEncryption, cfg.Transport.UseCompression)
|
||||
if cfg.Transport.UseEncryption {
|
||||
local, err = libio.WithEncryption(local, []byte(serverCfg.Auth.Token))
|
||||
if err != nil {
|
||||
xl.Error("create encryption stream error: %v", err)
|
||||
xl.Errorf("create encryption stream error: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -258,7 +258,7 @@ func (pxy *BaseProxy) handleUserTCPConnection(userConn net.Conn) {
|
||||
})
|
||||
}
|
||||
|
||||
xl.Debug("join connections, workConn(l[%s] r[%s]) userConn(l[%s] r[%s])", workConn.LocalAddr().String(),
|
||||
xl.Debugf("join connections, workConn(l[%s] r[%s]) userConn(l[%s] r[%s])", workConn.LocalAddr().String(),
|
||||
workConn.RemoteAddr().String(), userConn.LocalAddr().String(), userConn.RemoteAddr().String())
|
||||
|
||||
name := pxy.GetName()
|
||||
@ -268,7 +268,7 @@ func (pxy *BaseProxy) handleUserTCPConnection(userConn net.Conn) {
|
||||
metrics.Server.CloseConnection(name, proxyType)
|
||||
metrics.Server.AddTrafficIn(name, proxyType, inCount)
|
||||
metrics.Server.AddTrafficOut(name, proxyType, outCount)
|
||||
xl.Debug("join connections closed")
|
||||
xl.Debugf("join connections closed")
|
||||
}
|
||||
|
||||
type Options struct {
|
||||
|
@ -53,7 +53,7 @@ func (pxy *STCPProxy) Run() (remoteAddr string, err error) {
|
||||
return
|
||||
}
|
||||
pxy.listeners = append(pxy.listeners, listener)
|
||||
xl.Info("stcp proxy custom listen success")
|
||||
xl.Infof("stcp proxy custom listen success")
|
||||
|
||||
pxy.startCommonTCPListenersHandler()
|
||||
return
|
||||
|
@ -53,7 +53,7 @@ func (pxy *SUDPProxy) Run() (remoteAddr string, err error) {
|
||||
return
|
||||
}
|
||||
pxy.listeners = append(pxy.listeners, listener)
|
||||
xl.Info("sudp proxy custom listen success")
|
||||
xl.Infof("sudp proxy custom listen success")
|
||||
|
||||
pxy.startCommonTCPListenersHandler()
|
||||
return
|
||||
|
@ -62,7 +62,7 @@ func (pxy *TCPProxy) Run() (remoteAddr string, err error) {
|
||||
}()
|
||||
pxy.realBindPort = realBindPort
|
||||
pxy.listeners = append(pxy.listeners, l)
|
||||
xl.Info("tcp proxy listen port [%d] in group [%s]", pxy.cfg.RemotePort, pxy.cfg.LoadBalancer.Group)
|
||||
xl.Infof("tcp proxy listen port [%d] in group [%s]", pxy.cfg.RemotePort, pxy.cfg.LoadBalancer.Group)
|
||||
} else {
|
||||
pxy.realBindPort, err = pxy.rc.TCPPortManager.Acquire(pxy.name, pxy.cfg.RemotePort)
|
||||
if err != nil {
|
||||
@ -79,7 +79,7 @@ func (pxy *TCPProxy) Run() (remoteAddr string, err error) {
|
||||
return
|
||||
}
|
||||
pxy.listeners = append(pxy.listeners, listener)
|
||||
xl.Info("tcp proxy listen port [%d]", pxy.cfg.RemotePort)
|
||||
xl.Infof("tcp proxy listen port [%d]", pxy.cfg.RemotePort)
|
||||
}
|
||||
|
||||
pxy.cfg.RemotePort = pxy.realBindPort
|
||||
|
@ -65,7 +65,7 @@ func (pxy *TCPMuxProxy) httpConnectListen(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pxy.xl.Info("tcpmux httpconnect multiplexer listens for host [%s], group [%s] routeByHTTPUser [%s]",
|
||||
pxy.xl.Infof("tcpmux httpconnect multiplexer listens for host [%s], group [%s] routeByHTTPUser [%s]",
|
||||
domain, pxy.cfg.LoadBalancer.Group, pxy.cfg.RouteByHTTPUser)
|
||||
pxy.listeners = append(pxy.listeners, l)
|
||||
return append(addrs, util.CanonicalAddr(domain, pxy.serverCfg.TCPMuxHTTPConnectPort)), nil
|
||||
|
@ -97,10 +97,10 @@ func (pxy *UDPProxy) Run() (remoteAddr string, err error) {
|
||||
udpConn, errRet := net.ListenUDP("udp", addr)
|
||||
if errRet != nil {
|
||||
err = errRet
|
||||
xl.Warn("listen udp port error: %v", err)
|
||||
xl.Warnf("listen udp port error: %v", err)
|
||||
return
|
||||
}
|
||||
xl.Info("udp proxy listen port [%d]", pxy.cfg.RemotePort)
|
||||
xl.Infof("udp proxy listen port [%d]", pxy.cfg.RemotePort)
|
||||
|
||||
pxy.udpConn = udpConn
|
||||
pxy.sendCh = make(chan *msg.UDPPacket, 1024)
|
||||
@ -114,11 +114,11 @@ func (pxy *UDPProxy) Run() (remoteAddr string, err error) {
|
||||
rawMsg msg.Message
|
||||
errRet error
|
||||
)
|
||||
xl.Trace("loop waiting message from udp workConn")
|
||||
xl.Tracef("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))
|
||||
if rawMsg, errRet = msg.ReadMsg(conn); errRet != nil {
|
||||
xl.Warn("read from workConn for udp error: %v", errRet)
|
||||
xl.Warnf("read from workConn for udp error: %v", errRet)
|
||||
_ = conn.Close()
|
||||
// notify proxy to start a new work connection
|
||||
// ignore error here, it means the proxy is closed
|
||||
@ -128,15 +128,15 @@ func (pxy *UDPProxy) Run() (remoteAddr string, err error) {
|
||||
return
|
||||
}
|
||||
if err := conn.SetReadDeadline(time.Time{}); err != nil {
|
||||
xl.Warn("set read deadline error: %v", err)
|
||||
xl.Warnf("set read deadline error: %v", err)
|
||||
}
|
||||
switch m := rawMsg.(type) {
|
||||
case *msg.Ping:
|
||||
xl.Trace("udp work conn get ping message")
|
||||
xl.Tracef("udp work conn get ping message")
|
||||
continue
|
||||
case *msg.UDPPacket:
|
||||
if errRet := errors.PanicToError(func() {
|
||||
xl.Trace("get udp message from workConn: %s", m.Content)
|
||||
xl.Tracef("get udp message from workConn: %s", m.Content)
|
||||
pxy.readCh <- m
|
||||
metrics.Server.AddTrafficOut(
|
||||
pxy.GetName(),
|
||||
@ -145,7 +145,7 @@ func (pxy *UDPProxy) Run() (remoteAddr string, err error) {
|
||||
)
|
||||
}); errRet != nil {
|
||||
conn.Close()
|
||||
xl.Info("reader goroutine for udp work connection closed")
|
||||
xl.Infof("reader goroutine for udp work connection closed")
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -159,15 +159,15 @@ func (pxy *UDPProxy) Run() (remoteAddr string, err error) {
|
||||
select {
|
||||
case udpMsg, ok := <-pxy.sendCh:
|
||||
if !ok {
|
||||
xl.Info("sender goroutine for udp work connection closed")
|
||||
xl.Infof("sender goroutine for udp work connection closed")
|
||||
return
|
||||
}
|
||||
if errRet = msg.WriteMsg(conn, udpMsg); errRet != nil {
|
||||
xl.Info("sender goroutine for udp work connection closed: %v", errRet)
|
||||
xl.Infof("sender goroutine for udp work connection closed: %v", errRet)
|
||||
conn.Close()
|
||||
return
|
||||
}
|
||||
xl.Trace("send message to udp workConn: %s", udpMsg.Content)
|
||||
xl.Tracef("send message to udp workConn: %s", udpMsg.Content)
|
||||
metrics.Server.AddTrafficIn(
|
||||
pxy.GetName(),
|
||||
pxy.GetConfigurer().GetBaseConfig().Type,
|
||||
@ -175,7 +175,7 @@ func (pxy *UDPProxy) Run() (remoteAddr string, err error) {
|
||||
)
|
||||
continue
|
||||
case <-ctx.Done():
|
||||
xl.Info("sender goroutine for udp work connection closed")
|
||||
xl.Infof("sender goroutine for udp work connection closed")
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -207,7 +207,7 @@ func (pxy *UDPProxy) Run() (remoteAddr string, err error) {
|
||||
if pxy.cfg.Transport.UseEncryption {
|
||||
rwc, err = libio.WithEncryption(rwc, []byte(pxy.serverCfg.Auth.Token))
|
||||
if err != nil {
|
||||
xl.Error("create encryption stream error: %v", err)
|
||||
xl.Errorf("create encryption stream error: %v", err)
|
||||
workConn.Close()
|
||||
continue
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ func (pxy *XTCPProxy) Run() (remoteAddr string, err error) {
|
||||
}
|
||||
errRet = msg.WriteMsg(workConn, m)
|
||||
if errRet != nil {
|
||||
xl.Warn("write nat hole sid package error, %v", errRet)
|
||||
xl.Warnf("write nat hole sid package error, %v", errRet)
|
||||
}
|
||||
workConn.Close()
|
||||
}
|
||||
|
@ -172,13 +172,13 @@ func NewService(cfg *v1.ServerConfig) (*Service, error) {
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create vhost tcpMuxer error, %v", err)
|
||||
}
|
||||
log.Info("tcpmux httpconnect multiplexer listen on %s, passthough: %v", address, cfg.TCPMuxPassthrough)
|
||||
log.Infof("tcpmux httpconnect multiplexer listen on %s, passthough: %v", address, cfg.TCPMuxPassthrough)
|
||||
}
|
||||
|
||||
// Init all plugins
|
||||
for _, p := range cfg.HTTPPlugins {
|
||||
svr.pluginManager.Register(plugin.NewHTTPPluginOptions(p))
|
||||
log.Info("plugin [%s] has been registered", p.Name)
|
||||
log.Infof("plugin [%s] has been registered", p.Name)
|
||||
}
|
||||
svr.rc.PluginManager = svr.pluginManager
|
||||
|
||||
@ -222,7 +222,7 @@ func NewService(cfg *v1.ServerConfig) (*Service, error) {
|
||||
ln = svr.muxer.DefaultListener()
|
||||
|
||||
svr.listener = ln
|
||||
log.Info("frps tcp listen on %s", address)
|
||||
log.Infof("frps tcp listen on %s", address)
|
||||
|
||||
// Listen for accepting connections from client using kcp protocol.
|
||||
if cfg.KCPBindPort > 0 {
|
||||
@ -231,7 +231,7 @@ func NewService(cfg *v1.ServerConfig) (*Service, error) {
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("listen on kcp udp address %s error: %v", address, err)
|
||||
}
|
||||
log.Info("frps kcp listen on udp %s", address)
|
||||
log.Infof("frps kcp listen on udp %s", address)
|
||||
}
|
||||
|
||||
if cfg.QUICBindPort > 0 {
|
||||
@ -246,7 +246,7 @@ func NewService(cfg *v1.ServerConfig) (*Service, error) {
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("listen on quic udp address %s error: %v", address, err)
|
||||
}
|
||||
log.Info("frps quic listen on %s", address)
|
||||
log.Infof("frps quic listen on %s", address)
|
||||
}
|
||||
|
||||
if cfg.SSHTunnelGateway.BindPort > 0 {
|
||||
@ -255,7 +255,7 @@ func NewService(cfg *v1.ServerConfig) (*Service, error) {
|
||||
return nil, fmt.Errorf("create ssh gateway error: %v", err)
|
||||
}
|
||||
svr.sshTunnelGateway = sshGateway
|
||||
log.Info("frps sshTunnelGateway listen on port %d", cfg.SSHTunnelGateway.BindPort)
|
||||
log.Infof("frps sshTunnelGateway listen on port %d", cfg.SSHTunnelGateway.BindPort)
|
||||
}
|
||||
|
||||
// Listen for accepting connections from client using websocket protocol.
|
||||
@ -289,7 +289,7 @@ func NewService(cfg *v1.ServerConfig) (*Service, error) {
|
||||
go func() {
|
||||
_ = server.Serve(l)
|
||||
}()
|
||||
log.Info("http service listen on %s", address)
|
||||
log.Infof("http service listen on %s", address)
|
||||
}
|
||||
|
||||
// Create https vhost muxer.
|
||||
@ -303,7 +303,7 @@ func NewService(cfg *v1.ServerConfig) (*Service, error) {
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create server listener error, %v", err)
|
||||
}
|
||||
log.Info("https service listen on %s", address)
|
||||
log.Infof("https service listen on %s", address)
|
||||
}
|
||||
|
||||
svr.rc.VhostHTTPSMuxer, err = vhost.NewHTTPSMuxer(l, vhostReadWriteTimeout)
|
||||
@ -335,9 +335,9 @@ func (svr *Service) Run(ctx context.Context) {
|
||||
// run dashboard web server.
|
||||
if svr.webServer != nil {
|
||||
go func() {
|
||||
log.Info("dashboard listen on %s", svr.webServer.Address())
|
||||
log.Infof("dashboard listen on %s", svr.webServer.Address())
|
||||
if err := svr.webServer.Run(); err != nil {
|
||||
log.Warn("dashboard server exit with error: %v", err)
|
||||
log.Warnf("dashboard server exit with error: %v", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
@ -408,7 +408,7 @@ func (svr *Service) handleConnection(ctx context.Context, conn net.Conn, interna
|
||||
|
||||
_ = conn.SetReadDeadline(time.Now().Add(connReadTimeout))
|
||||
if rawMsg, err = msg.ReadMsg(conn); err != nil {
|
||||
log.Trace("Failed to read message: %v", err)
|
||||
log.Tracef("Failed to read message: %v", err)
|
||||
conn.Close()
|
||||
return
|
||||
}
|
||||
@ -430,7 +430,7 @@ func (svr *Service) handleConnection(ctx context.Context, conn net.Conn, interna
|
||||
// If login failed, send error message there.
|
||||
// Otherwise send success message in control's work goroutine.
|
||||
if err != nil {
|
||||
xl.Warn("register control error: %v", err)
|
||||
xl.Warnf("register control error: %v", err)
|
||||
_ = msg.WriteMsg(conn, &msg.LoginResp{
|
||||
Version: version.Full(),
|
||||
Error: util.GenerateResponseErrorString("register control error", err, lo.FromPtr(svr.cfg.DetailedErrorsToClient)),
|
||||
@ -443,7 +443,7 @@ func (svr *Service) handleConnection(ctx context.Context, conn net.Conn, interna
|
||||
}
|
||||
case *msg.NewVisitorConn:
|
||||
if err = svr.RegisterVisitorConn(conn, m); err != nil {
|
||||
xl.Warn("register visitor conn error: %v", err)
|
||||
xl.Warnf("register visitor conn error: %v", err)
|
||||
_ = msg.WriteMsg(conn, &msg.NewVisitorConnResp{
|
||||
ProxyName: m.ProxyName,
|
||||
Error: util.GenerateResponseErrorString("register visitor conn error", err, lo.FromPtr(svr.cfg.DetailedErrorsToClient)),
|
||||
@ -456,7 +456,7 @@ func (svr *Service) handleConnection(ctx context.Context, conn net.Conn, interna
|
||||
})
|
||||
}
|
||||
default:
|
||||
log.Warn("Error message type for the new connection [%s]", conn.RemoteAddr().String())
|
||||
log.Warnf("Error message type for the new connection [%s]", conn.RemoteAddr().String())
|
||||
conn.Close()
|
||||
}
|
||||
}
|
||||
@ -469,7 +469,7 @@ func (svr *Service) HandleListener(l net.Listener, internal bool) {
|
||||
for {
|
||||
c, err := l.Accept()
|
||||
if err != nil {
|
||||
log.Warn("Listener for incoming connections from client closed")
|
||||
log.Warnf("Listener for incoming connections from client closed")
|
||||
return
|
||||
}
|
||||
// inject xlog object into net.Conn context
|
||||
@ -479,17 +479,17 @@ func (svr *Service) HandleListener(l net.Listener, internal bool) {
|
||||
c = netpkg.NewContextConn(xlog.NewContext(ctx, xl), c)
|
||||
|
||||
if !internal {
|
||||
log.Trace("start check TLS connection...")
|
||||
log.Tracef("start check TLS connection...")
|
||||
originConn := c
|
||||
forceTLS := svr.cfg.Transport.TLS.Force
|
||||
var isTLS, custom bool
|
||||
c, isTLS, custom, err = netpkg.CheckAndEnableTLSServerConnWithTimeout(c, svr.tlsConfig, forceTLS, connReadTimeout)
|
||||
if err != nil {
|
||||
log.Warn("CheckAndEnableTLSServerConnWithTimeout error: %v", err)
|
||||
log.Warnf("CheckAndEnableTLSServerConnWithTimeout error: %v", err)
|
||||
originConn.Close()
|
||||
continue
|
||||
}
|
||||
log.Trace("check TLS connection success, isTLS: %v custom: %v internal: %v", isTLS, custom, internal)
|
||||
log.Tracef("check TLS connection success, isTLS: %v custom: %v internal: %v", isTLS, custom, internal)
|
||||
}
|
||||
|
||||
// Start a new goroutine to handle connection.
|
||||
@ -501,7 +501,7 @@ func (svr *Service) HandleListener(l net.Listener, internal bool) {
|
||||
fmuxCfg.MaxStreamWindowSize = 6 * 1024 * 1024
|
||||
session, err := fmux.Server(frpConn, fmuxCfg)
|
||||
if err != nil {
|
||||
log.Warn("Failed to create mux connection: %v", err)
|
||||
log.Warnf("Failed to create mux connection: %v", err)
|
||||
frpConn.Close()
|
||||
return
|
||||
}
|
||||
@ -509,7 +509,7 @@ func (svr *Service) HandleListener(l net.Listener, internal bool) {
|
||||
for {
|
||||
stream, err := session.AcceptStream()
|
||||
if err != nil {
|
||||
log.Debug("Accept new mux stream error: %v", err)
|
||||
log.Debugf("Accept new mux stream error: %v", err)
|
||||
session.Close()
|
||||
return
|
||||
}
|
||||
@ -527,7 +527,7 @@ func (svr *Service) HandleQUICListener(l *quic.Listener) {
|
||||
for {
|
||||
c, err := l.Accept(context.Background())
|
||||
if err != nil {
|
||||
log.Warn("QUICListener for incoming connections from client closed")
|
||||
log.Warnf("QUICListener for incoming connections from client closed")
|
||||
return
|
||||
}
|
||||
// Start a new goroutine to handle connection.
|
||||
@ -535,7 +535,7 @@ func (svr *Service) HandleQUICListener(l *quic.Listener) {
|
||||
for {
|
||||
stream, err := frpConn.AcceptStream(context.Background())
|
||||
if err != nil {
|
||||
log.Debug("Accept new quic mux stream error: %v", err)
|
||||
log.Debugf("Accept new quic mux stream error: %v", err)
|
||||
_ = frpConn.CloseWithError(0, "")
|
||||
return
|
||||
}
|
||||
@ -560,7 +560,7 @@ func (svr *Service) RegisterControl(ctlConn net.Conn, loginMsg *msg.Login, inter
|
||||
xl := xlog.FromContextSafe(ctx)
|
||||
xl.AppendPrefix(loginMsg.RunID)
|
||||
ctx = xlog.NewContext(ctx, xl)
|
||||
xl.Info("client login info: ip [%s] version [%s] hostname [%s] os [%s] arch [%s]",
|
||||
xl.Infof("client login info: ip [%s] version [%s] hostname [%s] os [%s] arch [%s]",
|
||||
ctlConn.RemoteAddr().String(), loginMsg.Version, loginMsg.Hostname, loginMsg.Os, loginMsg.Arch)
|
||||
|
||||
// Check auth.
|
||||
@ -575,7 +575,7 @@ func (svr *Service) RegisterControl(ctlConn net.Conn, loginMsg *msg.Login, inter
|
||||
// TODO(fatedier): use SessionContext
|
||||
ctl, err := NewControl(ctx, svr.rc, svr.pxyManager, svr.pluginManager, authVerifier, ctlConn, !internal, loginMsg, svr.cfg)
|
||||
if err != nil {
|
||||
xl.Warn("create new controller error: %v", err)
|
||||
xl.Warnf("create new controller error: %v", err)
|
||||
// don't return detailed errors to client
|
||||
return fmt.Errorf("unexpected error when creating new controller")
|
||||
}
|
||||
@ -601,7 +601,7 @@ func (svr *Service) RegisterWorkConn(workConn net.Conn, newMsg *msg.NewWorkConn)
|
||||
xl := netpkg.NewLogFromConn(workConn)
|
||||
ctl, exist := svr.ctlManager.GetByID(newMsg.RunID)
|
||||
if !exist {
|
||||
xl.Warn("No client control found for run id [%s]", newMsg.RunID)
|
||||
xl.Warnf("No client control found for run id [%s]", newMsg.RunID)
|
||||
return fmt.Errorf("no client control found for run id [%s]", newMsg.RunID)
|
||||
}
|
||||
// server plugin hook
|
||||
@ -620,7 +620,7 @@ func (svr *Service) RegisterWorkConn(workConn net.Conn, newMsg *msg.NewWorkConn)
|
||||
err = ctl.authVerifier.VerifyNewWorkConn(newMsg)
|
||||
}
|
||||
if err != nil {
|
||||
xl.Warn("invalid NewWorkConn with run id [%s]", newMsg.RunID)
|
||||
xl.Warnf("invalid NewWorkConn with run id [%s]", newMsg.RunID)
|
||||
_ = msg.WriteMsg(workConn, &msg.StartWorkConn{
|
||||
Error: util.GenerateResponseErrorString("invalid NewWorkConn", err, lo.FromPtr(svr.cfg.DetailedErrorsToClient)),
|
||||
})
|
||||
|
@ -18,10 +18,10 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"slices"
|
||||
"sync"
|
||||
|
||||
libio "github.com/fatedier/golib/io"
|
||||
"github.com/samber/lo"
|
||||
|
||||
netpkg "github.com/fatedier/frp/pkg/util/net"
|
||||
"github.com/fatedier/frp/pkg/util/util"
|
||||
@ -75,7 +75,7 @@ func (vm *Manager) NewConn(name string, conn net.Conn, timestamp int64, signKey
|
||||
return
|
||||
}
|
||||
|
||||
if !lo.Contains(l.allowUsers, visitorUser) && !lo.Contains(l.allowUsers, "*") {
|
||||
if !slices.Contains(l.allowUsers, visitorUser) && !slices.Contains(l.allowUsers, "*") {
|
||||
err = fmt.Errorf("visitor connection of [%s] user [%s] not allowed", name, visitorUser)
|
||||
return
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ func RunE2ETests(t *testing.T) {
|
||||
// Randomize specs as well as suites
|
||||
suiteConfig.RandomizeAllSpecs = true
|
||||
|
||||
log.Info("Starting e2e run %q on Ginkgo node %d of total %d",
|
||||
log.Infof("Starting e2e run %q on Ginkgo node %d of total %d",
|
||||
framework.RunID, suiteConfig.ParallelProcess, suiteConfig.ParallelTotal)
|
||||
ginkgo.RunSpecs(t, "frp e2e suite", suiteConfig, reporterConfig)
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ func TestMain(m *testing.M) {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
log.InitLog("console", framework.TestContext.LogLevel, 0, true)
|
||||
log.InitLogger("console", framework.TestContext.LogLevel, 0, true)
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ func (f *Framework) RunProcesses(serverTemplates []string, clientTemplates []str
|
||||
ExpectNoError(err)
|
||||
|
||||
if TestContext.Debug {
|
||||
flog.Debug("[%s] %s", path, outs[i])
|
||||
flog.Debugf("[%s] %s", path, outs[i])
|
||||
}
|
||||
|
||||
p := process.NewWithEnvs(TestContext.FRPServerPath, []string{"-c", path}, f.osEnvs)
|
||||
@ -52,7 +52,7 @@ func (f *Framework) RunProcesses(serverTemplates []string, clientTemplates []str
|
||||
ExpectNoError(err)
|
||||
|
||||
if TestContext.Debug {
|
||||
flog.Debug("[%s] %s", path, outs[index])
|
||||
flog.Debugf("[%s] %s", path, outs[index])
|
||||
}
|
||||
|
||||
p := process.NewWithEnvs(TestContext.FRPClientPath, []string{"-c", path}, f.osEnvs)
|
||||
|
@ -20,7 +20,7 @@ func ExpectResponseCode(code int) EnsureFunc {
|
||||
if resp.Code == code {
|
||||
return true
|
||||
}
|
||||
flog.Warn("Expect code %d, but got %d", code, resp.Code)
|
||||
flog.Warnf("Expect code %d, but got %d", code, resp.Code)
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -111,14 +111,14 @@ func (e *RequestExpect) Ensure(fns ...EnsureFunc) {
|
||||
|
||||
if len(fns) == 0 {
|
||||
if !bytes.Equal(e.expectResp, ret.Content) {
|
||||
flog.Trace("Response info: %+v", ret)
|
||||
flog.Tracef("Response info: %+v", ret)
|
||||
}
|
||||
ExpectEqualValuesWithOffset(1, ret.Content, e.expectResp, e.explain...)
|
||||
} else {
|
||||
for _, fn := range fns {
|
||||
ok := fn(ret)
|
||||
if !ok {
|
||||
flog.Trace("Response info: %+v", ret)
|
||||
flog.Tracef("Response info: %+v", ret)
|
||||
}
|
||||
ExpectTrueWithOffset(1, ok, e.explain...)
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ var _ = ginkgo.Describe("[Feature: Monitor]", func() {
|
||||
framework.NewRequestExpect(f).RequestModify(func(r *request.Request) {
|
||||
r.HTTP().Port(dashboardPort).HTTPPath("/metrics")
|
||||
}).Ensure(func(resp *request.Response) bool {
|
||||
log.Trace("prometheus metrics response: \n%s", resp.Content)
|
||||
log.Tracef("prometheus metrics response: \n%s", resp.Content)
|
||||
if resp.Code != 200 {
|
||||
return false
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ var _ = ginkgo.Describe("[Feature: Real IP]", func() {
|
||||
rd := bufio.NewReader(c)
|
||||
ppHeader, err := pp.Read(rd)
|
||||
if err != nil {
|
||||
log.Error("read proxy protocol error: %v", err)
|
||||
log.Errorf("read proxy protocol error: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@ var _ = ginkgo.Describe("[Feature: Real IP]", func() {
|
||||
f.RunProcesses([]string{serverConf}, []string{clientConf})
|
||||
|
||||
framework.NewRequestExpect(f).Port(remotePort).Ensure(func(resp *request.Response) bool {
|
||||
log.Trace("ProxyProtocol get SourceAddr: %s", string(resp.Content))
|
||||
log.Tracef("ProxyProtocol get SourceAddr: %s", string(resp.Content))
|
||||
addr, err := net.ResolveTCPAddr("tcp", string(resp.Content))
|
||||
if err != nil {
|
||||
return false
|
||||
@ -121,7 +121,7 @@ var _ = ginkgo.Describe("[Feature: Real IP]", func() {
|
||||
rd := bufio.NewReader(c)
|
||||
ppHeader, err := pp.Read(rd)
|
||||
if err != nil {
|
||||
log.Error("read proxy protocol error: %v", err)
|
||||
log.Errorf("read proxy protocol error: %v", err)
|
||||
return
|
||||
}
|
||||
srcAddrRecord = ppHeader.SourceAddr.String()
|
||||
@ -142,7 +142,7 @@ var _ = ginkgo.Describe("[Feature: Real IP]", func() {
|
||||
r.HTTP().HTTPHost("normal.example.com")
|
||||
}).Ensure(framework.ExpectResponseCode(404))
|
||||
|
||||
log.Trace("ProxyProtocol get SourceAddr: %s", srcAddrRecord)
|
||||
log.Tracef("ProxyProtocol get SourceAddr: %s", srcAddrRecord)
|
||||
addr, err := net.ResolveTCPAddr("tcp", srcAddrRecord)
|
||||
framework.ExpectNoError(err, srcAddrRecord)
|
||||
framework.ExpectEqualValues("127.0.0.1", addr.IP.String())
|
||||
|
@ -26,7 +26,7 @@ func NewHTTPPluginServer(port int, newFunc NewPluginRequest, handler Handler, tl
|
||||
w.WriteHeader(500)
|
||||
return
|
||||
}
|
||||
log.Trace("plugin request: %s", string(buf))
|
||||
log.Tracef("plugin request: %s", string(buf))
|
||||
err = json.Unmarshal(buf, &r)
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
@ -34,7 +34,7 @@ func NewHTTPPluginServer(port int, newFunc NewPluginRequest, handler Handler, tl
|
||||
}
|
||||
resp := handler(r)
|
||||
buf, _ = json.Marshal(resp)
|
||||
log.Trace("plugin response: %s", string(buf))
|
||||
log.Tracef("plugin response: %s", string(buf))
|
||||
_, _ = w.Write(buf)
|
||||
})),
|
||||
)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user