...
1 package dns
2
3
4
5
6
7 func Dedup(rrs []RR, m map[string]RR) []RR {
8
9 if m == nil {
10 m = make(map[string]RR)
11 }
12
13 keys := make([]*string, 0, len(rrs))
14
15 for _, r := range rrs {
16 key := normalizedString(r)
17 keys = append(keys, &key)
18 if mr, ok := m[key]; ok {
19
20 rh, mrh := r.Header(), mr.Header()
21 if mrh.Ttl > rh.Ttl {
22 mrh.Ttl = rh.Ttl
23 }
24 continue
25 }
26
27 m[key] = r
28 }
29
30
31 if len(m) == len(rrs) {
32 return rrs
33 }
34
35 j := 0
36 for i, r := range rrs {
37
38 if _, ok := m[*keys[i]]; ok {
39 delete(m, *keys[i])
40 rrs[j] = r
41 j++
42 }
43
44 if len(m) == 0 {
45 break
46 }
47 }
48
49 return rrs[:j]
50 }
51
52
53
54
55
56 func normalizedString(r RR) string {
57
58 b := []byte(r.String())
59
60
61 esc := false
62 ttlStart, ttlEnd := 0, 0
63 for i := 0; i < len(b) && ttlEnd == 0; i++ {
64 switch {
65 case b[i] == '\\':
66 esc = !esc
67 case b[i] == '\t' && !esc:
68 if ttlStart == 0 {
69 ttlStart = i
70 continue
71 }
72 if ttlEnd == 0 {
73 ttlEnd = i
74 }
75 case b[i] >= 'A' && b[i] <= 'Z' && !esc:
76 b[i] += 32
77 default:
78 esc = false
79 }
80 }
81
82
83 copy(b[ttlStart:], b[ttlEnd:])
84 cut := ttlEnd - ttlStart
85 return string(b[:len(b)-cut])
86 }
87
View as plain text