1 parent
0b6dcbd547
commit
d48c1863bf
9 files changed
+222
-7
No files matched your search
@@ -23,6 +23,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
@@ -202,7 +203,14 @@ type EDNS struct {
|
||||
PreserveEDNS0 bool `yaml:"preserve"`
|
||||
}
|
||||
|
||||
// ForwardZone routes the apex and every name below it exclusively to Servers.
|
||||
type ForwardZone struct {
|
||||
Zone string `yaml:"zone" json:"zone"`
|
||||
Servers []UpstreamServer `yaml:"servers" json:"servers"`
|
||||
}
|
||||
|
||||
type Upstream struct {
|
||||
ForwardZones []ForwardZone `yaml:"forward_zones,omitempty" json:"forward_zones,omitempty"`
|
||||
// Servers is the upstream pool.
|
||||
Servers []UpstreamServer `yaml:"servers"`
|
||||
// Policy is "parallel" (query all, first answer wins), "random" (pick N)
|
||||
@@ -962,6 +970,24 @@ func (c *Config) applyDefaults() {
|
||||
l.MaxBytes = 512 << 20
|
||||
}
|
||||
}
|
||||
for i := range c.Upstream.ForwardZones {
|
||||
z := &c.Upstream.ForwardZones[i]
|
||||
z.Zone = strings.ToLower(strings.TrimSuffix(strings.TrimSpace(z.Zone), "."))
|
||||
for j := range z.Servers {
|
||||
u := &z.Servers[j]
|
||||
if u.Proto == "" {
|
||||
u.Proto = "udp"
|
||||
}
|
||||
if u.Weight <= 0 {
|
||||
u.Weight = 1
|
||||
}
|
||||
if u.Addr != "" {
|
||||
if _, _, err := net.SplitHostPort(u.Addr); err != nil {
|
||||
u.Addr = net.JoinHostPort(u.Addr, defaultPort(u.Proto))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for i := range c.Upstream.Servers {
|
||||
u := &c.Upstream.Servers[i]
|
||||
if u.Proto == "" {
|
||||
@@ -1035,6 +1061,31 @@ func (c *Config) Validate() error {
|
||||
if len(c.Upstream.Servers) == 0 {
|
||||
add("upstream.servers must not be empty")
|
||||
}
|
||||
zones := map[string]bool{}
|
||||
for i, z := range c.Upstream.ForwardZones {
|
||||
name := strings.ToLower(strings.TrimSuffix(z.Zone, "."))
|
||||
if _, ok := dns.IsDomainName(name); !ok || name == "" || strings.Contains(name, "*") {
|
||||
add("upstream.forward_zones[%d]: invalid zone %q", i, z.Zone)
|
||||
}
|
||||
if zones[name] {
|
||||
add("upstream.forward_zones[%d]: duplicate zone %q", i, z.Zone)
|
||||
}
|
||||
zones[name] = true
|
||||
if len(z.Servers) == 0 {
|
||||
add("upstream.forward_zones[%d]: servers must not be empty", i)
|
||||
}
|
||||
for _, u := range z.Servers {
|
||||
host, port, err := net.SplitHostPort(u.Addr)
|
||||
if err != nil || host == "" || port == "" {
|
||||
add("upstream.forward_zones[%d]: invalid server address %q", i, u.Addr)
|
||||
}
|
||||
switch u.Proto {
|
||||
case "udp", "tcp", "tls":
|
||||
default:
|
||||
add("upstream.forward_zones[%d]: invalid proto %q", i, u.Proto)
|
||||
}
|
||||
}
|
||||
}
|
||||
seen := map[string]bool{}
|
||||
for i, u := range c.Upstream.Servers {
|
||||
if u.Addr == "" {
|
||||
|
||||
@@ -371,3 +371,33 @@ func writeTempConfig(t *testing.T, content string) string {
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
func TestForwardZoneConfig(t *testing.T) {
|
||||
c := Default()
|
||||
c.Block.Enabled = false
|
||||
c.Upstream.ForwardZones = []ForwardZone{{Zone: "LOCAL.", Servers: []UpstreamServer{{Addr: "10.10.0.1"}}}}
|
||||
c.applyDefaults()
|
||||
if err := c.Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
z := c.Upstream.ForwardZones[0]
|
||||
if z.Zone != "local" || z.Servers[0].Addr != "10.10.0.1:53" || z.Servers[0].Proto != "udp" {
|
||||
t.Fatalf("defaults: %+v", z)
|
||||
}
|
||||
for _, bad := range []ForwardZone{
|
||||
{Zone: "*.local", Servers: z.Servers},
|
||||
{Zone: "", Servers: z.Servers},
|
||||
{Zone: "local"},
|
||||
{Zone: "local", Servers: []UpstreamServer{{Addr: "", Proto: "udp"}}},
|
||||
{Zone: "local", Servers: []UpstreamServer{{Addr: "10.10.0.1:53", Proto: "http"}}},
|
||||
} {
|
||||
c.Upstream.ForwardZones = []ForwardZone{bad}
|
||||
if err := c.Validate(); err == nil {
|
||||
t.Fatalf("accepted %+v", bad)
|
||||
}
|
||||
}
|
||||
c.Upstream.ForwardZones = []ForwardZone{z, z}
|
||||
if err := c.Validate(); err == nil {
|
||||
t.Fatal("accepted duplicate zone")
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user