aboutsummaryrefslogtreecommitdiff
path: root/core/config.go
diff options
context:
space:
mode:
Diffstat (limited to 'core/config.go')
-rw-r--r--core/config.go340
1 files changed, 0 insertions, 340 deletions
diff --git a/core/config.go b/core/config.go
deleted file mode 100644
index eea099a70..000000000
--- a/core/config.go
+++ /dev/null
@@ -1,340 +0,0 @@
-package core
-
-import (
- "bytes"
- "fmt"
- "io"
- "log"
- "net"
- "sync"
-
- "github.com/miekg/coredns/core/parse"
- "github.com/miekg/coredns/core/setup"
- "github.com/miekg/coredns/server"
-)
-
-const (
- // DefaultConfigFile is the name of the configuration file that is loaded
- // by default if no other file is specified.
- DefaultConfigFile = "Corefile"
-)
-
-func loadConfigsUpToIncludingTLS(filename string, input io.Reader) ([]server.Config, []parse.ServerBlock, int, error) {
- var configs []server.Config
-
- // Each server block represents similar hosts/addresses, since they
- // were grouped together in the Corefile.
- serverBlocks, err := parse.ServerBlocks(filename, input, true)
- if err != nil {
- return nil, nil, 0, err
- }
- if len(serverBlocks) == 0 {
- newInput := DefaultInput()
- serverBlocks, err = parse.ServerBlocks(newInput.Path(), bytes.NewReader(newInput.Body()), true)
- if err != nil {
- return nil, nil, 0, err
- }
- }
-
- var lastDirectiveIndex int // we set up directives in two parts; this stores where we left off
-
- // Iterate each server block and make a config for each one,
- // executing the directives that were parsed in order up to the tls
- // directive; this is because we must activate Let's Encrypt.
- for i, sb := range serverBlocks {
- onces := makeOnces()
- storages := makeStorages()
-
- for j, addr := range sb.Addresses {
- config := server.Config{
- Host: addr.Host,
- Port: addr.Port,
- Root: Root,
- ConfigFile: filename,
- AppName: AppName,
- AppVersion: AppVersion,
- }
-
- // It is crucial that directives are executed in the proper order.
- for k, dir := range directiveOrder {
- // Execute directive if it is in the server block
- if tokens, ok := sb.Tokens[dir.name]; ok {
- // Each setup function gets a controller, from which setup functions
- // get access to the config, tokens, and other state information useful
- // to set up its own host only.
- controller := &setup.Controller{
- Config: &config,
- Dispenser: parse.NewDispenserTokens(filename, tokens),
- OncePerServerBlock: func(f func() error) error {
- var err error
- onces[dir.name].Do(func() {
- err = f()
- })
- return err
- },
- ServerBlockIndex: i,
- ServerBlockHostIndex: j,
- ServerBlockHosts: sb.HostList(),
- ServerBlockStorage: storages[dir.name],
- }
- // execute setup function and append middleware handler, if any
- midware, err := dir.setup(controller)
- if err != nil {
- return nil, nil, lastDirectiveIndex, err
- }
- if midware != nil {
- config.Middleware = append(config.Middleware, midware)
- }
- storages[dir.name] = controller.ServerBlockStorage // persist for this server block
- }
-
- // Stop after TLS setup, since we need to activate Let's Encrypt before continuing;
- // it makes some changes to the configs that middlewares might want to know about.
- if dir.name == "tls" {
- lastDirectiveIndex = k
- break
- }
- }
-
- configs = append(configs, config)
- }
- }
- return configs, serverBlocks, lastDirectiveIndex, nil
-}
-
-// loadConfigs reads input (named filename) and parses it, returning the
-// server configurations in the order they appeared in the input. As part
-// of this, it activates Let's Encrypt for the configs that are produced.
-// Thus, the returned configs are already optimally configured for HTTPS.
-func loadConfigs(filename string, input io.Reader) ([]server.Config, error) {
- configs, serverBlocks, lastDirectiveIndex, err := loadConfigsUpToIncludingTLS(filename, input)
- if err != nil {
- return nil, err
- }
-
- // Now we have all the configs, but they have only been set up to the
- // point of tls. We need to activate Let's Encrypt before setting up
- // the rest of the middlewares so they have correct information regarding
- // TLS configuration, if necessary. (this only appends, so our iterations
- // over server blocks below shouldn't be affected)
- if !IsRestart() && !Quiet {
- fmt.Println("Activating privacy features...")
- }
- /* TODO(miek): stopped for now
- configs, err = https.Activate(configs)
- if err != nil {
- return nil, err
- } else if !IsRestart() && !Quiet {
- fmt.Println(" done.")
- }
- */
-
- // Finish setting up the rest of the directives, now that TLS is
- // optimally configured. These loops are similar to above except
- // we don't iterate all the directives from the beginning and we
- // don't create new configs.
- configIndex := -1
- for i, sb := range serverBlocks {
- onces := makeOnces()
- storages := makeStorages()
-
- for j := range sb.Addresses {
- configIndex++
-
- for k := lastDirectiveIndex + 1; k < len(directiveOrder); k++ {
- dir := directiveOrder[k]
-
- if tokens, ok := sb.Tokens[dir.name]; ok {
- controller := &setup.Controller{
- Config: &configs[configIndex],
- Dispenser: parse.NewDispenserTokens(filename, tokens),
- OncePerServerBlock: func(f func() error) error {
- var err error
- onces[dir.name].Do(func() {
- err = f()
- })
- return err
- },
- ServerBlockIndex: i,
- ServerBlockHostIndex: j,
- ServerBlockHosts: sb.HostList(),
- ServerBlockStorage: storages[dir.name],
- }
- midware, err := dir.setup(controller)
- if err != nil {
- return nil, err
- }
- if midware != nil {
- configs[configIndex].Middleware = append(configs[configIndex].Middleware, midware)
- }
- storages[dir.name] = controller.ServerBlockStorage // persist for this server block
- }
- }
- }
- }
-
- return configs, nil
-}
-
-// makeOnces makes a map of directive name to sync.Once
-// instance. This is intended to be called once per server
-// block when setting up configs so that Setup functions
-// for each directive can perform a task just once per
-// server block, even if there are multiple hosts on the block.
-//
-// We need one Once per directive, otherwise the first
-// directive to use it would exclude other directives from
-// using it at all, which would be a bug.
-func makeOnces() map[string]*sync.Once {
- onces := make(map[string]*sync.Once)
- for _, dir := range directiveOrder {
- onces[dir.name] = new(sync.Once)
- }
- return onces
-}
-
-// makeStorages makes a map of directive name to interface{}
-// so that directives' setup functions can persist state
-// between different hosts on the same server block during the
-// setup phase.
-func makeStorages() map[string]interface{} {
- storages := make(map[string]interface{})
- for _, dir := range directiveOrder {
- storages[dir.name] = nil
- }
- return storages
-}
-
-// arrangeBindings groups configurations by their bind address. For example,
-// a server that should listen on localhost and another on 127.0.0.1 will
-// be grouped into the same address: 127.0.0.1. It will return an error
-// if an address is malformed or a TLS listener is configured on the
-// same address as a plaintext HTTP listener. The return value is a map of
-// bind address to list of configs that would become VirtualHosts on that
-// server. Use the keys of the returned map to create listeners, and use
-// the associated values to set up the virtualhosts.
-func arrangeBindings(allConfigs []server.Config) (bindingGroup, error) {
- var groupings bindingGroup
-
- // Group configs by bind address
- for _, conf := range allConfigs {
- // use default port if none is specified
- if conf.Port == "" {
- conf.Port = Port
- }
-
- bindAddr, warnErr, fatalErr := resolveAddr(conf)
- if fatalErr != nil {
- return groupings, fatalErr
- }
- if warnErr != nil {
- log.Printf("[WARNING] Resolving bind address for %s: %v", conf.Address(), warnErr)
- }
-
- // Make sure to compare the string representation of the address,
- // not the pointer, since a new *TCPAddr is created each time.
- var existing bool
- for i := 0; i < len(groupings); i++ {
- if groupings[i].BindAddr.String() == bindAddr.String() {
- groupings[i].Configs = append(groupings[i].Configs, conf)
- existing = true
- break
- }
- }
- if !existing {
- groupings = append(groupings, bindingMapping{
- BindAddr: bindAddr,
- Configs: []server.Config{conf},
- })
- }
- }
-
- // Don't allow HTTP and HTTPS to be served on the same address
- for _, group := range groupings {
- isTLS := group.Configs[0].TLS.Enabled
- for _, config := range group.Configs {
- if config.TLS.Enabled != isTLS {
- thisConfigProto, otherConfigProto := "HTTP", "HTTP"
- if config.TLS.Enabled {
- thisConfigProto = "HTTPS"
- }
- if group.Configs[0].TLS.Enabled {
- otherConfigProto = "HTTPS"
- }
- return groupings, fmt.Errorf("configuration error: Cannot multiplex %s (%s) and %s (%s) on same address",
- group.Configs[0].Address(), otherConfigProto, config.Address(), thisConfigProto)
- }
- }
- }
-
- return groupings, nil
-}
-
-// resolveAddr determines the address (host and port) that a config will
-// bind to. The returned address, resolvAddr, should be used to bind the
-// listener or group the config with other configs using the same address.
-// The first error, if not nil, is just a warning and should be reported
-// but execution may continue. The second error, if not nil, is a real
-// problem and the server should not be started.
-//
-// This function does not handle edge cases like port "http" or "https" if
-// they are not known to the system. It does, however, serve on the wildcard
-// host if resolving the address of the specific hostname fails.
-func resolveAddr(conf server.Config) (resolvAddr *net.TCPAddr, warnErr, fatalErr error) {
- resolvAddr, warnErr = net.ResolveTCPAddr("tcp", net.JoinHostPort(conf.BindHost, conf.Port))
- if warnErr != nil {
- // the hostname probably couldn't be resolved, just bind to wildcard then
- resolvAddr, fatalErr = net.ResolveTCPAddr("tcp", net.JoinHostPort("", conf.Port))
- if fatalErr != nil {
- return
- }
- }
-
- return
-}
-
-// validDirective returns true if d is a valid
-// directive; false otherwise.
-func validDirective(d string) bool {
- for _, dir := range directiveOrder {
- if dir.name == d {
- return true
- }
- }
- return false
-}
-
-// DefaultInput returns the default Corefile input
-// to use when it is otherwise empty or missing.
-// It uses the default host and port and root.
-func DefaultInput() CorefileInput {
- port := Port
- return CorefileInput{
- Contents: []byte(fmt.Sprintf("%s:%s\nroot %s", Host, port, Root)),
- }
-}
-
-// These defaults are configurable through the command line
-var (
- // Root is the site root
- Root = DefaultRoot
-
- // Host is the site host
- Host = DefaultHost
-
- // Port is the site port
- Port = DefaultPort
-)
-
-// bindingMapping maps a network address to configurations
-// that will bind to it. The order of the configs is important.
-type bindingMapping struct {
- BindAddr *net.TCPAddr
- Configs []server.Config
-}
-
-// bindingGroup maps network addresses to their configurations.
-// Preserving the order of the groupings is important
-// (related to graceful shutdown and restart)
-// so this is a slice, not a literal map.
-type bindingGroup []bindingMapping