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  }