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
dnscrypt-proxy 2 - A flexible DNS proxy, with support for encrypted DNS protocols.

Overview A flexible DNS proxy, with support for modern encrypted DNS protocols such as DNSCrypt v2, DNS-over-HTTPS and Anonymized DNSCrypt. dnscrypt-p

DNSCrypt 8.9k Jun 29, 2022
A smol DNS server (<100 loc) that's configured with a static JSON file. Useful for split-dns.

A smol DNS server (<100 loc) that's configured with a static JSON file. Useful for split-dns.

Arne Bahlo 78 Jun 15, 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 25, 2022
Multicast DNS library for Go

Introduction This package allows Go processes to publish multicast DNS style records onto their local network segment. For more information about mDNS

Dave Cheney 188 Dec 18, 2021
DNS over HTTPS [mirror]

dnss dnss is a daemon for using DNS over HTTPS. It can act as a proxy, receiving DNS requests and resolving them using DNS-over-HTTPs (DoH). This can

Alberto Bertogli 96 Apr 15, 2022
DNS server with per-client targeted responses

GeoDNS servers This is the DNS server powering the NTP Pool system and other similar services. Questions or suggestions? For bug reports or feature re

Ask Bjørn Hansen 1.2k Jun 19, 2022
GRONG is a DNS (Domain Name System) authoritative name server.It is more a research project than a production-ready program.

GRONG (Gross and ROugh Nameserver written in Go) is a DNS (Domain Name System) authoritative name server. It is intended as a research project and is

Stéphane Bortzmeyer 57 Oct 17, 2020
Resolver (DNS) cache daemon.

RESCACHED(1) Manual Page NAME rescached - DNS resolver cache daemon. Table of Contents SYNOPSIS OPTIONS DESCRIPTION FEATURES BEHIND THE DNS HOW CACHE

Shulhan 26 May 25, 2022
CUP - Cloudflare (DNS) Updater Program

CUP The Cloudflare (DNS) Updater CUP is a tool to turn CloudFlare DNS into a Dynamic DNS service. Documentation Documentation can be found in the docs

Taylor Vierrether 29 Jun 6, 2022
🐶 Command-line DNS Client for Humans. Written in Golang

doggo ?? Command-line DNS client for humans doggo is a modern command-line DNS client (like dig) written in Golang. It outputs information in a neat c

Karan Sharma 912 Jun 26, 2022
CoreDNS is a DNS server that chains plugins

CoreDNS is a DNS server/forwarder, written in Go, that chains plugins. Each plugin performs a (DNS) function. CoreDNS is a Cloud Native Computing Foun

CoreDNS 9.4k Jun 28, 2022
Fast and lightweight DNS proxy as ad-blocker for local network with many features

Blocky Blocky is a DNS proxy and ad-blocker for the local network written in Go with following features: Features Blocking - Blocking of DNS queries w

Dimitri Herzog 1.6k Jun 21, 2022
Are you forwarding DNS traffic to another server for some reason, but want to make sure only queries for certain names are passed? Say no more.

DNSFWD Redirect DNS traffic to an upstream. Get Latest: wget https://github.com/C-Sto/dnsfwd/releases/latest/download/dnsfwd_linux (replace linux with

C_Sto 15 Apr 13, 2022
Fast DNS implementation for Go

Fast DNS implementation for Go Features 0 Dependency Similar Interface with net/http Fast DoH Server Co-create with fasthttp Fast DNS Client with rich

phuslu 67 May 29, 2022
Gotator is a tool to generate DNS wordlists through permutations.

Gotator is a tool to generate DNS wordlists through permutations.

Josué Encinar 194 Jun 26, 2022
DNS lookup using Go

DNS lookup using Go

Muhammad Daffa 5 Jun 17, 2022
DNSTake — A fast tool to check missing hosted DNS zones that can lead to subdomain takeover

DNSTake — A fast tool to check missing hosted DNS zones that can lead to subdomain takeover

Pwnesia 638 Jun 22, 2022
A tool to solve DNS pollution of GitHub website. Query the real IP address of domain names such as github.com, and refresh the domain name setting of the system hosts file.

githubDNS Target A tool to solve DNS pollution of GitHub website. Query the real IP address of domain names such as github.com, and refresh the domain

null 0 Oct 14, 2021
forward - facilitates proxying DNS messages to upstream resolvers.

forward Name forward - facilitates proxying DNS messages to upstream resolvers. Description The forward plugin re-uses already opened sockets to the u

Q.Z.Lin 0 Oct 16, 2021