Skip to content

Commit

Permalink
support quic options (fatedier#3211)
Browse files Browse the repository at this point in the history
  • Loading branch information
fatedier authored Dec 18, 2022
1 parent b2e3946 commit 7678938
Show file tree
Hide file tree
Showing 12 changed files with 76 additions and 37 deletions.
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ frp also has a P2P connect mode.
* [For Each Proxy](#for-each-proxy)
* [TCP Stream Multiplexing](#tcp-stream-multiplexing)
* [Support KCP Protocol](#support-kcp-protocol)
* [Support QUIC Protocol](#support-quic-protocol)
* [Connection Pooling](#connection-pooling)
* [Load balancing](#load-balancing)
* [Service Health Check](#service-health-check)
Expand Down Expand Up @@ -761,6 +762,35 @@ KCP mode uses UDP as the underlying transport. Using KCP in frp:
protocol = kcp
```

### Support QUIC Protocol

QUIC is a new multiplexed transport built on top of UDP.

Using QUIC in frp:

1. Enable QUIC in frps:

```ini
# frps.ini
[common]
bind_port = 7000
# Specify a UDP port for QUIC.
quic_bind_port = 7000
```

The `quic_bind_port` number can be the same number as `bind_port`, since `bind_port` field specifies a TCP port.

2. Configure `frpc.ini` to use QUIC to connect to frps:

```ini
# frpc.ini
[common]
server_addr = x.x.x.x
# Same as the 'quic_bind_port' in frps.ini
server_port = 7000
protocol = quic
```

### Connection Pooling

By default, frps creates a new frpc connection to the backend service upon a user request. With connection pooling, frps keeps a certain number of pre-established connections, reducing the time needed to establish a connection.
Expand Down
3 changes: 2 additions & 1 deletion Release.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
### New

* Add oidc_scope parameter to frpc when authentication_method = oidc .
* Add `oidc_scope` parameter to frpc when `authentication_method = oidc`.
* Support quic protocol between frpc and frps.


### Improve
Expand Down
2 changes: 1 addition & 1 deletion client/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ func (ctl *Control) HandleReqWorkConn(inMsg *msg.ReqWorkConn) {

var startMsg msg.StartWorkConn
if err = msg.ReadMsgInto(workConn, &startMsg); err != nil {
xl.Error("work connection closed before response StartWorkConn message: %v", err)
xl.Trace("work connection closed before response StartWorkConn message: %v", err)
workConn.Close()
return
}
Expand Down
6 changes: 5 additions & 1 deletion client/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,11 @@ func (cm *ConnectionManager) OpenConnection() error {

conn, err := quic.DialAddr(
net.JoinHostPort(cm.cfg.ServerAddr, strconv.Itoa(cm.cfg.ServerPort)),
tlsConfig, nil)
tlsConfig, &quic.Config{
MaxIdleTimeout: time.Duration(cm.cfg.QUICMaxIdleTimeout) * time.Second,
MaxIncomingStreams: int64(cm.cfg.QUICMaxIncomingStreams),
KeepAlivePeriod: time.Duration(cm.cfg.QUICKeepalivePeriod) * time.Second,
})
if err != nil {
return err
}
Expand Down
5 changes: 5 additions & 0 deletions conf/frpc_full.ini
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ protocol = tcp
# only when protocol = tcp or websocket, the value will be used.
connect_server_local_ip = 0.0.0.0

# quic protocol options
# quic_keepalive_period = 10
# quic_max_idle_timeout = 30
# quic_max_incoming_streams = 100000

# if tls_enable is true, frpc will connect frps by tls
tls_enable = true

Expand Down
4 changes: 4 additions & 0 deletions conf/frps_full.ini
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ kcp_bind_port = 7000
# udp port used for quic protocol.
# if not set, quic is disabled in frps.
# quic_bind_port = 7002
# quic protocol options
# quic_keepalive_period = 10
# quic_max_idle_timeout = 30
# quic_max_incoming_streams = 100000

# specify which address proxy will listen for, default value is same with bind_addr
# proxy_bind_addr = 127.0.0.1
Expand Down
19 changes: 7 additions & 12 deletions pkg/config/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ type ClientCommonConf struct {
// Valid values are "tcp", "kcp", "quic" and "websocket". By default, this value
// is "tcp".
Protocol string `ini:"protocol" json:"protocol"`
// QUIC protocol options
QUICKeepalivePeriod int `ini:"quic_keepalive_period" json:"quic_keepalive_period" validate:"gte=0"`
QUICMaxIdleTimeout int `ini:"quic_max_idle_timeout" json:"quic_max_idle_timeout" validate:"gte=0"`
QUICMaxIncomingStreams int `ini:"quic_max_incoming_streams" json:"quic_max_incoming_streams" validate:"gte=0"`
// TLSEnable specifies whether or not TLS should be used when communicating
// with the server. If "tls_cert_file" and "tls_key_file" are valid,
// client will load the supplied tls configuration.
Expand Down Expand Up @@ -172,30 +176,21 @@ func GetDefaultClientConf() ClientCommonConf {
LogWay: "console",
LogLevel: "info",
LogMaxDays: 3,
DisableLogColor: false,
AdminAddr: "127.0.0.1",
AdminPort: 0,
AdminUser: "",
AdminPwd: "",
AssetsDir: "",
PoolCount: 1,
TCPMux: true,
TCPMuxKeepaliveInterval: 60,
User: "",
DNSServer: "",
LoginFailExit: true,
Start: make([]string, 0),
Protocol: "tcp",
TLSEnable: false,
TLSCertFile: "",
TLSKeyFile: "",
TLSTrustedCaFile: "",
QUICKeepalivePeriod: 10,
QUICMaxIdleTimeout: 30,
QUICMaxIncomingStreams: 100000,
HeartbeatInterval: 30,
HeartbeatTimeout: 90,
Metas: make(map[string]string),
UDPPacketSize: 1500,
IncludeConfigFiles: make([]string, 0),
PprofEnable: false,
}
}

Expand Down
3 changes: 3 additions & 0 deletions pkg/config/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,9 @@ func Test_LoadClientCommonConf(t *testing.T) {
User: "your_name",
LoginFailExit: true,
Protocol: "tcp",
QUICKeepalivePeriod: 10,
QUICMaxIdleTimeout: 30,
QUICMaxIncomingStreams: 100000,
TLSEnable: true,
TLSCertFile: "client.crt",
TLSKeyFile: "client.key",
Expand Down
27 changes: 7 additions & 20 deletions pkg/config/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ type ServerCommonConf struct {
// Set this value to 0 will disable this feature.
// By default, the value is 0.
QUICBindPort int `ini:"quic_bind_port" json:"quic_bind_port" validate:"gte=0,lte=65535"`
// QUIC protocol options
QUICKeepalivePeriod int `ini:"quic_keepalive_period" json:"quic_keepalive_period" validate:"gte=0"`
QUICMaxIdleTimeout int `ini:"quic_max_idle_timeout" json:"quic_max_idle_timeout" validate:"gte=0"`
QUICMaxIncomingStreams int `ini:"quic_max_incoming_streams" json:"quic_max_incoming_streams" validate:"gte=0"`
// ProxyBindAddr specifies the address that the proxy binds to. This value
// may be the same as BindAddr.
ProxyBindAddr string `ini:"proxy_bind_addr" json:"proxy_bind_addr"`
Expand Down Expand Up @@ -199,43 +203,26 @@ func GetDefaultServerConf() ServerCommonConf {
ServerConfig: auth.GetDefaultServerConf(),
BindAddr: "0.0.0.0",
BindPort: 7000,
BindUDPPort: 0,
KCPBindPort: 0,
ProxyBindAddr: "",
VhostHTTPPort: 0,
VhostHTTPSPort: 0,
TCPMuxHTTPConnectPort: 0,
TCPMuxPassthrough: false,
QUICKeepalivePeriod: 10,
QUICMaxIdleTimeout: 30,
QUICMaxIncomingStreams: 100000,
VhostHTTPTimeout: 60,
DashboardAddr: "0.0.0.0",
DashboardPort: 0,
DashboardUser: "",
DashboardPwd: "",
EnablePrometheus: false,
AssetsDir: "",
LogFile: "console",
LogWay: "console",
LogLevel: "info",
LogMaxDays: 3,
DisableLogColor: false,
DetailedErrorsToClient: true,
SubDomainHost: "",
TCPMux: true,
TCPMuxKeepaliveInterval: 60,
TCPKeepAlive: 7200,
AllowPorts: make(map[int]struct{}),
MaxPoolCount: 5,
MaxPortsPerClient: 0,
TLSOnly: false,
TLSCertFile: "",
TLSKeyFile: "",
TLSTrustedCaFile: "",
HeartbeatTimeout: 90,
UserConnTimeout: 10,
Custom404Page: "",
HTTPPlugins: make(map[string]plugin.HTTPPluginOptions),
UDPPacketSize: 1500,
PprofEnable: false,
}
}

Expand Down
6 changes: 6 additions & 0 deletions pkg/config/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ func Test_LoadServerCommonConf(t *testing.T) {
BindPort: 7009,
BindUDPPort: 7008,
KCPBindPort: 7007,
QUICKeepalivePeriod: 10,
QUICMaxIdleTimeout: 30,
QUICMaxIncomingStreams: 100000,
ProxyBindAddr: "127.0.0.9",
VhostHTTPPort: 89,
VhostHTTPSPort: 449,
Expand Down Expand Up @@ -179,6 +182,9 @@ func Test_LoadServerCommonConf(t *testing.T) {
BindAddr: "0.0.0.9",
BindPort: 7009,
BindUDPPort: 7008,
QUICKeepalivePeriod: 10,
QUICMaxIdleTimeout: 30,
QUICMaxIncomingStreams: 100000,
ProxyBindAddr: "0.0.0.9",
VhostHTTPTimeout: 60,
DashboardAddr: "0.0.0.0",
Expand Down
2 changes: 1 addition & 1 deletion pkg/util/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
"strings"
)

var version = "0.45.0"
var version = "0.46.0"

func Full() string {
return version
Expand Down
6 changes: 5 additions & 1 deletion server/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,11 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) {
address := net.JoinHostPort(cfg.BindAddr, strconv.Itoa(cfg.QUICBindPort))
quicTLSCfg := tlsConfig.Clone()
quicTLSCfg.NextProtos = []string{"frp"}
svr.quicListener, err = quic.ListenAddr(address, quicTLSCfg, nil)
svr.quicListener, err = quic.ListenAddr(address, quicTLSCfg, &quic.Config{
MaxIdleTimeout: time.Duration(cfg.QUICMaxIdleTimeout) * time.Second,
MaxIncomingStreams: int64(cfg.QUICMaxIncomingStreams),
KeepAlivePeriod: time.Duration(cfg.QUICKeepalivePeriod) * time.Second,
})
if err != nil {
err = fmt.Errorf("listen on quic udp address %s error: %v", address, err)
return
Expand Down

0 comments on commit 7678938

Please sign in to comment.