Skip to content

Commit

Permalink
upstream: slog
Browse files Browse the repository at this point in the history
  • Loading branch information
Mizzick committed Jun 25, 2024
1 parent 0596984 commit 1305183
Show file tree
Hide file tree
Showing 19 changed files with 165 additions and 47 deletions.
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,7 @@ func (opts *Options) initUpstreams(

timeout := opts.Timeout.Duration
bootOpts := &upstream.Options{
Logger: l,
HTTPVersions: httpVersions,
InsecureSkipVerify: opts.Insecure,
Timeout: timeout,
Expand Down
6 changes: 5 additions & 1 deletion proxy/lookup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"testing"

"github.com/AdguardTeam/dnsproxy/upstream"
"github.com/AdguardTeam/golibs/logutil/slogutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand All @@ -14,7 +15,10 @@ func TestLookupNetIP(t *testing.T) {
// Use AdGuard DNS here.
dnsUpstream, err := upstream.AddressToUpstream(
"94.140.14.14",
&upstream.Options{Timeout: defaultTimeout},
&upstream.Options{
Logger: slogutil.NewDiscardLogger(),
Timeout: defaultTimeout,
},
)
require.NoError(t, err)

Expand Down
6 changes: 5 additions & 1 deletion proxy/proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,10 @@ func newTestUpstreamConfigWithBoot(
) (u *UpstreamConfig) {
googleRslv, err := upstream.NewUpstreamResolver(
"8.8.8.8:53",
&upstream.Options{Timeout: timeout},
&upstream.Options{
Logger: slogutil.NewDiscardLogger(),
Timeout: timeout,
},
)
require.NoError(t, err)

Expand Down Expand Up @@ -826,6 +829,7 @@ func TestFallbackFromInvalidBootstrap(t *testing.T) {
t.Parallel()

invalidRslv, err := upstream.NewUpstreamResolver("8.8.8.8:555", &upstream.Options{
Logger: slogutil.NewDiscardLogger(),
Timeout: testTimeout,
})
require.NoError(t, err)
Expand Down
4 changes: 3 additions & 1 deletion proxy/upstreams.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ func ParseUpstreamsConfig(
opts *upstream.Options,
) (conf *UpstreamConfig, err error) {
if opts == nil {
opts = &upstream.Options{}
opts = &upstream.Options{
Logger: slog.Default(),
}
}

p := &configParser{
Expand Down
12 changes: 10 additions & 2 deletions upstream/dnscrypt.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ package upstream
import (
"fmt"
"io"
"log/slog"
"net/url"
"os"
"sync"
"time"

"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
"github.com/ameshkov/dnscrypt/v2"
"github.com/miekg/dns"
)
Expand All @@ -28,6 +28,9 @@ type dnsCrypt struct {
// addr is the DNSCrypt server URL.
addr *url.URL

// logger is used for exchange logging. It is never nil.
logger *slog.Logger

// verifyCert is a callback that verifies the resolver's certificate.
verifyCert func(cert *dnscrypt.Cert) (err error)

Expand All @@ -40,6 +43,7 @@ func newDNSCrypt(addr *url.URL, opts *Options) (u *dnsCrypt) {
return &dnsCrypt{
mu: &sync.RWMutex{},
addr: addr,
logger: opts.Logger,
verifyCert: opts.VerifyDNSCryptCertificate,
timeout: opts.Timeout,
}
Expand Down Expand Up @@ -107,7 +111,11 @@ func (p *dnsCrypt) exchangeDNSCrypt(m *dns.Msg) (resp *dns.Msg, err error) {
resp, err = client.Exchange(m, resolverInfo)
if resp != nil && resp.Truncated {
q := &m.Question[0]
log.Debug("dnscrypt %s: received truncated, falling back to tcp with %s", p.addr, q)
p.logger.Debug(
"dnscrypt received truncated, falling back to tcp",
"addr", p.addr,
"question", q,
)

tcpClient := &dnscrypt.Client{Timeout: p.timeout, Net: networkTCP}
resp, err = tcpClient.Exchange(m, resolverInfo)
Expand Down
22 changes: 18 additions & 4 deletions upstream/dnscrypt_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"time"

"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/logutil/slogutil"
"github.com/AdguardTeam/golibs/netutil"
"github.com/AdguardTeam/golibs/testutil"
"github.com/ameshkov/dnscrypt/v2"
Expand Down Expand Up @@ -92,7 +93,10 @@ func TestUpstreamDNSCrypt(t *testing.T) {

// AdGuard DNS (DNSCrypt)
address := "sdns://AQMAAAAAAAAAETk0LjE0MC4xNC4xNDo1NDQzINErR_JS3PLCu_iZEIbq95zkSV2LFsigxDIuUso_OQhzIjIuZG5zY3J5cHQuZGVmYXVsdC5uczEuYWRndWFyZC5jb20"
u, err := AddressToUpstream(address, &Options{Timeout: dialTimeout})
u, err := AddressToUpstream(address, &Options{
Logger: slogutil.NewDiscardLogger(),
Timeout: dialTimeout,
})
require.NoError(t, err)
testutil.CleanupAndRequireSuccess(t, u.Close)

Expand Down Expand Up @@ -135,7 +139,10 @@ func TestDNSCrypt_Exchange_truncated(t *testing.T) {
})
srvStamp := startTestDNSCryptServer(t, rc, h)

u, err := AddressToUpstream(srvStamp.String(), &Options{Timeout: timeout})
u, err := AddressToUpstream(srvStamp.String(), &Options{
Logger: slogutil.NewDiscardLogger(),
Timeout: timeout,
})
require.NoError(t, err)
testutil.CleanupAndRequireSuccess(t, u.Close)

Expand Down Expand Up @@ -164,7 +171,10 @@ func TestDNSCrypt_Exchange_deadline(t *testing.T) {
srvStamp := startTestDNSCryptServer(t, rc, h)

// Use a shorter timeout to speed up the test.
u, err := AddressToUpstream(srvStamp.String(), &Options{Timeout: 100 * time.Millisecond})
u, err := AddressToUpstream(srvStamp.String(), &Options{
Logger: slogutil.NewDiscardLogger(),
Timeout: 100 * time.Millisecond,
})
require.NoError(t, err)
testutil.CleanupAndRequireSuccess(t, u.Close)

Expand Down Expand Up @@ -192,7 +202,10 @@ func TestDNSCrypt_Exchange_dialFail(t *testing.T) {
srvStamp := startTestDNSCryptServer(t, rc, h)

// Use a shorter timeout to speed up the test.
u, err = AddressToUpstream(srvStamp.String(), &Options{Timeout: 100 * time.Millisecond})
u, err = AddressToUpstream(srvStamp.String(), &Options{
Logger: slogutil.NewDiscardLogger(),
Timeout: 100 * time.Millisecond,
})
require.NoError(t, err)
}))

Expand All @@ -213,6 +226,7 @@ func TestDNSCrypt_Exchange_dialFail(t *testing.T) {

// Use a shorter timeout to speed up the test.
u, err = AddressToUpstream(srvStamp.String(), &Options{
Logger: slogutil.NewDiscardLogger(),
Timeout: 100 * time.Millisecond,
VerifyDNSCryptCertificate: func(cert *dnscrypt.Cert) (err error) {
return validationErr
Expand Down
27 changes: 17 additions & 10 deletions upstream/doh.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"encoding/base64"
"fmt"
"io"
"log/slog"
"net"
"net/http"
"net/url"
Expand All @@ -15,7 +16,7 @@ import (

"github.com/AdguardTeam/dnsproxy/internal/bootstrap"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/logutil/slogutil"
"github.com/miekg/dns"
"github.com/quic-go/quic-go"
"github.com/quic-go/quic-go/http3"
Expand Down Expand Up @@ -63,6 +64,9 @@ type dnsOverHTTPS struct {
// clientMu protects client.
clientMu *sync.Mutex

// logger is used for exchange logging. It is never nil.
logger *slog.Logger

// quicConf is the QUIC configuration that is used if HTTP/3 is enabled
// for this upstream.
quicConf *quic.Config
Expand Down Expand Up @@ -115,6 +119,7 @@ func newDoH(addr *url.URL, opts *Options) (u Upstream, err error) {
VerifyConnection: opts.VerifyConnection,
},
clientMu: &sync.Mutex{},
logger: opts.Logger,
addrRedacted: addr.Redacted(),
timeout: opts.Timeout,
}
Expand Down Expand Up @@ -268,7 +273,7 @@ func (p *dnsOverHTTPS) exchangeHTTPSClient(
if err != nil {
return nil, fmt.Errorf("requesting %s: %w", p.addrRedacted, err)
}
defer log.OnCloserError(httpResp.Body, log.DEBUG)
defer slogutil.CloseAndLog(context.TODO(), p.logger, httpResp.Body, slog.LevelDebug)

body, err := io.ReadAll(httpResp.Body)
if err != nil {
Expand Down Expand Up @@ -342,11 +347,11 @@ func (p *dnsOverHTTPS) resetClient(resetErr error) (client *http.Client, err err
if oldClient != nil {
closeErr := p.closeClient(oldClient)
if closeErr != nil {
log.Info("warning: failed to close the old http client: %v", closeErr)
p.logger.Warn("failed to close the old http client", slogutil.KeyError, closeErr)
}
}

log.Debug("re-creating the http client due to %v", resetErr)
p.logger.Debug("recreating the http client", slogutil.KeyError, resetErr)
p.client, err = p.createClient()

return p.client, err
Expand Down Expand Up @@ -390,7 +395,7 @@ func (p *dnsOverHTTPS) getClient() (c *http.Client, isCached bool, err error) {
return nil, false, fmt.Errorf("timeout exceeded: %s", elapsed)
}

log.Debug("creating a new http client")
p.logger.Debug("creating a new http client")
p.client, err = p.createClient()

return p.client, false, err
Expand Down Expand Up @@ -437,11 +442,12 @@ func (p *dnsOverHTTPS) createTransport() (t http.RoundTripper, err error) {
tlsConf := p.tlsConf.Clone()
transportH3, err := p.createTransportH3(tlsConf, dialContext)
if err == nil {
log.Debug("using HTTP/3 for this upstream: QUIC was faster")
p.logger.Debug("using http/3 for this upstream: quic was faster")

return transportH3, nil
}

log.Debug("using HTTP/2 for this upstream: %v", err)
p.logger.Debug("got error, switching to http/2 for this upstream", slogutil.KeyError, err)

if !p.supportsHTTP() {
return nil, errors.Error("HTTP1/1 and HTTP2 are not supported by this upstream")
Expand Down Expand Up @@ -621,7 +627,8 @@ func (p *dnsOverHTTPS) probeH3(
case tlsErr := <-chTLS:
if tlsErr != nil {
// Return immediately, TLS failed.
log.Debug("probing TLS: %v", tlsErr)
p.logger.Debug("probing tls", slogutil.KeyError, tlsErr)

return addr, nil
}

Expand Down Expand Up @@ -653,7 +660,7 @@ func (p *dnsOverHTTPS) probeQUIC(addr string, tlsConfig *tls.Config, ch chan err
ch <- nil

elapsed := time.Since(startTime)
log.Debug("elapsed on establishing a QUIC connection: %s", elapsed)
p.logger.Debug("quic connection established", "elapsed", elapsed)
}

// probeTLS attempts to establish a TLS connection to the specified address. We
Expand All @@ -673,7 +680,7 @@ func (p *dnsOverHTTPS) probeTLS(dialContext bootstrap.DialHandler, tlsConfig *tl
ch <- nil

elapsed := time.Since(startTime)
log.Debug("elapsed on establishing a TLS connection: %s", elapsed)
p.logger.Debug("tls connection established", "elapsed", elapsed)
}

// supportsH3 returns true if HTTP/3 is supported by this upstream.
Expand Down
5 changes: 5 additions & 0 deletions upstream/doh_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"testing"
"time"

"github.com/AdguardTeam/golibs/logutil/slogutil"
"github.com/AdguardTeam/golibs/testutil"
"github.com/miekg/dns"
"github.com/quic-go/quic-go"
Expand Down Expand Up @@ -75,6 +76,7 @@ func TestUpstreamDoH(t *testing.T) {

var lastState tls.ConnectionState
opts := &Options{
Logger: slogutil.NewDiscardLogger(),
InsecureSkipVerify: true,
HTTPVersions: tc.httpVersions,
VerifyConnection: func(state tls.ConnectionState) (err error) {
Expand Down Expand Up @@ -183,6 +185,7 @@ func TestUpstreamDoH_raceReconnect(t *testing.T) {
// race test.
address := fmt.Sprintf("https://%s/dns-query", srv.addr)
opts := &Options{
Logger: slogutil.NewDiscardLogger(),
InsecureSkipVerify: true,
HTTPVersions: tc.httpVersions,
Timeout: timeout,
Expand Down Expand Up @@ -232,6 +235,7 @@ func TestUpstreamDoH_serverRestart(t *testing.T) {

var err error
u, err = AddressToUpstream(upsAddr, &Options{
Logger: slogutil.NewDiscardLogger(),
InsecureSkipVerify: true,
HTTPVersions: tc.httpVersions,
Timeout: 100 * time.Millisecond,
Expand Down Expand Up @@ -280,6 +284,7 @@ func TestUpstreamDoH_0RTT(t *testing.T) {
tracer := &quicTracer{}
address := fmt.Sprintf("h3://%s/dns-query", srv.addr)
u, err := AddressToUpstream(address, &Options{
Logger: slogutil.NewDiscardLogger(),
InsecureSkipVerify: true,
QUICTracer: tracer.TracerForConnection,
})
Expand Down
15 changes: 10 additions & 5 deletions upstream/doq.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"crypto/tls"
"fmt"
"log/slog"
"net"
"net/url"
"os"
Expand All @@ -13,7 +14,7 @@ import (

"github.com/AdguardTeam/dnsproxy/proxyutil"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/logutil/slogutil"
"github.com/miekg/dns"
"github.com/quic-go/quic-go"
"github.com/quic-go/quic-go/http3"
Expand Down Expand Up @@ -87,6 +88,9 @@ type dnsOverQUIC struct {
// bytesPoolGuard protects bytesPool.
bytesPoolMu *sync.Mutex

// logger is used for exchange logging. It is never nil.
logger *slog.Logger

// timeout is the timeout for the upstream connection.
timeout time.Duration
}
Expand Down Expand Up @@ -122,6 +126,7 @@ func newDoQ(addr *url.URL, opts *Options) (u Upstream, err error) {
quicConfigMu: &sync.Mutex{},
connMu: &sync.Mutex{},
bytesPoolMu: &sync.Mutex{},
logger: opts.Logger,
timeout: opts.Timeout,
}

Expand Down Expand Up @@ -163,7 +168,7 @@ func (p *dnsOverQUIC) Exchange(m *dns.Msg) (resp *dns.Msg, err error) {
// connection could have been closed by the server or simply be broken due
// to how UDP NAT works. In this case the connection should be re-created.
if cached && err != nil {
log.Debug("dnsproxy: re-creating the QUIC connection and retrying due to %v", err)
p.logger.Debug("recreating the quic connection and retrying", slogutil.KeyError, err)

// Close the active connection to make sure the cached connection is
// cleaned up.
Expand Down Expand Up @@ -239,7 +244,7 @@ func (p *dnsOverQUIC) exchangeQUIC(req *dns.Msg, conn quic.Connection) (resp *dn
// of the stream, but does not prevent reading from it.
err = stream.Close()
if err != nil {
log.Debug("dnsproxy: closing quic stream: %s", err)
p.logger.Debug("closing quic stream", slogutil.KeyError, err)
}

return p.readMsg(stream)
Expand Down Expand Up @@ -334,7 +339,7 @@ func (p *dnsOverQUIC) openConnection() (conn quic.Connection, err error) {
// It's never actually used.
err = rawConn.Close()
if err != nil {
log.Debug("dnsproxy: closing raw connection for %s: %s", p.addr, err)
p.logger.Debug("closing raw connection", "addr", p.addr, slogutil.KeyError, err)
}

udpConn, ok := rawConn.(*net.UDPConn)
Expand Down Expand Up @@ -374,7 +379,7 @@ func (p *dnsOverQUIC) closeConnWithError(conn quic.Connection, err error) {

err = conn.CloseWithError(code, "")
if err != nil {
log.Error("dnsproxy: failed to close the conn: %v", err)
p.logger.Error("failed to close the conn", slogutil.KeyError, err)
}

// If the connection that's being closed is cached, reset the cache.
Expand Down
Loading

0 comments on commit 1305183

Please sign in to comment.