core

package
v0.0.0-...-cf93e4e Latest Latest
Warning

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

Go to latest
Published: Dec 4, 2024 License: BSD-3-Clause Imports: 13 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// These constants represent resource event types.  The backend informs
	// distributors if a resource is new, has changed, or has disappeared.
	ResourceUnchanged = iota
	ResourceIsNew
	ResourceChanged
	ResourceIsGone
	ResourceError
)
View Source
const (
	// The following constants represent the states that a resource can be in.
	// Before rdsys had a chance to ask bridgestrap about a resource's state,
	// it's untested.  Afterwards, it's either functional or not functional.
	StateUntested = iota
	StateFunctional
	StateDysfunctional
)
View Source
const (
	// The following constants act as a crude representation of the bandwidth speed
	// that a resource can have. This is meant as a way to check whether or not the ratio
	// meets the bandwidth threshold for the given resource without requiring the context.
	// Before an onbasca test, a resource's speed is untested.  Afterwards, it's either
	// sufficient or insufficient.
	SpeedUntested = iota
	SpeedAccepted
	SpeedRejected
)

Variables

This section is empty.

Functions

func NewHashnode

func NewHashnode(k Hashkey, r Resource) *hashnode

NewHashnode returns a new hash node and sets its LastUpdate field to the current UTC time.

func SpeedToString

func SpeedToString(speed int) string

func StateToString

func StateToString(state int) string

Types

type BackendResources

type BackendResources struct {
	Collection

	// OnlyFunctional resources will be provided to distributors
	OnlyFunctional bool

	// UseBandwidthRatio to decide wich bridges to distribute
	UseBandwidthRatio bool

	// The mutex us used to protect the access to ResourceDiffRecipients.
	// The hashrings in the Collection have their own mutex and the entries
	// of the Collection map are only set during intialization.
	sync.RWMutex
	// ResourceDiffRecipients maps a distributor name (e.g., "moat") to an resource
	// diff recipient struct that helps us keep track of notifying distributors when
	// their resources change. It is used by the resource stream API.
	ResourceDiffRecipients map[string][]*ResourceDiffRecipient
}

BackendResources implements a collection of resources for our backend. The backend uses this data structure to keep track of all of its resource types.

func NewBackendResources

func NewBackendResources(cfg *CollectionConfig) *BackendResources

NewBackendResources creates and returns a new resource collection. rTypes is a map of resource type names to a boolean indicating if the resource is unpartitioend

func (*BackendResources) Add

func (ctx *BackendResources) Add(r1 Resource)

Add adds the given resource to the resource collection. If the resource already exists but has changed (i.e. its unique ID remains the same but its object ID changed), we update the existing resource.

func (*BackendResources) Get

func (ctx *BackendResources) Get(distName string, rType string, ipVersion IPVersion) ResourceState

Get returns a struct that contains the state of resources distributor.

func (*BackendResources) Prune

func (ctx *BackendResources) Prune(rName string) []Resource

Prune removes expired resources and notifies on not working ones

func (*BackendResources) RegisterChan

func (ctx *BackendResources) RegisterChan(req *ResourceRequest, recipient chan *ResourceDiff)

RegisterChan registers a channel to be informed about resource updates.

func (*BackendResources) UnregisterChan

func (ctx *BackendResources) UnregisterChan(distName string, recipient chan *ResourceDiff)

UnregisterChan unregisters a channel to be informed about resource updates.

type BridgeRequest

type BridgeRequest struct {
	// IPVersion can be used to select only resources of IPv6 or IPv4.
	// In case of IPAny any resources will be returned.
	IPVersion IPVersion

	// Country is the country from where the request is being placed,
	// it will be used to don't return bridges known to be blocked in that country.
	Country string
}

BridgeRequest holds the options to request a bridge from the hashring. If an empty request is created by BridgeRequest{} it should work for selecting any bridge.

type Collection

type Collection map[string]ResourceGroup

Collection maps a resource type (e.g. "obfs4") to its corresponding Hashring

func NewCollection

func NewCollection(cfg *CollectionConfig) Collection

NewCollection creates and returns a new resource collection

func (Collection) Add

func (c Collection) Add(resource Resource) error

Add resource to the collection

func (Collection) ApplyDiff

func (c Collection) ApplyDiff(diff *ResourceDiff)

ApplyDiff updates the collection with the resources changed in ResrouceDiff

func (Collection) GetHashring

func (c Collection) GetHashring(partitionName string, rType string) *Hashring

GetHashring returns the hashring of the requested type for the given distributor.

func (Collection) Save

func (c Collection) Save()

Save to the persitant store

func (Collection) String

func (c Collection) String() string

String returns a summary of the backend resources.

type CollectionConfig

type CollectionConfig struct {
	// StorageDir is the path to the persistant folder where data will be stored
	StorageDir string

	// Types is the list of Resource types that will be stored in the collection
	Types []TypeConfig
}

CollectionConfig holds the configuration to create a Collection

type Dummy

type Dummy struct {
	ObjectId   Hashkey
	UniqueId   Hashkey
	ExpiryTime time.Duration

	Distribution string
	RelationIds  []string
	IPVer        IPVersion
	Blocked      LocationSet
	// contains filtered or unexported fields
}

Dummy implements a simple Resource, which we use in unit tests.

func NewDummy

func NewDummy(oid Hashkey, uid Hashkey) *Dummy

func (*Dummy) BlockedIn

func (d *Dummy) BlockedIn() LocationSet

func (*Dummy) Distributor

func (d *Dummy) Distributor() string

func (*Dummy) Expiry

func (d *Dummy) Expiry() time.Duration

func (*Dummy) IPVersion

func (d *Dummy) IPVersion() IPVersion

func (*Dummy) IsValid

func (d *Dummy) IsValid() bool

func (*Dummy) Oid

func (d *Dummy) Oid() Hashkey

func (*Dummy) RelationIdentifiers

func (d *Dummy) RelationIdentifiers() []string

func (*Dummy) SetBlockedIn

func (d *Dummy) SetBlockedIn(LocationSet)

func (*Dummy) SetTest

func (d *Dummy) SetTest(t *ResourceTest)

func (*Dummy) SetTestFunc

func (d *Dummy) SetTestFunc(f func(Resource))

func (*Dummy) String

func (d *Dummy) String() string

func (*Dummy) Test

func (d *Dummy) Test()

func (*Dummy) TestResult

func (d *Dummy) TestResult() *ResourceTest

func (*Dummy) Type

func (d *Dummy) Type() string

func (*Dummy) Uid

func (d *Dummy) Uid() Hashkey

type FilterFunc

type FilterFunc func(r Resource) bool

FilterFunc takes as input a resource and returns true or false, depending on its filtering criteria.

type Hashkey

type Hashkey uint64

Hashkey represents an index in a hashring.

func NewHashkey

func NewHashkey(id string) Hashkey

NewHashkey calculates a hash from the id to be used index in the hashring

type Hashring

type Hashring struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

Hashring represents a hashring consisting of resources.

func NewHashring

func NewHashring() *Hashring

NewHashring returns a new hashring.

func (*Hashring) Add

func (h *Hashring) Add(r Resource) error

Add adds the given resource to the hashring. If the resource is already present, we update its timestamp and return an error.

func (*Hashring) AddOrUpdate

func (h *Hashring) AddOrUpdate(r Resource) (event int)

AddOrUpdate attempts to add the given resource to the hashring. If it already is in the hashring, we update it if (and only if) its object ID changed.

func (*Hashring) ApplyDiff

func (h *Hashring) ApplyDiff(d *ResourceDiff)

ApplyDiff applies the given ResourceDiff to the hashring. New resources are added, changed resources are updated, and gone resources are removed.

func (*Hashring) Clear

func (h *Hashring) Clear()

Clear removes every resource from the Hashring

func (*Hashring) Filter

func (h *Hashring) Filter(f FilterFunc) []Resource

Filter filters the resources of this hashring with the given filter function and returns the remaining resources as another hashring.

func (*Hashring) Get

func (h *Hashring) Get(k Hashkey) (Resource, error)

Get attempts to retrieve the element identified by the given hash key. If the hashring is empty, an error is returned. If there is no exact match for the given hash key, we return the element whose hash key is the closest to the given hash key in descending direction.

func (*Hashring) GetAll

func (h *Hashring) GetAll() []Resource

GetAll returns all of the hashring's resources.

func (*Hashring) GetExact

func (h *Hashring) GetExact(k Hashkey) (Resource, error)

GetExact attempts to retrieve the element identified by the given hash key. If we cannot find the element, an error is returned.

func (*Hashring) GetMany

func (h *Hashring) GetMany(k Hashkey, num int, req *BridgeRequest) (resources []Resource, err error)

GetMany behaves like Get with the exception that it attempts to return the given number of elements. If the number of desired elements exceeds the number of elements in the hashring all the resources in the hashring will be returned.

func (*Hashring) Len

func (h *Hashring) Len() int

Len implements the sort interface. This function is unsafe and needs a mutex lock before being used

func (*Hashring) Less

func (h *Hashring) Less(i, j int) bool

Less implements the sort interface. This function is unsafe and needs a mutex lock before being used

func (*Hashring) Prune

func (h *Hashring) Prune() []Resource

Prune prunes and returns expired resources from the hashring.

func (*Hashring) Remove

func (h *Hashring) Remove(r Resource) error

Remove removes the given resource from the hashring. If the hashring is empty or we cannot find the key, an error is returned.

func (*Hashring) Swap

func (h *Hashring) Swap(i, j int)

Swap implements the sort interface. This function is unsafe and needs a mutex lock before being used

type IPVersion

type IPVersion uint16
const (
	IPAny IPVersion = 0
	IPv4  IPVersion = 4
	IPv6  IPVersion = 6
)

func (IPVersion) ValidFor

func (ver IPVersion) ValidFor(ipVersion IPVersion) bool

type Location

type Location struct {
	CountryCode string // ISO 3166-1 alpha-2 country code, e.g. "AR".
	ASN         uint32 // Autonomous system number, e.g. 1234.
}

Location represents the physical and topological location of a resource or requester.

func (*Location) String

func (l *Location) String() string

String returns the string representation of the given location, e.g. "RU 1234".

type LocationSet

type LocationSet map[string]bool

LocationSet maps the string representation of locations (because we cannot use structs as map keys) to 'true'.

func (LocationSet) HasLocationsNotIn

func (s1 LocationSet) HasLocationsNotIn(s2 LocationSet) bool

HasLocationsNotIn returns true if s1 contains at least one location that is not in s2.

func (LocationSet) String

func (l LocationSet) String() string

String returns a string representation of the given location set.

type Resource

type Resource interface {
	Type() string
	String() string
	IsValid() bool
	BlockedIn() LocationSet
	SetBlockedIn(LocationSet)
	// Uid returns the resource's unique identifier.  Bridges with different
	// fingerprints have different unique identifiers.
	Uid() Hashkey
	// Oid returns the resource's object identifier.  Bridges with the *same*
	// fingerprint but different, say, IP addresses have different object
	// identifiers.  If two resources have the same Oid, they must have the
	// same Uid but not vice versa.
	Oid() Hashkey

	// RelationIdentifiers retrunrs a list of identifiers that represent a
	// relation between resources. For example the fingerprint, two resources
	// with the same fingerprint are related to eachother.
	RelationIdentifiers() []string

	Test()
	TestResult() *ResourceTest
	// Expiry returns the duration after which the resource should be deleted
	// from the backend (if the backend hasn't received an update).
	Expiry() time.Duration

	// Distributor set for this resource
	Distributor() string

	// IPVersion() returns IPv4 or IPv6 if the resource IP is not dummy otherwise IPAny
	IPVersion() IPVersion
}

Resource specifies the resources that rdsys hands out to users. This could be a vanilla Tor bridge, and obfs4 bridge, a Snowflake proxy, and even Tor Browser links. Your imagination is the limit.

type ResourceBase

type ResourceBase struct {
	RType      string      `json:"type"`
	RBlockedIn LocationSet `json:"blocked_in"`
	Location   *Location
	Test       *ResourceTest `json:"test_result"`
}

ResourceBase provides a data structure plus associated methods that are shared across all of our resources.

func NewResourceBase

func NewResourceBase() *ResourceBase

NewResourceBase returns a new ResourceBase.

func (*ResourceBase) BlockedIn

func (r *ResourceBase) BlockedIn() LocationSet

BlockedIn returns the set of locations that block the resource.

func (*ResourceBase) SetBlockedIn

func (r *ResourceBase) SetBlockedIn(l LocationSet)

SetBlockedIn adds the given location set to the set of locations that block the resource.

func (*ResourceBase) SetType

func (r *ResourceBase) SetType(Type string)

SetType sets the resource's type to the given type.

func (*ResourceBase) TestResult

func (r *ResourceBase) TestResult() *ResourceTest

TestResult returns the resource's test result.

func (*ResourceBase) Type

func (r *ResourceBase) Type() string

Type returns the resource's type.

type ResourceDiff

type ResourceDiff struct {
	New     ResourceMap `json:"new"`
	Changed ResourceMap `json:"changed"`
	Gone    ResourceMap `json:"gone"`

	// FullUpdate indicates that this diff contains the full list of
	// resources on the New field.
	FullUpdate bool `json:"full_update"`
}

ResourceDiff represents a diff that contains new, changed, and gone resources. A resource diff can be applied onto data structures that implement a collection of resources, e.g. a Hashring.

func NewResourceDiff

func NewResourceDiff() *ResourceDiff

NewResourceDiff returns a new ResourceDiff.

func (*ResourceDiff) String

func (m *ResourceDiff) String() string

String returns a string representation of ResourceDiff.

type ResourceDiffRecipient

type ResourceDiffRecipient struct {
	Chan    chan *ResourceDiff
	Request *ResourceRequest
}

ResourceDiffRecipient represents the recipient of a resource event, i.e. a distributor; or rather, what we need to send updates to said distributor.

type ResourceGroup

type ResourceGroup interface {
	Add(resource Resource) error
	AddOrUpdate(resource Resource) int
	Remove(resource Resource) error
	Len() int
	Clear()
	Filter(FilterFunc) []Resource
	GetAll() []Resource
	Prune() []Resource
	// contains filtered or unexported methods
}

ResourceGroup is a type that holds a list of resources like a Hashring

type ResourceMap

type ResourceMap map[string]ResourceQueue

ResourceMap maps a resource type to a slice of respective resources

func (ResourceMap) ApplyDiff

func (m ResourceMap) ApplyDiff(d *ResourceDiff)

ApplyDiff applies the given ResourceDiff to the ResourceMap. New resources are added, changed resources are updated, and gone resources are removed.

func (ResourceMap) String

func (m ResourceMap) String() string

String returns a string representation of the resource map that's easy on the eyes.

type ResourceQueue

type ResourceQueue []Resource

ResourceQueue implements a queue of resources.

func (*ResourceQueue) Delete

func (q *ResourceQueue) Delete(r1 Resource) error

Delete removes the resource from the queue. If the queue is empty, the function returns an error.

func (*ResourceQueue) Dequeue

func (q *ResourceQueue) Dequeue() (Resource, error)

Dequeue return and removes the oldest resource in the queue. If the queue is empty, the function returns an error.

func (*ResourceQueue) Enqueue

func (q *ResourceQueue) Enqueue(r1 Resource) error

Enqueue adds a resource to the queue. The function returns an error if the resource already exists in the queue.

func (*ResourceQueue) Search

func (q *ResourceQueue) Search(key Hashkey) (Resource, error)

Search searches the resource queue for the given unique ID and either returns the resource it found, or an error if the resource could not be found.

func (*ResourceQueue) Update

func (q *ResourceQueue) Update(r1 Resource) error

Update updates an existing resource if its unique ID matches the unique ID of the given resource. If the queue is empty, the function returns an error.

type ResourceRequest

type ResourceRequest struct {
	// Name of requesting distributor.
	RequestOrigin string             `json:"request_origin"`
	ResourceTypes []string           `json:"resource_types"`
	IPVersion     IPVersion          `json:"ip-version"`
	Receiver      chan *ResourceDiff `json:"-"`
}

ResourceRequest represents a request for resources. Distributors use ResourceRequest to request resources from the backend.

func (*ResourceRequest) HasResourceIP

func (r *ResourceRequest) HasResourceIP(ipVersion IPVersion) bool

HasResourceIP returns true if the resource request contains the given IPVersion.

func (*ResourceRequest) HasResourceType

func (r *ResourceRequest) HasResourceType(rType1 string) bool

HasResourceType returns true if the resource request contains the given resource type.

type ResourceState

type ResourceState struct {
	Working    []Resource `json:"working"`
	Notworking []Resource `json:"not_working"`
}

type ResourceTest

type ResourceTest struct {
	State       int       `json:"-"`
	Speed       int       `json:"-"`
	Ratio       *float64  `json:"-"`
	LastTested  time.Time `json:"-"`
	LastWorking time.Time `json:"last_working"`
	Error       string    `json:"-"`
}

ResourceTest represents the result of a test of a resource. We use the tool bridgestrap for testing if the bridge is functional: https://gitlab.torproject.org/tpo/anti-censorship/bridgestrap And onbasca to test it's speed ratio: https://gitlab.torproject.org/tpo/network-health/onbasca/

type TypeConfig

type TypeConfig struct {
	// Type name of the Resources
	Type string

	// NewResource is a function that retourns a new resource of the Type
	NewResource func() Resource

	// Unpartitioned if the resource hosted in a single Hashring or in a partitioned one
	Unpartitioned bool

	// Proportions is used for partitioned hashrings and indicates the names
	// of each partition and it's proportion of resources that should be asigned to it
	Proportions map[string]int

	// Stored indicates if the resources of this type should be persistant stored in StoreDir
	Stored bool
}

TypeConfig holds the configuration of one Resource type

Jump to

Keyboard shortcuts

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