dslx

package
v0.30.0 Latest Latest
Warning

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

Go to latest
Published: Nov 26, 2024 License: GPL-3.0 Imports: 18 Imported by: 0

Documentation

Overview

Package dslx implements a domain specific language for writing network experiments.

See https://github.com/ooni/probe-cli/blob/master/docs/design/dd-005-dslx.md for the design document explaining why we introduced this package.

Index

Constants

This section is empty.

Variables

View Source
var ErrDNSLookupParallel = errors.New("dslx: DNSLookupParallel failed")

ErrDNSLookupParallel indicates that DNSLookupParallel failed.

View Source
var ErrSkip = errors.New("dslx: error already processed by a previous stage")

ErrSkip is an error that indicates that we already processed an error emitted by a previous stage, so we are using this error to avoid counting the original error more than once when computing statistics, e.g., in *Stats.

Functions

func ApplyAsync deprecated

func ApplyAsync[A, B any](
	ctx context.Context,
	fx Func[A, B],
	input A,
) <-chan *Maybe[B]

ApplyAsync is equivalent to calling Apply but returns a channel.

Deprecated: use Matrix instead.

func Collect

func Collect[T any](c <-chan T) (v []T)

Collect collects all the elements inside a channel under the assumption that the channel will be closed to signal EOF.

func Map deprecated

func Map[A, B any](
	ctx context.Context,
	parallelism Parallelism,
	fx Func[A, B],
	inputs <-chan A,
) <-chan *Maybe[B]

Map applies fx to the list of elements produced by a generator channel.

Arguments:

- ctx is the context;

- parallelism is the number of goroutines to use (we'll use a single goroutine if parallelism is < 1);

- fx is the function to apply;

- inputs receives arguments on which to apply fx. We expect this channel to be closed to signal EOF to the background workers.

The return value is the channel generating fx(a) for every a in inputs. This channel will also be closed to signal EOF to the consumer.

Deprecated: use Matrix instead.

func Matrix

func Matrix[A, B any](ctx context.Context, N Parallelism, inputs []A, functions []Func[A, B]) <-chan *Maybe[B]

Matrix invokes each function on each input using N goroutines and streams the results to a channel.

func ParallelAsync deprecated

func ParallelAsync[A, B any](
	ctx context.Context,
	parallelism Parallelism,
	input A,
	funcs <-chan Func[A, B],
) <-chan *Maybe[B]

ParallelAsync is like Parallel but deals with channels. We assume the input channel will be closed to signal EOF. We will close the output channel to signal EOF to the consumer.

Deprecated: use Matrix instead.

func StreamList

func StreamList[T any](ts ...T) <-chan T

StreamList creates a channel out of static values. This function will close the channel when it has streamed all the available elements.

func Zip

func Zip[T any](sources ...<-chan T) <-chan T

Zip zips together results from many channels under the assumption that each channel will be closed when it has streamed all elements.

func ZipAndCollect

func ZipAndCollect[T any](sources ...<-chan T) []T

ZipAndCollect is syntactic sugar for Collect(Zip(sources...)).

Types

type AddressSet

type AddressSet struct {
	// M is the map we use to represent the set.
	M map[string]bool
}

AddressSet is a set of IP addresses. The zero value struct is invalid, please initialize M or use NewAddressSet.

func NewAddressSet

func NewAddressSet(dns ...*Maybe[*ResolvedAddresses]) *AddressSet

NewAddressSet creates a new address set from optional addresses resolved by DNS.

func (*AddressSet) Add

func (as *AddressSet) Add(addrs ...string) *AddressSet

Add MUTATES the set to add a (possibly-new) address to the set and returns the same set to the caller allowing for chaining calls.

func (*AddressSet) RemoveBogons

func (as *AddressSet) RemoveBogons() *AddressSet

RemoveBogons MUTATES the set to remove bogons from the set and returns the same set to the caller allowing for chaining calls.

func (*AddressSet) ToEndpoints deprecated

func (as *AddressSet) ToEndpoints(
	network EndpointNetwork, port EndpointPort, options ...EndpointOption) (v []*Endpoint)

ToEndpoints transforms this set of IP addresses to a list of endpoints. We will combine each IP address with the network and the port to construct an endpoint and we will also apply any additional option to each endpoint.

Deprecated: use MakeEndpoint instead.

func (*AddressSet) Uniq

func (as *AddressSet) Uniq() (uniq []string)

Uniq returns the unique addresses.

type DNSLookupOption

type DNSLookupOption func(*DomainToResolve)

DNSLookupOption is an option you can pass to NewDomainToResolve.

func DNSLookupOptionTags

func DNSLookupOptionTags(value ...string) DNSLookupOption

DNSLookupOptionTags allows to set tags to tag observations.

type DomainName

type DomainName string

DomainName is a domain name to resolve.

type DomainToResolve

type DomainToResolve struct {
	// Domain is the MANDATORY domain name to lookup.
	Domain string

	// Tags contains OPTIONAL tags to tag observations.
	Tags []string
}

DomainToResolve is the input for DNS lookup functions.

You should construct this type using the NewDomainToResolve constructor as well as DNSLookupOption options to fill optional values. If you want to construct this type manually, please make sure you initialize all the variables marked as MANDATORY.

func NewDomainToResolve

func NewDomainToResolve(domain DomainName, options ...DNSLookupOption) *DomainToResolve

NewDomainToResolve creates input for performing DNS lookups. The only mandatory argument is the domain name to resolve. You can also supply optional values by passing options to this function.

type Endpoint

type Endpoint struct {
	// Address is the MANDATORY endpoint address.
	Address string

	// Domain is the OPTIONAL domain used to resolve the endpoints' IP address.
	Domain string

	// Network is the MANDATORY endpoint network.
	Network string

	// Tags contains OPTIONAL tags for tagging observations.
	Tags []string
}

Endpoint is a network endpoint along with configuration for measuring it. You should construct from an AddressSet or using NewEndpoint. Otherwise, make sure you initialize all the fields marked as MANDATORY.

func NewEndpoint

func NewEndpoint(
	network EndpointNetwork, address EndpointAddress, options ...EndpointOption) *Endpoint

NewEndpoint creates a new network endpoint (i.e., a three tuple composed of a network protocol, an IP address, and a port).

Arguments:

- network is either "tcp" or "udp";

- address is the NewEndpoint address represented as an IP address followed by ":" followed by a port. IPv6 addresses must be quoted (e.g., "[::1]:80");

- options contains additional options.

type EndpointAddress

type EndpointAddress string

EndpointAddress is the endpoint address.

type EndpointNetwork

type EndpointNetwork string

EndpointNetwork is the network of the endpoint

type EndpointOption

type EndpointOption func(*Endpoint)

EndpointOption is an option you can use to construct EndpointState.

func EndpointOptionDomain

func EndpointOptionDomain(value string) EndpointOption

EndpointOptionDomain allows to set the domain.

func EndpointOptionTags

func EndpointOptionTags(value ...string) EndpointOption

EndpointOptionTags allows to set tags to tag observations.

type EndpointPort

type EndpointPort uint16

EndpointPort is the port for an endpoint.

type Func

type Func[A, B any] interface {
	Apply(ctx context.Context, a *Maybe[A]) *Maybe[B]
}

Func is a function f: (context.Context, A) -> B.

func Compose10

func Compose10[
	T0 any,
	T1 any,
	T2 any,
	T3 any,
	T4 any,
	T5 any,
	T6 any,
	T7 any,
	T8 any,
	T9 any,
	T10 any,
](
	f0 Func[T0, T1],
	f1 Func[T1, T2],
	f2 Func[T2, T3],
	f3 Func[T3, T4],
	f4 Func[T4, T5],
	f5 Func[T5, T6],
	f6 Func[T6, T7],
	f7 Func[T7, T8],
	f8 Func[T8, T9],
	f9 Func[T9, T10],
) Func[T0, T10]

Compose10 composes N=10 functions.

func Compose11

func Compose11[
	T0 any,
	T1 any,
	T2 any,
	T3 any,
	T4 any,
	T5 any,
	T6 any,
	T7 any,
	T8 any,
	T9 any,
	T10 any,
	T11 any,
](
	f0 Func[T0, T1],
	f1 Func[T1, T2],
	f2 Func[T2, T3],
	f3 Func[T3, T4],
	f4 Func[T4, T5],
	f5 Func[T5, T6],
	f6 Func[T6, T7],
	f7 Func[T7, T8],
	f8 Func[T8, T9],
	f9 Func[T9, T10],
	f10 Func[T10, T11],
) Func[T0, T11]

Compose11 composes N=11 functions.

func Compose12

func Compose12[
	T0 any,
	T1 any,
	T2 any,
	T3 any,
	T4 any,
	T5 any,
	T6 any,
	T7 any,
	T8 any,
	T9 any,
	T10 any,
	T11 any,
	T12 any,
](
	f0 Func[T0, T1],
	f1 Func[T1, T2],
	f2 Func[T2, T3],
	f3 Func[T3, T4],
	f4 Func[T4, T5],
	f5 Func[T5, T6],
	f6 Func[T6, T7],
	f7 Func[T7, T8],
	f8 Func[T8, T9],
	f9 Func[T9, T10],
	f10 Func[T10, T11],
	f11 Func[T11, T12],
) Func[T0, T12]

Compose12 composes N=12 functions.

func Compose13

func Compose13[
	T0 any,
	T1 any,
	T2 any,
	T3 any,
	T4 any,
	T5 any,
	T6 any,
	T7 any,
	T8 any,
	T9 any,
	T10 any,
	T11 any,
	T12 any,
	T13 any,
](
	f0 Func[T0, T1],
	f1 Func[T1, T2],
	f2 Func[T2, T3],
	f3 Func[T3, T4],
	f4 Func[T4, T5],
	f5 Func[T5, T6],
	f6 Func[T6, T7],
	f7 Func[T7, T8],
	f8 Func[T8, T9],
	f9 Func[T9, T10],
	f10 Func[T10, T11],
	f11 Func[T11, T12],
	f12 Func[T12, T13],
) Func[T0, T13]

Compose13 composes N=13 functions.

func Compose14

func Compose14[
	T0 any,
	T1 any,
	T2 any,
	T3 any,
	T4 any,
	T5 any,
	T6 any,
	T7 any,
	T8 any,
	T9 any,
	T10 any,
	T11 any,
	T12 any,
	T13 any,
	T14 any,
](
	f0 Func[T0, T1],
	f1 Func[T1, T2],
	f2 Func[T2, T3],
	f3 Func[T3, T4],
	f4 Func[T4, T5],
	f5 Func[T5, T6],
	f6 Func[T6, T7],
	f7 Func[T7, T8],
	f8 Func[T8, T9],
	f9 Func[T9, T10],
	f10 Func[T10, T11],
	f11 Func[T11, T12],
	f12 Func[T12, T13],
	f13 Func[T13, T14],
) Func[T0, T14]

Compose14 composes N=14 functions.

func Compose2

func Compose2[A, B, C any](f Func[A, B], g Func[B, C]) Func[A, C]

Compose2 composes two operations such as TCPConnect and TLSHandshake.

func Compose3

func Compose3[
	T0 any,
	T1 any,
	T2 any,
	T3 any,
](
	f0 Func[T0, T1],
	f1 Func[T1, T2],
	f2 Func[T2, T3],
) Func[T0, T3]

Compose3 composes N=3 functions.

func Compose4

func Compose4[
	T0 any,
	T1 any,
	T2 any,
	T3 any,
	T4 any,
](
	f0 Func[T0, T1],
	f1 Func[T1, T2],
	f2 Func[T2, T3],
	f3 Func[T3, T4],
) Func[T0, T4]

Compose4 composes N=4 functions.

func Compose5

func Compose5[
	T0 any,
	T1 any,
	T2 any,
	T3 any,
	T4 any,
	T5 any,
](
	f0 Func[T0, T1],
	f1 Func[T1, T2],
	f2 Func[T2, T3],
	f3 Func[T3, T4],
	f4 Func[T4, T5],
) Func[T0, T5]

Compose5 composes N=5 functions.

func Compose6

func Compose6[
	T0 any,
	T1 any,
	T2 any,
	T3 any,
	T4 any,
	T5 any,
	T6 any,
](
	f0 Func[T0, T1],
	f1 Func[T1, T2],
	f2 Func[T2, T3],
	f3 Func[T3, T4],
	f4 Func[T4, T5],
	f5 Func[T5, T6],
) Func[T0, T6]

Compose6 composes N=6 functions.

func Compose7

func Compose7[
	T0 any,
	T1 any,
	T2 any,
	T3 any,
	T4 any,
	T5 any,
	T6 any,
	T7 any,
](
	f0 Func[T0, T1],
	f1 Func[T1, T2],
	f2 Func[T2, T3],
	f3 Func[T3, T4],
	f4 Func[T4, T5],
	f5 Func[T5, T6],
	f6 Func[T6, T7],
) Func[T0, T7]

Compose7 composes N=7 functions.

func Compose8

func Compose8[
	T0 any,
	T1 any,
	T2 any,
	T3 any,
	T4 any,
	T5 any,
	T6 any,
	T7 any,
	T8 any,
](
	f0 Func[T0, T1],
	f1 Func[T1, T2],
	f2 Func[T2, T3],
	f3 Func[T3, T4],
	f4 Func[T4, T5],
	f5 Func[T5, T6],
	f6 Func[T6, T7],
	f7 Func[T7, T8],
) Func[T0, T8]

Compose8 composes N=8 functions.

func Compose9

func Compose9[
	T0 any,
	T1 any,
	T2 any,
	T3 any,
	T4 any,
	T5 any,
	T6 any,
	T7 any,
	T8 any,
	T9 any,
](
	f0 Func[T0, T1],
	f1 Func[T1, T2],
	f2 Func[T2, T3],
	f3 Func[T3, T4],
	f4 Func[T4, T5],
	f5 Func[T5, T6],
	f6 Func[T6, T7],
	f7 Func[T7, T8],
	f8 Func[T8, T9],
) Func[T0, T9]

Compose9 composes N=9 functions.

func DNSLookupGetaddrinfo

func DNSLookupGetaddrinfo(rt Runtime) Func[*DomainToResolve, *ResolvedAddresses]

DNSLookupGetaddrinfo returns a function that resolves a domain name to IP addresses using libc's getaddrinfo function.

func DNSLookupParallel

DNSLookupParallel runs DNS lookups in parallel. On success, this function returns a unique list of IP addresses aggregated from all resolvers. On failure, this function returns ErrDNSLookupParallel. You can always obtain the individual errors by processing observations or by creating a per-DNS-resolver pipeline.

func DNSLookupUDP

func DNSLookupUDP(rt Runtime, endpoint string) Func[*DomainToResolve, *ResolvedAddresses]

DNSLookupUDP returns a function that resolves a domain name to IP addresses using the given DNS-over-UDP resolver.

func Discard

func Discard[T any]() Func[T, Void]

Discard transforms any type to Void.

func HTTPConnectionQUIC

func HTTPConnectionQUIC(rt Runtime) Func[*QUICConnection, *HTTPConnection]

HTTPConnectionQUIC converts a QUIC connection into an HTTP connection.

func HTTPConnectionTCP

func HTTPConnectionTCP(rt Runtime) Func[*TCPConnection, *HTTPConnection]

HTTPConnectionTCP converts a TCP connection into an HTTP connection.

func HTTPConnectionTLS

func HTTPConnectionTLS(rt Runtime) Func[*TLSConnection, *HTTPConnection]

HTTPConnectionTLS converts a TLS connection into an HTTP connection.

func HTTPRequest

func HTTPRequest(rt Runtime, options ...HTTPRequestOption) Func[*HTTPConnection, *HTTPResponse]

HTTPRequest issues an HTTP request using a transport and returns a response.

func HTTPRequestOverQUIC

func HTTPRequestOverQUIC(rt Runtime, options ...HTTPRequestOption) Func[*QUICConnection, *HTTPResponse]

HTTPRequestOverQUIC returns a Func that issues HTTP requests over QUIC.

func HTTPRequestOverTCP

func HTTPRequestOverTCP(rt Runtime, options ...HTTPRequestOption) Func[*TCPConnection, *HTTPResponse]

HTTPRequestOverTCP returns a Func that issues HTTP requests over TCP.

func HTTPRequestOverTLS

func HTTPRequestOverTLS(rt Runtime, options ...HTTPRequestOption) Func[*TLSConnection, *HTTPResponse]

HTTPRequestOverTLS returns a Func that issues HTTP requests over TLS.

func MakeEndpoint

func MakeEndpoint(network EndpointNetwork, port EndpointPort, options ...EndpointOption) Func[*ResolvedAddress, *Endpoint]

MakeEndpoint returns a Func that creates an *Endpoint given *ResolvedAddress.

func MeasureResolvedAddresses

func MeasureResolvedAddresses(fxs ...Func[*ResolvedAddress, Void]) Func[*ResolvedAddresses, Void]

MeasureResolvedAddresses returns a Func that measures the resolved addresses provided as the input argument using each of the provided functions.

func QUICHandshake

func QUICHandshake(rt Runtime, options ...TLSHandshakeOption) Func[*Endpoint, *QUICConnection]

QUICHandshake returns a function performing QUIC handshakes.

func TCPConnect

func TCPConnect(rt Runtime) Func[*Endpoint, *TCPConnection]

TCPConnect returns a function that establishes TCP connections.

func TLSHandshake

func TLSHandshake(rt Runtime, options ...TLSHandshakeOption) Func[*TCPConnection, *TLSConnection]

TLSHandshake returns a function performing TSL handshakes.

type FuncAdapter

type FuncAdapter[A, B any] func(ctx context.Context, a *Maybe[A]) *Maybe[B]

FuncAdapter adapts a func to be a Func.

func (FuncAdapter[A, B]) Apply

func (fa FuncAdapter[A, B]) Apply(ctx context.Context, a *Maybe[A]) *Maybe[B]

Apply implements Func.

type HTTPConnection

type HTTPConnection struct {
	// Address is the MANDATORY address we're connected to.
	Address string

	// Domain is the OPTIONAL domain from which the address was resolved.
	Domain string

	// Network is the MANDATORY network used by the underlying conn.
	Network string

	// Scheme is the MANDATORY URL scheme to use.
	Scheme string

	// TLSNegotiatedProtocol is the OPTIONAL negotiated protocol.
	TLSNegotiatedProtocol string

	// Trace is the MANDATORY trace we're using.
	Trace Trace

	// Transport is the MANDATORY HTTP transport we're using.
	Transport model.HTTPTransport
}

HTTPConnection is an HTTP connection bound to a TCP, TLS or QUIC connection that would use such a connection only and for any input URL. You generally use [HTTPTransportTCP], [HTTPTransportTLS] or [HTTPTransportQUIC] to create a new instance; if you want to initialize manually, make sure you init the fields marked as MANDATORY.

type HTTPRequestOption

type HTTPRequestOption func(req *http.Request)

HTTPRequestOption is an option you can pass to HTTPRequest.

func HTTPRequestOptionAccept

func HTTPRequestOptionAccept(value string) HTTPRequestOption

HTTPRequestOptionAccept sets the Accept header.

func HTTPRequestOptionAcceptLanguage

func HTTPRequestOptionAcceptLanguage(value string) HTTPRequestOption

HTTPRequestOptionAcceptLanguage sets the Accept header.

func HTTPRequestOptionHost

func HTTPRequestOptionHost(value string) HTTPRequestOption

HTTPRequestOptionHost sets the Host header.

func HTTPRequestOptionMethod

func HTTPRequestOptionMethod(value string) HTTPRequestOption

HTTPRequestOptionHost sets the request method.

func HTTPRequestOptionReferer

func HTTPRequestOptionReferer(value string) HTTPRequestOption

HTTPRequestOptionReferer sets the Referer header.

func HTTPRequestOptionURLPath

func HTTPRequestOptionURLPath(value string) HTTPRequestOption

HTTPRequestOptionURLPath sets the URL path.

func HTTPRequestOptionUserAgent

func HTTPRequestOptionUserAgent(value string) HTTPRequestOption

HTTPRequestOptionUserAgent sets the UserAgent header.

type HTTPResponse

type HTTPResponse struct {
	// Address is the MANDATORY address we're connected to.
	Address string

	// Domain is the OPTIONAL domain from which we determined Address.
	Domain string

	// HTTPRequest is the possibly-nil HTTP request.
	HTTPRequest *http.Request

	// HTTPResponse is the HTTP response or nil if Err != nil.
	HTTPResponse *http.Response

	// HTTPResponseBodySnapshot is the response body or nil if Err != nil.
	HTTPResponseBodySnapshot []byte

	// Network is the MANDATORY network we're connected to.
	Network string

	// Trace is the MANDATORY trace we're using. The trace is drained
	// when you call the Observations method.
	Trace Trace
}

HTTPResponse is the response generated by an HTTP requests. Generally obtained by HTTPRequest().Apply. To init manually, init at least MANDATORY fields.

type Maybe

type Maybe[State any] struct {
	// Error is either the error that occurred or nil.
	Error error

	// State contains state passed between function calls. You should
	// only access State when Error is nil and Skipped is false.
	State State
}

Maybe is the result of an operation implemented by this package that may fail such as TCPConnect or TLSHandshake.

func NewMaybeWithError

func NewMaybeWithError[State any](err error) *Maybe[State]

NewMaybeWithError constructs a Maybe containing the given error.

func NewMaybeWithValue

func NewMaybeWithValue[State any](value State) *Maybe[State]

NewMaybeWithValue constructs a Maybe containing the given value.

func Parallel deprecated

func Parallel[A, B any](
	ctx context.Context,
	parallelism Parallelism,
	input A,
	fn ...Func[A, B],
) []*Maybe[B]

Parallel executes f1...fn in parallel over the same input.

Arguments:

- ctx is the context;

- parallelism is the number of goroutines to use (we'll use a single goroutine if parallelism is < 1);

- input is the input;

- fn is the list of functions.

The return value is the list [fx(a)] for every fx in fn.

Deprecated: use Matrix instead.

type MinimalRuntime

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

MinimalRuntime is a minimal Runtime implementation.

func NewMinimalRuntime

func NewMinimalRuntime(logger model.Logger, zeroTime time.Time, options ...MinimalRuntimeOption) *MinimalRuntime

NewMinimalRuntime creates a minimal Runtime implementation.

This Runtime implementation does not collect any *Observations.

func (*MinimalRuntime) Close

func (p *MinimalRuntime) Close() error

Close implements Runtime.

func (*MinimalRuntime) IDGenerator

func (p *MinimalRuntime) IDGenerator() *atomic.Int64

IDGenerator implements Runtime.

func (*MinimalRuntime) Logger

func (p *MinimalRuntime) Logger() model.Logger

Logger implements Runtime.

func (*MinimalRuntime) MaybeTrackConn

func (p *MinimalRuntime) MaybeTrackConn(conn io.Closer)

MaybeTrackConn implements Runtime.

func (*MinimalRuntime) NewTrace

func (p *MinimalRuntime) NewTrace(index int64, zeroTime time.Time, tags ...string) Trace

NewTrace implements Runtime.

func (*MinimalRuntime) Observations

func (p *MinimalRuntime) Observations() *Observations

Observations implements Runtime.

func (*MinimalRuntime) SaveObservations

func (p *MinimalRuntime) SaveObservations(obs ...*Observations)

SaveObservations implements Runtime.

func (*MinimalRuntime) ZeroTime

func (p *MinimalRuntime) ZeroTime() time.Time

ZeroTime implements Runtime.

type MinimalRuntimeOption

type MinimalRuntimeOption func(rt *MinimalRuntime)

MinimalRuntimeOption is an option for configuring the *MinimalRuntime.

func MinimalRuntimeOptionMeasuringNetwork

func MinimalRuntimeOptionMeasuringNetwork(netx model.MeasuringNetwork) MinimalRuntimeOption

MinimalRuntimeOptionMeasuringNetwork configures the model.MeasuringNetwork to use.

type Observations

type Observations struct {
	// NetworkEvents contains I/O events.
	NetworkEvents []*model.ArchivalNetworkEvent `json:"network_events"`

	// Queries contains the DNS queries results.
	Queries []*model.ArchivalDNSLookupResult `json:"queries"`

	// Requests contains HTTP request results.
	Requests []*model.ArchivalHTTPRequestResult `json:"requests"`

	// TCPConnect contains the TCP connect results.
	TCPConnect []*model.ArchivalTCPConnectResult `json:"tcp_connect"`

	// TLSHandshakes contains the TLS handshakes results.
	TLSHandshakes []*model.ArchivalTLSOrQUICHandshakeResult `json:"tls_handshakes"`

	// QUICHandshakes contains the QUIC handshakes results.
	QUICHandshakes []*model.ArchivalTLSOrQUICHandshakeResult `json:"quic_handshakes"`
}

Observations is the skeleton shared by most OONI measurements where we group observations by type using standard test keys.

func NewObservations

func NewObservations() *Observations

NewObservations initializes all measurements to empty arrays and returns the Observations skeleton.

type Operation

type Operation[A, B any] func(ctx context.Context, a A) (B, error)

Operation adapts a golang function to behave like a Func.

func (Operation[A, B]) Apply

func (op Operation[A, B]) Apply(ctx context.Context, a *Maybe[A]) *Maybe[B]

Apply implements Func.

type Parallelism

type Parallelism int

Parallelism is the type used to specify parallelism.

type QUICConnection

type QUICConnection struct {
	// Address is the MANDATORY address we tried to connect to.
	Address string

	// QUICConn is the established QUIC conn.
	QUICConn quic.EarlyConnection

	// Domain is the OPTIONAL domain we resolved.
	Domain string

	// Network is the MANDATORY network we tried to use when connecting.
	Network string

	// TLSConfig is the config we used to establish a QUIC connection and will
	// be needed when constructing an HTTP/3 transport.
	TLSConfig *tls.Config

	// TLSState is the possibly-empty TLS connection state.
	TLSState tls.ConnectionState

	// Trace is the MANDATORY trace we're using.
	Trace Trace
}

QUICConnection is an established QUIC connection. If you initialize manually, init at least the ones marked as MANDATORY.

type ResolvedAddress

type ResolvedAddress struct {
	// Address is the address that was resolved.
	Address string

	// Domain is the domain from which we resolved the address.
	Domain string
}

ResolvedAddress is a single address resolved using a DNS lookup function.

type ResolvedAddresses

type ResolvedAddresses struct {
	// Addresses contains the nonempty resolved addresses.
	Addresses []string

	// Domain is the domain we resolved. We inherit this field
	// from the value inside the DomainToResolve.
	Domain string
}

ResolvedAddresses contains the results of DNS lookups. To initialize this struct manually, follow specific instructions for each field.

func (*ResolvedAddresses) Flatten

func (ra *ResolvedAddresses) Flatten() (out []*ResolvedAddress)

Flatten transforms a ResolvedAddresses into a slice of zero or more ResolvedAddress.

type Runtime

type Runtime interface {
	// Close closes all the connection tracked using MaybeTrackConn.
	Close() error

	// IDGenerator returns an atomic counter used to generate
	// separate unique IDs for each trace.
	IDGenerator() *atomic.Int64

	// Logger returns the base logger to use.
	Logger() model.Logger

	// MaybeTrackConn tracks a connection such that it is closed
	// when you call the Runtime's Close method.
	MaybeTrackConn(conn io.Closer)

	// NewTrace creates a [Trace] instance. Note that each [Runtime]
	// creates its own [Trace] type. A [Trace] is not guaranteed to collect
	// [*Observations]. For example, [NewMinimalRuntime] creates a [Runtime]
	// that does not collect any [*Observations].
	NewTrace(index int64, zeroTime time.Time, tags ...string) Trace

	// Observations returns the [*Observations] saved so far and clears our
	// internal copy such that the next call to this method only returns
	// the [*Observations] saved since the previous call.
	//
	// You can safely call this method from multiple goroutine contexts.
	Observations() *Observations

	// SaveObservations saves [*Observations] inside the [Runtime]. You can
	// get the saved [*Observations] by calling Observations.
	//
	// You can safely call this method from multiple goroutine contexts.
	SaveObservations(obs ...*Observations)

	// ZeroTime returns the runtime's "zero" time, which is used as the
	// starting point to generate observation's delta times.
	ZeroTime() time.Time
}

Runtime is the runtime in which we execute the DSL.

type RuntimeMeasurexLite

type RuntimeMeasurexLite struct {
	*MinimalRuntime
	// contains filtered or unexported fields
}

RuntimeMeasurexLite uses measurexlite to collect [*Observations.]

func NewRuntimeMeasurexLite

func NewRuntimeMeasurexLite(logger model.Logger, zeroTime time.Time, options ...RuntimeMeasurexLiteOption) *RuntimeMeasurexLite

NewRuntimeMeasurexLite creates a Runtime using measurexlite to collect *Observations.

func (*RuntimeMeasurexLite) NewTrace

func (p *RuntimeMeasurexLite) NewTrace(index int64, zeroTime time.Time, tags ...string) Trace

NewTrace implements Runtime.

type RuntimeMeasurexLiteOption

type RuntimeMeasurexLiteOption func(rt *RuntimeMeasurexLite)

RuntimeMeasurexLiteOption is an option for initializing a *RuntimeMeasurexLite.

func RuntimeMeasurexLiteOptionMeasuringNetwork

func RuntimeMeasurexLiteOptionMeasuringNetwork(netx model.MeasuringNetwork) RuntimeMeasurexLiteOption

RuntimeMeasurexLiteOptionMeasuringNetwork allows to configure which model.MeasuringNetwork to use.

type Stats

type Stats[T any] struct {
	// contains filtered or unexported fields
}

Stats measures the number of successes and failures.

The zero value is invalid; use NewStats.

func NewStats

func NewStats[T any]() *Stats[T]

NewStats creates a *Stats instance.

func (*Stats[T]) Export

func (s *Stats[T]) Export() (out map[string]int64)

Export exports the current stats without clearing the internally used map such that statistics accumulate over time and never reset for the *Stats lifecycle.

func (*Stats[T]) Observer

func (s *Stats[T]) Observer() Func[T, T]

Observer returns a Func that observes the results of the previous pipeline stage. This function converts any error that it sees to ErrSkip. This function does not account for ErrSkip, meaning that you will never see ErrSkip in the stats returned by Stats.Export.

type TCPConnection

type TCPConnection struct {
	// Address is the MANDATORY address we tried to connect to.
	Address string

	// Conn is the established connection.
	Conn net.Conn

	// Domain is the OPTIONAL domain from which we resolved the Address.
	Domain string

	// Network is the MANDATORY network we tried to use when connecting.
	Network string

	// Trace is the MANDATORY trace we're using.
	Trace Trace
}

TCPConnection is an established TCP connection. If you initialize manually, init at least the ones marked as MANDATORY.

type TLSConnection

type TLSConnection struct {
	// Address is the MANDATORY address we tried to connect to.
	Address string

	// Conn is the established TLS conn.
	Conn netxlite.TLSConn

	// Domain is the OPTIONAL domain we resolved.
	Domain string

	// Network is the MANDATORY network we tried to use when connecting.
	Network string

	// TLSState is the possibly-empty TLS connection state.
	TLSState tls.ConnectionState

	// Trace is the MANDATORY trace we're using.
	Trace Trace
}

TLSConnection is an established TLS connection. If you initialize manually, init at least the ones marked as MANDATORY.

type TLSHandshakeOption

type TLSHandshakeOption func(config *tls.Config)

TLSHandshakeOption is an option you can pass to TLSHandshake.

func TLSHandshakeOptionInsecureSkipVerify

func TLSHandshakeOptionInsecureSkipVerify(value bool) TLSHandshakeOption

TLSHandshakeOptionInsecureSkipVerify controls whether TLS verification is enabled.

func TLSHandshakeOptionNextProto

func TLSHandshakeOptionNextProto(value []string) TLSHandshakeOption

TLSHandshakeOptionNextProto allows to configure the ALPN protocols.

func TLSHandshakeOptionRootCAs

func TLSHandshakeOptionRootCAs(value *x509.CertPool) TLSHandshakeOption

TLSHandshakeOptionRootCAs allows to configure custom root CAs.

func TLSHandshakeOptionServerName

func TLSHandshakeOptionServerName(value string) TLSHandshakeOption

TLSHandshakeOptionServerName allows to configure the SNI to use.

type Trace

type Trace interface {
	// CloneBytesReceivedMap returns a clone of the internal bytes received map. The key of the
	// map is a string following the "EPNT_ADDRESS PROTO" pattern where the "EPNT_ADDRESS" contains
	// the endpoint address and "PROTO" is "tcp" or "udp".
	CloneBytesReceivedMap() (out map[string]int64)

	// DNSLookupsFromRoundTrip returns all the DNS lookup results collected so far.
	DNSLookupsFromRoundTrip() (out []*model.ArchivalDNSLookupResult)

	// Index returns the unique index used by this trace.
	Index() int64

	// NewDialerWithoutResolver is equivalent to netxlite.Netx.NewDialerWithoutResolver
	// except that it returns a model.Dialer that uses this trace.
	//
	// Caveat: the dialer wrappers are there to implement the
	// model.MeasuringNetwork interface, but they're not used by this function.
	NewDialerWithoutResolver(dl model.DebugLogger, wrappers ...model.DialerWrapper) model.Dialer

	// NewParallelUDPResolver returns a possibly-trace-ware parallel UDP resolver
	NewParallelUDPResolver(logger model.DebugLogger, dialer model.Dialer, address string) model.Resolver

	// NewQUICDialerWithoutResolver is equivalent to
	// netxlite.Netx.NewQUICDialerWithoutResolver except that it returns a
	// model.QUICDialer that uses this trace.
	//
	// Caveat: the dialer wrappers are there to implement the
	// model.MeasuringNetwork interface, but they're not used by this function.
	NewQUICDialerWithoutResolver(listener model.UDPListener,
		dl model.DebugLogger, wrappers ...model.QUICDialerWrapper) model.QUICDialer

	// NewTLSHandshakerStdlib is equivalent to netxlite.Netx.NewTLSHandshakerStdlib
	// except that it returns a model.TLSHandshaker that uses this trace.
	NewTLSHandshakerStdlib(dl model.DebugLogger) model.TLSHandshaker

	// NetworkEvents returns all the network events collected so far.
	NetworkEvents() (out []*model.ArchivalNetworkEvent)

	// NewStdlibResolver returns a possibly-trace-ware system resolver.
	NewStdlibResolver(logger model.DebugLogger) model.Resolver

	// NewUDPListener implements model.MeasuringNetwork.
	NewUDPListener() model.UDPListener

	// QUICHandshakes collects all the QUIC handshake results collected so far.
	QUICHandshakes() (out []*model.ArchivalTLSOrQUICHandshakeResult)

	// TCPConnects collects all the TCP connect results collected so far.
	TCPConnects() (out []*model.ArchivalTCPConnectResult)

	// TLSHandshakes collects all the TLS handshake results collected so far.
	TLSHandshakes() (out []*model.ArchivalTLSOrQUICHandshakeResult)

	// Tags returns the trace tags.
	Tags() []string

	// TimeSince is equivalent to Trace.TimeNow().Sub(t0).
	TimeSince(t0 time.Time) time.Duration

	// ZeroTime returns the "zero" time of this trace.
	ZeroTime() time.Time
}

Trace collects *Observations using tracing. Specific implementations of this interface may be engineered to collect no *Observations for efficiency (i.e., when you don't care about collecting *Observations but you still want to use this package).

type Void

type Void struct{}

Void is the empty data structure.

Jump to

Keyboard shortcuts

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