fix(cmd): shallow-copy leaks in node/service expansion, inconsistent auth priority
Three bugs in CLI-to-config conversion: 1. Comma-separated -F nodes shared Connector/Dialer/Metadata pointers due to struct value copy; add deep-copy helpers per node. 2. Port-range-expanded -L services shared Handler/Listener/Metadata pointers; deep-copy per service so metadata mutations don't cross-talk. 3. buildServiceConfig's ?auth= query param unconditionally overwrote URL-embedded auth; buildNodeConfig used fallback-only. Align both on URL-auth-first semantics (query param as fallback).
This commit is contained in:
+78
-4
@@ -157,6 +157,9 @@ func BuildConfigFromCmd(serviceList, nodeList []string) (*config.Config, error)
|
||||
}
|
||||
nodeCfg := &config.NodeConfig{}
|
||||
*nodeCfg = *nodeConfig
|
||||
nodeCfg.Connector = copyConnectorConfig(nodeConfig.Connector)
|
||||
nodeCfg.Dialer = copyDialerConfig(nodeConfig.Dialer)
|
||||
nodeCfg.Metadata = copyMap(nodeConfig.Metadata)
|
||||
nodeCfg.Name = fmt.Sprintf("%snode-%d", namePrefix, len(nodes))
|
||||
nodeCfg.Addr = host
|
||||
nodes = append(nodes, nodeCfg)
|
||||
@@ -488,7 +491,7 @@ func buildServiceConfig(url *url.URL) ([]*config.ServiceConfig, error) {
|
||||
}
|
||||
md := mdx.NewMetadata(m)
|
||||
|
||||
if sa := mdutil.GetString(md, "auth"); sa != "" {
|
||||
if sa := mdutil.GetString(md, "auth"); sa != "" && auth == nil {
|
||||
au, err := parseAuthFromCmd(sa)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -585,9 +588,9 @@ func buildServiceConfig(url *url.URL) ([]*config.ServiceConfig, error) {
|
||||
if svc.Forwarder != nil {
|
||||
svc.Forwarder.Selector = selector
|
||||
}
|
||||
svc.Handler = handlerCfg
|
||||
svc.Listener = listenerCfg
|
||||
svc.Metadata = serviceMd
|
||||
svc.Handler = copyHandlerConfig(handlerCfg)
|
||||
svc.Listener = copyListenerConfig(listenerCfg)
|
||||
svc.Metadata = copyMap(serviceMd)
|
||||
}
|
||||
|
||||
return services, nil
|
||||
@@ -837,3 +840,74 @@ func parseSelector(m map[string]any) *config.SelectorConfig {
|
||||
FailTimeout: failTimeout,
|
||||
}
|
||||
}
|
||||
|
||||
func copyMap(m map[string]any) map[string]any {
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
c := make(map[string]any, len(m))
|
||||
for k, v := range m {
|
||||
c[k] = v
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func copyAuth(cfg *config.AuthConfig) *config.AuthConfig {
|
||||
if cfg == nil {
|
||||
return nil
|
||||
}
|
||||
c := *cfg
|
||||
return &c
|
||||
}
|
||||
|
||||
func copyTLS(cfg *config.TLSConfig) *config.TLSConfig {
|
||||
if cfg == nil {
|
||||
return nil
|
||||
}
|
||||
c := *cfg
|
||||
return &c
|
||||
}
|
||||
|
||||
func copyConnectorConfig(cfg *config.ConnectorConfig) *config.ConnectorConfig {
|
||||
if cfg == nil {
|
||||
return nil
|
||||
}
|
||||
c := *cfg
|
||||
c.Auth = copyAuth(cfg.Auth)
|
||||
c.TLS = copyTLS(cfg.TLS)
|
||||
c.Metadata = copyMap(cfg.Metadata)
|
||||
return &c
|
||||
}
|
||||
|
||||
func copyDialerConfig(cfg *config.DialerConfig) *config.DialerConfig {
|
||||
if cfg == nil {
|
||||
return nil
|
||||
}
|
||||
c := *cfg
|
||||
c.Auth = copyAuth(cfg.Auth)
|
||||
c.TLS = copyTLS(cfg.TLS)
|
||||
c.Metadata = copyMap(cfg.Metadata)
|
||||
return &c
|
||||
}
|
||||
|
||||
func copyHandlerConfig(cfg *config.HandlerConfig) *config.HandlerConfig {
|
||||
if cfg == nil {
|
||||
return nil
|
||||
}
|
||||
c := *cfg
|
||||
c.Auth = copyAuth(cfg.Auth)
|
||||
c.TLS = copyTLS(cfg.TLS)
|
||||
c.Metadata = copyMap(cfg.Metadata)
|
||||
return &c
|
||||
}
|
||||
|
||||
func copyListenerConfig(cfg *config.ListenerConfig) *config.ListenerConfig {
|
||||
if cfg == nil {
|
||||
return nil
|
||||
}
|
||||
c := *cfg
|
||||
c.Auth = copyAuth(cfg.Auth)
|
||||
c.TLS = copyTLS(cfg.TLS)
|
||||
c.Metadata = copyMap(cfg.Metadata)
|
||||
return &c
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user