Skip to content

Commit ccfe8c9

Browse files
authored
Merge pull request #4392 from fatedier/dev
bump version
2 parents 243ca99 + 03c8d7b commit ccfe8c9

33 files changed

+272
-132
lines changed

.github/FUNDING.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# These are supported funding model platforms
22

33
github: [fatedier]
4-
custom: ["https://afdian.net/a/fatedier"]
4+
custom: ["https://afdian.com/a/fatedier"]

.golangci.yml

+1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ linters-settings:
8888
excludes:
8989
- G401
9090
- G402
91+
- G404
9192
- G501
9293

9394
issues:

Makefile.cross-compiles

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ export PATH := $(PATH):`go env GOPATH`/bin
22
export GO111MODULE=on
33
LDFLAGS := -s -w
44

5-
os-archs=darwin:amd64 darwin:arm64 freebsd:amd64 linux:amd64 linux:arm:7 linux:arm:5 linux:arm64 windows:amd64 windows:arm64 linux:mips64 linux:mips64le linux:mips:softfloat linux:mipsle:softfloat linux:riscv64 android:arm64
5+
os-archs=darwin:amd64 darwin:arm64 freebsd:amd64 linux:amd64 linux:arm:7 linux:arm:5 linux:arm64 windows:amd64 windows:arm64 linux:mips64 linux:mips64le linux:mips:softfloat linux:mipsle:softfloat linux:riscv64 linux:loong64 android:arm64
66

77
all: build
88

README.md

-5
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,6 @@
99

1010
<h3 align="center">Gold Sponsors</h3>
1111
<!--gold sponsors start-->
12-
<p align="center">
13-
<a href="https://lokal.so/?utm_campaign=github_repo&utm_medium=referral&utm_content=frp&utm_source=github" target="_blank">
14-
<img width="420px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_lokal.png">
15-
</a>
16-
</p>
1712
<p align="center">
1813
<a href="https://workos.com/?utm_campaign=github_repo&utm_medium=referral&utm_content=frp&utm_source=github" target="_blank">
1914
<img width="420px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_workos.png">

README_zh.md

-5
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,6 @@ frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP
1111

1212
<h3 align="center">Gold Sponsors</h3>
1313
<!--gold sponsors start-->
14-
<p align="center">
15-
<a href="https://lokal.so/?utm_campaign=github_repo&utm_medium=referral&utm_content=frp&utm_source=github" target="_blank">
16-
<img width="420px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_lokal.png">
17-
</a>
18-
</p>
1914
<p align="center">
2015
<a href="https://workos.com/?utm_campaign=github_repo&utm_medium=referral&utm_content=frp&utm_source=github" target="_blank">
2116
<img width="420px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_workos.png">

Release.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
### Features
22

3-
* Added a new plugin "http2http" which allows forwarding HTTP requests to another HTTP server, supporting options like local address binding, host header rewrite, and custom request headers.
4-
* Added `enableHTTP2` option to control whether to enable HTTP/2 in plugin https2http and https2https, default is true.
3+
* Added a new plugin `tls2raw`: Enables TLS termination and forwarding of decrypted raw traffic to local service.
4+
* Added a default timeout of 30 seconds for the frpc subcommands to prevent commands from being stuck for a long time due to network issues.
55

6-
### Changes
6+
### Fixes
77

8-
* Plugin https2http & https2https: return 421 `Misdirected Request` if host not match sni.
8+
* Fixed the issue that when `loginFailExit = false`, the frpc stop command cannot be stopped correctly if the server is not successfully connected after startup.

client/proxy/proxy.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ func (pxy *BaseProxy) HandleTCPWorkConnection(workConn net.Conn, m *msg.StartWor
192192
if pxy.proxyPlugin != nil {
193193
// if plugin is set, let plugin handle connection first
194194
xl.Debugf("handle by plugin: %s", pxy.proxyPlugin.Name())
195-
pxy.proxyPlugin.Handle(remote, workConn, &extraInfo)
195+
pxy.proxyPlugin.Handle(pxy.ctx, remote, workConn, &extraInfo)
196196
xl.Debugf("handle by plugin finished")
197197
return
198198
}

client/service.go

+9-8
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,15 @@ func (svr *Service) Run(ctx context.Context) error {
169169
netpkg.SetDefaultDNSAddress(svr.common.DNSServer)
170170
}
171171

172+
if svr.webServer != nil {
173+
go func() {
174+
log.Infof("admin server listen on %s", svr.webServer.Address())
175+
if err := svr.webServer.Run(); err != nil {
176+
log.Warnf("admin server exit with error: %v", err)
177+
}
178+
}()
179+
}
180+
172181
// first login to frps
173182
svr.loopLoginUntilSuccess(10*time.Second, lo.FromPtr(svr.common.LoginFailExit))
174183
if svr.ctl == nil {
@@ -179,14 +188,6 @@ func (svr *Service) Run(ctx context.Context) error {
179188

180189
go svr.keepControllerWorking()
181190

182-
if svr.webServer != nil {
183-
go func() {
184-
log.Infof("admin server listen on %s", svr.webServer.Address())
185-
if err := svr.webServer.Run(); err != nil {
186-
log.Warnf("admin server exit with error: %v", err)
187-
}
188-
}()
189-
}
190191
<-svr.ctx.Done()
191192
svr.stop()
192193
return nil

cmd/frpc/sub/admin.go

+27-19
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@
1515
package sub
1616

1717
import (
18+
"context"
1819
"fmt"
1920
"os"
2021
"strings"
22+
"time"
2123

2224
"github.com/rodaine/table"
2325
"github.com/spf13/cobra"
@@ -27,24 +29,24 @@ import (
2729
clientsdk "github.com/fatedier/frp/pkg/sdk/client"
2830
)
2931

30-
func init() {
31-
rootCmd.AddCommand(NewAdminCommand(
32-
"reload",
33-
"Hot-Reload frpc configuration",
34-
ReloadHandler,
35-
))
32+
var adminAPITimeout = 30 * time.Second
3633

37-
rootCmd.AddCommand(NewAdminCommand(
38-
"status",
39-
"Overview of all proxies status",
40-
StatusHandler,
41-
))
34+
func init() {
35+
commands := []struct {
36+
name string
37+
description string
38+
handler func(*v1.ClientCommonConfig) error
39+
}{
40+
{"reload", "Hot-Reload frpc configuration", ReloadHandler},
41+
{"status", "Overview of all proxies status", StatusHandler},
42+
{"stop", "Stop the running frpc", StopHandler},
43+
}
4244

43-
rootCmd.AddCommand(NewAdminCommand(
44-
"stop",
45-
"Stop the running frpc",
46-
StopHandler,
47-
))
45+
for _, cmdConfig := range commands {
46+
cmd := NewAdminCommand(cmdConfig.name, cmdConfig.description, cmdConfig.handler)
47+
cmd.Flags().DurationVar(&adminAPITimeout, "api-timeout", adminAPITimeout, "Timeout for admin API calls")
48+
rootCmd.AddCommand(cmd)
49+
}
4850
}
4951

5052
func NewAdminCommand(name, short string, handler func(*v1.ClientCommonConfig) error) *cobra.Command {
@@ -73,7 +75,9 @@ func NewAdminCommand(name, short string, handler func(*v1.ClientCommonConfig) er
7375
func ReloadHandler(clientCfg *v1.ClientCommonConfig) error {
7476
client := clientsdk.New(clientCfg.WebServer.Addr, clientCfg.WebServer.Port)
7577
client.SetAuth(clientCfg.WebServer.User, clientCfg.WebServer.Password)
76-
if err := client.Reload(strictConfigMode); err != nil {
78+
ctx, cancel := context.WithTimeout(context.Background(), adminAPITimeout)
79+
defer cancel()
80+
if err := client.Reload(ctx, strictConfigMode); err != nil {
7781
return err
7882
}
7983
fmt.Println("reload success")
@@ -83,7 +87,9 @@ func ReloadHandler(clientCfg *v1.ClientCommonConfig) error {
8387
func StatusHandler(clientCfg *v1.ClientCommonConfig) error {
8488
client := clientsdk.New(clientCfg.WebServer.Addr, clientCfg.WebServer.Port)
8589
client.SetAuth(clientCfg.WebServer.User, clientCfg.WebServer.Password)
86-
res, err := client.GetAllProxyStatus()
90+
ctx, cancel := context.WithTimeout(context.Background(), adminAPITimeout)
91+
defer cancel()
92+
res, err := client.GetAllProxyStatus(ctx)
8793
if err != nil {
8894
return err
8995
}
@@ -109,7 +115,9 @@ func StatusHandler(clientCfg *v1.ClientCommonConfig) error {
109115
func StopHandler(clientCfg *v1.ClientCommonConfig) error {
110116
client := clientsdk.New(clientCfg.WebServer.Addr, clientCfg.WebServer.Port)
111117
client.SetAuth(clientCfg.WebServer.User, clientCfg.WebServer.Password)
112-
if err := client.Stop(); err != nil {
118+
ctx, cancel := context.WithTimeout(context.Background(), adminAPITimeout)
119+
defer cancel()
120+
if err := client.Stop(ctx); err != nil {
113121
return err
114122
}
115123
fmt.Println("stop success")

conf/frpc_full_example.toml

+10
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,16 @@ localAddr = "127.0.0.1:80"
325325
hostHeaderRewrite = "127.0.0.1"
326326
requestHeaders.set.x-from-where = "frp"
327327

328+
[[proxies]]
329+
name = "plugin_tls2raw"
330+
type = "https"
331+
remotePort = 6008
332+
[proxies.plugin]
333+
type = "tls2raw"
334+
localAddr = "127.0.0.1:80"
335+
crtPath = "./server.crt"
336+
keyPath = "./server.key"
337+
328338
[[proxies]]
329339
name = "secret_tcp"
330340
# If the type is secret tcp, remotePort is useless

go.mod

+3-4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ require (
2323
github.com/spf13/pflag v1.0.5
2424
github.com/stretchr/testify v1.9.0
2525
github.com/tidwall/gjson v1.17.1
26-
github.com/xtaci/kcp-go/v5 v5.6.8
26+
github.com/xtaci/kcp-go/v5 v5.6.13
2727
golang.org/x/crypto v0.22.0
2828
golang.org/x/net v0.24.0
2929
golang.org/x/oauth2 v0.16.0
@@ -59,9 +59,8 @@ require (
5959
github.com/prometheus/client_model v0.5.0 // indirect
6060
github.com/prometheus/common v0.48.0 // indirect
6161
github.com/prometheus/procfs v0.12.0 // indirect
62-
github.com/rogpeppe/go-internal v1.11.0 // indirect
63-
github.com/templexxx/cpu v0.1.0 // indirect
64-
github.com/templexxx/xorsimd v0.4.2 // indirect
62+
github.com/templexxx/cpu v0.1.1 // indirect
63+
github.com/templexxx/xorsimd v0.4.3 // indirect
6564
github.com/tidwall/match v1.1.1 // indirect
6665
github.com/tidwall/pretty v1.2.0 // indirect
6766
github.com/tjfoc/gmsm v1.4.1 // indirect

go.sum

+8-8
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,8 @@ github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
116116
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
117117
github.com/rodaine/table v1.2.0 h1:38HEnwK4mKSHQJIkavVj+bst1TEY7j9zhLMWu4QJrMA=
118118
github.com/rodaine/table v1.2.0/go.mod h1:wejb/q/Yd4T/SVmBSRMr7GCq3KlcZp3gyNYdLSBhkaE=
119-
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
120-
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
119+
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
120+
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
121121
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
122122
github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA=
123123
github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
@@ -136,10 +136,10 @@ github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
136136
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
137137
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
138138
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
139-
github.com/templexxx/cpu v0.1.0 h1:wVM+WIJP2nYaxVxqgHPD4wGA2aJ9rvrQRV8CvFzNb40=
140-
github.com/templexxx/cpu v0.1.0/go.mod h1:w7Tb+7qgcAlIyX4NhLuDKt78AHA5SzPmq0Wj6HiEnnk=
141-
github.com/templexxx/xorsimd v0.4.2 h1:ocZZ+Nvu65LGHmCLZ7OoCtg8Fx8jnHKK37SjvngUoVI=
142-
github.com/templexxx/xorsimd v0.4.2/go.mod h1:HgwaPoDREdi6OnULpSfxhzaiiSUY4Fi3JPn1wpt28NI=
139+
github.com/templexxx/cpu v0.1.1 h1:isxHaxBXpYFWnk2DReuKkigaZyrjs2+9ypIdGP4h+HI=
140+
github.com/templexxx/cpu v0.1.1/go.mod h1:w7Tb+7qgcAlIyX4NhLuDKt78AHA5SzPmq0Wj6HiEnnk=
141+
github.com/templexxx/xorsimd v0.4.3 h1:9AQTFHd7Bhk3dIT7Al2XeBX5DWOvsUPZCuhyAtNbHjU=
142+
github.com/templexxx/xorsimd v0.4.3/go.mod h1:oZQcD6RFDisW2Am58dSAGwwL6rHjbzrlu25VDqfWkQg=
143143
github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U=
144144
github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
145145
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
@@ -148,8 +148,8 @@ github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
148148
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
149149
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
150150
github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
151-
github.com/xtaci/kcp-go/v5 v5.6.8 h1:jlI/0jAyjoOjT/SaGB58s4bQMJiNS41A2RKzR6TMWeI=
152-
github.com/xtaci/kcp-go/v5 v5.6.8/go.mod h1:oE9j2NVqAkuKO5o8ByKGch3vgVX3BNf8zqP8JiGq0bM=
151+
github.com/xtaci/kcp-go/v5 v5.6.13 h1:FEjtz9+D4p8t2x4WjciGt/jsIuhlWjjgPCCWjrVR4Hk=
152+
github.com/xtaci/kcp-go/v5 v5.6.13/go.mod h1:75S1AKYYzNUSXIv30h+jPKJYZUwqpfvLshu63nCNSOM=
153153
github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37 h1:EWU6Pktpas0n8lLQwDsRyZfmkPeRbdgPtW609es+/9E=
154154
github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37/go.mod h1:HpMP7DB2CyokmAh4lp0EQnnWhmycP/TvwBGzvuie+H0=
155155
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=

package.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ rm -rf ./release/packages
1818
mkdir -p ./release/packages
1919

2020
os_all='linux windows darwin freebsd android'
21-
arch_all='386 amd64 arm arm64 mips64 mips64le mips mipsle riscv64'
21+
arch_all='386 amd64 arm arm64 mips64 mips64le mips mipsle riscv64 loong64'
2222
extra_all='_ hf'
2323

2424
cd ./release

pkg/config/v1/plugin.go

+11
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ const (
8383
PluginSocks5 = "socks5"
8484
PluginStaticFile = "static_file"
8585
PluginUnixDomainSocket = "unix_domain_socket"
86+
PluginTLS2Raw = "tls2raw"
8687
)
8788

8889
var clientPluginOptionsTypeMap = map[string]reflect.Type{
@@ -94,6 +95,7 @@ var clientPluginOptionsTypeMap = map[string]reflect.Type{
9495
PluginSocks5: reflect.TypeOf(Socks5PluginOptions{}),
9596
PluginStaticFile: reflect.TypeOf(StaticFilePluginOptions{}),
9697
PluginUnixDomainSocket: reflect.TypeOf(UnixDomainSocketPluginOptions{}),
98+
PluginTLS2Raw: reflect.TypeOf(TLS2RawPluginOptions{}),
9799
}
98100

99101
type HTTP2HTTPSPluginOptions struct {
@@ -174,3 +176,12 @@ type UnixDomainSocketPluginOptions struct {
174176
}
175177

176178
func (o *UnixDomainSocketPluginOptions) Complete() {}
179+
180+
type TLS2RawPluginOptions struct {
181+
Type string `json:"type,omitempty"`
182+
LocalAddr string `json:"localAddr,omitempty"`
183+
CrtPath string `json:"crtPath,omitempty"`
184+
KeyPath string `json:"keyPath,omitempty"`
185+
}
186+
187+
func (o *TLS2RawPluginOptions) Complete() {}

pkg/config/v1/validation/plugin.go

+9
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ func ValidateClientPluginOptions(c v1.ClientPluginOptions) error {
3232
return validateStaticFilePluginOptions(v)
3333
case *v1.UnixDomainSocketPluginOptions:
3434
return validateUnixDomainSocketPluginOptions(v)
35+
case *v1.TLS2RawPluginOptions:
36+
return validateTLS2RawPluginOptions(v)
3537
}
3638
return nil
3739
}
@@ -70,3 +72,10 @@ func validateUnixDomainSocketPluginOptions(c *v1.UnixDomainSocketPluginOptions)
7072
}
7173
return nil
7274
}
75+
76+
func validateTLS2RawPluginOptions(c *v1.TLS2RawPluginOptions) error {
77+
if c.LocalAddr == "" {
78+
return errors.New("localAddr is required")
79+
}
80+
return nil
81+
}

pkg/plugin/client/http2http.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
//go:build !frps
16+
1517
package plugin
1618

1719
import (
20+
"context"
1821
"io"
1922
stdlog "log"
2023
"net"
@@ -77,7 +80,7 @@ func NewHTTP2HTTPPlugin(options v1.ClientPluginOptions) (Plugin, error) {
7780
return p, nil
7881
}
7982

80-
func (p *HTTP2HTTPPlugin) Handle(conn io.ReadWriteCloser, realConn net.Conn, _ *ExtraInfo) {
83+
func (p *HTTP2HTTPPlugin) Handle(_ context.Context, conn io.ReadWriteCloser, realConn net.Conn, _ *ExtraInfo) {
8184
wrapConn := netpkg.WrapReadWriteCloserToConn(conn, realConn)
8285
_ = p.l.PutConn(wrapConn)
8386
}

pkg/plugin/client/http2https.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package plugin
1818

1919
import (
20+
"context"
2021
"crypto/tls"
2122
"io"
2223
stdlog "log"
@@ -88,7 +89,7 @@ func NewHTTP2HTTPSPlugin(options v1.ClientPluginOptions) (Plugin, error) {
8889
return p, nil
8990
}
9091

91-
func (p *HTTP2HTTPSPlugin) Handle(conn io.ReadWriteCloser, realConn net.Conn, _ *ExtraInfo) {
92+
func (p *HTTP2HTTPSPlugin) Handle(_ context.Context, conn io.ReadWriteCloser, realConn net.Conn, _ *ExtraInfo) {
9293
wrapConn := netpkg.WrapReadWriteCloserToConn(conn, realConn)
9394
_ = p.l.PutConn(wrapConn)
9495
}

pkg/plugin/client/http_proxy.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package plugin
1818

1919
import (
2020
"bufio"
21+
"context"
2122
"encoding/base64"
2223
"io"
2324
"net"
@@ -68,7 +69,7 @@ func (hp *HTTPProxy) Name() string {
6869
return v1.PluginHTTPProxy
6970
}
7071

71-
func (hp *HTTPProxy) Handle(conn io.ReadWriteCloser, realConn net.Conn, _ *ExtraInfo) {
72+
func (hp *HTTPProxy) Handle(_ context.Context, conn io.ReadWriteCloser, realConn net.Conn, _ *ExtraInfo) {
7273
wrapConn := netpkg.WrapReadWriteCloserToConn(conn, realConn)
7374

7475
sc, rd := libnet.NewSharedConn(wrapConn)

0 commit comments

Comments
 (0)