diff --git a/resolver.go b/resolver.go index 5952c08..13923ee 100644 --- a/resolver.go +++ b/resolver.go @@ -119,28 +119,30 @@ func createQuery(opts cli.Flags, rrTypes []uint16) []dns.Msg { func newTransport(server string, transportType transport.Type, tlsConfig *tls.Config) (*transport.Transport, error) { var ts transport.Transport + common := transport.Common{ + Server: server, + ReuseConn: opts.ReuseConn, + Timeout: opts.Timeout, + } + switch transportType { case transport.TypeHTTP: if opts.ODoHProxy != "" { log.Debugf("Using ODoH transport with target %s proxy %s", server, opts.ODoHProxy) ts = &transport.ODoH{ - Target: server, Proxy: opts.ODoHProxy, TLSConfig: tlsConfig, - ReuseConn: opts.ReuseConn, } } else { log.Debugf("Using HTTP(s) transport: %s", server) ts = &transport.HTTP{ - Server: server, + Common: common, TLSConfig: tlsConfig, UserAgent: opts.HTTPUserAgent, Method: opts.HTTPMethod, - Timeout: opts.Timeout, HTTP2: opts.HTTP2, HTTP3: opts.HTTP3, NoPMTUd: !opts.PMTUD, - ReuseConn: opts.ReuseConn, } } case transport.TypeDNSCrypt: @@ -148,20 +150,17 @@ func newTransport(server string, transportType transport.Type, tlsConfig *tls.Co if strings.HasPrefix(server, "sdns://") { log.Traceln("Using provided DNS stamp for DNSCrypt") ts = &transport.DNSCrypt{ + Common: common, ServerStamp: server, TCP: opts.DNSCryptTCP, - Timeout: opts.Timeout, UDPSize: opts.DNSCryptUDPSize, - ReuseConn: opts.ReuseConn, } } else { log.Traceln("Using manual DNSCrypt configuration") - ts = &transport.DNSCrypt{ + ts = &transport.DNSCrypt{Common: common, + TCP: opts.DNSCryptTCP, - Timeout: opts.Timeout, UDPSize: opts.DNSCryptUDPSize, - ReuseConn: opts.ReuseConn, - Server: server, PublicKey: opts.DNSCryptPublicKey, ProviderName: opts.DNSCryptProvider, } @@ -173,34 +172,29 @@ func newTransport(server string, transportType transport.Type, tlsConfig *tls.Co tlsConfig.NextProtos = opts.QUICALPNTokens ts = &transport.QUIC{ - Server: server, + Common: common, TLSConfig: tc, PMTUD: opts.PMTUD, AddLengthPrefix: opts.QUICLengthPrefix, - ReuseConn: opts.ReuseConn, } case transport.TypeTLS: log.Debugf("Using TLS transport: %s", server) ts = &transport.TLS{ - Server: server, + Common: common, TLSConfig: tlsConfig, - Timeout: opts.Timeout, - ReuseConn: opts.ReuseConn, } case transport.TypeTCP: log.Debugf("Using TCP transport: %s", server) ts = &transport.Plain{ - Server: server, + Common: common, PreferTCP: true, - Timeout: opts.Timeout, UDPBuffer: opts.UDPBuffer, } case transport.TypePlain: log.Debugf("Using UDP with TCP fallback: %s", server) ts = &transport.Plain{ - Server: server, + Common: common, PreferTCP: false, - Timeout: opts.Timeout, UDPBuffer: opts.UDPBuffer, } default: diff --git a/transport/dnscrypt.go b/transport/dnscrypt.go index 14363fe..2f1a018 100644 --- a/transport/dnscrypt.go +++ b/transport/dnscrypt.go @@ -1,8 +1,6 @@ package transport import ( - "time" - "github.com/ameshkov/dnscrypt/v2" "github.com/jedisct1/go-dnsstamps" "github.com/miekg/dns" @@ -10,14 +8,12 @@ import ( ) type DNSCrypt struct { + Common ServerStamp string TCP bool // default false (UDP) - Timeout time.Duration UDPSize int - ReuseConn bool // ServerStamp takes precedence if set - Server string PublicKey string ProviderName string diff --git a/transport/dnscrypt_test.go b/transport/dnscrypt_test.go index 3d45766..213780b 100644 --- a/transport/dnscrypt_test.go +++ b/transport/dnscrypt_test.go @@ -4,8 +4,8 @@ import "time" func dnscryptTransport() *DNSCrypt { d := &DNSCrypt{ + Common: Common{Timeout: 1 * time.Second}, ServerStamp: "sdns://AQMAAAAAAAAAETk0LjE0MC4xNC4xNDo1NDQzINErR_JS3PLCu_iZEIbq95zkSV2LFsigxDIuUso_OQhzIjIuZG5zY3J5cHQuZGVmYXVsdC5uczEuYWRndWFyZC5jb20", - Timeout: 1 * time.Second, } return d } diff --git a/transport/http.go b/transport/http.go index 97d807f..3ef987f 100644 --- a/transport/http.go +++ b/transport/http.go @@ -7,7 +7,6 @@ import ( "fmt" "io" "net/http" - "time" "github.com/miekg/dns" "github.com/quic-go/quic-go" @@ -18,14 +17,12 @@ import ( // HTTP makes a DNS query over HTTP(s) type HTTP struct { - Server string + Common TLSConfig *tls.Config UserAgent string Method string - Timeout time.Duration HTTP2, HTTP3 bool NoPMTUd bool - ReuseConn bool conn *http.Client } diff --git a/transport/http_test.go b/transport/http_test.go index 571e0f2..62aa5d5 100644 --- a/transport/http_test.go +++ b/transport/http_test.go @@ -12,11 +12,13 @@ import ( func httpTransport() *HTTP { return &HTTP{ - Server: "https://cloudflare-dns.com/dns-query", + Common: Common{ + Server: "https://cloudflare-dns.com/dns-query", + Timeout: 2 * time.Second, + }, TLSConfig: &tls.Config{}, UserAgent: "", Method: http.MethodGet, - Timeout: 2 * time.Second, HTTP3: false, NoPMTUd: false, } diff --git a/transport/odoh.go b/transport/odoh.go index b4267c5..1449a4f 100644 --- a/transport/odoh.go +++ b/transport/odoh.go @@ -61,10 +61,9 @@ func buildURL(s, defaultPath string) *url.URL { // ODoH makes a DNS query over ODoH type ODoH struct { - Target string + Common // Server is the target Proxy string TLSConfig *tls.Config - ReuseConn bool conn *http.Client } @@ -73,7 +72,7 @@ func (o *ODoH) Exchange(m *dns.Msg) (*dns.Msg, error) { // Query ODoH configs on target req, err := http.NewRequest( http.MethodGet, - buildURL(strings.TrimSuffix(o.Target, "/dns-query"), "/.well-known/odohconfigs").String(), + buildURL(strings.TrimSuffix(o.Server, "/dns-query"), "/.well-known/odohconfigs").String(), nil, ) if err != nil { @@ -118,7 +117,7 @@ func (o *ODoH) Exchange(m *dns.Msg) (*dns.Msg, error) { return nil, fmt.Errorf("encrypt query: %s", err) } - t := buildURL(o.Target, "/dns-query") + t := buildURL(o.Server, "/dns-query") p := buildURL(o.Proxy, "/proxy") qry := p.Query() if qry.Get("targethost") == "" { diff --git a/transport/odoh_test.go b/transport/odoh_test.go index b5dc467..b39c181 100644 --- a/transport/odoh_test.go +++ b/transport/odoh_test.go @@ -8,7 +8,7 @@ import ( func odohTransport() *ODoH { return &ODoH{ - Target: "odoh.cloudflare-dns.com", + Common: Common{Server: "odoh.cloudflare-dns.com"}, Proxy: "odoh.crypto.sx", } } @@ -31,7 +31,7 @@ func TestODoHBuildURL(t *testing.T) { func TestTransportODoHInvalidTarget(t *testing.T) { tp := odohTransport() - tp.Target = "example.com" + tp.Server = "example.com" _, err := tp.Exchange(validQuery()) assert.NotNil(t, err) assert.Contains(t, err.Error(), "Invalid serialized ObliviousDoHConfig") diff --git a/transport/plain.go b/transport/plain.go index 6d547f6..33e6b13 100644 --- a/transport/plain.go +++ b/transport/plain.go @@ -1,17 +1,14 @@ package transport import ( - "time" - "github.com/miekg/dns" log "github.com/sirupsen/logrus" ) // Plain makes a DNS query over TCP or UDP (with TCP fallback) type Plain struct { - Server string + Common PreferTCP bool - Timeout time.Duration UDPBuffer uint16 } diff --git a/transport/plain_test.go b/transport/plain_test.go index d95cd00..6373fe1 100644 --- a/transport/plain_test.go +++ b/transport/plain_test.go @@ -10,9 +10,11 @@ import ( func plainTransport() *Plain { return &Plain{ - Server: "9.9.9.9:53", + Common: Common{ + Server: "9.9.9.9:53", + Timeout: 5 * time.Second, + }, PreferTCP: false, - Timeout: 5 * time.Second, UDPBuffer: 1232, } } diff --git a/transport/quic.go b/transport/quic.go index 1044aa7..745c349 100644 --- a/transport/quic.go +++ b/transport/quic.go @@ -27,11 +27,10 @@ const ( // QUIC makes a DNS query over QUIC type QUIC struct { - Server string + Common TLSConfig *tls.Config PMTUD bool AddLengthPrefix bool - ReuseConn bool conn *quic.Connection } @@ -51,6 +50,7 @@ func (q *QUIC) setServerName() { func (q *QUIC) Exchange(msg *dns.Msg) (*dns.Msg, error) { if q.conn == nil || !q.ReuseConn { + log.Debugf("Connecting to %s", q.Server) q.setServerName() if len(q.TLSConfig.NextProtos) == 0 { log.Debug("No ALPN tokens specified, using default: \"doq\"") diff --git a/transport/quic_test.go b/transport/quic_test.go index c683dc6..dc209de 100644 --- a/transport/quic_test.go +++ b/transport/quic_test.go @@ -4,7 +4,7 @@ import "crypto/tls" func quicTransport() *QUIC { return &QUIC{ - Server: "dns.adguard.com:8853", + Common: Common{Server: "dns.adguard.com:8853"}, PMTUD: true, AddLengthPrefix: true, TLSConfig: &tls.Config{NextProtos: []string{"doq"}}, diff --git a/transport/tls.go b/transport/tls.go index c4fb996..2e72f51 100644 --- a/transport/tls.go +++ b/transport/tls.go @@ -4,19 +4,15 @@ import ( "crypto/tls" "fmt" "net" - "time" "github.com/miekg/dns" ) // TLS makes a DNS query over TLS type TLS struct { - Server string + Common TLSConfig *tls.Config - Timeout time.Duration - ReuseConn bool - - conn *tls.Conn + conn *tls.Conn } func (t *TLS) Exchange(msg *dns.Msg) (*dns.Msg, error) { diff --git a/transport/tls_test.go b/transport/tls_test.go index e14fa86..4f97059 100644 --- a/transport/tls_test.go +++ b/transport/tls_test.go @@ -6,8 +6,10 @@ import ( func tlsTransport() *TLS { return &TLS{ - Server: "dns.quad9.net:853", - Timeout: 1 * time.Second, - ReuseConn: false, + Common: Common{ + Server: "dns.quad9.net:853", + Timeout: 1 * time.Second, + ReuseConn: false, + }, } } diff --git a/transport/transport.go b/transport/transport.go index 1508af3..8ed693e 100644 --- a/transport/transport.go +++ b/transport/transport.go @@ -1,12 +1,22 @@ package transport -import "github.com/miekg/dns" +import ( + "time" + + "github.com/miekg/dns" +) type Transport interface { Exchange(*dns.Msg) (*dns.Msg, error) Close() error } +type Common struct { + Server string + ReuseConn bool + Timeout time.Duration +} + type Type string const (