summaryrefslogtreecommitdiff
path: root/internal/resolver/hints.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/resolver/hints.go')
-rw-r--r--internal/resolver/hints.go49
1 files changed, 49 insertions, 0 deletions
diff --git a/internal/resolver/hints.go b/internal/resolver/hints.go
new file mode 100644
index 0000000..c7b23b4
--- /dev/null
+++ b/internal/resolver/hints.go
@@ -0,0 +1,49 @@
+package resolver
+
+import (
+ "bufio"
+ "fmt"
+ "os"
+ "strings"
+)
+
+type NS struct {
+ Name string
+ Addr string
+}
+
+func LoadHints(path string) ([]NS, error) {
+ f, err := os.Open(path)
+ if err != nil {
+ return nil, fmt.Errorf("hints file %s not found — download from https://www.internic.net/domain/named.root: %w", path, err)
+ }
+ defer f.Close()
+
+ var nsNames []string
+ glue := make(map[string]string)
+ sc := bufio.NewScanner(f)
+ for sc.Scan() {
+ fields := strings.Fields(sc.Text())
+ if len(fields) < 4 || fields[0] == ";" {
+ continue
+ }
+ if fields[0] == "." && fields[2] == "NS" {
+ nsNames = append(nsNames, fields[3])
+ }
+ if fields[2] == "A" {
+ glue[fields[0]] = fields[3]
+ }
+ }
+ if err := sc.Err(); err != nil {
+ return nil, err
+ }
+
+ var hints []NS
+ for _, name := range nsNames {
+ hints = append(hints, NS{Name: name, Addr: glue[name]})
+ }
+ if len(hints) == 0 {
+ return nil, fmt.Errorf("no root hints parsed from %s", path)
+ }
+ return hints, nil
+}