code optimization (#3625)

pull/3641/head
fatedier 1 year ago committed by GitHub
parent 5c8ea51eb5
commit 5e70d5bee0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

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

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

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

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

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

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

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

@ -32,7 +32,6 @@ import (
"github.com/fatedier/frp/pkg/config/legacy" "github.com/fatedier/frp/pkg/config/legacy"
v1 "github.com/fatedier/frp/pkg/config/v1" v1 "github.com/fatedier/frp/pkg/config/v1"
"github.com/fatedier/frp/pkg/config/v1/validation" "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/msg"
"github.com/fatedier/frp/pkg/util/util" "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) { 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 { if configurer == nil {
return nil, fmt.Errorf("unknown proxy type: %s", m.ProxyType) return nil, fmt.Errorf("unknown proxy type: %s", m.ProxyType)
} }

@ -165,7 +165,7 @@ type AuthClientConfig struct {
// authenticate frpc with frps. If "token" is specified - token will be // authenticate frpc with frps. If "token" is specified - token will be
// read into login message. If "oidc" is specified - OIDC (Open ID Connect) // 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". // 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. // Specify whether to include auth info in additional scope.
// Current supported scopes are: "HeartBeats", "NewWorkConns". // Current supported scopes are: "HeartBeats", "NewWorkConns".
AdditionalScopes []AuthScope `json:"additionalScopes,omitempty"` AdditionalScopes []AuthScope `json:"additionalScopes,omitempty"`

@ -26,7 +26,7 @@ func TestClientConfigComplete(t *testing.T) {
c := &ClientConfig{} c := &ClientConfig{}
c.Complete() 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.Transport.TCPMux))
require.Equal(true, lo.FromPtr(c.LoginFailExit)) require.Equal(true, lo.FromPtr(c.LoginFailExit))
require.Equal(true, lo.FromPtr(c.Transport.TLS.Enable)) require.Equal(true, lo.FromPtr(c.Transport.TLS.Enable))

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

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

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

@ -26,7 +26,7 @@ func TestServerConfigComplete(t *testing.T) {
c := &ServerConfig{} c := &ServerConfig{}
c.Complete() 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.Transport.TCPMux))
require.Equal(true, lo.FromPtr(c.DetailedErrorsToClient)) require.Equal(true, lo.FromPtr(c.DetailedErrorsToClient))
} }

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

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

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

@ -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"
)

@ -76,7 +76,7 @@ func NewHTTP2HTTPSPlugin(options v1.ClientPluginOptions) (Plugin, error) {
return p, nil 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) wrapConn := utilnet.WrapReadWriteCloserToConn(conn, realConn)
_ = p.l.PutConn(wrapConn) _ = p.l.PutConn(wrapConn)
} }

@ -65,7 +65,7 @@ func (hp *HTTPProxy) Name() string {
return v1.PluginHTTPProxy 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) wrapConn := utilnet.WrapReadWriteCloserToConn(conn, realConn)
sc, rd := libnet.NewSharedConn(wrapConn) sc, rd := libnet.NewSharedConn(wrapConn)

@ -95,7 +95,7 @@ func (p *HTTPS2HTTPPlugin) genTLSConfig() (*tls.Config, error) {
return config, nil 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) wrapConn := utilnet.WrapReadWriteCloserToConn(conn, realConn)
_ = p.l.PutConn(wrapConn) _ = p.l.PutConn(wrapConn)
} }

@ -101,7 +101,7 @@ func (p *HTTPS2HTTPSPlugin) genTLSConfig() (*tls.Config, error) {
return config, nil 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) wrapConn := utilnet.WrapReadWriteCloserToConn(conn, realConn)
_ = p.l.PutConn(wrapConn) _ = p.l.PutConn(wrapConn)
} }

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

@ -48,7 +48,7 @@ func NewSocks5Plugin(options v1.ClientPluginOptions) (p Plugin, err error) {
return 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() defer conn.Close()
wrapConn := utilnet.WrapReadWriteCloserToConn(conn, realConn) wrapConn := utilnet.WrapReadWriteCloserToConn(conn, realConn)
_ = sp.Server.ServeConn(wrapConn) _ = sp.Server.ServeConn(wrapConn)

@ -66,7 +66,7 @@ func NewStaticFilePlugin(options v1.ClientPluginOptions) (Plugin, error) {
return sp, nil 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) wrapConn := utilnet.WrapReadWriteCloserToConn(conn, realConn)
_ = sp.l.PutConn(wrapConn) _ = sp.l.PutConn(wrapConn)
} }

@ -46,13 +46,13 @@ func NewUnixDomainSocketPlugin(options v1.ClientPluginOptions) (p Plugin, err er
return 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) localConn, err := net.DialUnix("unix", nil, uds.UnixAddr)
if err != nil { if err != nil {
return return
} }
if len(extraBufToLocal) > 0 { if extra.ProxyProtocolHeader != nil {
if _, err := localConn.Write(extraBufToLocal); err != nil { if _, err := extra.ProxyProtocolHeader.WriteTo(localConn); err != nil {
return return
} }
} }

@ -45,38 +45,3 @@ func Major(v string) int64 {
func Minor(v string) int64 { func Minor(v string) int64 {
return getSubVersion(v, 2) 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
}

@ -51,15 +51,3 @@ func TestVersion(t *testing.T) {
version := Full() version := Full()
assert.Equal(parseVerion, version) 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)
}

@ -568,7 +568,15 @@ func (ctl *Control) RegisterProxy(pxyMsg *msg.NewProxy) (remoteAddr string, err
// NewProxy will return an interface Proxy. // NewProxy will return an interface Proxy.
// In fact, it creates different proxies based on the proxy type. We just call run() here. // 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 { if err != nil {
return remoteAddr, err return remoteAddr, err
} }

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

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

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

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

@ -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]", 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) 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. // Check auth.
if err = svr.authVerifier.VerifyLogin(loginMsg); err != nil { if err = svr.authVerifier.VerifyLogin(loginMsg); err != nil {
return return

Loading…
Cancel
Save