mirror of
https://github.com/andwati/dns-resolver.git
synced 2026-10-18 02:32:52 +00:00
90 lines
1.9 KiB
Go
90 lines
1.9 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/andwati/dns-resolver/internal/dns"
|
|
"github.com/andwati/dns-resolver/internal/network"
|
|
"log"
|
|
)
|
|
|
|
func main() {
|
|
domain := "dns.google.com"
|
|
|
|
rootServer := "198.41.0.4:53"
|
|
ip, err := resolve(domain, rootServer)
|
|
if err != nil {
|
|
log.Fatalf("Failed to resolve %s: %v", domain, err)
|
|
}
|
|
|
|
fmt.Printf("Resolved %s to IP: %s\n", domain, ip)
|
|
}
|
|
|
|
func resolve(domain, nameServer string) (string, error) {
|
|
for {
|
|
fmt.Printf("Querying %s for %s\n", nameServer, domain)
|
|
|
|
header := dns.DNSHeader{
|
|
ID: dns.GenerateRandomID(),
|
|
Flags: 0,
|
|
QDCount: 1,
|
|
}
|
|
|
|
question := dns.DNSQuestion{
|
|
QName: domain,
|
|
QType: dns.QTypeA,
|
|
QClass: dns.QClassIN,
|
|
}
|
|
|
|
message := dns.DNSMessage{
|
|
Header: header,
|
|
Question: question,
|
|
}
|
|
query := message.Serialize()
|
|
|
|
response, err := network.SendDNSQuery(query, nameServer)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to send query: %w", err)
|
|
}
|
|
|
|
answers, authorities, additionals, err := dns.ParseFullResponse(response)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to parse response: %w", err)
|
|
}
|
|
|
|
for _, answer := range answers {
|
|
if answer.Type == dns.QTypeA {
|
|
return answer.Data, nil
|
|
}
|
|
if answer.Type == dns.QTypeCNAME {
|
|
domain = answer.Data
|
|
}
|
|
}
|
|
|
|
var nextNameServer string
|
|
for _, additional := range additionals {
|
|
if additional.Type == dns.QTypeA {
|
|
nextNameServer = additional.Data
|
|
break
|
|
}
|
|
}
|
|
|
|
if nextNameServer == "" && len(authorities) > 0 {
|
|
for _, authority := range authorities {
|
|
if authority.Type == dns.QTypeNS {
|
|
ns := authority.Data
|
|
nextNameServer, err = resolve(ns, "198.41.0.4:53") // Use root server for NS IP
|
|
if err == nil {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if nextNameServer == "" {
|
|
return "", fmt.Errorf("could not find next name server")
|
|
}
|
|
|
|
nameServer = nextNameServer + ":53"
|
|
}
|
|
}
|