github.com/icodeface/tls@v0.0.0-20230910023335-34df9250cd12/internal/x/net/dns/dnsmessage/example_test.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package dnsmessage_test 6 7 import ( 8 "fmt" 9 "net" 10 "strings" 11 12 "github.com/icodeface/tls/internal/x/net/dns/dnsmessage" 13 ) 14 15 func mustNewName(name string) dnsmessage.Name { 16 n, err := dnsmessage.NewName(name) 17 if err != nil { 18 panic(err) 19 } 20 return n 21 } 22 23 func ExampleParser() { 24 msg := dnsmessage.Message{ 25 Header: dnsmessage.Header{Response: true, Authoritative: true}, 26 Questions: []dnsmessage.Question{ 27 { 28 Name: mustNewName("foo.bar.example.com."), 29 Type: dnsmessage.TypeA, 30 Class: dnsmessage.ClassINET, 31 }, 32 { 33 Name: mustNewName("bar.example.com."), 34 Type: dnsmessage.TypeA, 35 Class: dnsmessage.ClassINET, 36 }, 37 }, 38 Answers: []dnsmessage.Resource{ 39 { 40 Header: dnsmessage.ResourceHeader{ 41 Name: mustNewName("foo.bar.example.com."), 42 Type: dnsmessage.TypeA, 43 Class: dnsmessage.ClassINET, 44 }, 45 Body: &dnsmessage.AResource{A: [4]byte{127, 0, 0, 1}}, 46 }, 47 { 48 Header: dnsmessage.ResourceHeader{ 49 Name: mustNewName("bar.example.com."), 50 Type: dnsmessage.TypeA, 51 Class: dnsmessage.ClassINET, 52 }, 53 Body: &dnsmessage.AResource{A: [4]byte{127, 0, 0, 2}}, 54 }, 55 }, 56 } 57 58 buf, err := msg.Pack() 59 if err != nil { 60 panic(err) 61 } 62 63 wantName := "bar.example.com." 64 65 var p dnsmessage.Parser 66 if _, err := p.Start(buf); err != nil { 67 panic(err) 68 } 69 70 for { 71 q, err := p.Question() 72 if err == dnsmessage.ErrSectionDone { 73 break 74 } 75 if err != nil { 76 panic(err) 77 } 78 79 if q.Name.String() != wantName { 80 continue 81 } 82 83 fmt.Println("Found question for name", wantName) 84 if err := p.SkipAllQuestions(); err != nil { 85 panic(err) 86 } 87 break 88 } 89 90 var gotIPs []net.IP 91 for { 92 h, err := p.AnswerHeader() 93 if err == dnsmessage.ErrSectionDone { 94 break 95 } 96 if err != nil { 97 panic(err) 98 } 99 100 if (h.Type != dnsmessage.TypeA && h.Type != dnsmessage.TypeAAAA) || h.Class != dnsmessage.ClassINET { 101 continue 102 } 103 104 if !strings.EqualFold(h.Name.String(), wantName) { 105 if err := p.SkipAnswer(); err != nil { 106 panic(err) 107 } 108 continue 109 } 110 111 switch h.Type { 112 case dnsmessage.TypeA: 113 r, err := p.AResource() 114 if err != nil { 115 panic(err) 116 } 117 gotIPs = append(gotIPs, r.A[:]) 118 case dnsmessage.TypeAAAA: 119 r, err := p.AAAAResource() 120 if err != nil { 121 panic(err) 122 } 123 gotIPs = append(gotIPs, r.AAAA[:]) 124 } 125 } 126 127 fmt.Printf("Found A/AAAA records for name %s: %v\n", wantName, gotIPs) 128 129 // Output: 130 // Found question for name bar.example.com. 131 // Found A/AAAA records for name bar.example.com.: [127.0.0.2] 132 }