From 020b814402add8165c6dbbee341888bb89700c12 Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Fri, 28 Feb 2025 14:27:53 +0700 Subject: [PATCH] cmd/cli: fix validating remote custom config Currently, custom config is only validated against invalid syntax, not the validating rules for each configuration value. It causes ctrld process fatal instead of disregarding as expected. To fix this, force the validating rule after fetching remote config. While at it, also add the default network value if non-existed. --- cmd/cli/cli.go | 42 +++++++++++++++++++++++++++++++----------- cmd/cli/prog.go | 1 + 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/cmd/cli/cli.go b/cmd/cli/cli.go index de2945b..7c79921 100644 --- a/cmd/cli/cli.go +++ b/cmd/cli/cli.go @@ -649,11 +649,15 @@ func processCDFlags(cfg *ctrld.Config) (*controld.ResolverConfig, error) { // Fetch config, unmarshal to cfg. if resolverConfig.Ctrld.CustomConfig != "" { logger.Info().Msg("using defined custom config of Control-D resolver") - if err := validateCdRemoteConfig(resolverConfig, cfg); err == nil { + var cfgErr error + if cfgErr = validateCdRemoteConfig(resolverConfig, cfg); cfgErr == nil { setListenerDefaultValue(cfg) - return resolverConfig, nil + setNetworkDefaultValue(cfg) + if cfgErr = validateConfig(cfg); cfgErr == nil { + return resolverConfig, nil + } } - mainLog.Load().Err(err).Msg("disregarding invalid custom config") + mainLog.Load().Warn().Err(err).Msg("disregarding invalid custom config") } bootstrapIP := func(endpoint string) string { @@ -670,11 +674,7 @@ func processCDFlags(cfg *ctrld.Config) (*controld.ResolverConfig, error) { } return "" } - cfg.Network = make(map[string]*ctrld.NetworkConfig) - cfg.Network["0"] = &ctrld.NetworkConfig{ - Name: "Network 0", - Cidrs: []string{"0.0.0.0/0"}, - } + cfg.Upstream = make(map[string]*ctrld.UpstreamConfig) cfg.Upstream["0"] = &ctrld.UpstreamConfig{ BootstrapIP: bootstrapIP(resolverConfig.DOH), @@ -697,6 +697,7 @@ func processCDFlags(cfg *ctrld.Config) (*controld.ResolverConfig, error) { // Set default value. setListenerDefaultValue(cfg) + setNetworkDefaultValue(cfg) return resolverConfig, nil } @@ -710,7 +711,21 @@ func setListenerDefaultValue(cfg *ctrld.Config) { } } +// setListenerDefaultValue sets the default value for cfg.Listener if none existed. +func setNetworkDefaultValue(cfg *ctrld.Config) { + if len(cfg.Network) == 0 { + cfg.Network = map[string]*ctrld.NetworkConfig{ + "0": { + Name: "Network 0", + Cidrs: []string{"0.0.0.0/0"}, + }, + } + } +} + // validateCdRemoteConfig validates the custom config from ControlD if defined. +// This only validate the config syntax. To validate the config rules, calling +// validateConfig with the cfg after calling this function. func validateCdRemoteConfig(rc *controld.ResolverConfig, cfg *ctrld.Config) error { if rc.Ctrld.CustomConfig == "" { return nil @@ -1826,8 +1841,10 @@ func doValidateCdRemoteConfig(cdUID string, fatal bool) error { } // validateCdRemoteConfig clobbers v, saving it here to restore later. oldV := v - if err := validateCdRemoteConfig(rc, &ctrld.Config{}); err != nil { - if errors.As(err, &viper.ConfigParseError{}) { + var cfgErr error + remoteCfg := &ctrld.Config{} + if cfgErr = validateCdRemoteConfig(rc, remoteCfg); cfgErr != nil { + if errors.As(cfgErr, &viper.ConfigParseError{}) { if configStr, _ := base64.StdEncoding.DecodeString(rc.Ctrld.CustomConfig); len(configStr) > 0 { tmpDir := os.TempDir() tmpConfFile := filepath.Join(tmpDir, "ctrld.toml") @@ -1843,12 +1860,15 @@ func doValidateCdRemoteConfig(cdUID string, fatal bool) error { } // If we could not log details error, emit what we have already got. if !errorLogged { - mainLog.Load().Error().Msgf("failed to parse custom config: %v", err) + mainLog.Load().Error().Msgf("failed to parse custom config: %v", cfgErr) } } } else { mainLog.Load().Error().Msgf("failed to unmarshal custom config: %v", err) } + } + cfgErr = validateConfig(remoteCfg) + if cfgErr != nil { mainLog.Load().Warn().Msg("disregarding invalid custom config") } v = oldV diff --git a/cmd/cli/prog.go b/cmd/cli/prog.go index ad1cb88..05be35c 100644 --- a/cmd/cli/prog.go +++ b/cmd/cli/prog.go @@ -359,6 +359,7 @@ func (p *prog) apiConfigReload() { return } setListenerDefaultValue(cfg) + setNetworkDefaultValue(cfg) logger.Debug().Msg("custom config changes detected, reloading...") p.apiReloadCh <- cfg } else {