diff --git a/internal/experiment/webconnectivitylte/dnsresolvers.go b/internal/experiment/webconnectivitylte/dnsresolvers.go index 812d47142..49a1ad95b 100644 --- a/internal/experiment/webconnectivitylte/dnsresolvers.go +++ b/internal/experiment/webconnectivitylte/dnsresolvers.go @@ -98,9 +98,7 @@ func (t *DNSResolvers) run(parentCtx context.Context) []DNSEntry { whoamiSystemV4Out := make(chan []webconnectivityalgo.DNSWhoamiInfoEntry) whoamiUDPv4Out := make(chan []webconnectivityalgo.DNSWhoamiInfoEntry) - // TODO(bassosimone): add opportunistic support for detecting - // whether DNS queries are answered regardless of dest addr by - // sending a few queries to root DNS servers + // TODO(https://github.com/ooni/probe/issues/1521): detecting DNS interception udpAddress := t.udpAddress() @@ -292,14 +290,12 @@ func (t *DNSResolvers) do53SplitQueries( return } -// TODO(bassosimone): maybe cycle through a bunch of well known addresses - // Returns the UDP resolver we should be using by default. func (t *DNSResolvers) udpAddress() string { if t.UDPAddress != "" { return t.UDPAddress } - return "8.8.4.4:53" + return webconnectivityalgo.RandomDNSOverUDPResolverEndpointIPv4() } // OpportunisticDNSOverHTTPSSingleton is the singleton used to keep diff --git a/internal/experiment/webconnectivitylte/measurer.go b/internal/experiment/webconnectivitylte/measurer.go index bfa7121ae..4368d912e 100644 --- a/internal/experiment/webconnectivitylte/measurer.go +++ b/internal/experiment/webconnectivitylte/measurer.go @@ -132,9 +132,7 @@ func (m *Measurer) Run(ctx context.Context, args *model.ExperimentArgs) error { tk.Finalize(sess.Logger()) // set the test helper we used - // TODO(bassosimone): it may be more informative to know about all the - // test helpers we _tried_ to use, however the data format does not have - // support for that as far as I can tell... + // TODO(https://github.com/ooni/probe/issues/1857): record how we submitted if th := tk.getTestHelper(); th != nil { measurement.TestHelpers = map[string]interface{}{ "backend": th, diff --git a/internal/experiment/webconnectivitylte/summary.go b/internal/experiment/webconnectivitylte/summary.go index 5f63e4493..3d6d8850a 100644 --- a/internal/experiment/webconnectivitylte/summary.go +++ b/internal/experiment/webconnectivitylte/summary.go @@ -13,7 +13,8 @@ type SummaryKeys struct { // MeasurementSummaryKeys implements model.MeasurementSummaryKeysProvider. func (tk *TestKeys) MeasurementSummaryKeys() model.MeasurementSummaryKeys { - // TODO(https://github.com/ooni/probe/issues/1684) + // TODO(https://github.com/ooni/probe/issues/1684): accessible not computed correctly (which + // is an issue that needs some extra investigation to understand how to fix it). sk := &SummaryKeys{} switch v := tk.Blocking.(type) { case string: diff --git a/internal/netemx/address.go b/internal/netemx/address.go index 5a0492ad0..0f0150daa 100644 --- a/internal/netemx/address.go +++ b/internal/netemx/address.go @@ -33,8 +33,11 @@ const AddressThreeThOONIOrg = "209.97.183.73" // AddressTHCloudfront is the IP address for d33d1gs9kpq1c5.cloudfront.net. const AddressTHCloudfront = "52.85.15.84" -// AddressDNSQuad9Net is the IP address for dns.quad9.net. -const AddressDNSQuad9Net = "9.9.9.9" +// AddressDNSQuad9Net9999 is the IP address for dns.quad9.net. +const AddressDNSQuad9Net9999 = "9.9.9.9" + +// AddressDNSQuad9NetOther is the the other IP address for dns.quad9.net. +const AddressDNSQuad9NetOther = "149.112.112.112" // AddressMozillaCloudflareDNSCom is the IP address for mozilla.cloudflare-dns.com. const AddressMozillaCloudflareDNSCom = "172.64.41.4" @@ -83,3 +86,15 @@ const AddressCloudflareCache1 = "104.16.132.229" // AddressHTTPBinCom1 is the first address associated an httpbin.com-like // service which our QA environment exports as httpbin.com. const AddressHTTPBinCom1 = "172.67.144.64" + +// AddressCloudflareDNSCom1111 is the 1.1.1.1 adress. +const AddressCloudflareDNSCom1111 = "1.1.1.1" + +// AddressCloudflareDNSCom1001 is the 1.0.0.1 adress. +const AddressCloudflareDNSCom1001 = "1.0.0.1" + +// AddressOpenDNS222 is the 208.67.222.222 opendns.com address. +const AddressOpenDNS222 = "208.67.222.222" + +// AddressOpenDNS220 is the 208.67.220.220 opendns.com address. +const AddressOpenDNS220 = "208.67.220.220" diff --git a/internal/netemx/example_test.go b/internal/netemx/example_test.go index 317439881..6b285318f 100644 --- a/internal/netemx/example_test.go +++ b/internal/netemx/example_test.go @@ -283,7 +283,7 @@ func Example_dnsOverUDPWithInternetScenario() { net.JoinHostPort(netemx.RootResolverAddress, "53"), net.JoinHostPort(netemx.AddressDNSGoogle8844, "53"), net.JoinHostPort(netemx.AddressDNSGoogle8888, "53"), - net.JoinHostPort(netemx.AddressDNSQuad9Net, "53"), + net.JoinHostPort(netemx.AddressDNSQuad9Net9999, "53"), net.JoinHostPort(netemx.AddressMozillaCloudflareDNSCom, "53"), } diff --git a/internal/netemx/scenario.go b/internal/netemx/scenario.go index d3f45c7ef..39389a175 100644 --- a/internal/netemx/scenario.go +++ b/internal/netemx/scenario.go @@ -129,11 +129,30 @@ var InternetScenario = []*ScenarioDomainAddresses{{ }, { Domains: []string{"dns.quad9.net"}, Addresses: []string{ - AddressDNSQuad9Net, + AddressDNSQuad9Net9999, + AddressDNSQuad9NetOther, }, Role: ScenarioRolePublicDNS, ServerNameMain: "dns.quad9.net", ServerNameExtras: []string{}, +}, { + Domains: []string{"cloudflare-dns.com"}, + Addresses: []string{ + AddressCloudflareDNSCom1001, + AddressCloudflareDNSCom1111, + }, + Role: ScenarioRolePublicDNS, + ServerNameMain: "cloudflare-dns.com", + ServerNameExtras: []string{}, +}, { + Domains: []string{"doh.opendns.com"}, + Addresses: []string{ + AddressOpenDNS220, + AddressOpenDNS222, + }, + Role: ScenarioRolePublicDNS, + ServerNameMain: "doh.opendns.com", + ServerNameExtras: []string{}, }, { Domains: []string{"mozilla.cloudflare-dns.com"}, Addresses: []string{ diff --git a/internal/webconnectivityalgo/dnsoverudp.go b/internal/webconnectivityalgo/dnsoverudp.go new file mode 100644 index 000000000..06bde13d2 --- /dev/null +++ b/internal/webconnectivityalgo/dnsoverudp.go @@ -0,0 +1,31 @@ +package webconnectivityalgo + +import ( + "math/rand" + "net" +) + +// dnsOverUDPResolverAddressIPv4 is the list of DNS-over-UDP IPv4 addresses. +var dnsOverUDPResolverAddressIPv4 = []string{ + // dns.google + "8.8.8.8", + "8.8.4.4", + + // dns.quad9.net + "9.9.9.9", + "149.112.112.112", + + // cloudflare-dns.com + "1.1.1.1", + "1.0.0.1", + + // doh.opendns.com + "208.67.222.222", + "208.67.220.220", +} + +// RandomDNSOverUDPResolverEndpointIPv4 returns a random DNS-over-UDP resolver endpoint using IPv4. +func RandomDNSOverUDPResolverEndpointIPv4() string { + idx := rand.Intn(len(dnsOverUDPResolverAddressIPv4)) + return net.JoinHostPort(dnsOverUDPResolverAddressIPv4[idx], "53") +} diff --git a/internal/webconnectivityalgo/dnsoverudp_test.go b/internal/webconnectivityalgo/dnsoverudp_test.go new file mode 100644 index 000000000..f5c0c0cba --- /dev/null +++ b/internal/webconnectivityalgo/dnsoverudp_test.go @@ -0,0 +1,16 @@ +package webconnectivityalgo + +import "testing" + +func TestRandomDNSOverUDPResolverEndpointIPv4(t *testing.T) { + results := make(map[string]int64) + const maxruns = 1024 + for idx := 0; idx < maxruns; idx++ { + endpoint := RandomDNSOverUDPResolverEndpointIPv4() + results[endpoint]++ + } + t.Log(results) + if len(results) < 3 { + t.Fatal("expected to see at least three different results out of 1024 runs") + } +} diff --git a/internal/x/dslx/qa_test.go b/internal/x/dslx/qa_test.go index 56398e616..fe5609dcf 100644 --- a/internal/x/dslx/qa_test.go +++ b/internal/x/dslx/qa_test.go @@ -91,7 +91,7 @@ func TestDNSLookupQA(t *testing.T) { // create DNS lookup function function := dslx.DNSLookupParallel( dslx.DNSLookupGetaddrinfo(rt), - dslx.DNSLookupUDP(rt, net.JoinHostPort(netemx.AddressDNSQuad9Net, "53")), + dslx.DNSLookupUDP(rt, net.JoinHostPort(netemx.AddressDNSQuad9Net9999, "53")), ) // create context