-
Notifications
You must be signed in to change notification settings - Fork 35
/
rdap.go
104 lines (93 loc) · 2.16 KB
/
rdap.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
93
94
95
96
97
98
99
100
101
102
103
104
package build
import (
"encoding/json"
"fmt"
)
const ianaRDAPURL = "https://data.iana.org/rdap/dns.json"
// FetchRDAPFromIANA retrieves the map of zones to RDAP service endpoints from IANA.
func FetchRDAPFromIANA(zones map[string]*Zone) error {
res, err := Fetch(ianaRDAPURL)
if err != nil {
return err
}
defer res.Body.Close()
// The IANA bootstrap RDAP schema is an array of pairs with the first element a list of
// domains and the second element a list of RDAP service endpoints for those domains, e.g.
// {
// ...
// "services": [
// [
// ["foo", "bar", "baz"], ["https://example.com/rdap"]
// ],
// ...
// ],
// "version": "1.0"
// }
x := struct {
Services [][][]string // I'm screaming at this schema
}{}
d := json.NewDecoder(res.Body)
err = d.Decode(&x)
if err != nil {
return err
}
if len(x.Services) == 0 {
// An empty mapping implies bad data or a version change, best stop
return fmt.Errorf("empty RDAP services array")
}
for _, svc := range x.Services {
domains := svc[0]
for _, domain := range domains {
// Convert IDNA ASCII to Unicode form
domain = Normalize(domain)
z, ok := zones[domain]
if !ok {
if len(zones) > 1000 {
Trace("@{y}Unknown domain in IANA RDAP feed: %s\n", domain)
}
continue
}
z.RDAPURLs = []string{}
for _, rdapURL := range svc[1] {
if rdapURL == "" {
continue
}
normURL := NormalizeURL(rdapURL)
if normURL == "" {
Trace("@{r}invalid RDAP URL %q\n", rdapURL)
continue
}
z.RDAPURLs = append(z.RDAPURLs, normURL)
}
}
}
return nil
}
func AddRDAPURLs(zones map[string]*Zone, urls []string) {
// Normalize the input URLS
var nurls []string
for _, u := range urls {
nu := NormalizeURL(u)
if nu == "" {
Trace("@{r}skipping invalid RDAP URL %q\n", u)
continue
}
nurls = append(nurls, nu)
}
if len(nurls) == 0 {
return
}
var added, modified int
for _, z := range zones {
rus := NewSet(z.RDAPURLs...)
n := len(rus)
rus.Add(nurls...)
m := len(rus) - n
if m != 0 {
z.RDAPURLs = rus.Values()
added += m
modified++
}
}
Trace("@{.}Added %d RDAP URL(s) to %d zone(s)\n", added, modified)
}