refactor(dnsx): prepare for merging with netxlite (#515)

Part of https://github.com/ooni/probe/issues/1591
This commit is contained in:
Simone Basso 2021-09-28 10:47:59 +02:00 committed by GitHub
parent 8b9fe1a160
commit 12cf4b9990
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 92 additions and 92 deletions

View File

@ -19,9 +19,9 @@ type (
DNSOverHTTPS = dnsx.DNSOverHTTPS DNSOverHTTPS = dnsx.DNSOverHTTPS
DNSOverTCP = dnsx.DNSOverTCP DNSOverTCP = dnsx.DNSOverTCP
DNSOverUDP = dnsx.DNSOverUDP DNSOverUDP = dnsx.DNSOverUDP
MiekgEncoder = dnsx.MiekgEncoder MiekgEncoder = dnsx.DNSEncoderMiekg
MiekgDecoder = dnsx.MiekgDecoder MiekgDecoder = dnsx.DNSDecoderMiekg
RoundTripper = dnsx.RoundTripper RoundTripper = dnsx.DNSTransport
SerialResolver = dnsx.SerialResolver SerialResolver = dnsx.SerialResolver
Dialer = dnsx.Dialer Dialer = dnsx.Dialer
DialContextFunc = dnsx.DialContextFunc DialContextFunc = dnsx.DialContextFunc

View File

@ -9,8 +9,8 @@ import (
// HTTPSSvc is an HTTPSSvc reply. // HTTPSSvc is an HTTPSSvc reply.
type HTTPSSvc = model.HTTPSSvc type HTTPSSvc = model.HTTPSSvc
// The Decoder decodes DNS replies. // The DNSDecoder decodes DNS replies.
type Decoder interface { type DNSDecoder interface {
// DecodeLookupHost decodes an A or AAAA reply. // DecodeLookupHost decodes an A or AAAA reply.
DecodeLookupHost(qtype uint16, data []byte) ([]string, error) DecodeLookupHost(qtype uint16, data []byte) ([]string, error)
@ -18,10 +18,10 @@ type Decoder interface {
DecodeHTTPS(data []byte) (*HTTPSSvc, error) DecodeHTTPS(data []byte) (*HTTPSSvc, error)
} }
// MiekgDecoder uses github.com/miekg/dns to implement the Decoder. // DNSDecoderMiekg uses github.com/miekg/dns to implement the Decoder.
type MiekgDecoder struct{} type DNSDecoderMiekg struct{}
func (d *MiekgDecoder) parseReply(data []byte) (*dns.Msg, error) { func (d *DNSDecoderMiekg) parseReply(data []byte) (*dns.Msg, error) {
reply := new(dns.Msg) reply := new(dns.Msg)
if err := reply.Unpack(data); err != nil { if err := reply.Unpack(data); err != nil {
return nil, err return nil, err
@ -40,7 +40,7 @@ func (d *MiekgDecoder) parseReply(data []byte) (*dns.Msg, error) {
} }
} }
func (d *MiekgDecoder) DecodeHTTPS(data []byte) (*HTTPSSvc, error) { func (d *DNSDecoderMiekg) DecodeHTTPS(data []byte) (*HTTPSSvc, error) {
reply, err := d.parseReply(data) reply, err := d.parseReply(data)
if err != nil { if err != nil {
return nil, err return nil, err
@ -71,7 +71,7 @@ func (d *MiekgDecoder) DecodeHTTPS(data []byte) (*HTTPSSvc, error) {
return out, nil return out, nil
} }
func (d *MiekgDecoder) DecodeLookupHost(qtype uint16, data []byte) ([]string, error) { func (d *DNSDecoderMiekg) DecodeLookupHost(qtype uint16, data []byte) ([]string, error) {
reply, err := d.parseReply(data) reply, err := d.parseReply(data)
if err != nil { if err != nil {
return nil, err return nil, err
@ -97,4 +97,4 @@ func (d *MiekgDecoder) DecodeLookupHost(qtype uint16, data []byte) ([]string, er
return addrs, nil return addrs, nil
} }
var _ Decoder = &MiekgDecoder{} var _ DNSDecoder = &DNSDecoderMiekg{}

View File

@ -12,7 +12,7 @@ import (
) )
func TestDecoderUnpackError(t *testing.T) { func TestDecoderUnpackError(t *testing.T) {
d := &MiekgDecoder{} d := &DNSDecoderMiekg{}
data, err := d.DecodeLookupHost(dns.TypeA, nil) data, err := d.DecodeLookupHost(dns.TypeA, nil)
if err == nil { if err == nil {
t.Fatal("expected an error here") t.Fatal("expected an error here")
@ -23,7 +23,7 @@ func TestDecoderUnpackError(t *testing.T) {
} }
func TestDecoderNXDOMAIN(t *testing.T) { func TestDecoderNXDOMAIN(t *testing.T) {
d := &MiekgDecoder{} d := &DNSDecoderMiekg{}
data, err := d.DecodeLookupHost(dns.TypeA, genReplyError(t, dns.RcodeNameError)) data, err := d.DecodeLookupHost(dns.TypeA, genReplyError(t, dns.RcodeNameError))
if err == nil || !strings.HasSuffix(err.Error(), "no such host") { if err == nil || !strings.HasSuffix(err.Error(), "no such host") {
t.Fatal("not the error we expected", err) t.Fatal("not the error we expected", err)
@ -34,7 +34,7 @@ func TestDecoderNXDOMAIN(t *testing.T) {
} }
func TestDecoderRefusedError(t *testing.T) { func TestDecoderRefusedError(t *testing.T) {
d := &MiekgDecoder{} d := &DNSDecoderMiekg{}
data, err := d.DecodeLookupHost(dns.TypeA, genReplyError(t, dns.RcodeRefused)) data, err := d.DecodeLookupHost(dns.TypeA, genReplyError(t, dns.RcodeRefused))
if !errors.Is(err, errorsx.ErrOODNSRefused) { if !errors.Is(err, errorsx.ErrOODNSRefused) {
t.Fatal("not the error we expected", err) t.Fatal("not the error we expected", err)
@ -45,7 +45,7 @@ func TestDecoderRefusedError(t *testing.T) {
} }
func TestDecoderNoAddress(t *testing.T) { func TestDecoderNoAddress(t *testing.T) {
d := &MiekgDecoder{} d := &DNSDecoderMiekg{}
data, err := d.DecodeLookupHost(dns.TypeA, genReplySuccess(t, dns.TypeA)) data, err := d.DecodeLookupHost(dns.TypeA, genReplySuccess(t, dns.TypeA))
if !errors.Is(err, errorsx.ErrOODNSNoAnswer) { if !errors.Is(err, errorsx.ErrOODNSNoAnswer) {
t.Fatal("not the error we expected", err) t.Fatal("not the error we expected", err)
@ -56,7 +56,7 @@ func TestDecoderNoAddress(t *testing.T) {
} }
func TestDecoderDecodeA(t *testing.T) { func TestDecoderDecodeA(t *testing.T) {
d := &MiekgDecoder{} d := &DNSDecoderMiekg{}
data, err := d.DecodeLookupHost( data, err := d.DecodeLookupHost(
dns.TypeA, genReplySuccess(t, dns.TypeA, "1.1.1.1", "8.8.8.8")) dns.TypeA, genReplySuccess(t, dns.TypeA, "1.1.1.1", "8.8.8.8"))
if err != nil { if err != nil {
@ -74,7 +74,7 @@ func TestDecoderDecodeA(t *testing.T) {
} }
func TestDecoderDecodeAAAA(t *testing.T) { func TestDecoderDecodeAAAA(t *testing.T) {
d := &MiekgDecoder{} d := &DNSDecoderMiekg{}
data, err := d.DecodeLookupHost( data, err := d.DecodeLookupHost(
dns.TypeAAAA, genReplySuccess(t, dns.TypeAAAA, "::1", "fe80::1")) dns.TypeAAAA, genReplySuccess(t, dns.TypeAAAA, "::1", "fe80::1"))
if err != nil { if err != nil {
@ -92,7 +92,7 @@ func TestDecoderDecodeAAAA(t *testing.T) {
} }
func TestDecoderUnexpectedAReply(t *testing.T) { func TestDecoderUnexpectedAReply(t *testing.T) {
d := &MiekgDecoder{} d := &DNSDecoderMiekg{}
data, err := d.DecodeLookupHost( data, err := d.DecodeLookupHost(
dns.TypeA, genReplySuccess(t, dns.TypeAAAA, "::1", "fe80::1")) dns.TypeA, genReplySuccess(t, dns.TypeAAAA, "::1", "fe80::1"))
if !errors.Is(err, errorsx.ErrOODNSNoAnswer) { if !errors.Is(err, errorsx.ErrOODNSNoAnswer) {
@ -104,7 +104,7 @@ func TestDecoderUnexpectedAReply(t *testing.T) {
} }
func TestDecoderUnexpectedAAAAReply(t *testing.T) { func TestDecoderUnexpectedAAAAReply(t *testing.T) {
d := &MiekgDecoder{} d := &DNSDecoderMiekg{}
data, err := d.DecodeLookupHost( data, err := d.DecodeLookupHost(
dns.TypeAAAA, genReplySuccess(t, dns.TypeA, "1.1.1.1", "8.8.4.4.")) dns.TypeAAAA, genReplySuccess(t, dns.TypeA, "1.1.1.1", "8.8.4.4."))
if !errors.Is(err, errorsx.ErrOODNSNoAnswer) { if !errors.Is(err, errorsx.ErrOODNSNoAnswer) {
@ -184,7 +184,7 @@ func genReplySuccess(t *testing.T, qtype uint16, ips ...string) []byte {
} }
func TestParseReply(t *testing.T) { func TestParseReply(t *testing.T) {
d := &MiekgDecoder{} d := &DNSDecoderMiekg{}
msg := &dns.Msg{} msg := &dns.Msg{}
msg.Rcode = dns.RcodeFormatError // an rcode we don't handle msg.Rcode = dns.RcodeFormatError // an rcode we don't handle
data, err := msg.Pack() data, err := msg.Pack()
@ -265,7 +265,7 @@ func genReplyHTTPS(t *testing.T, alpns, ipv4, ipv6 []string) []byte {
func TestDecodeHTTPS(t *testing.T) { func TestDecodeHTTPS(t *testing.T) {
t.Run("with nil data", func(t *testing.T) { t.Run("with nil data", func(t *testing.T) {
d := &MiekgDecoder{} d := &DNSDecoderMiekg{}
reply, err := d.DecodeHTTPS(nil) reply, err := d.DecodeHTTPS(nil)
if err == nil || err.Error() != "dns: overflow unpacking uint16" { if err == nil || err.Error() != "dns: overflow unpacking uint16" {
t.Fatal("not the error we expected", err) t.Fatal("not the error we expected", err)
@ -277,7 +277,7 @@ func TestDecodeHTTPS(t *testing.T) {
t.Run("with empty answer", func(t *testing.T) { t.Run("with empty answer", func(t *testing.T) {
data := genReplyHTTPS(t, nil, nil, nil) data := genReplyHTTPS(t, nil, nil, nil)
d := &MiekgDecoder{} d := &DNSDecoderMiekg{}
reply, err := d.DecodeHTTPS(data) reply, err := d.DecodeHTTPS(data)
if !errors.Is(err, errorsx.ErrOODNSNoAnswer) { if !errors.Is(err, errorsx.ErrOODNSNoAnswer) {
t.Fatal("unexpected err", err) t.Fatal("unexpected err", err)
@ -292,7 +292,7 @@ func TestDecodeHTTPS(t *testing.T) {
v4 := []string{"1.1.1.1"} v4 := []string{"1.1.1.1"}
v6 := []string{"::1"} v6 := []string{"::1"}
data := genReplyHTTPS(t, alpn, v4, v6) data := genReplyHTTPS(t, alpn, v4, v6)
d := &MiekgDecoder{} d := &DNSDecoderMiekg{}
reply, err := d.DecodeHTTPS(data) reply, err := d.DecodeHTTPS(data)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

View File

@ -2,27 +2,27 @@ package dnsx
import "github.com/miekg/dns" import "github.com/miekg/dns"
// The Encoder encodes DNS queries to bytes // The DNSEncoder encodes DNS queries to bytes
type Encoder interface { type DNSEncoder interface {
Encode(domain string, qtype uint16, padding bool) ([]byte, error) Encode(domain string, qtype uint16, padding bool) ([]byte, error)
} }
// MiekgEncoder uses github.com/miekg/dns to implement the Encoder. // DNSEncoderMiekg uses github.com/miekg/dns to implement the Encoder.
type MiekgEncoder struct{} type DNSEncoderMiekg struct{}
const ( const (
// PaddingDesiredBlockSize is the size that the padded query should be multiple of // dnsPaddingDesiredBlockSize is the size that the padded query should be multiple of
PaddingDesiredBlockSize = 128 dnsPaddingDesiredBlockSize = 128
// EDNS0MaxResponseSize is the maximum response size for EDNS0 // dnsEDNS0MaxResponseSize is the maximum response size for EDNS0
EDNS0MaxResponseSize = 4096 dnsEDNS0MaxResponseSize = 4096
// DNSSECEnabled turns on support for DNSSEC when using EDNS0 // dnsDNSSECEnabled turns on support for DNSSEC when using EDNS0
DNSSECEnabled = true dnsDNSSECEnabled = true
) )
// Encode implements Encoder.Encode // Encode implements Encoder.Encode
func (e *MiekgEncoder) Encode(domain string, qtype uint16, padding bool) ([]byte, error) { func (e *DNSEncoderMiekg) Encode(domain string, qtype uint16, padding bool) ([]byte, error) {
question := dns.Question{ question := dns.Question{
Name: dns.Fqdn(domain), Name: dns.Fqdn(domain),
Qtype: qtype, Qtype: qtype,
@ -34,14 +34,14 @@ func (e *MiekgEncoder) Encode(domain string, qtype uint16, padding bool) ([]byte
query.Question = make([]dns.Question, 1) query.Question = make([]dns.Question, 1)
query.Question[0] = question query.Question[0] = question
if padding { if padding {
query.SetEdns0(EDNS0MaxResponseSize, DNSSECEnabled) query.SetEdns0(dnsEDNS0MaxResponseSize, dnsDNSSECEnabled)
// Clients SHOULD pad queries to the closest multiple of // Clients SHOULD pad queries to the closest multiple of
// 128 octets RFC8467#section-4.1. We inflate the query // 128 octets RFC8467#section-4.1. We inflate the query
// length by the size of the option (i.e. 4 octets). The // length by the size of the option (i.e. 4 octets). The
// cast to uint is necessary to make the modulus operation // cast to uint is necessary to make the modulus operation
// work as intended when the desiredBlockSize is smaller // work as intended when the desiredBlockSize is smaller
// than (query.Len()+4) ¯\_(ツ)_/¯. // than (query.Len()+4) ¯\_(ツ)_/¯.
remainder := (PaddingDesiredBlockSize - uint(query.Len()+4)) % PaddingDesiredBlockSize remainder := (dnsPaddingDesiredBlockSize - uint(query.Len()+4)) % dnsPaddingDesiredBlockSize
opt := new(dns.EDNS0_PADDING) opt := new(dns.EDNS0_PADDING)
opt.Padding = make([]byte, remainder) opt.Padding = make([]byte, remainder)
query.IsEdns0().Option = append(query.IsEdns0().Option, opt) query.IsEdns0().Option = append(query.IsEdns0().Option, opt)
@ -49,4 +49,4 @@ func (e *MiekgEncoder) Encode(domain string, qtype uint16, padding bool) ([]byte
return query.Pack() return query.Pack()
} }
var _ Encoder = &MiekgEncoder{} var _ DNSEncoder = &DNSEncoderMiekg{}

View File

@ -8,7 +8,7 @@ import (
) )
func TestEncoderEncodeA(t *testing.T) { func TestEncoderEncodeA(t *testing.T) {
e := &MiekgEncoder{} e := &DNSEncoderMiekg{}
data, err := e.Encode("x.org", dns.TypeA, false) data, err := e.Encode("x.org", dns.TypeA, false)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -17,7 +17,7 @@ func TestEncoderEncodeA(t *testing.T) {
} }
func TestEncoderEncodeAAAA(t *testing.T) { func TestEncoderEncodeAAAA(t *testing.T) {
e := &MiekgEncoder{} e := &DNSEncoderMiekg{}
data, err := e.Encode("x.org", dns.TypeAAAA, false) data, err := e.Encode("x.org", dns.TypeAAAA, false)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -67,7 +67,7 @@ func TestEncoderPadding(t *testing.T) {
// The purpose of this unit test is to make sure that for a wide // The purpose of this unit test is to make sure that for a wide
// array of values we obtain the right query size. // array of values we obtain the right query size.
getquerylen := func(domainlen int, padding bool) int { getquerylen := func(domainlen int, padding bool) int {
e := &MiekgEncoder{} e := &DNSEncoderMiekg{}
data, err := e.Encode( data, err := e.Encode(
// This is not a valid name because it ends up being way // This is not a valid name because it ends up being way
// longer than 255 octets. However, the library is allowing // longer than 255 octets. However, the library is allowing
@ -88,7 +88,7 @@ func TestEncoderPadding(t *testing.T) {
if vanillalen < domainlen { if vanillalen < domainlen {
t.Fatal("vanillalen is smaller than domainlen") t.Fatal("vanillalen is smaller than domainlen")
} }
if (paddedlen % PaddingDesiredBlockSize) != 0 { if (paddedlen % dnsPaddingDesiredBlockSize) != 0 {
t.Fatal("paddedlen is not a multiple of PaddingDesiredBlockSize") t.Fatal("paddedlen is not a multiple of PaddingDesiredBlockSize")
} }
if paddedlen < vanillalen { if paddedlen < vanillalen {

View File

@ -86,4 +86,4 @@ func (t *DNSOverHTTPS) CloseIdleConnections() {
t.Client.CloseIdleConnections() t.Client.CloseIdleConnections()
} }
var _ RoundTripper = &DNSOverHTTPS{} var _ DNSTransport = &DNSOverHTTPS{}

View File

@ -99,4 +99,4 @@ func (t *DNSOverTCP) CloseIdleConnections() {
// nothing to do // nothing to do
} }
var _ RoundTripper = &DNSOverTCP{} var _ DNSTransport = &DNSOverTCP{}

View File

@ -66,4 +66,4 @@ func (t *DNSOverUDP) CloseIdleConnections() {
// nothing to do // nothing to do
} }
var _ RoundTripper = &DNSOverUDP{} var _ DNSTransport = &DNSOverUDP{}

View File

@ -2,8 +2,8 @@ package dnsx
import "context" import "context"
// RoundTripper represents an abstract DNS transport. // DNSTransport represents an abstract DNS transport.
type RoundTripper interface { type DNSTransport interface {
// RoundTrip sends a DNS query and receives the reply. // RoundTrip sends a DNS query and receives the reply.
RoundTrip(ctx context.Context, query []byte) (reply []byte, err error) RoundTrip(ctx context.Context, query []byte) (reply []byte, err error)

View File

@ -5,19 +5,19 @@ import "github.com/ooni/probe-cli/v3/internal/netxlite/dnsx/model"
// HTTPSSvc is the result of HTTPS queries. // HTTPSSvc is the result of HTTPS queries.
type HTTPSSvc = model.HTTPSSvc type HTTPSSvc = model.HTTPSSvc
// Decoder allows mocking dnsx.Decoder. // DNSDecoder allows mocking dnsx.DNSDecoder.
type Decoder struct { type DNSDecoder struct {
MockDecodeLookupHost func(qtype uint16, reply []byte) ([]string, error) MockDecodeLookupHost func(qtype uint16, reply []byte) ([]string, error)
MockDecodeHTTPS func(reply []byte) (*HTTPSSvc, error) MockDecodeHTTPS func(reply []byte) (*HTTPSSvc, error)
} }
// DecodeLookupHost calls MockDecodeLookupHost. // DecodeLookupHost calls MockDecodeLookupHost.
func (e *Decoder) DecodeLookupHost(qtype uint16, reply []byte) ([]string, error) { func (e *DNSDecoder) DecodeLookupHost(qtype uint16, reply []byte) ([]string, error) {
return e.MockDecodeLookupHost(qtype, reply) return e.MockDecodeLookupHost(qtype, reply)
} }
// DecodeHTTPS calls MockDecodeHTTPS. // DecodeHTTPS calls MockDecodeHTTPS.
func (e *Decoder) DecodeHTTPS(reply []byte) (*HTTPSSvc, error) { func (e *DNSDecoder) DecodeHTTPS(reply []byte) (*HTTPSSvc, error) {
return e.MockDecodeHTTPS(reply) return e.MockDecodeHTTPS(reply)
} }

View File

@ -7,10 +7,10 @@ import (
"github.com/miekg/dns" "github.com/miekg/dns"
) )
func TestDecoder(t *testing.T) { func TestDNSDecoder(t *testing.T) {
t.Run("DecodeLookupHost", func(t *testing.T) { t.Run("DecodeLookupHost", func(t *testing.T) {
expected := errors.New("mocked error") expected := errors.New("mocked error")
e := &Decoder{ e := &DNSDecoder{
MockDecodeLookupHost: func(qtype uint16, reply []byte) ([]string, error) { MockDecodeLookupHost: func(qtype uint16, reply []byte) ([]string, error) {
return nil, expected return nil, expected
}, },
@ -26,7 +26,7 @@ func TestDecoder(t *testing.T) {
t.Run("DecodeHTTPS", func(t *testing.T) { t.Run("DecodeHTTPS", func(t *testing.T) {
expected := errors.New("mocked error") expected := errors.New("mocked error")
e := &Decoder{ e := &DNSDecoder{
MockDecodeHTTPS: func(reply []byte) (*HTTPSSvc, error) { MockDecodeHTTPS: func(reply []byte) (*HTTPSSvc, error) {
return nil, expected return nil, expected
}, },

View File

@ -1,11 +1,11 @@
package mocks package mocks
// Encoder allows mocking dnsx.Encoder. // DNSEncoder allows mocking dnsx.DNSEncoder.
type Encoder struct { type DNSEncoder struct {
MockEncode func(domain string, qtype uint16, padding bool) ([]byte, error) MockEncode func(domain string, qtype uint16, padding bool) ([]byte, error)
} }
// Encode calls MockEncode. // Encode calls MockEncode.
func (e *Encoder) Encode(domain string, qtype uint16, padding bool) ([]byte, error) { func (e *DNSEncoder) Encode(domain string, qtype uint16, padding bool) ([]byte, error) {
return e.MockEncode(domain, qtype, padding) return e.MockEncode(domain, qtype, padding)
} }

View File

@ -7,10 +7,10 @@ import (
"github.com/miekg/dns" "github.com/miekg/dns"
) )
func TestEncoder(t *testing.T) { func TestDNSEncoder(t *testing.T) {
t.Run("Encode", func(t *testing.T) { t.Run("Encode", func(t *testing.T) {
expected := errors.New("mocked error") expected := errors.New("mocked error")
e := &Encoder{ e := &DNSEncoder{
MockEncode: func(domain string, qtype uint16, padding bool) ([]byte, error) { MockEncode: func(domain string, qtype uint16, padding bool) ([]byte, error) {
return nil, expected return nil, expected
}, },

View File

@ -2,8 +2,8 @@ package mocks
import "context" import "context"
// RoundTripper allows mocking dnsx.RoundTripper. // DNSTransport allows mocking dnsx.DNSTransport.
type RoundTripper struct { type DNSTransport struct {
MockRoundTrip func(ctx context.Context, query []byte) (reply []byte, err error) MockRoundTrip func(ctx context.Context, query []byte) (reply []byte, err error)
MockRequiresPadding func() bool MockRequiresPadding func() bool
@ -16,26 +16,26 @@ type RoundTripper struct {
} }
// RoundTrip calls MockRoundTrip. // RoundTrip calls MockRoundTrip.
func (txp *RoundTripper) RoundTrip(ctx context.Context, query []byte) (reply []byte, err error) { func (txp *DNSTransport) RoundTrip(ctx context.Context, query []byte) (reply []byte, err error) {
return txp.MockRoundTrip(ctx, query) return txp.MockRoundTrip(ctx, query)
} }
// RequiresPadding calls MockRequiresPadding. // RequiresPadding calls MockRequiresPadding.
func (txp *RoundTripper) RequiresPadding() bool { func (txp *DNSTransport) RequiresPadding() bool {
return txp.MockRequiresPadding() return txp.MockRequiresPadding()
} }
// Network calls MockNetwork. // Network calls MockNetwork.
func (txp *RoundTripper) Network() string { func (txp *DNSTransport) Network() string {
return txp.MockNetwork() return txp.MockNetwork()
} }
// Address calls MockAddress. // Address calls MockAddress.
func (txp *RoundTripper) Address() string { func (txp *DNSTransport) Address() string {
return txp.MockAddress() return txp.MockAddress()
} }
// CloseIdleConnections calls MockCloseIdleConnections. // CloseIdleConnections calls MockCloseIdleConnections.
func (txp *RoundTripper) CloseIdleConnections() { func (txp *DNSTransport) CloseIdleConnections() {
txp.MockCloseIdleConnections() txp.MockCloseIdleConnections()
} }

View File

@ -8,10 +8,10 @@ import (
"github.com/ooni/probe-cli/v3/internal/atomicx" "github.com/ooni/probe-cli/v3/internal/atomicx"
) )
func TestRoundTripper(t *testing.T) { func TestDNSTransport(t *testing.T) {
t.Run("RoundTrip", func(t *testing.T) { t.Run("RoundTrip", func(t *testing.T) {
expected := errors.New("mocked error") expected := errors.New("mocked error")
txp := &RoundTripper{ txp := &DNSTransport{
MockRoundTrip: func(ctx context.Context, query []byte) ([]byte, error) { MockRoundTrip: func(ctx context.Context, query []byte) ([]byte, error) {
return nil, expected return nil, expected
}, },
@ -26,7 +26,7 @@ func TestRoundTripper(t *testing.T) {
}) })
t.Run("RequiresPadding", func(t *testing.T) { t.Run("RequiresPadding", func(t *testing.T) {
txp := &RoundTripper{ txp := &DNSTransport{
MockRequiresPadding: func() bool { MockRequiresPadding: func() bool {
return true return true
}, },
@ -37,7 +37,7 @@ func TestRoundTripper(t *testing.T) {
}) })
t.Run("Network", func(t *testing.T) { t.Run("Network", func(t *testing.T) {
txp := &RoundTripper{ txp := &DNSTransport{
MockNetwork: func() string { MockNetwork: func() string {
return "antani" return "antani"
}, },
@ -48,7 +48,7 @@ func TestRoundTripper(t *testing.T) {
}) })
t.Run("Address", func(t *testing.T) { t.Run("Address", func(t *testing.T) {
txp := &RoundTripper{ txp := &DNSTransport{
MockAddress: func() string { MockAddress: func() string {
return "mascetti" return "mascetti"
}, },
@ -60,7 +60,7 @@ func TestRoundTripper(t *testing.T) {
t.Run("CloseIdleConnections", func(t *testing.T) { t.Run("CloseIdleConnections", func(t *testing.T) {
called := &atomicx.Int64{} called := &atomicx.Int64{}
txp := &RoundTripper{ txp := &DNSTransport{
MockCloseIdleConnections: func() { MockCloseIdleConnections: func() {
called.Add(1) called.Add(1)
}, },

View File

@ -12,24 +12,24 @@ import (
// SerialResolver is a resolver that first issues an A query and then // SerialResolver is a resolver that first issues an A query and then
// issues an AAAA query for the requested domain. // issues an AAAA query for the requested domain.
type SerialResolver struct { type SerialResolver struct {
Encoder Encoder Encoder DNSEncoder
Decoder Decoder Decoder DNSDecoder
NumTimeouts *atomicx.Int64 NumTimeouts *atomicx.Int64
Txp RoundTripper Txp DNSTransport
} }
// NewSerialResolver creates a new OONI Resolver instance. // NewSerialResolver creates a new OONI Resolver instance.
func NewSerialResolver(t RoundTripper) *SerialResolver { func NewSerialResolver(t DNSTransport) *SerialResolver {
return &SerialResolver{ return &SerialResolver{
Encoder: &MiekgEncoder{}, Encoder: &DNSEncoderMiekg{},
Decoder: &MiekgDecoder{}, Decoder: &DNSDecoderMiekg{},
NumTimeouts: &atomicx.Int64{}, NumTimeouts: &atomicx.Int64{},
Txp: t, Txp: t,
} }
} }
// Transport returns the transport being used. // Transport returns the transport being used.
func (r *SerialResolver) Transport() RoundTripper { func (r *SerialResolver) Transport() DNSTransport {
return r.Txp return r.Txp
} }

View File

@ -32,7 +32,7 @@ func TestOONIEncodeError(t *testing.T) {
mocked := errors.New("mocked error") mocked := errors.New("mocked error")
txp := NewDNSOverTLS((&tls.Dialer{}).DialContext, "8.8.8.8:853") txp := NewDNSOverTLS((&tls.Dialer{}).DialContext, "8.8.8.8:853")
r := SerialResolver{ r := SerialResolver{
Encoder: &mocks.Encoder{ Encoder: &mocks.DNSEncoder{
MockEncode: func(domain string, qtype uint16, padding bool) ([]byte, error) { MockEncode: func(domain string, qtype uint16, padding bool) ([]byte, error) {
return nil, mocked return nil, mocked
}, },
@ -50,7 +50,7 @@ func TestOONIEncodeError(t *testing.T) {
func TestOONIRoundTripError(t *testing.T) { func TestOONIRoundTripError(t *testing.T) {
mocked := errors.New("mocked error") mocked := errors.New("mocked error")
txp := &mocks.RoundTripper{ txp := &mocks.DNSTransport{
MockRoundTrip: func(ctx context.Context, query []byte) (reply []byte, err error) { MockRoundTrip: func(ctx context.Context, query []byte) (reply []byte, err error) {
return nil, mocked return nil, mocked
}, },
@ -69,7 +69,7 @@ func TestOONIRoundTripError(t *testing.T) {
} }
func TestOONIWithEmptyReply(t *testing.T) { func TestOONIWithEmptyReply(t *testing.T) {
txp := &mocks.RoundTripper{ txp := &mocks.DNSTransport{
MockRoundTrip: func(ctx context.Context, query []byte) (reply []byte, err error) { MockRoundTrip: func(ctx context.Context, query []byte) (reply []byte, err error) {
return genReplySuccess(t, dns.TypeA), nil return genReplySuccess(t, dns.TypeA), nil
}, },
@ -88,7 +88,7 @@ func TestOONIWithEmptyReply(t *testing.T) {
} }
func TestOONIWithAReply(t *testing.T) { func TestOONIWithAReply(t *testing.T) {
txp := &mocks.RoundTripper{ txp := &mocks.DNSTransport{
MockRoundTrip: func(ctx context.Context, query []byte) (reply []byte, err error) { MockRoundTrip: func(ctx context.Context, query []byte) (reply []byte, err error) {
return genReplySuccess(t, dns.TypeA, "8.8.8.8"), nil return genReplySuccess(t, dns.TypeA, "8.8.8.8"), nil
}, },
@ -107,7 +107,7 @@ func TestOONIWithAReply(t *testing.T) {
} }
func TestOONIWithAAAAReply(t *testing.T) { func TestOONIWithAAAAReply(t *testing.T) {
txp := &mocks.RoundTripper{ txp := &mocks.DNSTransport{
MockRoundTrip: func(ctx context.Context, query []byte) (reply []byte, err error) { MockRoundTrip: func(ctx context.Context, query []byte) (reply []byte, err error) {
return genReplySuccess(t, dns.TypeAAAA, "::1"), nil return genReplySuccess(t, dns.TypeAAAA, "::1"), nil
}, },
@ -126,7 +126,7 @@ func TestOONIWithAAAAReply(t *testing.T) {
} }
func TestOONIWithTimeout(t *testing.T) { func TestOONIWithTimeout(t *testing.T) {
txp := &mocks.RoundTripper{ txp := &mocks.DNSTransport{
MockRoundTrip: func(ctx context.Context, query []byte) (reply []byte, err error) { MockRoundTrip: func(ctx context.Context, query []byte) (reply []byte, err error) {
return nil, &net.OpError{Err: errorsx.ETIMEDOUT, Op: "dial"} return nil, &net.OpError{Err: errorsx.ETIMEDOUT, Op: "dial"}
}, },
@ -150,7 +150,7 @@ func TestOONIWithTimeout(t *testing.T) {
func TestSerialResolverCloseIdleConnections(t *testing.T) { func TestSerialResolverCloseIdleConnections(t *testing.T) {
var called bool var called bool
r := &SerialResolver{ r := &SerialResolver{
Txp: &mocks.RoundTripper{ Txp: &mocks.DNSTransport{
MockCloseIdleConnections: func() { MockCloseIdleConnections: func() {
called = true called = true
}, },
@ -166,14 +166,14 @@ func TestSerialResolverLookupHTTPS(t *testing.T) {
t.Run("for encoding error", func(t *testing.T) { t.Run("for encoding error", func(t *testing.T) {
expected := errors.New("mocked error") expected := errors.New("mocked error")
r := &SerialResolver{ r := &SerialResolver{
Encoder: &mocks.Encoder{ Encoder: &mocks.DNSEncoder{
MockEncode: func(domain string, qtype uint16, padding bool) ([]byte, error) { MockEncode: func(domain string, qtype uint16, padding bool) ([]byte, error) {
return nil, expected return nil, expected
}, },
}, },
Decoder: nil, Decoder: nil,
NumTimeouts: &atomicx.Int64{}, NumTimeouts: &atomicx.Int64{},
Txp: &mocks.RoundTripper{ Txp: &mocks.DNSTransport{
MockRequiresPadding: func() bool { MockRequiresPadding: func() bool {
return false return false
}, },
@ -192,14 +192,14 @@ func TestSerialResolverLookupHTTPS(t *testing.T) {
t.Run("for round-trip error", func(t *testing.T) { t.Run("for round-trip error", func(t *testing.T) {
expected := errors.New("mocked error") expected := errors.New("mocked error")
r := &SerialResolver{ r := &SerialResolver{
Encoder: &mocks.Encoder{ Encoder: &mocks.DNSEncoder{
MockEncode: func(domain string, qtype uint16, padding bool) ([]byte, error) { MockEncode: func(domain string, qtype uint16, padding bool) ([]byte, error) {
return make([]byte, 64), nil return make([]byte, 64), nil
}, },
}, },
Decoder: nil, Decoder: nil,
NumTimeouts: &atomicx.Int64{}, NumTimeouts: &atomicx.Int64{},
Txp: &mocks.RoundTripper{ Txp: &mocks.DNSTransport{
MockRoundTrip: func(ctx context.Context, query []byte) (reply []byte, err error) { MockRoundTrip: func(ctx context.Context, query []byte) (reply []byte, err error) {
return nil, expected return nil, expected
}, },
@ -221,18 +221,18 @@ func TestSerialResolverLookupHTTPS(t *testing.T) {
t.Run("for decode error", func(t *testing.T) { t.Run("for decode error", func(t *testing.T) {
expected := errors.New("mocked error") expected := errors.New("mocked error")
r := &SerialResolver{ r := &SerialResolver{
Encoder: &mocks.Encoder{ Encoder: &mocks.DNSEncoder{
MockEncode: func(domain string, qtype uint16, padding bool) ([]byte, error) { MockEncode: func(domain string, qtype uint16, padding bool) ([]byte, error) {
return make([]byte, 64), nil return make([]byte, 64), nil
}, },
}, },
Decoder: &mocks.Decoder{ Decoder: &mocks.DNSDecoder{
MockDecodeHTTPS: func(reply []byte) (*mocks.HTTPSSvc, error) { MockDecodeHTTPS: func(reply []byte) (*mocks.HTTPSSvc, error) {
return nil, expected return nil, expected
}, },
}, },
NumTimeouts: &atomicx.Int64{}, NumTimeouts: &atomicx.Int64{},
Txp: &mocks.RoundTripper{ Txp: &mocks.DNSTransport{
MockRoundTrip: func(ctx context.Context, query []byte) (reply []byte, err error) { MockRoundTrip: func(ctx context.Context, query []byte) (reply []byte, err error) {
return make([]byte, 128), nil return make([]byte, 128), nil
}, },