netxlite

package
v0.0.0-...-41ba115 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 30, 2023 License: GPL-3.0 Imports: 29 Imported by: 0

Documentation

Overview

Package netxlite contains network extensions.

This package is the basic networking building block that you should be using every time you need networking.

It implements interfaces defined in the internal/model package.

You should consider checking the tutorial explaining how to use this package for network measurements: https://github.com/ooni/probe-cli/tree/master/internal/tutorial/netxlite.

Naming and history

Previous versions of this package were called netx. Compared to such versions this package is lightweight because it does not contain code to perform the measurements, hence its name.

Design

We want to potentially be able to observe each low-level operation separately, even though this is not done by this package. This is the use case where we are performing measurements.

We also want to be able to use this package in a more casual way without having to compose each operation separately. This, instead, is the use case where we're communicating with the OONI backend.

We want to optionally provide detailed logging of every operation, thus users can use `-v` to obtain OONI logs.

We also want to mock any underlying dependency for testing.

We also want to map errors to OONI failures, which are described by https://github.com/ooni/spec/blob/master/data-formats/df-007-errors.md.

We want to have reasonable watchdog timeouts for each operation.

Operations

This package implements the following operations:

1. establishing a TCP connection;

2. performing a domain name resolution with the "system" resolver (i.e., getaddrinfo on Unix) or custom DNS transports (e.g., DoT, DoH);

3. performing the TLS handshake;

4. performing the QUIC handshake;

5. dialing with TCP, TLS, and QUIC (where in this context dialing means combining domain name resolution and "connecting");

6. performing HTTP, HTTP2, and HTTP3 round trips.

Operations 1, 2, 3, and 4 are used when we perform measurements, while 5 and 6 are mostly used when speaking with our backend.

Index

Constants

View Source
const (
	DNSNoSuchHostSuffix        = "no such host"
	DNSServerMisbehavingSuffix = "server misbehaving"
	DNSNoAnswerSuffix          = "no answer from DNS server"
)

We use these strings to string-match errors in the standard library and map such errors to OONI failures.

View Source
const (
	// DNSOverUDPCollectMultipleReplies tells DNSOverUDPReadRawRepliesFrom to collect
	// all the replies rather than stopping after the first good one.
	DNSOverUDPCollectMultipleReplies = 1 << iota

	// DNSOverUDPIncludeRepliesFromUnexpectedServers causes DNSOverUDPReadRawRepliesFrom
	// to also include in the returned replies the ones coming from unexpected addrs.
	DNSOverUDPIncludeRepliesFromUnexpectedServers

	// DNSOverUDPOmitTimeoutIfSomeRepliesReturned causes DNSOverUDPReadRawRepliesFrom
	// to omit the final timeout error in case at least one reply was returned.
	DNSOverUDPOmitTimeoutIfSomeRepliesReturned
)
View Source
const (
	FailureAddressFamilyNotSupported    = "address_family_not_supported"
	FailureAddressInUse                 = "address_in_use"
	FailureAddressNotAvailable          = "address_not_available"
	FailureAlreadyConnected             = "already_connected"
	FailureBadAddress                   = "bad_address"
	FailureBadFileDescriptor            = "bad_file_descriptor"
	FailureConnectionAborted            = "connection_aborted"
	FailureConnectionAlreadyClosed      = "connection_already_closed"
	FailureConnectionAlreadyInProgress  = "connection_already_in_progress"
	FailureConnectionRefused            = "connection_refused"
	FailureConnectionReset              = "connection_reset"
	FailureDNSBogonError                = "dns_bogon_error"
	FailureDNSNXDOMAINError             = "dns_nxdomain_error"
	FailureDNSNoAnswer                  = "dns_no_answer"
	FailureDNSNonRecoverableFailure     = "dns_non_recoverable_failure"
	FailureDNSRefusedError              = "dns_refused_error"
	FailureDNSReplyFromUnexpectedServer = "dns_reply_from_unexpected_server"
	FailureDNSReplyWithWrongQueryID     = "dns_reply_with_wrong_query_id"
	FailureDNSServerMisbehaving         = "dns_server_misbehaving"
	FailureDNSTemporaryFailure          = "dns_temporary_failure"
	FailureDNSServfailError             = "dns_servfail_error"
	FailureDestinationAddressRequired   = "destination_address_required"
	FailureEOFError                     = "eof_error"
	FailureGenericTimeoutError          = "generic_timeout_error"
	FailureHostUnreachable              = "host_unreachable"
	FailureInterrupted                  = "interrupted"
	FailureInvalidArgument              = "invalid_argument"
	FailureJSONParseError               = "json_parse_error"
	FailureMessageSize                  = "message_size"
	FailureNetworkDown                  = "network_down"
	FailureNetworkReset                 = "network_reset"
	FailureNetworkUnreachable           = "network_unreachable"
	FailureNoBufferSpace                = "no_buffer_space"
	FailureNoProtocolOption             = "no_protocol_option"
	FailureNotASocket                   = "not_a_socket"
	FailureNotConnected                 = "not_connected"
	FailureOperationWouldBlock          = "operation_would_block"
	FailurePermissionDenied             = "permission_denied"
	FailureProtocolNotSupported         = "protocol_not_supported"
	FailureQUICIncompatibleVersion      = "quic_incompatible_version"
	FailureSSLFailedHandshake           = "ssl_failed_handshake"
	FailureSSLInvalidCertificate        = "ssl_invalid_certificate"
	FailureSSLInvalidHostname           = "ssl_invalid_hostname"
	FailureSSLUnknownAuthority          = "ssl_unknown_authority"
	FailureTimedOut                     = "timed_out"
	FailureWrongProtocolType            = "wrong_protocol_type"
)

This enumeration lists the failures defined at https://github.com/ooni/spec/blob/master/data-formats/df-007-errors.md. Please, refer to that document for more information.

View Source
const (
	ECONNREFUSED    = unix.ECONNREFUSED
	ECONNRESET      = unix.ECONNRESET
	EHOSTUNREACH    = unix.EHOSTUNREACH
	ETIMEDOUT       = unix.ETIMEDOUT
	EAFNOSUPPORT    = unix.EAFNOSUPPORT
	EADDRINUSE      = unix.EADDRINUSE
	EADDRNOTAVAIL   = unix.EADDRNOTAVAIL
	EISCONN         = unix.EISCONN
	EFAULT          = unix.EFAULT
	EBADF           = unix.EBADF
	ECONNABORTED    = unix.ECONNABORTED
	EALREADY        = unix.EALREADY
	EDESTADDRREQ    = unix.EDESTADDRREQ
	EINTR           = unix.EINTR
	EINVAL          = unix.EINVAL
	EMSGSIZE        = unix.EMSGSIZE
	ENETDOWN        = unix.ENETDOWN
	ENETRESET       = unix.ENETRESET
	ENETUNREACH     = unix.ENETUNREACH
	ENOBUFS         = unix.ENOBUFS
	ENOPROTOOPT     = unix.ENOPROTOOPT
	ENOTSOCK        = unix.ENOTSOCK
	ENOTCONN        = unix.ENOTCONN
	EWOULDBLOCK     = unix.EWOULDBLOCK
	EACCES          = unix.EACCES
	EPROTONOSUPPORT = unix.EPROTONOSUPPORT
	EPROTOTYPE      = unix.EPROTOTYPE
)

This enumeration provides a canonical name for every system-call error we support. Note: this list is system dependent. You're currently looking at the list of errors for linux.

View Source
const (
	// ResolveOperation is the operation where we resolve a domain name.
	ResolveOperation = "resolve"

	// ConnectOperation is the operation where we do a TCP connect.
	ConnectOperation = "connect"

	// TLSHandshakeOperation is the TLS handshake.
	TLSHandshakeOperation = "tls_handshake"

	// QUICHandshakeOperation is the handshake to setup a QUIC connection.
	QUICHandshakeOperation = "quic_handshake"

	// QUICListenOperation is when we open a listening UDP conn for QUIC.
	//
	// Note: this name is already widely used so we should probably not change
	// it, but a more correct name for this event would be "udp_listen".
	QUICListenOperation = "quic_listen"

	// HTTPRoundTripOperation is the HTTP round trip.
	HTTPRoundTripOperation = "http_round_trip"

	// CloseOperation is when we close a socket.
	CloseOperation = "close"

	// ReadOperation is when we read from a socket.
	ReadOperation = "read"

	// WriteOperation is when we write to a socket.
	WriteOperation = "write"

	// ReadFromOperation is when we read from an UDP socket.
	ReadFromOperation = "read_from"

	// WriteToOperation is when we write to an UDP socket.
	WriteToOperation = "write_to"

	// UnknownOperation is when we cannot determine the operation.
	UnknownOperation = "unknown"

	// TopLevelOperation is used when the failure happens at top level. This
	// happens for example with urlgetter with a cancelled context.
	TopLevelOperation = "top_level"
)

Operations that we measure. They are the possible values of the ErrWrapper.Operation field.

Variables

View Source
var (
	ErrOODNSNoSuchHost  = fmt.Errorf("ooniresolver: %s", DNSNoSuchHostSuffix)
	ErrOODNSMisbehaving = fmt.Errorf("ooniresolver: %s", DNSServerMisbehavingSuffix)
	ErrOODNSNoAnswer    = fmt.Errorf("ooniresolver: %s", DNSNoAnswerSuffix)
)

These errors are returned by custom DNSTransport instances (e.g., DNSOverHTTPS and DNSOverUDP). Their suffix matches the equivalent unexported errors used by the Go standard library.

View Source
var (
	ErrOODNSRefused  = errors.New("ooniresolver: refused")
	ErrOODNSServfail = errors.New("ooniresolver: servfail")
)

These errors are not part of the Go standard library but we can return them in our custom resolvers.

View Source
var (
	// ErrDNSReplyWithWrongQueryID indicates we have got a DNS reply with the wrong queryID.
	ErrDNSReplyWithWrongQueryID = errors.New(FailureDNSReplyWithWrongQueryID)

	// ErrDNSIsResponse indicates that we were passed a DNS response.
	ErrDNSIsResponse = errors.New("ooresolver: expected query but received response")

	// ErrDNSIsQuery indicates that we were passed a DNS query.
	ErrDNSIsQuery = errors.New("ooresolver: expected response but received query")
)
View Source
var (
	DefaultDialer        = &dialerSystem{}
	DefaultTLSHandshaker = defaultTLSHandshaker
	NewConnUTLS          = newConnUTLS
	DefaultResolver      = &resolverSystem{}
)

These vars export internal names to legacy ooni/probe-cli code.

Deprecated: do not use these names in new code.

View Source
var ErrDNSBogon = errors.New("dns: detected bogon address")

ErrDNSBogon indicates that we found a bogon address. Code that filters for DNS bogons MUST use this error.

View Source
var ErrDNSIPAddress = errors.New("ooresolver: expected domain, found IP address")

ErrDNSIPAddress indicates that you passed an IP address to a DNS function that only works with domain names.

View Source
var ErrDNSNotImplemented = errors.New("ooresolver: DNS query not implemented")

ErrDNSNotImplemented indicates that a given query is not implemented.

View Source
var ErrInvalidIP = errors.New("netxlite: invalid IP")

ErrInvalidIP indicates that a string is not a valid IP.

View Source
var ErrInvalidTLSVersion = errors.New("invalid TLS version")

ErrInvalidTLSVersion indicates that you passed us a string that does not represent a valid TLS version.

View Source
var ErrNoConnReuse = errors.New("cannot reuse connection")

ErrNoConnReuse is the type of error returned when you create a "single use" dialer or a "single use" TLS dialer and you dial more than once, which is not supported by such a dialer.

View Source
var ErrNoDNSTransport = errors.New("operation requires a DNS transport")

ErrNoDNSTransport is the error returned when you attempt to perform a DNS operation that requires a custom DNSTransport (e.g., DNSOverHTTPS) but you are using the "system" resolver instead.

View Source
var ErrNoDialer = errors.New("no configured dialer")

ErrNoDialer is the type of error returned by "null" dialers when you attempt to dial with them.

View Source
var ErrNoResolver = errors.New("no configured resolver")

ErrNoResolver is the type of error returned by "without resolver" dialer when asked to dial for and endpoint containing a domain name, since they can only dial for endpoints containing IP addresses.

View Source
var ErrNoTLSDialer = errors.New("no configured TLS dialer")

ErrNoTLSDialer is the type of error returned by "null" TLS dialers when you attempt to dial with them.

View Source
var ErrNotTLSConn = errors.New("not a TLSConn")

ErrNotTLSConn occur when an interface accepts a net.Conn but internally needs a TLSConn and you pass a net.Conn that doesn't implement TLSConn to such an interface.

View Source
var ErrUTLSHandshakePanic = errors.New("utls: handshake panic")

ErrUTLSHandshakePanic indicates that there was panic handshaking when we were using the yawning/utls library for parroting. See https://github.com/ooni/probe/issues/1770 for more information.

TProxy is the fundamental variable controlling how netxlite creates net.Conn and model.UDPLikeConn, as well as how it uses the stdlib resolver. By modifying this variable, you can effectively transparently proxy netxlite (and hence OONI) activities to other services. This is quite convenient when performing quality assurance tests.

Functions

func ClassifyResolverError

func ClassifyResolverError(err error) string

ClassifyResolverError maps DNS resolution errors to OONI failure strings.

If the input error is an *ErrWrapper we don't perform the classification again and we return its Failure.

If this classifier fails, it calls ClassifyGenericError and returns to the caller its return value.

func ConfigureTLSVersion

func ConfigureTLSVersion(config *tls.Config, version string) error

ConfigureTLSVersion configures the correct TLS version into a *tls.Config or returns ErrInvalidTLSVersion.

Recognized strings: TLSv1.3, TLSv1.2, TLSv1.1, TLSv1.0.

func CopyContext

func CopyContext(ctx context.Context, dst io.Writer, src io.Reader) (int64, error)

CopyContext is like io.Copy but may terminate earlier when the context expires. This function has the same caveats of ReadAllContext regarding the temporary leaking of the background I/O goroutine.

As of Go 1.17.6, CopyContext additionally deals with wrapped io.EOF correctly, while io.Copy does not. See https://github.com/ooni/probe/issues/1965.

func DNSOverUDPReadRawRepliesFrom

func DNSOverUDPReadRawRepliesFrom(pconn model.UDPLikeConn, expectedAddr net.Addr,
	deadline time.Time, flags int64) <-chan *DNSOverUDPRawReply

DNSOverUDPReadRawRepliesFrom receives raw DNS replies form the given UDP conn.

Arguments:

- pconn is the UDP conn to use;

- expectedAddr is the address from which we expect replies;

- deadline is the i/o timeout deadline;

- flags contains flags modifying the behavior.

The return value is the channel when we emit events occurring while attempting to receive raw replies from the given UDP socket. The channel is closed when the background goroutine that attempts receiving returns.

If you do not specify any flag, this function will always post a single DNSOverUDPRawReply entry to the returned channel. To determine whether this reply is successful or an error, check the .Error field.

We support the following flags:

1. DNSOverUDPCollectMultipleReplies prevents this function from stopping receiving once it has received the first raw reply from the socket. The function will continue running until an error occurs. Among the errors that may occur, there is notably the timeout caused by the deadline.

2. DNSOverUDPIncludeRepliesFromUnexpectedServers makes this function more lax so that also replies coming from unexpected servers are returned. If you specify this flag, check the .ValidSourceAddr field to determine whether a returned raw reply came from the expected DNS server.

3. DNSOverUDPOmitTimeoutIfSomeRepliesReturned is such that, when we hit the final deadline timeout, we will not post it as an error iff we've already posted to the channel _at least_ one raw reply.

func DNSOverUDPWriteRawQueryTo

func DNSOverUDPWriteRawQueryTo(listener model.UDPListener,
	serverEndpoint string, rawQuery []byte) (model.UDPLikeConn, net.Addr, error)

DNSOverUDPwriteRawQueryTo sends a raw query to the given remote server. and returns the connection from which we'll receive replies.

func IsBogon

func IsBogon(address string) bool

IsBogon returns whether an IP address is bogon. Passing to this function a non-IP address causes it to return true.

func IsIPv6

func IsIPv6(candidate string) (bool, error)

IsIPv6 returns true if the given candidate is a valid IP address representation and such representation is IPv6.

func IsLoopback

func IsLoopback(address string) bool

IsLoopback returns whether an IP address is loopback. Passing to this function a non-IP address causes it to return true.

func NewDefaultCertPool

func NewDefaultCertPool() *x509.CertPool

NewDefaultCertPool returns the default x509 certificate pool that we bundle from Mozilla. It's safe to modify the returned value: every invocation returns a distinct *x509.CertPool instance.

func NewDialerWithResolver

func NewDialerWithResolver(logger model.DebugLogger, resolver model.Resolver) model.Dialer

NewDialerWithResolver calls WrapDialer for the stdlib dialer.

func NewDialerWithoutResolver

func NewDialerWithoutResolver(logger model.DebugLogger) model.Dialer

NewDialerWithoutResolver calls NewDialerWithResolver with a "null" resolver.

The returned dialer fails with ErrNoResolver if passed a domain name.

func NewHTTP3Transport

func NewHTTP3Transport(
	logger model.DebugLogger, dialer model.QUICDialer, tlsConfig *tls.Config) model.HTTPTransport

NewHTTP3Transport creates a new HTTPTransport using http3. The dialer argument MUST NOT be nil. If the tlsConfig argument is nil, then the code will use the default TLS configuration.

func NewHTTPClientStdlib

func NewHTTPClientStdlib(logger model.DebugLogger) model.HTTPClient

NewHTTPClientStdlib creates a new HTTPClient that uses the standard library for TLS and DNS resolutions.

func NewHTTPTransport

func NewHTTPTransport(logger model.DebugLogger, dialer model.Dialer, tlsDialer model.TLSDialer) model.HTTPTransport

NewHTTPTransport combines NewOOHTTPBaseTransport and WrapHTTPTransport.

This factory and NewHTTPTransportStdlib are the recommended ways of creating a new HTTPTransport.

func NewHTTPTransportStdlib

func NewHTTPTransportStdlib(logger model.DebugLogger) model.HTTPTransport

NewHTTPTransportStdlib creates a new HTTPTransport using the stdlib for DNS resolutions and TLS.

This factory calls NewHTTPTransport with suitable dialers.

This factory and NewHTTPTransport are the recommended ways of creating a new HTTPTransport.

func NewNullDialer

func NewNullDialer() model.Dialer

NewNullDialer returns a dialer that always fails with ErrNoDialer.

func NewNullTLSDialer

func NewNullTLSDialer() model.TLSDialer

NewNullTLSDialer returns a TLS dialer that always fails with ErrNoTLSDialer.

func NewOOHTTPBaseTransport

func NewOOHTTPBaseTransport(dialer model.Dialer, tlsDialer model.TLSDialer) model.HTTPTransport

NewOOHTTPBaseTransport creates an HTTPTransport using the given dialers.

The returned transport will gracefully handle TLS connections created using gitlab.com/yawning/utls.git, if the TLS dialer is a dialer using such library for TLS operations.

The returned transport will not have a configured proxy, not even the proxy configurable from the environment.

The returned transport will disable transparent decompression of compressed response bodies (and will not automatically ask for such compression, though you can always do that manually).

The returned transport will configure TCP and TLS connections created using its dialer and TLS dialer to always have a read watchdog timeout to address https://github.com/ooni/probe/issues/1609.

The returned transport will always enforce 1 connection per host and we cannot get rid of this QUIRK requirement because it is necessary to perform sane measurements with tracing. We will be able to possibly relax this requirement after we change the way in which we perform measurements.

This is a low level factory. Consider not using it directly.

func NewQUICDialerWithResolver

func NewQUICDialerWithResolver(listener model.UDPListener,
	logger model.DebugLogger, resolver model.Resolver) model.QUICDialer

NewQUICDialerWithResolver returns a QUICDialer using the given UDPListener to create listening connections and the given Resolver to resolve domain names (if needed).

Properties of the dialer:

1. logs events using the given logger;

2. resolves domain names using the givern resolver;

3. when using a resolver, _may_ attempt multiple dials in parallel (happy eyeballs) and _may_ return an aggregate error to the caller;

4. wraps errors;

5. has a configured connect timeout;

6. if a dialer wraps a resolver, the dialer will forward the CloseIdleConnection call to its resolver (which is instrumental to manage a DoH resolver connections properly).

func NewQUICDialerWithoutResolver

func NewQUICDialerWithoutResolver(listener model.UDPListener, logger model.DebugLogger) model.QUICDialer

NewQUICDialerWithoutResolver is like NewQUICDialerWithResolver except that there is no configured resolver. So, if you pass in an address containing a domain name, the dial will fail with the ErrNoResolver failure.

func NewResolverStdlib

func NewResolverStdlib(logger model.DebugLogger) model.Resolver

NewResolverStdlib creates a new Resolver by combining WrapResolver with a a DNSSystemResolver using a DNSSystemTransport.

func NewResolverUDP

func NewResolverUDP(logger model.DebugLogger, dialer model.Dialer, address string) model.Resolver

NewResolverUDP creates a new Resolver using DNS-over-UDP.

Arguments:

- logger is the logger to use

- dialer is the dialer to create and connect UDP conns

- address is the server address (e.g., 1.1.1.1:53)

func NewSingleUseDialer

func NewSingleUseDialer(conn net.Conn) model.Dialer

NewSingleUseDialer returns a "single use" dialer. The first dial will succed and return conn regardless of the network and address arguments passed to DialContext. Any subsequent dial returns ErrNoConnReuse.

func NewSingleUseQUICDialer

func NewSingleUseQUICDialer(sess quic.EarlySession) model.QUICDialer

NewSingleUseQUICDialer is like NewSingleUseDialer but for QUIC.

func NewSingleUseTLSDialer

func NewSingleUseTLSDialer(conn TLSConn) model.TLSDialer

NewSingleUseTLSDialer is like NewSingleUseDialer but takes in input a TLSConn rather than a net.Conn.

func NewTLSDialer

func NewTLSDialer(dialer model.Dialer, handshaker model.TLSHandshaker) model.TLSDialer

NewTLSDialer creates a new TLS dialer using the given dialer and handshaker.

func NewTLSDialerWithConfig

func NewTLSDialerWithConfig(d model.Dialer, h model.TLSHandshaker, c *tls.Config) model.TLSDialer

NewTLSDialerWithConfig is like NewTLSDialer with an optional config.

func NewTLSHandshakerStdlib

func NewTLSHandshakerStdlib(logger model.DebugLogger) model.TLSHandshaker

NewTLSHandshakerStdlib creates a new TLS handshaker using the go standard library to manage TLS.

The handshaker guarantees:

1. logging

2. error wrapping

func NewTLSHandshakerUTLS

func NewTLSHandshakerUTLS(logger model.DebugLogger, id *utls.ClientHelloID) model.TLSHandshaker

NewTLSHandshakerUTLS creates a new TLS handshaker using gitlab.com/yawning/utls for TLS.

The id is the address of something like utls.HelloFirefox_55.

The handshaker guarantees:

1. logging

2. error wrapping

Passing a nil `id` will make this function panic.

func NewUDPListener

func NewUDPListener() model.UDPListener

NewUDPListener creates a new UDPListener using the standard library to create listening UDP sockets.

func ParseUDPAddr

func ParseUDPAddr(address string) (*net.UDPAddr, error)

ParseUDPAddr maps the string representation of an UDP endpoint to the corresponding *net.UDPAddr representation.

func ReadAllContext

func ReadAllContext(ctx context.Context, r io.Reader) ([]byte, error)

ReadAllContext is like io.ReadAll but reads r in a background goroutine. This function will return earlier if the context is cancelled. In which case we will continue reading from the reader in the background goroutine, and we will discard the result. To stop the long-running goroutine, close the connection bound to the reader. Until such a connection is closed, you're leaking the backround goroutine and doing I/O.

As of Go 1.17.6, ReadAllContext additionally deals with wrapped io.EOF correctly, while io.ReadAll does not. See https://github.com/ooni/probe/issues/1965.

func TLSCipherSuiteString

func TLSCipherSuiteString(value uint16) string

TLSCipherSuiteString returns the TLS cipher suite as a string. If value is zero, we return the empty string. If we don't know the mapping from the value to a cipher suite name, we return `TLS_CIPHER_SUITE_UNKNOWN_ddd` where `ddd` is the numeric value passed to this function.

func TLSVersionString

func TLSVersionString(value uint16) string

TLSVersionString returns a TLS version string. If value is zero, we return the empty string. If the value is unknown, we return `TLS_VERSION_UNKNOWN_ddd` where `ddd` is the numeric value passed to this function.

func WrapDialer

func WrapDialer(logger model.DebugLogger, resolver model.Resolver, dialer model.Dialer) model.Dialer

WrapDialer creates a new Dialer that wraps the given Dialer. The returned Dialer has the following properties:

1. logs events using the given logger;

2. resolves domain names using the givern resolver;

3. when the resolver is not a "null" resolver, each available enpoint is tried sequentially. On error, the code will return what it believes to be the most representative error in the pack. Most often, the first error that occurred. Choosing the error to return using this logic is a QUIRK that we owe to the original implementation of netx. We cannot change this behavior until we refactor legacy code using it.

Removing this quirk from the codebase is documented as TODO(https://github.com/ooni/probe/issues/1779).

4. wraps errors;

5. has a configured connect timeout;

6. if a dialer wraps a resolver, the dialer will forward the CloseIdleConnection call to its resolver (which is instrumental to manage a DoH resolver connections properly).

In general, do not use WrapDialer directly but try to use more high-level factories, e.g., NewDialerWithResolver.

func WrapHTTPClient

func WrapHTTPClient(clnt model.HTTPClient) model.HTTPClient

WrapHTTPClient wraps an HTTP client to add error wrapping capabilities.

func WrapHTTPTransport

func WrapHTTPTransport(logger model.DebugLogger, txp model.HTTPTransport) model.HTTPTransport

WrapHTTPTransport creates an HTTPTransport using the given logger and guarantees that returned errors are wrapped.

This is a low level factory. Consider not using it directly.

func WrapResolver

func WrapResolver(logger model.DebugLogger, resolver model.Resolver) model.Resolver

WrapResolver creates a new resolver that wraps an existing resolver to add these properties:

1. handles IDNA;

2. performs logging;

3. short-circuits IP addresses like getaddrinfo does (i.e., resolving "1.1.1.1" yields []string{"1.1.1.1"};

4. wraps errors;

5. enforces reasonable timeouts ( see https://github.com/ooni/probe/issues/1726).

This is a low-level factory. Use only if out of alternatives.

Types

type AddressResolver deprecated

type AddressResolver = resolverShortCircuitIPAddr

These types export internal names to legacy ooni/probe-cli code.

Deprecated: do not use these names in new code.

type Classifier

type Classifier func(err error) string

Classifier is the type of the function that maps a Go error to a OONI failure string defined at https://github.com/ooni/spec/blob/master/data-formats/df-007-errors.md.

type DNSDecoderMiekg

type DNSDecoderMiekg struct{}

DNSDecoderMiekg uses github.com/miekg/dns to implement the Decoder.

func (*DNSDecoderMiekg) DecodeLookupHTTPS

func (d *DNSDecoderMiekg) DecodeLookupHTTPS(data []byte, queryID uint16) (*model.HTTPSSvc, error)

func (*DNSDecoderMiekg) DecodeLookupHost

func (d *DNSDecoderMiekg) DecodeLookupHost(
	qtype uint16, data []byte, queryID uint16) ([]string, error)

func (*DNSDecoderMiekg) DecodeLookupNS

func (d *DNSDecoderMiekg) DecodeLookupNS(data []byte, queryID uint16) ([]*net.NS, error)

func (*DNSDecoderMiekg) DecodeLookupPTR

func (d *DNSDecoderMiekg) DecodeLookupPTR(data []byte, queryID uint16) ([]string, error)

func (*DNSDecoderMiekg) DecodeReplyLookupHTTPS

func (d *DNSDecoderMiekg) DecodeReplyLookupHTTPS(reply *dns.Msg) (*model.HTTPSSvc, error)

func (*DNSDecoderMiekg) DecodeReplyLookupHost

func (d *DNSDecoderMiekg) DecodeReplyLookupHost(qtype uint16, reply *dns.Msg) ([]string, error)

func (*DNSDecoderMiekg) DecodeReplyLookupNS

func (d *DNSDecoderMiekg) DecodeReplyLookupNS(reply *dns.Msg) ([]*net.NS, error)

func (*DNSDecoderMiekg) DecodeReplyLookupPTR

func (d *DNSDecoderMiekg) DecodeReplyLookupPTR(reply *dns.Msg) ([]string, error)

func (*DNSDecoderMiekg) ParseQuery

func (d *DNSDecoderMiekg) ParseQuery(data []byte) (*dns.Msg, error)

func (*DNSDecoderMiekg) ParseReply

func (d *DNSDecoderMiekg) ParseReply(data []byte) (*dns.Msg, error)

func (*DNSDecoderMiekg) ParseReplyForQueryID

func (d *DNSDecoderMiekg) ParseReplyForQueryID(data []byte, queryID uint16) (*dns.Msg, error)

type DNSEncoderMiekg

type DNSEncoderMiekg struct{}

DNSEncoderMiekg uses github.com/miekg/dns to implement the Encoder.

func (*DNSEncoderMiekg) EncodeQuery

func (e *DNSEncoderMiekg) EncodeQuery(
	domain string, qtype uint16, padding bool) ([]byte, uint16, error)

func (*DNSEncoderMiekg) EncodeReply

func (e *DNSEncoderMiekg) EncodeReply(query *dns.Msg, addresses []string) (*dns.Msg, error)

type DNSOverHTTPSTransport

type DNSOverHTTPSTransport struct {
	// Client is the MANDATORY http client to use.
	Client model.HTTPClient

	// URL is the MANDATORY URL of the DNS-over-HTTPS server.
	URL string

	// HostOverride is OPTIONAL and allows to override the
	// Host header sent in every request.
	HostOverride string

	// Protocol is the MANDATORY protocol to report to the caller
	// via Network(). It should be "doh" or "doh3".
	Protocol string
}

DNSOverHTTPSTransport is a DNS-over-HTTPS DNSTransport.

func NewDNSOverHTTPSTransport

func NewDNSOverHTTPSTransport(client model.HTTPClient, URL string) *DNSOverHTTPSTransport

NewDNSOverHTTPSTransport creates a new DNSOverHTTPS instance.

Arguments:

- client in http.Client-like type (e.g., http.DefaultClient);

- URL is the DoH resolver URL (e.g., https://1.1.1.1/dns-query).

func NewDNSOverHTTPSTransportWithHostOverride

func NewDNSOverHTTPSTransportWithHostOverride(
	client model.HTTPClient, URL, hostOverride string) *DNSOverHTTPSTransport

NewDNSOverHTTPSTransportWithHostOverride creates a new DNSOverHTTPSTransport with the given Host header override.

func (*DNSOverHTTPSTransport) Address

func (t *DNSOverHTTPSTransport) Address() string

Address returns the URL we're using for the DoH server.

func (*DNSOverHTTPSTransport) CloseIdleConnections

func (t *DNSOverHTTPSTransport) CloseIdleConnections()

CloseIdleConnections closes idle connections, if any.

func (*DNSOverHTTPSTransport) Network

func (t *DNSOverHTTPSTransport) Network() string

Network returns the transport network, i.e., "doh".

func (*DNSOverHTTPSTransport) RequiresPadding

func (t *DNSOverHTTPSTransport) RequiresPadding() bool

RequiresPadding returns true for DoH according to RFC8467.

func (*DNSOverHTTPSTransport) RoundTrip

func (t *DNSOverHTTPSTransport) RoundTrip(ctx context.Context, query []byte) ([]byte, error)

RoundTrip sends a query and receives a reply.

type DNSOverTCPTransport

type DNSOverTCPTransport struct {
	// contains filtered or unexported fields
}

DNSOverTCPTransport is a DNS-over-{TCP,TLS} DNSTransport.

Bug: this implementation always creates a new connection for each query.

func NewDNSOverTCPTransport

func NewDNSOverTCPTransport(dial DialContextFunc, address string) *DNSOverTCPTransport

NewDNSOverTCPTransport creates a new DNSOverTCP transport.

Arguments:

- dial is a function with the net.Dialer.DialContext's signature;

- address is the endpoint address (e.g., 8.8.8.8:53).

func NewDNSOverTLS

func NewDNSOverTLS(dial DialContextFunc, address string) *DNSOverTCPTransport

NewDNSOverTLS creates a new DNSOverTLS transport.

Arguments:

- dial is a function with the net.Dialer.DialContext's signature;

- address is the endpoint address (e.g., 8.8.8.8:853).

func (*DNSOverTCPTransport) Address

func (t *DNSOverTCPTransport) Address() string

Address returns the upstream server endpoint (e.g., "1.1.1.1:853").

func (*DNSOverTCPTransport) CloseIdleConnections

func (t *DNSOverTCPTransport) CloseIdleConnections()

CloseIdleConnections closes idle connections, if any.

func (*DNSOverTCPTransport) Network

func (t *DNSOverTCPTransport) Network() string

Network returns the transport network, i.e., "dot" or "tcp".

func (*DNSOverTCPTransport) RequiresPadding

func (t *DNSOverTCPTransport) RequiresPadding() bool

RequiresPadding returns true for DoT and false for TCP according to RFC8467.

func (*DNSOverTCPTransport) RoundTrip

func (t *DNSOverTCPTransport) RoundTrip(ctx context.Context, query []byte) ([]byte, error)

RoundTrip sends a query and receives a reply.

type DNSOverUDPRawReply

type DNSOverUDPRawReply struct {
	// Error indicates that an error occurred.
	Error error

	// RawReply contains the raw reply.
	RawReply []byte

	// Received is the time when we received the reply.
	Received time.Time

	// SourceAddr is address that sent the reply.
	SourceAddr net.Addr

	// ValidSourceAddr is true if SourceAddr is equal to ExpectedAddr.
	ValidSourceAddr bool
}

DNSOverUDPRawReply is the a raw reply returned by DNSOverUDPReadRawRepliesFrom.

type DNSOverUDPTransport

type DNSOverUDPTransport struct {
	// contains filtered or unexported fields
}

DNSOverUDPTransport is a DNS-over-UDP DNSTransport.

func NewDNSOverUDPTransport

func NewDNSOverUDPTransport(dialer model.Dialer, address string) *DNSOverUDPTransport

NewDNSOverUDPTransport creates a DNSOverUDP instance.

Arguments:

- dialer is any type that implements the Dialer interface;

- address is the endpoint address (e.g., 8.8.8.8:53).

func (*DNSOverUDPTransport) Address

func (t *DNSOverUDPTransport) Address() string

Address returns the upstream server address.

func (*DNSOverUDPTransport) CloseIdleConnections

func (t *DNSOverUDPTransport) CloseIdleConnections()

CloseIdleConnections closes idle connections, if any.

func (*DNSOverUDPTransport) Network

func (t *DNSOverUDPTransport) Network() string

Network returns the transport network, i.e., "udp".

func (*DNSOverUDPTransport) RequiresPadding

func (t *DNSOverUDPTransport) RequiresPadding() bool

RequiresPadding returns false for UDP according to RFC8467.

func (*DNSOverUDPTransport) RoundTrip

func (t *DNSOverUDPTransport) RoundTrip(ctx context.Context, rawQuery []byte) ([]byte, error)

RoundTrip sends a query and receives a reply.

type DNSSystemResolver

type DNSSystemResolver struct {
	// contains filtered or unexported fields
}

DNSSystemResolver is a resolver using DNSSystemTransport.

func NewDNSSystemResolver

func NewDNSSystemResolver(txp model.DNSTransport) *DNSSystemResolver

NewDNSSystemResolver creates a new DNSSystemResolver instance using the given DNSSystemTransport instance.

func (*DNSSystemResolver) Address

func (r *DNSSystemResolver) Address() string

Address implements Resolver.Address.

func (*DNSSystemResolver) CloseIdleConnections

func (r *DNSSystemResolver) CloseIdleConnections()

CloseIdleConnections implements Resolver.CloseIdleConnections.

func (*DNSSystemResolver) LookupHTTPS

func (r *DNSSystemResolver) LookupHTTPS(
	ctx context.Context, domain string) (*model.HTTPSSvc, error)

LookupHTTPS implements DNSResolver.LookupHTTPS.

func (*DNSSystemResolver) LookupHost

func (r *DNSSystemResolver) LookupHost(
	ctx context.Context, hostname string) (addrs []string, err error)

LookupHost implements Resolver.LookupHost.

func (*DNSSystemResolver) LookupNS

func (r *DNSSystemResolver) LookupNS(
	ctx context.Context, domain string) ([]*net.NS, error)

LookupNS implements DNSResolver.LookupNS.

func (*DNSSystemResolver) LookupPTR

func (r *DNSSystemResolver) LookupPTR(
	ctx context.Context, domain string) ([]string, error)

LookupPTR implements DNSResolver.LookupPTR.

func (*DNSSystemResolver) Network

func (r *DNSSystemResolver) Network() string

Network implements Resolver.Network.

type DNSSystemTransport

type DNSSystemTransport struct {
	// contains filtered or unexported fields
}

DNSSystemTransport is a transport that uses getaddrinfo or the go standard library to perform a DNS resolution.

func NewDNSSystemTransport

func NewDNSSystemTransport() *DNSSystemTransport

NewDNSSystemTransport returns a new DNSSystemTransport.

func (*DNSSystemTransport) Address

func (txp *DNSSystemTransport) Address() string

Address implements DNSTransport.Address.

func (*DNSSystemTransport) CloseIdleConnections

func (txp *DNSSystemTransport) CloseIdleConnections()

CloseIdleConnections closes idle connections, if any.

func (*DNSSystemTransport) Network

func (txp *DNSSystemTransport) Network() string

Network implements DNSTransport.Network.

func (*DNSSystemTransport) RequiresPadding

func (txp *DNSSystemTransport) RequiresPadding() bool

RequiresPadding implements DNSTransport.RequiresPadding.

func (*DNSSystemTransport) RoundTrip

func (txp *DNSSystemTransport) RoundTrip(
	ctx context.Context, query []byte) (reply []byte, err error)

RoundTrip implements DNSTransport.RoundTrip. This function expects in input a single query for dns.ANY and performs a DNS lookup using the system resolver. It returns all the found records. Obviously, the returned DNS reply is a fake reply different from the queries sent on the wire.

type DialContextFunc

type DialContextFunc func(context.Context, string, string) (net.Conn, error)

DialContextFunc is the type of net.Dialer.DialContext.

type DialerLogger deprecated

type DialerLogger = dialerLogger

These types export internal names to legacy ooni/probe-cli code.

Deprecated: do not use these names in new code.

type DialerResolver deprecated

type DialerResolver = dialerResolver

These types export internal names to legacy ooni/probe-cli code.

Deprecated: do not use these names in new code.

type DialerSystem deprecated

type DialerSystem = dialerSystem

These types export internal names to legacy ooni/probe-cli code.

Deprecated: do not use these names in new code.

type ErrWrapper

type ErrWrapper struct {
	// Failure is the OONI failure string. The failure strings are
	// loosely backward compatible with Measurement Kit.
	//
	// This is either one of the FailureXXX strings or any other
	// string like `unknown_failure: ...`. The latter represents an
	// error that we have not yet mapped to a failure.
	Failure string

	// Operation is the operation that failed.
	//
	// If possible, the Operation string SHOULD be a _major_
	// operation. Major operations are:
	//
	// - ResolveOperation: resolving a domain name failed
	// - ConnectOperation: connecting to an IP failed
	// - TLSHandshakeOperation: TLS handshaking failed
	// - QUICHandshakeOperation: QUIC handshaking failed
	// - HTTPRoundTripOperation: other errors during round trip
	//
	// Because a network connection doesn't necessarily know
	// what is the current major operation we also have the
	// following _minor_ operations:
	//
	// - CloseOperation: CLOSE failed
	// - ReadOperation: READ failed
	// - WriteOperation: WRITE failed
	//
	// If an ErrWrapper referring to a major operation is wrapping
	// another ErrWrapper and such ErrWrapper already refers to
	// a major operation, then the new ErrWrapper should use the
	// child ErrWrapper major operation. Otherwise, it should use
	// its own major operation. This way, the topmost wrapper is
	// supposed to refer to the major operation that failed.
	Operation string

	// WrappedErr is the error that we're wrapping.
	WrappedErr error
}

ErrWrapper is our error wrapper for Go errors. The key objective of this structure is to properly set Failure, which is also returned by the Error() method, to be one of the OONI failure strings.

OONI failure strings are defined in the github.com/ooni/spec repo at https://github.com/ooni/spec/blob/master/data-formats/df-007-errors.md.

func NewErrWrapper

func NewErrWrapper(c Classifier, op string, err error) *ErrWrapper

NewErrWrapper creates a new ErrWrapper using the given classifier, operation name, and underlying error.

This function panics if classifier is nil, or operation is the empty string or error is nil.

If the err argument has already been classified, the returned error wrapper will use the same classification string and will determine whether to keep the major operation as documented in the ErrWrapper.Operation documentation.

func NewTopLevelGenericErrWrapper

func NewTopLevelGenericErrWrapper(err error) *ErrWrapper

NewTopLevelGenericErrWrapper wraps an error occurring at top level using ClassifyGenericError as classifier.

If the err argument has already been classified, the returned error wrapper will use the same classification string and failed operation of the original error.

func (*ErrWrapper) Error

func (e *ErrWrapper) Error() string

Error returns the OONI failure string for this error.

func (*ErrWrapper) MarshalJSON

func (e *ErrWrapper) MarshalJSON() ([]byte, error)

MarshalJSON converts an ErrWrapper to a JSON value.

func (*ErrWrapper) Unwrap

func (e *ErrWrapper) Unwrap() error

Unwrap allows to access the underlying error.

type ErrorWrapperDialer deprecated

type ErrorWrapperDialer = dialerErrWrapper

These types export internal names to legacy ooni/probe-cli code.

Deprecated: do not use these names in new code.

type ErrorWrapperQUICDialer deprecated

type ErrorWrapperQUICDialer = quicDialerErrWrapper

These types export internal names to legacy ooni/probe-cli code.

Deprecated: do not use these names in new code.

type ErrorWrapperQUICListener deprecated

type ErrorWrapperQUICListener = quicListenerErrWrapper

These types export internal names to legacy ooni/probe-cli code.

Deprecated: do not use these names in new code.

type ErrorWrapperResolver deprecated

type ErrorWrapperResolver = resolverErrWrapper

These types export internal names to legacy ooni/probe-cli code.

Deprecated: do not use these names in new code.

type ErrorWrapperTLSHandshaker deprecated

type ErrorWrapperTLSHandshaker = tlsHandshakerErrWrapper

These types export internal names to legacy ooni/probe-cli code.

Deprecated: do not use these names in new code.

type HTTPTransportLogger deprecated

type HTTPTransportLogger = httpTransportLogger

These types export internal names to legacy ooni/probe-cli code.

Deprecated: do not use these names in new code.

type ParallelResolver

type ParallelResolver struct {
	// Encoder is the MANDATORY encoder to use.
	Encoder model.DNSEncoder

	// Decoder is the MANDATORY decoder to use.
	Decoder model.DNSDecoder

	// NumTimeouts is MANDATORY and counts the number of timeouts.
	NumTimeouts *atomicx.Int64

	// Txp is the underlying DNS transport.
	Txp model.DNSTransport
}

ParallelResolver uses a transport and sends performs a LookupHost operation in a parallel fashion, hence its name.

You should probably use NewUnwrappedParallel to create a new instance.

func NewUnwrappedParallelResolver

func NewUnwrappedParallelResolver(t model.DNSTransport) *ParallelResolver

UnwrappedParallelResolver creates a new ParallelResolver instance.

func (*ParallelResolver) Address

func (r *ParallelResolver) Address() string

Address returns the "address" of the underlying transport.

func (*ParallelResolver) CloseIdleConnections

func (r *ParallelResolver) CloseIdleConnections()

CloseIdleConnections closes idle connections, if any.

func (*ParallelResolver) LookupHTTPS

func (r *ParallelResolver) LookupHTTPS(
	ctx context.Context, hostname string) (*model.HTTPSSvc, error)

LookupHTTPS implements Resolver.LookupHTTPS.

func (*ParallelResolver) LookupHost

func (r *ParallelResolver) LookupHost(ctx context.Context, hostname string) ([]string, error)

LookupHost performs an A lookup followed by an AAAA lookup for hostname.

func (*ParallelResolver) LookupNS

func (r *ParallelResolver) LookupNS(
	ctx context.Context, hostname string) ([]*net.NS, error)

LookupNS implements Resolver.LookupNS.

func (*ParallelResolver) LookupPTR

func (r *ParallelResolver) LookupPTR(
	ctx context.Context, hostname string) ([]string, error)

LookupPTR implements Resolver.LookupPTR.

func (*ParallelResolver) Network

func (r *ParallelResolver) Network() string

Network returns the "network" of the underlying transport.

func (*ParallelResolver) Transport

func (r *ParallelResolver) Transport() model.DNSTransport

Transport returns the transport being used.

type QUICDialerLogger deprecated

type QUICDialerLogger = quicDialerLogger

These types export internal names to legacy ooni/probe-cli code.

Deprecated: do not use these names in new code.

type QUICDialerQUICGo deprecated

type QUICDialerQUICGo = quicDialerQUICGo

These types export internal names to legacy ooni/probe-cli code.

Deprecated: do not use these names in new code.

type QUICDialerResolver deprecated

type QUICDialerResolver = quicDialerResolver

These types export internal names to legacy ooni/probe-cli code.

Deprecated: do not use these names in new code.

type QUICListenerStdlib deprecated

type QUICListenerStdlib = quicListenerStdlib

These types export internal names to legacy ooni/probe-cli code.

Deprecated: do not use these names in new code.

type ResolverIDNA deprecated

type ResolverIDNA = resolverIDNA

These types export internal names to legacy ooni/probe-cli code.

Deprecated: do not use these names in new code.

type ResolverLogger deprecated

type ResolverLogger = resolverLogger

These types export internal names to legacy ooni/probe-cli code.

Deprecated: do not use these names in new code.

type ResolverSystem deprecated

type ResolverSystem = resolverSystem

These types export internal names to legacy ooni/probe-cli code.

Deprecated: do not use these names in new code.

type SerialResolver

type SerialResolver struct {
	// Encoder is the MANDATORY encoder to use.
	Encoder model.DNSEncoder

	// Decoder is the MANDATORY decoder to use.
	Decoder model.DNSDecoder

	// NumTimeouts is MANDATORY and counts the number of timeouts.
	NumTimeouts *atomicx.Int64

	// Txp is the underlying DNS transport.
	Txp model.DNSTransport
}

SerialResolver uses a transport and sends performs a LookupHost operation in a serial fashion (query for A first, wait for response, then query for AAAA, and wait for response), hence its name.

You should probably use NewSerialResolver to create a new instance.

func NewSerialResolver

func NewSerialResolver(t model.DNSTransport) *SerialResolver

NewSerialResolver creates a new SerialResolver instance.

func (*SerialResolver) Address

func (r *SerialResolver) Address() string

Address returns the "address" of the underlying transport.

func (*SerialResolver) CloseIdleConnections

func (r *SerialResolver) CloseIdleConnections()

CloseIdleConnections closes idle connections, if any.

func (*SerialResolver) LookupHTTPS

func (r *SerialResolver) LookupHTTPS(
	ctx context.Context, hostname string) (*model.HTTPSSvc, error)

LookupHTTPS implements Resolver.LookupHTTPS.

func (*SerialResolver) LookupHost

func (r *SerialResolver) LookupHost(ctx context.Context, hostname string) ([]string, error)

LookupHost performs an A lookup followed by an AAAA lookup for hostname.

func (*SerialResolver) LookupNS

func (r *SerialResolver) LookupNS(
	ctx context.Context, hostname string) ([]*net.NS, error)

LookupNS implements Resolver.LookupNS.

func (*SerialResolver) LookupPTR

func (r *SerialResolver) LookupPTR(
	ctx context.Context, hostname string) ([]string, error)

LookupPTR implements Resolver.LookupPTR.

func (*SerialResolver) Network

func (r *SerialResolver) Network() string

Network returns the "network" of the underlying transport.

func (*SerialResolver) Transport

func (r *SerialResolver) Transport() model.DNSTransport

Transport returns the transport being used.

type TLSConn

type TLSConn = oohttp.TLSConn

TLSConn is the type of connection that oohttp expects from any library that implements TLS functionality. By using this kind of TLSConn we're able to use both the standard library and gitlab.com/yawning/utls.git to perform TLS operations. Note that the stdlib's tls.Conn implements this interface.

type TLSDialerLegacy deprecated

type TLSDialerLegacy = tlsDialer

These types export internal names to legacy ooni/probe-cli code.

Deprecated: do not use these names in new code.

type TLSHandshakerConfigurable deprecated

type TLSHandshakerConfigurable = tlsHandshakerConfigurable

These types export internal names to legacy ooni/probe-cli code.

Deprecated: do not use these names in new code.

type TLSHandshakerLogger deprecated

type TLSHandshakerLogger = tlsHandshakerLogger

These types export internal names to legacy ooni/probe-cli code.

Deprecated: do not use these names in new code.

type TProxyStdlib

type TProxyStdlib struct{}

TProxyStdlib is the default model.UnderlyingNetworkLibrary using the stdlib in the most obvious way for every functionality.

func (*TProxyStdlib) ListenUDP

func (*TProxyStdlib) ListenUDP(network string, laddr *net.UDPAddr) (model.UDPLikeConn, error)

ListenUDP calls net.ListenUDP.

func (*TProxyStdlib) LookupHost

func (*TProxyStdlib) LookupHost(ctx context.Context, domain string) ([]string, error)

LookupHost calls net.DefaultResolver.LookupHost.

func (*TProxyStdlib) NewSimpleDialer

func (*TProxyStdlib) NewSimpleDialer(timeout time.Duration) model.SimpleDialer

NewSimpleDialer returns a &net.Dialer{Timeout: timeout} instance.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL