Skip to content

Commit 005081e

Browse files
committed
address requested changes after merge review:
* never return IsAnomaly=true * early return in case the communication to the API fails * remove (most) top level TestKeys, including custom SummaryKeys and keep urlgetter keys * however keeps invalid CA cert handling, since unattended expired certs was a root cause for false positives in the past * removes snowflake + tor handling as part of the complexity reduction of the test * remove API response bodys from testkeys, addresses also removal of geolocation API reponse * adapts unit tests
1 parent 2e868a0 commit 005081e

2 files changed

Lines changed: 83 additions & 451 deletions

File tree

internal/experiment/riseupvpn/riseupvpn.go

Lines changed: 22 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,11 @@ package riseupvpn
66
import (
77
"context"
88
"encoding/json"
9-
"errors"
109
"time"
1110

1211
"github.com/ooni/probe-cli/v3/internal/experiment/urlgetter"
1312
"github.com/ooni/probe-cli/v3/internal/model"
1413
"github.com/ooni/probe-cli/v3/internal/netxlite"
15-
"github.com/ooni/probe-cli/v3/internal/tracex"
1614
)
1715

1816
const (
@@ -24,19 +22,19 @@ const (
2422
tcpConnect = "tcpconnect://"
2523
)
2624

27-
// EipService is the main JSON object of eip-service.json.
28-
type EipService struct {
25+
// EipServiceV3 is the main JSON object of eip-service.json.
26+
type EipServiceV3 struct {
2927
Gateways []GatewayV3
3028
}
3129

32-
// Capabilities is a list of transports a gateway supports
33-
type Capabilities struct {
30+
// CapabilitiesV3 is a list of transports a gateway supports
31+
type CapabilitiesV3 struct {
3432
Transport []TransportV3
3533
}
3634

3735
// GatewayV3 describes a gateway.
3836
type GatewayV3 struct {
39-
Capabilities Capabilities
37+
Capabilities CapabilitiesV3
4038
Host string
4139
IPAddress string `json:"ip_address"`
4240
Location string `json:"location"`
@@ -83,21 +81,15 @@ type Config struct {
8381
// TestKeys contains riseupvpn test keys.
8482
type TestKeys struct {
8583
urlgetter.TestKeys
86-
APIFailure []string `json:"api_failure"`
87-
APIStatus string `json:"api_status"`
88-
CACertStatus bool `json:"ca_cert_status"`
89-
FailingGateways []GatewayConnection `json:"failing_gateways"`
90-
TransportStatus map[string]string `json:"transport_status"`
84+
APIFailure []string `json:"api_failure"`
85+
CACertStatus bool `json:"ca_cert_status"`
9186
}
9287

9388
// NewTestKeys creates new riseupvpn TestKeys.
9489
func NewTestKeys() *TestKeys {
9590
return &TestKeys{
96-
APIFailure: nil,
97-
APIStatus: "ok",
98-
CACertStatus: true,
99-
FailingGateways: nil,
100-
TransportStatus: nil,
91+
APIFailure: nil,
92+
CACertStatus: true,
10193
}
10294
}
10395

@@ -109,11 +101,6 @@ func (tk *TestKeys) UpdateProviderAPITestKeys(v urlgetter.MultiOutput) {
109101
tk.TCPConnect = append(tk.TCPConnect, v.TestKeys.TCPConnect...)
110102
tk.TLSHandshakes = append(tk.TLSHandshakes, v.TestKeys.TLSHandshakes...)
111103
if v.TestKeys.Failure != nil {
112-
for _, request := range v.TestKeys.Requests {
113-
if request.Request.URL == eipServiceURL && request.Failure != nil {
114-
tk.APIStatus = "blocked"
115-
}
116-
}
117104
tk.APIFailure = append(tk.APIFailure, *v.TestKeys.Failure)
118105
return
119106
}
@@ -125,42 +112,6 @@ func (tk *TestKeys) UpdateProviderAPITestKeys(v urlgetter.MultiOutput) {
125112
func (tk *TestKeys) AddGatewayConnectTestKeys(v urlgetter.MultiOutput, transportType string) {
126113
tk.NetworkEvents = append(tk.NetworkEvents, v.TestKeys.NetworkEvents...)
127114
tk.TCPConnect = append(tk.TCPConnect, v.TestKeys.TCPConnect...)
128-
for _, tcpConnect := range v.TestKeys.TCPConnect {
129-
if !tcpConnect.Status.Success {
130-
gatewayConnection := newGatewayConnection(tcpConnect, transportType)
131-
tk.FailingGateways = append(tk.FailingGateways, *gatewayConnection)
132-
}
133-
}
134-
}
135-
136-
func (tk *TestKeys) updateTransportStatus(openvpnGatewayCount, obfs4GatewayCount int) {
137-
failingOpenvpnGateways, failingObfs4Gateways := 0, 0
138-
for _, gw := range tk.FailingGateways {
139-
if gw.TransportType == "openvpn" {
140-
failingOpenvpnGateways++
141-
} else if gw.TransportType == "obfs4" {
142-
failingObfs4Gateways++
143-
}
144-
}
145-
if failingOpenvpnGateways < openvpnGatewayCount {
146-
tk.TransportStatus["openvpn"] = "ok"
147-
} else {
148-
tk.TransportStatus["openvpn"] = "blocked"
149-
}
150-
if failingObfs4Gateways < obfs4GatewayCount {
151-
tk.TransportStatus["obfs4"] = "ok"
152-
} else {
153-
tk.TransportStatus["obfs4"] = "blocked"
154-
}
155-
}
156-
157-
func newGatewayConnection(
158-
tcpConnect tracex.TCPConnectEntry, transportType string) *GatewayConnection {
159-
return &GatewayConnection{
160-
IP: tcpConnect.IP,
161-
Port: tcpConnect.Port,
162-
TransportType: transportType,
163-
}
164115
}
165116

166117
// AddCACertFetchTestKeys adds generic urlgetter.Get() testKeys to riseupvpn specific test keys
@@ -264,27 +215,16 @@ func (m Measurer) Run(ctx context.Context, args *model.ExperimentArgs) error {
264215
testkeys.UpdateProviderAPITestKeys(entry)
265216
}
266217

267-
if testkeys.APIStatus == "blocked" {
268-
for i := range inputs {
269-
inputs[i].Config.Tunnel = "torsf"
270-
}
271-
272-
for entry := range multi.CollectOverall(ctx, inputs, 5, 20, "riseupvpn", callbacks) {
273-
testkeys.UpdateProviderAPITestKeys(entry)
274-
}
218+
if testkeys.APIFailure != nil {
219+
return nil
275220
}
276221

277222
// test gateways now
278-
testkeys.TransportStatus = map[string]string{}
279223
gateways := parseGateways(testkeys)
280224
openvpnEndpoints := generateMultiInputs(gateways, "openvpn")
281225
obfs4Endpoints := generateMultiInputs(gateways, "obfs4")
282226
overallCount := 1 + len(inputs) + len(openvpnEndpoints) + len(obfs4Endpoints)
283227
startCount := 1 + len(inputs)
284-
if testkeys.APIStatus == "blocked" {
285-
startCount += len(inputs)
286-
overallCount += len(inputs)
287-
}
288228

289229
// measure openvpn in parallel
290230
for entry := range multi.CollectOverall(
@@ -303,7 +243,7 @@ func (m Measurer) Run(ctx context.Context, args *model.ExperimentArgs) error {
303243
}
304244

305245
// set transport status based on gateway test results
306-
testkeys.updateTransportStatus(len(openvpnEndpoints), len(obfs4Endpoints))
246+
//testkeys.updateTransportStatus(len(openvpnEndpoints), len(obfs4Endpoints))
307247
return nil
308248
}
309249

@@ -333,8 +273,9 @@ func generateMultiInputs(gateways []GatewayV3, transportType string) []urlgetter
333273
}
334274

335275
func parseGateways(testKeys *TestKeys) []GatewayV3 {
336-
var eipService *EipService = nil
276+
var eipService *EipServiceV3 = nil
337277
var geoService *GeoService = nil
278+
var scrubbedRequests = []model.ArchivalHTTPRequestResult{}
338279
for _, requestEntry := range testKeys.Requests {
339280
if requestEntry.Request.URL == eipServiceURL && requestEntry.Response.Code == 200 {
340281
var err error = nil
@@ -350,12 +291,15 @@ func parseGateways(testKeys *TestKeys) []GatewayV3 {
350291
testKeys.APIFailure = append(testKeys.APIFailure, "invalid_geoservice_response")
351292
}
352293
}
294+
requestEntry.Response.Body = model.ArchivalHTTPBody{Value: "[scrubbed]"}
295+
scrubbedRequests = append(scrubbedRequests, requestEntry)
353296
}
297+
testKeys.Requests = scrubbedRequests
354298
return filterGateways(eipService, geoService)
355299
}
356300

357301
// filterGateways selects a subset of available gateways supporting obfs4
358-
func filterGateways(eipService *EipService, geoService *GeoService) []GatewayV3 {
302+
func filterGateways(eipService *EipServiceV3, geoService *GeoService) []GatewayV3 {
359303
var result []GatewayV3 = nil
360304
if eipService != nil {
361305
locations := getLocationsUnderTest(eipService, geoService)
@@ -375,7 +319,7 @@ func filterGateways(eipService *EipService, geoService *GeoService) []GatewayV3
375319
}
376320

377321
// getLocationsUnderTest parses all gateways supporting obfs4 and returns the two locations having most obfs4 bridges
378-
func getLocationsUnderTest(eipService *EipService, geoService *GeoService) []string {
322+
func getLocationsUnderTest(eipService *EipServiceV3, geoService *GeoService) []string {
379323
var result []string = nil
380324
if eipService != nil {
381325
locationMap := map[string]int{}
@@ -447,8 +391,8 @@ func (geoService *GeoService) isHealthyGateway(gateway GatewayV3) bool {
447391
}
448392

449393
// DecodeEIP3 decodes eip-service.json version 3
450-
func DecodeEIP3(body string) (*EipService, error) {
451-
var eip EipService
394+
func DecodeEIP3(body string) (*EipServiceV3, error) {
395+
var eip EipServiceV3
452396
err := json.Unmarshal([]byte(body), &eip)
453397
if err != nil {
454398
return nil, err
@@ -476,28 +420,11 @@ func NewExperimentMeasurer(config Config) model.ExperimentMeasurer {
476420
// Note that this structure is part of the ABI contract with ooniprobe
477421
// therefore we should be careful when changing it.
478422
type SummaryKeys struct {
479-
APIBlocked bool `json:"api_blocked"`
480-
ValidCACert bool `json:"valid_ca_cert"`
481-
FailingGateways int `json:"failing_gateways"`
482-
TransportStatus map[string]string `json:"transport_status"`
483-
IsAnomaly bool `json:"-"`
423+
IsAnomaly bool `json:"-"`
484424
}
485425

486426
// GetSummaryKeys implements model.ExperimentMeasurer.GetSummaryKeys.
487427
func (m Measurer) GetSummaryKeys(measurement *model.Measurement) (interface{}, error) {
488428
sk := SummaryKeys{IsAnomaly: false}
489-
tk, ok := measurement.TestKeys.(*TestKeys)
490-
if !ok {
491-
return sk, errors.New("invalid test keys type")
492-
}
493-
sk.APIBlocked = tk.APIStatus != "ok"
494-
sk.ValidCACert = tk.CACertStatus
495-
sk.FailingGateways = len(tk.FailingGateways)
496-
sk.TransportStatus = tk.TransportStatus
497-
// Note: the order in the following OR chains matter: TransportStatus
498-
// is nil if APIBlocked
499-
sk.IsAnomaly = (sk.APIBlocked ||
500-
tk.TransportStatus["openvpn"] == "blocked" ||
501-
tk.TransportStatus["obfs4"] == "blocked")
502429
return sk, nil
503430
}

0 commit comments

Comments
 (0)