all: rework fetching/generating config in cd mode

Config fetching/generating in cd mode is currently weird, error prone,
and easy for user to break ctrld when using custom config.

This commit reworks the flow:

 - Fetching config from Control D API.
 - No custom config, use the current default config.
 - If custom config presents, but there's no listener, use 0.0.0.0:53.
 - Try listening on current ip+port config, if ok, ctrld could be a
   direct listener with current setup, moving on.
 - If failed, trying 127.0.0.1:53.
 - If failed, trying current ip + port 5354
 - If still failed, pick a random ip:port pair, retry until listening ok.

With this flow, thing is more predictable/stable, and help removing the
Config interface for router.
This commit is contained in:
Cuong Manh Le
2023-07-07 21:07:26 +07:00
committed by Cuong Manh Le
parent 3f3c1d6d78
commit 7af59ee589
23 changed files with 442 additions and 344 deletions

View File

@@ -12,6 +12,8 @@ import (
"net/url"
"os"
"runtime"
"sort"
"strconv"
"strings"
"sync"
"sync/atomic"
@@ -123,6 +125,25 @@ func (c *Config) HasUpstreamSendClientInfo() bool {
return false
}
// FirstListener returns the first listener config of current config. Listeners are sorted numerically.
//
// It panics if Config has no listeners configured.
func (c *Config) FirstListener() *ListenerConfig {
listeners := make([]int, 0, len(c.Listener))
for k := range c.Listener {
n, err := strconv.Atoi(k)
if err != nil {
continue
}
listeners = append(listeners, n)
}
if len(listeners) == 0 {
panic("missing listener config")
}
sort.Ints(listeners)
return c.Listener[strconv.Itoa(listeners[0])]
}
// ServiceConfig specifies the general ctrld config.
type ServiceConfig struct {
LogLevel string `mapstructure:"log_level" toml:"log_level,omitempty"`