probeservices

package
v3.21.0 Latest Latest
Warning

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

Go to latest
Published: Mar 27, 2024 License: GPL-3.0 Imports: 16 Imported by: 0

Documentation

Overview

Package probeservices contains code to contact OONI probe services.

The probe services are HTTPS endpoints distributed across a bunch of data centres implementing a bunch of OONI APIs. When started, OONI will benchmark the available probe services and select the fastest one. Eventually all the possible OONI APIs will run as probe services.

This package implements the following APIs:

1. v2.0.0 of the OONI bouncer specification defined in https://github.com/ooni/spec/blob/master/backends/bk-004-bouncer;

2. v2.0.0 of the OONI collector specification defined in https://github.com/ooni/spec/blob/master/backends/bk-003-collector.md;

3. most of the OONI orchestra API: login, register, fetch URLs for the Web Connectivity experiment, input for Tor and Psiphon.

Orchestra is a set of OONI APIs for probe orchestration. We currently mainly using it for fetching inputs for the tor, psiphon, and web experiments.

In addition, this package also contains code to benchmark the available probe services, discard non working ones, select the fastest.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrUnsupportedDataFormatVersion indicates that the user provided
	// in input a data format version that we do not support.
	ErrUnsupportedDataFormatVersion = errors.New("unsupported data format version")

	// ErrUnsupportedFormat indicates that the format is not supported.
	ErrUnsupportedFormat = errors.New("unsupported format")

	// ErrJSONFormatNotSupported indicates that the collector we're using
	// does not support the JSON report format.
	ErrJSONFormatNotSupported = errors.New("JSON format not supported")
)
View Source
var (
	// ErrUnsupportedEndpoint indicates that we don't support this endpoint type.
	ErrUnsupportedEndpoint = errors.New("probe services: unsupported endpoint type")

	// ErrUnsupportedCloudFrontAddress indicates that we don't support this
	// cloudfront address (e.g. wrong scheme, presence of port).
	ErrUnsupportedCloudFrontAddress = errors.New(
		"probe services: unsupported cloud front address",
	)

	// ErrNotRegistered indicates that the probe is not registered
	// with the OONI orchestra backend.
	ErrNotRegistered = errors.New("not registered")

	// ErrNotLoggedIn indicates that we are not logged in
	ErrNotLoggedIn = errors.New("not logged in")

	// ErrInvalidMetadata indicates that the metadata is not valid
	ErrInvalidMetadata = errors.New("invalid metadata")
)

Functions

func Default

func Default() []model.OOAPIService

Default returns the default probe services

func NewReportTemplate

func NewReportTemplate(m *model.Measurement) model.OOAPIReportTemplate

NewReportTemplate creates a new ReportTemplate from a Measurement.

func OnlyFallbacks

func OnlyFallbacks(in []model.OOAPIService) (out []model.OOAPIService)

OnlyFallbacks returns the fallback endpoints only.

func OnlyHTTPS

func OnlyHTTPS(in []model.OOAPIService) (out []model.OOAPIService)

OnlyHTTPS returns the HTTPS endpoints only.

func SortEndpoints

func SortEndpoints(in []model.OOAPIService) (out []model.OOAPIService)

SortEndpoints gives priority to https, then cloudfronted, then onion.

Types

type Candidate

type Candidate struct {
	// Duration is the time it took to access the service.
	Duration time.Duration

	// Err indicates whether the service works.
	Err error

	// Endpoint is the service endpoint.
	Endpoint model.OOAPIService

	// TestHelpers contains the data returned by the endpoint.
	TestHelpers map[string][]model.OOAPIService
}

Candidate is a candidate probe service.

func SelectBest

func SelectBest(candidates []*Candidate) (selected *Candidate)

SelectBest selects the best among the candidates. If there is no suitable candidate, then this function returns nil.

func TryAll

func TryAll(ctx context.Context, sess Session, in []model.OOAPIService) (out []*Candidate)

TryAll tries all the input services using the provided context and session. It returns a list containing information on each candidate that was tried. We will try all the HTTPS candidates first. So, the beginning of the list will contain all of them, and for each of them you will know whether it worked (by checking the Err field) and how fast it was (by checking the Duration field). You should pick the fastest one that worked. If none of them works, then TryAll will subsequently attempt with all the available fallbacks, and return at the first success. In such case, you will see a list of N failing HTTPS candidates, followed by a single successful fallback candidate (e.g. cloudfronted). If all candidates fail, you see in output a list containing all entries where Err is not nil.

type Client

type Client struct {
	httpx.APIClientTemplate
	KVStore       model.KeyValueStore
	LoginCalls    *atomic.Int64
	RegisterCalls *atomic.Int64
	StateFile     StateFile
}

Client is a client for the OONI probe services API.

func NewClient

func NewClient(sess Session, endpoint model.OOAPIService) (*Client, error)

NewClient creates a new client for the specified probe services endpoint. This function fails, e.g., we don't support the specified endpoint.

func (Client) CheckIn

CheckIn function is called by probes asking if there are tests to be run The config argument contains the mandatory settings. This function will additionally update the checkincache such that we track selected parts of the check-in API response. Returns the list of tests to run and the URLs, on success, or an explanatory error, in case of failure.

func (Client) FetchPsiphonConfig

func (c Client) FetchPsiphonConfig(ctx context.Context) ([]byte, error)

FetchPsiphonConfig fetches psiphon config from authenticated OONI orchestra.

func (Client) FetchTorTargets

func (c Client) FetchTorTargets(ctx context.Context, cc string) (result map[string]model.OOAPITorTarget, err error)

FetchTorTargets returns the targets for the tor experiment.

func (Client) GetCredsAndAuth

func (c Client) GetCredsAndAuth() (*model.OOAPILoginCredentials, *model.OOAPILoginAuth, error)

GetCredsAndAuth is an utility function that returns the credentials with which we are registered and the token with which we're logged in. If we're not registered or not logged in, an error is returned instead.

func (Client) GetMeasurementMeta

func (c Client) GetMeasurementMeta(
	ctx context.Context, config model.OOAPIMeasurementMetaConfig) (*model.OOAPIMeasurementMeta, error)

GetMeasurementMeta returns meta information about a measurement.

func (Client) GetTestHelpers

func (c Client) GetTestHelpers(
	ctx context.Context) (output map[string][]model.OOAPIService, err error)

GetTestHelpers is like GetCollectors but for test helpers.

func (Client) MaybeLogin

func (c Client) MaybeLogin(ctx context.Context) error

MaybeLogin performs login if necessary

func (Client) MaybeRegister

func (c Client) MaybeRegister(ctx context.Context, metadata model.OOAPIProbeMetadata) error

MaybeRegister registers this client if not already registered

func (Client) OpenReport

OpenReport opens a new report.

type ReportChannel

type ReportChannel interface {
	CanSubmit(m *model.Measurement) bool
	ReportID() string
	SubmitMeasurement(ctx context.Context, m *model.Measurement) error
}

ReportChannel is a channel through which one could submit measurements belonging to the same report. The Report struct belongs to this interface.

type ReportOpener

type ReportOpener interface {
	OpenReport(ctx context.Context, rt model.OOAPIReportTemplate) (ReportChannel, error)
}

ReportOpener is any struct that is able to open a new ReportChannel. The Client struct belongs to this interface.

type Session

type Session interface {
	DefaultHTTPClient() model.HTTPClient
	KeyValueStore() model.KeyValueStore
	Logger() model.Logger
	ProxyURL() *url.URL
	UserAgent() string
}

Session is how this package sees a Session.

type State

type State struct {
	ClientID string
	Expire   time.Time
	Password string
	Token    string
}

State is the state stored inside the state file

func (State) Auth

func (s State) Auth() *model.OOAPILoginAuth

Auth returns an authentication structure, if possible, otherwise it returns nil, meaning that you should login again.

func (State) Credentials

func (s State) Credentials() *model.OOAPILoginCredentials

Credentials returns login credentials, if possible, otherwise it returns nil, meaning that you should create an account.

type StateFile

type StateFile struct {
	Store model.KeyValueStore
	// contains filtered or unexported fields
}

StateFile is the orchestra state file. It is backed by a generic key-value store configured by the user.

func NewStateFile

func NewStateFile(kvstore model.KeyValueStore) StateFile

NewStateFile creates a new state file backed by a key-value store

func (StateFile) Get

func (sf StateFile) Get() (state State)

Get returns the current state. In case of any error with the underlying key-value store, we return an empty state.

func (StateFile) GetMockable

func (sf StateFile) GetMockable(sfget func(string) ([]byte, error),
	unmarshal func([]byte, interface{}) error) (State, error)

GetMockable is a mockable version of Get

func (StateFile) Set

func (sf StateFile) Set(s State) error

Set saves the current state on the key-value store.

func (StateFile) SetMockable

func (sf StateFile) SetMockable(s State, mf func(interface{}) ([]byte, error)) error

SetMockable is a mockable version of Set

type Submitter

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

Submitter is an abstraction allowing you to submit arbitrary measurements to a given OONI backend. This implementation will take care of opening reports when needed as well as of closing reports when needed. Nonetheless you need to remember to call its Close method when done, because there is likely an open report that has not been closed yet.

func NewSubmitter

func NewSubmitter(opener ReportOpener, logger model.Logger) *Submitter

NewSubmitter creates a new Submitter instance.

func (*Submitter) Submit

func (sub *Submitter) Submit(ctx context.Context, m *model.Measurement) error

Submit submits the current measurement to the OONI backend created using the ReportOpener passed to the constructor.

Jump to

Keyboard shortcuts

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