DNS library in Go

Overview

Build Status Code Coverage Go Report Card

Alternative (more granular) approach to a DNS library

Less is more.

Complete and usable DNS library. All Resource Records are supported, including the DNSSEC types. It follows a lean and mean philosophy. If there is stuff you should know as a DNS programmer there isn't a convenience function for it. Server side and client side programming is supported, i.e. you can build servers and resolvers with it.

We try to keep the "master" branch as sane as possible and at the bleeding edge of standards, avoiding breaking changes wherever reasonable. We support the last two versions of Go.

Goals

  • KISS;
  • Fast;
  • Small API. If it's easy to code in Go, don't make a function for it.

Users

A not-so-up-to-date-list-that-may-be-actually-current:

Send pull request if you want to be listed here.

Features

  • UDP/TCP queries, IPv4 and IPv6
  • RFC 1035 zone file parsing ($INCLUDE, $ORIGIN, $TTL and $GENERATE (for all record types) are supported
  • Fast
  • Server side programming (mimicking the net/http package)
  • Client side programming
  • DNSSEC: signing, validating and key generation for DSA, RSA, ECDSA and Ed25519
  • EDNS0, NSID, Cookies
  • AXFR/IXFR
  • TSIG, SIG(0)
  • DNS over TLS (DoT): encrypted connection between client and server over TCP
  • DNS name compression

Have fun!

Miek Gieben - 2010-2012 - [email protected] DNS Authors 2012-

Building

This library uses Go modules and uses semantic versioning. Building is done with the go tool, so the following should work:

go get github.com/miekg/dns
go build github.com/miekg/dns

Examples

A short "how to use the API" is at the beginning of doc.go (this also will show when you call godoc github.com/miekg/dns).

Example programs can be found in the github.com/miekg/exdns repository.

Supported RFCs

all of them

  • 103{4,5} - DNS standard
  • 1348 - NSAP record (removed the record)
  • 1982 - Serial Arithmetic
  • 1876 - LOC record
  • 1995 - IXFR
  • 1996 - DNS notify
  • 2136 - DNS Update (dynamic updates)
  • 2181 - RRset definition - there is no RRset type though, just []RR
  • 2537 - RSAMD5 DNS keys
  • 2065 - DNSSEC (updated in later RFCs)
  • 2671 - EDNS record
  • 2782 - SRV record
  • 2845 - TSIG record
  • 2915 - NAPTR record
  • 2929 - DNS IANA Considerations
  • 3110 - RSASHA1 DNS keys
  • 3123 - APL record
  • 3225 - DO bit (DNSSEC OK)
  • 340{1,2,3} - NAPTR record
  • 3445 - Limiting the scope of (DNS)KEY
  • 3597 - Unknown RRs
  • 403{3,4,5} - DNSSEC + validation functions
  • 4255 - SSHFP record
  • 4343 - Case insensitivity
  • 4408 - SPF record
  • 4509 - SHA256 Hash in DS
  • 4592 - Wildcards in the DNS
  • 4635 - HMAC SHA TSIG
  • 4701 - DHCID
  • 4892 - id.server
  • 5001 - NSID
  • 5155 - NSEC3 record
  • 5205 - HIP record
  • 5702 - SHA2 in the DNS
  • 5936 - AXFR
  • 5966 - TCP implementation recommendations
  • 6605 - ECDSA
  • 6725 - IANA Registry Update
  • 6742 - ILNP DNS
  • 6840 - Clarifications and Implementation Notes for DNS Security
  • 6844 - CAA record
  • 6891 - EDNS0 update
  • 6895 - DNS IANA considerations
  • 6944 - DNSSEC DNSKEY Algorithm Status
  • 6975 - Algorithm Understanding in DNSSEC
  • 7043 - EUI48/EUI64 records
  • 7314 - DNS (EDNS) EXPIRE Option
  • 7477 - CSYNC RR
  • 7828 - edns-tcp-keepalive EDNS0 Option
  • 7553 - URI record
  • 7858 - DNS over TLS: Initiation and Performance Considerations
  • 7871 - EDNS0 Client Subnet
  • 7873 - Domain Name System (DNS) Cookies
  • 8080 - EdDSA for DNSSEC
  • 8499 - DNS Terminology

Loosely Based Upon

Issues
  • [ISSUE-95] Send replies from the right source IP address

    [ISSUE-95] Send replies from the right source IP address

    Fixes #95

    I didn't test this enough, but lets see what you have to say about it :) I tried to keep it as simple as possible.

    This has to be tested with IPv6. I guess that IPv6 is not supported yet (shouldn't be too hard to add IPv6 support though), but first lets make sure it doesn't break it.

    opened by omribahumi 49
  • Implement SVCB

    Implement SVCB

    Resolves #1064

    Seems to work well. Can be tested with @ghedo's python code and his Go code (Now my code uses the same numbers. I've updated his Go code, below, to work with the new edns-like code:)

    package main
    
    import (
    	"fmt"
    	"github.com/DesWurstes/dns"
    	"net"
    	"sync"
    )
    
    func handleRequest(w dns.ResponseWriter, r *dns.Msg) {
    	fmt.Println("GOT REQUEST", r)
    
    	m := new(dns.Msg)
    	m.SetReply(r)
    
    	svcb := &dns.SVCB{
    		Hdr: dns.RR_Header{
    			Name:   r.Question[0].Name,
    			Rrtype: dns.TypeSVCB,
    			Class:  dns.ClassINET,
    			Ttl:    3600,
    		},
    		Priority: 1,
    		Target:   ".",
    		Value: []dns.SVCBKeyValue{
    			&dns.SVCBAlpn{
    				Alpn: []string{"h2", "h3"},
    			},
    			&dns.SVCBPort{
    				Port: 117,
    			},
    			&dns.SVCBIPv4Hint{
    				Hint: []net.IP{net.IPv4(1, 1, 1, 1), net.IPv4(1, 1, 1, 2)},
    			},
    			&dns.SVCBECHConfig{
    				ECH: []byte{1, 2},
    			},
    		},
    	}
    
    	m.Answer = append(m.Answer, svcb)
    	err := w.WriteMsg(m)
    	if err != nil {
    		fmt.Println(err)
    	}
    }
    
    func main() {
    	var wg sync.WaitGroup
    	wg.Add(1)
    
    	dns.HandleFunc("svcb.example.", handleRequest)
    
    	server := &dns.Server{Addr: ":53", Net: "udp"}
    	go server.ListenAndServe()
    
    	wg.Wait()
    }
    
    opened by DesWurstes 46
  • GSS-TSIG support

    GSS-TSIG support

    Would it be possible to add support for GSS-TSIG (RFC 3645)? This would make it possible to perform secure DNS updates to a Windows Active Directory environment, which AFAICT doesn't support normal TSIG updates. I figured maybe https://github.com/jcmturner/gokrb5 could be useful to do the Kerberos side of things.

    question 
    opened by bodgit 46
  • Request spike use CPU and memory

    Request spike use CPU and memory

    These are two issues that are interesting:

    • https://github.com/coredns/coredns/issues/2593
    • https://github.com/coredns/coredns/issues/2624

    Both are not reproduced in a minimal setting and I failed reproducing it.

    It looks like if you restrain the CPU a process has it can get behind and (in some cases) never recover. One way this can show up in this library is too many worker goroutines.

    I took a quick look at the code in server.go, in this comment at the top of the file looked a bit ominous:

    // The maximum number of idle workers.
    //
    // This controls the maximum number of workers that are allowed to stay
    // idle waiting for incoming requests before being torn down.
    //
    // If this limit is reached, the server will just keep spawning new
    // workers (goroutines) for each incoming request. In this case, each
    // worker will only be used for a single request.
    const maxIdleWorkersCount = 10000
    

    esp. the last paragraph.

    As said, I'm not sure how best to repro this (just sit on queries for 10 seconds?), but if we can it would help to debug the above issues and would be a good (unit) test in general.

    opened by miekg 43
  • Fix Server.Shutdown() error

    Fix Server.Shutdown() error

    • Ignore TCP server shutdown returns excepted error(use of closed network connection)
    • Make sure server re-serve works do after shutdown
    • Fix server.inFlight race
    • WaitGroup deadlock(=.= hanging
    opened by oif 41
  • More efficient A record (un)packing

    More efficient A record (un)packing

    The generic struct pack and unpack routines make heavy use of reflection to correctly translate between bytes and Go objects.

    Given most questions and answers are A records, writing a specific A record packer/unpacker makes the fast path quicker and generates significantly less garbage.

    The pack and unpack routines for specific data types were extracted from the generic routine so that they may be shared with the optimised routines.

    Results of go test -bench \(Unp\|P\)ackRRA

    | Benchmark | Iterations | ns/op | B/op | allocs/op | | --- | --- | --- | --- | --- | | BenchmarkPackRRA (before) | 2000000 | 688 ns/op | 112 B/op | 7 allocs/op | | BenchmarkPackRRA (after) | 20000000 | 85.9 ns/op | 0 B/op | 0 allocs/op | | BenchmarkUnpackRRA (before) | 1000000 | 1443 ns/op | 272 B/op | 12 allocs/op | | BenchmarkUnpackRRA (after) | 5000000 | 290 ns/op | 128 B/op | 4 allocs/op |

    opened by cbranch 34
  • Properly interpret relative names in master files

    Properly interpret relative names in master files

    This library has a nasty habit of interpreting domain names relative to the DNS root when it shouldn't. Per RFC 1035, "A relative name is an error when no origin is available" and we should emit an error token from ParseZone when encountering such a case.

    This bug was originally reported with a mistaken assumption of initial origin, which uncovered the above issue:

    Original report A fix will probably be big, but we're doing the wrong thing right now:
    input
    example.com. 3600 IN SOA ns1.example.com. hostmaster 1 (
    	86400
    	   60
    	86400
    	 3600
    ) ; SOA with relative RNAME
    
    	NS ns1 ; implied-owner NS with implied TTL/CLASS and relative-domain RDATA
    
    ns1 60 A 192.0.2.1 ; relative owner with implied CLASS
    
    $ORIGIN api ; relative origin
    
    @ IN A 192.0.2.2 ; origin-shorthand owner with implied TTL
    
    apac 30 CNAME @ ; relative owner with implied CLASS and origin-shorthand RDATA
    
    $ORIGIN NA ; relative origin relative to existing origin
    
    @ 30 IN CNAME cdn.example ; origin-shorthand owner with relative RDATA
    cdn.example.NA.api.example.com. 60 IN A 192.0.2.3
    
    ParseZone output
    ; SOA with relative RNAME
    ; mismatch, expected:
    ; example.com.	3600	IN	SOA	ns1.example.com. hostmaster.example.com. 1 86400 60 86400 3600
    example.com.	3600	IN	SOA	ns1.example.com. hostmaster. 1 86400 60 86400 3600
    
    ; implied-owner NS with implied TTL/CLASS and relative-domain RDATA
    ; mismatch, expected:
    ; example.com.	3600	IN	NS	ns1.example.com.
    example.com.	3600	IN	NS	ns1.
    
    ; relative owner with implied CLASS
    ; mismatch, expected:
    ; ns1.example.com.	60	IN	A	192.0.2.1
    ns1.	60	IN	A	192.0.2.1
    
    ; origin-shorthand owner with implied TTL
    ; mismatch, expected:
    ; api.example.com.	60	IN	A	192.0.2.2
    api.	3600	IN	A	192.0.2.2
    
    ; relative owner with implied CLASS and origin-shorthand RDATA
    ; mismatch, expected:
    ; apac.api.example.com.	30	IN	CNAME	api.example.com.
    apac.api.	30	IN	CNAME	api.
    
    ; origin-shorthand owner with relative RDATA
    ; mismatch, expected:
    ; NA.api.example.com.	30	IN	CNAME	cdn.example.NA.api.example.com.
    NA.api.	30	IN	CNAME	cdn.example.NA.api.
    
    ; match
    cdn.example.NA.api.example.com.	60	IN	A	192.0.2.3
    
    diff
    --- actual
    +++ expected
     ; SOA with relative RNAME
    -example.com.	3600	IN	SOA	ns1.example.com. hostmaster. 1 86400 60 86400 3600
    +example.com.	3600	IN	SOA	ns1.example.com. hostmaster.example.com. 1 86400 60 86400 3600
     
     ; implied-owner NS with implied TTL/CLASS and relative-domain RDATA
    -example.com.	3600	IN	NS	ns1.
    +example.com.	3600	IN	NS	ns1.example.com.
     
     ; relative owner with implied CLASS
    -ns1.	60	IN	A	192.0.2.1
    +ns1.example.com.	60	IN	A	192.0.2.1
     
     ; origin-shorthand owner with implied TTL
    -api.	3600	IN	A	192.0.2.2
    +api.example.com.	60	IN	A	192.0.2.2
     
     ; relative owner with implied CLASS and origin-shorthand RDATA
    -apac.api.	30	IN	CNAME	api.
    +apac.api.example.com.	30	IN	CNAME	api.example.com.
     
     ; origin-shorthand owner with relative RDATA
    -NA.api.	30	IN	CNAME	cdn.example.NA.api.
    +NA.api.example.com.	30	IN	CNAME	cdn.example.NA.api.example.com.
     cdn.example.NA.api.example.com.	60	IN	A	192.0.2.3
    
    opened by gibson042 32
  • Using 'ANY' as class in presentation format

    Using 'ANY' as class in presentation format

    This works fine x, xErr := NewRR("www.miek.nl. 3600 IN TXT "first" "second"")

    but this doesn't: x, xErr := NewRR("www.miek.nl. 3600 ANY TXT "first" "second"") if xErr != nil { t.Fatalf("failed to parse TXT: %s", xErr) }

    it fails with the following error: dns_test.go:461: failed to parse TXT: dns: unknown RR type: "TXT" at line: 1:26

    I assume this should work - or am I confused?

    bug 
    opened by spsholleman 31
  • Provide zp.ClearError()

    Provide zp.ClearError()

    Various zone files distributed by ICANN via the CZDS as well as via direct interfaces provided by the respective registry operator, contain malformed or bogus records.

    Examples at the time of this writing include .us as distributed by Neustar and .tel as available through the CZDS.

    High-performance processing pipelines can benefit from filtering those bogus records on the fly.

    The ClearError() method allows these classes of applications to simply have the parser state machine to step through these errors without changing the parser or otherwise affecting its correctness.

    opened by nerdlem 29
  • Memory Leak in github.com/miekg/dns.parseZone

    Memory Leak in github.com/miekg/dns.parseZone

    I'm using coredns 1.2.2 with the built-in file plugin (https://github.com/coredns/coredns/tree/master/plugin/file) to serve a few RFC 1035 master zone files. coredns uses github.com/miekg/dns. I'm also using the more resent version of Go (1.11.1).

    In this configuration, coredns memory usage grows steadily and crashes after about 18 hours with an OOM error with a server that contains 2GB of memory. Here's a snippet from the coredns log file showing the crash:

    2018/10/10 13:56:17 [INFO] CoreDNS-1.2.2 2018/10/10 13:56:17 [INFO] linux/amd64, go1.11.1, 8a9c6174 ... 1360 fatal error: runtime: out of memory 1361 1362 runtime stack: 1363 runtime.throw(0x192f945, 0x16) 1364 /home/ubuntu/go1.11/src/runtime/panic.go:608 +0x72 1365 runtime.sysMap(0xc064000000, 0x4000000, 0x29ef978) 1366 /home/ubuntu/go1.11/src/runtime/mem_linux.go:156 +0xc7 1367 runtime.(*mheap).sysAlloc(0x29d59a0, 0x4000000, 0x29d59b8, 0x7fd3ecb43a28) 1368 /home/ubuntu/go1.11/src/runtime/malloc.go:619 +0x1c7 1369 runtime.(*mheap).grow(0x29d59a0, 0x1, 0x0) 1370 /home/ubuntu/go1.11/src/runtime/mheap.go:920 +0x42 1371 runtime.(*mheap).allocSpanLocked(0x29d59a0, 0x1, 0x29ef988, 0x0) 1372 /home/ubuntu/go1.11/src/runtime/mheap.go:848 +0x337 1373 runtime.(*mheap).alloc_m(0x29d59a0, 0x1, 0x430008, 0xc000044500) 1374 /home/ubuntu/go1.11/src/runtime/mheap.go:692 +0x119 1375 runtime.(*mheap).alloc.func1() 1376 /home/ubuntu/go1.11/src/runtime/mheap.go:759 +0x4c 1377 runtime.(*mheap).alloc(0x29d59a0, 0x1, 0xc000010008, 0x432339) 1378 /home/ubuntu/go1.11/src/runtime/mheap.go:758 +0x8a 1379 runtime.(*mcentral).grow(0x29d6ed8, 0x0) 1380 /home/ubuntu/go1.11/src/runtime/mcentral.go:232 +0x94 1381 runtime.(*mcentral).cacheSpan(0x29d6ed8, 0xc063aef0d8) 1382 /home/ubuntu/go1.11/src/runtime/mcentral.go:106 +0x2f8 1383 runtime.(*mcache).refill(0x7fd3f5229000, 0xc0000a7b08) 1384 /home/ubuntu/go1.11/src/runtime/mcache.go:122 +0x95 1385 runtime.(*mcache).nextFree.func1() 1386 /home/ubuntu/go1.11/src/runtime/malloc.go:749 +0x32 1387 runtime.systemstack(0xc00008cd00) 1388 /home/ubuntu/go1.11/src/runtime/asm_amd64.s:351 +0x66 1389 runtime.mstart() 1390 /home/ubuntu/go1.11/src/runtime/proc.go:1229 1392 goroutine 4058 [running]: 1393 runtime.systemstack_switch() 1394 /home/ubuntu/go1.11/src/runtime/asm_amd64.s:311 fp=0xc0620b7508 sp=0xc0620b7500 pc=0x45a340 1395 runtime.(*mcache).nextFree(0x7fd3f5229000, 0x8, 0xc06370d3c0, 0x0, 0xc000146a80) 1396 /home/ubuntu/go1.11/src/runtime/malloc.go:748 +0xb6 fp=0xc0620b7560 sp=0xc0620b7508 pc=0x40b7b6 1397 runtime.mallocgc(0x30, 0x176dfc0, 0x1, 0xc06370d3c0) 1398 /home/ubuntu/go1.11/src/runtime/malloc.go:903 +0x793 fp=0xc0620b7600 sp=0xc0620b7560 pc=0x40c103 1399 runtime.newobject(0x176dfc0, 0x446d56) 1400 /home/ubuntu/go1.11/src/runtime/malloc.go:1032 +0x38 fp=0xc0620b7630 sp=0xc0620b7600 pc=0x40c4e8 1401 github.com/miekg/dns.setCNAME(0xc063ff3770, 0x23, 0x3c00010005, 0x0, 0xc063aef080, 0xc0000a1d86, 0x12, 0xc000092b40, 0x22, 0x23, ...) 1402 /home/ubuntu/go/src/github.com/miekg/dns/scan_rr.go:515 +0x3f fp=0xc0620b7730 sp=0xc0620b7630 pc=0x71d01f 1403 github.com/miekg/dns.setRR(0xc063ff3770, 0x23, 0x3c00010005, 0x0, 0xc063aef080, 0xc0000a1d86, 0x12, 0xc000092b40, 0x22, 0x1b68b80, ...) 1404 /home/ubuntu/go/src/github.com/miekg/dns/scan_rr.go:29 +0xdd fp=0xc0620b78c0 sp=0xc0620b7730 pc=0x71731d 1405 github.com/miekg/dns.parseZone(0x1b44740, 0xc00000cea0, 0xc0000a1d86, 0x12, 0xc000092b40, 0x22, 0xc014998348, 0xc063256180, 0x0) 1406 /home/ubuntu/go/src/github.com/miekg/dns/scan.go:469 +0x1fdc fp=0xc0620b7f98 sp=0xc0620b78c0 pc=0x71292c 1407 runtime.goexit() 1408 /home/ubuntu/go1.11/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc0620b7fa0 sp=0xc0620b7f98 pc=0x45c2a1 1409 created by github.com/miekg/dns.parseZoneHelper 1410 /home/ubuntu/go/src/github.com/miekg/dns/scan.go:162 +0xc3

    I enabled profiling in the coredns config file and have been watching the heap. Here are two examples showing this issue. Notice that github.com/miekg/dns.parseZone grows continually by about 100MB each hour:

    File: coredns Type: inuse_space Time: Oct 11, 2018 at 3:43pm (EDT) Entering interactive mode (type "help" for commands, "o" for options) (pprof) top5 Showing nodes accounting for 385.64MB, 95.53% of 403.68MB total Dropped 11 nodes (cum <= 2.02MB) Showing top 5 nodes out of 23 flat flat% sum% cum cum% 106MB 26.26% 26.26% 303.02MB 75.06% github.com/miekg/dns.parseZone 98.50MB 24.40% 50.66% 98.50MB 24.40% github.com/miekg/dns.appendOrigin (inline) 98MB 24.28% 74.94% 98MB 24.28% github.com/miekg/dns.setCNAME 68MB 16.85% 91.78% 68MB 16.85% github.com/miekg/dns.zlexer 15.12MB 3.75% 95.53% 15.12MB 3.75% github.com/miekg/dns.parseZoneHelper

    File: coredns Type: inuse_space Time: Oct 11, 2018 at 4:58pm (EDT) Entering interactive mode (type "help" for commands, "o" for options) (pprof) top5 Showing nodes accounting for 512.96MB, 96.51% of 531.51MB total Dropped 11 nodes (cum <= 2.66MB) Showing top 5 nodes out of 23 flat flat% sum% cum cum% 138.01MB 25.96% 25.96% 138.01MB 25.96% github.com/miekg/dns.appendOrigin (inline) 137.51MB 25.87% 51.84% 404.02MB 76.01% github.com/miekg/dns.parseZone 127.51MB 23.99% 75.83% 127.51MB 23.99% github.com/miekg/dns.setCNAME 90.50MB 17.03% 92.85% 90.50MB 17.03% github.com/miekg/dns.zlexer

    Here is the coredns config file I am using: coredns.conf.txt

    The zone files being served have about 100,000 records.

    Thanks,

    Brad

    opened by 62726164 27
  • Client's Exchange always creates new socket

    Client's Exchange always creates new socket

    There is issue I'm observing while trying to create fast moving tool with your library (which is great).

    On high levels of concurrency, when I let goroutines run wild I'm getting "dial udp a.b.c.d:53: too many open files" error.

    IMO that's due to client's exchange logic that only has single way of doing things ritght now, "Exchange() -> dial()/send()->write()/receive()->read()"

    That will essentially create socket in OS for every operation and send/receive on it via "send and recv". Sendto and recvfrom in my situation would be most efficient but syscall lib is very hard to deal with, I'm trying to find simpler solutions...

    IMO other version of Exchange could have additional net.Conn parameter for clients who send bunch of requests to same address... As coder I'd expect it this way:

    dnsconn := c.Dial(addr)
    for _, msg := range queries {
        resp, rtt, err := c.ExchangeWith(dnsconn)
        if err {
             ...
        }
        ...
    }
    

    Should not be hard to implement... You might suggest different way of handling that. I understand that retrying logic might require to keep more than one net.Conn inside of that "dnsconn" structure.

    opened by asergeyev 27
  • Parsing TXT records does not properly de-escape quotes

    Parsing TXT records does not properly de-escape quotes

    When calling NewRR() on a TXT record, an escaped quote isn't properly de-escaped.

    A line such as:

    example.com. IN TXT "inner\"quote"
    

    It gets parsed to: inner\"quote I was expecting: inner"quote

    Maybe I'm misreading the RFC? It just seems that without removing the \ there's no way to know what the \ means in the resulting string.

    I've created https://github.com/miekg/dns/pull/1383 to demonstrate the issue.

    opened by TomOnTime 2
  • A.copy does not preserve the nilness of A.IP

    A.copy does not preserve the nilness of A.IP

    In short:

    package main
    
    import (
    	"fmt"
    
    	"github.com/miekg/dns"
    )
    
    func main() {
    	a := &dns.A{}
    	a2 := dns.Copy(a).(*dns.A)
    	fmt.Println(a.A == nil, a2.A == nil)
    }
    
    true false
    

    https://go.dev/play/p/1i32nD_s_GY

    We've recently stumbled upon this while performing some tests. We had some code that returned a net.IP from *dns.Msg data, and another piece of code that assumed that the returned net.IP is either nil or a valid net.IP. But it seems that if the response contains a *dns.A RR with a nil net.IP, and that response is then copied, that nilness is lost, and the copy now contains an empty, non-nil net.IP.

    opened by ainar-g 0
  • TSIGProvider Generate and Verify functions don't have access to the DNS Message

    TSIGProvider Generate and Verify functions don't have access to the DNS Message

    This causes problems on zone transfers where the server is hosting many different zone names. Passing the DNS Message via the context as a parameter opens up many possibilities for how TSIGs are handled. For example:

    1. We could use a sync.RWMutex to ensure that even after the server has been started, TSIGs can be rotated out of band without worrying about data races.
    2. We could allow multiple zones with different names to support TSIGs with the same name.

    There is many more possibilities that this could open up. I.E Zone specific TSIG verification/Generation.

    opened by Fattouche 1
  • dns.Exchange is slow compared to the rtt value

    dns.Exchange is slow compared to the rtt value

    Hi @miekg, first of all, thanks for this awesome package.

    I'm using it for educational purposes and I'm trying to build my own dns proxy, and I found the Exchange function. But, I have some issues with it in terms of response time compared to the resolution time in the remote server.

    for example

    now := time.Now()
    dnsClient := &dns.Client{Net: "udp"}
    response, rtt, _ := dnsClient.Exchange(m, "8.8.8.8:53")
    afterExchange := time.Now()
    
    fmt.Printf("rtt: %+v, exchange time: %+v\n", rtt, afterExchange.Sub(now))
    

    Debugging this code using dig I got the following outputs:

    dig @127.0.0.1 www.google.com
    
    rtt: 14.973578ms, exchange time: 1.015674963s
    rtt: 14.97958ms, exchange time: 1.015913842s
    rtt: 13.814305ms, exchange time: 1.014382583s
    rtt: 15.392057ms, exchange time: 1.015638857s
    rtt: 14.714699ms, exchange time: 1.015217071s
    rtt: 15.114772ms, exchange time: 1.01604594s
    rtt: 15.573436ms, exchange time: 1.015828802s
    

    As you read rtt is at least 1 second faster than time used in the exchange function.

    Could you tell what I am do it wrong here?

    Thanks in advance

    opened by mfuentesg 7
  • Add RFC4034 domain comparison + NSEC Cover

    Add RFC4034 domain comparison + NSEC Cover

    I noticed that this library has a good Cover() method for NSEC3 RRs, but not for NSEC. This PR adds a similar Cover() method for NSEC, plus a DomainCompare function for comparing domain names as defined by RFC4034's canonical ordering.

    Feedback is welcome.

    opened by monoidic 20
Verify IP addresses of respectful crawlers like Googlebot by reverse dns and forward dns lookups

goodbots - trust but verify goodbots verifies the IP addresses of respectful crawlers like Googlebot by performing reverse dns and forward dns lookups

Eric Wu 29 Jun 21, 2022
The Dual-Stack Dynamic DNS client, the world's first dynamic DNS client built for IPv6.

dsddns DsDDNS is the Dual-Stack Dynamic DNS client. A dynamic DNS client keeps your DNS records in sync with the IP addresses associated with your hom

Ryan Young 10 Jun 20, 2022
netcup DNS module for caddy: dns.providers.netcup

netcup DNS module for Caddy This package contains a DNS provider module for Caddy. It can be used to manage DNS records with the netcup DNS API using

null 6 Mar 3, 2022
A fork on miekg/dns (since I've already forked zmap/dns)

Alternative (more granular) approach to a DNS library Less is more. Complete and usable DNS library. All Resource Records are supported, including the

null 0 Jan 19, 2022
A simple DNS forwarder that forwards DNS queries to various upstreams

A simple DNS forwarder that forwards DNS queries to various upstreams. If an upstream returns NXDomain, the next upstream is tried.

null 1 May 10, 2022
DNS library in Go

Alternative (more granular) approach to a DNS library Less is more. Complete and usable DNS library. All Resource Records are supported, including the

Miek Gieben 6.4k Jun 30, 2022
Forked Version of Miekg's DNS library that recycles UDP sockets

Alternative (more granular) approach to a DNS library Less is more. Complete and usable DNS library. All Resource Records are supported, including the

null 0 Jan 20, 2022
DNS service discovery library for Go

Discovery DNS service discovery library for Go Documentation see pkg.go.dev Installation

Taufik Mulyana 1 Mar 10, 2022
Hostkeydns - Library for verifying remote ssh keys using DNS and SSHFP resource records

hostkeydns import "suah.dev/hostkeydns" Package hostkeydns facilitates verifying

Aaron Bieber 4 Feb 11, 2022
A client software for acme-dns with emphasis on usability and guidance through setup and additional security safeguard mechanisms

acme-dns-client A client software for acme-dns with emphasis on usability and guidance through setup and additional security safeguard mechanisms. It

null 60 Jun 9, 2022
Network-wide ads & trackers blocking DNS server

Privacy protection center for you and your devices Free and open source, powerful network-wide ads & trackers blocking DNS server. AdGuard.com | Wiki

AdGuard 11.9k Jun 21, 2022
A tiny command line DNS client with support for UDP, DoT, DoH, and DoQ.

q A tiny command line DNS client with support for UDP, DoT, DoH, and DoQ. Usage q command line DNS client (https://github.com/natesales/q) Usage: q

Nate Sales 665 Jun 21, 2022
Fast Private DNS,提供自定义的DNS记录配置和DNS解析缓存。

fpdns Fast Private DNS,提供自定义的DNS记录配置和DNS解析缓存。 特性: A记录 CNAME 泛解析 DNS负载均衡 缓存DNS解析结果 上游同时多DNS Server查询 各系统测试情况 Linux: 已稳定运行3年多 Darwin: 已开发测试 Windows: 未测试

QLeelulu 24 Nov 4, 2021
Information Gathering tool - DNS / Subdomains / Ports / Directories enumeration

Information Gathering tool - DNS / Subdomains / Ports / Directories enumeration

gilfoyle97 464 Jun 28, 2022
Privacy important, fast, recursive dns resolver server with dnssec support

?? Privacy important, fast, recursive dns resolver server with dnssec support Installation go get github.com/semihalev/sdns Pre-build Binaries Downloa

Yasar Alev 704 Jun 27, 2022
一个 DNS 转发器。

mosdns-cn 一个 DNS 转发器。 上游服务器支持 UDP/TCP/DoT/DoH 协议。支持 socks5 代理。 自带本地/远程 DNS 分流功能。可以根据域名和 IP 分流。 数据可以直接从 v2ray dat 文件载入。 无需配置。一键安装。开箱即用。 参数 -s, --serv

Irine Sistiana 186 Jun 28, 2022
IONOS DNS module for caddy

This package contains a DNS provider module for Caddy. It is used to manage DNS records with the IONOS DNS API using libdns-ionos..

null 5 May 19, 2022
sonarbyte is a simple and fast subdomain scanner written in go to extract subdomain from Rapid7's DNS Database using omnisint's api.

sonarbyte Description Sonarbyte is a simple and fast subdomain scanner written in go to extract subdomains from Rapid7's DNS Database using omnisint's

Chan Nyein Wai 24 Mar 31, 2022
A simple tool to detect WAN IP changes and updates your cloudflare DNS entries.

Cloudflare IP Updater A simple tool to detect WAN IP changes and updates your cloudflare DNS entries. Usage Create a new Cloudflare API token Copy the

AJ 11 Dec 10, 2021