Full Code of miekg/dns for AI

master cd053176d80a cached
105 files
913.8 KB
319.8k tokens
2144 symbols
1 requests
Download .txt
Showing preview only (950K chars total). Download the full file or copy to clipboard to get everything.
Repository: miekg/dns
Branch: master
Commit: cd053176d80a
Files: 105
Total size: 913.8 KB

Directory structure:
gitextract_r63mkn93/

├── .codecov.yml
├── .github/
│   ├── dependabot.yml
│   ├── pull_request_template.md
│   └── workflows/
│       ├── codeql-analysis.yml
│       └── go.yml
├── .gitignore
├── AUTHORS
├── CODEOWNERS
├── CONTRIBUTORS
├── COPYRIGHT
├── LICENSE
├── Makefile.fuzz
├── Makefile.release
├── README.md
├── acceptfunc.go
├── acceptfunc_test.go
├── client.go
├── client_test.go
├── clientconfig.go
├── clientconfig_test.go
├── dane.go
├── defaults.go
├── dns.go
├── dns_bench_test.go
├── dns_test.go
├── dnssec.go
├── dnssec_keygen.go
├── dnssec_keyscan.go
├── dnssec_privkey.go
├── dnssec_test.go
├── dnsutil/
│   ├── util.go
│   └── util_test.go
├── doc.go
├── duplicate.go
├── duplicate_generate.go
├── duplicate_test.go
├── dyn_test.go
├── edns.go
├── edns_test.go
├── example_test.go
├── format.go
├── format_test.go
├── fuzz.go
├── fuzz_test.go
├── generate.go
├── generate_test.go
├── go.mod
├── go.sum
├── hash.go
├── issue_test.go
├── labels.go
├── labels_test.go
├── leak_test.go
├── length_test.go
├── listen_no_socket_options.go
├── listen_socket_options.go
├── msg.go
├── msg_generate.go
├── msg_helpers.go
├── msg_helpers_test.go
├── msg_test.go
├── msg_truncate.go
├── msg_truncate_test.go
├── nsecx.go
├── nsecx_test.go
├── parse_test.go
├── privaterr.go
├── privaterr_test.go
├── reverse.go
├── rr_test.go
├── sanitize.go
├── sanitize_test.go
├── scan.go
├── scan_rr.go
├── scan_test.go
├── serve_mux.go
├── serve_mux_test.go
├── server.go
├── server_test.go
├── sig0.go
├── sig0_test.go
├── smimea.go
├── svcb.go
├── svcb_test.go
├── tlsa.go
├── tmpdir_darwin_test.go
├── tmpdir_test.go
├── tools.go
├── tsig.go
├── tsig_test.go
├── types.go
├── types_generate.go
├── types_test.go
├── udp.go
├── udp_no_control.go
├── udp_test.go
├── update.go
├── update_test.go
├── version.go
├── version_test.go
├── xfr.go
├── xfr_test.go
├── zduplicate.go
├── zmsg.go
└── ztypes.go

================================================
FILE CONTENTS
================================================

================================================
FILE: .codecov.yml
================================================
coverage:
  status:
    project:
      default:
        target: 40%
        threshold: null
    patch: false
    changes: false


================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
  - package-ecosystem: "gomod"
    directory: "/"
    schedule:
      interval: "monthly"
    groups:
      all:
        patterns:
          - "*"


================================================
FILE: .github/pull_request_template.md
================================================
Thanks for you pull request, do note the following:

- If your PR introduces backward incompatible changes it will very likely not be merged.

- We support the last two major Go versions, if your PR uses features from a too new Go version, it
  will not be merged.

- If this text is not replaced (deleted, or preferably replaced with something sensible), your PR will be closed.


================================================
FILE: .github/workflows/codeql-analysis.yml
================================================
name: "Code scanning - action"

on:
  push:
    branches: [master, ]
  pull_request:
    branches: [master]
  schedule:
    - cron: '0 23 * * 5'

jobs:
  CodeQL-Build:

    runs-on: ubuntu-latest

    steps:
    - name: Checkout repository
      uses: actions/checkout@v3
      with:
        fetch-depth: 2

    - run: git checkout HEAD^2
      if: ${{ github.event_name == 'pull_request' }}

    - name: Initialize CodeQL
      uses: github/codeql-action/init@v2

    - name: Autobuild
      uses: github/codeql-action/autobuild@v2

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v2


================================================
FILE: .github/workflows/go.yml
================================================
name: Go
on: [push, pull_request]
jobs:

  build:
    name: Build and Test
    runs-on: ubuntu-latest
    strategy:
      matrix:
        go: [ 1.22.x, 1.23.x, 1.24.x ]
    steps:

    - name: Set up Go
      uses: actions/setup-go@v3
      with:
        go-version: ${{ matrix.go }}

    - name: Check out code
      uses: actions/checkout@v3

    - name: Build
      run: go build -v ./...

    - name: Test
      run: go test -v ./...


================================================
FILE: .gitignore
================================================
*.6
tags
test.out
a.out


================================================
FILE: AUTHORS
================================================
Miek Gieben <miek@miek.nl>


================================================
FILE: CODEOWNERS
================================================
* @miekg @tmthrgd


================================================
FILE: CONTRIBUTORS
================================================
Alex A. Skinner
Andrew Tunnell-Jones
Ask Bjørn Hansen
Dave Cheney
Dusty Wilson
Marek Majkowski
Peter van Dijk
Omri Bahumi
Alex Sergeyev
James Hartig


================================================
FILE: COPYRIGHT
================================================
Copyright 2009 The Go Authors. All rights reserved. Use of this source code
is governed by a BSD-style license that can be found in the LICENSE file.
Extensions of the original work are copyright (c) 2011 Miek Gieben

Copyright 2011 Miek Gieben. All rights reserved. Use of this source code is
governed by a BSD-style license that can be found in the LICENSE file.

Copyright 2014 CloudFlare. All rights reserved. Use of this source code is
governed by a BSD-style license that can be found in the LICENSE file.


================================================
FILE: LICENSE
================================================
BSD 3-Clause License

Copyright (c) 2009, The Go Authors. Extensions copyright (c) 2011, Miek Gieben. 
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its
   contributors may be used to endorse or promote products derived from
   this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


================================================
FILE: Makefile.fuzz
================================================
# Makefile for fuzzing
#
# Use go-fuzz and needs the tools installed.
# See https://blog.cloudflare.com/dns-parser-meet-go-fuzzer/
#
# Installing go-fuzz:
# $ make -f Makefile.fuzz get
# Installs:
# * github.com/dvyukov/go-fuzz/go-fuzz
# * get github.com/dvyukov/go-fuzz/go-fuzz-build

all: build

.PHONY: build
build:
	go-fuzz-build -tags fuzz github.com/miekg/dns

.PHONY: build-newrr
build-newrr:
	go-fuzz-build -func FuzzNewRR -tags fuzz github.com/miekg/dns

.PHONY: fuzz
fuzz:
	go-fuzz -bin=dns-fuzz.zip -workdir=fuzz

.PHONY: get
get:
	go get github.com/dvyukov/go-fuzz/go-fuzz
	go get github.com/dvyukov/go-fuzz/go-fuzz-build

.PHONY: clean
clean:
	rm *-fuzz.zip


================================================
FILE: Makefile.release
================================================
# Makefile for releasing.
#
# The release is controlled from version.go. The version found there is
# used to tag the git repo, we're not building any artifacts so there is nothing
# to upload to github.
#
# * Up the version in version.go
# * Run: make -f Makefile.release release
#   * will *commit* your change with 'Release $VERSION'
#   * push to github
#

define GO
//+build ignore

package main

import (
	"fmt"

	"github.com/miekg/dns"
)

func main() {
	fmt.Println(dns.Version.String())
}
endef

$(file > version_release.go,$(GO))
VERSION:=$(shell go run version_release.go)
TAG="v$(VERSION)"

all:
	@echo Use the \'release\' target to start a release $(VERSION)
	rm -f version_release.go

.PHONY: release
release: commit push
	@echo Released $(VERSION)
	rm -f version_release.go

.PHONY: commit
commit:
	@echo Committing release $(VERSION)
	git commit -am"Release $(VERSION)"
	git tag $(TAG)

.PHONY: push
push:
	@echo Pushing release $(VERSION) to master
	git push --tags
	git push


================================================
FILE: README.md
================================================
[![Build Status](https://travis-ci.org/miekg/dns.svg?branch=master)](https://travis-ci.org/miekg/dns)
[![Code Coverage](https://img.shields.io/codecov/c/github/miekg/dns/master.svg)](https://codecov.io/github/miekg/dns?branch=master)
[![Go Report Card](https://goreportcard.com/badge/github.com/miekg/dns)](https://goreportcard.com/report/miekg/dns)
[![](https://godoc.org/github.com/miekg/dns?status.svg)](https://godoc.org/github.com/miekg/dns)

DNS version 2 is now available at <https://codeberg.org/miekg/dns>. This version should be 2x faster across
the board. Further optimizations welcome.

The version here will only see specific fixes and nothing else. At some point this repo will be archived.

# 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:

- https://github.com/coredns/coredns
- https://github.com/abh/geodns
- https://github.com/baidu/bfe
- http://www.statdns.com/
- http://www.dnsinspect.com/
- https://github.com/chuangbo/jianbing-dictionary-dns
- http://www.dns-lg.com/
- https://github.com/fcambus/rrda
- https://github.com/kenshinx/godns
- https://github.com/skynetservices/skydns
- https://github.com/hashicorp/consul
- https://github.com/DevelopersPL/godnsagent
- https://github.com/duedil-ltd/discodns
- https://github.com/StalkR/dns-reverse-proxy
- https://github.com/tianon/rawdns
- https://mesosphere.github.io/mesos-dns/
- https://github.com/fcambus/statzone
- https://github.com/benschw/dns-clb-go
- https://github.com/corny/dnscheck for <http://public-dns.info/>
- https://github.com/miekg/unbound
- https://github.com/miekg/exdns
- https://dnslookup.org
- https://github.com/looterz/grimd
- https://github.com/phamhongviet/serf-dns
- https://github.com/mehrdadrad/mylg
- https://github.com/bamarni/dockness
- https://github.com/fffaraz/microdns
- https://github.com/ipdcode/hades <https://jd.com>
- https://github.com/StackExchange/dnscontrol/
- https://www.dnsperf.com/
- https://dnssectest.net/
- https://github.com/oif/apex
- https://github.com/jedisct1/dnscrypt-proxy (migrated to v2)
- https://github.com/jedisct1/rpdns
- https://github.com/xor-gate/sshfp
- https://github.com/rs/dnstrace
- https://blitiri.com.ar/p/dnss ([github mirror](https://github.com/albertito/dnss))
- https://render.com
- https://github.com/peterzen/goresolver
- https://github.com/folbricht/routedns
- https://domainr.com/
- https://zonedb.org/
- https://router7.org/
- https://github.com/fortio/dnsping
- https://github.com/Luzilla/dnsbl_exporter
- https://github.com/bodgit/tsig
- https://github.com/v2fly/v2ray-core (test only)
- https://kuma.io/
- https://www.misaka.io/services/dns
- https://ping.sx/dig
- https://fleetdeck.io/
- https://github.com/markdingo/autoreverse
- https://github.com/slackhq/nebula
- https://addr.tools/
- https://dnscheck.tools/
- https://github.com/egbakou/domainverifier
- https://github.com/semihalev/sdns
- https://github.com/wintbiit/NineDNS
- https://linuxcontainers.org/incus/
- https://ifconfig.es
- https://github.com/zmap/zdns
- https://framagit.org/bortzmeyer/check-soa
- https://github.com/jkerdreux-imt/owns

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 - <miek@miek.nl>
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
- 3596 - AAAA record
- 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
- 8490 - DNS Stateful Operations
- 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)
- 9460 - Service Binding and Parameter Specification via the DNS
- 9461 - Service Binding Mapping for DNS Servers
- 9462 - Discovery of Designated Resolvers
- 9460 - SVCB and HTTPS Records
- 9567 - DNS Error Reporting
- 9606 - DNS Resolver Information
- 9660 - DNS Zone Version (ZONEVERSION) Option
- Draft - Compact Denial of Existence in DNSSEC

## Loosely Based Upon

- ldns - <https://nlnetlabs.nl/projects/ldns/about/>
- NSD - <https://nlnetlabs.nl/projects/nsd/about/>
- Net::DNS - <http://www.net-dns.org/>
- GRONG - <https://github.com/bortzmeyer/grong>


================================================
FILE: acceptfunc.go
================================================
package dns

// MsgAcceptFunc is used early in the server code to accept or reject a message with RcodeFormatError.
// It returns a MsgAcceptAction to indicate what should happen with the message.
type MsgAcceptFunc func(dh Header) MsgAcceptAction

// DefaultMsgAcceptFunc checks the request and will reject if:
//
// * isn't a request (don't respond in that case)
//
// * opcode isn't OpcodeQuery or OpcodeNotify
//
// * does not have exactly 1 question in the question section
//
// * has more than 1 RR in the Answer section
//
// * has more than 0 RRs in the Authority section
//
// * has more than 2 RRs in the Additional section
var DefaultMsgAcceptFunc MsgAcceptFunc = defaultMsgAcceptFunc

// MsgAcceptAction represents the action to be taken.
type MsgAcceptAction int

// Allowed returned values from a MsgAcceptFunc.
const (
	MsgAccept               MsgAcceptAction = iota // Accept the message
	MsgReject                                      // Reject the message with a RcodeFormatError
	MsgIgnore                                      // Ignore the error and send nothing back.
	MsgRejectNotImplemented                        // Reject the message with a RcodeNotImplemented
)

func defaultMsgAcceptFunc(dh Header) MsgAcceptAction {
	if isResponse := dh.Bits&_QR != 0; isResponse {
		return MsgIgnore
	}

	// Don't allow dynamic updates, because then the sections can contain a whole bunch of RRs.
	opcode := int(dh.Bits>>11) & 0xF
	if opcode != OpcodeQuery && opcode != OpcodeNotify {
		return MsgRejectNotImplemented
	}

	if dh.Qdcount != 1 {
		return MsgReject
	}
	// NOTIFY requests can have a SOA in the ANSWER section. See RFC 1996 Section 3.7 and 3.11.
	if dh.Ancount > 1 {
		return MsgReject
	}
	// IXFR request could have one SOA RR in the NS section. See RFC 1995, section 3.
	if dh.Nscount > 1 {
		return MsgReject
	}
	if dh.Arcount > 2 {
		return MsgReject
	}
	return MsgAccept
}


================================================
FILE: acceptfunc_test.go
================================================
package dns

import (
	"encoding/binary"
	"net"
	"testing"
)

func TestAcceptNotify(t *testing.T) {
	HandleFunc("example.org.", handleNotify)
	s, addrstr, _, err := RunLocalUDPServer(":0")
	if err != nil {
		t.Fatalf("unable to run test server: %v", err)
	}
	defer s.Shutdown()

	m := new(Msg)
	m.SetNotify("example.org.")
	// Set a SOA hint in the answer section, this is allowed according to RFC 1996.
	soa, _ := NewRR("example.org. IN SOA sns.dns.icann.org. noc.dns.icann.org. 2018112827 7200 3600 1209600 3600")
	m.Answer = []RR{soa}

	c := new(Client)
	resp, _, err := c.Exchange(m, addrstr)
	if err != nil {
		t.Errorf("failed to exchange: %v", err)
	}
	if resp.Rcode != RcodeSuccess {
		t.Errorf("expected %s, got %s", RcodeToString[RcodeSuccess], RcodeToString[resp.Rcode])
	}
}

func handleNotify(w ResponseWriter, req *Msg) {
	m := new(Msg)
	m.SetReply(req)
	w.WriteMsg(m)
}

func TestInvalidMsg(t *testing.T) {
	HandleFunc("example.org.", func(ResponseWriter, *Msg) {
		t.Fatal("the handler must not be called in any of these tests")
	})
	s, addrstr, _, err := RunLocalTCPServer(":0")
	if err != nil {
		t.Fatalf("unable to run test server: %v", err)
	}
	defer s.Shutdown()

	s.MsgAcceptFunc = func(dh Header) MsgAcceptAction {
		switch dh.Id {
		case 0x0001:
			return MsgAccept
		case 0x0002:
			return MsgReject
		case 0x0003:
			return MsgIgnore
		case 0x0004:
			return MsgRejectNotImplemented
		default:
			t.Errorf("unexpected ID %x", dh.Id)
			return -1
		}
	}

	invalidErrors := make(chan error)
	s.MsgInvalidFunc = func(m []byte, err error) {
		invalidErrors <- err
	}

	c, err := net.Dial("tcp", addrstr)
	if err != nil {
		t.Fatalf("cannot connect to test server: %v", err)
	}

	write := func(m []byte) {
		var length [2]byte
		binary.BigEndian.PutUint16(length[:], uint16(len(m)))
		_, err := c.Write(length[:])
		if err != nil {
			t.Fatalf("length write failed: %v", err)
		}
		_, err = c.Write(m)
		if err != nil {
			t.Fatalf("content write failed: %v", err)
		}
	}

	/* Message is too short, so there is no header to accept or reject. */

	tooShortMessage := make([]byte, 11)
	tooShortMessage[1] = 0x3 // ID = 3, would be ignored if it were parsable.

	write(tooShortMessage)
	// Expect an error to be reported.
	<-invalidErrors

	/* Message is accepted but is actually invalid. */

	badMessage := make([]byte, 13)
	badMessage[1] = 0x1 // ID = 1, Accept.
	badMessage[5] = 1   // QDCOUNT = 1
	badMessage[12] = 99 // Bad question section.  Invalid!

	write(badMessage)
	// Expect an error to be reported.
	<-invalidErrors

	/* Message is rejected before it can be determined to be invalid. */

	close(invalidErrors) // A call to InvalidMsgFunc would panic due to the closed chan.

	badMessage[1] = 0x2 // ID = 2, Reject
	write(badMessage)

	badMessage[1] = 0x3 // ID = 3, Ignore
	write(badMessage)

	badMessage[1] = 0x4 // ID = 4, RejectNotImplemented
	write(badMessage)
}


================================================
FILE: client.go
================================================
package dns

// A client implementation.

import (
	"context"
	"crypto/tls"
	"encoding/binary"
	"io"
	"net"
	"strings"
	"time"
)

const (
	dnsTimeout     time.Duration = 2 * time.Second
	tcpIdleTimeout time.Duration = 8 * time.Second
)

func isPacketConn(c net.Conn) bool {
	if _, ok := c.(net.PacketConn); !ok {
		return false
	}

	if ua, ok := c.LocalAddr().(*net.UnixAddr); ok {
		return ua.Net == "unixgram" || ua.Net == "unixpacket"
	}

	return true
}

// A Conn represents a connection to a DNS server.
type Conn struct {
	net.Conn                         // a net.Conn holding the connection
	UDPSize        uint16            // minimum receive buffer for UDP messages
	TsigSecret     map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2)
	TsigProvider   TsigProvider      // An implementation of the TsigProvider interface. If defined it replaces TsigSecret and is used for all TSIG operations.
	tsigRequestMAC string
}

func (co *Conn) tsigProvider() TsigProvider {
	if co.TsigProvider != nil {
		return co.TsigProvider
	}
	// tsigSecretProvider will return ErrSecret if co.TsigSecret is nil.
	return tsigSecretProvider(co.TsigSecret)
}

// A Client defines parameters for a DNS client.
type Client struct {
	Net       string      // if "tcp" or "tcp-tls" (DNS over TLS) a TCP query will be initiated, otherwise an UDP one (default is "" for UDP)
	UDPSize   uint16      // minimum receive buffer for UDP messages
	TLSConfig *tls.Config // TLS connection configuration
	Dialer    *net.Dialer // a net.Dialer used to set local address, timeouts and more
	// Timeout is a cumulative timeout for dial, write and read, defaults to 0 (disabled) - overrides DialTimeout, ReadTimeout,
	// WriteTimeout when non-zero. Can be overridden with net.Dialer.Timeout (see Client.ExchangeWithDialer and
	// Client.Dialer) or context.Context.Deadline (see ExchangeContext)
	Timeout      time.Duration
	DialTimeout  time.Duration     // net.DialTimeout, defaults to 2 seconds, or net.Dialer.Timeout if expiring earlier - overridden by Timeout when that value is non-zero
	ReadTimeout  time.Duration     // net.Conn.SetReadDeadline value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero
	WriteTimeout time.Duration     // net.Conn.SetWriteDeadline value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero
	TsigSecret   map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2)
	TsigProvider TsigProvider      // An implementation of the TsigProvider interface. If defined it replaces TsigSecret and is used for all TSIG operations.

	// SingleInflight previously serialised multiple concurrent queries for the
	// same Qname, Qtype and Qclass to ensure only one would be in flight at a
	// time.
	//
	// Deprecated: This is a no-op. Callers should implement their own in flight
	// query caching if needed. See github.com/miekg/dns/issues/1449.
	SingleInflight bool
}

// Exchange performs a synchronous UDP query. It sends the message m to the address
// contained in a and waits for a reply. Exchange does not retry a failed query, nor
// will it fall back to TCP in case of truncation.
// See client.Exchange for more information on setting larger buffer sizes.
func Exchange(m *Msg, a string) (r *Msg, err error) {
	client := Client{Net: "udp"}
	r, _, err = client.Exchange(m, a)
	return r, err
}

func (c *Client) dialTimeout() time.Duration {
	if c.Timeout != 0 {
		return c.Timeout
	}
	if c.DialTimeout != 0 {
		return c.DialTimeout
	}
	return dnsTimeout
}

func (c *Client) readTimeout() time.Duration {
	if c.Timeout != 0 {
		return c.Timeout
	}
	if c.ReadTimeout != 0 {
		return c.ReadTimeout
	}
	return dnsTimeout
}

func (c *Client) writeTimeout() time.Duration {
	if c.Timeout != 0 {
		return c.Timeout
	}
	if c.WriteTimeout != 0 {
		return c.WriteTimeout
	}
	return dnsTimeout
}

// Dial connects to the address on the named network.
func (c *Client) Dial(address string) (conn *Conn, err error) {
	return c.DialContext(context.Background(), address)
}

// DialContext connects to the address on the named network, with a context.Context.
func (c *Client) DialContext(ctx context.Context, address string) (conn *Conn, err error) {
	// create a new dialer with the appropriate timeout
	var d net.Dialer
	if c.Dialer == nil {
		d = net.Dialer{Timeout: c.getTimeoutForRequest(c.dialTimeout())}
	} else {
		d = *c.Dialer
	}

	network := c.Net
	if network == "" {
		network = "udp"
	}

	useTLS := strings.HasPrefix(network, "tcp") && strings.HasSuffix(network, "-tls")

	conn = new(Conn)
	if useTLS {
		network = strings.TrimSuffix(network, "-tls")

		tlsDialer := tls.Dialer{
			NetDialer: &d,
			Config:    c.TLSConfig,
		}
		conn.Conn, err = tlsDialer.DialContext(ctx, network, address)
	} else {
		conn.Conn, err = d.DialContext(ctx, network, address)
	}
	if err != nil {
		return nil, err
	}
	conn.UDPSize = c.UDPSize
	return conn, nil
}

// Exchange performs a synchronous query. It sends the message m to the address
// contained in a and waits for a reply. Basic use pattern with a *dns.Client:
//
//	c := new(dns.Client)
//	in, rtt, err := c.Exchange(message, "127.0.0.1:53")
//
// Exchange does not retry a failed query, nor will it fall back to TCP in
// case of truncation.
// It is up to the caller to create a message that allows for larger responses to be
// returned. Specifically this means adding an EDNS0 OPT RR that will advertise a larger
// buffer, see SetEdns0. Messages without an OPT RR will fallback to the historic limit
// of 512 bytes
// To specify a local address or a timeout, the caller has to set the `Client.Dialer`
// attribute appropriately
func (c *Client) Exchange(m *Msg, address string) (r *Msg, rtt time.Duration, err error) {
	co, err := c.Dial(address)

	if err != nil {
		return nil, 0, err
	}
	defer co.Close()
	return c.ExchangeWithConn(m, co)
}

// ExchangeWithConn has the same behavior as Exchange, just with a predetermined connection
// that will be used instead of creating a new one.
// Usage pattern with a *dns.Client:
//
//	c := new(dns.Client)
//	// connection management logic goes here
//
//	conn := c.Dial(address)
//	in, rtt, err := c.ExchangeWithConn(message, conn)
//
// This allows users of the library to implement their own connection management,
// as opposed to Exchange, which will always use new connections and incur the added overhead
// that entails when using "tcp" and especially "tcp-tls" clients.
func (c *Client) ExchangeWithConn(m *Msg, conn *Conn) (r *Msg, rtt time.Duration, err error) {
	return c.ExchangeWithConnContext(context.Background(), m, conn)
}

// ExchangeWithConnContext has the same behaviour as ExchangeWithConn and
// additionally obeys deadlines from the passed Context.
func (c *Client) ExchangeWithConnContext(ctx context.Context, m *Msg, co *Conn) (r *Msg, rtt time.Duration, err error) {
	opt := m.IsEdns0()
	// If EDNS0 is used use that for size.
	if opt != nil && opt.UDPSize() >= MinMsgSize {
		co.UDPSize = opt.UDPSize()
	}
	// Otherwise use the client's configured UDP size.
	if opt == nil && c.UDPSize >= MinMsgSize {
		co.UDPSize = c.UDPSize
	}

	// write with the appropriate write timeout
	t := time.Now()
	writeDeadline := t.Add(c.getTimeoutForRequest(c.writeTimeout()))
	readDeadline := t.Add(c.getTimeoutForRequest(c.readTimeout()))
	if deadline, ok := ctx.Deadline(); ok {
		if deadline.Before(writeDeadline) {
			writeDeadline = deadline
		}
		if deadline.Before(readDeadline) {
			readDeadline = deadline
		}
	}
	co.SetWriteDeadline(writeDeadline)
	co.SetReadDeadline(readDeadline)

	co.TsigSecret, co.TsigProvider = c.TsigSecret, c.TsigProvider

	if err = co.WriteMsg(m); err != nil {
		return nil, 0, err
	}

	if isPacketConn(co.Conn) {
		for {
			r, err = co.ReadMsg()
			// Ignore replies with mismatched IDs because they might be
			// responses to earlier queries that timed out.
			if err != nil || r.Id == m.Id {
				break
			}
		}
	} else {
		r, err = co.ReadMsg()
		if err == nil && r.Id != m.Id {
			err = ErrId
		}
	}
	rtt = time.Since(t)
	return r, rtt, err
}

// ReadMsg reads a message from the connection co.
// If the received message contains a TSIG record the transaction signature
// is verified. This method always tries to return the message, however if an
// error is returned there are no guarantees that the returned message is a
// valid representation of the packet read.
func (co *Conn) ReadMsg() (*Msg, error) {
	p, err := co.ReadMsgHeader(nil)
	if err != nil {
		return nil, err
	}

	m := new(Msg)
	if err := m.Unpack(p); err != nil {
		// If an error was returned, we still want to allow the user to use
		// the message, but naively they can just check err if they don't want
		// to use an erroneous message
		return m, err
	}
	if t := m.IsTsig(); t != nil {
		// Need to work on the original message p, as that was used to calculate the tsig.
		err = TsigVerifyWithProvider(p, co.tsigProvider(), co.tsigRequestMAC, false)
	}
	return m, err
}

// ReadMsgHeader reads a DNS message, parses and populates hdr (when hdr is not nil).
// Returns message as a byte slice to be parsed with Msg.Unpack later on.
// Note that error handling on the message body is not possible as only the header is parsed.
func (co *Conn) ReadMsgHeader(hdr *Header) ([]byte, error) {
	var (
		p   []byte
		n   int
		err error
	)

	if isPacketConn(co.Conn) {
		if co.UDPSize > MinMsgSize {
			p = make([]byte, co.UDPSize)
		} else {
			p = make([]byte, MinMsgSize)
		}
		n, err = co.Read(p)
	} else {
		var length uint16
		if err := binary.Read(co.Conn, binary.BigEndian, &length); err != nil {
			return nil, err
		}

		p = make([]byte, length)
		n, err = io.ReadFull(co.Conn, p)
	}

	if err != nil {
		return nil, err
	} else if n < headerSize {
		return nil, ErrShortRead
	}

	p = p[:n]
	if hdr != nil {
		dh, _, err := unpackMsgHdr(p, 0)
		if err != nil {
			return nil, err
		}
		*hdr = dh
	}
	return p, err
}

// Read implements the net.Conn read method.
func (co *Conn) Read(p []byte) (n int, err error) {
	if co.Conn == nil {
		return 0, ErrConnEmpty
	}

	if isPacketConn(co.Conn) {
		// UDP connection
		return co.Conn.Read(p)
	}

	var length uint16
	if err := binary.Read(co.Conn, binary.BigEndian, &length); err != nil {
		return 0, err
	}
	if int(length) > len(p) {
		return 0, io.ErrShortBuffer
	}

	return io.ReadFull(co.Conn, p[:length])
}

// WriteMsg sends a message through the connection co.
// If the message m contains a TSIG record the transaction
// signature is calculated.
func (co *Conn) WriteMsg(m *Msg) (err error) {
	var out []byte
	if t := m.IsTsig(); t != nil {
		// Set tsigRequestMAC for the next read, although only used in zone transfers.
		out, co.tsigRequestMAC, err = TsigGenerateWithProvider(m, co.tsigProvider(), co.tsigRequestMAC, false)
	} else {
		out, err = m.Pack()
	}
	if err != nil {
		return err
	}
	_, err = co.Write(out)
	return err
}

// Write implements the net.Conn Write method.
func (co *Conn) Write(p []byte) (int, error) {
	if len(p) > MaxMsgSize {
		return 0, &Error{err: "message too large"}
	}

	if isPacketConn(co.Conn) {
		return co.Conn.Write(p)
	}

	msg := make([]byte, 2+len(p))
	binary.BigEndian.PutUint16(msg, uint16(len(p)))
	copy(msg[2:], p)
	return co.Conn.Write(msg)
}

// Return the appropriate timeout for a specific request
func (c *Client) getTimeoutForRequest(timeout time.Duration) time.Duration {
	var requestTimeout time.Duration
	if c.Timeout != 0 {
		requestTimeout = c.Timeout
	} else {
		requestTimeout = timeout
	}
	// net.Dialer.Timeout has priority if smaller than the timeouts computed so
	// far
	if c.Dialer != nil && c.Dialer.Timeout != 0 {
		if c.Dialer.Timeout < requestTimeout {
			requestTimeout = c.Dialer.Timeout
		}
	}
	return requestTimeout
}

// Dial connects to the address on the named network.
func Dial(network, address string) (conn *Conn, err error) {
	conn = new(Conn)
	conn.Conn, err = net.Dial(network, address)
	if err != nil {
		return nil, err
	}
	return conn, nil
}

// ExchangeContext performs a synchronous UDP query, like Exchange. It
// additionally obeys deadlines from the passed Context.
func ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, err error) {
	client := Client{Net: "udp"}
	r, _, err = client.ExchangeContext(ctx, m, a)
	// ignoring rtt to leave the original ExchangeContext API unchanged, but
	// this function will go away
	return r, err
}

// ExchangeConn performs a synchronous query. It sends the message m via the connection
// c and waits for a reply. The connection c is not closed by ExchangeConn.
// Deprecated: This function is going away, but can easily be mimicked:
//
//	co := &dns.Conn{Conn: c} // c is your net.Conn
//	co.WriteMsg(m)
//	in, _  := co.ReadMsg()
//	co.Close()
func ExchangeConn(c net.Conn, m *Msg) (r *Msg, err error) {
	println("dns: ExchangeConn: this function is deprecated")
	co := new(Conn)
	co.Conn = c
	if err = co.WriteMsg(m); err != nil {
		return nil, err
	}
	r, err = co.ReadMsg()
	if err == nil && r.Id != m.Id {
		err = ErrId
	}
	return r, err
}

// DialTimeout acts like Dial but takes a timeout.
func DialTimeout(network, address string, timeout time.Duration) (conn *Conn, err error) {
	client := Client{Net: network, Dialer: &net.Dialer{Timeout: timeout}}
	return client.Dial(address)
}

// DialWithTLS connects to the address on the named network with TLS.
func DialWithTLS(network, address string, tlsConfig *tls.Config) (conn *Conn, err error) {
	if !strings.HasSuffix(network, "-tls") {
		network += "-tls"
	}
	client := Client{Net: network, TLSConfig: tlsConfig}
	return client.Dial(address)
}

// DialTimeoutWithTLS acts like DialWithTLS but takes a timeout.
func DialTimeoutWithTLS(network, address string, tlsConfig *tls.Config, timeout time.Duration) (conn *Conn, err error) {
	if !strings.HasSuffix(network, "-tls") {
		network += "-tls"
	}
	client := Client{Net: network, Dialer: &net.Dialer{Timeout: timeout}, TLSConfig: tlsConfig}
	return client.Dial(address)
}

// ExchangeContext acts like Exchange, but honors the deadline on the provided
// context, if present. If there is both a context deadline and a configured
// timeout on the client, the earliest of the two takes effect.
func (c *Client) ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
	conn, err := c.DialContext(ctx, a)
	if err != nil {
		return nil, 0, err
	}
	defer conn.Close()

	return c.ExchangeWithConnContext(ctx, m, conn)
}


================================================
FILE: client_test.go
================================================
package dns

import (
	"context"
	"crypto/tls"
	"errors"
	"fmt"
	"net"
	"strconv"
	"strings"
	"syscall"
	"testing"
	"time"
)

func TestIsPacketConn(t *testing.T) {
	t.Run("UDP", func(t *testing.T) {
		s, addrstr, _, err := RunLocalUDPServer(":0")
		if err != nil {
			t.Fatalf("unable to run test server: %v", err)
		}
		defer s.Shutdown()
		c, err := net.Dial("udp", addrstr)
		if err != nil {
			t.Fatalf("failed to dial: %v", err)
		}
		defer c.Close()
		if !isPacketConn(c) {
			t.Error("UDP connection should be a packet conn")
		}
		if !isPacketConn(struct{ *net.UDPConn }{c.(*net.UDPConn)}) {
			t.Error("UDP connection (wrapped type) should be a packet conn")
		}
	})

	t.Run("TCP", func(t *testing.T) {
		s, addrstr, _, err := RunLocalTCPServer(":0")
		if err != nil {
			t.Fatalf("unable to run test server: %v", err)
		}
		defer s.Shutdown()
		c, err := net.Dial("tcp", addrstr)
		if err != nil {
			t.Fatalf("failed to dial: %v", err)
		}
		defer c.Close()
		if isPacketConn(c) {
			t.Error("TCP connection should not be a packet conn")
		}
		if isPacketConn(struct{ *net.TCPConn }{c.(*net.TCPConn)}) {
			t.Error("TCP connection (wrapped type) should not be a packet conn")
		}
	})

	t.Run("Unix datagram", func(t *testing.T) {
		s, addrstr, _, err := RunLocalUnixGramServer(tempFile(t, "unixgram.sock"))
		if err != nil {
			t.Fatalf("unable to run test server: %v", err)
		}
		defer s.Shutdown()
		c, err := net.Dial("unixgram", addrstr)
		if err != nil {
			t.Fatalf("failed to dial: %v", err)
		}
		defer c.Close()
		if !isPacketConn(c) {
			t.Error("Unix datagram connection should be a packet conn")
		}
		if !isPacketConn(struct{ *net.UnixConn }{c.(*net.UnixConn)}) {
			t.Error("Unix datagram connection (wrapped type) should be a packet conn")
		}
	})

	t.Run("Unix Seqpacket", func(t *testing.T) {
		shutChan, addrstr, err := RunLocalUnixSeqPacketServer(tempFile(t, "unixpacket.sock"))
		if err != nil {
			if errors.Is(err, syscall.EPROTONOSUPPORT) {
				t.Skip("unix seqpacket not supported on this OS")
			}
			t.Fatalf("unable to run test server: %v", err)
		}

		defer func() {
			shutChan <- &struct{}{}
		}()
		c, err := net.Dial("unixpacket", addrstr)
		if err != nil {
			t.Fatalf("failed to dial: %v", err)
		}
		defer c.Close()
		if !isPacketConn(c) {
			t.Error("Unix datagram connection should be a packet conn")
		}
		if !isPacketConn(struct{ *net.UnixConn }{c.(*net.UnixConn)}) {
			t.Error("Unix datagram connection (wrapped type) should be a packet conn")
		}
	})

	t.Run("Unix stream", func(t *testing.T) {
		s, addrstr, _, err := RunLocalUnixServer(tempFile(t, "unixstream.sock"))
		if err != nil {
			t.Fatalf("unable to run test server: %v", err)
		}
		defer s.Shutdown()
		c, err := net.Dial("unix", addrstr)
		if err != nil {
			t.Fatalf("failed to dial: %v", err)
		}
		defer c.Close()
		if isPacketConn(c) {
			t.Error("Unix stream connection should not be a packet conn")
		}
		if isPacketConn(struct{ *net.UnixConn }{c.(*net.UnixConn)}) {
			t.Error("Unix stream connection (wrapped type) should not be a packet conn")
		}
	})
}

func TestDialUDP(t *testing.T) {
	HandleFunc("miek.nl.", HelloServer)
	defer HandleRemove("miek.nl.")

	s, addrstr, _, err := RunLocalUDPServer(":0")
	if err != nil {
		t.Fatalf("unable to run test server: %v", err)
	}
	defer s.Shutdown()

	m := new(Msg)
	m.SetQuestion("miek.nl.", TypeSOA)

	c := new(Client)
	conn, err := c.Dial(addrstr)
	if err != nil {
		t.Fatalf("failed to dial: %v", err)
	}
	if conn == nil {
		t.Fatalf("conn is nil")
	}
}

func TestClientSync(t *testing.T) {
	HandleFunc("miek.nl.", HelloServer)
	defer HandleRemove("miek.nl.")

	s, addrstr, _, err := RunLocalUDPServer(":0")
	if err != nil {
		t.Fatalf("unable to run test server: %v", err)
	}
	defer s.Shutdown()

	m := new(Msg)
	m.SetQuestion("miek.nl.", TypeSOA)

	c := new(Client)
	r, _, err := c.Exchange(m, addrstr)
	if err != nil {
		t.Fatalf("failed to exchange: %v", err)
	}
	if r == nil {
		t.Fatal("response is nil")
	}
	if r.Rcode != RcodeSuccess {
		t.Errorf("failed to get an valid answer\n%v", r)
	}
	// And now with plain Exchange().
	r, err = Exchange(m, addrstr)
	if err != nil {
		t.Errorf("failed to exchange: %v", err)
	}
	if r == nil || r.Rcode != RcodeSuccess {
		t.Errorf("failed to get an valid answer\n%v", r)
	}
}

func TestClientLocalAddress(t *testing.T) {
	HandleFunc("miek.nl.", HelloServerEchoAddrPort)
	defer HandleRemove("miek.nl.")

	s, addrstr, _, err := RunLocalUDPServer(":0")
	if err != nil {
		t.Fatalf("unable to run test server: %v", err)
	}
	defer s.Shutdown()

	m := new(Msg)
	m.SetQuestion("miek.nl.", TypeSOA)

	c := new(Client)
	laddr := net.UDPAddr{IP: net.ParseIP("0.0.0.0"), Port: 12345, Zone: ""}
	c.Dialer = &net.Dialer{LocalAddr: &laddr}
	r, _, err := c.Exchange(m, addrstr)
	if err != nil {
		t.Fatalf("failed to exchange: %v", err)
	}
	if r != nil && r.Rcode != RcodeSuccess {
		t.Errorf("failed to get an valid answer\n%v", r)
	}
	if len(r.Extra) != 1 {
		t.Fatalf("failed to get additional answers\n%v", r)
	}
	txt := r.Extra[0].(*TXT)
	if txt == nil {
		t.Errorf("invalid TXT response\n%v", txt)
	}
	if len(txt.Txt) != 1 || !strings.Contains(txt.Txt[0], ":12345") {
		t.Errorf("invalid TXT response\n%v", txt.Txt)
	}
}

func TestClientTLSSyncV4(t *testing.T) {
	HandleFunc("miek.nl.", HelloServer)
	defer HandleRemove("miek.nl.")

	cert, err := tls.X509KeyPair(CertPEMBlock, KeyPEMBlock)
	if err != nil {
		t.Fatalf("unable to build certificate: %v", err)
	}

	config := tls.Config{
		Certificates: []tls.Certificate{cert},
	}

	s, addrstr, _, err := RunLocalTLSServer(":0", &config)
	if err != nil {
		t.Fatalf("unable to run test server: %v", err)
	}
	defer s.Shutdown()

	m := new(Msg)
	m.SetQuestion("miek.nl.", TypeSOA)

	c := new(Client)

	// test tcp-tls
	c.Net = "tcp-tls"
	c.TLSConfig = &tls.Config{
		InsecureSkipVerify: true,
	}

	r, _, err := c.Exchange(m, addrstr)
	if err != nil {
		t.Fatalf("failed to exchange: %v", err)
	}
	if r == nil {
		t.Fatal("response is nil")
	}
	if r.Rcode != RcodeSuccess {
		t.Errorf("failed to get an valid answer\n%v", r)
	}

	// test tcp4-tls
	c.Net = "tcp4-tls"
	c.TLSConfig = &tls.Config{
		InsecureSkipVerify: true,
	}

	r, _, err = c.Exchange(m, addrstr)
	if err != nil {
		t.Fatalf("failed to exchange: %v", err)
	}
	if r == nil {
		t.Fatal("response is nil")
	}
	if r.Rcode != RcodeSuccess {
		t.Errorf("failed to get an valid answer\n%v", r)
	}
}

func isNetworkTimeout(err error) bool {
	// TODO: when Go 1.14 support is dropped, do this: https://golang.org/doc/go1.15#net
	var netError net.Error
	return errors.As(err, &netError) && netError.Timeout()
}

func TestClientSyncBadID(t *testing.T) {
	HandleFunc("miek.nl.", HelloServerBadID)
	defer HandleRemove("miek.nl.")

	s, addrstr, _, err := RunLocalUDPServer(":0")
	if err != nil {
		t.Fatalf("unable to run test server: %v", err)
	}
	defer s.Shutdown()

	m := new(Msg)
	m.SetQuestion("miek.nl.", TypeSOA)

	// Test with client.Exchange, the plain Exchange function is just a wrapper, so
	// we don't need to test that separately.
	c := &Client{
		Timeout: 10 * time.Millisecond,
	}
	if _, _, err := c.Exchange(m, addrstr); err == nil || !isNetworkTimeout(err) {
		t.Errorf("query did not time out")
	}
}

func TestClientSyncBadThenGoodID(t *testing.T) {
	HandleFunc("miek.nl.", HelloServerBadThenGoodID)
	defer HandleRemove("miek.nl.")

	s, addrstr, _, err := RunLocalUDPServer(":0")
	if err != nil {
		t.Fatalf("unable to run test server: %v", err)
	}
	defer s.Shutdown()

	m := new(Msg)
	m.SetQuestion("miek.nl.", TypeSOA)

	c := new(Client)
	r, _, err := c.Exchange(m, addrstr)
	if err != nil {
		t.Errorf("failed to exchange: %v", err)
	}
	if r.Id != m.Id {
		t.Errorf("failed to get response with expected Id")
	}
}

func TestClientSyncTCPBadID(t *testing.T) {
	HandleFunc("miek.nl.", HelloServerBadID)
	defer HandleRemove("miek.nl.")

	s, addrstr, _, err := RunLocalTCPServer(":0")
	if err != nil {
		t.Fatalf("unable to run test server: %v", err)
	}
	defer s.Shutdown()

	m := new(Msg)
	m.SetQuestion("miek.nl.", TypeSOA)

	c := &Client{
		Net: "tcp",
	}
	if _, _, err := c.Exchange(m, addrstr); err != ErrId {
		t.Errorf("did not find a bad Id")
	}
}

func TestClientEDNS0(t *testing.T) {
	HandleFunc("miek.nl.", HelloServer)
	defer HandleRemove("miek.nl.")

	s, addrstr, _, err := RunLocalUDPServer(":0")
	if err != nil {
		t.Fatalf("unable to run test server: %v", err)
	}
	defer s.Shutdown()

	m := new(Msg)
	m.SetQuestion("miek.nl.", TypeDNSKEY)

	m.SetEdns0(2048, true)

	c := new(Client)
	r, _, err := c.Exchange(m, addrstr)
	if err != nil {
		t.Fatalf("failed to exchange: %v", err)
	}

	if r != nil && r.Rcode != RcodeSuccess {
		t.Errorf("failed to get a valid answer\n%v", r)
	}
}

// Validates the transmission and parsing of local EDNS0 options.
func TestClientEDNS0Local(t *testing.T) {
	optStr1 := "1979:0x0707"
	optStr2 := strconv.Itoa(EDNS0LOCALSTART) + ":0x0601"

	handler := func(w ResponseWriter, req *Msg) {
		m := new(Msg)
		m.SetReply(req)

		m.Extra = make([]RR, 1, 2)
		m.Extra[0] = &TXT{Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello local edns"}}

		// If the local options are what we expect, then reflect them back.
		ec1 := req.Extra[0].(*OPT).Option[0].(*EDNS0_LOCAL).String()
		ec2 := req.Extra[0].(*OPT).Option[1].(*EDNS0_LOCAL).String()
		if ec1 == optStr1 && ec2 == optStr2 {
			m.Extra = append(m.Extra, req.Extra[0])
		}

		w.WriteMsg(m)
	}

	HandleFunc("miek.nl.", handler)
	defer HandleRemove("miek.nl.")

	s, addrstr, _, err := RunLocalUDPServer(":0")
	if err != nil {
		t.Fatalf("unable to run test server: %s", err)
	}
	defer s.Shutdown()

	m := new(Msg)
	m.SetQuestion("miek.nl.", TypeTXT)

	// Add two local edns options to the query.
	ec1 := &EDNS0_LOCAL{Code: 1979, Data: []byte{7, 7}}
	ec2 := &EDNS0_LOCAL{Code: EDNS0LOCALSTART, Data: []byte{6, 1}}
	o := &OPT{Hdr: RR_Header{Name: ".", Rrtype: TypeOPT}, Option: []EDNS0{ec1, ec2}}
	m.Extra = append(m.Extra, o)

	c := new(Client)
	r, _, err := c.Exchange(m, addrstr)
	if err != nil {
		t.Fatalf("failed to exchange: %s", err)
	}

	if r == nil {
		t.Fatal("response is nil")
	}
	if r.Rcode != RcodeSuccess {
		t.Fatal("failed to get a valid answer")
	}

	txt := r.Extra[0].(*TXT).Txt[0]
	if txt != "Hello local edns" {
		t.Error("Unexpected result for miek.nl", txt, "!= Hello local edns")
	}

	// Validate the local options in the reply.
	got := r.Extra[1].(*OPT).Option[0].(*EDNS0_LOCAL).String()
	if got != optStr1 {
		t.Errorf("failed to get local edns0 answer; got %s, expected %s", got, optStr1)
	}

	got = r.Extra[1].(*OPT).Option[1].(*EDNS0_LOCAL).String()
	if got != optStr2 {
		t.Errorf("failed to get local edns0 answer; got %s, expected %s", got, optStr2)
	}
}

func TestClientConn(t *testing.T) {
	HandleFunc("miek.nl.", HelloServer)
	defer HandleRemove("miek.nl.")

	// This uses TCP just to make it slightly different than TestClientSync
	s, addrstr, _, err := RunLocalTCPServer(":0")
	if err != nil {
		t.Fatalf("unable to run test server: %v", err)
	}
	defer s.Shutdown()

	m := new(Msg)
	m.SetQuestion("miek.nl.", TypeSOA)

	cn, err := Dial("tcp", addrstr)
	if err != nil {
		t.Errorf("failed to dial %s: %v", addrstr, err)
	}

	err = cn.WriteMsg(m)
	if err != nil {
		t.Errorf("failed to exchange: %v", err)
	}
	r, err := cn.ReadMsg()
	if err != nil {
		t.Errorf("failed to get a valid answer: %v", err)
	}
	if r == nil || r.Rcode != RcodeSuccess {
		t.Errorf("failed to get an valid answer\n%v", r)
	}

	err = cn.WriteMsg(m)
	if err != nil {
		t.Errorf("failed to exchange: %v", err)
	}
	h := new(Header)
	buf, err := cn.ReadMsgHeader(h)
	if buf == nil {
		t.Errorf("failed to get an valid answer\n%v", r)
	}
	if err != nil {
		t.Errorf("failed to get a valid answer: %v", err)
	}
	if int(h.Bits&0xF) != RcodeSuccess {
		t.Errorf("failed to get an valid answer in ReadMsgHeader\n%v", r)
	}
	if h.Ancount != 0 || h.Qdcount != 1 || h.Nscount != 0 || h.Arcount != 1 {
		t.Errorf("expected to have question and additional in response; got something else: %+v", h)
	}
	if err = r.Unpack(buf); err != nil {
		t.Errorf("unable to unpack message fully: %v", err)
	}
}

func TestClientConnWriteSinglePacket(t *testing.T) {
	c := &countingConn{}
	conn := Conn{
		Conn: c,
	}
	m := new(Msg)
	m.SetQuestion("miek.nl.", TypeTXT)
	err := conn.WriteMsg(m)
	if err != nil {
		t.Fatalf("failed to write: %v", err)
	}

	if c.writes != 1 {
		t.Fatalf("incorrect number of Write calls")
	}
}

func TestTruncatedMsg(t *testing.T) {
	m := new(Msg)
	m.SetQuestion("miek.nl.", TypeSRV)
	cnt := 10
	for i := 0; i < cnt; i++ {
		r := &SRV{
			Hdr:    RR_Header{Name: m.Question[0].Name, Rrtype: TypeSRV, Class: ClassINET, Ttl: 0},
			Port:   uint16(i + 8000),
			Target: "target.miek.nl.",
		}
		m.Answer = append(m.Answer, r)

		re := &A{
			Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeA, Class: ClassINET, Ttl: 0},
			A:   net.ParseIP(fmt.Sprintf("127.0.0.%d", i)).To4(),
		}
		m.Extra = append(m.Extra, re)
	}
	buf, err := m.Pack()
	if err != nil {
		t.Errorf("failed to pack: %v", err)
	}

	r := new(Msg)
	if err = r.Unpack(buf); err != nil {
		t.Errorf("unable to unpack message: %v", err)
	}
	if len(r.Answer) != cnt {
		t.Errorf("answer count after regular unpack doesn't match: %d", len(r.Answer))
	}
	if len(r.Extra) != cnt {
		t.Errorf("extra count after regular unpack doesn't match: %d", len(r.Extra))
	}

	m.Truncated = true
	buf, err = m.Pack()
	if err != nil {
		t.Errorf("failed to pack truncated message: %v", err)
	}

	r = new(Msg)
	if err = r.Unpack(buf); err != nil {
		t.Errorf("failed to unpack truncated message: %v", err)
	}
	if !r.Truncated {
		t.Errorf("truncated message wasn't unpacked as truncated")
	}
	if len(r.Answer) != cnt {
		t.Errorf("answer count after truncated unpack doesn't match: %d", len(r.Answer))
	}
	if len(r.Extra) != cnt {
		t.Errorf("extra count after truncated unpack doesn't match: %d", len(r.Extra))
	}

	// Now we want to remove almost all of the extra records
	// We're going to loop over the extra to get the count of the size of all
	// of them
	off := 0
	buf1 := make([]byte, m.Len())
	for i := 0; i < len(m.Extra); i++ {
		off, err = PackRR(m.Extra[i], buf1, off, nil, m.Compress)
		if err != nil {
			t.Errorf("failed to pack extra: %v", err)
		}
	}

	// Remove all of the extra bytes but 10 bytes from the end of buf
	off -= 10
	buf1 = buf[:len(buf)-off]

	r = new(Msg)
	if err = r.Unpack(buf1); err == nil {
		t.Error("cutoff message should have failed to unpack")
	}
	// r's header might be still usable.
	if !r.Truncated {
		t.Error("truncated cutoff message wasn't unpacked as truncated")
	}
	if len(r.Answer) != cnt {
		t.Errorf("answer count after cutoff unpack doesn't match: %d", len(r.Answer))
	}
	if len(r.Extra) != 0 {
		t.Errorf("extra count after cutoff unpack is not zero: %d", len(r.Extra))
	}

	// Now we want to remove almost all of the answer records too
	buf1 = make([]byte, m.Len())
	as := 0
	for i := 0; i < len(m.Extra); i++ {
		off1 := off
		off, err = PackRR(m.Extra[i], buf1, off, nil, m.Compress)
		as = off - off1
		if err != nil {
			t.Errorf("failed to pack extra: %v", err)
		}
	}

	// Keep exactly one answer left
	// This should still cause Answer to be nil
	off -= as
	buf1 = buf[:len(buf)-off]

	r = new(Msg)
	if err = r.Unpack(buf1); err == nil {
		t.Error("cutoff message should have failed to unpack")
	}
	if !r.Truncated {
		t.Error("truncated cutoff message wasn't unpacked as truncated")
	}
	if len(r.Answer) != 0 {
		t.Errorf("answer count after second cutoff unpack is not zero: %d", len(r.Answer))
	}

	// Now leave only 1 byte of the question
	// Since the header is always 12 bytes, we just need to keep 13
	buf1 = buf[:13]

	r = new(Msg)
	err = r.Unpack(buf1)
	if err == nil {
		t.Errorf("error should be nil after question cutoff unpack: %v", err)
	}

	// Finally, if we only have the header, we don't return an error.
	buf1 = buf[:12]

	r = new(Msg)
	if err = r.Unpack(buf1); err != nil {
		t.Errorf("from header-only unpack should not return an error: %v", err)
	}
}

func TestTimeout(t *testing.T) {
	// Set up a dummy UDP server that won't respond
	addr, err := net.ResolveUDPAddr("udp", ":0")
	if err != nil {
		t.Fatalf("unable to resolve local udp address: %v", err)
	}
	conn, err := net.ListenUDP("udp", addr)
	if err != nil {
		t.Fatalf("unable to run test server: %v", err)
	}
	defer conn.Close()
	addrstr := conn.LocalAddr().String()

	// Message to send
	m := new(Msg)
	m.SetQuestion("miek.nl.", TypeTXT)

	runTest := func(name string, exchange func(m *Msg, addr string, timeout time.Duration) (*Msg, time.Duration, error)) {
		t.Run(name, func(t *testing.T) {
			start := time.Now()

			timeout := time.Millisecond
			allowable := timeout + 10*time.Millisecond

			_, _, err := exchange(m, addrstr, timeout)
			if err == nil {
				t.Errorf("no timeout using Client.%s", name)
			}

			length := time.Since(start)
			if length > allowable {
				t.Errorf("exchange took longer %v than specified Timeout %v", length, allowable)
			}
		})
	}
	runTest("Exchange", func(m *Msg, addr string, timeout time.Duration) (*Msg, time.Duration, error) {
		c := &Client{Timeout: timeout}
		return c.Exchange(m, addr)
	})
	runTest("ExchangeContext", func(m *Msg, addr string, timeout time.Duration) (*Msg, time.Duration, error) {
		ctx, cancel := context.WithTimeout(context.Background(), timeout)
		defer cancel()

		return new(Client).ExchangeContext(ctx, m, addrstr)
	})
}

func TestExchangeWithConn(t *testing.T) {
	HandleFunc("miek.nl.", HelloServer)
	defer HandleRemove("miek.nl.")

	s, addrstr, _, err := RunLocalUDPServer(":0")
	if err != nil {
		t.Fatalf("unable to run test server: %v", err)
	}
	defer s.Shutdown()

	m := new(Msg)
	m.SetQuestion("miek.nl.", TypeSOA)

	c := new(Client)
	conn, err := c.Dial(addrstr)
	if err != nil {
		t.Fatalf("failed to dial: %v", err)
	}

	r, _, err := c.ExchangeWithConn(m, conn)
	if err != nil {
		t.Fatalf("failed to exchange: %v", err)
	}
	if r == nil {
		t.Fatal("response is nil")
	}
	if r.Rcode != RcodeSuccess {
		t.Errorf("failed to get an valid answer\n%v", r)
	}
}


================================================
FILE: clientconfig.go
================================================
package dns

import (
	"bufio"
	"io"
	"os"
	"strconv"
	"strings"
)

// ClientConfig wraps the contents of the /etc/resolv.conf file.
type ClientConfig struct {
	Servers  []string // servers to use
	Search   []string // suffixes to append to local name
	Port     string   // what port to use
	Ndots    int      // number of dots in name to trigger absolute lookup
	Timeout  int      // seconds before giving up on packet
	Attempts int      // lost packets before giving up on server, not used in the package dns
}

// ClientConfigFromFile parses a resolv.conf(5) like file and returns
// a *ClientConfig.
func ClientConfigFromFile(resolvconf string) (*ClientConfig, error) {
	file, err := os.Open(resolvconf)
	if err != nil {
		return nil, err
	}
	defer file.Close()
	return ClientConfigFromReader(file)
}

// ClientConfigFromReader works like ClientConfigFromFile but takes an io.Reader as argument
func ClientConfigFromReader(resolvconf io.Reader) (*ClientConfig, error) {
	c := new(ClientConfig)
	scanner := bufio.NewScanner(resolvconf)
	c.Servers = make([]string, 0)
	c.Search = make([]string, 0)
	c.Port = "53"
	c.Ndots = 1
	c.Timeout = 5
	c.Attempts = 2

	for scanner.Scan() {
		if err := scanner.Err(); err != nil {
			return nil, err
		}
		line := scanner.Text()
		f := strings.Fields(line)
		if len(f) < 1 {
			continue
		}
		switch f[0] {
		case "nameserver": // add one name server
			if len(f) > 1 {
				// One more check: make sure server name is
				// just an IP address.  Otherwise we need DNS
				// to look it up.
				name := f[1]
				c.Servers = append(c.Servers, name)
			}

		case "domain": // set search path to just this domain
			if len(f) > 1 {
				c.Search = make([]string, 1)
				c.Search[0] = f[1]
			} else {
				c.Search = make([]string, 0)
			}

		case "search": // set search path to given servers
			c.Search = cloneSlice(f[1:])

		case "options": // magic options
			for _, s := range f[1:] {
				switch {
				case len(s) >= 6 && s[:6] == "ndots:":
					n, _ := strconv.Atoi(s[6:])
					if n < 0 {
						n = 0
					} else if n > 15 {
						n = 15
					}
					c.Ndots = n
				case len(s) >= 8 && s[:8] == "timeout:":
					n, _ := strconv.Atoi(s[8:])
					if n < 1 {
						n = 1
					}
					c.Timeout = n
				case len(s) >= 9 && s[:9] == "attempts:":
					n, _ := strconv.Atoi(s[9:])
					if n < 1 {
						n = 1
					}
					c.Attempts = n
				case s == "rotate":
					/* not imp */
				}
			}
		}
	}
	return c, nil
}

// NameList returns all of the names that should be queried based on the
// config. It is based off of go's net/dns name building, but it does not
// check the length of the resulting names.
func (c *ClientConfig) NameList(name string) []string {
	// if this domain is already fully qualified, no append needed.
	if IsFqdn(name) {
		return []string{name}
	}

	// Check to see if the name has more labels than Ndots. Do this before making
	// the domain fully qualified.
	hasNdots := CountLabel(name) > c.Ndots
	// Make the domain fully qualified.
	name = Fqdn(name)

	// Make a list of names based off search.
	names := []string{}

	// If name has enough dots, try that first.
	if hasNdots {
		names = append(names, name)
	}
	for _, s := range c.Search {
		names = append(names, Fqdn(name+s))
	}
	// If we didn't have enough dots, try after suffixes.
	if !hasNdots {
		names = append(names, name)
	}
	return names
}


================================================
FILE: clientconfig_test.go
================================================
package dns

import (
	"os"
	"path/filepath"
	"strings"
	"testing"
)

const normal string = `
# Comment
domain somedomain.com
nameserver 10.28.10.2
nameserver 11.28.10.1
`

const missingNewline string = `
domain somedomain.com
nameserver 10.28.10.2
nameserver 11.28.10.1` // <- NOTE: NO newline.

func testConfig(t *testing.T, data string) {
	cc, err := ClientConfigFromReader(strings.NewReader(data))
	if err != nil {
		t.Errorf("error parsing resolv.conf: %v", err)
	}
	if l := len(cc.Servers); l != 2 {
		t.Errorf("incorrect number of nameservers detected: %d", l)
	}
	if l := len(cc.Search); l != 1 {
		t.Errorf("domain directive not parsed correctly: %v", cc.Search)
	} else {
		if cc.Search[0] != "somedomain.com" {
			t.Errorf("domain is unexpected: %v", cc.Search[0])
		}
	}
}

func TestNameserver(t *testing.T)          { testConfig(t, normal) }
func TestMissingFinalNewLine(t *testing.T) { testConfig(t, missingNewline) }

func TestNdots(t *testing.T) {
	ndotsVariants := map[string]int{
		"options ndots:0":  0,
		"options ndots:1":  1,
		"options ndots:15": 15,
		"options ndots:16": 15,
		"options ndots:-1": 0,
		"":                 1,
	}

	for data := range ndotsVariants {
		cc, err := ClientConfigFromReader(strings.NewReader(data))
		if err != nil {
			t.Errorf("error parsing resolv.conf: %v", err)
		}
		if cc.Ndots != ndotsVariants[data] {
			t.Errorf("Ndots not properly parsed: (Expected: %d / Was: %d)", ndotsVariants[data], cc.Ndots)
		}
	}
}

func TestClientConfigFromReaderAttempts(t *testing.T) {
	testCases := []struct {
		data     string
		expected int
	}{
		{data: "options attempts:0", expected: 1},
		{data: "options attempts:1", expected: 1},
		{data: "options attempts:15", expected: 15},
		{data: "options attempts:16", expected: 16},
		{data: "options attempts:-1", expected: 1},
		{data: "options attempt:", expected: 2},
	}

	for _, test := range testCases {
		test := test
		t.Run(strings.Replace(test.data, ":", " ", -1), func(t *testing.T) {
			t.Parallel()

			cc, err := ClientConfigFromReader(strings.NewReader(test.data))
			if err != nil {
				t.Errorf("error parsing resolv.conf: %v", err)
			}
			if cc.Attempts != test.expected {
				t.Errorf("A attempts not properly parsed: (Expected: %d / Was: %d)", test.expected, cc.Attempts)
			}
		})
	}
}

func TestReadFromFile(t *testing.T) {
	tempDir := t.TempDir()

	path := filepath.Join(tempDir, "resolv.conf")
	if err := os.WriteFile(path, []byte(normal), 0o644); err != nil {
		t.Fatalf("writeFile: %v", err)
	}
	cc, err := ClientConfigFromFile(path)
	if err != nil {
		t.Errorf("error parsing resolv.conf: %v", err)
	}
	if l := len(cc.Servers); l != 2 {
		t.Errorf("incorrect number of nameservers detected: %d", l)
	}
	if l := len(cc.Search); l != 1 {
		t.Errorf("domain directive not parsed correctly: %v", cc.Search)
	} else {
		if cc.Search[0] != "somedomain.com" {
			t.Errorf("domain is unexpected: %v", cc.Search[0])
		}
	}
}

func TestNameListNdots1(t *testing.T) {
	cfg := ClientConfig{
		Ndots: 1,
	}
	// fqdn should be only result returned
	names := cfg.NameList("miek.nl.")
	if len(names) != 1 {
		t.Errorf("NameList returned != 1 names: %v", names)
	} else if names[0] != "miek.nl." {
		t.Errorf("NameList didn't return sent fqdn domain: %v", names[0])
	}

	cfg.Search = []string{
		"test",
	}
	// Sent domain has NDots and search
	names = cfg.NameList("miek.nl")
	if len(names) != 2 {
		t.Errorf("NameList returned != 2 names: %v", names)
	} else if names[0] != "miek.nl." {
		t.Errorf("NameList didn't return sent domain first: %v", names[0])
	} else if names[1] != "miek.nl.test." {
		t.Errorf("NameList didn't return search last: %v", names[1])
	}
}

func TestNameListNdots2(t *testing.T) {
	cfg := ClientConfig{
		Ndots: 2,
	}

	// Sent domain has less than NDots and search
	cfg.Search = []string{
		"test",
	}
	names := cfg.NameList("miek.nl")

	if len(names) != 2 {
		t.Errorf("NameList returned != 2 names: %v", names)
	} else if names[0] != "miek.nl.test." {
		t.Errorf("NameList didn't return search first: %v", names[0])
	} else if names[1] != "miek.nl." {
		t.Errorf("NameList didn't return sent domain last: %v", names[1])
	}
}

func TestNameListNdots0(t *testing.T) {
	cfg := ClientConfig{
		Ndots: 0,
	}
	cfg.Search = []string{
		"test",
	}
	// Sent domain has less than NDots and search
	names := cfg.NameList("miek")
	if len(names) != 2 {
		t.Errorf("NameList returned != 2 names: %v", names)
	} else if names[0] != "miek." {
		t.Errorf("NameList didn't return search first: %v", names[0])
	} else if names[1] != "miek.test." {
		t.Errorf("NameList didn't return sent domain last: %v", names[1])
	}
}


================================================
FILE: dane.go
================================================
package dns

import (
	"crypto/sha256"
	"crypto/sha512"
	"crypto/x509"
	"encoding/hex"
	"errors"
)

// CertificateToDANE converts a certificate to a hex string as used in the TLSA or SMIMEA records.
func CertificateToDANE(selector, matchingType uint8, cert *x509.Certificate) (string, error) {
	switch matchingType {
	case 0:
		switch selector {
		case 0:
			return hex.EncodeToString(cert.Raw), nil
		case 1:
			return hex.EncodeToString(cert.RawSubjectPublicKeyInfo), nil
		}
	case 1:
		h := sha256.New()
		switch selector {
		case 0:
			h.Write(cert.Raw)
			return hex.EncodeToString(h.Sum(nil)), nil
		case 1:
			h.Write(cert.RawSubjectPublicKeyInfo)
			return hex.EncodeToString(h.Sum(nil)), nil
		}
	case 2:
		h := sha512.New()
		switch selector {
		case 0:
			h.Write(cert.Raw)
			return hex.EncodeToString(h.Sum(nil)), nil
		case 1:
			h.Write(cert.RawSubjectPublicKeyInfo)
			return hex.EncodeToString(h.Sum(nil)), nil
		}
	}
	return "", errors.New("dns: bad MatchingType or Selector")
}


================================================
FILE: defaults.go
================================================
package dns

import (
	"errors"
	"net"
	"strconv"
	"strings"
)

const hexDigit = "0123456789abcdef"

// Everything is assumed in ClassINET.

// SetReply creates a reply message from a request message.
func (dns *Msg) SetReply(request *Msg) *Msg {
	dns.Id = request.Id
	dns.Response = true
	dns.Opcode = request.Opcode
	if dns.Opcode == OpcodeQuery {
		dns.RecursionDesired = request.RecursionDesired // Copy rd bit
		dns.CheckingDisabled = request.CheckingDisabled // Copy cd bit
	}
	dns.Rcode = RcodeSuccess
	if len(request.Question) > 0 {
		dns.Question = []Question{request.Question[0]}
	}
	return dns
}

// SetQuestion creates a question message, it sets the Question
// section, generates an Id and sets the RecursionDesired (RD)
// bit to true.
func (dns *Msg) SetQuestion(z string, t uint16) *Msg {
	dns.Id = Id()
	dns.RecursionDesired = true
	dns.Question = make([]Question, 1)
	dns.Question[0] = Question{z, t, ClassINET}
	return dns
}

// SetNotify creates a notify message, it sets the Question
// section, generates an Id and sets the Authoritative (AA)
// bit to true.
func (dns *Msg) SetNotify(z string) *Msg {
	dns.Opcode = OpcodeNotify
	dns.Authoritative = true
	dns.Id = Id()
	dns.Question = make([]Question, 1)
	dns.Question[0] = Question{z, TypeSOA, ClassINET}
	return dns
}

// SetRcode creates an error message suitable for the request.
func (dns *Msg) SetRcode(request *Msg, rcode int) *Msg {
	dns.SetReply(request)
	dns.Rcode = rcode
	return dns
}

// SetRcodeFormatError creates a message with FormError set.
func (dns *Msg) SetRcodeFormatError(request *Msg) *Msg {
	dns.Rcode = RcodeFormatError
	dns.Opcode = OpcodeQuery
	dns.Response = true
	dns.Authoritative = false
	dns.Id = request.Id
	return dns
}

// SetUpdate makes the message a dynamic update message. It
// sets the ZONE section to: z, TypeSOA, ClassINET.
func (dns *Msg) SetUpdate(z string) *Msg {
	dns.Id = Id()
	dns.Response = false
	dns.Opcode = OpcodeUpdate
	dns.Compress = false // BIND9 cannot handle compression
	dns.Question = make([]Question, 1)
	dns.Question[0] = Question{z, TypeSOA, ClassINET}
	return dns
}

// SetIxfr creates message for requesting an IXFR.
func (dns *Msg) SetIxfr(z string, serial uint32, ns, mbox string) *Msg {
	dns.Id = Id()
	dns.Question = make([]Question, 1)
	dns.Ns = make([]RR, 1)
	s := new(SOA)
	s.Hdr = RR_Header{z, TypeSOA, ClassINET, defaultTtl, 0}
	s.Serial = serial
	s.Ns = ns
	s.Mbox = mbox
	dns.Question[0] = Question{z, TypeIXFR, ClassINET}
	dns.Ns[0] = s
	return dns
}

// SetAxfr creates message for requesting an AXFR.
func (dns *Msg) SetAxfr(z string) *Msg {
	dns.Id = Id()
	dns.Question = make([]Question, 1)
	dns.Question[0] = Question{z, TypeAXFR, ClassINET}
	return dns
}

// SetTsig appends a TSIG RR to the message.
// This is only a skeleton TSIG RR that is added as the last RR in the
// additional section. The TSIG is calculated when the message is being send.
func (dns *Msg) SetTsig(z, algo string, fudge uint16, timesigned int64) *Msg {
	t := new(TSIG)
	t.Hdr = RR_Header{z, TypeTSIG, ClassANY, 0, 0}
	t.Algorithm = algo
	t.Fudge = fudge
	t.TimeSigned = uint64(timesigned)
	t.OrigId = dns.Id
	dns.Extra = append(dns.Extra, t)
	return dns
}

// SetEdns0 appends a EDNS0 OPT RR to the message.
// TSIG should always the last RR in a message.
func (dns *Msg) SetEdns0(udpsize uint16, do bool) *Msg {
	e := new(OPT)
	e.Hdr.Name = "."
	e.Hdr.Rrtype = TypeOPT
	e.SetUDPSize(udpsize)
	if do {
		e.SetDo()
	}
	dns.Extra = append(dns.Extra, e)
	return dns
}

// IsTsig checks if the message has a TSIG record as the last record
// in the additional section. It returns the TSIG record found or nil.
func (dns *Msg) IsTsig() *TSIG {
	if len(dns.Extra) > 0 {
		if dns.Extra[len(dns.Extra)-1].Header().Rrtype == TypeTSIG {
			return dns.Extra[len(dns.Extra)-1].(*TSIG)
		}
	}
	return nil
}

// IsEdns0 checks if the message has a EDNS0 (OPT) record, any EDNS0
// record in the additional section will do. It returns the OPT record
// found or nil.
func (dns *Msg) IsEdns0() *OPT {
	// RFC 6891, Section 6.1.1 allows the OPT record to appear
	// anywhere in the additional record section, but it's usually at
	// the end so start there.
	for i := len(dns.Extra) - 1; i >= 0; i-- {
		if dns.Extra[i].Header().Rrtype == TypeOPT {
			return dns.Extra[i].(*OPT)
		}
	}
	return nil
}

// popEdns0 is like IsEdns0, but it removes the record from the message.
func (dns *Msg) popEdns0() *OPT {
	// RFC 6891, Section 6.1.1 allows the OPT record to appear
	// anywhere in the additional record section, but it's usually at
	// the end so start there.
	for i := len(dns.Extra) - 1; i >= 0; i-- {
		if dns.Extra[i].Header().Rrtype == TypeOPT {
			opt := dns.Extra[i].(*OPT)
			dns.Extra = append(dns.Extra[:i], dns.Extra[i+1:]...)
			return opt
		}
	}
	return nil
}

// IsDomainName checks if s is a valid domain name, it returns the number of
// labels and true, when a domain name is valid.  Note that non fully qualified
// domain name is considered valid, in this case the last label is counted in
// the number of labels.  When false is returned the number of labels is not
// defined.  Also note that this function is extremely liberal; almost any
// string is a valid domain name as the DNS is 8 bit protocol. It checks if each
// label fits in 63 characters and that the entire name will fit into the 255
// octet wire format limit.
func IsDomainName(s string) (labels int, ok bool) {
	// XXX: The logic in this function was copied from packDomainName and
	// should be kept in sync with that function.

	const lenmsg = 256

	if len(s) == 0 { // Ok, for instance when dealing with update RR without any rdata.
		return 0, false
	}

	s = Fqdn(s)

	// Each dot ends a segment of the name. Except for escaped dots (\.), which
	// are normal dots.

	var (
		off    int
		begin  int
		wasDot bool
		escape bool
	)
	for i := 0; i < len(s); i++ {
		switch s[i] {
		case '\\':
			escape = !escape
			if off+1 > lenmsg {
				return labels, false
			}

			// check for \DDD
			if isDDD(s[i+1:]) {
				i += 3
				begin += 3
			} else {
				i++
				begin++
			}

			wasDot = false
		case '.':
			escape = false
			if i == 0 && len(s) > 1 {
				// leading dots are not legal except for the root zone
				return labels, false
			}

			if wasDot {
				// two dots back to back is not legal
				return labels, false
			}
			wasDot = true

			labelLen := i - begin
			if labelLen >= 1<<6 { // top two bits of length must be clear
				return labels, false
			}

			// off can already (we're in a loop) be bigger than lenmsg
			// this happens when a name isn't fully qualified
			off += 1 + labelLen
			if off > lenmsg {
				return labels, false
			}

			labels++
			begin = i + 1
		default:
			escape = false
			wasDot = false
		}
	}
	if escape {
		return labels, false
	}
	return labels, true
}

// IsSubDomain checks if child is indeed a child of the parent. If child and parent
// are the same domain true is returned as well.
func IsSubDomain(parent, child string) bool {
	// Entire child is contained in parent
	return CompareDomainName(parent, child) == CountLabel(parent)
}

// IsMsg sanity checks buf and returns an error if it isn't a valid DNS packet.
// The checking is performed on the binary payload.
func IsMsg(buf []byte) error {
	// Header
	if len(buf) < headerSize {
		return errors.New("dns: bad message header")
	}
	// Header: Opcode
	// TODO(miek): more checks here, e.g. check all header bits.
	return nil
}

// IsFqdn checks if a domain name is fully qualified.
func IsFqdn(s string) bool {
	// Check for (and remove) a trailing dot, returning if there isn't one.
	if s == "" || s[len(s)-1] != '.' {
		return false
	}
	s = s[:len(s)-1]

	// If we don't have an escape sequence before the final dot, we know it's
	// fully qualified and can return here.
	if s == "" || s[len(s)-1] != '\\' {
		return true
	}

	// Otherwise we have to check if the dot is escaped or not by checking if
	// there are an odd or even number of escape sequences before the dot.
	i := strings.LastIndexFunc(s, func(r rune) bool {
		return r != '\\'
	})
	return (len(s)-i)%2 != 0
}

// IsRRset reports whether a set of RRs is a valid RRset as defined by RFC 2181.
// This means the RRs need to have the same type, name, and class.
func IsRRset(rrset []RR) bool {
	if len(rrset) == 0 {
		return false
	}

	baseH := rrset[0].Header()
	for _, rr := range rrset[1:] {
		curH := rr.Header()
		if curH.Rrtype != baseH.Rrtype || curH.Class != baseH.Class || curH.Name != baseH.Name {
			// Mismatch between the records, so this is not a valid rrset for
			// signing/verifying
			return false
		}
	}

	return true
}

// Fqdn return the fully qualified domain name from s.
// If s is already fully qualified, it behaves as the identity function.
func Fqdn(s string) string {
	if IsFqdn(s) {
		return s
	}
	return s + "."
}

// CanonicalName returns the domain name in canonical form. A name in canonical
// form is lowercase and fully qualified. Only US-ASCII letters are affected. See
// Section 6.2 in RFC 4034.
func CanonicalName(s string) string {
	return strings.Map(func(r rune) rune {
		if r >= 'A' && r <= 'Z' {
			r += 'a' - 'A'
		}
		return r
	}, Fqdn(s))
}

// Copied from the official Go code.

// ReverseAddr returns the in-addr.arpa. or ip6.arpa. hostname of the IP
// address suitable for reverse DNS (PTR) record lookups or an error if it fails
// to parse the IP address.
func ReverseAddr(addr string) (arpa string, err error) {
	ip := net.ParseIP(addr)
	if ip == nil {
		return "", &Error{err: "unrecognized address: " + addr}
	}
	if v4 := ip.To4(); v4 != nil {
		buf := make([]byte, 0, net.IPv4len*4+len("in-addr.arpa."))
		// Add it, in reverse, to the buffer
		for i := len(v4) - 1; i >= 0; i-- {
			buf = strconv.AppendInt(buf, int64(v4[i]), 10)
			buf = append(buf, '.')
		}
		// Append "in-addr.arpa." and return (buf already has the final .)
		buf = append(buf, "in-addr.arpa."...)
		return string(buf), nil
	}
	// Must be IPv6
	buf := make([]byte, 0, net.IPv6len*4+len("ip6.arpa."))
	// Add it, in reverse, to the buffer
	for i := len(ip) - 1; i >= 0; i-- {
		v := ip[i]
		buf = append(buf, hexDigit[v&0xF], '.', hexDigit[v>>4], '.')
	}
	// Append "ip6.arpa." and return (buf already has the final .)
	buf = append(buf, "ip6.arpa."...)
	return string(buf), nil
}

// String returns the string representation for the type t.
func (t Type) String() string {
	if t1, ok := TypeToString[uint16(t)]; ok {
		return t1
	}
	return "TYPE" + strconv.Itoa(int(t))
}

// String returns the string representation for the class c.
func (c Class) String() string {
	if s, ok := ClassToString[uint16(c)]; ok {
		// Only emit mnemonics when they are unambiguous, specially ANY is in both.
		if _, ok := StringToType[s]; !ok {
			return s
		}
	}
	return "CLASS" + strconv.Itoa(int(c))
}

// String returns the string representation for the name n.
func (n Name) String() string {
	return sprintName(string(n))
}


================================================
FILE: dns.go
================================================
package dns

import (
	"encoding/hex"
	"strconv"
)

const (
	year68     = 1 << 31 // For RFC1982 (Serial Arithmetic) calculations in 32 bits.
	defaultTtl = 3600    // Default internal TTL.

	// DefaultMsgSize is the standard default for messages larger than 512 bytes.
	DefaultMsgSize = 4096
	// MinMsgSize is the minimal size of a DNS packet.
	MinMsgSize = 512
	// MaxMsgSize is the largest possible DNS packet.
	MaxMsgSize = 65535
)

// Error represents a DNS error.
type Error struct{ err string }

func (e *Error) Error() string {
	if e == nil {
		return "dns: <nil>"
	}
	return "dns: " + e.err
}

// An RR represents a resource record.
type RR interface {
	// Header returns the header of an resource record. The header contains
	// everything up to the rdata.
	Header() *RR_Header
	// String returns the text representation of the resource record.
	String() string

	// copy returns a copy of the RR
	copy() RR

	// len returns the length (in octets) of the compressed or uncompressed RR in wire format.
	//
	// If compression is nil, the uncompressed size will be returned, otherwise the compressed
	// size will be returned and domain names will be added to the map for future compression.
	len(off int, compression map[string]struct{}) int

	// pack packs the records RDATA into wire format. The header will
	// already have been packed into msg.
	pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error)

	// unpack unpacks an RR from wire format.
	//
	// This will only be called on a new and empty RR type with only the header populated. It
	// will only be called if the record's RDATA is non-empty.
	unpack(msg []byte, off int) (off1 int, err error)

	// parse parses an RR from zone file format.
	//
	// This will only be called on a new and empty RR type with only the header populated.
	parse(c *zlexer, origin string) *ParseError

	// isDuplicate returns whether the two RRs are duplicates.
	isDuplicate(r2 RR) bool
}

// RR_Header is the header all DNS resource records share.
type RR_Header struct {
	Name     string `dns:"cdomain-name"`
	Rrtype   uint16
	Class    uint16
	Ttl      uint32
	Rdlength uint16 // Length of data after header.
}

// Header returns itself. This is here to make RR_Header implements the RR interface.
func (h *RR_Header) Header() *RR_Header { return h }

// Just to implement the RR interface.
func (h *RR_Header) copy() RR { return nil }

func (h *RR_Header) String() string {
	var s string

	if h.Rrtype == TypeOPT {
		s = ";"
		// and maybe other things
	}

	s += sprintName(h.Name) + "\t"
	s += strconv.FormatInt(int64(h.Ttl), 10) + "\t"
	s += Class(h.Class).String() + "\t"
	s += Type(h.Rrtype).String() + "\t"
	return s
}

func (h *RR_Header) len(off int, compression map[string]struct{}) int {
	l := domainNameLen(h.Name, off, compression, true)
	l += 10 // rrtype(2) + class(2) + ttl(4) + rdlength(2)
	return l
}

func (h *RR_Header) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
	// RR_Header has no RDATA to pack.
	return off, nil
}

func (h *RR_Header) unpack(msg []byte, off int) (int, error) {
	panic("dns: internal error: unpack should never be called on RR_Header")
}

func (h *RR_Header) parse(c *zlexer, origin string) *ParseError {
	panic("dns: internal error: parse should never be called on RR_Header")
}

// ToRFC3597 converts a known RR to the unknown RR representation from RFC 3597.
func (rr *RFC3597) ToRFC3597(r RR) error {
	buf := make([]byte, Len(r))
	headerEnd, off, err := packRR(r, buf, 0, compressionMap{}, false)
	if err != nil {
		return err
	}
	buf = buf[:off]

	*rr = RFC3597{Hdr: *r.Header()}
	rr.Hdr.Rdlength = uint16(off - headerEnd)

	if noRdata(rr.Hdr) {
		return nil
	}

	_, err = rr.unpack(buf, headerEnd)
	return err
}

// fromRFC3597 converts an unknown RR representation from RFC 3597 to the known RR type.
func (rr *RFC3597) fromRFC3597(r RR) error {
	hdr := r.Header()
	*hdr = rr.Hdr

	// Can't overflow uint16 as the length of Rdata is validated in (*RFC3597).parse.
	// We can only get here when rr was constructed with that method.
	hdr.Rdlength = uint16(hex.DecodedLen(len(rr.Rdata)))

	if noRdata(*hdr) {
		// Dynamic update.
		return nil
	}

	// rr.pack requires an extra allocation and a copy so we just decode Rdata
	// manually, it's simpler anyway.
	msg, err := hex.DecodeString(rr.Rdata)
	if err != nil {
		return err
	}

	_, err = r.unpack(msg, 0)
	return err
}


================================================
FILE: dns_bench_test.go
================================================
package dns

import (
	"fmt"
	"net"
	"testing"
)

func BenchmarkMsgLength(b *testing.B) {
	b.StopTimer()
	makeMsg := func(question string, ans, ns, e []RR) *Msg {
		msg := new(Msg)
		msg.SetQuestion(Fqdn(question), TypeANY)
		msg.Answer = append(msg.Answer, ans...)
		msg.Ns = append(msg.Ns, ns...)
		msg.Extra = append(msg.Extra, e...)
		msg.Compress = true
		return msg
	}
	name1 := "12345678901234567890123456789012345.12345678.123."
	rrMx := testRR(name1 + " 3600 IN MX 10 " + name1)
	msg := makeMsg(name1, []RR{rrMx, rrMx}, nil, nil)
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		msg.Len()
	}
}

func BenchmarkMsgLengthNoCompression(b *testing.B) {
	b.StopTimer()
	makeMsg := func(question string, ans, ns, e []RR) *Msg {
		msg := new(Msg)
		msg.SetQuestion(Fqdn(question), TypeANY)
		msg.Answer = append(msg.Answer, ans...)
		msg.Ns = append(msg.Ns, ns...)
		msg.Extra = append(msg.Extra, e...)
		return msg
	}
	name1 := "12345678901234567890123456789012345.12345678.123."
	rrMx := testRR(name1 + " 3600 IN MX 10 " + name1)
	msg := makeMsg(name1, []RR{rrMx, rrMx}, nil, nil)
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		msg.Len()
	}
}

func BenchmarkMsgLengthPack(b *testing.B) {
	makeMsg := func(question string, ans, ns, e []RR) *Msg {
		msg := new(Msg)
		msg.SetQuestion(Fqdn(question), TypeANY)
		msg.Answer = append(msg.Answer, ans...)
		msg.Ns = append(msg.Ns, ns...)
		msg.Extra = append(msg.Extra, e...)
		msg.Compress = true
		return msg
	}
	name1 := "12345678901234567890123456789012345.12345678.123."
	rrMx := testRR(name1 + " 3600 IN MX 10 " + name1)
	msg := makeMsg(name1, []RR{rrMx, rrMx}, nil, nil)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_, _ = msg.Pack()
	}
}

func BenchmarkMsgLengthMassive(b *testing.B) {
	makeMsg := func(question string, ans, ns, e []RR) *Msg {
		msg := new(Msg)
		msg.SetQuestion(Fqdn(question), TypeANY)
		msg.Answer = append(msg.Answer, ans...)
		msg.Ns = append(msg.Ns, ns...)
		msg.Extra = append(msg.Extra, e...)
		msg.Compress = true
		return msg
	}
	const name1 = "12345678901234567890123456789012345.12345678.123."
	rrMx := testRR(name1 + " 3600 IN MX 10 " + name1)
	answer := []RR{rrMx, rrMx}
	for i := 0; i < 128; i++ {
		rrA := testRR(fmt.Sprintf("example%03d.something%03delse.org. 2311 IN A 127.0.0.1", i/32, i%32))
		answer = append(answer, rrA)
	}
	answer = append(answer, rrMx, rrMx)
	msg := makeMsg(name1, answer, nil, nil)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		msg.Len()
	}
}

func BenchmarkMsgLengthOnlyQuestion(b *testing.B) {
	msg := new(Msg)
	msg.SetQuestion(Fqdn("12345678901234567890123456789012345.12345678.123."), TypeANY)
	msg.Compress = true
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		msg.Len()
	}
}

func BenchmarkMsgLengthEscapedName(b *testing.B) {
	msg := new(Msg)
	msg.SetQuestion(`\1\2\3\4\5\6\7\8\9\0\1\2\3\4\5\6\7\8\9\0\1\2\3\4\5\6\7\8\9\0\1\2\3\4\5.\1\2\3\4\5\6\7\8.\1\2\3.`, TypeANY)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		msg.Len()
	}
}

func BenchmarkPackDomainName(b *testing.B) {
	name1 := "12345678901234567890123456789012345.12345678.123."
	buf := make([]byte, len(name1)+1)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_, _ = PackDomainName(name1, buf, 0, nil, false)
	}
}

func BenchmarkUnpackDomainName(b *testing.B) {
	name1 := "12345678901234567890123456789012345.12345678.123."
	buf := make([]byte, len(name1)+1)
	_, _ = PackDomainName(name1, buf, 0, nil, false)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_, _, _ = UnpackDomainName(buf, 0)
	}
}

func BenchmarkUnpackDomainNameUnprintable(b *testing.B) {
	name1 := "\x02\x02\x02\x025\x02\x02\x02\x02.12345678.123."
	buf := make([]byte, len(name1)+1)
	_, _ = PackDomainName(name1, buf, 0, nil, false)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_, _, _ = UnpackDomainName(buf, 0)
	}
}

func BenchmarkUnpackDomainNameLongest(b *testing.B) {
	buf := make([]byte, len(longestDomain)+1)
	n, err := PackDomainName(longestDomain, buf, 0, nil, false)
	if err != nil {
		b.Fatal(err)
	}
	if n != maxDomainNameWireOctets {
		b.Fatalf("name wrong size in wire format, expected %d, got %d", maxDomainNameWireOctets, n)
	}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_, _, _ = UnpackDomainName(buf, 0)
	}
}

func BenchmarkUnpackDomainNameLongestUnprintable(b *testing.B) {
	buf := make([]byte, len(longestUnprintableDomain)+1)
	n, err := PackDomainName(longestUnprintableDomain, buf, 0, nil, false)
	if err != nil {
		b.Fatal(err)
	}
	if n != maxDomainNameWireOctets {
		b.Fatalf("name wrong size in wire format, expected %d, got %d", maxDomainNameWireOctets, n)
	}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_, _, _ = UnpackDomainName(buf, 0)
	}
}

func BenchmarkCopy(b *testing.B) {
	b.ReportAllocs()
	m := new(Msg)
	m.SetQuestion("miek.nl.", TypeA)
	rr := testRR("miek.nl. 2311 IN A 127.0.0.1")
	m.Answer = []RR{rr}
	rr = testRR("miek.nl. 2311 IN NS 127.0.0.1")
	m.Ns = []RR{rr}
	rr = testRR("miek.nl. 2311 IN A 127.0.0.1")
	m.Extra = []RR{rr}

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		m.Copy()
	}
}

func BenchmarkPackA(b *testing.B) {
	a := &A{Hdr: RR_Header{Name: ".", Rrtype: TypeA, Class: ClassANY}, A: net.IPv4(127, 0, 0, 1)}

	buf := make([]byte, Len(a))
	b.ReportAllocs()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_, _ = PackRR(a, buf, 0, nil, false)
	}
}

func BenchmarkUnpackA(b *testing.B) {
	a := &A{Hdr: RR_Header{Name: ".", Rrtype: TypeA, Class: ClassANY}, A: net.IPv4(127, 0, 0, 1)}

	buf := make([]byte, Len(a))
	PackRR(a, buf, 0, nil, false)
	a = nil
	b.ReportAllocs()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_, _, _ = UnpackRR(buf, 0)
	}
}

func BenchmarkPackMX(b *testing.B) {
	m := &MX{Hdr: RR_Header{Name: ".", Rrtype: TypeA, Class: ClassANY}, Mx: "mx.miek.nl."}

	buf := make([]byte, Len(m))
	b.ReportAllocs()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_, _ = PackRR(m, buf, 0, nil, false)
	}
}

func BenchmarkUnpackMX(b *testing.B) {
	m := &MX{Hdr: RR_Header{Name: ".", Rrtype: TypeA, Class: ClassANY}, Mx: "mx.miek.nl."}

	buf := make([]byte, Len(m))
	PackRR(m, buf, 0, nil, false)
	m = nil
	b.ReportAllocs()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_, _, _ = UnpackRR(buf, 0)
	}
}

func BenchmarkPackAAAAA(b *testing.B) {
	aaaa := testRR(". IN AAAA ::1")

	buf := make([]byte, Len(aaaa))
	b.ReportAllocs()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_, _ = PackRR(aaaa, buf, 0, nil, false)
	}
}

func BenchmarkUnpackAAAA(b *testing.B) {
	aaaa := testRR(". IN AAAA ::1")

	buf := make([]byte, Len(aaaa))
	PackRR(aaaa, buf, 0, nil, false)
	aaaa = nil
	b.ReportAllocs()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_, _, _ = UnpackRR(buf, 0)
	}
}

func BenchmarkPackMsg(b *testing.B) {
	makeMsg := func(question string, ans, ns, e []RR) *Msg {
		msg := new(Msg)
		msg.SetQuestion(Fqdn(question), TypeANY)
		msg.Answer = append(msg.Answer, ans...)
		msg.Ns = append(msg.Ns, ns...)
		msg.Extra = append(msg.Extra, e...)
		msg.Compress = true
		return msg
	}
	name1 := "12345678901234567890123456789012345.12345678.123."
	rrMx := testRR(name1 + " 3600 IN MX 10 " + name1)
	msg := makeMsg(name1, []RR{rrMx, rrMx}, nil, nil)
	buf := make([]byte, 512)
	b.ReportAllocs()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_, _ = msg.PackBuffer(buf)
	}
}

func BenchmarkPackMsgMassive(b *testing.B) {
	makeMsg := func(question string, ans, ns, e []RR) *Msg {
		msg := new(Msg)
		msg.SetQuestion(Fqdn(question), TypeANY)
		msg.Answer = append(msg.Answer, ans...)
		msg.Ns = append(msg.Ns, ns...)
		msg.Extra = append(msg.Extra, e...)
		msg.Compress = true
		return msg
	}
	const name1 = "12345678901234567890123456789012345.12345678.123."
	rrMx := testRR(name1 + " 3600 IN MX 10 " + name1)
	answer := []RR{rrMx, rrMx}
	for i := 0; i < 128; i++ {
		rrA := testRR(fmt.Sprintf("example%03d.something%03delse.org. 2311 IN A 127.0.0.1", i/32, i%32))
		answer = append(answer, rrA)
	}
	answer = append(answer, rrMx, rrMx)
	msg := makeMsg(name1, answer, nil, nil)
	buf := make([]byte, 512)
	b.ReportAllocs()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_, _ = msg.PackBuffer(buf)
	}
}

func BenchmarkPackMsgOnlyQuestion(b *testing.B) {
	msg := new(Msg)
	msg.SetQuestion(Fqdn("12345678901234567890123456789012345.12345678.123."), TypeANY)
	msg.Compress = true
	buf := make([]byte, 512)
	b.ReportAllocs()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_, _ = msg.PackBuffer(buf)
	}
}

func BenchmarkUnpackMsg(b *testing.B) {
	makeMsg := func(question string, ans, ns, e []RR) *Msg {
		msg := new(Msg)
		msg.SetQuestion(Fqdn(question), TypeANY)
		msg.Answer = append(msg.Answer, ans...)
		msg.Ns = append(msg.Ns, ns...)
		msg.Extra = append(msg.Extra, e...)
		msg.Compress = true
		return msg
	}
	name1 := "12345678901234567890123456789012345.12345678.123."
	rrMx := testRR(name1 + " 3600 IN MX 10 " + name1)
	msg := makeMsg(name1, []RR{rrMx, rrMx}, nil, nil)
	msgBuf, _ := msg.Pack()
	b.ReportAllocs()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_ = msg.Unpack(msgBuf)
	}
}

func BenchmarkIdGeneration(b *testing.B) {
	for i := 0; i < b.N; i++ {
		_ = id()
	}
}

func BenchmarkReverseAddr(b *testing.B) {
	b.Run("IP4", func(b *testing.B) {
		for n := 0; n < b.N; n++ {
			addr, err := ReverseAddr("192.0.2.1")
			if err != nil {
				b.Fatal(err)
			}
			if expect := "1.2.0.192.in-addr.arpa."; addr != expect {
				b.Fatalf("invalid reverse address, expected %q, got %q", expect, addr)
			}
		}
	})

	b.Run("IP6", func(b *testing.B) {
		for n := 0; n < b.N; n++ {
			addr, err := ReverseAddr("2001:db8::68")
			if err != nil {
				b.Fatal(err)
			}
			if expect := "8.6.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa."; addr != expect {
				b.Fatalf("invalid reverse address, expected %q, got %q", expect, addr)
			}
		}
	})
}


================================================
FILE: dns_test.go
================================================
package dns

import (
	"bytes"
	"encoding/hex"
	"net"
	"testing"
)

func TestPackUnpack(t *testing.T) {
	out := new(Msg)
	out.Answer = make([]RR, 1)
	key := &DNSKEY{Flags: 257, Protocol: 3, Algorithm: RSASHA1}
	key.Hdr = RR_Header{Name: "miek.nl.", Rrtype: TypeDNSKEY, Class: ClassINET, Ttl: 3600}
	key.PublicKey = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFqNDzr//kZ"

	out.Answer[0] = key
	msg, err := out.Pack()
	if err != nil {
		t.Error("failed to pack msg with DNSKEY")
	}
	in := new(Msg)
	if in.Unpack(msg) != nil {
		t.Error("failed to unpack msg with DNSKEY")
	}

	sig := &RRSIG{TypeCovered: TypeDNSKEY, Algorithm: RSASHA1, Labels: 2,
		OrigTtl: 3600, Expiration: 4000, Inception: 4000, KeyTag: 34641, SignerName: "miek.nl.",
		Signature: "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFqNDzr//kZ"}
	sig.Hdr = RR_Header{Name: "miek.nl.", Rrtype: TypeRRSIG, Class: ClassINET, Ttl: 3600}

	out.Answer[0] = sig
	msg, err = out.Pack()
	if err != nil {
		t.Error("failed to pack msg with RRSIG")
	}

	if in.Unpack(msg) != nil {
		t.Error("failed to unpack msg with RRSIG")
	}
}

func TestPackUnpack2(t *testing.T) {
	m := new(Msg)
	m.Extra = make([]RR, 1)
	m.Answer = make([]RR, 1)
	dom := "miek.nl."
	rr := new(A)
	rr.Hdr = RR_Header{Name: dom, Rrtype: TypeA, Class: ClassINET, Ttl: 0}
	rr.A = net.IPv4(127, 0, 0, 1)

	x := new(TXT)
	x.Hdr = RR_Header{Name: dom, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}
	x.Txt = []string{"heelalaollo"}

	m.Extra[0] = x
	m.Answer[0] = rr
	_, err := m.Pack()
	if err != nil {
		t.Error("Packing failed: ", err)
		return
	}
}

func TestPackUnpack3(t *testing.T) {
	m := new(Msg)
	m.Extra = make([]RR, 2)
	m.Answer = make([]RR, 1)
	dom := "miek.nl."
	rr := new(A)
	rr.Hdr = RR_Header{Name: dom, Rrtype: TypeA, Class: ClassINET, Ttl: 0}
	rr.A = net.IPv4(127, 0, 0, 1)

	x1 := new(TXT)
	x1.Hdr = RR_Header{Name: dom, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}
	x1.Txt = []string{}

	x2 := new(TXT)
	x2.Hdr = RR_Header{Name: dom, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}
	x2.Txt = []string{"heelalaollo"}

	m.Extra[0] = x1
	m.Extra[1] = x2
	m.Answer[0] = rr
	b, err := m.Pack()
	if err != nil {
		t.Error("packing failed: ", err)
		return
	}

	var unpackMsg Msg
	err = unpackMsg.Unpack(b)
	if err != nil {
		t.Error("unpacking failed")
		return
	}
}

func TestBailiwick(t *testing.T) {
	yes := map[string]string{
		"miek1.nl": "miek1.nl",
		"miek.nl":  "ns.miek.nl",
		".":        "miek.nl",
	}
	for parent, child := range yes {
		if !IsSubDomain(parent, child) {
			t.Errorf("%s should be child of %s", child, parent)
			t.Errorf("comparelabels %d", CompareDomainName(parent, child))
			t.Errorf("lenlabels %d %d", CountLabel(parent), CountLabel(child))
		}
	}
	no := map[string]string{
		"www.miek.nl":  "ns.miek.nl",
		"m\\.iek.nl":   "ns.miek.nl",
		"w\\.iek.nl":   "w.iek.nl",
		"p\\\\.iek.nl": "ns.p.iek.nl", // p\\.iek.nl , literal \ in domain name
		"miek.nl":      ".",
	}
	for parent, child := range no {
		if IsSubDomain(parent, child) {
			t.Errorf("%s should not be child of %s", child, parent)
			t.Errorf("comparelabels %d", CompareDomainName(parent, child))
			t.Errorf("lenlabels %d %d", CountLabel(parent), CountLabel(child))
		}
	}
}

func TestPackNAPTR(t *testing.T) {
	for _, n := range []string{
		`apple.com. IN NAPTR   100 50 "se" "SIP+D2U" "" _sip._udp.apple.com.`,
		`apple.com. IN NAPTR   90 50 "se" "SIP+D2T" "" _sip._tcp.apple.com.`,
		`apple.com. IN NAPTR   50 50 "se" "SIPS+D2T" "" _sips._tcp.apple.com.`,
	} {
		rr := testRR(n)
		msg := make([]byte, Len(rr))
		if off, err := PackRR(rr, msg, 0, nil, false); err != nil {
			t.Errorf("packing failed: %v", err)
			t.Errorf("length %d, need more than %d", Len(rr), off)
		}
	}
}

func TestToRFC3597(t *testing.T) {
	a := testRR("miek.nl. IN A 10.0.1.1")
	x := new(RFC3597)
	x.ToRFC3597(a)
	if x.String() != `miek.nl.	3600	CLASS1	TYPE1	\# 4 0a000101` {
		t.Errorf("string mismatch, got: %s", x)
	}

	b := testRR("miek.nl. IN MX 10 mx.miek.nl.")
	x.ToRFC3597(b)
	if x.String() != `miek.nl.	3600	CLASS1	TYPE15	\# 14 000a026d78046d69656b026e6c00` {
		t.Errorf("string mismatch, got: %s", x)
	}
}

func TestNoRdataPack(t *testing.T) {
	data := make([]byte, 1024)
	for typ, fn := range TypeToRR {
		r := fn()
		*r.Header() = RR_Header{Name: "miek.nl.", Rrtype: typ, Class: ClassINET, Ttl: 16}
		_, err := PackRR(r, data, 0, nil, false)
		if err != nil {
			t.Errorf("failed to pack RR with zero rdata: %s: %v", TypeToString[typ], err)
		}
	}
}

func TestNoRdataUnpack(t *testing.T) {
	data := make([]byte, 1024)
	for typ, fn := range TypeToRR {
		if typ == TypeSOA || typ == TypeTSIG || typ == TypeTKEY {
			// SOA, TSIG will not be seen (like this) in dyn. updates?
			// TKEY requires length fields to be present for the Key and OtherData fields
			continue
		}
		r := fn()
		*r.Header() = RR_Header{Name: "miek.nl.", Rrtype: typ, Class: ClassINET, Ttl: 16}
		off, err := PackRR(r, data, 0, nil, false)
		if err != nil {
			// Should always works, TestNoDataPack should have caught this
			t.Errorf("failed to pack RR: %v", err)
			continue
		}
		if _, _, err := UnpackRR(data[:off], 0); err != nil {
			t.Errorf("failed to unpack RR with zero rdata: %s: %v", TypeToString[typ], err)
		}
	}
}

func TestRdataOverflow(t *testing.T) {
	rr := new(RFC3597)
	rr.Hdr.Name = "."
	rr.Hdr.Class = ClassINET
	rr.Hdr.Rrtype = 65280
	rr.Rdata = hex.EncodeToString(make([]byte, 0xFFFF))
	buf := make([]byte, 0xFFFF*2)
	if _, err := PackRR(rr, buf, 0, nil, false); err != nil {
		t.Fatalf("maximum size rrdata pack failed: %v", err)
	}
	rr.Rdata += "00"
	if _, err := PackRR(rr, buf, 0, nil, false); err != ErrRdata {
		t.Fatalf("oversize rrdata pack didn't return ErrRdata - instead: %v", err)
	}
}

func TestCopy(t *testing.T) {
	rr := testRR("miek.nl. 2311 IN A 127.0.0.1") // Weird TTL to avoid catching TTL
	rr1 := Copy(rr)
	if rr.String() != rr1.String() {
		t.Fatalf("Copy() failed %s != %s", rr.String(), rr1.String())
	}
}

func TestMsgCopy(t *testing.T) {
	m := new(Msg)
	m.SetQuestion("miek.nl.", TypeA)
	rr := testRR("miek.nl. 2311 IN A 127.0.0.1")
	m.Answer = []RR{rr}
	rr = testRR("miek.nl. 2311 IN NS 127.0.0.1")
	m.Ns = []RR{rr}

	m1 := m.Copy()
	if m.String() != m1.String() {
		t.Fatalf("Msg.Copy() failed %s != %s", m.String(), m1.String())
	}

	m1.Answer[0] = testRR("somethingelse.nl. 2311 IN A 127.0.0.1")
	if m.String() == m1.String() {
		t.Fatalf("Msg.Copy() failed; change to copy changed template %s", m.String())
	}

	rr = testRR("miek.nl. 2311 IN A 127.0.0.2")
	m1.Answer = append(m1.Answer, rr)
	if m1.Ns[0].String() == m1.Answer[1].String() {
		t.Fatalf("Msg.Copy() failed; append changed underlying array %s", m1.Ns[0].String())
	}
}

func TestMsgPackBuffer(t *testing.T) {
	var testMessages = []string{
		// news.ycombinator.com.in.escapemg.com.	IN	A, response
		"586285830001000000010000046e6577730b79636f6d62696e61746f7203636f6d02696e086573636170656d6703636f6d0000010001c0210006000100000e10002c036e7332c02103646e730b67726f6f7665736861726bc02d77ed50e600002a3000000e1000093a8000000e10",

		// news.ycombinator.com.in.escapemg.com.	IN	A, question
		"586201000001000000000000046e6577730b79636f6d62696e61746f7203636f6d02696e086573636170656d6703636f6d0000010001",

		"398781020001000000000000046e6577730b79636f6d62696e61746f7203636f6d0000010001",
	}

	for i, hexData := range testMessages {
		// we won't fail the decoding of the hex
		input, _ := hex.DecodeString(hexData)
		m := new(Msg)
		if err := m.Unpack(input); err != nil {
			t.Errorf("packet %d failed to unpack", i)
			continue
		}
	}
}

// Make sure we can decode a TKEY packet from the string, modify the RR, and then pack it again.
func TestTKEY(t *testing.T) {
	// An example TKEY RR captured.  There is no known accepted standard text format for a TKEY
	// record so we do this from a hex string instead of from a text readable string.
	tkeyStr := "0737362d6d732d370932322d3332633233332463303439663961662d633065612d313165372d363839362d6463333937396666656666640000f900ff0000000000d2086773732d747369670059fd01f359fe53730003000000b8a181b53081b2a0030a0100a10b06092a864882f712010202a2819d04819a60819706092a864886f71201020202006f8187308184a003020105a10302010fa2783076a003020112a26f046db29b1b1d2625da3b20b49dafef930dd1e9aad335e1c5f45dcd95e0005d67a1100f3e573d70506659dbed064553f1ab890f68f65ae10def0dad5b423b39f240ebe666f2886c5fe03819692d29182bbed87b83e1f9d16b7334ec16a3c4fc5ad4a990088e0be43f0c6957916f5fe60000"
	tkeyBytes, err := hex.DecodeString(tkeyStr)
	if err != nil {
		t.Fatal("unable to decode TKEY string ", err)
	}
	// Decode the RR
	rr, tkeyLen, unPackErr := UnpackRR(tkeyBytes, 0)
	if unPackErr != nil {
		t.Fatal("unable to decode TKEY RR", unPackErr)
	}
	// Make sure it's a TKEY record
	if rr.Header().Rrtype != TypeTKEY {
		t.Fatal("Unable to decode TKEY")
	}
	// Make sure we get back the same length
	if Len(rr) != len(tkeyBytes) {
		t.Fatalf("Lengths don't match %d != %d", Len(rr), len(tkeyBytes))
	}
	// make space for it with some fudge room
	msg := make([]byte, tkeyLen+1000)
	offset, packErr := PackRR(rr, msg, 0, nil, false)
	if packErr != nil {
		t.Fatal("unable to pack TKEY RR", packErr)
	}
	if offset != len(tkeyBytes) {
		t.Fatalf("mismatched TKEY RR size %d != %d", len(tkeyBytes), offset)
	}
	if !bytes.Equal(tkeyBytes, msg[0:offset]) {
		t.Fatal("mismatched TKEY data after rewriting bytes")
	}

	// Now add some bytes to this and make sure we can encode OtherData properly
	tkey := rr.(*TKEY)
	tkey.OtherData = "abcd"
	tkey.OtherLen = 2
	offset, packErr = PackRR(tkey, msg, 0, nil, false)
	if packErr != nil {
		t.Fatal("unable to pack TKEY RR after modification", packErr)
	}
	if offset != len(tkeyBytes)+2 {
		t.Fatalf("mismatched TKEY RR size %d != %d", offset, len(tkeyBytes)+2)
	}

	// Make sure we can parse our string output
	tkey.Hdr.Class = ClassINET // https://github.com/miekg/dns/issues/577
	_, newError := NewRR(tkey.String())
	if newError != nil {
		t.Fatalf("unable to parse TKEY string: %s", newError)
	}
}

var (
	sinkBool   bool
	sinkString string
)

func BenchmarkIsFQDN(b *testing.B) {
	b.Run("no_dot", func(b *testing.B) {
		var r bool
		for n := 0; n < b.N; n++ {
			r = IsFqdn("www.google.com")
		}
		sinkBool = r
	})
	b.Run("unescaped", func(b *testing.B) {
		var r bool
		for n := 0; n < b.N; n++ {
			r = IsFqdn("www.google.com.")
		}
		sinkBool = r
	})
	b.Run("escaped", func(b *testing.B) {
		var r bool
		for n := 0; n < b.N; n++ {
			r = IsFqdn(`www.google.com\\\\\\\\.`)
		}
		sinkBool = r
	})
}

func BenchmarkFQDN(b *testing.B) {
	b.Run("is_fqdn", func(b *testing.B) {
		var r string
		for n := 0; n < b.N; n++ {
			r = Fqdn("www.google.com.")
		}
		sinkString = r
	})
	b.Run("not_fqdn", func(b *testing.B) {
		var r string
		for n := 0; n < b.N; n++ {
			r = Fqdn("www.google.com")
		}
		sinkString = r
	})
}


================================================
FILE: dnssec.go
================================================
package dns

import (
	"bytes"
	"crypto"
	"crypto/ecdsa"
	"crypto/ed25519"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/rsa"
	_ "crypto/sha1"   // need its init function
	_ "crypto/sha256" // need its init function
	_ "crypto/sha512" // need its init function
	"encoding/asn1"
	"encoding/binary"
	"encoding/hex"
	"math/big"
	"sort"
	"strings"
	"time"
)

// DNSSEC encryption algorithm codes.
const (
	_ uint8 = iota
	RSAMD5
	DH
	DSA
	_ // Skip 4, RFC 6725, section 2.1
	RSASHA1
	DSANSEC3SHA1
	RSASHA1NSEC3SHA1
	RSASHA256
	_ // Skip 9, RFC 6725, section 2.1
	RSASHA512
	_ // Skip 11, RFC 6725, section 2.1
	ECCGOST
	ECDSAP256SHA256
	ECDSAP384SHA384
	ED25519
	ED448
	INDIRECT   uint8 = 252
	PRIVATEDNS uint8 = 253 // Private (experimental keys)
	PRIVATEOID uint8 = 254
)

// AlgorithmToString is a map of algorithm IDs to algorithm names.
var AlgorithmToString = map[uint8]string{
	RSAMD5:           "RSAMD5",
	DH:               "DH",
	DSA:              "DSA",
	RSASHA1:          "RSASHA1",
	DSANSEC3SHA1:     "DSA-NSEC3-SHA1",
	RSASHA1NSEC3SHA1: "RSASHA1-NSEC3-SHA1",
	RSASHA256:        "RSASHA256",
	RSASHA512:        "RSASHA512",
	ECCGOST:          "ECC-GOST",
	ECDSAP256SHA256:  "ECDSAP256SHA256",
	ECDSAP384SHA384:  "ECDSAP384SHA384",
	ED25519:          "ED25519",
	ED448:            "ED448",
	INDIRECT:         "INDIRECT",
	PRIVATEDNS:       "PRIVATEDNS",
	PRIVATEOID:       "PRIVATEOID",
}

// AlgorithmToHash is a map of algorithm crypto hash IDs to crypto.Hash's.
// For newer algorithm that do their own hashing (i.e. ED25519) the returned value
// is 0, implying no (external) hashing should occur. The non-exported identityHash is then
// used.
var AlgorithmToHash = map[uint8]crypto.Hash{
	RSAMD5:           crypto.MD5, // Deprecated in RFC 6725
	DSA:              crypto.SHA1,
	RSASHA1:          crypto.SHA1,
	RSASHA1NSEC3SHA1: crypto.SHA1,
	RSASHA256:        crypto.SHA256,
	ECDSAP256SHA256:  crypto.SHA256,
	ECDSAP384SHA384:  crypto.SHA384,
	RSASHA512:        crypto.SHA512,
	ED25519:          0,
}

// DNSSEC hashing algorithm codes.
const (
	_      uint8 = iota
	SHA1         // RFC 4034
	SHA256       // RFC 4509
	GOST94       // RFC 5933
	SHA384       // Experimental
	SHA512       // Experimental
)

// HashToString is a map of hash IDs to names.
var HashToString = map[uint8]string{
	SHA1:   "SHA1",
	SHA256: "SHA256",
	GOST94: "GOST94",
	SHA384: "SHA384",
	SHA512: "SHA512",
}

// DNSKEY flag values.
const (
	SEP    = 1
	REVOKE = 1 << 7
	ZONE   = 1 << 8
)

// The RRSIG needs to be converted to wireformat with some of the rdata (the signature) missing.
type rrsigWireFmt struct {
	TypeCovered uint16
	Algorithm   uint8
	Labels      uint8
	OrigTtl     uint32
	Expiration  uint32
	Inception   uint32
	KeyTag      uint16
	SignerName  string `dns:"domain-name"`
	/* No Signature */
}

// Used for converting DNSKEY's rdata to wirefmt.
type dnskeyWireFmt struct {
	Flags     uint16
	Protocol  uint8
	Algorithm uint8
	PublicKey string `dns:"base64"`
	/* Nothing is left out */
}

// KeyTag calculates the keytag (or key-id) of the DNSKEY.
func (k *DNSKEY) KeyTag() uint16 {
	if k == nil {
		return 0
	}
	var keytag int
	switch k.Algorithm {
	case RSAMD5:
		// This algorithm has been deprecated, but keep this key-tag calculation.
		// Look at the bottom two bytes of the modules, which the last item in the pubkey.
		// See https://www.rfc-editor.org/errata/eid193 .
		modulus, _ := fromBase64([]byte(k.PublicKey))
		if len(modulus) > 1 {
			x := binary.BigEndian.Uint16(modulus[len(modulus)-3:])
			keytag = int(x)
		}
	default:
		keywire := new(dnskeyWireFmt)
		keywire.Flags = k.Flags
		keywire.Protocol = k.Protocol
		keywire.Algorithm = k.Algorithm
		keywire.PublicKey = k.PublicKey
		wire := make([]byte, DefaultMsgSize)
		n, err := packKeyWire(keywire, wire)
		if err != nil {
			return 0
		}
		wire = wire[:n]
		for i, v := range wire {
			if i&1 != 0 {
				keytag += int(v) // must be larger than uint32
			} else {
				keytag += int(v) << 8
			}
		}
		keytag += keytag >> 16 & 0xFFFF
		keytag &= 0xFFFF
	}
	return uint16(keytag)
}

// ToDS converts a DNSKEY record to a DS record.
func (k *DNSKEY) ToDS(h uint8) *DS {
	if k == nil {
		return nil
	}
	ds := new(DS)
	ds.Hdr.Name = k.Hdr.Name
	ds.Hdr.Class = k.Hdr.Class
	ds.Hdr.Rrtype = TypeDS
	ds.Hdr.Ttl = k.Hdr.Ttl
	ds.Algorithm = k.Algorithm
	ds.DigestType = h
	ds.KeyTag = k.KeyTag()

	keywire := new(dnskeyWireFmt)
	keywire.Flags = k.Flags
	keywire.Protocol = k.Protocol
	keywire.Algorithm = k.Algorithm
	keywire.PublicKey = k.PublicKey
	wire := make([]byte, DefaultMsgSize)
	n, err := packKeyWire(keywire, wire)
	if err != nil {
		return nil
	}
	wire = wire[:n]

	owner := make([]byte, 255)
	off, err1 := PackDomainName(CanonicalName(k.Hdr.Name), owner, 0, nil, false)
	if err1 != nil {
		return nil
	}
	owner = owner[:off]
	// RFC4034:
	// digest = digest_algorithm( DNSKEY owner name | DNSKEY RDATA);
	// "|" denotes concatenation
	// DNSKEY RDATA = Flags | Protocol | Algorithm | Public Key.

	var hash crypto.Hash
	switch h {
	case SHA1:
		hash = crypto.SHA1
	case SHA256:
		hash = crypto.SHA256
	case SHA384:
		hash = crypto.SHA384
	case SHA512:
		hash = crypto.SHA512
	default:
		return nil
	}

	s := hash.New()
	s.Write(owner)
	s.Write(wire)
	ds.Digest = hex.EncodeToString(s.Sum(nil))
	return ds
}

// ToCDNSKEY converts a DNSKEY record to a CDNSKEY record.
func (k *DNSKEY) ToCDNSKEY() *CDNSKEY {
	c := &CDNSKEY{DNSKEY: *k}
	c.Hdr = k.Hdr
	c.Hdr.Rrtype = TypeCDNSKEY
	return c
}

// ToCDS converts a DS record to a CDS record.
func (d *DS) ToCDS() *CDS {
	c := &CDS{DS: *d}
	c.Hdr = d.Hdr
	c.Hdr.Rrtype = TypeCDS
	return c
}

// Sign signs an RRSet. The signature needs to be filled in with the values:
// Inception, Expiration, KeyTag, SignerName and Algorithm.  The rest is copied
// from the RRset. Sign returns a non-nill error when the signing went OK.
// There is no check if RRSet is a proper (RFC 2181) RRSet.  If OrigTTL is non
// zero, it is used as-is, otherwise the TTL of the RRset is used as the
// OrigTTL.
func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error {
	h0 := rrset[0].Header()
	rr.Hdr.Rrtype = TypeRRSIG
	rr.Hdr.Name = h0.Name
	rr.Hdr.Class = h0.Class
	if rr.OrigTtl == 0 { // If set don't override
		rr.OrigTtl = h0.Ttl
	}
	rr.TypeCovered = h0.Rrtype
	rr.Labels = uint8(CountLabel(h0.Name))

	if strings.HasPrefix(h0.Name, "*") {
		rr.Labels-- // wildcard, remove from label count
	}

	return rr.signAsIs(k, rrset)
}

func (rr *RRSIG) signAsIs(k crypto.Signer, rrset []RR) error {
	if k == nil {
		return ErrPrivKey
	}
	// s.Inception and s.Expiration may be 0 (rollover etc.), the rest must be set
	if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 {
		return ErrKey
	}

	sigwire := new(rrsigWireFmt)
	sigwire.TypeCovered = rr.TypeCovered
	sigwire.Algorithm = rr.Algorithm
	sigwire.Labels = rr.Labels
	sigwire.OrigTtl = rr.OrigTtl
	sigwire.Expiration = rr.Expiration
	sigwire.Inception = rr.Inception
	sigwire.KeyTag = rr.KeyTag
	// For signing, lowercase this name
	sigwire.SignerName = CanonicalName(rr.SignerName)

	// Create the desired binary blob
	signdata := make([]byte, DefaultMsgSize)
	n, err := packSigWire(sigwire, signdata)
	if err != nil {
		return err
	}
	signdata = signdata[:n]
	wire, err := rawSignatureData(rrset, rr)
	if err != nil {
		return err
	}

	h, cryptohash, err := hashFromAlgorithm(rr.Algorithm)
	if err != nil {
		return err
	}

	switch rr.Algorithm {
	case RSAMD5, DSA, DSANSEC3SHA1:
		// See RFC 6944.
		return ErrAlg
	default:
		h.Write(signdata)
		h.Write(wire)

		signature, err := sign(k, h.Sum(nil), cryptohash, rr.Algorithm)
		if err != nil {
			return err
		}

		rr.Signature = toBase64(signature)
		return nil
	}
}

func sign(k crypto.Signer, hashed []byte, hash crypto.Hash, alg uint8) ([]byte, error) {
	signature, err := k.Sign(rand.Reader, hashed, hash)
	if err != nil {
		return nil, err
	}

	switch alg {
	case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512, ED25519:
		return signature, nil
	case ECDSAP256SHA256, ECDSAP384SHA384:
		ecdsaSignature := &struct {
			R, S *big.Int
		}{}
		if _, err := asn1.Unmarshal(signature, ecdsaSignature); err != nil {
			return nil, err
		}

		var intlen int
		switch alg {
		case ECDSAP256SHA256:
			intlen = 32
		case ECDSAP384SHA384:
			intlen = 48
		}

		signature := intToBytes(ecdsaSignature.R, intlen)
		signature = append(signature, intToBytes(ecdsaSignature.S, intlen)...)
		return signature, nil
	default:
		return nil, ErrAlg
	}
}

// Verify validates an RRSet with the signature and key. This is only the
// cryptographic test, the signature validity period must be checked separately.
// This function copies the rdata of some RRs (to lowercase domain names) for the validation to work.
// It also checks that the Zone Key bit (RFC 4034 2.1.1) is set on the DNSKEY
// and that the Protocol field is set to 3 (RFC 4034 2.1.2).
func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
	// First the easy checks
	if !IsRRset(rrset) {
		return ErrRRset
	}
	if rr.KeyTag != k.KeyTag() {
		return ErrKey
	}
	if rr.Hdr.Class != k.Hdr.Class {
		return ErrKey
	}
	if rr.Algorithm != k.Algorithm {
		return ErrKey
	}

	signerName := CanonicalName(rr.SignerName)
	if !equal(signerName, k.Hdr.Name) {
		return ErrKey
	}

	if k.Protocol != 3 {
		return ErrKey
	}
	// RFC 4034 2.1.1 If bit 7 has value 0, then the DNSKEY record holds some
	// other type of DNS public key and MUST NOT be used to verify RRSIGs that
	// cover RRsets.
	if k.Flags&ZONE == 0 {
		return ErrKey
	}

	// IsRRset checked that we have at least one RR and that the RRs in
	// the set have consistent type, class, and name. Also check that type,
	// class and name matches the RRSIG record.
	// Also checks RFC 4035 5.3.1 the number of labels in the RRset owner
	// name MUST be greater than or equal to the value in the RRSIG RR's Labels field.
	// RFC 4035 5.3.1 Signer's Name MUST be the name of the zone that [contains the RRset].
	// Since we don't have SOA info, checking suffix may be the best we can do...?
	if h0 := rrset[0].Header(); h0.Class != rr.Hdr.Class ||
		h0.Rrtype != rr.TypeCovered ||
		uint8(CountLabel(h0.Name)) < rr.Labels ||
		!equal(h0.Name, rr.Hdr.Name) ||
		!strings.HasSuffix(CanonicalName(h0.Name), signerName) {

		return ErrRRset
	}

	// RFC 4035 5.3.2.  Reconstructing the Signed Data
	// Copy the sig, except the rrsig data
	sigwire := new(rrsigWireFmt)
	sigwire.TypeCovered = rr.TypeCovered
	sigwire.Algorithm = rr.Algorithm
	sigwire.Labels = rr.Labels
	sigwire.OrigTtl = rr.OrigTtl
	sigwire.Expiration = rr.Expiration
	sigwire.Inception = rr.Inception
	sigwire.KeyTag = rr.KeyTag
	sigwire.SignerName = signerName
	// Create the desired binary blob
	signeddata := make([]byte, DefaultMsgSize)
	n, err := packSigWire(sigwire, signeddata)
	if err != nil {
		return err
	}
	signeddata = signeddata[:n]
	wire, err := rawSignatureData(rrset, rr)
	if err != nil {
		return err
	}

	sigbuf := rr.sigBuf() // Get the binary signature data
	// TODO(miek)
	// remove the domain name and assume its ours?
	// if rr.Algorithm == PRIVATEDNS { // PRIVATEOID
	// }

	h, cryptohash, err := hashFromAlgorithm(rr.Algorithm)
	if err != nil {
		return err
	}

	switch rr.Algorithm {
	case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512:
		// TODO(mg): this can be done quicker, ie. cache the pubkey data somewhere??
		pubkey := k.publicKeyRSA() // Get the key
		if pubkey == nil {
			return ErrKey
		}

		h.Write(signeddata)
		h.Write(wire)
		return rsa.VerifyPKCS1v15(pubkey, cryptohash, h.Sum(nil), sigbuf)

	case ECDSAP256SHA256, ECDSAP384SHA384:
		pubkey := k.publicKeyECDSA()
		if pubkey == nil {
			return ErrKey
		}

		// Split sigbuf into the r and s coordinates
		r := new(big.Int).SetBytes(sigbuf[:len(sigbuf)/2])
		s := new(big.Int).SetBytes(sigbuf[len(sigbuf)/2:])

		h.Write(signeddata)
		h.Write(wire)
		if ecdsa.Verify(pubkey, h.Sum(nil), r, s) {
			return nil
		}
		return ErrSig

	case ED25519:
		pubkey := k.publicKeyED25519()
		if pubkey == nil {
			return ErrKey
		}

		if ed25519.Verify(pubkey, append(signeddata, wire...), sigbuf) {
			return nil
		}
		return ErrSig

	default:
		return ErrAlg
	}
}

// ValidityPeriod uses RFC1982 serial arithmetic to calculate
// if a signature period is valid. If t is the zero time, the
// current time is taken other t is. Returns true if the signature
// is valid at the given time, otherwise returns false.
func (rr *RRSIG) ValidityPeriod(t time.Time) bool {
	var utc int64
	if t.IsZero() {
		utc = time.Now().UTC().Unix()
	} else {
		utc = t.UTC().Unix()
	}
	modi := (int64(rr.Inception) - utc) / year68
	mode := (int64(rr.Expiration) - utc) / year68
	ti := int64(rr.Inception) + modi*year68
	te := int64(rr.Expiration) + mode*year68
	return ti <= utc && utc <= te
}

// Return the signatures base64 encoding sigdata as a byte slice.
func (rr *RRSIG) sigBuf() []byte {
	sigbuf, err := fromBase64([]byte(rr.Signature))
	if err != nil {
		return nil
	}
	return sigbuf
}

// publicKeyRSA returns the RSA public key from a DNSKEY record.
func (k *DNSKEY) publicKeyRSA() *rsa.PublicKey {
	keybuf, err := fromBase64([]byte(k.PublicKey))
	if err != nil {
		return nil
	}

	if len(keybuf) < 1+1+64 {
		// Exponent must be at least 1 byte and modulus at least 64
		return nil
	}

	// RFC 2537/3110, section 2. RSA Public KEY Resource Records
	// Length is in the 0th byte, unless its zero, then it
	// it in bytes 1 and 2 and its a 16 bit number
	explen := uint16(keybuf[0])
	keyoff := 1
	if explen == 0 {
		explen = uint16(keybuf[1])<<8 | uint16(keybuf[2])
		keyoff = 3
	}

	if explen > 4 || explen == 0 || keybuf[keyoff] == 0 {
		// Exponent larger than supported by the crypto package,
		// empty, or contains prohibited leading zero.
		return nil
	}

	modoff := keyoff + int(explen)
	modlen := len(keybuf) - modoff
	if modlen < 64 || modlen > 512 || keybuf[modoff] == 0 {
		// Modulus is too small, large, or contains prohibited leading zero.
		return nil
	}

	pubkey := new(rsa.PublicKey)

	var expo uint64
	// The exponent of length explen is between keyoff and modoff.
	for _, v := range keybuf[keyoff:modoff] {
		expo <<= 8
		expo |= uint64(v)
	}
	if expo > 1<<31-1 {
		// Larger exponent than supported by the crypto package.
		return nil
	}

	pubkey.E = int(expo)
	pubkey.N = new(big.Int).SetBytes(keybuf[modoff:])
	return pubkey
}

// publicKeyECDSA returns the Curve public key from the DNSKEY record.
func (k *DNSKEY) publicKeyECDSA() *ecdsa.PublicKey {
	keybuf, err := fromBase64([]byte(k.PublicKey))
	if err != nil {
		return nil
	}
	pubkey := new(ecdsa.PublicKey)
	switch k.Algorithm {
	case ECDSAP256SHA256:
		pubkey.Curve = elliptic.P256()
		if len(keybuf) != 64 {
			// wrongly encoded key
			return nil
		}
	case ECDSAP384SHA384:
		pubkey.Curve = elliptic.P384()
		if len(keybuf) != 96 {
			// Wrongly encoded key
			return nil
		}
	}
	pubkey.X = new(big.Int).SetBytes(keybuf[:len(keybuf)/2])
	pubkey.Y = new(big.Int).SetBytes(keybuf[len(keybuf)/2:])
	return pubkey
}

func (k *DNSKEY) publicKeyED25519() ed25519.PublicKey {
	keybuf, err := fromBase64([]byte(k.PublicKey))
	if err != nil {
		return nil
	}
	if len(keybuf) != ed25519.PublicKeySize {
		return nil
	}
	return keybuf
}

type wireSlice [][]byte

func (p wireSlice) Len() int      { return len(p) }
func (p wireSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p wireSlice) Less(i, j int) bool {
	_, ioff, _ := UnpackDomainName(p[i], 0)
	_, joff, _ := UnpackDomainName(p[j], 0)
	return bytes.Compare(p[i][ioff+10:], p[j][joff+10:]) < 0
}

// Return the raw signature data.
func rawSignatureData(rrset []RR, s *RRSIG) (buf []byte, err error) {
	wires := make(wireSlice, len(rrset))
	for i, r := range rrset {
		r1 := r.copy()
		h := r1.Header()
		h.Ttl = s.OrigTtl
		labels := SplitDomainName(h.Name)
		// 6.2. Canonical RR Form. (4) - wildcards
		if len(labels) > int(s.Labels) {
			// Wildcard
			h.Name = "*." + strings.Join(labels[len(labels)-int(s.Labels):], ".") + "."
		}
		// RFC 4034: 6.2.  Canonical RR Form. (2) - domain name to lowercase
		h.Name = CanonicalName(h.Name)
		// 6.2. Canonical RR Form. (3) - domain rdata to lowercase.
		//   NS, MD, MF, CNAME, SOA, MB, MG, MR, PTR,
		//   HINFO, MINFO, MX, RP, AFSDB, RT, SIG, PX, NXT, NAPTR, KX,
		//   SRV, DNAME, A6
		//
		// RFC 6840 - Clarifications and Implementation Notes for DNS Security (DNSSEC):
		//	Section 6.2 of [RFC4034] also erroneously lists HINFO as a record
		//	that needs conversion to lowercase, and twice at that.  Since HINFO
		//	records contain no domain names, they are not subject to case
		//	conversion.
		switch x := r1.(type) {
		case *NS:
			x.Ns = CanonicalName(x.Ns)
		case *MD:
			x.Md = CanonicalName(x.Md)
		case *MF:
			x.Mf = CanonicalName(x.Mf)
		case *CNAME:
			x.Target = CanonicalName(x.Target)
		case *SOA:
			x.Ns = CanonicalName(x.Ns)
			x.Mbox = CanonicalName(x.Mbox)
		case *MB:
			x.Mb = CanonicalName(x.Mb)
		case *MG:
			x.Mg = CanonicalName(x.Mg)
		case *MR:
			x.Mr = CanonicalName(x.Mr)
		case *PTR:
			x.Ptr = CanonicalName(x.Ptr)
		case *MINFO:
			x.Rmail = CanonicalName(x.Rmail)
			x.Email = CanonicalName(x.Email)
		case *MX:
			x.Mx = CanonicalName(x.Mx)
		case *RP:
			x.Mbox = CanonicalName(x.Mbox)
			x.Txt = CanonicalName(x.Txt)
		case *AFSDB:
			x.Hostname = CanonicalName(x.Hostname)
		case *RT:
			x.Host = CanonicalName(x.Host)
		case *SIG:
			x.SignerName = CanonicalName(x.SignerName)
		case *PX:
			x.Map822 = CanonicalName(x.Map822)
			x.Mapx400 = CanonicalName(x.Mapx400)
		case *NAPTR:
			x.Replacement = CanonicalName(x.Replacement)
		case *KX:
			x.Exchanger = CanonicalName(x.Exchanger)
		case *SRV:
			x.Target = CanonicalName(x.Target)
		case *DNAME:
			x.Target = CanonicalName(x.Target)
		}
		// 6.2. Canonical RR Form. (5) - origTTL
		wire := make([]byte, Len(r1)+1) // +1 to be safe(r)
		off, err1 := PackRR(r1, wire, 0, nil, false)
		if err1 != nil {
			return nil, err1
		}
		wire = wire[:off]
		wires[i] = wire
	}
	sort.Sort(wires)
	for i, wire := range wires {
		if i > 0 && bytes.Equal(wire, wires[i-1]) {
			continue
		}
		buf = append(buf, wire...)
	}
	return buf, nil
}

func packSigWire(sw *rrsigWireFmt, msg []byte) (int, error) {
	// copied from zmsg.go RRSIG packing
	off, err := packUint16(sw.TypeCovered, msg, 0)
	if err != nil {
		return off, err
	}
	off, err = packUint8(sw.Algorithm, msg, off)
	if err != nil {
		return off, err
	}
	off, err = packUint8(sw.Labels, msg, off)
	if err != nil {
		return off, err
	}
	off, err = packUint32(sw.OrigTtl, msg, off)
	if err != nil {
		return off, err
	}
	off, err = packUint32(sw.Expiration, msg, off)
	if err != nil {
		return off, err
	}
	off, err = packUint32(sw.Inception, msg, off)
	if err != nil {
		return off, err
	}
	off, err = packUint16(sw.KeyTag, msg, off)
	if err != nil {
		return off, err
	}
	off, err = PackDomainName(sw.SignerName, msg, off, nil, false)
	if err != nil {
		return off, err
	}
	return off, nil
}

func packKeyWire(dw *dnskeyWireFmt, msg []byte) (int, error) {
	// copied from zmsg.go DNSKEY packing
	off, err := packUint16(dw.Flags, msg, 0)
	if err != nil {
		return off, err
	}
	off, err = packUint8(dw.Protocol, msg, off)
	if err != nil {
		return off, err
	}
	off, err = packUint8(dw.Algorithm, msg, off)
	if err != nil {
		return off, err
	}
	off, err = packStringBase64(dw.PublicKey, msg, off)
	if err != nil {
		return off, err
	}
	return off, nil
}


================================================
FILE: dnssec_keygen.go
================================================
package dns

import (
	"crypto"
	"crypto/ecdsa"
	"crypto/ed25519"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/rsa"
	"math/big"
)

// Generate generates a DNSKEY of the given bit size.
// The public part is put inside the DNSKEY record.
// The Algorithm in the key must be set as this will define
// what kind of DNSKEY will be generated.
// The ECDSA algorithms imply a fixed keysize, in that case
// bits should be set to the size of the algorithm.
func (k *DNSKEY) Generate(bits int) (crypto.PrivateKey, error) {
	switch k.Algorithm {
	case RSASHA1, RSASHA256, RSASHA1NSEC3SHA1:
		if bits < 512 || bits > 4096 {
			return nil, ErrKeySize
		}
	case RSASHA512:
		if bits < 1024 || bits > 4096 {
			return nil, ErrKeySize
		}
	case ECDSAP256SHA256:
		if bits != 256 {
			return nil, ErrKeySize
		}
	case ECDSAP384SHA384:
		if bits != 384 {
			return nil, ErrKeySize
		}
	case ED25519:
		if bits != 256 {
			return nil, ErrKeySize
		}
	default:
		return nil, ErrAlg
	}

	switch k.Algorithm {
	case RSASHA1, RSASHA256, RSASHA512, RSASHA1NSEC3SHA1:
		priv, err := rsa.GenerateKey(rand.Reader, bits)
		if err != nil {
			return nil, err
		}
		k.setPublicKeyRSA(priv.PublicKey.E, priv.PublicKey.N)
		return priv, nil
	case ECDSAP256SHA256, ECDSAP384SHA384:
		var c elliptic.Curve
		switch k.Algorithm {
		case ECDSAP256SHA256:
			c = elliptic.P256()
		case ECDSAP384SHA384:
			c = elliptic.P384()
		}
		priv, err := ecdsa.GenerateKey(c, rand.Reader)
		if err != nil {
			return nil, err
		}
		k.setPublicKeyECDSA(priv.PublicKey.X, priv.PublicKey.Y)
		return priv, nil
	case ED25519:
		pub, priv, err := ed25519.GenerateKey(rand.Reader)
		if err != nil {
			return nil, err
		}
		k.setPublicKeyED25519(pub)
		return priv, nil
	default:
		return nil, ErrAlg
	}
}

// Set the public key (the value E and N)
func (k *DNSKEY) setPublicKeyRSA(_E int, _N *big.Int) bool {
	if _E == 0 || _N == nil {
		return false
	}
	buf := exponentToBuf(_E)
	buf = append(buf, _N.Bytes()...)
	k.PublicKey = toBase64(buf)
	return true
}

// Set the public key for Elliptic Curves
func (k *DNSKEY) setPublicKeyECDSA(_X, _Y *big.Int) bool {
	if _X == nil || _Y == nil {
		return false
	}
	var intlen int
	switch k.Algorithm {
	case ECDSAP256SHA256:
		intlen = 32
	case ECDSAP384SHA384:
		intlen = 48
	}
	k.PublicKey = toBase64(curveToBuf(_X, _Y, intlen))
	return true
}

// Set the public key for Ed25519
func (k *DNSKEY) setPublicKeyED25519(_K ed25519.PublicKey) bool {
	if _K == nil {
		return false
	}
	k.PublicKey = toBase64(_K)
	return true
}

// Set the public key (the values E and N) for RSA
// RFC 3110: Section 2. RSA Public KEY Resource Records
func exponentToBuf(_E int) []byte {
	var buf []byte
	i := big.NewInt(int64(_E)).Bytes()
	if len(i) < 256 {
		buf = make([]byte, 1, 1+len(i))
		buf[0] = uint8(len(i))
	} else {
		buf = make([]byte, 3, 3+len(i))
		buf[0] = 0
		buf[1] = uint8(len(i) >> 8)
		buf[2] = uint8(len(i))
	}
	buf = append(buf, i...)
	return buf
}

// Set the public key for X and Y for Curve. The two
// values are just concatenated.
func curveToBuf(_X, _Y *big.Int, intlen int) []byte {
	buf := intToBytes(_X, intlen)
	buf = append(buf, intToBytes(_Y, intlen)...)
	return buf
}


================================================
FILE: dnssec_keyscan.go
================================================
package dns

import (
	"bufio"
	"crypto"
	"crypto/ecdsa"
	"crypto/ed25519"
	"crypto/rsa"
	"io"
	"math/big"
	"strconv"
	"strings"
)

// NewPrivateKey returns a PrivateKey by parsing the string s.
// s should be in the same form of the BIND private key files.
func (k *DNSKEY) NewPrivateKey(s string) (crypto.PrivateKey, error) {
	if s == "" || s[len(s)-1] != '\n' { // We need a closing newline
		return k.ReadPrivateKey(strings.NewReader(s+"\n"), "")
	}
	return k.ReadPrivateKey(strings.NewReader(s), "")
}

// ReadPrivateKey reads a private key from the io.Reader q. The string file is
// only used in error reporting.
// The public key must be known, because some cryptographic algorithms embed
// the public inside the privatekey.
func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, error) {
	m, err := parseKey(q, file)
	if m == nil {
		return nil, err
	}
	if _, ok := m["private-key-format"]; !ok {
		return nil, ErrPrivKey
	}
	if m["private-key-format"] != "v1.2" && m["private-key-format"] != "v1.3" {
		return nil, ErrPrivKey
	}
	// TODO(mg): check if the pubkey matches the private key
	algoStr, _, _ := strings.Cut(m["algorithm"], " ")
	algo, err := strconv.ParseUint(algoStr, 10, 8)
	if err != nil {
		return nil, ErrPrivKey
	}
	switch uint8(algo) {
	case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512:
		priv, err := readPrivateKeyRSA(m)
		if err != nil {
			return nil, err
		}
		pub := k.publicKeyRSA()
		if pub == nil {
			return nil, ErrKey
		}
		priv.PublicKey = *pub
		return priv, nil
	case ECDSAP256SHA256, ECDSAP384SHA384:
		priv, err := readPrivateKeyECDSA(m)
		if err != nil {
			return nil, err
		}
		pub := k.publicKeyECDSA()
		if pub == nil {
			return nil, ErrKey
		}
		priv.PublicKey = *pub
		return priv, nil
	case ED25519:
		return readPrivateKeyED25519(m)
	default:
		return nil, ErrAlg
	}
}

// Read a private key (file) string and create a public key. Return the private key.
func readPrivateKeyRSA(m map[string]string) (*rsa.PrivateKey, error) {
	p := new(rsa.PrivateKey)
	p.Primes = []*big.Int{nil, nil}
	for k, v := range m {
		switch k {
		case "modulus", "publicexponent", "privateexponent", "prime1", "prime2":
			v1, err := fromBase64([]byte(v))
			if err != nil {
				return nil, err
			}
			switch k {
			case "modulus":
				p.PublicKey.N = new(big.Int).SetBytes(v1)
			case "publicexponent":
				i := new(big.Int).SetBytes(v1)
				p.PublicKey.E = int(i.Int64()) // int64 should be large enough
			case "privateexponent":
				p.D = new(big.Int).SetBytes(v1)
			case "prime1":
				p.Primes[0] = new(big.Int).SetBytes(v1)
			case "prime2":
				p.Primes[1] = new(big.Int).SetBytes(v1)
			}
		case "exponent1", "exponent2", "coefficient":
			// not used in Go (yet)
		case "created", "publish", "activate":
			// not used in Go (yet)
		}
	}
	return p, nil
}

func readPrivateKeyECDSA(m map[string]string) (*ecdsa.PrivateKey, error) {
	p := new(ecdsa.PrivateKey)
	p.D = new(big.Int)
	// TODO: validate that the required flags are present
	for k, v := range m {
		switch k {
		case "privatekey":
			v1, err := fromBase64([]byte(v))
			if err != nil {
				return nil, err
			}
			p.D.SetBytes(v1)
		case "created", "publish", "activate":
			/* not used in Go (yet) */
		}
	}
	return p, nil
}

func readPrivateKeyED25519(m map[string]string) (ed25519.PrivateKey, error) {
	var p ed25519.PrivateKey
	// TODO: validate that the required flags are present
	for k, v := range m {
		switch k {
		case "privatekey":
			p1, err := fromBase64([]byte(v))
			if err != nil {
				return nil, err
			}
			if len(p1) != ed25519.SeedSize {
				return nil, ErrPrivKey
			}
			p = ed25519.NewKeyFromSeed(p1)
		case "created", "publish", "activate":
			/* not used in Go (yet) */
		}
	}
	return p, nil
}

// parseKey reads a private key from r. It returns a map[string]string,
// with the key-value pairs, or an error when the file is not correct.
func parseKey(r io.Reader, file string) (map[string]string, error) {
	m := make(map[string]string)
	var k string

	c := newKLexer(r)

	for l, ok := c.Next(); ok; l, ok = c.Next() {
		// It should alternate
		switch l.value {
		case zKey:
			k = l.token
		case zValue:
			if k == "" {
				return nil, &ParseError{file: file, err: "no private key seen", lex: l}
			}

			m[strings.ToLower(k)] = l.token
			k = ""
		}
	}

	// Surface any read errors from r.
	if err := c.Err(); err != nil {
		return nil, &ParseError{file: file, err: err.Error()}
	}

	return m, nil
}

type klexer struct {
	br io.ByteReader

	readErr error

	line   int
	column int

	key bool

	eol bool // end-of-line
}

func newKLexer(r io.Reader) *klexer {
	br, ok := r.(io.ByteReader)
	if !ok {
		br = bufio.NewReaderSize(r, 1024)
	}

	return &klexer{
		br: br,

		line: 1,

		key: true,
	}
}

func (kl *klexer) Err() error {
	if kl.readErr == io.EOF {
		return nil
	}

	return kl.readErr
}

// readByte returns the next byte from the input
func (kl *klexer) readByte() (byte, bool) {
	if kl.readErr != nil {
		return 0, false
	}

	c, err := kl.br.ReadByte()
	if err != nil {
		kl.readErr = err
		return 0, false
	}

	// delay the newline handling until the next token is delivered,
	// fixes off-by-one errors when reporting a parse error.
	if kl.eol {
		kl.line++
		kl.column = 0
		kl.eol = false
	}

	if c == '\n' {
		kl.eol = true
	} else {
		kl.column++
	}

	return c, true
}

func (kl *klexer) Next() (lex, bool) {
	var (
		l lex

		str strings.Builder

		commt bool
	)

	for x, ok := kl.readByte(); ok; x, ok = kl.readByte() {
		l.line, l.column = kl.line, kl.column

		switch x {
		case ':':
			if commt || !kl.key {
				break
			}

			kl.key = false

			// Next token is a space, eat it
			kl.readByte()

			l.value = zKey
			l.token = str.String()
			return l, true
		case ';':
			commt = true
		case '\n':
			if commt {
				// Reset a comment
				commt = false
			}

			if kl.key && str.Len() == 0 {
				// ignore empty lines
				break
			}

			kl.key = true

			l.value = zValue
			l.token = str.String()
			return l, true
		default:
			if commt {
				break
			}

			str.WriteByte(x)
		}
	}

	if kl.readErr != nil && kl.readErr != io.EOF {
		// Don't return any tokens after a read error occurs.
		return lex{value: zEOF}, false
	}

	if str.Len() > 0 {
		// Send remainder
		l.value = zValue
		l.token = str.String()
		return l, true
	}

	return lex{value: zEOF}, false
}


================================================
FILE: dnssec_privkey.go
================================================
package dns

import (
	"crypto"
	"crypto/ecdsa"
	"crypto/ed25519"
	"crypto/rsa"
	"math/big"
	"strconv"
)

const format = "Private-key-format: v1.3\n"

var bigIntOne = big.NewInt(1)

// PrivateKeyString converts a PrivateKey to a string. This string has the same
// format as the private-key-file of BIND9 (Private-key-format: v1.3).
// It needs some info from the key (the algorithm), so its a method of the DNSKEY.
// It supports *rsa.PrivateKey, *ecdsa.PrivateKey and ed25519.PrivateKey.
func (r *DNSKEY) PrivateKeyString(p crypto.PrivateKey) string {
	algorithm := strconv.Itoa(int(r.Algorithm))
	algorithm += " (" + AlgorithmToString[r.Algorithm] + ")"

	switch p := p.(type) {
	case *rsa.PrivateKey:
		modulus := toBase64(p.PublicKey.N.Bytes())
		e := big.NewInt(int64(p.PublicKey.E))
		publicExponent := toBase64(e.Bytes())
		privateExponent := toBase64(p.D.Bytes())
		prime1 := toBase64(p.Primes[0].Bytes())
		prime2 := toBase64(p.Primes[1].Bytes())
		// Calculate Exponent1/2 and Coefficient as per: http://en.wikipedia.org/wiki/RSA#Using_the_Chinese_remainder_algorithm
		// and from: http://code.google.com/p/go/issues/detail?id=987
		p1 := new(big.Int).Sub(p.Primes[0], bigIntOne)
		q1 := new(big.Int).Sub(p.Primes[1], bigIntOne)
		exp1 := new(big.Int).Mod(p.D, p1)
		exp2 := new(big.Int).Mod(p.D, q1)
		coeff := new(big.Int).ModInverse(p.Primes[1], p.Primes[0])

		exponent1 := toBase64(exp1.Bytes())
		exponent2 := toBase64(exp2.Bytes())
		coefficient := toBase64(coeff.Bytes())

		return format +
			"Algorithm: " + algorithm + "\n" +
			"Modulus: " + modulus + "\n" +
			"PublicExponent: " + publicExponent + "\n" +
			"PrivateExponent: " + privateExponent + "\n" +
			"Prime1: " + prime1 + "\n" +
			"Prime2: " + prime2 + "\n" +
			"Exponent1: " + exponent1 + "\n" +
			"Exponent2: " + exponent2 + "\n" +
			"Coefficient: " + coefficient + "\n"

	case *ecdsa.PrivateKey:
		var intlen int
		switch r.Algorithm {
		case ECDSAP256SHA256:
			intlen = 32
		case ECDSAP384SHA384:
			intlen = 48
		}
		private := toBase64(intToBytes(p.D, intlen))
		return format +
			"Algorithm: " + algorithm + "\n" +
			"PrivateKey: " + private + "\n"

	case ed25519.PrivateKey:
		private := toBase64(p.Seed())
		return format +
			"Algorithm: " + algorithm + "\n" +
			"PrivateKey: " + private + "\n"

	default:
		return ""
	}
}


================================================
FILE: dnssec_test.go
================================================
package dns

import (
	"crypto"
	"crypto/ecdsa"
	"crypto/ed25519"
	"crypto/rsa"
	"reflect"
	"strings"
	"testing"
	"time"
)

func getSoa() *SOA {
	soa := new(SOA)
	soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0}
	soa.Ns = "open.nlnetlabs.nl."
	soa.Mbox = "miekg.atoom.net."
	soa.Serial = 1293945905
	soa.Refresh = 14400
	soa.Retry = 3600
	soa.Expire = 604800
	soa.Minttl = 86400
	return soa
}

func TestSecure(t *testing.T) {
	soa := getSoa()

	sig := new(RRSIG)
	sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
	sig.TypeCovered = TypeSOA
	sig.Algorithm = RSASHA256
	sig.Labels = 2
	sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
	sig.Inception = 1293942305  // date -u '+%s' -d"2011-01-02 04:25:05"
	sig.OrigTtl = 14400
	sig.KeyTag = 12051
	sig.SignerName = "miek.nl."
	sig.Signature = "oMCbslaAVIp/8kVtLSms3tDABpcPRUgHLrOR48OOplkYo+8TeEGWwkSwaz/MRo2fB4FxW0qj/hTlIjUGuACSd+b1wKdH5GvzRJc2pFmxtCbm55ygAh4EUL0F6U5cKtGJGSXxxg6UFCQ0doJCmiGFa78LolaUOXImJrk6AFrGa0M="

	key := new(DNSKEY)
	key.Hdr.Name = "miek.nl."
	key.Hdr.Class = ClassINET
	key.Hdr.Ttl = 14400
	key.Flags = 256
	key.Protocol = 3
	key.Algorithm = RSASHA256
	key.PublicKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz"

	// It should validate. Period is checked separately, so this will keep on working
	if sig.Verify(key, []RR{soa}) != nil {
		t.Error("failure to validate")
	}
}

func TestSignature(t *testing.T) {
	sig := new(RRSIG)
	sig.Hdr.Name = "miek.nl."
	sig.Hdr.Class = ClassINET
	sig.Hdr.Ttl = 3600
	sig.TypeCovered = TypeDNSKEY
	sig.Algorithm = RSASHA1
	sig.Labels = 2
	sig.OrigTtl = 4000
	sig.Expiration = 1000 //Thu Jan  1 02:06:40 CET 1970
	sig.Inception = 800   //Thu Jan  1 01:13:20 CET 1970
	sig.KeyTag = 34641
	sig.SignerName = "miek.nl."
	sig.Signature = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFqNDzr//kZ"

	// Should not be valid
	if sig.ValidityPeriod(time.Now()) {
		t.Error("should not be valid")
	}

	sig.Inception = 315565800   //Tue Jan  1 10:10:00 CET 1980
	sig.Expiration = 4102477800 //Fri Jan  1 10:10:00 CET 2100
	if !sig.ValidityPeriod(time.Now()) {
		t.Error("should be valid")
	}
}

func TestSignVerify(t *testing.T) {
	// The record we want to sign
	soa := new(SOA)
	soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0}
	soa.Ns = "open.nlnetlabs.nl."
	soa.Mbox = "miekg.atoom.net."
	soa.Serial = 1293945905
	soa.Refresh = 14400
	soa.Retry = 3600
	soa.Expire = 604800
	soa.Minttl = 86400

	soa1 := new(SOA)
	soa1.Hdr = RR_Header{"*.miek.nl.", TypeSOA, ClassINET, 14400, 0}
	soa1.Ns = "open.nlnetlabs.nl."
	soa1.Mbox = "miekg.atoom.net."
	soa1.Serial = 1293945905
	soa1.Refresh = 14400
	soa1.Retry = 3600
	soa1.Expire = 604800
	soa1.Minttl = 86400

	srv := new(SRV)
	srv.Hdr = RR_Header{"srv.miek.nl.", TypeSRV, ClassINET, 14400, 0}
	srv.Port = 1000
	srv.Weight = 800
	srv.Target = "web1.miek.nl."

	hinfo := &HINFO{
		Hdr: RR_Header{
			Name:   "miek.nl.",
			Rrtype: TypeHINFO,
			Class:  ClassINET,
			Ttl:    3789,
		},
		Cpu: "X",
		Os:  "Y",
	}

	// With this key
	key := new(DNSKEY)
	key.Hdr.Rrtype = TypeDNSKEY
	key.Hdr.Name = "miek.nl."
	key.Hdr.Class = ClassINET
	key.Hdr.Ttl = 14400
	key.Flags = 256
	key.Protocol = 3
	key.Algorithm = RSASHA256
	privkey, err := key.Generate(1024)
	if err != nil {
		t.Fatal("failure to generate private key:", err)
	}

	// Fill in the values of the Sig, before signing
	sig := new(RRSIG)
	sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
	sig.TypeCovered = soa.Hdr.Rrtype
	sig.Labels = uint8(CountLabel(soa.Hdr.Name)) // works for all 3
	sig.OrigTtl = soa.Hdr.Ttl
	sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
	sig.Inception = 1293942305  // date -u '+%s' -d"2011-01-02 04:25:05"
	sig.KeyTag = key.KeyTag()   // Get the keyfrom the Key
	sig.SignerName = key.Hdr.Name
	sig.Algorithm = RSASHA256

	for _, r := range []RR{soa, soa1, srv, hinfo} {
		if err := sig.Sign(privkey.(*rsa.PrivateKey), []RR{r}); err != nil {
			t.Error("failure to sign the record:", err)
			continue
		}
		if err := sig.Verify(key, []RR{r}); err != nil {
			t.Errorf("failure to validate: %s", r.Header().Name)
			continue
		}
	}
}

// Test if RRSIG.Verify() conforms to RFC 4035 Section 5.3.1
func TestShouldNotVerifyInvalidSig(t *testing.T) {
	// The RRSIG RR and the RRset MUST have the same owner name
	rrNameMismatch := getSoa()
	rrNameMismatch.Hdr.Name = "example.com."

	// ... and the same class
	rrClassMismatch := getSoa()
	rrClassMismatch.Hdr.Class = ClassCHAOS

	// The RRSIG RR's Type Covered field MUST equal the RRset's type.
	rrTypeMismatch := getSoa()
	rrTypeMismatch.Hdr.Rrtype = TypeA

	// The number of labels in the RRset owner name MUST be greater than
	// or equal to the value in the RRSIG RR's Labels field.
	rrLabelLessThan := getSoa()
	rrLabelLessThan.Hdr.Name = "nl."

	// Time checks are done in ValidityPeriod

	// With this key
	key := new(DNSKEY)
	key.Hdr.Rrtype = TypeDNSKEY
	key.Hdr.Name = "miek.nl."
	key.Hdr.Class = ClassINET
	key.Hdr.Ttl = 14400
	key.Flags = 256
	key.Protocol = 3
	key.Algorithm = RSASHA256
	privkey, err := key.Generate(1024)
	if err != nil {
		t.Fatal("failure to generate private key:", err)
	}

	normalSoa := getSoa()

	// Fill in the normal values of the Sig, before signing
	sig := new(RRSIG)
	sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
	sig.TypeCovered = TypeSOA
	sig.Labels = uint8(CountLabel(normalSoa.Hdr.Name))
	sig.OrigTtl = normalSoa.Hdr.Ttl
	sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
	sig.Inception = 1293942305  // date -u '+%s' -d"2011-01-02 04:25:05"
	sig.KeyTag = key.KeyTag()   // Get the keyfrom the Key
	sig.SignerName = key.Hdr.Name
	sig.Algorithm = RSASHA256

	for i, rr := range []RR{rrNameMismatch, rrClassMismatch, rrTypeMismatch, rrLabelLessThan} {
		if i != 0 { // Just for the rrNameMismatch case, we need the name to mismatch
			sig := sig.copy().(*RRSIG)
			sig.SignerName = rr.Header().Name
			sig.Hdr.Name = rr.Header().Name
			key := key.copy().(*DNSKEY)
			key.Hdr.Name = rr.Header().Name
		}

		if err := sig.signAsIs(privkey.(*rsa.PrivateKey), []RR{rr}); err != nil {
			t.Error("failure to sign the record:", err)
			continue
		}

		if err := sig.Verify(key, []RR{rr}); err == nil {
			t.Error("should not validate: ", rr)
			continue
		} else {
			t.Logf("expected failure: %v for RR name %s, class %d, type %d, rrsig labels %d", err, rr.Header().Name, rr.Header().Class, rr.Header().Rrtype, CountLabel(rr.Header().Name))
		}
	}

	// The RRSIG RR's Signer's Name field MUST be the name of the zone that contains the RRset.
	// The RRSIG RR's Signer's Name, Algorithm, and Key Tag fields MUST match the owner name,
	// algorithm, and key tag for some DNSKEY RR in the zone's apex DNSKEY RRset.
	sigMismatchName := sig.copy().(*RRSIG)
	sigMismatchName.SignerName = "example.com."
	soaMismatchName := getSoa()
	soaMismatchName.Hdr.Name = "example.com."
	keyMismatchName := key.copy().(*DNSKEY)
	keyMismatchName.Hdr.Name = "example.com."
	if err := sigMismatchName.signAsIs(privkey.(*rsa.PrivateKey), []RR{soaMismatchName}); err != nil {
		t.Error("failure to sign the record:", err)
	} else if err := sigMismatchName.Verify(keyMismatchName, []RR{soaMismatchName}); err == nil {
		t.Error("should not validate: ", soaMismatchName, ", RRSIG's signer's name does not match the owner name")
	} else {
		t.Logf("expected failure: %v for signer %s and owner %s", err, sigMismatchName.SignerName, sigMismatchName.Hdr.Name)
	}

	sigMismatchAlgo := sig.copy().(*RRSIG)
	sigMismatchAlgo.Algorithm = RSASHA1
	sigMismatchKeyTag := sig.copy().(*RRSIG)
	sigMismatchKeyTag.KeyTag = 12345
	for _, sigMismatch := range []*RRSIG{sigMismatchAlgo, sigMismatchKeyTag} {
		if err := sigMismatch.Sign(privkey.(*rsa.PrivateKey), []RR{normalSoa}); err != nil {
			t.Error("failure to sign the record:", err)
		} else if err := sigMismatch.Verify(key, []RR{normalSoa}); err == nil {
			t.Error("should not validate: ", normalSoa)
		} else {
			t.Logf("expected failure: %v for signer %s algo %d keytag %d", err, sigMismatch.SignerName, sigMismatch.Algorithm, sigMismatch.KeyTag)
		}
	}

	// The matching DNSKEY RR MUST have the Zone Flag bit (DNSKEY RDATA Flag bit 7) set.
	keyZoneBitWrong := key.copy().(*DNSKEY)
	keyZoneBitWrong.Flags = key.Flags &^ ZONE
	if err := sig.Sign(privkey.(*rsa.PrivateKey), []RR{normalSoa}); err != nil {
		t.Error("failure to sign the record:", err)
	} else if err := sig.Verify(keyZoneBitWrong, []RR{normalSoa}); err == nil {
		t.Error("should not validate: ", normalSoa)
	} else {
		t.Logf("expected failure: %v for key flags %d", err, keyZoneBitWrong.Flags)
	}
}

func Test65534(t *testing.T) {
	t6 := new(RFC3597)
	t6.Hdr = RR_Header{"miek.nl.", 65534, ClassINET, 14400, 0}
	t6.Rdata = "505D870001"
	key := new(DNSKEY)
	key.Hdr.Name = "miek.nl."
	key.Hdr.Rrtype = TypeDNSKEY
	key.Hdr.Class = ClassINET
	key.Hdr.Ttl = 14400
	key.Flags = 256
	key.Protocol = 3
	key.Algorithm = RSASHA256
	privkey, err := key.Generate(1024)
	if err != nil {
		t.Fatal("failure to generate private key:", err)
	}

	sig := new(RRSIG)
	sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
	sig.TypeCovered = t6.Hdr.Rrtype
	sig.Labels = uint8(CountLabel(t6.Hdr.Name))
	sig.OrigTtl = t6.Hdr.Ttl
	sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
	sig.Inception = 1293942305  // date -u '+%s' -d"2011-01-02 04:25:05"
	sig.KeyTag = key.KeyTag()
	sig.SignerName = key.Hdr.Name
	sig.Algorithm = RSASHA256
	if err := sig.Sign(privkey.(*rsa.PrivateKey), []RR{t6}); err != nil {
		t.Error(err)
		t.Error("failure to sign the TYPE65534 record")
	}
	if err := sig.Verify(key, []RR{t6}); err != nil {
		t.Error(err)
		t.Errorf("failure to validate %s", t6.Header().Name)
	}
}

func TestDnskey(t *testing.T) {
	pubkey, err := ReadRR(strings.NewReader(`
miek.nl.	IN	DNSKEY	256 3 10 AwEAAZuMCu2FdugHkTrXYgl5qixvcDw1aDDlvL46/xJKbHBAHY16fNUb2b65cwko2Js/aJxUYJbZk5dwCDZxYfrfbZVtDPQuc3o8QaChVxC7/JYz2AHc9qHvqQ1j4VrH71RWINlQo6VYjzN/BGpMhOZoZOEwzp1HfsOE3lNYcoWU1smL ;{id = 5240 (zsk), size = 1024b}
`), "Kmiek.nl.+010+05240.key")
	if err != nil {
		t.Fatal(err)
	}
	privStr := `Private-key-format: v1.3
Algorithm: 10 (RSASHA512)
Modulus: m4wK7YV26AeROtdiCXmqLG9wPDVoMOW8vjr/EkpscEAdjXp81RvZvrlzCSjYmz9onFRgltmTl3AINnFh+t9tlW0M9C5zejxBoKFXELv8ljPYAdz2oe+pDWPhWsfvVFYg2VCjpViPM38EakyE5mhk4TDOnUd+w4TeU1hyhZTWyYs=
PublicExponent: AQAB
PrivateExponent: UfCoIQ/Z38l8vB6SSqOI/feGjHEl/fxIPX4euKf0D/32k30fHbSaNFrFOuIFmWMB3LimWVEs6u3dpbB9CQeCVg7hwU5puG7OtuiZJgDAhNeOnxvo5btp4XzPZrJSxR4WNQnwIiYWbl0aFlL1VGgHC/3By89ENZyWaZcMLW4KGWE=
Prime1: yxwC6ogAu8aVcDx2wg1V0b5M5P6jP8qkRFVMxWNTw60Vkn+ECvw6YAZZBHZPaMyRYZLzPgUlyYRd0cjupy4+fQ==
Prime2: xA1bF8M0RTIQ6+A11AoVG6GIR/aPGg5sogRkIZ7ID/sF6g9HMVU/CM2TqVEBJLRPp73cv6ZeC3bcqOCqZhz+pw==
Exponent1: xzkblyZ96bGYxTVZm2/vHMOXswod4KWIyMoOepK6B/ZPcZoIT6omLCgtypWtwHLfqyCz3MK51Nc0G2EGzg8rFQ==
Exponent2: Pu5+mCEb7T5F+kFNZhQadHUklt0JUHbi3hsEvVoHpEGSw3BGDQrtIflDde0/rbWHgDPM4WQY+hscd8UuTXrvLw==
Coefficient: UuRoNqe7YHnKmQzE6iDWKTMIWTuoqqrFAmXPmKQnC+Y+BQzOVEHUo9bXdDnoI9hzXP1gf8zENMYwYLeWpuYlFQ==
`
	privkey, err := pubkey.(*DNSKEY).ReadPrivateKey(strings.NewReader(privStr),
		"Kmiek.nl.+010+05240.private")
	if err != nil {
		t.Fatal(err)
	}
	if pubkey.(*DNSKEY).PublicKey != "AwEAAZuMCu2FdugHkTrXYgl5qixvcDw1aDDlvL46/xJKbHBAHY16fNUb2b65cwko2Js/aJxUYJbZk5dwCDZxYfrfbZVtDPQuc3o8QaChVxC7/JYz2AHc9qHvqQ1j4VrH71RWINlQo6VYjzN/BGpMhOZoZOEwzp1HfsOE3lNYcoWU1smL" {
		t.Error("pubkey is not what we've read")
	}
	if pubkey.(*DNSKEY).PrivateKeyString(privkey) != privStr {
		t.Error("privkey is not what we've read")
		t.Errorf("%v", pubkey.(*DNSKEY).PrivateKeyString(privkey))
	}
}

func TestTag(t *testing.T) {
	key := new(DNSKEY)
	key.Hdr.Name = "miek.nl."
	key.Hdr.Rrtype = TypeDNSKEY
	key.Hdr.Class = ClassINET
	key.Hdr.Ttl = 3600
	key.Flags = 256
	key.Protocol = 3
	key.Algorithm = RSASHA256
	key.PublicKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz"

	tag := key.KeyTag()
	if tag != 12051 {
		t.Errorf("wrong key tag: %d for key %v", tag, key)
	}
}

func TestKeyRSA(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}
	key := new(DNSKEY)
	key.Hdr.Name = "miek.nl."
	key.Hdr.Rrtype = TypeDNSKEY
	key.Hdr.Class = ClassINET
	key.Hdr.Ttl = 3600
	key.Flags = 256
	key.Protocol = 3
	key.Algorithm = RSASHA256
	priv, err := key.Generate(1024)
	if err != nil {
		t.Fatal("failure to generate private key:", err)
	}

	soa := new(SOA)
	soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0}
	soa.Ns = "open.nlnetlabs.nl."
	soa.Mbox = "miekg.atoom.net."
	soa.Serial = 1293945905
	soa.Refresh = 14400
	soa.Retry = 3600
	soa.Expire = 604800
	soa.Minttl = 86400

	sig := new(RRSIG)
	sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
	sig.TypeCovered = TypeSOA
	sig.Algorithm = RSASHA256
	sig.Labels = 2
	sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
	sig.Inception = 1293942305  // date -u '+%s' -d"2011-01-02 04:25:05"
	sig.OrigTtl = soa.Hdr.Ttl
	sig.KeyTag = key.KeyTag()
	sig.SignerName = key.Hdr.Name

	if err := sig.Sign(priv.(*rsa.PrivateKey), []RR{soa}); err != nil {
		t.Error("failed to sign")
		return
	}
	if err := sig.Verify(key, []RR{soa}); err != nil {
		t.Error("failed to verify")
	}
}

func TestKeyToDS(t *testing.T) {
	key := new(DNSKEY)
	key.Hdr.Name = "miek.nl."
	key.Hdr.Rrtype = TypeDNSKEY
	key.Hdr.Class = ClassINET
	key.Hdr.Ttl = 3600
	key.Flags = 256
	key.Protocol = 3
	key.Algorithm = RSASHA256
	key.PublicKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz"

	ds := key.ToDS(SHA1)
	if strings.ToUpper(ds.Digest) != "B5121BDB5B8D86D0CC5FFAFBAAABE26C3E20BAC1" {
		t.Errorf("wrong DS digest for SHA1\n%v", ds)
	}
}

func TestSignRSA(t *testing.T) {
	pub := "miek.nl. IN DNSKEY 256 3 5 AwEAAb+8lGNCxJgLS8rYVer6EnHVuIkQDghdjdtewDzU3G5R7PbMbKVRvH2Ma7pQyYceoaqWZQirSj72euPWfPxQnMy9ucCylA+FuH9cSjIcPf4PqJfdupHk9X6EBYjxrCLY4p1/yBwgyBIRJtZtAqM3ceAH2WovEJD6rTtOuHo5AluJ"

	priv := `Private-key-format: v1.3
Algorithm: 5 (RSASHA1)
Modulus: v7yUY0LEmAtLythV6voScdW4iRAOCF2N217APNTcblHs9sxspVG8fYxrulDJhx6hqpZlCKtKPvZ649Z8/FCczL25wLKUD4W4f1xKMhw9/g+ol926keT1foQFiPGsItjinX/IHCDIEhEm1m0Cozdx4AfZai8QkPqtO064ejkCW4k=
PublicExponent: AQAB
PrivateExponent: YPwEmwjk5HuiROKU4xzHQ6l1hG8Iiha4cKRG3P5W2b66/EN/GUh07ZSf0UiYB67o257jUDVEgwCuPJz776zfApcCB4oGV+YDyEu7Hp/rL8KcSN0la0k2r9scKwxTp4BTJT23zyBFXsV/1wRDK1A5NxsHPDMYi2SoK63Enm/1ptk=
Prime1: /wjOG+fD0ybNoSRn7nQ79udGeR1b0YhUA5mNjDx/x2fxtIXzygYk0Rhx9QFfDy6LOBvz92gbNQlzCLz3DJt5hw==
Prime2: wHZsJ8OGhkp5p3mrJFZXMDc2mbYusDVTA+t+iRPdS797Tj0pjvU2HN4vTnTj8KBQp6hmnY7dLp9Y1qserySGbw==
Exponent1: N0A7FsSRIg+IAN8YPQqlawoTtG1t1OkJ+nWrurPootScApX6iMvn8fyvw3p2k51rv84efnzpWAYiC8SUaQDNxQ==
Exponent2: SvuYRaGyvo0zemE3oS+WRm2scxR8eiA8WJGeOc+obwOKCcBgeZblXzfdHGcEC1KaOcetOwNW/vwMA46lpLzJNw==
Coefficient: 8+7ZN/JgByqv0NfULiFKTjtyegUcijRuyij7yNxYbCBneDvZGxJwKNi4YYXWx743pcAj4Oi4Oh86gcmxLs+hGw==
Created: 20110302104537
Publish: 20110302104537
Activate: 20110302104537`

	xk := testRR(pub)
	k := xk.(*DNSKEY)
	p, err := k.NewPrivateKey(priv)
	if err != nil {
		t.Error(err)
	}
	switch priv := p.(type) {
	case *rsa.PrivateKey:
		if priv.PublicKey.E != 65537 {
			t.Error("exponenent should be 65537")
		}
	default:
		t.Errorf("we should have read an RSA key: %v", priv)
	}
	if k.KeyTag() != 37350 {
		t.Errorf("keytag should be 37350, got %d %v", k.KeyTag(), k)
	}

	soa := new(SOA)
	soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0}
	soa.Ns = "open.nlnetlabs.nl."
	soa.Mbox = "miekg.atoom.net."
	soa.Serial = 1293945905
	soa.Refresh = 14400
	soa.Retry = 3600
	soa.Expire = 604800
	soa.Minttl = 86400

	sig := new(RRSIG)
	sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
	sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
	sig.Inception = 1293942305  // date -u '+%s' -d"2011-01-02 04:25:05"
	sig.KeyTag = k.KeyTag()
	sig.SignerName = k.Hdr.Name
	sig.Algorithm = k.Algorithm

	sig.Sign(p.(*rsa.PrivateKey), []RR{soa})
	if sig.Signature != "D5zsobpQcmMmYsUMLxCVEtgAdCvTu8V/IEeP4EyLBjqPJmjt96bwM9kqihsccofA5LIJ7DN91qkCORjWSTwNhzCv7bMyr2o5vBZElrlpnRzlvsFIoAZCD9xg6ZY7ZyzUJmU6IcTwG4v3xEYajcpbJJiyaw/RqR90MuRdKPiBzSo=" {
		t.Errorf("signature is not correct: %v", sig)
	}
}

func TestSignVerifyECDSA(t *testing.T) {
	pub := `example.net. 3600 IN DNSKEY 257 3 14 (
	xKYaNhWdGOfJ+nPrL8/arkwf2EY3MDJ+SErKivBVSum1
	w/egsXvSADtNJhyem5RCOpgQ6K8X1DRSEkrbYQ+OB+v8
	/uX45NBwY8rp65F6Glur8I/mlVNgF6W/qTI37m40 )`
	priv := `Private-key-format: v1.2
Algorithm: 14 (ECDSAP384SHA384)
PrivateKey: WURgWHCcYIYUPWgeLmiPY2DJJk02vgrmTfitxgqcL4vwW7BOrbawVmVe0d9V94SR`

	eckey := testRR(pub)
	privkey, err := eckey.(*DNSKEY).NewPrivateKey(priv)
	if err != nil {
		t.Fatal(err)
	}
	// TODO: Create separate test for this
	ds := eckey.(*DNSKEY).ToDS(SHA384)
	if ds.KeyTag != 10771 {
		t.Fatal("wrong keytag on DS")
	}
	if ds.Digest != "72d7b62976ce06438e9c0bf319013cf801f09ecc84b8d7e9495f27e305c6a9b0563a9b5f4d288405c3008a946df983d6" {
		t.Fatal("wrong DS Digest")
	}
	a := testRR("www.example.net. 3600 IN A 192.0.2.1")
	sig := new(RRSIG)
	sig.Hdr = RR_Header{"example.net.", TypeRRSIG, ClassINET, 14400, 0}
	sig.Expiration, _ = StringToTime("20100909102025")
	sig.Inception, _ = StringToTime("20100812102025")
	sig.KeyTag = eckey.(*DNSKEY).KeyTag()
	sig.SignerName = eckey.(*DNSKEY).Hdr.Name
	sig.Algorithm = eckey.(*DNSKEY).Algorithm

	if sig.Sign(privkey.(*ecdsa.PrivateKey), []RR{a}) != nil {
		t.Fatal("failure to sign the record")
	}

	if err := sig.Verify(eckey.(*DNSKEY), []RR{a}); err != nil {
		t.Fatalf("failure to validate:\n%s\n%s\n%s\n\n%s\n\n%v",
			eckey.(*DNSKEY).String(),
			a.String(),
			sig.String(),
			eckey.(*DNSKEY).PrivateKeyString(privkey),
			err,
		)
	}
}

func TestSignVerifyECDSA2(t *testing.T) {
	srv1 := testRR("srv.miek.nl. IN SRV 1000 800 0 web1.miek.nl.")
	srv := srv1.(*SRV)

	// With this key
	key := new(DNSKEY)
	key.Hdr.Rrtype = TypeDNSKEY
	key.Hdr.Name = "miek.nl."
	key.Hdr.Class = ClassINET
	key.Hdr.Ttl = 14400
	key.Flags = 256
	key.Protocol = 3
	key.Algorithm = ECDSAP256SHA256
	privkey, err := key.Generate(256)
	if err != nil {
		t.Fatal("failure to generate key")
	}

	// Fill in the values of the Sig, before signing
	sig := new(RRSIG)
	sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
	sig.TypeCovered = srv.Hdr.Rrtype
	sig.Labels = uint8(CountLabel(srv.Hdr.Name)) // works for all 3
	sig.OrigTtl = srv.Hdr.Ttl
	sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
	sig.Inception = 1293942305  // date -u '+%s' -d"2011-01-02 04:25:05"
	sig.KeyTag = key.KeyTag()   // Get the keyfrom the Key
	sig.SignerName = key.Hdr.Name
	sig.Algorithm = ECDSAP256SHA256

	if sig.Sign(privkey.(*ecdsa.PrivateKey), []RR{srv}) != nil {
		t.Fatal("failure to sign the record")
	}

	err = sig.Verify(key, []RR{srv})
	if err != nil {
		t.Errorf("failure to validate:\n%s\n%s\n%s\n\n%s\n\n%v",
			key.String(),
			srv.String(),
			sig.String(),
			key.PrivateKeyString(privkey),
			err,
		)
	}
}

func TestSignVerifyEd25519(t *testing.T) {
	srv1, err := NewRR("srv.miek.nl. IN SRV 1000 800 0 web1.miek.nl.")
	if err != nil {
		t.Fatal(err)
	}
	srv := srv1.(*SRV)

	// With this key
	key := new(DNSKEY)
	key.Hdr.Rrtype = TypeDNSKEY
	key.Hdr.Name = "miek.nl."
	key.Hdr.Class = ClassINET
	key.Hdr.Ttl = 14400
	key.Flags = 256
	key.Protocol = 3
	key.Algorithm = ED25519
	privkey, err := key.Generate(256)
	if err != nil {
		t.Fatal("failure to generate key")
	}

	// Fill in the values of the Sig, before signing
	sig := new(RRSIG)
	sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
	sig.TypeCovered = srv.Hdr.Rrtype
	sig.Labels = uint8(CountLabel(srv.Hdr.Name)) // works for all 3
	sig.OrigTtl = srv.Hdr.Ttl
	sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
	sig.Inception = 1293942305  // date -u '+%s' -d"2011-01-02 04:25:05"
	sig.KeyTag = key.KeyTag()   // Get the keyfrom the Key
	sig.SignerName = key.Hdr.Name
	sig.Algorithm = ED25519

	if sig.Sign(privkey.(ed25519.PrivateKey), []RR{srv}) != nil {
		t.Fatal("failure to sign the record")
	}

	err = sig.Verify(key, []RR{srv})
	if err != nil {
		t.Logf("failure to validate:\n%s\n%s\n%s\n\n%s\n\n%v",
			key.String(),
			srv.String(),
			sig.String(),
			key.PrivateKeyString(privkey),
			err,
		)
	}
}

// Here the test vectors from the relevant RFCs are checked.
// rfc6605 6.1
func TestRFC6605P256(t *testing.T) {
	exDNSKEY := `example.net. 3600 IN DNSKEY 257 3 13 (
                 GojIhhXUN/u4v54ZQqGSnyhWJwaubCvTmeexv7bR6edb
                 krSqQpF64cYbcB7wNcP+e+MAnLr+Wi9xMWyQLc8NAA== )`
	exPriv := `Private-key-format: v1.2
Algorithm: 13 (ECDSAP256SHA256)
PrivateKey: GU6SnQ/Ou+xC5RumuIUIuJZteXT2z0O/ok1s38Et6mQ=`
	rrDNSKEY := testRR(exDNSKEY)
	priv, err := rrDNSKEY.(*DNSKEY).NewPrivateKey(exPriv)
	if err != nil {
		t.Fatal(err)
	}

	exDS := `example.net. 3600 IN DS 55648 13 2 (
             b4c8c1fe2e7477127b27115656ad6256f424625bf5c1
             e2770ce6d6e37df61d17 )`
	rrDS := testRR(exDS)
	ourDS := rrDNSKEY.(*DNSKEY).ToDS(SHA256)
	if !reflect.DeepEqual(ourDS, rrDS.(*DS)) {
		t.Errorf("DS record differs:\n%v\n%v", ourDS, rrDS.(*DS))
	}

	exA := `www.example.net. 3600 IN A 192.0.2.1`
	exRRSIG := `www.example.net. 3600 IN RRSIG A 13 3 3600 (
                20100909100439 20100812100439 55648 example.net.
                qx6wLYqmh+l9oCKTN6qIc+bw6ya+KJ8oMz0YP107epXA
                yGmt+3SNruPFKG7tZoLBLlUzGGus7ZwmwWep666VCw== )`
	rrA := testRR(exA)
	rrRRSIG := testRR(exRRSIG)
	if err := rrRRSIG.(*RRSIG).Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil {
		t.Errorf("failure to validate the spec RRSIG: %v", err)
	}

	ourRRSIG := &RRSIG{
		Hdr: RR_Header{
			Ttl: rrA.Header().Ttl,
		},
		KeyTag:     rrDNSKEY.(*DNSKEY).KeyTag(),
		SignerName: rrDNSKEY.(*DNSKEY).Hdr.Name,
		Algorithm:  rrDNSKEY.(*DNSKEY).Algorithm,
	}
	ourRRSIG.Expiration, _ = StringToTime("20100909100439")
	ourRRSIG.Inception, _ = StringToTime("20100812100439")
	err = ourRRSIG.Sign(priv.(*ecdsa.PrivateKey), []RR{rrA})
	if err != nil {
		t.Fatal(err)
	}

	if err = ourRRSIG.Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil {
		t.Errorf("failure to validate our RRSIG: %v", err)
	}

	// Signatures are randomized
	rrRRSIG.(*RRSIG).Signature = ""
	ourRRSIG.Signature = ""
	if !reflect.DeepEqual(ourRRSIG, rrRRSIG.(*RRSIG)) {
		t.Fatalf("RRSIG record differs:\n%v\n%v", ourRRSIG, rrRRSIG.(*RRSIG))
	}
}

// rfc6605 6.2
func TestRFC6605P384(t *testing.T) {
	exDNSKEY := `example.net. 3600 IN DNSKEY 257 3 14 (
                 xKYaNhWdGOfJ+nPrL8/arkwf2EY3MDJ+SErKivBVSum1
                 w/egsXvSADtNJhyem5RCOpgQ6K8X1DRSEkrbYQ+OB+v8
                 /uX45NBwY8rp65F6Glur8I/mlVNgF6W/qTI37m40 )`
	exPriv := `Private-key-format: v1.2
Algorithm: 14 (ECDSAP384SHA384)
PrivateKey: WURgWHCcYIYUPWgeLmiPY2DJJk02vgrmTfitxgqcL4vwW7BOrbawVmVe0d9V94SR`
	rrDNSKEY := testRR(exDNSKEY)
	priv, err := rrDNSKEY.(*DNSKEY).NewPrivateKey(exPriv)
	if err != nil {
		t.Fatal(err)
	}

	exDS := `example.net. 3600 IN DS 10771 14 4 (
           72d7b62976ce06438e9c0bf319013cf801f09ecc84b8
           d7e9495f27e305c6a9b0563a9b5f4d288405c3008a94
           6df983d6 )`
	rrDS := testRR(exDS)
	ourDS := rrDNSKEY.(*DNSKEY).ToDS(SHA384)
	if !reflect.DeepEqual(ourDS, rrDS.(*DS)) {
		t.Fatalf("DS record differs:\n%v\n%v", ourDS, rrDS.(*DS))
	}

	exA := `www.example.net. 3600 IN A 192.0.2.1`
	exRRSIG := `www.example.net. 3600 IN RRSIG A 14 3 3600 (
           20100909102025 20100812102025 10771 example.net.
           /L5hDKIvGDyI1fcARX3z65qrmPsVz73QD1Mr5CEqOiLP
           95hxQouuroGCeZOvzFaxsT8Glr74hbavRKayJNuydCuz
           WTSSPdz7wnqXL5bdcJzusdnI0RSMROxxwGipWcJm )`
	rrA := testRR(exA)
	rrRRSIG := testRR(exRRSIG)
	if err != nil {
		t.Fatal(err)
	}
	if err = rrRRSIG.(*RRSIG).Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil {
		t.Errorf("failure to validate the spec RRSIG: %v", err)
	}

	ourRRSIG := &RRSIG{
		Hdr: RR_Header{
			Ttl: rrA.Header().Ttl,
		},
		KeyTag:     rrDNSKEY.(*DNSKEY).KeyTag(),
		SignerName: rrDNSKEY.(*DNSKEY).Hdr.Name,
		Algorithm:  rrDNSKEY.(*DNSKEY).Algorithm,
	}
	ourRRSIG.Expiration, _ = StringToTime("20100909102025")
	ourRRSIG.Inception, _ = StringToTime("20100812102025")
	err = ourRRSIG.Sign(priv.(*ecdsa.PrivateKey), []RR{rrA})
	if err != nil {
		t.Fatal(err)
	}

	if err = ourRRSIG.Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil {
		t.Errorf("failure to validate our RRSIG: %v", err)
	}

	// Signatures are randomized
	rrRRSIG.(*RRSIG).Signature = ""
	ourRRSIG.Signature = ""
	if !reflect.DeepEqual(ourRRSIG, rrRRSIG.(*RRSIG)) {
		t.Fatalf("RRSIG record differs:\n%v\n%v", ourRRSIG, rrRRSIG.(*RRSIG))
	}
}

// rfc8080 6.1
func TestRFC8080Ed25519Example1(t *testing.T) {
	exDNSKEY := `example.com. 3600 IN DNSKEY 257 3 15 (
             l02Woi0iS8Aa25FQkUd9RMzZHJpBoRQwAQEX1SxZJA4= )`
	exPriv := `Private-key-format: v1.2
Algorithm: 15 (ED25519)
PrivateKey: ODIyNjAzODQ2MjgwODAxMjI2NDUxOTAyMDQxNDIyNjI=`
	rrDNSKEY, err := NewRR(exDNSKEY)
	if err != nil {
		t.Fatal(err)
	}
	priv, err := rrDNSKEY.(*DNSKEY).NewPrivateKey(exPriv)
	if err != nil {
		t.Fatal(err)
	}

	exDS := `example.com. 3600 IN DS 3613 15 2 (
             3aa5ab37efce57f737fc1627013fee07bdf241bd10f3b1964ab55c78e79
             a304b )`
	rrDS, err := NewRR(exDS)
	if err != nil {
		t.Fatal(err)
	}
	ourDS := rrDNSKEY.(*DNSKEY).ToDS(SHA256)
	if !reflect.DeepEqual(ourDS, rrDS.(*DS)) {
		t.Fatalf("DS record differs:\n%v\n%v", ourDS, rrDS.(*DS))
	}

	exMX := `example.com. 3600 IN MX 10 mail.example.com.`
	exRRSIG := `example.com. 3600 IN RRSIG MX 15 2 3600 (
             1440021600 1438207200 3613 example.com. (
             oL9krJun7xfBOIWcGHi7mag5/hdZrKWw15jPGrHpjQeRAvTdszaPD+QLs3f
             x8A4M3e23mRZ9VrbpMngwcrqNAg== ) )`
	rrMX, err := NewRR(exMX)
	if err != nil {
		t.Fatal(err)
	}
	rrRRSIG, err := NewRR(exRRSIG)
	if err != nil {
		t.Fatal(err)
	}
	if err = rrRRSIG.(*RRSIG).Verify(rrDNSKEY.(*DNSKEY), []RR{rrMX}); err != nil {
		t.Errorf("failure to validate the spec RRSIG: %v", err)
	}

	ourRRSIG := &RRSIG{
		Hdr: RR_Header{
			Ttl: rrMX.Header().Ttl,
		},
		KeyTag:     rrDNSKEY.(*DNSKEY).KeyTag(),
		SignerName: rrDNSKEY.(*DNSKEY).Hdr.Name,
		Algorithm:  rrDNSKEY.(*DNSKEY).Algorithm,
	}
	ourRRSIG.Expiration, _ = StringToTime("20150819220000")
	ourRRSIG.Inception, _ = StringToTime("20150729220000")
	err = ourRRSIG.Sign(priv.(ed25519.PrivateKey), []RR{rrMX})
	if err != nil {
		t.Fatal(err)
	}

	if err = ourRRSIG.Verify(rrDNSKEY.(*DNSKEY), []RR{rrMX}); err != nil {
		t.Errorf("failure to validate our RRSIG: %v", err)
	}

	if !reflect.DeepEqual(ourRRSIG, rrRRSIG.(*RRSIG)) {
		t.Fatalf("RRSIG record differs:\n%v\n%v", ourRRSIG, rrRRSIG.(*RRSIG))
	}
}

// rfc8080 6.1
func TestRFC8080Ed25519Example2(t *testing.T) {
	exDNSKEY := `example.com. 3600 IN DNSKEY 257 3 15 (
             zPnZ/QwEe7S8C5SPz2OfS5RR40ATk2/rYnE9xHIEijs= )`
	exPriv := `Private-key-format: v1.2
Algorithm: 15 (ED25519)
PrivateKey: DSSF3o0s0f+ElWzj9E/Osxw8hLpk55chkmx0LYN5WiY=`
	rrDNSKEY, err := NewRR(exDNSKEY)
	if err != nil {
		t.Fatal(err)
	}
	priv, err := rrDNSKEY.(*DNSKEY).NewPrivateKey(exPriv)
	if err != nil {
		t.Fatal(err)
	}

	exDS := `example.com. 3600 IN DS 35217 15 2 (
             401781b934e392de492ec77ae2e15d70f6575a1c0bc59c5275c04ebe80c
             6614c )`
	rrDS, err := NewRR(exDS)
	if err != nil {
		t.Fatal(err)
	}
	ourDS := rrDNSKEY.(*DNSKEY).ToDS(SHA256)
	if !reflect.DeepEqual(ourDS, rrDS.(*DS)) {
		t.Fatalf("DS record differs:\n%v\n%v", ourDS, rrDS.(*DS))
	}

	exMX := `example.com. 3600 IN MX 10 mail.example.com.`
	exRRSIG := `example.com. 3600 IN RRSIG MX 15 2 3600 (
             1440021600 1438207200 35217 example.com. (
             zXQ0bkYgQTEFyfLyi9QoiY6D8ZdYo4wyUhVioYZXFdT410QPRITQSqJSnzQ
             oSm5poJ7gD7AQR0O7KuI5k2pcBg== ) )`
	rrMX, err := NewRR(exMX)
	if err != nil {
		t.Fatal(err)
	}
	rrRRSIG, err := NewRR(exRRSIG)
	if err != nil {
		t.Fatal(err)
	}
	if err = rrRRSIG.(*RRSIG).Verify(rrDNSKEY.(*DNSKEY), []RR{rrMX}); err != nil {
		t.Errorf("failure to validate the spec RRSIG: %v", err)
	}

	ourRRSIG := &RRSIG{
		Hdr: RR_Header{
			Ttl: rrMX.Header().Ttl,
		},
		KeyTag:     rrDNSKEY.(*DNSKEY).KeyTag(),
		SignerName: rrDNSKEY.(*DNSKEY).Hdr.Name,
		Algorithm:  rrDNSKEY.(*DNSKEY).Algorithm,
	}
	ourRRSIG.Expiration, _ = StringToTime("20150819220000")
	ourRRSIG.Inception, _ = StringToTime("20150729220000")
	err = ourRRSIG.Sign(priv.(ed25519.PrivateKey), []RR{rrMX})
	if err != nil {
		t.Fatal(err)
	}

	if err = ourRRSIG.Verify(rrDNSKEY.(*DNSKEY), []RR{rrMX}); err != nil {
		t.Errorf("failure to validate our RRSIG: %v", err)
	}

	if !reflect.DeepEqual(ourRRSIG, rrRRSIG.(*RRSIG)) {
		t.Fatalf("RRSIG record differs:\n%v\n%v", ourRRSIG, rrRRSIG.(*RRSIG))
	}
}

func TestInvalidRRSet(t *testing.T) {
	goodRecords := make([]RR, 2)
	goodRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}}
	goodRecords[1] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"_o/"}}

	// Generate key
	keyname := "cloudflare.com."
	key := &DNSKEY{
		Hdr:       RR_Header{Name: keyname, Rrtype: TypeDNSKEY, Class: ClassINET, Ttl: 0},
		Algorithm: ECDSAP256SHA256,
		Flags:     ZONE,
		Protocol:  3,
	}
	privatekey, err := key.Generate(256)
	if err != nil {
		t.Fatal(err.Error())
	}

	// Need to fill in: Inception, Expiration, KeyTag, SignerName and Algorithm
	curTime := time.Now()
	signature := &RRSIG{
		Inception:  uint32(curTime.Unix()),
		Expiration: uint32(curTime.Add(time.Hour).Unix()),
		KeyTag:     key.KeyTag(),
		SignerName: keyname,
		Algorithm:  ECDSAP256SHA256,
	}

	// Inconsistent name between records
	badRecords := make([]RR, 2)
	badRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}}
	badRecords[1] = &TXT{Hdr: RR_Header{Name: "nama.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"_o/"}}

	if IsRRset(badRecords) {
		t.Fatal("Record set with inconsistent names considered valid")
	}

	badRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}}
	badRecords[1] = &A{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeA, Class: ClassINET, Ttl: 0}}

	if IsRRset(badRecords) {
		t.Fatal("Record set with inconsistent record types considered valid")
	}

	badRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}}
	badRecords[1] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassCHAOS, Ttl: 0}, Txt: []string{"_o/"}}

	if IsRRset(badRecords) {
		t.Fatal("Record set with inconsistent record class considered valid")
	}

	// Sign the good record set and then make sure verification fails on the bad record set
	if err := signature.Sign(privatekey.(crypto.Signer), goodRecords); err != nil {
		t.Fatal("Signing good records failed")
	}

	if err := signature.Verify(key, badRecords); err != ErrRRset {
		t.Fatal("Verification did not return ErrRRset with inconsistent records")
	}
}

// Issue #688 - RSA exponent unpacked in reverse
func TestRsaExponentUnpack(t *testing.T) {
	zskRrDnskey, _ := NewRR("isc.org.                7200    IN      DNSKEY  256 3 5 AwEAAcdkaRUlsRD4gcF63PpPJJ1E6kOIb3yn/UHptVsPEQtEbgJ2y20O eix4unpwoQkz+bIAd2rrOU/95wgV530x0/qqKwBLWoGkxdcnNcvVT4hl 3SOTZy1VjwkAfyayHPU8VisXqJGbB3KWevBZlb6AtrXzFu8AHuBeeAAe /fOgreCh")
	kskRrDnskey, _ := NewRR("isc.org.                7200    IN      DNSKEY  257 3 5 BEAAAAOhHQDBrhQbtphgq2wQUpEQ5t4DtUHxoMVFu2hWLDMvoOMRXjGr hhCeFvAZih7yJHf8ZGfW6hd38hXG/xylYCO6Krpbdojwx8YMXLA5/kA+ u50WIL8ZR1R6KTbsYVMf/Qx5RiNbPClw+vT+U8eXEJmO20jIS1ULgqy3 47cBB1zMnnz/4LJpA0da9CbKj3A254T515sNIMcwsB8/2+2E63/zZrQz Bkj0BrN/9Bexjpiks3jRhZatEsXn3dTy47R09Uix5WcJt+xzqZ7+ysyL KOOedS39Z7SDmsn2eA0FKtQpwA6LXeG2w+jxmw3oA8lVUgEf/rzeC/bB yBNsO70aEFTd")
	kskRrRrsig, _ := NewRR("isc.org.                7200    IN      RRSIG   DNSKEY 5 2 7200 20180627230244 20180528230244 12892 isc.org. ebKBlhYi1hPGTdPg6zSwvprOIkoFMs+WIhMSjoYW6/K5CS9lDDFdK4cu TgXJRT3etrltTuJiFe2HRpp+7t5cKLy+CeJZVzqrCz200MoHiFuLI9yI DJQGaS5YYCiFbw5+jUGU6aUhZ7Y5/YufeqATkRZzdrKwgK+zri8LPw9T WLoVJPAOW7GR0dgxl9WKmO7Fzi9P8BZR3NuwLV7329X94j+4zyswaw7q e5vif0ybzFveODLsEi/E0a2rTXc4QzzyM0fSVxRkVQyQ7ifIPP4ohnnT d5qpPUbE8xxBzTdWR/TaKADC5aCFkppG9lVAq5CPfClii2949X5RYzy1 rxhuSA==")
	zskRrRrsig, _ := NewRR("isc.org.                7200    IN      RRSIG   DNSKEY 5 2 7200 20180627230244 20180528230244 19923 isc.org. RgCfzUeq4RJPGoe9RRB6cWf6d/Du+tHK5SxI5QL1waA3O5qVtQKFkY1C dq/yyVjwzfjD9F62TObujOaktv8X80ZMcNPmgHbvK1xOqelMBWv5hxj3 xRe+QQObLZ5NPfHFsphQKXvwgO5Sjk8py2B2iCr3BHCZ8S38oIfuSrQx sn8=")

	zsk, ksk := zskRrDnskey.(*DNSKEY), kskRrDnskey.(*DNSKEY)
	zskSig, kskSig := zskRrRrsig.(*RRSIG), kskRrRrsig.(*RRSIG)

	if e := zskSig.Verify(zsk, []RR{zsk, ksk}); e != nil {
		t.Fatalf("cannot verify RRSIG with keytag [%d]. Cause [%s]", zsk.KeyTag(), e.Error())
	}

	if e := kskSig.Verify(ksk, []RR{zsk, ksk}); e != nil {
		t.Fatalf("cannot verify RRSIG with keytag [%d]. Cause [%s]", ksk.KeyTag(), e.Error())
	}
}

func TestParseKeyReadError(t *testing.T) {
	m, err := parseKey(errReader{}, "")
	if err == nil || !strings.Contains(err.Error(), errTestReadError.Error()) {
		t.Errorf("expected error to contain %q, but got %v", errTestReadError, err)
	}
	if m != nil {
		t.Errorf("expected a nil map, but got %v", m)
	}
}

func TestRSAMD5KeyTag(t *testing.T) {
	rr1, _ := NewRR("test.  IN DNSKEY  257 3 1 AwEAAcntNdoMnY8pvyPcpDTAaiqHyAhf53XUBANq166won/fjBFvmuzhTuP5r4el/pV0tzEBL73zpoU48BqF66uiL+qRijXCySJiaBUvLNll5rpwuduAOoVpmwOmkC4fV6izHOAx/Uy8c+pYP0YR8+1P7GuTFxgnMmt9sUGtoe+la0X/ ;{id = 27461 (ksk), size = 1024b}")
	rr2, _ := NewRR("test.  IN DNSKEY  257 3 1 AwEAAf0bKO/m45ylk5BlSLmQHQRBLx1m/ZUXvyPFB387bJXxnTk6so3ub97L1RQ+8bOoiRh3Qm5EaYihjco7J8b/W5WbS3tVsE79nY584RfTKT2zcZ9AoFP2XLChXxPIf/6l0H9n6sH0aBjsG8vabEIp8e06INM3CXVPiMRPPeGNa0Ub ;{id = 27461 (ksk), size = 1024b}")

	exp := uint16(27461)
	if x := rr1.(*DNSKEY).KeyTag(); x != exp {
		t.Errorf("expected %d, got %d, as keytag for rr1", exp, x)
	}
	if x := rr2.(*DNSKEY).KeyTag(); x != exp { // yes, same key tag
		t.Errorf("expected %d, got %d, as keytag for rr2", exp, x)
	}
}


================================================
FILE: dnsutil/util.go
================================================
// Package dnsutil contains higher-level methods useful with the dns
// package.  While package dns implements the DNS protocols itself,
// these functions are related but not directly required for protocol
// processing.  They are often useful in preparing input/output of the
// functions in package dns.
package dnsutil

import (
	"strings"

	"github.com/miekg/dns"
)

// AddOrigin adds origin to s if s is not already a FQDN.
// Note that the result may not be a FQDN.  If origin does not end
// with a ".", the result won't either.
// This implements the zonefile convention (specified in RFC 1035,
// Section "5.1. Format") that "@" represents the
// apex (bare) domain. i.e. AddOrigin("@", "foo.com.") returns "foo.com.".
func AddOrigin(s, origin string) string {
	// ("foo.", "origin.") -> "foo." (already a FQDN)
	// ("foo", "origin.") -> "foo.origin."
	// ("foo", "origin") -> "foo.origin"
	// ("foo", ".") -> "foo." (Same as dns.Fqdn())
	// ("foo.", ".") -> "foo." (Same as dns.Fqdn())
	// ("@", "origin.") -> "origin." (@ represents the apex (bare) domain)
	// ("", "origin.") -> "origin." (not obvious)
	// ("foo", "") -> "foo" (not obvious)

	if dns.IsFqdn(s) {
		return s // s is already a FQDN, no need to mess with it.
	}
	if origin == "" {
		return s // Nothing to append.
	}
	if s == "@" || s == "" {
		return origin // Expand apex.
	}
	if origin == "." {
		return dns.Fqdn(s)
	}

	return s + "." + origin // The simple case.
}

// TrimDomainName trims origin from s if s is a subdomain.
// This function will never return "", but returns "@" instead (@ represents the apex domain).
func TrimDomainName(s, origin string) string {
	// An apex (bare) domain is always returned as "@".
	// If the return value ends in a ".", the domain was not the suffix.
	// origin can end in "." or not. Either way the results should be the same.

	if s == "" {
		return "@"
	}
	// Someone is using TrimDomainName(s, ".") to remove a dot if it exists.
	if origin == "." {
		return strings.TrimSuffix(s, origin)
	}

	original := s
	s = dns.Fqdn(s)
	origin = dns.Fqdn(origin)

	if !dns.IsSubDomain(origin, s) {
		return original
	}

	slabels := dns.Split(s)
	olabels := dns.Split(origin)
	m := dns.CompareDomainName(s, origin)
	if len(olabels) == m {
		if len(olabels) == len(slabels) {
			return "@" // origin == s
		}
		if (s[0] == '.') && (len(slabels) == (len(olabels) + 1)) {
			return "@" // TrimDomainName(".foo.", "foo.")
		}
	}

	// Return the first (len-m) labels:
	return s[:slabels[len(slabels)-m]-1]
}


================================================
FILE: dnsutil/util_test.go
================================================
package dnsutil

import "testing"

func TestAddOrigin(t *testing.T) {
	var tests = []struct{ e1, e2, expected string }{
		{"@", "example.com", "example.com"},
		{"foo", "example.com", "foo.example.com"},
		{"foo.", "example.com", "foo."},
		{"@", "example.com.", "example.com."},
		{"foo", "example.com.", "foo.example.com."},
		{"foo.", "example.com.", "foo."},
		{"example.com", ".", "example.com."},
		{"example.com.", ".", "example.com."},
		// Oddball tests:
		// In general origin should not be "" or "." but at least
		// these tests verify we don't crash and will keep results
		// from changing unexpectedly.
		{"*.", "", "*."},
		{"@", "", "@"},
		{"foobar", "", "foobar"},
		{"foobar.", "", "foobar."},
		{"*.", ".", "*."},
		{"@", ".", "."},
		{"foobar", ".", "foobar."},
		{"foobar.", ".", "foobar."},
	}
	for _, test := range tests {
		actual := AddOrigin(test.e1, test.e2)
		if test.expected != actual {
			t.Errorf("AddOrigin(%#v, %#v) expected %#v, got %#v\n", test.e1, test.e2, test.expected, actual)
		}
	}
}

func TestTrimDomainName(t *testing.T) {
	// Basic tests.
	// Try trimming "example.com" and "example.com." from typical use cases.
	testsEx := []struct{ experiment, expected string }{
		{"foo.example.com", "foo"},
		{"foo.example.com.", "foo"},
		{".foo.example.com", ".foo"},
		{".foo.example.com.", ".foo"},
		{"*.example.com", "*"},
		{"example.com", "@"},
		{"example.com.", "@"},
		{"com.", "com."},
		{"foo.", "foo."},
		{"serverfault.com.", "serverfault.com."},
		{"serverfault.com", "serverfault.com"},
		{".foo.ronco.com", ".foo.ronco.com"},
		{".foo.ronco.com.", ".foo.ronco.com."},
	}
	for _, dom := range []string{"example.com", "example.com."} {
		for i, test := range testsEx {
			actual := TrimDomainName(test.experiment, dom)
			if test.expected != actual {
				t.Errorf("%d TrimDomainName(%#v, %#v): expected %v, got %v\n", i, test.experiment, dom, test.expected, actual)
			}
		}
	}

	// Paranoid tests.
	// These test shouldn't be needed but I was weary of off-by-one errors.
	// In theory, these can't happen because there are no single-letter TLDs,
	// but it is good to exercise the code this way.
	tests := []struct{ experiment, expected string }{
		{"", "@"},
		{".", "."},
		{"a.b.c.d.e.f.", "a.b.c.d.e"},
		{"b.c.d.e.f.", "b.c.d.e"},
		{"c.d.e.f.", "c.d.e"},
		{"d.e.f.", "d.e"},
		{"e.f.", "e"},
		{"f.", "@"},
		{".a.b.c.d.e.f.", ".a.b.c.d.e"},
		{".b.c.d.e.f.", ".b.c.d.e"},
		{".c.d.e.f.", ".c.d.e"},
		{".d.e.f.", ".d.e"},
		{".e.f.", ".e"},
		{".f.", "@"},
		{"a.b.c.d.e.f", "a.b.c.d.e"},
		{"a.b.c.d.e.", "a.b.c.d.e."},
		{"a.b.c.d.e", "a.b.c.d.e"},
		{"a.b.c.d.", "a.b.c.d."},
		{"a.b.c.d", "a.b.c.d"},
		{"a.b.c.", "a.b.c."},
		{"a.b.c", "a.b.c"},
		{"a.b.", "a.b."},
		{"a.b", "a.b"},
		{"a.", "a."},
		{"a", "a"},
		{".a.b.c.d.e.f", ".a.b.c.d.e"},
		{".a.b.c.d.e.", ".a.b.c.d.e."},
		{".a.b.c.d.e", ".a.b.c.d.e"},
		{".a.b.c.d.", ".a.b.c.d."},
		{".a.b.c.d", ".a.b.c.d"},
		{".a.b.c.", ".a.b.c."},
		{".a.b.c", ".a.b.c"},
		{".a.b.", ".a.b."},
		{".a.b", ".a.b"},
		{".a.", ".a."},
		{".a", ".a"},
	}
	for _, dom := range []string{"f", "f."} {
		for i, test := range tests {
			actual := TrimDomainName(test.experiment, dom)
			if test.expected != actual {
				t.Errorf("%d TrimDomainName(%#v, %#v): expected %v, got %v\n", i, test.experiment, dom, test.expected, actual)
			}
		}
	}

	// Test cases for bugs found in the wild.
	// These test cases provide both origin, s, and the expected result.
	// If you find a bug in the while, this is probably the easiest place
	// to add it as a test case.
	var testsWild = []struct{ e1, e2, expected string }{
		{"mathoverflow.net.", ".", "mathoverflow.net"},
		{"mathoverflow.net", ".", "mathoverflow.net"},
		{"", ".", "@"},
		{"@", ".", "@"},
	}
	for i, test := range testsWild {
		actual := TrimDomainName(test.e1, test.e2)
		if test.expected != actual {
			t.Errorf("%d TrimDomainName(%#v, %#v): expected %v, got %v\n", i, test.e1, test.e2, test.expected, actual)
		}
	}
}


================================================
FILE: doc.go
================================================
/*
Package dns implements a full featured interface to the Domain Name System.
Both server- and client-side programming is supported. The package allows
complete control over what is sent out to the DNS. The API follows the
less-is-more principle, by presenting a small, clean interface.

It supports (asynchronous) querying/replying, incoming/outgoing zone transfers,
TSIG, EDNS0, dynamic updates, notifies and DNSSEC validation/signing.

Note that domain names MUST be fully qualified before sending them, unqualified
names in a message will result in a packing failure.

Resource records are native types. They are not stored in wire format. Basic
usage pattern for creating a new resource record:

	r := new(dns.MX)
	r.Hdr = dns.RR_Header{Name: "miek.nl.", Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: 3600}
	r.Preference = 10
	r.Mx = "mx.miek.nl."

Or directly from a string:

	mx, err := dns.NewRR("miek.nl. 3600 IN MX 10 mx.miek.nl.")

Or when the default origin (.) and TTL (3600) and class (IN) suit you:

	mx, err := dns.NewRR("miek.nl MX 10 mx.miek.nl")

Or even:

	mx, err := dns.NewRR("$ORIGIN nl.\nmiek 1H IN MX 10 mx.miek")

In the DNS messages are exchanged, these messages contain resource records
(sets). Use pattern for creating a message:

	m := new(dns.Msg)
	m.SetQuestion("miek.nl.", dns.TypeMX)

Or when not certain if the domain name is fully qualified:

	m.SetQuestion(dns.Fqdn("miek.nl"), dns.TypeMX)

The message m is now a message with the question section set to ask the MX
records for the miek.nl. zone.

The following is slightly more verbose, but more flexible:

	m1 := new(dns.Msg)
	m1.Id = dns.Id()
	m1.RecursionDesired = true
	m1.Question = make([]dns.Question, 1)
	m1.Question[0] = dns.Question{"miek.nl.", dns.TypeMX, dns.ClassINET}

After creating a message it can be sent. Basic use pattern for synchronous
querying the DNS at a server configured on 127.0.0.1 and port 53:

	c := new(dns.Client)
	in, rtt, err := c.Exchange(m1, "127.0.0.1:53")

Suppressing multiple outstanding queries (with the same question, type and
class) is as easy as setting:

	c.SingleInflight = true

More advanced options are available using a net.Dialer and the corresponding API.
For example it is possible to set a timeout, or to specify a source IP address
and port to use for the connection:

	c := new(dns.Client)
	laddr := net.UDPAddr{
		IP: net.ParseIP("[::1]"),
		Port: 12345,
		Zone: "",
	}
	c.Dialer = &net.Dialer{
		Timeout: 200 * time.Millisecond,
		LocalAddr: &laddr,
	}
	in, rtt, err := c.Exchange(m1, "8.8.8.8:53")

If these "advanced" features are not needed, a simple UDP query can be sent,
with:

	in, err := dns.Exchange(m1, "127.0.0.1:53")

When this functions returns you will get DNS message. A DNS message consists
out of four sections.
The question section: in.Question, the answer section: in.Answer,
the authority section: in.Ns and the additional section: in.Extra.

Each of these sections (except the Question section) contain a []RR. Basic
use pattern for accessing the rdata of a TXT RR as the first RR in
the Answer section:

	if t, ok := in.Answer[0].(*dns.TXT); ok {
		// do something with t.Txt
	}

# Domain Name and TXT Character String Representations

Both domain names and TXT character strings are converted to presentation form
both when unpacked and when converted to strings.

For TXT character strings, tabs, carriage returns and line feeds will be
converted to \t, \r and \n respectively. Back slashes and quotations marks will
be escaped. Bytes below 32 and above 127 will be converted to \DDD form.

For domain names, in addition to the above rules brackets, periods, spaces,
semicolons and the at symbol are escaped.

# DNSSEC

DNSSEC (DNS Security Extension) adds a layer of security to the DNS. It uses
public key cryptography to sign resource records. The public keys are stored in
DNSKEY records and the signatures in RRSIG records.

Requesting DNSSEC information for a zone is done by adding the DO (DNSSEC OK)
bit to a request.

	m := new(dns.Msg)
	m.SetEdns0(4096, true)

Signature generation, signature verification and key generation are all supported.

# DYNAMIC UPDATES

Dynamic updates reuses the DNS message format, but renames three of the
sections. Question is Zone, Answer is Prerequisite, Authority is Update, only
the Additional is not renamed. See RFC 2136 for the gory details.

You can set a rather complex set of rules for the existence of absence of
certain resource records or names in a zone to specify if resource records
should be added or removed. The table from RFC 2136 supplemented with the Go
DNS function shows which functions exist to specify the prerequisites.

	3.2.4 - Table Of Metavalues Used In Prerequisite Section

	 CLASS    TYPE     RDATA    Meaning                    Function
	 --------------------------------------------------------------
	 ANY      ANY      empty    Name is in use             dns.NameUsed
	 ANY      rrset    empty    RRset exists (value indep) dns.RRsetUsed
	 NONE     ANY      empty    Name is not in use         dns.NameNotUsed
	 NONE     rrset    empty    RRset does not exist       dns.RRsetNotUsed
	 zone     rrset    rr       RRset exists (value dep)   dns.Used

The prerequisite section can also be left empty. If you have decided on the
prerequisites you can tell what RRs should be added or deleted. The next table
shows the options you have and what functions to call.

	3.4.2.6 - Table Of Metavalues Used In Update Section

	 CLASS    TYPE     RDATA    Meaning                     Function
	 ---------------------------------------------------------------
	 ANY      ANY      empty    Delete all RRsets from name dns.RemoveName
	 ANY      rrset    empty    Delete an RRset             dns.RemoveRRset
	 NONE     rrset    rr       Delete an RR from RRset     dns.Remove
	 zone     rrset    rr       Add to an RRset             dns.Insert

# TRANSACTION SIGNATURE

An TSIG or transaction signature adds a HMAC TSIG record to each message sent.
The supported algorithms include: HmacSHA1, HmacSHA256 and HmacSHA512.

Basic use pattern when querying with a TSIG name "axfr." (note that these key names
must be fully qualified - as they are domain names) and the base64 secret
"so6ZGir4GPAqINNh9U5c3A==":

If an incoming message contains a TSIG record it MUST be the last record in
the additional section (RFC2845 3.2).  This means that you should make the
call to SetTsig last, right before executing the query.  If you make any
changes to the RRset after calling SetTsig() the signature will be incorrect.

	c := new(dns.Client)
	c.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
	m := new(dns.Msg)
	m.SetQuestion("miek.nl.", dns.TypeMX)
	m.SetTsig("axfr.", dns.HmacSHA256, 300, time.Now().Unix())
	...
	// When sending the TSIG RR is calculated and filled in before sending

When requesting an zone transfer (almost all TSIG usage is when requesting zone
transfers), with TSIG, this is the basic use pattern. In this example we
request an AXFR for miek.nl. with TSIG key named "axfr." and secret
"so6ZGir4GPAqINNh9U5c3A==" and using the server 176.58.119.54:

	t := new(dns.Transfer)
	m := new(dns.Msg)
	t.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
	m.SetAxfr("miek.nl.")
	m.SetTsig("axfr.", dns.HmacSHA256, 300, time.Now().Unix())
	c, err := t.In(m, "176.58.119.54:53")
	for r := range c { ... }

You can now read the records from the transfer as they come in. Each envelope
is checked with TSIG. If something is not correct an error is returned.

A custom TSIG implementation can be used. This requires additional code to
perform any session establishment and signature generation/verification. The
client must be configured with an implementation of the TsigProvider interface:

	type Provider struct{}

	func (*Provider) Generate(msg []byte, tsig *dns.TSIG) ([]byte, error) {
		// Use tsig.Hdr.Name and tsig.Algorithm in your code to
		// generate the MAC using msg as the payload.
	}

	func (*Provider) Verify(msg []byte, tsig *dns.TSIG) error {
		// Use tsig.Hdr.Name and tsig.Algorithm in your code to verify
		// that msg matches the value in tsig.MAC.
	}

	c := new(dns.Client)
	c.TsigProvider = new(Provider)
	m := new(dns.Msg)
	m.SetQuestion("miek.nl.", dns.TypeMX)
	m.SetTsig(keyname, dns.HmacSHA256, 300, time.Now().Unix())
	...
	// TSIG RR is calculated by calling your Generate method

Basic use pattern validating and replying to a message that has TSIG set.

	server := &dns.Server{Addr: ":53", Net: "udp"}
	server.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
	go server.ListenAndServe()
	dns.HandleFunc(".", handleRequest)

	func handleRequest(w dns.ResponseWriter, r *dns.Msg) {
		m := new(dns.Msg)
		m.SetReply(r)
		if r.IsTsig() != nil {
			if w.TsigStatus() == nil {
				// *Msg r has an TSIG record and it was validated
				m.SetTsig("axfr.", dns.HmacSHA256, 300, time.Now().Unix())
			} else {
				// *Msg r has an TSIG records and it was not validated
			}
		}
		w.WriteMsg(m)
	}

# PRIVATE RRS

RFC 6895 sets aside a range of type codes for private use. This range is 65,280
- 65,534 (0xFF00 - 0xFFFE). When experimenting with new Resource Records these
can be used, before requesting an official type code from IANA.

See https://miek.nl/2014/september/21/idn-and-private-rr-in-go-dns/ for more
information.

# EDNS0

EDNS0 is an extension mechanism for the DNS defined in RFC 2671 and updated by
RFC 6891. It defines a new RR type, the OPT RR, which is then completely
abused.

Basic use pattern for creating an (empty) OPT RR:

	o := new(dns.OPT)
	o.Hdr.Name = "." // MUST be the root zone, per definition.
	o.Hdr.Rrtype = dns.TypeOPT

The rdata of an OPT RR consists out of a slice of EDNS0 (RFC 6891) interfaces.
Currently only a few have been standardized: EDNS0_NSID (RFC 5001) and
EDNS0_SUBNET (RFC 7871). Note that these options may be combined in an OPT RR.
Basic use pattern for a server to check if (and which) options are set:

	// o is a dns.OPT
	for _, s := range o.Option {
		switch e := s.(type) {
		case *dns.EDNS0_NSID:
			// do stuff with e.Nsid
		case *dns.EDNS0_SUBNET:
			// access e.Family, e.Address, etc.
		}
	}

SIG(0)

From RFC 2931:

	SIG(0) provides protection for DNS transactions and requests ....
	... protection for glue records, DNS requests, protection for message headers
	on requests and responses, and protection of the overall integrity of a response.

It works like TSIG, except that SIG(0) uses public key cryptography, instead of
the shared secret approach in TSIG. Supported algorithms: ECDSAP256SHA256,
ECDSAP384SHA384, RSASHA1, RSASHA256 and RSASHA512.

Signing subsequent messages in multi-message sessions is not implemented.
*/
package dns


================================================
FILE: duplicate.go
================================================
package dns

//go:generate go run duplicate_generate.go

// IsDuplicate checks of r1 and r2 are duplicates of each other, excluding the TTL.
// So this means the header data is equal *and* the RDATA is the same. Returns true
// if so, otherwise false. It's a protocol violation to have identical RRs in a message.
func IsDuplicate(r1, r2 RR) bool {
	// Check whether the record header is identical.
	if !r1.Header().isDuplicate(r2.Header()) {
		return false
	}

	// Check whether the RDATA is identical.
	return r1.isDuplicate(r2)
}

func (r1 *RR_Header) isDuplicate(_r2 RR) bool {
	r2, ok := _r2.(*RR_Header)
	if !ok {
		return false
	}
	if r1.Class != r2.Class {
		return false
	}
	if r1.Rrtype != r2.Rrtype {
		return false
	}
	if !isDuplicateName(r1.Name, r2.Name) {
		return false
	}
	// ignore TTL
	return true
}

// isDuplicateName checks if the domain names s1 and s2 are equal.
func isDuplicateName(s1, s2 string) bool { return equal(s1, s2) }


================================================
FILE: duplicate_generate.go
================================================
//go:build ignore
// +build ignore

// types_generate.go is meant to run with go generate. It will use
// go/{importer,types} to track down all the RR struct types. Then for each type
// it will generate conversion tables (TypeToRR and TypeToString) and banal
// methods (len, Header, copy) based on the struct tags. The generated source is
// written to ztypes.go, and is meant to be checked into git.
package main

import (
	"bytes"
	"fmt"
	"go/format"
	"go/types"
	"log"
	"os"

	"golang.org/x/tools/go/packages"
)

var packageHdr = `
// Code generated by "go run duplicate_generate.go"; DO NOT EDIT.

package dns

`

func getTypeStruct(t types.Type, scope *types.Scope) (*types.Struct, bool) {
	st, ok := t.Underlying().(*types.Struct)
	if !ok {
		return nil, false
	}
	if st.NumFields() == 0 {
		return nil, false
	}
	if st.Field(0).Type() == scope.Lookup("RR_Header").Type() {
		return st, false
	}
	if st.Field(0).Anonymous() {
		st, _ := getTypeStruct(st.Field(0).Type(), scope)
		return st, true
	}
	return nil, false
}

// loadModule retrieves package description for a given module.
func loadModule(name string) (*types.Package, error) {
	conf := packages.Config{Mode: packages.NeedTypes | packages.NeedTypesInfo}
	pkgs, err := packages.Load(&conf, name)
	if err != nil {
		return nil, err
	}
	return pkgs[0].Types, nil
}

func main() {
	// Import and type-check the package
	pkg, err := loadModule("github.com/miekg/dns")
	fatalIfErr(err)
	scope := pkg.Scope()

	// Collect actual types (*X)
	var namedTypes []string
	for _, name := range scope.Names() {
		o := scope.Lookup(name)
		if o == nil || !o.Exported() {
			continue
		}

		if st, _ := getTypeStruct(o.Type(), scope); st == nil {
			continue
		}

		if name == "PrivateRR" || name == "OPT" {
			continue
		}

		namedTypes = append(namedTypes, o.Name())
	}

	b := &bytes.Buffer{}
	b.WriteString(packageHdr)

	// Generate the duplicate check for each type.
	fmt.Fprint(b, "// isDuplicate() functions\n\n")
	for _, name := range namedTypes {

		o := scope.Lookup(name)
		st, _ := getTypeStruct(o.Type(), scope)
		fmt.Fprintf(b, "func (r1 *%s) isDuplicate(_r2 RR) bool {\n", name)
		fmt.Fprintf(b, "r2, ok := _r2.(*%s)\n", name)
		fmt.Fprint(b, "if !ok { return false }\n")
		fmt.Fprint(b, "_ = r2\n")
		for i := 1; i < st.NumFields(); i++ {
			field := st.Field(i).Name()
			o2 := func(s string) { fmt.Fprintf(b, s+"\n", field, field) }
			o3 := func(s string) { fmt.Fprintf(b, s+"\n", field, field, field) }

			// For some reason, a and aaaa don't pop up as *types.Slice here (mostly like because the are
			// *indirectly* defined as a slice in the net package).
			if _, ok := st.Field(i).Type().(*types.Slice); ok {
				o2("if len(r1.%s) != len(r2.%s) {\nreturn false\n}")

				if st.Tag(i) == `dns:"cdomain-name"` || st.Tag(i) == `dns:"domain-name"` {
					o3(`for i := 0; i < len(r1.%s); i++ {
						if !isDuplicateName(r1.%s[i], r2.%s[i]) {
							return false
						}
					}`)

					continue
				}

				if st.Tag(i) == `dns:"apl"` {
					o3(`for i := 0; i < len(r1.%s); i++ {
						if !r1.%s[i].equals(&r2.%s[i]) {
							return false
						}
					}`)

					continue
				}

				if st.Tag(i) == `dns:"pairs"` {
					o2(`if !areSVCBPairArraysEqual(r1.%s, r2.%s) {
						return false
					}`)

					continue
				}

				o3(`for i := 0; i < len(r1.%s); i++ {
					if r1.%s[i] != r2.%s[i] {
						return false
					}
				}`)

				continue
			}

			switch st.Tag(i) {
			case `dns:"-"`:
				// ignored
			case `dns:"a"`, `dns:"aaaa"`:
				o2("if !r1.%s.Equal(r2.%s) {\nreturn false\n}")
			case `dns:"cdomain-name"`, `dns:"domain-name"`:
				o2("if !isDuplicateName(r1.%s, r2.%s) {\nreturn false\n}")
			case `dns:"ipsechost"`, `dns:"amtrelayhost"`:
				o2(`switch r1.GatewayType {
				case IPSECGatewayIPv4, IPSECGatewayIPv6:
					if !r1.GatewayAddr.Equal(r2.GatewayAddr) {
						return false
					}
				case IPSECGatewayHost:
					if !isDuplicateName(r1.%s, r2.%s) {
						return false
					}
				}
				`)
			default:
				o2("if r1.%s != r2.%s {\nreturn false\n}")
			}
		}
		fmt.Fprint(b, "return true\n}\n\n")
	}

	// gofmt
	res, err := format.Source(b.Bytes())
	if err != nil {
		b.WriteTo(os.Stderr)
		log.Fatal(err)
	}

	// write result
	f, err := os.Create("zduplicate.go")
	fatalIfErr(err)
	defer f.Close()
	f.Write(res)
}

func fatalIfErr(err error) {
	if err != nil {
		log.Fatal(err)
	}
}


================================================
FILE: duplicate_test.go
================================================
package dns

import "testing"

func TestDuplicateA(t *testing.T) {
	a1, _ := NewRR("www.example.org. 2700 IN A 127.0.0.1")
	a2, _ := NewRR("www.example.org. IN A 127.0.0.1")
	if !IsDuplicate(a1, a2) {
		t.Errorf("expected %s/%s to be duplicates, but got false", a1.String(), a2.String())
	}

	a2, _ = NewRR("www.example.org. IN A 127.0.0.2")
	if IsDuplicate(a1, a2) {
		t.Errorf("expected %s/%s not to be duplicates, but got true", a1.String(), a2.String())
	}
}

func TestDuplicateTXT(t *testing.T) {
	a1, _ := NewRR("www.example.org. IN TXT \"aa\"")
	a2, _ := NewRR("www.example.org. IN TXT \"aa\"")

	if !IsDuplicate(a1, a2) {
		t.Errorf("expected %s/%s to be duplicates, but got false", a1.String(), a2.String())
	}

	a2, _ = NewRR("www.example.org. IN TXT \"aa\" \"bb\"")
	if IsDuplicate(a1, a2) {
		t.Errorf("expected %s/%s not to be duplicates, but got true", a1.String(), a2.String())
	}

	a1, _ = NewRR("www.example.org. IN TXT \"aa\" \"bc\"")
	if IsDuplicate(a1, a2) {
		t.Errorf("expected %s/%s not to be duplicates, but got true", a1.String(), a2.String())
	}
}

func TestDuplicateSVCB(t *testing.T) {
	a1, _ := NewRR(`example.com. 3600 IN SVCB 1 . ipv6hint=1::3:3:3:3 key65300=\254\032\030\000\ \043,\;`)
	a2, _ := NewRR(`example.com. 3600 IN SVCB 1 . ipv6hint=1:0::3:3:3:3 key65300="\254\ \030\000 +\,;"`)

	if !IsDuplicate(a1, a2) {
		t.Errorf("expected %s/%s to be duplicates, but got false", a1.String(), a2.String())
	}

	a2, _ = NewRR(`example.com. 3600 IN SVCB 1 . ipv6hint=1::3:3:3:3 key65300="\255\ \030\000 +\,;"`)

	if IsDuplicate(a1, a2) {
		t.Errorf("expected %s/%s not to be duplicates, but got true", a1.String(), a2.String())
	}

	a1, _ = NewRR(`example.com. 3600 IN SVCB 1 . ipv6hint=1::3:3:3:3`)

	if IsDuplicate(a1, a2) {
		t.Errorf("expected %s/%s not to be duplicates, but got true", a1.String(), a2.String())
	}

	a2, _ = NewRR(`example.com. 3600 IN SVCB 1 . ipv4hint=1.1.1.1`)

	if IsDuplicate(a1, a2) {
		t.Errorf("expected %s/%s not to be duplicates, but got true", a1.String(), a2.String())
	}

	a1, _ = NewRR(`example.com. 3600 IN SVCB 1 . ipv4hint=1.1.1.1,1.0.2.1`)

	if IsDuplicate(a1, a2) {
		t.Errorf("expected %s/%s not to be duplicates, but got true", a1.String(), a2.String())
	}
}

func TestDuplicateOwner(t *testing.T) {
	a1, _ := NewRR("www.example.org. IN A 127.0.0.1")
	a2, _ := NewRR("www.example.org. IN A 127.0.0.1")
	if !IsDuplicate(a1, a2) {
		t.Errorf("expected %s/%s to be duplicates, but got false", a1.String(), a2.String())
	}

	a2, _ = NewRR("WWw.exaMPle.org. IN A 127.0.0.2")
	if IsDuplicate(a1, a2) {
		t.Errorf("expected %s/%s to be duplicates, but got false", a1.String(), a2.String())
	}
}

func TestDuplicateDomain(t *testing.T) {
	a1, _ := NewRR("www.example.org. IN CNAME example.org.")
	a2, _ := NewRR("www.example.org. IN CNAME example.org.")
	if !IsDuplicate(a1, a2) {
		t.Errorf("expected %s/%s to be duplicates, but got false", a1.String(), a2.String())
	}

	a2, _ = NewRR("www.example.org. IN CNAME exAMPLe.oRG.")
	if !IsDuplicate(a1, a2) {
		t.Errorf("expected %s/%s to be duplicates, but got false", a1.String(), a2.String())
	}
}

func TestDuplicateWrongRrtype(t *testing.T) {
	// Test that IsDuplicate won't panic for a record that's lying about
	// it's Rrtype.

	r1 := &A{Hdr: RR_Header{Rrtype: TypeA}}
	r2 := &AAAA{Hdr: RR_Header{Rrtype: TypeA}}
	if IsDuplicate(r1, r2) {
		t.Errorf("expected %s/%s not to be duplicates, but got true", r1.String(), r2.String())
	}

	r3 := &AAAA{Hdr: RR_Header{Rrtype: TypeA}}
	r4 := &A{Hdr: RR_Header{Rrtype: TypeA}}
	if IsDuplicate(r3, r4) {
		t.Errorf("expected %s/%s not to be duplicates, but got true", r3.String(), r4.String())
	}

	r5 := &AAAA{Hdr: RR_Header{Rrtype: TypeA}}
	r6 := &AAAA{Hdr: RR_Header{Rrtype: TypeA}}
	if !IsDuplicate(r5, r6) {
		t.Errorf("expected %s/%s to be duplicates, but got false", r5.String(), r6.String())
	}
}


================================================
FILE: dyn_test.go
================================================
package dns

// Find better solution


================================================
FILE: edns.go
================================================
package dns

import (
	"encoding/binary"
	"encoding/hex"
	"errors"
	"fmt"
	"net"
	"strconv"
)

// EDNS0 Option codes.
const (
	EDNS0LLQ          = 0x1     // long lived queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01
	EDNS0UL           = 0x2     // update lease draft: http://files.dns-sd.org/draft-sekar-dns-ul.txt
	EDNS0NSID         = 0x3     // nsid (See RFC 5001)
	EDNS0ESU          = 0x4     // ENUM Source-URI draft: https://datatracker.ietf.org/doc/html/draft-kaplan-enum-source-uri-00
	EDNS0DAU          = 0x5     // DNSSEC Algorithm Understood
	EDNS0DHU          = 0x6     // DS Hash Understood
	EDNS0N3U          = 0x7     // NSEC3 Hash Understood
	EDNS0SUBNET       = 0x8     // client-subnet (See RFC 7871)
	EDNS0EXPIRE       = 0x9     // EDNS0 expire
	EDNS0COOKIE       = 0xa     // EDNS0 Cookie
	EDNS0TCPKEEPALIVE = 0xb     // EDNS0 tcp keep alive (See RFC 7828)
	EDNS0PADDING      = 0xc     // EDNS0 padding (See RFC 7830)
	EDNS0EDE          = 0xf     // EDNS0 extended DNS errors (See RFC 8914)
	EDNS0REPORTING    = 0x12    // EDNS0 reporting (See RFC 9567)
	EDNS0ZONEVERSION  = 0x13    // EDNS0 Zone Version (See RFC 9660)
	EDNS0LOCALSTART   = 0xFDE9  // Beginning of range reserved for local/experimental use (See RFC 6891)
	EDNS0LOCALEND     = 0xFFFE  // End of range reserved for local/experimental use (See RFC 6891)
	_DO               = 1 << 15 // DNSSEC OK
	_CO               = 1 << 14 // Compact Answers OK
)

// makeDataOpt is used to unpack the EDNS0 option(s) from a message.
func makeDataOpt(code uint16) EDNS0 {
	// All the EDNS0.* constants above need to be in this switch.
	switch code {
	case EDNS0LLQ:
		return new(EDNS0_LLQ)
	case EDNS0UL:
		return new(EDNS0_UL)
	case EDNS0NSID:
		return new(EDNS0_NSID)
	case EDNS0DAU:
		return new(EDNS0_DAU)
	case EDNS0DHU:
		return new(EDNS0_DHU)
	case EDNS0N3U:
		return new(EDNS0_N3U)
	case EDNS0SUBNET:
		return new(EDNS0_SUBNET)
	case EDNS0EXPIRE:
		return new(EDNS0_EXPIRE)
	case EDNS0COOKIE:
		return new(EDNS0_COOKIE)
	case EDNS0TCPKEEPALIVE:
		return new(EDNS0_TCP_KEEPALIVE)
	case EDNS0PADDING:
		return new(EDNS0_PADDING)
	case EDNS0EDE:
		return new(EDNS0_EDE)
	case EDNS0ESU:
		return new(EDNS0_ESU)
	case EDNS0REPORTING:
		return new(EDNS0_REPORTING)
	case EDNS0ZONEVERSION:
		return new(EDNS0_ZONEVERSION)
	default:
		e := new(EDNS0_LOCAL)
		e.Code = code
		return e
	}
}

// OPT is the EDNS0 RR appended to messages to convey extra (meta) information. See RFC 6891.
type OPT struct {
	Hdr    RR_Header
	Option []EDNS0 `dns:"opt"`
}

func (rr *OPT) String() string {
	s := "\n;; OPT PSEUDOSECTION:\n; EDNS: version " + strconv.Itoa(int(rr.Version())) + "; "
	s += "flags:"
	if rr.Do() {
		s += " do"
	}
	if rr.Co() {
		s += " co"
	}
	s += "; "
	if z := rr.Z(); z != 0 {
		s += fmt.Sprintf("MBZ: 0x%04x, ", z)
	}
	s += "udp: " + strconv.Itoa(int(rr.UDPSize()))

	for _, o := range rr.Option {
		switch o.(type) {
		case *EDNS0_NSID:
			s += "\n; NSID: " + o.String()
			h, e := o.pack()
			var r string
			if e == nil {
				for _, c := range h {
					r += "(" + string(c) + ")"
				}
				s += "  " + r
			}
		case *EDNS0_SUBNET:
			s += "\n; SUBNET: " + o.String()
		case *EDNS0_COOKIE:
			s += "\n; COOKIE: " + o.String()
		case *EDNS0_EXPIRE:
			s += "\n; EXPIRE: " + o.String()
		case *EDNS0_TCP_KEEPALIVE:
			s += "\n; KEEPALIVE: " + o.String()
		case *EDNS0_UL:
			s += "\n; UPDATE LEASE: " + o.String()
		case *EDNS0_LLQ:
			s += "\n; LONG LIVED QUERIES: " + o.String()
		case *EDNS0_DAU:
			s += "\n; DNSSEC ALGORITHM UNDERSTOOD: " + o.String()
		case *EDNS0_DHU:
			s += "\n; DS HASH UNDERSTOOD: " + o.String()
		case *EDNS0_N3U:
			s += "\n; NSEC3 HASH UNDERSTOOD: " + o.String()
		case *EDNS0_LOCAL:
			s += "\n; LOCAL OPT: " + o.String()
		case *EDNS0_PADDING:
			s += "\n; PADDING: " + o.String()
		case *EDNS0_EDE:
			s += "\n; EDE: " + o.String()
		case *EDNS0_ESU:
			s += "\n; ESU: " + o.String()
		case *EDNS0_REPORTING:
			s += "\n; REPORT-CHANNEL: " + o.String()
		case *EDNS0_ZONEVERSION:
			s += "\n; ZONEVERSION: " + o.String()
		}
	}
	return s
}

func (rr *OPT) len(off int, compression map[string]struct{}) int {
	l := rr.Hdr.len(off, compression)
	for _, o := range rr.Option {
		l += 4 // Account for 2-byte option code and 2-byte option length.
		lo, _ := o.pack()
		l += len(lo)
	}
	return l
}

func (*OPT) parse(c *zlexer, origin string) *ParseError {
	return &ParseError{err: "OPT records do not have a presentation format"}
}

func (rr *OPT) isDuplicate(r2 RR) bool { return false }

// Version returns the EDNS version used. Only zero is defined.
func (rr *OPT) Version() uint8 {
	return uint8(rr.Hdr.Ttl & 0x00FF0000 >> 16)
}

// SetVersion sets the version of EDNS. This is usually zero.
func (rr *OPT) SetVersion(v uint8) {
	rr.Hdr.Ttl = rr.Hdr.Ttl&0xFF00FFFF | uint32(v)<<16
}

// ExtendedRcode returns the EDNS extended RCODE field (the upper 8 bits of the TTL).
func (rr *OPT) ExtendedRcode() int {
	return int(rr.Hdr.Ttl&0xFF000000>>24) << 4
}

// SetExtendedRcode sets the EDNS extended RCODE field.
//
// If the RCODE is not an extended RCODE, will reset the extended RCODE field to 0.
func (rr *OPT) SetExtendedRcode(v uint16) {
	rr.Hdr.Ttl = rr.Hdr.Ttl&0x00FFFFFF | uint32(v>>4)<<24
}

// UDPSize returns the UDP buffer size.
func (rr *OPT) UDPSize() uint16 {
	return rr.Hdr.Class
}

// SetUDPSize sets the UDP buffer size.
func (rr *OPT) SetUDPSize(size uint16) {
	rr.Hdr.Class = size
}

// Do returns the value of the DO (DNSSEC OK) bit.
func (rr *OPT) Do() bool {
	return rr.Hdr.Ttl&_DO == _DO
}

// SetDo sets the DO (DNSSEC OK) bit.
// If we pass an argument, set the DO bit to that value.
// It is possible to pass 2 or more arguments, but they will be ignored.
func (rr *OPT) SetDo(do ...bool) {
	if len(do) == 1 {
		if do[0] {
			rr.Hdr.Ttl |= _DO
		} else {
			rr.Hdr.Ttl &^= _DO
		}
	} else {
		rr.Hdr.Ttl |= _DO
	}
}

// Co returns the value of the CO (Compact Answers OK) bit.
func (rr *OPT) Co() bool {
	return rr.Hdr.Ttl&_CO == _CO
}

// SetCo sets the CO (Compact Answers OK) bit.
// If we pass an argument, set the CO bit to that value.
// It is possible to pass 2 or more arguments, but they will be ignored.
func (rr *OPT) SetCo(co ...bool) {
	if len(co) == 1 {
		if co[0] {
			rr.Hdr.Ttl |= _CO
		} else {
			rr.Hdr.Ttl &^= _CO
		}
	} else {
		rr.Hdr.Ttl |= _CO
	}
}

// Z returns the Z part of the OPT RR as a uint16 with only the 14 least significant bits used.
func (rr *OPT) Z() uint16 {
	return uint16(rr.Hdr.Ttl & 0x3FFF)
}

// SetZ sets the Z part of the OPT RR, note only the 14 least significant bits of z are used.
func (rr *OPT) SetZ(z uint16) {
	rr.Hdr.Ttl = rr.Hdr.Ttl&^0x3FFF | uint32(z&0x3FFF)
}

// EDNS0 defines an EDNS0 Option. An OPT RR can have multiple options appended to it.
type EDNS0 interface {
	// Option returns the option code for the option.
	Option() uint16
	// pack returns the bytes of the option data.
	pack() ([]byte, error)
	// unpack sets the data as found in the buffer. Is also sets
	// the length of the slice as the length of the option data.
	unpack([]byte) error
	// String returns the string representation of the option.
	String() string
	// copy returns a deep-copy of the option.
	copy() EDNS0
}

// EDNS0_NSID option is used to retrieve a nameserver
// identifier. When sending a request Nsid must be set to the empty string
// The identifier is an opaque stri
Download .txt
gitextract_r63mkn93/

├── .codecov.yml
├── .github/
│   ├── dependabot.yml
│   ├── pull_request_template.md
│   └── workflows/
│       ├── codeql-analysis.yml
│       └── go.yml
├── .gitignore
├── AUTHORS
├── CODEOWNERS
├── CONTRIBUTORS
├── COPYRIGHT
├── LICENSE
├── Makefile.fuzz
├── Makefile.release
├── README.md
├── acceptfunc.go
├── acceptfunc_test.go
├── client.go
├── client_test.go
├── clientconfig.go
├── clientconfig_test.go
├── dane.go
├── defaults.go
├── dns.go
├── dns_bench_test.go
├── dns_test.go
├── dnssec.go
├── dnssec_keygen.go
├── dnssec_keyscan.go
├── dnssec_privkey.go
├── dnssec_test.go
├── dnsutil/
│   ├── util.go
│   └── util_test.go
├── doc.go
├── duplicate.go
├── duplicate_generate.go
├── duplicate_test.go
├── dyn_test.go
├── edns.go
├── edns_test.go
├── example_test.go
├── format.go
├── format_test.go
├── fuzz.go
├── fuzz_test.go
├── generate.go
├── generate_test.go
├── go.mod
├── go.sum
├── hash.go
├── issue_test.go
├── labels.go
├── labels_test.go
├── leak_test.go
├── length_test.go
├── listen_no_socket_options.go
├── listen_socket_options.go
├── msg.go
├── msg_generate.go
├── msg_helpers.go
├── msg_helpers_test.go
├── msg_test.go
├── msg_truncate.go
├── msg_truncate_test.go
├── nsecx.go
├── nsecx_test.go
├── parse_test.go
├── privaterr.go
├── privaterr_test.go
├── reverse.go
├── rr_test.go
├── sanitize.go
├── sanitize_test.go
├── scan.go
├── scan_rr.go
├── scan_test.go
├── serve_mux.go
├── serve_mux_test.go
├── server.go
├── server_test.go
├── sig0.go
├── sig0_test.go
├── smimea.go
├── svcb.go
├── svcb_test.go
├── tlsa.go
├── tmpdir_darwin_test.go
├── tmpdir_test.go
├── tools.go
├── tsig.go
├── tsig_test.go
├── types.go
├── types_generate.go
├── types_test.go
├── udp.go
├── udp_no_control.go
├── udp_test.go
├── update.go
├── update_test.go
├── version.go
├── version_test.go
├── xfr.go
├── xfr_test.go
├── zduplicate.go
├── zmsg.go
└── ztypes.go
Download .txt
SYMBOL INDEX (2144 symbols across 86 files)

FILE: acceptfunc.go
  type MsgAcceptFunc (line 5) | type MsgAcceptFunc
  type MsgAcceptAction (line 23) | type MsgAcceptAction
  constant MsgAccept (line 27) | MsgAccept               MsgAcceptAction = iota
  constant MsgReject (line 28) | MsgReject
  constant MsgIgnore (line 29) | MsgIgnore
  constant MsgRejectNotImplemented (line 30) | MsgRejectNotImplemented
  function defaultMsgAcceptFunc (line 33) | func defaultMsgAcceptFunc(dh Header) MsgAcceptAction {

FILE: acceptfunc_test.go
  function TestAcceptNotify (line 9) | func TestAcceptNotify(t *testing.T) {
  function handleNotify (line 33) | func handleNotify(w ResponseWriter, req *Msg) {
  function TestInvalidMsg (line 39) | func TestInvalidMsg(t *testing.T) {

FILE: client.go
  constant dnsTimeout (line 16) | dnsTimeout     time.Duration = 2 * time.Second
  constant tcpIdleTimeout (line 17) | tcpIdleTimeout time.Duration = 8 * time.Second
  function isPacketConn (line 20) | func isPacketConn(c net.Conn) bool {
  type Conn (line 33) | type Conn struct
    method tsigProvider (line 41) | func (co *Conn) tsigProvider() TsigProvider {
    method ReadMsg (line 254) | func (co *Conn) ReadMsg() (*Msg, error) {
    method ReadMsgHeader (line 277) | func (co *Conn) ReadMsgHeader(hdr *Header) ([]byte, error) {
    method Read (line 319) | func (co *Conn) Read(p []byte) (n int, err error) {
    method WriteMsg (line 343) | func (co *Conn) WriteMsg(m *Msg) (err error) {
    method Write (line 359) | func (co *Conn) Write(p []byte) (int, error) {
  type Client (line 50) | type Client struct
    method dialTimeout (line 84) | func (c *Client) dialTimeout() time.Duration {
    method readTimeout (line 94) | func (c *Client) readTimeout() time.Duration {
    method writeTimeout (line 104) | func (c *Client) writeTimeout() time.Duration {
    method Dial (line 115) | func (c *Client) Dial(address string) (conn *Conn, err error) {
    method DialContext (line 120) | func (c *Client) DialContext(ctx context.Context, address string) (con...
    method Exchange (line 169) | func (c *Client) Exchange(m *Msg, address string) (r *Msg, rtt time.Du...
    method ExchangeWithConn (line 192) | func (c *Client) ExchangeWithConn(m *Msg, conn *Conn) (r *Msg, rtt tim...
    method ExchangeWithConnContext (line 198) | func (c *Client) ExchangeWithConnContext(ctx context.Context, m *Msg, ...
    method getTimeoutForRequest (line 375) | func (c *Client) getTimeoutForRequest(timeout time.Duration) time.Dura...
    method ExchangeContext (line 461) | func (c *Client) ExchangeContext(ctx context.Context, m *Msg, a string...
  function Exchange (line 78) | func Exchange(m *Msg, a string) (r *Msg, err error) {
  function Dial (line 393) | func Dial(network, address string) (conn *Conn, err error) {
  function ExchangeContext (line 404) | func ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, err...
  function ExchangeConn (line 420) | func ExchangeConn(c net.Conn, m *Msg) (r *Msg, err error) {
  function DialTimeout (line 435) | func DialTimeout(network, address string, timeout time.Duration) (conn *...
  function DialWithTLS (line 441) | func DialWithTLS(network, address string, tlsConfig *tls.Config) (conn *...
  function DialTimeoutWithTLS (line 450) | func DialTimeoutWithTLS(network, address string, tlsConfig *tls.Config, ...

FILE: client_test.go
  function TestIsPacketConn (line 16) | func TestIsPacketConn(t *testing.T) {
  function TestDialUDP (line 119) | func TestDialUDP(t *testing.T) {
  function TestClientSync (line 142) | func TestClientSync(t *testing.T) {
  function TestClientLocalAddress (line 176) | func TestClientLocalAddress(t *testing.T) {
  function TestClientTLSSyncV4 (line 211) | func TestClientTLSSyncV4(t *testing.T) {
  function isNetworkTimeout (line 270) | func isNetworkTimeout(err error) bool {
  function TestClientSyncBadID (line 276) | func TestClientSyncBadID(t *testing.T) {
  function TestClientSyncBadThenGoodID (line 299) | func TestClientSyncBadThenGoodID(t *testing.T) {
  function TestClientSyncTCPBadID (line 322) | func TestClientSyncTCPBadID(t *testing.T) {
  function TestClientEDNS0 (line 343) | func TestClientEDNS0(t *testing.T) {
  function TestClientEDNS0Local (line 370) | func TestClientEDNS0Local(t *testing.T) {
  function TestClientConn (line 439) | func TestClientConn(t *testing.T) {
  function TestClientConnWriteSinglePacket (line 493) | func TestClientConnWriteSinglePacket(t *testing.T) {
  function TestTruncatedMsg (line 510) | func TestTruncatedMsg(t *testing.T) {
  function TestTimeout (line 642) | func TestTimeout(t *testing.T) {
  function TestExchangeWithConn (line 689) | func TestExchangeWithConn(t *testing.T) {

FILE: clientconfig.go
  type ClientConfig (line 12) | type ClientConfig struct
    method NameList (line 108) | func (c *ClientConfig) NameList(name string) []string {
  function ClientConfigFromFile (line 23) | func ClientConfigFromFile(resolvconf string) (*ClientConfig, error) {
  function ClientConfigFromReader (line 33) | func ClientConfigFromReader(resolvconf io.Reader) (*ClientConfig, error) {

FILE: clientconfig_test.go
  constant normal (line 10) | normal string = `
  constant missingNewline (line 17) | missingNewline string = `
  function testConfig (line 22) | func testConfig(t *testing.T, data string) {
  function TestNameserver (line 39) | func TestNameserver(t *testing.T)          { testConfig(t, normal) }
  function TestMissingFinalNewLine (line 40) | func TestMissingFinalNewLine(t *testing.T) { testConfig(t, missingNewlin...
  function TestNdots (line 42) | func TestNdots(t *testing.T) {
  function TestClientConfigFromReaderAttempts (line 63) | func TestClientConfigFromReaderAttempts(t *testing.T) {
  function TestReadFromFile (line 92) | func TestReadFromFile(t *testing.T) {
  function TestNameListNdots1 (line 115) | func TestNameListNdots1(t *testing.T) {
  function TestNameListNdots2 (line 141) | func TestNameListNdots2(t *testing.T) {
  function TestNameListNdots0 (line 161) | func TestNameListNdots0(t *testing.T) {

FILE: dane.go
  function CertificateToDANE (line 12) | func CertificateToDANE(selector, matchingType uint8, cert *x509.Certific...

FILE: defaults.go
  constant hexDigit (line 10) | hexDigit = "0123456789abcdef"
  method SetReply (line 15) | func (dns *Msg) SetReply(request *Msg) *Msg {
  method SetQuestion (line 33) | func (dns *Msg) SetQuestion(z string, t uint16) *Msg {
  method SetNotify (line 44) | func (dns *Msg) SetNotify(z string) *Msg {
  method SetRcode (line 54) | func (dns *Msg) SetRcode(request *Msg, rcode int) *Msg {
  method SetRcodeFormatError (line 61) | func (dns *Msg) SetRcodeFormatError(request *Msg) *Msg {
  method SetUpdate (line 72) | func (dns *Msg) SetUpdate(z string) *Msg {
  method SetIxfr (line 83) | func (dns *Msg) SetIxfr(z string, serial uint32, ns, mbox string) *Msg {
  method SetAxfr (line 98) | func (dns *Msg) SetAxfr(z string) *Msg {
  method SetTsig (line 108) | func (dns *Msg) SetTsig(z, algo string, fudge uint16, timesigned int64) ...
  method SetEdns0 (line 121) | func (dns *Msg) SetEdns0(udpsize uint16, do bool) *Msg {
  method IsTsig (line 135) | func (dns *Msg) IsTsig() *TSIG {
  method IsEdns0 (line 147) | func (dns *Msg) IsEdns0() *OPT {
  method popEdns0 (line 160) | func (dns *Msg) popEdns0() *OPT {
  function IsDomainName (line 182) | func IsDomainName(s string) (labels int, ok bool) {
  function IsSubDomain (line 261) | func IsSubDomain(parent, child string) bool {
  function IsMsg (line 268) | func IsMsg(buf []byte) error {
  function IsFqdn (line 279) | func IsFqdn(s string) bool {
  function IsRRset (line 302) | func IsRRset(rrset []RR) bool {
  function Fqdn (line 322) | func Fqdn(s string) string {
  function CanonicalName (line 332) | func CanonicalName(s string) string {
  function ReverseAddr (line 346) | func ReverseAddr(addr string) (arpa string, err error) {
  method String (line 375) | func (t Type) String() string {
  method String (line 383) | func (c Class) String() string {
  method String (line 394) | func (n Name) String() string {

FILE: dns.go
  constant year68 (line 9) | year68     = 1 << 31
  constant defaultTtl (line 10) | defaultTtl = 3600
  constant DefaultMsgSize (line 13) | DefaultMsgSize = 4096
  constant MinMsgSize (line 15) | MinMsgSize = 512
  constant MaxMsgSize (line 17) | MaxMsgSize = 65535
  type Error (line 21) | type Error struct
    method Error (line 23) | func (e *Error) Error() string {
  type RR (line 31) | type RR interface
  type RR_Header (line 67) | type RR_Header struct
    method Header (line 76) | func (h *RR_Header) Header() *RR_Header { return h }
    method copy (line 79) | func (h *RR_Header) copy() RR { return nil }
    method String (line 81) | func (h *RR_Header) String() string {
    method len (line 96) | func (h *RR_Header) len(off int, compression map[string]struct{}) int {
    method pack (line 102) | func (h *RR_Header) pack(msg []byte, off int, compression compressionM...
    method unpack (line 107) | func (h *RR_Header) unpack(msg []byte, off int) (int, error) {
    method parse (line 111) | func (h *RR_Header) parse(c *zlexer, origin string) *ParseError {
  method ToRFC3597 (line 116) | func (rr *RFC3597) ToRFC3597(r RR) error {
  method fromRFC3597 (line 136) | func (rr *RFC3597) fromRFC3597(r RR) error {

FILE: dns_bench_test.go
  function BenchmarkMsgLength (line 9) | func BenchmarkMsgLength(b *testing.B) {
  function BenchmarkMsgLengthNoCompression (line 29) | func BenchmarkMsgLengthNoCompression(b *testing.B) {
  function BenchmarkMsgLengthPack (line 48) | func BenchmarkMsgLengthPack(b *testing.B) {
  function BenchmarkMsgLengthMassive (line 67) | func BenchmarkMsgLengthMassive(b *testing.B) {
  function BenchmarkMsgLengthOnlyQuestion (line 92) | func BenchmarkMsgLengthOnlyQuestion(b *testing.B) {
  function BenchmarkMsgLengthEscapedName (line 102) | func BenchmarkMsgLengthEscapedName(b *testing.B) {
  function BenchmarkPackDomainName (line 111) | func BenchmarkPackDomainName(b *testing.B) {
  function BenchmarkUnpackDomainName (line 120) | func BenchmarkUnpackDomainName(b *testing.B) {
  function BenchmarkUnpackDomainNameUnprintable (line 130) | func BenchmarkUnpackDomainNameUnprintable(b *testing.B) {
  function BenchmarkUnpackDomainNameLongest (line 140) | func BenchmarkUnpackDomainNameLongest(b *testing.B) {
  function BenchmarkUnpackDomainNameLongestUnprintable (line 155) | func BenchmarkUnpackDomainNameLongestUnprintable(b *testing.B) {
  function BenchmarkCopy (line 170) | func BenchmarkCopy(b *testing.B) {
  function BenchmarkPackA (line 187) | func BenchmarkPackA(b *testing.B) {
  function BenchmarkUnpackA (line 198) | func BenchmarkUnpackA(b *testing.B) {
  function BenchmarkPackMX (line 211) | func BenchmarkPackMX(b *testing.B) {
  function BenchmarkUnpackMX (line 222) | func BenchmarkUnpackMX(b *testing.B) {
  function BenchmarkPackAAAAA (line 235) | func BenchmarkPackAAAAA(b *testing.B) {
  function BenchmarkUnpackAAAA (line 246) | func BenchmarkUnpackAAAA(b *testing.B) {
  function BenchmarkPackMsg (line 259) | func BenchmarkPackMsg(b *testing.B) {
  function BenchmarkPackMsgMassive (line 280) | func BenchmarkPackMsgMassive(b *testing.B) {
  function BenchmarkPackMsgOnlyQuestion (line 307) | func BenchmarkPackMsgOnlyQuestion(b *testing.B) {
  function BenchmarkUnpackMsg (line 319) | func BenchmarkUnpackMsg(b *testing.B) {
  function BenchmarkIdGeneration (line 340) | func BenchmarkIdGeneration(b *testing.B) {
  function BenchmarkReverseAddr (line 346) | func BenchmarkReverseAddr(b *testing.B) {

FILE: dns_test.go
  function TestPackUnpack (line 10) | func TestPackUnpack(t *testing.T) {
  function TestPackUnpack2 (line 43) | func TestPackUnpack2(t *testing.T) {
  function TestPackUnpack3 (line 65) | func TestPackUnpack3(t *testing.T) {
  function TestBailiwick (line 99) | func TestBailiwick(t *testing.T) {
  function TestPackNAPTR (line 128) | func TestPackNAPTR(t *testing.T) {
  function TestToRFC3597 (line 143) | func TestToRFC3597(t *testing.T) {
  function TestNoRdataPack (line 158) | func TestNoRdataPack(t *testing.T) {
  function TestNoRdataUnpack (line 170) | func TestNoRdataUnpack(t *testing.T) {
  function TestRdataOverflow (line 192) | func TestRdataOverflow(t *testing.T) {
  function TestCopy (line 208) | func TestCopy(t *testing.T) {
  function TestMsgCopy (line 216) | func TestMsgCopy(t *testing.T) {
  function TestMsgPackBuffer (line 241) | func TestMsgPackBuffer(t *testing.T) {
  function TestTKEY (line 264) | func TestTKEY(t *testing.T) {
  function BenchmarkIsFQDN (line 323) | func BenchmarkIsFQDN(b *testing.B) {
  function BenchmarkFQDN (line 347) | func BenchmarkFQDN(b *testing.B) {

FILE: dnssec.go
  constant _ (line 25) | _ uint8 = iota
  constant RSAMD5 (line 26) | RSAMD5
  constant DH (line 27) | DH
  constant DSA (line 28) | DSA
  constant _ (line 29) | _
  constant RSASHA1 (line 30) | RSASHA1
  constant DSANSEC3SHA1 (line 31) | DSANSEC3SHA1
  constant RSASHA1NSEC3SHA1 (line 32) | RSASHA1NSEC3SHA1
  constant RSASHA256 (line 33) | RSASHA256
  constant _ (line 34) | _
  constant RSASHA512 (line 35) | RSASHA512
  constant _ (line 36) | _
  constant ECCGOST (line 37) | ECCGOST
  constant ECDSAP256SHA256 (line 38) | ECDSAP256SHA256
  constant ECDSAP384SHA384 (line 39) | ECDSAP384SHA384
  constant ED25519 (line 40) | ED25519
  constant ED448 (line 41) | ED448
  constant INDIRECT (line 42) | INDIRECT   uint8 = 252
  constant PRIVATEDNS (line 43) | PRIVATEDNS uint8 = 253
  constant PRIVATEOID (line 44) | PRIVATEOID uint8 = 254
  constant _ (line 85) | _      uint8 = iota
  constant SHA1 (line 86) | SHA1
  constant SHA256 (line 87) | SHA256
  constant GOST94 (line 88) | GOST94
  constant SHA384 (line 89) | SHA384
  constant SHA512 (line 90) | SHA512
  constant SEP (line 104) | SEP    = 1
  constant REVOKE (line 105) | REVOKE = 1 << 7
  constant ZONE (line 106) | ZONE   = 1 << 8
  type rrsigWireFmt (line 110) | type rrsigWireFmt struct
  type dnskeyWireFmt (line 123) | type dnskeyWireFmt struct
  method KeyTag (line 132) | func (k *DNSKEY) KeyTag() uint16 {
  method ToDS (line 173) | func (k *DNSKEY) ToDS(h uint8) *DS {
  method ToCDNSKEY (line 231) | func (k *DNSKEY) ToCDNSKEY() *CDNSKEY {
  method ToCDS (line 239) | func (d *DS) ToCDS() *CDS {
  method Sign (line 252) | func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error {
  method signAsIs (line 270) | func (rr *RRSIG) signAsIs(k crypto.Signer, rrset []RR) error {
  function sign (line 325) | func sign(k crypto.Signer, hashed []byte, hash crypto.Hash, alg uint8) (...
  method Verify (line 363) | func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
  method ValidityPeriod (line 492) | func (rr *RRSIG) ValidityPeriod(t time.Time) bool {
  method sigBuf (line 507) | func (rr *RRSIG) sigBuf() []byte {
  method publicKeyRSA (line 516) | func (k *DNSKEY) publicKeyRSA() *rsa.PublicKey {
  method publicKeyECDSA (line 569) | func (k *DNSKEY) publicKeyECDSA() *ecdsa.PublicKey {
  method publicKeyED25519 (line 594) | func (k *DNSKEY) publicKeyED25519() ed25519.PublicKey {
  type wireSlice (line 605) | type wireSlice
    method Len (line 607) | func (p wireSlice) Len() int      { return len(p) }
    method Swap (line 608) | func (p wireSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
    method Less (line 609) | func (p wireSlice) Less(i, j int) bool {
  function rawSignatureData (line 616) | func rawSignatureData(rrset []RR, s *RRSIG) (buf []byte, err error) {
  function packSigWire (line 705) | func packSigWire(sw *rrsigWireFmt, msg []byte) (int, error) {
  function packKeyWire (line 742) | func packKeyWire(dw *dnskeyWireFmt, msg []byte) (int, error) {

FILE: dnssec_keygen.go
  method Generate (line 19) | func (k *DNSKEY) Generate(bits int) (crypto.PrivateKey, error) {
  method setPublicKeyRSA (line 80) | func (k *DNSKEY) setPublicKeyRSA(_E int, _N *big.Int) bool {
  method setPublicKeyECDSA (line 91) | func (k *DNSKEY) setPublicKeyECDSA(_X, _Y *big.Int) bool {
  method setPublicKeyED25519 (line 107) | func (k *DNSKEY) setPublicKeyED25519(_K ed25519.PublicKey) bool {
  function exponentToBuf (line 117) | func exponentToBuf(_E int) []byte {
  function curveToBuf (line 135) | func curveToBuf(_X, _Y *big.Int, intlen int) []byte {

FILE: dnssec_keyscan.go
  method NewPrivateKey (line 17) | func (k *DNSKEY) NewPrivateKey(s string) (crypto.PrivateKey, error) {
  method ReadPrivateKey (line 28) | func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.Privat...
  function readPrivateKeyRSA (line 76) | func readPrivateKeyRSA(m map[string]string) (*rsa.PrivateKey, error) {
  function readPrivateKeyECDSA (line 108) | func readPrivateKeyECDSA(m map[string]string) (*ecdsa.PrivateKey, error) {
  function readPrivateKeyED25519 (line 127) | func readPrivateKeyED25519(m map[string]string) (ed25519.PrivateKey, err...
  function parseKey (line 150) | func parseKey(r io.Reader, file string) (map[string]string, error) {
  type klexer (line 179) | type klexer struct
    method Err (line 207) | func (kl *klexer) Err() error {
    method readByte (line 216) | func (kl *klexer) readByte() (byte, bool) {
    method Next (line 244) | func (kl *klexer) Next() (lex, bool) {
  function newKLexer (line 192) | func newKLexer(r io.Reader) *klexer {

FILE: dnssec_privkey.go
  constant format (line 12) | format = "Private-key-format: v1.3\n"
  method PrivateKeyString (line 20) | func (r *DNSKEY) PrivateKeyString(p crypto.PrivateKey) string {

FILE: dnssec_test.go
  function getSoa (line 14) | func getSoa() *SOA {
  function TestSecure (line 27) | func TestSecure(t *testing.T) {
  function TestSignature (line 57) | func TestSignature(t *testing.T) {
  function TestSignVerify (line 84) | func TestSignVerify(t *testing.T) {
  function TestShouldNotVerifyInvalidSig (line 162) | func TestShouldNotVerifyInvalidSig(t *testing.T) {
  function Test65534 (line 275) | func Test65534(t *testing.T) {
  function TestDnskey (line 312) | func TestDnskey(t *testing.T) {
  function TestTag (line 344) | func TestTag(t *testing.T) {
  function TestKeyRSA (line 361) | func TestKeyRSA(t *testing.T) {
  function TestKeyToDS (line 408) | func TestKeyToDS(t *testing.T) {
  function TestSignRSA (line 425) | func TestSignRSA(t *testing.T) {
  function TestSignVerifyECDSA (line 484) | func TestSignVerifyECDSA(t *testing.T) {
  function TestSignVerifyECDSA2 (line 530) | func TestSignVerifyECDSA2(t *testing.T) {
  function TestSignVerifyEd25519 (line 576) | func TestSignVerifyEd25519(t *testing.T) {
  function TestRFC6605P256 (line 627) | func TestRFC6605P256(t *testing.T) {
  function TestRFC6605P384 (line 688) | func TestRFC6605P384(t *testing.T) {
  function TestRFC8080Ed25519Example1 (line 755) | func TestRFC8080Ed25519Example1(t *testing.T) {
  function TestRFC8080Ed25519Example2 (line 824) | func TestRFC8080Ed25519Example2(t *testing.T) {
  function TestInvalidRRSet (line 892) | func TestInvalidRRSet(t *testing.T) {
  function TestRsaExponentUnpack (line 954) | func TestRsaExponentUnpack(t *testing.T) {
  function TestParseKeyReadError (line 972) | func TestParseKeyReadError(t *testing.T) {
  function TestRSAMD5KeyTag (line 982) | func TestRSAMD5KeyTag(t *testing.T) {

FILE: dnsutil/util.go
  function AddOrigin (line 20) | func AddOrigin(s, origin string) string {
  function TrimDomainName (line 48) | func TrimDomainName(s, origin string) string {

FILE: dnsutil/util_test.go
  function TestAddOrigin (line 5) | func TestAddOrigin(t *testing.T) {
  function TestTrimDomainName (line 36) | func TestTrimDomainName(t *testing.T) {

FILE: duplicate.go
  function IsDuplicate (line 8) | func IsDuplicate(r1, r2 RR) bool {
  method isDuplicate (line 18) | func (r1 *RR_Header) isDuplicate(_r2 RR) bool {
  function isDuplicateName (line 37) | func isDuplicateName(s1, s2 string) bool { return equal(s1, s2) }

FILE: duplicate_generate.go
  function getTypeStruct (line 29) | func getTypeStruct(t types.Type, scope *types.Scope) (*types.Struct, boo...
  function loadModule (line 48) | func loadModule(name string) (*types.Package, error) {
  function main (line 57) | func main() {
  function fatalIfErr (line 182) | func fatalIfErr(err error) {

FILE: duplicate_test.go
  function TestDuplicateA (line 5) | func TestDuplicateA(t *testing.T) {
  function TestDuplicateTXT (line 18) | func TestDuplicateTXT(t *testing.T) {
  function TestDuplicateSVCB (line 37) | func TestDuplicateSVCB(t *testing.T) {
  function TestDuplicateOwner (line 70) | func TestDuplicateOwner(t *testing.T) {
  function TestDuplicateDomain (line 83) | func TestDuplicateDomain(t *testing.T) {
  function TestDuplicateWrongRrtype (line 96) | func TestDuplicateWrongRrtype(t *testing.T) {

FILE: edns.go
  constant EDNS0LLQ (line 14) | EDNS0LLQ          = 0x1
  constant EDNS0UL (line 15) | EDNS0UL           = 0x2
  constant EDNS0NSID (line 16) | EDNS0NSID         = 0x3
  constant EDNS0ESU (line 17) | EDNS0ESU          = 0x4
  constant EDNS0DAU (line 18) | EDNS0DAU          = 0x5
  constant EDNS0DHU (line 19) | EDNS0DHU          = 0x6
  constant EDNS0N3U (line 20) | EDNS0N3U          = 0x7
  constant EDNS0SUBNET (line 21) | EDNS0SUBNET       = 0x8
  constant EDNS0EXPIRE (line 22) | EDNS0EXPIRE       = 0x9
  constant EDNS0COOKIE (line 23) | EDNS0COOKIE       = 0xa
  constant EDNS0TCPKEEPALIVE (line 24) | EDNS0TCPKEEPALIVE = 0xb
  constant EDNS0PADDING (line 25) | EDNS0PADDING      = 0xc
  constant EDNS0EDE (line 26) | EDNS0EDE          = 0xf
  constant EDNS0REPORTING (line 27) | EDNS0REPORTING    = 0x12
  constant EDNS0ZONEVERSION (line 28) | EDNS0ZONEVERSION  = 0x13
  constant EDNS0LOCALSTART (line 29) | EDNS0LOCALSTART   = 0xFDE9
  constant EDNS0LOCALEND (line 30) | EDNS0LOCALEND     = 0xFFFE
  constant _DO (line 31) | _DO               = 1 << 15
  constant _CO (line 32) | _CO               = 1 << 14
  function makeDataOpt (line 36) | func makeDataOpt(code uint16) EDNS0 {
  type OPT (line 77) | type OPT struct
    method String (line 82) | func (rr *OPT) String() string {
    method len (line 144) | func (rr *OPT) len(off int, compression map[string]struct{}) int {
    method parse (line 154) | func (*OPT) parse(c *zlexer, origin string) *ParseError {
    method isDuplicate (line 158) | func (rr *OPT) isDuplicate(r2 RR) bool { return false }
    method Version (line 161) | func (rr *OPT) Version() uint8 {
    method SetVersion (line 166) | func (rr *OPT) SetVersion(v uint8) {
    method ExtendedRcode (line 171) | func (rr *OPT) ExtendedRcode() int {
    method SetExtendedRcode (line 178) | func (rr *OPT) SetExtendedRcode(v uint16) {
    method UDPSize (line 183) | func (rr *OPT) UDPSize() uint16 {
    method SetUDPSize (line 188) | func (rr *OPT) SetUDPSize(size uint16) {
    method Do (line 193) | func (rr *OPT) Do() bool {
    method SetDo (line 200) | func (rr *OPT) SetDo(do ...bool) {
    method Co (line 213) | func (rr *OPT) Co() bool {
    method SetCo (line 220) | func (rr *OPT) SetCo(co ...bool) {
    method Z (line 233) | func (rr *OPT) Z() uint16 {
    method SetZ (line 238) | func (rr *OPT) SetZ(z uint16) {
  type EDNS0 (line 243) | type EDNS0 interface
  type EDNS0_NSID (line 269) | type EDNS0_NSID struct
    method pack (line 274) | func (e *EDNS0_NSID) pack() ([]byte, error) {
    method Option (line 283) | func (e *EDNS0_NSID) Option() uint16        { return EDNS0NSID }
    method unpack (line 284) | func (e *EDNS0_NSID) unpack(b []byte) error { e.Nsid = hex.EncodeToStr...
    method String (line 285) | func (e *EDNS0_NSID) String() string        { return e.Nsid }
    method copy (line 286) | func (e *EDNS0_NSID) copy() EDNS0           { return &EDNS0_NSID{e.Cod...
  type EDNS0_SUBNET (line 308) | type EDNS0_SUBNET struct
    method Option (line 317) | func (e *EDNS0_SUBNET) Option() uint16 { return EDNS0SUBNET }
    method pack (line 319) | func (e *EDNS0_SUBNET) pack() ([]byte, error) {
    method unpack (line 370) | func (e *EDNS0_SUBNET) unpack(b []byte) error {
    method String (line 405) | func (e *EDNS0_SUBNET) String() (s string) {
    method copy (line 417) | func (e *EDNS0_SUBNET) copy() EDNS0 {
  type EDNS0_COOKIE (line 445) | type EDNS0_COOKIE struct
    method pack (line 450) | func (e *EDNS0_COOKIE) pack() ([]byte, error) {
    method Option (line 459) | func (e *EDNS0_COOKIE) Option() uint16        { return EDNS0COOKIE }
    method unpack (line 460) | func (e *EDNS0_COOKIE) unpack(b []byte) error { e.Cookie = hex.EncodeT...
    method String (line 461) | func (e *EDNS0_COOKIE) String() string        { return e.Cookie }
    method copy (line 462) | func (e *EDNS0_COOKIE) copy() EDNS0           { return &EDNS0_COOKIE{e...
  type EDNS0_UL (line 476) | type EDNS0_UL struct
    method Option (line 483) | func (e *EDNS0_UL) Option() uint16 { return EDNS0UL }
    method String (line 484) | func (e *EDNS0_UL) String() string { return fmt.Sprintf("%d %d", e.Lea...
    method copy (line 485) | func (e *EDNS0_UL) copy() EDNS0    { return &EDNS0_UL{e.Code, e.Lease,...
    method pack (line 488) | func (e *EDNS0_UL) pack() ([]byte, error) {
    method unpack (line 500) | func (e *EDNS0_UL) unpack(b []byte) error {
  type EDNS0_LLQ (line 515) | type EDNS0_LLQ struct
    method Option (line 525) | func (e *EDNS0_LLQ) Option() uint16 { return EDNS0LLQ }
    method pack (line 527) | func (e *EDNS0_LLQ) pack() ([]byte, error) {
    method unpack (line 537) | func (e *EDNS0_LLQ) unpack(b []byte) error {
    method String (line 549) | func (e *EDNS0_LLQ) String() string {
    method copy (line 556) | func (e *EDNS0_LLQ) copy() EDNS0 {
  type EDNS0_DAU (line 561) | type EDNS0_DAU struct
    method Option (line 567) | func (e *EDNS0_DAU) Option() uint16        { return EDNS0DAU }
    method pack (line 568) | func (e *EDNS0_DAU) pack() ([]byte, error) { return cloneSlice(e.AlgCo...
    method unpack (line 569) | func (e *EDNS0_DAU) unpack(b []byte) error { e.AlgCode = cloneSlice(b)...
    method String (line 571) | func (e *EDNS0_DAU) String() string {
    method copy (line 582) | func (e *EDNS0_DAU) copy() EDNS0 { return &EDNS0_DAU{e.Code, e.AlgCode} }
  type EDNS0_DHU (line 585) | type EDNS0_DHU struct
    method Option (line 591) | func (e *EDNS0_DHU) Option() uint16        { return EDNS0DHU }
    method pack (line 592) | func (e *EDNS0_DHU) pack() ([]byte, error) { return cloneSlice(e.AlgCo...
    method unpack (line 593) | func (e *EDNS0_DHU) unpack(b []byte) error { e.AlgCode = cloneSlice(b)...
    method String (line 595) | func (e *EDNS0_DHU) String() string {
    method copy (line 606) | func (e *EDNS0_DHU) copy() EDNS0 { return &EDNS0_DHU{e.Code, e.AlgCode} }
  type EDNS0_N3U (line 609) | type EDNS0_N3U struct
    method Option (line 615) | func (e *EDNS0_N3U) Option() uint16        { return EDNS0N3U }
    method pack (line 616) | func (e *EDNS0_N3U) pack() ([]byte, error) { return cloneSlice(e.AlgCo...
    method unpack (line 617) | func (e *EDNS0_N3U) unpack(b []byte) error { e.AlgCode = cloneSlice(b)...
    method String (line 619) | func (e *EDNS0_N3U) String() string {
    method copy (line 631) | func (e *EDNS0_N3U) copy() EDNS0 { return &EDNS0_N3U{e.Code, e.AlgCode} }
  type EDNS0_EXPIRE (line 634) | type EDNS0_EXPIRE struct
    method Option (line 641) | func (e *EDNS0_EXPIRE) Option() uint16 { return EDNS0EXPIRE }
    method copy (line 642) | func (e *EDNS0_EXPIRE) copy() EDNS0    { return &EDNS0_EXPIRE{e.Code, ...
    method pack (line 644) | func (e *EDNS0_EXPIRE) pack() ([]byte, error) {
    method unpack (line 653) | func (e *EDNS0_EXPIRE) unpack(b []byte) error {
    method String (line 667) | func (e *EDNS0_EXPIRE) String() (s string) {
  type EDNS0_LOCAL (line 687) | type EDNS0_LOCAL struct
    method Option (line 693) | func (e *EDNS0_LOCAL) Option() uint16 { return e.Code }
    method String (line 695) | func (e *EDNS0_LOCAL) String() string {
    method copy (line 699) | func (e *EDNS0_LOCAL) copy() EDNS0 {
    method pack (line 703) | func (e *EDNS0_LOCAL) pack() ([]byte, error) {
    method unpack (line 707) | func (e *EDNS0_LOCAL) unpack(b []byte) error {
  type EDNS0_TCP_KEEPALIVE (line 714) | type EDNS0_TCP_KEEPALIVE struct
    method Option (line 728) | func (e *EDNS0_TCP_KEEPALIVE) Option() uint16 { return EDNS0TCPKEEPALI...
    method pack (line 730) | func (e *EDNS0_TCP_KEEPALIVE) pack() ([]byte, error) {
    method unpack (line 739) | func (e *EDNS0_TCP_KEEPALIVE) unpack(b []byte) error {
    method String (line 750) | func (e *EDNS0_TCP_KEEPALIVE) String() string {
    method copy (line 760) | func (e *EDNS0_TCP_KEEPALIVE) copy() EDNS0 { return &EDNS0_TCP_KEEPALI...
  type EDNS0_PADDING (line 765) | type EDNS0_PADDING struct
    method Option (line 770) | func (e *EDNS0_PADDING) Option() uint16        { return EDNS0PADDING }
    method pack (line 771) | func (e *EDNS0_PADDING) pack() ([]byte, error) { return cloneSlice(e.P...
    method unpack (line 772) | func (e *EDNS0_PADDING) unpack(b []byte) error { e.Padding = cloneSlic...
    method String (line 773) | func (e *EDNS0_PADDING) String() string        { return fmt.Sprintf("%...
    method copy (line 774) | func (e *EDNS0_PADDING) copy() EDNS0           { return &EDNS0_PADDING...
  constant ExtendedErrorCodeOther (line 778) | ExtendedErrorCodeOther uint16 = iota
  constant ExtendedErrorCodeUnsupportedDNSKEYAlgorithm (line 779) | ExtendedErrorCodeUnsupportedDNSKEYAlgorithm
  constant ExtendedErrorCodeUnsupportedDSDigestType (line 780) | ExtendedErrorCodeUnsupportedDSDigestType
  constant ExtendedErrorCodeStaleAnswer (line 781) | ExtendedErrorCodeStaleAnswer
  constant ExtendedErrorCodeForgedAnswer (line 782) | ExtendedErrorCodeForgedAnswer
  constant ExtendedErrorCodeDNSSECIndeterminate (line 783) | ExtendedErrorCodeDNSSECIndeterminate
  constant ExtendedErrorCodeDNSBogus (line 784) | ExtendedErrorCodeDNSBogus
  constant ExtendedErrorCodeSignatureExpired (line 785) | ExtendedErrorCodeSignatureExpired
  constant ExtendedErrorCodeSignatureNotYetValid (line 786) | ExtendedErrorCodeSignatureNotYetValid
  constant ExtendedErrorCodeDNSKEYMissing (line 787) | ExtendedErrorCodeDNSKEYMissing
  constant ExtendedErrorCodeRRSIGsMissing (line 788) | ExtendedErrorCodeRRSIGsMissing
  constant ExtendedErrorCodeNoZoneKeyBitSet (line 789) | ExtendedErrorCodeNoZoneKeyBitSet
  constant ExtendedErrorCodeNSECMissing (line 790) | ExtendedErrorCodeNSECMissing
  constant ExtendedErrorCodeCachedError (line 791) | ExtendedErrorCodeCachedError
  constant ExtendedErrorCodeNotReady (line 792) | ExtendedErrorCodeNotReady
  constant ExtendedErrorCodeBlocked (line 793) | ExtendedErrorCodeBlocked
  constant ExtendedErrorCodeCensored (line 794) | ExtendedErrorCodeCensored
  constant ExtendedErrorCodeFiltered (line 795) | ExtendedErrorCodeFiltered
  constant ExtendedErrorCodeProhibited (line 796) | ExtendedErrorCodeProhibited
  constant ExtendedErrorCodeStaleNXDOMAINAnswer (line 797) | ExtendedErrorCodeStaleNXDOMAINAnswer
  constant ExtendedErrorCodeNotAuthoritative (line 798) | ExtendedErrorCodeNotAuthoritative
  constant ExtendedErrorCodeNotSupported (line 799) | ExtendedErrorCodeNotSupported
  constant ExtendedErrorCodeNoReachableAuthority (line 800) | ExtendedErrorCodeNoReachableAuthority
  constant ExtendedErrorCodeNetworkError (line 801) | ExtendedErrorCodeNetworkError
  constant ExtendedErrorCodeInvalidData (line 802) | ExtendedErrorCodeInvalidData
  constant ExtendedErrorCodeSignatureExpiredBeforeValid (line 803) | ExtendedErrorCodeSignatureExpiredBeforeValid
  constant ExtendedErrorCodeTooEarly (line 804) | ExtendedErrorCodeTooEarly
  constant ExtendedErrorCodeUnsupportedNSEC3IterValue (line 805) | ExtendedErrorCodeUnsupportedNSEC3IterValue
  constant ExtendedErrorCodeUnableToConformToPolicy (line 806) | ExtendedErrorCodeUnableToConformToPolicy
  constant ExtendedErrorCodeSynthesized (line 807) | ExtendedErrorCodeSynthesized
  constant ExtendedErrorCodeInvalidQueryType (line 808) | ExtendedErrorCodeInvalidQueryType
  type EDNS0_EDE (line 853) | type EDNS0_EDE struct
    method Option (line 859) | func (e *EDNS0_EDE) Option() uint16 { return EDNS0EDE }
    method copy (line 860) | func (e *EDNS0_EDE) copy() EDNS0    { return &EDNS0_EDE{e.InfoCode, e....
    method String (line 862) | func (e *EDNS0_EDE) String() string {
    method pack (line 870) | func (e *EDNS0_EDE) pack() ([]byte, error) {
    method unpack (line 877) | func (e *EDNS0_EDE) unpack(b []byte) error {
  type EDNS0_ESU (line 887) | type EDNS0_ESU struct
    method Option (line 892) | func (e *EDNS0_ESU) Option() uint16        { return EDNS0ESU }
    method String (line 893) | func (e *EDNS0_ESU) String() string        { return e.Uri }
    method copy (line 894) | func (e *EDNS0_ESU) copy() EDNS0           { return &EDNS0_ESU{e.Code,...
    method pack (line 895) | func (e *EDNS0_ESU) pack() ([]byte, error) { return []byte(e.Uri), nil }
    method unpack (line 896) | func (e *EDNS0_ESU) unpack(b []byte) error {
  type EDNS0_REPORTING (line 902) | type EDNS0_REPORTING struct
    method Option (line 907) | func (e *EDNS0_REPORTING) Option() uint16 { return EDNS0REPORTING }
    method String (line 908) | func (e *EDNS0_REPORTING) String() string { return e.AgentDomain }
    method copy (line 909) | func (e *EDNS0_REPORTING) copy() EDNS0    { return &EDNS0_REPORTING{e....
    method pack (line 910) | func (e *EDNS0_REPORTING) pack() ([]byte, error) {
    method unpack (line 918) | func (e *EDNS0_REPORTING) unpack(b []byte) error {
  type EDNS0_ZONEVERSION (line 928) | type EDNS0_ZONEVERSION struct
    method Option (line 941) | func (e *EDNS0_ZONEVERSION) Option() uint16 { return EDNS0ZONEVERSION }
    method String (line 942) | func (e *EDNS0_ZONEVERSION) String() string { return e.Version }
    method copy (line 943) | func (e *EDNS0_ZONEVERSION) copy() EDNS0 {
    method pack (line 946) | func (e *EDNS0_ZONEVERSION) pack() ([]byte, error) {
    method unpack (line 958) | func (e *EDNS0_ZONEVERSION) unpack(b []byte) error {

FILE: edns_test.go
  function TestOPTTtl (line 9) | func TestOPTTtl(t *testing.T) {
  function TestEDNS0_SUBNETUnpack (line 114) | func TestEDNS0_SUBNETUnpack(t *testing.T) {
  function TestEDNS0_UL (line 147) | func TestEDNS0_UL(t *testing.T) {
  function TestZ (line 171) | func TestZ(t *testing.T) {
  function TestEDNS0_ESU (line 197) | func TestEDNS0_ESU(t *testing.T) {
  function TestEDNS0_TCP_KEEPALIVE_unpack (line 231) | func TestEDNS0_TCP_KEEPALIVE_unpack(t *testing.T) {
  function TestEDNS0_TCP_KEEPALIVE_pack (line 272) | func TestEDNS0_TCP_KEEPALIVE_pack(t *testing.T) {

FILE: example_test.go
  function ExampleMX (line 13) | func ExampleMX() {
  function ExampleDS (line 35) | func ExampleDS() {
  constant TypeAPAIR (line 58) | TypeAPAIR = 0x0F99
  type APAIR (line 60) | type APAIR struct
    method String (line 66) | func (rd *APAIR) String() string { return rd.addr[0].String() + " " + ...
    method Parse (line 68) | func (rd *APAIR) Parse(txt []string) error {
    method Pack (line 82) | func (rd *APAIR) Pack(buf []byte) (int, error) {
    method Unpack (line 91) | func (rd *APAIR) Unpack(buf []byte) (int, error) {
    method Copy (line 105) | func (rd *APAIR) Copy(dest dns.PrivateRdata) error {
    method Len (line 118) | func (rd *APAIR) Len() int {
  function NewAPAIR (line 64) | func NewAPAIR() dns.PrivateRdata { return new(APAIR) }
  function ExamplePrivateHandle (line 122) | func ExamplePrivateHandle() {

FILE: format.go
  function NumField (line 10) | func NumField(r RR) int {
  function Field (line 18) | func Field(r RR, i int) string {

FILE: format_test.go
  function TestFieldEmptyAOrAAAAData (line 7) | func TestFieldEmptyAOrAAAAData(t *testing.T) {

FILE: fuzz.go
  function Fuzz (line 8) | func Fuzz(data []byte) int {
  function FuzzNewRR (line 21) | func FuzzNewRR(data []byte) int {

FILE: fuzz_test.go
  function TestPackDataOpt (line 15) | func TestPackDataOpt(t *testing.T) {
  function TestCrashNSEC (line 85) | func TestCrashNSEC(t *testing.T) {
  function TestCrashNSEC3 (line 119) | func TestCrashNSEC3(t *testing.T) {
  function TestNewRRCommentLengthCrasherString (line 148) | func TestNewRRCommentLengthCrasherString(t *testing.T) {

FILE: generate.go
  method generate (line 21) | func (zp *ZoneParser) generate(l lex) (RR, bool) {
  type generateReader (line 93) | type generateReader struct
    method parseError (line 112) | func (r *generateReader) parseError(msg string, end int) *ParseError {
    method Read (line 122) | func (r *generateReader) Read(p []byte) (int, error) {
    method ReadByte (line 129) | func (r *generateReader) ReadByte() (byte, error) {
  function modToPrintf (line 211) | func modToPrintf(s string) (string, int64, string) {

FILE: generate_test.go
  function TestGenerateRangeGuard (line 11) | func TestGenerateRangeGuard(t *testing.T) {
  function TestGenerateIncludeDepth (line 82) | func TestGenerateIncludeDepth(t *testing.T) {
  function TestGenerateIncludeDisallowed (line 111) | func TestGenerateIncludeDisallowed(t *testing.T) {
  function TestGenerateSurfacesErrors (line 126) | func TestGenerateSurfacesErrors(t *testing.T) {
  function TestGenerateSurfacesLexerErrors (line 141) | func TestGenerateSurfacesLexerErrors(t *testing.T) {
  function TestGenerateModToPrintf (line 156) | func TestGenerateModToPrintf(t *testing.T) {
  function BenchmarkGenerate (line 191) | func BenchmarkGenerate(b *testing.B) {
  function TestCrasherString (line 208) | func TestCrasherString(t *testing.T) {

FILE: hash.go
  type identityHash (line 10) | type identityHash struct
    method Write (line 16) | func (i identityHash) Write(b []byte) (int, error) { return i.b.Write(...
    method Size (line 17) | func (i identityHash) Size() int                   { return i.b.Len() }
    method BlockSize (line 18) | func (i identityHash) BlockSize() int              { return 1024 }
    method Reset (line 19) | func (i identityHash) Reset()                      { i.b.Reset() }
    method Sum (line 20) | func (i identityHash) Sum(b []byte) []byte         { return append(b, ...
  function hashFromAlgorithm (line 22) | func hashFromAlgorithm(alg uint8) (hash.Hash, crypto.Hash, error) {

FILE: issue_test.go
  function TestNSEC3MissingSalt (line 10) | func TestNSEC3MissingSalt(t *testing.T) {
  function TestNSEC3MixedNextDomain (line 28) | func TestNSEC3MixedNextDomain(t *testing.T) {

FILE: labels.go
  function SplitDomainName (line 12) | func SplitDomainName(s string) (labels []string) {
  function CompareDomainName (line 49) | func CompareDomainName(s1, s2 string) (n int) {
  function CountLabel (line 88) | func CountLabel(s string) (labels int) {
  function Split (line 107) | func Split(s string) []int {
  function NextLabel (line 128) | func NextLabel(s string, offset int) (i int, end bool) {
  function PrevLabel (line 154) | func PrevLabel(s string, n int) (i int, start bool) {
  function equal (line 190) | func equal(a, b string) bool {

FILE: labels_test.go
  function TestCompareDomainName (line 5) | func TestCompareDomainName(t *testing.T) {
  function TestSplit (line 41) | func TestSplit(t *testing.T) {
  function TestSplit2 (line 62) | func TestSplit2(t *testing.T) {
  function TestNextLabel (line 83) | func TestNextLabel(t *testing.T) {
  function TestPrevLabel (line 102) | func TestPrevLabel(t *testing.T) {
  function TestCountLabel (line 131) | func TestCountLabel(t *testing.T) {
  function TestSplitDomainName (line 146) | func TestSplitDomainName(t *testing.T) {
  function TestIsDomainName (line 173) | func TestIsDomainName(t *testing.T) {
  function TestIsFqdnEscaped (line 201) | func TestIsFqdnEscaped(t *testing.T) {
  function TestCanonicalName (line 237) | func TestCanonicalName(t *testing.T) {
  function BenchmarkSplitLabels (line 255) | func BenchmarkSplitLabels(b *testing.B) {
  function BenchmarkLenLabels (line 261) | func BenchmarkLenLabels(b *testing.B) {
  function BenchmarkCompareDomainName (line 267) | func BenchmarkCompareDomainName(b *testing.B) {
  function BenchmarkIsSubDomain (line 274) | func BenchmarkIsSubDomain(b *testing.B) {
  function BenchmarkNextLabelSimple (line 283) | func BenchmarkNextLabelSimple(b *testing.B) {
  function BenchmarkPrevLabelSimple (line 292) | func BenchmarkPrevLabelSimple(b *testing.B) {
  function BenchmarkNextLabelComplex (line 301) | func BenchmarkNextLabelComplex(b *testing.B) {
  function BenchmarkPrevLabelComplex (line 310) | func BenchmarkPrevLabelComplex(b *testing.B) {
  function BenchmarkNextLabelMixed (line 319) | func BenchmarkNextLabelMixed(b *testing.B) {
  function BenchmarkPrevLabelMixed (line 331) | func BenchmarkPrevLabelMixed(b *testing.B) {

FILE: leak_test.go
  function interestingGoroutines (line 15) | func interestingGoroutines() (gs []string) {
  function goroutineLeaked (line 45) | func goroutineLeaked() error {

FILE: length_test.go
  function TestCompressLength (line 11) | func TestCompressLength(t *testing.T) {
  function TestMsgCompressLength (line 22) | func TestMsgCompressLength(t *testing.T) {
  function TestMsgLength (line 53) | func TestMsgLength(t *testing.T) {
  function TestCompressionLenSearchInsert (line 84) | func TestCompressionLenSearchInsert(t *testing.T) {
  function TestCompressionLenSearch (line 140) | func TestCompressionLenSearch(t *testing.T) {
  function TestMsgLength2 (line 170) | func TestMsgLength2(t *testing.T) {
  function TestMsgLengthCompressionMalformed (line 210) | func TestMsgLengthCompressionMalformed(t *testing.T) {
  function TestMsgCompressLength2 (line 226) | func TestMsgCompressLength2(t *testing.T) {
  function TestMsgCompressLengthLargeRecords (line 243) | func TestMsgCompressLengthLargeRecords(t *testing.T) {
  function compressionMapsEqual (line 263) | func compressionMapsEqual(a map[string]struct{}, b map[string]int) bool {
  function compressionMapsDifference (line 277) | func compressionMapsDifference(a map[string]struct{}, b map[string]int) ...
  function TestCompareCompressionMapsForANY (line 309) | func TestCompareCompressionMapsForANY(t *testing.T) {
  function TestCompareCompressionMapsForSRV (line 342) | func TestCompareCompressionMapsForSRV(t *testing.T) {
  function TestMsgCompressLengthLargeRecordsWithPaddingPermutation (line 375) | func TestMsgCompressLengthLargeRecordsWithPaddingPermutation(t *testing....
  function TestMsgCompressLengthLargeRecordsAllValues (line 398) | func TestMsgCompressLengthLargeRecordsAllValues(t *testing.T) {
  function TestMsgCompressionMultipleQuestions (line 426) | func TestMsgCompressionMultipleQuestions(t *testing.T) {
  function TestMsgCompressMultipleCompressedNames (line 442) | func TestMsgCompressMultipleCompressedNames(t *testing.T) {
  function TestMsgCompressLengthEscapingMatch (line 467) | func TestMsgCompressLengthEscapingMatch(t *testing.T) {
  function TestMsgLengthEscaped (line 488) | func TestMsgLengthEscaped(t *testing.T) {
  function TestMsgCompressLengthEscaped (line 502) | func TestMsgCompressLengthEscaped(t *testing.T) {

FILE: listen_no_socket_options.go
  constant supportsReusePort (line 12) | supportsReusePort = false
  constant supportsReuseAddr (line 13) | supportsReuseAddr = false
  function listenTCP (line 16) | func listenTCP(network, addr string, reuseport, reuseaddr bool) (net.Lis...
  function listenUDP (line 24) | func listenUDP(network, addr string, reuseport, reuseaddr bool) (net.Pac...
  function checkReuseport (line 33) | func checkReuseport(fd uintptr) (bool, error) {
  function checkReuseaddr (line 38) | func checkReuseaddr(fd uintptr) (bool, error) {

FILE: listen_socket_options.go
  constant supportsReusePort (line 14) | supportsReusePort = true
  function reuseportControl (line 16) | func reuseportControl(network, address string, c syscall.RawConn) error {
  constant supportsReuseAddr (line 28) | supportsReuseAddr = true
  function reuseaddrControl (line 30) | func reuseaddrControl(network, address string, c syscall.RawConn) error {
  function reuseaddrandportControl (line 42) | func reuseaddrandportControl(network, address string, c syscall.RawConn)...
  function checkReuseport (line 52) | func checkReuseport(fd uintptr) (bool, error) {
  function checkReuseaddr (line 62) | func checkReuseaddr(fd uintptr) (bool, error) {
  function listenTCP (line 71) | func listenTCP(network, addr string, reuseport, reuseaddr bool) (net.Lis...
  function listenUDP (line 85) | func listenUDP(network, addr string, reuseport, reuseaddr bool) (net.Pac...

FILE: msg.go
  constant maxCompressionOffset (line 23) | maxCompressionOffset    = 2 << 13
  constant maxDomainNameWireOctets (line 24) | maxDomainNameWireOctets = 255
  constant maxCompressionPointers (line 36) | maxCompressionPointers = (maxDomainNameWireOctets+1)/2 - 2
  constant maxDomainNamePresentationLength (line 46) | maxDomainNamePresentationLength = 61*4 + 1 + 63*4 + 1 + 63*4 + 1 + 63*4 + 1
  function id (line 84) | func id() uint16 {
  type MsgHdr (line 94) | type MsgHdr struct
    method String (line 681) | func (h *MsgHdr) String() string {
  type Msg (line 109) | type Msg struct
    method Pack (line 722) | func (dns *Msg) Pack() (msg []byte, err error) {
    method PackBuffer (line 727) | func (dns *Msg) PackBuffer(buf []byte) (msg []byte, err error) {
    method packBufferWithCompressionMap (line 739) | func (dns *Msg) packBufferWithCompressionMap(buf []byte, compression c...
    method unpack (line 827) | func (dns *Msg) unpack(dh Header, msg []byte, off int) (err error) {
    method Unpack (line 883) | func (dns *Msg) Unpack(msg []byte) (err error) {
    method String (line 894) | func (dns *Msg) String() string {
    method isCompressible (line 961) | func (dns *Msg) isCompressible() bool {
    method Len (line 971) | func (dns *Msg) Len() int {
    method Copy (line 1073) | func (dns *Msg) Copy() *Msg { return dns.CopyTo(new(Msg)) }
    method CopyTo (line 1076) | func (dns *Msg) CopyTo(r1 *Msg) *Msg {
    method setHdr (line 1213) | func (dns *Msg) setHdr(dh Header) {
  type compressionMap (line 168) | type compressionMap struct
    method valid (line 173) | func (m compressionMap) valid() bool {
    method insert (line 177) | func (m compressionMap) insert(s string, pos int) {
    method find (line 185) | func (m compressionMap) find(s string) (int, bool) {
  function PackDomainName (line 202) | func PackDomainName(s string, msg []byte, off int, compression map[strin...
  function packDomainName (line 206) | func packDomainName(s string, msg []byte, off int, compression compressi...
  function isRootLabel (line 354) | func isRootLabel(s string, bs []byte, off, end int) bool {
  function UnpackDomainName (line 381) | func UnpackDomainName(msg []byte, off int) (string, int, error) {
  function packTxt (line 454) | func packTxt(txt []string, msg []byte, offset int) (int, error) {
  function packTxtString (line 472) | func packTxtString(s string, msg []byte, offset int) (int, error) {
  function packOctetString (line 507) | func packOctetString(s string, msg []byte, offset int) (int, error) {
  function unpackTxt (line 535) | func unpackTxt(msg []byte, off0 int) (ss []string, off int, err error) {
  function isDigit (line 548) | func isDigit(b byte) bool { return b >= '0' && b <= '9' }
  function isDDD (line 550) | func isDDD[T ~[]byte | ~string](s T) bool {
  function dddToByte (line 554) | func dddToByte[T ~[]byte | ~string](s T) byte {
  function intToBytes (line 560) | func intToBytes(i *big.Int, length int) []byte {
  function PackRR (line 572) | func PackRR(rr RR, msg []byte, off int, compression map[string]int, comp...
  function packRR (line 582) | func packRR(rr RR, msg []byte, off int, compression compressionMap, comp...
  function UnpackRR (line 608) | func UnpackRR(msg []byte, off int) (rr RR, off1 int, err error) {
  function UnpackRRWithHeader (line 619) | func UnpackRRWithHeader(h RR_Header, msg []byte, off int) (rr RR, off1 i...
  function unpackRRslice (line 653) | func unpackRRslice(l int, msg []byte, off int) (dst1 []RR, off1 int, err...
  function msgLenWithCompressionMap (line 982) | func msgLenWithCompressionMap(dns *Msg, compression map[string]struct{})...
  function domainNameLen (line 1007) | func domainNameLen(s string, off int, compression map[string]struct{}, c...
  function escapedNameLen (line 1033) | func escapedNameLen(s string) int {
  function compressionLenSearch (line 1052) | func compressionLenSearch(c map[string]struct{}, s string, msgOff int) (...
  function Copy (line 1067) | func Copy(r RR) RR { return r.copy() }
  function Len (line 1070) | func Len(r RR) int { return r.len(0, nil) }
  method pack (line 1105) | func (q *Question) pack(msg []byte, off int, compression compressionMap,...
  function unpackQuestion (line 1121) | func unpackQuestion(msg []byte, off int) (Question, int, error) {
  method pack (line 1152) | func (dh *Header) pack(msg []byte, off int, compression compressionMap, ...
  function unpackMsgHdr (line 1180) | func unpackMsgHdr(msg []byte, off int) (Header, int, error) {

FILE: msg_generate.go
  function getTypeStruct (line 35) | func getTypeStruct(t types.Type, scope *types.Scope) (*types.Struct, boo...
  function loadModule (line 54) | func loadModule(name string) (*types.Package, error) {
  function main (line 63) | func main() {
  function structMember (line 335) | func structMember(s string) string {
  function structTag (line 341) | func structTag(s string) string {
  function fatalIfErr (line 347) | func fatalIfErr(err error) {

FILE: msg_helpers.go
  function unpackDataA (line 19) | func unpackDataA(msg []byte, off int) (net.IP, int, error) {
  function packDataA (line 26) | func packDataA(a net.IP, msg []byte, off int) (int, error) {
  function unpackDataAAAA (line 44) | func unpackDataAAAA(msg []byte, off int) (net.IP, int, error) {
  function packDataAAAA (line 51) | func packDataAAAA(aaaa net.IP, msg []byte, off int) (int, error) {
  function unpackHeader (line 70) | func unpackHeader(msg []byte, off int) (rr RR_Header, off1 int, truncmsg...
  method packHeader (line 102) | func (hdr RR_Header) packHeader(msg []byte, off int, compression compres...
  function truncateMsgFromRdlength (line 134) | func truncateMsgFromRdlength(msg []byte, off int, rdlength uint16) (trun...
  function fromBase32 (line 144) | func fromBase32(s []byte) (buf []byte, err error) {
  function toBase32 (line 157) | func toBase32(b []byte) string {
  function fromBase64 (line 161) | func fromBase64(s []byte) (buf []byte, err error) {
  function toBase64 (line 169) | func toBase64(b []byte) string { return base64.StdEncoding.EncodeToStrin...
  function noRdata (line 172) | func noRdata(h RR_Header) bool { return h.Rdlength == 0 }
  function unpackUint8 (line 174) | func unpackUint8(msg []byte, off int) (i uint8, off1 int, err error) {
  function packUint8 (line 181) | func packUint8(i uint8, msg []byte, off int) (off1 int, err error) {
  function unpackUint16 (line 189) | func unpackUint16(msg []byte, off int) (i uint16, off1 int, err error) {
  function packUint16 (line 196) | func packUint16(i uint16, msg []byte, off int) (off1 int, err error) {
  function unpackUint32 (line 204) | func unpackUint32(msg []byte, off int) (i uint32, off1 int, err error) {
  function packUint32 (line 211) | func packUint32(i uint32, msg []byte, off int) (off1 int, err error) {
  function unpackUint48 (line 219) | func unpackUint48(msg []byte, off int) (i uint64, off1 int, err error) {
  function packUint48 (line 230) | func packUint48(i uint64, msg []byte, off int) (off1 int, err error) {
  function unpackUint64 (line 244) | func unpackUint64(msg []byte, off int) (i uint64, off1 int, err error) {
  function packUint64 (line 251) | func packUint64(i uint64, msg []byte, off int) (off1 int, err error) {
  function unpackString (line 260) | func unpackString(msg []byte, off int) (string, int, error) {
  function packString (line 297) | func packString(s string, msg []byte, off int) (int, error) {
  function unpackStringBase32 (line 305) | func unpackStringBase32(msg []byte, off, end int) (string, int, error) {
  function packStringBase32 (line 313) | func packStringBase32(s string, msg []byte, off int) (int, error) {
  function unpackStringBase64 (line 326) | func unpackStringBase64(msg []byte, off, end int) (string, int, error) {
  function packStringBase64 (line 337) | func packStringBase64(s string, msg []byte, off int) (int, error) {
  function unpackStringHex (line 350) | func unpackStringHex(msg []byte, off, end int) (string, int, error) {
  function packStringHex (line 362) | func packStringHex(s string, msg []byte, off int) (int, error) {
  function unpackStringAny (line 375) | func unpackStringAny(msg []byte, off, end int) (string, int, error) {
  function packStringAny (line 382) | func packStringAny(s string, msg []byte, off int) (int, error) {
  function unpackStringTxt (line 391) | func unpackStringTxt(msg []byte, off int) ([]string, int, error) {
  function packStringTxt (line 399) | func packStringTxt(s []string, msg []byte, off int) (int, error) {
  function unpackDataOpt (line 407) | func unpackDataOpt(msg []byte, off int) ([]EDNS0, int, error) {
  function packDataOpt (line 430) | func packDataOpt(options []EDNS0, msg []byte, off int) (int, error) {
  function unpackStringOctet (line 449) | func unpackStringOctet(msg []byte, off int) (string, int, error) {
  function packStringOctet (line 454) | func packStringOctet(s string, msg []byte, off int) (int, error) {
  function unpackDataNsec (line 462) | func unpackDataNsec(msg []byte, off int) ([]uint16, int, error) {
  function typeBitMapLen (line 524) | func typeBitMapLen(bitmap []uint16) int {
  function packDataNsec (line 545) | func packDataNsec(bitmap []uint16, msg []byte, off int) (int, error) {
  function unpackDataSVCB (line 585) | func unpackDataSVCB(msg []byte, off int) ([]SVCBKeyValue, int, error) {
  function packDataSVCB (line 615) | func packDataSVCB(pairs []SVCBKeyValue, msg []byte, off int) (int, error) {
  function unpackDataDomainNames (line 644) | func unpackDataDomainNames(msg []byte, off, end int) ([]string, int, err...
  function packDataDomainNames (line 663) | func packDataDomainNames(names []string, msg []byte, off int, compressio...
  function packDataApl (line 674) | func packDataApl(data []APLPrefix, msg []byte, off int) (int, error) {
  function packDataAplPrefix (line 685) | func packDataAplPrefix(p *APLPrefix, msg []byte, off int) (int, error) {
  function unpackDataApl (line 736) | func unpackDataApl(msg []byte, off int) ([]APLPrefix, int, error) {
  function unpackDataAplPrefix (line 749) | func unpackDataAplPrefix(msg []byte, off int) (APLPrefix, int, error) {
  function unpackIPSECGateway (line 802) | func unpackIPSECGateway(msg []byte, off int, gatewayType uint8) (net.IP,...
  function packIPSECGateway (line 820) | func packIPSECGateway(gatewayAddr net.IP, gatewayString string, msg []by...

FILE: msg_helpers_test.go
  function TestPackDataNsec (line 13) | func TestPackDataNsec(t *testing.T) {
  function TestPackDataNsecDirtyBuffer (line 140) | func TestPackDataNsecDirtyBuffer(t *testing.T) {
  function BenchmarkPackDataNsec (line 153) | func BenchmarkPackDataNsec(b *testing.B) {
  function TestUnpackString (line 171) | func TestUnpackString(t *testing.T) {
  function BenchmarkUnpackString (line 185) | func BenchmarkUnpackString(b *testing.B) {
  function TestPackDataAplPrefix (line 218) | func TestPackDataAplPrefix(t *testing.T) {
  function TestPackDataAplPrefix_Failures (line 292) | func TestPackDataAplPrefix_Failures(t *testing.T) {
  function TestPackDataAplPrefix_BufferBounds (line 324) | func TestPackDataAplPrefix_BufferBounds(t *testing.T) {
  function TestPackDataApl (line 354) | func TestPackDataApl(t *testing.T) {
  function TestUnpackDataAplPrefix (line 388) | func TestUnpackDataAplPrefix(t *testing.T) {
  function TestUnpackDataAplPrefix_Errors (line 447) | func TestUnpackDataAplPrefix_Errors(t *testing.T) {
  function TestUnpackDataApl (line 503) | func TestUnpackDataApl(t *testing.T) {

FILE: msg_test.go
  constant maxPrintableLabel (line 11) | maxPrintableLabel = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY...
  function TestPackNoSideEffect (line 31) | func TestPackNoSideEffect(t *testing.T) {
  function TestPackExtendedBadCookie (line 53) | func TestPackExtendedBadCookie(t *testing.T) {
  function TestUnPackExtendedRcode (line 92) | func TestUnPackExtendedRcode(t *testing.T) {
  function TestUnpackDomainName (line 124) | func TestUnpackDomainName(t *testing.T) {
  function TestPackDomainNameCompressionMap (line 222) | func TestPackDomainNameCompressionMap(t *testing.T) {
  function TestPackDomainNameNSECTypeBitmap (line 246) | func TestPackDomainNameNSECTypeBitmap(t *testing.T) {
  function TestPackUnpackManyCompressionPointers (line 291) | func TestPackUnpackManyCompressionPointers(t *testing.T) {
  function TestLenDynamicA (line 311) | func TestLenDynamicA(t *testing.T) {

FILE: msg_truncate.go
  method Truncate (line 29) | func (dns *Msg) Truncate(size int) {
  function truncateLoop (line 99) | func truncateLoop(rrs []RR, size, l int, compression map[string]struct{}...

FILE: msg_truncate_test.go
  function TestRequestTruncateAnswer (line 8) | func TestRequestTruncateAnswer(t *testing.T) {
  function TestRequestTruncateExtra (line 28) | func TestRequestTruncateExtra(t *testing.T) {
  function TestRequestTruncateExtraEdns0 (line 48) | func TestRequestTruncateExtraEdns0(t *testing.T) {
  function TestRequestTruncateExtraRegression (line 76) | func TestRequestTruncateExtraRegression(t *testing.T) {
  function TestTruncation (line 108) | func TestTruncation(t *testing.T) {
  function TestRequestTruncateAnswerExact (line 138) | func TestRequestTruncateAnswerExact(t *testing.T) {
  function BenchmarkMsgTruncate (line 160) | func BenchmarkMsgTruncate(b *testing.B) {

FILE: nsecx.go
  function HashName (line 10) | func HashName(label string, ha uint8, iter uint16, salt string) string {
  method Cover (line 47) | func (rr *NSEC3) Cover(name string) bool {
  method Match (line 79) | func (rr *NSEC3) Match(name string) bool {

FILE: nsecx_test.go
  function TestPackNsec3 (line 8) | func TestPackNsec3(t *testing.T) {
  function TestNsec3 (line 20) | func TestNsec3(t *testing.T) {
  function TestNsec3EmptySalt (line 150) | func TestNsec3EmptySalt(t *testing.T) {
  function BenchmarkHashName (line 158) | func BenchmarkHashName(b *testing.B) {

FILE: parse_test.go
  function TestDotInName (line 18) | func TestDotInName(t *testing.T) {
  function TestDotLastInLabel (line 36) | func TestDotLastInLabel(t *testing.T) {
  function TestTooLongDomainName (line 49) | func TestTooLongDomainName(t *testing.T) {
  function TestDomainName (line 62) | func TestDomainName(t *testing.T) {
  function TestDomainNameAndTXTEscapes (line 84) | func TestDomainNameAndTXTEscapes(t *testing.T) {
  function TestTXTEscapeParsing (line 113) | func TestTXTEscapeParsing(t *testing.T) {
  function GenerateDomain (line 147) | func GenerateDomain(r *rand.Rand, size int) []byte {
  function TestDomainQuick (line 175) | func TestDomainQuick(t *testing.T) {
  function GenerateTXT (line 205) | func GenerateTXT(r *rand.Rand, size int) []byte {
  function TestParseDirectiveMisc (line 228) | func TestParseDirectiveMisc(t *testing.T) {
  function TestNSEC (line 255) | func TestNSEC(t *testing.T) {
  function TestParseLOC (line 287) | func TestParseLOC(t *testing.T) {
  function TestStringToCm (line 334) | func TestStringToCm(t *testing.T) {
  function TestParseDS (line 394) | func TestParseDS(t *testing.T) {
  function TestQuotes (line 410) | func TestQuotes(t *testing.T) {
  function TestParseClass (line 442) | func TestParseClass(t *testing.T) {
  function TestBrace (line 464) | func TestBrace(t *testing.T) {
  function TestParseFailure (line 513) | func TestParseFailure(t *testing.T) {
  function TestOmittedTTL (line 534) | func TestOmittedTTL(t *testing.T) {
  function TestRelativeNameErrors (line 575) | func TestRelativeNameErrors(t *testing.T) {
  function TestHIP (line 618) | func TestHIP(t *testing.T) {
  function TestLineNumberError2 (line 655) | func TestLineNumberError2(t *testing.T) {
  function TestRfc1982 (line 679) | func TestRfc1982(t *testing.T) {
  function TestEmpty (line 719) | func TestEmpty(t *testing.T) {
  function TestLowercaseTokens (line 729) | func TestLowercaseTokens(t *testing.T) {
  function TestSRVPacking (line 755) | func TestSRVPacking(t *testing.T) {
  function TestParseBackslash (line 790) | func TestParseBackslash(t *testing.T) {
  function TestILNP (line 802) | func TestILNP(t *testing.T) {
  function TestGposEidNimloc (line 829) | func TestGposEidNimloc(t *testing.T) {
  function TestPX (line 849) | func TestPX(t *testing.T) {
  function TestComment (line 866) | func TestComment(t *testing.T) {
  function TestZoneParserComments (line 907) | func TestZoneParserComments(t *testing.T) {
  function TestEUIxx (line 1007) | func TestEUIxx(t *testing.T) {
  function TestUserRR (line 1023) | func TestUserRR(t *testing.T) {
  function TestTXT (line 1040) | func TestTXT(t *testing.T) {
  function TestTypeXXXX (line 1139) | func TestTypeXXXX(t *testing.T) {
  function TestPTR (line 1154) | func TestPTR(t *testing.T) {
  function TestDigit (line 1161) | func TestDigit(t *testing.T) {
  function TestParseRRSIGTimestamp (line 1188) | func TestParseRRSIGTimestamp(t *testing.T) {
  function TestTxtEqual (line 1201) | func TestTxtEqual(t *testing.T) {
  function TestTxtLong (line 1212) | func TestTxtLong(t *testing.T) {
  function TestMalformedPackets (line 1228) | func TestMalformedPackets(t *testing.T) {
  type algorithm (line 1241) | type algorithm struct
  function TestNewPrivateKey (line 1246) | func TestNewPrivateKey(t *testing.T) {
  function TestNewRRSpecial (line 1291) | func TestNewRRSpecial(t *testing.T) {
  function TestPrintfVerbsRdata (line 1353) | func TestPrintfVerbsRdata(t *testing.T) {
  function TestParseTokenOverflow (line 1389) | func TestParseTokenOverflow(t *testing.T) {
  function TestParseTLSA (line 1396) | func TestParseTLSA(t *testing.T) {
  function TestParseSMIMEA (line 1414) | func TestParseSMIMEA(t *testing.T) {
  function TestParseSSHFP (line 1433) | func TestParseSSHFP(t *testing.T) {
  function TestParseHINFO (line 1453) | func TestParseHINFO(t *testing.T) {
  function TestParseISDN (line 1476) | func TestParseISDN(t *testing.T) {
  function TestParseCAA (line 1493) | func TestParseCAA(t *testing.T) {
  function TestPackCAA (line 1513) | func TestPackCAA(t *testing.T) {
  function TestParseURI (line 1542) | func TestParseURI(t *testing.T) {
  function TestParseAVC (line 1559) | func TestParseAVC(t *testing.T) {
  function TestParseCSYNC (line 1575) | func TestParseCSYNC(t *testing.T) {
  function TestParseSVCB (line 1591) | func TestParseSVCB(t *testing.T) {
  function TestParseBadSVCB (line 1636) | func TestParseBadSVCB(t *testing.T) {
  function TestParseBadNAPTR (line 1687) | func TestParseBadNAPTR(t *testing.T) {
  function TestUnbalancedParens (line 1699) | func TestUnbalancedParens(t *testing.T) {
  function TestBad (line 1710) | func TestBad(t *testing.T) {
  function TestNULLRecord (line 1727) | func TestNULLRecord(t *testing.T) {
  function TestAAAAParsing (line 1740) | func TestAAAAParsing(t *testing.T) {
  function TestParseAPL (line 1768) | func TestParseAPL(t *testing.T) {
  function TestParseAPLErrors (line 1850) | func TestParseAPLErrors(t *testing.T) {
  function TestUnpackRRWithHeaderInvalidLengths (line 1902) | func TestUnpackRRWithHeaderInvalidLengths(t *testing.T) {
  function TestParseZONEMD (line 1940) | func TestParseZONEMD(t *testing.T) {
  function TestParseIPSECKEY (line 2011) | func TestParseIPSECKEY(t *testing.T) {
  function TestParseAMTRELAY (line 2027) | func TestParseAMTRELAY(t *testing.T) {
  function TestParseOPENPGPKEY (line 2043) | func TestParseOPENPGPKEY(t *testing.T) {
  function TestParseRRSIGAlgNames (line 2057) | func TestParseRRSIGAlgNames(t *testing.T) {

FILE: privaterr.go
  type PrivateRdata (line 8) | type PrivateRdata interface
  type PrivateRR (line 25) | type PrivateRR struct
    method Header (line 33) | func (r *PrivateRR) Header() *RR_Header { return &r.Hdr }
    method String (line 35) | func (r *PrivateRR) String() string { return r.Hdr.String() + r.Data.S...
    method len (line 38) | func (r *PrivateRR) len(off int, compression map[string]struct{}) int {
    method copy (line 44) | func (r *PrivateRR) copy() RR {
    method pack (line 55) | func (r *PrivateRR) pack(msg []byte, off int, compression compressionM...
    method unpack (line 64) | func (r *PrivateRR) unpack(msg []byte, off int) (int, error) {
    method parse (line 70) | func (r *PrivateRR) parse(c *zlexer, origin string) *ParseError {
    method isDuplicate (line 93) | func (r *PrivateRR) isDuplicate(r2 RR) bool { return false }
  function PrivateHandle (line 97) | func PrivateHandle(rtypestr string, rtype uint16, generator func() Priva...
  function PrivateHandleRemove (line 106) | func PrivateHandleRemove(rtype uint16) {

FILE: privaterr_test.go
  constant TypeISBN (line 10) | TypeISBN uint16 = 0xFF00
  type ISBN (line 13) | type ISBN struct
    method Len (line 19) | func (rd *ISBN) Len() int       { return len([]byte(rd.x)) }
    method String (line 20) | func (rd *ISBN) String() string { return rd.x }
    method Parse (line 22) | func (rd *ISBN) Parse(txt []string) error {
    method Pack (line 27) | func (rd *ISBN) Pack(buf []byte) (int, error) {
    method Unpack (line 36) | func (rd *ISBN) Unpack(buf []byte) (int, error) {
    method Copy (line 41) | func (rd *ISBN) Copy(dest dns.PrivateRdata) error {
  function NewISBN (line 17) | func NewISBN() dns.PrivateRdata { return &ISBN{""} }
  function TestPrivateText (line 52) | func TestPrivateText(t *testing.T) {
  function TestPrivateByteSlice (line 65) | func TestPrivateByteSlice(t *testing.T) {
  constant TypeVERSION (line 100) | TypeVERSION uint16 = 0xFF01
  type VERSION (line 102) | type VERSION struct
    method String (line 108) | func (rd *VERSION) String() string { return rd.x }
    method Parse (line 109) | func (rd *VERSION) Parse(txt []string) error {
    method Pack (line 114) | func (rd *VERSION) Pack(buf []byte) (int, error) {
    method Unpack (line 123) | func (rd *VERSION) Unpack(buf []byte) (int, error) {
    method Copy (line 128) | func (rd *VERSION) Copy(dest dns.PrivateRdata) error {
    method Len (line 137) | func (rd *VERSION) Len() int {
  function NewVersion (line 106) | func NewVersion() dns.PrivateRdata { return &VERSION{""} }
  function TestPrivateZoneParser (line 154) | func TestPrivateZoneParser(t *testing.T) {

FILE: reverse.go
  function init (line 15) | func init() {
  function reverseInt8 (line 33) | func reverseInt8(m map[uint8]string) map[string]uint8 {
  function reverseInt16 (line 41) | func reverseInt16(m map[uint16]string) map[string]uint16 {
  function reverseInt (line 49) | func reverseInt(m map[int]string) map[string]int {

FILE: rr_test.go
  function testRR (line 4) | func testRR(s string) RR {

FILE: sanitize.go
  function Dedup (line 7) | func Dedup(rrs []RR, m map[string]RR) []RR {
  function normalizedString (line 56) | func normalizedString(r RR) string {

FILE: sanitize_test.go
  function TestDedup (line 5) | func TestDedup(t *testing.T) {
  function BenchmarkDedup (line 51) | func BenchmarkDedup(b *testing.B) {
  function TestNormalizedString (line 63) | func TestNormalizedString(t *testing.T) {

FILE: scan.go
  constant maxTok (line 16) | maxTok = 512
  constant maxIncludeDepth (line 20) | maxIncludeDepth = 7
  constant zEOF (line 30) | zEOF = iota
  constant zString (line 31) | zString
  constant zBlank (line 32) | zBlank
  constant zQuote (line 33) | zQuote
  constant zNewline (line 34) | zNewline
  constant zRrtpe (line 35) | zRrtpe
  constant zOwner (line 36) | zOwner
  constant zClass (line 37) | zClass
  constant zDirOrigin (line 38) | zDirOrigin
  constant zDirTTL (line 39) | zDirTTL
  constant zDirInclude (line 40) | zDirInclude
  constant zDirGenerate (line 41) | zDirGenerate
  constant zValue (line 44) | zValue
  constant zKey (line 45) | zKey
  constant zExpectOwnerDir (line 47) | zExpectOwnerDir
  constant zExpectOwnerBl (line 48) | zExpectOwnerBl
  constant zExpectAny (line 49) | zExpectAny
  constant zExpectAnyNoClass (line 50) | zExpectAnyNoClass
  constant zExpectAnyNoClassBl (line 51) | zExpectAnyNoClassBl
  constant zExpectAnyNoTTL (line 52) | zExpectAnyNoTTL
  constant zExpectAnyNoTTLBl (line 53) | zExpectAnyNoTTLBl
  constant zExpectRrtype (line 54) | zExpectRrtype
  constant zExpectRrtypeBl (line 55) | zExpectRrtypeBl
  constant zExpectRdata (line 56) | zExpectRdata
  constant zExpectDirTTLBl (line 57) | zExpectDirTTLBl
  constant zExpectDirTTL (line 58) | zExpectDirTTL
  constant zExpectDirOriginBl (line 59) | zExpectDirOriginBl
  constant zExpectDirOrigin (line 60) | zExpectDirOrigin
  constant zExpectDirIncludeBl (line 61) | zExpectDirIncludeBl
  constant zExpectDirInclude (line 62) | zExpectDirInclude
  constant zExpectDirGenerate (line 63) | zExpectDirGenerate
  constant zExpectDirGenerateBl (line 64) | zExpectDirGenerateBl
  type ParseError (line 69) | type ParseError struct
    method Error (line 76) | func (e *ParseError) Error() (s string) {
    method Unwrap (line 88) | func (e *ParseError) Unwrap() error { return e.wrappedErr }
  type lex (line 90) | type lex struct
  type ttlState (line 100) | type ttlState struct
  function NewRR (line 114) | func NewRR(s string) (RR, error) {
  function ReadRR (line 127) | func ReadRR(r io.Reader, file string) (RR, error) {
  type ZoneParser (line 168) | type ZoneParser struct
    method SetDefaultTTL (line 219) | func (zp *ZoneParser) SetDefaultTTL(ttl uint32) {
    method SetIncludeAllowed (line 232) | func (zp *ZoneParser) SetIncludeAllowed(v bool) {
    method SetIncludeFS (line 250) | func (zp *ZoneParser) SetIncludeFS(fsys fs.FS) {
    method Err (line 256) | func (zp *ZoneParser) Err() error {
    method setParseError (line 270) | func (zp *ZoneParser) setParseError(err string, l lex) (RR, bool) {
    method Comment (line 277) | func (zp *ZoneParser) Comment() string {
    method subNext (line 289) | func (zp *ZoneParser) subNext() (RR, bool) {
    method Next (line 315) | func (zp *ZoneParser) Next() (RR, bool) {
  function NewZoneParser (line 199) | func NewZoneParser(r io.Reader, origin, file string) *ZoneParser {
  type zlexer (line 705) | type zlexer struct
    method Err (line 746) | func (zl *zlexer) Err() error {
    method readByte (line 755) | func (zl *zlexer) readByte() (byte, bool) {
    method Peek (line 783) | func (zl *zlexer) Peek() lex {
    method Next (line 804) | func (zl *zlexer) Next() (lex, bool) {
    method Comment (line 1199) | func (zl *zlexer) Comment() string {
  function newZLexer (line 731) | func newZLexer(r io.Reader) *zlexer {
  function classToInt (line 1208) | func classToInt(token string) (uint16, bool) {
  function typeToInt (line 1221) | func typeToInt(token string) (uint16, bool) {
  function stringToTTL (line 1234) | func stringToTTL(token string) (uint32, bool) {
  function stringToCm (line 1269) | func stringToCm(token string) (e, m uint8, ok bool) {
  function toAbsoluteName (line 1315) | func toAbsoluteName(name, origin string) (absolute string, ok bool) {
  function appendOrigin (line 1350) | func appendOrigin(name, origin string) string {
  function locCheckNorth (line 1358) | func locCheckNorth(token string, latitude uint32) (uint32, bool) {
  function locCheckEast (line 1372) | func locCheckEast(token string, longitude uint32) (uint32, bool) {
  function slurpRemainder (line 1386) | func slurpRemainder(c *zlexer) *ParseError {
  function stringToNodeID (line 1404) | func stringToNodeID(l lex) (uint64, *ParseError) {

FILE: scan_rr.go
  function endingToString (line 14) | func endingToString(c *zlexer, errstr string) (string, *ParseError) {
  function endingToTxtSlice (line 36) | func endingToTxtSlice(c *zlexer, errstr string) ([]string, *ParseError) {
  method parse (line 96) | func (rr *A) parse(c *zlexer, o string) *ParseError {
  method parse (line 110) | func (rr *AAAA) parse(c *zlexer, o string) *ParseError {
  method parse (line 122) | func (rr *NS) parse(c *zlexer, o string) *ParseError {
  method parse (line 132) | func (rr *PTR) parse(c *zlexer, o string) *ParseError {
  method parse (line 142) | func (rr *NSAPPTR) parse(c *zlexer, o string) *ParseError {
  method parse (line 152) | func (rr *RP) parse(c *zlexer, o string) *ParseError {
  method parse (line 173) | func (rr *MR) parse(c *zlexer, o string) *ParseError {
  method parse (line 183) | func (rr *MB) parse(c *zlexer, o string) *ParseError {
  method parse (line 193) | func (rr *MG) parse(c *zlexer, o string) *ParseError {
  method parse (line 203) | func (rr *HINFO) parse(c *zlexer, o string) *ParseError {
  method parse (line 226) | func (rr *ISDN) parse(c *zlexer, o string) *ParseError {
  method parse (line 249) | func (rr *MINFO) parse(c *zlexer, o string) *ParseError {
  method parse (line 270) | func (rr *MF) parse(c *zlexer, o string) *ParseError {
  method parse (line 280) | func (rr *MD) parse(c *zlexer, o string) *ParseError {
  method parse (line 290) | func (rr *MX) parse(c *zlexer, o string) *ParseError {
  method parse (line 311) | func (rr *RT) parse(c *zlexer, o string) *ParseError {
  method parse (line 332) | func (rr *AFSDB) parse(c *zlexer, o string) *ParseError {
  method parse (line 352) | func (rr *X25) parse(c *zlexer, o string) *ParseError {
  method parse (line 361) | func (rr *KX) parse(c *zlexer, o string) *ParseError {
  method parse (line 381) | func (rr *CNAME) parse(c *zlexer, o string) *ParseError {
  method parse (line 391) | func (rr *DNAME) parse(c *zlexer, o string) *ParseError {
  method parse (line 401) | func (rr *SOA) parse(c *zlexer, o string) *ParseError {
  method parse (line 463) | func (rr *SRV) parse(c *zlexer, o string) *ParseError {
  method parse (line 499) | func (rr *NAPTR) parse(c *zlexer, o string) *ParseError {
  method parse (line 585) | func (rr *TALINK) parse(c *zlexer, o string) *ParseError {
  method parse (line 606) | func (rr *LOC) parse(c *zlexer, o string) *ParseError {
  method parse (line 737) | func (rr *HIP) parse(c *zlexer, o string) *ParseError {
  method parse (line 789) | func (rr *CERT) parse(c *zlexer, o string) *ParseError {
  method parse (line 822) | func (rr *OPENPGPKEY) parse(c *zlexer, o string) *ParseError {
  method parse (line 831) | func (rr *CSYNC) parse(c *zlexer, o string) *ParseError {
  method parse (line 876) | func (rr *ZONEMD) parse(c *zlexer, o string) *ParseError {
  method parse (line 908) | func (rr *SIG) parse(c *zlexer, o string) *ParseError { return rr.RRSIG....
  method parse (line 910) | func (rr *RRSIG) parse(c *zlexer, o string) *ParseError {
  method parse (line 1009) | func (rr *NXT) parse(c *zlexer, o string) *ParseError { return rr.NSEC.p...
  method parse (line 1011) | func (rr *NSEC) parse(c *zlexer, o string) *ParseError {
  method parse (line 1045) | func (rr *NSEC3) parse(c *zlexer, o string) *ParseError {
  method parse (line 1110) | func (rr *NSEC3PARAM) parse(c *zlexer, o string) *ParseError {
  method parse (line 1140) | func (rr *EUI48) parse(c *zlexer, o string) *ParseError {
  method parse (line 1166) | func (rr *EUI64) parse(c *zlexer, o string) *ParseError {
  method parse (line 1192) | func (rr *SSHFP) parse(c *zlexer, o string) *ParseError {
  method parseDNSKEY (line 1215) | func (rr *DNSKEY) parseDNSKEY(c *zlexer, o, typ string) *ParseError {
  method parse (line 1244) | func (rr *DNSKEY) parse(c *zlexer, o string) *ParseError  { return rr.pa...
  method parse (line 1245) | func (rr *KEY) parse(c *zlexer, o string) *ParseError     { return rr.pa...
  method parse (line 1246) | func (rr *CDNSKEY) parse(c *zlexer, o string) *ParseError { return rr.pa...
  method parse (line 1247) | func (rr *DS) parse(c *zlexer, o string) *ParseError      { return rr.pa...
  method parse (line 1248) | func (rr *DLV) parse(c *zlexer, o string) *ParseError     { return rr.pa...
  method parse (line 1249) | func (rr *CDS) parse(c *zlexer, o string) *ParseError     { return rr.pa...
  method parse (line 1251) | func (rr *IPSECKEY) parse(c *zlexer, o string) *ParseError {
  method parse (line 1296) | func (rr *AMTRELAY) parse(c *zlexer, o string) *ParseError {
  function parseAddrHostUnion (line 1337) | func parseAddrHostUnion(token, o string, gatewayType uint8) (addr net.IP...
  method parse (line 1362) | func (rr *RKEY) parse(c *zlexer, o string) *ParseError {
  method parse (line 1391) | func (rr *EID) parse(c *zlexer, o string) *ParseError {
  method parse (line 1400) | func (rr *NIMLOC) parse(c *zlexer, o string) *ParseError {
  method parse (line 1409) | func (rr *GPOS) parse(c *zlexer, o string) *ParseError {
  method parseDS (line 1433) | func (rr *DS) parseDS(c *zlexer, o, typ string) *ParseError {
  method parse (line 1467) | func (rr *TA) parse(c *zlexer, o string) *ParseError {
  method parse (line 1501) | func (rr *TLSA) parse(c *zlexer, o string) *ParseError {
  method parse (line 1531) | func (rr *SMIMEA) parse(c *zlexer, o string) *ParseError {
  method parse (line 1561) | func (rr *RFC3597) parse(c *zlexer, o string) *ParseError {
  method parse (line 1585) | func (rr *SPF) parse(c *zlexer, o string) *ParseError {
  method parse (line 1594) | func (rr *AVC) parse(c *zlexer, o string) *ParseError {
  method parse (line 1603) | func (rr *TXT) parse(c *zlexer, o string) *ParseError {
  method parse (line 1614) | func (rr *NINFO) parse(c *zlexer, o string) *ParseError {
  method parse (line 1624) | func (rr *RESINFO) parse(c *zlexer, o string) *ParseError {
  method parse (line 1633) | func (rr *URI) parse(c *zlexer, o string) *ParseError {
  method parse (line 1660) | func (rr *DHCID) parse(c *zlexer, o string) *ParseError {
  method parse (line 1670) | func (rr *NID) parse(c *zlexer, o string) *ParseError {
  method parse (line 1687) | func (rr *L32) parse(c *zlexer, o string) *ParseError {
  method parse (line 1703) | func (rr *LP) parse(c *zlexer, o string) *ParseError {
  method parse (line 1722) | func (rr *L64) parse(c *zlexer, o string) *ParseError {
  method parse (line 1739) | func (rr *UID) parse(c *zlexer, o string) *ParseError {
  method parse (line 1749) | func (rr *GID) parse(c *zlexer, o string) *ParseError {
  method parse (line 1759) | func (rr *UINFO) parse(c *zlexer, o string) *ParseError {
  method parse (line 1771) | func (rr *PX) parse(c *zlexer, o string) *ParseError {
  method parse (line 1799) | func (rr *CAA) parse(c *zlexer, o string) *ParseError {
  method parse (line 1826) | func (rr *TKEY) parse(c *zlexer, o string) *ParseError {
  method parse (line 1867) | func (rr *APL) parse(c *zlexer, o string) *ParseError {
  function escapedStringOffset (line 1936) | func escapedStringOffset(s string, desiredByteOffset int) (int, bool) {

FILE: scan_test.go
  function TestZoneParserGenerate (line 14) | func TestZoneParserGenerate(t *testing.T) {
  function TestZoneParserInclude (line 53) | func TestZoneParserInclude(t *testing.T) {
  function TestZoneParserIncludeFS (line 102) | func TestZoneParserIncludeFS(t *testing.T) {
  function TestZoneParserIncludeFSPaths (line 141) | func TestZoneParserIncludeFSPaths(t *testing.T) {
  function TestZoneParserIncludeDisallowed (line 174) | func TestZoneParserIncludeDisallowed(t *testing.T) {
  function TestZoneParserAddressAAAA (line 199) | func TestZoneParserAddressAAAA(t *testing.T) {
  function TestZoneParserTargetBad (line 229) | func TestZoneParserTargetBad(t *testing.T) {
  function TestZoneParserAddressBad (line 245) | func TestZoneParserAddressBad(t *testing.T) {
  function TestParseTA (line 260) | func TestParseTA(t *testing.T) {
  type errReader (line 272) | type errReader struct
    method Read (line 274) | func (errReader) Read(p []byte) (int, error) { return 0, errTestReadEr...
  function TestParseZoneReadError (line 276) | func TestParseZoneReadError(t *testing.T) {
  function TestUnexpectedNewline (line 286) | func TestUnexpectedNewline(t *testing.T) {
  function TestParseRFC3597InvalidLength (line 321) | func TestParseRFC3597InvalidLength(t *testing.T) {
  function TestParseKnownRRAsRFC3597 (line 330) | func TestParseKnownRRAsRFC3597(t *testing.T) {
  function TestParseOpenEscape (line 378) | func TestParseOpenEscape(t *testing.T) {
  function BenchmarkNewRR (line 387) | func BenchmarkNewRR(b *testing.B) {
  function BenchmarkReadRR (line 399) | func BenchmarkReadRR(b *testing.B) {
  constant benchZone (line 415) | benchZone = `
  function BenchmarkZoneParser (line 434) | func BenchmarkZoneParser(b *testing.B) {
  function TestEscapedStringOffset (line 447) | func TestEscapedStringOffset(t *testing.T) {

FILE: serve_mux.go
  type ServeMux (line 18) | type ServeMux struct
    method match (line 31) | func (mux *ServeMux) match(q string, t uint16) Handler {
    method Handle (line 60) | func (mux *ServeMux) Handle(pattern string, handler Handler) {
    method HandleFunc (line 73) | func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseW...
    method HandleRemove (line 78) | func (mux *ServeMux) HandleRemove(pattern string) {
    method ServeDNS (line 96) | func (mux *ServeMux) ServeDNS(w ResponseWriter, req *Msg) {
  function NewServeMux (line 24) | func NewServeMux() *ServeMux {
  function Handle (line 112) | func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pa...
  function HandleRemove (line 116) | func HandleRemove(pattern string) { DefaultServeMux.HandleRemove(pattern) }
  function HandleFunc (line 120) | func HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) {

FILE: serve_mux_test.go
  function TestDotAsCatchAllWildcard (line 5) | func TestDotAsCatchAllWildcard(t *testing.T) {
  function TestCaseFolding (line 31) | func TestCaseFolding(t *testing.T) {
  function TestRootServer (line 46) | func TestRootServer(t *testing.T) {
  function BenchmarkMuxMatch (line 56) | func BenchmarkMuxMatch(b *testing.B) {

FILE: server.go
  constant maxTCPQueries (line 18) | maxTCPQueries = 128
  type Handler (line 25) | type Handler interface
  type HandlerFunc (line 33) | type HandlerFunc
    method ServeDNS (line 36) | func (f HandlerFunc) ServeDNS(w ResponseWriter, r *Msg) {
  type ResponseWriter (line 42) | type ResponseWriter interface
  type ConnectionStater (line 64) | type ConnectionStater interface
  type response (line 68) | type response struct
    method WriteMsg (line 747) | func (w *response) WriteMsg(m *Msg) (err error) {
    method Write (line 772) | func (w *response) Write(m []byte) (int, error) {
    method LocalAddr (line 798) | func (w *response) LocalAddr() net.Addr {
    method RemoteAddr (line 810) | func (w *response) RemoteAddr() net.Addr {
    method TsigStatus (line 824) | func (w *response) TsigStatus() error { return w.tsigStatus }
    method TsigTimersOnly (line 827) | func (w *response) TsigTimersOnly(b bool) { w.tsigTimersOnly = b }
    method Hijack (line 830) | func (w *response) Hijack() { w.hijacked = true }
    method Close (line 833) | func (w *response) Close() error {
    method ConnectionState (line 851) | func (w *response) ConnectionState() *tls.ConnectionState {
  function handleRefused (line 83) | func handleRefused(w ResponseWriter, r *Msg) {
  function HandleFailed (line 91) | func HandleFailed(w ResponseWriter, r *Msg) {
  function ListenAndServe (line 100) | func ListenAndServe(addr string, network string, handler Handler) error {
  function ListenAndServeTLS (line 107) | func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) ...
  function ActivateAndServe (line 131) | func ActivateAndServe(l net.Listener, p net.PacketConn, handler Handler)...
  type Writer (line 137) | type Writer interface
  type Reader (line 142) | type Reader interface
  type PacketConnReader (line 152) | type PacketConnReader interface
  type defaultReader (line 163) | type defaultReader struct
    method ReadTCP (line 169) | func (dr defaultReader) ReadTCP(conn net.Conn, timeout time.Duration) ...
    method ReadUDP (line 173) | func (dr defaultReader) ReadUDP(conn *net.UDPConn, timeout time.Durati...
    method ReadPacketConn (line 177) | func (dr defaultReader) ReadPacketConn(conn net.PacketConn, timeout ti...
  type DecorateReader (line 185) | type DecorateReader
  type DecorateWriter (line 189) | type DecorateWriter
  type MsgInvalidFunc (line 195) | type MsgInvalidFunc
  function defaultMsgInvalidFunc (line 199) | func defaultMsgInvalidFunc(m []byte, err error) {}
  type Server (line 202) | type Server struct
    method tsigProvider (line 260) | func (srv *Server) tsigProvider() TsigProvider {
    method isStarted (line 270) | func (srv *Server) isStarted() bool {
    method init (line 283) | func (srv *Server) init() {
    method ListenAndServe (line 309) | func (srv *Server) ListenAndServe() error {
    method ActivateAndServe (line 369) | func (srv *Server) ActivateAndServe() error {
    method Shutdown (line 402) | func (srv *Server) Shutdown() error {
    method ShutdownContext (line 411) | func (srv *Server) ShutdownContext(ctx context.Context) error {
    method getReadTimeout (line 455) | func (srv *Server) getReadTimeout() time.Duration {
    method serveTCP (line 463) | func (srv *Server) serveTCP(l net.Listener) error {
    method serveUDP (line 499) | func (srv *Server) serveUDP(l net.PacketConn) error {
    method serveTCPConn (line 561) | func (srv *Server) serveTCPConn(wg *sync.WaitGroup, rw net.Conn) {
    method serveUDPPacket (line 616) | func (srv *Server) serveUDPPacket(wg *sync.WaitGroup, m []byte, u net....
    method serveDNS (line 628) | func (srv *Server) serveDNS(m []byte, w *response) {
    method readTCP (line 686) | func (srv *Server) readTCP(conn net.Conn, timeout time.Duration) ([]by...
    method readUDP (line 710) | func (srv *Server) readUDP(conn *net.UDPConn, timeout time.Duration) (...
    method readPacketConn (line 728) | func (srv *Server) readPacketConn(conn net.PacketConn, timeout time.Du...
  function makeUDPBuffer (line 277) | func makeUDPBuffer(size int) func() interface{} {
  function unlockOnce (line 303) | func unlockOnce(l sync.Locker) func() {

FILE: server_test.go
  function HelloServer (line 20) | func HelloServer(w ResponseWriter, req *Msg) {
  function HelloServerBadID (line 29) | func HelloServerBadID(w ResponseWriter, req *Msg) {
  function HelloServerBadThenGoodID (line 39) | func HelloServerBadThenGoodID(w ResponseWriter, req *Msg) {
  function HelloServerEchoAddrPort (line 52) | func HelloServerEchoAddrPort(w ResponseWriter, req *Msg) {
  function AnotherHelloServer (line 62) | func AnotherHelloServer(w ResponseWriter, req *Msg) {
  function RunLocalServer (line 71) | func RunLocalServer(pc net.PacketConn, l net.Listener, opts ...func(*Ser...
  function RunLocalUDPServer (line 114) | func RunLocalUDPServer(laddr string, opts ...func(*Server)) (*Server, st...
  function RunLocalPacketConnServer (line 123) | func RunLocalPacketConnServer(laddr string, opts ...func(*Server)) (*Ser...
  function RunLocalTCPServer (line 130) | func RunLocalTCPServer(laddr string, opts ...func(*Server)) (*Server, st...
  function RunLocalTLSServer (line 139) | func RunLocalTLSServer(laddr string, config *tls.Config) (*Server, strin...
  function RunLocalUnixServer (line 145) | func RunLocalUnixServer(laddr string, opts ...func(*Server)) (*Server, s...
  function RunLocalUnixGramServer (line 154) | func RunLocalUnixGramServer(laddr string, opts ...func(*Server)) (*Serve...
  function RunLocalUnixSeqPacketServer (line 163) | func RunLocalUnixSeqPacketServer(laddr string) (chan interface{}, string...
  function TestServing (line 178) | func TestServing(t *testing.T) {
  function TestServeIgnoresZFlag (line 239) | func TestServeIgnoresZFlag(t *testing.T) {
  function TestServeNotImplemented (line 267) | func TestServeNotImplemented(t *testing.T) {
  function TestServingTLS (line 295) | func TestServingTLS(t *testing.T) {
  function TestServingTLSConnectionState (line 360) | func TestServingTLSConnectionState(t *testing.T) {
  function TestServingListenAndServe (line 447) | func TestServingListenAndServe(t *testing.T) {
  function TestServingListenAndServeTLS (line 474) | func TestServingListenAndServeTLS(t *testing.T) {
  function BenchmarkServe (line 511) | func BenchmarkServe(b *testing.B) {
  function BenchmarkServe6 (line 537) | func BenchmarkServe6(b *testing.B) {
  function HelloServerCompress (line 565) | func HelloServerCompress(w ResponseWriter, req *Msg) {
  function BenchmarkServeCompress (line 574) | func BenchmarkServeCompress(b *testing.B) {
  type maxRec (line 598) | type maxRec struct
  function HelloServerLargeResponse (line 605) | func HelloServerLargeResponse(resp ResponseWriter, req *Msg) {
  function TestServingLargeResponses (line 628) | func TestServingLargeResponses(t *testing.T) {
  function TestServingResponse (line 667) | func TestServingResponse(t *testing.T) {
  function TestShutdownTCP (line 694) | func TestShutdownTCP(t *testing.T) {
  function init (line 713) | func init() {
  function checkInProgressQueriesAtShutdownServer (line 719) | func checkInProgressQueriesAtShutdownServer(t *testing.T, srv *Server, a...
  function TestInProgressQueriesAtShutdownTCP (line 825) | func TestInProgressQueriesAtShutdownTCP(t *testing.T) {
  function TestShutdownTLS (line 835) | func TestShutdownTLS(t *testing.T) {
  function TestInProgressQueriesAtShutdownTLS (line 855) | func TestInProgressQueriesAtShutdownTLS(t *testing.T) {
  function TestHandlerCloseTCP (line 879) | func TestHandlerCloseTCP(t *testing.T) {
  function TestShutdownUDP (line 923) | func TestShutdownUDP(t *testing.T) {
  function TestShutdownPacketConn (line 942) | func TestShutdownPacketConn(t *testing.T) {
  function TestInProgressQueriesAtShutdownUDP (line 961) | func TestInProgressQueriesAtShutdownUDP(t *testing.T) {
  function TestInProgressQueriesAtShutdownPacketConn (line 971) | func TestInProgressQueriesAtShutdownPacketConn(t *testing.T) {
  function TestServerStartStopRace (line 981) | func TestServerStartStopRace(t *testing.T) {
  function TestSocketOptions (line 999) | func TestSocketOptions(t *testing.T) {
  function TestServerReuseport (line 1094) | func TestServerReuseport(t *testing.T) {
  function TestServerReuseaddr (line 1140) | func TestServerReuseaddr(t *testing.T) {
  function TestServerRoundtripTsig (line 1310) | func TestServerRoundtripTsig(t *testing.T) {
  function TestResponseAfterClose (line 1375) | func TestResponseAfterClose(t *testing.T) {
  function TestResponseDoubleClose (line 1397) | func TestResponseDoubleClose(t *testing.T) {
  type countingConn (line 1406) | type countingConn struct
    method Write (line 1411) | func (c *countingConn) Write(p []byte) (int, error) {
  function TestResponseWriteSinglePacket (line 1416) | func TestResponseWriteSinglePacket(t *testing.T) {
  type ExampleFrameLengthWriter (line 1436) | type ExampleFrameLengthWriter struct
    method Write (line 1440) | func (e *ExampleFrameLengthWriter) Write(m []byte) (int, error) {
  function ExampleDecorateWriter (line 1445) | func ExampleDecorateWriter() {

FILE: sig0.go
  method Sign (line 16) | func (rr *SIG) Sign(k crypto.Signer, m *Msg) ([]byte, error) {
  method Verify (line 76) | func (rr *SIG) Verify(k *KEY, buf []byte) error {

FILE: sig0_test.go
  function TestSIG0 (line 9) | func TestSIG0(t *testing.T) {

FILE: smimea.go
  method Sign (line 10) | func (r *SMIMEA) Sign(usage, selector, matchingType int, cert *x509.Cert...
  method Verify (line 22) | func (r *SMIMEA) Verify(cert *x509.Certificate) error {
  function SMIMEAName (line 35) | func SMIMEAName(email, domain string) (string, error) {

FILE: svcb.go
  type SVCBKey (line 15) | type SVCBKey
    method String (line 57) | func (key SVCBKey) String() string {
  constant SVCB_MANDATORY (line 19) | SVCB_MANDATORY SVCBKey = iota
  constant SVCB_ALPN (line 20) | SVCB_ALPN
  constant SVCB_NO_DEFAULT_ALPN (line 21) | SVCB_NO_DEFAULT_ALPN
  constant SVCB_PORT (line 22) | SVCB_PORT
  constant SVCB_IPV4HINT (line 23) | SVCB_IPV4HINT
  constant SVCB_ECHCONFIG (line 24) | SVCB_ECHCONFIG
  constant SVCB_IPV6HINT (line 25) | SVCB_IPV6HINT
  constant SVCB_DOHPATH (line 26) | SVCB_DOHPATH
  constant SVCB_OHTTP (line 27) | SVCB_OHTTP
  constant svcb_RESERVED (line 29) | svcb_RESERVED SVCBKey = 65535
  function reverseSVCBKeyMap (line 46) | func reverseSVCBKeyMap(m map[SVCBKey]string) map[string]SVCBKey {
  function svcbStringToKey (line 70) | func svcbStringToKey(s string) SVCBKey {
  function makeSVCBKeyValue (line 188) | func makeSVCBKeyValue(key SVCBKey) SVCBKeyValue {
  type SVCB (line 218) | type SVCB struct
    method parse (line 86) | func (rr *SVCB) parse(c *zlexer, o string) *ParseError {
    method String (line 891) | func (rr *SVCB) String() string {
  type HTTPS (line 227) | type HTTPS struct
    method String (line 231) | func (rr *HTTPS) String() string {
    method parse (line 235) | func (rr *HTTPS) parse(c *zlexer, o string) *ParseError {
  type SVCBKeyValue (line 241) | type SVCBKeyValue interface
  type SVCBMandatory (line 273) | type SVCBMandatory struct
    method Key (line 277) | func (*SVCBMandatory) Key() SVCBKey { return SVCB_MANDATORY }
    method String (line 279) | func (s *SVCBMandatory) String() string {
    method pack (line 287) | func (s *SVCBMandatory) pack() ([]byte, error) {
    method unpack (line 299) | func (s *SVCBMandatory) unpack(b []byte) error {
    method parse (line 312) | func (s *SVCBMandatory) parse(b string) error {
    method len (line 323) | func (s *SVCBMandatory) len() int {
    method copy (line 327) | func (s *SVCBMandatory) copy() SVCBKeyValue {
  type SVCBAlpn (line 342) | type SVCBAlpn struct
    method Key (line 346) | func (*SVCBAlpn) Key() SVCBKey { return SVCB_ALPN }
    method String (line 348) | func (s *SVCBAlpn) String() string {
    method pack (line 393) | func (s *SVCBAlpn) pack() ([]byte, error) {
    method unpack (line 409) | func (s *SVCBAlpn) unpack(b []byte) error {
    method parse (line 425) | func (s *SVCBAlpn) parse(b string) error {
    method len (line 470) | func (s *SVCBAlpn) len() int {
    method copy (line 478) | func (s *SVCBAlpn) copy() SVCBKeyValue {
  type SVCBNoDefaultAlpn (line 492) | type SVCBNoDefaultAlpn struct
    method Key (line 494) | func (*SVCBNoDefaultAlpn) Key() SVCBKey          { return SVCB_NO_DEFA...
    method copy (line 495) | func (*SVCBNoDefaultAlpn) copy() SVCBKeyValue    { return &SVCBNoDefau...
    method pack (line 496) | func (*SVCBNoDefaultAlpn) pack() ([]byte, error) { return []byte{}, nil }
    method String (line 497) | func (*SVCBNoDefaultAlpn) String() string        { return "" }
    method len (line 498) | func (*SVCBNoDefaultAlpn) len() int              { return 0 }
    method unpack (line 500) | func (*SVCBNoDefaultAlpn) unpack(b []byte) error {
    method parse (line 507) | func (*SVCBNoDefaultAlpn) parse(b string) error {
  type SVCBPort (line 521) | type SVCBPort struct
    method Key (line 525) | func (*SVCBPort) Key() SVCBKey         { return SVCB_PORT }
    method len (line 526) | func (*SVCBPort) len() int             { return 2 }
    method String (line 527) | func (s *SVCBPort) String() string     { return strconv.FormatUint(uin...
    method copy (line 528) | func (s *SVCBPort) copy() SVCBKeyValue { return &SVCBPort{s.Port} }
    method unpack (line 530) | func (s *SVCBPort) unpack(b []byte) error {
    method pack (line 538) | func (s *SVCBPort) pack() ([]byte, error) {
    method parse (line 544) | func (s *SVCBPort) parse(b string) error {
  type SVCBIPv4Hint (line 568) | type SVCBIPv4Hint struct
    method Key (line 572) | func (*SVCBIPv4Hint) Key() SVCBKey { return SVCB_IPV4HINT }
    method len (line 573) | func (s *SVCBIPv4Hint) len() int   { return 4 * len(s.Hint) }
    method pack (line 575) | func (s *SVCBIPv4Hint) pack() ([]byte, error) {
    method unpack (line 587) | func (s *SVCBIPv4Hint) unpack(b []byte) error {
    method String (line 600) | func (s *SVCBIPv4Hint) String() string {
    method parse (line 612) | func (s *SVCBIPv4Hint) parse(b string) error {
    method copy (line 634) | func (s *SVCBIPv4Hint) copy() SVCBKeyValue {
  type SVCBECHConfig (line 650) | type SVCBECHConfig struct
    method Key (line 654) | func (*SVCBECHConfig) Key() SVCBKey     { return SVCB_ECHCONFIG }
    method String (line 655) | func (s *SVCBECHConfig) String() string { return toBase64(s.ECH) }
    method len (line 656) | func (s *SVCBECHConfig) len() int       { return len(s.ECH) }
    method pack (line 658) | func (s *SVCBECHConfig) pack() ([]byte, error) {
    method copy (line 662) | func (s *SVCBECHConfig) copy() SVCBKeyValue {
    method unpack (line 666) | func (s *SVCBECHConfig) unpack(b []byte) error {
    method parse (line 671) | func (s *SVCBECHConfig) parse(b string) error {
  type SVCBIPv6Hint (line 691) | type SVCBIPv6Hint struct
    method Key (line 695) | func (*SVCBIPv6Hint) Key() SVCBKey { return SVCB_IPV6HINT }
    method len (line 696) | func (s *SVCBIPv6Hint) len() int   { return 16 * len(s.Hint) }
    method pack (line 698) | func (s *SVCBIPv6Hint) pack() ([]byte, error) {
    method unpack (line 709) | func (s *SVCBIPv6Hint) unpack(b []byte) error {
    method String (line 726) | func (s *SVCBIPv6Hint) String() string {
    method parse (line 737) | func (s *SVCBIPv6Hint) parse(b string) error {
    method copy (line 759) | func (s *SVCBIPv6Hint) copy() SVCBKeyValue {
  type SVCBDoHPath (line 786) | type SVCBDoHPath struct
    method Key (line 790) | func (*SVCBDoHPath) Key() SVCBKey            { return SVCB_DOHPATH }
    method String (line 791) | func (s *SVCBDoHPath) String() string        { return svcbParamToStr([...
    method len (line 792) | func (s *SVCBDoHPath) len() int              { return len(s.Template) }
    method pack (line 793) | func (s *SVCBDoHPath) pack() ([]byte, error) { return []byte(s.Templat...
    method unpack (line 795) | func (s *SVCBDoHPath) unpack(b []byte) error {
    method parse (line 800) | func (s *SVCBDoHPath) parse(b string) error {
    method copy (line 809) | func (s *SVCBDoHPath) copy() SVCBKeyValue {
  type SVCBOhttp (line 831) | type SVCBOhttp struct
    method Key (line 833) | func (*SVCBOhttp) Key() SVCBKey          { return SVCB_OHTTP }
    method copy (line 834) | func (*SVCBOhttp) copy() SVCBKeyValue    { return &SVCBOhttp{} }
    method pack (line 835) | func (*SVCBOhttp) pack() ([]byte, error) { return []byte{}, nil }
    method String (line 836) | func (*SVCBOhttp) String() string        { return "" }
    method len (line 837) | func (*SVCBOhttp) len() int              { return 0 }
    method unpack (line 839) | func (*SVCBOhttp) unpack(b []byte) error {
    method parse (line 846) | func (*SVCBOhttp) parse(b string) error {
  type SVCBLocal (line 863) | type SVCBLocal struct
    method Key (line 868) | func (s *SVCBLocal) Key() SVCBKey          { return s.KeyCode }
    method String (line 869) | func (s *SVCBLocal) String() string        { return svcbParamToStr(s.D...
    method pack (line 870) | func (s *SVCBLocal) pack() ([]byte, error) { return cloneSlice(s.Data)...
    method len (line 871) | func (s *SVCBLocal) len() int              { return len(s.Data) }
    method unpack (line 873) | func (s *SVCBLocal) unpack(b []byte) error {
    method parse (line 878) | func (s *SVCBLocal) parse(b string) error {
    method copy (line 887) | func (s *SVCBLocal) copy() SVCBKeyValue {
  function areSVCBPairArraysEqual (line 903) | func areSVCBPairArraysEqual(a []SVCBKeyValue, b []SVCBKeyValue) bool {
  function svcbParamToStr (line 922) | func svcbParamToStr(s []byte) string {
  function svcbParseParam (line 942) | func svcbParseParam(b string) ([]byte, error) {

FILE: svcb_test.go
  function TestSVCB (line 9) | func TestSVCB(t *testing.T) {
  function TestDecodeBadSVCB (line 65) | func TestDecodeBadSVCB(t *testing.T) {
  function TestPresentationSVCBAlpn (line 103) | func TestPresentationSVCBAlpn(t *testing.T) {
  function TestSVCBAlpn (line 119) | func TestSVCBAlpn(t *testing.T) {
  function TestCompareSVCB (line 145) | func TestCompareSVCB(t *testing.T) {

FILE: tlsa.go
  method Sign (line 10) | func (r *TLSA) Sign(usage, selector, matchingType int, cert *x509.Certif...
  method Verify (line 22) | func (r *TLSA) Verify(cert *x509.Certificate) error {
  function TLSAName (line 35) | func TLSAName(name, service, network string) (string, error) {

FILE: tmpdir_darwin_test.go
  function tempFile (line 20) | func tempFile(t *testing.T, filename string) string {

FILE: tmpdir_test.go
  function tempFile (line 12) | func tempFile(t *testing.T, filename string) string {

FILE: tsig.go
  constant HmacSHA1 (line 18) | HmacSHA1   = "hmac-sha1."
  constant HmacSHA224 (line 19) | HmacSHA224 = "hmac-sha224."
  constant HmacSHA256 (line 20) | HmacSHA256 = "hmac-sha256."
  constant HmacSHA384 (line 21) | HmacSHA384 = "hmac-sha384."
  constant HmacSHA512 (line 22) | HmacSHA512 = "hmac-sha512."
  constant HmacMD5 (line 24) | HmacMD5 = "hmac-md5.sig-alg.reg.int."
  type TsigProvider (line 28) | type TsigProvider interface
  type tsigHMACProvider (line 35) | type tsigHMACProvider
    method Generate (line 37) | func (key tsigHMACProvider) Generate(msg []byte, t *TSIG) ([]byte, err...
    method Verify (line 62) | func (key tsigHMACProvider) Verify(msg []byte, t *TSIG) error {
  type tsigSecretProvider (line 77) | type tsigSecretProvider
    method Generate (line 79) | func (ts tsigSecretProvider) Generate(msg []byte, t *TSIG) ([]byte, er...
    method Verify (line 87) | func (ts tsigSecretProvider) Verify(msg []byte, t *TSIG) error {
  type TSIG (line 97) | type TSIG struct
    method String (line 112) | func (rr *TSIG) String() string {
    method parse (line 127) | func (*TSIG) parse(c *zlexer, origin string) *ParseError {
  type tsigWireFmt (line 133) | type tsigWireFmt struct
  type macWireFmt (line 149) | type macWireFmt struct
  type timerWireFmt (line 155) | type timerWireFmt struct
  function TsigGenerate (line 166) | func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([...
  function TsigGenerateWithProvider (line 171) | func TsigGenerateWithProvider(m *Msg, provider TsigProvider, requestMAC ...
  function TsigVerify (line 221) | func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) ...
  function TsigVerifyWithProvider (line 226) | func TsigVerifyWithProvider(msg []byte, provider TsigProvider, requestMA...
  function tsigVerify (line 231) | func tsigVerify(msg []byte, provider TsigProvider, requestMAC string, ti...
  function tsigBuffer (line 263) | func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly b...
  function stripTsig (line 325) | func stripTsig(msg []byte) ([]byte, *TSIG, error) {
  function tsigTimeToString (line 385) | func tsigTimeToString(t uint64) string {
  function packTsigWire (line 390) | func packTsigWire(tw *tsigWireFmt, msg []byte) (int, error) {
  function packMacWire (line 434) | func packMacWire(mw *macWireFmt, msg []byte) (int, error) {
  function packTimerWire (line 446) | func packTimerWire(tw *timerWireFmt, msg []byte) (int, error) {

FILE: tsig_test.go
  function newTsig (line 13) | func newTsig(algo string) *Msg {
  function TestTsig (line 20) | func TestTsig(t *testing.T) {
  function TestTsigCase (line 46) | func TestTsigCase(t *testing.T) {
  function TestTsigErrorResponse (line 58) | func TestTsigErrorResponse(t *testing.T) {
  function TestTsigBadTimeResponse (line 85) | func TestTsigBadTimeResponse(t *testing.T) {
  constant wireMsg (line 117) | wireMsg = "c60028000001000000010001076578616d706c6503636f6d0000060001016...
  constant testSecret (line 122) | testSecret = "NoTCJU+DMqFWywaPyxSijrDEA/eC3nK0xi3AMEZuPVk="
  constant timeSigned (line 124) | timeSigned uint64 = 1594855491
  function TestTsigErrors (line 127) | func TestTsigErrors(t *testing.T) {
  function TestTsigGenerate (line 187) | func TestTsigGenerate(t *testing.T) {
  function TestTSIGHMAC224And384 (line 253) | func TestTSIGHMAC224And384(t *testing.T) {
  constant testGoodKeyName (line 298) | testGoodKeyName = "goodkey."
  type testProvider (line 306) | type testProvider struct
    method Generate (line 310) | func (provider *testProvider) Generate(_ []byte, t *TSIG) ([]byte, err...
    method Verify (line 317) | func (*testProvider) Verify(_ []byte, t *TSIG) error {
  function TestTsigGenerateProvider (line 324) | func TestTsigGenerateProvider(t *testing.T) {
  function TestTsigVerifyProvider (line 369) | func TestTsigVerifyProvider(t *testing.T) {

FILE: types.go
  type Type (line 14) | type Type
  type Class (line 16) | type Class
  type Name (line 18) | type Name
  constant TypeNone (line 27) | TypeNone       uint16 = 0
  constant TypeA (line 28) | TypeA          uint16 = 1
  constant TypeNS (line 29) | TypeNS         uint16 = 2
  constant TypeMD (line 30) | TypeMD         uint16 = 3
  constant TypeMF (line 31) | TypeMF         uint16 = 4
  constant TypeCNAME (line 32) | TypeCNAME      uint16 = 5
  constant TypeSOA (line 33) | TypeSOA        uint16 = 6
  constant TypeMB (line 34) | TypeMB         uint16 = 7
  constant TypeMG (line 35) | TypeMG         uint16 = 8
  constant TypeMR (line 36) | TypeMR         uint16 = 9
  constant TypeNULL (line 37) | TypeNULL       uint16 = 10
  constant TypePTR (line 38) | TypePTR        uint16 = 12
  constant TypeHINFO (line 39) | TypeHINFO      uint16 = 13
  constant TypeMINFO (line 40) | TypeMINFO      uint16 = 14
  constant TypeMX (line 41) | TypeMX         uint16 = 15
  constant TypeTXT (line 42) | TypeTXT        uint16 = 16
  constant TypeRP (line 43) | TypeRP         uint16 = 17
  constant TypeAFSDB (line 44) | TypeAFSDB      uint16 = 18
  constant TypeX25 (line 45) | TypeX25        uint16 = 19
  constant TypeISDN (line 46) | TypeISDN       uint16 = 20
  constant TypeRT (line 47) | TypeRT         uint16 = 21
  constant TypeNSAPPTR (line 48) | TypeNSAPPTR    uint16 = 23
  constant TypeSIG (line 49) | TypeSIG        uint16 = 24
  constant TypeKEY (line 50) | TypeKEY        uint16 = 25
  constant TypePX (line 51) | TypePX         uint16 = 26
  constant TypeGPOS (line 52) | TypeGPOS       uint16 = 27
  constant TypeAAAA (line 53) | TypeAAAA       uint16 = 28
  constant TypeLOC (line 54) | TypeLOC        uint16 = 29
  constant TypeNXT (line 55) | TypeNXT        uint16 = 30
  constant TypeEID (line 56) | TypeEID        uint16 = 31
  constant TypeNIMLOC (line 57) | TypeNIMLOC     uint16 = 32
  constant TypeSRV (line 58) | TypeSRV        uint16 = 33
  constant TypeATMA (line 59) | TypeATMA       uint16 = 34
  constant TypeNAPTR (line 60) | TypeNAPTR      uint16 = 35
  constant TypeKX (line 61) | TypeKX         uint16 = 36
  constant TypeCERT (line 62) | TypeCERT       uint16 = 37
  constant TypeDNAME (line 63) | TypeDNAME      uint16 = 39
  constant TypeOPT (line 64) | TypeOPT        uint16 = 41
  constant TypeAPL (line 65) | TypeAPL        uint16 = 42
  constant TypeDS (line 66) | TypeDS         uint16 = 43
  constant TypeSSHFP (line 67) | TypeSSHFP      uint16 = 44
  constant TypeIPSECKEY (line 68) | TypeIPSECKEY   uint16 = 45
  constant TypeRRSIG (line 69) | TypeRRSIG      uint16 = 46
  constant TypeNSEC (line 70) | TypeNSEC       uint16 = 47
  constant TypeDNSKEY (line 71) | TypeDNSKEY     uint16 = 48
  constant TypeDHCID (line 72) | TypeDHCID      uint16 = 49
  constant TypeNSEC3 (line 73) | TypeNSEC3      uint16 = 50
  constant TypeNSEC3PARAM (line 74) | TypeNSEC3PARAM uint16 = 51
  constant TypeTLSA (line 75) | TypeTLSA       uint16 = 52
  constant TypeSMIMEA (line 76) | TypeSMIMEA     uint16 = 53
  constant TypeHIP (line 77) | TypeHIP        uint16 = 55
  constant TypeNINFO (line 78) | TypeNINFO      uint16 = 56
  constant TypeRKEY (line 79) | TypeRKEY       uint16 = 57
  constant TypeTALINK (line 80) | TypeTALINK     uint16 = 58
  constant TypeCDS (line 81) | TypeCDS        uint16 = 59
  constant TypeCDNSKEY (line 82) | TypeCDNSKEY    uint16 = 60
  constant TypeOPENPGPKEY (line 83) | TypeOPENPGPKEY uint16 = 61
  constant TypeCSYNC (line 84) | TypeCSYNC      uint16 = 62
  constant TypeZONEMD (line 85) | TypeZONEMD     uint16 = 63
  constant TypeSVCB (line 86) | TypeSVCB       uint16 = 64
  constant TypeHTTPS (line 87) | TypeHTTPS      uint16 = 65
  constant TypeSPF (line 88) | TypeSPF        uint16 = 99
  constant TypeUINFO (line 89) | TypeUINFO      uint16 = 100
  constant TypeUID (line 90) | TypeUID        uint16 = 101
  constant TypeGID (line 91) | TypeGID        uint16 = 102
  constant TypeUNSPEC (line 92) | TypeUNSPEC     uint16 = 103
  constant TypeNID (line 93) | TypeNID        uint16 = 104
  constant TypeL32 (line 94) | TypeL32        uint16 = 105
  constant TypeL64 (line 95) | TypeL64        uint16 = 106
  constant TypeLP (line 96) | TypeLP         uint16 = 107
  constant TypeEUI48 (line 97) | TypeEUI48      uint16 = 108
  constant TypeEUI64 (line 98) | TypeEUI64      uint16 = 109
  constant TypeNXNAME (line 99) | TypeNXNAME     uint16 = 128
  constant TypeURI (line 100) | TypeURI        uint16 = 256
  constant TypeCAA (line 101) | TypeCAA        uint16 = 257
  constant TypeAVC (line 102) | TypeAVC        uint16 = 258
  constant TypeAMTRELAY (line 103) | TypeAMTRELAY   uint16 = 260
  constant TypeRESINFO (line 104) | TypeRESINFO    uint16 = 261
  constant TypeTKEY (line 106) | TypeTKEY uint16 = 249
  constant TypeTSIG (line 107) | TypeTSIG uint16 = 250
  constant TypeIXFR (line 110) | TypeIXFR  uint16 = 251
  constant TypeAXFR (line 111) | TypeAXFR  uint16 = 252
  constant TypeMAILB (line 112) | TypeMAILB uint16 = 253
  constant TypeMAILA (line 113) | TypeMAILA uint16 = 254
  constant TypeANY (line 114) | TypeANY   uint16 = 255
  constant TypeTA (line 116) | TypeTA       uint16 = 32768
  constant TypeDLV (line 117) | TypeDLV      uint16 = 32769
  constant TypeReserved (line 118) | TypeReserved uint16 = 65535
  constant ClassINET (line 121) | ClassINET   = 1
  constant ClassCSNET (line 122) | ClassCSNET  = 2
  constant ClassCHAOS (line 123) | ClassCHAOS  = 3
  constant ClassHESIOD (line 124) | ClassHESIOD = 4
  constant ClassNONE (line 125) | ClassNONE   = 254
  constant ClassANY (line 126) | ClassANY    = 255
  constant RcodeSuccess (line 129) | RcodeSuccess                    = 0
  constant RcodeFormatError (line 130) | RcodeFormatError                = 1
  constant RcodeServerFailure (line 131) | RcodeServerFailure              = 2
  constant RcodeNameError (line 132) | RcodeNameError                  = 3
  constant RcodeNotImplemented (line 133) | RcodeNotImplemented             = 4
  constant RcodeRefused (line 134) | RcodeRefused                    = 5
  constant RcodeYXDomain (line 135) | RcodeYXDomain                   = 6
  constant RcodeYXRrset (line 136) | RcodeYXRrset                    = 7
  constant RcodeNXRrset (line 137) | RcodeNXRrset                    = 8
  constant RcodeNotAuth (line 138) | RcodeNotAuth                    = 9
  constant RcodeNotZone (line 139) | RcodeNotZone                    = 10
  constant RcodeStatefulTypeNotImplemented (line 140) | RcodeStatefulTypeNotImplemented = 11
  constant RcodeBadSig (line 141) | RcodeBadSig                     = 16
  constant RcodeBadVers (line 142) | RcodeBadVers                    = 16
  constant RcodeBadKey (line 143) | RcodeBadKey                     = 17
  constant RcodeBadTime (line 144) | RcodeBadTime                    = 18
  constant RcodeBadMode (line 145) | RcodeBadMode                    = 19
  constant RcodeBadName (line 146) | RcodeBadName                    = 20
  constant RcodeBadAlg (line 147) | RcodeBadAlg                     = 21
  constant RcodeBadTrunc (line 148) | RcodeBadTrunc                   = 22
  constant RcodeBadCookie (line 149) | RcodeBadCookie                  = 23
  constant OpcodeQuery (line 152) | OpcodeQuery    = 0
  constant OpcodeIQuery (line 153) | OpcodeIQuery   = 1
  constant OpcodeStatus (line 154) | OpcodeStatus   = 2
  constant OpcodeNotify (line 155) | OpcodeNotify   = 4
  constant OpcodeUpdate (line 156) | OpcodeUpdate   = 5
  constant OpcodeStateful (line 157) | OpcodeStateful = 6
  constant ZoneMDSchemeSimple (line 162) | ZoneMDSchemeSimple = 1
  constant ZoneMDHashAlgSHA384 (line 164) | ZoneMDHashAlgSHA384 = 1
  constant ZoneMDHashAlgSHA512 (line 165) | ZoneMDHashAlgSHA512 = 2
  constant IPSECGatewayNone (line 170) | IPSECGatewayNone uint8 = iota
  constant IPSECGatewayIPv4 (line 171) | IPSECGatewayIPv4
  constant IPSECGatewayIPv6 (line 172) | IPSECGatewayIPv6
  constant IPSECGatewayHost (line 173) | IPSECGatewayHost
  constant AMTRELAYNone (line 178) | AMTRELAYNone = IPSECGatewayNone
  constant AMTRELAYIPv4 (line 179) | AMTRELAYIPv4 = IPSECGatewayIPv4
  constant AMTRELAYIPv6 (line 180) | AMTRELAYIPv6 = IPSECGatewayIPv6
  constant AMTRELAYHost (line 181) | AMTRELAYHost = IPSECGatewayHost
  constant StatefulTypeKeepAlive (line 186) | StatefulTypeKeepAlive uint16 = iota + 1
  constant StatefulTypeRetryDelay (line 187) | StatefulTypeRetryDelay
  constant StatefulTypeEncryptionPadding (line 188) | StatefulTypeEncryptionPadding
  type Header (line 198) | type Header struct
  constant headerSize (line 205) | headerSize = 12
  constant _QR (line 208) | _QR = 1 << 15
  constant _AA (line 209) | _AA = 1 << 10
  constant _TC (line 210) | _TC = 1 << 9
  constant _RD (line 211) | _RD = 1 << 8
  constant _RA (line 212) | _RA = 1 << 7
  constant _Z (line 213) | _Z  = 1 << 6
  constant _AD (line 214) | _AD = 1 << 5
  constant _CD (line 215) | _CD = 1 << 4
  constant LOC_EQUATOR (line 220) | LOC_EQUATOR       = 1 << 31
  constant LOC_PRIMEMERIDIAN (line 221) | LOC_PRIMEMERIDIAN = 1 << 31
  constant LOC_HOURS (line 222) | LOC_HOURS         = 60 * 1000
  constant LOC_DEGREES (line 223) | LOC_DEGREES       = 60 * LOC_HOURS
  constant LOC_ALTITUDEBASE (line 224) | LOC_ALTITUDEBASE  = 100000
  constant CertPKIX (line 229) | CertPKIX = 1 + iota
  constant CertSPKI (line 230) | CertSPKI
  constant CertPGP (line 231) | CertPGP
  constant CertIPIX (line 232) | CertIPIX
  constant CertISPKI (line 233) | CertISPKI
  constant CertIPGP (line 234) | CertIPGP
  constant CertACPKIX (line 235) | CertACPKIX
  constant CertIACPKIX (line 236) | CertIACPKIX
  constant CertURI (line 237) | CertURI = 253
  constant CertOID (line 238) | CertOID = 254
  constant ipv4InIPv6Prefix (line 257) | ipv4InIPv6Prefix = "::ffff:"
  type Question (line 266) | type Question struct
    method len (line 272) | func (q *Question) len(off int, compression map[string]struct{}) int {
    method String (line 278) | func (q *Question) String() (s string) {
  type ANY (line 297) | type ANY struct
    method String (line 302) | func (rr *ANY) String() string { return rr.Hdr.String() }
    method parse (line 304) | func (*ANY) parse(c *zlexer, origin string) *ParseError {
  type NULL (line 309) | type NULL struct
    method String (line 314) | func (rr *NULL) String() string {
    method parse (line 319) | func (*NULL) parse(c *zlexer, origin string) *ParseError {
  type NXNAME (line 325) | type NXNAME struct
    method String (line 330) | func (rr *NXNAME) String() string { return rr.Hdr.String() }
    method parse (line 332) | func (*NXNAME) parse(c *zlexer, origin string) *ParseError {
  type CNAME (line 337) | type CNAME struct
    method String (line 342) | func (rr *CNAME) String() string { return rr.Hdr.String() + sprintName...
  type HINFO (line 345) | type HINFO struct
    method String (line 351) | func (rr *HINFO) String() string {
  type MB (line 356) | type MB struct
    method String (line 361) | func (rr *MB) String() string { return rr.Hdr.String() + sprintName(rr...
  type MG (line 364) | type MG struct
    method String (line 369) | func (rr *MG) String() string { return rr.Hdr.String() + sprintName(rr...
  type MINFO (line 372) | type MINFO struct
    method String (line 378) | func (rr *MINFO) String() string {
  type MR (line 383) | type MR struct
    method String (line 388) | func (rr *MR) String() string {
  type MF (line 393) | type MF struct
    method String (line 398) | func (rr *MF) String() string {
  type MD (line 403) | type MD struct
    method String (line 408) | func (rr *MD) String() string {
  type MX (line 413) | type MX struct
    method String (line 419) | func (rr *MX) String() string {
  type AFSDB (line 424) | type AFSDB struct
    method String (line 430) | func (rr *AFSDB) String() string {
  type X25 (line 435) | type X25 struct
    method String (line 440) | func (rr *X25) String() string {
  type ISDN (line 445) | type ISDN struct
    method String (line 451) | func (rr *ISDN) String() string {
  type RT (line 456) | type RT struct
    method String (line 462) | func (rr *RT) String() string {
  type NS (line 467) | type NS struct
    method String (line 472) | func (rr *NS) String() string {
  type PTR (line 477) | type PTR struct
    method String (line 482) | func (rr *PTR) String() string {
  type RP (line 487) | type RP struct
    method String (line 493) | func (rr *RP) String() string {
  type SOA (line 498) | type SOA struct
    method String (line 509) | func (rr *SOA) String() string {
  type TXT (line 519) | type TXT struct
    method String (line 524) | func (rr *TXT) String() string { return rr.Hdr.String() + sprintTxt(rr...
  function sprintName (line 526) | func sprintName(s string) string {
  function sprintTxtOctet (line 572) | func sprintTxtOctet(s string) string {
  function sprintTxt (line 595) | func sprintTxt(txt []string) string {
  function writeTXTStringByte (line 617) | func writeTXTStringByte(s *strings.Builder, b byte) {
  constant escapedByteSmall (line 630) | escapedByteSmall = "" +
  constant escapedByteLarge (line 635) | escapedByteLarge = `\127\128\129` +
  function escapeByte (line 653) | func escapeByte(b byte) string {
  function isDomainNameLabelSpecial (line 666) | func isDomainNameLabelSpecial(b byte) bool {
  function nextByte (line 674) | func nextByte(s string, offset int) (byte, int) {
  type SPF (line 696) | type SPF struct
    method String (line 701) | func (rr *SPF) String() string { return rr.Hdr.String() + sprintTxt(rr...
  type AVC (line 704) | type AVC struct
    method String (line 709) | func (rr *AVC) String() string { return rr.Hdr.String() + sprintTxt(rr...
  type SRV (line 712) | type SRV struct
    method String (line 720) | func (rr *SRV) String() string {
  type NAPTR (line 728) | type NAPTR struct
    method String (line 738) | func (rr *NAPTR) String() string {
  type CERT (line 749) | type CERT struct
    method String (line 757) | func (rr *CERT) String() string {
  type DNAME (line 775) | type DNAME struct
    method String (line 780) | func (rr *DNAME) String() string {
  type A (line 785) | type A struct
    method String (line 790) | func (rr *A) String() string {
  type AAAA (line 798) | type AAAA struct
    method String (line 803) | func (rr *AAAA) String() string {
  type PX (line 816) | type PX struct
    method String (line 823) | func (rr *PX) String() string {
  type GPOS (line 828) | type GPOS struct
    method String (line 835) | func (rr *GPOS) String() string {
  type LOC (line 840) | type LOC struct
    method String (line 873) | func (rr *LOC) String() string {
  function cmToM (line 853) | func cmToM(x uint8) string {
  type SIG (line 919) | type SIG struct
  type RRSIG (line 924) | type RRSIG struct
    method String (line 937) | func (rr *RRSIG) String() string {
  type NXT (line 952) | type NXT struct
  type NSEC (line 957) | type NSEC struct
    method String (line 963) | func (rr *NSEC) String() string {
    method len (line 971) | func (rr *NSEC) len(off int, compression map[string]struct{}) int {
  type DLV (line 979) | type DLV struct
  type CDS (line 982) | type CDS struct
  type DS (line 985) | type DS struct
    method String (line 993) | func (rr *DS) String() string {
  type KX (line 1001) | type KX struct
    method String (line 1007) | func (rr *KX) String() string {
  type TA (line 1013) | type TA struct
    method String (line 1021) | func (rr *TA) String() string {
  type TALINK (line 1029) | type TALINK struct
    method String (line 1035) | func (rr *TALINK) String() string {
  type SSHFP (line 1041) | type SSHFP struct
    method String (line 1048) | func (rr *SSHFP) String() string {
  type KEY (line 1055) | type KEY struct
  type CDNSKEY (line 1060) | type CDNSKEY struct
  type DNSKEY (line 1065) | type DNSKEY struct
    method String (line 1073) | func (rr *DNSKEY) String() string {
  type IPSECKEY (line 1081) | type IPSECKEY struct
    method String (line 1091) | func (rr *IPSECKEY) String() string {
  type AMTRELAY (line 1112) | type AMTRELAY struct
    method String (line 1120) | func (rr *AMTRELAY) String() string {
  type RKEY (line 1144) | type RKEY struct
    method String (line 1152) | func (rr *RKEY) String() string {
  type NSAPPTR (line 1160) | type NSAPPTR struct
    method String (line 1165) | func (rr *NSAPPTR) String() string { return rr.Hdr.String() + sprintNa...
  type NSEC3 (line 1168) | type NSEC3 struct
    method String (line 1180) | func (rr *NSEC3) String() string {
    method len (line 1193) | func (rr *NSEC3) len(off int, compression map[string]struct{}) int {
  type NSEC3PARAM (line 1201) | type NSEC3PARAM struct
    method String (line 1210) | func (rr *NSEC3PARAM) String() string {
  type TKEY (line 1220) | type TKEY struct
    method String (line 1234) | func (rr *TKEY) String() string {
  type RFC3597 (line 1249) | type RFC3597 struct
    method String (line 1254) | func (rr *RFC3597) String() string {
  function rfc3597Header (line 1262) | func rfc3597Header(h RR_Header) string {
  type URI (line 1273) | type URI struct
    method String (line 1281) | func (rr *URI) String() string {
  type DHCID (line 1287) | type DHCID struct
    method String (line 1292) | func (rr *DHCID) String() string { return rr.Hdr.String() + rr.Digest }
  type TLSA (line 1295) | type TLSA struct
    method String (line 1303) | func (rr *TLSA) String() string {
  type SMIMEA (line 1312) | type SMIMEA struct
    method String (line 1320) | func (rr *SMIMEA) String() string {
  type HIP (line 1335) | type HIP struct
    method String (line 1345) | func (rr *HIP) String() string {
  type NINFO (line 1357) | type NINFO struct
    method String (line 1362) | func (rr *NINFO) String() string { return rr.Hdr.String() + sprintTxt(...
  type NID (line 1365) | type NID struct
    method String (line 1371) | func (rr *NID) String() string {
  type L32 (line 1379) | type L32 struct
    method String (line 1385) | func (rr *L32) String() string {
  type L64 (line 1394) | type L64 struct
    method String (line 1400) | func (rr *L64) String() string {
  type LP (line 1408) | type LP struct
    method String (line 1414) | func (rr *LP) String() string {
  type EUI48 (line 1419) | type EUI48 struct
    method String (line 1424) | func (rr *EUI48) String() string { return rr.Hdr.String() + euiToStrin...
  type EUI64 (line 1427) | type EUI64 struct
    method String (line 1432) | func (rr *EUI64) String() string { return rr.Hdr.String() + euiToStrin...
  type CAA (line 1435) | type CAA struct
    method String (line 1443) | func (rr *CAA) String() string {
  type UID (line 1448) | type UID struct
    method String (line 1453) | func (rr *UID) String() string { return rr.Hdr.String() + strconv.Form...
  type GID (line 1456) | type GID struct
    method String (line 1461) | func (rr *GID) String() string { return rr.Hdr.String() + strconv.Form...
  type UINFO (line 1464) | type UINFO struct
    method String (line 1469) | func (rr *UINFO) String() string { return rr.Hdr.String() + sprintTxt(...
  type EID (line 1472) | type EID struct
    method String (line 1477) | func (rr *EID) String() string { return rr.Hdr.String() + strings.ToUp...
  type NIMLOC (line 1480) | type NIMLOC struct
    method String (line 1485) | func (rr *NIMLOC) String() string { return rr.Hdr.String() + strings.T...
  type OPENPGPKEY (line 1488) | type OPENPGPKEY struct
    method String (line 1493) | func (rr *OPENPGPKEY) String() string { return rr.Hdr.String() + rr.Pu...
  type CSYNC (line 1496) | type CSYNC struct
    method String (line 1503) | func (rr *CSYNC) String() string {
    method len (line 1512) | func (rr *CSYNC) len(off int, compression map[string]struct{}) int {
  type ZONEMD (line 1520) | type ZONEMD struct
    method String (line 1528) | func (rr *ZONEMD) String() string {
  type RESINFO (line 1538) | type RESINFO struct
    method String (line 1543) | func (rr *RESINFO) String() string { return rr.Hdr.String() + sprintTx...
  type APL (line 1546) | type APL struct
    method String (line 1558) | func (rr *APL) String() string {
  type APLPrefix (line 1552) | type APLPrefix struct
    method str (line 1571) | func (a *APLPrefix) str() string {
    method equals (line 1606) | func (a *APLPrefix) equals(b *APLPrefix) bool {
    method copy (line 1613) | func (a *APLPrefix) copy() APLPrefix {
    method len (line 1621) | func (a *APLPrefix) len() int {
  function TimeToString (line 1630) | func TimeToString(t uint32) string {
  function StringToTime (line 1642) | func StringToTime(s string) (uint32, error) {
  function saltToString (line 1655) | func saltToString(s string) string {
  function euiToString (line 1662) | func euiToString(eui uint64, bits int) (hex string) {
  function cloneSlice (line 1677) | func cloneSlice[E any, S ~[]E](s S) S {
  function copyNet (line 1685) | func copyNet(n net.IPNet) net.IPNet {
  function splitN (line 1694) | func splitN(s string, n int) []string {

FILE: types_generate.go
  function getTypeStruct (line 71) | func getTypeStruct(t types.Type, scope *types.Scope) (*types.Struct, boo...
  function loadModule (line 90) | func loadModule(name string) (*types.Package, error) {
  function main (line 99) | func main() {
  function fatalIfErr (line 328) | func fatalIfErr(err error) {

FILE: types_test.go
  function TestCmToM (line 7) | func TestCmToM(t *testing.T) {
  function TestSplitN (line 44) | func TestSplitN(t *testing.T) {
  function TestSprintName (line 76) | func TestSprintName(t *testing.T) {
  function TestSprintTxtOctet (line 107) | func TestSprintTxtOctet(t *testing.T) {
  function TestSprintTxt (line 115) | func TestSprintTxt(t *testing.T) {
  function TestRPStringer (line 126) | func TestRPStringer(t *testing.T) {
  function BenchmarkSprintName (line 149) | func BenchmarkSprintName(b *testing.B) {
  function BenchmarkSprintName_NoEscape (line 159) | func BenchmarkSprintName_NoEscape(b *testing.B) {
  function BenchmarkSprintTxtOctet (line 169) | func BenchmarkSprintTxtOctet(b *testing.B) {
  function BenchmarkSprintTxt (line 179) | func BenchmarkSprintTxt(b *testing.B) {

FILE: udp.go
  type SessionUDP (line 31) | type SessionUDP struct
    method RemoteAddr (line 37) | func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr }
  function ReadFromSessionUDP (line 41) | func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, ...
  function WriteToSessionUDP (line 51) | func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP)...
  function setUDPSocketOptions (line 57) | func setUDPSocketOptions(conn *net.UDPConn) error {
  function parseDstFromOOB (line 69) | func parseDstFromOOB(oob []byte) net.IP {
  function correctSource (line 85) | func correctSource(oob []byte) []byte {

FILE: udp_no_control.go
  type SessionUDP (line 14) | type SessionUDP struct
    method RemoteAddr (line 19) | func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr }
  function ReadFromSessionUDP (line 23) | func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, ...
  function WriteToSessionUDP (line 32) | func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP)...
  function setUDPSocketOptions (line 36) | func setUDPSocketOptions(*net.UDPConn) error { return nil }
  function parseDstFromOOB (line 37) | func parseDstFromOOB([]byte, net.IP) net.IP  { return nil }

FILE: udp_test.go
  function TestSetUDPSocketOptions (line 18) | func TestSetUDPSocketOptions(t *testing.T) {
  function TestParseDstFromOOB (line 83) | func TestParseDstFromOOB(t *testing.T) {
  function TestCorrectSource (line 123) | func TestCorrectSource(t *testing.T) {

FILE: update.go
  method NameUsed (line 6) | func (u *Msg) NameUsed(rr []RR) {
  method NameNotUsed (line 17) | func (u *Msg) NameNotUsed(rr []RR) {
  method Used (line 28) | func (u *Msg) Used(rr []RR) {
  method RRsetUsed (line 46) | func (u *Msg) RRsetUsed(rr []RR) {
  method RRsetNotUsed (line 59) | func (u *Msg) RRsetNotUsed(rr []RR) {
  method Insert (line 71) | func (u *Msg) Insert(rr []RR) {
  method RemoveRRset (line 86) | func (u *Msg) RemoveRRset(rr []RR) {
  method RemoveName (line 98) | func (u *Msg) RemoveName(rr []RR) {
  method Remove (line 109) | func (u *Msg) Remove(rr []RR) {

FILE: update_test.go
  function TestDynamicUpdateParsing (line 8) | func TestDynamicUpdateParsing(t *testing.T) {
  function TestDynamicUpdateUnpack (line 35) | func TestDynamicUpdateUnpack(t *testing.T) {
  function TestDynamicUpdateZeroRdataUnpack (line 48) | func TestDynamicUpdateZeroRdataUnpack(t *testing.T) {
  function TestRemoveRRset (line 66) | func TestRemoveRRset(t *testing.T) {
  function TestPreReqAndRemovals (line 94) | func TestPreReqAndRemovals(t *testing.T) {

FILE: version.go
  type v (line 9) | type v struct
    method String (line 13) | func (v v) String() string {

FILE: version_test.go
  function TestVersion (line 5) | func TestVersion(t *testing.T) {

FILE: xfr.go
  type Envelope (line 10) | type Envelope struct
  type Transfer (line 16) | type Transfer struct
    method tsigProvider (line 27) | func (t *Transfer) tsigProvider() TsigProvider {
    method In (line 49) | func (t *Transfer) In(q *Msg, a string) (env chan *Envelope, err error) {
    method inAxfr (line 87) | func (t *Transfer) inAxfr(q *Msg, c chan *Envelope) {
    method inIxfr (line 140) | func (t *Transfer) inIxfr(q *Msg, c chan *Envelope) {
    method Out (line 223) | func (t *Transfer) Out(w ResponseWriter, q *Msg, ch chan *Envelope) er...
    method ReadMsg (line 243) | func (t *Transfer) ReadMsg() (*Msg, error) {
    method WriteMsg (line 266) | func (t *Transfer) WriteMsg(m *Msg) (err error) {
  function isSOAFirst (line 280) | func isSOAFirst(in *Msg) bool {
  function isSOALast (line 285) | func isSOALast(in *Msg) bool {
  constant errXFR (line 290) | errXFR = "bad xfr rcode: %d"

FILE: xfr_test.go
  function InvalidXfrServer (line 18) | func InvalidXfrServer(w ResponseWriter, req *Msg) {
  function SingleEnvelopeXfrServer (line 28) | func SingleEnvelopeXfrServer(w ResponseWriter, req *Msg) {
  function MultipleEnvelopeXfrServer (line 38) | func MultipleEnvelopeXfrServer(w ResponseWriter, req *Msg) {
  function TestInvalidXfr (line 51) | func TestInvalidXfr(t *testing.T) {
  function TestSingleEnvelopeXfr (line 77) | func TestSingleEnvelopeXfr(t *testing.T) {
  function TestSingleEnvelopeXfrTLS (line 92) | func TestSingleEnvelopeXfrTLS(t *testing.T) {
  function TestMultiEnvelopeXfr (line 113) | func TestMultiEnvelopeXfr(t *testing.T) {
  function axfrTestingSuite (line 128) | func axfrTestingSuite(t *testing.T, addrstr string) {
  function axfrTestingSuiteTLS (line 157) | func axfrTestingSuiteTLS(t *testing.T, addrstr string) {
  function axfrTestingSuiteWithCustomTsig (line 189) | func axfrTestingSuiteWithCustomTsig(t *testing.T, addrstr string, provid...
  function axfrTestingSuiteWithMsgNotSigned (line 225) | func axfrTestingSuiteWithMsgNotSigned(t *testing.T, addrstr string, prov...
  function TestCustomTsigProvider (line 248) | func TestCustomTsigProvider(t *testing.T) {
  function TestTSIGNotSigned (line 263) | func TestTSIGNotSigned(t *testing.T) {

FILE: zduplicate.go
  method isDuplicate (line 7) | func (r1 *A) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 19) | func (r1 *AAAA) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 31) | func (r1 *AFSDB) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 46) | func (r1 *AMTRELAY) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 72) | func (r1 *ANY) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 81) | func (r1 *APL) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 98) | func (r1 *AVC) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 115) | func (r1 *CAA) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 133) | func (r1 *CDNSKEY) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 154) | func (r1 *CDS) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 175) | func (r1 *CERT) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 196) | func (r1 *CNAME) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 208) | func (r1 *CSYNC) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 231) | func (r1 *DHCID) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 243) | func (r1 *DLV) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 264) | func (r1 *DNAME) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 276) | func (r1 *DNSKEY) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 297) | func (r1 *DS) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 318) | func (r1 *EID) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 330) | func (r1 *EUI48) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 342) | func (r1 *EUI64) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 354) | func (r1 *GID) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 366) | func (r1 *GPOS) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 384) | func (r1 *HINFO) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 399) | func (r1 *HIP) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 431) | func (r1 *HTTPS) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 452) | func (r1 *IPSECKEY) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 484) | func (r1 *ISDN) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 499) | func (r1 *KEY) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 520) | func (r1 *KX) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 535) | func (r1 *L32) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 550) | func (r1 *L64) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 565) | func (r1 *LOC) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 595) | func (r1 *LP) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 610) | func (r1 *MB) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 622) | func (r1 *MD) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 634) | func (r1 *MF) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 646) | func (r1 *MG) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 658) | func (r1 *MINFO) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 673) | func (r1 *MR) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 685) | func (r1 *MX) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 700) | func (r1 *NAPTR) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 727) | func (r1 *NID) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 742) | func (r1 *NIMLOC) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 754) | func (r1 *NINFO) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 771) | func (r1 *NS) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 783) | func (r1 *NSAPPTR) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 795) | func (r1 *NSEC) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 815) | func (r1 *NSEC3) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 853) | func (r1 *NSEC3PARAM) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 877) | func (r1 *NULL) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 889) | func (r1 *NXNAME) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 898) | func (r1 *NXT) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 918) | func (r1 *OPENPGPKEY) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 930) | func (r1 *PTR) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 942) | func (r1 *PX) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 960) | func (r1 *RESINFO) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 977) | func (r1 *RFC3597) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 989) | func (r1 *RKEY) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 1010) | func (r1 *RP) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 1025) | func (r1 *RRSIG) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 1061) | func (r1 *RT) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 1076) | func (r1 *SIG) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 1112) | func (r1 *SMIMEA) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 1133) | func (r1 *SOA) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 1163) | func (r1 *SPF) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 1180) | func (r1 *SRV) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 1201) | func (r1 *SSHFP) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 1219) | func (r1 *SVCB) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 1240) | func (r1 *TA) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 1261) | func (r1 *TALINK) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 1276) | func (r1 *TKEY) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 1312) | func (r1 *TLSA) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 1333) | func (r1 *TSIG) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 1369) | func (r1 *TXT) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 1386) | func (r1 *UID) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 1398) | func (r1 *UINFO) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 1410) | func (r1 *URI) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 1428) | func (r1 *X25) isDuplicate(_r2 RR) bool {
  method isDuplicate (line 1440) | func (r1 *ZONEMD) isDuplicate(_r2 RR) bool {

FILE: zmsg.go
  method pack (line 9) | func (rr *A) pack(msg []byte, off int, compression compressionMap, compr...
  method pack (line 17) | func (rr *AAAA) pack(msg []byte, off int, compression compressionMap, co...
  method pack (line 25) | func (rr *AFSDB) pack(msg []byte, off int, compression compressionMap, c...
  method pack (line 37) | func (rr *AMTRELAY) pack(msg []byte, off int, compression compressionMap...
  method pack (line 53) | func (rr *ANY) pack(msg []byte, off int, compression compressionMap, com...
  method pack (line 57) | func (rr *APL) pack(msg []byte, off int, compression compressionMap, com...
  method pack (line 65) | func (rr *AVC) pack(msg []byte, off int, compression compressionMap, com...
  method pack (line 73) | func (rr *CAA) pack(msg []byte, off int, compression compressionMap, com...
  method pack (line 89) | func (rr *CDNSKEY) pack(msg []byte, off int, compression compressionMap,...
  method pack (line 109) | func (rr *CDS) pack(msg []byte, off int, compression compressionMap, com...
  method pack (line 129) | func (rr *CERT) pack(msg []byte, off int, compression compressionMap, co...
  method pack (line 149) | func (rr *CNAME) pack(msg []byte, off int, compression compressionMap, c...
  method pack (line 157) | func (rr *CSYNC) pack(msg []byte, off int, compression compressionMap, c...
  method pack (line 173) | func (rr *DHCID) pack(msg []byte, off int, compression compressionMap, c...
  method pack (line 181) | func (rr *DLV) pack(msg []byte, off int, compression compressionMap, com...
  method pack (line 201) | func (rr *DNAME) pack(msg []byte, off int, compression compressionMap, c...
  method pack (line 209) | func (rr *DNSKEY) pack(msg []byte, off int, compression compressionMap, ...
  method pack (line 229) | func (rr *DS) pack(msg []byte, off int, compression compressionMap, comp...
  method pack (line 249) | func (rr *EID) pack(msg []byte, off int, compression compressionMap, com...
  method pack (line 257) | func (rr *EUI48) pack(msg []byte, off int, compression compressionMap, c...
  method pack (line 265) | func (rr *EUI64) pack(msg []byte, off int, compression compressionMap, c...
  method pack (line 273) | func (rr *GID) pack(msg []byte, off int, compression compressionMap, com...
  method pack (line 281) | func (rr *GPOS) pack(msg []byte, off int, compression compressionMap, co...
  method pack (line 297) | func (rr *HINFO) pack(msg []byte, off int, compression compressionMap, c...
  method pack (line 309) | func (rr *HIP) pack(msg []byte, off int, compression compressionMap, com...
  method pack (line 337) | func (rr *HTTPS) pack(msg []byte, off int, compression compressionMap, c...
  method pack (line 353) | func (rr *IPSECKEY) pack(msg []byte, off int, compression compressionMap...
  method pack (line 377) | func (rr *ISDN) pack(msg []byte, off int, compression compressionMap, co...
  method pack (line 389) | func (rr *KEY) pack(msg []byte, off int, compression compressionMap, com...
  method pack (line 409) | func (rr *KX) pack(msg []byte, off int, compression compressionMap, comp...
  method pack (line 421) | func (rr *L32) pack(msg []byte, off int, compression compressionMap, com...
  method pack (line 433) | func (rr *L64) pack(msg []byte, off int, compression compressionMap, com...
  method pack (line 445) | func (rr *LOC) pack(msg []byte, off int, compression compressionMap, com...
  method pack (line 477) | func (rr *LP) pack(msg []byte, off int, compression compressionMap, comp...
  method pack (line 489) | func (rr *MB) pack(msg []byte, off int, compression compressionMap, comp...
  method pack (line 497) | func (rr *MD) pack(msg []byte, off int, compression compressionMap, comp...
  method pack (line 505) | func (rr *MF) pack(msg []byte, off int, compression compressionMap, comp...
  method pack (line 513) | func (rr *MG) pack(msg []byte, off int, compression compressionMap, comp...
  method pack (line 521) | func (rr *MINFO) pack(msg []byte, off int, compression compressionMap, c...
  method pack (line 533) | func (rr *MR) pack(msg []byte, off int, compression compressionMap, comp...
  method pack (line 541) | func (rr *MX) pack(msg []byte, off int, compression compressionMap, comp...
  method pack (line 553) | func (rr *NAPTR) pack(msg []byte, off int, compression compressionMap, c...
  method pack (line 581) | func (rr *NID) pack(msg []byte, off int, compression compressionMap, com...
  method pack (line 593) | func (rr *NIMLOC) pack(msg []byte, off int, compression compressionMap, ...
  method pack (line 601) | func (rr *NINFO) pack(msg []byte, off int, compression compressionMap, c...
  method pack (line 609) | func (rr *NS) pack(msg []byte, off int, compression compressionMap, comp...
  method pack (line 617) | func (rr *NSAPPTR) pack(msg []byte, off int, compression compressionMap,...
  method pack (line 625) | func (rr *NSEC) pack(msg []byte, off int, compression compressionMap, co...
  method pack (line 637) | func (rr *NSEC3) pack(msg []byte, off int, compression compressionMap, c...
  method pack (line 676) | func (rr *NSEC3PARAM) pack(msg []byte, off int, compression compressionM...
  method pack (line 703) | func (rr *NULL) pack(msg []byte, off int, compression compressionMap, co...
  method pack (line 711) | func (rr *NXNAME) pack(msg []byte, off int, compression compressionMap, ...
  method pack (line 715) | func (rr *NXT) pack(msg []byte, off int, compression compressionMap, com...
  method pack (line 727) | func (rr *OPENPGPKEY) pack(msg []byte, off int, compression compressionM...
  method pack (line 735) | func (rr *OPT) pack(msg []byte, off int, compression compressionMap, com...
  method pack (line 743) | func (rr *PTR) pack(msg []byte, off int, compression compressionMap, com...
  method pack (line 751) | func (rr *PX) pack(msg []byte, off int, compression compressionMap, comp...
  method pack (line 767) | func (rr *RESINFO) pack(msg []byte, off int, compression compressionMap,...
  method pack (line 775) | func (rr *RFC3597) pack(msg []byte, off int, compression compressionMap,...
  method pack (line 783) | func (rr *RKEY) pack(msg []byte, off int, compression compressionMap, co...
  method pack (line 803) | func (rr *RP) pack(msg []byte, off int, compression compressionMap, comp...
  method pack (line 815) | func (rr *RRSIG) pack(msg []byte, off int, compression compressionMap, c...
  method pack (line 855) | func (rr *RT) pack(msg []byte, off int, compression compressionMap, comp...
  method pack (line 867) | func (rr *SIG) pack(msg []byte, off int, compression compressionMap, com...
  method pack (line 907) | func (rr *SMIMEA) pack(msg []byte, off int, compression compressionMap, ...
  method pack (line 927) | func (rr *SOA) pack(msg []byte, off int, compression compressionMap, com...
  method pack (line 959) | func (rr *SPF) pack(msg []byte, off int, compression compressionMap, com...
  method pack (line 967) | func (rr *SRV) pack(msg []byte, off int, compression compressionMap, com...
  method pack (line 987) | func (rr *SSHFP) pack(msg []byte, off int, compression compressionMap, c...
  method pack (line 1003) | func (rr *SVCB) pack(msg []byte, off int, compression compressionMap, co...
  method pack (line 1019) | func (rr *TA) pack(msg []byte, off int, compression compressionMap, comp...
  method pack (line 1039) | func (rr *TALINK) pack(msg []byte, off int, compression compressionMap, ...
  method pack (line 1051) | func (rr *TKEY) pack(msg []byte, off int, compression compressionMap, co...
  method pack (line 1091) | func (rr *TLSA) pack(msg []byte, off int, compression compressionMap, co...
  method pack (line 1111) | func (rr *TSIG) pack(msg []byte, off int, compression compressionMap, co...
  method pack (line 1151) | func (rr *TXT) pack(msg []byte, off int, compression compressionMap, com...
  method pack (line 1159) | func (rr *UID) pack(msg []byte, off int, compression compressionMap, com...
  method pack (line 1167) | func (rr *UINFO) pack(msg []byte, off int, compression compressionMap, c...
  method pack (line 1175) | func (rr *URI) pack(msg []byte, off int, compression compressionMap, com...
  method pack (line 1191) | func (rr *X25) pack(msg []byte, off int, compression compressionMap, com...
  method pack (line 1199) | func (rr *ZONEMD) pack(msg []byte, off int, compression compressionMap, ...
  method unpack (line 1221) | func (rr *A) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1232) | func (rr *AAAA) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1243) | func (rr *AFSDB) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1261) | func (rr *AMTRELAY) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1289) | func (rr *ANY) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1296) | func (rr *APL) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1307) | func (rr *AVC) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1318) | func (rr *CAA) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1343) | func (rr *CDNSKEY) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1375) | func (rr *CDS) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1407) | func (rr *CERT) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1439) | func (rr *CNAME) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1450) | func (rr *CSYNC) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1475) | func (rr *DHCID) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1486) | func (rr *DLV) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1518) | func (rr *DNAME) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1529) | func (rr *DNSKEY) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1561) | func (rr *DS) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1593) | func (rr *EID) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1604) | func (rr *EUI48) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1615) | func (rr *EUI64) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1626) | func (rr *GID) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1637) | func (rr *GPOS) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1662) | func (rr *HINFO) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1680) | func (rr *HIP) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1720) | func (rr *HTTPS) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1745) | func (rr *IPSECKEY) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1787) | func (rr *ISDN) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1805) | func (rr *KEY) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1837) | func (rr *KX) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1855) | func (rr *L32) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1873) | func (rr *L64) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1891) | func (rr *LOC) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1944) | func (rr *LP) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1962) | func (rr *MB) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1973) | func (rr *MD) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1984) | func (rr *MF) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 1995) | func (rr *MG) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2006) | func (rr *MINFO) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2024) | func (rr *MR) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2035) | func (rr *MX) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2053) | func (rr *NAPTR) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2099) | func (rr *NID) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2117) | func (rr *NIMLOC) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2128) | func (rr *NINFO) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2139) | func (rr *NS) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2150) | func (rr *NSAPPTR) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2161) | func (rr *NSEC) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2179) | func (rr *NSEC3) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2233) | func (rr *NSEC3PARAM) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2272) | func (rr *NULL) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2283) | func (rr *NXNAME) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2290) | func (rr *NXT) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2308) | func (rr *OPENPGPKEY) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2319) | func (rr *OPT) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2330) | func (rr *PTR) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2341) | func (rr *PX) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2366) | func (rr *RESINFO) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2377) | func (rr *RFC3597) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2388) | func (rr *RKEY) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2420) | func (rr *RP) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2438) | func (rr *RRSIG) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2505) | func (rr *RT) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2523) | func (rr *SIG) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2590) | func (rr *SMIMEA) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2622) | func (rr *SOA) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2675) | func (rr *SPF) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2686) | func (rr *SRV) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2718) | func (rr *SSHFP) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2743) | func (rr *SVCB) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2768) | func (rr *TA) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2800) | func (rr *TALINK) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2818) | func (rr *TKEY) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2882) | func (rr *TLSA) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2914) | func (rr *TSIG) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2978) | func (rr *TXT) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 2989) | func (rr *UID) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 3000) | func (rr *UINFO) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 3011) | func (rr *URI) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 3036) | func (rr *X25) unpack(msg []byte, off int) (off1 int, err error) {
  method unpack (line 3047) | func (rr *ZONEMD) unpack(msg []byte, off int) (off1 int, err error) {

FILE: ztypes.go
  method Header (line 186) | func (rr *A) Header() *RR_Header          { return &rr.Hdr }
  method Header (line 187) | func (rr *AAAA) Header() *RR_Header       { return &rr.Hdr }
  method Header (line 188) | func (rr *AFSDB) Header() *RR_Header      { return &rr.Hdr }
  method Header (line 189) | func (rr *AMTRELAY) Header() *RR_Header   { return &rr.Hdr }
  method Header (line 190) | func (rr *ANY) Header() *RR_Header        { return &rr.Hdr }
  method Header (line 191) | func (rr *APL) Header() *RR_Header        { return &rr.Hdr }
  method Header (line 192) | func (rr *AVC) Header() *RR_Header        { return &rr.Hdr }
  method Header (line 193) | func (rr *CAA) Header() *RR_Header        { return &rr.Hdr }
  method Header (line 194) | func (rr *CDNSKEY) Header() *RR_Header    { return &rr.Hdr }
  method Header (line 195) | func (rr *CDS) Header() *RR_Header        { return &rr.Hdr }
  method Header (line 196) | func (rr *CERT) Header() *RR_Header       { return &rr.Hdr }
  method Header (line 197) | func (rr *CNAME) Header() *RR_Header      { return &rr.Hdr }
  method Header (line 198) | func (rr *CSYNC) Header() *RR_Header      { return &rr.Hdr }
  method Header (line 199) | func (rr *DHCID) Header() *RR_Header      { return &rr.Hdr }
  method Header (line 200) | func (rr *DLV) Header() *RR_Header        { return &rr.Hdr }
  method Header (line 201) | func (rr *DNAME) Header() *RR_Header      { return &rr.Hdr }
  method Header (line 202) | func (rr *DNSKEY) Header() *RR_Header     { return &rr.Hdr }
  method Header (line 203) | func (rr *DS) Header() *RR_Header         { return &rr.Hdr }
  method Header (line 204) | func (rr *EID) Header() *RR_Header        { return &rr.Hdr }
  method Header (line 205) | func (rr *EUI48) Header() *RR_Header      { return &rr.Hdr }
  method Header (line 206) | func (rr *EUI64) Header() *RR_Header      { return &rr.Hdr }
  method Header (line 207) | func (rr *GID) Header() *RR_Header        { return &rr.Hdr }
  method Header (line 208) | func (rr *GPOS) Header() *RR_Header       { return &rr.Hdr }
  method Header (line 209) | func (rr *HINFO) Header() *RR_Header      { return &rr.Hdr }
  method Header (line 210) | func (rr *HIP) Header() *RR_Header        { return &rr.Hdr }
  method Header (line 211) | func (rr *HTTPS) Header() *RR_Header      { return &rr.Hdr }
  method Header (line 212) | func (rr *IPSECKEY) Header() *RR_Header   { return &rr.Hdr }
  method Header (line 213) | func (rr *ISDN) Header() *RR_Header       { return &rr.Hdr }
  method Header (line 214) | func (rr *KEY) Header() *RR_Header        { return &rr.Hdr }
  method Header (line 215) | func (rr *KX) Header() *RR_Header         { return &rr.Hdr }
  method Header (line 216) | func (rr *L32) Header() *RR_Header        { return &rr.Hdr }
  method Header (line 217) | func (rr *L64) Header() *RR_Header        { return &rr.Hdr }
  method Header (line 218) | func (rr *LOC) Header() *RR_Header        { return &rr.Hdr }
  method Header (line 219) | func (rr *LP) Header() *RR_Header         { return &rr.Hdr }
  method Header (line 220) | func (rr *MB) Header() *RR_Header         { return &rr.Hdr }
  method Header (line 221) | func (rr *MD) Header() *RR_Header         { return &rr.Hdr }
  method Header (line 222) | func (rr *MF) Header() *RR_Header         { return &rr.Hdr }
  method Header (line 223) | func (rr *MG) Header() *RR_Header         { return &rr.Hdr }
  method Header (line 224) | func (rr *MINFO) Header() *RR_Header      { return &rr.Hdr }
  method Header (line 225) | func (rr *MR) Header() *RR_Header         { return &rr.Hdr }
  method Header (line 226) | func (rr *MX) Header() *RR_Header         { return &rr.Hdr }
  method Header (line 227) | func (rr *NAPTR) Header() *RR_Header      { return &rr.Hdr }
  method Header (line 228) | func (rr *NID) Header() *RR_Header        { return &rr.Hdr }
  method Header (line 229) | func (rr *NIMLOC) Header() *RR_Header     { return &rr.Hdr }
  method Header (line 230) | func (rr *NINFO) Header() *RR_Header      { return &rr.Hdr }
  method Header (line 231) | func (rr *NS) Header() *RR_Header         { return &rr.Hdr }
  method Header (line 232) | func (rr *NSAPPTR) Header() *RR_Header    { return &rr.Hdr }
  method Header (line 233) | func (rr *NSEC) Header() *RR_Header       { return &rr.Hdr }
  method Header (line 234) | func (rr *NSEC3) Header() *RR_Header      { return &rr.Hdr }
  method Header (line 235) | func (rr *NSEC3PARAM) Header() *RR_Header { return &rr.Hdr }
  method Header (line 236) | func (rr *NULL) Header() *RR_Header       { return &rr.Hdr }
  method Header (line 237) | func (rr *NXNAME) Header() *RR_Header     { return &rr.Hdr }
  method Header (line 238) | func (rr *NXT) Header() *RR_Header        { return &rr.Hdr }
  method Header (line 239) | func (rr *OPENPGPKEY) Header() *RR_Header { return &rr.Hdr }
  method Header (line 240) | func (rr *OPT) Header() *RR_Header        { return &rr.Hdr }
  method Header (line 241) | func (rr *PTR) Header() *RR_Header        { return &rr.Hdr }
  method Header (line 242) | func (rr *PX) Header() *RR_Header         { return &rr.Hdr }
  method Header (line 243) | func (rr *RESINFO) Header() *RR_Header    { return &rr.Hdr }
  method Header (line 244) | func (rr *RFC3597) Header() *RR_Header    { return &rr.Hdr }
  method Header (line 245) | func (rr *RKEY) Header() *RR_Header       { return &rr.Hdr }
  method Header (line 246) | func (rr *RP) Header() *RR_Header         { return &rr.Hdr }
  method Header (line 247) | func (rr *RRSIG) Header() *RR_Header      { return &rr.Hdr }
  method Header (line 248) | func (rr *RT) Header() *RR_Header         { return &rr.Hdr }
  method Header (line 249) | func (rr *SIG) Header() *RR_Header        { return &rr.Hdr }
  method Header (line 250) | func (rr *SMIMEA) Header() *RR_Header     { return &rr.Hdr }
  method Header (line 251) | func (rr *SOA) Header() *RR_Header        { return &rr.Hdr }
  method Header (line 252) | func (rr *SPF) Header() *RR_Header        { return &rr.Hdr }
  method Header (line 253) | func (rr *SRV) Header() *RR_Header        { return &rr.Hdr }
  method Header (line 254) | func (rr *SSHFP) Header() *RR_Header      { return &rr.Hdr }
  method Header (line 255) | func (rr *SVCB) Header() *RR_Header       { return &rr.Hdr }
  method Header (line 256) | func (rr *TA) Header() *RR_Header         { return &rr.Hdr }
  method Header (line 257) | func (rr *TALINK) Header() *RR_Header     { return &rr.Hdr }
  method Header (line 258) | func (rr *TKEY) Header() *RR_Header       { return &rr.Hdr }
  method Header (line 259) | func (rr *TLSA) Header() *RR_Header       { return &rr.Hdr }
  method Header (line 260) | func (rr *TSIG) Header() *RR_Header       { return &rr.Hdr }
  method Header (line 261) | func (rr *TXT) Header() *RR_Header        { return &rr.Hdr }
  method Header (line 262) | func (rr *UID) Header() *RR_Header        { return &rr.Hdr }
  method Header (line 263) | func (rr *UINFO) Header() *RR_Header      { return &rr.Hdr }
  method Header (line 264) | func (rr *URI) Header() *RR_Header        { return &rr.Hdr }
  method Header (line 265) | func (rr *X25) Header() *RR_Header        { return &rr.Hdr }
  method Header (line 266) | func (rr *ZONEMD) Header() *RR_Header     { return &rr.Hdr }
  method len (line 269) | func (rr *A) len(off int, compression map[string]struct{}) int {
  method len (line 277) | func (rr *AAAA) len(off int, compression map[string]struct{}) int {
  method len (line 285) | func (rr *AFSDB) len(off int, compression map[string]struct{}) int {
  method len (line 292) | func (rr *AMTRELAY) len(off int, compression map[string]struct{}) int {
  method len (line 307) | func (rr *ANY) len(off int, compression map[string]struct{}) int {
  method len (line 312) | func (rr *APL) len(off int, compression map[string]struct{}) int {
  method len (line 320) | func (rr *AVC) len(off int, compression map[string]struct{}) int {
  method len (line 328) | func (rr *CAA) len(off int, compression map[string]struct{}) int {
  method len (line 336) | func (rr *CERT) len(off int, compression map[string]struct{}) int {
  method len (line 345) | func (rr *CNAME) len(off int, compression map[string]struct{}) int {
  method len (line 351) | func (rr *DHCID) len(off int, compression map[string]struct{}) int {
  method len (line 357) | func (rr *DNAME) len(off int, compression map[string]struct{}) int {
  method len (line 363) | func (rr *DNSKEY) len(off int, compression map[string]struct{}) int {
  method len (line 372) | func (rr *DS) len(off int, compression map[string]struct{}) int {
  method len (line 381) | func (rr *EID) len(off int, compression map[string]struct{}) int {
  method len (line 387) | func (rr *EUI48) len(off int, compression map[string]struct{}) int {
  method len (line 393) | func (rr *EUI64) len(off int, compression map[string]struct{}) int {
  method len (line 399) | func (rr *GID) len(off int, compression map[string]struct{}) int {
  method len (line 405) | func (rr *GPOS) len(off int, compression map[string]struct{}) int {
  method len (line 413) | func (rr *HINFO) len(off int, compression map[string]struct{}) int {
  method len (line 420) | func (rr *HIP) len(off int, compression map[string]struct{}) int {
  method len (line 433) | func (rr *IPSECKEY) len(off int, compression map[string]struct{}) int {
  method len (line 450) | func (rr *ISDN) len(off int, compression map[string]struct{}) int {
  method len (line 457) | func (rr *KX) len(off int, compression map[string]struct{}) int {
  method len (line 464) | func (rr *L32) len(off int, compression map[string]struct{}) int {
  method len (line 473) | func (rr *L64) len(off int, compression map[string]struct{}) int {
  method len (line 480) | func (rr *LOC) len(off int, compression map[string]struct{}) int {
  method len (line 492) | func (rr *LP) len(off int, compression map[string]struct{}) int {
  method len (line 499) | func (rr *MB) len(off int, compression map[string]struct{}) int {
  method len (line 505) | func (rr *MD) len(off int, compression map[string]struct{}) int {
  method len (line 511) | func (rr *MF) len(off int, compression map[string]struct{}) int {
  method len (line 517) | func (rr *MG) len(off int, compression map[string]struct{}) int {
  method len (line 523) | func (rr *MINFO) len(off int, compression map[string]struct{}) int {
  method len (line 530) | func (rr *MR) len(off int, compression map[string]struct{}) int {
  method len (line 536) | func (rr *MX) len(off int, compression map[string]struct{}) int {
  method len (line 543) | func (rr *NAPTR) len(off int, compression map[string]struct{}) int {
  method len (line 554) | func (rr *NID) len(off int, compression map[string]struct{}) int {
  method len (line 561) | func (rr *NIMLOC) len(off int, compression map[string]struct{}) int {
  method len (line 567) | func (rr *NINFO) len(off int, compression map[string]struct{}) int {
  method len (line 575) | func (rr *NS) len(off int, compression map[string]struct{}) int {
  method len (line 581) | func (rr *NSAPPTR) len(off int, compression map[string]struct{}) int {
  method len (line 587) | func (rr *NSEC3PARAM) len(off int, compression map[string]struct{}) int {
  method len (line 597) | func (rr *NULL) len(off int, compression map[string]struct{}) int {
  method len (line 603) | func (rr *NXNAME) len(off int, compression map[string]struct{}) int {
  method len (line 608) | func (rr *OPENPGPKEY) len(off int, compression map[string]struct{}) int {
  method len (line 614) | func (rr *PTR) len(off int, compression map[string]struct{}) int {
  method len (line 620) | func (rr *PX) len(off int, compression map[string]struct{}) int {
  method len (line 628) | func (rr *RESINFO) len(off int, compression map[string]struct{}) int {
  method len (line 636) | func (rr *RFC3597) len(off int, compression map[string]struct{}) int {
  method len (line 642) | func (rr *RKEY) len(off int, compression map[string]struct{}) int {
  method len (line 651) | func (rr *RP) len(off int, compression map[string]struct{}) int {
  method len (line 658) | func (rr *RRSIG) len(off int, compression map[string]struct{}) int {
  method len (line 672) | func (rr *RT) len(off int, compression map[string]struct{}) int {
  method len (line 679) | func (rr *SMIMEA) len(off int, compression map[string]struct{}) int {
  method len (line 688) | func (rr *SOA) len(off int, compression map[string]struct{}) int {
  method len (line 700) | func (rr *SPF) len(off int, compression map[string]struct{}) int {
  method len (line 708) | func (rr *SRV) len(off int, compression map[string]struct{}) int {
  method len (line 717) | func (rr *SSHFP) len(off int, compression map[string]struct{}) int {
  method len (line 725) | func (rr *SVCB) len(off int, compression map[string]struct{}) int {
  method len (line 735) | func (rr *TA) len(off int, compression map[string]struct{}) int {
  method len (line 744) | func (rr *TALINK) len(off int, compression map[string]struct{}) int {
  method len (line 751) | func (rr *TKEY) len(off int, compression map[string]struct{}) int {
  method len (line 765) | func (rr *TLSA) len(off int, compression map[string]struct{}) int {
  method len (line 774) | func (rr *TSIG) len(off int, compression map[string]struct{}) int {
  method len (line 788) | func (rr *TXT) len(off int, compression map[string]struct{}) int {
  method len (line 796) | func (rr *UID) len(off int, compression map[string]struct{}) int {
  method len (line 802) | func (rr *UINFO) len(off int, compression map[string]struct{}) int {
  method len (line 808) | func (rr *URI) len(off int, compression map[string]struct{}) int {
  method len (line 816) | func (rr *X25) len(off int, compression map[string]struct{}) int {
  method len (line 822) | func (rr *ZONEMD) len(off int, compression map[string]struct{}) int {
  method copy (line 832) | func (rr *A) copy() RR {
  method copy (line 836) | func (rr *AAAA) copy() RR {
  method copy (line 840) | func (rr *AFSDB) copy() RR {
  method copy (line 844) | func (rr *AMTRELAY) copy() RR {
  method copy (line 854) | func (rr *ANY) copy() RR {
  method copy (line 858) | func (rr *APL) copy() RR {
  method copy (line 866) | func (rr *AVC) copy() RR {
  method copy (line 870) | func (rr *CAA) copy() RR {
  method copy (line 879) | func (rr *CDNSKEY) copy() RR {
  method copy (line 883) | func (rr *CDS) copy() RR {
  method copy (line 887) | func (rr *CERT) copy() RR {
  method copy (line 897) | func (rr *CNAME) copy() RR {
  method copy (line 901) | func (rr *CSYNC) copy() RR {
  method copy (line 910) | func (rr *DHCID) copy() RR {
  method copy (line 914) | func (rr *DLV) copy() RR {
  method copy (line 918) | func (rr *DNAME) copy() RR {
  method copy (line 922) | func (rr *DNSKEY) copy() RR {
  method copy (line 932) | func (rr *DS) copy() RR {
  method copy (line 942) | func (rr *EID) copy() RR {
  method copy (line 946) | func (rr *EUI48) copy() RR {
  method copy (line 950) | func (rr *EUI64) copy() RR {
  method copy (line 954) | func (rr *GID) copy() RR {
  method copy (line 958) | func (rr *GPOS) copy() RR {
  method copy (line 967) | func (rr *HINFO) copy() RR {
  method copy (line 971) | func (rr *HIP) copy() RR {
  method copy (line 983) | func (rr *HTTPS) copy() RR {
  method copy (line 987) | func (rr *IPSECKEY) copy() RR {
  method copy (line 999) | func (rr *ISDN) copy() RR {
  method copy (line 1003) | func (rr *KEY) copy() RR {
  method copy (line 1007) | func (rr *KX) copy() RR {
  method copy (line 1011) | func (rr *L32) copy() RR {
  method copy (line 1015) | func (rr *L64) copy() RR {
  method copy (line 1019) | func (rr *LOC) copy() RR {
  method copy (line 1032) | func (rr *LP) copy() RR {
  method copy (line 1036) | func (rr *MB) copy() RR {
  method copy (line 1040) | func (rr *MD) copy() RR {
  method copy (line 1044) | func (rr *MF) copy() RR {
  method copy (line 1048) | func (rr *MG) copy() RR {
  method copy (line 1052) | func (rr *MINFO) copy() RR {
  method copy (line 1056) | func (rr *MR) copy() RR {
  method copy (line 1060) | func (rr *MX) copy() RR {
  method copy (line 1064) | func (rr *NAPTR) copy() RR {
  method copy (line 1076) | func (rr *NID) copy() RR {
  method copy (line 1080) | func (rr *NIMLOC) copy() RR {
  method copy (line 1084) | func (rr *NINFO) copy() RR {
  method copy (line 1088) | func (rr *NS) copy() RR {
  method copy (line 1092) | func (rr *NSAPPTR) copy() RR {
  method copy (line 1096) | func (rr *NSEC) copy() RR {
  method copy (line 1100) | func (rr *NSEC3) copy() RR {
  method copy (line 1114) | func (rr *NSEC3PARAM) copy() RR {
  method copy (line 1125) | func (rr *NULL) copy() RR {
  method copy (line 1129) | func (rr *NXNAME) copy() RR {
  method copy (line 1133) | func (rr *NXT) copy() RR {
  method copy (line 1137) | func (rr *OPENPGPKEY) copy() RR {
  method copy (line 1141) | func (rr *OPT) copy() RR {
  method copy (line 1149) | func (rr *PTR) copy() RR {
  method copy (line 1153) | func (rr *PX) copy() RR {
  method copy (line 1162) | func (rr *RESINFO) copy() RR {
  method copy (line 1166) | func (rr *RFC3597) copy() RR {
  method copy (line 1170) | func (rr *RKEY) copy() RR {
  method copy (line 1180) | func (rr *RP) copy() RR {
  method copy (line 1184) | func (rr *RRSIG) copy() RR {
  method copy (line 1199) | func (rr *RT) copy() RR {
  method copy (line 1203) | func (rr *SIG) copy() RR {
  method copy (line 1207) | func (rr *SMIMEA) copy() RR {
  method copy (line 1217) | func (rr *SOA) copy() RR {
  method copy (line 1230) | func (rr *SPF) copy() RR {
  method copy (line 1234) | func (rr *SRV) copy() RR {
  method copy (line 1244) | func (rr *SSHFP) copy() RR {
  method copy (line 1253) | func (rr *SVCB) copy() RR {
  method copy (line 1266) | func (rr *TA) copy() RR {
  method copy (line 1276) | func (rr *TALINK) copy() RR {
  method copy (line 1280) | func (rr *TKEY) copy() RR {
  method copy (line 1295) | func (rr *TLSA) copy() RR {
  method copy (line 1305) | func (rr *TSIG) copy() RR {
  method copy (line 1320) | func (rr *TXT) copy() RR {
  method copy (line 1324) | func (rr *UID) copy() RR {
  method copy (line 1328) | func (rr *UINFO) copy() RR {
  method copy (line 1332) | func (rr *URI) copy() RR {
  method copy (line 1341) | func (rr *X25) copy() RR {
  method copy (line 1345) | func (rr *ZONEMD) copy() RR {
Condensed preview — 105 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,032K chars).
[
  {
    "path": ".codecov.yml",
    "chars": 128,
    "preview": "coverage:\n  status:\n    project:\n      default:\n        target: 40%\n        threshold: null\n    patch: false\n    changes"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 167,
    "preview": "version: 2\nupdates:\n  - package-ecosystem: \"gomod\"\n    directory: \"/\"\n    schedule:\n      interval: \"monthly\"\n    groups"
  },
  {
    "path": ".github/pull_request_template.md",
    "chars": 380,
    "preview": "Thanks for you pull request, do note the following:\n\n- If your PR introduces backward incompatible changes it will very "
  },
  {
    "path": ".github/workflows/codeql-analysis.yml",
    "chars": 614,
    "preview": "name: \"Code scanning - action\"\n\non:\n  push:\n    branches: [master, ]\n  pull_request:\n    branches: [master]\n  schedule:\n"
  },
  {
    "path": ".github/workflows/go.yml",
    "chars": 438,
    "preview": "name: Go\non: [push, pull_request]\njobs:\n\n  build:\n    name: Build and Test\n    runs-on: ubuntu-latest\n    strategy:\n    "
  },
  {
    "path": ".gitignore",
    "chars": 24,
    "preview": "*.6\ntags\ntest.out\na.out\n"
  },
  {
    "path": "AUTHORS",
    "chars": 27,
    "preview": "Miek Gieben <miek@miek.nl>\n"
  },
  {
    "path": "CODEOWNERS",
    "chars": 18,
    "preview": "* @miekg @tmthrgd\n"
  },
  {
    "path": "CONTRIBUTORS",
    "chars": 149,
    "preview": "Alex A. Skinner\nAndrew Tunnell-Jones\nAsk Bjørn Hansen\nDave Cheney\nDusty Wilson\nMarek Majkowski\nPeter van Dijk\nOmri Bahum"
  },
  {
    "path": "COPYRIGHT",
    "chars": 512,
    "preview": "Copyright 2009 The Go Authors. All rights reserved. Use of this source code\nis governed by a BSD-style license that can "
  },
  {
    "path": "LICENSE",
    "chars": 1568,
    "preview": "BSD 3-Clause License\n\nCopyright (c) 2009, The Go Authors. Extensions copyright (c) 2011, Miek Gieben. \nAll rights reserv"
  },
  {
    "path": "Makefile.fuzz",
    "chars": 671,
    "preview": "# Makefile for fuzzing\n#\n# Use go-fuzz and needs the tools installed.\n# See https://blog.cloudflare.com/dns-parser-meet-"
  },
  {
    "path": "Makefile.release",
    "chars": 992,
    "preview": "# Makefile for releasing.\n#\n# The release is controlled from version.go. The version found there is\n# used to tag the gi"
  },
  {
    "path": "README.md",
    "chars": 7352,
    "preview": "[![Build Status](https://travis-ci.org/miekg/dns.svg?branch=master)](https://travis-ci.org/miekg/dns)\n[![Code Coverage]("
  },
  {
    "path": "acceptfunc.go",
    "chars": 1904,
    "preview": "package dns\n\n// MsgAcceptFunc is used early in the server code to accept or reject a message with RcodeFormatError.\n// I"
  },
  {
    "path": "acceptfunc_test.go",
    "chars": 2900,
    "preview": "package dns\n\nimport (\n\t\"encoding/binary\"\n\t\"net\"\n\t\"testing\"\n)\n\nfunc TestAcceptNotify(t *testing.T) {\n\tHandleFunc(\"example"
  },
  {
    "path": "client.go",
    "chars": 14643,
    "preview": "package dns\n\n// A client implementation.\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"encoding/binary\"\n\t\"io\"\n\t\"net\"\n\t\"strings\"\n\t"
  },
  {
    "path": "client_test.go",
    "chars": 18114,
    "preview": "package dns\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"strconv\"\n\t\"strings\"\n\t\"syscall\"\n\t\"testing\"\n\t\"tim"
  },
  {
    "path": "clientconfig.go",
    "chars": 3365,
    "preview": "package dns\n\nimport (\n\t\"bufio\"\n\t\"io\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// ClientConfig wraps the contents of the /etc/resol"
  },
  {
    "path": "clientconfig_test.go",
    "chars": 4631,
    "preview": "package dns\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n)\n\nconst normal string = `\n# Comment\ndomain somedomai"
  },
  {
    "path": "dane.go",
    "chars": 997,
    "preview": "package dns\n\nimport (\n\t\"crypto/sha256\"\n\t\"crypto/sha512\"\n\t\"crypto/x509\"\n\t\"encoding/hex\"\n\t\"errors\"\n)\n\n// CertificateToDANE"
  },
  {
    "path": "defaults.go",
    "chars": 10928,
    "preview": "package dns\n\nimport (\n\t\"errors\"\n\t\"net\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nconst hexDigit = \"0123456789abcdef\"\n\n// Everything is as"
  },
  {
    "path": "dns.go",
    "chars": 4449,
    "preview": "package dns\n\nimport (\n\t\"encoding/hex\"\n\t\"strconv\"\n)\n\nconst (\n\tyear68     = 1 << 31 // For RFC1982 (Serial Arithmetic) cal"
  },
  {
    "path": "dns_bench_test.go",
    "chars": 9647,
    "preview": "package dns\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"testing\"\n)\n\nfunc BenchmarkMsgLength(b *testing.B) {\n\tb.StopTimer()\n\tmakeMsg := fun"
  },
  {
    "path": "dns_test.go",
    "chars": 11006,
    "preview": "package dns\n\nimport (\n\t\"bytes\"\n\t\"encoding/hex\"\n\t\"net\"\n\t\"testing\"\n)\n\nfunc TestPackUnpack(t *testing.T) {\n\tout := new(Msg)"
  },
  {
    "path": "dnssec.go",
    "chars": 19341,
    "preview": "package dns\n\nimport (\n\t\"bytes\"\n\t\"crypto\"\n\t\"crypto/ecdsa\"\n\t\"crypto/ed25519\"\n\t\"crypto/elliptic\"\n\t\"crypto/rand\"\n\t\"crypto/rs"
  },
  {
    "path": "dnssec_keygen.go",
    "chars": 3176,
    "preview": "package dns\n\nimport (\n\t\"crypto\"\n\t\"crypto/ecdsa\"\n\t\"crypto/ed25519\"\n\t\"crypto/elliptic\"\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"math"
  },
  {
    "path": "dnssec_keyscan.go",
    "chars": 6345,
    "preview": "package dns\n\nimport (\n\t\"bufio\"\n\t\"crypto\"\n\t\"crypto/ecdsa\"\n\t\"crypto/ed25519\"\n\t\"crypto/rsa\"\n\t\"io\"\n\t\"math/big\"\n\t\"strconv\"\n\t\""
  },
  {
    "path": "dnssec_privkey.go",
    "chars": 2325,
    "preview": "package dns\n\nimport (\n\t\"crypto\"\n\t\"crypto/ecdsa\"\n\t\"crypto/ed25519\"\n\t\"crypto/rsa\"\n\t\"math/big\"\n\t\"strconv\"\n)\n\nconst format ="
  },
  {
    "path": "dnssec_test.go",
    "chars": 34768,
    "preview": "package dns\n\nimport (\n\t\"crypto\"\n\t\"crypto/ecdsa\"\n\t\"crypto/ed25519\"\n\t\"crypto/rsa\"\n\t\"reflect\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\""
  },
  {
    "path": "dnsutil/util.go",
    "chars": 2515,
    "preview": "// Package dnsutil contains higher-level methods useful with the dns\n// package.  While package dns implements the DNS p"
  },
  {
    "path": "dnsutil/util_test.go",
    "chars": 3987,
    "preview": "package dnsutil\n\nimport \"testing\"\n\nfunc TestAddOrigin(t *testing.T) {\n\tvar tests = []struct{ e1, e2, expected string }{\n"
  },
  {
    "path": "doc.go",
    "chars": 10725,
    "preview": "/*\nPackage dns implements a full featured interface to the Domain Name System.\nBoth server- and client-side programming "
  },
  {
    "path": "duplicate.go",
    "chars": 953,
    "preview": "package dns\n\n//go:generate go run duplicate_generate.go\n\n// IsDuplicate checks of r1 and r2 are duplicates of each other"
  },
  {
    "path": "duplicate_generate.go",
    "chars": 4369,
    "preview": "//go:build ignore\n// +build ignore\n\n// types_generate.go is meant to run with go generate. It will use\n// go/{importer,t"
  },
  {
    "path": "duplicate_test.go",
    "chars": 3862,
    "preview": "package dns\n\nimport \"testing\"\n\nfunc TestDuplicateA(t *testing.T) {\n\ta1, _ := NewRR(\"www.example.org. 2700 IN A 127.0.0.1"
  },
  {
    "path": "dyn_test.go",
    "chars": 37,
    "preview": "package dns\n\n// Find better solution\n"
  },
  {
    "path": "edns.go",
    "chars": 29676,
    "preview": "package dns\n\nimport (\n\t\"encoding/binary\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"strconv\"\n)\n\n// EDNS0 Option codes.\nco"
  },
  {
    "path": "edns_test.go",
    "chars": 7134,
    "preview": "package dns\n\nimport (\n\t\"bytes\"\n\t\"net\"\n\t\"testing\"\n)\n\nfunc TestOPTTtl(t *testing.T) {\n\te := &OPT{}\n\te.Hdr.Name = \".\"\n\te.Hd"
  },
  {
    "path": "example_test.go",
    "chars": 3335,
    "preview": "package dns_test\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\t\"net\"\n\n\t\"github.com/miekg/dns\"\n)\n\n// Retrieve the MX records for mie"
  },
  {
    "path": "format.go",
    "chars": 2454,
    "preview": "package dns\n\nimport (\n\t\"net\"\n\t\"reflect\"\n\t\"strconv\"\n)\n\n// NumField returns the number of rdata fields r has.\nfunc NumFiel"
  },
  {
    "path": "format_test.go",
    "chars": 279,
    "preview": "package dns\n\nimport (\n\t\"testing\"\n)\n\nfunc TestFieldEmptyAOrAAAAData(t *testing.T) {\n\tres := Field(new(A), 1)\n\tif res != \""
  },
  {
    "path": "fuzz.go",
    "chars": 552,
    "preview": "//go:build fuzz\n// +build fuzz\n\npackage dns\n\nimport \"strings\"\n\nfunc Fuzz(data []byte) int {\n\tmsg := new(Msg)\n\n\tif err :="
  },
  {
    "path": "fuzz_test.go",
    "chars": 7723,
    "preview": "package dns\n\nimport (\n\t\"net\"\n\t\"testing\"\n)\n\n// TestPackDataOpt tests generated using fuzz.go and with a message pack\n// c"
  },
  {
    "path": "generate.go",
    "chars": 5014,
    "preview": "package dns\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// Parse the $GENERATE statement as used in BIND9 z"
  },
  {
    "path": "generate_test.go",
    "chars": 6952,
    "preview": "package dns\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestGenerateRangeGuard(t *testing.T) {"
  },
  {
    "path": "go.mod",
    "chars": 225,
    "preview": "module github.com/miekg/dns\n\ngo 1.24.0\n\ntoolchain go1.24.2\n\nrequire (\n\tgolang.org/x/net v0.49.0\n\tgolang.org/x/sync v0.19"
  },
  {
    "path": "go.sum",
    "chars": 938,
    "preview": "github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\ngithub.com/google/go-cmp v0.6.0/go.mod h"
  },
  {
    "path": "hash.go",
    "chars": 875,
    "preview": "package dns\n\nimport (\n\t\"bytes\"\n\t\"crypto\"\n\t\"hash\"\n)\n\n// identityHash will not hash, it only buffers the data written into"
  },
  {
    "path": "issue_test.go",
    "chars": 1216,
    "preview": "package dns\n\n// Tests that solve that an specific issue.\n\nimport (\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestNSEC3MissingSalt(t "
  },
  {
    "path": "labels.go",
    "chars": 4246,
    "preview": "package dns\n\n// Holds a bunch of helper functions for dealing with labels.\n\n// SplitDomainName splits a name string into"
  },
  {
    "path": "labels_test.go",
    "chars": 8257,
    "preview": "package dns\n\nimport \"testing\"\n\nfunc TestCompareDomainName(t *testing.T) {\n\ts1 := \"www.miek.nl.\"\n\ts2 := \"miek.nl.\"\n\ts3 :="
  },
  {
    "path": "leak_test.go",
    "chars": 1851,
    "preview": "package dns\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"runtime\"\n\t\"sort\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n)\n\n// copied from net/http/main_test"
  },
  {
    "path": "length_test.go",
    "chars": 20979,
    "preview": "package dns\n\nimport (\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"net\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestCompressLength(t *testing.T) {\n\tm "
  },
  {
    "path": "listen_no_socket_options.go",
    "chars": 921,
    "preview": "//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd\n// +build !aix,!darwin,!dragonfly,"
  },
  {
    "path": "listen_socket_options.go",
    "chars": 2177,
    "preview": "//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd\n// +build aix darwin dragonfly freebsd li"
  },
  {
    "path": "msg.go",
    "chars": 33768,
    "preview": "// DNS packet assembly, see RFC 1035. Converting from - Unpack() -\n// and to - Pack() - wire format.\n// All the packers "
  },
  {
    "path": "msg_generate.go",
    "chars": 10835,
    "preview": "//go:build ignore\n// +build ignore\n\n// msg_generate.go is meant to run with go generate. It will use\n// go/{importer,typ"
  },
  {
    "path": "msg_helpers.go",
    "chars": 22419,
    "preview": "package dns\n\nimport (\n\t\"encoding/base32\"\n\t\"encoding/base64\"\n\t\"encoding/binary\"\n\t\"encoding/hex\"\n\t\"net\"\n\t\"sort\"\n\t\"strings\""
  },
  {
    "path": "msg_helpers_test.go",
    "chars": 14280,
    "preview": "package dns\n\nimport (\n\t\"bytes\"\n\t\"net\"\n\t\"testing\"\n)\n\n// TestPacketDataNsec tests generated using fuzz.go and with a messa"
  },
  {
    "path": "msg_test.go",
    "chars": 9338,
    "preview": "package dns\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\t\"testing\"\n)\n\nconst maxPrintableLabel = \"abcdefghijklmnopqr"
  },
  {
    "path": "msg_truncate.go",
    "chars": 3478,
    "preview": "package dns\n\n// Truncate ensures the reply message will fit into the requested buffer\n// size by removing records that e"
  },
  {
    "path": "msg_truncate_test.go",
    "chars": 5115,
    "preview": "package dns\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n)\n\nfunc TestRequestTruncateAnswer(t *testing.T) {\n\tm := new(Msg)\n\tm.SetQuestion("
  },
  {
    "path": "nsecx.go",
    "chars": 2442,
    "preview": "package dns\n\nimport (\n\t\"crypto/sha1\"\n\t\"encoding/hex\"\n\t\"strings\"\n)\n\n// HashName hashes a string (label) according to RFC "
  },
  {
    "path": "nsecx_test.go",
    "chars": 4886,
    "preview": "package dns\n\nimport (\n\t\"strconv\"\n\t\"testing\"\n)\n\nfunc TestPackNsec3(t *testing.T) {\n\tnsec3 := HashName(\"dnsex.nl.\", SHA1, "
  },
  {
    "path": "parse_test.go",
    "chars": 82451,
    "preview": "package dns\n\nimport (\n\t\"bytes\"\n\t\"crypto/rsa\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"math/rand\"\n\t\"net\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"strconv\"\n"
  },
  {
    "path": "privaterr.go",
    "chars": 3307,
    "preview": "package dns\n\nimport \"strings\"\n\n// PrivateRdata is an interface used for implementing \"Private Use\" RR types, see\n// RFC "
  },
  {
    "path": "privaterr_test.go",
    "chars": 3598,
    "preview": "package dns_test\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/miekg/dns\"\n)\n\nconst TypeISBN uint16 = 0xFF00\n\n// A crazy "
  },
  {
    "path": "reverse.go",
    "chars": 1479,
    "preview": "package dns\n\n// StringToType is the reverse of TypeToString, needed for string parsing.\nvar StringToType = reverseInt16("
  },
  {
    "path": "rr_test.go",
    "chars": 191,
    "preview": "package dns\n\n// testRR is a helper that wraps a call to NewRR and panics if the error is non-nil.\nfunc testRR(s string) "
  },
  {
    "path": "sanitize.go",
    "chars": 2028,
    "preview": "package dns\n\n// Dedup removes identical RRs from rrs. It preserves the original ordering.\n// The lowest TTL of any dupli"
  },
  {
    "path": "sanitize_test.go",
    "chars": 2051,
    "preview": "package dns\n\nimport \"testing\"\n\nfunc TestDedup(t *testing.T) {\n\ttestcases := map[[3]RR][]string{\n\t\t[...]RR{\n\t\t\ttestRR(\"mI"
  },
  {
    "path": "scan.go",
    "chars": 32261,
    "preview": "package dns\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\t\"math\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n)\n\ncon"
  },
  {
    "path": "scan_rr.go",
    "chars": 47396,
    "preview": "package dns\n\nimport (\n\t\"encoding/base64\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// A remainder of the rdata wi"
  },
  {
    "path": "scan_test.go",
    "chars": 13100,
    "preview": "package dns\n\nimport (\n\t\"errors\"\n\t\"io\"\n\t\"io/fs\"\n\t\"net\"\n\t\"os\"\n\t\"strings\"\n\t\"testing\"\n\t\"testing/fstest\"\n)\n\nfunc TestZonePars"
  },
  {
    "path": "serve_mux.go",
    "chars": 3449,
    "preview": "package dns\n\nimport (\n\t\"sync\"\n)\n\n// ServeMux is an DNS request multiplexer. It matches the zone name of\n// each incoming"
  },
  {
    "path": "serve_mux_test.go",
    "chars": 1667,
    "preview": "package dns\n\nimport \"testing\"\n\nfunc TestDotAsCatchAllWildcard(t *testing.T) {\n\tmux := NewServeMux()\n\tmux.Handle(\".\", Han"
  },
  {
    "path": "server.go",
    "chars": 23445,
    "preview": "// DNS server implementation.\n\npackage dns\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"io\"\n\t\"net\"\n"
  },
  {
    "path": "server_test.go",
    "chars": 39587,
    "preview": "package dns\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"runtime\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atomic"
  },
  {
    "path": "sig0.go",
    "chars": 4606,
    "preview": "package dns\n\nimport (\n\t\"crypto\"\n\t\"crypto/ecdsa\"\n\t\"crypto/ed25519\"\n\t\"crypto/rsa\"\n\t\"encoding/binary\"\n\t\"math/big\"\n\t\"time\"\n)"
  },
  {
    "path": "sig0_test.go",
    "chars": 2276,
    "preview": "package dns\n\nimport (\n\t\"crypto\"\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestSIG0(t *testing.T) {\n\tif testing.Short() {\n\t\tt.Skip(\"skip"
  },
  {
    "path": "smimea.go",
    "chars": 1361,
    "preview": "package dns\n\nimport (\n\t\"crypto/sha256\"\n\t\"crypto/x509\"\n\t\"encoding/hex\"\n)\n\n// Sign creates a SMIMEA record from an SSL cer"
  },
  {
    "path": "svcb.go",
    "chars": 27678,
    "preview": "package dns\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// SVCBKey is"
  },
  {
    "path": "svcb_test.go",
    "chars": 4016,
    "preview": "package dns\n\nimport (\n\t\"testing\"\n)\n\n// This tests everything valid about SVCB but parsing.\n// Parsing tests belong to pa"
  },
  {
    "path": "tlsa.go",
    "chars": 1131,
    "preview": "package dns\n\nimport (\n\t\"crypto/x509\"\n\t\"net\"\n\t\"strconv\"\n)\n\n// Sign creates a TLSA record from an SSL certificate.\nfunc (r"
  },
  {
    "path": "tmpdir_darwin_test.go",
    "chars": 807,
    "preview": "//go:build darwin\n\npackage dns\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n)\n\n// tempDir creates a temporary "
  },
  {
    "path": "tmpdir_test.go",
    "chars": 350,
    "preview": "//go:build !darwin\n\npackage dns\n\nimport (\n\t\"path/filepath\"\n\t\"testing\"\n)\n\n// tempDir creates a temporary directory for te"
  },
  {
    "path": "tools.go",
    "chars": 343,
    "preview": "//go:build tools\n// +build tools\n\n// We include our tool dependencies for `go generate` here to ensure they're\n// proper"
  },
  {
    "path": "tsig.go",
    "chars": 12028,
    "preview": "package dns\n\nimport (\n\t\"crypto/hmac\"\n\t\"crypto/sha1\"\n\t\"crypto/sha256\"\n\t\"crypto/sha512\"\n\t\"encoding/binary\"\n\t\"encoding/hex\""
  },
  {
    "path": "tsig_test.go",
    "chars": 12308,
    "preview": "package dns\n\nimport (\n\t\"encoding/binary\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n)\n\nfunc newTsig("
  },
  {
    "path": "types.go",
    "chars": 41065,
    "preview": "package dns\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"net\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\ntype (\n\t// Type is a DNS type.\n\tType uint1"
  },
  {
    "path": "types_generate.go",
    "chars": 9035,
    "preview": "//go:build ignore\n// +build ignore\n\n// types_generate.go is meant to run with go generate. It will use\n// go/{importer,t"
  },
  {
    "path": "types_test.go",
    "chars": 4470,
    "preview": "package dns\n\nimport (\n\t\"testing\"\n)\n\nfunc TestCmToM(t *testing.T) {\n\ts := cmToM((0 << 4) + 0)\n\tif s != \"0.00\" {\n\t\tt.Error"
  },
  {
    "path": "udp.go",
    "chars": 3004,
    "preview": "//go:build !windows && !darwin\n// +build !windows,!darwin\n\npackage dns\n\nimport (\n\t\"net\"\n\n\t\"golang.org/x/net/ipv4\"\n\t\"gola"
  },
  {
    "path": "udp_no_control.go",
    "chars": 1207,
    "preview": "//go:build windows || darwin\n// +build windows darwin\n\n// TODO(tmthrgd): Remove this Windows-specific code if go.dev/iss"
  },
  {
    "path": "udp_test.go",
    "chars": 4543,
    "preview": "//go:build linux && !appengine\n// +build linux,!appengine\n\npackage dns\n\nimport (\n\t\"bytes\"\n\t\"net\"\n\t\"runtime\"\n\t\"strings\"\n\t"
  },
  {
    "path": "update.go",
    "chars": 3510,
    "preview": "package dns\n\n// NameUsed sets the RRs in the prereq section to\n// \"Name is in use\" RRs. RFC 2136 section 2.4.4.\n// See ["
  },
  {
    "path": "update_test.go",
    "chars": 4477,
    "preview": "package dns\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n)\n\nfunc TestDynamicUpdateParsing(t *testing.T) {\n\tconst prefix = \"example.com."
  },
  {
    "path": "version.go",
    "chars": 275,
    "preview": "package dns\n\nimport \"fmt\"\n\n// Version is current version of this library.\nvar Version = v{1, 1, 72}\n\n// v holds the vers"
  },
  {
    "path": "version_test.go",
    "chars": 180,
    "preview": "package dns\n\nimport \"testing\"\n\nfunc TestVersion(t *testing.T) {\n\tv := v{1, 0, 0}\n\tif x := v.String(); x != \"1.0.0\" {\n\t\tt"
  },
  {
    "path": "xfr.go",
    "chars": 7572,
    "preview": "package dns\n\nimport (\n\t\"crypto/tls\"\n\t\"fmt\"\n\t\"time\"\n)\n\n// Envelope is used when doing a zone transfer with a remote serve"
  },
  {
    "path": "xfr_test.go",
    "chars": 6059,
    "preview": "package dns\n\nimport (\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"testing\"\n\t\"time\"\n)\n\nvar (\n\ttsigSecret  = map[string]string{\"axfr.\": \"so6"
  },
  {
    "path": "zduplicate.go",
    "chars": 22737,
    "preview": "// Code generated by \"go run duplicate_generate.go\"; DO NOT EDIT.\n\npackage dns\n\n// isDuplicate() functions\n\nfunc (r1 *A)"
  },
  {
    "path": "zmsg.go",
    "chars": 72441,
    "preview": "// Code generated by \"go run msg_generate.go\"; DO NOT EDIT.\n\npackage dns\n\nimport \"fmt\"\n\n// pack*() functions\n\nfunc (rr *"
  },
  {
    "path": "ztypes.go",
    "chars": 32877,
    "preview": "// Code generated by \"go run types_generate.go\"; DO NOT EDIT.\n\npackage dns\n\nimport (\n\t\"encoding/base64\"\n\t\"net\"\n)\n\n// Typ"
  }
]

About this extraction

This page contains the full source code of the miekg/dns GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 105 files (913.8 KB), approximately 319.8k tokens, and a symbol index with 2144 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!