diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index db967ba5..dea44859 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -13,9 +13,9 @@ jobs: os: [ubuntu-latest, windows-latest, macOS-latest] steps: - name: Set up Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v3 with: - go-version: 1.17 + go-version: 1.18 - name: Check out code uses: actions/checkout@v3 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 7c34372a..2bbccfd4 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -28,12 +28,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 with: languages: ${{ matrix.language }} - name: Autobuild - uses: github/codeql-action/autobuild@v1 + uses: github/codeql-action/autobuild@v2 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 \ No newline at end of file + uses: github/codeql-action/analyze@v2 \ No newline at end of file diff --git a/.github/workflows/dockerhub-push.yml b/.github/workflows/dockerhub-push.yml index e28ea58d..22acd6f2 100644 --- a/.github/workflows/dockerhub-push.yml +++ b/.github/workflows/dockerhub-push.yml @@ -20,19 +20,19 @@ jobs: echo "::set-output name=tag::$(curl --silent "https://api.github.com/repos/projectdiscovery/dnsx/releases/latest" | jq -r .tag_name)" - name: Set up QEMU - uses: docker/setup-qemu-action@v1 + uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Login to DockerHub - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} - name: Build and push - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v3 with: context: . platforms: linux/amd64,linux/arm64,linux/arm diff --git a/.github/workflows/functional-test.yml b/.github/workflows/functional-test.yml index bf27bd58..5bf2c369 100644 --- a/.github/workflows/functional-test.yml +++ b/.github/workflows/functional-test.yml @@ -14,9 +14,9 @@ jobs: os: [ubuntu-latest, windows-latest, macOS-latest] steps: - name: Set up Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v3 with: - go-version: 1.17 + go-version: 1.18 - name: Check out code uses: actions/checkout@v3 diff --git a/.github/workflows/lint-test.yml b/.github/workflows/lint-test.yml index e9621098..97b87888 100644 --- a/.github/workflows/lint-test.yml +++ b/.github/workflows/lint-test.yml @@ -12,11 +12,11 @@ jobs: - name: Checkout code uses: actions/checkout@v3 - name: "Set up Go" - uses: actions/setup-go@v2 + uses: actions/setup-go@v3 with: - go-version: 1.17 + go-version: 1.18 - name: Run golangci-lint - uses: golangci/golangci-lint-action@v3.1.0 + uses: golangci/golangci-lint-action@v3.2.0 with: version: latest args: --timeout 5m diff --git a/.github/workflows/release-binary.yml b/.github/workflows/release-binary.yml index 2872ad87..c7dfd79a 100644 --- a/.github/workflows/release-binary.yml +++ b/.github/workflows/release-binary.yml @@ -15,12 +15,12 @@ jobs: fetch-depth: 0 - name: "Set up Go" - uses: actions/setup-go@v2 + uses: actions/setup-go@v3 with: - go-version: 1.17 + go-version: 1.18 - name: "Create release on GitHub" - uses: goreleaser/goreleaser-action@v2 + uses: goreleaser/goreleaser-action@v3 with: args: "release --rm-dist" version: latest diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index 12299306..e0df6963 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -18,9 +18,9 @@ jobs: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - name: "Set up Go" - uses: actions/setup-go@v2 + uses: actions/setup-go@v3 with: - go-version: 1.17 + go-version: 1.18 - name: Run unit Tests run: | diff --git a/.gitignore b/.gitignore index 2f2df1a2..4ea055d9 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ cmd/functional-test/functional-test cmd/functional-test/dnsx cmd/functional-test/log.txt cmd/functional-test/*.cfg +.vscode/ diff --git a/Dockerfile b/Dockerfile index b8b9264c..207cdaa4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,8 @@ -FROM golang:1.17.8-alpine3.14 AS build-env +FROM golang:1.18.2-alpine3.14 AS build-env RUN apk add --no-cache build-base RUN go install -v github.com/projectdiscovery/dnsx/cmd/dnsx@latest -FROM alpine:3.15.0 +FROM alpine:3.16.2 RUN apk add --no-cache bind-tools ca-certificates COPY --from=build-env /go/bin/dnsx /usr/local/bin/dnsx ENTRYPOINT ["dnsx"] diff --git a/Makefile b/Makefile index 97ca109e..d0021f08 100644 --- a/Makefile +++ b/Makefile @@ -3,12 +3,17 @@ GOCMD=go GOBUILD=$(GOCMD) build GOMOD=$(GOCMD) mod GOTEST=$(GOCMD) test -GOGET=$(GOCMD) get - +GOFLAGS := -v +LDFLAGS := -s -w + +ifneq ($(shell go env GOOS),darwin) +LDFLAGS := -extldflags "-static" +endif + all: build build: - $(GOBUILD) -v -ldflags="-extldflags=-static" -o "dnsx" cmd/dnsx/dnsx.go + $(GOBUILD) $(GOFLAGS) -ldflags '$(LDFLAGS)' -o "dnsx" cmd/dnsx/dnsx.go test: - $(GOTEST) -v ./... + $(GOTEST) $(GOFLAGS) ./... tidy: - $(GOMOD) tidy + $(GOMOD) tidy diff --git a/README.md b/README.md index e6909711..0d103f06 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@

- dnsx + dnsx

-

Fast and multi-purpose DNS toolkit allow to run multiple DNS queries.

+

A fast and multi-purpose DNS toolkit designed for running DNS queries

@@ -17,7 +17,7 @@ FeaturesInstallationUsage • - Running dnsx • + Running `dnsx`WildcardNotesJoin Discord @@ -27,7 +27,7 @@ --- -**dnsx** is a fast and multi-purpose DNS toolkit allow to run multiple probes using [retryabledns](https://github.com/projectdiscovery/retryabledns) library, that allows you to perform multiple DNS queries of your choice with a list of user supplied resolvers, additionally supports DNS wildcard filtering like [shuffledns](https://github.com/projectdiscovery/shuffledns). +`dnsx` is a fast and multi-purpose DNS toolkit designed for running various probes through the [retryabledns](https://github.com/projectdiscovery/retryabledns) library. It supports multiple DNS queries, user supplied resolvers, DNS wildcard filtering like [shuffledns](https://github.com/projectdiscovery/shuffledns) etc. # Features @@ -49,7 +49,7 @@ # Installation Instructions -dnsx requires **go1.17** to install successfully. Run the following command to get the repo - +`dnsx` requires **go1.17** to install successfully. Run the following command to install the latest version: ```sh go install -v github.com/projectdiscovery/dnsx/cmd/dnsx@latest @@ -78,14 +78,19 @@ QUERY: -ptr query PTR record -mx query MX record -soa query SOA record + -axfr query AXFR + -caa query CAA record -FILTERS: - -resp display dns response - -resp-only display dns response only - -rcode, -rc string filter result by dns status code (eg. -rcode noerror,servfail,refused) +FILTER: + -re, -resp display dns response + -ro, -resp-only display dns response only + -rc, -rcode string filter result by dns status code (eg. -rcode noerror,servfail,refused) + +PROBE: + -cdn display cdn name RATE-LIMIT: - -t, -c int number of concurrent threads to use (default 100) + -t, -threads int number of concurrent threads to use (default 100) -rl, -rate-limit int number of dns request/second to make (disabled as default) (default -1) OUTPUT: @@ -93,19 +98,20 @@ OUTPUT: -json write output in JSONL(ines) format DEBUG: - -silent display only results in the output - -v, -verbose display verbose output - -raw, -debug display raw dns response - -stats display stats of the running scan - -version display version of dnsx + -hc, -health-check run diagnostic check up + -silent display only results in the output + -v, -verbose display verbose output + -raw, -debug display raw dns response + -stats display stats of the running scan + -version display version of dnsx OPTIMIZATION: - -retry int number of dns retries to make (default 2) + -retry int number of dns attempts to make (must be at least 1) (default 2) -hf, -hostsfile use system host file -trace perform dns tracing -trace-max-recursion int Max recursion for dns trace (default 32767) - -flush-interval int flush interval of output file (default 10) -resume resume existing scan + -stream stream mode (wordlist, wildcard, stats and stop/resume will be disabled) CONFIGURATIONS: -r, -resolver string list of resolvers to use (file or comma separated) @@ -117,7 +123,7 @@ CONFIGURATIONS: ### DNS Resolving -**dnsx** can be used to filter active hostnames from the list of passive subdomains obtained from various sources, for example:- +Filter active hostnames from the list of passive subdomains, obtained from various sources: ```console subfinder -silent -d hackerone.com | dnsx -silent @@ -135,10 +141,10 @@ events.hackerone.com support.hackerone.com ``` -**dnsx** can be used to print **A** records for the given list of subdomains, for example:- +Print **A** records for the given list of subdomains: ```console -subfinder -silent -d hackerone.com | dnsx -silent -a -cname -resp +subfinder -silent -d hackerone.com | dnsx -silent -a -resp www.hackerone.com [104.16.100.52] www.hackerone.com [104.16.99.52] @@ -150,41 +156,33 @@ mta-sts.forwarding.hackerone.com [185.199.108.153] mta-sts.forwarding.hackerone.com [185.199.109.153] mta-sts.forwarding.hackerone.com [185.199.110.153] mta-sts.forwarding.hackerone.com [185.199.111.153] -mta-sts.forwarding.hackerone.com [hacker0x01.github.io] a.ns.hackerone.com [162.159.0.31] resources.hackerone.com [52.60.160.16] resources.hackerone.com [3.98.63.202] resources.hackerone.com [52.60.165.183] resources.hackerone.com [read.uberflip.com] -resources.hackerone.com [nlb-ext-traefik-ca-central-1-d39d611502919b07.elb.ca-central-1.amazonaws.com] mta-sts.hackerone.com [185.199.110.153] mta-sts.hackerone.com [185.199.111.153] mta-sts.hackerone.com [185.199.109.153] mta-sts.hackerone.com [185.199.108.153] -mta-sts.hackerone.com [hacker0x01.github.io] gslink.hackerone.com [13.35.210.17] gslink.hackerone.com [13.35.210.38] gslink.hackerone.com [13.35.210.83] gslink.hackerone.com [13.35.210.19] -gslink.hackerone.com [d3rxkn2g2bbsjp.cloudfront.net] b.ns.hackerone.com [162.159.1.31] docs.hackerone.com [185.199.109.153] docs.hackerone.com [185.199.110.153] docs.hackerone.com [185.199.111.153] docs.hackerone.com [185.199.108.153] -docs.hackerone.com [hacker0x01.github.io] support.hackerone.com [104.16.51.111] support.hackerone.com [104.16.53.111] -support.hackerone.com [hackerone.zendesk.com] mta-sts.managed.hackerone.com [185.199.108.153] mta-sts.managed.hackerone.com [185.199.109.153] mta-sts.managed.hackerone.com [185.199.110.153] mta-sts.managed.hackerone.com [185.199.111.153] -mta-sts.managed.hackerone.com [hacker0x01.github.io] ``` - -**dnsx** can be used to extract **A** records for the given list of subdomains, for example:- +Extract **A** records for the given list of subdomains: ```console subfinder -silent -d hackerone.com | dnsx -silent -a -resp-only @@ -208,7 +206,7 @@ subfinder -silent -d hackerone.com | dnsx -silent -a -resp-only 185.199.111.153 ``` -**dnsx** can be used to extract **CNAME** records for the given list of subdomains, for example:- +Extract **CNAME** records for the given list of subdomains: ```console subfinder -silent -d hackerone.com | dnsx -silent -cname -resp @@ -220,7 +218,7 @@ mta-sts.forwarding.hackerone.com [hacker0x01.github.io] events.hackerone.com [whitelabel.bigmarker.com] ``` -**dnsx** can be used to probe by given [dns status code](https://github.com/projectdiscovery/dnsx/wiki/RCODE-ID-VALUE-Mapping) on given list of sub(domains), for example:- +Probe using [dns status code](https://github.com/projectdiscovery/dnsx/wiki/RCODE-ID-VALUE-Mapping) on given list of (sub)domains: ```console subfinder -silent -d hackerone.com | dnsx -silent -rcode noerror,servfail,refused @@ -236,7 +234,7 @@ mta-sts.forwarding.hackerone.com [NOERROR] docs.hackerone.com [NOERROR] ``` -**dnsx** can be used to extract subdomains from given network range using `PTR` query, for example:- +Extract subdomains from given network range using `PTR` query: ```console echo 173.0.84.0/24 | dnsx -silent -resp-only -ptr @@ -258,7 +256,7 @@ fpdbs.paypal.com ### DNS Bruteforce -**dnsx** can be used to bruteforce subdomains for given domain or list of domains using `d` and `w` flag. +Bruteforce subdomains for given domain or list of domains using `d` and `w` flag: ```console dnsx -silent -d facebook.com -w dns_worldlist.txt @@ -279,7 +277,7 @@ careers.facebook.com code.facebook.com ``` -**dnsx** can be used to bruteforce targeted subdomain using single or multiple keyword input, as `d` or `w` flag supports file or comma separated keyword inputs. +Bruteforce targeted subdomain using single or multiple keyword input, as `d` or `w` flag supports file or comma separated keyword inputs: ```console dnsx -silent -d domains.txt -w jira,grafana,jenkins @@ -301,7 +299,7 @@ jira.atlassian.net jira.atlassian.com ``` -**dnsx** support **stdin** input for all the input flags (`list`,`domain`,`wordlist`), as default `l` flag is supported for `stdin`, other input flag can be used by specifying the flag input with dash (`-`). +Values are accepted from **stdin** for all the input types (`-list`, `-domain`, `-wordlist`). The `-list` flag defaults to `stdin`, but the same can be achieved for other input types by adding a `-` (dash) as parameter: ```console cat domains.txt | dnsx -silent -w jira,grafana,jenkins -d - @@ -325,19 +323,71 @@ jira.atlassian.com ### Wildcard filtering -A special feature of **dnsx** is its ability to handle **multi-level DNS based wildcards** and do it so with very less number of DNS requests. Sometimes all the subdomains will resolve which will lead to lots of garbage in the results. The way **dnsx** handles this is it will keep track of how many subdomains point to an IP and if the count of the Subdomains increase beyond a certain small threshold, it will check for wildcard on all the levels of the hosts for that IP iteratively. +A special feature of `dnsx` is its ability to handle **multi-level DNS based wildcards**, and do it so with a very reduced number of DNS requests. Sometimes all the subdomains will resolve, which leads to lots of garbage in the output. The way `dnsx` handles this is by keeping track of how many subdomains point to an IP and if the count of the subdomains increase beyond a certain threshold, it will check for wildcards on all the levels of the hosts for that IP iteratively. ```console dnsx -l subdomain_list.txt -wd airbnb.com -o output.txt ``` +--------- + +### Dnsx as a library + +It's possible to use the library directly in your golang programs. The following code snippets is an example of use in golang programs. Please refer to [here](https://pkg.go.dev/github.com/projectdiscovery/dnsx@v1.1.0/libs/dnsx) for detailed package configuration and usage. + +```go +package main + +import ( + "fmt" + + "github.com/projectdiscovery/dnsx/libs/dnsx" +) + +func main() { + // Create DNS Resolver with default options + dnsClient, err := dnsx.New(dnsx.DefaultOptions) + if err != nil { + fmt.Printf("err: %v\n", err) + return + } + + // DNS A question and returns corresponding IPs + result, err := dnsClient.Lookup("hackerone.com") + if err != nil { + fmt.Printf("err: %v\n", err) + return + } + for idx, msg := range result { + fmt.Printf("%d: %s\n", idx+1, msg) + } + + // Query + rawResp, err := dnsClient.QueryOne("hackerone.com") + if err != nil { + fmt.Printf("err: %v\n", err) + return + } + fmt.Printf("rawResp: %v\n", rawResp) + + jsonStr, err := rawResp.JSON() + if err != nil { + fmt.Printf("err: %v\n", err) + return + } + fmt.Println(jsonStr) + + return +} +``` + # 📋 Notes -- As default, **dnsx** checks for **A** record. -- As default dnsx uses Google, Cloudflare, Quad9 [resolver](https://github.com/projectdiscovery/dnsx/blob/43af78839e237ea8cbafe571df1ab0d6cbe7f445/libs/dnsx/dnsx.go#L31). -- Custom resolver list can be used using `r` flag. +- As default, `dnsx` checks for **A** record. +- As default `dnsx` uses Google, Cloudflare, Quad9 [resolver](https://github.com/projectdiscovery/dnsx/blob/43af78839e237ea8cbafe571df1ab0d6cbe7f445/libs/dnsx/dnsx.go#L31). +- Custom resolver list can be loaded using the `r` flag. - Domain name (`wd`) input is mandatory for wildcard elimination. - DNS record flag can not be used when using wildcard filtering. -- DNS resolution (`l`) and DNS Bruteforcing (`w`) can't be used together. +- DNS resolution (`l`) and DNS brute-forcing (`w`) can't be used together. -dnsx is made with 🖤 by the [projectdiscovery](https://projectdiscovery.io) team. +`dnsx` is made with 🖤 by the [projectdiscovery](https://projectdiscovery.io) team. diff --git a/go.mod b/go.mod index 60c5d26e..9cf9f042 100644 --- a/go.mod +++ b/go.mod @@ -4,18 +4,19 @@ go 1.17 require ( github.com/logrusorgru/aurora v2.0.3+incompatible - github.com/miekg/dns v1.1.46 + github.com/miekg/dns v1.1.50 github.com/pkg/errors v0.9.1 + github.com/projectdiscovery/cdncheck v0.0.3 github.com/projectdiscovery/clistats v0.0.8 - github.com/projectdiscovery/fileutil v0.0.0-20220308101036-16c79af1cf5d + github.com/projectdiscovery/fileutil v0.0.1 github.com/projectdiscovery/goconfig v0.0.0-20210804090219-f893ccd0c69c - github.com/projectdiscovery/goflags v0.0.7 + github.com/projectdiscovery/goflags v0.1.0 github.com/projectdiscovery/gologger v1.1.4 github.com/projectdiscovery/hmap v0.0.2 - github.com/projectdiscovery/iputil v0.0.0-20210804143329-3a30fcde43f3 - github.com/projectdiscovery/mapcidr v0.0.8 - github.com/projectdiscovery/retryabledns v1.0.13 - github.com/rs/xid v1.3.0 + github.com/projectdiscovery/iputil v0.0.0-20220712175312-b9406f31cdd8 + github.com/projectdiscovery/mapcidr v1.0.1 + github.com/projectdiscovery/retryabledns v1.0.15 + github.com/rs/xid v1.4.0 go.uber.org/ratelimit v0.2.0 ) @@ -25,6 +26,7 @@ require ( github.com/akrylysov/pogreb v0.10.1 // indirect github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect + github.com/aymerick/douceur v0.2.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.1.1 // indirect github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 // indirect @@ -36,34 +38,37 @@ require ( github.com/dgraph-io/badger v1.6.2 // indirect github.com/dgraph-io/ristretto v0.0.3 // indirect github.com/dustin/go-humanize v1.0.0 // indirect - github.com/gogo/protobuf v1.3.1 // indirect + github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/golang/snappy v0.0.4 // indirect + github.com/gorilla/css v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/karrick/godirwalk v1.16.1 // indirect github.com/klauspost/compress v1.11.7 // indirect github.com/kr/pretty v0.2.1 // indirect github.com/kr/text v0.2.0 // indirect + github.com/microcosm-cc/bluemonday v1.0.20 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/onsi/ginkgo v1.16.4 // indirect github.com/onsi/gomega v1.16.0 // indirect - github.com/projectdiscovery/blackrock v0.0.0-20210903102120-5a9d2412d21d // indirect + github.com/projectdiscovery/blackrock v0.0.0-20220628111055-35616c71b2dc // indirect github.com/projectdiscovery/reflectutil v0.0.0-20210804085554-4d90952bf92f // indirect github.com/projectdiscovery/retryablehttp-go v1.0.2 // indirect - github.com/projectdiscovery/stringsutil v0.0.0-20220208075244-7c05502ca8e9 // indirect + github.com/projectdiscovery/sliceutil v0.0.0-20220625085859-c3a4ecb669f4 // indirect + github.com/projectdiscovery/stringsutil v0.0.1 // indirect + github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca // indirect github.com/syndtr/goleveldb v1.0.0 // indirect + github.com/yl2chen/cidranger v1.0.2 // indirect go.etcd.io/bbolt v1.3.5 // indirect go.uber.org/atomic v1.9.0 // indirect + go.uber.org/multierr v1.8.0 // indirect golang.org/x/exp v0.0.0-20200513190911-00229845015e // indirect - golang.org/x/mod v0.5.1 // indirect - golang.org/x/net v0.0.0-20220121210141-e204ce36a2ba // indirect - golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect + golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect + golang.org/x/net v0.0.0-20220927171203-f486391704dc // indirect + golang.org/x/sys v0.0.0-20220731174439-a90be440212d // indirect golang.org/x/text v0.3.7 // indirect - golang.org/x/tools v0.1.9 // indirect - golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + golang.org/x/tools v0.1.12 // indirect google.golang.org/protobuf v1.26.0 // indirect gopkg.in/ini.v1 v1.66.3 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index d5ebbd3f..e7757a12 100644 --- a/go.sum +++ b/go.sum @@ -23,6 +23,8 @@ github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgp github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= +github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= @@ -93,8 +95,9 @@ github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6Wezm github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -125,6 +128,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= +github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= @@ -146,13 +151,13 @@ github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0b github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= -github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw= github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= @@ -181,8 +186,12 @@ github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpe github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= -github.com/miekg/dns v1.1.46 h1:uzwpxRtSVxtcIZmz/4Uz6/Rn7G11DvsaslXoy5LxQio= -github.com/miekg/dns v1.1.46/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= +github.com/microcosm-cc/bluemonday v1.0.18/go.mod h1:Z0r70sCuXHig8YpBzCc5eGHAap2K7e/u082ZUpDRRqM= +github.com/microcosm-cc/bluemonday v1.0.19/go.mod h1:QNzV2UbLK2/53oIIwTOyLUSABMkjZ4tqiyC1g/DyqxE= +github.com/microcosm-cc/bluemonday v1.0.20 h1:flpzsq4KU3QIYAYGV/szUat7H+GPOXR0B2JU5A1Wp8Y= +github.com/microcosm-cc/bluemonday v1.0.20/go.mod h1:yfBmMi8mxvaZut3Yytv+jTXRY8mxyjJ0/kQBTElld50= +github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= +github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -221,17 +230,23 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/projectdiscovery/blackrock v0.0.0-20210415162320-b38689ae3a2e/go.mod h1:/IsapnEYiWG+yEDPXp0e8NWj3npzB9Ccy9lXEUJwMZs= -github.com/projectdiscovery/blackrock v0.0.0-20210903102120-5a9d2412d21d h1:1Q94movG4VMVo+qf781ttXXt2bxBOIGMenmuCAJDLfE= -github.com/projectdiscovery/blackrock v0.0.0-20210903102120-5a9d2412d21d/go.mod h1:/IsapnEYiWG+yEDPXp0e8NWj3npzB9Ccy9lXEUJwMZs= +github.com/projectdiscovery/blackrock v0.0.0-20220628111055-35616c71b2dc h1:jqZK68yPOnNNRmwuXqytl+T9EbwneEUCvMDRjLe0J04= +github.com/projectdiscovery/blackrock v0.0.0-20220628111055-35616c71b2dc/go.mod h1:5tNGQP9kOfW+X5+40pZP8aqPYLHs45nJkFaSHLxdeH8= +github.com/projectdiscovery/cdncheck v0.0.3 h1:li2/rUJmhVXSqRFyhJMqi6pdBX6ZxMnwzBfE0Kifj/g= +github.com/projectdiscovery/cdncheck v0.0.3/go.mod h1:EevMeCG1ogBoUJYaa0Mv9R1VUboDm/DiynId7DboKy0= github.com/projectdiscovery/clistats v0.0.8 h1:tjmWb15mqsPf/yrQXVHLe2ThZX/5+mgKSfZBKWWLh20= github.com/projectdiscovery/clistats v0.0.8/go.mod h1:lV6jUHAv2bYWqrQstqW8iVIydKJhWlVaLl3Xo9ioVGg= -github.com/projectdiscovery/fileutil v0.0.0-20210926202739-6050d0acf73c/go.mod h1:U+QCpQnX8o2N2w0VUGyAzjM3yBAe4BKedVElxiImsx0= -github.com/projectdiscovery/fileutil v0.0.0-20220308101036-16c79af1cf5d h1:r3W250mWWVgWdztfX2NKbXwlzzxA+1dd3i8K8CQEiiw= +github.com/projectdiscovery/fileutil v0.0.0-20210928100737-cab279c5d4b5/go.mod h1:U+QCpQnX8o2N2w0VUGyAzjM3yBAe4BKedVElxiImsx0= github.com/projectdiscovery/fileutil v0.0.0-20220308101036-16c79af1cf5d/go.mod h1:Pm0f+MWgDFMSSI9NBedNh48LyYPs8gD3Jd8DXGmp4aQ= +github.com/projectdiscovery/fileutil v0.0.0-20220609150212-453ac591c36c/go.mod h1:g8wsrb0S5NtEN0JgVyyPeb3FQdArx+UMESmFX94bcGY= +github.com/projectdiscovery/fileutil v0.0.0-20220705195237-01becc2a8963/go.mod h1:DaY7wmLPMleyHDCD/14YApPCDtrARY4J8Eny2ZGsG/g= +github.com/projectdiscovery/fileutil v0.0.1 h1:3K3UqCDOan3LsvWhV0nyvVuMWSwCloNPUJIGcXsi1os= +github.com/projectdiscovery/fileutil v0.0.1/go.mod h1:Oo6ZEvXmQz/xPF0YukzmwpdW2LYinWCSEmzZOQsJCLg= github.com/projectdiscovery/goconfig v0.0.0-20210804090219-f893ccd0c69c h1:1XRSp+44bhWudAWz+2+wHYJBHvDfE8mk9uWpzX+DU9k= github.com/projectdiscovery/goconfig v0.0.0-20210804090219-f893ccd0c69c/go.mod h1:mBv7GRD5n3WNbFE9blG8ynzXTM5eh9MmwaK6EOyn6Pk= -github.com/projectdiscovery/goflags v0.0.7 h1:aykmRkrOgDyRwcvGrK3qp+9aqcjGfAMs/+LtRmtyxwk= -github.com/projectdiscovery/goflags v0.0.7/go.mod h1:Jjwsf4eEBPXDSQI2Y+6fd3dBumJv/J1U0nmpM+hy2YY= +github.com/projectdiscovery/goflags v0.0.8/go.mod h1:GDSkWyXa6kfQjpJu10SO64DN8lXuKXVENlBMk8N7H80= +github.com/projectdiscovery/goflags v0.1.0 h1:Z7sUVK8wgH6aGJWinmGQEtsn+GNf/0RQ+z1wQcpCeeA= +github.com/projectdiscovery/goflags v0.1.0/go.mod h1:/YBPA+1igSkQbwD7a91o0HUIwMDlsmQDRZL2oSYSyEQ= github.com/projectdiscovery/gologger v1.0.1/go.mod h1:Ok+axMqK53bWNwDSU1nTNwITLYMXMdZtRc8/y1c7sWE= github.com/projectdiscovery/gologger v1.1.4 h1:qWxGUq7ukHWT849uGPkagPKF3yBPYAsTtMKunQ8O2VI= github.com/projectdiscovery/gologger v1.1.4/go.mod h1:Bhb6Bdx2PV1nMaFLoXNBmHIU85iROS9y1tBuv7T5pMY= @@ -239,27 +254,34 @@ github.com/projectdiscovery/hmap v0.0.1/go.mod h1:VDEfgzkKQdq7iGTKz8Ooul0NuYHQ8q github.com/projectdiscovery/hmap v0.0.2 h1:fe3k0b6tj95mn9a1phD3JXvAAOmmWAh/Upg1Bf0Tfos= github.com/projectdiscovery/hmap v0.0.2/go.mod h1:YU3TeNTDmLW2dtb4LvuEtDsPTsQ06XMnmOeD3KOuU6c= github.com/projectdiscovery/ipranger v0.0.2/go.mod h1:kcAIk/lo5rW+IzUrFkeYyXnFJ+dKwYooEOHGVPP/RWE= -github.com/projectdiscovery/iputil v0.0.0-20210804143329-3a30fcde43f3 h1:VZ9H51A7tI7R/9I5W5l960Nkq7eMJqGd3y1wsuwzdjE= -github.com/projectdiscovery/iputil v0.0.0-20210804143329-3a30fcde43f3/go.mod h1:blmYJkS8lSrrx3QcmcgS2tZIxlojeVmoGeA9twslCBU= +github.com/projectdiscovery/iputil v0.0.0-20220712175312-b9406f31cdd8 h1:HRqev12wKvcwK1fe4pSlMfQdPHo9LfTxuFeRN4f3tS4= +github.com/projectdiscovery/iputil v0.0.0-20220712175312-b9406f31cdd8/go.mod h1:vHRC+9exsfSbEngMKDl0xiWqkxlLk3lHQZpbS2yFT8U= github.com/projectdiscovery/mapcidr v0.0.4/go.mod h1:ALOIj6ptkWujNoX8RdQwB2mZ+kAmKuLJBq9T5gR5wG0= -github.com/projectdiscovery/mapcidr v0.0.7/go.mod h1:7CzdUdjuLVI0s33dQ33lWgjg3vPuLFw2rQzZ0RxkT00= -github.com/projectdiscovery/mapcidr v0.0.8 h1:16U05F2x3o/jSTsxSCY2hCuCs9xOSwVxjo2zlsL4L4E= -github.com/projectdiscovery/mapcidr v0.0.8/go.mod h1:7CzdUdjuLVI0s33dQ33lWgjg3vPuLFw2rQzZ0RxkT00= +github.com/projectdiscovery/mapcidr v1.0.1 h1:eaLBRrImwlYXv8vbXTwR4sxoQqIxR3Y5k/Sd7HhTIII= +github.com/projectdiscovery/mapcidr v1.0.1/go.mod h1:/qxlpxXZQFFjHynSc9u5O0kUPzH46VskECiwLiz7/vw= github.com/projectdiscovery/reflectutil v0.0.0-20210804085554-4d90952bf92f h1:HR3R/nhELwLXufUlO1ZkKVqrZl4lN1cWFBdN8RcMuLo= github.com/projectdiscovery/reflectutil v0.0.0-20210804085554-4d90952bf92f/go.mod h1:3L0WfNIcVWXIDur8k+gKDLZLWY2F+rs0SQXtcn/3AYU= -github.com/projectdiscovery/retryabledns v1.0.13 h1:Ogfv0fl3Nszb+Nq2S2qQmE+PJDlStVxyLkmTotMohZY= -github.com/projectdiscovery/retryabledns v1.0.13/go.mod h1:EeqHcAPp0g2GljT4qkxKSAE47Dj0ZrJQ46R9ct3Muhk= +github.com/projectdiscovery/retryabledns v1.0.15 h1:3Nn119UwYsfUPC3g0q57ftz0Wb5Zl5ppvw8R0Xu0DEI= +github.com/projectdiscovery/retryabledns v1.0.15/go.mod h1:3YbsQVqP7jbQ3CDmarhyVtkJaJ8XcB7S19vMeyMxZxk= github.com/projectdiscovery/retryablehttp-go v1.0.2 h1:LV1/KAQU+yeWhNVlvveaYFsjBYRwXlNEq0PvrezMV0U= github.com/projectdiscovery/retryablehttp-go v1.0.2/go.mod h1:dx//aY9V247qHdsRf0vdWHTBZuBQ2vm6Dq5dagxrDYI= +github.com/projectdiscovery/sliceutil v0.0.0-20220617151003-15892688e1d6/go.mod h1:9YZb6LRjLYAvSOm65v787dwauurixSyjlqXyYa4rTTA= +github.com/projectdiscovery/sliceutil v0.0.0-20220625085859-c3a4ecb669f4 h1:C04j5gVVMXqFyBIetAz92SyPRYCpkFgIwZw0L/pps9Q= +github.com/projectdiscovery/sliceutil v0.0.0-20220625085859-c3a4ecb669f4/go.mod h1:RxDaccMjPzIuF7F8XbdGl1yOcqxN4YPiHr9xHpfCkGI= github.com/projectdiscovery/stringsutil v0.0.0-20210804142656-fd3c28dbaafe/go.mod h1:oTRc18WBv9t6BpaN9XBY+QmG28PUpsyDzRht56Qf49I= -github.com/projectdiscovery/stringsutil v0.0.0-20210823090203-2f5f137e8e1d/go.mod h1:oTRc18WBv9t6BpaN9XBY+QmG28PUpsyDzRht56Qf49I= -github.com/projectdiscovery/stringsutil v0.0.0-20220208075244-7c05502ca8e9 h1:4fvUw6b4sS4GoWbHr60mJo3dI//4mGt3BuLx8Sz9aNw= github.com/projectdiscovery/stringsutil v0.0.0-20220208075244-7c05502ca8e9/go.mod h1:oTRc18WBv9t6BpaN9XBY+QmG28PUpsyDzRht56Qf49I= +github.com/projectdiscovery/stringsutil v0.0.0-20220422150559-b54fb5dc6833/go.mod h1:oTRc18WBv9t6BpaN9XBY+QmG28PUpsyDzRht56Qf49I= +github.com/projectdiscovery/stringsutil v0.0.0-20220612082425-0037ce9f89f3/go.mod h1:mF5sh4jTghoGWwgUb9qWi5waTFklClDbtrqtJU93awc= +github.com/projectdiscovery/stringsutil v0.0.0-20220731064040-4b67f194751e/go.mod h1:32NYmKyHkKsmisAOAaWrR15lz2ysz2M8x3KMeeoRHoU= +github.com/projectdiscovery/stringsutil v0.0.1 h1:a6TCMT+D1aUsoZxNiYf9O30wiDOoLOHDwj89HBjr5BQ= +github.com/projectdiscovery/stringsutil v0.0.1/go.mod h1:TDi2LEqR3OML0BxGoMbbfAHSk5AdfHX762Oc302sgmM= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/rs/xid v1.3.0 h1:6NjYksEUlhurdVehpc7S7dk6DAmcKv8V9gG0FsVN2U4= -github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY= +github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI= +github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU= github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= @@ -275,13 +297,18 @@ github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb6 github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.7.3/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= @@ -296,18 +323,22 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1: github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= +github.com/yl2chen/cidranger v1.0.2 h1:lbOWZVCG1tCRX4u24kuM1Tb4nHqWkDxwLdoS+SevawU= github.com/yl2chen/cidranger v1.0.2/go.mod h1:9U1yz7WPYDwf0vpNWFaeRh0bjwz5RVgRy/9UEQfHl0g= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/ratelimit v0.2.0 h1:UQE2Bgi7p2B85uP5dC2bbRtig0C+OeNRnNEafLjsLPA= go.uber.org/ratelimit v0.2.0/go.mod h1:YYBV4e4naJvhpitQrWJu1vCpgB7CboMe0qhltKt6mUg= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -316,6 +347,7 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20200513190911-00229845015e h1:rMqLP+9XLy+LdbCXHjJHAmTfXCr93W7oruWA6Hq1Alc= @@ -328,10 +360,11 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38= -golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -343,25 +376,34 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210414194228-064579744ee0/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210521195947-fe42d452be8f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220121210141-e204ce36a2ba h1:6u6sik+bn/y7vILcYkK3iwTBWN7WtBvB0+SZswQnbf8= -golang.org/x/net v0.0.0-20220121210141-e204ce36a2ba/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220728211354-c7608f3a8462/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20220927171203-f486391704dc h1:FxpXZdoBqT8RjqTy6i1E8nXHhW21wK7ptQ/EPIGxzPQ= +golang.org/x/net v0.0.0-20220927171203-f486391704dc/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -388,10 +430,11 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220731174439-a90be440212d h1:Sv5ogFZatcgIMMtBSTTAgMYsicp25MXBubjXNDKwm80= +golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -411,10 +454,12 @@ golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8= -golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -459,7 +504,8 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/internal/runner/banner.go b/internal/runner/banner.go index 4df70d9d..b9e7f2b0 100644 --- a/internal/runner/banner.go +++ b/internal/runner/banner.go @@ -7,11 +7,11 @@ const banner = ` __| | _ __ ___ \ \/ / / _' || '_ \ / __| \ / | (_| || | | |\__ \ / \ - \__,_||_| |_||___//_/\_\ v1.1.0 + \__,_||_| |_||___//_/\_\ v1.1.1 ` // Version is the current version of dnsx -const Version = `1.1.0` +const Version = `1.1.1` // showBanner is used to show the banner to the user func showBanner() { diff --git a/internal/runner/healthcheck.go b/internal/runner/healthcheck.go new file mode 100644 index 00000000..2ab7ca1e --- /dev/null +++ b/internal/runner/healthcheck.go @@ -0,0 +1,73 @@ +package runner + +import ( + "fmt" + "net" + "runtime" + "strings" + + "github.com/projectdiscovery/fileutil" + "github.com/projectdiscovery/goflags" +) + +func DoHealthCheck(options *Options) string { + // RW permissions on config file + cfgFilePath, _ := goflags.GetConfigFilePath() + var test strings.Builder + test.WriteString(fmt.Sprintf("Version: %s\n", Version)) + test.WriteString(fmt.Sprintf("Operative System: %s\n", runtime.GOOS)) + test.WriteString(fmt.Sprintf("Architecture: %s\n", runtime.GOARCH)) + test.WriteString(fmt.Sprintf("Go Version: %s\n", runtime.Version())) + test.WriteString(fmt.Sprintf("Compiler: %s\n", runtime.Compiler)) + + var testResult string + ok, err := fileutil.IsReadable(cfgFilePath) + if ok { + testResult = "Ok" + } else { + testResult = "Ko" + } + if err != nil { + testResult += fmt.Sprintf(" (%s)", err) + } + test.WriteString(fmt.Sprintf("Config file \"%s\" Read => %s\n", cfgFilePath, testResult)) + ok, err = fileutil.IsWriteable(cfgFilePath) + if ok { + testResult = "Ok" + } else { + testResult = "Ko" + } + if err != nil { + testResult += fmt.Sprintf(" (%s)", err) + } + test.WriteString(fmt.Sprintf("Config file \"%s\" Write => %s\n", cfgFilePath, testResult)) + c4, err := net.Dial("tcp4", "scanme.sh:80") + if err == nil && c4 != nil { + c4.Close() + } + testResult = "Ok" + if err != nil { + testResult = fmt.Sprintf("Ko (%s)", err) + } + test.WriteString(fmt.Sprintf("IPv4 connectivity to scanme.sh:80 => %s\n", testResult)) + c6, err := net.Dial("tcp6", "scanme.sh:80") + if err == nil && c6 != nil { + c6.Close() + } + testResult = "Ok" + if err != nil { + testResult = fmt.Sprintf("Ko (%s)", err) + } + test.WriteString(fmt.Sprintf("IPv6 connectivity to scanme.sh:80 => %s\n", testResult)) + u, err := net.Dial("udp", "scanme.sh:53") + if err == nil && c6 != nil { + u.Close() + } + testResult = "Ok" + if err != nil { + testResult = fmt.Sprintf("Ko (%s)", err) + } + test.WriteString(fmt.Sprintf("UDP connectivity to scanme.sh:53 => %s\n", testResult)) + + return test.String() +} diff --git a/internal/runner/options.go b/internal/runner/options.go index eb76613c..cd581e85 100644 --- a/internal/runner/options.go +++ b/internal/runner/options.go @@ -42,6 +42,7 @@ type Options struct { MX bool SOA bool TXT bool + AXFR bool JSON bool Trace bool TraceMaxRecursion int @@ -53,9 +54,11 @@ type Options struct { hasRCodes bool Resume bool resumeCfg *ResumeCfg - FlushInterval int HostsFile bool Stream bool + CAA bool + OutputCDN bool + HealthCheck bool } // ShouldLoadResume resume file @@ -74,14 +77,13 @@ func ParseOptions() *Options { flagSet := goflags.NewFlagSet() flagSet.SetDescription(`dnsx is a fast and multi-purpose DNS toolkit allow to run multiple probes using retryabledns library.`) - createGroup(flagSet, "input", "Input", - flagSet.BoolVar(&options.Stream, "stream", false, "stream mode (wordlist, wildcard, stats and stop/resume will be disabled)"), + flagSet.CreateGroup("input", "Input", flagSet.StringVarP(&options.Hosts, "list", "l", "", "list of sub(domains)/hosts to resolve (file or stdin)"), flagSet.StringVarP(&options.Domains, "domain", "d", "", "list of domain to bruteforce (file or comma separated or stdin)"), flagSet.StringVarP(&options.WordList, "wordlist", "w", "", "list of words to bruteforce (file or comma separated or stdin)"), ) - createGroup(flagSet, "query", "Query", + flagSet.CreateGroup("query", "Query", flagSet.BoolVar(&options.A, "a", false, "query A record (default)"), flagSet.BoolVar(&options.AAAA, "aaaa", false, "query AAAA record"), flagSet.BoolVar(&options.CNAME, "cname", false, "query CNAME record"), @@ -90,25 +92,32 @@ func ParseOptions() *Options { flagSet.BoolVar(&options.PTR, "ptr", false, "query PTR record"), flagSet.BoolVar(&options.MX, "mx", false, "query MX record"), flagSet.BoolVar(&options.SOA, "soa", false, "query SOA record"), + flagSet.BoolVar(&options.AXFR, "axfr", false, "query AXFR"), + flagSet.BoolVar(&options.CAA, "caa", false, "query CAA record"), + ) + + flagSet.CreateGroup("filter", "Filter", + flagSet.BoolVarP(&options.Response, "resp", "re", false, "display dns response"), + flagSet.BoolVarP(&options.ResponseOnly, "resp-only", "ro", false, "display dns response only"), + flagSet.StringVarP(&options.RCode, "rcode", "rc", "", "filter result by dns status code (eg. -rcode noerror,servfail,refused)"), ) - createGroup(flagSet, "filters", "Filters", - flagSet.BoolVar(&options.Response, "resp", false, "display dns response"), - flagSet.BoolVar(&options.ResponseOnly, "resp-only", false, "display dns response only"), - flagSet.StringVarP(&options.RCode, "rc", "rcode", "", "filter result by dns status code (eg. -rcode noerror,servfail,refused)"), + flagSet.CreateGroup("probe", "Probe", + flagSet.BoolVar(&options.OutputCDN, "cdn", false, "display cdn name"), ) - createGroup(flagSet, "rate-limit", "Rate-limit", - flagSet.IntVarP(&options.Threads, "c", "t", 100, "number of concurrent threads to use"), + flagSet.CreateGroup("rate-limit", "Rate-limit", + flagSet.IntVarP(&options.Threads, "threads", "t", 100, "number of concurrent threads to use"), flagSet.IntVarP(&options.RateLimit, "rate-limit", "rl", -1, "number of dns request/second to make (disabled as default)"), ) - createGroup(flagSet, "output", "Output", + flagSet.CreateGroup("output", "Output", flagSet.StringVarP(&options.OutputFile, "output", "o", "", "file to write output"), flagSet.BoolVar(&options.JSON, "json", false, "write output in JSONL(ines) format"), ) - createGroup(flagSet, "debug", "Debug", + flagSet.CreateGroup("debug", "Debug", + flagSet.BoolVarP(&options.HealthCheck, "health-check", "hc", false, "run diagnostic check up"), flagSet.BoolVar(&options.Silent, "silent", false, "display only results in the output"), flagSet.BoolVarP(&options.Verbose, "verbose", "v", false, "display verbose output"), flagSet.BoolVarP(&options.Raw, "debug", "raw", false, "display raw dns response"), @@ -116,16 +125,16 @@ func ParseOptions() *Options { flagSet.BoolVar(&options.Version, "version", false, "display version of dnsx"), ) - createGroup(flagSet, "optimization", "Optimization", - flagSet.IntVar(&options.Retries, "retry", 2, "number of dns retries to make"), + flagSet.CreateGroup("optimization", "Optimization", + flagSet.IntVar(&options.Retries, "retry", 2, "number of dns attempts to make (must be at least 1)"), flagSet.BoolVarP(&options.HostsFile, "hostsfile", "hf", false, "use system host file"), flagSet.BoolVar(&options.Trace, "trace", false, "perform dns tracing"), flagSet.IntVar(&options.TraceMaxRecursion, "trace-max-recursion", math.MaxInt16, "Max recursion for dns trace"), - flagSet.IntVar(&options.FlushInterval, "flush-interval", 10, "flush interval of output file"), flagSet.BoolVar(&options.Resume, "resume", false, "resume existing scan"), + flagSet.BoolVar(&options.Stream, "stream", false, "stream mode (wordlist, wildcard, stats and stop/resume will be disabled)"), ) - createGroup(flagSet, "configs", "Configurations", + flagSet.CreateGroup("configs", "Configurations", flagSet.StringVarP(&options.Resolvers, "resolver", "r", "", "list of resolvers to use (file or comma separated)"), flagSet.IntVarP(&options.WildcardThreshold, "wildcard-threshold", "wt", 5, "wildcard filter threshold"), flagSet.StringVarP(&options.WildcardDomain, "wildcard-domain", "wd", "", "domain name for wildcard filtering (other flags will be ignored)"), @@ -133,6 +142,11 @@ func ParseOptions() *Options { _ = flagSet.Parse() + if options.HealthCheck { + gologger.Print().Msgf("%s\n", DoHealthCheck(options)) + os.Exit(0) + } + // Read the inputs and configure the logging options.configureOutput() @@ -163,6 +177,10 @@ func (options *Options) validateOptions() { gologger.Fatal().Msgf("resp and resp-only can't be used at the same time") } + if options.Retries == 0 { + gologger.Fatal().Msgf("retries must be at least 1") + } + wordListPresent := options.WordList != "" domainsPresent := options.Domains != "" hostsPresent := options.Hosts != "" @@ -295,10 +313,3 @@ func (options *Options) configureResume() error { } return nil } - -func createGroup(flagSet *goflags.FlagSet, groupName, description string, flags ...*goflags.FlagData) { - flagSet.SetGroup(groupName, description) - for _, currentFlag := range flags { - currentFlag.Group(groupName) - } -} diff --git a/internal/runner/runner.go b/internal/runner/runner.go index fc8dfcb7..9b0e8ff1 100644 --- a/internal/runner/runner.go +++ b/internal/runner/runner.go @@ -2,9 +2,8 @@ package runner import ( "bufio" - "bytes" "fmt" - "io/ioutil" + "io" "os" "strings" "sync" @@ -20,7 +19,7 @@ import ( "github.com/projectdiscovery/hmap/store/hybrid" "github.com/projectdiscovery/iputil" "github.com/projectdiscovery/mapcidr" - retryabledns "github.com/projectdiscovery/retryabledns" + "github.com/projectdiscovery/retryabledns" "go.uber.org/ratelimit" ) @@ -41,6 +40,7 @@ type Runner struct { limiter ratelimit.Limiter hm *hybrid.HybridMap stats clistats.StatisticsClient + tmpStdinFile string } func New(options *Options) (*Runner, error) { @@ -50,7 +50,7 @@ func New(options *Options) (*Runner, error) { dnsxOptions.MaxRetries = options.Retries dnsxOptions.TraceMaxRecursion = options.TraceMaxRecursion dnsxOptions.Hostsfile = options.HostsFile - + dnsxOptions.OutputCDN = options.OutputCDN if options.Resolvers != "" { dnsxOptions.BaseResolvers = []string{} // If it's a file load resolvers from it @@ -95,6 +95,10 @@ func New(options *Options) (*Runner, error) { if options.NS { questionTypes = append(questionTypes, dns.TypeNS) } + if options.CAA { + questionTypes = append(questionTypes, dns.TypeCAA) + } + // If no option is specified or wildcard filter has been requested use query type A if len(questionTypes) == 0 || options.WildcardDomain != "" { options.A = true @@ -188,50 +192,71 @@ func (r *Runner) InputWorker() { } func (r *Runner) prepareInput() error { - var dataDomains []byte - var sc *bufio.Scanner + var ( + dataDomains chan string + sc chan string + err error + ) - // prepare wordlist - var prefixs []string - if r.options.WordList != "" { - dataWordList, err := preProcessArgument(r.options.WordList) + // copy stdin to a temporary file + hasStdin := fileutil.HasStdin() + if hasStdin { + tmpStdinFile, err := fileutil.GetTempFileName() if err != nil { return err } - prefixs = normalizeToSlice(dataWordList) + r.tmpStdinFile = tmpStdinFile + + stdinFile, err := os.Create(r.tmpStdinFile) + if err != nil { + return err + } + if _, err := io.Copy(stdinFile, os.Stdin); err != nil { + return err + } + // closes the file as we will read it multiple times to build the iterations + stdinFile.Close() + defer os.RemoveAll(r.tmpStdinFile) } if r.options.Domains != "" { - var err error - dataDomains, err = preProcessArgument(r.options.Domains) + dataDomains, err = r.preProcessArgument(r.options.Domains) if err != nil { return err } - sc = bufio.NewScanner(bytes.NewReader(dataDomains)) + sc = dataDomains } if sc == nil { // attempt to load list from file if fileutil.FileExists(r.options.Hosts) { - f, err := os.Open(r.options.Hosts) + f, err := fileutil.ReadFile(r.options.Hosts) + if err != nil { + return err + } + sc = f + } else if argumentHasStdin(r.options.Hosts) || hasStdin { + sc, err = fileutil.ReadFile(r.tmpStdinFile) if err != nil { return err } - sc = bufio.NewScanner(f) - } else if argumentHasStdin(r.options.Hosts) || hasStdin() { - sc = bufio.NewScanner(os.Stdin) } else { return errors.New("hosts file or stdin not provided") } } numHosts := 0 - for sc.Scan() { - item := strings.TrimSpace(sc.Text()) + for item := range sc { + item := normalize(item) var hosts []string switch { case r.options.WordList != "": - for _, prefix := range prefixs { + // prepare wordlist + prefixes, err := r.preProcessArgument(r.options.WordList) + if err != nil { + return err + } + for prefix := range prefixes { // domains Cartesian product with wordlist subdomain := strings.TrimSpace(prefix) + "." + item hosts = append(hosts, subdomain) @@ -265,48 +290,26 @@ func (r *Runner) prepareInput() error { return nil } -func hasStdin() bool { - stat, _ := os.Stdin.Stat() - return (stat.Mode() & os.ModeCharDevice) == 0 -} - -func preProcessArgument(arg string) ([]byte, error) { - var ( - data []byte - err error - ) +func (r *Runner) preProcessArgument(arg string) (chan string, error) { // read from: // file switch { case fileutil.FileExists(arg): - data, err = os.ReadFile(arg) - if err != nil { - return nil, err - } + return fileutil.ReadFile(arg) // stdin case argumentHasStdin(arg): - data, err = ioutil.ReadAll(os.Stdin) - if err != nil { - return nil, err - } + return fileutil.ReadFile(r.tmpStdinFile) // inline case arg != "": - data = []byte(arg) + data := strings.ReplaceAll(arg, Comma, NewLine) + return fileutil.ReadFileWithReader(strings.NewReader(data)) default: return nil, errors.New("empty argument") } - - return bytes.Replace(data, []byte(Comma), []byte(NewLine), -1), nil } -func normalizeToSlice(data []byte) []string { - var s []string - sc := bufio.NewScanner(bytes.NewReader(data)) - for sc.Scan() { - item := strings.TrimSpace(sc.Text()) - s = append(s, item) - } - return s +func normalize(data string) string { + return strings.TrimSpace(data) } // nolint:deadcode @@ -498,24 +501,13 @@ func (r *Runner) HandleOutput() { defer foutput.Close() w = bufio.NewWriter(foutput) defer w.Flush() - var flushTicker *time.Ticker - if r.options.FlushInterval >= 0 { - flushTicker = time.NewTicker(time.Duration(r.options.FlushInterval) * time.Second) - defer flushTicker.Stop() - go func() { - for range flushTicker.C { - w.Flush() - } - }() - } } for item := range r.outputchan { - if r.options.OutputFile != "" { + if foutput != nil { // uses a buffer to write to file - // nolint:errcheck - w.WriteString(item + "\n") + _, _ = w.WriteString(item + "\n") } - // otherwise writes sequentially to stdout + // writes sequentially to stdout gologger.Silent().Msgf("%s\n", item) } } @@ -550,11 +542,11 @@ func (r *Runner) worker() { domain = extractDomain(domain) } r.limiter.Take() - + dnsData := dnsx.ResponseData{} // Ignoring errors as partial results are still good - dnsData, _ := r.dnsx.QueryMultiple(domain) + dnsData.DNSData, _ = r.dnsx.QueryMultiple(domain) // Just skipping nil responses (in case of critical errors) - if dnsData == nil { + if dnsData.DNSData == nil { continue } @@ -562,10 +554,13 @@ func (r *Runner) worker() { continue } - // skip responses not having the expected response code - if len(r.options.rcodes) > 0 { - if _, ok := r.options.rcodes[dnsData.StatusCodeRaw]; !ok { - continue + // results from hosts file are always returned + if !dnsData.HostsFile { + // skip responses not having the expected response code + if len(r.options.rcodes) > 0 { + if _, ok := r.options.rcodes[dnsData.StatusCodeRaw]; !ok { + continue + } } } @@ -588,10 +583,27 @@ func (r *Runner) worker() { } } + if r.options.AXFR { + hasAxfrData := false + axfrData, _ := r.dnsx.AXFR(domain) + if axfrData != nil { + dnsData.AXFRData = axfrData + hasAxfrData = len(axfrData.DNSData) > 0 + } + + // if the query type is only AFXR then output only if we have results (ref: https://github.com/projectdiscovery/dnsx/issues/230#issuecomment-1256659249) + if len(r.dnsx.Options.QuestionTypes) == 1 && !hasAxfrData && !r.options.JSON { + continue + } + } + // add flags for cdn + if r.options.OutputCDN { + dnsData.IsCDNIP, dnsData.CDNName, _ = r.dnsx.CdnCheck(domain) + } // if wildcard filtering just store the data if r.options.WildcardDomain != "" { // nolint:errcheck - r.storeDNSData(dnsData) + r.storeDNSData(dnsData.DNSData) continue } if r.options.JSON { @@ -608,42 +620,48 @@ func (r *Runner) worker() { continue } if r.options.A { - r.outputRecordType(domain, dnsData.A) + r.outputRecordType(domain, dnsData.A, dnsData.CDNName) } if r.options.AAAA { - r.outputRecordType(domain, dnsData.AAAA) + r.outputRecordType(domain, dnsData.AAAA, dnsData.CDNName) } if r.options.CNAME { - r.outputRecordType(domain, dnsData.CNAME) + r.outputRecordType(domain, dnsData.CNAME, dnsData.CDNName) } if r.options.PTR { - r.outputRecordType(domain, dnsData.PTR) + r.outputRecordType(domain, dnsData.PTR, dnsData.CDNName) } if r.options.MX { - r.outputRecordType(domain, dnsData.MX) + r.outputRecordType(domain, dnsData.MX, dnsData.CDNName) } if r.options.NS { - r.outputRecordType(domain, dnsData.NS) + r.outputRecordType(domain, dnsData.NS, dnsData.CDNName) } if r.options.SOA { - r.outputRecordType(domain, dnsData.SOA) + r.outputRecordType(domain, dnsData.SOA, dnsData.CDNName) } if r.options.TXT { - r.outputRecordType(domain, dnsData.TXT) + r.outputRecordType(domain, dnsData.TXT, dnsData.CDNName) + } + if r.options.CAA { + r.outputRecordType(domain, dnsData.CAA, dnsData.CDNName) } } } -func (r *Runner) outputRecordType(domain string, items []string) { +func (r *Runner) outputRecordType(domain string, items []string, cdnName string) { + if cdnName != "" { + cdnName = fmt.Sprintf(" [%s]", cdnName) + } for _, item := range items { item := strings.ToLower(item) if r.options.ResponseOnly { - r.outputchan <- item + r.outputchan <- item + cdnName } else if r.options.Response { - r.outputchan <- domain + " [" + item + "]" + r.outputchan <- domain + " [" + item + "]" + cdnName } else { // just prints out the domain if it has a record type and exit - r.outputchan <- domain + r.outputchan <- domain + cdnName break } } diff --git a/internal/runner/util.go b/internal/runner/util.go index 2828f125..7174eb70 100644 --- a/internal/runner/util.go +++ b/internal/runner/util.go @@ -1,12 +1,12 @@ package runner import ( - "bufio" "fmt" "net/url" - "os" "strings" "time" + + "github.com/projectdiscovery/fileutil" ) const ( @@ -17,14 +17,11 @@ const ( func linesInFile(fileName string) ([]string, error) { result := []string{} - f, err := os.Open(fileName) + f, err := fileutil.ReadFile(fileName) if err != nil { - return result, err + return nil, err } - defer f.Close() - scanner := bufio.NewScanner(f) - for scanner.Scan() { - line := scanner.Text() + for line := range f { result = append(result, line) } return result, nil diff --git a/internal/testutils/integration.go b/internal/testutils/integration.go index 527a6eb0..6c00550b 100644 --- a/internal/testutils/integration.go +++ b/internal/testutils/integration.go @@ -57,7 +57,7 @@ func RunDnsxBinaryAndGetResults(target string, dnsxBinary string, debug bool, ar parts = append(parts, i) } } - return parts,nil + return parts, nil } // TestCase is a single integration test case diff --git a/libs/dnsx/cdn.go b/libs/dnsx/cdn.go new file mode 100644 index 00000000..9821cea8 --- /dev/null +++ b/libs/dnsx/cdn.go @@ -0,0 +1,24 @@ +package dnsx + +import ( + "net" + + "github.com/pkg/errors" + "github.com/projectdiscovery/iputil" +) + +// CdnCheck verifies if the given ip is part of Cdn ranges +func (d *DNSX) CdnCheck(domain string) (bool, string, error) { + if d.cdn == nil { + return false, "", errors.New("cdn client not initialized") + } + ips, err := net.LookupIP(domain) + if err != nil { + return false, "", err + } + ipAddr := ips[0].String() + if !iputil.IsIP(ipAddr) { + return false, "", errors.Errorf("%s is not a valid ip", ipAddr) + } + return d.cdn.Check(net.ParseIP((ipAddr))) +} diff --git a/libs/dnsx/dnsx.go b/libs/dnsx/dnsx.go index 68d2c116..659bb588 100644 --- a/libs/dnsx/dnsx.go +++ b/libs/dnsx/dnsx.go @@ -1,10 +1,12 @@ package dnsx import ( + "encoding/json" "errors" "math" miekgdns "github.com/miekg/dns" + "github.com/projectdiscovery/cdncheck" "github.com/projectdiscovery/iputil" retryabledns "github.com/projectdiscovery/retryabledns" ) @@ -13,6 +15,7 @@ import ( type DNSX struct { dnsClient *retryabledns.Client Options *Options + cdn *cdncheck.Client } // Options contains configuration options @@ -23,6 +26,19 @@ type Options struct { Trace bool TraceMaxRecursion int Hostsfile bool + OutputCDN bool +} + +// ResponseData to show output result +type ResponseData struct { + *retryabledns.DNSData + IsCDNIP bool `json:"cdn,omitempty" csv:"cdn"` + CDNName string `json:"cdn-name,omitempty" csv:"cdn-name"` +} + +func (d *ResponseData) JSON() (string, error) { + b, err := json.Marshal(&d) + return string(b), err } // DefaultOptions contains the default configuration options @@ -50,10 +66,20 @@ func New(options Options) (*DNSX, error) { Hostsfile: options.Hostsfile, } - dnsClient := retryabledns.NewWithOptions(retryablednsOptions) + dnsClient, err := retryabledns.NewWithOptions(retryablednsOptions) + if err != nil { + return nil, err + } dnsClient.TCPFallback = true - - return &DNSX{dnsClient: dnsClient, Options: &options}, nil + dnsx := &DNSX{dnsClient: dnsClient, Options: &options} + if options.OutputCDN { + var err error + dnsx.cdn, err = cdncheck.NewWithCache() + if err != nil { + return nil, err + } + } + return dnsx, nil } // Lookup performs a DNS A question and returns corresponding IPs @@ -88,3 +114,8 @@ func (d *DNSX) QueryMultiple(hostname string) (*retryabledns.DNSData, error) { func (d *DNSX) Trace(hostname string) (*retryabledns.TraceData, error) { return d.dnsClient.Trace(hostname, d.Options.QuestionTypes[0], d.Options.TraceMaxRecursion) } + +// Trace performs a DNS trace of the specified types and returns raw responses +func (d *DNSX) AXFR(hostname string) (*retryabledns.AXFRData, error) { + return d.dnsClient.AXFR(hostname) +}