github.com/elfadel/cilium@v1.6.12/pkg/fqdn/lookup_test.go (about) 1 // Copyright 2018 Authors of Cilium 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // +build !privileged_tests 16 17 package fqdn 18 19 import ( 20 "errors" 21 "fmt" 22 "net" 23 24 "github.com/miekg/dns" 25 26 . "gopkg.in/check.v1" 27 ) 28 29 func init() { 30 // setup dummy dnsConfig for tests 31 dnsConfig = &dns.ClientConfig{ 32 Servers: []string{"1.2.3.4", "5.6.7.8"}, 33 Search: make([]string, 0), 34 Port: "53", 35 Ndots: 1, 36 Timeout: 5, 37 Attempts: 2, 38 } 39 } 40 41 func makeResponse(qname string, dnsType uint16, rcode int, answers []dns.RR) *dns.Msg { 42 ret := &dns.Msg{} 43 ret.SetQuestion(dns.Fqdn(qname), dnsType) 44 ret.Opcode = dns.OpcodeQuery 45 ret.Rcode = rcode 46 ret.RecursionDesired = true 47 ret.RecursionAvailable = true 48 ret.Response = true 49 ret.Answer = answers 50 return ret 51 } 52 53 // TestDNSResolverQueryAllNames tests that DNSLookupDefaultResolver should: 54 // - query all names in dnsNames 55 // - query for A and AAAA for each name 56 // - use the TTL in CNAMEs to set the TTL, and choose the lowest 57 func (ds *FQDNTestSuite) TestDNSResolverQueryAllNames(c *C) { 58 dnsNames := []string{"a.com", "b.com", "c.com"} 59 60 lookups := make(map[string]int) 61 lookupFunc := func(server string, name string, dnsType uint16) (response *dns.Msg, err error) { 62 lookups[name]++ 63 switch dnsType { 64 case dns.TypeA: 65 return makeResponse(name, dnsType, dns.RcodeSuccess, []dns.RR{ 66 &dns.CNAME{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypeCNAME, Class: dns.ClassINET, Ttl: 20}, Target: "something.else."}, 67 &dns.A{Hdr: dns.RR_Header{Name: "something.else.", Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 60}, A: net.ParseIP("1.1.1.1")}, 68 &dns.A{Hdr: dns.RR_Header{Name: "something.else.", Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 60}, A: net.ParseIP("2.2.2.2")}, 69 }), nil 70 case dns.TypeAAAA: 71 return makeResponse(name, dnsType, dns.RcodeSuccess, []dns.RR{ 72 &dns.CNAME{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypeCNAME, Class: dns.ClassINET, Ttl: 10}, Target: "something.else."}, 73 &dns.AAAA{Hdr: dns.RR_Header{Name: "something.else.", Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 60}, AAAA: net.ParseIP("cafe::face")}, 74 &dns.AAAA{Hdr: dns.RR_Header{Name: "something.else.", Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 60}, AAAA: net.ParseIP("face::cafe")}, 75 }), nil 76 77 default: 78 return makeResponse(name, dnsType, dns.RcodeRefused, nil), nil 79 } 80 } 81 82 responses, errors := doResolverLogic(lookupFunc, dnsNames) 83 c.Assert(len(errors), Equals, 0, Commentf("Returned unexpected errors for some names: %v", errors)) 84 c.Assert(len(responses), Equals, len(dnsNames), Commentf("Did not return results for all query names")) 85 c.Assert(len(lookups), Equals, len(dnsNames), Commentf("Did not do a lookup for all names")) 86 for name, ans := range responses { 87 c.Assert(lookups[name], Equals, 2, Commentf("More than 2 expected lookups (A & AAAA) for %s: %v", name, lookups)) 88 89 c.Assert(len(ans.IPs), Equals, 4, Commentf("Incorrect number of IPs returned from lookups")) 90 for i, correctIP := range []string{"1.1.1.1", "2.2.2.2", "cafe::face", "face::cafe"} { 91 c.Assert(ans.IPs[i].String(), Equals, correctIP, Commentf("Incorrect IP returned")) 92 } 93 94 c.Assert(ans.TTL, Equals, 10, Commentf("TTL is not the smallest of all A, AAAA, and CNAME records")) 95 } 96 } 97 98 // TestDNSResolverNextServerOnError tests that DNSLookupDefaultResolver should: 99 // test that we skip to next server on error 100 func (ds *FQDNTestSuite) TestDNSResolverNextServerOnError(c *C) { 101 dnsNames := []string{"a.com"} 102 103 lookups := make(map[string]int) 104 lookupFunc := func(server string, name string, dnsType uint16) (response *dns.Msg, err error) { 105 lookups[server]++ 106 107 // Return an error on the first lookup, then work correctly 108 if len(lookups) == 1 { 109 return nil, errors.New("test error") 110 111 } 112 113 switch dnsType { 114 case dns.TypeA: 115 return makeResponse(name, dnsType, dns.RcodeSuccess, []dns.RR{ 116 &dns.A{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 30}, A: net.ParseIP("1.1.1.1")}, 117 &dns.A{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 30}, A: net.ParseIP("2.2.2.2")}, 118 }), nil 119 case dns.TypeAAAA: 120 return makeResponse(name, dnsType, dns.RcodeSuccess, []dns.RR{ 121 &dns.AAAA{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 60}, AAAA: net.ParseIP("cafe::face")}, 122 &dns.AAAA{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 60}, AAAA: net.ParseIP("face::cafe")}, 123 }), nil 124 } 125 126 return nil, fmt.Errorf("Unhandled DNS query type: %v", dnsType) 127 } 128 129 responses, errors := doResolverLogic(lookupFunc, dnsNames) 130 c.Assert(len(errors), Equals, 0, Commentf("Returned incorrect number of errors(cleared on success): %v", errors)) 131 c.Assert(len(lookups), Equals, len(dnsConfig.Servers), Commentf("Did not query 2/2 DNS servers (expected due to test-induced error): %v", lookups)) 132 c.Assert(lookups[dnsConfig.Servers[0]+":"+dnsConfig.Port], Equals, 2, Commentf("First server in list not queried enough times (1 error, 1 success): %v", lookups)) 133 c.Assert(lookups[dnsConfig.Servers[1]+":"+dnsConfig.Port], Equals, 1, Commentf("Second server in list not queried enough times (1 success from failover): %v", lookups)) 134 for _, ans := range responses { 135 c.Assert(len(ans.IPs), Equals, 4, Commentf("Incorrect number of IPs returned from lookups")) 136 for i, correctIP := range []string{"1.1.1.1", "2.2.2.2", "cafe::face", "face::cafe"} { 137 c.Assert(ans.IPs[i].String(), Equals, correctIP, Commentf("Incorrect IP returned")) 138 } 139 140 c.Assert(ans.TTL, Equals, 30, Commentf("TTL is not the smallest of all A, AAAA, and CNAME records")) 141 } 142 143 }