Not finished stuff

This commit is contained in:
2025-05-01 12:34:30 +01:00
parent bf190b2396
commit 2e0042153a
6 changed files with 673 additions and 443 deletions

View File

@@ -2,64 +2,128 @@ package do53
import (
"fmt"
"log"
"net"
"sync"
"github.com/miekg/dns"
)
type Do53Client struct {
udpConn *net.UDPConn
type Config struct {
HostAndPort string
DNSSEC bool
}
func New(dest string) (*Do53Client, error) {
type Client struct {
udpAddr *net.UDPAddr
conn *net.UDPConn
udpAddr, err := net.ResolveUDPAddr("udp", dest)
if err != nil {
return nil, fmt.Errorf("failed to resolve UDP address: %v", err)
}
responseChannels map[uint16]chan *dns.Msg
responseMutex *sync.Mutex
udpConn, err := net.DialUDP("udp", nil, udpAddr)
if err != nil {
return nil, fmt.Errorf("failed to dial UDP connection: %v", err)
}
return &Do53Client{udpConn: udpConn}, nil
config Config
}
func (c *Do53Client) Close() {
if c.udpConn != nil {
c.udpConn.Close()
func New(config Config) (*Client, error) {
udpAddr, err := net.ResolveUDPAddr("udp", config.HostAndPort)
if err != nil {
return nil, fmt.Errorf("do53: failed to resolve UDP address %q: %w", config.HostAndPort, err)
}
conn, err := net.DialUDP("udp", nil, udpAddr)
if err != nil {
return nil, fmt.Errorf("do53: failed to dial UDP connection to %s: %w", config.HostAndPort, err)
}
responseChannels := map[uint16]chan *dns.Msg{}
rcMutex := new(sync.Mutex)
client := &Client{
udpAddr: udpAddr,
conn: conn,
responseChannels: responseChannels,
responseMutex: rcMutex,
config: config,
}
go client.receiveLoop()
return client, nil
}
func (c *Client) Close() {
if c.conn != nil {
c.conn.Close()
c.conn = nil
}
}
func (c *Do53Client) Query(domain, queryType, dest string, dnssec bool) error {
func (c *Client) receiveLoop() {
message, err := NewDNSMessage(domain, queryType)
if err != nil {
return err
buffer := make([]byte, dns.MaxMsgSize)
for {
// Reads one UDP Datagram
n, err := c.conn.Read(buffer)
if err != nil {
log.Printf("do53: failed to read DNS response: %s", err.Error())
}
recvMsg := new(dns.Msg)
err = recvMsg.Unpack(buffer[:n])
if err != nil {
log.Printf("do53: failed to unpack DNS response: %s", err.Error())
continue
}
c.responseMutex.Lock()
respChan, ok := c.responseChannels[recvMsg.Id]
delete(c.responseChannels, recvMsg.Id)
c.responseMutex.Unlock()
if ok {
respChan <- recvMsg
} else {
log.Printf("Receiver: Received DNS response for unknown or already processed msg ID: %v\n", recvMsg.Id)
}
}
_, err = c.udpConn.Write(message)
if err != nil {
return fmt.Errorf("failed to send DNS query: %v", err)
}
buf := make([]byte, 4096)
n, err := c.udpConn.Read(buf)
if err != nil {
return fmt.Errorf("failed to read DNS response: %v", err)
}
recvMsg := new(dns.Msg)
err = recvMsg.Unpack(buf[:n])
if err != nil {
return fmt.Errorf("failed to parse DNS response: %v", err)
}
// TODO: Check if the response had no errors or TD bit set
for _, answer := range recvMsg.Answer {
fmt.Println(answer.String())
}
return nil
}
func (c *Client) Query(domain string, queryType uint16) (*dns.Msg, error) {
msg := new(dns.Msg)
msg.SetQuestion(dns.Fqdn(domain), queryType)
msg.Id = dns.Id()
msg.RecursionDesired = true
if c.config.DNSSEC {
msg.SetEdns0(4096, true)
}
respChan := make(chan *dns.Msg)
c.responseMutex.Lock()
c.responseChannels[msg.Id] = respChan
c.responseMutex.Unlock()
packedMsg, err := msg.Pack()
if err != nil {
c.responseMutex.Lock()
delete(c.responseChannels, msg.Id)
c.responseMutex.Unlock()
return nil, fmt.Errorf("do53: failed to pack DNS message: %w", err)
}
_, err = c.conn.Write(packedMsg)
if err != nil {
c.responseMutex.Lock()
delete(c.responseChannels, msg.Id)
c.responseMutex.Unlock()
return nil, fmt.Errorf("do53: failed to send DNS query: %w", err)
}
recvMsg := <-respChan
return recvMsg, nil
}