ooni-probe-cli/internal/engine/netx/dialer/dialer.go

91 lines
2.8 KiB
Go

package dialer
import (
"context"
"net"
"net/url"
"github.com/ooni/probe-cli/v3/internal/engine/netx/trace"
"github.com/ooni/probe-cli/v3/internal/errorsx"
"github.com/ooni/probe-cli/v3/internal/netxlite"
)
// Dialer establishes network connections.
type Dialer interface {
// DialContext behaves like net.Dialer.DialContext.
DialContext(ctx context.Context, network, address string) (net.Conn, error)
}
// Resolver is the interface we expect from a DNS resolver.
type Resolver interface {
// LookupHost behaves like net.Resolver.LookupHost.
LookupHost(ctx context.Context, hostname string) (addrs []string, err error)
}
// Logger is the interface we expect from a logger.
type Logger interface {
// Debugf formats and emits a debug message.
Debugf(format string, v ...interface{})
// Debug emits a debug message.
Debug(msg string)
}
// Config contains the settings for New.
type Config struct {
// ContextByteCounting optionally configures context-based
// byte counting. By default we don't do that.
//
// Use WithExperimentByteCounter and WithSessionByteCounter
// to assign byte counters to a context. The code will use
// corresponding, private functions to access the configured
// byte counters and will notify them about I/O events.
//
// Bug
//
// This implementation cannot properly account for the bytes that are sent by
// persistent connections, because they strick to the counters set when the
// connection was established. This typically means we miss the bytes sent and
// received when submitting a measurement. Such bytes are specifically not
// seen by the experiment specific byte counter.
//
// For this reason, this implementation may be heavily changed/removed.
ContextByteCounting bool
// DialSaver is the optional saver for dialing events. If not
// set, we will not save any dialing event.
DialSaver *trace.Saver
// Logger is the optional logger. If not set, there
// will be no logging from the new dialer.
Logger Logger
// ProxyURL is the optional proxy URL.
ProxyURL *url.URL
// ReadWriteSaver is like DialSaver but for I/O events.
ReadWriteSaver *trace.Saver
}
// New creates a new Dialer from the specified config and resolver.
func New(config *Config, resolver Resolver) Dialer {
var d Dialer = netxlite.DefaultDialer
d = &errorsx.ErrorWrapperDialer{Dialer: d}
if config.Logger != nil {
d = &netxlite.DialerLogger{Dialer: d, Logger: config.Logger}
}
if config.DialSaver != nil {
d = &saverDialer{Dialer: d, Saver: config.DialSaver}
}
if config.ReadWriteSaver != nil {
d = &saverConnDialer{Dialer: d, Saver: config.ReadWriteSaver}
}
d = &netxlite.DialerResolver{Resolver: resolver, Dialer: d}
d = &proxyDialer{ProxyURL: config.ProxyURL, Dialer: d}
if config.ContextByteCounting {
d = &byteCounterDialer{Dialer: d}
}
d = &shapingDialer{Dialer: d}
return d
}