mirror of
				https://github.com/coredns/coredns.git
				synced 2025-11-04 03:03:14 -05:00 
			
		
		
		
	plugin/hosts: create inline map in setup (#3071)
* plugin/hosts: create inline map in setup The inline map wasn't create in the setup.go fuction leading to a crash, which is masked by a recover (but leads to a SERVFAIL, and not logging the request). Various other simplifications. host plugin could use some test that actually cover these edgecases. Signed-off-by: Miek Gieben <miek@miek.nl> * PR review changes Signed-off-by: Miek Gieben <miek@miek.nl>
This commit is contained in:
		@@ -15,6 +15,9 @@ The plugin reloads the content of the hosts file every 5 seconds. Upon reload, C
 | 
				
			|||||||
new definitions. Should the file be deleted, any inlined content will continue to be served. When
 | 
					new definitions. Should the file be deleted, any inlined content will continue to be served. When
 | 
				
			||||||
the file is restored, it will then again be used.
 | 
					the file is restored, it will then again be used.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you want to pass the request to the rest of the plugin chain if there is no match in the *hosts*
 | 
				
			||||||
 | 
					plugin, you must specify the `fallthrough` option.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This plugin can only be used once per Server Block.
 | 
					This plugin can only be used once per Server Block.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## The hosts file
 | 
					## The hosts file
 | 
				
			||||||
@@ -60,7 +63,9 @@ hosts [FILE [ZONES...]] {
 | 
				
			|||||||
   then all of them will be treated as the additional content for hosts file. The specified hosts
 | 
					   then all of them will be treated as the additional content for hosts file. The specified hosts
 | 
				
			||||||
   file path will still be read but entries will be overridden.
 | 
					   file path will still be read but entries will be overridden.
 | 
				
			||||||
* `ttl` change the DNS TTL of the records generated (forward and reverse). The default is 3600 seconds (1 hour).
 | 
					* `ttl` change the DNS TTL of the records generated (forward and reverse). The default is 3600 seconds (1 hour).
 | 
				
			||||||
* `reload` change the period between each hostsfile reload. A time of zero seconds disable the feature. Examples of valid durations: "300ms", "1.5h" or "2h45m" are valid duration with units "ns" (nanosecond), "us" (or "µs" for microsecond), "ms" (millisecond), "s" (second), "m" (minute), "h" (hour).
 | 
					* `reload` change the period between each hostsfile reload. A time of zero seconds disables the
 | 
				
			||||||
 | 
					  feature. Examples of valid durations: "300ms", "1.5h" or "2h45m". See Go's
 | 
				
			||||||
 | 
					  [time](https://godoc.org/time). package.
 | 
				
			||||||
* `no_reverse` disable the automatic generation of the `in-addr.arpa` or `ip6.arpa` entries for the hosts
 | 
					* `no_reverse` disable the automatic generation of the `in-addr.arpa` or `ip6.arpa` entries for the hosts
 | 
				
			||||||
* `fallthrough` If zone matches and no record can be generated, pass request to the next plugin.
 | 
					* `fallthrough` If zone matches and no record can be generated, pass request to the next plugin.
 | 
				
			||||||
  If **[ZONES...]** is omitted, then fallthrough happens for all zones for which the plugin
 | 
					  If **[ZONES...]** is omitted, then fallthrough happens for all zones for which the plugin
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,8 +29,8 @@ func (h Hosts) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	zone := plugin.Zones(h.Origins).Matches(qname)
 | 
						zone := plugin.Zones(h.Origins).Matches(qname)
 | 
				
			||||||
	if zone == "" {
 | 
						if zone == "" {
 | 
				
			||||||
		// PTR zones don't need to be specified in Origins
 | 
							// PTR zones don't need to be specified in Origins.
 | 
				
			||||||
		if state.Type() != "PTR" {
 | 
							if state.QType() != dns.TypePTR {
 | 
				
			||||||
			// if this doesn't match we need to fall through regardless of h.Fallthrough
 | 
								// if this doesn't match we need to fall through regardless of h.Fallthrough
 | 
				
			||||||
			return plugin.NextOrFailure(h.Name(), h.Next, ctx, w, r)
 | 
								return plugin.NextOrFailure(h.Name(), h.Next, ctx, w, r)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -56,8 +56,10 @@ func (h Hosts) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (
 | 
				
			|||||||
		if h.Fall.Through(qname) {
 | 
							if h.Fall.Through(qname) {
 | 
				
			||||||
			return plugin.NextOrFailure(h.Name(), h.Next, ctx, w, r)
 | 
								return plugin.NextOrFailure(h.Name(), h.Next, ctx, w, r)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if !h.otherRecordsExist(state.QType(), qname) {
 | 
							// We want to send an NXDOMAIN, but because of /etc/hosts' setup we don't have a SOA, so we make it REFUSED
 | 
				
			||||||
			return dns.RcodeNameError, nil
 | 
							// to at least give an answer back to signals we're having problems resolving this.
 | 
				
			||||||
 | 
							if !h.otherRecordsExist(qname) {
 | 
				
			||||||
 | 
								return dns.RcodeServerFailure, nil
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -70,24 +72,13 @@ func (h Hosts) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (
 | 
				
			|||||||
	return dns.RcodeSuccess, nil
 | 
						return dns.RcodeSuccess, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (h Hosts) otherRecordsExist(qtype uint16, qname string) bool {
 | 
					func (h Hosts) otherRecordsExist(qname string) bool {
 | 
				
			||||||
	switch qtype {
 | 
					 | 
				
			||||||
	case dns.TypeA:
 | 
					 | 
				
			||||||
		if len(h.LookupStaticHostV6(qname)) > 0 {
 | 
					 | 
				
			||||||
			return true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	case dns.TypeAAAA:
 | 
					 | 
				
			||||||
		if len(h.LookupStaticHostV4(qname)) > 0 {
 | 
					 | 
				
			||||||
			return true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
	if len(h.LookupStaticHostV4(qname)) > 0 {
 | 
						if len(h.LookupStaticHostV4(qname)) > 0 {
 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(h.LookupStaticHostV6(qname)) > 0 {
 | 
						if len(h.LookupStaticHostV6(qname)) > 0 {
 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return false
 | 
						return false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -73,13 +73,12 @@ func setup(c *caddy.Controller) error {
 | 
				
			|||||||
func hostsParse(c *caddy.Controller) (Hosts, error) {
 | 
					func hostsParse(c *caddy.Controller) (Hosts, error) {
 | 
				
			||||||
	config := dnsserver.GetConfig(c)
 | 
						config := dnsserver.GetConfig(c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	options := newOptions()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	h := Hosts{
 | 
						h := Hosts{
 | 
				
			||||||
		Hostsfile: &Hostsfile{
 | 
							Hostsfile: &Hostsfile{
 | 
				
			||||||
			path:    "/etc/hosts",
 | 
								path:    "/etc/hosts",
 | 
				
			||||||
			hmap:    newMap(),
 | 
								hmap:    newMap(),
 | 
				
			||||||
			options: options,
 | 
								inline:  newMap(),
 | 
				
			||||||
 | 
								options: newOptions(),
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -129,7 +128,7 @@ func hostsParse(c *caddy.Controller) (Hosts, error) {
 | 
				
			|||||||
			case "fallthrough":
 | 
								case "fallthrough":
 | 
				
			||||||
				h.Fall.SetZonesFromArgs(c.RemainingArgs())
 | 
									h.Fall.SetZonesFromArgs(c.RemainingArgs())
 | 
				
			||||||
			case "no_reverse":
 | 
								case "no_reverse":
 | 
				
			||||||
				options.autoReverse = false
 | 
									h.options.autoReverse = false
 | 
				
			||||||
			case "ttl":
 | 
								case "ttl":
 | 
				
			||||||
				remaining := c.RemainingArgs()
 | 
									remaining := c.RemainingArgs()
 | 
				
			||||||
				if len(remaining) < 1 {
 | 
									if len(remaining) < 1 {
 | 
				
			||||||
@@ -142,7 +141,7 @@ func hostsParse(c *caddy.Controller) (Hosts, error) {
 | 
				
			|||||||
				if ttl <= 0 || ttl > 65535 {
 | 
									if ttl <= 0 || ttl > 65535 {
 | 
				
			||||||
					return h, c.Errf("ttl provided is invalid")
 | 
										return h, c.Errf("ttl provided is invalid")
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				options.ttl = uint32(ttl)
 | 
									h.options.ttl = uint32(ttl)
 | 
				
			||||||
			case "reload":
 | 
								case "reload":
 | 
				
			||||||
				remaining := c.RemainingArgs()
 | 
									remaining := c.RemainingArgs()
 | 
				
			||||||
				if len(remaining) != 1 {
 | 
									if len(remaining) != 1 {
 | 
				
			||||||
@@ -155,7 +154,7 @@ func hostsParse(c *caddy.Controller) (Hosts, error) {
 | 
				
			|||||||
				if reload < 0 {
 | 
									if reload < 0 {
 | 
				
			||||||
					return h, c.Errf("invalid negative duration for reload '%s'", remaining[0])
 | 
										return h, c.Errf("invalid negative duration for reload '%s'", remaining[0])
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				options.reload = reload
 | 
									h.options.reload = reload
 | 
				
			||||||
			default:
 | 
								default:
 | 
				
			||||||
				if len(h.Fall.Zones) == 0 {
 | 
									if len(h.Fall.Zones) == 0 {
 | 
				
			||||||
					line := strings.Join(append([]string{c.Val()}, c.RemainingArgs()...), " ")
 | 
										line := strings.Join(append([]string{c.Val()}, c.RemainingArgs()...), " ")
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user