mirror of
https://github.com/daeuniverse/dae.git
synced 2025-07-14 17:59:57 +07:00
refactor(dns): replace dnsmessage with miekg/dns (#188)
This commit is contained in:
@ -6,98 +6,44 @@
|
||||
package control
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"hash/fnv"
|
||||
"math/rand"
|
||||
"net/netip"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/net/dns/dnsmessage"
|
||||
dnsmessage "github.com/miekg/dns"
|
||||
)
|
||||
|
||||
// FlipDnsQuestionCase is used to reduce dns pollution.
|
||||
func FlipDnsQuestionCase(dm *dnsmessage.Message) {
|
||||
if len(dm.Questions) == 0 {
|
||||
return
|
||||
}
|
||||
q := &dm.Questions[0]
|
||||
// For reproducibility, we use dm.ID as input and add some entropy to make the results more discrete.
|
||||
h := fnv.New64()
|
||||
var buf [4]byte
|
||||
binary.BigEndian.PutUint16(buf[:], dm.ID)
|
||||
h.Write(buf[:2])
|
||||
binary.BigEndian.PutUint32(buf[:], 20230204) // entropy
|
||||
h.Write(buf[:])
|
||||
r := rand.New(rand.NewSource(int64(h.Sum64())))
|
||||
perm := r.Perm(int(q.Name.Length))
|
||||
for i := 0; i < int(q.Name.Length/3); i++ {
|
||||
j := perm[i]
|
||||
// Upper to lower; lower to upper.
|
||||
if q.Name.Data[j] >= 'a' && q.Name.Data[j] <= 'z' {
|
||||
q.Name.Data[j] -= 'a' - 'A'
|
||||
} else if q.Name.Data[j] >= 'A' && q.Name.Data[j] <= 'Z' {
|
||||
q.Name.Data[j] += 'a' - 'A'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// EnsureAdditionalOpt makes sure there is additional record OPT in the request.
|
||||
func EnsureAdditionalOpt(dm *dnsmessage.Message, isReqAdd bool) (bool, error) {
|
||||
// Check healthy resp.
|
||||
if isReqAdd == dm.Response || dm.RCode != dnsmessage.RCodeSuccess || len(dm.Questions) == 0 {
|
||||
return false, UnsupportedQuestionTypeError
|
||||
}
|
||||
q := dm.Questions[0]
|
||||
switch q.Type {
|
||||
case dnsmessage.TypeA, dnsmessage.TypeAAAA:
|
||||
default:
|
||||
return false, UnsupportedQuestionTypeError
|
||||
}
|
||||
|
||||
for _, ad := range dm.Additionals {
|
||||
if ad.Header.Type == dnsmessage.TypeOPT {
|
||||
// Already has additional record OPT.
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
if !isReqAdd {
|
||||
return false, nil
|
||||
}
|
||||
// Add one.
|
||||
dm.Additionals = append(dm.Additionals, dnsmessage.Resource{
|
||||
Header: dnsmessage.ResourceHeader{
|
||||
Name: dnsmessage.MustNewName("."),
|
||||
Type: dnsmessage.TypeOPT,
|
||||
Class: 512, TTL: 0, Length: 0,
|
||||
},
|
||||
Body: &dnsmessage.OPTResource{
|
||||
Options: nil,
|
||||
},
|
||||
})
|
||||
return false, nil
|
||||
}
|
||||
|
||||
type RscWrapper struct {
|
||||
Rsc dnsmessage.Resource
|
||||
Rsc dnsmessage.RR
|
||||
}
|
||||
|
||||
func (w RscWrapper) String() string {
|
||||
var strBody string
|
||||
switch body := w.Rsc.Body.(type) {
|
||||
case *dnsmessage.AResource:
|
||||
strBody = netip.AddrFrom4(body.A).String()
|
||||
case *dnsmessage.AAAAResource:
|
||||
strBody = netip.AddrFrom16(body.AAAA).String()
|
||||
switch body := w.Rsc.(type) {
|
||||
case *dnsmessage.A:
|
||||
strBody = body.A.String()
|
||||
case *dnsmessage.AAAA:
|
||||
strBody = body.AAAA.String()
|
||||
case *dnsmessage.CNAME:
|
||||
strBody = body.Target
|
||||
default:
|
||||
strBody = body.GoString()
|
||||
strBody = body.String()
|
||||
}
|
||||
return fmt.Sprintf("%v(%v): %v", w.Rsc.Header.Name.String(), w.Rsc.Header.Type.String(), strBody)
|
||||
return fmt.Sprintf("%v(%v): %v", w.Rsc.Header().Name, QtypeToString(w.Rsc.Header().Rrtype), strBody)
|
||||
}
|
||||
func FormatDnsRsc(ans []dnsmessage.Resource) string {
|
||||
|
||||
func FormatDnsRsc(ans []dnsmessage.RR) string {
|
||||
var w []string
|
||||
for _, a := range ans {
|
||||
w = append(w, RscWrapper{Rsc: a}.String())
|
||||
}
|
||||
return strings.Join(w, "; ")
|
||||
}
|
||||
|
||||
func QtypeToString(qtype uint16) string {
|
||||
str, ok := dnsmessage.TypeToString[qtype]
|
||||
if !ok {
|
||||
str = strconv.Itoa(int(qtype))
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
Reference in New Issue
Block a user