Skip to content

Commit dda1339

Browse files
committed
refactor(riseupvpn): handle failing API and simplify test keys
This diff incorporates part of what has been implemented by @cyBerta in #1125 in response to my review. I have omitted the work to use the geo service to figure out which are the correct gateways to test for now, which allows me to simplify the diff that I am committing to the master branch. The spirit of the changes is the following: 1. reduce the test keys to the minimum required by riseup to process the experiment results; 2. skip TLS verification if we cannot fetch the CA certificate and unconditionally fetch information about gateways. The major difference between this diff and the above-mentioned pull request is that I did not feel good to keep the `api_failure` name with a different type, which seems like a very breaking change, and instead I introduced a new type called `api_failures`. This work is part of ooni/probe#1432.
1 parent 85da220 commit dda1339

File tree

2 files changed

+96
-262
lines changed

2 files changed

+96
-262
lines changed

internal/experiment/riseupvpn/riseupvpn.go

+20-70
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"time"
1010

1111
"github.com/ooni/probe-cli/v3/internal/experiment/urlgetter"
12-
"github.com/ooni/probe-cli/v3/internal/legacy/tracex"
1312
"github.com/ooni/probe-cli/v3/internal/model"
1413
"github.com/ooni/probe-cli/v3/internal/netxlite"
1514
)
@@ -63,21 +62,15 @@ type Config struct {
6362
// TestKeys contains riseupvpn test keys.
6463
type TestKeys struct {
6564
urlgetter.TestKeys
66-
APIFailure *string `json:"api_failure"`
67-
APIStatus string `json:"api_status"`
68-
CACertStatus bool `json:"ca_cert_status"`
69-
FailingGateways []GatewayConnection `json:"failing_gateways"`
70-
TransportStatus map[string]string `json:"transport_status"`
65+
APIFailures []string `json:"api_failures"`
66+
CACertStatus bool `json:"ca_cert_status"`
7167
}
7268

7369
// NewTestKeys creates new riseupvpn TestKeys.
7470
func NewTestKeys() *TestKeys {
7571
return &TestKeys{
76-
APIFailure: nil,
77-
APIStatus: "ok",
78-
CACertStatus: true,
79-
FailingGateways: nil,
80-
TransportStatus: nil,
72+
APIFailures: []string{},
73+
CACertStatus: true,
8174
}
8275
}
8376

@@ -88,12 +81,8 @@ func (tk *TestKeys) UpdateProviderAPITestKeys(v urlgetter.MultiOutput) {
8881
tk.Requests = append(tk.Requests, v.TestKeys.Requests...)
8982
tk.TCPConnect = append(tk.TCPConnect, v.TestKeys.TCPConnect...)
9083
tk.TLSHandshakes = append(tk.TLSHandshakes, v.TestKeys.TLSHandshakes...)
91-
if tk.APIStatus != "ok" {
92-
return // we already flipped the state
93-
}
9484
if v.TestKeys.Failure != nil {
95-
tk.APIStatus = "blocked"
96-
tk.APIFailure = v.TestKeys.Failure
85+
tk.APIFailures = append(tk.APIFailures, *v.TestKeys.Failure)
9786
return
9887
}
9988
}
@@ -104,42 +93,6 @@ func (tk *TestKeys) UpdateProviderAPITestKeys(v urlgetter.MultiOutput) {
10493
func (tk *TestKeys) AddGatewayConnectTestKeys(v urlgetter.MultiOutput, transportType string) {
10594
tk.NetworkEvents = append(tk.NetworkEvents, v.TestKeys.NetworkEvents...)
10695
tk.TCPConnect = append(tk.TCPConnect, v.TestKeys.TCPConnect...)
107-
for _, tcpConnect := range v.TestKeys.TCPConnect {
108-
if !tcpConnect.Status.Success {
109-
gatewayConnection := newGatewayConnection(tcpConnect, transportType)
110-
tk.FailingGateways = append(tk.FailingGateways, *gatewayConnection)
111-
}
112-
}
113-
}
114-
115-
func (tk *TestKeys) updateTransportStatus(openvpnGatewayCount, obfs4GatewayCount int) {
116-
failingOpenvpnGateways, failingObfs4Gateways := 0, 0
117-
for _, gw := range tk.FailingGateways {
118-
if gw.TransportType == "openvpn" {
119-
failingOpenvpnGateways++
120-
} else if gw.TransportType == "obfs4" {
121-
failingObfs4Gateways++
122-
}
123-
}
124-
if failingOpenvpnGateways < openvpnGatewayCount {
125-
tk.TransportStatus["openvpn"] = "ok"
126-
} else {
127-
tk.TransportStatus["openvpn"] = "blocked"
128-
}
129-
if failingObfs4Gateways < obfs4GatewayCount {
130-
tk.TransportStatus["obfs4"] = "ok"
131-
} else {
132-
tk.TransportStatus["obfs4"] = "blocked"
133-
}
134-
}
135-
136-
func newGatewayConnection(
137-
tcpConnect tracex.TCPConnectEntry, transportType string) *GatewayConnection {
138-
return &GatewayConnection{
139-
IP: tcpConnect.IP,
140-
Port: tcpConnect.Port,
141-
TransportType: transportType,
142-
}
14396
}
14497

14598
// AddCACertFetchTestKeys adds generic urlgetter.Get() testKeys to riseupvpn specific test keys
@@ -149,11 +102,6 @@ func (tk *TestKeys) AddCACertFetchTestKeys(testKeys urlgetter.TestKeys) {
149102
tk.Requests = append(tk.Requests, testKeys.Requests...)
150103
tk.TCPConnect = append(tk.TCPConnect, testKeys.TCPConnect...)
151104
tk.TLSHandshakes = append(tk.TLSHandshakes, testKeys.TLSHandshakes...)
152-
if testKeys.Failure != nil {
153-
tk.APIStatus = "blocked"
154-
tk.APIFailure = tk.Failure
155-
tk.CACertStatus = false
156-
}
157105
}
158106

159107
// Measurer performs the measurement.
@@ -206,22 +154,24 @@ func (m Measurer) Run(ctx context.Context, args *model.ExperimentArgs) error {
206154
FailOnHTTPError: true,
207155
}},
208156
}
209-
for entry := range multi.CollectOverall(ctx, inputs, 0, 20, "riseupvpn", callbacks) {
157+
158+
nullCallbacks := model.NewPrinterCallbacks(model.DiscardLogger)
159+
noTLSVerify := true
160+
for entry := range multi.CollectOverall(ctx, inputs, 0, 20, "riseupvpn", nullCallbacks) {
210161
tk := entry.TestKeys
211162
testkeys.AddCACertFetchTestKeys(tk)
212163
if tk.Failure != nil {
213-
// TODO(bassosimone,cyberta): should we update the testkeys
214-
// in this case (e.g., APIFailure?)
215-
// See https://github.com/ooni/probe/issues/1432.
216-
return nil
164+
testkeys.CACertStatus = false
165+
testkeys.APIFailures = append(testkeys.APIFailures, *tk.Failure)
166+
continue
217167
}
218168
if ok := certPool.AppendCertsFromPEM([]byte(tk.HTTPResponseBody)); !ok {
219169
testkeys.CACertStatus = false
220-
testkeys.APIStatus = "blocked"
221-
errorValue := "invalid_ca"
222-
testkeys.APIFailure = &errorValue
223-
return nil
170+
testkeys.APIFailures = append(testkeys.APIFailures, "invalid_ca")
171+
continue
224172
}
173+
// We have a CA so we can verify certificates
174+
noTLSVerify = false
225175
}
226176

227177
// Now test the service endpoints using the above-fetched CA
@@ -232,24 +182,26 @@ func (m Measurer) Run(ctx context.Context, args *model.ExperimentArgs) error {
232182
CertPool: certPool,
233183
Method: "GET",
234184
FailOnHTTPError: true,
185+
NoTLSVerify: noTLSVerify,
235186
}},
236187
{Target: eipServiceURL, Config: urlgetter.Config{
237188
CertPool: certPool,
238189
Method: "GET",
239190
FailOnHTTPError: true,
191+
NoTLSVerify: noTLSVerify,
240192
}},
241193
{Target: geoServiceURL, Config: urlgetter.Config{
242194
CertPool: certPool,
243195
Method: "GET",
244196
FailOnHTTPError: true,
197+
NoTLSVerify: noTLSVerify,
245198
}},
246199
}
247-
for entry := range multi.CollectOverall(ctx, inputs, 1, 20, "riseupvpn", callbacks) {
200+
for entry := range multi.CollectOverall(ctx, inputs, 1, 20, "riseupvpn", nullCallbacks) {
248201
testkeys.UpdateProviderAPITestKeys(entry)
249202
}
250203

251204
// test gateways now
252-
testkeys.TransportStatus = map[string]string{}
253205
gateways := parseGateways(testkeys)
254206
openvpnEndpoints := generateMultiInputs(gateways, "openvpn")
255207
obfs4Endpoints := generateMultiInputs(gateways, "obfs4")
@@ -272,8 +224,6 @@ func (m Measurer) Run(ctx context.Context, args *model.ExperimentArgs) error {
272224
testkeys.AddGatewayConnectTestKeys(entry, "obfs4")
273225
}
274226

275-
// set transport status based on gateway test results
276-
testkeys.updateTransportStatus(len(openvpnEndpoints), len(obfs4Endpoints))
277227
return nil
278228
}
279229

0 commit comments

Comments
 (0)