package webconnectivity import ( "context" "fmt" "net/url" "sort" "time" "github.com/ooni/probe-cli/v3/internal/engine/experiment/urlgetter" "github.com/ooni/probe-cli/v3/internal/model" ) // DNSLookupConfig contains settings for the DNS lookup. type DNSLookupConfig struct { Begin time.Time Session model.ExperimentSession URL *url.URL } // DNSLookupResult contains the result of the DNS lookup. type DNSLookupResult struct { Addrs map[string]int64 Failure *string TestKeys urlgetter.TestKeys } // DNSLookup performs the DNS lookup part of Web Connectivity. func DNSLookup(ctx context.Context, config DNSLookupConfig) (out DNSLookupResult) { target := fmt.Sprintf("dnslookup://%s", config.URL.Hostname()) config.Session.Logger().Infof("%s...", target) result, err := urlgetter.Getter{ Begin: config.Begin, Session: config.Session, Target: target}.Get(ctx) out.Addrs = make(map[string]int64) for _, query := range result.Queries { for _, answer := range query.Answers { if answer.IPv4 != "" { out.Addrs[answer.IPv4] = answer.ASN continue } if answer.IPv6 != "" { out.Addrs[answer.IPv6] = answer.ASN continue } } } config.Session.Logger().Infof("%s... %+v", target, model.ErrorToStringOrOK(err)) out.Failure = result.Failure out.TestKeys = result return } // Addresses returns the IP addresses in the DNSLookupResult func (r DNSLookupResult) Addresses() (out []string) { out = []string{} for addr := range r.Addrs { out = append(out, addr) } sort.Slice(out, func(i, j int) bool { return out[i] < out[j] }) return }