fixed maybe, need to deduplicate results

This commit is contained in:
kayos@tcp.direct 2022-08-18 00:11:39 -07:00
parent a974cd7a35
commit 0ec09475d9
Signed by: kayos
GPG Key ID: 4B841471B4BEE979
6 changed files with 97 additions and 23 deletions

18
_example/log.go Normal file
View File

@ -0,0 +1,18 @@
package main
import (
"os"
"runtime"
"github.com/rs/zerolog"
)
var log zerolog.Logger
func init() {
log = zerolog.New(zerolog.ConsoleWriter{
Out: os.Stdout,
NoColor: runtime.GOOS == "windows",
}).With().Timestamp().Logger()
zerolog.SetGlobalLevel(zerolog.TraceLevel)
}

40
_example/main.go Normal file
View File

@ -0,0 +1,40 @@
package main
import (
"os"
"git.tcp.direct/kayos/name5"
)
func main() {
var nores []string
dnm := name5.NewDNSMap(os.Args[1])
println("\n----------ptr-\n")
for kv := range dnm.IPToPTR.IterBuffered() {
println("ip:", kv.Key, "ptr:", kv.Val.(string))
}
println("\n-------------\n")
for kv := range dnm.NameToIPs.IterBuffered() {
vals := kv.Val.(*name5.IPName)
if len(vals.IPs) == 0 {
nores = append(nores, kv.Key)
continue
}
println("name:", kv.Key)
if len(vals.IPs) == 1 {
print(vals.IPs[0] + "\n")
continue
}
for _, addr := range vals.IPs {
println(addr)
}
println("- - - - -")
}
if len(nores) < 1 {
return
}
println("\nobjects with no results:")
for _, name := range nores {
println(name)
}
}

View File

@ -11,17 +11,16 @@ import (
"github.com/rs/zerolog/log"
)
type ipname struct {
type IPName struct {
Name string
IPs []string
}
// DNSMap is used for resolving and keeping track of DNS query results and their relationships
type DNSMap struct {
IPToPTR cmap.ConcurrentMap
NameToIPs cmap.ConcurrentMap // map[string]*ipname
Working *int64
CNAMETargets *int64
IPToPTR cmap.ConcurrentMap
NameToIPs cmap.ConcurrentMap // map[string]*IPName
Working *int64
born *time.Time
ctx context.Context
@ -33,12 +32,11 @@ func newPtr(i int64) *int64 {
func (dnm *DNSMap) initCounters() {
dnm.Working = newPtr(0)
dnm.CNAMETargets = newPtr(0)
}
func (dnm *DNSMap) initMaps() {
dnm.IPToPTR = cmap.New()
dnm.NameToIPs = cmap.New() // make(map[string]*ipname)
dnm.NameToIPs = cmap.New() // make(map[string]*IPName)
}
// NewDNSMap creates a new DNSMap type
@ -47,6 +45,7 @@ func NewDNSMap(name string) *DNSMap {
name = dns.Fqdn(name)
dnsmap := &DNSMap{ // ipaddr[domain][ipaddr]boolean
born: &tn,
ctx: context.Background(),
}
dnsmap.initMaps()
@ -70,15 +69,20 @@ func NewDNSMap(name string) *DNSMap {
func (dnm *DNSMap) waitUntilDone() {
time.Sleep(1 * time.Second)
var count = 0
for {
select {
case <-dnm.ctx.Done():
return
default:
time.Sleep(5 * time.Second)
if atomic.LoadInt64(dnm.Working) == 0 &&
atomic.LoadInt64(dnm.CNAMETargets) == 0 {
return
time.Sleep(1250 * time.Millisecond)
if atomic.LoadInt64(dnm.Working) <= 0 {
count++
if count > 2 {
return
}
} else {
log.Trace().Msgf("Waiting for %d DNS queries to finish", atomic.LoadInt64(dnm.Working))
}
}
}
@ -96,30 +100,27 @@ func (dnm *DNSMap) chipOff(delay int) {
}
func (dnm *DNSMap) process(in *dns.Msg) {
defer dnm.chipOff(100)
question := in.Question[0].Name
var addrs []string
for _, resource := range in.Answer {
log.Trace().Int64("working", atomic.LoadInt64(dnm.Working)).
Interface("resource", resource).Msg("working...")
/*log.Trace().Int64("working", atomic.LoadInt64(dnm.Working)).
Interface("resource", resource).Msg("working...")*/
switch record := resource.(type) {
case *dns.NULL:
log.Error().Caller().Msg(record.Data)
dnm.chipOff(500)
continue
case *dns.A:
a := record.A.String()
addrs = append(addrs, a)
atomic.AddInt64(dnm.Working, 1)
go dnm.process(QueryPTR(a))
dnm.chipOff(100)
case *dns.AAAA:
aaaa := record.AAAA.String()
addrs = append(addrs, aaaa)
atomic.AddInt64(dnm.Working, 1)
go dnm.process(QueryPTR(aaaa))
dnm.chipOff(100)
case *dns.PTR:
ptr := record.Ptr
ogIP, ok := arpaToIP.Get(in.Question[0].Name)
@ -133,7 +134,6 @@ func (dnm *DNSMap) process(in *dns.Msg) {
go dnm.process(Query4(ptr))
go dnm.process(Query6(ptr))
}
dnm.chipOff(100)
case *dns.CNAME:
cname := record.Target
if !dnm.NameToIPs.Has(cname) {
@ -141,20 +141,19 @@ func (dnm *DNSMap) process(in *dns.Msg) {
go dnm.process(Query4(cname))
go dnm.process(Query6(cname))
}
dnm.chipOff(100)
default:
log.Warn().Caller().Interface("resource", record).Msg("unhandled record")
}
}
if len(addrs) < 0 {
if len(addrs) < 0 || in.Question[0].Qtype == dns.TypePTR {
return
}
current, ok := dnm.NameToIPs.Get(question)
if !ok {
dnm.NameToIPs.Set(question, &ipname{Name: question, IPs: addrs})
dnm.NameToIPs.Set(question, &IPName{Name: question, IPs: addrs})
return
}
resolved := current.(*ipname)
resolved := current.(*IPName)
resolved.IPs = append(resolved.IPs, addrs...)
dnm.NameToIPs.Set(question, resolved)
}

2
go.mod
View File

@ -6,12 +6,14 @@ require (
github.com/miekg/dns v1.1.50
github.com/orcaman/concurrent-map v1.0.0
github.com/rs/zerolog v1.27.0
github.com/yunginnanet/Rate5 v1.1.0
inet.af/netaddr v0.0.0-20220811202034-502d2d690317
)
require (
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
go4.org/intern v0.0.0-20211027215823-ae77deb06f29 // indirect
go4.org/unsafe/assume-no-moving-gc v0.0.0-20220617031537-928513b29760 // indirect
golang.org/x/mod v0.4.2 // indirect

4
go.sum
View File

@ -9,12 +9,16 @@ 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/orcaman/concurrent-map v1.0.0 h1:I/2A2XPCb4IuQWcQhBhSwGfiuybl/J0ev9HDbW65HOY=
github.com/orcaman/concurrent-map v1.0.0/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.27.0 h1:1T7qCieN22GVc8S4Q2yuexzBb1EqjbgjSH9RohbMjKs=
github.com/rs/zerolog v1.27.0/go.mod h1:7frBqO0oezxmnO7GF86FY++uy8I0Tk/If5ni1G9Qc0U=
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/yunginnanet/Rate5 v1.1.0 h1:FGp+IwKju0cTrrM3VffZGZiFgRt1jFXOWRCPwB1HPek=
github.com/yunginnanet/Rate5 v1.1.0/go.mod h1:f0r66kVQZojRqUgVdLC/CKexMlF0nUDAmd01tBeF4Ms=
go4.org/intern v0.0.0-20211027215823-ae77deb06f29 h1:UXLjNohABv4S58tHmeuIZDO6e3mHpW2Dx33gaNt03LE=
go4.org/intern v0.0.0-20211027215823-ae77deb06f29/go.mod h1:cS2ma+47FKrLPdXFpr7CuxiTW3eyJbWew4qx0qtQWDA=
go4.org/unsafe/assume-no-moving-gc v0.0.0-20211027215541-db492cf91b37/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E=

View File

@ -7,9 +7,20 @@ import (
"github.com/miekg/dns"
cmap "github.com/orcaman/concurrent-map"
"github.com/rs/zerolog/log"
rl "github.com/yunginnanet/Rate5"
"inet.af/netaddr"
)
var (
dnsResolver = "127.0.0.1:53"
dnsRater *rl.Limiter
dnsTimeout = 5 // Seconds
)
func init() {
dnsRater = rl.NewLimiter(5, 50)
}
// TODO: benchmarks
// TODO: better ratelimiting logic
// global dummy type for rater