Skip to content

Commit

Permalink
Merge pull request #4092 from fatedier/dev
Browse files Browse the repository at this point in the history
bump v0.56.0
  • Loading branch information
fatedier authored Mar 21, 2024
2 parents a5b7abf + f16ef00 commit 5a6d9f6
Show file tree
Hide file tree
Showing 32 changed files with 317 additions and 57 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
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
version: v1.57

# Optional: golangci-lint command line arguments.
# args: --issues-exit-code=0
Expand Down
27 changes: 9 additions & 18 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
service:
golangci-lint-version: 1.56.x # use the fixed version to not introduce new linters unexpectedly
golangci-lint-version: 1.57.x # use the fixed version to not introduce new linters unexpectedly

run:
concurrency: 4
Expand All @@ -8,23 +8,6 @@ run:
build-tags:
- integ
- integfuzz
# which dirs to skip: they won't be analyzed;
# can use regexp here: generated.*, regexp is applied on full path;
# default value is empty list, but next dirs are always skipped independently
# from this option's value:
# vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
skip-dirs:
- genfiles$
- vendor$
- bin$

# which files to skip: they will be analyzed, but issues from them
# won't be reported. Default value is empty list, but there is
# no need to include all autogenerated files, we confidently recognize
# autogenerated files. If it's not please let us know.
skip-files:
- ".*\\.pb\\.go"
- ".*\\.gen\\.go"

linters:
disable-all: true
Expand Down Expand Up @@ -136,6 +119,14 @@ issues:
- unparam
text: "is always false"

exclude-dirs:
- genfiles$
- vendor$
- bin$
exclude-files:
- ".*\\.pb\\.go"
- ".*\\.gen\\.go"

# Independently from option `exclude` we use default exclude patterns,
# it can be disabled by this option. To list all
# excluded by default patterns execute `golangci-lint run --help`.
Expand Down
2 changes: 1 addition & 1 deletion Makefile.cross-compiles
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export PATH := $(PATH):`go env GOPATH`/bin
export GO111MODULE=on
LDFLAGS := -s -w

os-archs=darwin:amd64 darwin:arm64 freebsd:amd64 linux:amd64 linux:arm linux:arm64 windows:amd64 windows:arm64 linux:mips64 linux:mips64le linux:mips:softfloat linux:mipsle:softfloat linux:riscv64
os-archs=darwin:amd64 darwin:arm64 freebsd:amd64 linux:amd64 linux:arm linux:arm64 windows:amd64 windows:arm64 linux:mips64 linux:mips64le linux:mips:softfloat linux:mipsle:softfloat linux:riscv64 android:arm64

all: build

Expand Down
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ frp also offers a P2P connect mode.
* [URL Routing](#url-routing)
* [TCP Port Multiplexing](#tcp-port-multiplexing)
* [Connecting to frps via PROXY](#connecting-to-frps-via-proxy)
* [Port range mapping](#port-range-mapping)
* [Client Plugins](#client-plugins)
* [Server Manage Plugins](#server-manage-plugins)
* [SSH Tunnel Gateway](#ssh-tunnel-gateway)
Expand Down Expand Up @@ -1158,6 +1159,24 @@ serverPort = 7000
transport.proxyURL = "http://user:[email protected]:8080"
```

### Port range mapping

*Added in v0.56.0*

We can use the range syntax of Go template combined with the built-in `parseNumberRangePair` function to achieve port range mapping.

The following example, when run, will create 8 proxies named `test-6000, test-6001 ... test-6007`, each mapping the remote port to the local port.

```
{{- range $_, $v := parseNumberRangePair "6000-6006,6007" "6000-6006,6007" }}
[[proxies]]
name = "tcp-{{ $v.First }}"
type = "tcp"
localPort = {{ $v.First }}
remotePort = {{ $v.Second }}
{{- end }}
```

### Client Plugins

frpc only forwards requests to local TCP or UDP ports by default.
Expand Down
26 changes: 25 additions & 1 deletion Release.md
Original file line number Diff line number Diff line change
@@ -1 +1,25 @@
No feature changes, just a fix for the issue of no released assets in version 0.55.0.
### Features

* Support range ports mapping in TOML/YAML/JSON configuration file by using go template syntax.

For example:

```
{{- range $_, $v := parseNumberRangePair "6000-6006,6007" "6000-6006,6007" }}
[[proxies]]
name = "tcp-{{ $v.First }}"
type = "tcp"
localPort = {{ $v.First }}
remotePort = {{ $v.Second }}
{{- end }}
```

This will create 8 proxies such as `tcp-6000, tcp-6001, ... tcp-6007`.

* Health check supports custom request headers.
* Enable compatibility mode for the Android system to solve the issues of incorrect log time caused by time zone problems and default DNS resolution failures.

### Fixes

* Fix the issue of incorrect interval time for rotating the log by day.
* Disable quic-go's ECN support by default. It may cause issues on certain operating systems.
12 changes: 10 additions & 2 deletions client/health/health.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ type Monitor struct {
addr string

// For http
url string

url string
header http.Header
failedTimes uint64
statusOK bool
statusNormalFn func()
Expand Down Expand Up @@ -73,13 +73,19 @@ func NewMonitor(ctx context.Context, cfg v1.HealthCheckConfig, addr string,
}
url = s + cfg.Path
}
header := make(http.Header)
for _, h := range cfg.HTTPHeaders {
header.Set(h.Name, h.Value)
}

return &Monitor{
checkType: cfg.Type,
interval: time.Duration(cfg.IntervalSeconds) * time.Second,
timeout: time.Duration(cfg.TimeoutSeconds) * time.Second,
maxFailedTimes: cfg.MaxFailed,
addr: addr,
url: url,
header: header,
statusOK: false,
statusNormalFn: statusNormalFn,
statusFailedFn: statusFailedFn,
Expand Down Expand Up @@ -163,6 +169,8 @@ func (monitor *Monitor) doHTTPCheck(ctx context.Context) error {
if err != nil {
return err
}
req.Header = monitor.header
req.Host = monitor.header.Get("Host")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
Expand Down
7 changes: 7 additions & 0 deletions client/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"errors"
"fmt"
"net"
"os"
"runtime"
"sync"
"time"
Expand All @@ -40,6 +41,12 @@ import (

func init() {
crypto.DefaultSalt = "frp"
// Disable quic-go's receive buffer warning.
os.Setenv("QUIC_GO_DISABLE_RECEIVE_BUFFER_WARNING", "true")
// Disable quic-go's ECN support by default. It may cause issues on certain operating systems.
if os.Getenv("QUIC_GO_DISABLE_ECN") == "" {
os.Setenv("QUIC_GO_DISABLE_ECN", "true")
}
}

type cancelErr struct {
Expand Down
2 changes: 2 additions & 0 deletions cmd/frpc/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ package main
import (
_ "github.com/fatedier/frp/assets/frpc"
"github.com/fatedier/frp/cmd/frpc/sub"
"github.com/fatedier/frp/pkg/util/system"
)

func main() {
system.EnableCompatibilityMode()
sub.Execute()
}
5 changes: 2 additions & 3 deletions cmd/frps/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,12 @@
package main

import (
"github.com/fatedier/golib/crypto"

_ "github.com/fatedier/frp/assets/frps"
_ "github.com/fatedier/frp/pkg/metrics"
"github.com/fatedier/frp/pkg/util/system"
)

func main() {
crypto.DefaultSalt = "frp"
system.EnableCompatibilityMode()
Execute()
}
4 changes: 4 additions & 0 deletions conf/frpc_full_example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,10 @@ healthCheck.path = "/status"
healthCheck.intervalSeconds = 10
healthCheck.maxFailed = 3
healthCheck.timeoutSeconds = 3
# set health check headers
healthCheck.httpHeaders=[
{ name = "x-from-where", value = "frp" }
]

[[proxies]]
name = "web02"
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ 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/golib v0.4.0
github.com/fatedier/golib v0.4.2
github.com/google/uuid v1.3.0
github.com/gorilla/mux v1.8.0
github.com/gorilla/websocket v1.5.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +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/golib v0.4.0 h1:lafvYRMhFmqrfIUChKy/f5AXqs1eDSk+GAUtLexN5bU=
github.com/fatedier/golib v0.4.0/go.mod h1:gpu+1vXxtJ072NYaNsn/YWgojDL8Ap2kFZQtbzT2qkg=
github.com/fatedier/golib v0.4.2 h1:k+ZBdUFTTipnP1RHfEhGbzyShRdz/rZtFGnjpXG9D9c=
github.com/fatedier/golib v0.4.2/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=
Expand Down
5 changes: 4 additions & 1 deletion pkg/config/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,10 @@ func DetectLegacyINIFormatFromFile(path string) bool {
}

func RenderWithTemplate(in []byte, values *Values) ([]byte, error) {
tmpl, err := template.New("frp").Parse(string(in))
tmpl, err := template.New("frp").Funcs(template.FuncMap{
"parseNumberRange": parseNumberRange,
"parseNumberRangePair": parseNumberRangePair,
}).Parse(string(in))
if err != nil {
return nil, err
}
Expand Down
52 changes: 52 additions & 0 deletions pkg/config/template.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright 2024 The frp Authors
//
// 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 config

import (
"fmt"

"github.com/fatedier/frp/pkg/util/util"
)

type NumberPair struct {
First int64
Second int64
}

func parseNumberRangePair(firstRangeStr, secondRangeStr string) ([]NumberPair, error) {
firstRangeNumbers, err := util.ParseRangeNumbers(firstRangeStr)
if err != nil {
return nil, err
}
secondRangeNumbers, err := util.ParseRangeNumbers(secondRangeStr)
if err != nil {
return nil, err
}
if len(firstRangeNumbers) != len(secondRangeNumbers) {
return nil, fmt.Errorf("first and second range numbers are not in pairs")
}
pairs := make([]NumberPair, 0, len(firstRangeNumbers))
for i := 0; i < len(firstRangeNumbers); i++ {
pairs = append(pairs, NumberPair{
First: firstRangeNumbers[i],
Second: secondRangeNumbers[i],
})
}
return pairs, nil
}

func parseNumberRange(firstRangeStr string) ([]int64, error) {
return util.ParseRangeNumbers(firstRangeStr)
}
5 changes: 5 additions & 0 deletions pkg/config/v1/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,8 @@ type HTTPPluginOptions struct {
type HeaderOperations struct {
Set map[string]string `json:"set,omitempty"`
}

type HTTPHeader struct {
Name string `json:"name"`
Value string `json:"value"`
}
3 changes: 3 additions & 0 deletions pkg/config/v1/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ type HealthCheckConfig struct {
// Path specifies the path to send health checks to if the
// health check type is "http".
Path string `json:"path,omitempty"`
// HTTPHeaders specifies the headers to send with the health request, if
// the health check type is "http".
HTTPHeaders []HTTPHeader `json:"httpHeaders,omitempty"`
}

type DomainConfig struct {
Expand Down
6 changes: 3 additions & 3 deletions pkg/nathole/nathole.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ package nathole
import (
"context"
"fmt"
"math/rand"
"math/rand/v2"
"net"
"slices"
"strconv"
Expand Down Expand Up @@ -341,7 +341,7 @@ func sendSidMessage(
TransactionID: transactionID,
Sid: sid,
Response: false,
Nonce: strings.Repeat("0", rand.Intn(20)),
Nonce: strings.Repeat("0", rand.IntN(20)),
}
buf, err := EncodeMessage(m, key)
if err != nil {
Expand Down Expand Up @@ -398,7 +398,7 @@ func sendSidMessageToRandomPorts(
used := sets.New[int]()
getUnusedPort := func() int {
for i := 0; i < 10; i++ {
port := rand.Intn(65535-1024) + 1024
port := rand.IntN(65535-1024) + 1024
if !used.Has(port) {
used.Insert(port)
return port
Expand Down
4 changes: 2 additions & 2 deletions pkg/util/net/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ func SetDefaultDNSAddress(dnsAddress string) {
// Change default dns server
net.DefaultResolver = &net.Resolver{
PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
return net.Dial("udp", dnsAddress)
Dial: func(ctx context.Context, network, _ string) (net.Conn, error) {
return net.Dial(network, dnsAddress)
},
}
}
22 changes: 22 additions & 0 deletions pkg/util/system/system.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright 2024 The frp Authors
//
// 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.

//go:build !android

package system

// EnableCompatibilityMode enables compatibility mode for different system.
// For example, on Android, the inability to obtain the correct time zone will result in incorrect log time output.
func EnableCompatibilityMode() {
}
Loading

0 comments on commit 5a6d9f6

Please sign in to comment.