ooni-probe-cli/internal/netxlite/dnsx/decoder.go

55 lines
1.3 KiB
Go
Raw Normal View History

package dnsx
import (
"errors"
"github.com/miekg/dns"
)
// The Decoder decodes a DNS reply into A or AAAA entries. It will use the
// provided qtype and only look for mathing entries. It will return error if
// there are no entries for the requested qtype inside the reply.
type Decoder interface {
Decode(qtype uint16, data []byte) ([]string, error)
}
// MiekgDecoder uses github.com/miekg/dns to implement the Decoder.
type MiekgDecoder struct{}
// Decode implements Decoder.Decode.
func (d *MiekgDecoder) Decode(qtype uint16, data []byte) ([]string, error) {
reply := new(dns.Msg)
if err := reply.Unpack(data); err != nil {
return nil, err
}
// TODO(bassosimone): map more errors to net.DNSError names
switch reply.Rcode {
case dns.RcodeSuccess:
case dns.RcodeNameError:
return nil, errors.New("ooniresolver: no such host")
default:
return nil, errors.New("ooniresolver: query failed")
}
var addrs []string
for _, answer := range reply.Answer {
switch qtype {
case dns.TypeA:
if rra, ok := answer.(*dns.A); ok {
ip := rra.A
addrs = append(addrs, ip.String())
}
case dns.TypeAAAA:
if rra, ok := answer.(*dns.AAAA); ok {
ip := rra.AAAA
addrs = append(addrs, ip.String())
}
}
}
if len(addrs) <= 0 {
return nil, errors.New("ooniresolver: no response returned")
}
return addrs, nil
}
var _ Decoder = &MiekgDecoder{}