The resolver does not ask itself for upstreams
dnsmasq read /etc/resolv.conf to find where to forward. Whatever points a machine at the mesh writes its own address into that file — so dnsmasq's upstream was dnsmasq, and every query it could not answer locally looped. Its receive queue filled with 15KB of them and every lookup on the machine hung, which is why this arrived as a thirty-second timeout rather than a wrong answer. It needs no upstream at all: the asking module routes only the mesh's suffix here and leaves everything else where the machine already sent it. And it names none, because choosing one would send every query this machine makes somewhere nobody agreed to. Also corrected: the comment claiming it takes only 127.0.0.55. Listening on a loopback address makes dnsmasq take the rest of loopback with it, 127.0.0.1 included — which is what claiming `the-dns-port` already says, and which the comment was quietly denying. That is the same comfortable claim as ".54 is free", in the same file, made twice.
This commit is contained in:
@@ -192,3 +192,25 @@ func TestTheExamplesAreWellFormed(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The resolver must not look up its own upstreams.
|
||||
//
|
||||
// Whatever points a machine at the mesh writes that address into resolv.conf, so a resolver that
|
||||
// read it would find itself — and every query it could not answer locally would loop until its
|
||||
// receive queue filled. It did: 15KB of queries backed up and every lookup on the machine hung.
|
||||
//
|
||||
// It needs no upstream because it is never asked for anything else: the asking module routes only
|
||||
// the mesh's suffix here and leaves the rest where the machine already sent it.
|
||||
func TestTheResolverDoesNotAskItselfForUpstreams(t *testing.T) {
|
||||
config := read(t, "dnsmasq.json").Resources[1]["content"].(string)
|
||||
if !strings.Contains(config, "\nno-resolv\n") {
|
||||
t.Fatalf("it reads resolv.conf for upstreams, which now points at itself:\n%s", config)
|
||||
}
|
||||
// And names no upstream of its own: choosing one would send every query this machine cannot
|
||||
// answer somewhere nobody agreed to.
|
||||
for _, line := range strings.Split(config, "\n") {
|
||||
if strings.HasPrefix(strings.TrimSpace(line), "server=") {
|
||||
t.Fatalf("it forwards to %q, which is not the mesh's to choose", line)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user