diff --git a/config/parsing/chain/parse.go b/config/parsing/chain/parse.go index b8011888..7a9b3e91 100644 --- a/config/parsing/chain/parse.go +++ b/config/parsing/chain/parse.go @@ -33,6 +33,10 @@ func ParseChain(cfg *config.ChainConfig, log logger.Logger) (chain.Chainer, erro ) for _, ch := range cfg.Hops { + if ch == nil { + continue + } + var hop hop.Hop var err error diff --git a/config/parsing/hop/parse.go b/config/parsing/hop/parse.go index d4ad1b2f..e7ebf2d8 100644 --- a/config/parsing/hop/parse.go +++ b/config/parsing/hop/parse.go @@ -78,12 +78,13 @@ func ParseHop(cfg *config.HopConfig, log logger.Logger) (hop.Hop, error) { continue } - m := v.Metadata - if m == nil { - m = map[string]any{} - v.Metadata = m + // Build a merged metadata map for inheritance without mutating + // the original node config. + merged := make(map[string]any) + for k, val := range v.Metadata { + merged[k] = val } - md := metadata.NewMetadata(m) + md := metadata.NewMetadata(merged) if v.Resolver == "" { v.Resolver = cfg.Resolver @@ -93,37 +94,30 @@ func ParseHop(cfg *config.HopConfig, log logger.Logger) (hop.Hop, error) { } if !md.IsExists(parsing.MDKeyInterface) { - // inherit from hop if ifce != "" { - m[parsing.MDKeyInterface] = ifce + merged[parsing.MDKeyInterface] = ifce } - // node level if v.Interface != "" { - m[parsing.MDKeyInterface] = v.Interface + merged[parsing.MDKeyInterface] = v.Interface } } if !md.IsExists(parsing.MDKeySoMark) { - // inherit from hop if soMark != 0 { - m[parsing.MDKeySoMark] = soMark + merged[parsing.MDKeySoMark] = soMark } - // node level if v.SockOpts != nil && v.SockOpts.Mark != 0 { - m[parsing.MDKeySoMark] = v.SockOpts.Mark + merged[parsing.MDKeySoMark] = v.SockOpts.Mark } } if !md.IsExists(parsing.MDKeyProxyProtocol) && ppv > 0 { - // inherit from hop - m[parsing.MDKeyProxyProtocol] = ppv + merged[parsing.MDKeyProxyProtocol] = ppv } if !md.IsExists(parsing.MDKeyNetns) { - // inherit from hop if netns != "" { - m[parsing.MDKeyNetns] = netns + merged[parsing.MDKeyNetns] = netns } - // node level if v.Netns != "" { - m[parsing.MDKeyNetns] = v.Netns + merged[parsing.MDKeyNetns] = v.Netns } } @@ -141,7 +135,11 @@ func ParseHop(cfg *config.HopConfig, log logger.Logger) (hop.Hop, error) { v.Dialer.Type = "tcp" } + // Temporarily swap merged metadata so ParseNode sees inherited values. + origMeta := v.Metadata + v.Metadata = merged node, err := node_parser.ParseNode(cfg.Name, v, log) + v.Metadata = origMeta if err != nil { return nil, err } diff --git a/config/parsing/node/parse.go b/config/parsing/node/parse.go index efd5ef34..d1d9fc32 100644 --- a/config/parsing/node/parse.go +++ b/config/parsing/node/parse.go @@ -29,29 +29,33 @@ func ParseNode(hop string, cfg *config.NodeConfig, log logger.Logger) (*chain.No return nil, nil } - if cfg.Connector == nil { - cfg.Connector = &config.ConnectorConfig{ - Type: "http", - } + connCfg := cfg.Connector + if connCfg == nil { + connCfg = &config.ConnectorConfig{} + } + if connCfg.Type == "" { + connCfg.Type = "http" } - if cfg.Dialer == nil { - cfg.Dialer = &config.DialerConfig{ - Type: "tcp", - } + dialCfg := cfg.Dialer + if dialCfg == nil { + dialCfg = &config.DialerConfig{} + } + if dialCfg.Type == "" { + dialCfg.Type = "tcp" } nodeLogger := log.WithFields(map[string]any{ "hop": hop, "kind": "node", "node": cfg.Name, - "connector": cfg.Connector.Type, - "dialer": cfg.Dialer.Type, + "connector": connCfg.Type, + "dialer": dialCfg.Type, }) serverName, _, _ := net.SplitHostPort(cfg.Addr) - tlsCfg := cfg.Connector.TLS + tlsCfg := connCfg.TLS if tlsCfg == nil { tlsCfg = &config.TLSConfig{} } @@ -68,25 +72,22 @@ func ParseNode(hop string, cfg *config.NodeConfig, log logger.Logger) (*chain.No "kind": "connector", }) var cr connector.Connector - if rf := registry.ConnectorRegistry().Get(cfg.Connector.Type); rf != nil { + if rf := registry.ConnectorRegistry().Get(connCfg.Type); rf != nil { cr = rf( - connector.AuthOption(auth_parser.Info(cfg.Connector.Auth)), + connector.AuthOption(auth_parser.Info(connCfg.Auth)), connector.TLSConfigOption(tlsConfig), connector.LoggerOption(connectorLogger), ) } else { - return nil, fmt.Errorf("unregistered connector: %s", cfg.Connector.Type) + return nil, fmt.Errorf("unregistered connector: %s", connCfg.Type) } - if cfg.Connector.Metadata == nil { - cfg.Connector.Metadata = make(map[string]any) - } - if err := cr.Init(mdx.NewMetadata(cfg.Connector.Metadata)); err != nil { + if err := cr.Init(mdx.NewMetadata(connCfg.Metadata)); err != nil { connectorLogger.Error("init: ", err) return nil, err } - tlsCfg = cfg.Dialer.TLS + tlsCfg = dialCfg.TLS if tlsCfg == nil { tlsCfg = &config.TLSConfig{} } @@ -106,21 +107,18 @@ func ParseNode(hop string, cfg *config.NodeConfig, log logger.Logger) (*chain.No }) var d dialer.Dialer - if rf := registry.DialerRegistry().Get(cfg.Dialer.Type); rf != nil { + if rf := registry.DialerRegistry().Get(dialCfg.Type); rf != nil { d = rf( - dialer.AuthOption(auth_parser.Info(cfg.Dialer.Auth)), + dialer.AuthOption(auth_parser.Info(dialCfg.Auth)), dialer.TLSConfigOption(tlsConfig), dialer.LoggerOption(dialerLogger), dialer.ProxyProtocolOption(mdutil.GetInt(md, parsing.MDKeyProxyProtocol)), ) } else { - return nil, fmt.Errorf("unregistered dialer: %s", cfg.Dialer.Type) + return nil, fmt.Errorf("unregistered dialer: %s", dialCfg.Type) } - if cfg.Dialer.Metadata == nil { - cfg.Dialer.Metadata = make(map[string]any) - } - if err := d.Init(mdx.NewMetadata(cfg.Dialer.Metadata)); err != nil { + if err := d.Init(mdx.NewMetadata(dialCfg.Metadata)); err != nil { dialerLogger.Error("init: ", err) return nil, err } diff --git a/config/parsing/parser/parser.go b/config/parsing/parser/parser.go index 91b996d5..dcb0e1e9 100644 --- a/config/parsing/parser/parser.go +++ b/config/parsing/parser/parser.go @@ -84,24 +84,28 @@ func (p *parser) Parse() (*config.Config, error) { } if v := os.Getenv("GOST_LOGGER_LEVEL"); v != "" { - cfg.Log = &config.LogConfig{ - Level: v, + if cfg.Log == nil { + cfg.Log = &config.LogConfig{} } + cfg.Log.Level = v } if v := os.Getenv("GOST_API"); v != "" { - cfg.API = &config.APIConfig{ - Addr: v, + if cfg.API == nil { + cfg.API = &config.APIConfig{} } + cfg.API.Addr = v } if v := os.Getenv("GOST_METRICS"); v != "" { - cfg.Metrics = &config.MetricsConfig{ - Addr: v, + if cfg.Metrics == nil { + cfg.Metrics = &config.MetricsConfig{} } + cfg.Metrics.Addr = v } if v := os.Getenv("GOST_PROFILING"); v != "" { - cfg.Profiling = &config.ProfilingConfig{ - Addr: v, + if cfg.Profiling == nil { + cfg.Profiling = &config.ProfilingConfig{} } + cfg.Profiling.Addr = v } if p.args.Debug || p.args.Trace { diff --git a/config/parsing/router/parse.go b/config/parsing/router/parse.go index da0f6983..bf295626 100644 --- a/config/parsing/router/parse.go +++ b/config/parsing/router/parse.go @@ -51,7 +51,9 @@ func ParseRouter(cfg *config.RouterConfig) router.Router { _, ipNet, _ := net.ParseCIDR(route.Net) dst := route.Dst if dst != "" { - _, ipNet, _ = net.ParseCIDR(dst) + if _, parsed, _ := net.ParseCIDR(dst); parsed != nil { + ipNet = parsed + } } else { if ipNet != nil { dst = ipNet.String()