feat: gettin there
parent
f888bd220f
commit
df306e18a9
|
@ -0,0 +1,31 @@
|
||||||
|
# doggo - v1.0 Milestone
|
||||||
|
|
||||||
|
## Resolver
|
||||||
|
- [ ] Create a DNS Resolver struct
|
||||||
|
- [ ] Add methods to initialise the config, set defaults
|
||||||
|
- [ ] Add a resolve method
|
||||||
|
- [ ] Make it separate from Hub
|
||||||
|
|
||||||
|
## CLI Features
|
||||||
|
- [ ] `digfile`
|
||||||
|
- [ ] `ndots` support
|
||||||
|
- [ ] `search path` support
|
||||||
|
- [ ] JSON output
|
||||||
|
- [ ] Colorized output
|
||||||
|
- [ ] Table output
|
||||||
|
|
||||||
|
## CLI Grunt
|
||||||
|
- [ ] Query args
|
||||||
|
- [ ] Neatly package them to load args in different functions
|
||||||
|
- [ ] Upper case is not mandatory for query type/classes
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
## Release Checklist
|
||||||
|
- [ ] Add packages to all package managers
|
||||||
|
- [ ] Snap
|
||||||
|
- [ ] Homebrew
|
||||||
|
- [ ] Alpine Linux
|
||||||
|
- [ ] ARM support too
|
BIN
bin/doggo.bin
BIN
bin/doggo.bin
Binary file not shown.
32
cmd/cli.go
32
cmd/cli.go
|
@ -4,9 +4,9 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/mr-karan/doggo/pkg/resolver"
|
resolver "github.com/mr-karan/doggo/pkg/resolve"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -37,23 +37,28 @@ func main() {
|
||||||
app.Name = "doggo"
|
app.Name = "doggo"
|
||||||
app.Usage = "Command-line DNS Client"
|
app.Usage = "Command-line DNS Client"
|
||||||
app.Version = buildVersion
|
app.Version = buildVersion
|
||||||
app.Author = "Karan Sharma @mrkaran"
|
|
||||||
// Register command line args.
|
|
||||||
app.Flags = []cli.Flag{
|
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "verbose",
|
|
||||||
Usage: "Enable verbose logging",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
var (
|
var (
|
||||||
logger = initLogger(true)
|
logger = initLogger(true)
|
||||||
)
|
)
|
||||||
// Initialize hub.
|
// Initialize hub.
|
||||||
hub := NewHub(logger, buildVersion)
|
hub := NewHub(logger, buildVersion)
|
||||||
|
// Register command line args.
|
||||||
|
app.Flags = []cli.Flag{
|
||||||
|
&cli.StringSliceFlag{
|
||||||
|
Name: "query",
|
||||||
|
Usage: "Domain name to query",
|
||||||
|
Destination: hub.Domains,
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "verbose",
|
||||||
|
Usage: "Enable verbose logging",
|
||||||
|
},
|
||||||
|
}
|
||||||
app.Action = func(c *cli.Context) error {
|
app.Action = func(c *cli.Context) error {
|
||||||
|
|
||||||
// parse arguments
|
// parse arguments
|
||||||
for _, arg := range c.Args() {
|
var domains cli.StringSlice
|
||||||
|
for _, arg := range c.Args().Slice() {
|
||||||
if strings.HasPrefix(arg, "@") {
|
if strings.HasPrefix(arg, "@") {
|
||||||
hub.Nameservers = append(hub.Nameservers, arg)
|
hub.Nameservers = append(hub.Nameservers, arg)
|
||||||
} else if isUpper(arg) {
|
} else if isUpper(arg) {
|
||||||
|
@ -63,7 +68,8 @@ func main() {
|
||||||
hub.QClass = append(hub.QClass, arg)
|
hub.QClass = append(hub.QClass, arg)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
hub.Domains = append(hub.Domains, arg)
|
domains.Set(arg)
|
||||||
|
hub.Domains = &domains
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// load defaults
|
// load defaults
|
||||||
|
|
|
@ -2,14 +2,14 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Hub represents the structure for all app wide functions and structs.
|
// Hub represents the structure for all app wide functions and structs.
|
||||||
type Hub struct {
|
type Hub struct {
|
||||||
Logger *logrus.Logger
|
Logger *logrus.Logger
|
||||||
Version string
|
Version string
|
||||||
Domains []string
|
Domains *cli.StringSlice
|
||||||
QTypes []string
|
QTypes []string
|
||||||
QClass []string
|
QClass []string
|
||||||
Nameservers []string
|
Nameservers []string
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
func (hub *Hub) loadFlags() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hub *Hub) loadFreeForm() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hub *Hub) loadFallbacks() {
|
||||||
|
|
||||||
|
}
|
|
@ -8,12 +8,12 @@ import (
|
||||||
|
|
||||||
// Resolve resolves the domain name
|
// Resolve resolves the domain name
|
||||||
func (hub *Hub) Resolve() {
|
func (hub *Hub) Resolve() {
|
||||||
var messages = make([]dns.Msg, 0, len(hub.Domains))
|
var messages = make([]dns.Msg, 0, len(hub.Domains.Value()))
|
||||||
for _, d := range hub.Domains {
|
for _, d := range hub.Domains.Value() {
|
||||||
msg := dns.Msg{}
|
msg := dns.Msg{}
|
||||||
msg.Id = dns.Id()
|
msg.Id = dns.Id()
|
||||||
msg.RecursionDesired = true
|
msg.RecursionDesired = true
|
||||||
msg.Question = []dns.Question{(dns.Question{d, dns.TypeA, dns.ClassINET})}
|
msg.Question = []dns.Question{(dns.Question{dns.Fqdn(d), dns.TypeA, dns.ClassINET})}
|
||||||
messages = append(messages, msg)
|
messages = append(messages, msg)
|
||||||
}
|
}
|
||||||
c := new(dns.Client)
|
c := new(dns.Client)
|
||||||
|
@ -27,6 +27,6 @@ func (hub *Hub) Resolve() {
|
||||||
fmt.Println(t.String())
|
fmt.Println(t.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Println("rtt is", rtt, msg.Question)
|
fmt.Println("rtt is", rtt, msg.Question[0].Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -5,5 +5,5 @@ go 1.15
|
||||||
require (
|
require (
|
||||||
github.com/miekg/dns v1.1.35
|
github.com/miekg/dns v1.1.35
|
||||||
github.com/sirupsen/logrus v1.7.0
|
github.com/sirupsen/logrus v1.7.0
|
||||||
github.com/urfave/cli v1.22.5
|
github.com/urfave/cli/v2 v2.3.0
|
||||||
)
|
)
|
||||||
|
|
10
go.sum
10
go.sum
|
@ -1,9 +1,11 @@
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/miekg/dns v1.1.35 h1:oTfOaDH+mZkdcgdIjH6yBajRGtIwcwcaR+rt23ZSrJs=
|
github.com/miekg/dns v1.1.35 h1:oTfOaDH+mZkdcgdIjH6yBajRGtIwcwcaR+rt23ZSrJs=
|
||||||
github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||||
|
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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
|
@ -11,9 +13,10 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5I
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
|
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU=
|
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
|
||||||
github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
@ -22,6 +25,7 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g=
|
golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g=
|
||||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
@ -33,4 +37,4 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package models
|
||||||
|
|
||||||
|
// Question represents a given query to the client.
|
||||||
|
// A question can have multiple domains, multiple nameservers
|
||||||
|
// but it's the responsibility of the client to send each question
|
||||||
|
// to the nameserver and collect responses.
|
||||||
|
type Question struct {
|
||||||
|
Domain []string
|
||||||
|
Nameservers []string
|
||||||
|
QClass []uint16
|
||||||
|
QType []uint16
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package resolver
|
package resolve
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
|
@ -0,0 +1,91 @@
|
||||||
|
package resolve
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"github.com/miekg/dns"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Resolver holds the configuration for a dns.Client
|
||||||
|
type Resolver struct {
|
||||||
|
client *dns.Client
|
||||||
|
servers []string
|
||||||
|
}
|
||||||
|
|
||||||
|
//DefaultResolvConfPath specifies path to default resolv config file on UNIX.
|
||||||
|
const DefaultResolvConfPath = "/etc/resolv.conf"
|
||||||
|
|
||||||
|
// NewResolver accepts a list of nameservers and configures a DNS resolver.
|
||||||
|
func NewResolver(servers []string) *Resolver {
|
||||||
|
client := &dns.Client{}
|
||||||
|
return &Resolver{
|
||||||
|
client: client,
|
||||||
|
servers: servers,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewResolverFromResolvFile loads the configuration from resolv config file
|
||||||
|
// and initialises a DNS resolver.
|
||||||
|
func NewResolverFromResolvFile(resolvFilePath string) (*Resolver, error) {
|
||||||
|
if resolvFilePath == "" {
|
||||||
|
resolvFilePath = DefaultResolvConfPath
|
||||||
|
}
|
||||||
|
cfg, err := dns.ClientConfigFromFile(resolvFilePath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
servers := make([]string, 0, len(cfg.Servers))
|
||||||
|
for _, s := range cfg.Servers {
|
||||||
|
ip := net.ParseIP(s)
|
||||||
|
// handle IPv6
|
||||||
|
if ip != nil && ip.To4() != nil {
|
||||||
|
servers = append(servers, fmt.Sprintf("%s:%s", s, cfg.Port))
|
||||||
|
} else {
|
||||||
|
servers = append(servers, fmt.Sprintf("[%s]:%s", s, cfg.Port))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &dns.Client{}
|
||||||
|
return &Resolver{
|
||||||
|
client: client,
|
||||||
|
servers: servers,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Resolver) Lookup(domains []string) []error {
|
||||||
|
// Prepare a list of DNS messages to be sent to the server.
|
||||||
|
// It's possible to send multiple question in one message
|
||||||
|
// but some nameservers are not able to
|
||||||
|
var messages = make([]dns.Msg, 0, len(domains))
|
||||||
|
|
||||||
|
for _, d := range domains {
|
||||||
|
msg := dns.Msg{}
|
||||||
|
msg.Id = dns.Id()
|
||||||
|
msg.RecursionDesired = true
|
||||||
|
// It's recommended to only send 1 question for 1 DNS message.
|
||||||
|
msg.Question = []dns.Question{(dns.Question{
|
||||||
|
Name: dns.Fqdn(d),
|
||||||
|
Qtype: dns.TypeA,
|
||||||
|
Qclass: dns.ClassINET,
|
||||||
|
})}
|
||||||
|
messages = append(messages, msg)
|
||||||
|
}
|
||||||
|
var errors []error
|
||||||
|
for _, msg := range messages {
|
||||||
|
for _, srv := range r.servers {
|
||||||
|
in, rtt, err := r.client.Exchange(&msg, srv)
|
||||||
|
if err != nil {
|
||||||
|
errors = append(errors, err)
|
||||||
|
}
|
||||||
|
for _, ans := range in.Answer {
|
||||||
|
if t, ok := ans.(*dns.A); ok {
|
||||||
|
fmt.Println(t.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println("rtt is", rtt, msg.Question)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errors
|
||||||
|
}
|
Loading…
Reference in New Issue