cleanup: remove the original netx implementation (#653)
This commit completely removes the original netx implementation, which was only used by `tor`, since this has changed in https://github.com/ooni/probe-cli/pull/652. The original netx implementation was my first attempt at performing network measurements using Go. It started its life inside of the https://github.com/ooni/netx repository. It was later merged into the https://github.com/ooni/probe-engine repository. It finally ended up into this repository when we merged probe-engine with it. The main issue with the original implementation is that it was a bit too complex and used channels where they were probably not necessary. Because of that, later I introduced a second netx implementation, which currently lives in ./internal/engine/netx. The current netx implementation, the third one, lives in the ./internal/netxlite package. We are currently working to replace the second implementation with the third one, but this is happening at a slow pace. Also, the second implementation does not have big maintenance concerns but it's just a bit too bureaucratic to use since it involves creating lots of `Config` structures. The reference issue is probably https://github.com/ooni/probe/issues/1688, since this diff has been enabled by rewriting Tor to use `measurex` (a library living on top of `netxlite`).
This commit is contained in:
@@ -1,79 +0,0 @@
|
||||
package resolver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/modelx"
|
||||
)
|
||||
|
||||
// EmitterTransport is a RoundTripper that emits events when they occur.
|
||||
type EmitterTransport struct {
|
||||
RoundTripper
|
||||
}
|
||||
|
||||
// RoundTrip implements RoundTripper.RoundTrip
|
||||
func (txp EmitterTransport) RoundTrip(ctx context.Context, querydata []byte) ([]byte, error) {
|
||||
root := modelx.ContextMeasurementRootOrDefault(ctx)
|
||||
root.Handler.OnMeasurement(modelx.Measurement{
|
||||
DNSQuery: &modelx.DNSQueryEvent{
|
||||
Data: querydata,
|
||||
DurationSinceBeginning: time.Since(root.Beginning),
|
||||
},
|
||||
})
|
||||
replydata, err := txp.RoundTripper.RoundTrip(ctx, querydata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
root.Handler.OnMeasurement(modelx.Measurement{
|
||||
DNSReply: &modelx.DNSReplyEvent{
|
||||
Data: replydata,
|
||||
DurationSinceBeginning: time.Since(root.Beginning),
|
||||
},
|
||||
})
|
||||
return replydata, nil
|
||||
}
|
||||
|
||||
// EmitterResolver is a resolver that emits events
|
||||
type EmitterResolver struct {
|
||||
Resolver
|
||||
}
|
||||
|
||||
// LookupHost returns the IP addresses of a host
|
||||
func (r EmitterResolver) LookupHost(ctx context.Context, hostname string) ([]string, error) {
|
||||
var (
|
||||
network string
|
||||
address string
|
||||
)
|
||||
type queryableResolver interface {
|
||||
Transport() RoundTripper
|
||||
}
|
||||
if qr, ok := r.Resolver.(queryableResolver); ok {
|
||||
txp := qr.Transport()
|
||||
network, address = txp.Network(), txp.Address()
|
||||
}
|
||||
root := modelx.ContextMeasurementRootOrDefault(ctx)
|
||||
root.Handler.OnMeasurement(modelx.Measurement{
|
||||
ResolveStart: &modelx.ResolveStartEvent{
|
||||
DurationSinceBeginning: time.Since(root.Beginning),
|
||||
Hostname: hostname,
|
||||
TransportAddress: address,
|
||||
TransportNetwork: network,
|
||||
},
|
||||
})
|
||||
addrs, err := r.Resolver.LookupHost(ctx, hostname)
|
||||
root.Handler.OnMeasurement(modelx.Measurement{
|
||||
ResolveDone: &modelx.ResolveDoneEvent{
|
||||
Addresses: addrs,
|
||||
DurationSinceBeginning: time.Since(root.Beginning),
|
||||
Error: err,
|
||||
Hostname: hostname,
|
||||
TransportAddress: address,
|
||||
TransportNetwork: network,
|
||||
},
|
||||
})
|
||||
return addrs, err
|
||||
}
|
||||
|
||||
var _ RoundTripper = EmitterTransport{}
|
||||
var _ Resolver = EmitterResolver{}
|
||||
@@ -1,194 +0,0 @@
|
||||
package resolver_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/handlers"
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/modelx"
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/netx/resolver"
|
||||
"github.com/ooni/probe-cli/v3/internal/model/mocks"
|
||||
)
|
||||
|
||||
func TestEmitterTransportSuccess(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
handler := &handlers.SavingHandler{}
|
||||
root := &modelx.MeasurementRoot{
|
||||
Beginning: time.Now(),
|
||||
Handler: handler,
|
||||
}
|
||||
ctx = modelx.WithMeasurementRoot(ctx, root)
|
||||
txp := resolver.EmitterTransport{RoundTripper: resolver.FakeTransport{
|
||||
Data: resolver.GenReplySuccess(t, dns.TypeA, "8.8.8.8"),
|
||||
}}
|
||||
e := resolver.MiekgEncoder{}
|
||||
querydata, err := e.Encode("www.google.com", dns.TypeAAAA, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
replydata, err := txp.RoundTrip(ctx, querydata)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
events := handler.Read()
|
||||
if len(events) != 2 {
|
||||
t.Fatal("unexpected number of events")
|
||||
}
|
||||
if events[0].DNSQuery == nil {
|
||||
t.Fatal("missing DNSQuery field")
|
||||
}
|
||||
if !bytes.Equal(events[0].DNSQuery.Data, querydata) {
|
||||
t.Fatal("invalid query data")
|
||||
}
|
||||
if events[0].DNSQuery.DurationSinceBeginning <= 0 {
|
||||
t.Fatal("invalid duration since beginning")
|
||||
}
|
||||
if events[1].DNSReply == nil {
|
||||
t.Fatal("missing DNSReply field")
|
||||
}
|
||||
if !bytes.Equal(events[1].DNSReply.Data, replydata) {
|
||||
t.Fatal("missing reply data")
|
||||
}
|
||||
if events[1].DNSReply.DurationSinceBeginning <= 0 {
|
||||
t.Fatal("invalid duration since beginning")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmitterTransportFailure(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
handler := &handlers.SavingHandler{}
|
||||
root := &modelx.MeasurementRoot{
|
||||
Beginning: time.Now(),
|
||||
Handler: handler,
|
||||
}
|
||||
ctx = modelx.WithMeasurementRoot(ctx, root)
|
||||
mocked := errors.New("mocked error")
|
||||
txp := resolver.EmitterTransport{RoundTripper: resolver.FakeTransport{
|
||||
Err: mocked,
|
||||
}}
|
||||
e := resolver.MiekgEncoder{}
|
||||
querydata, err := e.Encode("www.google.com", dns.TypeAAAA, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
replydata, err := txp.RoundTrip(ctx, querydata)
|
||||
if !errors.Is(err, mocked) {
|
||||
t.Fatal("not the error we expected")
|
||||
}
|
||||
if replydata != nil {
|
||||
t.Fatal("expected nil replydata")
|
||||
}
|
||||
events := handler.Read()
|
||||
if len(events) != 1 {
|
||||
t.Fatal("unexpected number of events")
|
||||
}
|
||||
if events[0].DNSQuery == nil {
|
||||
t.Fatal("missing DNSQuery field")
|
||||
}
|
||||
if !bytes.Equal(events[0].DNSQuery.Data, querydata) {
|
||||
t.Fatal("invalid query data")
|
||||
}
|
||||
if events[0].DNSQuery.DurationSinceBeginning <= 0 {
|
||||
t.Fatal("invalid duration since beginning")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmitterResolverFailure(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
handler := &handlers.SavingHandler{}
|
||||
root := &modelx.MeasurementRoot{
|
||||
Beginning: time.Now(),
|
||||
Handler: handler,
|
||||
}
|
||||
ctx = modelx.WithMeasurementRoot(ctx, root)
|
||||
r := resolver.EmitterResolver{Resolver: resolver.NewSerialResolver(
|
||||
&resolver.DNSOverHTTPS{
|
||||
Client: &mocks.HTTPClient{
|
||||
MockDo: func(req *http.Request) (*http.Response, error) {
|
||||
return nil, io.EOF
|
||||
},
|
||||
},
|
||||
URL: "https://dns.google.com/",
|
||||
},
|
||||
)}
|
||||
replies, err := r.LookupHost(ctx, "www.google.com")
|
||||
if !errors.Is(err, io.EOF) {
|
||||
t.Fatal("not the error we expected")
|
||||
}
|
||||
if replies != nil {
|
||||
t.Fatal("expected nil replies")
|
||||
}
|
||||
events := handler.Read()
|
||||
if len(events) != 2 {
|
||||
t.Fatal("unexpected number of events")
|
||||
}
|
||||
if events[0].ResolveStart == nil {
|
||||
t.Fatal("missing ResolveStart field")
|
||||
}
|
||||
if events[0].ResolveStart.DurationSinceBeginning <= 0 {
|
||||
t.Fatal("invalid duration since beginning")
|
||||
}
|
||||
if events[0].ResolveStart.Hostname != "www.google.com" {
|
||||
t.Fatal("invalid Hostname")
|
||||
}
|
||||
if events[0].ResolveStart.TransportAddress != "https://dns.google.com/" {
|
||||
t.Fatal("invalid TransportAddress")
|
||||
}
|
||||
if events[0].ResolveStart.TransportNetwork != "doh" {
|
||||
t.Fatal("invalid TransportNetwork")
|
||||
}
|
||||
if events[1].ResolveDone == nil {
|
||||
t.Fatal("missing ResolveDone field")
|
||||
}
|
||||
if events[1].ResolveDone.DurationSinceBeginning <= 0 {
|
||||
t.Fatal("invalid duration since beginning")
|
||||
}
|
||||
if events[1].ResolveDone.Error != io.EOF {
|
||||
t.Fatal("invalid Error")
|
||||
}
|
||||
if events[1].ResolveDone.Hostname != "www.google.com" {
|
||||
t.Fatal("invalid Hostname")
|
||||
}
|
||||
if events[1].ResolveDone.TransportAddress != "https://dns.google.com/" {
|
||||
t.Fatal("invalid TransportAddress")
|
||||
}
|
||||
if events[1].ResolveDone.TransportNetwork != "doh" {
|
||||
t.Fatal("invalid TransportNetwork")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmitterResolverSuccess(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
handler := &handlers.SavingHandler{}
|
||||
root := &modelx.MeasurementRoot{
|
||||
Beginning: time.Now(),
|
||||
Handler: handler,
|
||||
}
|
||||
ctx = modelx.WithMeasurementRoot(ctx, root)
|
||||
r := resolver.EmitterResolver{Resolver: resolver.NewFakeResolverWithResult(
|
||||
[]string{"8.8.8.8"},
|
||||
)}
|
||||
replies, err := r.LookupHost(ctx, "dns.google.com")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(replies) != 1 {
|
||||
t.Fatal("expected a single replies")
|
||||
}
|
||||
events := handler.Read()
|
||||
if len(events) != 2 {
|
||||
t.Fatal("unexpected number of events")
|
||||
}
|
||||
if events[1].ResolveDone == nil {
|
||||
t.Fatal("missing ResolveDone field")
|
||||
}
|
||||
if events[1].ResolveDone.Addresses[0] != "8.8.8.8" {
|
||||
t.Fatal("invalid Addresses")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user