cleanup(netx): remove subpackages and unnecessary code (#788)
This pull request consists of several small and obvious cleanups in the netx directory. See https://github.com/ooni/probe/issues/2121
This commit is contained in:
parent
9354191b85
commit
1cb820b19d
|
@ -1,4 +1,4 @@
|
|||
package resolver
|
||||
package netx
|
||||
|
||||
import (
|
||||
"context"
|
|
@ -1,17 +1,21 @@
|
|||
package resolver_test
|
||||
package netx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/netx/resolver"
|
||||
"github.com/ooni/probe-cli/v3/internal/model/mocks"
|
||||
)
|
||||
|
||||
func TestCacheFailure(t *testing.T) {
|
||||
func TestCacheResolverFailure(t *testing.T) {
|
||||
expected := errors.New("mocked error")
|
||||
r := resolver.NewFakeResolverWithExplicitError(expected)
|
||||
cache := &resolver.CacheResolver{Resolver: r}
|
||||
r := &mocks.Resolver{
|
||||
MockLookupHost: func(ctx context.Context, domain string) ([]string, error) {
|
||||
return nil, expected
|
||||
},
|
||||
}
|
||||
cache := &CacheResolver{Resolver: r}
|
||||
addrs, err := cache.LookupHost(context.Background(), "www.google.com")
|
||||
if !errors.Is(err, expected) {
|
||||
t.Fatal("not the error we expected")
|
||||
|
@ -24,10 +28,14 @@ func TestCacheFailure(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestCacheHitSuccess(t *testing.T) {
|
||||
func TestCacheResolverHitSuccess(t *testing.T) {
|
||||
expected := errors.New("mocked error")
|
||||
r := resolver.NewFakeResolverWithExplicitError(expected)
|
||||
cache := &resolver.CacheResolver{Resolver: r}
|
||||
r := &mocks.Resolver{
|
||||
MockLookupHost: func(ctx context.Context, domain string) ([]string, error) {
|
||||
return nil, expected
|
||||
},
|
||||
}
|
||||
cache := &CacheResolver{Resolver: r}
|
||||
cache.Set("dns.google.com", []string{"8.8.8.8"})
|
||||
addrs, err := cache.LookupHost(context.Background(), "dns.google.com")
|
||||
if err != nil {
|
||||
|
@ -38,9 +46,13 @@ func TestCacheHitSuccess(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestCacheMissSuccess(t *testing.T) {
|
||||
r := resolver.NewFakeResolverWithResult([]string{"8.8.8.8"})
|
||||
cache := &resolver.CacheResolver{Resolver: r}
|
||||
func TestCacheResolverMissSuccess(t *testing.T) {
|
||||
r := &mocks.Resolver{
|
||||
MockLookupHost: func(ctx context.Context, domain string) ([]string, error) {
|
||||
return []string{"8.8.8.8"}, nil
|
||||
},
|
||||
}
|
||||
cache := &CacheResolver{Resolver: r}
|
||||
addrs, err := cache.LookupHost(context.Background(), "dns.google.com")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
@ -53,9 +65,13 @@ func TestCacheMissSuccess(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestCacheReadonlySuccess(t *testing.T) {
|
||||
r := resolver.NewFakeResolverWithResult([]string{"8.8.8.8"})
|
||||
cache := &resolver.CacheResolver{Resolver: r, ReadOnly: true}
|
||||
func TestCacheResolverReadonlySuccess(t *testing.T) {
|
||||
r := &mocks.Resolver{
|
||||
MockLookupHost: func(ctx context.Context, domain string) ([]string, error) {
|
||||
return []string{"8.8.8.8"}, nil
|
||||
},
|
||||
}
|
||||
cache := &CacheResolver{Resolver: r, ReadOnly: true}
|
||||
addrs, err := cache.LookupHost(context.Background(), "dns.google.com")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
|
@ -1,7 +1,4 @@
|
|||
// Package dialer allows you to create a net.Dialer-compatible
|
||||
// DialContext-enabled dialer with error wrapping, optional logging,
|
||||
// optional network-events saving, and optional proxying.
|
||||
package dialer
|
||||
package netx
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
|
@ -12,8 +9,8 @@ import (
|
|||
"github.com/ooni/probe-cli/v3/internal/tracex"
|
||||
)
|
||||
|
||||
// Config contains the settings for New.
|
||||
type Config struct {
|
||||
// dialerConfig contains the settings for New.
|
||||
type dialerConfig struct {
|
||||
// ContextByteCounting optionally configures context-based
|
||||
// byte counting. By default we don't do that.
|
||||
//
|
||||
|
@ -48,8 +45,8 @@ type Config struct {
|
|||
ReadWriteSaver *tracex.Saver
|
||||
}
|
||||
|
||||
// New creates a new Dialer from the specified config and resolver.
|
||||
func New(config *Config, resolver model.Resolver) model.Dialer {
|
||||
// newDialer creates a new Dialer from the specified config and resolver.
|
||||
func newDialer(config *dialerConfig, resolver model.Resolver) model.Dialer {
|
||||
var logger model.DebugLogger = model.DiscardLogger
|
||||
if config.Logger != nil {
|
||||
logger = config.Logger
|
|
@ -1,4 +1,4 @@
|
|||
package dialer
|
||||
package netx
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
@ -13,7 +13,7 @@ import (
|
|||
|
||||
func TestNewCreatesTheExpectedChain(t *testing.T) {
|
||||
saver := &tracex.Saver{}
|
||||
dlr := New(&Config{
|
||||
dlr := newDialer(&dialerConfig{
|
||||
ContextByteCounting: true,
|
||||
DialSaver: saver,
|
||||
Logger: log.Log,
|
||||
|
@ -37,7 +37,7 @@ func TestDialerNewSuccess(t *testing.T) {
|
|||
t.Skip("skip test in short mode")
|
||||
}
|
||||
log.SetLevel(log.DebugLevel)
|
||||
d := New(&Config{Logger: log.Log}, netxlite.DefaultResolver)
|
||||
d := newDialer(&dialerConfig{Logger: log.Log}, netxlite.DefaultResolver)
|
||||
txp := &http.Transport{DialContext: d.DialContext}
|
||||
client := &http.Client{Transport: txp}
|
||||
resp, err := client.Get("http://www.google.com")
|
|
@ -1,59 +0,0 @@
|
|||
package netx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/ooni/probe-cli/v3/internal/netxlite"
|
||||
)
|
||||
|
||||
type FakeDialer struct {
|
||||
Conn net.Conn
|
||||
Err error
|
||||
}
|
||||
|
||||
func (d FakeDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
time.Sleep(10 * time.Microsecond)
|
||||
return d.Conn, d.Err
|
||||
}
|
||||
|
||||
func (d FakeDialer) CloseIdleConnections() {}
|
||||
|
||||
type FakeTransport struct {
|
||||
Err error
|
||||
Func func(*http.Request) (*http.Response, error)
|
||||
Resp *http.Response
|
||||
}
|
||||
|
||||
func (txp FakeTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
time.Sleep(10 * time.Microsecond)
|
||||
if txp.Func != nil {
|
||||
return txp.Func(req)
|
||||
}
|
||||
if req.Body != nil {
|
||||
netxlite.ReadAllContext(req.Context(), req.Body)
|
||||
req.Body.Close()
|
||||
}
|
||||
if txp.Err != nil {
|
||||
return nil, txp.Err
|
||||
}
|
||||
txp.Resp.Request = req // non thread safe but it doesn't matter
|
||||
return txp.Resp, nil
|
||||
}
|
||||
|
||||
func (txp FakeTransport) CloseIdleConnections() {}
|
||||
|
||||
type FakeBody struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
func (fb FakeBody) Read(p []byte) (int, error) {
|
||||
time.Sleep(10 * time.Microsecond)
|
||||
return 0, fb.Err
|
||||
}
|
||||
|
||||
func (fb FakeBody) Close() error {
|
||||
return nil
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
// Package httptransport contains HTTP transport extensions.
|
||||
package httptransport
|
||||
package netx
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
|
@ -8,32 +7,32 @@ import (
|
|||
"github.com/ooni/probe-cli/v3/internal/netxlite"
|
||||
)
|
||||
|
||||
// Config contains the configuration required for constructing an HTTP transport
|
||||
type Config struct {
|
||||
// httpTransportConfig contains the configuration required for constructing an HTTP transport
|
||||
type httpTransportConfig struct {
|
||||
Dialer model.Dialer
|
||||
QUICDialer model.QUICDialer
|
||||
TLSDialer model.TLSDialer
|
||||
TLSConfig *tls.Config
|
||||
}
|
||||
|
||||
// NewHTTP3Transport creates a new HTTP3Transport instance.
|
||||
// newHTTP3Transport creates a new HTTP3Transport instance.
|
||||
//
|
||||
// Deprecation warning
|
||||
//
|
||||
// New code should use netxlite.NewHTTP3Transport instead.
|
||||
func NewHTTP3Transport(config Config) model.HTTPTransport {
|
||||
func newHTTP3Transport(config httpTransportConfig) model.HTTPTransport {
|
||||
// Rationale for using NoLogger here: previously this code did
|
||||
// not use a logger as well, so it's fine to keep it as is.
|
||||
return netxlite.NewHTTP3Transport(model.DiscardLogger,
|
||||
config.QUICDialer, config.TLSConfig)
|
||||
}
|
||||
|
||||
// NewSystemTransport creates a new "system" HTTP transport. That is a transport
|
||||
// newSystemTransport creates a new "system" HTTP transport. That is a transport
|
||||
// using the Go standard library with custom dialer and TLS dialer.
|
||||
//
|
||||
// Deprecation warning
|
||||
//
|
||||
// New code should use netxlite.NewHTTPTransport instead.
|
||||
func NewSystemTransport(config Config) model.HTTPTransport {
|
||||
func newSystemTransport(config httpTransportConfig) model.HTTPTransport {
|
||||
return netxlite.NewOOHTTPBaseTransport(config.Dialer, config.TLSDialer)
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
package netx_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/apex/log"
|
||||
"github.com/ooni/probe-cli/v3/internal/bytecounter"
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/netx"
|
||||
"github.com/ooni/probe-cli/v3/internal/netxlite"
|
||||
"github.com/ooni/probe-cli/v3/internal/tracex"
|
||||
)
|
||||
|
||||
func TestSuccess(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skip test in short mode")
|
||||
}
|
||||
log.SetLevel(log.DebugLevel)
|
||||
counter := bytecounter.New()
|
||||
config := netx.Config{
|
||||
BogonIsError: true,
|
||||
ByteCounter: counter,
|
||||
CacheResolutions: true,
|
||||
ContextByteCounting: true,
|
||||
DialSaver: &tracex.Saver{},
|
||||
HTTPSaver: &tracex.Saver{},
|
||||
Logger: log.Log,
|
||||
ReadWriteSaver: &tracex.Saver{},
|
||||
ResolveSaver: &tracex.Saver{},
|
||||
TLSSaver: &tracex.Saver{},
|
||||
}
|
||||
txp := netx.NewHTTPTransport(config)
|
||||
client := &http.Client{Transport: txp}
|
||||
resp, err := client.Get("https://www.google.com")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err = netxlite.ReadAllContext(context.Background(), resp.Body); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err = resp.Body.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if counter.Sent.Load() <= 0 {
|
||||
t.Fatal("no bytes sent?!")
|
||||
}
|
||||
if counter.Received.Load() <= 0 {
|
||||
t.Fatal("no bytes received?!")
|
||||
}
|
||||
if ev := config.DialSaver.Read(); len(ev) <= 0 {
|
||||
t.Fatal("no dial events?!")
|
||||
}
|
||||
if ev := config.HTTPSaver.Read(); len(ev) <= 0 {
|
||||
t.Fatal("no HTTP events?!")
|
||||
}
|
||||
if ev := config.ReadWriteSaver.Read(); len(ev) <= 0 {
|
||||
t.Fatal("no R/W events?!")
|
||||
}
|
||||
if ev := config.ResolveSaver.Read(); len(ev) <= 0 {
|
||||
t.Fatal("no resolver events?!")
|
||||
}
|
||||
if ev := config.TLSSaver.Read(); len(ev) <= 0 {
|
||||
t.Fatal("no TLS events?!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBogonResolutionNotBroken(t *testing.T) {
|
||||
saver := new(tracex.Saver)
|
||||
r := netx.NewResolver(netx.Config{
|
||||
BogonIsError: true,
|
||||
DNSCache: map[string][]string{
|
||||
"www.google.com": {"127.0.0.1"},
|
||||
},
|
||||
ResolveSaver: saver,
|
||||
Logger: log.Log,
|
||||
})
|
||||
addrs, err := r.LookupHost(context.Background(), "www.google.com")
|
||||
if !errors.Is(err, netxlite.ErrDNSBogon) {
|
||||
t.Fatal("not the error we expected")
|
||||
}
|
||||
if err.Error() != netxlite.FailureDNSBogonError {
|
||||
t.Fatal("error not correctly wrapped")
|
||||
}
|
||||
if len(addrs) > 0 {
|
||||
t.Fatal("expected no addresses here")
|
||||
}
|
||||
}
|
|
@ -31,9 +31,6 @@ import (
|
|||
"net/url"
|
||||
|
||||
"github.com/ooni/probe-cli/v3/internal/bytecounter"
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/netx/dialer"
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/netx/httptransport"
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/netx/resolver"
|
||||
"github.com/ooni/probe-cli/v3/internal/model"
|
||||
"github.com/ooni/probe-cli/v3/internal/netxlite"
|
||||
"github.com/ooni/probe-cli/v3/internal/tracex"
|
||||
|
@ -85,10 +82,10 @@ func NewResolver(config Config) model.Resolver {
|
|||
Resolver: r,
|
||||
}
|
||||
if config.CacheResolutions {
|
||||
r = &resolver.CacheResolver{Resolver: r}
|
||||
r = &CacheResolver{Resolver: r}
|
||||
}
|
||||
if config.DNSCache != nil {
|
||||
cache := &resolver.CacheResolver{Resolver: r, ReadOnly: true}
|
||||
cache := &CacheResolver{Resolver: r, ReadOnly: true}
|
||||
for key, values := range config.DNSCache {
|
||||
cache.Set(key, values)
|
||||
}
|
||||
|
@ -113,7 +110,7 @@ func NewDialer(config Config) model.Dialer {
|
|||
if config.FullResolver == nil {
|
||||
config.FullResolver = NewResolver(config)
|
||||
}
|
||||
return dialer.New(&dialer.Config{
|
||||
return newDialer(&dialerConfig{
|
||||
ContextByteCounting: config.ContextByteCounting,
|
||||
DialSaver: config.DialSaver,
|
||||
Logger: config.Logger,
|
||||
|
@ -175,7 +172,7 @@ func NewHTTPTransport(config Config) model.HTTPTransport {
|
|||
}
|
||||
|
||||
tInfo := allTransportsInfo[config.HTTP3Enabled]
|
||||
txp := tInfo.Factory(httptransport.Config{
|
||||
txp := tInfo.Factory(httpTransportConfig{
|
||||
Dialer: config.Dialer, QUICDialer: config.QUICDialer, TLSDialer: config.TLSDialer,
|
||||
TLSConfig: config.TLSConfig})
|
||||
|
||||
|
@ -195,17 +192,17 @@ func NewHTTPTransport(config Config) model.HTTPTransport {
|
|||
|
||||
// httpTransportInfo contains the constructing function as well as the transport name
|
||||
type httpTransportInfo struct {
|
||||
Factory func(httptransport.Config) model.HTTPTransport
|
||||
Factory func(httpTransportConfig) model.HTTPTransport
|
||||
TransportName string
|
||||
}
|
||||
|
||||
var allTransportsInfo = map[bool]httpTransportInfo{
|
||||
false: {
|
||||
Factory: httptransport.NewSystemTransport,
|
||||
Factory: newSystemTransport,
|
||||
TransportName: "tcp",
|
||||
},
|
||||
true: {
|
||||
Factory: httptransport.NewHTTP3Transport,
|
||||
Factory: newHTTP3Transport,
|
||||
TransportName: "quic",
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
package netx
|
||||
|
||||
import "crypto/x509"
|
||||
|
||||
// DefaultCertPool allows tests to access the default cert pool.
|
||||
func DefaultCertPool() *x509.CertPool {
|
||||
return defaultCertPool
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package netx_test
|
||||
package netx
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -11,15 +11,13 @@ import (
|
|||
|
||||
"github.com/apex/log"
|
||||
"github.com/ooni/probe-cli/v3/internal/bytecounter"
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/netx"
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/netx/resolver"
|
||||
"github.com/ooni/probe-cli/v3/internal/model/mocks"
|
||||
"github.com/ooni/probe-cli/v3/internal/netxlite"
|
||||
"github.com/ooni/probe-cli/v3/internal/tracex"
|
||||
)
|
||||
|
||||
func TestNewResolverVanilla(t *testing.T) {
|
||||
r := netx.NewResolver(netx.Config{})
|
||||
r := NewResolver(Config{})
|
||||
ir, ok := r.(*netxlite.ResolverIDNA)
|
||||
if !ok {
|
||||
t.Fatal("not the resolver we expected")
|
||||
|
@ -39,7 +37,7 @@ func TestNewResolverVanilla(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewResolverSpecificResolver(t *testing.T) {
|
||||
r := netx.NewResolver(netx.Config{
|
||||
r := NewResolver(Config{
|
||||
BaseResolver: &netxlite.BogonResolver{
|
||||
// not initialized because it doesn't matter in this context
|
||||
},
|
||||
|
@ -63,7 +61,7 @@ func TestNewResolverSpecificResolver(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewResolverWithBogonFilter(t *testing.T) {
|
||||
r := netx.NewResolver(netx.Config{
|
||||
r := NewResolver(Config{
|
||||
BogonIsError: true,
|
||||
})
|
||||
ir, ok := r.(*netxlite.ResolverIDNA)
|
||||
|
@ -89,7 +87,7 @@ func TestNewResolverWithBogonFilter(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewResolverWithLogging(t *testing.T) {
|
||||
r := netx.NewResolver(netx.Config{
|
||||
r := NewResolver(Config{
|
||||
Logger: log.Log,
|
||||
})
|
||||
ir, ok := r.(*netxlite.ResolverIDNA)
|
||||
|
@ -119,7 +117,7 @@ func TestNewResolverWithLogging(t *testing.T) {
|
|||
|
||||
func TestNewResolverWithSaver(t *testing.T) {
|
||||
saver := new(tracex.Saver)
|
||||
r := netx.NewResolver(netx.Config{
|
||||
r := NewResolver(Config{
|
||||
ResolveSaver: saver,
|
||||
})
|
||||
ir, ok := r.(*netxlite.ResolverIDNA)
|
||||
|
@ -148,7 +146,7 @@ func TestNewResolverWithSaver(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewResolverWithReadWriteCache(t *testing.T) {
|
||||
r := netx.NewResolver(netx.Config{
|
||||
r := NewResolver(Config{
|
||||
CacheResolutions: true,
|
||||
})
|
||||
ir, ok := r.(*netxlite.ResolverIDNA)
|
||||
|
@ -159,7 +157,7 @@ func TestNewResolverWithReadWriteCache(t *testing.T) {
|
|||
if !ok {
|
||||
t.Fatal("not the resolver we expected")
|
||||
}
|
||||
cr, ok := ewr.Resolver.(*resolver.CacheResolver)
|
||||
cr, ok := ewr.Resolver.(*CacheResolver)
|
||||
if !ok {
|
||||
t.Fatal("not the resolver we expected")
|
||||
}
|
||||
|
@ -177,7 +175,7 @@ func TestNewResolverWithReadWriteCache(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewResolverWithPrefilledReadonlyCache(t *testing.T) {
|
||||
r := netx.NewResolver(netx.Config{
|
||||
r := NewResolver(Config{
|
||||
DNSCache: map[string][]string{
|
||||
"dns.google.com": {"8.8.8.8"},
|
||||
},
|
||||
|
@ -190,7 +188,7 @@ func TestNewResolverWithPrefilledReadonlyCache(t *testing.T) {
|
|||
if !ok {
|
||||
t.Fatal("not the resolver we expected")
|
||||
}
|
||||
cr, ok := ewr.Resolver.(*resolver.CacheResolver)
|
||||
cr, ok := ewr.Resolver.(*CacheResolver)
|
||||
if !ok {
|
||||
t.Fatal("not the resolver we expected")
|
||||
}
|
||||
|
@ -211,7 +209,7 @@ func TestNewResolverWithPrefilledReadonlyCache(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewTLSDialerVanilla(t *testing.T) {
|
||||
td := netx.NewTLSDialer(netx.Config{})
|
||||
td := NewTLSDialer(Config{})
|
||||
rtd, ok := td.(*netxlite.TLSDialerLegacy)
|
||||
if !ok {
|
||||
t.Fatal("not the TLSDialer we expected")
|
||||
|
@ -222,7 +220,7 @@ func TestNewTLSDialerVanilla(t *testing.T) {
|
|||
if rtd.Config.NextProtos[0] != "h2" || rtd.Config.NextProtos[1] != "http/1.1" {
|
||||
t.Fatal("invalid Config.NextProtos")
|
||||
}
|
||||
if rtd.Config.RootCAs != netx.DefaultCertPool() {
|
||||
if rtd.Config.RootCAs != defaultCertPool {
|
||||
t.Fatal("invalid Config.RootCAs")
|
||||
}
|
||||
if rtd.Dialer == nil {
|
||||
|
@ -241,7 +239,7 @@ func TestNewTLSDialerVanilla(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewTLSDialerWithConfig(t *testing.T) {
|
||||
td := netx.NewTLSDialer(netx.Config{
|
||||
td := NewTLSDialer(Config{
|
||||
TLSConfig: new(tls.Config),
|
||||
})
|
||||
rtd, ok := td.(*netxlite.TLSDialerLegacy)
|
||||
|
@ -251,7 +249,7 @@ func TestNewTLSDialerWithConfig(t *testing.T) {
|
|||
if len(rtd.Config.NextProtos) != 0 {
|
||||
t.Fatal("invalid len(config.NextProtos)")
|
||||
}
|
||||
if rtd.Config.RootCAs != netx.DefaultCertPool() {
|
||||
if rtd.Config.RootCAs != defaultCertPool {
|
||||
t.Fatal("invalid Config.RootCAs")
|
||||
}
|
||||
if rtd.Dialer == nil {
|
||||
|
@ -270,7 +268,7 @@ func TestNewTLSDialerWithConfig(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewTLSDialerWithLogging(t *testing.T) {
|
||||
td := netx.NewTLSDialer(netx.Config{
|
||||
td := NewTLSDialer(Config{
|
||||
Logger: log.Log,
|
||||
})
|
||||
rtd, ok := td.(*netxlite.TLSDialerLegacy)
|
||||
|
@ -283,7 +281,7 @@ func TestNewTLSDialerWithLogging(t *testing.T) {
|
|||
if rtd.Config.NextProtos[0] != "h2" || rtd.Config.NextProtos[1] != "http/1.1" {
|
||||
t.Fatal("invalid Config.NextProtos")
|
||||
}
|
||||
if rtd.Config.RootCAs != netx.DefaultCertPool() {
|
||||
if rtd.Config.RootCAs != defaultCertPool {
|
||||
t.Fatal("invalid Config.RootCAs")
|
||||
}
|
||||
if rtd.Dialer == nil {
|
||||
|
@ -310,7 +308,7 @@ func TestNewTLSDialerWithLogging(t *testing.T) {
|
|||
|
||||
func TestNewTLSDialerWithSaver(t *testing.T) {
|
||||
saver := new(tracex.Saver)
|
||||
td := netx.NewTLSDialer(netx.Config{
|
||||
td := NewTLSDialer(Config{
|
||||
TLSSaver: saver,
|
||||
})
|
||||
rtd, ok := td.(*netxlite.TLSDialerLegacy)
|
||||
|
@ -323,7 +321,7 @@ func TestNewTLSDialerWithSaver(t *testing.T) {
|
|||
if rtd.Config.NextProtos[0] != "h2" || rtd.Config.NextProtos[1] != "http/1.1" {
|
||||
t.Fatal("invalid Config.NextProtos")
|
||||
}
|
||||
if rtd.Config.RootCAs != netx.DefaultCertPool() {
|
||||
if rtd.Config.RootCAs != defaultCertPool {
|
||||
t.Fatal("invalid Config.RootCAs")
|
||||
}
|
||||
if rtd.Dialer == nil {
|
||||
|
@ -349,7 +347,7 @@ func TestNewTLSDialerWithSaver(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewTLSDialerWithNoTLSVerifyAndConfig(t *testing.T) {
|
||||
td := netx.NewTLSDialer(netx.Config{
|
||||
td := NewTLSDialer(Config{
|
||||
TLSConfig: new(tls.Config),
|
||||
NoTLSVerify: true,
|
||||
})
|
||||
|
@ -363,7 +361,7 @@ func TestNewTLSDialerWithNoTLSVerifyAndConfig(t *testing.T) {
|
|||
if rtd.Config.InsecureSkipVerify != true {
|
||||
t.Fatal("expected true InsecureSkipVerify")
|
||||
}
|
||||
if rtd.Config.RootCAs != netx.DefaultCertPool() {
|
||||
if rtd.Config.RootCAs != defaultCertPool {
|
||||
t.Fatal("invalid Config.RootCAs")
|
||||
}
|
||||
if rtd.Dialer == nil {
|
||||
|
@ -382,7 +380,7 @@ func TestNewTLSDialerWithNoTLSVerifyAndConfig(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewTLSDialerWithNoTLSVerifyAndNoConfig(t *testing.T) {
|
||||
td := netx.NewTLSDialer(netx.Config{
|
||||
td := NewTLSDialer(Config{
|
||||
NoTLSVerify: true,
|
||||
})
|
||||
rtd, ok := td.(*netxlite.TLSDialerLegacy)
|
||||
|
@ -398,7 +396,7 @@ func TestNewTLSDialerWithNoTLSVerifyAndNoConfig(t *testing.T) {
|
|||
if rtd.Config.InsecureSkipVerify != true {
|
||||
t.Fatal("expected true InsecureSkipVerify")
|
||||
}
|
||||
if rtd.Config.RootCAs != netx.DefaultCertPool() {
|
||||
if rtd.Config.RootCAs != defaultCertPool {
|
||||
t.Fatal("invalid Config.RootCAs")
|
||||
}
|
||||
if rtd.Dialer == nil {
|
||||
|
@ -417,7 +415,7 @@ func TestNewTLSDialerWithNoTLSVerifyAndNoConfig(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewVanilla(t *testing.T) {
|
||||
txp := netx.NewHTTPTransport(netx.Config{})
|
||||
txp := NewHTTPTransport(Config{})
|
||||
if _, ok := txp.(*netxlite.HTTPTransportWrapper); !ok {
|
||||
t.Fatal("not the transport we expected")
|
||||
}
|
||||
|
@ -425,8 +423,12 @@ func TestNewVanilla(t *testing.T) {
|
|||
|
||||
func TestNewWithDialer(t *testing.T) {
|
||||
expected := errors.New("mocked error")
|
||||
dialer := netx.FakeDialer{Err: expected}
|
||||
txp := netx.NewHTTPTransport(netx.Config{
|
||||
dialer := &mocks.Dialer{
|
||||
MockDialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
return nil, expected
|
||||
},
|
||||
}
|
||||
txp := NewHTTPTransport(Config{
|
||||
Dialer: dialer,
|
||||
})
|
||||
client := &http.Client{Transport: txp}
|
||||
|
@ -453,7 +455,7 @@ func TestNewWithTLSDialer(t *testing.T) {
|
|||
},
|
||||
TLSHandshaker: &netxlite.TLSHandshakerConfigurable{},
|
||||
}
|
||||
txp := netx.NewHTTPTransport(netx.Config{
|
||||
txp := NewHTTPTransport(Config{
|
||||
TLSDialer: tlsDialer,
|
||||
})
|
||||
client := &http.Client{Transport: txp}
|
||||
|
@ -468,7 +470,7 @@ func TestNewWithTLSDialer(t *testing.T) {
|
|||
|
||||
func TestNewWithByteCounter(t *testing.T) {
|
||||
counter := bytecounter.New()
|
||||
txp := netx.NewHTTPTransport(netx.Config{
|
||||
txp := NewHTTPTransport(Config{
|
||||
ByteCounter: counter,
|
||||
})
|
||||
bctxp, ok := txp.(*bytecounter.HTTPTransport)
|
||||
|
@ -484,7 +486,7 @@ func TestNewWithByteCounter(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewWithLogger(t *testing.T) {
|
||||
txp := netx.NewHTTPTransport(netx.Config{
|
||||
txp := NewHTTPTransport(Config{
|
||||
Logger: log.Log,
|
||||
})
|
||||
ltxp, ok := txp.(*netxlite.HTTPTransportLogger)
|
||||
|
@ -501,7 +503,7 @@ func TestNewWithLogger(t *testing.T) {
|
|||
|
||||
func TestNewWithSaver(t *testing.T) {
|
||||
saver := new(tracex.Saver)
|
||||
txp := netx.NewHTTPTransport(netx.Config{
|
||||
txp := NewHTTPTransport(Config{
|
||||
HTTPSaver: saver,
|
||||
})
|
||||
stxptxp, ok := txp.(*tracex.HTTPTransportSaver)
|
||||
|
@ -520,7 +522,7 @@ func TestNewWithSaver(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewDNSClientInvalidURL(t *testing.T) {
|
||||
dnsclient, err := netx.NewDNSClient(netx.Config{}, "\t\t\t")
|
||||
dnsclient, err := NewDNSClient(Config{}, "\t\t\t")
|
||||
if err == nil || !strings.HasSuffix(err.Error(), "invalid control character in URL") {
|
||||
t.Fatal("not the error we expected")
|
||||
}
|
||||
|
@ -530,7 +532,7 @@ func TestNewDNSClientInvalidURL(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewDNSClientUnsupportedScheme(t *testing.T) {
|
||||
dnsclient, err := netx.NewDNSClient(netx.Config{}, "antani:///")
|
||||
dnsclient, err := NewDNSClient(Config{}, "antani:///")
|
||||
if err == nil || err.Error() != "unsupported resolver scheme" {
|
||||
t.Fatal("not the error we expected")
|
||||
}
|
||||
|
@ -540,8 +542,8 @@ func TestNewDNSClientUnsupportedScheme(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewDNSClientSystemResolver(t *testing.T) {
|
||||
dnsclient, err := netx.NewDNSClient(
|
||||
netx.Config{}, "system:///")
|
||||
dnsclient, err := NewDNSClient(
|
||||
Config{}, "system:///")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -552,8 +554,8 @@ func TestNewDNSClientSystemResolver(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewDNSClientEmpty(t *testing.T) {
|
||||
dnsclient, err := netx.NewDNSClient(
|
||||
netx.Config{}, "")
|
||||
dnsclient, err := NewDNSClient(
|
||||
Config{}, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -564,8 +566,8 @@ func TestNewDNSClientEmpty(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewDNSClientPowerdnsDoH(t *testing.T) {
|
||||
dnsclient, err := netx.NewDNSClient(
|
||||
netx.Config{}, "doh://powerdns")
|
||||
dnsclient, err := NewDNSClient(
|
||||
Config{}, "doh://powerdns")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -580,8 +582,8 @@ func TestNewDNSClientPowerdnsDoH(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewDNSClientGoogleDoH(t *testing.T) {
|
||||
dnsclient, err := netx.NewDNSClient(
|
||||
netx.Config{}, "doh://google")
|
||||
dnsclient, err := NewDNSClient(
|
||||
Config{}, "doh://google")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -596,8 +598,8 @@ func TestNewDNSClientGoogleDoH(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewDNSClientCloudflareDoH(t *testing.T) {
|
||||
dnsclient, err := netx.NewDNSClient(
|
||||
netx.Config{}, "doh://cloudflare")
|
||||
dnsclient, err := NewDNSClient(
|
||||
Config{}, "doh://cloudflare")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -613,8 +615,8 @@ func TestNewDNSClientCloudflareDoH(t *testing.T) {
|
|||
|
||||
func TestNewDNSClientCloudflareDoHSaver(t *testing.T) {
|
||||
saver := new(tracex.Saver)
|
||||
dnsclient, err := netx.NewDNSClient(
|
||||
netx.Config{ResolveSaver: saver}, "doh://cloudflare")
|
||||
dnsclient, err := NewDNSClient(
|
||||
Config{ResolveSaver: saver}, "doh://cloudflare")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -633,8 +635,8 @@ func TestNewDNSClientCloudflareDoHSaver(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewDNSClientUDP(t *testing.T) {
|
||||
dnsclient, err := netx.NewDNSClient(
|
||||
netx.Config{}, "udp://8.8.8.8:53")
|
||||
dnsclient, err := NewDNSClient(
|
||||
Config{}, "udp://8.8.8.8:53")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -650,8 +652,8 @@ func TestNewDNSClientUDP(t *testing.T) {
|
|||
|
||||
func TestNewDNSClientUDPDNSSaver(t *testing.T) {
|
||||
saver := new(tracex.Saver)
|
||||
dnsclient, err := netx.NewDNSClient(
|
||||
netx.Config{ResolveSaver: saver}, "udp://8.8.8.8:53")
|
||||
dnsclient, err := NewDNSClient(
|
||||
Config{ResolveSaver: saver}, "udp://8.8.8.8:53")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -670,8 +672,8 @@ func TestNewDNSClientUDPDNSSaver(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewDNSClientTCP(t *testing.T) {
|
||||
dnsclient, err := netx.NewDNSClient(
|
||||
netx.Config{}, "tcp://8.8.8.8:53")
|
||||
dnsclient, err := NewDNSClient(
|
||||
Config{}, "tcp://8.8.8.8:53")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -691,8 +693,8 @@ func TestNewDNSClientTCP(t *testing.T) {
|
|||
|
||||
func TestNewDNSClientTCPDNSSaver(t *testing.T) {
|
||||
saver := new(tracex.Saver)
|
||||
dnsclient, err := netx.NewDNSClient(
|
||||
netx.Config{ResolveSaver: saver}, "tcp://8.8.8.8:53")
|
||||
dnsclient, err := NewDNSClient(
|
||||
Config{ResolveSaver: saver}, "tcp://8.8.8.8:53")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -715,8 +717,8 @@ func TestNewDNSClientTCPDNSSaver(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewDNSClientDoT(t *testing.T) {
|
||||
dnsclient, err := netx.NewDNSClient(
|
||||
netx.Config{}, "dot://8.8.8.8:53")
|
||||
dnsclient, err := NewDNSClient(
|
||||
Config{}, "dot://8.8.8.8:53")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -736,8 +738,8 @@ func TestNewDNSClientDoT(t *testing.T) {
|
|||
|
||||
func TestNewDNSClientDoTDNSSaver(t *testing.T) {
|
||||
saver := new(tracex.Saver)
|
||||
dnsclient, err := netx.NewDNSClient(
|
||||
netx.Config{ResolveSaver: saver}, "dot://8.8.8.8:53")
|
||||
dnsclient, err := NewDNSClient(
|
||||
Config{ResolveSaver: saver}, "dot://8.8.8.8:53")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -760,8 +762,8 @@ func TestNewDNSClientDoTDNSSaver(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewDNSCLientDoTWithoutPort(t *testing.T) {
|
||||
c, err := netx.NewDNSClientWithOverrides(
|
||||
netx.Config{}, "dot://8.8.8.8", "", "8.8.8.8", "")
|
||||
c, err := NewDNSClientWithOverrides(
|
||||
Config{}, "dot://8.8.8.8", "", "8.8.8.8", "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -771,8 +773,8 @@ func TestNewDNSCLientDoTWithoutPort(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewDNSCLientTCPWithoutPort(t *testing.T) {
|
||||
c, err := netx.NewDNSClientWithOverrides(
|
||||
netx.Config{}, "tcp://8.8.8.8", "", "8.8.8.8", "")
|
||||
c, err := NewDNSClientWithOverrides(
|
||||
Config{}, "tcp://8.8.8.8", "", "8.8.8.8", "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -782,8 +784,8 @@ func TestNewDNSCLientTCPWithoutPort(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewDNSCLientUDPWithoutPort(t *testing.T) {
|
||||
c, err := netx.NewDNSClientWithOverrides(
|
||||
netx.Config{}, "udp://8.8.8.8", "", "8.8.8.8", "")
|
||||
c, err := NewDNSClientWithOverrides(
|
||||
Config{}, "udp://8.8.8.8", "", "8.8.8.8", "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -793,33 +795,108 @@ func TestNewDNSCLientUDPWithoutPort(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewDNSClientBadDoTEndpoint(t *testing.T) {
|
||||
_, err := netx.NewDNSClient(
|
||||
netx.Config{}, "dot://bad:endpoint:53")
|
||||
_, err := NewDNSClient(
|
||||
Config{}, "dot://bad:endpoint:53")
|
||||
if err == nil || !strings.Contains(err.Error(), "too many colons in address") {
|
||||
t.Fatal("expected error with bad endpoint")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewDNSClientBadTCPEndpoint(t *testing.T) {
|
||||
_, err := netx.NewDNSClient(
|
||||
netx.Config{}, "tcp://bad:endpoint:853")
|
||||
_, err := NewDNSClient(
|
||||
Config{}, "tcp://bad:endpoint:853")
|
||||
if err == nil || !strings.Contains(err.Error(), "too many colons in address") {
|
||||
t.Fatal("expected error with bad endpoint")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewDNSClientBadUDPEndpoint(t *testing.T) {
|
||||
_, err := netx.NewDNSClient(
|
||||
netx.Config{}, "udp://bad:endpoint:853")
|
||||
_, err := NewDNSClient(
|
||||
Config{}, "udp://bad:endpoint:853")
|
||||
if err == nil || !strings.Contains(err.Error(), "too many colons in address") {
|
||||
t.Fatal("expected error with bad endpoint")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewDNSCLientWithInvalidTLSVersion(t *testing.T) {
|
||||
_, err := netx.NewDNSClientWithOverrides(
|
||||
netx.Config{}, "dot://8.8.8.8", "", "", "TLSv999")
|
||||
_, err := NewDNSClientWithOverrides(
|
||||
Config{}, "dot://8.8.8.8", "", "", "TLSv999")
|
||||
if !errors.Is(err, netxlite.ErrInvalidTLSVersion) {
|
||||
t.Fatalf("not the error we expected: %+v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSuccess(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skip test in short mode")
|
||||
}
|
||||
log.SetLevel(log.DebugLevel)
|
||||
counter := bytecounter.New()
|
||||
config := Config{
|
||||
BogonIsError: true,
|
||||
ByteCounter: counter,
|
||||
CacheResolutions: true,
|
||||
ContextByteCounting: true,
|
||||
DialSaver: &tracex.Saver{},
|
||||
HTTPSaver: &tracex.Saver{},
|
||||
Logger: log.Log,
|
||||
ReadWriteSaver: &tracex.Saver{},
|
||||
ResolveSaver: &tracex.Saver{},
|
||||
TLSSaver: &tracex.Saver{},
|
||||
}
|
||||
txp := NewHTTPTransport(config)
|
||||
client := &http.Client{Transport: txp}
|
||||
resp, err := client.Get("https://www.google.com")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err = netxlite.ReadAllContext(context.Background(), resp.Body); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err = resp.Body.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if counter.Sent.Load() <= 0 {
|
||||
t.Fatal("no bytes sent?!")
|
||||
}
|
||||
if counter.Received.Load() <= 0 {
|
||||
t.Fatal("no bytes received?!")
|
||||
}
|
||||
if ev := config.DialSaver.Read(); len(ev) <= 0 {
|
||||
t.Fatal("no dial events?!")
|
||||
}
|
||||
if ev := config.HTTPSaver.Read(); len(ev) <= 0 {
|
||||
t.Fatal("no HTTP events?!")
|
||||
}
|
||||
if ev := config.ReadWriteSaver.Read(); len(ev) <= 0 {
|
||||
t.Fatal("no R/W events?!")
|
||||
}
|
||||
if ev := config.ResolveSaver.Read(); len(ev) <= 0 {
|
||||
t.Fatal("no resolver events?!")
|
||||
}
|
||||
if ev := config.TLSSaver.Read(); len(ev) <= 0 {
|
||||
t.Fatal("no TLS events?!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBogonResolutionNotBroken(t *testing.T) {
|
||||
saver := new(tracex.Saver)
|
||||
r := NewResolver(Config{
|
||||
BogonIsError: true,
|
||||
DNSCache: map[string][]string{
|
||||
"www.google.com": {"127.0.0.1"},
|
||||
},
|
||||
ResolveSaver: saver,
|
||||
Logger: log.Log,
|
||||
})
|
||||
addrs, err := r.LookupHost(context.Background(), "www.google.com")
|
||||
if !errors.Is(err, netxlite.ErrDNSBogon) {
|
||||
t.Fatal("not the error we expected")
|
||||
}
|
||||
if err.Error() != netxlite.FailureDNSBogonError {
|
||||
t.Fatal("error not correctly wrapped")
|
||||
}
|
||||
if len(addrs) > 0 {
|
||||
t.Fatal("expected no addresses here")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,128 +0,0 @@
|
|||
package resolver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/ooni/probe-cli/v3/internal/model"
|
||||
"github.com/ooni/probe-cli/v3/internal/model/mocks"
|
||||
"github.com/ooni/probe-cli/v3/internal/netxlite"
|
||||
"github.com/ooni/probe-cli/v3/internal/runtimex"
|
||||
)
|
||||
|
||||
type FakeDialer struct {
|
||||
Conn net.Conn
|
||||
Err error
|
||||
}
|
||||
|
||||
func (d FakeDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
time.Sleep(10 * time.Microsecond)
|
||||
return d.Conn, d.Err
|
||||
}
|
||||
|
||||
type FakeConn struct {
|
||||
ReadError error
|
||||
ReadData []byte
|
||||
SetDeadlineError error
|
||||
SetReadDeadlineError error
|
||||
SetWriteDeadlineError error
|
||||
WriteError error
|
||||
}
|
||||
|
||||
func (c *FakeConn) Read(b []byte) (int, error) {
|
||||
if len(c.ReadData) > 0 {
|
||||
n := copy(b, c.ReadData)
|
||||
c.ReadData = c.ReadData[n:]
|
||||
return n, nil
|
||||
}
|
||||
if c.ReadError != nil {
|
||||
return 0, c.ReadError
|
||||
}
|
||||
return 0, io.EOF
|
||||
}
|
||||
|
||||
func (c *FakeConn) Write(b []byte) (n int, err error) {
|
||||
if c.WriteError != nil {
|
||||
return 0, c.WriteError
|
||||
}
|
||||
n = len(b)
|
||||
return
|
||||
}
|
||||
|
||||
func (*FakeConn) Close() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (*FakeConn) LocalAddr() net.Addr {
|
||||
return &net.TCPAddr{}
|
||||
}
|
||||
|
||||
func (*FakeConn) RemoteAddr() net.Addr {
|
||||
return &net.TCPAddr{}
|
||||
}
|
||||
|
||||
func (c *FakeConn) SetDeadline(t time.Time) (err error) {
|
||||
return c.SetDeadlineError
|
||||
}
|
||||
|
||||
func (c *FakeConn) SetReadDeadline(t time.Time) (err error) {
|
||||
return c.SetReadDeadlineError
|
||||
}
|
||||
|
||||
func (c *FakeConn) SetWriteDeadline(t time.Time) (err error) {
|
||||
return c.SetWriteDeadlineError
|
||||
}
|
||||
|
||||
func NewFakeResolverThatFails() model.Resolver {
|
||||
return NewFakeResolverWithExplicitError(netxlite.ErrOODNSNoSuchHost)
|
||||
}
|
||||
|
||||
func NewFakeResolverWithExplicitError(err error) model.Resolver {
|
||||
runtimex.PanicIfNil(err, "passed nil error")
|
||||
return &mocks.Resolver{
|
||||
MockLookupHost: func(ctx context.Context, domain string) ([]string, error) {
|
||||
return nil, err
|
||||
},
|
||||
MockNetwork: func() string {
|
||||
return "fake"
|
||||
},
|
||||
MockAddress: func() string {
|
||||
return ""
|
||||
},
|
||||
MockCloseIdleConnections: func() {
|
||||
// nothing
|
||||
},
|
||||
MockLookupHTTPS: func(ctx context.Context, domain string) (*model.HTTPSSvc, error) {
|
||||
return nil, errors.New("not implemented")
|
||||
},
|
||||
MockLookupNS: func(ctx context.Context, domain string) ([]*net.NS, error) {
|
||||
return nil, errors.New("not implemented")
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func NewFakeResolverWithResult(r []string) model.Resolver {
|
||||
return &mocks.Resolver{
|
||||
MockLookupHost: func(ctx context.Context, domain string) ([]string, error) {
|
||||
return r, nil
|
||||
},
|
||||
MockNetwork: func() string {
|
||||
return "fake"
|
||||
},
|
||||
MockAddress: func() string {
|
||||
return ""
|
||||
},
|
||||
MockCloseIdleConnections: func() {
|
||||
// nothing
|
||||
},
|
||||
MockLookupHTTPS: func(ctx context.Context, domain string) (*model.HTTPSSvc, error) {
|
||||
return nil, errors.New("not implemented")
|
||||
},
|
||||
MockLookupNS: func(ctx context.Context, domain string) ([]*net.NS, error) {
|
||||
return nil, errors.New("not implemented")
|
||||
},
|
||||
}
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
package resolver
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
func GenReplyError(t *testing.T, code int) []byte {
|
||||
question := dns.Question{
|
||||
Name: dns.Fqdn("x.org"),
|
||||
Qtype: dns.TypeA,
|
||||
Qclass: dns.ClassINET,
|
||||
}
|
||||
query := new(dns.Msg)
|
||||
query.Id = dns.Id()
|
||||
query.RecursionDesired = true
|
||||
query.Question = make([]dns.Question, 1)
|
||||
query.Question[0] = question
|
||||
reply := new(dns.Msg)
|
||||
reply.Compress = true
|
||||
reply.MsgHdr.RecursionAvailable = true
|
||||
reply.SetRcode(query, code)
|
||||
data, err := reply.Pack()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
func GenReplySuccess(t *testing.T, qtype uint16, ips ...string) []byte {
|
||||
question := dns.Question{
|
||||
Name: dns.Fqdn("x.org"),
|
||||
Qtype: qtype,
|
||||
Qclass: dns.ClassINET,
|
||||
}
|
||||
query := new(dns.Msg)
|
||||
query.Id = dns.Id()
|
||||
query.RecursionDesired = true
|
||||
query.Question = make([]dns.Question, 1)
|
||||
query.Question[0] = question
|
||||
reply := new(dns.Msg)
|
||||
reply.Compress = true
|
||||
reply.MsgHdr.RecursionAvailable = true
|
||||
reply.SetReply(query)
|
||||
for _, ip := range ips {
|
||||
switch qtype {
|
||||
case dns.TypeA:
|
||||
reply.Answer = append(reply.Answer, &dns.A{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: dns.Fqdn("x.org"),
|
||||
Rrtype: qtype,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: 0,
|
||||
},
|
||||
A: net.ParseIP(ip),
|
||||
})
|
||||
case dns.TypeAAAA:
|
||||
reply.Answer = append(reply.Answer, &dns.AAAA{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: dns.Fqdn("x.org"),
|
||||
Rrtype: qtype,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: 0,
|
||||
},
|
||||
AAAA: net.ParseIP(ip),
|
||||
})
|
||||
}
|
||||
}
|
||||
data, err := reply.Pack()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return data
|
||||
}
|
|
@ -1,119 +0,0 @@
|
|||
package resolver_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/apex/log"
|
||||
"github.com/ooni/probe-cli/v3/internal/model"
|
||||
"github.com/ooni/probe-cli/v3/internal/netxlite"
|
||||
)
|
||||
|
||||
func init() {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
}
|
||||
|
||||
func testresolverquick(t *testing.T, reso model.Resolver) {
|
||||
if testing.Short() {
|
||||
t.Skip("skip test in short mode")
|
||||
}
|
||||
reso = &netxlite.ResolverLogger{
|
||||
Logger: log.Log,
|
||||
Resolver: reso,
|
||||
}
|
||||
addrs, err := reso.LookupHost(context.Background(), "dns.google.com")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if addrs == nil {
|
||||
t.Fatal("expected non-nil addrs here")
|
||||
}
|
||||
var foundquad8 bool
|
||||
for _, addr := range addrs {
|
||||
// See https://github.com/ooni/probe-engine/pull/954/checks?check_run_id=1182269025
|
||||
if addr == "8.8.8.8" || addr == "2001:4860:4860::8888" {
|
||||
foundquad8 = true
|
||||
}
|
||||
}
|
||||
if !foundquad8 {
|
||||
t.Fatalf("did not find 8.8.8.8 in output; output=%+v", addrs)
|
||||
}
|
||||
}
|
||||
|
||||
// Ensuring we can handle Internationalized Domain Names (IDNs) without issues
|
||||
func testresolverquickidna(t *testing.T, reso model.Resolver) {
|
||||
if testing.Short() {
|
||||
t.Skip("skip test in short mode")
|
||||
}
|
||||
reso = &netxlite.ResolverIDNA{
|
||||
Resolver: &netxlite.ResolverLogger{
|
||||
Logger: log.Log,
|
||||
Resolver: reso,
|
||||
},
|
||||
}
|
||||
addrs, err := reso.LookupHost(context.Background(), "яндекс.рф")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if addrs == nil {
|
||||
t.Fatal("expected non-nil addrs here")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewResolverSystem(t *testing.T) {
|
||||
reso := netxlite.NewResolverSystem()
|
||||
testresolverquick(t, reso)
|
||||
testresolverquickidna(t, reso)
|
||||
}
|
||||
|
||||
func TestNewResolverUDPAddress(t *testing.T) {
|
||||
reso := netxlite.NewUnwrappedSerialResolver(
|
||||
netxlite.NewUnwrappedDNSOverUDPTransport(netxlite.DefaultDialer, "8.8.8.8:53"))
|
||||
testresolverquick(t, reso)
|
||||
testresolverquickidna(t, reso)
|
||||
}
|
||||
|
||||
func TestNewResolverUDPDomain(t *testing.T) {
|
||||
reso := netxlite.NewUnwrappedSerialResolver(
|
||||
netxlite.NewUnwrappedDNSOverUDPTransport(netxlite.DefaultDialer, "dns.google.com:53"))
|
||||
testresolverquick(t, reso)
|
||||
testresolverquickidna(t, reso)
|
||||
}
|
||||
|
||||
func TestNewResolverTCPAddress(t *testing.T) {
|
||||
reso := netxlite.NewUnwrappedSerialResolver(
|
||||
netxlite.NewUnwrappedDNSOverTCPTransport(new(net.Dialer).DialContext, "8.8.8.8:53"))
|
||||
testresolverquick(t, reso)
|
||||
testresolverquickidna(t, reso)
|
||||
}
|
||||
|
||||
func TestNewResolverTCPDomain(t *testing.T) {
|
||||
reso := netxlite.NewUnwrappedSerialResolver(
|
||||
netxlite.NewUnwrappedDNSOverTCPTransport(new(net.Dialer).DialContext, "dns.google.com:53"))
|
||||
testresolverquick(t, reso)
|
||||
testresolverquickidna(t, reso)
|
||||
}
|
||||
|
||||
func TestNewResolverDoTAddress(t *testing.T) {
|
||||
reso := netxlite.NewUnwrappedSerialResolver(
|
||||
netxlite.NewUnwrappedDNSOverTLSTransport(new(tls.Dialer).DialContext, "8.8.8.8:853"))
|
||||
testresolverquick(t, reso)
|
||||
testresolverquickidna(t, reso)
|
||||
}
|
||||
|
||||
func TestNewResolverDoTDomain(t *testing.T) {
|
||||
reso := netxlite.NewUnwrappedSerialResolver(
|
||||
netxlite.NewUnwrappedDNSOverTLSTransport(new(tls.Dialer).DialContext, "dns.google.com:853"))
|
||||
testresolverquick(t, reso)
|
||||
testresolverquickidna(t, reso)
|
||||
}
|
||||
|
||||
func TestNewResolverDoH(t *testing.T) {
|
||||
reso := netxlite.NewUnwrappedSerialResolver(
|
||||
netxlite.NewUnwrappedDNSOverHTTPSTransport(http.DefaultClient, "https://cloudflare-dns.com/dns-query"))
|
||||
testresolverquick(t, reso)
|
||||
testresolverquickidna(t, reso)
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
package tlsdialer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"io"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
type EOFDialer struct{}
|
||||
|
||||
func (EOFDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
time.Sleep(10 * time.Microsecond)
|
||||
return nil, io.EOF
|
||||
}
|
||||
|
||||
type EOFConnDialer struct{}
|
||||
|
||||
func (EOFConnDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
return EOFConn{}, nil
|
||||
}
|
||||
|
||||
type EOFConn struct {
|
||||
net.Conn
|
||||
}
|
||||
|
||||
func (EOFConn) Read(p []byte) (int, error) {
|
||||
time.Sleep(10 * time.Microsecond)
|
||||
return 0, io.EOF
|
||||
}
|
||||
|
||||
func (EOFConn) Write(p []byte) (int, error) {
|
||||
time.Sleep(10 * time.Microsecond)
|
||||
return 0, io.EOF
|
||||
}
|
||||
|
||||
func (EOFConn) Close() error {
|
||||
time.Sleep(10 * time.Microsecond)
|
||||
return io.EOF
|
||||
}
|
||||
|
||||
func (EOFConn) LocalAddr() net.Addr {
|
||||
return EOFAddr{}
|
||||
}
|
||||
|
||||
func (EOFConn) RemoteAddr() net.Addr {
|
||||
return EOFAddr{}
|
||||
}
|
||||
|
||||
func (EOFConn) SetDeadline(t time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (EOFConn) SetReadDeadline(t time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (EOFConn) SetWriteDeadline(t time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type EOFAddr struct{}
|
||||
|
||||
func (EOFAddr) Network() string {
|
||||
return "tcp"
|
||||
}
|
||||
|
||||
func (EOFAddr) String() string {
|
||||
return "127.0.0.1:1234"
|
||||
}
|
||||
|
||||
type EOFTLSHandshaker struct{}
|
||||
|
||||
func (EOFTLSHandshaker) Handshake(
|
||||
ctx context.Context, conn net.Conn, config *tls.Config,
|
||||
) (net.Conn, tls.ConnectionState, error) {
|
||||
time.Sleep(10 * time.Microsecond)
|
||||
return nil, tls.ConnectionState{}, io.EOF
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
package tlsdialer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
type FakeDialer struct {
|
||||
Conn net.Conn
|
||||
Err error
|
||||
}
|
||||
|
||||
func (d FakeDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
time.Sleep(10 * time.Microsecond)
|
||||
return d.Conn, d.Err
|
||||
}
|
||||
|
||||
type FakeConn struct {
|
||||
ReadError error
|
||||
ReadData []byte
|
||||
SetDeadlineError error
|
||||
SetReadDeadlineError error
|
||||
SetWriteDeadlineError error
|
||||
WriteError error
|
||||
}
|
||||
|
||||
func (c *FakeConn) Read(b []byte) (int, error) {
|
||||
if len(c.ReadData) > 0 {
|
||||
n := copy(b, c.ReadData)
|
||||
c.ReadData = c.ReadData[n:]
|
||||
return n, nil
|
||||
}
|
||||
if c.ReadError != nil {
|
||||
return 0, c.ReadError
|
||||
}
|
||||
return 0, io.EOF
|
||||
}
|
||||
|
||||
func (c *FakeConn) Write(b []byte) (n int, err error) {
|
||||
if c.WriteError != nil {
|
||||
return 0, c.WriteError
|
||||
}
|
||||
n = len(b)
|
||||
return
|
||||
}
|
||||
|
||||
func (*FakeConn) Close() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (*FakeConn) LocalAddr() net.Addr {
|
||||
return &net.TCPAddr{}
|
||||
}
|
||||
|
||||
func (*FakeConn) RemoteAddr() net.Addr {
|
||||
return &net.TCPAddr{}
|
||||
}
|
||||
|
||||
func (c *FakeConn) SetDeadline(t time.Time) (err error) {
|
||||
return c.SetDeadlineError
|
||||
}
|
||||
|
||||
func (c *FakeConn) SetReadDeadline(t time.Time) (err error) {
|
||||
return c.SetReadDeadlineError
|
||||
}
|
||||
|
||||
func (c *FakeConn) SetWriteDeadline(t time.Time) (err error) {
|
||||
return c.SetWriteDeadlineError
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package tlsdialer_test
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/apex/log"
|
||||
oohttp "github.com/ooni/oohttp"
|
||||
"github.com/ooni/probe-cli/v3/internal/netxlite"
|
||||
)
|
||||
|
||||
func TestTLSDialerSuccess(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skip test in short mode")
|
||||
}
|
||||
log.SetLevel(log.DebugLevel)
|
||||
dialer := &netxlite.TLSDialerLegacy{Dialer: netxlite.DefaultDialer,
|
||||
TLSHandshaker: &netxlite.TLSHandshakerLogger{
|
||||
TLSHandshaker: &netxlite.TLSHandshakerConfigurable{},
|
||||
DebugLogger: log.Log,
|
||||
},
|
||||
}
|
||||
txp := &oohttp.StdlibTransport{
|
||||
Transport: &oohttp.Transport{
|
||||
DialTLSContext: dialer.DialTLSContext,
|
||||
ForceAttemptHTTP2: true,
|
||||
},
|
||||
}
|
||||
client := &http.Client{Transport: txp}
|
||||
resp, err := client.Get("https://www.google.com")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
resp.Body.Close()
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package tlsdialer_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"io"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/netx/tlsdialer"
|
||||
"github.com/ooni/probe-cli/v3/internal/netxlite"
|
||||
)
|
||||
|
||||
func TestSystemTLSHandshakerEOFError(t *testing.T) {
|
||||
h := &netxlite.TLSHandshakerConfigurable{}
|
||||
conn, _, err := h.Handshake(context.Background(), tlsdialer.EOFConn{}, &tls.Config{
|
||||
ServerName: "x.org",
|
||||
})
|
||||
if err != io.EOF {
|
||||
t.Fatal("not the error that we expected")
|
||||
}
|
||||
if conn != nil {
|
||||
t.Fatal("expected nil con here")
|
||||
}
|
||||
}
|
||||
|
||||
type SetDeadlineConn struct {
|
||||
tlsdialer.EOFConn
|
||||
deadlines []time.Time
|
||||
}
|
||||
|
||||
func (c *SetDeadlineConn) SetDeadline(t time.Time) error {
|
||||
c.deadlines = append(c.deadlines, t)
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user