diff --git a/plugin/forward/resolve.go b/plugin/forward/resolve.go index f10e8817b..0bb3e2761 100644 --- a/plugin/forward/resolve.go +++ b/plugin/forward/resolve.go @@ -1,6 +1,7 @@ package forward import ( + "errors" "fmt" "net" "strings" @@ -39,9 +40,14 @@ func classifyToAddrs(toAddrs []string) ([]toEntry, error) { continue } + // Empty file are skip + if errors.Is(parseErr, parse.ErrNoNameservers) { + continue + } + // Only fall through to hostname parsing if the error specifically // indicates the address is not an IP or file. Other errors (like - // "no nameservers found" from file parsing) should be propagated. + // "invalid address" from ip parsing) should be propagated. if !strings.Contains(parseErr.Error(), "not an IP address or file") { return nil, parseErr } diff --git a/plugin/forward/resolve_test.go b/plugin/forward/resolve_test.go index 2d989b5dc..d2d1d6d08 100644 --- a/plugin/forward/resolve_test.go +++ b/plugin/forward/resolve_test.go @@ -24,6 +24,13 @@ func TestClassifyToAddrs(t *testing.T) { } defer os.Remove(resolv) + // Create a commented.conf for file test + const commentedResolv = "commented_resolv.conf" + if err := os.WriteFile(commentedResolv, []byte("# nameserver 1.1.1.1\n# nameserver 1.0.0.1\n"), 0666); err != nil { + t.Fatal(err) + } + defer os.Remove(commentedResolv) + tests := []struct { name string input []string @@ -84,10 +91,10 @@ func TestClassifyToAddrs(t *testing.T) { wantDynamic: 1, }, { - name: "/dev/null returns file error", - input: []string{"/dev/null"}, - wantErr: true, - errContains: "no nameservers", + name: "an existing file not empty but without nameserver is skipped", + input: []string{commentedResolv}, + wantDynamic: 0, + wantStatic: 0, }, } diff --git a/plugin/forward/setup_test.go b/plugin/forward/setup_test.go index b13150d52..350194ef2 100644 --- a/plugin/forward/setup_test.go +++ b/plugin/forward/setup_test.go @@ -242,6 +242,14 @@ nameserver 10.10.255.253`), 0666); err != nil { } defer os.Remove(resolvIPV6) + const emptyResolv = "empty.conf" + if err := os.WriteFile(emptyResolv, + []byte(`# nameserver 1.1.1.1 +# nameserver 1.0.0.1`), 0666); err != nil { + t.Fatalf("Failed to write empty.conf file: %s", err) + } + defer os.Remove(emptyResolv) + tests := []struct { input string shouldErr bool @@ -251,9 +259,11 @@ nameserver 10.10.255.253`), 0666); err != nil { // pass {`forward . ` + resolv, false, "", []string{"10.10.255.252:53", "10.10.255.253:53"}}, // fail - {`forward . /dev/null`, true, "no nameservers", nil}, + {`forward . /dev/null`, true, "no valid upstream addresses found", nil}, // IPV6 with local zone {`forward . ` + resolvIPV6, false, "", []string{"[0388:d254:7aec:6892:9f7f:e93b:5806:1b0f]:53"}}, + // pass when empty forward file is found + {`forward . ` + emptyResolv + ` 127.0.0.1`, false, "", []string{"127.0.0.1:53"}}, } for i, test := range tests { @@ -517,6 +527,7 @@ func TestMultiForward(t *testing.T) { t.Error("expected third plugin to be last, but Next is not nil") } } + func TestNextAlternate(t *testing.T) { testsValid := []struct { input string diff --git a/plugin/pkg/parse/host.go b/plugin/pkg/parse/host.go index 029d4f258..c6cbbc4be 100644 --- a/plugin/pkg/parse/host.go +++ b/plugin/pkg/parse/host.go @@ -54,7 +54,7 @@ func HostPortOrFile(s ...string) ([]string, error) { servers = append(servers, ss...) continue } - return servers, fmt.Errorf("not an IP address or file: %q", host) + return servers, fmt.Errorf("not an IP address or file %q: %w", host, err) } var ss string switch trans { @@ -79,7 +79,7 @@ func HostPortOrFile(s ...string) ([]string, error) { servers = append(servers, ss...) continue } - return servers, fmt.Errorf("not an IP address or file: %q", host) + return servers, fmt.Errorf("not an IP address or file %q: %w", host, err) } servers = append(servers, h) } @@ -92,13 +92,13 @@ func HostPortOrFile(s ...string) ([]string, error) { // Try to open this is a file first. func tryFile(s string) ([]string, error) { c, err := dns.ClientConfigFromFile(s) - if err == os.ErrNotExist { + if errors.Is(err, os.ErrNotExist) { return nil, fmt.Errorf("failed to open file %q: %q", s, err) } else if err != nil { return nil, err } - servers := []string{} + var servers []string for _, s := range c.Servers { servers = append(servers, net.JoinHostPort(stripZone(s), c.Port)) }