Verified Commit b8ba6f94 authored by meskio's avatar meskio 🏔️
Browse files

Test resource bandwidth with onbasca

Get the resource bandwidth ration from onbasca and use it to decide if
the resource should be distributed or not.

There are two services testing resources now:
* bridgestrap testing if the resource works
* onbasca testing the bandwidth of the resource

In the future we might want to drop the support for bridgestrap and use
only onbasca, but let's first gain some experience with onbasca by using
them in parallel.

Closes: #150
parent 2b6af80e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -6,6 +6,8 @@
        "blocklist_file": "",
        "allowlist_file": "",
        "bridgestrap_endpoint": "http://127.0.0.1:5001/bridge-state",
        "onbasca_endpoint": "http://127.0.0.1:5002/bridge-state",
        "bandwidth_ratio_threshold": 0.75,
        "api_endpoint_resources": "/resources",
        "api_endpoint_resource_stream": "/resource-stream",
        "api_endpoint_targets": "/targets",
+12 −3
Original line number Diff line number Diff line
Resource testing
================

Rdsys tests its resources and only hands out resources that are known to work.
The actual testing is done by a separate service,
[bridgestrap](https://gitlab.torproject.org/tpo/anti-censorship/bridgestrap).
Rdsys tests its resources and only hands out resources that are known to work
and have enough bandwidth. The actual testing is done by two separate services,
[bridgestrap](https://gitlab.torproject.org/tpo/anti-censorship/bridgestrap)
and [onbasca](https://gitlab.torproject.org/tpo/network-health/onbasca).

Rdsys requests resource tests by talking to bridgestrap's
[HTTP API](https://gitlab.torproject.org/tpo/anti-censorship/bridgestrap#input)
(the API endpoint is set in rdsys's
@@ -11,6 +13,13 @@ Rdsys requests resource tests by talking to bridgestrap's
When a resource is first added to rdsys, it is in state "untested".  Once it's
tested, it's either in state "functional" or "dysfunctional".

The same mechanism is being used to request onbasca to test the bandwidth of
the resource and provide a ratio. Onbasca does test the resources asyncronosly,
instead of testing them at the moment of the request, the response to the 
request includes the last tested ratio or a 0 if this resource hasn't being
tested yet. Rdsys does distribute every resource that has a ratio higher than 
the configured threshold or that doesn't have a ratio yet.

Mechanism
---------

+5 −2
Original line number Diff line number Diff line
@@ -89,7 +89,7 @@ func (b *BackendContext) InitBackend(cfg *Config) {
	b.Config = cfg
	b.metrics = InitMetrics()

	b.Resources = *core.NewBackendResources()
	b.Resources = *core.NewBackendResources(cfg.Backend.BandwidthRatioThreshold)
	for rType, conf := range cfg.Backend.Resources {
		if _, exists := resources.ResourceMap[rType]; !exists {
			log.Printf("Error: Skipping %q because we have no constructor for it.", rType)
@@ -105,7 +105,7 @@ func (b *BackendContext) InitBackend(cfg *Config) {
		b.Resources.AddResourceType(rType, conf.Unpartitioned, proportions)
	}

	b.rTestPool = NewResourceTestPool(cfg.Backend.BridgestrapEndpoint)
	b.rTestPool = NewResourceTestPool(cfg.Backend.BridgestrapEndpoint, cfg.Backend.OnbascaEndpoint)
	defer b.rTestPool.Stop()

	quit := make(chan bool)
@@ -317,6 +317,9 @@ func (b *BackendContext) statusHandler(w http.ResponseWriter, r *http.Request) {

		for _, resource := range resources {
			rResult := fmt.Sprintf("* %s: %s\n", rType, statuses[resource.TestResult().State])
			if resource.TestResult().Ratio != nil {
				rResult += fmt.Sprintf("  Bandwidth Ratio: %f\n", *resource.TestResult().Ratio)
			}
			if resource.TestResult().Error != "" {
				rResult += fmt.Sprintf("  Error: %s\n", resource.TestResult().Error)
			}
+1 −1
Original line number Diff line number Diff line
@@ -62,7 +62,7 @@ func TestPostResourcesHandler(t *testing.T) {
	b.Config.Backend.ApiTokens = make(map[string]string)
	b.Config.Backend.ApiTokens["foo"] = "bar"

	b.Resources = *core.NewBackendResources()
	b.Resources = *core.NewBackendResources(0)
	b.Resources.AddResourceType("obfs4", false, nil)
	b.rStore = &ResourceStore{}

+2 −0
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@ type BackendConfig struct {
	StatusEndpoint          string            `json:"web_endpoint_status"`
	MetricsEndpoint         string            `json:"web_endpoint_metrics"`
	BridgestrapEndpoint     string            `json:"bridgestrap_endpoint"`
	OnbascaEndpoint         string            `json:"onbasca_endpoint"`
	BandwidthRatioThreshold float64           `json:"bandwidth_ratio_threshold"`
	StorageDir              string            `json:"storage_dir"`
	AssignmentsFile         string            `json:"assignments_file"`
	// DistProportions contains the proportion of resources that each
Loading