bedrocktool/dns.go

96 lines
1.8 KiB
Go

package main
import (
"fmt"
"log"
"net"
"github.com/miekg/dns"
)
var override_dns = map[string]bool{
"geo.hivebedrock.network.": true,
}
func answerQuery(remote net.Addr, req *dns.Msg) (reply *dns.Msg) {
reply = new(dns.Msg)
answered := false
for _, q := range req.Question {
switch q.Qtype {
case dns.TypeA:
log.Printf("Query for %s\n", q.Name)
if override_dns[q.Name] {
host, _, _ := net.SplitHostPort(remote.String())
remote_ip := net.ParseIP(host)
addrs, _ := net.InterfaceAddrs()
var ip string
for _, addr := range addrs {
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
if ipnet.Contains(remote_ip) {
ip = ipnet.IP.String()
}
}
}
if ip == "" {
log.Panicf("query from outside of own network??")
}
rr, err := dns.NewRR(fmt.Sprintf("%s A %s", q.Name, ip))
if err == nil {
reply.Answer = append(reply.Answer, rr)
answered = true
}
}
}
}
// forward to 1.1.1.1 if not intercepted
if !answered {
c, err := dns.DialWithTLS("tcp4", "1.1.1.1:853", nil)
if err != nil {
panic(err)
}
if err = c.WriteMsg(req); err != nil {
panic(err)
}
if reply, err = c.ReadMsg(); err != nil {
panic(err)
}
c.Close()
}
return reply
}
func dns_handler(w dns.ResponseWriter, req *dns.Msg) {
var reply *dns.Msg
switch req.Opcode {
case dns.OpcodeQuery:
reply = answerQuery(w.RemoteAddr(), req)
default:
reply = new(dns.Msg)
}
reply.SetReply(req)
w.WriteMsg(reply)
}
func init_dns() {
dns.HandleFunc(".", dns_handler)
server := &dns.Server{Addr: ":53", Net: "udp"}
go func() {
fmt.Printf("Starting dns at %s:53\n", GetLocalIP())
err := server.ListenAndServe()
defer server.Shutdown()
if err != nil {
log.Printf("Failed to start dns server: %s\n ", err.Error())
println("you may have to use bedrockconnect")
}
}()
}