github.com/moby/docker@v26.1.3+incompatible/integration/internal/network/dns.go (about) 1 package network 2 3 import ( 4 "net" 5 "os" 6 "testing" 7 8 "github.com/miekg/dns" 9 "gotest.tools/v3/assert" 10 ) 11 12 const DNSRespAddr = "10.11.12.13" 13 14 // WriteTempResolvConf writes a resolv.conf that only contains a single 15 // nameserver line, with address addr. 16 // It returns the name of the temp file. The temp file will be deleted 17 // automatically by a t.Cleanup(). 18 func WriteTempResolvConf(t *testing.T, addr string) string { 19 t.Helper() 20 // Not using t.TempDir() here because in rootless mode, while the temporary 21 // directory gets mode 0777, it's a subdir of an 0700 directory owned by root. 22 // So, it's not accessible by the daemon. 23 f, err := os.CreateTemp("", "resolv.conf") 24 assert.NilError(t, err) 25 t.Cleanup(func() { os.Remove(f.Name()) }) 26 err = f.Chmod(0644) 27 assert.NilError(t, err) 28 f.Write([]byte("nameserver " + addr + "\n")) 29 return f.Name() 30 } 31 32 // StartDaftDNS starts and returns a really, really daft DNS server that only 33 // responds to type-A requests, and always with address dnsRespAddr. 34 // The DNS server will be stopped automatically by a t.Cleanup(). 35 func StartDaftDNS(t *testing.T, addr string) { 36 serveDNS := func(w dns.ResponseWriter, query *dns.Msg) { 37 if query.Question[0].Qtype == dns.TypeA { 38 resp := &dns.Msg{} 39 resp.SetReply(query) 40 answer := &dns.A{ 41 Hdr: dns.RR_Header{ 42 Name: query.Question[0].Name, 43 Rrtype: dns.TypeA, 44 Class: dns.ClassINET, 45 Ttl: 600, 46 }, 47 } 48 answer.A = net.ParseIP(DNSRespAddr) 49 resp.Answer = append(resp.Answer, answer) 50 _ = w.WriteMsg(resp) 51 } 52 } 53 54 conn, err := net.ListenUDP("udp", &net.UDPAddr{ 55 IP: net.ParseIP(addr), 56 Port: 53, 57 }) 58 assert.NilError(t, err) 59 60 server := &dns.Server{Handler: dns.HandlerFunc(serveDNS), PacketConn: conn} 61 go func() { 62 _ = server.ActivateAndServe() 63 }() 64 65 t.Cleanup(func() { server.Shutdown() }) 66 }