3 files changed,
78 insertions(+),
16 deletions(-)
Author:
Oleksandr Smirnov
olexsmir@gmail.com
Committed at:
2026-03-26 18:19:02 +0200
Change ID:
pnxluqsomvqylquousnzqttxttptwuvo
Parent:
7075724
jump to
| M | dns-server/main.go |
| M | dns-server/question.go |
| M | dns-server/record.go |
M
dns-server/main.go
··· 8 8 ) 9 9 10 10 func main() { 11 - qname := "google.com" 11 + qname := "olexsmir.xyz" 12 12 server := "8.8.8.8:53" 13 13 14 14 conn, _ := net.Dial("udp", server) ··· 19 19 p.Header.RecursionDesired = true 20 20 p.Questions = append(p.Questions, Question{ 21 21 Name: qname, 22 - Type: 1, // A 22 + Type: AType, 23 23 Class: 1, // IN 24 24 }) 25 25
M
dns-server/record.go
··· 19 19 ) 20 20 21 21 type Record struct { 22 - Name string 23 - Type QueryType 24 - Class uint16 25 - TTL uint32 26 - Data string 22 + Name string 23 + Type QueryType 24 + Class uint16 25 + TTL uint32 26 + Data string 27 + Priority uint16 27 28 } 28 29 29 30 func ReadRecord(r *bytes.Reader, packet []byte) (Record, error) { ··· 41 42 _ = binary.Read(r, binary.BigEndian, &rdlen) 42 43 43 44 var data string 45 + var priority uint16 44 46 switch rtype { 45 47 case AType: 46 48 var ip [4]byte 47 49 _, _ = r.Read(ip[:]) 48 - data = fmt.Sprintf("%d.%d.%d.%d", 49 - ip[0], ip[1], ip[2], ip[3]) 50 + data = net.IP(ip[:]).String() 51 + 52 + case AAAAType: 53 + var ip [16]byte 54 + _, _ = r.Read(ip[:]) 55 + data = net.IP(ip[:]).String() 56 + 57 + case NSType, CNAMEType: 58 + data, _ = readName(r, packet) 59 + 60 + case MXType: 61 + var pri uint16 62 + _ = binary.Read(r, binary.BigEndian, &pri) 63 + host, _ := readName(r, packet) 64 + priority = pri 65 + data = host 50 66 51 67 default: 52 68 buf := make([]byte, rdlen) ··· 55 71 } 56 72 57 73 return Record{ 58 - Name: name, 59 - Type: rtype, 60 - Class: class, 61 - TTL: ttl, 62 - Data: data, 74 + Name: name, 75 + Type: rtype, 76 + Class: class, 77 + TTL: ttl, 78 + Data: data, 79 + Priority: priority, 63 80 }, nil 64 81 } 65 82 ··· 80 97 81 98 _, _ = b.Write(ip) 82 99 100 + case AAAAType: 101 + _ = writeName(b, r.Name) 102 + _ = binary.Write(b, binary.BigEndian, r.Type) 103 + _ = binary.Write(b, binary.BigEndian, r.Class) 104 + _ = binary.Write(b, binary.BigEndian, r.TTL) 105 + _ = binary.Write(b, binary.BigEndian, uint16(16)) 106 + 107 + ip := net.ParseIP(r.Data).To16() 108 + if ip == nil { 109 + return 0, fmt.Errorf("invalid IPv6 address: %s", r.Data) 110 + } 111 + 112 + _, _ = b.Write(ip) 113 + 114 + case NSType, CNAMEType: 115 + _ = writeName(b, r.Name) 116 + _ = binary.Write(b, binary.BigEndian, r.Type) 117 + _ = binary.Write(b, binary.BigEndian, r.Class) 118 + _ = binary.Write(b, binary.BigEndian, r.TTL) 119 + 120 + encoded := encodeName(r.Data) 121 + _ = binary.Write(b, binary.BigEndian, uint16(len(encoded))) 122 + _, _ = b.Write(encoded) 123 + 124 + case MXType: 125 + _ = writeName(b, r.Name) 126 + _ = binary.Write(b, binary.BigEndian, r.Type) 127 + _ = binary.Write(b, binary.BigEndian, r.Class) 128 + _ = binary.Write(b, binary.BigEndian, r.TTL) 129 + 130 + encoded := encodeName(r.Data) 131 + _ = binary.Write(b, binary.BigEndian, uint16(2+len(encoded))) 132 + _ = binary.Write(b, binary.BigEndian, uint16(r.Priority)) 133 + _, _ = b.Write(encoded) 134 + 83 135 default: 84 136 fmt.Printf("Skipping record: %+v\n", r) 85 137 } ··· 119 171 labels = append(labels, string(buf)) 120 172 } 121 173 return strings.Join(labels, "."), nil 174 +} 175 + 176 +func encodeName(name string) []byte { 177 + var b bytes.Buffer 178 + for label := range strings.SplitSeq(name, ".") { 179 + _ = b.WriteByte(byte(len(label))) 180 + _, _ = b.WriteString(label) 181 + } 182 + _ = b.WriteByte(0) 183 + return b.Bytes() 122 184 } 123 185 124 186 // TODO: wrap the Buffer, to have the len == 512 guard