package resolver import ( "fmt" "net" "linum/internal/dns" ) type Forwarder struct { upstream string } func NewForwarder(upstream string) *Forwarder { return &Forwarder{upstream: upstream} } func (f *Forwarder) Resolve(query *dns.Msg) (*dns.Msg, error) { query.Header.SetRD(true) wire, err := dns.Pack(query) if err != nil { return nil, fmt.Errorf("pack: %w", err) } conn, err := net.Dial("udp", f.upstream) if err != nil { return nil, fmt.Errorf("dial %s: %w", f.upstream, err) } defer conn.Close() if _, err := conn.Write(wire); err != nil { return nil, fmt.Errorf("write: %w", err) } buf := make([]byte, 4096) n, err := conn.Read(buf) if err != nil { return nil, fmt.Errorf("read: %w", err) } resp, err := dns.Unpack(buf[:n]) if err != nil { return nil, fmt.Errorf("unpack response: $w", err) } return resp, nil }