refactor: move TH structs and definitions to model (#894)

This commit moves the TH structs and definitions to model. We don't want
oohelperd to depend on web_connectivity@v0.4.

Part of https://github.com/ooni/probe/issues/2240
This commit is contained in:
Simone Basso
2022-08-28 20:20:12 +02:00
committed by GitHub
parent 110a11828b
commit bb6563f363
12 changed files with 161 additions and 157 deletions
@@ -9,90 +9,15 @@ import (
"github.com/ooni/probe-cli/v3/internal/netxlite"
)
// TODO(bassosimone): these struct definitions should be moved outside the
// specific implementation of Web Connectivity v0.4.
// ControlRequest is the request that we send to the control
type ControlRequest struct {
HTTPRequest string `json:"http_request"`
HTTPRequestHeaders map[string][]string `json:"http_request_headers"`
TCPConnect []string `json:"tcp_connect"`
}
// ControlTCPConnectResult is the result of the TCP connect
// attempt performed by the control vantage point.
type ControlTCPConnectResult struct {
Status bool `json:"status"`
Failure *string `json:"failure"`
}
// ControlTLSHandshakeResult is the result of the TLS handshake
// attempt performed by the control vantage point.
type ControlTLSHandshakeResult struct {
ServerName string `json:"server_name"`
Status bool `json:"status"`
Failure *string `json:"failure"`
}
// ControlHTTPRequestResult is the result of the HTTP request
// performed by the control vantage point.
type ControlHTTPRequestResult struct {
BodyLength int64 `json:"body_length"`
Failure *string `json:"failure"`
Title string `json:"title"`
Headers map[string]string `json:"headers"`
StatusCode int64 `json:"status_code"`
}
// TODO(bassosimone): ASNs and FillASNs are private implementation details of v0.4
// that are actually ~annoying because we are mixing the data model with fields used
// by just the v0.4 client implementation. We should avoid repeating this mistake
// when implementing v0.5 of the client.
// ControlDNSResult is the result of the DNS lookup
// performed by the control vantage point.
type ControlDNSResult struct {
Failure *string `json:"failure"`
Addrs []string `json:"addrs"`
ASNs []int64 `json:"-"` // not visible from the JSON
}
// ControlIPInfo contains information about IP addresses resolved either
// by the probe or by the TH and processed by the TH.
type ControlIPInfo struct {
// ASN contains the address' AS number.
ASN int64 `json:"asn"`
// Flags contains flags describing this address.
Flags int64 `json:"flags"`
}
const (
// ControlIPInfoFlagResolvedByProbe indicates that the probe has
// resolved this IP address.
ControlIPInfoFlagResolvedByProbe = 1 << iota
// ControlIPInfoFlagResolvedByTH indicates that the test helper
// has resolved this IP address.
ControlIPInfoFlagResolvedByTH
// ControlIPInfoFlagIsBogon indicates that the address is a bogon
ControlIPInfoFlagIsBogon
// ControlIPInfoFlagValidForDomain indicates that an IP address
// is valid for the domain because it works with TLS
ControlIPInfoFlagValidForDomain
// Redirect to types defined inside the model package
type (
ControlRequest = model.THRequest
ControlResponse = model.THResponse
ControlDNSResult = model.THDNSResult
ControlHTTPRequestResult = model.THHTTPRequestResult
ControlTCPConnectResult = model.THTCPConnectResult
)
// ControlResponse is the response from the control service.
type ControlResponse struct {
TCPConnect map[string]ControlTCPConnectResult `json:"tcp_connect"`
TLSHandshake map[string]ControlTLSHandshakeResult `json:"tls_handshake"`
HTTPRequest ControlHTTPRequestResult `json:"http_request"`
DNS ControlDNSResult `json:"dns"`
IPInfo map[string]*ControlIPInfo `json:"ip_info"`
}
// Control performs the control request and returns the response.
func Control(
ctx context.Context, sess model.ExperimentSession,
@@ -110,16 +35,16 @@ func Control(
err = netxlite.NewTopLevelGenericErrWrapper(err)
}
sess.Logger().Infof("control for %s... %+v", creq.HTTPRequest, model.ErrorToStringOrOK(err))
(&out.DNS).FillASNs(sess)
fillASNs(&out.DNS)
return
}
// FillASNs fills the ASNs array of ControlDNSResult. For each Addr inside
// fillASNs fills the ASNs array of ControlDNSResult. For each Addr inside
// of the ControlDNSResult structure, we obtain the corresponding ASN.
//
// This is very useful to know what ASNs were the IP addresses returned by
// the control according to the probe's ASN database.
func (dns *ControlDNSResult) FillASNs(sess model.ExperimentSession) {
func fillASNs(dns *ControlDNSResult) {
dns.ASNs = []int64{}
for _, ip := range dns.Addrs {
asn, _, _ := geoipx.LookupASN(ip)
@@ -1,26 +1,23 @@
package webconnectivity_test
package webconnectivity
import (
"testing"
"github.com/google/go-cmp/cmp"
"github.com/ooni/probe-cli/v3/internal/engine/experiment/webconnectivity"
"github.com/ooni/probe-cli/v3/internal/engine/mockable"
)
func TestFillASNsEmpty(t *testing.T) {
dns := new(webconnectivity.ControlDNSResult)
dns.FillASNs(new(mockable.Session))
dns := new(ControlDNSResult)
fillASNs(dns)
if diff := cmp.Diff(dns.ASNs, []int64{}); diff != "" {
t.Fatal(diff)
}
}
func TestFillASNsSuccess(t *testing.T) {
sess := newsession(t, false)
dns := new(webconnectivity.ControlDNSResult)
dns := new(ControlDNSResult)
dns.Addrs = []string{"8.8.8.8", "1.1.1.1"}
dns.FillASNs(sess)
fillASNs(dns)
if diff := cmp.Diff(dns.ASNs, []int64{15169, 13335}); diff != "" {
t.Fatal(diff)
}
@@ -4,6 +4,7 @@ import (
"net"
"net/url"
"github.com/ooni/probe-cli/v3/internal/model"
"github.com/ooni/probe-cli/v3/internal/netxlite"
)
@@ -14,7 +15,7 @@ type DNSAnalysisResult struct {
}
// DNSNameError is the error returned by the control on NXDOMAIN
const DNSNameError = "dns_name_error"
const DNSNameError = model.THDNSNameError
var (
// DNSConsistent indicates that the measurement and the