106 lines
2.1 KiB
Go
106 lines
2.1 KiB
Go
//go:build false
|
|
|
|
package utils
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
|
|
"github.com/bedrock-tool/bedrocktool/locale"
|
|
"github.com/miekg/dns"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
var overrideDNS = map[string]bool{
|
|
"geo.hivebedrock.network.": true,
|
|
}
|
|
|
|
type DNSServer struct{}
|
|
|
|
func (d *DNSServer) 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:
|
|
logrus.Infof("Query for %s", q.Name)
|
|
|
|
if overrideDNS[q.Name] {
|
|
host, _, _ := net.SplitHostPort(remote.String())
|
|
remoteIP := 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(remoteIP) {
|
|
ip = ipnet.IP.String()
|
|
}
|
|
}
|
|
}
|
|
if ip == "" {
|
|
logrus.Warn("query from outside of own network")
|
|
continue
|
|
}
|
|
|
|
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 (d *DNSServer) handler(w dns.ResponseWriter, req *dns.Msg) {
|
|
var reply *dns.Msg
|
|
|
|
switch req.Opcode {
|
|
case dns.OpcodeQuery:
|
|
reply = d.answerQuery(w.RemoteAddr(), req)
|
|
default:
|
|
reply = new(dns.Msg)
|
|
}
|
|
|
|
reply.SetReply(req)
|
|
w.WriteMsg(reply)
|
|
}
|
|
|
|
func InitDNS() {
|
|
if !Options.EnableDNS {
|
|
return
|
|
}
|
|
d := DNSServer{}
|
|
dns.HandleFunc(".", d.handler)
|
|
|
|
server := &dns.Server{Addr: ":53", Net: "udp"}
|
|
go func() {
|
|
logrus.Infof(locale.Loc("starting_dns", locale.Strmap{"Ip": GetLocalIP()}))
|
|
err := server.ListenAndServe()
|
|
defer server.Shutdown()
|
|
if err != nil {
|
|
logrus.Warnf(locale.Loc("failed_to_start_dns", locale.Strmap{"Err": err.Error()}))
|
|
logrus.Info(locale.Loc("suggest_bedrockconnect", nil))
|
|
}
|
|
}()
|
|
}
|