98 lines
1.7 KiB
Go
98 lines
1.7 KiB
Go
package node
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"net"
|
|
)
|
|
|
|
type LuxDnsServer struct {
|
|
node *LuxNode
|
|
stopChan chan bool
|
|
}
|
|
|
|
func NewLuxDnsServer(node *LuxNode) *LuxDnsServer {
|
|
return &LuxDnsServer{
|
|
node: node,
|
|
stopChan: make(chan bool),
|
|
}
|
|
}
|
|
|
|
var NO = binary.BigEndian
|
|
|
|
func (sv *LuxDnsServer) HandleRequest(req []byte) []byte {
|
|
id := NO.Uint16(req[0:2])
|
|
flags := NO.Uint16(req[2:4])
|
|
qdcount := NO.Uint16(req[4:6])
|
|
ancount := NO.Uint16(req[6:8])
|
|
nscount := NO.Uint16(req[8:10])
|
|
arcount := NO.Uint16(req[10:12])
|
|
data := req[12:]
|
|
|
|
qr := flags >> 15
|
|
opcode := (flags >> 11) & 0b1111
|
|
var rcode uint16
|
|
|
|
if qr != 0 || opcode != 0 {
|
|
// throw not supported
|
|
goto reply
|
|
}
|
|
|
|
qr = 1
|
|
rcode = 4
|
|
reply:
|
|
flags |= (qr << 15) | rcode
|
|
|
|
hdr := make([]byte, 12)
|
|
NO.PutUint16(hdr[0:2], id)
|
|
NO.PutUint16(hdr[2:4], flags)
|
|
NO.PutUint16(hdr[4:6], qdcount)
|
|
NO.PutUint16(hdr[6:8], ancount)
|
|
NO.PutUint16(hdr[8:10], nscount)
|
|
NO.PutUint16(hdr[10:12], arcount)
|
|
|
|
return append(hdr, data...)
|
|
}
|
|
|
|
func (sv *LuxDnsServer) CreateFrontend(udpListen string) error {
|
|
listenAddr, err := net.ResolveUDPAddr("udp", udpListen)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
conn, err := net.ListenUDP("udp", listenAddr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
go func(sv *LuxDnsServer) {
|
|
defer conn.Close()
|
|
|
|
buf := make([]byte, 512)
|
|
|
|
for {
|
|
select {
|
|
case <-sv.stopChan:
|
|
return
|
|
default:
|
|
n, addr, err := conn.ReadFromUDP(buf)
|
|
if err != nil {
|
|
log.Debugf("failed to recv dns udp: %v\n", err)
|
|
}
|
|
|
|
res := sv.HandleRequest(buf[:n])
|
|
if len(res) > 0 {
|
|
_, err := conn.WriteToUDP(res, addr)
|
|
if err != nil {
|
|
log.Debugf("failed to send dns reply: %v\n", err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}(sv)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (sv *LuxDnsServer) Stop() {
|
|
sv.stopChan <- true
|
|
}
|