From 358c5ee72207c37712e44edcdb479c97f1266c8a Mon Sep 17 00:00:00 2001 From: Shulhan Date: Thu, 14 Apr 2022 22:47:33 +0700 Subject: cmd/resolver: implement caches command The caches command fetch and print all caches from rescached server. --- cmd/resolver/main.go | 68 +++++++++++++++++++++++++++++++++----------- cmd/resolver/resolver.go | 73 ++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 116 insertions(+), 25 deletions(-) (limited to 'cmd/resolver') diff --git a/cmd/resolver/main.go b/cmd/resolver/main.go index 49ba6a6..98e448d 100644 --- a/cmd/resolver/main.go +++ b/cmd/resolver/main.go @@ -15,7 +15,8 @@ import ( // List of valid commands. const ( - cmdQuery = "query" + cmdCaches = "caches" + cmdQuery = "query" ) func main() { @@ -28,8 +29,9 @@ func main() { log.SetFlags(0) + flag.BoolVar(&rsol.insecure, "insecure", false, "Ignore invalid server certificate.") flag.StringVar(&rsol.nameserver, "ns", "", "Parent name server address using scheme based.") - flag.BoolVar(&rsol.insecure, "insecure", false, "Ignore invalid server certificate") + flag.StringVar(&rsol.rescachedUrl, "server", defRescachedUrl, "Set the rescached HTTP server.") flag.BoolVar(&optHelp, "h", false, "") flag.Parse() @@ -49,6 +51,9 @@ func main() { rsol.cmd = strings.ToLower(args[0]) switch rsol.cmd { + case cmdCaches: + rsol.doCmdCaches() + case cmdQuery: args = args[1:] if len(args) == 0 { @@ -69,25 +74,36 @@ func help() { == Usage - resolver [-ns nameserver] [-insecure] + resolver [-insecure] [-ns nameserver] [-server] [args...] == Options -Accepted command is query. +The following options affect the commands operation. + +-insecure + + Ignore invalid server certificate when querying DoT, DoH, or rescached + server. -ns nameserver Parent name server address using scheme based. For example, - udp://35.240.172.103:53 for querying with UDP, - tcp://35.240.172.103:53 for querying with TCP, - https://35.240.172:103:853 for querying with DNS over TLS (DoT), and - https://kilabit.info/dns-query for querying with DNS over HTTPS (DoH). --insecure + * udp://35.240.172.103:53 for querying with UDP, + * tcp://35.240.172.103:53 for querying with TCP, + * https://35.240.172:103:853 for querying with DNS over TLS (DoT), and + * https://kilabit.info/dns-query for querying with DNS over HTTPS + (DoH). - Ignore invalid server certificate when querying DoT, DoH, or rescached - server. +-server + + Set the location of rescached HTTP server where commands will send. + The rescached-URL use HTTP scheme: + + ("http" / "https") "://" (domain / ip-address) [":" port] + + Default to "https://127.0.0.1:5380" if its empty. == Commands @@ -105,19 +121,37 @@ query [type] [class] Valid class are either IN, CS, HS. Default value is IN. +caches + + Fetch and print all caches from rescached server. + == Examples -Query the MX records using UDP on name server 35.240.172.103, +Query the IPv4 address for kilabit.info, + + $ resolver query kilabit.info - $ resolver -ns udp://35.240.172.103 query kilabit.info MX +Query the mail exchange (MX) for domain kilabit.info, -Query the IPv4 records of domain name "kilabit.info" using DNS over TLS on -name server 35.240.172.103, + $ resolver query kilabit.info MX - $ resolver -ns https://35.240.172.103 -insecure query kilabit.info +Query the IPv4 address for kilabit.info using 127.0.0.1 at port 53 as +name server, + + $ resolver -ns=udp://127.0.0.1:53 query kilabit.info + +Query the IPv4 address of domain name "kilabit.info" using DNS over TLS at +name server 194.233.68.184, + + $ resolver -insecure -ns=https://194.233.68.184 query kilabit.info Query the IPv4 records of domain name "kilabit.info" using DNS over HTTPS on name server kilabit.info, - $ resolver -ns https://kilabit.info/dns-query query kilabit.info`) + $ resolver -insecure -ns=https://kilabit.info/dns-query query kilabit.info + +Inspect the rescached's caches on server at http://127.0.0.1:5380 + + $ resolver -server=http://127.0.0.1:5380 caches +`) } diff --git a/cmd/resolver/resolver.go b/cmd/resolver/resolver.go index 19cebaf..c9f172e 100644 --- a/cmd/resolver/resolver.go +++ b/cmd/resolver/resolver.go @@ -10,16 +10,18 @@ import ( "strings" "time" + "github.com/shuLhan/rescached-go/v4" "github.com/shuLhan/share/lib/dns" libnet "github.com/shuLhan/share/lib/net" ) const ( - defAttempts = 1 - defQueryType = "A" - defQueryClass = "IN" - defResolvConf = "/etc/resolv.conf" - defTimeout = 5 * time.Second + defAttempts = 1 + defQueryType = "A" + defQueryClass = "IN" + defRescachedUrl = "http://127.0.0.1:5380" + defResolvConf = "/etc/resolv.conf" + defTimeout = 5 * time.Second ) type resolver struct { @@ -31,13 +33,68 @@ type resolver struct { sqtype string sqclass string - nameserver string - qtype dns.RecordType - qclass dns.RecordClass + nameserver string + rescachedUrl string + + qtype dns.RecordType + qclass dns.RecordClass insecure bool } +func (rsol *resolver) doCmdCaches() { + var ( + resc *rescached.Client + answer *dns.Answer + answers []*dns.Answer + format string + header string + line strings.Builder + err error + x int + maxNameLen int + ) + + if len(rsol.rescachedUrl) == 0 { + rsol.rescachedUrl = defRescachedUrl + } + + resc = rescached.NewClient(rsol.rescachedUrl, rsol.insecure) + + answers, err = resc.Caches() + if err != nil { + log.Printf("resolver: caches: %s", err) + return + } + + fmt.Printf("Total caches: %d\n", len(answers)) + + for _, answer = range answers { + if len(answer.QName) > maxNameLen { + maxNameLen = len(answer.QName) + } + } + + format = fmt.Sprintf("%%4s | %%%ds | %%4s | %%5s | %%30s | %%30s", maxNameLen) + header = fmt.Sprintf(format, "#", "Name", "Type", "Class", "Received at", "Accessed at") + for x = 0; x < len(header); x++ { + line.WriteString("-") + } + fmt.Println(line.String()) + fmt.Println(header) + fmt.Println(line.String()) + + format = fmt.Sprintf("%%4d | %%%ds | %%4s | %%5s | %%30s | %%30s\n", maxNameLen) + for x, answer = range answers { + fmt.Printf(format, x, answer.QName, + dns.RecordTypeNames[answer.RType], + dns.RecordClassName[answer.RClass], + time.Unix(answer.ReceivedAt, 0), + time.Unix(answer.AccessedAt, 0), + ) + } +} + func (rsol *resolver) doCmdQuery(args []string) { var ( maxAttempts = defAttempts -- cgit v1.3