mirror of
https://github.com/fatedier/frp.git
synced 2025-07-29 01:07:38 +00:00
support yaml/json/toml configuration format, make ini deprecated (#3599)
This commit is contained in:
90
pkg/config/v1/validation/client.go
Normal file
90
pkg/config/v1/validation/client.go
Normal file
@@ -0,0 +1,90 @@
|
||||
// Copyright 2023 The frp Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/samber/lo"
|
||||
|
||||
v1 "github.com/fatedier/frp/pkg/config/v1"
|
||||
)
|
||||
|
||||
func ValidateClientCommonConfig(c *v1.ClientCommonConfig) (Warning, error) {
|
||||
var (
|
||||
warnings Warning
|
||||
errs error
|
||||
)
|
||||
if c.Transport.HeartbeatTimeout > 0 && c.Transport.HeartbeatInterval > 0 {
|
||||
if c.Transport.HeartbeatTimeout < c.Transport.HeartbeatInterval {
|
||||
errs = AppendError(errs, fmt.Errorf("invalid transport.heartbeatTimeout, heartbeat timeout should not less than heartbeat interval"))
|
||||
}
|
||||
}
|
||||
|
||||
if !lo.FromPtr(c.Transport.TLS.Enable) {
|
||||
checkTLSConfig := func(name string, value string) Warning {
|
||||
if value != "" {
|
||||
return fmt.Errorf("%s is invalid when transport.tls.enable is false", name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
warnings = AppendError(warnings, checkTLSConfig("transport.tls.certFile", c.Transport.TLS.CertFile))
|
||||
warnings = AppendError(warnings, checkTLSConfig("transport.tls.keyFile", c.Transport.TLS.KeyFile))
|
||||
warnings = AppendError(warnings, checkTLSConfig("transport.tls.trustedCaFile", c.Transport.TLS.TrustedCaFile))
|
||||
}
|
||||
|
||||
if !lo.Contains([]string{"tcp", "kcp", "quic", "websocket", "wss"}, c.Transport.Protocol) {
|
||||
errs = AppendError(errs, fmt.Errorf("invalid transport.protocol, only support tcp, kcp, quic, websocket, wss"))
|
||||
}
|
||||
|
||||
for _, f := range c.IncludeConfigFiles {
|
||||
absDir, err := filepath.Abs(filepath.Dir(f))
|
||||
if err != nil {
|
||||
errs = AppendError(errs, fmt.Errorf("include: parse directory of %s failed: %v", f, err))
|
||||
continue
|
||||
}
|
||||
if _, err := os.Stat(absDir); os.IsNotExist(err) {
|
||||
errs = AppendError(errs, fmt.Errorf("include: directory of %s not exist", f))
|
||||
}
|
||||
}
|
||||
return warnings, errs
|
||||
}
|
||||
|
||||
func ValidateAllClientConfig(c *v1.ClientCommonConfig, pxyCfgs []v1.ProxyConfigurer, visitorCfgs []v1.VisitorConfigurer) (Warning, error) {
|
||||
var warnings Warning
|
||||
if c != nil {
|
||||
warning, err := ValidateClientCommonConfig(c)
|
||||
warnings = AppendError(warnings, warning)
|
||||
if err != nil {
|
||||
return err, warnings
|
||||
}
|
||||
}
|
||||
|
||||
for _, c := range pxyCfgs {
|
||||
if err := ValidateProxyConfigurerForClient(c); err != nil {
|
||||
return warnings, fmt.Errorf("proxy %s: %v", c.GetBaseConfig().Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, c := range visitorCfgs {
|
||||
if err := ValidateVisitorConfigurer(c); err != nil {
|
||||
return warnings, fmt.Errorf("visitor %s: %v", c.GetBaseConfig().Name, err)
|
||||
}
|
||||
}
|
||||
return warnings, nil
|
||||
}
|
41
pkg/config/v1/validation/common.go
Normal file
41
pkg/config/v1/validation/common.go
Normal file
@@ -0,0 +1,41 @@
|
||||
// Copyright 2023 The frp Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
v1 "github.com/fatedier/frp/pkg/config/v1"
|
||||
)
|
||||
|
||||
func validateWebServerConfig(c *v1.WebServerConfig) error {
|
||||
if c.TLS != nil {
|
||||
if c.TLS.CertFile == "" {
|
||||
return fmt.Errorf("tls.certFile must be specified when tls is enabled")
|
||||
}
|
||||
if c.TLS.KeyFile == "" {
|
||||
return fmt.Errorf("tls.keyFile must be specified when tls is enabled")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValidatePort checks that the network port is in range
|
||||
func ValidatePort(port int) error {
|
||||
if 0 <= port && port <= 65535 {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("port number %d must be in the range 0..65535", port)
|
||||
}
|
72
pkg/config/v1/validation/plugin.go
Normal file
72
pkg/config/v1/validation/plugin.go
Normal file
@@ -0,0 +1,72 @@
|
||||
// Copyright 2023 The frp Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
v1 "github.com/fatedier/frp/pkg/config/v1"
|
||||
)
|
||||
|
||||
func ValidateClientPluginOptions(c v1.ClientPluginOptions) error {
|
||||
switch v := c.(type) {
|
||||
case *v1.HTTP2HTTPSPluginOptions:
|
||||
return validateHTTP2HTTPSPluginOptions(v)
|
||||
case *v1.HTTPS2HTTPPluginOptions:
|
||||
return validateHTTPS2HTTPPluginOptions(v)
|
||||
case *v1.HTTPS2HTTPSPluginOptions:
|
||||
return validateHTTPS2HTTPSPluginOptions(v)
|
||||
case *v1.StaticFilePluginOptions:
|
||||
return validateStaticFilePluginOptions(v)
|
||||
case *v1.UnixDomainSocketPluginOptions:
|
||||
return validateUnixDomainSocketPluginOptions(v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateHTTP2HTTPSPluginOptions(c *v1.HTTP2HTTPSPluginOptions) error {
|
||||
if c.LocalAddr == "" {
|
||||
return errors.New("localAddr is required")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateHTTPS2HTTPPluginOptions(c *v1.HTTPS2HTTPPluginOptions) error {
|
||||
if c.LocalAddr == "" {
|
||||
return errors.New("localAddr is required")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateHTTPS2HTTPSPluginOptions(c *v1.HTTPS2HTTPSPluginOptions) error {
|
||||
if c.LocalAddr == "" {
|
||||
return errors.New("localAddr is required")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateStaticFilePluginOptions(c *v1.StaticFilePluginOptions) error {
|
||||
if c.LocalPath == "" {
|
||||
return errors.New("localPath is required")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateUnixDomainSocketPluginOptions(c *v1.UnixDomainSocketPluginOptions) error {
|
||||
if c.UnixPath == "" {
|
||||
return errors.New("unixPath is required")
|
||||
}
|
||||
return nil
|
||||
}
|
234
pkg/config/v1/validation/proxy.go
Normal file
234
pkg/config/v1/validation/proxy.go
Normal file
@@ -0,0 +1,234 @@
|
||||
// Copyright 2023 The frp Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/samber/lo"
|
||||
|
||||
v1 "github.com/fatedier/frp/pkg/config/v1"
|
||||
"github.com/fatedier/frp/pkg/consts"
|
||||
)
|
||||
|
||||
func validateProxyBaseConfigForClient(c *v1.ProxyBaseConfig) error {
|
||||
if c.Name == "" {
|
||||
return errors.New("name should not be empty")
|
||||
}
|
||||
|
||||
if !lo.Contains([]string{"", "v1", "v2"}, c.Transport.ProxyProtocolVersion) {
|
||||
return fmt.Errorf("not support proxy protocol version: %s", c.Transport.ProxyProtocolVersion)
|
||||
}
|
||||
|
||||
if !lo.Contains([]string{"client", "server"}, c.Transport.BandwidthLimitMode) {
|
||||
return fmt.Errorf("bandwidth limit mode should be client or server")
|
||||
}
|
||||
|
||||
if c.Plugin.Type == "" {
|
||||
if err := ValidatePort(c.LocalPort); err != nil {
|
||||
return fmt.Errorf("localPort: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if !lo.Contains([]string{"", "tcp", "http"}, c.HealthCheck.Type) {
|
||||
return fmt.Errorf("not support health check type: %s", c.HealthCheck.Type)
|
||||
}
|
||||
if c.HealthCheck.Type != "" {
|
||||
if c.HealthCheck.Type == "http" &&
|
||||
c.HealthCheck.Path == "" {
|
||||
return fmt.Errorf("health check path should not be empty")
|
||||
}
|
||||
}
|
||||
|
||||
if c.Plugin.Type != "" {
|
||||
if err := ValidateClientPluginOptions(c.Plugin.ClientPluginOptions); err != nil {
|
||||
return fmt.Errorf("plugin %s: %v", c.Plugin.Type, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateProxyBaseConfigForServer(c *v1.ProxyBaseConfig, s *v1.ServerConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateDomainConfigForClient(c *v1.DomainConfig) error {
|
||||
if c.SubDomain == "" && len(c.CustomDomains) == 0 {
|
||||
return errors.New("subdomain and custom domains should not be both empty")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateDomainConfigForServer(c *v1.DomainConfig, s *v1.ServerConfig) error {
|
||||
for _, domain := range c.CustomDomains {
|
||||
if s.SubDomainHost != "" && len(strings.Split(s.SubDomainHost, ".")) < len(strings.Split(domain, ".")) {
|
||||
if strings.Contains(domain, s.SubDomainHost) {
|
||||
return fmt.Errorf("custom domain [%s] should not belong to subdomain host [%s]", domain, s.SubDomainHost)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if c.SubDomain != "" {
|
||||
if s.SubDomainHost == "" {
|
||||
return errors.New("subdomain is not supported because this feature is not enabled in server")
|
||||
}
|
||||
|
||||
if strings.Contains(c.SubDomain, ".") || strings.Contains(c.SubDomain, "*") {
|
||||
return errors.New("'.' and '*' are not supported in subdomain")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ValidateProxyConfigurerForClient(c v1.ProxyConfigurer) error {
|
||||
base := c.GetBaseConfig()
|
||||
if err := validateProxyBaseConfigForClient(base); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch v := c.(type) {
|
||||
case *v1.TCPProxyConfig:
|
||||
return validateTCPProxyConfigForClient(v)
|
||||
case *v1.UDPProxyConfig:
|
||||
return validateUDPProxyConfigForClient(v)
|
||||
case *v1.TCPMuxProxyConfig:
|
||||
return validateTCPMuxProxyConfigForClient(v)
|
||||
case *v1.HTTPProxyConfig:
|
||||
return validateHTTPProxyConfigForClient(v)
|
||||
case *v1.HTTPSProxyConfig:
|
||||
return validateHTTPSProxyConfigForClient(v)
|
||||
case *v1.STCPProxyConfig:
|
||||
return validateSTCPProxyConfigForClient(v)
|
||||
case *v1.XTCPProxyConfig:
|
||||
return validateXTCPProxyConfigForClient(v)
|
||||
case *v1.SUDPProxyConfig:
|
||||
return validateSUDPProxyConfigForClient(v)
|
||||
}
|
||||
return errors.New("unknown proxy config type")
|
||||
}
|
||||
|
||||
func validateTCPProxyConfigForClient(c *v1.TCPProxyConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateUDPProxyConfigForClient(c *v1.UDPProxyConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateTCPMuxProxyConfigForClient(c *v1.TCPMuxProxyConfig) error {
|
||||
if err := validateDomainConfigForClient(&c.DomainConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !lo.Contains([]string{consts.HTTPConnectTCPMultiplexer}, c.Multiplexer) {
|
||||
return fmt.Errorf("not support multiplexer: %s", c.Multiplexer)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateHTTPProxyConfigForClient(c *v1.HTTPProxyConfig) error {
|
||||
return validateDomainConfigForClient(&c.DomainConfig)
|
||||
}
|
||||
|
||||
func validateHTTPSProxyConfigForClient(c *v1.HTTPSProxyConfig) error {
|
||||
return validateDomainConfigForClient(&c.DomainConfig)
|
||||
}
|
||||
|
||||
func validateSTCPProxyConfigForClient(c *v1.STCPProxyConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateXTCPProxyConfigForClient(c *v1.XTCPProxyConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateSUDPProxyConfigForClient(c *v1.SUDPProxyConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func ValidateProxyConfigurerForServer(c v1.ProxyConfigurer, s *v1.ServerConfig) error {
|
||||
base := c.GetBaseConfig()
|
||||
if err := validateProxyBaseConfigForServer(base, s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch v := c.(type) {
|
||||
case *v1.TCPProxyConfig:
|
||||
return validateTCPProxyConfigForServer(v, s)
|
||||
case *v1.UDPProxyConfig:
|
||||
return validateUDPProxyConfigForServer(v, s)
|
||||
case *v1.TCPMuxProxyConfig:
|
||||
return validateTCPMuxProxyConfigForServer(v, s)
|
||||
case *v1.HTTPProxyConfig:
|
||||
return validateHTTPProxyConfigForServer(v, s)
|
||||
case *v1.HTTPSProxyConfig:
|
||||
return validateHTTPSProxyConfigForServer(v, s)
|
||||
case *v1.STCPProxyConfig:
|
||||
return validateSTCPProxyConfigForServer(v, s)
|
||||
case *v1.XTCPProxyConfig:
|
||||
return validateXTCPProxyConfigForServer(v, s)
|
||||
case *v1.SUDPProxyConfig:
|
||||
return validateSUDPProxyConfigForServer(v, s)
|
||||
default:
|
||||
return errors.New("unknown proxy config type")
|
||||
}
|
||||
}
|
||||
|
||||
func validateTCPProxyConfigForServer(c *v1.TCPProxyConfig, s *v1.ServerConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateUDPProxyConfigForServer(c *v1.UDPProxyConfig, s *v1.ServerConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateTCPMuxProxyConfigForServer(c *v1.TCPMuxProxyConfig, s *v1.ServerConfig) error {
|
||||
if c.Multiplexer == consts.HTTPConnectTCPMultiplexer &&
|
||||
s.TCPMuxHTTPConnectPort == 0 {
|
||||
return fmt.Errorf("tcpmux with multiplexer httpconnect not supported because this feature is not enabled in server")
|
||||
}
|
||||
|
||||
return validateDomainConfigForServer(&c.DomainConfig, s)
|
||||
}
|
||||
|
||||
func validateHTTPProxyConfigForServer(c *v1.HTTPProxyConfig, s *v1.ServerConfig) error {
|
||||
if s.VhostHTTPPort == 0 {
|
||||
return fmt.Errorf("type [http] not supported when vhost http port is not set")
|
||||
}
|
||||
|
||||
return validateDomainConfigForServer(&c.DomainConfig, s)
|
||||
}
|
||||
|
||||
func validateHTTPSProxyConfigForServer(c *v1.HTTPSProxyConfig, s *v1.ServerConfig) error {
|
||||
if s.VhostHTTPSPort == 0 {
|
||||
return fmt.Errorf("type [https] not supported when vhost https port is not set")
|
||||
}
|
||||
|
||||
return validateDomainConfigForServer(&c.DomainConfig, s)
|
||||
}
|
||||
|
||||
func validateSTCPProxyConfigForServer(c *v1.STCPProxyConfig, s *v1.ServerConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateXTCPProxyConfigForServer(c *v1.XTCPProxyConfig, s *v1.ServerConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateSUDPProxyConfigForServer(c *v1.SUDPProxyConfig, s *v1.ServerConfig) error {
|
||||
return nil
|
||||
}
|
37
pkg/config/v1/validation/server.go
Normal file
37
pkg/config/v1/validation/server.go
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright 2023 The frp Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
v1 "github.com/fatedier/frp/pkg/config/v1"
|
||||
)
|
||||
|
||||
func ValidateServerConfig(c *v1.ServerConfig) (Warning, error) {
|
||||
var (
|
||||
warnings Warning
|
||||
errs error
|
||||
)
|
||||
if err := validateWebServerConfig(&c.WebServer); err != nil {
|
||||
errs = AppendError(errs, err)
|
||||
}
|
||||
|
||||
errs = AppendError(errs, ValidatePort(c.BindPort))
|
||||
errs = AppendError(errs, ValidatePort(c.KCPBindPort))
|
||||
errs = AppendError(errs, ValidatePort(c.QUICBindPort))
|
||||
errs = AppendError(errs, ValidatePort(c.VhostHTTPPort))
|
||||
errs = AppendError(errs, ValidatePort(c.VhostHTTPSPort))
|
||||
errs = AppendError(errs, ValidatePort(c.TCPMuxHTTPConnectPort))
|
||||
return warnings, errs
|
||||
}
|
28
pkg/config/v1/validation/validation.go
Normal file
28
pkg/config/v1/validation/validation.go
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright 2023 The frp Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
type Warning error
|
||||
|
||||
func AppendError(err error, errs ...error) error {
|
||||
if len(errs) == 0 {
|
||||
return err
|
||||
}
|
||||
return errors.Join(append([]error{err}, errs...)...)
|
||||
}
|
59
pkg/config/v1/validation/visitor.go
Normal file
59
pkg/config/v1/validation/visitor.go
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright 2023 The frp Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/samber/lo"
|
||||
|
||||
v1 "github.com/fatedier/frp/pkg/config/v1"
|
||||
)
|
||||
|
||||
func ValidateVisitorConfigurer(c v1.VisitorConfigurer) error {
|
||||
base := c.GetBaseConfig()
|
||||
if err := validateVisitorBaseConfig(base); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch v := c.(type) {
|
||||
case *v1.STCPVisitorConfig:
|
||||
case *v1.SUDPVisitorConfig:
|
||||
case *v1.XTCPVisitorConfig:
|
||||
return validateXTCPVisitorConfig(v)
|
||||
default:
|
||||
return errors.New("unknown visitor config type")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateVisitorBaseConfig(c *v1.VisitorBaseConfig) error {
|
||||
if c.Name == "" {
|
||||
return errors.New("name should not be empty")
|
||||
}
|
||||
|
||||
if c.BindPort == 0 {
|
||||
return errors.New("bind port is required")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateXTCPVisitorConfig(c *v1.XTCPVisitorConfig) error {
|
||||
if !lo.Contains([]string{"kcp", "quic"}, c.Protocol) {
|
||||
return fmt.Errorf("protocol should be kcp or quic")
|
||||
}
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user