-
Notifications
You must be signed in to change notification settings - Fork 14
/
query.go
92 lines (83 loc) · 2.5 KB
/
query.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package doh
import (
"bytes"
"encoding/binary"
"math/rand"
"strings"
"time"
)
// encodeQuery creates a DNS query message from the given fqdn, type and class.
func encodeQuery(fqdn string, t DNSType, c DNSClass) []byte {
q := bytes.NewBuffer(nil)
reqID := []byte{0, 0}
r := rand.New(rand.NewSource(time.Now().Unix()))
binary.BigEndian.PutUint16(reqID, uint16(r.Int31()))
/*
DNS HEADER
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ID |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR| Opcode |AA|TC|RD|RA| Z|AD|CD| RCODE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QDCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ANCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| NSCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ARCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
*/
q.Write([]byte{
reqID[0], reqID[1],
// QR = 0 (query)
// OPCODE = 0 (standard query)
// AA ignored
// TC = 0 (not truncated)
// RD = 1 (recursion desired)
(0 << 7) | (0 << 3) | (0 << 1) | 1,
// RA ignored
// Z = 0 (reserved)
// AD = 0
// CD = 1
// RCODE ignored
(1 << 4),
// QDCOUNT = 1
byte(0), byte(1),
// ANCOUNT = 0
byte(0), byte(0),
// NSCOUNT = 0
byte(0), byte(0),
// ARCOUNT = 0
byte(0), byte(0),
})
qtype := []byte{0, 0}
binary.BigEndian.PutUint16(qtype, uint16(t))
qclass := []byte{0, 0}
binary.BigEndian.PutUint16(qclass, uint16(c))
/*
DNS QUERY
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ QNAME /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QTYPE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QCLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
*/
labels := strings.Split(fqdn, ".")
for _, l := range labels {
q.Write([]byte{byte(len(l))})
q.Write([]byte(l))
}
q.Write([]byte{0})
q.Write(qtype)
q.Write(qclass)
return q.Bytes()
}