mirror of https://github.com/fatedier/frp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1072 lines
27 KiB
1072 lines
27 KiB
// 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 config |
|
|
|
import ( |
|
"fmt" |
|
"net" |
|
"reflect" |
|
"strconv" |
|
"strings" |
|
|
|
"github.com/fatedier/frp/pkg/consts" |
|
"github.com/fatedier/frp/pkg/msg" |
|
|
|
"gopkg.in/ini.v1" |
|
) |
|
|
|
// 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{}), |
|
} |
|
) |
|
|
|
func NewConfByType(proxyType string) ProxyConf { |
|
v, ok := proxyConfTypeMap[proxyType] |
|
if !ok { |
|
return nil |
|
} |
|
cfg := reflect.New(v).Interface().(ProxyConf) |
|
return cfg |
|
} |
|
|
|
type ProxyConf interface { |
|
GetBaseInfo() *BaseProxyConf |
|
UnmarshalFromMsg(*msg.NewProxy) |
|
UnmarshalFromIni(string, string, *ini.Section) error |
|
MarshalToMsg(*msg.NewProxy) |
|
CheckForCli() error |
|
CheckForSvr(ServerCommonConf) error |
|
Compare(ProxyConf) bool |
|
} |
|
|
|
// LocalSvrConf configures what location the client will to, or what |
|
// plugin will be used. |
|
type LocalSvrConf struct { |
|
// LocalIP specifies the IP address or host name to to. |
|
LocalIP string `ini:"local_ip" json:"local_ip"` |
|
// LocalPort specifies the port to to. |
|
LocalPort int `ini:"local_port" json:"local_port"` |
|
|
|
// Plugin specifies what plugin should be used for ng. If this value |
|
// is set, the LocalIp and LocalPort values will be ignored. By default, |
|
// this value is "". |
|
Plugin string `ini:"plugin" json:"plugin"` |
|
// PluginParams specify parameters to be passed to the plugin, if one is |
|
// being used. By default, this value is an empty map. |
|
PluginParams map[string]string `ini:"-"` |
|
} |
|
|
|
// HealthCheckConf configures health checking. This can be useful for load |
|
// balancing purposes to detect and remove proxies to failing services. |
|
type HealthCheckConf struct { |
|
// HealthCheckType specifies what protocol to use for health checking. |
|
// Valid values include "tcp", "http", and "". If this value is "", health |
|
// checking will not be performed. By default, this value is "". |
|
// |
|
// If the type is "tcp", a connection will be attempted to the target |
|
// server. If a connection cannot be established, the health check fails. |
|
// |
|
// If the type is "http", a GET request will be made to the endpoint |
|
// specified by HealthCheckURL. If the response is not a 200, the health |
|
// check fails. |
|
HealthCheckType string `ini:"health_check_type" json:"health_check_type"` // tcp | http |
|
// HealthCheckTimeoutS specifies the number of seconds to wait for a health |
|
// check attempt to connect. If the timeout is reached, this counts as a |
|
// health check failure. By default, this value is 3. |
|
HealthCheckTimeoutS int `ini:"health_check_timeout_s" json:"health_check_timeout_s"` |
|
// HealthCheckMaxFailed specifies the number of allowed failures before the |
|
// is stopped. By default, this value is 1. |
|
HealthCheckMaxFailed int `ini:"health_check_max_failed" json:"health_check_max_failed"` |
|
// HealthCheckIntervalS specifies the time in seconds between health |
|
// checks. By default, this value is 10. |
|
HealthCheckIntervalS int `ini:"health_check_interval_s" json:"health_check_interval_s"` |
|
// HealthCheckURL specifies the address to send health checks to if the |
|
// health check type is "http". |
|
HealthCheckURL string `ini:"health_check_url" json:"health_check_url"` |
|
// HealthCheckAddr specifies the address to connect to if the health check |
|
// type is "tcp". |
|
HealthCheckAddr string `ini:"-"` |
|
} |
|
|
|
// BaseProxyConf provides configuration info that is common to all types. |
|
type BaseProxyConf struct { |
|
// ProxyName is the name of this |
|
ProxyName string `ini:"name" json:"name"` |
|
// ProxyType specifies the type of this Valid values include "tcp", |
|
// "udp", "http", "https", "stcp", and "xtcp". By default, this value is |
|
// "tcp". |
|
ProxyType string `ini:"type" json:"type"` |
|
|
|
// UseEncryption controls whether or not communication with the server will |
|
// be encrypted. Encryption is done using the tokens supplied in the server |
|
// and client configuration. By default, this value is false. |
|
UseEncryption bool `ini:"use_encryption" json:"use_encryption"` |
|
// UseCompression controls whether or not communication with the server |
|
// will be compressed. By default, this value is false. |
|
UseCompression bool `ini:"use_compression" json:"use_compression"` |
|
// Group specifies which group the is a part of. The server will use |
|
// this information to load balance proxies in the same group. If the value |
|
// is "", this will not be in a group. By default, this value is "". |
|
Group string `ini:"group" json:"group"` |
|
// GroupKey specifies a group key, which should be the same among proxies |
|
// of the same group. By default, this value is "". |
|
GroupKey string `ini:"group_key" json:"group_key"` |
|
|
|
// ProxyProtocolVersion specifies which protocol version to use. Valid |
|
// values include "v1", "v2", and "". If the value is "", a protocol |
|
// version will be automatically selected. By default, this value is "". |
|
ProxyProtocolVersion string `ini:"proxy_protocol_version" json:"proxy_protocol_version"` |
|
|
|
// BandwidthLimit limit the bandwidth |
|
// 0 means no limit |
|
BandwidthLimit BandwidthQuantity `ini:"bandwidth_limit" json:"bandwidth_limit"` |
|
|
|
// meta info for each proxy |
|
Metas map[string]string `ini:"-" json:"metas"` |
|
|
|
LocalSvrConf `ini:",extends"` |
|
HealthCheckConf `ini:",extends"` |
|
} |
|
|
|
type DomainConf struct { |
|
CustomDomains []string `ini:"custom_domains" json:"custom_domains"` |
|
SubDomain string `ini:"subdomain" json:"subdomain"` |
|
} |
|
|
|
// HTTP |
|
type HTTPProxyConf struct { |
|
BaseProxyConf `ini:",extends"` |
|
DomainConf `ini:",extends"` |
|
|
|
Locations []string `ini:"locations" json:"locations"` |
|
HTTPUser string `ini:"http_user" json:"http_user"` |
|
HTTPPwd string `ini:"http_pwd" json:"http_pwd"` |
|
HostHeaderRewrite string `ini:"host_header_rewrite" json:"host_header_rewrite"` |
|
Headers map[string]string `ini:"-" json:"headers"` |
|
RouteByHTTPUser string `ini:"route_by_http_user" json:"route_by_http_user"` |
|
} |
|
|
|
// HTTPS |
|
type HTTPSProxyConf struct { |
|
BaseProxyConf `ini:",extends"` |
|
DomainConf `ini:",extends"` |
|
} |
|
|
|
// TCP |
|
type TCPProxyConf struct { |
|
BaseProxyConf `ini:",extends"` |
|
RemotePort int `ini:"remote_port" json:"remote_port"` |
|
} |
|
|
|
// TCPMux |
|
type TCPMuxProxyConf struct { |
|
BaseProxyConf `ini:",extends"` |
|
DomainConf `ini:",extends"` |
|
RouteByHTTPUser string `ini:"route_by_http_user" json:"route_by_http_user"` |
|
|
|
Multiplexer string `ini:"multiplexer"` |
|
} |
|
|
|
// STCP |
|
type STCPProxyConf struct { |
|
BaseProxyConf `ini:",extends"` |
|
|
|
Role string `ini:"role" json:"role"` |
|
Sk string `ini:"sk" json:"sk"` |
|
} |
|
|
|
// XTCP |
|
type XTCPProxyConf struct { |
|
BaseProxyConf `ini:",extends"` |
|
|
|
Role string `ini:"role" json:"role"` |
|
Sk string `ini:"sk" json:"sk"` |
|
} |
|
|
|
// UDP |
|
type UDPProxyConf struct { |
|
BaseProxyConf `ini:",extends"` |
|
|
|
RemotePort int `ini:"remote_port" json:"remote_port"` |
|
} |
|
|
|
// SUDP |
|
type SUDPProxyConf struct { |
|
BaseProxyConf `ini:",extends"` |
|
|
|
Role string `ini:"role" json:"role"` |
|
Sk string `ini:"sk" json:"sk"` |
|
} |
|
|
|
// Proxy Conf Loader |
|
// DefaultProxyConf creates a empty ProxyConf object by proxyType. |
|
// If proxyType doesn't exist, return nil. |
|
func DefaultProxyConf(proxyType string) ProxyConf { |
|
var conf ProxyConf |
|
switch proxyType { |
|
case consts.TCPProxy: |
|
conf = &TCPProxyConf{ |
|
BaseProxyConf: defaultBaseProxyConf(proxyType), |
|
} |
|
case consts.TCPMuxProxy: |
|
conf = &TCPMuxProxyConf{ |
|
BaseProxyConf: defaultBaseProxyConf(proxyType), |
|
} |
|
case consts.UDPProxy: |
|
conf = &UDPProxyConf{ |
|
BaseProxyConf: defaultBaseProxyConf(proxyType), |
|
} |
|
case consts.HTTPProxy: |
|
conf = &HTTPProxyConf{ |
|
BaseProxyConf: defaultBaseProxyConf(proxyType), |
|
} |
|
case consts.HTTPSProxy: |
|
conf = &HTTPSProxyConf{ |
|
BaseProxyConf: defaultBaseProxyConf(proxyType), |
|
} |
|
case consts.STCPProxy: |
|
conf = &STCPProxyConf{ |
|
BaseProxyConf: defaultBaseProxyConf(proxyType), |
|
Role: "server", |
|
} |
|
case consts.XTCPProxy: |
|
conf = &XTCPProxyConf{ |
|
BaseProxyConf: defaultBaseProxyConf(proxyType), |
|
Role: "server", |
|
} |
|
case consts.SUDPProxy: |
|
conf = &SUDPProxyConf{ |
|
BaseProxyConf: defaultBaseProxyConf(proxyType), |
|
Role: "server", |
|
} |
|
default: |
|
return nil |
|
} |
|
|
|
return conf |
|
} |
|
|
|
// 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() |
|
if proxyType == "" { |
|
proxyType = consts.TCPProxy |
|
} |
|
|
|
conf := DefaultProxyConf(proxyType) |
|
if conf == nil { |
|
return nil, fmt.Errorf("proxy %s has invalid type [%s]", name, proxyType) |
|
} |
|
|
|
if err := conf.UnmarshalFromIni(prefix, name, section); err != nil { |
|
return nil, err |
|
} |
|
|
|
if err := conf.CheckForCli(); err != nil { |
|
return nil, err |
|
} |
|
|
|
return conf, nil |
|
} |
|
|
|
// Proxy loaded from msg |
|
func NewProxyConfFromMsg(pMsg *msg.NewProxy, serverCfg ServerCommonConf) (ProxyConf, error) { |
|
if pMsg.ProxyType == "" { |
|
pMsg.ProxyType = consts.TCPProxy |
|
} |
|
|
|
conf := DefaultProxyConf(pMsg.ProxyType) |
|
if conf == nil { |
|
return nil, fmt.Errorf("proxy [%s] type [%s] error", pMsg.ProxyName, pMsg.ProxyType) |
|
} |
|
|
|
conf.UnmarshalFromMsg(pMsg) |
|
|
|
err := conf.CheckForSvr(serverCfg) |
|
if err != nil { |
|
return nil, err |
|
} |
|
|
|
return conf, nil |
|
} |
|
|
|
// Base |
|
func defaultBaseProxyConf(proxyType string) BaseProxyConf { |
|
return BaseProxyConf{ |
|
ProxyType: proxyType, |
|
LocalSvrConf: LocalSvrConf{ |
|
LocalIP: "127.0.0.1", |
|
}, |
|
} |
|
} |
|
|
|
func (cfg *BaseProxyConf) GetBaseInfo() *BaseProxyConf { |
|
return cfg |
|
} |
|
|
|
func (cfg *BaseProxyConf) compare(cmp *BaseProxyConf) bool { |
|
if cfg.ProxyName != cmp.ProxyName || |
|
cfg.ProxyType != cmp.ProxyType || |
|
cfg.UseEncryption != cmp.UseEncryption || |
|
cfg.UseCompression != cmp.UseCompression || |
|
cfg.Group != cmp.Group || |
|
cfg.GroupKey != cmp.GroupKey || |
|
cfg.ProxyProtocolVersion != cmp.ProxyProtocolVersion || |
|
!cfg.BandwidthLimit.Equal(&cmp.BandwidthLimit) || |
|
!reflect.DeepEqual(cfg.Metas, cmp.Metas) { |
|
return false |
|
} |
|
|
|
if !reflect.DeepEqual(cfg.LocalSvrConf, cmp.LocalSvrConf) { |
|
return false |
|
} |
|
if !reflect.DeepEqual(cfg.HealthCheckConf, cmp.HealthCheckConf) { |
|
return false |
|
} |
|
|
|
return true |
|
} |
|
|
|
// BaseProxyConf apply custom logic changes. |
|
func (cfg *BaseProxyConf) decorate(prefix string, name string, section *ini.Section) error { |
|
// proxy_name |
|
cfg.ProxyName = prefix + name |
|
|
|
// metas_xxx |
|
cfg.Metas = GetMapWithoutPrefix(section.KeysHash(), "meta_") |
|
|
|
// bandwidth_limit |
|
if bandwidth, err := section.GetKey("bandwidth_limit"); err == nil { |
|
cfg.BandwidthLimit, err = NewBandwidthQuantity(bandwidth.String()) |
|
if err != nil { |
|
return err |
|
} |
|
} |
|
|
|
// plugin_xxx |
|
cfg.LocalSvrConf.PluginParams = GetMapByPrefix(section.KeysHash(), "plugin_") |
|
|
|
// custom logic code |
|
if cfg.HealthCheckType == "tcp" && cfg.Plugin == "" { |
|
cfg.HealthCheckAddr = cfg.LocalIP + fmt.Sprintf(":%d", cfg.LocalPort) |
|
} |
|
|
|
if cfg.HealthCheckType == "http" && cfg.Plugin == "" && cfg.HealthCheckURL != "" { |
|
s := "http://" + net.JoinHostPort(cfg.LocalIP, strconv.Itoa(cfg.LocalPort)) |
|
if !strings.HasPrefix(cfg.HealthCheckURL, "/") { |
|
s += "/" |
|
} |
|
cfg.HealthCheckURL = s + cfg.HealthCheckURL |
|
} |
|
|
|
return nil |
|
} |
|
|
|
func (cfg *BaseProxyConf) marshalToMsg(pMsg *msg.NewProxy) { |
|
pMsg.ProxyName = cfg.ProxyName |
|
pMsg.ProxyType = cfg.ProxyType |
|
pMsg.UseEncryption = cfg.UseEncryption |
|
pMsg.UseCompression = cfg.UseCompression |
|
pMsg.Group = cfg.Group |
|
pMsg.GroupKey = cfg.GroupKey |
|
pMsg.Metas = cfg.Metas |
|
} |
|
|
|
func (cfg *BaseProxyConf) unmarshalFromMsg(pMsg *msg.NewProxy) { |
|
cfg.ProxyName = pMsg.ProxyName |
|
cfg.ProxyType = pMsg.ProxyType |
|
cfg.UseEncryption = pMsg.UseEncryption |
|
cfg.UseCompression = pMsg.UseCompression |
|
cfg.Group = pMsg.Group |
|
cfg.GroupKey = pMsg.GroupKey |
|
cfg.Metas = pMsg.Metas |
|
} |
|
|
|
func (cfg *BaseProxyConf) checkForCli() (err error) { |
|
if cfg.ProxyProtocolVersion != "" { |
|
if cfg.ProxyProtocolVersion != "v1" && cfg.ProxyProtocolVersion != "v2" { |
|
return fmt.Errorf("no support proxy protocol version: %s", cfg.ProxyProtocolVersion) |
|
} |
|
} |
|
|
|
if err = cfg.LocalSvrConf.checkForCli(); err != nil { |
|
return |
|
} |
|
if err = cfg.HealthCheckConf.checkForCli(); err != nil { |
|
return |
|
} |
|
return nil |
|
} |
|
|
|
func (cfg *BaseProxyConf) checkForSvr(conf ServerCommonConf) error { |
|
return nil |
|
} |
|
|
|
// DomainConf |
|
func (cfg *DomainConf) check() (err error) { |
|
if len(cfg.CustomDomains) == 0 && cfg.SubDomain == "" { |
|
err = fmt.Errorf("custom_domains and subdomain should set at least one of them") |
|
return |
|
} |
|
return |
|
} |
|
|
|
func (cfg *DomainConf) checkForCli() (err error) { |
|
if err = cfg.check(); err != nil { |
|
return |
|
} |
|
return |
|
} |
|
|
|
func (cfg *DomainConf) checkForSvr(serverCfg ServerCommonConf) (err error) { |
|
if err = cfg.check(); err != nil { |
|
return |
|
} |
|
|
|
for _, domain := range cfg.CustomDomains { |
|
if serverCfg.SubDomainHost != "" && len(strings.Split(serverCfg.SubDomainHost, ".")) < len(strings.Split(domain, ".")) { |
|
if strings.Contains(domain, serverCfg.SubDomainHost) { |
|
return fmt.Errorf("custom domain [%s] should not belong to subdomain_host [%s]", domain, serverCfg.SubDomainHost) |
|
} |
|
} |
|
} |
|
|
|
if cfg.SubDomain != "" { |
|
if serverCfg.SubDomainHost == "" { |
|
return fmt.Errorf("subdomain is not supported because this feature is not enabled in remote frps") |
|
} |
|
if strings.Contains(cfg.SubDomain, ".") || strings.Contains(cfg.SubDomain, "*") { |
|
return fmt.Errorf("'.' and '*' is not supported in subdomain") |
|
} |
|
} |
|
return nil |
|
} |
|
|
|
// LocalSvrConf |
|
func (cfg *LocalSvrConf) checkForCli() (err error) { |
|
if cfg.Plugin == "" { |
|
if cfg.LocalIP == "" { |
|
err = fmt.Errorf("local ip or plugin is required") |
|
return |
|
} |
|
if cfg.LocalPort <= 0 { |
|
err = fmt.Errorf("error local_port") |
|
return |
|
} |
|
} |
|
return |
|
} |
|
|
|
// HealthCheckConf |
|
func (cfg *HealthCheckConf) checkForCli() error { |
|
if cfg.HealthCheckType != "" && cfg.HealthCheckType != "tcp" && cfg.HealthCheckType != "http" { |
|
return fmt.Errorf("unsupport health check type") |
|
} |
|
if cfg.HealthCheckType != "" { |
|
if cfg.HealthCheckType == "http" && cfg.HealthCheckURL == "" { |
|
return fmt.Errorf("health_check_url is required for health check type 'http'") |
|
} |
|
} |
|
return nil |
|
} |
|
|
|
func preUnmarshalFromIni(cfg ProxyConf, prefix string, name string, section *ini.Section) error { |
|
err := section.MapTo(cfg) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
err = cfg.GetBaseInfo().decorate(prefix, name, section) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
return nil |
|
} |
|
|
|
// TCP |
|
func (cfg *TCPProxyConf) Compare(cmp ProxyConf) bool { |
|
cmpConf, ok := cmp.(*TCPProxyConf) |
|
if !ok { |
|
return false |
|
} |
|
|
|
if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) { |
|
return false |
|
} |
|
|
|
// Add custom logic equal if exists. |
|
if cfg.RemotePort != cmpConf.RemotePort { |
|
return false |
|
} |
|
|
|
return true |
|
} |
|
|
|
func (cfg *TCPProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) { |
|
cfg.BaseProxyConf.unmarshalFromMsg(pMsg) |
|
|
|
// Add custom logic unmarshal if exists |
|
cfg.RemotePort = pMsg.RemotePort |
|
} |
|
|
|
func (cfg *TCPProxyConf) UnmarshalFromIni(prefix string, name string, section *ini.Section) error { |
|
err := preUnmarshalFromIni(cfg, prefix, name, section) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
// Add custom logic unmarshal if exists |
|
|
|
return nil |
|
} |
|
|
|
func (cfg *TCPProxyConf) MarshalToMsg(pMsg *msg.NewProxy) { |
|
cfg.BaseProxyConf.marshalToMsg(pMsg) |
|
|
|
// Add custom logic marshal if exists |
|
pMsg.RemotePort = cfg.RemotePort |
|
} |
|
|
|
func (cfg *TCPProxyConf) CheckForCli() (err error) { |
|
if err = cfg.BaseProxyConf.checkForCli(); err != nil { |
|
return |
|
} |
|
|
|
// Add custom logic check if exists |
|
|
|
return |
|
} |
|
|
|
func (cfg *TCPProxyConf) CheckForSvr(serverCfg ServerCommonConf) error { |
|
return nil |
|
} |
|
|
|
// TCPMux |
|
func (cfg *TCPMuxProxyConf) Compare(cmp ProxyConf) bool { |
|
cmpConf, ok := cmp.(*TCPMuxProxyConf) |
|
if !ok { |
|
return false |
|
} |
|
|
|
if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) { |
|
return false |
|
} |
|
|
|
// Add custom logic equal if exists. |
|
if !reflect.DeepEqual(cfg.DomainConf, cmpConf.DomainConf) { |
|
return false |
|
} |
|
|
|
if cfg.Multiplexer != cmpConf.Multiplexer || cfg.RouteByHTTPUser != cmpConf.RouteByHTTPUser { |
|
return false |
|
} |
|
|
|
return true |
|
} |
|
|
|
func (cfg *TCPMuxProxyConf) UnmarshalFromIni(prefix string, name string, section *ini.Section) error { |
|
err := preUnmarshalFromIni(cfg, prefix, name, section) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
// Add custom logic unmarshal if exists |
|
|
|
return nil |
|
} |
|
|
|
func (cfg *TCPMuxProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) { |
|
cfg.BaseProxyConf.unmarshalFromMsg(pMsg) |
|
|
|
// Add custom logic unmarshal if exists |
|
cfg.CustomDomains = pMsg.CustomDomains |
|
cfg.SubDomain = pMsg.SubDomain |
|
cfg.Multiplexer = pMsg.Multiplexer |
|
cfg.RouteByHTTPUser = pMsg.RouteByHTTPUser |
|
} |
|
|
|
func (cfg *TCPMuxProxyConf) MarshalToMsg(pMsg *msg.NewProxy) { |
|
cfg.BaseProxyConf.marshalToMsg(pMsg) |
|
|
|
// Add custom logic marshal if exists |
|
pMsg.CustomDomains = cfg.CustomDomains |
|
pMsg.SubDomain = cfg.SubDomain |
|
pMsg.Multiplexer = cfg.Multiplexer |
|
pMsg.RouteByHTTPUser = cfg.RouteByHTTPUser |
|
} |
|
|
|
func (cfg *TCPMuxProxyConf) CheckForCli() (err error) { |
|
if err = cfg.BaseProxyConf.checkForCli(); err != nil { |
|
return |
|
} |
|
|
|
// Add custom logic check if exists |
|
if err = cfg.DomainConf.checkForCli(); err != nil { |
|
return |
|
} |
|
|
|
if cfg.Multiplexer != consts.HTTPConnectTCPMultiplexer { |
|
return fmt.Errorf("parse conf error: incorrect multiplexer [%s]", cfg.Multiplexer) |
|
} |
|
|
|
return |
|
} |
|
|
|
func (cfg *TCPMuxProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) { |
|
if cfg.Multiplexer != consts.HTTPConnectTCPMultiplexer { |
|
return fmt.Errorf("proxy [%s] incorrect multiplexer [%s]", cfg.ProxyName, cfg.Multiplexer) |
|
} |
|
|
|
if cfg.Multiplexer == consts.HTTPConnectTCPMultiplexer && serverCfg.TCPMuxHTTPConnectPort == 0 { |
|
return fmt.Errorf("proxy [%s] type [tcpmux] with multiplexer [httpconnect] requires tcpmux_httpconnect_port configuration", cfg.ProxyName) |
|
} |
|
|
|
if err = cfg.DomainConf.checkForSvr(serverCfg); err != nil { |
|
err = fmt.Errorf("proxy [%s] domain conf check error: %v", cfg.ProxyName, err) |
|
return |
|
} |
|
|
|
return |
|
} |
|
|
|
// UDP |
|
func (cfg *UDPProxyConf) Compare(cmp ProxyConf) bool { |
|
cmpConf, ok := cmp.(*UDPProxyConf) |
|
if !ok { |
|
return false |
|
} |
|
|
|
if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) { |
|
return false |
|
} |
|
|
|
// Add custom logic equal if exists. |
|
if cfg.RemotePort != cmpConf.RemotePort { |
|
return false |
|
} |
|
|
|
return true |
|
} |
|
|
|
func (cfg *UDPProxyConf) UnmarshalFromIni(prefix string, name string, section *ini.Section) error { |
|
err := preUnmarshalFromIni(cfg, prefix, name, section) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
// Add custom logic unmarshal if exists |
|
|
|
return nil |
|
} |
|
|
|
func (cfg *UDPProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) { |
|
cfg.BaseProxyConf.unmarshalFromMsg(pMsg) |
|
|
|
// Add custom logic unmarshal if exists |
|
cfg.RemotePort = pMsg.RemotePort |
|
} |
|
|
|
func (cfg *UDPProxyConf) MarshalToMsg(pMsg *msg.NewProxy) { |
|
cfg.BaseProxyConf.marshalToMsg(pMsg) |
|
|
|
// Add custom logic marshal if exists |
|
pMsg.RemotePort = cfg.RemotePort |
|
} |
|
|
|
func (cfg *UDPProxyConf) CheckForCli() (err error) { |
|
if err = cfg.BaseProxyConf.checkForCli(); err != nil { |
|
return |
|
} |
|
|
|
// Add custom logic check if exists |
|
|
|
return |
|
} |
|
|
|
func (cfg *UDPProxyConf) CheckForSvr(serverCfg ServerCommonConf) error { |
|
return nil |
|
} |
|
|
|
// HTTP |
|
func (cfg *HTTPProxyConf) Compare(cmp ProxyConf) bool { |
|
cmpConf, ok := cmp.(*HTTPProxyConf) |
|
if !ok { |
|
return false |
|
} |
|
|
|
if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) { |
|
return false |
|
} |
|
|
|
// Add custom logic equal if exists. |
|
if !reflect.DeepEqual(cfg.DomainConf, cmpConf.DomainConf) { |
|
return false |
|
} |
|
|
|
if !reflect.DeepEqual(cfg.Locations, cmpConf.Locations) || |
|
cfg.HTTPUser != cmpConf.HTTPUser || |
|
cfg.HTTPPwd != cmpConf.HTTPPwd || |
|
cfg.HostHeaderRewrite != cmpConf.HostHeaderRewrite || |
|
cfg.RouteByHTTPUser != cmpConf.RouteByHTTPUser || |
|
!reflect.DeepEqual(cfg.Headers, cmpConf.Headers) { |
|
return false |
|
} |
|
|
|
return true |
|
} |
|
|
|
func (cfg *HTTPProxyConf) UnmarshalFromIni(prefix string, name string, section *ini.Section) error { |
|
err := preUnmarshalFromIni(cfg, prefix, name, section) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
// Add custom logic unmarshal if exists |
|
cfg.Headers = GetMapWithoutPrefix(section.KeysHash(), "header_") |
|
|
|
return nil |
|
} |
|
|
|
func (cfg *HTTPProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) { |
|
cfg.BaseProxyConf.unmarshalFromMsg(pMsg) |
|
|
|
// Add custom logic unmarshal if exists |
|
cfg.CustomDomains = pMsg.CustomDomains |
|
cfg.SubDomain = pMsg.SubDomain |
|
cfg.Locations = pMsg.Locations |
|
cfg.HostHeaderRewrite = pMsg.HostHeaderRewrite |
|
cfg.HTTPUser = pMsg.HTTPUser |
|
cfg.HTTPPwd = pMsg.HTTPPwd |
|
cfg.Headers = pMsg.Headers |
|
cfg.RouteByHTTPUser = pMsg.RouteByHTTPUser |
|
} |
|
|
|
func (cfg *HTTPProxyConf) MarshalToMsg(pMsg *msg.NewProxy) { |
|
cfg.BaseProxyConf.marshalToMsg(pMsg) |
|
|
|
// Add custom logic marshal if exists |
|
pMsg.CustomDomains = cfg.CustomDomains |
|
pMsg.SubDomain = cfg.SubDomain |
|
pMsg.Locations = cfg.Locations |
|
pMsg.HostHeaderRewrite = cfg.HostHeaderRewrite |
|
pMsg.HTTPUser = cfg.HTTPUser |
|
pMsg.HTTPPwd = cfg.HTTPPwd |
|
pMsg.Headers = cfg.Headers |
|
pMsg.RouteByHTTPUser = cfg.RouteByHTTPUser |
|
} |
|
|
|
func (cfg *HTTPProxyConf) CheckForCli() (err error) { |
|
if err = cfg.BaseProxyConf.checkForCli(); err != nil { |
|
return |
|
} |
|
|
|
// Add custom logic check if exists |
|
if err = cfg.DomainConf.checkForCli(); err != nil { |
|
return |
|
} |
|
|
|
return |
|
} |
|
|
|
func (cfg *HTTPProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) { |
|
if serverCfg.VhostHTTPPort == 0 { |
|
return fmt.Errorf("type [http] not support when vhost_http_port is not set") |
|
} |
|
|
|
if err = cfg.DomainConf.checkForSvr(serverCfg); err != nil { |
|
err = fmt.Errorf("proxy [%s] domain conf check error: %v", cfg.ProxyName, err) |
|
return |
|
} |
|
|
|
return |
|
} |
|
|
|
// HTTPS |
|
func (cfg *HTTPSProxyConf) Compare(cmp ProxyConf) bool { |
|
cmpConf, ok := cmp.(*HTTPSProxyConf) |
|
if !ok { |
|
return false |
|
} |
|
|
|
if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) { |
|
return false |
|
} |
|
|
|
// Add custom logic equal if exists. |
|
if !reflect.DeepEqual(cfg.DomainConf, cmpConf.DomainConf) { |
|
return false |
|
} |
|
|
|
return true |
|
} |
|
|
|
func (cfg *HTTPSProxyConf) UnmarshalFromIni(prefix string, name string, section *ini.Section) error { |
|
err := preUnmarshalFromIni(cfg, prefix, name, section) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
// Add custom logic unmarshal if exists |
|
|
|
return nil |
|
} |
|
|
|
func (cfg *HTTPSProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) { |
|
cfg.BaseProxyConf.unmarshalFromMsg(pMsg) |
|
|
|
// Add custom logic unmarshal if exists |
|
cfg.CustomDomains = pMsg.CustomDomains |
|
cfg.SubDomain = pMsg.SubDomain |
|
} |
|
|
|
func (cfg *HTTPSProxyConf) MarshalToMsg(pMsg *msg.NewProxy) { |
|
cfg.BaseProxyConf.marshalToMsg(pMsg) |
|
|
|
// Add custom logic marshal if exists |
|
pMsg.CustomDomains = cfg.CustomDomains |
|
pMsg.SubDomain = cfg.SubDomain |
|
} |
|
|
|
func (cfg *HTTPSProxyConf) CheckForCli() (err error) { |
|
if err = cfg.BaseProxyConf.checkForCli(); err != nil { |
|
return |
|
} |
|
|
|
// Add custom logic check if exists |
|
if err = cfg.DomainConf.checkForCli(); err != nil { |
|
return |
|
} |
|
|
|
return |
|
} |
|
|
|
func (cfg *HTTPSProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) { |
|
if serverCfg.VhostHTTPSPort == 0 { |
|
return fmt.Errorf("type [https] not support when vhost_https_port is not set") |
|
} |
|
|
|
if err = cfg.DomainConf.checkForSvr(serverCfg); err != nil { |
|
err = fmt.Errorf("proxy [%s] domain conf check error: %v", cfg.ProxyName, err) |
|
return |
|
} |
|
|
|
return |
|
} |
|
|
|
// SUDP |
|
func (cfg *SUDPProxyConf) Compare(cmp ProxyConf) bool { |
|
cmpConf, ok := cmp.(*SUDPProxyConf) |
|
if !ok { |
|
return false |
|
} |
|
|
|
if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) { |
|
return false |
|
} |
|
|
|
// Add custom logic equal if exists. |
|
if cfg.Role != cmpConf.Role || |
|
cfg.Sk != cmpConf.Sk { |
|
return false |
|
} |
|
|
|
return true |
|
} |
|
|
|
func (cfg *SUDPProxyConf) UnmarshalFromIni(prefix string, name string, section *ini.Section) error { |
|
err := preUnmarshalFromIni(cfg, prefix, name, section) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
// Add custom logic unmarshal if exists |
|
|
|
return nil |
|
} |
|
|
|
// Only for role server. |
|
func (cfg *SUDPProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) { |
|
cfg.BaseProxyConf.unmarshalFromMsg(pMsg) |
|
|
|
// Add custom logic unmarshal if exists |
|
cfg.Sk = pMsg.Sk |
|
} |
|
|
|
func (cfg *SUDPProxyConf) MarshalToMsg(pMsg *msg.NewProxy) { |
|
cfg.BaseProxyConf.marshalToMsg(pMsg) |
|
|
|
// Add custom logic marshal if exists |
|
pMsg.Sk = cfg.Sk |
|
} |
|
|
|
func (cfg *SUDPProxyConf) CheckForCli() (err error) { |
|
if err := cfg.BaseProxyConf.checkForCli(); err != nil { |
|
return err |
|
} |
|
|
|
// Add custom logic check if exists |
|
if cfg.Role != "server" { |
|
return fmt.Errorf("role should be 'server'") |
|
} |
|
|
|
return nil |
|
} |
|
|
|
func (cfg *SUDPProxyConf) CheckForSvr(serverCfg ServerCommonConf) error { |
|
return nil |
|
} |
|
|
|
// STCP |
|
func (cfg *STCPProxyConf) Compare(cmp ProxyConf) bool { |
|
cmpConf, ok := cmp.(*STCPProxyConf) |
|
if !ok { |
|
return false |
|
} |
|
|
|
if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) { |
|
return false |
|
} |
|
|
|
// Add custom logic equal if exists. |
|
if cfg.Role != cmpConf.Role || |
|
cfg.Sk != cmpConf.Sk { |
|
return false |
|
} |
|
|
|
return true |
|
} |
|
|
|
func (cfg *STCPProxyConf) UnmarshalFromIni(prefix string, name string, section *ini.Section) error { |
|
err := preUnmarshalFromIni(cfg, prefix, name, section) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
// Add custom logic unmarshal if exists |
|
if cfg.Role == "" { |
|
cfg.Role = "server" |
|
} |
|
|
|
return nil |
|
} |
|
|
|
// Only for role server. |
|
func (cfg *STCPProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) { |
|
cfg.BaseProxyConf.unmarshalFromMsg(pMsg) |
|
|
|
// Add custom logic unmarshal if exists |
|
cfg.Sk = pMsg.Sk |
|
} |
|
|
|
func (cfg *STCPProxyConf) MarshalToMsg(pMsg *msg.NewProxy) { |
|
cfg.BaseProxyConf.marshalToMsg(pMsg) |
|
|
|
// Add custom logic marshal if exists |
|
pMsg.Sk = cfg.Sk |
|
} |
|
|
|
func (cfg *STCPProxyConf) CheckForCli() (err error) { |
|
if err = cfg.BaseProxyConf.checkForCli(); err != nil { |
|
return |
|
} |
|
|
|
// Add custom logic check if exists |
|
if cfg.Role != "server" { |
|
return fmt.Errorf("role should be 'server'") |
|
} |
|
|
|
return |
|
} |
|
|
|
func (cfg *STCPProxyConf) CheckForSvr(serverCfg ServerCommonConf) error { |
|
return nil |
|
} |
|
|
|
// XTCP |
|
func (cfg *XTCPProxyConf) Compare(cmp ProxyConf) bool { |
|
cmpConf, ok := cmp.(*XTCPProxyConf) |
|
if !ok { |
|
return false |
|
} |
|
|
|
if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) { |
|
return false |
|
} |
|
|
|
// Add custom logic equal if exists. |
|
if cfg.Role != cmpConf.Role || |
|
cfg.Sk != cmpConf.Sk { |
|
return false |
|
} |
|
|
|
return true |
|
} |
|
|
|
func (cfg *XTCPProxyConf) UnmarshalFromIni(prefix string, name string, section *ini.Section) error { |
|
err := preUnmarshalFromIni(cfg, prefix, name, section) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
// Add custom logic unmarshal if exists |
|
if cfg.Role == "" { |
|
cfg.Role = "server" |
|
} |
|
|
|
return nil |
|
} |
|
|
|
// Only for role server. |
|
func (cfg *XTCPProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) { |
|
cfg.BaseProxyConf.unmarshalFromMsg(pMsg) |
|
|
|
// Add custom logic unmarshal if exists |
|
cfg.Sk = pMsg.Sk |
|
} |
|
|
|
func (cfg *XTCPProxyConf) MarshalToMsg(pMsg *msg.NewProxy) { |
|
cfg.BaseProxyConf.marshalToMsg(pMsg) |
|
|
|
// Add custom logic marshal if exists |
|
pMsg.Sk = cfg.Sk |
|
} |
|
|
|
func (cfg *XTCPProxyConf) CheckForCli() (err error) { |
|
if err = cfg.BaseProxyConf.checkForCli(); err != nil { |
|
return |
|
} |
|
|
|
// Add custom logic check if exists |
|
if cfg.Role != "server" { |
|
return fmt.Errorf("role should be 'server'") |
|
} |
|
|
|
return |
|
} |
|
|
|
func (cfg *XTCPProxyConf) CheckForSvr(serverCfg ServerCommonConf) error { |
|
return nil |
|
}
|
|
|