"Fossies" - the Fresh Open Source Software Archive

Member "frp-0.36.2/pkg/config/proxy.go" (22 Mar 2021, 27472 Bytes) of package /linux/misc/frp-0.36.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Go source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "proxy.go": 0.36.1_vs_0.36.2.

    1 // Copyright 2016 fatedier, fatedier@gmail.com
    2 //
    3 // Licensed under the Apache License, Version 2.0 (the "License");
    4 // you may not use this file except in compliance with the License.
    5 // You may obtain a copy of the License at
    6 //
    7 //     http://www.apache.org/licenses/LICENSE-2.0
    8 //
    9 // Unless required by applicable law or agreed to in writing, software
   10 // distributed under the License is distributed on an "AS IS" BASIS,
   11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   12 // See the License for the specific language governing permissions and
   13 // limitations under the License.
   14 
   15 package config
   16 
   17 import (
   18     "fmt"
   19     "reflect"
   20     "strings"
   21 
   22     "github.com/fatedier/frp/pkg/consts"
   23     "github.com/fatedier/frp/pkg/msg"
   24 
   25     "gopkg.in/ini.v1"
   26 )
   27 
   28 // Proxy
   29 var (
   30     proxyConfTypeMap = map[string]reflect.Type{
   31         consts.TCPProxy:    reflect.TypeOf(TCPProxyConf{}),
   32         consts.TCPMuxProxy: reflect.TypeOf(TCPMuxProxyConf{}),
   33         consts.UDPProxy:    reflect.TypeOf(UDPProxyConf{}),
   34         consts.HTTPProxy:   reflect.TypeOf(HTTPProxyConf{}),
   35         consts.HTTPSProxy:  reflect.TypeOf(HTTPSProxyConf{}),
   36         consts.STCPProxy:   reflect.TypeOf(STCPProxyConf{}),
   37         consts.XTCPProxy:   reflect.TypeOf(XTCPProxyConf{}),
   38         consts.SUDPProxy:   reflect.TypeOf(SUDPProxyConf{}),
   39     }
   40 )
   41 
   42 func NewConfByType(proxyType string) ProxyConf {
   43     v, ok := proxyConfTypeMap[proxyType]
   44     if !ok {
   45         return nil
   46     }
   47     cfg := reflect.New(v).Interface().(ProxyConf)
   48     return cfg
   49 }
   50 
   51 type ProxyConf interface {
   52     GetBaseInfo() *BaseProxyConf
   53     UnmarshalFromMsg(*msg.NewProxy)
   54     UnmarshalFromIni(string, string, *ini.Section) error
   55     MarshalToMsg(*msg.NewProxy)
   56     CheckForCli() error
   57     CheckForSvr(ServerCommonConf) error
   58     Compare(ProxyConf) bool
   59 }
   60 
   61 // LocalSvrConf configures what location the client will to, or what
   62 // plugin will be used.
   63 type LocalSvrConf struct {
   64     // LocalIP specifies the IP address or host name to to.
   65     LocalIP string `ini:"local_ip" json:"local_ip"`
   66     // LocalPort specifies the port to to.
   67     LocalPort int `ini:"local_port" json:"local_port"`
   68 
   69     // Plugin specifies what plugin should be used for ng. If this value
   70     // is set, the LocalIp and LocalPort values will be ignored. By default,
   71     // this value is "".
   72     Plugin string `ini:"plugin" json:"plugin"`
   73     // PluginParams specify parameters to be passed to the plugin, if one is
   74     // being used. By default, this value is an empty map.
   75     PluginParams map[string]string `ini:"-"`
   76 }
   77 
   78 // HealthCheckConf configures health checking. This can be useful for load
   79 // balancing purposes to detect and remove proxies to failing services.
   80 type HealthCheckConf struct {
   81     // HealthCheckType specifies what protocol to use for health checking.
   82     // Valid values include "tcp", "http", and "". If this value is "", health
   83     // checking will not be performed. By default, this value is "".
   84     //
   85     // If the type is "tcp", a connection will be attempted to the target
   86     // server. If a connection cannot be established, the health check fails.
   87     //
   88     // If the type is "http", a GET request will be made to the endpoint
   89     // specified by HealthCheckURL. If the response is not a 200, the health
   90     // check fails.
   91     HealthCheckType string `ini:"health_check_type" json:"health_check_type"` // tcp | http
   92     // HealthCheckTimeoutS specifies the number of seconds to wait for a health
   93     // check attempt to connect. If the timeout is reached, this counts as a
   94     // health check failure. By default, this value is 3.
   95     HealthCheckTimeoutS int `ini:"health_check_timeout_s" json:"health_check_timeout_s"`
   96     // HealthCheckMaxFailed specifies the number of allowed failures before the
   97     // is stopped. By default, this value is 1.
   98     HealthCheckMaxFailed int `ini:"health_check_max_failed" json:"health_check_max_failed"`
   99     // HealthCheckIntervalS specifies the time in seconds between health
  100     // checks. By default, this value is 10.
  101     HealthCheckIntervalS int `ini:"health_check_interval_s" json:"health_check_interval_s"`
  102     // HealthCheckURL specifies the address to send health checks to if the
  103     // health check type is "http".
  104     HealthCheckURL string `ini:"health_check_url" json:"health_check_url"`
  105     // HealthCheckAddr specifies the address to connect to if the health check
  106     // type is "tcp".
  107     HealthCheckAddr string `ini:"-"`
  108 }
  109 
  110 // BaseProxyConf provides configuration info that is common to all types.
  111 type BaseProxyConf struct {
  112     // ProxyName is the name of this
  113     ProxyName string `ini:"name" json:"name"`
  114     // ProxyType specifies the type of this  Valid values include "tcp",
  115     // "udp", "http", "https", "stcp", and "xtcp". By default, this value is
  116     // "tcp".
  117     ProxyType string `ini:"type" json:"type"`
  118 
  119     // UseEncryption controls whether or not communication with the server will
  120     // be encrypted. Encryption is done using the tokens supplied in the server
  121     // and client configuration. By default, this value is false.
  122     UseEncryption bool `ini:"use_encryption" json:"use_encryption"`
  123     // UseCompression controls whether or not communication with the server
  124     // will be compressed. By default, this value is false.
  125     UseCompression bool `ini:"use_compression" json:"use_compression"`
  126     // Group specifies which group the is a part of. The server will use
  127     // this information to load balance proxies in the same group. If the value
  128     // is "", this will not be in a group. By default, this value is "".
  129     Group string `ini:"group" json:"group"`
  130     // GroupKey specifies a group key, which should be the same among proxies
  131     // of the same group. By default, this value is "".
  132     GroupKey string `ini:"group_key" json:"group_key"`
  133 
  134     // ProxyProtocolVersion specifies which protocol version to use. Valid
  135     // values include "v1", "v2", and "". If the value is "", a protocol
  136     // version will be automatically selected. By default, this value is "".
  137     ProxyProtocolVersion string `ini:"proxy_protocol_version" json:"proxy_protocol_version"`
  138 
  139     // BandwidthLimit limit the bandwidth
  140     // 0 means no limit
  141     BandwidthLimit BandwidthQuantity `ini:"bandwidth_limit" json:"bandwidth_limit"`
  142 
  143     // meta info for each proxy
  144     Metas map[string]string `ini:"-" json:"metas"`
  145 
  146     // TODO: LocalSvrConf => LocalAppConf
  147     LocalSvrConf    `ini:",extends"`
  148     HealthCheckConf `ini:",extends"`
  149 }
  150 
  151 type DomainConf struct {
  152     CustomDomains []string `ini:"custom_domains" json:"custom_domains"`
  153     SubDomain     string   `ini:"subdomain" json:"subdomain"`
  154 }
  155 
  156 // HTTP
  157 type HTTPProxyConf struct {
  158     BaseProxyConf `ini:",extends"`
  159     DomainConf    `ini:",extends"`
  160 
  161     Locations         []string          `ini:"locations" json:"locations"`
  162     HTTPUser          string            `ini:"http_user" json:"http_user"`
  163     HTTPPwd           string            `ini:"http_pwd" json:"http_pwd"`
  164     HostHeaderRewrite string            `ini:"host_header_rewrite" json:"host_header_rewrite"`
  165     Headers           map[string]string `ini:"-" json:"headers"`
  166 }
  167 
  168 // HTTPS
  169 type HTTPSProxyConf struct {
  170     BaseProxyConf `ini:",extends"`
  171     DomainConf    `ini:",extends"`
  172 }
  173 
  174 // TCP
  175 type TCPProxyConf struct {
  176     BaseProxyConf `ini:",extends"`
  177     RemotePort    int `ini:"remote_port" json:"remote_port"`
  178 }
  179 
  180 // TCPMux
  181 type TCPMuxProxyConf struct {
  182     BaseProxyConf `ini:",extends"`
  183     DomainConf    `ini:",extends"`
  184 
  185     Multiplexer string `ini:"multiplexer"`
  186 }
  187 
  188 // STCP
  189 type STCPProxyConf struct {
  190     BaseProxyConf `ini:",extends"`
  191 
  192     Role string `ini:"role" json:"role"`
  193     Sk   string `ini:"sk" json:"sk"`
  194 }
  195 
  196 // XTCP
  197 type XTCPProxyConf struct {
  198     BaseProxyConf `ini:",extends"`
  199 
  200     Role string `ini:"role" json:"role"`
  201     Sk   string `ini:"sk" json:"sk"`
  202 }
  203 
  204 // UDP
  205 type UDPProxyConf struct {
  206     BaseProxyConf `ini:",extends"`
  207 
  208     RemotePort int `ini:"remote_port" json:"remote_port"`
  209 }
  210 
  211 // SUDP
  212 type SUDPProxyConf struct {
  213     BaseProxyConf `ini:",extends"`
  214 
  215     Role string `ini:"role" json:"role"`
  216     Sk   string `ini:"sk" json:"sk"`
  217 }
  218 
  219 // Proxy Conf Loader
  220 // DefaultProxyConf creates a empty ProxyConf object by proxyType.
  221 // If proxyType doesn't exist, return nil.
  222 func DefaultProxyConf(proxyType string) ProxyConf {
  223     var conf ProxyConf
  224     switch proxyType {
  225     case consts.TCPProxy:
  226         conf = &TCPProxyConf{
  227             BaseProxyConf: defaultBaseProxyConf(proxyType),
  228         }
  229     case consts.TCPMuxProxy:
  230         conf = &TCPMuxProxyConf{
  231             BaseProxyConf: defaultBaseProxyConf(proxyType),
  232         }
  233     case consts.UDPProxy:
  234         conf = &UDPProxyConf{
  235             BaseProxyConf: defaultBaseProxyConf(proxyType),
  236         }
  237     case consts.HTTPProxy:
  238         conf = &HTTPProxyConf{
  239             BaseProxyConf: defaultBaseProxyConf(proxyType),
  240         }
  241     case consts.HTTPSProxy:
  242         conf = &HTTPSProxyConf{
  243             BaseProxyConf: defaultBaseProxyConf(proxyType),
  244         }
  245     case consts.STCPProxy:
  246         conf = &STCPProxyConf{
  247             BaseProxyConf: defaultBaseProxyConf(proxyType),
  248             Role:          "server",
  249         }
  250     case consts.XTCPProxy:
  251         conf = &XTCPProxyConf{
  252             BaseProxyConf: defaultBaseProxyConf(proxyType),
  253             Role:          "server",
  254         }
  255     case consts.SUDPProxy:
  256         conf = &SUDPProxyConf{
  257             BaseProxyConf: defaultBaseProxyConf(proxyType),
  258             Role:          "server",
  259         }
  260     default:
  261         return nil
  262     }
  263 
  264     return conf
  265 }
  266 
  267 // Proxy loaded from ini
  268 func NewProxyConfFromIni(prefix, name string, section *ini.Section) (ProxyConf, error) {
  269     // section.Key: if key not exists, section will set it with default value.
  270     proxyType := section.Key("type").String()
  271     if proxyType == "" {
  272         proxyType = consts.TCPProxy
  273     }
  274 
  275     conf := DefaultProxyConf(proxyType)
  276     if conf == nil {
  277         return nil, fmt.Errorf("proxy [%s] type [%s] error", name, proxyType)
  278     }
  279 
  280     if err := conf.UnmarshalFromIni(prefix, name, section); err != nil {
  281         return nil, err
  282     }
  283 
  284     if err := conf.CheckForCli(); err != nil {
  285         return nil, err
  286     }
  287 
  288     return conf, nil
  289 }
  290 
  291 // Proxy loaded from msg
  292 func NewProxyConfFromMsg(pMsg *msg.NewProxy, serverCfg ServerCommonConf) (ProxyConf, error) {
  293     if pMsg.ProxyType == "" {
  294         pMsg.ProxyType = consts.TCPProxy
  295     }
  296 
  297     conf := DefaultProxyConf(pMsg.ProxyType)
  298     if conf == nil {
  299         return nil, fmt.Errorf("proxy [%s] type [%s] error", pMsg.ProxyName, pMsg.ProxyType)
  300     }
  301 
  302     conf.UnmarshalFromMsg(pMsg)
  303 
  304     err := conf.CheckForSvr(serverCfg)
  305     if err != nil {
  306         return nil, err
  307     }
  308 
  309     return conf, nil
  310 }
  311 
  312 // Base
  313 func defaultBaseProxyConf(proxyType string) BaseProxyConf {
  314     return BaseProxyConf{
  315         ProxyType: proxyType,
  316         LocalSvrConf: LocalSvrConf{
  317             LocalIP: "127.0.0.1",
  318         },
  319     }
  320 }
  321 
  322 func (cfg *BaseProxyConf) GetBaseInfo() *BaseProxyConf {
  323     return cfg
  324 }
  325 
  326 func (cfg *BaseProxyConf) compare(cmp *BaseProxyConf) bool {
  327     if cfg.ProxyName != cmp.ProxyName ||
  328         cfg.ProxyType != cmp.ProxyType ||
  329         cfg.UseEncryption != cmp.UseEncryption ||
  330         cfg.UseCompression != cmp.UseCompression ||
  331         cfg.Group != cmp.Group ||
  332         cfg.GroupKey != cmp.GroupKey ||
  333         cfg.ProxyProtocolVersion != cmp.ProxyProtocolVersion ||
  334         !cfg.BandwidthLimit.Equal(&cmp.BandwidthLimit) ||
  335         !reflect.DeepEqual(cfg.Metas, cmp.Metas) {
  336         return false
  337     }
  338 
  339     if !reflect.DeepEqual(cfg.LocalSvrConf, cmp.LocalSvrConf) {
  340         return false
  341     }
  342     if !reflect.DeepEqual(cfg.HealthCheckConf, cmp.HealthCheckConf) {
  343         return false
  344     }
  345 
  346     return true
  347 }
  348 
  349 // BaseProxyConf apply custom logic changes.
  350 func (cfg *BaseProxyConf) decorate(prefix string, name string, section *ini.Section) error {
  351     // proxy_name
  352     cfg.ProxyName = prefix + name
  353 
  354     // metas_xxx
  355     cfg.Metas = GetMapWithoutPrefix(section.KeysHash(), "meta_")
  356 
  357     // bandwidth_limit
  358     if bandwidth, err := section.GetKey("bandwidth_limit"); err == nil {
  359         cfg.BandwidthLimit, err = NewBandwidthQuantity(bandwidth.String())
  360         if err != nil {
  361             return err
  362         }
  363     }
  364 
  365     // plugin_xxx
  366     cfg.LocalSvrConf.PluginParams = GetMapByPrefix(section.KeysHash(), "plugin_")
  367 
  368     // custom logic code
  369     if cfg.HealthCheckType == "tcp" && cfg.Plugin == "" {
  370         cfg.HealthCheckAddr = cfg.LocalIP + fmt.Sprintf(":%d", cfg.LocalPort)
  371     }
  372 
  373     if cfg.HealthCheckType == "http" && cfg.Plugin == "" && cfg.HealthCheckURL != "" {
  374         s := fmt.Sprintf("http://%s:%d", cfg.LocalIP, cfg.LocalPort)
  375         if !strings.HasPrefix(cfg.HealthCheckURL, "/") {
  376             s += "/"
  377         }
  378         cfg.HealthCheckURL = s + cfg.HealthCheckURL
  379     }
  380 
  381     return nil
  382 }
  383 
  384 func (cfg *BaseProxyConf) marshalToMsg(pMsg *msg.NewProxy) {
  385     pMsg.ProxyName = cfg.ProxyName
  386     pMsg.ProxyType = cfg.ProxyType
  387     pMsg.UseEncryption = cfg.UseEncryption
  388     pMsg.UseCompression = cfg.UseCompression
  389     pMsg.Group = cfg.Group
  390     pMsg.GroupKey = cfg.GroupKey
  391     pMsg.Metas = cfg.Metas
  392 }
  393 
  394 func (cfg *BaseProxyConf) unmarshalFromMsg(pMsg *msg.NewProxy) {
  395     cfg.ProxyName = pMsg.ProxyName
  396     cfg.ProxyType = pMsg.ProxyType
  397     cfg.UseEncryption = pMsg.UseEncryption
  398     cfg.UseCompression = pMsg.UseCompression
  399     cfg.Group = pMsg.Group
  400     cfg.GroupKey = pMsg.GroupKey
  401     cfg.Metas = pMsg.Metas
  402 }
  403 
  404 func (cfg *BaseProxyConf) checkForCli() (err error) {
  405     if cfg.ProxyProtocolVersion != "" {
  406         if cfg.ProxyProtocolVersion != "v1" && cfg.ProxyProtocolVersion != "v2" {
  407             return fmt.Errorf("no support proxy protocol version: %s", cfg.ProxyProtocolVersion)
  408         }
  409     }
  410 
  411     if err = cfg.LocalSvrConf.checkForCli(); err != nil {
  412         return
  413     }
  414     if err = cfg.HealthCheckConf.checkForCli(); err != nil {
  415         return
  416     }
  417     return nil
  418 }
  419 
  420 func (cfg *BaseProxyConf) checkForSvr(conf ServerCommonConf) error {
  421     return nil
  422 }
  423 
  424 // DomainConf
  425 func (cfg *DomainConf) check() (err error) {
  426     if len(cfg.CustomDomains) == 0 && cfg.SubDomain == "" {
  427         err = fmt.Errorf("custom_domains and subdomain should set at least one of them")
  428         return
  429     }
  430     return
  431 }
  432 
  433 func (cfg *DomainConf) checkForCli() (err error) {
  434     if err = cfg.check(); err != nil {
  435         return
  436     }
  437     return
  438 }
  439 
  440 func (cfg *DomainConf) checkForSvr(serverCfg ServerCommonConf) (err error) {
  441     if err = cfg.check(); err != nil {
  442         return
  443     }
  444 
  445     for _, domain := range cfg.CustomDomains {
  446         if serverCfg.SubDomainHost != "" && len(strings.Split(serverCfg.SubDomainHost, ".")) < len(strings.Split(domain, ".")) {
  447             if strings.Contains(domain, serverCfg.SubDomainHost) {
  448                 return fmt.Errorf("custom domain [%s] should not belong to subdomain_host [%s]", domain, serverCfg.SubDomainHost)
  449             }
  450         }
  451     }
  452 
  453     if cfg.SubDomain != "" {
  454         if serverCfg.SubDomainHost == "" {
  455             return fmt.Errorf("subdomain is not supported because this feature is not enabled in remote frps")
  456         }
  457         if strings.Contains(cfg.SubDomain, ".") || strings.Contains(cfg.SubDomain, "*") {
  458             return fmt.Errorf("'.' and '*' is not supported in subdomain")
  459         }
  460     }
  461     return nil
  462 }
  463 
  464 // LocalSvrConf
  465 func (cfg *LocalSvrConf) checkForCli() (err error) {
  466     if cfg.Plugin == "" {
  467         if cfg.LocalIP == "" {
  468             err = fmt.Errorf("local ip or plugin is required")
  469             return
  470         }
  471         if cfg.LocalPort <= 0 {
  472             err = fmt.Errorf("error local_port")
  473             return
  474         }
  475     }
  476     return
  477 }
  478 
  479 // HealthCheckConf
  480 func (cfg *HealthCheckConf) checkForCli() error {
  481     if cfg.HealthCheckType != "" && cfg.HealthCheckType != "tcp" && cfg.HealthCheckType != "http" {
  482         return fmt.Errorf("unsupport health check type")
  483     }
  484     if cfg.HealthCheckType != "" {
  485         if cfg.HealthCheckType == "http" && cfg.HealthCheckURL == "" {
  486             return fmt.Errorf("health_check_url is required for health check type 'http'")
  487         }
  488     }
  489     return nil
  490 }
  491 
  492 func preUnmarshalFromIni(cfg ProxyConf, prefix string, name string, section *ini.Section) error {
  493     err := section.MapTo(cfg)
  494     if err != nil {
  495         return err
  496     }
  497 
  498     err = cfg.GetBaseInfo().decorate(prefix, name, section)
  499     if err != nil {
  500         return err
  501     }
  502 
  503     return nil
  504 }
  505 
  506 // TCP
  507 func (cfg *TCPProxyConf) Compare(cmp ProxyConf) bool {
  508     cmpConf, ok := cmp.(*TCPProxyConf)
  509     if !ok {
  510         return false
  511     }
  512 
  513     if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) {
  514         return false
  515     }
  516 
  517     // Add custom logic equal if exists.
  518     if cfg.RemotePort != cmpConf.RemotePort {
  519         return false
  520     }
  521 
  522     return true
  523 }
  524 
  525 func (cfg *TCPProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
  526     cfg.BaseProxyConf.unmarshalFromMsg(pMsg)
  527 
  528     // Add custom logic unmarshal if exists
  529     cfg.RemotePort = pMsg.RemotePort
  530 }
  531 
  532 func (cfg *TCPProxyConf) UnmarshalFromIni(prefix string, name string, section *ini.Section) error {
  533     err := preUnmarshalFromIni(cfg, prefix, name, section)
  534     if err != nil {
  535         return err
  536     }
  537 
  538     // Add custom logic unmarshal if exists
  539 
  540     return nil
  541 }
  542 
  543 func (cfg *TCPProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
  544     cfg.BaseProxyConf.marshalToMsg(pMsg)
  545 
  546     // Add custom logic marshal if exists
  547     pMsg.RemotePort = cfg.RemotePort
  548 }
  549 
  550 func (cfg *TCPProxyConf) CheckForCli() (err error) {
  551     if err = cfg.BaseProxyConf.checkForCli(); err != nil {
  552         return
  553     }
  554 
  555     // Add custom logic check if exists
  556 
  557     return
  558 }
  559 
  560 func (cfg *TCPProxyConf) CheckForSvr(serverCfg ServerCommonConf) error {
  561     return nil
  562 }
  563 
  564 // TCPMux
  565 func (cfg *TCPMuxProxyConf) Compare(cmp ProxyConf) bool {
  566     cmpConf, ok := cmp.(*TCPMuxProxyConf)
  567     if !ok {
  568         return false
  569     }
  570 
  571     if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) {
  572         return false
  573     }
  574 
  575     // Add custom logic equal if exists.
  576     if !reflect.DeepEqual(cfg.DomainConf, cmpConf.DomainConf) {
  577         return false
  578     }
  579 
  580     if cfg.Multiplexer != cmpConf.Multiplexer {
  581         return false
  582     }
  583 
  584     return true
  585 }
  586 
  587 func (cfg *TCPMuxProxyConf) UnmarshalFromIni(prefix string, name string, section *ini.Section) error {
  588     err := preUnmarshalFromIni(cfg, prefix, name, section)
  589     if err != nil {
  590         return err
  591     }
  592 
  593     // Add custom logic unmarshal if exists
  594 
  595     return nil
  596 }
  597 
  598 func (cfg *TCPMuxProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
  599     cfg.BaseProxyConf.unmarshalFromMsg(pMsg)
  600 
  601     // Add custom logic unmarshal if exists
  602     cfg.CustomDomains = pMsg.CustomDomains
  603     cfg.SubDomain = pMsg.SubDomain
  604     cfg.Multiplexer = pMsg.Multiplexer
  605 }
  606 
  607 func (cfg *TCPMuxProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
  608     cfg.BaseProxyConf.marshalToMsg(pMsg)
  609 
  610     // Add custom logic marshal if exists
  611     pMsg.CustomDomains = cfg.CustomDomains
  612     pMsg.SubDomain = cfg.SubDomain
  613     pMsg.Multiplexer = cfg.Multiplexer
  614 }
  615 
  616 func (cfg *TCPMuxProxyConf) CheckForCli() (err error) {
  617     if err = cfg.BaseProxyConf.checkForCli(); err != nil {
  618         return
  619     }
  620 
  621     // Add custom logic check if exists
  622     if err = cfg.DomainConf.checkForCli(); err != nil {
  623         return
  624     }
  625 
  626     if cfg.Multiplexer != consts.HTTPConnectTCPMultiplexer {
  627         return fmt.Errorf("parse conf error: incorrect multiplexer [%s]", cfg.Multiplexer)
  628     }
  629 
  630     return
  631 }
  632 
  633 func (cfg *TCPMuxProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
  634     if cfg.Multiplexer != consts.HTTPConnectTCPMultiplexer {
  635         return fmt.Errorf("proxy [%s] incorrect multiplexer [%s]", cfg.ProxyName, cfg.Multiplexer)
  636     }
  637 
  638     if cfg.Multiplexer == consts.HTTPConnectTCPMultiplexer && serverCfg.TCPMuxHTTPConnectPort == 0 {
  639         return fmt.Errorf("proxy [%s] type [tcpmux] with multiplexer [httpconnect] requires tcpmux_httpconnect_port configuration", cfg.ProxyName)
  640     }
  641 
  642     if err = cfg.DomainConf.checkForSvr(serverCfg); err != nil {
  643         err = fmt.Errorf("proxy [%s] domain conf check error: %v", cfg.ProxyName, err)
  644         return
  645     }
  646 
  647     return
  648 }
  649 
  650 // UDP
  651 func (cfg *UDPProxyConf) Compare(cmp ProxyConf) bool {
  652     cmpConf, ok := cmp.(*UDPProxyConf)
  653     if !ok {
  654         return false
  655     }
  656 
  657     if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) {
  658         return false
  659     }
  660 
  661     // Add custom logic equal if exists.
  662     if cfg.RemotePort != cmpConf.RemotePort {
  663         return false
  664     }
  665 
  666     return true
  667 }
  668 
  669 func (cfg *UDPProxyConf) UnmarshalFromIni(prefix string, name string, section *ini.Section) error {
  670     err := preUnmarshalFromIni(cfg, prefix, name, section)
  671     if err != nil {
  672         return err
  673     }
  674 
  675     // Add custom logic unmarshal if exists
  676 
  677     return nil
  678 }
  679 
  680 func (cfg *UDPProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
  681     cfg.BaseProxyConf.unmarshalFromMsg(pMsg)
  682 
  683     // Add custom logic unmarshal if exists
  684     cfg.RemotePort = pMsg.RemotePort
  685 }
  686 
  687 func (cfg *UDPProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
  688     cfg.BaseProxyConf.marshalToMsg(pMsg)
  689 
  690     // Add custom logic marshal if exists
  691     pMsg.RemotePort = cfg.RemotePort
  692 }
  693 
  694 func (cfg *UDPProxyConf) CheckForCli() (err error) {
  695     if err = cfg.BaseProxyConf.checkForCli(); err != nil {
  696         return
  697     }
  698 
  699     // Add custom logic check if exists
  700 
  701     return
  702 }
  703 
  704 func (cfg *UDPProxyConf) CheckForSvr(serverCfg ServerCommonConf) error {
  705     return nil
  706 }
  707 
  708 // HTTP
  709 func (cfg *HTTPProxyConf) Compare(cmp ProxyConf) bool {
  710     cmpConf, ok := cmp.(*HTTPProxyConf)
  711     if !ok {
  712         return false
  713     }
  714 
  715     if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) {
  716         return false
  717     }
  718 
  719     // Add custom logic equal if exists.
  720     if !reflect.DeepEqual(cfg.DomainConf, cmpConf.DomainConf) {
  721         return false
  722     }
  723 
  724     if !reflect.DeepEqual(cfg.Locations, cmpConf.Locations) ||
  725         cfg.HTTPUser != cmpConf.HTTPUser ||
  726         cfg.HTTPPwd != cmpConf.HTTPPwd ||
  727         cfg.HostHeaderRewrite != cmpConf.HostHeaderRewrite ||
  728         !reflect.DeepEqual(cfg.Headers, cmpConf.Headers) {
  729         return false
  730     }
  731 
  732     return true
  733 }
  734 
  735 func (cfg *HTTPProxyConf) UnmarshalFromIni(prefix string, name string, section *ini.Section) error {
  736     err := preUnmarshalFromIni(cfg, prefix, name, section)
  737     if err != nil {
  738         return err
  739     }
  740 
  741     // Add custom logic unmarshal if exists
  742     cfg.Headers = GetMapWithoutPrefix(section.KeysHash(), "header_")
  743 
  744     return nil
  745 }
  746 
  747 func (cfg *HTTPProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
  748     cfg.BaseProxyConf.unmarshalFromMsg(pMsg)
  749 
  750     // Add custom logic unmarshal if exists
  751     cfg.CustomDomains = pMsg.CustomDomains
  752     cfg.SubDomain = pMsg.SubDomain
  753     cfg.Locations = pMsg.Locations
  754     cfg.HostHeaderRewrite = pMsg.HostHeaderRewrite
  755     cfg.HTTPUser = pMsg.HTTPUser
  756     cfg.HTTPPwd = pMsg.HTTPPwd
  757     cfg.Headers = pMsg.Headers
  758 }
  759 
  760 func (cfg *HTTPProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
  761     cfg.BaseProxyConf.marshalToMsg(pMsg)
  762 
  763     // Add custom logic marshal if exists
  764     pMsg.CustomDomains = cfg.CustomDomains
  765     pMsg.SubDomain = cfg.SubDomain
  766     pMsg.Locations = cfg.Locations
  767     pMsg.HostHeaderRewrite = cfg.HostHeaderRewrite
  768     pMsg.HTTPUser = cfg.HTTPUser
  769     pMsg.HTTPPwd = cfg.HTTPPwd
  770     pMsg.Headers = cfg.Headers
  771 }
  772 
  773 func (cfg *HTTPProxyConf) CheckForCli() (err error) {
  774     if err = cfg.BaseProxyConf.checkForCli(); err != nil {
  775         return
  776     }
  777 
  778     // Add custom logic check if exists
  779     if err = cfg.DomainConf.checkForCli(); err != nil {
  780         return
  781     }
  782 
  783     return
  784 }
  785 
  786 func (cfg *HTTPProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
  787     if serverCfg.VhostHTTPPort == 0 {
  788         return fmt.Errorf("type [http] not support when vhost_http_port is not set")
  789     }
  790 
  791     if err = cfg.DomainConf.checkForSvr(serverCfg); err != nil {
  792         err = fmt.Errorf("proxy [%s] domain conf check error: %v", cfg.ProxyName, err)
  793         return
  794     }
  795 
  796     return
  797 }
  798 
  799 // HTTPS
  800 func (cfg *HTTPSProxyConf) Compare(cmp ProxyConf) bool {
  801     cmpConf, ok := cmp.(*HTTPSProxyConf)
  802     if !ok {
  803         return false
  804     }
  805 
  806     if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) {
  807         return false
  808     }
  809 
  810     // Add custom logic equal if exists.
  811     if !reflect.DeepEqual(cfg.DomainConf, cmpConf.DomainConf) {
  812         return false
  813     }
  814 
  815     return true
  816 }
  817 
  818 func (cfg *HTTPSProxyConf) UnmarshalFromIni(prefix string, name string, section *ini.Section) error {
  819     err := preUnmarshalFromIni(cfg, prefix, name, section)
  820     if err != nil {
  821         return err
  822     }
  823 
  824     // Add custom logic unmarshal if exists
  825 
  826     return nil
  827 }
  828 
  829 func (cfg *HTTPSProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
  830     cfg.BaseProxyConf.unmarshalFromMsg(pMsg)
  831 
  832     // Add custom logic unmarshal if exists
  833     cfg.CustomDomains = pMsg.CustomDomains
  834     cfg.SubDomain = pMsg.SubDomain
  835 }
  836 
  837 func (cfg *HTTPSProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
  838     cfg.BaseProxyConf.marshalToMsg(pMsg)
  839 
  840     // Add custom logic marshal if exists
  841     pMsg.CustomDomains = cfg.CustomDomains
  842     pMsg.SubDomain = cfg.SubDomain
  843 }
  844 
  845 func (cfg *HTTPSProxyConf) CheckForCli() (err error) {
  846     if err = cfg.BaseProxyConf.checkForCli(); err != nil {
  847         return
  848     }
  849 
  850     // Add custom logic check if exists
  851     if err = cfg.DomainConf.checkForCli(); err != nil {
  852         return
  853     }
  854 
  855     return
  856 }
  857 
  858 func (cfg *HTTPSProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
  859     if serverCfg.VhostHTTPSPort == 0 {
  860         return fmt.Errorf("type [https] not support when vhost_https_port is not set")
  861     }
  862 
  863     if err = cfg.DomainConf.checkForSvr(serverCfg); err != nil {
  864         err = fmt.Errorf("proxy [%s] domain conf check error: %v", cfg.ProxyName, err)
  865         return
  866     }
  867 
  868     return
  869 }
  870 
  871 // SUDP
  872 func (cfg *SUDPProxyConf) Compare(cmp ProxyConf) bool {
  873     cmpConf, ok := cmp.(*SUDPProxyConf)
  874     if !ok {
  875         return false
  876     }
  877 
  878     if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) {
  879         return false
  880     }
  881 
  882     // Add custom logic equal if exists.
  883     if cfg.Role != cmpConf.Role ||
  884         cfg.Sk != cmpConf.Sk {
  885         return false
  886     }
  887 
  888     return true
  889 }
  890 
  891 func (cfg *SUDPProxyConf) UnmarshalFromIni(prefix string, name string, section *ini.Section) error {
  892     err := preUnmarshalFromIni(cfg, prefix, name, section)
  893     if err != nil {
  894         return err
  895     }
  896 
  897     // Add custom logic unmarshal if exists
  898 
  899     return nil
  900 }
  901 
  902 // Only for role server.
  903 func (cfg *SUDPProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
  904     cfg.BaseProxyConf.unmarshalFromMsg(pMsg)
  905 
  906     // Add custom logic unmarshal if exists
  907     cfg.Sk = pMsg.Sk
  908 }
  909 
  910 func (cfg *SUDPProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
  911     cfg.BaseProxyConf.marshalToMsg(pMsg)
  912 
  913     // Add custom logic marshal if exists
  914     pMsg.Sk = cfg.Sk
  915 }
  916 
  917 func (cfg *SUDPProxyConf) CheckForCli() (err error) {
  918     if err := cfg.BaseProxyConf.checkForCli(); err != nil {
  919         return err
  920     }
  921 
  922     // Add custom logic check if exists
  923     if cfg.Role != "server" {
  924         return fmt.Errorf("role should be 'server'")
  925     }
  926 
  927     return nil
  928 }
  929 
  930 func (cfg *SUDPProxyConf) CheckForSvr(serverCfg ServerCommonConf) error {
  931     return nil
  932 }
  933 
  934 // STCP
  935 func (cfg *STCPProxyConf) Compare(cmp ProxyConf) bool {
  936     cmpConf, ok := cmp.(*STCPProxyConf)
  937     if !ok {
  938         return false
  939     }
  940 
  941     if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) {
  942         return false
  943     }
  944 
  945     // Add custom logic equal if exists.
  946     if cfg.Role != cmpConf.Role ||
  947         cfg.Sk != cmpConf.Sk {
  948         return false
  949     }
  950 
  951     return true
  952 }
  953 
  954 func (cfg *STCPProxyConf) UnmarshalFromIni(prefix string, name string, section *ini.Section) error {
  955     err := preUnmarshalFromIni(cfg, prefix, name, section)
  956     if err != nil {
  957         return err
  958     }
  959 
  960     // Add custom logic unmarshal if exists
  961     if cfg.Role == "" {
  962         cfg.Role = "server"
  963     }
  964 
  965     return nil
  966 }
  967 
  968 // Only for role server.
  969 func (cfg *STCPProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
  970     cfg.BaseProxyConf.unmarshalFromMsg(pMsg)
  971 
  972     // Add custom logic unmarshal if exists
  973     cfg.Sk = pMsg.Sk
  974 }
  975 
  976 func (cfg *STCPProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
  977     cfg.BaseProxyConf.marshalToMsg(pMsg)
  978 
  979     // Add custom logic marshal if exists
  980     pMsg.Sk = cfg.Sk
  981 }
  982 
  983 func (cfg *STCPProxyConf) CheckForCli() (err error) {
  984     if err = cfg.BaseProxyConf.checkForCli(); err != nil {
  985         return
  986     }
  987 
  988     // Add custom logic check if exists
  989     if cfg.Role != "server" {
  990         return fmt.Errorf("role should be 'server'")
  991     }
  992 
  993     return
  994 }
  995 
  996 func (cfg *STCPProxyConf) CheckForSvr(serverCfg ServerCommonConf) error {
  997     return nil
  998 }
  999 
 1000 // XTCP
 1001 func (cfg *XTCPProxyConf) Compare(cmp ProxyConf) bool {
 1002     cmpConf, ok := cmp.(*XTCPProxyConf)
 1003     if !ok {
 1004         return false
 1005     }
 1006 
 1007     if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) {
 1008         return false
 1009     }
 1010 
 1011     // Add custom logic equal if exists.
 1012     if cfg.Role != cmpConf.Role ||
 1013         cfg.Sk != cmpConf.Sk {
 1014         return false
 1015     }
 1016 
 1017     return true
 1018 }
 1019 
 1020 func (cfg *XTCPProxyConf) UnmarshalFromIni(prefix string, name string, section *ini.Section) error {
 1021     err := preUnmarshalFromIni(cfg, prefix, name, section)
 1022     if err != nil {
 1023         return err
 1024     }
 1025 
 1026     // Add custom logic unmarshal if exists
 1027     if cfg.Role == "" {
 1028         cfg.Role = "server"
 1029     }
 1030 
 1031     return nil
 1032 }
 1033 
 1034 // Only for role server.
 1035 func (cfg *XTCPProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
 1036     cfg.BaseProxyConf.unmarshalFromMsg(pMsg)
 1037 
 1038     // Add custom logic unmarshal if exists
 1039     cfg.Sk = pMsg.Sk
 1040 }
 1041 
 1042 func (cfg *XTCPProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
 1043     cfg.BaseProxyConf.marshalToMsg(pMsg)
 1044 
 1045     // Add custom logic marshal if exists
 1046     pMsg.Sk = cfg.Sk
 1047 }
 1048 
 1049 func (cfg *XTCPProxyConf) CheckForCli() (err error) {
 1050     if err = cfg.BaseProxyConf.checkForCli(); err != nil {
 1051         return
 1052     }
 1053 
 1054     // Add custom logic check if exists
 1055     if cfg.Role != "server" {
 1056         return fmt.Errorf("role should be 'server'")
 1057     }
 1058 
 1059     return
 1060 }
 1061 
 1062 func (cfg *XTCPProxyConf) CheckForSvr(serverCfg ServerCommonConf) error {
 1063     return nil
 1064 }