parent
79c5fc7283
commit
7619cbdeb0
3
TODO.md
3
TODO.md
|
@ -62,5 +62,8 @@
|
|||
- [ ] Add tests for CLI Output.
|
||||
- [ ] Homebrew - Goreleaser
|
||||
- [ ] Add support for `dig +trace` like functionality.
|
||||
- [ ] Add `dig +x` short output
|
||||
- [x] Add `--strategy` for picking nameservers.
|
||||
- [ ] Explore `dig.rc` kinda file
|
||||
- [x] Separate Authority/Answer in JSON output.
|
||||
- [x] Error on NXDomain (Related upstream [bug](https://github.com/miekg/dns/issues/1198))
|
||||
|
|
|
@ -45,6 +45,7 @@ func main() {
|
|||
f.Int("ndots", -1, "Specify the ndots parameter. Default value is taken from resolv.conf and fallbacks to 1 if ndots statement is missing in resolv.conf")
|
||||
f.BoolP("ipv4", "4", false, "Use IPv4 only")
|
||||
f.BoolP("ipv6", "6", false, "Use IPv6 only")
|
||||
f.String("strategy", "all", "Strategy to query nameservers in resolv.conf file (`all`, `random`, `first`)")
|
||||
|
||||
// Output Options
|
||||
f.BoolP("json", "J", false, "Set the output format as JSON")
|
||||
|
@ -126,6 +127,7 @@ func main() {
|
|||
Ndots: app.ResolverOpts.Ndots,
|
||||
Timeout: app.QueryFlags.Timeout * time.Second,
|
||||
Logger: app.Logger,
|
||||
Strategy: app.QueryFlags.Strategy,
|
||||
})
|
||||
if err != nil {
|
||||
app.Logger.WithError(err).Error("error loading resolver")
|
||||
|
|
|
@ -47,11 +47,12 @@ var appHelpTextTemplate = `{{ "NAME" | color "" "heading" }}:
|
|||
{{"-x, --reverse" | color "yellow" ""}} Performs a DNS Lookup for an IPv4 or IPv6 address. Sets the query type and class to PTR and IN respectively.
|
||||
|
||||
{{ "Resolver Options" | color "" "heading" }}:
|
||||
{{"--ndots=INT" | color "yellow" ""}} Specify ndots parameter. Takes value from /etc/resolv.conf if using the system namesever or 1 otherwise.
|
||||
{{"--search" | color "yellow" ""}} Use the search list defined in resolv.conf. Defaults to true. Set --search=false to disable search list.
|
||||
{{"--timeout" | color "yellow" ""}} Specify timeout (in seconds) for the resolver to return a response.
|
||||
{{"-4 --ipv4" | color "yellow" ""}} Use IPv4 only.
|
||||
{{"-6 --ipv6" | color "yellow" ""}} Use IPv6 only.
|
||||
{{"--strategy=STRATEGY" | color "yellow" ""}} Specify strategy to query nameserver listed in etc/resolv.conf. ({{"all, random, first" | color "cyan" ""}}).
|
||||
{{"--ndots=INT" | color "yellow" ""}} Specify ndots parameter. Takes value from /etc/resolv.conf if using the system namesever or 1 otherwise.
|
||||
{{"--search" | color "yellow" ""}} Use the search list defined in resolv.conf. Defaults to true. Set --search=false to disable search list.
|
||||
{{"--timeout" | color "yellow" ""}} Specify timeout (in seconds) for the resolver to return a response.
|
||||
{{"-4 --ipv4" | color "yellow" ""}} Use IPv4 only.
|
||||
{{"-6 --ipv6" | color "yellow" ""}} Use IPv6 only.
|
||||
|
||||
{{ "Output Options" | color "" "heading" }}:
|
||||
{{"-J, --json " | color "yellow" ""}} Format the output as JSON.
|
||||
|
|
|
@ -2,8 +2,10 @@ package app
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/ameshkov/dnsstamps"
|
||||
"github.com/mr-karan/doggo/pkg/config"
|
||||
|
@ -29,7 +31,7 @@ func (app *App) LoadNameservers() error {
|
|||
// fallback to system nameserver
|
||||
// in case no nameserver is specified by user.
|
||||
if len(app.Nameservers) == 0 {
|
||||
ns, ndots, search, err := getDefaultServers()
|
||||
ns, ndots, search, err := getDefaultServers(app.QueryFlags.Strategy)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error fetching system default nameserver")
|
||||
}
|
||||
|
@ -117,18 +119,44 @@ func initNameserver(n string) (models.Nameserver, error) {
|
|||
return ns, nil
|
||||
}
|
||||
|
||||
func getDefaultServers() ([]models.Nameserver, int, []string, error) {
|
||||
func getDefaultServers(strategy string) ([]models.Nameserver, int, []string, error) {
|
||||
// Load nameservers from `/etc/resolv.conf`.
|
||||
dnsServers, ndots, search, err := config.GetDefaultServers()
|
||||
if err != nil {
|
||||
return nil, 0, nil, err
|
||||
}
|
||||
servers := make([]models.Nameserver, 0, len(dnsServers))
|
||||
for _, s := range dnsServers {
|
||||
|
||||
switch strategy {
|
||||
case "random":
|
||||
// Choose a random server from the list.
|
||||
rand.Seed(time.Now().Unix())
|
||||
srv := dnsServers[rand.Intn(len(dnsServers))]
|
||||
ns := models.Nameserver{
|
||||
Type: models.UDPResolver,
|
||||
Address: net.JoinHostPort(s, models.DefaultUDPPort),
|
||||
Address: net.JoinHostPort(srv, models.DefaultUDPPort),
|
||||
}
|
||||
servers = append(servers, ns)
|
||||
|
||||
case "first":
|
||||
// Choose the first from the list, always.
|
||||
srv := dnsServers[0]
|
||||
ns := models.Nameserver{
|
||||
Type: models.UDPResolver,
|
||||
Address: net.JoinHostPort(srv, models.DefaultUDPPort),
|
||||
}
|
||||
servers = append(servers, ns)
|
||||
|
||||
default:
|
||||
// Default behaviour is to load all nameservers.
|
||||
for _, s := range dnsServers {
|
||||
ns := models.Nameserver{
|
||||
Type: models.UDPResolver,
|
||||
Address: net.JoinHostPort(s, models.DefaultUDPPort),
|
||||
}
|
||||
servers = append(servers, ns)
|
||||
}
|
||||
}
|
||||
|
||||
return servers, ndots, search, nil
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ type QueryFlags struct {
|
|||
ShowJSON bool `koanf:"json" json:"-"`
|
||||
UseSearchList bool `koanf:"search" json:"-"`
|
||||
ReverseLookup bool `koanf:"reverse" reverse:"-"`
|
||||
Strategy string `koanf:"strategy" strategy:"-"`
|
||||
}
|
||||
|
||||
// Nameserver represents the type of Nameserver
|
||||
|
|
|
@ -18,6 +18,7 @@ type Options struct {
|
|||
Ndots int
|
||||
Timeout time.Duration
|
||||
Logger *logrus.Logger
|
||||
Strategy string
|
||||
}
|
||||
|
||||
// Resolver implements the configuration for a DNS
|
||||
|
|
Loading…
Reference in New Issue