Bladeren bron

code optimization (#3625)

fatedier 1 jaar geleden
bovenliggende
commit
5e70d5bee0

+ 6 - 9
client/proxy/proxy.go

@@ -15,7 +15,6 @@
 package proxy
 
 import (
-	"bytes"
 	"context"
 	"io"
 	"net"
@@ -149,7 +148,7 @@ func (pxy *BaseProxy) HandleTCPWorkConnection(workConn net.Conn, m *msg.StartWor
 	}
 
 	// check if we need to send proxy protocol info
-	var extraInfo []byte
+	var extraInfo plugin.ExtraInfo
 	if baseCfg.Transport.ProxyProtocolVersion != "" {
 		if m.SrcAddr != "" && m.SrcPort != 0 {
 			if m.DstAddr == "" {
@@ -175,16 +174,14 @@ func (pxy *BaseProxy) HandleTCPWorkConnection(workConn net.Conn, m *msg.StartWor
 				h.Version = 2
 			}
 
-			buf := bytes.NewBuffer(nil)
-			_, _ = h.WriteTo(buf)
-			extraInfo = buf.Bytes()
+			extraInfo.ProxyProtocolHeader = h
 		}
 	}
 
 	if pxy.proxyPlugin != nil {
 		// if plugin is set, let plugin handle connection first
 		xl.Debug("handle by plugin: %s", pxy.proxyPlugin.Name())
-		pxy.proxyPlugin.Handle(remote, workConn, extraInfo)
+		pxy.proxyPlugin.Handle(remote, workConn, &extraInfo)
 		xl.Debug("handle by plugin finished")
 		return
 	}
@@ -202,10 +199,10 @@ func (pxy *BaseProxy) HandleTCPWorkConnection(workConn net.Conn, m *msg.StartWor
 	xl.Debug("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 len(extraInfo) > 0 {
-		if _, err := localConn.Write(extraInfo); err != nil {
+	if extraInfo.ProxyProtocolHeader != nil {
+		if _, err := extraInfo.ProxyProtocolHeader.WriteTo(localConn); err != nil {
 			workConn.Close()
-			xl.Error("write extraInfo to local conn error: %v", err)
+			xl.Error("write proxy protocol header to local conn error: %v", err)
 			return
 		}
 	}

+ 2 - 2
cmd/frpc/sub/admin.go

@@ -90,12 +90,12 @@ func StatusHandler(clientCfg *v1.ClientCommonConfig) error {
 
 	fmt.Printf("Proxy Status...\n\n")
 	for _, typ := range proxyTypes {
-		arrs := res[typ]
+		arrs := res[string(typ)]
 		if len(arrs) == 0 {
 			continue
 		}
 
-		fmt.Println(strings.ToUpper(typ))
+		fmt.Println(strings.ToUpper(string(typ)))
 		tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error")
 		for _, ps := range arrs {
 			tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err)

+ 17 - 18
cmd/frpc/sub/proxy.go

@@ -23,24 +23,23 @@ import (
 
 	v1 "github.com/fatedier/frp/pkg/config/v1"
 	"github.com/fatedier/frp/pkg/config/v1/validation"
-	"github.com/fatedier/frp/pkg/consts"
 )
 
-var proxyTypes = []string{
-	consts.TCPProxy,
-	consts.UDPProxy,
-	consts.TCPMuxProxy,
-	consts.HTTPProxy,
-	consts.HTTPSProxy,
-	consts.STCPProxy,
-	consts.SUDPProxy,
-	consts.XTCPProxy,
+var proxyTypes = []v1.ProxyType{
+	v1.ProxyTypeTCP,
+	v1.ProxyTypeUDP,
+	v1.ProxyTypeTCPMUX,
+	v1.ProxyTypeHTTP,
+	v1.ProxyTypeHTTPS,
+	v1.ProxyTypeSTCP,
+	v1.ProxyTypeSUDP,
+	v1.ProxyTypeXTCP,
 }
 
-var visitorTypes = []string{
-	consts.STCPProxy,
-	consts.SUDPProxy,
-	consts.XTCPProxy,
+var visitorTypes = []v1.VisitorType{
+	v1.VisitorTypeSTCP,
+	v1.VisitorTypeSUDP,
+	v1.VisitorTypeXTCP,
 }
 
 func init() {
@@ -50,17 +49,17 @@ func init() {
 			panic("proxy type: " + typ + " not support")
 		}
 		clientCfg := v1.ClientCommonConfig{}
-		cmd := NewProxyCommand(typ, c, &clientCfg)
+		cmd := NewProxyCommand(string(typ), c, &clientCfg)
 		RegisterClientCommonConfigFlags(cmd, &clientCfg)
 		RegisterProxyFlags(cmd, c)
 
 		// add sub command for visitor
-		if lo.Contains(visitorTypes, typ) {
-			vc := v1.NewVisitorConfigurerByType(typ)
+		if lo.Contains(visitorTypes, v1.VisitorType(typ)) {
+			vc := v1.NewVisitorConfigurerByType(v1.VisitorType(typ))
 			if vc == nil {
 				panic("visitor type: " + typ + " not support")
 			}
-			visitorCmd := NewVisitorCommand(typ, vc, &clientCfg)
+			visitorCmd := NewVisitorCommand(string(typ), vc, &clientCfg)
 			RegisterVisitorFlags(visitorCmd, vc)
 			cmd.AddCommand(visitorCmd)
 		}

+ 4 - 5
pkg/auth/auth.go

@@ -18,7 +18,6 @@ import (
 	"fmt"
 
 	v1 "github.com/fatedier/frp/pkg/config/v1"
-	"github.com/fatedier/frp/pkg/consts"
 	"github.com/fatedier/frp/pkg/msg"
 )
 
@@ -30,9 +29,9 @@ type Setter interface {
 
 func NewAuthSetter(cfg v1.AuthClientConfig) (authProvider Setter) {
 	switch cfg.Method {
-	case consts.TokenAuthMethod:
+	case v1.AuthMethodToken:
 		authProvider = NewTokenAuth(cfg.AdditionalScopes, cfg.Token)
-	case consts.OidcAuthMethod:
+	case v1.AuthMethodOIDC:
 		authProvider = NewOidcAuthSetter(cfg.AdditionalScopes, cfg.OIDC)
 	default:
 		panic(fmt.Sprintf("wrong method: '%s'", cfg.Method))
@@ -48,9 +47,9 @@ type Verifier interface {
 
 func NewAuthVerifier(cfg v1.AuthServerConfig) (authVerifier Verifier) {
 	switch cfg.Method {
-	case consts.TokenAuthMethod:
+	case v1.AuthMethodToken:
 		authVerifier = NewTokenAuth(cfg.AdditionalScopes, cfg.Token)
-	case consts.OidcAuthMethod:
+	case v1.AuthMethodOIDC:
 		authVerifier = NewOidcAuthVerifier(cfg.AdditionalScopes, cfg.OIDC)
 	}
 	return authVerifier

+ 2 - 2
pkg/config/legacy/conversion.go

@@ -26,7 +26,7 @@ import (
 func Convert_ClientCommonConf_To_v1(conf *ClientCommonConf) *v1.ClientCommonConfig {
 	out := &v1.ClientCommonConfig{}
 	out.User = conf.User
-	out.Auth.Method = conf.ClientConfig.AuthenticationMethod
+	out.Auth.Method = v1.AuthMethod(conf.ClientConfig.AuthenticationMethod)
 	out.Auth.Token = conf.ClientConfig.Token
 	if conf.ClientConfig.AuthenticateHeartBeats {
 		out.Auth.AdditionalScopes = append(out.Auth.AdditionalScopes, v1.AuthScopeHeartBeats)
@@ -86,7 +86,7 @@ func Convert_ClientCommonConf_To_v1(conf *ClientCommonConf) *v1.ClientCommonConf
 
 func Convert_ServerCommonConf_To_v1(conf *ServerCommonConf) *v1.ServerConfig {
 	out := &v1.ServerConfig{}
-	out.Auth.Method = conf.ServerConfig.AuthenticationMethod
+	out.Auth.Method = v1.AuthMethod(conf.ServerConfig.AuthenticationMethod)
 	out.Auth.Token = conf.ServerConfig.Token
 	if conf.ServerConfig.AuthenticateHeartBeats {
 		out.Auth.AdditionalScopes = append(out.Auth.AdditionalScopes, v1.AuthScopeHeartBeats)

+ 26 - 14
pkg/config/legacy/proxy.go

@@ -21,20 +21,32 @@ import (
 	"gopkg.in/ini.v1"
 
 	"github.com/fatedier/frp/pkg/config/types"
-	"github.com/fatedier/frp/pkg/consts"
+)
+
+type ProxyType string
+
+const (
+	ProxyTypeTCP    ProxyType = "tcp"
+	ProxyTypeUDP    ProxyType = "udp"
+	ProxyTypeTCPMUX ProxyType = "tcpmux"
+	ProxyTypeHTTP   ProxyType = "http"
+	ProxyTypeHTTPS  ProxyType = "https"
+	ProxyTypeSTCP   ProxyType = "stcp"
+	ProxyTypeXTCP   ProxyType = "xtcp"
+	ProxyTypeSUDP   ProxyType = "sudp"
 )
 
 // Proxy
 var (
-	proxyConfTypeMap = map[string]reflect.Type{
-		consts.TCPProxy:    reflect.TypeOf(TCPProxyConf{}),
-		consts.TCPMuxProxy: reflect.TypeOf(TCPMuxProxyConf{}),
-		consts.UDPProxy:    reflect.TypeOf(UDPProxyConf{}),
-		consts.HTTPProxy:   reflect.TypeOf(HTTPProxyConf{}),
-		consts.HTTPSProxy:  reflect.TypeOf(HTTPSProxyConf{}),
-		consts.STCPProxy:   reflect.TypeOf(STCPProxyConf{}),
-		consts.XTCPProxy:   reflect.TypeOf(XTCPProxyConf{}),
-		consts.SUDPProxy:   reflect.TypeOf(SUDPProxyConf{}),
+	proxyConfTypeMap = map[ProxyType]reflect.Type{
+		ProxyTypeTCP:    reflect.TypeOf(TCPProxyConf{}),
+		ProxyTypeUDP:    reflect.TypeOf(UDPProxyConf{}),
+		ProxyTypeTCPMUX: reflect.TypeOf(TCPMuxProxyConf{}),
+		ProxyTypeHTTP:   reflect.TypeOf(HTTPProxyConf{}),
+		ProxyTypeHTTPS:  reflect.TypeOf(HTTPSProxyConf{}),
+		ProxyTypeSTCP:   reflect.TypeOf(STCPProxyConf{}),
+		ProxyTypeXTCP:   reflect.TypeOf(XTCPProxyConf{}),
+		ProxyTypeSUDP:   reflect.TypeOf(SUDPProxyConf{}),
 	}
 )
 
@@ -46,7 +58,7 @@ type ProxyConf interface {
 	UnmarshalFromIni(string, string, *ini.Section) error
 }
 
-func NewConfByType(proxyType string) ProxyConf {
+func NewConfByType(proxyType ProxyType) ProxyConf {
 	v, ok := proxyConfTypeMap[proxyType]
 	if !ok {
 		return nil
@@ -58,16 +70,16 @@ func NewConfByType(proxyType string) ProxyConf {
 // Proxy Conf Loader
 // DefaultProxyConf creates a empty ProxyConf object by proxyType.
 // If proxyType doesn't exist, return nil.
-func DefaultProxyConf(proxyType string) ProxyConf {
+func DefaultProxyConf(proxyType ProxyType) ProxyConf {
 	return NewConfByType(proxyType)
 }
 
 // Proxy loaded from ini
 func NewProxyConfFromIni(prefix, name string, section *ini.Section) (ProxyConf, error) {
 	// section.Key: if key not exists, section will set it with default value.
-	proxyType := section.Key("type").String()
+	proxyType := ProxyType(section.Key("type").String())
 	if proxyType == "" {
-		proxyType = consts.TCPProxy
+		proxyType = ProxyTypeTCP
 	}
 
 	conf := DefaultProxyConf(proxyType)

+ 13 - 7
pkg/config/legacy/visitor.go

@@ -19,16 +19,22 @@ import (
 	"reflect"
 
 	"gopkg.in/ini.v1"
+)
+
+type VisitorType string
 
-	"github.com/fatedier/frp/pkg/consts"
+const (
+	VisitorTypeSTCP VisitorType = "stcp"
+	VisitorTypeXTCP VisitorType = "xtcp"
+	VisitorTypeSUDP VisitorType = "sudp"
 )
 
 // Visitor
 var (
-	visitorConfTypeMap = map[string]reflect.Type{
-		consts.STCPProxy: reflect.TypeOf(STCPVisitorConf{}),
-		consts.XTCPProxy: reflect.TypeOf(XTCPVisitorConf{}),
-		consts.SUDPProxy: reflect.TypeOf(SUDPVisitorConf{}),
+	visitorConfTypeMap = map[VisitorType]reflect.Type{
+		VisitorTypeSTCP: reflect.TypeOf(STCPVisitorConf{}),
+		VisitorTypeXTCP: reflect.TypeOf(XTCPVisitorConf{}),
+		VisitorTypeSUDP: reflect.TypeOf(SUDPVisitorConf{}),
 	}
 )
 
@@ -41,7 +47,7 @@ type VisitorConf interface {
 
 // DefaultVisitorConf creates a empty VisitorConf object by visitorType.
 // If visitorType doesn't exist, return nil.
-func DefaultVisitorConf(visitorType string) VisitorConf {
+func DefaultVisitorConf(visitorType VisitorType) VisitorConf {
 	v, ok := visitorConfTypeMap[visitorType]
 	if !ok {
 		return nil
@@ -161,7 +167,7 @@ func (cfg *XTCPVisitorConf) UnmarshalFromIni(prefix string, name string, section
 // Visitor loaded from ini
 func NewVisitorConfFromIni(prefix string, name string, section *ini.Section) (VisitorConf, error) {
 	// section.Key: if key not exists, section will set it with default value.
-	visitorType := section.Key("type").String()
+	visitorType := VisitorType(section.Key("type").String())
 
 	if visitorType == "" {
 		return nil, fmt.Errorf("type shouldn't be empty")

+ 2 - 3
pkg/config/load.go

@@ -32,7 +32,6 @@ import (
 	"github.com/fatedier/frp/pkg/config/legacy"
 	v1 "github.com/fatedier/frp/pkg/config/v1"
 	"github.com/fatedier/frp/pkg/config/v1/validation"
-	"github.com/fatedier/frp/pkg/consts"
 	"github.com/fatedier/frp/pkg/msg"
 	"github.com/fatedier/frp/pkg/util/util"
 )
@@ -124,9 +123,9 @@ func LoadConfigure(b []byte, c any) error {
 }
 
 func NewProxyConfigurerFromMsg(m *msg.NewProxy, serverCfg *v1.ServerConfig) (v1.ProxyConfigurer, error) {
-	m.ProxyType = util.EmptyOr(m.ProxyType, consts.TCPProxy)
+	m.ProxyType = util.EmptyOr(m.ProxyType, string(v1.ProxyTypeTCP))
 
-	configurer := v1.NewProxyConfigurerByType(m.ProxyType)
+	configurer := v1.NewProxyConfigurerByType(v1.ProxyType(m.ProxyType))
 	if configurer == nil {
 		return nil, fmt.Errorf("unknown proxy type: %s", m.ProxyType)
 	}

+ 1 - 1
pkg/config/v1/client.go

@@ -165,7 +165,7 @@ type AuthClientConfig struct {
 	// authenticate frpc with frps. If "token" is specified - token will be
 	// read into login message. If "oidc" is specified - OIDC (Open ID Connect)
 	// token will be issued using OIDC settings. By default, this value is "token".
-	Method string `json:"method,omitempty"`
+	Method AuthMethod `json:"method,omitempty"`
 	// Specify whether to include auth info in additional scope.
 	// Current supported scopes are: "HeartBeats", "NewWorkConns".
 	AdditionalScopes []AuthScope `json:"additionalScopes,omitempty"`

+ 1 - 1
pkg/config/v1/client_test.go

@@ -26,7 +26,7 @@ func TestClientConfigComplete(t *testing.T) {
 	c := &ClientConfig{}
 	c.Complete()
 
-	require.Equal("token", c.Auth.Method)
+	require.EqualValues("token", c.Auth.Method)
 	require.Equal(true, lo.FromPtr(c.Transport.TCPMux))
 	require.Equal(true, lo.FromPtr(c.LoginFailExit))
 	require.Equal(true, lo.FromPtr(c.Transport.TLS.Enable))

+ 7 - 0
pkg/config/v1/common.go

@@ -25,6 +25,13 @@ const (
 	AuthScopeNewWorkConns AuthScope = "NewWorkConns"
 )
 
+type AuthMethod string
+
+const (
+	AuthMethodToken AuthMethod = "token"
+	AuthMethodOIDC  AuthMethod = "oidc"
+)
+
 // QUIC protocol options
 type QUICOptions struct {
 	KeepalivePeriod    int `json:"quicKeepalivePeriod,omitempty" validate:"gte=0"`

+ 30 - 12
pkg/config/v1/proxy.go

@@ -23,7 +23,6 @@ import (
 	"github.com/samber/lo"
 
 	"github.com/fatedier/frp/pkg/config/types"
-	"github.com/fatedier/frp/pkg/consts"
 	"github.com/fatedier/frp/pkg/msg"
 	"github.com/fatedier/frp/pkg/util/util"
 )
@@ -174,7 +173,7 @@ func (c *TypedProxyConfig) UnmarshalJSON(b []byte) error {
 	}
 
 	c.Type = typeStruct.Type
-	configurer := NewProxyConfigurerByType(typeStruct.Type)
+	configurer := NewProxyConfigurerByType(ProxyType(typeStruct.Type))
 	if configurer == nil {
 		return fmt.Errorf("unknown proxy type: %s", typeStruct.Type)
 	}
@@ -196,18 +195,31 @@ type ProxyConfigurer interface {
 	UnmarshalFromMsg(*msg.NewProxy)
 }
 
-var proxyConfigTypeMap = map[string]reflect.Type{
-	consts.TCPProxy:    reflect.TypeOf(TCPProxyConfig{}),
-	consts.UDPProxy:    reflect.TypeOf(UDPProxyConfig{}),
-	consts.HTTPProxy:   reflect.TypeOf(HTTPProxyConfig{}),
-	consts.HTTPSProxy:  reflect.TypeOf(HTTPSProxyConfig{}),
-	consts.TCPMuxProxy: reflect.TypeOf(TCPMuxProxyConfig{}),
-	consts.STCPProxy:   reflect.TypeOf(STCPProxyConfig{}),
-	consts.XTCPProxy:   reflect.TypeOf(XTCPProxyConfig{}),
-	consts.SUDPProxy:   reflect.TypeOf(SUDPProxyConfig{}),
+type ProxyType string
+
+const (
+	ProxyTypeTCP    ProxyType = "tcp"
+	ProxyTypeUDP    ProxyType = "udp"
+	ProxyTypeTCPMUX ProxyType = "tcpmux"
+	ProxyTypeHTTP   ProxyType = "http"
+	ProxyTypeHTTPS  ProxyType = "https"
+	ProxyTypeSTCP   ProxyType = "stcp"
+	ProxyTypeXTCP   ProxyType = "xtcp"
+	ProxyTypeSUDP   ProxyType = "sudp"
+)
+
+var proxyConfigTypeMap = map[ProxyType]reflect.Type{
+	ProxyTypeTCP:    reflect.TypeOf(TCPProxyConfig{}),
+	ProxyTypeUDP:    reflect.TypeOf(UDPProxyConfig{}),
+	ProxyTypeHTTP:   reflect.TypeOf(HTTPProxyConfig{}),
+	ProxyTypeHTTPS:  reflect.TypeOf(HTTPSProxyConfig{}),
+	ProxyTypeTCPMUX: reflect.TypeOf(TCPMuxProxyConfig{}),
+	ProxyTypeSTCP:   reflect.TypeOf(STCPProxyConfig{}),
+	ProxyTypeXTCP:   reflect.TypeOf(XTCPProxyConfig{}),
+	ProxyTypeSUDP:   reflect.TypeOf(SUDPProxyConfig{}),
 }
 
-func NewProxyConfigurerByType(proxyType string) ProxyConfigurer {
+func NewProxyConfigurerByType(proxyType ProxyType) ProxyConfigurer {
 	v, ok := proxyConfigTypeMap[proxyType]
 	if !ok {
 		return nil
@@ -316,6 +328,12 @@ func (c *HTTPSProxyConfig) UnmarshalFromMsg(m *msg.NewProxy) {
 	c.SubDomain = m.SubDomain
 }
 
+type TCPMultiplexerType string
+
+const (
+	TCPMultiplexerHTTPConnect TCPMultiplexerType = "httpconnect"
+)
+
 var _ ProxyConfigurer = &TCPMuxProxyConfig{}
 
 type TCPMuxProxyConfig struct {

+ 1 - 1
pkg/config/v1/server.go

@@ -120,7 +120,7 @@ func (c *ServerConfig) Complete() {
 }
 
 type AuthServerConfig struct {
-	Method           string               `json:"method,omitempty"`
+	Method           AuthMethod           `json:"method,omitempty"`
 	AdditionalScopes []AuthScope          `json:"additionalScopes,omitempty"`
 	Token            string               `json:"token,omitempty"`
 	OIDC             AuthOIDCServerConfig `json:"oidc,omitempty"`

+ 1 - 1
pkg/config/v1/server_test.go

@@ -26,7 +26,7 @@ func TestServerConfigComplete(t *testing.T) {
 	c := &ServerConfig{}
 	c.Complete()
 
-	require.Equal("token", c.Auth.Method)
+	require.EqualValues("token", c.Auth.Method)
 	require.Equal(true, lo.FromPtr(c.Transport.TCPMux))
 	require.Equal(true, lo.FromPtr(c.DetailedErrorsToClient))
 }

+ 2 - 3
pkg/config/v1/validation/proxy.go

@@ -22,7 +22,6 @@ import (
 	"github.com/samber/lo"
 
 	v1 "github.com/fatedier/frp/pkg/config/v1"
-	"github.com/fatedier/frp/pkg/consts"
 )
 
 func validateProxyBaseConfigForClient(c *v1.ProxyBaseConfig) error {
@@ -134,7 +133,7 @@ func validateTCPMuxProxyConfigForClient(c *v1.TCPMuxProxyConfig) error {
 		return err
 	}
 
-	if !lo.Contains([]string{consts.HTTPConnectTCPMultiplexer}, c.Multiplexer) {
+	if !lo.Contains([]string{string(v1.TCPMultiplexerHTTPConnect)}, c.Multiplexer) {
 		return fmt.Errorf("not support multiplexer: %s", c.Multiplexer)
 	}
 	return nil
@@ -197,7 +196,7 @@ func validateUDPProxyConfigForServer(c *v1.UDPProxyConfig, s *v1.ServerConfig) e
 }
 
 func validateTCPMuxProxyConfigForServer(c *v1.TCPMuxProxyConfig, s *v1.ServerConfig) error {
-	if c.Multiplexer == consts.HTTPConnectTCPMultiplexer &&
+	if c.Multiplexer == string(v1.TCPMultiplexerHTTPConnect) &&
 		s.TCPMuxHTTPConnectPort == 0 {
 		return fmt.Errorf("tcpmux with multiplexer httpconnect not supported because this feature is not enabled in server")
 	}

+ 1 - 1
pkg/config/v1/validation/validation.go

@@ -30,7 +30,7 @@ var (
 		"wss",
 	}
 
-	SupportedAuthMethods = []string{
+	SupportedAuthMethods = []v1.AuthMethod{
 		"token",
 		"oidc",
 	}

+ 14 - 7
pkg/config/v1/visitor.go

@@ -22,7 +22,6 @@ import (
 
 	"github.com/samber/lo"
 
-	"github.com/fatedier/frp/pkg/consts"
 	"github.com/fatedier/frp/pkg/util/util"
 )
 
@@ -73,10 +72,18 @@ type VisitorConfigurer interface {
 	GetBaseConfig() *VisitorBaseConfig
 }
 
-var visitorConfigTypeMap = map[string]reflect.Type{
-	consts.STCPProxy: reflect.TypeOf(STCPVisitorConfig{}),
-	consts.XTCPProxy: reflect.TypeOf(XTCPVisitorConfig{}),
-	consts.SUDPProxy: reflect.TypeOf(SUDPVisitorConfig{}),
+type VisitorType string
+
+const (
+	VisitorTypeSTCP VisitorType = "stcp"
+	VisitorTypeXTCP VisitorType = "xtcp"
+	VisitorTypeSUDP VisitorType = "sudp"
+)
+
+var visitorConfigTypeMap = map[VisitorType]reflect.Type{
+	VisitorTypeSTCP: reflect.TypeOf(STCPVisitorConfig{}),
+	VisitorTypeXTCP: reflect.TypeOf(XTCPVisitorConfig{}),
+	VisitorTypeSUDP: reflect.TypeOf(SUDPVisitorConfig{}),
 }
 
 type TypedVisitorConfig struct {
@@ -97,7 +104,7 @@ func (c *TypedVisitorConfig) UnmarshalJSON(b []byte) error {
 	}
 
 	c.Type = typeStruct.Type
-	configurer := NewVisitorConfigurerByType(typeStruct.Type)
+	configurer := NewVisitorConfigurerByType(VisitorType(typeStruct.Type))
 	if configurer == nil {
 		return fmt.Errorf("unknown visitor type: %s", typeStruct.Type)
 	}
@@ -108,7 +115,7 @@ func (c *TypedVisitorConfig) UnmarshalJSON(b []byte) error {
 	return nil
 }
 
-func NewVisitorConfigurerByType(t string) VisitorConfigurer {
+func NewVisitorConfigurerByType(t VisitorType) VisitorConfigurer {
 	v, ok := visitorConfigTypeMap[t]
 	if !ok {
 		return nil

+ 0 - 41
pkg/consts/consts.go

@@ -1,41 +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 consts
-
-var (
-	// proxy status
-	Idle    = "idle"
-	Working = "working"
-	Closed  = "closed"
-	Online  = "online"
-	Offline = "offline"
-
-	// proxy type
-	TCPProxy    = "tcp"
-	UDPProxy    = "udp"
-	TCPMuxProxy = "tcpmux"
-	HTTPProxy   = "http"
-	HTTPSProxy  = "https"
-	STCPProxy   = "stcp"
-	XTCPProxy   = "xtcp"
-	SUDPProxy   = "sudp"
-
-	// authentication method
-	TokenAuthMethod = "token"
-	OidcAuthMethod  = "oidc"
-
-	// TCP multiplexer
-	HTTPConnectTCPMultiplexer = "httpconnect"
-)

+ 1 - 1
pkg/plugin/client/http2https.go

@@ -76,7 +76,7 @@ func NewHTTP2HTTPSPlugin(options v1.ClientPluginOptions) (Plugin, error) {
 	return p, nil
 }
 
-func (p *HTTP2HTTPSPlugin) Handle(conn io.ReadWriteCloser, realConn net.Conn, _ []byte) {
+func (p *HTTP2HTTPSPlugin) Handle(conn io.ReadWriteCloser, realConn net.Conn, _ *ExtraInfo) {
 	wrapConn := utilnet.WrapReadWriteCloserToConn(conn, realConn)
 	_ = p.l.PutConn(wrapConn)
 }

+ 1 - 1
pkg/plugin/client/http_proxy.go

@@ -65,7 +65,7 @@ func (hp *HTTPProxy) Name() string {
 	return v1.PluginHTTPProxy
 }
 
-func (hp *HTTPProxy) Handle(conn io.ReadWriteCloser, realConn net.Conn, _ []byte) {
+func (hp *HTTPProxy) Handle(conn io.ReadWriteCloser, realConn net.Conn, _ *ExtraInfo) {
 	wrapConn := utilnet.WrapReadWriteCloserToConn(conn, realConn)
 
 	sc, rd := libnet.NewSharedConn(wrapConn)

+ 1 - 1
pkg/plugin/client/https2http.go

@@ -95,7 +95,7 @@ func (p *HTTPS2HTTPPlugin) genTLSConfig() (*tls.Config, error) {
 	return config, nil
 }
 
-func (p *HTTPS2HTTPPlugin) Handle(conn io.ReadWriteCloser, realConn net.Conn, _ []byte) {
+func (p *HTTPS2HTTPPlugin) Handle(conn io.ReadWriteCloser, realConn net.Conn, _ *ExtraInfo) {
 	wrapConn := utilnet.WrapReadWriteCloserToConn(conn, realConn)
 	_ = p.l.PutConn(wrapConn)
 }

+ 1 - 1
pkg/plugin/client/https2https.go

@@ -101,7 +101,7 @@ func (p *HTTPS2HTTPSPlugin) genTLSConfig() (*tls.Config, error) {
 	return config, nil
 }
 
-func (p *HTTPS2HTTPSPlugin) Handle(conn io.ReadWriteCloser, realConn net.Conn, _ []byte) {
+func (p *HTTPS2HTTPSPlugin) Handle(conn io.ReadWriteCloser, realConn net.Conn, _ *ExtraInfo) {
 	wrapConn := utilnet.WrapReadWriteCloserToConn(conn, realConn)
 	_ = p.l.PutConn(wrapConn)
 }

+ 6 - 2
pkg/plugin/client/plugin.go

@@ -21,6 +21,7 @@ import (
 	"sync"
 
 	"github.com/fatedier/golib/errors"
+	pp "github.com/pires/go-proxyproto"
 
 	v1 "github.com/fatedier/frp/pkg/config/v1"
 )
@@ -47,11 +48,14 @@ func Create(name string, options v1.ClientPluginOptions) (p Plugin, err error) {
 	return
 }
 
+type ExtraInfo struct {
+	ProxyProtocolHeader *pp.Header
+}
+
 type Plugin interface {
 	Name() string
 
-	// extraBufToLocal will send to local connection first, then join conn with local connection
-	Handle(conn io.ReadWriteCloser, realConn net.Conn, extraBufToLocal []byte)
+	Handle(conn io.ReadWriteCloser, realConn net.Conn, extra *ExtraInfo)
 	Close() error
 }
 

+ 1 - 1
pkg/plugin/client/socks5.go

@@ -48,7 +48,7 @@ func NewSocks5Plugin(options v1.ClientPluginOptions) (p Plugin, err error) {
 	return
 }
 
-func (sp *Socks5Plugin) Handle(conn io.ReadWriteCloser, realConn net.Conn, _ []byte) {
+func (sp *Socks5Plugin) Handle(conn io.ReadWriteCloser, realConn net.Conn, _ *ExtraInfo) {
 	defer conn.Close()
 	wrapConn := utilnet.WrapReadWriteCloserToConn(conn, realConn)
 	_ = sp.Server.ServeConn(wrapConn)

+ 1 - 1
pkg/plugin/client/static_file.go

@@ -66,7 +66,7 @@ func NewStaticFilePlugin(options v1.ClientPluginOptions) (Plugin, error) {
 	return sp, nil
 }
 
-func (sp *StaticFilePlugin) Handle(conn io.ReadWriteCloser, realConn net.Conn, _ []byte) {
+func (sp *StaticFilePlugin) Handle(conn io.ReadWriteCloser, realConn net.Conn, _ *ExtraInfo) {
 	wrapConn := utilnet.WrapReadWriteCloserToConn(conn, realConn)
 	_ = sp.l.PutConn(wrapConn)
 }

+ 3 - 3
pkg/plugin/client/unix_domain_socket.go

@@ -46,13 +46,13 @@ func NewUnixDomainSocketPlugin(options v1.ClientPluginOptions) (p Plugin, err er
 	return
 }
 
-func (uds *UnixDomainSocketPlugin) Handle(conn io.ReadWriteCloser, _ net.Conn, extraBufToLocal []byte) {
+func (uds *UnixDomainSocketPlugin) Handle(conn io.ReadWriteCloser, _ net.Conn, extra *ExtraInfo) {
 	localConn, err := net.DialUnix("unix", nil, uds.UnixAddr)
 	if err != nil {
 		return
 	}
-	if len(extraBufToLocal) > 0 {
-		if _, err := localConn.Write(extraBufToLocal); err != nil {
+	if extra.ProxyProtocolHeader != nil {
+		if _, err := extra.ProxyProtocolHeader.WriteTo(localConn); err != nil {
 			return
 		}
 	}

+ 0 - 35
pkg/util/version/version.go

@@ -45,38 +45,3 @@ func Major(v string) int64 {
 func Minor(v string) int64 {
 	return getSubVersion(v, 2)
 }
-
-// add every case there if server will not accept client's protocol and return false
-func Compat(client string) (ok bool, msg string) {
-	if LessThan(client, "0.18.0") {
-		return false, "Please upgrade your frpc version to at least 0.18.0"
-	}
-	return true, ""
-}
-
-func LessThan(client string, server string) bool {
-	vc := Proto(client)
-	vs := Proto(server)
-	if vc > vs {
-		return false
-	} else if vc < vs {
-		return true
-	}
-
-	vc = Major(client)
-	vs = Major(server)
-	if vc > vs {
-		return false
-	} else if vc < vs {
-		return true
-	}
-
-	vc = Minor(client)
-	vs = Minor(server)
-	if vc > vs {
-		return false
-	} else if vc < vs {
-		return true
-	}
-	return false
-}

+ 0 - 12
pkg/util/version/version_test.go

@@ -51,15 +51,3 @@ func TestVersion(t *testing.T) {
 	version := Full()
 	assert.Equal(parseVerion, version)
 }
-
-func TestCompact(t *testing.T) {
-	assert := assert.New(t)
-	ok, _ := Compat("0.9.0")
-	assert.False(ok)
-
-	ok, _ = Compat("10.0.0")
-	assert.True(ok)
-
-	ok, _ = Compat("0.10.0")
-	assert.False(ok)
-}

+ 9 - 1
server/control.go

@@ -568,7 +568,15 @@ func (ctl *Control) RegisterProxy(pxyMsg *msg.NewProxy) (remoteAddr string, err
 
 	// NewProxy will return an interface Proxy.
 	// In fact, it creates different proxies based on the proxy type. We just call run() here.
-	pxy, err := proxy.NewProxy(ctl.ctx, userInfo, ctl.rc, ctl.poolCount, ctl.GetWorkConn, pxyConf, ctl.serverCfg, ctl.loginMsg)
+	pxy, err := proxy.NewProxy(ctl.ctx, &proxy.Options{
+		UserInfo:           userInfo,
+		LoginMsg:           ctl.loginMsg,
+		PoolCount:          ctl.poolCount,
+		ResourceController: ctl.rc,
+		GetWorkConnFn:      ctl.GetWorkConn,
+		Configurer:         pxyConf,
+		ServerCfg:          ctl.serverCfg,
+	})
 	if err != nil {
 		return remoteAddr, err
 	}

+ 13 - 14
server/dashboard_api.go

@@ -22,7 +22,6 @@ import (
 
 	"github.com/fatedier/frp/pkg/config/types"
 	v1 "github.com/fatedier/frp/pkg/config/v1"
-	"github.com/fatedier/frp/pkg/consts"
 	"github.com/fatedier/frp/pkg/metrics/mem"
 	"github.com/fatedier/frp/pkg/util/log"
 	"github.com/fatedier/frp/pkg/util/version"
@@ -139,21 +138,21 @@ type XTCPOutConf struct {
 	BaseOutConf
 }
 
-func getConfByType(proxyType string) interface{} {
-	switch proxyType {
-	case consts.TCPProxy:
+func getConfByType(proxyType string) any {
+	switch v1.ProxyType(proxyType) {
+	case v1.ProxyTypeTCP:
 		return &TCPOutConf{}
-	case consts.TCPMuxProxy:
+	case v1.ProxyTypeTCPMUX:
 		return &TCPMuxOutConf{}
-	case consts.UDPProxy:
+	case v1.ProxyTypeUDP:
 		return &UDPOutConf{}
-	case consts.HTTPProxy:
+	case v1.ProxyTypeHTTP:
 		return &HTTPOutConf{}
-	case consts.HTTPSProxy:
+	case v1.ProxyTypeHTTPS:
 		return &HTTPSOutConf{}
-	case consts.STCPProxy:
+	case v1.ProxyTypeSTCP:
 		return &STCPOutConf{}
-	case consts.XTCPProxy:
+	case v1.ProxyTypeXTCP:
 		return &XTCPOutConf{}
 	default:
 		return nil
@@ -215,12 +214,12 @@ func (svr *Service) getProxyStatsByType(proxyType string) (proxyInfos []*ProxySt
 				log.Warn("unmarshal proxy [%s] conf info error: %v", ps.Name, err)
 				continue
 			}
-			proxyInfo.Status = consts.Online
+			proxyInfo.Status = "online"
 			if pxy.GetLoginMsg() != nil {
 				proxyInfo.ClientVersion = pxy.GetLoginMsg().Version
 			}
 		} else {
-			proxyInfo.Status = consts.Offline
+			proxyInfo.Status = "offline"
 		}
 		proxyInfo.Name = ps.Name
 		proxyInfo.TodayTrafficIn = ps.TodayTrafficIn
@@ -293,9 +292,9 @@ func (svr *Service) getProxyStatsByTypeAndName(proxyType string, proxyName strin
 				msg = "parse conf error"
 				return
 			}
-			proxyInfo.Status = consts.Online
+			proxyInfo.Status = "online"
 		} else {
-			proxyInfo.Status = consts.Offline
+			proxyInfo.Status = "offline"
 		}
 		proxyInfo.TodayTrafficIn = ps.TodayTrafficIn
 		proxyInfo.TodayTrafficOut = ps.TodayTrafficOut

+ 3 - 3
server/group/tcpmux.go

@@ -22,7 +22,7 @@ import (
 
 	gerr "github.com/fatedier/golib/errors"
 
-	"github.com/fatedier/frp/pkg/consts"
+	v1 "github.com/fatedier/frp/pkg/config/v1"
 	"github.com/fatedier/frp/pkg/util/tcpmux"
 	"github.com/fatedier/frp/pkg/util/vhost"
 )
@@ -59,8 +59,8 @@ func (tmgc *TCPMuxGroupCtl) Listen(
 	}
 	tmgc.mu.Unlock()
 
-	switch multiplexer {
-	case consts.HTTPConnectTCPMultiplexer:
+	switch v1.TCPMultiplexerType(multiplexer) {
+	case v1.TCPMultiplexerHTTPConnect:
 		return tcpMuxGroup.HTTPConnectListen(ctx, group, groupKey, routeConfig)
 	default:
 		err = fmt.Errorf("unknown multiplexer [%s]", multiplexer)

+ 18 - 9
server/proxy/proxy.go

@@ -271,9 +271,18 @@ func (pxy *BaseProxy) handleUserTCPConnection(userConn net.Conn) {
 	xl.Debug("join connections closed")
 }
 
-func NewProxy(ctx context.Context, userInfo plugin.UserInfo, rc *controller.ResourceController, poolCount int,
-	getWorkConnFn GetWorkConnFn, configurer v1.ProxyConfigurer, serverCfg *v1.ServerConfig, loginMsg *msg.Login,
-) (pxy Proxy, err error) {
+type Options struct {
+	UserInfo           plugin.UserInfo
+	LoginMsg           *msg.Login
+	PoolCount          int
+	ResourceController *controller.ResourceController
+	GetWorkConnFn      GetWorkConnFn
+	Configurer         v1.ProxyConfigurer
+	ServerCfg          *v1.ServerConfig
+}
+
+func NewProxy(ctx context.Context, options *Options) (pxy Proxy, err error) {
+	configurer := options.Configurer
 	xl := xlog.FromContextSafe(ctx).Spawn().AppendPrefix(configurer.GetBaseConfig().Name)
 
 	var limiter *rate.Limiter
@@ -284,16 +293,16 @@ func NewProxy(ctx context.Context, userInfo plugin.UserInfo, rc *controller.Reso
 
 	basePxy := BaseProxy{
 		name:          configurer.GetBaseConfig().Name,
-		rc:            rc,
+		rc:            options.ResourceController,
 		listeners:     make([]net.Listener, 0),
-		poolCount:     poolCount,
-		getWorkConnFn: getWorkConnFn,
-		serverCfg:     serverCfg,
+		poolCount:     options.PoolCount,
+		getWorkConnFn: options.GetWorkConnFn,
+		serverCfg:     options.ServerCfg,
 		limiter:       limiter,
 		xl:            xl,
 		ctx:           xlog.NewContext(ctx, xl),
-		userInfo:      userInfo,
-		loginMsg:      loginMsg,
+		userInfo:      options.UserInfo,
+		loginMsg:      options.LoginMsg,
 		configurer:    configurer,
 	}
 

+ 2 - 3
server/proxy/tcpmux.go

@@ -21,7 +21,6 @@ import (
 	"strings"
 
 	v1 "github.com/fatedier/frp/pkg/config/v1"
-	"github.com/fatedier/frp/pkg/consts"
 	"github.com/fatedier/frp/pkg/util/util"
 	"github.com/fatedier/frp/pkg/util/vhost"
 )
@@ -99,8 +98,8 @@ func (pxy *TCPMuxProxy) httpConnectRun() (remoteAddr string, err error) {
 }
 
 func (pxy *TCPMuxProxy) Run() (remoteAddr string, err error) {
-	switch pxy.cfg.Multiplexer {
-	case consts.HTTPConnectTCPMultiplexer:
+	switch v1.TCPMultiplexerType(pxy.cfg.Multiplexer) {
+	case v1.TCPMultiplexerHTTPConnect:
 		remoteAddr, err = pxy.httpConnectRun()
 	default:
 		err = fmt.Errorf("unknown multiplexer [%s]", pxy.cfg.Multiplexer)

+ 0 - 6
server/service.go

@@ -533,12 +533,6 @@ func (svr *Service) RegisterControl(ctlConn net.Conn, loginMsg *msg.Login) (err
 	xl.Info("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 client version.
-	if ok, msg := version.Compat(loginMsg.Version); !ok {
-		err = fmt.Errorf("%s", msg)
-		return
-	}
-
 	// Check auth.
 	if err = svr.authVerifier.VerifyLogin(loginMsg); err != nil {
 		return