Giter Club home page Giter Club logo

dns's Introduction

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
  • 1183 - ISDN, X25 and other deprecated records
  • 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
  • 4025 - A Method for Storing IPsec Keying Material in DNS
  • 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
  • 8659 - DNS Certification Authority Authorization (CAA) Resource Record
  • 8777 - DNS Reverse IP Automatic Multicast Tunneling (AMT) Discovery
  • 8914 - Extended DNS Errors
  • 8976 - Message Digest for DNS Zones (ZONEMD RR)

Loosely Based Upon

dns's People

Contributors

abh avatar ameshkov avatar andrewtj avatar asergeyev avatar axaxs avatar chantra avatar corny avatar dependabot[bot] avatar deswurstes avatar fcelda avatar filosottile avatar gibson042 avatar jameshartig avatar jinmeiib avatar jsha avatar majek avatar matje avatar michaelharo avatar middelink avatar miekg avatar mimuret avatar rafaeljusto avatar rolandshoemaker avatar semihalev avatar shane-ns1 avatar shawnps avatar stalkr avatar systemcrash avatar taralx avatar tmthrgd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dns's Issues

EDNS Subnet

Can you add an example of how to use the EDNS subnet option (in the server)?

dns: overflow packing domain-name 91

Should I be concerned about these?

2012-08-31 06:53:52.161312500 dns: overflow packing domain-name 91
2012-08-31 06:54:00.627255500 dns: overflow packing domain-name 91
2012-08-31 06:54:07.093995500 dns: overflow packing domain-name 91
2012-08-31 06:54:11.751124500 dns: overflow packing domain-name 91
2012-08-31 06:54:32.695499500 dns: overflow packing domain-name 205
2012-08-31 06:54:32.695597500 dns: overflow packing domain-name 205
2012-08-31 06:54:32.695598500 dns: overflow packing domain-name 205

Can't pack an SRV RR

I'd expect the following to work unless I'm doing something wrong.

package dns

import (
    "net"
    "strconv"
    "testing"
)

func TestSRVPacking(t *testing.T) {
    msg := Msg{}

    things := []string{"1.2.3.4:8484",
        "45.45.45.45:8484",
        "84.84.84.84:8484",
    }

    for i, n := range things {
        h, p, err := net.SplitHostPort(n)
        if err != nil {
            continue
        }
        port := 8484
        tmp, err := strconv.Atoi(p)
        if err == nil {
            port = tmp
        }

        rr := &RR_SRV{
            Hdr: RR_Header{Name: "somename",
                Rrtype: TypeSRV,
                Class:  ClassINET,
                Ttl:    5},
            Priority: uint16(i),
            Weight:   5,
            Port:     uint16(port),
            Target:   h,
        }

        msg.Answer = append(msg.Answer, rr)
    }

    _, ok := msg.Pack()
    if !ok {
        t.Fatalf("Couldn't pack %v\n", msg)
    }
}

Getting "dns: overflow unpacking uint32"

I'm getting an error decoding a response with the client "dns: overflow unpacking uint32". The response is being generated with the same library, and contains a combination of SRV and A records. Nothing crazy as far as I can tell. Below is the binary buffer after packing that is being sent:

[130 137 133 0 0 1 0 10 0 1 0 5 3 119 101 98 7 115 101 114 118 105 99 101 6 99 111 110 115 117 108 0 0 255 0 1 3 119 101 98 7 115 101 114 118 105 99 101 6 99 111 110 115 117 108 0 0 1 0 1 0 0 0 0 0 4 127 0 0 11 3 119 101 98 7 115 101 114 118 105 99 101 6 99 111 110 115 117 108 0 0 1 0 1 0 0 0 0 0 4 127 0 0 5 3 119 101 98 7 115 101 114 118 105 99 101 6 99 111 110 115 117 108 0 0 1 0 1 0 0 0 0 0 4 127 0 0 1 3 119 101 98 7 115 101 114 118 105 99 101 6 99 111 110 115 117 108 0 0 1 0 1 0 0 0 0 0 4 127 0 0 3 3 119 101 98 7 115 101 114 118 105 99 101 6 99 111 110 115 117 108 0 0 1 0 1 0 0 0 0 0 4 127 0 0 7 3 119 101 98 7 115 101 114 118 105 99 101 6 99 111 110 115 117 108 0 0 33 0 1 0 0 0 0 0 29 0 1 0 1 31 64 5 102 111 111 49 48 4 110 111 100 101 3 100 99 49 6 99 111 110 115 117 108 0 3 119 101 98 7 115 101 114 118 105 99 101 6 99 111 110 115 117 108 0 0 33 0 1 0 0 0 0 0 28 0 1 0 1 31 64 4 102 111 111 52 4 110 111 100 101 3 100 99 49 6 99 111 110 115 117 108 0 3 119 101 98 7 115 101 114 118 105 99 101 6 99 111 110 115 117 108 0 0 33 0 1 0 0 0 0 0 28 0 1 0 1 31 64 4 102 111 111 48 4 110 111 100 101 3 100 99 49 6 99 111 110 115 117 108 0 3 119 101 98 7 115 101 114 118 105 99 101 6 99 111 110 115 117 108 0 0 33 0 1 0 0 0 0 0 28 0 1 0 1 31 64 4 102 111 111 50 4 110 111 100 101 3 100 99 49 6 99 111 110 115 117 108 0 3 119 101 98 7 115 101 114 118 105 99 101 6 99 111 110 115 117 108 0 0 33 0 1 0 0 0 0 0 28 0 1 0 1 31 64 4 102 111 111 54 4 110 111 100 101 3 100 99 49 6 99 111 110 115 117 108 0 6 99 111 110 115 117 108 0 0 6 0 1 0 0 0 0 0 50 2 110 115 6 99 111 110 115 117 108 0 10 112 111 115 116 109 97 115 116 101 114 6 99 111 110 115 117 108 0 82 254 117 230 0 0 14 16 0 0 2 88 0 1 81 128 0 0 0 0 5 102 111 111 49 48 4 110 111 100 101 3 100 99 49 6 99 111 110 115 117 108 0 0 1 0 1 0 0 0 0 0 4 127 0 0 11 4 102 111 111 52 4 110 111 100 101 3 100 99 49 6 99 111 110 115 117 108 0 0 1 0 1 0 0 0 0 0 4 127 0 0 5 4 102 111 111 48 4 110 111 100 101 3 100 99 49 6 99 111 110 115 117 108 0 0 1 0 1 0 0 0 0 0 4 127 0 0 1 4 102 111 111 50 4 110 111 100 101 3 100 99 49 6 99 111 110 115 117 108 0 0 1 0 1 0 0 0 0 0 4 127 0 0 3 4 102 111 111 54 4 110 111 100 101 3 100 99 49 6 99 111 110 115 117 108 0 0 1 0 1 0 0 0 0 0 4 127 0 0 7]

pack error on non-fully qualfied tsig key names

In the following program, m.Pack returns dns.ErrBuf instead of dns.ErrFqdn

package main

import (
    "fmt"
    "github.com/miekg/dns"
    "net"
    "os"
    "time"
)

func main() {
    c := new(dns.Client)
    c.TsigSecret = map[string]string{
        "example-key.": "aHVudGVyMg==",
    }

    m := new(dns.Msg)
    m.SetUpdate("example.")
    u1 := dns.A{dns.RR_Header{"example.", dns.TypeA, dns.ClassANY, 300, 0}, net.IPv4(1,2,3,4)}
    m.Ns = []dns.RR{&u1}

    // the key name isn't fully qualified
    m.SetTsig("example-key", dns.HmacMD5, 300, time.Now().Unix())

    _, err := m.Pack()
    if(err != nil) {
        fmt.Println("pack:", err)
        os.Exit(1)
    }
}

No RDATA records in text format

So.. when you use Dynamic Update queries, you sometimes use no RDATA rrs, like this:
screenshot from 2014-08-28 21 41 09

RData length will be 0 and there would be text representation like this:

example.org. 0 ANY A 

This library correctly represents such text representation from something like this:

&dns.A{
    Hdr: dns.RR_Header{
        Name:     "example.org.",
        Rrtype:   dns.TypeA,
        Class:    dns.ClassANY,
        Ttl:      0,
        Rdlength: 0,
    },
    A: nil,
}.String()

but fails to parse it back into RR, this one will panic regardless of whitespace after A:

_, err := dns.NewRR("example.org. ANY A")
if err != nil { panic("got error") }

This would not affect much real world operations! I don't know where the need of parsing such records in text format would arise but IMO it worth discussion if this behavior should be considered a bug.

I did not check much but Net::DNS is installed and seem to read those properly:

$ perl -Mv5.16 -MNet::DNS -e "say  Net::DNS::RR->new('example.org. ANY A')->string();"
example.org.    0   ANY A   ; no data

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.

chaos crashes if target nameserver refuses query

[cookiemonster:] owens% uname -a
Darwin cookiemonster.nysernet.org 11.3.0 Darwin Kernel Version 11.3.0: Thu Jan 12 18:47:41 PST 2012; root:xnu-1699.24.23
1/RELEASE_X86_64 x86_64
[cookiemonster:~] owens% go version
go version weekly.2012-03-13

Test case:
[cookiemonster:~] owens% chaos a.root-servers.net
panic: runtime error: index out of range

goroutine 1 [running]:
main.main()
/Users/owens/Projects/gocode/src/dns/ex/chaos/chaos.go:32 +0x3b3

goroutine 2 [syscall]:
created by runtime.main
/Users/owens/Projects/go/src/pkg/runtime/proc.c:221

goroutine 3 [chan receive]:
dns.(_Query).Query(0xf84004c620, 0x0)
/Users/owens/Projects/gocode/src/dns/client.go:176 +0xa4
dns.(_Query).ListenAndQuery(0xf84004c620, 0xf84004c620, 0x2571, 0x0)
/Users/owens/Projects/gocode/src/dns/client.go:191 +0x3b
created by dns.ListenAndQuery
/Users/owens/Projects/gocode/src/dns/client.go:199 +0x5c

goroutine 6 [syscall]:
syscall.Syscall6()
/Users/owens/Projects/go/src/pkg/syscall/asm_darwin_amd64.s:38 +0x5
syscall.kevent(0x7, 0x0, 0x0, 0xf84006d188, 0x10000000a, ...)
/Users/owens/Projects/go/src/pkg/syscall/zsyscall_darwin_amd64.go:199 +0x88
syscall.Kevent(0xf800000007, 0x0, 0x0, 0xf84006d188, 0xa0000000a, ...)
/Users/owens/Projects/go/src/pkg/syscall/syscall_bsd.go:538 +0xa4
net.(_pollster).WaitFD(0xf84006d180, 0xf840088000, 0x68189710, 0x0, 0x0, ...)
/Users/owens/Projects/go/src/pkg/net/fd_darwin.go:96 +0x185
net.(_pollServer).Run(0xf840088000, 0x0)
/Users/owens/Projects/go/src/pkg/net/fd.go:236 +0xe4
created by net.newPollServer
/Users/owens/Projects/go/src/pkg/net/newpollserver.go:35 +0x382

Many errors related to "error"

Even after patching for issue #9, godns does not compile with today's tip:

% make
8g -o go.8 clientconfig.go client.go defaults.go dns.go dnssec.go edns.go keygen.go kscan.go msg.go nsec3.go rawmsg.go server.go tsig.go types.go update.go xfr.go zscan.go zscan_rr.go
clientconfig.go:30: undefined: error
client.go:24: undefined: error
client.go:25: undefined: error
client.go:26: undefined: error
client.go:27: undefined: error
client.go:156: undefined: error
client.go:175: undefined: error
client.go:204: undefined: error
client.go:228: undefined: error
dns.go:168: undefined: error
client.go:228: too many errors
make: *** [go.8] Error 1

Something apparently changed recently in error types.

Unpacking a TXT record does not work as expected.

I noticed double-quotes were escaped in TXT records I received over the network. After a bit of digging I suspected it had something to do with unpackTxtString() not working correctly. Here's a test I case I hastily wrote up to verify this behavior:

package dns

import (
    "testing"
)

func TestTxtPackUnpack(t *testing.T) {
    var original string
    original = `{"Name": "alex", "Age": 22}`

    var (
        err   error
        msg   []byte
        buf   []byte
        check string
    )

    msg = make([]byte, 128)
    buf = make([]byte, 128)

    _, err = packTxtString(original, msg, 0, buf)
    if err != nil {
        t.Fatal(err)
    }

    check, _, err = unpackTxtString(msg, 0)
    if err != nil {
        t.Fatal(err)
    }

    if original != check {
        t.Fatalf("%s != %s\n", original, check)
    }
}

As expected it fails. At this point I don't know enough about this library to say if it should pass or not. So I have a few questions. Is this the desired behavior? If yes, why is this the case and how are we supposed to work around it (i.e. I don't want double-quotes escaped)? If no, then how should it be fixed? I would be willing to attempt fixing this in a pull request if I knew how these functions were supposed to actually run.

ex/q/q.go doesn't handle truncated answers

Hi,

it tries to support it but seems to fail:

    go run q.go SRV foo.example.com.
    ;; Truncated
    ;; opcode: QUERY, status: NOERROR, id: 50875
    ;; flags: qr tc rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0

    ;; QUESTION SECTION:
    ;foo.example.com. IN   SRV

    ;; query time: 31221 µs, server: 10.20.30.40:53(udp), size: 56 bytes

vs

    dig SRV foo.example.com.

    ; <<>> DiG 9.9.2-P1 <<>> SRV foo.example.com.
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 9662
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 14, AUTHORITY: 2, ADDITIONAL: 1

    ;; OPT PSEUDOSECTION:
    ; EDNS: version: 0, flags:; udp: 4096
    ;; QUESTION SECTION:
    ;foo.example.com. IN SRV

    ;; ANSWER SECTION:
    foo.example.com.  60 IN SRV 0 0 6566 app121.servers.example.com.
    foo.example.com.  60 IN SRV 0 0 6566 app122.servers.example.com.
    foo.example.com.  60 IN SRV 0 0 6566 app123.servers.example.com.
    foo.example.com.  60 IN SRV 0 0 6566 app126.servers.example.com.
    foo.example.com.  60 IN SRV 0 0 6566 app132.servers.example.com.
    foo.example.com.  60 IN SRV 0 0 6566 app018.servers.example.com.
    foo.example.com.  60 IN SRV 0 0 6566 app031.servers.example.com.
    foo.example.com.  60 IN SRV 0 0 6566 app035.servers.example.com.
    foo.example.com.  60 IN SRV 0 0 6566 app036.servers.example.com.
    foo.example.com.  60 IN SRV 0 0 6566 app091.servers.example.com.
    foo.example.com.  60 IN SRV 0 0 6566 app102.servers.example.com.
    foo.example.com.  60 IN SRV 0 0 6566 app107.servers.example.com.
    foo.example.com.  60 IN SRV 0 0 6566 app110.servers.example.com.
    foo.example.com.  60 IN SRV 0 0 6566 app116.servers.example.com.

    ;; AUTHORITY SECTION:
    example.com.  0 IN  NS  ns1.servers.example.com.
    example.com.  0 IN  NS  ns2.servers.example.com.

    ;; Query time: 30 msec
    ;; SERVER: 10.20.30.40#53(10.20.30.40)
    ;; WHEN: Tue Jun 25 19:45:10 2013
    ;; MSG SIZE  rcvd: 775

On a side note: Is it planned to have some higher level functions for resolving names? Because golang's net package doesn't handle truncated SRV records either: https://code.google.com/p/go/issues/detail?id=5686

DNS Server - panic: runtime error: index out of range

I'm running Go 1.0.1.

When run the "reflect" example and then run a nmap UDP port scan (nmap -sU localhost), the following error occurs (complete output log):

panic: runtime error: index out of range

goroutine 15 [running]:
dns.(*ServeMux).ServeDNS(0xf840066068, 0xf8400a4840, 0xf8400a4bc0, 0xf84006f480, 0xf8400a4bc0, ...)
        /opt/go/src/pkg/dns/server.go:138 +0x34
dns.(*conn).serve(0xf840098b40, 0x0)
        /opt/go/src/pkg/dns/server.go:339 +0x326
created by dns.(*Server).ServeUDP
        /opt/go/src/pkg/dns/server.go:285 +0x3c7

goroutine 1 [chan receive]:
main.main()
        /opt/go/dns/ex/reflect/reflect.go:148 +0x425

goroutine 2 [syscall]:
created by runtime.main
        /tmp/bindist510773444/go/src/pkg/runtime/proc.c:221

goroutine 3 [syscall]:
os/signal.loop()
        /usr/local/go/src/pkg/os/signal/signal_unix.go:20 +0x1c
created by os/signal.init·1
        /usr/local/go/src/pkg/os/signal/signal_unix.go:26 +0x2f

goroutine 4 [chan receive]:
net.(*pollServer).WaitRead(0xf84008a840, 0xf840089120, 0xf84004e7b0, 0xb, 0x1, ...)
        /usr/local/go/src/pkg/net/fd.go:268 +0x73
net.(*netFD).accept(0xf840089120, 0x46dfa1, 0x0, 0xf84004dc60, 0xf840066040, ...)
        /usr/local/go/src/pkg/net/fd.go:622 +0x20d
net.(*TCPListener).AcceptTCP(0xf840066240, 0x528188, 0x0, 0x0, 0xf840066068, ...)
        /usr/local/go/src/pkg/net/tcpsock_posix.go:320 +0x71
dns.(*Server).ServeTCP(0xf840001730, 0xf840066240, 0x0, 0x0, 0x0, ...)
        /opt/go/src/pkg/dns/server.go:213 +0xd3
dns.(*Server).ListenAndServe(0xf840001730, 0xf840001730, 0x0, 0x401aec)
        /opt/go/src/pkg/dns/server.go:187 +0x1c2
dns.ListenAndServe(0x572e8c, 0x33353a00000003, 0x5743ec, 0x3, 0x0, ...)
        /opt/go/src/pkg/dns/server.go:90 +0x84
main.serve(0x5743ec, 0x70637400000003, 0x0, 0x0, 0x0, ...)
        /opt/go/dns/ex/reflect/reflect.go:105 +0x72
created by main.main
        /opt/go/dns/ex/reflect/reflect.go:141 +0x376

goroutine 5 [runnable]:
syscall.Syscall6()
        /tmp/bindist510773444/go/src/pkg/syscall/asm_linux_amd64.s:55 +0x51
syscall.recvfrom(0x4, 0xf8400a5a00, 0x20000000200, 0x7f5f00000000, 0xf8400a3620, ...)
        /usr/local/go/src/pkg/syscall/zerrors_linux_amd64.go:3007 +0xa6
syscall.Recvfrom(0xf800000004, 0xf8400a5a00, 0x20000000200, 0x0, 0x201, ...)
        /usr/local/go/src/pkg/syscall/syscall_linux.go:512 +0xbb
net.(*netFD).ReadFrom(0xf8400a2000, 0xf8400a5a00, 0x20000000200, 0x100000000, 0x0, ...)
        /usr/local/go/src/pkg/net/fd.go:454 +0x150
net.(*UDPConn).ReadFromUDP(0xf840066230, 0xf8400a5a00, 0x20000000200, 0xf8400a5a00, 0x0, ...)
        /usr/local/go/src/pkg/net/udpsock_posix.go:164 +0x104
dns.(*Server).ServeUDP(0xf840098000, 0xf840066230, 0x0, 0x0, 0x0, ...)
        /opt/go/src/pkg/dns/server.go:269 +0x13a
dns.(*Server).ListenAndServe(0xf840098000, 0xf840098000, 0x0, 0x401aec)
        /opt/go/src/pkg/dns/server.go:197 +0x3e8
dns.ListenAndServe(0x572e8c, 0x33353a00000003, 0x57447c, 0x3, 0x0, ...)
        /opt/go/src/pkg/dns/server.go:90 +0x84
main.serve(0x57447c, 0x70647500000003, 0x0, 0x0, 0x0, ...)
        /opt/go/dns/ex/reflect/reflect.go:105 +0x72
created by main.main
        /opt/go/dns/ex/reflect/reflect.go:142 +0x3bc

goroutine 6 [syscall]:
syscall.Syscall6()
        /tmp/bindist510773444/go/src/pkg/syscall/asm_linux_amd64.s:40 +0x5
syscall.EpollWait(0xf800000007, 0xf84008e0c0, 0xa0000000a, 0xffffffff, 0xc, ...)
        /usr/local/go/src/pkg/syscall/zerrors_linux_amd64.go:1781 +0xa1
net.(*pollster).WaitFD(0xf84008e0b0, 0xf84008a840, 0x0, 0x0, 0x0, ...)
        /usr/local/go/src/pkg/net/fd_linux.go:146 +0x110
net.(*pollServer).Run(0xf84008a840, 0x0)
        /usr/local/go/src/pkg/net/fd.go:236 +0xe4
created by net.newPollServer
        /usr/local/go/src/pkg/net/newpollserver.go:35 +0x382

Thanks in advanced!

master doesn't build.

gopath/src/github.com/miekg/dns/edns.go:230: function ends without a return statement

Our continuous integration server just picked this up.

Send UDP DNS responses from the address we received them from

I have a problem with a server that has multiple IP address and is bound to 0.0.0.0.
I expect the DNS queries to be responded from the source IP address it was received on, but because of the way a UDP socket works when it's bound to 0.0.0.0, the OS is choosing the source IP when calling WriteTo().
For example, host(1) won't handle the response properly if it wasn't received from the destination address the query was sent to.

See this stackoverflow message for more information about this UDP problem:
http://stackoverflow.com/questions/3062205/setting-the-source-ip-for-a-udp-socket

So:

  1. Is this is a problem we even want to be addressing?
  2. How do other DNS servers (or any other UDP server that binds to 0.0.0.0) handle this?
  3. Is it possible to handle this in a cross-platform way on Go?

Thanks.

Missing file: config.go?

The makefile requires a config.go this file isn't in the repository and I don't see a way to generate it.

Removing the listing from the Makefile allows the software to build without error.

dns server hangs

I think a broken packet caused this (I didn't have logging turned on, sadly, but it looks like it crashed before it even called my handler so maybe it wouldn't have helped)


extra bytes in dns packet 12 < 23
panic: runtime error: index out of range

goroutine 47788 [running]:
github.com/miekg/dns.(*ServeMux).ServeDNS(0x188471c8, 0x1893c510, 0x18d538a0, 0x18a1eb90, 0x18d
538a0, ...)
        /opt/go/src/github.com/miekg/dns/server.go:143 +0x38
github.com/miekg/dns.(*conn).serve(0x18eb9f30, 0x0)
        /opt/go/src/github.com/miekg/dns/server.go:343 +0x251
created by github.com/miekg/dns.(*Server).ServeUDP
        /opt/go/src/github.com/miekg/dns/server.go:288 +0x318

API versioning

This is a follow-up to the remark I made about that in #25:

Just thinking out loud here:

It'd be nice if there was some way to have my build break when the dns API changes in maybe-incompatible ways. Because I use cgo I build my server on 3-4 different boxes, so my process for "keeping in sync" has just been to go get -u -v, but then it's hard to know exactly which version of dns I got.

For geodns itself I build it with

REVISION=`git rev-parse --short=8  HEAD`
go build -ldflags "-X main.gitVersion $REVISION" -v

... maybe I should just add another version like that for the dnsGitVersion.

As for you making a subdirectory for "v2", that sounds like a huge hassle. I think just do it on a branch, and if you need to keep v1 around when v2 is ready to be merged setup a separate git repository that people can import and alias to dns if they need the old version.

MsgHdr.Rdlength is not set by NewRR

When creating RRs via the NewRR function, I've found that rr.Header().Rdlength is not set to the length of the rdata. I'm still not sure the scope of real-world implications, here - it became a thorn in my side when testing my project, where I was using reflect.DeepEqual to compare a produced *Msg against an expected *Msg value.

library code shouldn't write to stdio

hi,

i see there is a call to println() in the Unpack() function:

    if off != len(msg) {
        // TODO(mg) remove eventually
        // Err: extra bytes in packet
        println("dns: extra bytes in dns packet", off, "<", len(msg))
    }

i ran into this today when decoding response messages from a broken authority server. my program was printing out the following:

dns: extra bytes in dns packet 43 < 49
dns: extra bytes in dns packet 59 < 67
dns: extra bytes in dns packet 42 < 48
dns: extra bytes in dns packet 43 < 49
dns: extra bytes in dns packet 43 < 49
dns: extra bytes in dns packet 42 < 48
dns: extra bytes in dns packet 43 < 49
dns: extra bytes in dns packet 43 < 49
dns: extra bytes in dns packet 43 < 49
dns: extra bytes in dns packet 59 < 67
dns: extra bytes in dns packet 42 < 48
dns: extra bytes in dns packet 42 < 48
dns: extra bytes in dns packet 43 < 49
dns: extra bytes in dns packet 42 < 48
dns: extra bytes in dns packet 43 < 49
dns: extra bytes in dns packet 42 < 48
dns: extra bytes in dns packet 43 < 49
dns: extra bytes in dns packet 43 < 49
dns: extra bytes in dns packet 59 < 67

etc. etc. i would prefer the message parser to be completely silent on my stdio streams :)

somewhat fortunately it seems this output goes to stderr rather than stdout, which would have been even worse. (coincidentally i'm generating YAML and the warning message that Unpack() prints happens to be valid YAML.)

i guess there is a related issue of how strict the message parser should be... perhaps there should be an UnpackStrict() function that treats DNS format errors like this as full-fledged errors, or perhaps there could be a Warning string (or []string) field in the Msg type that gets formatted into the result of String(), similar to what dig does, e.g.:

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28301
;; flags: qr ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: Messages has 19 extra bytes at end

but i think the issue of whether/how to return "warnings" is distinct from the issue of "library" code writing to stderr.

"RRsetDelete" update comes back with "FORMERR"

"RRsetDelete" update comes back with "FORMERR". I haven't been able to track down why this is quite yet. The server is not providing enough log information for this. A soon as I can get more info, I'll pass it along or a patch (or a nevermind if I'm the bad one).

The most simple test I could do came back with this as well, so it seems likely to be a real bug somewhere. I don't think this is a meta-RR problem, though. I'll report back soon when I have something to add.

"not reached" panic in server.go

Since upgrading to the latest version some of my boxes are crashing with this error. Looking at the code it seems impossible, so not sure what's going on. I wish there was an easy way to know exactly which version of the dns package is included or otherwise a better way to manage the package dependencies. :-/

geodns 00:33:23.263167 serve.go:139: Opening on 64.142.112.226:53 udp
geodns 00:33:23.263202 serve.go:139: Opening on 207.171.17.42:53 udp
geodns 00:33:23.263187 serve.go:139: Opening on 64.142.112.226:53 tcp
geodns 00:33:23.263215 serve.go:139: Opening on 207.171.17.42:53 tcp
geodns 00:33:23.268425 config.go:47: Updated file, going to read pool.ntp.org.json
panic: dns: not reached

goroutine 17 [running]:
github.com/miekg/dns.(*ServeMux).match(0x188571c8, 0x18bb6340, 0xc, 0x6f0001, 0x29, ...)
    /home/ask/go/src/github.com/miekg/dns/server.go:196 +0x10c
github.com/miekg/dns.(*ServeMux).ServeDNS(0x188571c8, 0x18bb7690, 0x18bb9000, 0x18bba000, 0x18bb9000, ...)
    /home/ask/go/src/github.com/miekg/dns/server.go:230 +0xe8
github.com/miekg/dns.(*conn).serve(0x18bb7000, 0x0)
    /home/ask/go/src/github.com/miekg/dns/server.go:419 +0x28e
created by github.com/miekg/dns.(*Server).serveUDP
    /home/ask/go/src/github.com/miekg/dns/server.go:377 +0x310

goroutine 1 [chan receive]:
...

Doesn't compile on go 1:57-3

I applied the automated migrations with

for i in */.go; do gofix $i; done

but it still doesn't compile:

6g -o go.6 clientconfig.go client.go defaults.go dns.go dnssec.go edns.go keygen.go msg.go nsec3.go server.go tsig.go types.go xfr.go
client.go:152: label forever defined and not used
keygen.go:61: t.P undefined (type rsa.PrivateKey has no field or method P)
keygen.go:62: t.Q undefined (type *rsa.PrivateKey has no field or method Q)
keygen.go:67: t.P undefined (type *rsa.PrivateKey has no field or method P)
keygen.go:68: t.Q undefined (type *rsa.PrivateKey has no field or method Q)
keygen.go:71: t.Q undefined (type *rsa.PrivateKey has no field or method Q)
keygen.go:71: t.P undefined (type *rsa.PrivateKey has no field or method P)
keygen.go:131: p.P undefined (type *rsa.PrivateKey has no field or method P)
keygen.go:132: p.P undefined (type *rsa.PrivateKey has no field or method P)
keygen.go:135: p.Q undefined (type *rsa.PrivateKey has no field or method Q)
keygen.go:135: too many errors
make: *
* [go.6] Error 1

Error in documentation for type Client

From the documentation for the Client type:

A nil Client is usable for sending queries.

This is not true. A pointer to the zero value is usable, nil is not.

Means of explicitly closing Server

I've got a scenario where I need to run multiple tests against different server configs. I really need the ability to end a ListenAndServe call from another goroutine. It's a bit weird that the feature doesn't already exist.

I'm willing to help implement this feature, by the way.

Crash of the test MX program

The demo mx program crashes:

Programmation/Go/godns % _examples/mx/mx
_examples/mx/mx DOMAIN

Programmation/Go/godns % _examples/mx/mx nic.fr
panic: runtime error: invalid memory address or nil pointer dereference

panic PC=0xb7656e90
runtime.panic+0x9f /usr/local/go/src/pkg/runtime/proc.c:1032
runtime.panic(0x80b8bb8, 0xb7652938)
runtime.panicstring+0x61 /usr/local/go/src/pkg/runtime/runtime.c:83
runtime.panicstring(0x81a6977, 0x44)
runtime.sigpanic+0x11b /usr/local/go/src/pkg/runtime/linux/thread.c:286
runtime.sigpanic()
main.main+0x27a /home/bortzmeyer/Programmation/Go/godns/_examples/mx/mx.go:32
main.main()
runtime.mainstart+0xf /usr/local/go/src/pkg/runtime/386/asm.s:84
runtime.mainstart()
runtime.goexit /usr/local/go/src/pkg/runtime/proc.c:148
runtime.goexit()

goroutine 3 [3]:
runtime.entersyscall+0x25 /usr/local/go/src/pkg/runtime/proc.c:572
runtime.entersyscall()
syscall.Syscall6+0x5 /usr/local/go/src/pkg/syscall/asm_linux_386.s:39
syscall.Syscall6()
syscall.EpollWait+0x74 /usr/local/go/src/pkg/syscall/zsyscall_linux_386.go:188
syscall.EpollWait(0x6, 0xb76536d0, 0x1, 0x1, 0xffffffff, ...)
net._pollster·WaitFD+0x134 /usr/local/go/src/pkg/net/fd_linux.go:116
net._pollster·WaitFD(0xb76528d8, 0x0, 0x0, 0x0, 0x0, ...)
net._pollServer·Run+0xcb /usr/local/go/src/pkg/net/fd.go:207
net._pollServer·Run(0xb767dd60, 0x0)
runtime.goexit /usr/local/go/src/pkg/runtime/proc.c:148
runtime.goexit()

goroutine 2 [4]:
runtime.gosched+0x75 /usr/local/go/src/pkg/runtime/proc.c:553
runtime.gosched()
runtime.selectgo+0x2c0 /usr/local/go/src/pkg/runtime/chan.c:768
runtime.selectgo(0xb76536f0, 0xb76717c0)
dns/resolver.query+0x549 /home/bortzmeyer/Programmation/Go/godns/resolver/resolver.go:130
dns/resolver.query(0xb7671540, 0xb76717c0, 0x0)
runtime.goexit /usr/local/go/src/pkg/runtime/proc.c:148
runtime.goexit()

go at its tip:

% hg summary
parent: 7016:4380423c630f tip
Fix documentation typo.
branch: default
commit: 6 unknown (clean)
update: (current)

godns at its tip:
% git log|head
commit 4592aba
Author: Miek Gieben [email protected]
Date: Mon Jan 3 11:34:54 2011 +0100

fix TODO

Debian squeeze:

% uname -a
Linux batilda 2.6.26-2-686 #1 SMP Thu Sep 16 19:35:51 UTC 2010 i686 GNU/Linux

/defaults.go:290: function ends without a return statment

When running latest master i get:

github.com/miekg/dns../src/github.com/miekg/dns/defaults.go:290: function ends without a return statement
../src/github.com/miekg/dns/defaults.go:299: function ends without a return statement

Another PackDomainName panic

I'll enable some logging and see what I find tomorrow.

dns: overflow packing domain-name 185
panic: runtime error: index out of range

goroutine 75236 [running]:
github.com/miekg/dns.PackDomainName(0x18b25830, 0xd, 0x18859600, 0xb9, 0xb9, ...)
        /opt/go/src/github.com/miekg/dns/msg.go:238 +0x2bc
github.com/miekg/dns.packStructValue(0x818d8b8, 0x18b45800, 0x196, 0x18859600, 0xb9, ...)
        /opt/go/src/github.com/miekg/dns/msg.go:590 +0x323a
----- stack segment boundary -----
github.com/miekg/dns.packStructValue(0x819131c, 0x18b45800, 0x196, 0x18859600, 0xb9, ...)
        /opt/go/src/github.com/miekg/dns/msg.go:527 +0x39ed
github.com/miekg/dns.packStructCompress(0x818c728, 0x18b45800, 0x18859600, 0xb9, 0xb9, ...)
        /opt/go/src/github.com/miekg/dns/msg.go:658 +0x71
github.com/miekg/dns.PackRR(0x18838c90, 0x18b45800, 0x18859600, 0xb9, 0xb9, ...)
        /opt/go/src/github.com/miekg/dns/msg.go:1064 +0x7e
github.com/miekg/dns.(*Msg).Pack(0x18ea0d20, 0x18859600, 0xb9, 0xb9, 0x1894c110, ...)
        /opt/go/src/github.com/miekg/dns/msg.go:1225 +0x43c
github.com/miekg/dns.(*response).Write(0x18c52400, 0x18ea0d20, 0x0, 0x0)
        /opt/go/src/github.com/miekg/dns/server.go:369 +0x17b
main.serve(0x188896c0, 0x18c52400, 0x18cfc640, 0x18949a00, 0x189499b4, ...)
        /opt/geodns/serve.go:71 +0x70f
main._func_003(0x188d5068, 0x80864f1, 0x188896c0, 0x18c52400, 0x18cfc640, ...)
        /opt/geodns/serve.go:129 +0x3e
github.com/miekg/dns.HandlerFunc.ServeDNS(0x189499a0, 0x188896c0, 0x18c52400, 0x18cfc640, 0x1887306
0, ...)
        /opt/go/src/github.com/miekg/dns/server.go:75 +0x35
github.com/miekg/dns.(*ServeMux).ServeDNS(0x188471c8, 0x188896c0, 0x18c52400, 0x18cfc640, 0x18c5240
0, ...)
        /opt/go/src/github.com/miekg/dns/server.go:147 +0xf0
github.com/miekg/dns.(*conn).serve(0x189da090, 0x1)
        /opt/go/src/github.com/miekg/dns/server.go:343 +0x251
created by github.com/miekg/dns.(*Server).ServeUDP
        /opt/go/src/github.com/miekg/dns/server.go:288 +0x318

RR documentation

I realize this is more of a Go language problem (my problem not understanding, not the language itself), but:

It'd be helpful - to me at least - with some more documentation on the types and how to work with them.

As the first question: In server_test.go I was trying to add a test to check that the appropriate response was returned, but r.Extra[0] is just an RR, but the content really is an RR_TXT. How do I cast it so I can access the .Txt ?

    m.SetQuestion("miek.nl.", TypeTXT)
    r, _ = c.Exchange(m, "127.0.0.1:8053")
    fmt.Println("Miek.nl:", r.Extra[0])  // not useful, but .Txt or .(RR_TXT).Txt doesn't work

Should SetRcode set Authoriative=false?

I noticed that my server wasn't returning the 'aa' bit for NXDOMAIN replies. I use msg.SetRcode to setup that reply and that code sets Authoritative to false. Shouldn't it leave that bit alone?

// SetRcode creates an error packet suitable for the request.
func (dns *Msg) SetRcode(request *Msg, rcode int) *Msg {
        dns.MsgHdr.Rcode = rcode
        dns.MsgHdr.Opcode = OpcodeQuery
        dns.MsgHdr.Response = true
        dns.MsgHdr.Authoritative = false
        dns.MsgHdr.Id = request.MsgHdr.Id
        dns.Question = make([]Question, 1)
        dns.Question[0] = request.Question[0]
        return dns
}

Or am I just doing it wrong? abh/geodns@45c00a7

undefined: TXT

if t, ok := in.Answer[len(in.Answer)-1].(*TXT); ok {
fmt.Printf(t.Txt)
// do something with t.Txt
}

I got undefined: TXT

dns.PackDomainName panic with bad NS records

Putting production traffic on my server made it panic with an "index out of range" error from msg.go (see below). The error was that my NS records weren't fqdn's (no dot at the end). Not sure if crashing is appropriate (if so just close the ticket) or if it should have been caught in some other way.

;; opcode: QUERY, status: NOERROR, id: 32885
;; flags: qr aa; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;pool.ntp.org.  IN   NS

;; ANSWER SECTION:
pool.ntp.org.   390 IN  NS  a.ntpns.org
pool.ntp.org.   390 IN  NS  b.ntpns.org
pool.ntp.org.   390 IN  NS  c.ntpns.org

panic: runtime error: index out of range

goroutine 2446 [running]:
github.com/miekg/dns.PackDomainName(0x18e7a200, 0xc, 0x1919e870, 0x8b, 0x8b, ...)
    /opt/go/src/github.com/miekg/dns/msg.go:245 +0x33c
github.com/miekg/dns.packStructValue(0x81861fc, 0x18c9a4e0, 0x196, 0x1919e870, 0x8b, ...)
    /opt/go/src/github.com/miekg/dns/msg.go:590 +0x323a
github.com/miekg/dns.packStructCompress(0x818c380, 0x18c9a4e0, 0x1919e870, 0x8b, 0x8b, ...)
    /opt/go/src/github.com/miekg/dns/msg.go:658 +0x71
github.com/miekg/dns.PackRR(0x1892d900, 0x18c9a4e0, 0x1919e870, 0x8b, 0x8b, ...)
    /opt/go/src/github.com/miekg/dns/msg.go:1064 +0x7e
github.com/miekg/dns.(*Msg).Pack(0x18dc6500, 0x1919e870, 0x8b, 0x8b, 0x18848090, ...)
    /opt/go/src/github.com/miekg/dns/msg.go:1222 +0x3c8
github.com/miekg/dns.(*response).Write(0x18e53640, 0x18dc6500, 0x0, 0x0)
    /opt/go/src/github.com/miekg/dns/server.go:369 +0x17b
main.serve(0x188da360, 0x18e53640, 0x1919f3c0, 0x188d9a00, 0x188d99b4, ...)
    /opt/geodns/serve.go:98 +0xe3f
main._func_003(0x188e38c0, 0x8086488, 0x188da360, 0x18e53640, 0x1919f3c0, ...)
    /opt/geodns/serve.go:129 +0x3e
github.com/miekg/dns.HandlerFunc.ServeDNS(0x188d99a0, 0x188da360, 0x18e53640, 0x1919f3c0, 0x18873040, ...)
    /opt/go/src/github.com/miekg/dns/server.go:75 +0x35
github.com/miekg/dns.(*ServeMux).ServeDNS(0x188481c8, 0x188da360, 0x18e53640, 0x1919f3c0, 0x18e53640, ...)
    /opt/go/src/github.com/miekg/dns/server.go:147 +0xf0
github.com/miekg/dns.(*conn).serve(0x18dc7480, 0x0)
    /opt/go/src/github.com/miekg/dns/server.go:343 +0x251
created by github.com/miekg/dns.(*Server).ServeUDP
    /opt/go/src/github.com/miekg/dns/server.go:288 +0x318

Panic in decode

This is from a downstream issue: hashicorp/consul#284

Looks like there is an issue in dns.unpackStructValue that can cause a panic. That ticket has all the information I know about this currently.

String() wrappers for DNS class and type values

it would be nice to have wrappers for the TypeToString and ClassToString maps that return the mnemonic if known, or RFC 3597 compliant generic representations otherwise. something like this:

import "strconv"

type RRType uint16
type RRClass uint16

func (t RRType) String() string {
    if s, ok := dns.TypeToString[uint16(t)]; ok {
        return s
    } else {
        return "TYPE" + strconv.Itoa(int(t))
    }
}

func (c RRClass) String() string {
    if s, ok := dns.ClassToString[uint16(c)]; ok {
        return s
    } else {
        return "CLASS" + strconv.Itoa(int(c))
    }
}

so that one could simply format integer class and type values with e.g.

fmt.Println("the rrclass is", dns.RRClass(rrclass))
fmt.Println("the rrtype is", dns.RRType(rrtype))

instead of the ten or so lines it would take otherwise.

Build fails

I'm cross-posting this issue (inhies/cjdcmd#39), because it actually belongs here.

I was building a packages that apparently depends on github.com/miekg/dns and stumbled upon an error in miekg/dns/labels.go, as follows:

$ go get github.com/inhies/cjdcmd
github.com/miekg/dns
projects/go/src/github.com/miekg/dns/labels.go:108: function ends without a return statement
projects/go/src/github.com/miekg/dns/labels.go:132: function ends without a return statement

System: Ubuntu 12.04 (amd64), go version go1.0.3b

I managed to solve this issue by adding something like "return CountLabes(s)" and "return Split(s)" to the end of the respective functions. Now it builds successfully. As I am a no good programmer and have never coded in golang, I did not dare to fork, edit and submit a pull request.

Thank you.

dns: bad rdlength

This is similar to issue #67 I filed, but instead of resolving for apple.com, if you choose google.com, I always get "dns: bad rdlength" when sending the response back to the client.

Lowercased Class and RRType could not be parsed

I was playing here and converted whole RR into lower case for some reason. That triggered inability of parser to read that RR back.

IMO needs to be corrected. I can work on it if needed with your recommendations. Case-insensitive support is somewhat implemented in parsing RRSIG but not in parsing RRs themselves, not sure why. maybe whole piece for reading type or class from buffer should be separated into function...

Packing overflow / compression bug

In some cases, I'm using the client to act like a recursive DNS server. However, with some queries, I get the following:

dns: overflow packing uint32

It seems to have to do with something in the response body. I have a minimal test case here: https://gist.github.com/armon/8248769

Once you run that server, use the following dig command:

time dig @127.0.0.1 -p 8600 +qr apple.com ANY

Inside the test case, there is a line with a comment to toggle the value. The compression flag on the response seems to change if this works. With compression enabled, the response goes through fine. Without compression, the packing error happens.

panic with msg.Len() with no SOA Hostmaster

Yes, the result is not standards-compliant. But no, it shouldn't result in a panic.

func NewSOA(answeringServer string, hostmaster string) dns.RR {
    return &dns.SOA{Hdr: dns.RR_Header{Name: answeringServer, Rrtype: dns.TypeSOA, Class: dns.ClassINET, Ttl: 12345},
        Ns:      answeringServer,
        Mbox:    hostmaster,
        Serial:  uint32(time.Now().Truncate(time.Hour).Unix()),
        Refresh: 28800,
        Retry:   7200,
        Expire:  604800,
        Minttl:  60,
    }
}

func NameError(m, req *dns.Msg) {
    //m.SetRcode(req, dns.RcodeNameError)
    m.Ns = []dns.RR{NewSOA("local.dns.skydns.local.", "")} // <-------------- "" is the Hostmaster
    m.Ns[0].Header().Ttl = 60 // s.config.MinTtl
    // StatsNameErrorCount.Inc(1)
}

func main() {
    m := new(dns.Msg)
    // START header
    m.Id = 33074
    m.Response = true
    m.Opcode = 0
    m.Authoritative = true
    m.Truncated = false // about to be set
    m.RecursionDesired = true
    m.RecursionAvailable = true
    m.Zero = false
    m.AuthenticatedData = false
    m.CheckingDisabled = false
    m.Rcode = 3
    // END header
    m.Compress = true // <-----------------
    // question
    m.Question = make([]dns.Question, 1)
    m.Question[0] = dns.Question{"skydns.test.", dns.TypeNS, dns.ClassINET}
    // EMPTY answer
    // ns
    NameError(m, nil)
    // EMPTY extra

    fmt.Println(m.Len())
}

I've run into this while testing SkyDNS. The corresponding entries in etcd went away resulting in an empty "Hostmaster" field.

SetRcode index out of range

One of the servers crashed with this last night:

2012-09-02 02:46:54.288897500 panic: runtime error: index out of range
2012-09-02 02:46:54.288902500 
2012-09-02 02:46:54.288905500 goroutine 1146879 [running]:
2012-09-02 02:46:54.288908500 github.com/miekg/dns.(*Msg).SetRcode(0x1d215dc0, 0x1d215d70, 0x2, 0x269f48, 0x1d215dc0, ...)
2012-09-02 02:46:54.288912500   /opt/go/src/github.com/miekg/dns/defaults.go:51 +0x9a
2012-09-02 02:46:54.288916500 github.com/miekg/dns.Failed(0x18801a80, 0x1b3ac220, 0x1d215d70, 0x8087b07)
2012-09-02 02:46:54.288919500   /opt/go/src/github.com/miekg/dns/server.go:88 +0x49
2012-09-02 02:46:54.288981500 github.com/miekg/dns.HandlerFunc.ServeDNS(0x808768e, 0x18801a80, 0x1b3ac220, 0x1d215d70, 0x808768e, ...)
2012-09-02 02:46:54.288986500   /opt/go/src/github.com/miekg/dns/server.go:81 +0x35
2012-09-02 02:46:54.288989500 github.com/miekg/dns.(*ServeMux).ServeDNS(0x188491c8, 0x18801a80, 0x1b3ac220, 0x1d215d70, 0x1b3ac220, ...)
2012-09-02 02:46:54.288993500   /opt/go/src/github.com/miekg/dns/server.go:156 +0xa2
2012-09-02 02:46:54.288997500 github.com/miekg/dns.(*conn).serve(0x1a0b6930, 0x1)
2012-09-02 02:46:54.296310500   /opt/go/src/github.com/miekg/dns/server.go:341 +0x28e
2012-09-02 02:46:54.296314500 created by github.com/miekg/dns.(*Server).serveUDP
2012-09-02 02:46:54.296318500   /opt/go/src/github.com/miekg/dns/server.go:299 +0x314
2012-09-02 02:46:54.296321500 

NAPTR lookup only appears to support 9 records in the msg.Answer

I have a NAPTR I am querying from a private DNS server. I am able to query and retrieve the msg in msg.Answer, but the library appears to provide a maximum of 9 entries in that msg.Answer. In this case, I actually have 10 in that NAPTR.

Since there is no guaranteed order, it is usually one of two fields that ends up always missing. If I use 'dig', I am able to get all 10 records each time.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.