mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Merge pull request #102847 from jayunit100/userspace-proxy-dns-demangler
fix dns modifications inside of the kube-proxy for windows userspace
This commit is contained in:
		
							
								
								
									
										34
									
								
								LICENSES/vendor/github.com/miekg/dns/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										34
									
								
								LICENSES/vendor/github.com/miekg/dns/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,34 +0,0 @@
 | 
				
			|||||||
= vendor/github.com/miekg/dns licensed under: =
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Copyright (c) 2009 The Go Authors. All rights reserved.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Redistribution and use in source and binary forms, with or without
 | 
					 | 
				
			||||||
modification, are permitted provided that the following conditions are
 | 
					 | 
				
			||||||
met:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   * Redistributions of source code must retain the above copyright
 | 
					 | 
				
			||||||
notice, this list of conditions and the following disclaimer.
 | 
					 | 
				
			||||||
   * 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.
 | 
					 | 
				
			||||||
   * Neither the name of Google Inc. 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
 | 
					 | 
				
			||||||
OWNER 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
As this is fork of the official Go code the same license applies.
 | 
					 | 
				
			||||||
Extensions of the original work are copyright (c) 2011 Miek Gieben
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
= vendor/github.com/miekg/dns/LICENSE 567c1ad6c08ca0ee8d7e0a0cf790aff9
 | 
					 | 
				
			||||||
							
								
								
									
										3
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								go.mod
									
									
									
									
									
								
							@@ -60,7 +60,6 @@ require (
 | 
				
			|||||||
	github.com/libopenstorage/openstorage v1.0.0
 | 
						github.com/libopenstorage/openstorage v1.0.0
 | 
				
			||||||
	github.com/lithammer/dedent v1.1.0
 | 
						github.com/lithammer/dedent v1.1.0
 | 
				
			||||||
	github.com/lpabon/godbc v0.1.1 // indirect
 | 
						github.com/lpabon/godbc v0.1.1 // indirect
 | 
				
			||||||
	github.com/miekg/dns v1.1.35
 | 
					 | 
				
			||||||
	github.com/moby/ipvs v1.0.1
 | 
						github.com/moby/ipvs v1.0.1
 | 
				
			||||||
	github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb // indirect
 | 
						github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb // indirect
 | 
				
			||||||
	github.com/mrunalp/fileutils v0.5.0
 | 
						github.com/mrunalp/fileutils v0.5.0
 | 
				
			||||||
@@ -338,7 +337,7 @@ replace (
 | 
				
			|||||||
	github.com/mattn/go-isatty => github.com/mattn/go-isatty v0.0.3
 | 
						github.com/mattn/go-isatty => github.com/mattn/go-isatty v0.0.3
 | 
				
			||||||
	github.com/mattn/go-runewidth => github.com/mattn/go-runewidth v0.0.9
 | 
						github.com/mattn/go-runewidth => github.com/mattn/go-runewidth v0.0.9
 | 
				
			||||||
	github.com/matttproud/golang_protobuf_extensions => github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369
 | 
						github.com/matttproud/golang_protobuf_extensions => github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369
 | 
				
			||||||
	github.com/miekg/dns => github.com/miekg/dns v1.1.35
 | 
						github.com/miekg/dns => github.com/miekg/dns v1.0.14
 | 
				
			||||||
	github.com/mindprince/gonvml => github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989
 | 
						github.com/mindprince/gonvml => github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989
 | 
				
			||||||
	github.com/mistifyio/go-zfs => github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible
 | 
						github.com/mistifyio/go-zfs => github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible
 | 
				
			||||||
	github.com/mitchellh/cli => github.com/mitchellh/cli v1.0.0
 | 
						github.com/mitchellh/cli => github.com/mitchellh/cli v1.0.0
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								go.sum
									
									
									
									
									
								
							@@ -320,8 +320,7 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx
 | 
				
			|||||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
 | 
					github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
 | 
				
			||||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
 | 
					github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
 | 
				
			||||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
 | 
					github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
 | 
				
			||||||
github.com/miekg/dns v1.1.35 h1:oTfOaDH+mZkdcgdIjH6yBajRGtIwcwcaR+rt23ZSrJs=
 | 
					github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
 | 
				
			||||||
github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
 | 
					 | 
				
			||||||
github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989 h1:PS1dLCGtD8bb9RPKJrc8bS7qHL6JnW1CZvwzH9dPoUs=
 | 
					github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989 h1:PS1dLCGtD8bb9RPKJrc8bS7qHL6JnW1CZvwzH9dPoUs=
 | 
				
			||||||
github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989/go.mod h1:2eu9pRWp8mo84xCg6KswZ+USQHjwgRhNp06sozOdsTY=
 | 
					github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989/go.mod h1:2eu9pRWp8mo84xCg6KswZ+USQHjwgRhNp06sozOdsTY=
 | 
				
			||||||
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible h1:aKW/4cBs+yK6gpqU3K/oIwk9Q/XICqd3zOX/UFuvqmk=
 | 
					github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible h1:aKW/4cBs+yK6gpqU3K/oIwk9Q/XICqd3zOX/UFuvqmk=
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,7 +52,6 @@ type serviceInfo struct {
 | 
				
			|||||||
	socket              proxySocket
 | 
						socket              proxySocket
 | 
				
			||||||
	timeout             time.Duration
 | 
						timeout             time.Duration
 | 
				
			||||||
	activeClients       *clientCache
 | 
						activeClients       *clientCache
 | 
				
			||||||
	dnsClients          *dnsClientCache
 | 
					 | 
				
			||||||
	sessionAffinityType v1.ServiceAffinity
 | 
						sessionAffinityType v1.ServiceAffinity
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -237,7 +236,6 @@ func (proxier *Proxier) addServicePortPortal(servicePortPortalName ServicePortPo
 | 
				
			|||||||
		socket:              sock,
 | 
							socket:              sock,
 | 
				
			||||||
		timeout:             timeout,
 | 
							timeout:             timeout,
 | 
				
			||||||
		activeClients:       newClientCache(),
 | 
							activeClients:       newClientCache(),
 | 
				
			||||||
		dnsClients:          newDNSClientCache(),
 | 
					 | 
				
			||||||
		sessionAffinityType: v1.ServiceAffinityNone, // default
 | 
							sessionAffinityType: v1.ServiceAffinityNone, // default
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	proxier.setServiceInfo(servicePortPortalName, si)
 | 
						proxier.setServiceInfo(servicePortPortalName, si)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,45 +23,13 @@ import (
 | 
				
			|||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
	"sync/atomic"
 | 
					 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/miekg/dns"
 | 
					 | 
				
			||||||
	v1 "k8s.io/api/core/v1"
 | 
						v1 "k8s.io/api/core/v1"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/types"
 | 
						"k8s.io/apimachinery/pkg/types"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/runtime"
 | 
						"k8s.io/apimachinery/pkg/util/runtime"
 | 
				
			||||||
	"k8s.io/klog/v2"
 | 
						"k8s.io/klog/v2"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/proxy"
 | 
						"k8s.io/kubernetes/pkg/proxy"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/util/ipconfig"
 | 
					 | 
				
			||||||
	"k8s.io/utils/exec"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	// Kubernetes DNS suffix search list
 | 
					 | 
				
			||||||
	// TODO: Get DNS suffix search list from docker containers.
 | 
					 | 
				
			||||||
	// --dns-search option doesn't work on Windows containers and has been
 | 
					 | 
				
			||||||
	// fixed recently in docker.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Kubernetes cluster domain
 | 
					 | 
				
			||||||
	clusterDomain = "cluster.local"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Kubernetes service domain
 | 
					 | 
				
			||||||
	serviceDomain = "svc." + clusterDomain
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Kubernetes default namespace domain
 | 
					 | 
				
			||||||
	namespaceServiceDomain = "default." + serviceDomain
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Kubernetes DNS service port name
 | 
					 | 
				
			||||||
	dnsPortName = "dns"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// DNS TYPE value A (a host address)
 | 
					 | 
				
			||||||
	dnsTypeA uint16 = 0x01
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// DNS TYPE value AAAA (a host IPv6 address)
 | 
					 | 
				
			||||||
	dnsTypeAAAA uint16 = 0x1c
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// DNS CLASS value IN (the Internet)
 | 
					 | 
				
			||||||
	dnsClassInternet uint16 = 0x01
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Abstraction over TCP/UDP sockets which are proxied.
 | 
					// Abstraction over TCP/UDP sockets which are proxied.
 | 
				
			||||||
@@ -150,7 +118,7 @@ func tryConnect(service ServicePortPortalName, srcAddr net.Addr, protocol string
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		return outConn, nil
 | 
							return outConn, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil, fmt.Errorf("failed to connect to an endpoint.")
 | 
						return nil, fmt.Errorf("failed to connect to an endpoint")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (tcp *tcpProxySocket) ProxyLoop(service ServicePortPortalName, myInfo *serviceInfo, proxier *Proxier) {
 | 
					func (tcp *tcpProxySocket) ProxyLoop(service ServicePortPortalName, myInfo *serviceInfo, proxier *Proxier) {
 | 
				
			||||||
@@ -239,277 +207,8 @@ func newClientCache() *clientCache {
 | 
				
			|||||||
	return &clientCache{clients: map[string]net.Conn{}}
 | 
						return &clientCache{clients: map[string]net.Conn{}}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// DNS query client classified by address and QTYPE
 | 
					 | 
				
			||||||
type dnsClientQuery struct {
 | 
					 | 
				
			||||||
	clientAddress string
 | 
					 | 
				
			||||||
	dnsQType      uint16
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Holds DNS client query, the value contains the index in DNS suffix search list,
 | 
					 | 
				
			||||||
// the original DNS message and length for the same client and QTYPE
 | 
					 | 
				
			||||||
type dnsClientCache struct {
 | 
					 | 
				
			||||||
	mu      sync.Mutex
 | 
					 | 
				
			||||||
	clients map[dnsClientQuery]*dnsQueryState
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type dnsQueryState struct {
 | 
					 | 
				
			||||||
	searchIndex int32
 | 
					 | 
				
			||||||
	msg         *dns.Msg
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func newDNSClientCache() *dnsClientCache {
 | 
					 | 
				
			||||||
	return &dnsClientCache{clients: map[dnsClientQuery]*dnsQueryState{}}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func packetRequiresDNSSuffix(dnsType, dnsClass uint16) bool {
 | 
					 | 
				
			||||||
	return (dnsType == dnsTypeA || dnsType == dnsTypeAAAA) && dnsClass == dnsClassInternet
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func isDNSService(portName string) bool {
 | 
					 | 
				
			||||||
	return portName == dnsPortName
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func appendDNSSuffix(msg *dns.Msg, buffer []byte, length int, dnsSuffix string) (int, error) {
 | 
					 | 
				
			||||||
	if msg == nil || len(msg.Question) == 0 {
 | 
					 | 
				
			||||||
		return length, fmt.Errorf("DNS message parameter is invalid")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Save the original name since it will be reused for next iteration
 | 
					 | 
				
			||||||
	origName := msg.Question[0].Name
 | 
					 | 
				
			||||||
	if dnsSuffix != "" {
 | 
					 | 
				
			||||||
		msg.Question[0].Name += dnsSuffix + "."
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	mbuf, err := msg.PackBuffer(buffer)
 | 
					 | 
				
			||||||
	msg.Question[0].Name = origName
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		klog.Warningf("Unable to pack DNS packet. Error is: %v", err)
 | 
					 | 
				
			||||||
		return length, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if &buffer[0] != &mbuf[0] {
 | 
					 | 
				
			||||||
		return length, fmt.Errorf("Buffer is too small in packing DNS packet")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return len(mbuf), nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func recoverDNSQuestion(origName string, msg *dns.Msg, buffer []byte, length int) (int, error) {
 | 
					 | 
				
			||||||
	if msg == nil || len(msg.Question) == 0 {
 | 
					 | 
				
			||||||
		return length, fmt.Errorf("DNS message parameter is invalid")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if origName == msg.Question[0].Name {
 | 
					 | 
				
			||||||
		return length, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	msg.Question[0].Name = origName
 | 
					 | 
				
			||||||
	if len(msg.Answer) > 0 {
 | 
					 | 
				
			||||||
		msg.Answer[0].Header().Name = origName
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	mbuf, err := msg.PackBuffer(buffer)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		klog.Warningf("Unable to pack DNS packet. Error is: %v", err)
 | 
					 | 
				
			||||||
		return length, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if &buffer[0] != &mbuf[0] {
 | 
					 | 
				
			||||||
		return length, fmt.Errorf("Buffer is too small in packing DNS packet")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return len(mbuf), nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func processUnpackedDNSQueryPacket(
 | 
					 | 
				
			||||||
	dnsClients *dnsClientCache,
 | 
					 | 
				
			||||||
	msg *dns.Msg,
 | 
					 | 
				
			||||||
	host string,
 | 
					 | 
				
			||||||
	dnsQType uint16,
 | 
					 | 
				
			||||||
	buffer []byte,
 | 
					 | 
				
			||||||
	length int,
 | 
					 | 
				
			||||||
	dnsSearch []string) int {
 | 
					 | 
				
			||||||
	if dnsSearch == nil || len(dnsSearch) == 0 {
 | 
					 | 
				
			||||||
		klog.V(1).Infof("DNS search list is not initialized and is empty.")
 | 
					 | 
				
			||||||
		return length
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// TODO: handle concurrent queries from a client
 | 
					 | 
				
			||||||
	dnsClients.mu.Lock()
 | 
					 | 
				
			||||||
	state, found := dnsClients.clients[dnsClientQuery{host, dnsQType}]
 | 
					 | 
				
			||||||
	if !found {
 | 
					 | 
				
			||||||
		state = &dnsQueryState{0, msg}
 | 
					 | 
				
			||||||
		dnsClients.clients[dnsClientQuery{host, dnsQType}] = state
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	dnsClients.mu.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	index := atomic.SwapInt32(&state.searchIndex, state.searchIndex+1)
 | 
					 | 
				
			||||||
	// Also update message ID if the client retries due to previous query time out
 | 
					 | 
				
			||||||
	state.msg.MsgHdr.Id = msg.MsgHdr.Id
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if index < 0 || index >= int32(len(dnsSearch)) {
 | 
					 | 
				
			||||||
		klog.V(1).Infof("Search index %d is out of range.", index)
 | 
					 | 
				
			||||||
		return length
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	length, err := appendDNSSuffix(msg, buffer, length, dnsSearch[index])
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		klog.Errorf("Append DNS suffix failed: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return length
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func processUnpackedDNSResponsePacket(
 | 
					 | 
				
			||||||
	svrConn net.Conn,
 | 
					 | 
				
			||||||
	dnsClients *dnsClientCache,
 | 
					 | 
				
			||||||
	msg *dns.Msg,
 | 
					 | 
				
			||||||
	rcode int,
 | 
					 | 
				
			||||||
	host string,
 | 
					 | 
				
			||||||
	dnsQType uint16,
 | 
					 | 
				
			||||||
	buffer []byte,
 | 
					 | 
				
			||||||
	length int,
 | 
					 | 
				
			||||||
	dnsSearch []string) (bool, int) {
 | 
					 | 
				
			||||||
	var drop bool
 | 
					 | 
				
			||||||
	var err error
 | 
					 | 
				
			||||||
	if dnsSearch == nil || len(dnsSearch) == 0 {
 | 
					 | 
				
			||||||
		klog.V(1).Infof("DNS search list is not initialized and is empty.")
 | 
					 | 
				
			||||||
		return drop, length
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dnsClients.mu.Lock()
 | 
					 | 
				
			||||||
	state, found := dnsClients.clients[dnsClientQuery{host, dnsQType}]
 | 
					 | 
				
			||||||
	dnsClients.mu.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if found {
 | 
					 | 
				
			||||||
		index := atomic.SwapInt32(&state.searchIndex, state.searchIndex+1)
 | 
					 | 
				
			||||||
		if rcode != 0 && index >= 0 && index < int32(len(dnsSearch)) {
 | 
					 | 
				
			||||||
			// If the response has failure and iteration through the search list has not
 | 
					 | 
				
			||||||
			// reached the end, retry on behalf of the client using the original query message
 | 
					 | 
				
			||||||
			drop = true
 | 
					 | 
				
			||||||
			length, err = appendDNSSuffix(state.msg, buffer, length, dnsSearch[index])
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				klog.Errorf("Append DNS suffix failed: %v", err)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			_, err = svrConn.Write(buffer[0:length])
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				if !logTimeout(err) {
 | 
					 | 
				
			||||||
					klog.Errorf("Write failed: %v", err)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			length, err = recoverDNSQuestion(state.msg.Question[0].Name, msg, buffer, length)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				klog.Errorf("Recover DNS question failed: %v", err)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			dnsClients.mu.Lock()
 | 
					 | 
				
			||||||
			delete(dnsClients.clients, dnsClientQuery{host, dnsQType})
 | 
					 | 
				
			||||||
			dnsClients.mu.Unlock()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return drop, length
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func processDNSQueryPacket(
 | 
					 | 
				
			||||||
	dnsClients *dnsClientCache,
 | 
					 | 
				
			||||||
	cliAddr net.Addr,
 | 
					 | 
				
			||||||
	buffer []byte,
 | 
					 | 
				
			||||||
	length int,
 | 
					 | 
				
			||||||
	dnsSearch []string) (int, error) {
 | 
					 | 
				
			||||||
	msg := &dns.Msg{}
 | 
					 | 
				
			||||||
	if err := msg.Unpack(buffer[:length]); err != nil {
 | 
					 | 
				
			||||||
		klog.Warningf("Unable to unpack DNS packet. Error is: %v", err)
 | 
					 | 
				
			||||||
		return length, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Query - Response bit that specifies whether this message is a query (0) or a response (1).
 | 
					 | 
				
			||||||
	if msg.MsgHdr.Response {
 | 
					 | 
				
			||||||
		return length, fmt.Errorf("DNS packet should be a query message")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// QDCOUNT
 | 
					 | 
				
			||||||
	if len(msg.Question) != 1 {
 | 
					 | 
				
			||||||
		klog.V(1).Infof("Number of entries in the question section of the DNS packet is: %d", len(msg.Question))
 | 
					 | 
				
			||||||
		klog.V(1).Infof("DNS suffix appending does not support more than one question.")
 | 
					 | 
				
			||||||
		return length, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// ANCOUNT, NSCOUNT, ARCOUNT
 | 
					 | 
				
			||||||
	if len(msg.Answer) != 0 || len(msg.Ns) != 0 || len(msg.Extra) != 0 {
 | 
					 | 
				
			||||||
		klog.V(1).Infof("DNS packet contains more than question section.")
 | 
					 | 
				
			||||||
		return length, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dnsQType := msg.Question[0].Qtype
 | 
					 | 
				
			||||||
	dnsQClass := msg.Question[0].Qclass
 | 
					 | 
				
			||||||
	if packetRequiresDNSSuffix(dnsQType, dnsQClass) {
 | 
					 | 
				
			||||||
		host, _, err := net.SplitHostPort(cliAddr.String())
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			klog.V(1).Infof("Failed to get host from client address: %v", err)
 | 
					 | 
				
			||||||
			host = cliAddr.String()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		length = processUnpackedDNSQueryPacket(dnsClients, msg, host, dnsQType, buffer, length, dnsSearch)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return length, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func processDNSResponsePacket(
 | 
					 | 
				
			||||||
	svrConn net.Conn,
 | 
					 | 
				
			||||||
	dnsClients *dnsClientCache,
 | 
					 | 
				
			||||||
	cliAddr net.Addr,
 | 
					 | 
				
			||||||
	buffer []byte,
 | 
					 | 
				
			||||||
	length int,
 | 
					 | 
				
			||||||
	dnsSearch []string) (bool, int, error) {
 | 
					 | 
				
			||||||
	var drop bool
 | 
					 | 
				
			||||||
	msg := &dns.Msg{}
 | 
					 | 
				
			||||||
	if err := msg.Unpack(buffer[:length]); err != nil {
 | 
					 | 
				
			||||||
		klog.Warningf("Unable to unpack DNS packet. Error is: %v", err)
 | 
					 | 
				
			||||||
		return drop, length, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Query - Response bit that specifies whether this message is a query (0) or a response (1).
 | 
					 | 
				
			||||||
	if !msg.MsgHdr.Response {
 | 
					 | 
				
			||||||
		return drop, length, fmt.Errorf("DNS packet should be a response message")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// QDCOUNT
 | 
					 | 
				
			||||||
	if len(msg.Question) != 1 {
 | 
					 | 
				
			||||||
		klog.V(1).Infof("Number of entries in the response section of the DNS packet is: %d", len(msg.Answer))
 | 
					 | 
				
			||||||
		return drop, length, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dnsQType := msg.Question[0].Qtype
 | 
					 | 
				
			||||||
	dnsQClass := msg.Question[0].Qclass
 | 
					 | 
				
			||||||
	if packetRequiresDNSSuffix(dnsQType, dnsQClass) {
 | 
					 | 
				
			||||||
		host, _, err := net.SplitHostPort(cliAddr.String())
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			klog.V(1).Infof("Failed to get host from client address: %v", err)
 | 
					 | 
				
			||||||
			host = cliAddr.String()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		drop, length = processUnpackedDNSResponsePacket(svrConn, dnsClients, msg, msg.MsgHdr.Rcode, host, dnsQType, buffer, length, dnsSearch)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return drop, length, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (udp *udpProxySocket) ProxyLoop(service ServicePortPortalName, myInfo *serviceInfo, proxier *Proxier) {
 | 
					func (udp *udpProxySocket) ProxyLoop(service ServicePortPortalName, myInfo *serviceInfo, proxier *Proxier) {
 | 
				
			||||||
	var buffer [4096]byte // 4KiB should be enough for most whole-packets
 | 
						var buffer [4096]byte // 4KiB should be enough for most whole-packets
 | 
				
			||||||
	var dnsSearch []string
 | 
					 | 
				
			||||||
	if isDNSService(service.Port) {
 | 
					 | 
				
			||||||
		dnsSearch = []string{"", namespaceServiceDomain, serviceDomain, clusterDomain}
 | 
					 | 
				
			||||||
		execer := exec.New()
 | 
					 | 
				
			||||||
		ipconfigInterface := ipconfig.New(execer)
 | 
					 | 
				
			||||||
		suffixList, err := ipconfigInterface.GetDNSSuffixSearchList()
 | 
					 | 
				
			||||||
		if err == nil {
 | 
					 | 
				
			||||||
			dnsSearch = append(dnsSearch, suffixList...)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for {
 | 
						for {
 | 
				
			||||||
		if !myInfo.isAlive() {
 | 
							if !myInfo.isAlive() {
 | 
				
			||||||
@@ -531,16 +230,8 @@ func (udp *udpProxySocket) ProxyLoop(service ServicePortPortalName, myInfo *serv
 | 
				
			|||||||
			break
 | 
								break
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// If this is DNS query packet
 | 
					 | 
				
			||||||
		if isDNSService(service.Port) {
 | 
					 | 
				
			||||||
			n, err = processDNSQueryPacket(myInfo.dnsClients, cliAddr, buffer[:], n, dnsSearch)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				klog.Errorf("Process DNS query packet failed: %v", err)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// If this is a client we know already, reuse the connection and goroutine.
 | 
							// If this is a client we know already, reuse the connection and goroutine.
 | 
				
			||||||
		svrConn, err := udp.getBackendConn(myInfo.activeClients, myInfo.dnsClients, cliAddr, proxier, service, myInfo.timeout, dnsSearch)
 | 
							svrConn, err := udp.getBackendConn(myInfo.activeClients, cliAddr, proxier, service, myInfo.timeout)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -562,7 +253,7 @@ func (udp *udpProxySocket) ProxyLoop(service ServicePortPortalName, myInfo *serv
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (udp *udpProxySocket) getBackendConn(activeClients *clientCache, dnsClients *dnsClientCache, cliAddr net.Addr, proxier *Proxier, service ServicePortPortalName, timeout time.Duration, dnsSearch []string) (net.Conn, error) {
 | 
					func (udp *udpProxySocket) getBackendConn(activeClients *clientCache, cliAddr net.Addr, proxier *Proxier, service ServicePortPortalName, timeout time.Duration) (net.Conn, error) {
 | 
				
			||||||
	activeClients.mu.Lock()
 | 
						activeClients.mu.Lock()
 | 
				
			||||||
	defer activeClients.mu.Unlock()
 | 
						defer activeClients.mu.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -581,17 +272,17 @@ func (udp *udpProxySocket) getBackendConn(activeClients *clientCache, dnsClients
 | 
				
			|||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		activeClients.clients[cliAddr.String()] = svrConn
 | 
							activeClients.clients[cliAddr.String()] = svrConn
 | 
				
			||||||
		go func(cliAddr net.Addr, svrConn net.Conn, activeClients *clientCache, dnsClients *dnsClientCache, service ServicePortPortalName, timeout time.Duration, dnsSearch []string) {
 | 
							go func(cliAddr net.Addr, svrConn net.Conn, activeClients *clientCache, service ServicePortPortalName, timeout time.Duration) {
 | 
				
			||||||
			defer runtime.HandleCrash()
 | 
								defer runtime.HandleCrash()
 | 
				
			||||||
			udp.proxyClient(cliAddr, svrConn, activeClients, dnsClients, service, timeout, dnsSearch)
 | 
								udp.proxyClient(cliAddr, svrConn, activeClients, service, timeout)
 | 
				
			||||||
		}(cliAddr, svrConn, activeClients, dnsClients, service, timeout, dnsSearch)
 | 
							}(cliAddr, svrConn, activeClients, service, timeout)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return svrConn, nil
 | 
						return svrConn, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// This function is expected to be called as a goroutine.
 | 
					// This function is expected to be called as a goroutine.
 | 
				
			||||||
// TODO: Track and log bytes copied, like TCP
 | 
					// TODO: Track and log bytes copied, like TCP
 | 
				
			||||||
func (udp *udpProxySocket) proxyClient(cliAddr net.Addr, svrConn net.Conn, activeClients *clientCache, dnsClients *dnsClientCache, service ServicePortPortalName, timeout time.Duration, dnsSearch []string) {
 | 
					func (udp *udpProxySocket) proxyClient(cliAddr net.Addr, svrConn net.Conn, activeClients *clientCache, service ServicePortPortalName, timeout time.Duration) {
 | 
				
			||||||
	defer svrConn.Close()
 | 
						defer svrConn.Close()
 | 
				
			||||||
	var buffer [4096]byte
 | 
						var buffer [4096]byte
 | 
				
			||||||
	for {
 | 
						for {
 | 
				
			||||||
@@ -603,15 +294,6 @@ func (udp *udpProxySocket) proxyClient(cliAddr net.Addr, svrConn net.Conn, activ
 | 
				
			|||||||
			break
 | 
								break
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		drop := false
 | 
					 | 
				
			||||||
		if isDNSService(service.Port) {
 | 
					 | 
				
			||||||
			drop, n, err = processDNSResponsePacket(svrConn, dnsClients, cliAddr, buffer[:], n, dnsSearch)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				klog.Errorf("Process DNS response packet failed: %v", err)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if !drop {
 | 
					 | 
				
			||||||
		err = svrConn.SetDeadline(time.Now().Add(timeout))
 | 
							err = svrConn.SetDeadline(time.Now().Add(timeout))
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			klog.Errorf("SetDeadline failed: %v", err)
 | 
								klog.Errorf("SetDeadline failed: %v", err)
 | 
				
			||||||
@@ -625,7 +307,6 @@ func (udp *udpProxySocket) proxyClient(cliAddr net.Addr, svrConn net.Conn, activ
 | 
				
			|||||||
			break
 | 
								break
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	activeClients.mu.Lock()
 | 
						activeClients.mu.Lock()
 | 
				
			||||||
	delete(activeClients.clients, cliAddr.String())
 | 
						delete(activeClients.clients, cliAddr.String())
 | 
				
			||||||
	activeClients.mu.Unlock()
 | 
						activeClients.mu.Unlock()
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										8
									
								
								vendor/github.com/miekg/dns/.codecov.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/miekg/dns/.codecov.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,8 +0,0 @@
 | 
				
			|||||||
coverage:
 | 
					 | 
				
			||||||
  status:
 | 
					 | 
				
			||||||
    project:
 | 
					 | 
				
			||||||
      default:
 | 
					 | 
				
			||||||
        target: 40%
 | 
					 | 
				
			||||||
        threshold: null
 | 
					 | 
				
			||||||
    patch: false
 | 
					 | 
				
			||||||
    changes: false
 | 
					 | 
				
			||||||
							
								
								
									
										4
									
								
								vendor/github.com/miekg/dns/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/miekg/dns/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,4 +0,0 @@
 | 
				
			|||||||
*.6
 | 
					 | 
				
			||||||
tags
 | 
					 | 
				
			||||||
test.out
 | 
					 | 
				
			||||||
a.out
 | 
					 | 
				
			||||||
							
								
								
									
										17
									
								
								vendor/github.com/miekg/dns/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								vendor/github.com/miekg/dns/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,17 +0,0 @@
 | 
				
			|||||||
language: go
 | 
					 | 
				
			||||||
sudo: false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
go:
 | 
					 | 
				
			||||||
  - 1.14.x
 | 
					 | 
				
			||||||
  - 1.15.x
 | 
					 | 
				
			||||||
  - tip
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
env:
 | 
					 | 
				
			||||||
  - GO111MODULE=on
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
script:
 | 
					 | 
				
			||||||
  - go generate ./... && test `git ls-files --modified | wc -l` = 0
 | 
					 | 
				
			||||||
  - go test -race -v -bench=. -coverprofile=coverage.txt -covermode=atomic ./...
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
after_success:
 | 
					 | 
				
			||||||
  - bash <(curl -s https://codecov.io/bash)
 | 
					 | 
				
			||||||
							
								
								
									
										1
									
								
								vendor/github.com/miekg/dns/AUTHORS
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/miekg/dns/AUTHORS
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
				
			|||||||
Miek Gieben <miek@miek.nl>
 | 
					 | 
				
			||||||
							
								
								
									
										1
									
								
								vendor/github.com/miekg/dns/CODEOWNERS
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/miekg/dns/CODEOWNERS
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
				
			|||||||
* @miekg @tmthrgd
 | 
					 | 
				
			||||||
							
								
								
									
										10
									
								
								vendor/github.com/miekg/dns/CONTRIBUTORS
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/miekg/dns/CONTRIBUTORS
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,10 +0,0 @@
 | 
				
			|||||||
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
 | 
					 | 
				
			||||||
							
								
								
									
										9
									
								
								vendor/github.com/miekg/dns/COPYRIGHT
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/miekg/dns/COPYRIGHT
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,9 +0,0 @@
 | 
				
			|||||||
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.
 | 
					 | 
				
			||||||
							
								
								
									
										30
									
								
								vendor/github.com/miekg/dns/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										30
									
								
								vendor/github.com/miekg/dns/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,30 +0,0 @@
 | 
				
			|||||||
Copyright (c) 2009 The Go Authors. All rights reserved.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Redistribution and use in source and binary forms, with or without
 | 
					 | 
				
			||||||
modification, are permitted provided that the following conditions are
 | 
					 | 
				
			||||||
met:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   * Redistributions of source code must retain the above copyright
 | 
					 | 
				
			||||||
notice, this list of conditions and the following disclaimer.
 | 
					 | 
				
			||||||
   * 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.
 | 
					 | 
				
			||||||
   * Neither the name of Google Inc. 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
 | 
					 | 
				
			||||||
OWNER 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
As this is fork of the official Go code the same license applies.
 | 
					 | 
				
			||||||
Extensions of the original work are copyright (c) 2011 Miek Gieben
 | 
					 | 
				
			||||||
							
								
								
									
										33
									
								
								vendor/github.com/miekg/dns/Makefile.fuzz
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										33
									
								
								vendor/github.com/miekg/dns/Makefile.fuzz
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,33 +0,0 @@
 | 
				
			|||||||
# 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
 | 
					 | 
				
			||||||
							
								
								
									
										52
									
								
								vendor/github.com/miekg/dns/Makefile.release
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										52
									
								
								vendor/github.com/miekg/dns/Makefile.release
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,52 +0,0 @@
 | 
				
			|||||||
# 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 artifects 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
 | 
					 | 
				
			||||||
							
								
								
									
										174
									
								
								vendor/github.com/miekg/dns/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										174
									
								
								vendor/github.com/miekg/dns/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,174 +0,0 @@
 | 
				
			|||||||
[](https://travis-ci.org/miekg/dns)
 | 
					 | 
				
			||||||
[](https://codecov.io/github/miekg/dns?branch=master)
 | 
					 | 
				
			||||||
[](https://goreportcard.com/report/miekg/dns)
 | 
					 | 
				
			||||||
[](https://godoc.org/github.com/miekg/dns)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# 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
 | 
					 | 
				
			||||||
* 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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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
 | 
					 | 
				
			||||||
* 1348 - NSAP record (removed the record)
 | 
					 | 
				
			||||||
* 1982 - Serial Arithmetic
 | 
					 | 
				
			||||||
* 1876 - LOC record
 | 
					 | 
				
			||||||
* 1995 - IXFR
 | 
					 | 
				
			||||||
* 1996 - DNS notify
 | 
					 | 
				
			||||||
* 2136 - DNS Update (dynamic updates)
 | 
					 | 
				
			||||||
* 2181 - RRset definition - there is no RRset type though, just []RR
 | 
					 | 
				
			||||||
* 2537 - RSAMD5 DNS keys
 | 
					 | 
				
			||||||
* 2065 - DNSSEC (updated in later RFCs)
 | 
					 | 
				
			||||||
* 2671 - EDNS record
 | 
					 | 
				
			||||||
* 2782 - SRV record
 | 
					 | 
				
			||||||
* 2845 - TSIG record
 | 
					 | 
				
			||||||
* 2915 - NAPTR record
 | 
					 | 
				
			||||||
* 2929 - DNS IANA Considerations
 | 
					 | 
				
			||||||
* 3110 - RSASHA1 DNS keys
 | 
					 | 
				
			||||||
* 3123 - APL record
 | 
					 | 
				
			||||||
* 3225 - DO bit (DNSSEC OK)
 | 
					 | 
				
			||||||
* 340{1,2,3} - NAPTR record
 | 
					 | 
				
			||||||
* 3445 - Limiting the scope of (DNS)KEY
 | 
					 | 
				
			||||||
* 3597 - Unknown RRs
 | 
					 | 
				
			||||||
* 403{3,4,5} - DNSSEC + validation functions
 | 
					 | 
				
			||||||
* 4255 - SSHFP record
 | 
					 | 
				
			||||||
* 4343 - Case insensitivity
 | 
					 | 
				
			||||||
* 4408 - SPF record
 | 
					 | 
				
			||||||
* 4509 - SHA256 Hash in DS
 | 
					 | 
				
			||||||
* 4592 - Wildcards in the DNS
 | 
					 | 
				
			||||||
* 4635 - HMAC SHA TSIG
 | 
					 | 
				
			||||||
* 4701 - DHCID
 | 
					 | 
				
			||||||
* 4892 - id.server
 | 
					 | 
				
			||||||
* 5001 - NSID
 | 
					 | 
				
			||||||
* 5155 - NSEC3 record
 | 
					 | 
				
			||||||
* 5205 - HIP record
 | 
					 | 
				
			||||||
* 5702 - SHA2 in the DNS
 | 
					 | 
				
			||||||
* 5936 - AXFR
 | 
					 | 
				
			||||||
* 5966 - TCP implementation recommendations
 | 
					 | 
				
			||||||
* 6605 - ECDSA
 | 
					 | 
				
			||||||
* 6725 - IANA Registry Update
 | 
					 | 
				
			||||||
* 6742 - ILNP DNS
 | 
					 | 
				
			||||||
* 6840 - Clarifications and Implementation Notes for DNS Security
 | 
					 | 
				
			||||||
* 6844 - CAA record
 | 
					 | 
				
			||||||
* 6891 - EDNS0 update
 | 
					 | 
				
			||||||
* 6895 - DNS IANA considerations
 | 
					 | 
				
			||||||
* 6944 - DNSSEC DNSKEY Algorithm Status
 | 
					 | 
				
			||||||
* 6975 - Algorithm Understanding in DNSSEC
 | 
					 | 
				
			||||||
* 7043 - EUI48/EUI64 records
 | 
					 | 
				
			||||||
* 7314 - DNS (EDNS) EXPIRE Option
 | 
					 | 
				
			||||||
* 7477 - CSYNC RR
 | 
					 | 
				
			||||||
* 7828 - edns-tcp-keepalive EDNS0 Option
 | 
					 | 
				
			||||||
* 7553 - URI record
 | 
					 | 
				
			||||||
* 7858 - DNS over TLS: Initiation and Performance Considerations
 | 
					 | 
				
			||||||
* 7871 - EDNS0 Client Subnet
 | 
					 | 
				
			||||||
* 7873 - Domain Name System (DNS) Cookies
 | 
					 | 
				
			||||||
* 8080 - EdDSA for DNSSEC
 | 
					 | 
				
			||||||
* 8499 - DNS Terminology
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Loosely Based Upon
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* 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>
 | 
					 | 
				
			||||||
							
								
								
									
										61
									
								
								vendor/github.com/miekg/dns/acceptfunc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										61
									
								
								vendor/github.com/miekg/dns/acceptfunc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,61 +0,0 @@
 | 
				
			|||||||
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
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// * Zero bit isn't zero
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// * has more than 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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										441
									
								
								vendor/github.com/miekg/dns/client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										441
									
								
								vendor/github.com/miekg/dns/client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,441 +0,0 @@
 | 
				
			|||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// A client implementation.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"context"
 | 
					 | 
				
			||||||
	"crypto/tls"
 | 
					 | 
				
			||||||
	"encoding/binary"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"io"
 | 
					 | 
				
			||||||
	"net"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	dnsTimeout     time.Duration = 2 * time.Second
 | 
					 | 
				
			||||||
	tcpIdleTimeout time.Duration = 8 * time.Second
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 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)
 | 
					 | 
				
			||||||
	tsigRequestMAC string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 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.SetReadTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero
 | 
					 | 
				
			||||||
	WriteTimeout   time.Duration     // net.Conn.SetWriteTimeout 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)
 | 
					 | 
				
			||||||
	SingleInflight bool              // if true suppress multiple outstanding queries for the same Qname, Qtype and Qclass
 | 
					 | 
				
			||||||
	group          singleflight
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 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.ReadTimeout != 0 {
 | 
					 | 
				
			||||||
		return c.ReadTimeout
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return dnsTimeout
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (c *Client) writeTimeout() time.Duration {
 | 
					 | 
				
			||||||
	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) {
 | 
					 | 
				
			||||||
	// 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")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		conn.Conn, err = tls.DialWithDialer(&d, network, address, c.TLSConfig)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		conn.Conn, err = d.Dial(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) {
 | 
					 | 
				
			||||||
	if !c.SingleInflight {
 | 
					 | 
				
			||||||
		return c.exchange(m, conn)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	q := m.Question[0]
 | 
					 | 
				
			||||||
	key := fmt.Sprintf("%s:%d:%d", q.Name, q.Qtype, q.Qclass)
 | 
					 | 
				
			||||||
	r, rtt, err, shared := c.group.Do(key, func() (*Msg, time.Duration, error) {
 | 
					 | 
				
			||||||
		return c.exchange(m, conn)
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
	if r != nil && shared {
 | 
					 | 
				
			||||||
		r = r.Copy()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return r, rtt, err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (c *Client) exchange(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
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	co.TsigSecret = c.TsigSecret
 | 
					 | 
				
			||||||
	t := time.Now()
 | 
					 | 
				
			||||||
	// write with the appropriate write timeout
 | 
					 | 
				
			||||||
	co.SetWriteDeadline(t.Add(c.getTimeoutForRequest(c.writeTimeout())))
 | 
					 | 
				
			||||||
	if err = co.WriteMsg(m); err != nil {
 | 
					 | 
				
			||||||
		return nil, 0, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	co.SetReadDeadline(time.Now().Add(c.getTimeoutForRequest(c.readTimeout())))
 | 
					 | 
				
			||||||
	if _, ok := co.Conn.(net.PacketConn); ok {
 | 
					 | 
				
			||||||
		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 {
 | 
					 | 
				
			||||||
		if _, ok := co.TsigSecret[t.Hdr.Name]; !ok {
 | 
					 | 
				
			||||||
			return m, ErrSecret
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		// Need to work on the original message p, as that was used to calculate the tsig.
 | 
					 | 
				
			||||||
		err = TsigVerify(p, co.TsigSecret[t.Hdr.Name], 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 _, ok := co.Conn.(net.PacketConn); ok {
 | 
					 | 
				
			||||||
		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 _, ok := co.Conn.(net.PacketConn); ok {
 | 
					 | 
				
			||||||
		// 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 {
 | 
					 | 
				
			||||||
		mac := ""
 | 
					 | 
				
			||||||
		if _, ok := co.TsigSecret[t.Hdr.Name]; !ok {
 | 
					 | 
				
			||||||
			return ErrSecret
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		out, mac, err = TsigGenerate(m, co.TsigSecret[t.Hdr.Name], co.tsigRequestMAC, false)
 | 
					 | 
				
			||||||
		// Set for the next read, although only used in zone transfers
 | 
					 | 
				
			||||||
		co.tsigRequestMAC = mac
 | 
					 | 
				
			||||||
	} 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 _, ok := co.Conn.(net.PacketConn); ok {
 | 
					 | 
				
			||||||
		return co.Conn.Write(p)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	l := make([]byte, 2)
 | 
					 | 
				
			||||||
	binary.BigEndian.PutUint16(l, uint16(len(p)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	n, err := (&net.Buffers{l, p}).WriteTo(co.Conn)
 | 
					 | 
				
			||||||
	return int(n), err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 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)
 | 
					 | 
				
			||||||
	// ignorint 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) {
 | 
					 | 
				
			||||||
	var timeout time.Duration
 | 
					 | 
				
			||||||
	if deadline, ok := ctx.Deadline(); !ok {
 | 
					 | 
				
			||||||
		timeout = 0
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		timeout = time.Until(deadline)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// not passing the context to the underlying calls, as the API does not support
 | 
					 | 
				
			||||||
	// context. For timeouts you should set up Client.Dialer and call Client.Exchange.
 | 
					 | 
				
			||||||
	// TODO(tmthrgd,miekg): this is a race condition.
 | 
					 | 
				
			||||||
	c.Dialer = &net.Dialer{Timeout: timeout}
 | 
					 | 
				
			||||||
	return c.Exchange(m, a)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										135
									
								
								vendor/github.com/miekg/dns/clientconfig.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										135
									
								
								vendor/github.com/miekg/dns/clientconfig.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,135 +0,0 @@
 | 
				
			|||||||
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 = append([]string(nil), 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
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										43
									
								
								vendor/github.com/miekg/dns/dane.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										43
									
								
								vendor/github.com/miekg/dns/dane.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,43 +0,0 @@
 | 
				
			|||||||
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")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										384
									
								
								vendor/github.com/miekg/dns/defaults.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										384
									
								
								vendor/github.com/miekg/dns/defaults.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,384 +0,0 @@
 | 
				
			|||||||
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 = make([]Question, 1)
 | 
					 | 
				
			||||||
		dns.Question[0] = 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
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	for i := 0; i < len(s); i++ {
 | 
					 | 
				
			||||||
		switch s[i] {
 | 
					 | 
				
			||||||
		case '\\':
 | 
					 | 
				
			||||||
			if off+1 > lenmsg {
 | 
					 | 
				
			||||||
				return labels, false
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			// check for \DDD
 | 
					 | 
				
			||||||
			if i+3 < len(s) && isDigit(s[i+1]) && isDigit(s[i+2]) && isDigit(s[i+3]) {
 | 
					 | 
				
			||||||
				i += 3
 | 
					 | 
				
			||||||
				begin += 3
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				i++
 | 
					 | 
				
			||||||
				begin++
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			wasDot = false
 | 
					 | 
				
			||||||
		case '.':
 | 
					 | 
				
			||||||
			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:
 | 
					 | 
				
			||||||
			wasDot = 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 {
 | 
					 | 
				
			||||||
	s2 := strings.TrimSuffix(s, ".")
 | 
					 | 
				
			||||||
	if s == s2 {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	i := strings.LastIndexFunc(s2, func(r rune) bool {
 | 
					 | 
				
			||||||
		return r != '\\'
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Test whether we have an even number of escape sequences before
 | 
					 | 
				
			||||||
	// the dot or none.
 | 
					 | 
				
			||||||
	return (len(s2)-i)%2 != 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// IsRRset checks if 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. Returns true
 | 
					 | 
				
			||||||
// if the RR set is valid, otherwise false.
 | 
					 | 
				
			||||||
func IsRRset(rrset []RR) bool {
 | 
					 | 
				
			||||||
	if len(rrset) == 0 {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(rrset) == 1 {
 | 
					 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	rrHeader := rrset[0].Header()
 | 
					 | 
				
			||||||
	rrType := rrHeader.Rrtype
 | 
					 | 
				
			||||||
	rrClass := rrHeader.Class
 | 
					 | 
				
			||||||
	rrName := rrHeader.Name
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for _, rr := range rrset[1:] {
 | 
					 | 
				
			||||||
		curRRHeader := rr.Header()
 | 
					 | 
				
			||||||
		if curRRHeader.Rrtype != rrType || curRRHeader.Class != rrClass || curRRHeader.Name != rrName {
 | 
					 | 
				
			||||||
			// 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. See Section 6.2 in RFC 4034.
 | 
					 | 
				
			||||||
func CanonicalName(s string) string {
 | 
					 | 
				
			||||||
	return strings.ToLower(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])
 | 
					 | 
				
			||||||
		buf = append(buf, '.')
 | 
					 | 
				
			||||||
		buf = append(buf, hexDigit[v>>4])
 | 
					 | 
				
			||||||
		buf = append(buf, '.')
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// 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))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										134
									
								
								vendor/github.com/miekg/dns/dns.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										134
									
								
								vendor/github.com/miekg/dns/dns.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,134 +0,0 @@
 | 
				
			|||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "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)*2)
 | 
					 | 
				
			||||||
	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)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										758
									
								
								vendor/github.com/miekg/dns/dnssec.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										758
									
								
								vendor/github.com/miekg/dns/dnssec.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,758 +0,0 @@
 | 
				
			|||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"crypto"
 | 
					 | 
				
			||||||
	"crypto/ecdsa"
 | 
					 | 
				
			||||||
	"crypto/elliptic"
 | 
					 | 
				
			||||||
	"crypto/rand"
 | 
					 | 
				
			||||||
	"crypto/rsa"
 | 
					 | 
				
			||||||
	_ "crypto/sha1"
 | 
					 | 
				
			||||||
	_ "crypto/sha256"
 | 
					 | 
				
			||||||
	_ "crypto/sha512"
 | 
					 | 
				
			||||||
	"encoding/asn1"
 | 
					 | 
				
			||||||
	"encoding/binary"
 | 
					 | 
				
			||||||
	"encoding/hex"
 | 
					 | 
				
			||||||
	"math/big"
 | 
					 | 
				
			||||||
	"sort"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"golang.org/x/crypto/ed25519"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 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.
 | 
					 | 
				
			||||||
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:          crypto.Hash(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 */
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func divRoundUp(a, b int) int {
 | 
					 | 
				
			||||||
	return (a + b - 1) / b
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 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:
 | 
					 | 
				
			||||||
		// Look at the bottom two bytes of the modules, which the last
 | 
					 | 
				
			||||||
		// item in the pubkey.
 | 
					 | 
				
			||||||
		// This algorithm has been deprecated, but keep this key-tag calculation.
 | 
					 | 
				
			||||||
		modulus, _ := fromBase64([]byte(k.PublicKey))
 | 
					 | 
				
			||||||
		if len(modulus) > 1 {
 | 
					 | 
				
			||||||
			x := binary.BigEndian.Uint16(modulus[len(modulus)-2:])
 | 
					 | 
				
			||||||
			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 {
 | 
					 | 
				
			||||||
	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
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	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
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	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
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	hash, ok := AlgorithmToHash[rr.Algorithm]
 | 
					 | 
				
			||||||
	if !ok {
 | 
					 | 
				
			||||||
		return ErrAlg
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch rr.Algorithm {
 | 
					 | 
				
			||||||
	case ED25519:
 | 
					 | 
				
			||||||
		// ed25519 signs the raw message and performs hashing internally.
 | 
					 | 
				
			||||||
		// All other supported signature schemes operate over the pre-hashed
 | 
					 | 
				
			||||||
		// message, and thus ed25519 must be handled separately here.
 | 
					 | 
				
			||||||
		//
 | 
					 | 
				
			||||||
		// The raw message is passed directly into sign and crypto.Hash(0) is
 | 
					 | 
				
			||||||
		// used to signal to the crypto.Signer that the data has not been hashed.
 | 
					 | 
				
			||||||
		signature, err := sign(k, append(signdata, wire...), crypto.Hash(0), rr.Algorithm)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		rr.Signature = toBase64(signature)
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	case RSAMD5, DSA, DSANSEC3SHA1:
 | 
					 | 
				
			||||||
		// See RFC 6944.
 | 
					 | 
				
			||||||
		return ErrAlg
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		h := hash.New()
 | 
					 | 
				
			||||||
		h.Write(signdata)
 | 
					 | 
				
			||||||
		h.Write(wire)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		signature, err := sign(k, h.Sum(nil), hash, 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:
 | 
					 | 
				
			||||||
		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
 | 
					 | 
				
			||||||
	case ED25519:
 | 
					 | 
				
			||||||
		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.
 | 
					 | 
				
			||||||
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
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if !strings.EqualFold(rr.SignerName, k.Hdr.Name) {
 | 
					 | 
				
			||||||
		return ErrKey
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if k.Protocol != 3 {
 | 
					 | 
				
			||||||
		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 and
 | 
					 | 
				
			||||||
	// class matches the RRSIG record.
 | 
					 | 
				
			||||||
	if h0 := rrset[0].Header(); h0.Class != rr.Hdr.Class || h0.Rrtype != rr.TypeCovered {
 | 
					 | 
				
			||||||
		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 = CanonicalName(rr.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
 | 
					 | 
				
			||||||
	if rr.Algorithm == PRIVATEDNS { // PRIVATEOID
 | 
					 | 
				
			||||||
		// TODO(miek)
 | 
					 | 
				
			||||||
		// remove the domain name and assume its ours?
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	hash, ok := AlgorithmToHash[rr.Algorithm]
 | 
					 | 
				
			||||||
	if !ok {
 | 
					 | 
				
			||||||
		return ErrAlg
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	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 := hash.New()
 | 
					 | 
				
			||||||
		h.Write(signeddata)
 | 
					 | 
				
			||||||
		h.Write(wire)
 | 
					 | 
				
			||||||
		return rsa.VerifyPKCS1v15(pubkey, hash, 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 := hash.New()
 | 
					 | 
				
			||||||
		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 encodedig 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
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										140
									
								
								vendor/github.com/miekg/dns/dnssec_keygen.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										140
									
								
								vendor/github.com/miekg/dns/dnssec_keygen.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,140 +0,0 @@
 | 
				
			|||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"crypto"
 | 
					 | 
				
			||||||
	"crypto/ecdsa"
 | 
					 | 
				
			||||||
	"crypto/elliptic"
 | 
					 | 
				
			||||||
	"crypto/rand"
 | 
					 | 
				
			||||||
	"crypto/rsa"
 | 
					 | 
				
			||||||
	"math/big"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"golang.org/x/crypto/ed25519"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 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
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										310
									
								
								vendor/github.com/miekg/dns/dnssec_keyscan.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										310
									
								
								vendor/github.com/miekg/dns/dnssec_keyscan.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,310 +0,0 @@
 | 
				
			|||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bufio"
 | 
					 | 
				
			||||||
	"crypto"
 | 
					 | 
				
			||||||
	"crypto/ecdsa"
 | 
					 | 
				
			||||||
	"crypto/rsa"
 | 
					 | 
				
			||||||
	"io"
 | 
					 | 
				
			||||||
	"math/big"
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"golang.org/x/crypto/ed25519"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 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
 | 
					 | 
				
			||||||
	algo, err := strconv.ParseUint(strings.SplitN(m["algorithm"], " ", 2)[0], 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, "no private key seen", 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
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										78
									
								
								vendor/github.com/miekg/dns/dnssec_privkey.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										78
									
								
								vendor/github.com/miekg/dns/dnssec_privkey.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,78 +0,0 @@
 | 
				
			|||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"crypto"
 | 
					 | 
				
			||||||
	"crypto/ecdsa"
 | 
					 | 
				
			||||||
	"crypto/rsa"
 | 
					 | 
				
			||||||
	"math/big"
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"golang.org/x/crypto/ed25519"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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 ""
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										268
									
								
								vendor/github.com/miekg/dns/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										268
									
								
								vendor/github.com/miekg/dns/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,268 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
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: HmacMD5, 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.HmacMD5, 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.HmacMD5, 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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.HmacMD5, 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 an 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
 | 
					 | 
				
			||||||
							
								
								
									
										37
									
								
								vendor/github.com/miekg/dns/duplicate.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										37
									
								
								vendor/github.com/miekg/dns/duplicate.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,37 +0,0 @@
 | 
				
			|||||||
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) }
 | 
					 | 
				
			||||||
							
								
								
									
										675
									
								
								vendor/github.com/miekg/dns/edns.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										675
									
								
								vendor/github.com/miekg/dns/edns.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,675 +0,0 @@
 | 
				
			|||||||
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)
 | 
					 | 
				
			||||||
	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)
 | 
					 | 
				
			||||||
	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
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 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())) + "; "
 | 
					 | 
				
			||||||
	if rr.Do() {
 | 
					 | 
				
			||||||
		s += "flags: do; "
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		s += "flags: ; "
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	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_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()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	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 (rr *OPT) parse(c *zlexer, origin string) *ParseError {
 | 
					 | 
				
			||||||
	panic("dns: internal error: parse should never be called on OPT")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r1 *OPT) isDuplicate(r2 RR) bool { return false }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// return the old value -> delete SetVersion?
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 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. Any arguments after the 1st is silently 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
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 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 string encoded as hex.
 | 
					 | 
				
			||||||
// Basic use pattern for creating an nsid option:
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//	o := new(dns.OPT)
 | 
					 | 
				
			||||||
//	o.Hdr.Name = "."
 | 
					 | 
				
			||||||
//	o.Hdr.Rrtype = dns.TypeOPT
 | 
					 | 
				
			||||||
//	e := new(dns.EDNS0_NSID)
 | 
					 | 
				
			||||||
//	e.Code = dns.EDNS0NSID
 | 
					 | 
				
			||||||
//	e.Nsid = "AA"
 | 
					 | 
				
			||||||
//	o.Option = append(o.Option, e)
 | 
					 | 
				
			||||||
type EDNS0_NSID struct {
 | 
					 | 
				
			||||||
	Code uint16 // Always EDNS0NSID
 | 
					 | 
				
			||||||
	Nsid string // This string needs to be hex encoded
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e *EDNS0_NSID) pack() ([]byte, error) {
 | 
					 | 
				
			||||||
	h, err := hex.DecodeString(e.Nsid)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return h, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Option implements the EDNS0 interface.
 | 
					 | 
				
			||||||
func (e *EDNS0_NSID) Option() uint16        { return EDNS0NSID } // Option returns the option code.
 | 
					 | 
				
			||||||
func (e *EDNS0_NSID) unpack(b []byte) error { e.Nsid = hex.EncodeToString(b); return nil }
 | 
					 | 
				
			||||||
func (e *EDNS0_NSID) String() string        { return e.Nsid }
 | 
					 | 
				
			||||||
func (e *EDNS0_NSID) copy() EDNS0           { return &EDNS0_NSID{e.Code, e.Nsid} }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// EDNS0_SUBNET is the subnet option that is used to give the remote nameserver
 | 
					 | 
				
			||||||
// an idea of where the client lives. See RFC 7871. It can then give back a different
 | 
					 | 
				
			||||||
// answer depending on the location or network topology.
 | 
					 | 
				
			||||||
// Basic use pattern for creating an subnet option:
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//	o := new(dns.OPT)
 | 
					 | 
				
			||||||
//	o.Hdr.Name = "."
 | 
					 | 
				
			||||||
//	o.Hdr.Rrtype = dns.TypeOPT
 | 
					 | 
				
			||||||
//	e := new(dns.EDNS0_SUBNET)
 | 
					 | 
				
			||||||
//	e.Code = dns.EDNS0SUBNET
 | 
					 | 
				
			||||||
//	e.Family = 1	// 1 for IPv4 source address, 2 for IPv6
 | 
					 | 
				
			||||||
//	e.SourceNetmask = 32	// 32 for IPV4, 128 for IPv6
 | 
					 | 
				
			||||||
//	e.SourceScope = 0
 | 
					 | 
				
			||||||
//	e.Address = net.ParseIP("127.0.0.1").To4()	// for IPv4
 | 
					 | 
				
			||||||
//	// e.Address = net.ParseIP("2001:7b8:32a::2")	// for IPV6
 | 
					 | 
				
			||||||
//	o.Option = append(o.Option, e)
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// This code will parse all the available bits when unpacking (up to optlen).
 | 
					 | 
				
			||||||
// When packing it will apply SourceNetmask. If you need more advanced logic,
 | 
					 | 
				
			||||||
// patches welcome and good luck.
 | 
					 | 
				
			||||||
type EDNS0_SUBNET struct {
 | 
					 | 
				
			||||||
	Code          uint16 // Always EDNS0SUBNET
 | 
					 | 
				
			||||||
	Family        uint16 // 1 for IP, 2 for IP6
 | 
					 | 
				
			||||||
	SourceNetmask uint8
 | 
					 | 
				
			||||||
	SourceScope   uint8
 | 
					 | 
				
			||||||
	Address       net.IP
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Option implements the EDNS0 interface.
 | 
					 | 
				
			||||||
func (e *EDNS0_SUBNET) Option() uint16 { return EDNS0SUBNET }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e *EDNS0_SUBNET) pack() ([]byte, error) {
 | 
					 | 
				
			||||||
	b := make([]byte, 4)
 | 
					 | 
				
			||||||
	binary.BigEndian.PutUint16(b[0:], e.Family)
 | 
					 | 
				
			||||||
	b[2] = e.SourceNetmask
 | 
					 | 
				
			||||||
	b[3] = e.SourceScope
 | 
					 | 
				
			||||||
	switch e.Family {
 | 
					 | 
				
			||||||
	case 0:
 | 
					 | 
				
			||||||
		// "dig" sets AddressFamily to 0 if SourceNetmask is also 0
 | 
					 | 
				
			||||||
		// We might don't need to complain either
 | 
					 | 
				
			||||||
		if e.SourceNetmask != 0 {
 | 
					 | 
				
			||||||
			return nil, errors.New("dns: bad address family")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	case 1:
 | 
					 | 
				
			||||||
		if e.SourceNetmask > net.IPv4len*8 {
 | 
					 | 
				
			||||||
			return nil, errors.New("dns: bad netmask")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if len(e.Address.To4()) != net.IPv4len {
 | 
					 | 
				
			||||||
			return nil, errors.New("dns: bad address")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		ip := e.Address.To4().Mask(net.CIDRMask(int(e.SourceNetmask), net.IPv4len*8))
 | 
					 | 
				
			||||||
		needLength := (e.SourceNetmask + 8 - 1) / 8 // division rounding up
 | 
					 | 
				
			||||||
		b = append(b, ip[:needLength]...)
 | 
					 | 
				
			||||||
	case 2:
 | 
					 | 
				
			||||||
		if e.SourceNetmask > net.IPv6len*8 {
 | 
					 | 
				
			||||||
			return nil, errors.New("dns: bad netmask")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if len(e.Address) != net.IPv6len {
 | 
					 | 
				
			||||||
			return nil, errors.New("dns: bad address")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		ip := e.Address.Mask(net.CIDRMask(int(e.SourceNetmask), net.IPv6len*8))
 | 
					 | 
				
			||||||
		needLength := (e.SourceNetmask + 8 - 1) / 8 // division rounding up
 | 
					 | 
				
			||||||
		b = append(b, ip[:needLength]...)
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return nil, errors.New("dns: bad address family")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return b, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e *EDNS0_SUBNET) unpack(b []byte) error {
 | 
					 | 
				
			||||||
	if len(b) < 4 {
 | 
					 | 
				
			||||||
		return ErrBuf
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	e.Family = binary.BigEndian.Uint16(b)
 | 
					 | 
				
			||||||
	e.SourceNetmask = b[2]
 | 
					 | 
				
			||||||
	e.SourceScope = b[3]
 | 
					 | 
				
			||||||
	switch e.Family {
 | 
					 | 
				
			||||||
	case 0:
 | 
					 | 
				
			||||||
		// "dig" sets AddressFamily to 0 if SourceNetmask is also 0
 | 
					 | 
				
			||||||
		// It's okay to accept such a packet
 | 
					 | 
				
			||||||
		if e.SourceNetmask != 0 {
 | 
					 | 
				
			||||||
			return errors.New("dns: bad address family")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		e.Address = net.IPv4(0, 0, 0, 0)
 | 
					 | 
				
			||||||
	case 1:
 | 
					 | 
				
			||||||
		if e.SourceNetmask > net.IPv4len*8 || e.SourceScope > net.IPv4len*8 {
 | 
					 | 
				
			||||||
			return errors.New("dns: bad netmask")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		addr := make(net.IP, net.IPv4len)
 | 
					 | 
				
			||||||
		copy(addr, b[4:])
 | 
					 | 
				
			||||||
		e.Address = addr.To16()
 | 
					 | 
				
			||||||
	case 2:
 | 
					 | 
				
			||||||
		if e.SourceNetmask > net.IPv6len*8 || e.SourceScope > net.IPv6len*8 {
 | 
					 | 
				
			||||||
			return errors.New("dns: bad netmask")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		addr := make(net.IP, net.IPv6len)
 | 
					 | 
				
			||||||
		copy(addr, b[4:])
 | 
					 | 
				
			||||||
		e.Address = addr
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return errors.New("dns: bad address family")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e *EDNS0_SUBNET) String() (s string) {
 | 
					 | 
				
			||||||
	if e.Address == nil {
 | 
					 | 
				
			||||||
		s = "<nil>"
 | 
					 | 
				
			||||||
	} else if e.Address.To4() != nil {
 | 
					 | 
				
			||||||
		s = e.Address.String()
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		s = "[" + e.Address.String() + "]"
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	s += "/" + strconv.Itoa(int(e.SourceNetmask)) + "/" + strconv.Itoa(int(e.SourceScope))
 | 
					 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e *EDNS0_SUBNET) copy() EDNS0 {
 | 
					 | 
				
			||||||
	return &EDNS0_SUBNET{
 | 
					 | 
				
			||||||
		e.Code,
 | 
					 | 
				
			||||||
		e.Family,
 | 
					 | 
				
			||||||
		e.SourceNetmask,
 | 
					 | 
				
			||||||
		e.SourceScope,
 | 
					 | 
				
			||||||
		e.Address,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// The EDNS0_COOKIE option is used to add a DNS Cookie to a message.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//	o := new(dns.OPT)
 | 
					 | 
				
			||||||
//	o.Hdr.Name = "."
 | 
					 | 
				
			||||||
//	o.Hdr.Rrtype = dns.TypeOPT
 | 
					 | 
				
			||||||
//	e := new(dns.EDNS0_COOKIE)
 | 
					 | 
				
			||||||
//	e.Code = dns.EDNS0COOKIE
 | 
					 | 
				
			||||||
//	e.Cookie = "24a5ac.."
 | 
					 | 
				
			||||||
//	o.Option = append(o.Option, e)
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// The Cookie field consists out of a client cookie (RFC 7873 Section 4), that is
 | 
					 | 
				
			||||||
// always 8 bytes. It may then optionally be followed by the server cookie. The server
 | 
					 | 
				
			||||||
// cookie is of variable length, 8 to a maximum of 32 bytes. In other words:
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//	cCookie := o.Cookie[:16]
 | 
					 | 
				
			||||||
//	sCookie := o.Cookie[16:]
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// There is no guarantee that the Cookie string has a specific length.
 | 
					 | 
				
			||||||
type EDNS0_COOKIE struct {
 | 
					 | 
				
			||||||
	Code   uint16 // Always EDNS0COOKIE
 | 
					 | 
				
			||||||
	Cookie string // Hex-encoded cookie data
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e *EDNS0_COOKIE) pack() ([]byte, error) {
 | 
					 | 
				
			||||||
	h, err := hex.DecodeString(e.Cookie)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return h, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Option implements the EDNS0 interface.
 | 
					 | 
				
			||||||
func (e *EDNS0_COOKIE) Option() uint16        { return EDNS0COOKIE }
 | 
					 | 
				
			||||||
func (e *EDNS0_COOKIE) unpack(b []byte) error { e.Cookie = hex.EncodeToString(b); return nil }
 | 
					 | 
				
			||||||
func (e *EDNS0_COOKIE) String() string        { return e.Cookie }
 | 
					 | 
				
			||||||
func (e *EDNS0_COOKIE) copy() EDNS0           { return &EDNS0_COOKIE{e.Code, e.Cookie} }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// The EDNS0_UL (Update Lease) (draft RFC) option is used to tell the server to set
 | 
					 | 
				
			||||||
// an expiration on an update RR. This is helpful for clients that cannot clean
 | 
					 | 
				
			||||||
// up after themselves. This is a draft RFC and more information can be found at
 | 
					 | 
				
			||||||
// https://tools.ietf.org/html/draft-sekar-dns-ul-02
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//	o := new(dns.OPT)
 | 
					 | 
				
			||||||
//	o.Hdr.Name = "."
 | 
					 | 
				
			||||||
//	o.Hdr.Rrtype = dns.TypeOPT
 | 
					 | 
				
			||||||
//	e := new(dns.EDNS0_UL)
 | 
					 | 
				
			||||||
//	e.Code = dns.EDNS0UL
 | 
					 | 
				
			||||||
//	e.Lease = 120 // in seconds
 | 
					 | 
				
			||||||
//	o.Option = append(o.Option, e)
 | 
					 | 
				
			||||||
type EDNS0_UL struct {
 | 
					 | 
				
			||||||
	Code     uint16 // Always EDNS0UL
 | 
					 | 
				
			||||||
	Lease    uint32
 | 
					 | 
				
			||||||
	KeyLease uint32
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Option implements the EDNS0 interface.
 | 
					 | 
				
			||||||
func (e *EDNS0_UL) Option() uint16 { return EDNS0UL }
 | 
					 | 
				
			||||||
func (e *EDNS0_UL) String() string { return fmt.Sprintf("%d %d", e.Lease, e.KeyLease) }
 | 
					 | 
				
			||||||
func (e *EDNS0_UL) copy() EDNS0    { return &EDNS0_UL{e.Code, e.Lease, e.KeyLease} }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Copied: http://golang.org/src/pkg/net/dnsmsg.go
 | 
					 | 
				
			||||||
func (e *EDNS0_UL) pack() ([]byte, error) {
 | 
					 | 
				
			||||||
	var b []byte
 | 
					 | 
				
			||||||
	if e.KeyLease == 0 {
 | 
					 | 
				
			||||||
		b = make([]byte, 4)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		b = make([]byte, 8)
 | 
					 | 
				
			||||||
		binary.BigEndian.PutUint32(b[4:], e.KeyLease)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	binary.BigEndian.PutUint32(b, e.Lease)
 | 
					 | 
				
			||||||
	return b, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e *EDNS0_UL) unpack(b []byte) error {
 | 
					 | 
				
			||||||
	switch len(b) {
 | 
					 | 
				
			||||||
	case 4:
 | 
					 | 
				
			||||||
		e.KeyLease = 0
 | 
					 | 
				
			||||||
	case 8:
 | 
					 | 
				
			||||||
		e.KeyLease = binary.BigEndian.Uint32(b[4:])
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return ErrBuf
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	e.Lease = binary.BigEndian.Uint32(b)
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// EDNS0_LLQ stands for Long Lived Queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01
 | 
					 | 
				
			||||||
// Implemented for completeness, as the EDNS0 type code is assigned.
 | 
					 | 
				
			||||||
type EDNS0_LLQ struct {
 | 
					 | 
				
			||||||
	Code      uint16 // Always EDNS0LLQ
 | 
					 | 
				
			||||||
	Version   uint16
 | 
					 | 
				
			||||||
	Opcode    uint16
 | 
					 | 
				
			||||||
	Error     uint16
 | 
					 | 
				
			||||||
	Id        uint64
 | 
					 | 
				
			||||||
	LeaseLife uint32
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Option implements the EDNS0 interface.
 | 
					 | 
				
			||||||
func (e *EDNS0_LLQ) Option() uint16 { return EDNS0LLQ }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e *EDNS0_LLQ) pack() ([]byte, error) {
 | 
					 | 
				
			||||||
	b := make([]byte, 18)
 | 
					 | 
				
			||||||
	binary.BigEndian.PutUint16(b[0:], e.Version)
 | 
					 | 
				
			||||||
	binary.BigEndian.PutUint16(b[2:], e.Opcode)
 | 
					 | 
				
			||||||
	binary.BigEndian.PutUint16(b[4:], e.Error)
 | 
					 | 
				
			||||||
	binary.BigEndian.PutUint64(b[6:], e.Id)
 | 
					 | 
				
			||||||
	binary.BigEndian.PutUint32(b[14:], e.LeaseLife)
 | 
					 | 
				
			||||||
	return b, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e *EDNS0_LLQ) unpack(b []byte) error {
 | 
					 | 
				
			||||||
	if len(b) < 18 {
 | 
					 | 
				
			||||||
		return ErrBuf
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	e.Version = binary.BigEndian.Uint16(b[0:])
 | 
					 | 
				
			||||||
	e.Opcode = binary.BigEndian.Uint16(b[2:])
 | 
					 | 
				
			||||||
	e.Error = binary.BigEndian.Uint16(b[4:])
 | 
					 | 
				
			||||||
	e.Id = binary.BigEndian.Uint64(b[6:])
 | 
					 | 
				
			||||||
	e.LeaseLife = binary.BigEndian.Uint32(b[14:])
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e *EDNS0_LLQ) String() string {
 | 
					 | 
				
			||||||
	s := strconv.FormatUint(uint64(e.Version), 10) + " " + strconv.FormatUint(uint64(e.Opcode), 10) +
 | 
					 | 
				
			||||||
		" " + strconv.FormatUint(uint64(e.Error), 10) + " " + strconv.FormatUint(e.Id, 10) +
 | 
					 | 
				
			||||||
		" " + strconv.FormatUint(uint64(e.LeaseLife), 10)
 | 
					 | 
				
			||||||
	return s
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (e *EDNS0_LLQ) copy() EDNS0 {
 | 
					 | 
				
			||||||
	return &EDNS0_LLQ{e.Code, e.Version, e.Opcode, e.Error, e.Id, e.LeaseLife}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// EDNS0_DUA implements the EDNS0 "DNSSEC Algorithm Understood" option. See RFC 6975.
 | 
					 | 
				
			||||||
type EDNS0_DAU struct {
 | 
					 | 
				
			||||||
	Code    uint16 // Always EDNS0DAU
 | 
					 | 
				
			||||||
	AlgCode []uint8
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Option implements the EDNS0 interface.
 | 
					 | 
				
			||||||
func (e *EDNS0_DAU) Option() uint16        { return EDNS0DAU }
 | 
					 | 
				
			||||||
func (e *EDNS0_DAU) pack() ([]byte, error) { return e.AlgCode, nil }
 | 
					 | 
				
			||||||
func (e *EDNS0_DAU) unpack(b []byte) error { e.AlgCode = b; return nil }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e *EDNS0_DAU) String() string {
 | 
					 | 
				
			||||||
	s := ""
 | 
					 | 
				
			||||||
	for _, alg := range e.AlgCode {
 | 
					 | 
				
			||||||
		if a, ok := AlgorithmToString[alg]; ok {
 | 
					 | 
				
			||||||
			s += " " + a
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			s += " " + strconv.Itoa(int(alg))
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return s
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (e *EDNS0_DAU) copy() EDNS0 { return &EDNS0_DAU{e.Code, e.AlgCode} }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// EDNS0_DHU implements the EDNS0 "DS Hash Understood" option. See RFC 6975.
 | 
					 | 
				
			||||||
type EDNS0_DHU struct {
 | 
					 | 
				
			||||||
	Code    uint16 // Always EDNS0DHU
 | 
					 | 
				
			||||||
	AlgCode []uint8
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Option implements the EDNS0 interface.
 | 
					 | 
				
			||||||
func (e *EDNS0_DHU) Option() uint16        { return EDNS0DHU }
 | 
					 | 
				
			||||||
func (e *EDNS0_DHU) pack() ([]byte, error) { return e.AlgCode, nil }
 | 
					 | 
				
			||||||
func (e *EDNS0_DHU) unpack(b []byte) error { e.AlgCode = b; return nil }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e *EDNS0_DHU) String() string {
 | 
					 | 
				
			||||||
	s := ""
 | 
					 | 
				
			||||||
	for _, alg := range e.AlgCode {
 | 
					 | 
				
			||||||
		if a, ok := HashToString[alg]; ok {
 | 
					 | 
				
			||||||
			s += " " + a
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			s += " " + strconv.Itoa(int(alg))
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return s
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (e *EDNS0_DHU) copy() EDNS0 { return &EDNS0_DHU{e.Code, e.AlgCode} }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// EDNS0_N3U implements the EDNS0 "NSEC3 Hash Understood" option. See RFC 6975.
 | 
					 | 
				
			||||||
type EDNS0_N3U struct {
 | 
					 | 
				
			||||||
	Code    uint16 // Always EDNS0N3U
 | 
					 | 
				
			||||||
	AlgCode []uint8
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Option implements the EDNS0 interface.
 | 
					 | 
				
			||||||
func (e *EDNS0_N3U) Option() uint16        { return EDNS0N3U }
 | 
					 | 
				
			||||||
func (e *EDNS0_N3U) pack() ([]byte, error) { return e.AlgCode, nil }
 | 
					 | 
				
			||||||
func (e *EDNS0_N3U) unpack(b []byte) error { e.AlgCode = b; return nil }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e *EDNS0_N3U) String() string {
 | 
					 | 
				
			||||||
	// Re-use the hash map
 | 
					 | 
				
			||||||
	s := ""
 | 
					 | 
				
			||||||
	for _, alg := range e.AlgCode {
 | 
					 | 
				
			||||||
		if a, ok := HashToString[alg]; ok {
 | 
					 | 
				
			||||||
			s += " " + a
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			s += " " + strconv.Itoa(int(alg))
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return s
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (e *EDNS0_N3U) copy() EDNS0 { return &EDNS0_N3U{e.Code, e.AlgCode} }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// EDNS0_EXPIRE implementes the EDNS0 option as described in RFC 7314.
 | 
					 | 
				
			||||||
type EDNS0_EXPIRE struct {
 | 
					 | 
				
			||||||
	Code   uint16 // Always EDNS0EXPIRE
 | 
					 | 
				
			||||||
	Expire uint32
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Option implements the EDNS0 interface.
 | 
					 | 
				
			||||||
func (e *EDNS0_EXPIRE) Option() uint16 { return EDNS0EXPIRE }
 | 
					 | 
				
			||||||
func (e *EDNS0_EXPIRE) String() string { return strconv.FormatUint(uint64(e.Expire), 10) }
 | 
					 | 
				
			||||||
func (e *EDNS0_EXPIRE) copy() EDNS0    { return &EDNS0_EXPIRE{e.Code, e.Expire} }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e *EDNS0_EXPIRE) pack() ([]byte, error) {
 | 
					 | 
				
			||||||
	b := make([]byte, 4)
 | 
					 | 
				
			||||||
	binary.BigEndian.PutUint32(b, e.Expire)
 | 
					 | 
				
			||||||
	return b, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e *EDNS0_EXPIRE) unpack(b []byte) error {
 | 
					 | 
				
			||||||
	if len(b) == 0 {
 | 
					 | 
				
			||||||
		// zero-length EXPIRE query, see RFC 7314 Section 2
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(b) < 4 {
 | 
					 | 
				
			||||||
		return ErrBuf
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	e.Expire = binary.BigEndian.Uint32(b)
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// The EDNS0_LOCAL option is used for local/experimental purposes. The option
 | 
					 | 
				
			||||||
// code is recommended to be within the range [EDNS0LOCALSTART, EDNS0LOCALEND]
 | 
					 | 
				
			||||||
// (RFC6891), although any unassigned code can actually be used.  The content of
 | 
					 | 
				
			||||||
// the option is made available in Data, unaltered.
 | 
					 | 
				
			||||||
// Basic use pattern for creating a local option:
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//	o := new(dns.OPT)
 | 
					 | 
				
			||||||
//	o.Hdr.Name = "."
 | 
					 | 
				
			||||||
//	o.Hdr.Rrtype = dns.TypeOPT
 | 
					 | 
				
			||||||
//	e := new(dns.EDNS0_LOCAL)
 | 
					 | 
				
			||||||
//	e.Code = dns.EDNS0LOCALSTART
 | 
					 | 
				
			||||||
//	e.Data = []byte{72, 82, 74}
 | 
					 | 
				
			||||||
//	o.Option = append(o.Option, e)
 | 
					 | 
				
			||||||
type EDNS0_LOCAL struct {
 | 
					 | 
				
			||||||
	Code uint16
 | 
					 | 
				
			||||||
	Data []byte
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Option implements the EDNS0 interface.
 | 
					 | 
				
			||||||
func (e *EDNS0_LOCAL) Option() uint16 { return e.Code }
 | 
					 | 
				
			||||||
func (e *EDNS0_LOCAL) String() string {
 | 
					 | 
				
			||||||
	return strconv.FormatInt(int64(e.Code), 10) + ":0x" + hex.EncodeToString(e.Data)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (e *EDNS0_LOCAL) copy() EDNS0 {
 | 
					 | 
				
			||||||
	b := make([]byte, len(e.Data))
 | 
					 | 
				
			||||||
	copy(b, e.Data)
 | 
					 | 
				
			||||||
	return &EDNS0_LOCAL{e.Code, b}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e *EDNS0_LOCAL) pack() ([]byte, error) {
 | 
					 | 
				
			||||||
	b := make([]byte, len(e.Data))
 | 
					 | 
				
			||||||
	copied := copy(b, e.Data)
 | 
					 | 
				
			||||||
	if copied != len(e.Data) {
 | 
					 | 
				
			||||||
		return nil, ErrBuf
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return b, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e *EDNS0_LOCAL) unpack(b []byte) error {
 | 
					 | 
				
			||||||
	e.Data = make([]byte, len(b))
 | 
					 | 
				
			||||||
	copied := copy(e.Data, b)
 | 
					 | 
				
			||||||
	if copied != len(b) {
 | 
					 | 
				
			||||||
		return ErrBuf
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// EDNS0_TCP_KEEPALIVE is an EDNS0 option that instructs the server to keep
 | 
					 | 
				
			||||||
// the TCP connection alive. See RFC 7828.
 | 
					 | 
				
			||||||
type EDNS0_TCP_KEEPALIVE struct {
 | 
					 | 
				
			||||||
	Code    uint16 // Always EDNSTCPKEEPALIVE
 | 
					 | 
				
			||||||
	Length  uint16 // the value 0 if the TIMEOUT is omitted, the value 2 if it is present;
 | 
					 | 
				
			||||||
	Timeout uint16 // an idle timeout value for the TCP connection, specified in units of 100 milliseconds, encoded in network byte order.
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Option implements the EDNS0 interface.
 | 
					 | 
				
			||||||
func (e *EDNS0_TCP_KEEPALIVE) Option() uint16 { return EDNS0TCPKEEPALIVE }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e *EDNS0_TCP_KEEPALIVE) pack() ([]byte, error) {
 | 
					 | 
				
			||||||
	if e.Timeout != 0 && e.Length != 2 {
 | 
					 | 
				
			||||||
		return nil, errors.New("dns: timeout specified but length is not 2")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if e.Timeout == 0 && e.Length != 0 {
 | 
					 | 
				
			||||||
		return nil, errors.New("dns: timeout not specified but length is not 0")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	b := make([]byte, 4+e.Length)
 | 
					 | 
				
			||||||
	binary.BigEndian.PutUint16(b[0:], e.Code)
 | 
					 | 
				
			||||||
	binary.BigEndian.PutUint16(b[2:], e.Length)
 | 
					 | 
				
			||||||
	if e.Length == 2 {
 | 
					 | 
				
			||||||
		binary.BigEndian.PutUint16(b[4:], e.Timeout)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return b, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e *EDNS0_TCP_KEEPALIVE) unpack(b []byte) error {
 | 
					 | 
				
			||||||
	if len(b) < 4 {
 | 
					 | 
				
			||||||
		return ErrBuf
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	e.Length = binary.BigEndian.Uint16(b[2:4])
 | 
					 | 
				
			||||||
	if e.Length != 0 && e.Length != 2 {
 | 
					 | 
				
			||||||
		return errors.New("dns: length mismatch, want 0/2 but got " + strconv.FormatUint(uint64(e.Length), 10))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if e.Length == 2 {
 | 
					 | 
				
			||||||
		if len(b) < 6 {
 | 
					 | 
				
			||||||
			return ErrBuf
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		e.Timeout = binary.BigEndian.Uint16(b[4:6])
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e *EDNS0_TCP_KEEPALIVE) String() (s string) {
 | 
					 | 
				
			||||||
	s = "use tcp keep-alive"
 | 
					 | 
				
			||||||
	if e.Length == 0 {
 | 
					 | 
				
			||||||
		s += ", timeout omitted"
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		s += fmt.Sprintf(", timeout %dms", e.Timeout*100)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (e *EDNS0_TCP_KEEPALIVE) copy() EDNS0 { return &EDNS0_TCP_KEEPALIVE{e.Code, e.Length, e.Timeout} }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// EDNS0_PADDING option is used to add padding to a request/response. The default
 | 
					 | 
				
			||||||
// value of padding SHOULD be 0x0 but other values MAY be used, for instance if
 | 
					 | 
				
			||||||
// compression is applied before encryption which may break signatures.
 | 
					 | 
				
			||||||
type EDNS0_PADDING struct {
 | 
					 | 
				
			||||||
	Padding []byte
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Option implements the EDNS0 interface.
 | 
					 | 
				
			||||||
func (e *EDNS0_PADDING) Option() uint16        { return EDNS0PADDING }
 | 
					 | 
				
			||||||
func (e *EDNS0_PADDING) pack() ([]byte, error) { return e.Padding, nil }
 | 
					 | 
				
			||||||
func (e *EDNS0_PADDING) unpack(b []byte) error { e.Padding = b; return nil }
 | 
					 | 
				
			||||||
func (e *EDNS0_PADDING) String() string        { return fmt.Sprintf("%0X", e.Padding) }
 | 
					 | 
				
			||||||
func (e *EDNS0_PADDING) copy() EDNS0 {
 | 
					 | 
				
			||||||
	b := make([]byte, len(e.Padding))
 | 
					 | 
				
			||||||
	copy(b, e.Padding)
 | 
					 | 
				
			||||||
	return &EDNS0_PADDING{b}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										93
									
								
								vendor/github.com/miekg/dns/format.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										93
									
								
								vendor/github.com/miekg/dns/format.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,93 +0,0 @@
 | 
				
			|||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"net"
 | 
					 | 
				
			||||||
	"reflect"
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NumField returns the number of rdata fields r has.
 | 
					 | 
				
			||||||
func NumField(r RR) int {
 | 
					 | 
				
			||||||
	return reflect.ValueOf(r).Elem().NumField() - 1 // Remove RR_Header
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Field returns the rdata field i as a string. Fields are indexed starting from 1.
 | 
					 | 
				
			||||||
// RR types that holds slice data, for instance the NSEC type bitmap will return a single
 | 
					 | 
				
			||||||
// string where the types are concatenated using a space.
 | 
					 | 
				
			||||||
// Accessing non existing fields will cause a panic.
 | 
					 | 
				
			||||||
func Field(r RR, i int) string {
 | 
					 | 
				
			||||||
	if i == 0 {
 | 
					 | 
				
			||||||
		return ""
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	d := reflect.ValueOf(r).Elem().Field(i)
 | 
					 | 
				
			||||||
	switch d.Kind() {
 | 
					 | 
				
			||||||
	case reflect.String:
 | 
					 | 
				
			||||||
		return d.String()
 | 
					 | 
				
			||||||
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 | 
					 | 
				
			||||||
		return strconv.FormatInt(d.Int(), 10)
 | 
					 | 
				
			||||||
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
 | 
					 | 
				
			||||||
		return strconv.FormatUint(d.Uint(), 10)
 | 
					 | 
				
			||||||
	case reflect.Slice:
 | 
					 | 
				
			||||||
		switch reflect.ValueOf(r).Elem().Type().Field(i).Tag {
 | 
					 | 
				
			||||||
		case `dns:"a"`:
 | 
					 | 
				
			||||||
			// TODO(miek): Hmm store this as 16 bytes
 | 
					 | 
				
			||||||
			if d.Len() < net.IPv4len {
 | 
					 | 
				
			||||||
				return ""
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if d.Len() < net.IPv6len {
 | 
					 | 
				
			||||||
				return net.IPv4(byte(d.Index(0).Uint()),
 | 
					 | 
				
			||||||
					byte(d.Index(1).Uint()),
 | 
					 | 
				
			||||||
					byte(d.Index(2).Uint()),
 | 
					 | 
				
			||||||
					byte(d.Index(3).Uint())).String()
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return net.IPv4(byte(d.Index(12).Uint()),
 | 
					 | 
				
			||||||
				byte(d.Index(13).Uint()),
 | 
					 | 
				
			||||||
				byte(d.Index(14).Uint()),
 | 
					 | 
				
			||||||
				byte(d.Index(15).Uint())).String()
 | 
					 | 
				
			||||||
		case `dns:"aaaa"`:
 | 
					 | 
				
			||||||
			if d.Len() < net.IPv6len {
 | 
					 | 
				
			||||||
				return ""
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return net.IP{
 | 
					 | 
				
			||||||
				byte(d.Index(0).Uint()),
 | 
					 | 
				
			||||||
				byte(d.Index(1).Uint()),
 | 
					 | 
				
			||||||
				byte(d.Index(2).Uint()),
 | 
					 | 
				
			||||||
				byte(d.Index(3).Uint()),
 | 
					 | 
				
			||||||
				byte(d.Index(4).Uint()),
 | 
					 | 
				
			||||||
				byte(d.Index(5).Uint()),
 | 
					 | 
				
			||||||
				byte(d.Index(6).Uint()),
 | 
					 | 
				
			||||||
				byte(d.Index(7).Uint()),
 | 
					 | 
				
			||||||
				byte(d.Index(8).Uint()),
 | 
					 | 
				
			||||||
				byte(d.Index(9).Uint()),
 | 
					 | 
				
			||||||
				byte(d.Index(10).Uint()),
 | 
					 | 
				
			||||||
				byte(d.Index(11).Uint()),
 | 
					 | 
				
			||||||
				byte(d.Index(12).Uint()),
 | 
					 | 
				
			||||||
				byte(d.Index(13).Uint()),
 | 
					 | 
				
			||||||
				byte(d.Index(14).Uint()),
 | 
					 | 
				
			||||||
				byte(d.Index(15).Uint()),
 | 
					 | 
				
			||||||
			}.String()
 | 
					 | 
				
			||||||
		case `dns:"nsec"`:
 | 
					 | 
				
			||||||
			if d.Len() == 0 {
 | 
					 | 
				
			||||||
				return ""
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			s := Type(d.Index(0).Uint()).String()
 | 
					 | 
				
			||||||
			for i := 1; i < d.Len(); i++ {
 | 
					 | 
				
			||||||
				s += " " + Type(d.Index(i).Uint()).String()
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return s
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			// if it does not have a tag its a string slice
 | 
					 | 
				
			||||||
			fallthrough
 | 
					 | 
				
			||||||
		case `dns:"txt"`:
 | 
					 | 
				
			||||||
			if d.Len() == 0 {
 | 
					 | 
				
			||||||
				return ""
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			s := d.Index(0).String()
 | 
					 | 
				
			||||||
			for i := 1; i < d.Len(); i++ {
 | 
					 | 
				
			||||||
				s += " " + d.Index(i).String()
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return s
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return ""
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										32
									
								
								vendor/github.com/miekg/dns/fuzz.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								vendor/github.com/miekg/dns/fuzz.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,32 +0,0 @@
 | 
				
			|||||||
// +build fuzz
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "strings"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func Fuzz(data []byte) int {
 | 
					 | 
				
			||||||
	msg := new(Msg)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err := msg.Unpack(data); err != nil {
 | 
					 | 
				
			||||||
		return 0
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if _, err := msg.Pack(); err != nil {
 | 
					 | 
				
			||||||
		return 0
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 1
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func FuzzNewRR(data []byte) int {
 | 
					 | 
				
			||||||
	str := string(data)
 | 
					 | 
				
			||||||
	// Do not fuzz lines that include the $INCLUDE keyword and hint the fuzzer
 | 
					 | 
				
			||||||
	// at avoiding them.
 | 
					 | 
				
			||||||
	// See GH#1025 for context.
 | 
					 | 
				
			||||||
	if strings.Contains(strings.ToUpper(str), "$INCLUDE") {
 | 
					 | 
				
			||||||
		return -1
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if _, err := NewRR(str); err != nil {
 | 
					 | 
				
			||||||
		return 0
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return 1
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										247
									
								
								vendor/github.com/miekg/dns/generate.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										247
									
								
								vendor/github.com/miekg/dns/generate.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,247 +0,0 @@
 | 
				
			|||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"io"
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Parse the $GENERATE statement as used in BIND9 zones.
 | 
					 | 
				
			||||||
// See http://www.zytrax.com/books/dns/ch8/generate.html for instance.
 | 
					 | 
				
			||||||
// We are called after '$GENERATE '. After which we expect:
 | 
					 | 
				
			||||||
// * the range (12-24/2)
 | 
					 | 
				
			||||||
// * lhs (ownername)
 | 
					 | 
				
			||||||
// * [[ttl][class]]
 | 
					 | 
				
			||||||
// * type
 | 
					 | 
				
			||||||
// * rhs (rdata)
 | 
					 | 
				
			||||||
// But we are lazy here, only the range is parsed *all* occurrences
 | 
					 | 
				
			||||||
// of $ after that are interpreted.
 | 
					 | 
				
			||||||
func (zp *ZoneParser) generate(l lex) (RR, bool) {
 | 
					 | 
				
			||||||
	token := l.token
 | 
					 | 
				
			||||||
	step := int64(1)
 | 
					 | 
				
			||||||
	if i := strings.IndexByte(token, '/'); i >= 0 {
 | 
					 | 
				
			||||||
		if i+1 == len(token) {
 | 
					 | 
				
			||||||
			return zp.setParseError("bad step in $GENERATE range", l)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		s, err := strconv.ParseInt(token[i+1:], 10, 64)
 | 
					 | 
				
			||||||
		if err != nil || s <= 0 {
 | 
					 | 
				
			||||||
			return zp.setParseError("bad step in $GENERATE range", l)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		step = s
 | 
					 | 
				
			||||||
		token = token[:i]
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sx := strings.SplitN(token, "-", 2)
 | 
					 | 
				
			||||||
	if len(sx) != 2 {
 | 
					 | 
				
			||||||
		return zp.setParseError("bad start-stop in $GENERATE range", l)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	start, err := strconv.ParseInt(sx[0], 10, 64)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return zp.setParseError("bad start in $GENERATE range", l)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	end, err := strconv.ParseInt(sx[1], 10, 64)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return zp.setParseError("bad stop in $GENERATE range", l)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if end < 0 || start < 0 || end < start || (end-start)/step > 65535 {
 | 
					 | 
				
			||||||
		return zp.setParseError("bad range in $GENERATE range", l)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// _BLANK
 | 
					 | 
				
			||||||
	l, ok := zp.c.Next()
 | 
					 | 
				
			||||||
	if !ok || l.value != zBlank {
 | 
					 | 
				
			||||||
		return zp.setParseError("garbage after $GENERATE range", l)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Create a complete new string, which we then parse again.
 | 
					 | 
				
			||||||
	var s string
 | 
					 | 
				
			||||||
	for l, ok := zp.c.Next(); ok; l, ok = zp.c.Next() {
 | 
					 | 
				
			||||||
		if l.err {
 | 
					 | 
				
			||||||
			return zp.setParseError("bad data in $GENERATE directive", l)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if l.value == zNewline {
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		s += l.token
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	r := &generateReader{
 | 
					 | 
				
			||||||
		s: s,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		cur:   int(start),
 | 
					 | 
				
			||||||
		start: int(start),
 | 
					 | 
				
			||||||
		end:   int(end),
 | 
					 | 
				
			||||||
		step:  int(step),
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		file: zp.file,
 | 
					 | 
				
			||||||
		lex:  &l,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	zp.sub = NewZoneParser(r, zp.origin, zp.file)
 | 
					 | 
				
			||||||
	zp.sub.includeDepth, zp.sub.includeAllowed = zp.includeDepth, zp.includeAllowed
 | 
					 | 
				
			||||||
	zp.sub.generateDisallowed = true
 | 
					 | 
				
			||||||
	zp.sub.SetDefaultTTL(defaultTtl)
 | 
					 | 
				
			||||||
	return zp.subNext()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type generateReader struct {
 | 
					 | 
				
			||||||
	s  string
 | 
					 | 
				
			||||||
	si int
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cur   int
 | 
					 | 
				
			||||||
	start int
 | 
					 | 
				
			||||||
	end   int
 | 
					 | 
				
			||||||
	step  int
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	mod bytes.Buffer
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	escape bool
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	eof bool
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	file string
 | 
					 | 
				
			||||||
	lex  *lex
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r *generateReader) parseError(msg string, end int) *ParseError {
 | 
					 | 
				
			||||||
	r.eof = true // Make errors sticky.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	l := *r.lex
 | 
					 | 
				
			||||||
	l.token = r.s[r.si-1 : end]
 | 
					 | 
				
			||||||
	l.column += r.si // l.column starts one zBLANK before r.s
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return &ParseError{r.file, msg, l}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r *generateReader) Read(p []byte) (int, error) {
 | 
					 | 
				
			||||||
	// NewZLexer, through NewZoneParser, should use ReadByte and
 | 
					 | 
				
			||||||
	// not end up here.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	panic("not implemented")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r *generateReader) ReadByte() (byte, error) {
 | 
					 | 
				
			||||||
	if r.eof {
 | 
					 | 
				
			||||||
		return 0, io.EOF
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if r.mod.Len() > 0 {
 | 
					 | 
				
			||||||
		return r.mod.ReadByte()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if r.si >= len(r.s) {
 | 
					 | 
				
			||||||
		r.si = 0
 | 
					 | 
				
			||||||
		r.cur += r.step
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		r.eof = r.cur > r.end || r.cur < 0
 | 
					 | 
				
			||||||
		return '\n', nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	si := r.si
 | 
					 | 
				
			||||||
	r.si++
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch r.s[si] {
 | 
					 | 
				
			||||||
	case '\\':
 | 
					 | 
				
			||||||
		if r.escape {
 | 
					 | 
				
			||||||
			r.escape = false
 | 
					 | 
				
			||||||
			return '\\', nil
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		r.escape = true
 | 
					 | 
				
			||||||
		return r.ReadByte()
 | 
					 | 
				
			||||||
	case '$':
 | 
					 | 
				
			||||||
		if r.escape {
 | 
					 | 
				
			||||||
			r.escape = false
 | 
					 | 
				
			||||||
			return '$', nil
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		mod := "%d"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if si >= len(r.s)-1 {
 | 
					 | 
				
			||||||
			// End of the string
 | 
					 | 
				
			||||||
			fmt.Fprintf(&r.mod, mod, r.cur)
 | 
					 | 
				
			||||||
			return r.mod.ReadByte()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if r.s[si+1] == '$' {
 | 
					 | 
				
			||||||
			r.si++
 | 
					 | 
				
			||||||
			return '$', nil
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		var offset int
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Search for { and }
 | 
					 | 
				
			||||||
		if r.s[si+1] == '{' {
 | 
					 | 
				
			||||||
			// Modifier block
 | 
					 | 
				
			||||||
			sep := strings.Index(r.s[si+2:], "}")
 | 
					 | 
				
			||||||
			if sep < 0 {
 | 
					 | 
				
			||||||
				return 0, r.parseError("bad modifier in $GENERATE", len(r.s))
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			var errMsg string
 | 
					 | 
				
			||||||
			mod, offset, errMsg = modToPrintf(r.s[si+2 : si+2+sep])
 | 
					 | 
				
			||||||
			if errMsg != "" {
 | 
					 | 
				
			||||||
				return 0, r.parseError(errMsg, si+3+sep)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if r.start+offset < 0 || int64(r.end) + int64(offset) > 1<<31-1 {
 | 
					 | 
				
			||||||
				return 0, r.parseError("bad offset in $GENERATE", si+3+sep)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			r.si += 2 + sep // Jump to it
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		fmt.Fprintf(&r.mod, mod, r.cur+offset)
 | 
					 | 
				
			||||||
		return r.mod.ReadByte()
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		if r.escape { // Pretty useless here
 | 
					 | 
				
			||||||
			r.escape = false
 | 
					 | 
				
			||||||
			return r.ReadByte()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return r.s[si], nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Convert a $GENERATE modifier 0,0,d to something Printf can deal with.
 | 
					 | 
				
			||||||
func modToPrintf(s string) (string, int, string) {
 | 
					 | 
				
			||||||
	// Modifier is { offset [ ,width [ ,base ] ] } - provide default
 | 
					 | 
				
			||||||
	// values for optional width and type, if necessary.
 | 
					 | 
				
			||||||
	var offStr, widthStr, base string
 | 
					 | 
				
			||||||
	switch xs := strings.Split(s, ","); len(xs) {
 | 
					 | 
				
			||||||
	case 1:
 | 
					 | 
				
			||||||
		offStr, widthStr, base = xs[0], "0", "d"
 | 
					 | 
				
			||||||
	case 2:
 | 
					 | 
				
			||||||
		offStr, widthStr, base = xs[0], xs[1], "d"
 | 
					 | 
				
			||||||
	case 3:
 | 
					 | 
				
			||||||
		offStr, widthStr, base = xs[0], xs[1], xs[2]
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return "", 0, "bad modifier in $GENERATE"
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch base {
 | 
					 | 
				
			||||||
	case "o", "d", "x", "X":
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return "", 0, "bad base in $GENERATE"
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	offset, err := strconv.ParseInt(offStr, 10, 64)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return "", 0, "bad offset in $GENERATE"
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	width, err := strconv.ParseInt(widthStr, 10, 64)
 | 
					 | 
				
			||||||
	if err != nil || width < 0 || width > 255 {
 | 
					 | 
				
			||||||
		return "", 0, "bad width in $GENERATE"
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if width == 0 {
 | 
					 | 
				
			||||||
		return "%" + base, int(offset), ""
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return "%0" + widthStr + base, int(offset), ""
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										11
									
								
								vendor/github.com/miekg/dns/go.mod
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/miekg/dns/go.mod
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,11 +0,0 @@
 | 
				
			|||||||
module github.com/miekg/dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
go 1.12
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
require (
 | 
					 | 
				
			||||||
	golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
 | 
					 | 
				
			||||||
	golang.org/x/net v0.0.0-20190923162816-aa69164e4478
 | 
					 | 
				
			||||||
	golang.org/x/sync v0.0.0-20190423024810-112230192c58
 | 
					 | 
				
			||||||
	golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe
 | 
					 | 
				
			||||||
	golang.org/x/tools v0.0.0-20191216052735-49a3e744a425 // indirect
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
							
								
								
									
										39
									
								
								vendor/github.com/miekg/dns/go.sum
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										39
									
								
								vendor/github.com/miekg/dns/go.sum
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,39 +0,0 @@
 | 
				
			|||||||
golang.org/x/crypto v0.0.0-20181001203147-e3636079e1a4 h1:Vk3wNqEZwyGyei9yq5ekj7frek2u7HUfffJ1/opblzc=
 | 
					 | 
				
			||||||
golang.org/x/crypto v0.0.0-20181001203147-e3636079e1a4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 | 
					 | 
				
			||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 | 
					 | 
				
			||||||
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 h1:Gv7RPwsi3eZ2Fgewe3CBsuOebPwO27PoXzRpJPsvSSM=
 | 
					 | 
				
			||||||
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 | 
					 | 
				
			||||||
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392 h1:ACG4HJsFiNMf47Y4PeRoebLNy/2lXT9EtprMuTFWt1M=
 | 
					 | 
				
			||||||
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
 | 
					 | 
				
			||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
 | 
					 | 
				
			||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 | 
					 | 
				
			||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
 | 
					 | 
				
			||||||
golang.org/x/net v0.0.0-20180926154720-4dfa2610cdf3 h1:dgd4x4kJt7G4k4m93AYLzM8Ni6h2qLTfh9n9vXJT3/0=
 | 
					 | 
				
			||||||
golang.org/x/net v0.0.0-20180926154720-4dfa2610cdf3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 | 
					 | 
				
			||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 | 
					 | 
				
			||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 | 
					 | 
				
			||||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
 | 
					 | 
				
			||||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 | 
					 | 
				
			||||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g=
 | 
					 | 
				
			||||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 | 
					 | 
				
			||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
 | 
					 | 
				
			||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
					 | 
				
			||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
 | 
					 | 
				
			||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
					 | 
				
			||||||
golang.org/x/sys v0.0.0-20180928133829-e4b3c5e90611 h1:O33LKL7WyJgjN9CvxfTIomjIClbd/Kq86/iipowHQU0=
 | 
					 | 
				
			||||||
golang.org/x/sys v0.0.0-20180928133829-e4b3c5e90611/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
					 | 
				
			||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
					 | 
				
			||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					 | 
				
			||||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd h1:DBH9mDw0zluJT/R+nGuV3jWFWLFaHyYZWD4tOT+cjn0=
 | 
					 | 
				
			||||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					 | 
				
			||||||
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					 | 
				
			||||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe h1:6fAMxZRR6sl1Uq8U61gxU+kPTs2tR8uOySCbBP7BN/M=
 | 
					 | 
				
			||||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					 | 
				
			||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 | 
					 | 
				
			||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 | 
					 | 
				
			||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 | 
					 | 
				
			||||||
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 | 
					 | 
				
			||||||
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425 h1:VvQyQJN0tSuecqgcIxMWnnfG5kSmgy9KZR9sW3W5QeA=
 | 
					 | 
				
			||||||
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 | 
					 | 
				
			||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
					 | 
				
			||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
					 | 
				
			||||||
							
								
								
									
										212
									
								
								vendor/github.com/miekg/dns/labels.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										212
									
								
								vendor/github.com/miekg/dns/labels.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,212 +0,0 @@
 | 
				
			|||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Holds a bunch of helper functions for dealing with labels.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SplitDomainName splits a name string into it's labels.
 | 
					 | 
				
			||||||
// www.miek.nl. returns []string{"www", "miek", "nl"}
 | 
					 | 
				
			||||||
// .www.miek.nl. returns []string{"", "www", "miek", "nl"},
 | 
					 | 
				
			||||||
// The root label (.) returns nil. Note that using
 | 
					 | 
				
			||||||
// strings.Split(s) will work in most cases, but does not handle
 | 
					 | 
				
			||||||
// escaped dots (\.) for instance.
 | 
					 | 
				
			||||||
// s must be a syntactically valid domain name, see IsDomainName.
 | 
					 | 
				
			||||||
func SplitDomainName(s string) (labels []string) {
 | 
					 | 
				
			||||||
	if len(s) == 0 {
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	fqdnEnd := 0 // offset of the final '.' or the length of the name
 | 
					 | 
				
			||||||
	idx := Split(s)
 | 
					 | 
				
			||||||
	begin := 0
 | 
					 | 
				
			||||||
	if IsFqdn(s) {
 | 
					 | 
				
			||||||
		fqdnEnd = len(s) - 1
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		fqdnEnd = len(s)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch len(idx) {
 | 
					 | 
				
			||||||
	case 0:
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	case 1:
 | 
					 | 
				
			||||||
		// no-op
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		for _, end := range idx[1:] {
 | 
					 | 
				
			||||||
			labels = append(labels, s[begin:end-1])
 | 
					 | 
				
			||||||
			begin = end
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return append(labels, s[begin:fqdnEnd])
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// CompareDomainName compares the names s1 and s2 and
 | 
					 | 
				
			||||||
// returns how many labels they have in common starting from the *right*.
 | 
					 | 
				
			||||||
// The comparison stops at the first inequality. The names are downcased
 | 
					 | 
				
			||||||
// before the comparison.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// www.miek.nl. and miek.nl. have two labels in common: miek and nl
 | 
					 | 
				
			||||||
// www.miek.nl. and www.bla.nl. have one label in common: nl
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// s1 and s2 must be syntactically valid domain names.
 | 
					 | 
				
			||||||
func CompareDomainName(s1, s2 string) (n int) {
 | 
					 | 
				
			||||||
	// the first check: root label
 | 
					 | 
				
			||||||
	if s1 == "." || s2 == "." {
 | 
					 | 
				
			||||||
		return 0
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	l1 := Split(s1)
 | 
					 | 
				
			||||||
	l2 := Split(s2)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	j1 := len(l1) - 1 // end
 | 
					 | 
				
			||||||
	i1 := len(l1) - 2 // start
 | 
					 | 
				
			||||||
	j2 := len(l2) - 1
 | 
					 | 
				
			||||||
	i2 := len(l2) - 2
 | 
					 | 
				
			||||||
	// the second check can be done here: last/only label
 | 
					 | 
				
			||||||
	// before we fall through into the for-loop below
 | 
					 | 
				
			||||||
	if equal(s1[l1[j1]:], s2[l2[j2]:]) {
 | 
					 | 
				
			||||||
		n++
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for {
 | 
					 | 
				
			||||||
		if i1 < 0 || i2 < 0 {
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if equal(s1[l1[i1]:l1[j1]], s2[l2[i2]:l2[j2]]) {
 | 
					 | 
				
			||||||
			n++
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		j1--
 | 
					 | 
				
			||||||
		i1--
 | 
					 | 
				
			||||||
		j2--
 | 
					 | 
				
			||||||
		i2--
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// CountLabel counts the number of labels in the string s.
 | 
					 | 
				
			||||||
// s must be a syntactically valid domain name.
 | 
					 | 
				
			||||||
func CountLabel(s string) (labels int) {
 | 
					 | 
				
			||||||
	if s == "." {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	off := 0
 | 
					 | 
				
			||||||
	end := false
 | 
					 | 
				
			||||||
	for {
 | 
					 | 
				
			||||||
		off, end = NextLabel(s, off)
 | 
					 | 
				
			||||||
		labels++
 | 
					 | 
				
			||||||
		if end {
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Split splits a name s into its label indexes.
 | 
					 | 
				
			||||||
// www.miek.nl. returns []int{0, 4, 9}, www.miek.nl also returns []int{0, 4, 9}.
 | 
					 | 
				
			||||||
// The root name (.) returns nil. Also see SplitDomainName.
 | 
					 | 
				
			||||||
// s must be a syntactically valid domain name.
 | 
					 | 
				
			||||||
func Split(s string) []int {
 | 
					 | 
				
			||||||
	if s == "." {
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	idx := make([]int, 1, 3)
 | 
					 | 
				
			||||||
	off := 0
 | 
					 | 
				
			||||||
	end := false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for {
 | 
					 | 
				
			||||||
		off, end = NextLabel(s, off)
 | 
					 | 
				
			||||||
		if end {
 | 
					 | 
				
			||||||
			return idx
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		idx = append(idx, off)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NextLabel returns the index of the start of the next label in the
 | 
					 | 
				
			||||||
// string s starting at offset.
 | 
					 | 
				
			||||||
// The bool end is true when the end of the string has been reached.
 | 
					 | 
				
			||||||
// Also see PrevLabel.
 | 
					 | 
				
			||||||
func NextLabel(s string, offset int) (i int, end bool) {
 | 
					 | 
				
			||||||
	if s == "" {
 | 
					 | 
				
			||||||
		return 0, true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for i = offset; i < len(s)-1; i++ {
 | 
					 | 
				
			||||||
		if s[i] != '.' {
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		j := i - 1
 | 
					 | 
				
			||||||
		for j >= 0 && s[j] == '\\' {
 | 
					 | 
				
			||||||
			j--
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (j-i)%2 == 0 {
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return i + 1, false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return i + 1, true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// PrevLabel returns the index of the label when starting from the right and
 | 
					 | 
				
			||||||
// jumping n labels to the left.
 | 
					 | 
				
			||||||
// The bool start is true when the start of the string has been overshot.
 | 
					 | 
				
			||||||
// Also see NextLabel.
 | 
					 | 
				
			||||||
func PrevLabel(s string, n int) (i int, start bool) {
 | 
					 | 
				
			||||||
	if s == "" {
 | 
					 | 
				
			||||||
		return 0, true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if n == 0 {
 | 
					 | 
				
			||||||
		return len(s), false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	l := len(s) - 1
 | 
					 | 
				
			||||||
	if s[l] == '.' {
 | 
					 | 
				
			||||||
		l--
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for ; l >= 0 && n > 0; l-- {
 | 
					 | 
				
			||||||
		if s[l] != '.' {
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		j := l - 1
 | 
					 | 
				
			||||||
		for j >= 0 && s[j] == '\\' {
 | 
					 | 
				
			||||||
			j--
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (j-l)%2 == 0 {
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		n--
 | 
					 | 
				
			||||||
		if n == 0 {
 | 
					 | 
				
			||||||
			return l + 1, false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0, n > 1
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// equal compares a and b while ignoring case. It returns true when equal otherwise false.
 | 
					 | 
				
			||||||
func equal(a, b string) bool {
 | 
					 | 
				
			||||||
	// might be lifted into API function.
 | 
					 | 
				
			||||||
	la := len(a)
 | 
					 | 
				
			||||||
	lb := len(b)
 | 
					 | 
				
			||||||
	if la != lb {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for i := la - 1; i >= 0; i-- {
 | 
					 | 
				
			||||||
		ai := a[i]
 | 
					 | 
				
			||||||
		bi := b[i]
 | 
					 | 
				
			||||||
		if ai >= 'A' && ai <= 'Z' {
 | 
					 | 
				
			||||||
			ai |= 'a' - 'A'
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if bi >= 'A' && bi <= 'Z' {
 | 
					 | 
				
			||||||
			bi |= 'a' - 'A'
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if ai != bi {
 | 
					 | 
				
			||||||
			return false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										44
									
								
								vendor/github.com/miekg/dns/listen_go111.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										44
									
								
								vendor/github.com/miekg/dns/listen_go111.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,44 +0,0 @@
 | 
				
			|||||||
// +build go1.11
 | 
					 | 
				
			||||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"context"
 | 
					 | 
				
			||||||
	"net"
 | 
					 | 
				
			||||||
	"syscall"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"golang.org/x/sys/unix"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const supportsReusePort = true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func reuseportControl(network, address string, c syscall.RawConn) error {
 | 
					 | 
				
			||||||
	var opErr error
 | 
					 | 
				
			||||||
	err := c.Control(func(fd uintptr) {
 | 
					 | 
				
			||||||
		opErr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1)
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return opErr
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func listenTCP(network, addr string, reuseport bool) (net.Listener, error) {
 | 
					 | 
				
			||||||
	var lc net.ListenConfig
 | 
					 | 
				
			||||||
	if reuseport {
 | 
					 | 
				
			||||||
		lc.Control = reuseportControl
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return lc.Listen(context.Background(), network, addr)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func listenUDP(network, addr string, reuseport bool) (net.PacketConn, error) {
 | 
					 | 
				
			||||||
	var lc net.ListenConfig
 | 
					 | 
				
			||||||
	if reuseport {
 | 
					 | 
				
			||||||
		lc.Control = reuseportControl
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return lc.ListenPacket(context.Background(), network, addr)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										23
									
								
								vendor/github.com/miekg/dns/listen_go_not111.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								vendor/github.com/miekg/dns/listen_go_not111.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,23 +0,0 @@
 | 
				
			|||||||
// +build !go1.11 !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "net"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const supportsReusePort = false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func listenTCP(network, addr string, reuseport bool) (net.Listener, error) {
 | 
					 | 
				
			||||||
	if reuseport {
 | 
					 | 
				
			||||||
		// TODO(tmthrgd): return an error?
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return net.Listen(network, addr)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func listenUDP(network, addr string, reuseport bool) (net.PacketConn, error) {
 | 
					 | 
				
			||||||
	if reuseport {
 | 
					 | 
				
			||||||
		// TODO(tmthrgd): return an error?
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return net.ListenPacket(network, addr)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										1190
									
								
								vendor/github.com/miekg/dns/msg.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1190
									
								
								vendor/github.com/miekg/dns/msg.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										833
									
								
								vendor/github.com/miekg/dns/msg_helpers.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										833
									
								
								vendor/github.com/miekg/dns/msg_helpers.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,833 +0,0 @@
 | 
				
			|||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/base32"
 | 
					 | 
				
			||||||
	"encoding/base64"
 | 
					 | 
				
			||||||
	"encoding/binary"
 | 
					 | 
				
			||||||
	"encoding/hex"
 | 
					 | 
				
			||||||
	"net"
 | 
					 | 
				
			||||||
	"sort"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// helper functions called from the generated zmsg.go
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// These function are named after the tag to help pack/unpack, if there is no tag it is the name
 | 
					 | 
				
			||||||
// of the type they pack/unpack (string, int, etc). We prefix all with unpackData or packData, so packDataA or
 | 
					 | 
				
			||||||
// packDataDomainName.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func unpackDataA(msg []byte, off int) (net.IP, int, error) {
 | 
					 | 
				
			||||||
	if off+net.IPv4len > len(msg) {
 | 
					 | 
				
			||||||
		return nil, len(msg), &Error{err: "overflow unpacking a"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	a := append(make(net.IP, 0, net.IPv4len), msg[off:off+net.IPv4len]...)
 | 
					 | 
				
			||||||
	off += net.IPv4len
 | 
					 | 
				
			||||||
	return a, off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func packDataA(a net.IP, msg []byte, off int) (int, error) {
 | 
					 | 
				
			||||||
	switch len(a) {
 | 
					 | 
				
			||||||
	case net.IPv4len, net.IPv6len:
 | 
					 | 
				
			||||||
		// It must be a slice of 4, even if it is 16, we encode only the first 4
 | 
					 | 
				
			||||||
		if off+net.IPv4len > len(msg) {
 | 
					 | 
				
			||||||
			return len(msg), &Error{err: "overflow packing a"}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		copy(msg[off:], a.To4())
 | 
					 | 
				
			||||||
		off += net.IPv4len
 | 
					 | 
				
			||||||
	case 0:
 | 
					 | 
				
			||||||
		// Allowed, for dynamic updates.
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return len(msg), &Error{err: "overflow packing a"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func unpackDataAAAA(msg []byte, off int) (net.IP, int, error) {
 | 
					 | 
				
			||||||
	if off+net.IPv6len > len(msg) {
 | 
					 | 
				
			||||||
		return nil, len(msg), &Error{err: "overflow unpacking aaaa"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	aaaa := append(make(net.IP, 0, net.IPv6len), msg[off:off+net.IPv6len]...)
 | 
					 | 
				
			||||||
	off += net.IPv6len
 | 
					 | 
				
			||||||
	return aaaa, off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func packDataAAAA(aaaa net.IP, msg []byte, off int) (int, error) {
 | 
					 | 
				
			||||||
	switch len(aaaa) {
 | 
					 | 
				
			||||||
	case net.IPv6len:
 | 
					 | 
				
			||||||
		if off+net.IPv6len > len(msg) {
 | 
					 | 
				
			||||||
			return len(msg), &Error{err: "overflow packing aaaa"}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		copy(msg[off:], aaaa)
 | 
					 | 
				
			||||||
		off += net.IPv6len
 | 
					 | 
				
			||||||
	case 0:
 | 
					 | 
				
			||||||
		// Allowed, dynamic updates.
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return len(msg), &Error{err: "overflow packing aaaa"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// unpackHeader unpacks an RR header, returning the offset to the end of the header and a
 | 
					 | 
				
			||||||
// re-sliced msg according to the expected length of the RR.
 | 
					 | 
				
			||||||
func unpackHeader(msg []byte, off int) (rr RR_Header, off1 int, truncmsg []byte, err error) {
 | 
					 | 
				
			||||||
	hdr := RR_Header{}
 | 
					 | 
				
			||||||
	if off == len(msg) {
 | 
					 | 
				
			||||||
		return hdr, off, msg, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	hdr.Name, off, err = UnpackDomainName(msg, off)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return hdr, len(msg), msg, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	hdr.Rrtype, off, err = unpackUint16(msg, off)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return hdr, len(msg), msg, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	hdr.Class, off, err = unpackUint16(msg, off)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return hdr, len(msg), msg, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	hdr.Ttl, off, err = unpackUint32(msg, off)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return hdr, len(msg), msg, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	hdr.Rdlength, off, err = unpackUint16(msg, off)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return hdr, len(msg), msg, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	msg, err = truncateMsgFromRdlength(msg, off, hdr.Rdlength)
 | 
					 | 
				
			||||||
	return hdr, off, msg, err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// packHeader packs an RR header, returning the offset to the end of the header.
 | 
					 | 
				
			||||||
// See PackDomainName for documentation about the compression.
 | 
					 | 
				
			||||||
func (hdr RR_Header) packHeader(msg []byte, off int, compression compressionMap, compress bool) (int, error) {
 | 
					 | 
				
			||||||
	if off == len(msg) {
 | 
					 | 
				
			||||||
		return off, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	off, err := packDomainName(hdr.Name, msg, off, compression, compress)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return len(msg), err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	off, err = packUint16(hdr.Rrtype, msg, off)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return len(msg), err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	off, err = packUint16(hdr.Class, msg, off)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return len(msg), err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	off, err = packUint32(hdr.Ttl, msg, off)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return len(msg), err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	off, err = packUint16(0, msg, off) // The RDLENGTH field will be set later in packRR.
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return len(msg), err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// helper helper functions.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// truncateMsgFromRdLength truncates msg to match the expected length of the RR.
 | 
					 | 
				
			||||||
// Returns an error if msg is smaller than the expected size.
 | 
					 | 
				
			||||||
func truncateMsgFromRdlength(msg []byte, off int, rdlength uint16) (truncmsg []byte, err error) {
 | 
					 | 
				
			||||||
	lenrd := off + int(rdlength)
 | 
					 | 
				
			||||||
	if lenrd > len(msg) {
 | 
					 | 
				
			||||||
		return msg, &Error{err: "overflowing header size"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return msg[:lenrd], nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var base32HexNoPadEncoding = base32.HexEncoding.WithPadding(base32.NoPadding)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func fromBase32(s []byte) (buf []byte, err error) {
 | 
					 | 
				
			||||||
	for i, b := range s {
 | 
					 | 
				
			||||||
		if b >= 'a' && b <= 'z' {
 | 
					 | 
				
			||||||
			s[i] = b - 32
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	buflen := base32HexNoPadEncoding.DecodedLen(len(s))
 | 
					 | 
				
			||||||
	buf = make([]byte, buflen)
 | 
					 | 
				
			||||||
	n, err := base32HexNoPadEncoding.Decode(buf, s)
 | 
					 | 
				
			||||||
	buf = buf[:n]
 | 
					 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func toBase32(b []byte) string {
 | 
					 | 
				
			||||||
	return base32HexNoPadEncoding.EncodeToString(b)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func fromBase64(s []byte) (buf []byte, err error) {
 | 
					 | 
				
			||||||
	buflen := base64.StdEncoding.DecodedLen(len(s))
 | 
					 | 
				
			||||||
	buf = make([]byte, buflen)
 | 
					 | 
				
			||||||
	n, err := base64.StdEncoding.Decode(buf, s)
 | 
					 | 
				
			||||||
	buf = buf[:n]
 | 
					 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func toBase64(b []byte) string { return base64.StdEncoding.EncodeToString(b) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// dynamicUpdate returns true if the Rdlength is zero.
 | 
					 | 
				
			||||||
func noRdata(h RR_Header) bool { return h.Rdlength == 0 }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func unpackUint8(msg []byte, off int) (i uint8, off1 int, err error) {
 | 
					 | 
				
			||||||
	if off+1 > len(msg) {
 | 
					 | 
				
			||||||
		return 0, len(msg), &Error{err: "overflow unpacking uint8"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return msg[off], off + 1, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func packUint8(i uint8, msg []byte, off int) (off1 int, err error) {
 | 
					 | 
				
			||||||
	if off+1 > len(msg) {
 | 
					 | 
				
			||||||
		return len(msg), &Error{err: "overflow packing uint8"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	msg[off] = i
 | 
					 | 
				
			||||||
	return off + 1, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func unpackUint16(msg []byte, off int) (i uint16, off1 int, err error) {
 | 
					 | 
				
			||||||
	if off+2 > len(msg) {
 | 
					 | 
				
			||||||
		return 0, len(msg), &Error{err: "overflow unpacking uint16"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return binary.BigEndian.Uint16(msg[off:]), off + 2, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func packUint16(i uint16, msg []byte, off int) (off1 int, err error) {
 | 
					 | 
				
			||||||
	if off+2 > len(msg) {
 | 
					 | 
				
			||||||
		return len(msg), &Error{err: "overflow packing uint16"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	binary.BigEndian.PutUint16(msg[off:], i)
 | 
					 | 
				
			||||||
	return off + 2, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func unpackUint32(msg []byte, off int) (i uint32, off1 int, err error) {
 | 
					 | 
				
			||||||
	if off+4 > len(msg) {
 | 
					 | 
				
			||||||
		return 0, len(msg), &Error{err: "overflow unpacking uint32"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return binary.BigEndian.Uint32(msg[off:]), off + 4, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func packUint32(i uint32, msg []byte, off int) (off1 int, err error) {
 | 
					 | 
				
			||||||
	if off+4 > len(msg) {
 | 
					 | 
				
			||||||
		return len(msg), &Error{err: "overflow packing uint32"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	binary.BigEndian.PutUint32(msg[off:], i)
 | 
					 | 
				
			||||||
	return off + 4, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func unpackUint48(msg []byte, off int) (i uint64, off1 int, err error) {
 | 
					 | 
				
			||||||
	if off+6 > len(msg) {
 | 
					 | 
				
			||||||
		return 0, len(msg), &Error{err: "overflow unpacking uint64 as uint48"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// Used in TSIG where the last 48 bits are occupied, so for now, assume a uint48 (6 bytes)
 | 
					 | 
				
			||||||
	i = uint64(msg[off])<<40 | uint64(msg[off+1])<<32 | uint64(msg[off+2])<<24 | uint64(msg[off+3])<<16 |
 | 
					 | 
				
			||||||
		uint64(msg[off+4])<<8 | uint64(msg[off+5])
 | 
					 | 
				
			||||||
	off += 6
 | 
					 | 
				
			||||||
	return i, off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func packUint48(i uint64, msg []byte, off int) (off1 int, err error) {
 | 
					 | 
				
			||||||
	if off+6 > len(msg) {
 | 
					 | 
				
			||||||
		return len(msg), &Error{err: "overflow packing uint64 as uint48"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	msg[off] = byte(i >> 40)
 | 
					 | 
				
			||||||
	msg[off+1] = byte(i >> 32)
 | 
					 | 
				
			||||||
	msg[off+2] = byte(i >> 24)
 | 
					 | 
				
			||||||
	msg[off+3] = byte(i >> 16)
 | 
					 | 
				
			||||||
	msg[off+4] = byte(i >> 8)
 | 
					 | 
				
			||||||
	msg[off+5] = byte(i)
 | 
					 | 
				
			||||||
	off += 6
 | 
					 | 
				
			||||||
	return off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func unpackUint64(msg []byte, off int) (i uint64, off1 int, err error) {
 | 
					 | 
				
			||||||
	if off+8 > len(msg) {
 | 
					 | 
				
			||||||
		return 0, len(msg), &Error{err: "overflow unpacking uint64"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return binary.BigEndian.Uint64(msg[off:]), off + 8, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func packUint64(i uint64, msg []byte, off int) (off1 int, err error) {
 | 
					 | 
				
			||||||
	if off+8 > len(msg) {
 | 
					 | 
				
			||||||
		return len(msg), &Error{err: "overflow packing uint64"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	binary.BigEndian.PutUint64(msg[off:], i)
 | 
					 | 
				
			||||||
	off += 8
 | 
					 | 
				
			||||||
	return off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func unpackString(msg []byte, off int) (string, int, error) {
 | 
					 | 
				
			||||||
	if off+1 > len(msg) {
 | 
					 | 
				
			||||||
		return "", off, &Error{err: "overflow unpacking txt"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	l := int(msg[off])
 | 
					 | 
				
			||||||
	off++
 | 
					 | 
				
			||||||
	if off+l > len(msg) {
 | 
					 | 
				
			||||||
		return "", off, &Error{err: "overflow unpacking txt"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	var s strings.Builder
 | 
					 | 
				
			||||||
	consumed := 0
 | 
					 | 
				
			||||||
	for i, b := range msg[off : off+l] {
 | 
					 | 
				
			||||||
		switch {
 | 
					 | 
				
			||||||
		case b == '"' || b == '\\':
 | 
					 | 
				
			||||||
			if consumed == 0 {
 | 
					 | 
				
			||||||
				s.Grow(l * 2)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			s.Write(msg[off+consumed : off+i])
 | 
					 | 
				
			||||||
			s.WriteByte('\\')
 | 
					 | 
				
			||||||
			s.WriteByte(b)
 | 
					 | 
				
			||||||
			consumed = i + 1
 | 
					 | 
				
			||||||
		case b < ' ' || b > '~': // unprintable
 | 
					 | 
				
			||||||
			if consumed == 0 {
 | 
					 | 
				
			||||||
				s.Grow(l * 2)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			s.Write(msg[off+consumed : off+i])
 | 
					 | 
				
			||||||
			s.WriteString(escapeByte(b))
 | 
					 | 
				
			||||||
			consumed = i + 1
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if consumed == 0 { // no escaping needed
 | 
					 | 
				
			||||||
		return string(msg[off : off+l]), off + l, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	s.Write(msg[off+consumed : off+l])
 | 
					 | 
				
			||||||
	return s.String(), off + l, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func packString(s string, msg []byte, off int) (int, error) {
 | 
					 | 
				
			||||||
	txtTmp := make([]byte, 256*4+1)
 | 
					 | 
				
			||||||
	off, err := packTxtString(s, msg, off, txtTmp)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return len(msg), err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func unpackStringBase32(msg []byte, off, end int) (string, int, error) {
 | 
					 | 
				
			||||||
	if end > len(msg) {
 | 
					 | 
				
			||||||
		return "", len(msg), &Error{err: "overflow unpacking base32"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	s := toBase32(msg[off:end])
 | 
					 | 
				
			||||||
	return s, end, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func packStringBase32(s string, msg []byte, off int) (int, error) {
 | 
					 | 
				
			||||||
	b32, err := fromBase32([]byte(s))
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return len(msg), err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if off+len(b32) > len(msg) {
 | 
					 | 
				
			||||||
		return len(msg), &Error{err: "overflow packing base32"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	copy(msg[off:off+len(b32)], b32)
 | 
					 | 
				
			||||||
	off += len(b32)
 | 
					 | 
				
			||||||
	return off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func unpackStringBase64(msg []byte, off, end int) (string, int, error) {
 | 
					 | 
				
			||||||
	// Rest of the RR is base64 encoded value, so we don't need an explicit length
 | 
					 | 
				
			||||||
	// to be set. Thus far all RR's that have base64 encoded fields have those as their
 | 
					 | 
				
			||||||
	// last one. What we do need is the end of the RR!
 | 
					 | 
				
			||||||
	if end > len(msg) {
 | 
					 | 
				
			||||||
		return "", len(msg), &Error{err: "overflow unpacking base64"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	s := toBase64(msg[off:end])
 | 
					 | 
				
			||||||
	return s, end, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func packStringBase64(s string, msg []byte, off int) (int, error) {
 | 
					 | 
				
			||||||
	b64, err := fromBase64([]byte(s))
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return len(msg), err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if off+len(b64) > len(msg) {
 | 
					 | 
				
			||||||
		return len(msg), &Error{err: "overflow packing base64"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	copy(msg[off:off+len(b64)], b64)
 | 
					 | 
				
			||||||
	off += len(b64)
 | 
					 | 
				
			||||||
	return off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func unpackStringHex(msg []byte, off, end int) (string, int, error) {
 | 
					 | 
				
			||||||
	// Rest of the RR is hex encoded value, so we don't need an explicit length
 | 
					 | 
				
			||||||
	// to be set. NSEC and TSIG have hex fields with a length field.
 | 
					 | 
				
			||||||
	// What we do need is the end of the RR!
 | 
					 | 
				
			||||||
	if end > len(msg) {
 | 
					 | 
				
			||||||
		return "", len(msg), &Error{err: "overflow unpacking hex"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	s := hex.EncodeToString(msg[off:end])
 | 
					 | 
				
			||||||
	return s, end, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func packStringHex(s string, msg []byte, off int) (int, error) {
 | 
					 | 
				
			||||||
	h, err := hex.DecodeString(s)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return len(msg), err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if off+len(h) > len(msg) {
 | 
					 | 
				
			||||||
		return len(msg), &Error{err: "overflow packing hex"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	copy(msg[off:off+len(h)], h)
 | 
					 | 
				
			||||||
	off += len(h)
 | 
					 | 
				
			||||||
	return off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func unpackStringAny(msg []byte, off, end int) (string, int, error) {
 | 
					 | 
				
			||||||
	if end > len(msg) {
 | 
					 | 
				
			||||||
		return "", len(msg), &Error{err: "overflow unpacking anything"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return string(msg[off:end]), end, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func packStringAny(s string, msg []byte, off int) (int, error) {
 | 
					 | 
				
			||||||
	if off+len(s) > len(msg) {
 | 
					 | 
				
			||||||
		return len(msg), &Error{err: "overflow packing anything"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	copy(msg[off:off+len(s)], s)
 | 
					 | 
				
			||||||
	off += len(s)
 | 
					 | 
				
			||||||
	return off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func unpackStringTxt(msg []byte, off int) ([]string, int, error) {
 | 
					 | 
				
			||||||
	txt, off, err := unpackTxt(msg, off)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, len(msg), err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return txt, off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func packStringTxt(s []string, msg []byte, off int) (int, error) {
 | 
					 | 
				
			||||||
	txtTmp := make([]byte, 256*4+1) // If the whole string consists out of \DDD we need this many.
 | 
					 | 
				
			||||||
	off, err := packTxt(s, msg, off, txtTmp)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return len(msg), err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func unpackDataOpt(msg []byte, off int) ([]EDNS0, int, error) {
 | 
					 | 
				
			||||||
	var edns []EDNS0
 | 
					 | 
				
			||||||
Option:
 | 
					 | 
				
			||||||
	var code uint16
 | 
					 | 
				
			||||||
	if off+4 > len(msg) {
 | 
					 | 
				
			||||||
		return nil, len(msg), &Error{err: "overflow unpacking opt"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	code = binary.BigEndian.Uint16(msg[off:])
 | 
					 | 
				
			||||||
	off += 2
 | 
					 | 
				
			||||||
	optlen := binary.BigEndian.Uint16(msg[off:])
 | 
					 | 
				
			||||||
	off += 2
 | 
					 | 
				
			||||||
	if off+int(optlen) > len(msg) {
 | 
					 | 
				
			||||||
		return nil, len(msg), &Error{err: "overflow unpacking opt"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	e := makeDataOpt(code)
 | 
					 | 
				
			||||||
	if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
 | 
					 | 
				
			||||||
		return nil, len(msg), err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	edns = append(edns, e)
 | 
					 | 
				
			||||||
	off += int(optlen)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if off < len(msg) {
 | 
					 | 
				
			||||||
		goto Option
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return edns, off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func makeDataOpt(code uint16) EDNS0 {
 | 
					 | 
				
			||||||
	switch code {
 | 
					 | 
				
			||||||
	case EDNS0NSID:
 | 
					 | 
				
			||||||
		return new(EDNS0_NSID)
 | 
					 | 
				
			||||||
	case EDNS0SUBNET:
 | 
					 | 
				
			||||||
		return new(EDNS0_SUBNET)
 | 
					 | 
				
			||||||
	case EDNS0COOKIE:
 | 
					 | 
				
			||||||
		return new(EDNS0_COOKIE)
 | 
					 | 
				
			||||||
	case EDNS0EXPIRE:
 | 
					 | 
				
			||||||
		return new(EDNS0_EXPIRE)
 | 
					 | 
				
			||||||
	case EDNS0UL:
 | 
					 | 
				
			||||||
		return new(EDNS0_UL)
 | 
					 | 
				
			||||||
	case EDNS0LLQ:
 | 
					 | 
				
			||||||
		return new(EDNS0_LLQ)
 | 
					 | 
				
			||||||
	case EDNS0DAU:
 | 
					 | 
				
			||||||
		return new(EDNS0_DAU)
 | 
					 | 
				
			||||||
	case EDNS0DHU:
 | 
					 | 
				
			||||||
		return new(EDNS0_DHU)
 | 
					 | 
				
			||||||
	case EDNS0N3U:
 | 
					 | 
				
			||||||
		return new(EDNS0_N3U)
 | 
					 | 
				
			||||||
	case EDNS0PADDING:
 | 
					 | 
				
			||||||
		return new(EDNS0_PADDING)
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		e := new(EDNS0_LOCAL)
 | 
					 | 
				
			||||||
		e.Code = code
 | 
					 | 
				
			||||||
		return e
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func packDataOpt(options []EDNS0, msg []byte, off int) (int, error) {
 | 
					 | 
				
			||||||
	for _, el := range options {
 | 
					 | 
				
			||||||
		b, err := el.pack()
 | 
					 | 
				
			||||||
		if err != nil || off+4 > len(msg) {
 | 
					 | 
				
			||||||
			return len(msg), &Error{err: "overflow packing opt"}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		binary.BigEndian.PutUint16(msg[off:], el.Option())      // Option code
 | 
					 | 
				
			||||||
		binary.BigEndian.PutUint16(msg[off+2:], uint16(len(b))) // Length
 | 
					 | 
				
			||||||
		off += 4
 | 
					 | 
				
			||||||
		if off+len(b) > len(msg) {
 | 
					 | 
				
			||||||
			return len(msg), &Error{err: "overflow packing opt"}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		// Actual data
 | 
					 | 
				
			||||||
		copy(msg[off:off+len(b)], b)
 | 
					 | 
				
			||||||
		off += len(b)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func unpackStringOctet(msg []byte, off int) (string, int, error) {
 | 
					 | 
				
			||||||
	s := string(msg[off:])
 | 
					 | 
				
			||||||
	return s, len(msg), nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func packStringOctet(s string, msg []byte, off int) (int, error) {
 | 
					 | 
				
			||||||
	txtTmp := make([]byte, 256*4+1)
 | 
					 | 
				
			||||||
	off, err := packOctetString(s, msg, off, txtTmp)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return len(msg), err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func unpackDataNsec(msg []byte, off int) ([]uint16, int, error) {
 | 
					 | 
				
			||||||
	var nsec []uint16
 | 
					 | 
				
			||||||
	length, window, lastwindow := 0, 0, -1
 | 
					 | 
				
			||||||
	for off < len(msg) {
 | 
					 | 
				
			||||||
		if off+2 > len(msg) {
 | 
					 | 
				
			||||||
			return nsec, len(msg), &Error{err: "overflow unpacking nsecx"}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		window = int(msg[off])
 | 
					 | 
				
			||||||
		length = int(msg[off+1])
 | 
					 | 
				
			||||||
		off += 2
 | 
					 | 
				
			||||||
		if window <= lastwindow {
 | 
					 | 
				
			||||||
			// RFC 4034: Blocks are present in the NSEC RR RDATA in
 | 
					 | 
				
			||||||
			// increasing numerical order.
 | 
					 | 
				
			||||||
			return nsec, len(msg), &Error{err: "out of order NSEC block"}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if length == 0 {
 | 
					 | 
				
			||||||
			// RFC 4034: Blocks with no types present MUST NOT be included.
 | 
					 | 
				
			||||||
			return nsec, len(msg), &Error{err: "empty NSEC block"}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if length > 32 {
 | 
					 | 
				
			||||||
			return nsec, len(msg), &Error{err: "NSEC block too long"}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if off+length > len(msg) {
 | 
					 | 
				
			||||||
			return nsec, len(msg), &Error{err: "overflowing NSEC block"}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Walk the bytes in the window and extract the type bits
 | 
					 | 
				
			||||||
		for j, b := range msg[off : off+length] {
 | 
					 | 
				
			||||||
			// Check the bits one by one, and set the type
 | 
					 | 
				
			||||||
			if b&0x80 == 0x80 {
 | 
					 | 
				
			||||||
				nsec = append(nsec, uint16(window*256+j*8+0))
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if b&0x40 == 0x40 {
 | 
					 | 
				
			||||||
				nsec = append(nsec, uint16(window*256+j*8+1))
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if b&0x20 == 0x20 {
 | 
					 | 
				
			||||||
				nsec = append(nsec, uint16(window*256+j*8+2))
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if b&0x10 == 0x10 {
 | 
					 | 
				
			||||||
				nsec = append(nsec, uint16(window*256+j*8+3))
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if b&0x8 == 0x8 {
 | 
					 | 
				
			||||||
				nsec = append(nsec, uint16(window*256+j*8+4))
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if b&0x4 == 0x4 {
 | 
					 | 
				
			||||||
				nsec = append(nsec, uint16(window*256+j*8+5))
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if b&0x2 == 0x2 {
 | 
					 | 
				
			||||||
				nsec = append(nsec, uint16(window*256+j*8+6))
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if b&0x1 == 0x1 {
 | 
					 | 
				
			||||||
				nsec = append(nsec, uint16(window*256+j*8+7))
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		off += length
 | 
					 | 
				
			||||||
		lastwindow = window
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nsec, off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// typeBitMapLen is a helper function which computes the "maximum" length of
 | 
					 | 
				
			||||||
// a the NSEC Type BitMap field.
 | 
					 | 
				
			||||||
func typeBitMapLen(bitmap []uint16) int {
 | 
					 | 
				
			||||||
	var l int
 | 
					 | 
				
			||||||
	var lastwindow, lastlength uint16
 | 
					 | 
				
			||||||
	for _, t := range bitmap {
 | 
					 | 
				
			||||||
		window := t / 256
 | 
					 | 
				
			||||||
		length := (t-window*256)/8 + 1
 | 
					 | 
				
			||||||
		if window > lastwindow && lastlength != 0 { // New window, jump to the new offset
 | 
					 | 
				
			||||||
			l += int(lastlength) + 2
 | 
					 | 
				
			||||||
			lastlength = 0
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if window < lastwindow || length < lastlength {
 | 
					 | 
				
			||||||
			// packDataNsec would return Error{err: "nsec bits out of order"} here, but
 | 
					 | 
				
			||||||
			// when computing the length, we want do be liberal.
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		lastwindow, lastlength = window, length
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	l += int(lastlength) + 2
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func packDataNsec(bitmap []uint16, msg []byte, off int) (int, error) {
 | 
					 | 
				
			||||||
	if len(bitmap) == 0 {
 | 
					 | 
				
			||||||
		return off, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	var lastwindow, lastlength uint16
 | 
					 | 
				
			||||||
	for _, t := range bitmap {
 | 
					 | 
				
			||||||
		window := t / 256
 | 
					 | 
				
			||||||
		length := (t-window*256)/8 + 1
 | 
					 | 
				
			||||||
		if window > lastwindow && lastlength != 0 { // New window, jump to the new offset
 | 
					 | 
				
			||||||
			off += int(lastlength) + 2
 | 
					 | 
				
			||||||
			lastlength = 0
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if window < lastwindow || length < lastlength {
 | 
					 | 
				
			||||||
			return len(msg), &Error{err: "nsec bits out of order"}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if off+2+int(length) > len(msg) {
 | 
					 | 
				
			||||||
			return len(msg), &Error{err: "overflow packing nsec"}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		// Setting the window #
 | 
					 | 
				
			||||||
		msg[off] = byte(window)
 | 
					 | 
				
			||||||
		// Setting the octets length
 | 
					 | 
				
			||||||
		msg[off+1] = byte(length)
 | 
					 | 
				
			||||||
		// Setting the bit value for the type in the right octet
 | 
					 | 
				
			||||||
		msg[off+1+int(length)] |= byte(1 << (7 - t%8))
 | 
					 | 
				
			||||||
		lastwindow, lastlength = window, length
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	off += int(lastlength) + 2
 | 
					 | 
				
			||||||
	return off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func unpackDataSVCB(msg []byte, off int) ([]SVCBKeyValue, int, error) {
 | 
					 | 
				
			||||||
	var xs []SVCBKeyValue
 | 
					 | 
				
			||||||
	var code uint16
 | 
					 | 
				
			||||||
	var length uint16
 | 
					 | 
				
			||||||
	var err error
 | 
					 | 
				
			||||||
	for off < len(msg) {
 | 
					 | 
				
			||||||
		code, off, err = unpackUint16(msg, off)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, len(msg), &Error{err: "overflow unpacking SVCB"}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		length, off, err = unpackUint16(msg, off)
 | 
					 | 
				
			||||||
		if err != nil || off+int(length) > len(msg) {
 | 
					 | 
				
			||||||
			return nil, len(msg), &Error{err: "overflow unpacking SVCB"}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		e := makeSVCBKeyValue(SVCBKey(code))
 | 
					 | 
				
			||||||
		if e == nil {
 | 
					 | 
				
			||||||
			return nil, len(msg), &Error{err: "bad SVCB key"}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if err := e.unpack(msg[off : off+int(length)]); err != nil {
 | 
					 | 
				
			||||||
			return nil, len(msg), err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if len(xs) > 0 && e.Key() <= xs[len(xs)-1].Key() {
 | 
					 | 
				
			||||||
			return nil, len(msg), &Error{err: "SVCB keys not in strictly increasing order"}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		xs = append(xs, e)
 | 
					 | 
				
			||||||
		off += int(length)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return xs, off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func packDataSVCB(pairs []SVCBKeyValue, msg []byte, off int) (int, error) {
 | 
					 | 
				
			||||||
	pairs = append([]SVCBKeyValue(nil), pairs...)
 | 
					 | 
				
			||||||
	sort.Slice(pairs, func(i, j int) bool {
 | 
					 | 
				
			||||||
		return pairs[i].Key() < pairs[j].Key()
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
	prev := svcb_RESERVED
 | 
					 | 
				
			||||||
	for _, el := range pairs {
 | 
					 | 
				
			||||||
		if el.Key() == prev {
 | 
					 | 
				
			||||||
			return len(msg), &Error{err: "repeated SVCB keys are not allowed"}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		prev = el.Key()
 | 
					 | 
				
			||||||
		packed, err := el.pack()
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return len(msg), err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		off, err = packUint16(uint16(el.Key()), msg, off)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return len(msg), &Error{err: "overflow packing SVCB"}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		off, err = packUint16(uint16(len(packed)), msg, off)
 | 
					 | 
				
			||||||
		if err != nil || off+len(packed) > len(msg) {
 | 
					 | 
				
			||||||
			return len(msg), &Error{err: "overflow packing SVCB"}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		copy(msg[off:off+len(packed)], packed)
 | 
					 | 
				
			||||||
		off += len(packed)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func unpackDataDomainNames(msg []byte, off, end int) ([]string, int, error) {
 | 
					 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		servers []string
 | 
					 | 
				
			||||||
		s       string
 | 
					 | 
				
			||||||
		err     error
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	if end > len(msg) {
 | 
					 | 
				
			||||||
		return nil, len(msg), &Error{err: "overflow unpacking domain names"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for off < end {
 | 
					 | 
				
			||||||
		s, off, err = UnpackDomainName(msg, off)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return servers, len(msg), err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		servers = append(servers, s)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return servers, off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func packDataDomainNames(names []string, msg []byte, off int, compression compressionMap, compress bool) (int, error) {
 | 
					 | 
				
			||||||
	var err error
 | 
					 | 
				
			||||||
	for _, name := range names {
 | 
					 | 
				
			||||||
		off, err = packDomainName(name, msg, off, compression, compress)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return len(msg), err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func packDataApl(data []APLPrefix, msg []byte, off int) (int, error) {
 | 
					 | 
				
			||||||
	var err error
 | 
					 | 
				
			||||||
	for i := range data {
 | 
					 | 
				
			||||||
		off, err = packDataAplPrefix(&data[i], msg, off)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return len(msg), err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func packDataAplPrefix(p *APLPrefix, msg []byte, off int) (int, error) {
 | 
					 | 
				
			||||||
	if len(p.Network.IP) != len(p.Network.Mask) {
 | 
					 | 
				
			||||||
		return len(msg), &Error{err: "address and mask lengths don't match"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var err error
 | 
					 | 
				
			||||||
	prefix, _ := p.Network.Mask.Size()
 | 
					 | 
				
			||||||
	addr := p.Network.IP.Mask(p.Network.Mask)[:(prefix+7)/8]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch len(p.Network.IP) {
 | 
					 | 
				
			||||||
	case net.IPv4len:
 | 
					 | 
				
			||||||
		off, err = packUint16(1, msg, off)
 | 
					 | 
				
			||||||
	case net.IPv6len:
 | 
					 | 
				
			||||||
		off, err = packUint16(2, msg, off)
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		err = &Error{err: "unrecognized address family"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return len(msg), err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	off, err = packUint8(uint8(prefix), msg, off)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return len(msg), err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var n uint8
 | 
					 | 
				
			||||||
	if p.Negation {
 | 
					 | 
				
			||||||
		n = 0x80
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// trim trailing zero bytes as specified in RFC3123 Sections 4.1 and 4.2.
 | 
					 | 
				
			||||||
	i := len(addr) - 1
 | 
					 | 
				
			||||||
	for ; i >= 0 && addr[i] == 0; i-- {
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	addr = addr[:i+1]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	adflen := uint8(len(addr)) & 0x7f
 | 
					 | 
				
			||||||
	off, err = packUint8(n|adflen, msg, off)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return len(msg), err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if off+len(addr) > len(msg) {
 | 
					 | 
				
			||||||
		return len(msg), &Error{err: "overflow packing APL prefix"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	off += copy(msg[off:], addr)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func unpackDataApl(msg []byte, off int) ([]APLPrefix, int, error) {
 | 
					 | 
				
			||||||
	var result []APLPrefix
 | 
					 | 
				
			||||||
	for off < len(msg) {
 | 
					 | 
				
			||||||
		prefix, end, err := unpackDataAplPrefix(msg, off)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, len(msg), err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		off = end
 | 
					 | 
				
			||||||
		result = append(result, prefix)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return result, off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func unpackDataAplPrefix(msg []byte, off int) (APLPrefix, int, error) {
 | 
					 | 
				
			||||||
	family, off, err := unpackUint16(msg, off)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return APLPrefix{}, len(msg), &Error{err: "overflow unpacking APL prefix"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	prefix, off, err := unpackUint8(msg, off)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return APLPrefix{}, len(msg), &Error{err: "overflow unpacking APL prefix"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	nlen, off, err := unpackUint8(msg, off)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return APLPrefix{}, len(msg), &Error{err: "overflow unpacking APL prefix"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var ip []byte
 | 
					 | 
				
			||||||
	switch family {
 | 
					 | 
				
			||||||
	case 1:
 | 
					 | 
				
			||||||
		ip = make([]byte, net.IPv4len)
 | 
					 | 
				
			||||||
	case 2:
 | 
					 | 
				
			||||||
		ip = make([]byte, net.IPv6len)
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return APLPrefix{}, len(msg), &Error{err: "unrecognized APL address family"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if int(prefix) > 8*len(ip) {
 | 
					 | 
				
			||||||
		return APLPrefix{}, len(msg), &Error{err: "APL prefix too long"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	afdlen := int(nlen & 0x7f)
 | 
					 | 
				
			||||||
	if afdlen > len(ip) {
 | 
					 | 
				
			||||||
		return APLPrefix{}, len(msg), &Error{err: "APL length too long"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if off+afdlen > len(msg) {
 | 
					 | 
				
			||||||
		return APLPrefix{}, len(msg), &Error{err: "overflow unpacking APL address"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	off += copy(ip, msg[off:off+afdlen])
 | 
					 | 
				
			||||||
	if afdlen > 0 {
 | 
					 | 
				
			||||||
		last := ip[afdlen-1]
 | 
					 | 
				
			||||||
		if last == 0 {
 | 
					 | 
				
			||||||
			return APLPrefix{}, len(msg), &Error{err: "extra APL address bits"}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	ipnet := net.IPNet{
 | 
					 | 
				
			||||||
		IP:   ip,
 | 
					 | 
				
			||||||
		Mask: net.CIDRMask(int(prefix), 8*len(ip)),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	network := ipnet.IP.Mask(ipnet.Mask)
 | 
					 | 
				
			||||||
	if !network.Equal(ipnet.IP) {
 | 
					 | 
				
			||||||
		return APLPrefix{}, len(msg), &Error{err: "invalid APL address length"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return APLPrefix{
 | 
					 | 
				
			||||||
		Negation: (nlen & 0x80) != 0,
 | 
					 | 
				
			||||||
		Network:  ipnet,
 | 
					 | 
				
			||||||
	}, off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										112
									
								
								vendor/github.com/miekg/dns/msg_truncate.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										112
									
								
								vendor/github.com/miekg/dns/msg_truncate.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,112 +0,0 @@
 | 
				
			|||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Truncate ensures the reply message will fit into the requested buffer
 | 
					 | 
				
			||||||
// size by removing records that exceed the requested size.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// It will first check if the reply fits without compression and then with
 | 
					 | 
				
			||||||
// compression. If it won't fit with compression, Truncate then walks the
 | 
					 | 
				
			||||||
// record adding as many records as possible without exceeding the
 | 
					 | 
				
			||||||
// requested buffer size.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// The TC bit will be set if any records were excluded from the message.
 | 
					 | 
				
			||||||
// If the TC bit is already set on the message it will be retained.
 | 
					 | 
				
			||||||
// TC indicates that the client should retry over TCP.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// According to RFC 2181, the TC bit should only be set if not all of the
 | 
					 | 
				
			||||||
// "required" RRs can be included in the response. Unfortunately, we have
 | 
					 | 
				
			||||||
// no way of knowing which RRs are required so we set the TC bit if any RR
 | 
					 | 
				
			||||||
// had to be omitted from the response.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// The appropriate buffer size can be retrieved from the requests OPT
 | 
					 | 
				
			||||||
// record, if present, and is transport specific otherwise. dns.MinMsgSize
 | 
					 | 
				
			||||||
// should be used for UDP requests without an OPT record, and
 | 
					 | 
				
			||||||
// dns.MaxMsgSize for TCP requests without an OPT record.
 | 
					 | 
				
			||||||
func (dns *Msg) Truncate(size int) {
 | 
					 | 
				
			||||||
	if dns.IsTsig() != nil {
 | 
					 | 
				
			||||||
		// To simplify this implementation, we don't perform
 | 
					 | 
				
			||||||
		// truncation on responses with a TSIG record.
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// RFC 6891 mandates that the payload size in an OPT record
 | 
					 | 
				
			||||||
	// less than 512 (MinMsgSize) bytes must be treated as equal to 512 bytes.
 | 
					 | 
				
			||||||
	//
 | 
					 | 
				
			||||||
	// For ease of use, we impose that restriction here.
 | 
					 | 
				
			||||||
	if size < MinMsgSize {
 | 
					 | 
				
			||||||
		size = MinMsgSize
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	l := msgLenWithCompressionMap(dns, nil) // uncompressed length
 | 
					 | 
				
			||||||
	if l <= size {
 | 
					 | 
				
			||||||
		// Don't waste effort compressing this message.
 | 
					 | 
				
			||||||
		dns.Compress = false
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dns.Compress = true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	edns0 := dns.popEdns0()
 | 
					 | 
				
			||||||
	if edns0 != nil {
 | 
					 | 
				
			||||||
		// Account for the OPT record that gets added at the end,
 | 
					 | 
				
			||||||
		// by subtracting that length from our budget.
 | 
					 | 
				
			||||||
		//
 | 
					 | 
				
			||||||
		// The EDNS(0) OPT record must have the root domain and
 | 
					 | 
				
			||||||
		// it's length is thus unaffected by compression.
 | 
					 | 
				
			||||||
		size -= Len(edns0)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	compression := make(map[string]struct{})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	l = headerSize
 | 
					 | 
				
			||||||
	for _, r := range dns.Question {
 | 
					 | 
				
			||||||
		l += r.len(l, compression)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var numAnswer int
 | 
					 | 
				
			||||||
	if l < size {
 | 
					 | 
				
			||||||
		l, numAnswer = truncateLoop(dns.Answer, size, l, compression)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var numNS int
 | 
					 | 
				
			||||||
	if l < size {
 | 
					 | 
				
			||||||
		l, numNS = truncateLoop(dns.Ns, size, l, compression)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var numExtra int
 | 
					 | 
				
			||||||
	if l < size {
 | 
					 | 
				
			||||||
		_, numExtra = truncateLoop(dns.Extra, size, l, compression)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// See the function documentation for when we set this.
 | 
					 | 
				
			||||||
	dns.Truncated = dns.Truncated || len(dns.Answer) > numAnswer ||
 | 
					 | 
				
			||||||
		len(dns.Ns) > numNS || len(dns.Extra) > numExtra
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dns.Answer = dns.Answer[:numAnswer]
 | 
					 | 
				
			||||||
	dns.Ns = dns.Ns[:numNS]
 | 
					 | 
				
			||||||
	dns.Extra = dns.Extra[:numExtra]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if edns0 != nil {
 | 
					 | 
				
			||||||
		// Add the OPT record back onto the additional section.
 | 
					 | 
				
			||||||
		dns.Extra = append(dns.Extra, edns0)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func truncateLoop(rrs []RR, size, l int, compression map[string]struct{}) (int, int) {
 | 
					 | 
				
			||||||
	for i, r := range rrs {
 | 
					 | 
				
			||||||
		if r == nil {
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		l += r.len(l, compression)
 | 
					 | 
				
			||||||
		if l > size {
 | 
					 | 
				
			||||||
			// Return size, rather than l prior to this record,
 | 
					 | 
				
			||||||
			// to prevent any further records being added.
 | 
					 | 
				
			||||||
			return size, i
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if l == size {
 | 
					 | 
				
			||||||
			return l, i + 1
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return l, len(rrs)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										95
									
								
								vendor/github.com/miekg/dns/nsecx.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										95
									
								
								vendor/github.com/miekg/dns/nsecx.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,95 +0,0 @@
 | 
				
			|||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"crypto/sha1"
 | 
					 | 
				
			||||||
	"encoding/hex"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// HashName hashes a string (label) according to RFC 5155. It returns the hashed string in uppercase.
 | 
					 | 
				
			||||||
func HashName(label string, ha uint8, iter uint16, salt string) string {
 | 
					 | 
				
			||||||
	if ha != SHA1 {
 | 
					 | 
				
			||||||
		return ""
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	wireSalt := make([]byte, hex.DecodedLen(len(salt)))
 | 
					 | 
				
			||||||
	n, err := packStringHex(salt, wireSalt, 0)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return ""
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	wireSalt = wireSalt[:n]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	name := make([]byte, 255)
 | 
					 | 
				
			||||||
	off, err := PackDomainName(strings.ToLower(label), name, 0, nil, false)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return ""
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	name = name[:off]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	s := sha1.New()
 | 
					 | 
				
			||||||
	// k = 0
 | 
					 | 
				
			||||||
	s.Write(name)
 | 
					 | 
				
			||||||
	s.Write(wireSalt)
 | 
					 | 
				
			||||||
	nsec3 := s.Sum(nil)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// k > 0
 | 
					 | 
				
			||||||
	for k := uint16(0); k < iter; k++ {
 | 
					 | 
				
			||||||
		s.Reset()
 | 
					 | 
				
			||||||
		s.Write(nsec3)
 | 
					 | 
				
			||||||
		s.Write(wireSalt)
 | 
					 | 
				
			||||||
		nsec3 = s.Sum(nsec3[:0])
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return toBase32(nsec3)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Cover returns true if a name is covered by the NSEC3 record.
 | 
					 | 
				
			||||||
func (rr *NSEC3) Cover(name string) bool {
 | 
					 | 
				
			||||||
	nameHash := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
 | 
					 | 
				
			||||||
	owner := strings.ToUpper(rr.Hdr.Name)
 | 
					 | 
				
			||||||
	labelIndices := Split(owner)
 | 
					 | 
				
			||||||
	if len(labelIndices) < 2 {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	ownerHash := owner[:labelIndices[1]-1]
 | 
					 | 
				
			||||||
	ownerZone := owner[labelIndices[1]:]
 | 
					 | 
				
			||||||
	if !IsSubDomain(ownerZone, strings.ToUpper(name)) { // name is outside owner zone
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	nextHash := rr.NextDomain
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// if empty interval found, try cover wildcard hashes so nameHash shouldn't match with ownerHash
 | 
					 | 
				
			||||||
	if ownerHash == nextHash && nameHash != ownerHash { // empty interval
 | 
					 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if ownerHash > nextHash { // end of zone
 | 
					 | 
				
			||||||
		if nameHash > ownerHash { // covered since there is nothing after ownerHash
 | 
					 | 
				
			||||||
			return true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return nameHash < nextHash // if nameHash is before beginning of zone it is covered
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if nameHash < ownerHash { // nameHash is before ownerHash, not covered
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nameHash < nextHash // if nameHash is before nextHash is it covered (between ownerHash and nextHash)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Match returns true if a name matches the NSEC3 record
 | 
					 | 
				
			||||||
func (rr *NSEC3) Match(name string) bool {
 | 
					 | 
				
			||||||
	nameHash := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
 | 
					 | 
				
			||||||
	owner := strings.ToUpper(rr.Hdr.Name)
 | 
					 | 
				
			||||||
	labelIndices := Split(owner)
 | 
					 | 
				
			||||||
	if len(labelIndices) < 2 {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	ownerHash := owner[:labelIndices[1]-1]
 | 
					 | 
				
			||||||
	ownerZone := owner[labelIndices[1]:]
 | 
					 | 
				
			||||||
	if !IsSubDomain(ownerZone, strings.ToUpper(name)) { // name is outside owner zone
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if ownerHash == nameHash {
 | 
					 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										113
									
								
								vendor/github.com/miekg/dns/privaterr.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										113
									
								
								vendor/github.com/miekg/dns/privaterr.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,113 +0,0 @@
 | 
				
			|||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "strings"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// PrivateRdata is an interface used for implementing "Private Use" RR types, see
 | 
					 | 
				
			||||||
// RFC 6895. This allows one to experiment with new RR types, without requesting an
 | 
					 | 
				
			||||||
// official type code. Also see dns.PrivateHandle and dns.PrivateHandleRemove.
 | 
					 | 
				
			||||||
type PrivateRdata interface {
 | 
					 | 
				
			||||||
	// String returns the text presentaton of the Rdata of the Private RR.
 | 
					 | 
				
			||||||
	String() string
 | 
					 | 
				
			||||||
	// Parse parses the Rdata of the private RR.
 | 
					 | 
				
			||||||
	Parse([]string) error
 | 
					 | 
				
			||||||
	// Pack is used when packing a private RR into a buffer.
 | 
					 | 
				
			||||||
	Pack([]byte) (int, error)
 | 
					 | 
				
			||||||
	// Unpack is used when unpacking a private RR from a buffer.
 | 
					 | 
				
			||||||
	Unpack([]byte) (int, error)
 | 
					 | 
				
			||||||
	// Copy copies the Rdata into the PrivateRdata argument.
 | 
					 | 
				
			||||||
	Copy(PrivateRdata) error
 | 
					 | 
				
			||||||
	// Len returns the length in octets of the Rdata.
 | 
					 | 
				
			||||||
	Len() int
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// PrivateRR represents an RR that uses a PrivateRdata user-defined type.
 | 
					 | 
				
			||||||
// It mocks normal RRs and implements dns.RR interface.
 | 
					 | 
				
			||||||
type PrivateRR struct {
 | 
					 | 
				
			||||||
	Hdr  RR_Header
 | 
					 | 
				
			||||||
	Data PrivateRdata
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	generator func() PrivateRdata // for copy
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Header return the RR header of r.
 | 
					 | 
				
			||||||
func (r *PrivateRR) Header() *RR_Header { return &r.Hdr }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r *PrivateRR) String() string { return r.Hdr.String() + r.Data.String() }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Private len and copy parts to satisfy RR interface.
 | 
					 | 
				
			||||||
func (r *PrivateRR) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := r.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += r.Data.Len()
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r *PrivateRR) copy() RR {
 | 
					 | 
				
			||||||
	// make new RR like this:
 | 
					 | 
				
			||||||
	rr := &PrivateRR{r.Hdr, r.generator(), r.generator}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err := r.Data.Copy(rr.Data); err != nil {
 | 
					 | 
				
			||||||
		panic("dns: got value that could not be used to copy Private rdata: " + err.Error())
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return rr
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r *PrivateRR) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) {
 | 
					 | 
				
			||||||
	n, err := r.Data.Pack(msg[off:])
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return len(msg), err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	off += n
 | 
					 | 
				
			||||||
	return off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r *PrivateRR) unpack(msg []byte, off int) (int, error) {
 | 
					 | 
				
			||||||
	off1, err := r.Data.Unpack(msg[off:])
 | 
					 | 
				
			||||||
	off += off1
 | 
					 | 
				
			||||||
	return off, err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r *PrivateRR) parse(c *zlexer, origin string) *ParseError {
 | 
					 | 
				
			||||||
	var l lex
 | 
					 | 
				
			||||||
	text := make([]string, 0, 2) // could be 0..N elements, median is probably 1
 | 
					 | 
				
			||||||
Fetch:
 | 
					 | 
				
			||||||
	for {
 | 
					 | 
				
			||||||
		// TODO(miek): we could also be returning _QUOTE, this might or might not
 | 
					 | 
				
			||||||
		// be an issue (basically parsing TXT becomes hard)
 | 
					 | 
				
			||||||
		switch l, _ = c.Next(); l.value {
 | 
					 | 
				
			||||||
		case zNewline, zEOF:
 | 
					 | 
				
			||||||
			break Fetch
 | 
					 | 
				
			||||||
		case zString:
 | 
					 | 
				
			||||||
			text = append(text, l.token)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	err := r.Data.Parse(text)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return &ParseError{"", err.Error(), l}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r1 *PrivateRR) isDuplicate(r2 RR) bool { return false }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// PrivateHandle registers a private resource record type. It requires
 | 
					 | 
				
			||||||
// string and numeric representation of private RR type and generator function as argument.
 | 
					 | 
				
			||||||
func PrivateHandle(rtypestr string, rtype uint16, generator func() PrivateRdata) {
 | 
					 | 
				
			||||||
	rtypestr = strings.ToUpper(rtypestr)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	TypeToRR[rtype] = func() RR { return &PrivateRR{RR_Header{}, generator(), generator} }
 | 
					 | 
				
			||||||
	TypeToString[rtype] = rtypestr
 | 
					 | 
				
			||||||
	StringToType[rtypestr] = rtype
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// PrivateHandleRemove removes definitions required to support private RR type.
 | 
					 | 
				
			||||||
func PrivateHandleRemove(rtype uint16) {
 | 
					 | 
				
			||||||
	rtypestr, ok := TypeToString[rtype]
 | 
					 | 
				
			||||||
	if ok {
 | 
					 | 
				
			||||||
		delete(TypeToRR, rtype)
 | 
					 | 
				
			||||||
		delete(TypeToString, rtype)
 | 
					 | 
				
			||||||
		delete(StringToType, rtypestr)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										52
									
								
								vendor/github.com/miekg/dns/reverse.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										52
									
								
								vendor/github.com/miekg/dns/reverse.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,52 +0,0 @@
 | 
				
			|||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// StringToType is the reverse of TypeToString, needed for string parsing.
 | 
					 | 
				
			||||||
var StringToType = reverseInt16(TypeToString)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// StringToClass is the reverse of ClassToString, needed for string parsing.
 | 
					 | 
				
			||||||
var StringToClass = reverseInt16(ClassToString)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// StringToOpcode is a map of opcodes to strings.
 | 
					 | 
				
			||||||
var StringToOpcode = reverseInt(OpcodeToString)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// StringToRcode is a map of rcodes to strings.
 | 
					 | 
				
			||||||
var StringToRcode = reverseInt(RcodeToString)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func init() {
 | 
					 | 
				
			||||||
	// Preserve previous NOTIMP typo, see github.com/miekg/dns/issues/733.
 | 
					 | 
				
			||||||
	StringToRcode["NOTIMPL"] = RcodeNotImplemented
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// StringToAlgorithm is the reverse of AlgorithmToString.
 | 
					 | 
				
			||||||
var StringToAlgorithm = reverseInt8(AlgorithmToString)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// StringToHash is a map of names to hash IDs.
 | 
					 | 
				
			||||||
var StringToHash = reverseInt8(HashToString)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// StringToCertType is the reverseof CertTypeToString.
 | 
					 | 
				
			||||||
var StringToCertType = reverseInt16(CertTypeToString)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Reverse a map
 | 
					 | 
				
			||||||
func reverseInt8(m map[uint8]string) map[string]uint8 {
 | 
					 | 
				
			||||||
	n := make(map[string]uint8, len(m))
 | 
					 | 
				
			||||||
	for u, s := range m {
 | 
					 | 
				
			||||||
		n[s] = u
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return n
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func reverseInt16(m map[uint16]string) map[string]uint16 {
 | 
					 | 
				
			||||||
	n := make(map[string]uint16, len(m))
 | 
					 | 
				
			||||||
	for u, s := range m {
 | 
					 | 
				
			||||||
		n[s] = u
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return n
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func reverseInt(m map[int]string) map[string]int {
 | 
					 | 
				
			||||||
	n := make(map[string]int, len(m))
 | 
					 | 
				
			||||||
	for u, s := range m {
 | 
					 | 
				
			||||||
		n[s] = u
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return n
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										86
									
								
								vendor/github.com/miekg/dns/sanitize.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										86
									
								
								vendor/github.com/miekg/dns/sanitize.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,86 +0,0 @@
 | 
				
			|||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Dedup removes identical RRs from rrs. It preserves the original ordering.
 | 
					 | 
				
			||||||
// The lowest TTL of any duplicates is used in the remaining one. Dedup modifies
 | 
					 | 
				
			||||||
// rrs.
 | 
					 | 
				
			||||||
// m is used to store the RRs temporary. If it is nil a new map will be allocated.
 | 
					 | 
				
			||||||
func Dedup(rrs []RR, m map[string]RR) []RR {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if m == nil {
 | 
					 | 
				
			||||||
		m = make(map[string]RR)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// Save the keys, so we don't have to call normalizedString twice.
 | 
					 | 
				
			||||||
	keys := make([]*string, 0, len(rrs))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for _, r := range rrs {
 | 
					 | 
				
			||||||
		key := normalizedString(r)
 | 
					 | 
				
			||||||
		keys = append(keys, &key)
 | 
					 | 
				
			||||||
		if mr, ok := m[key]; ok {
 | 
					 | 
				
			||||||
			// Shortest TTL wins.
 | 
					 | 
				
			||||||
			rh, mrh := r.Header(), mr.Header()
 | 
					 | 
				
			||||||
			if mrh.Ttl > rh.Ttl {
 | 
					 | 
				
			||||||
				mrh.Ttl = rh.Ttl
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		m[key] = r
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// If the length of the result map equals the amount of RRs we got,
 | 
					 | 
				
			||||||
	// it means they were all different. We can then just return the original rrset.
 | 
					 | 
				
			||||||
	if len(m) == len(rrs) {
 | 
					 | 
				
			||||||
		return rrs
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	j := 0
 | 
					 | 
				
			||||||
	for i, r := range rrs {
 | 
					 | 
				
			||||||
		// If keys[i] lives in the map, we should copy and remove it.
 | 
					 | 
				
			||||||
		if _, ok := m[*keys[i]]; ok {
 | 
					 | 
				
			||||||
			delete(m, *keys[i])
 | 
					 | 
				
			||||||
			rrs[j] = r
 | 
					 | 
				
			||||||
			j++
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if len(m) == 0 {
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return rrs[:j]
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// normalizedString returns a normalized string from r. The TTL
 | 
					 | 
				
			||||||
// is removed and the domain name is lowercased. We go from this:
 | 
					 | 
				
			||||||
// DomainName<TAB>TTL<TAB>CLASS<TAB>TYPE<TAB>RDATA to:
 | 
					 | 
				
			||||||
// lowercasename<TAB>CLASS<TAB>TYPE...
 | 
					 | 
				
			||||||
func normalizedString(r RR) string {
 | 
					 | 
				
			||||||
	// A string Go DNS makes has: domainname<TAB>TTL<TAB>...
 | 
					 | 
				
			||||||
	b := []byte(r.String())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// find the first non-escaped tab, then another, so we capture where the TTL lives.
 | 
					 | 
				
			||||||
	esc := false
 | 
					 | 
				
			||||||
	ttlStart, ttlEnd := 0, 0
 | 
					 | 
				
			||||||
	for i := 0; i < len(b) && ttlEnd == 0; i++ {
 | 
					 | 
				
			||||||
		switch {
 | 
					 | 
				
			||||||
		case b[i] == '\\':
 | 
					 | 
				
			||||||
			esc = !esc
 | 
					 | 
				
			||||||
		case b[i] == '\t' && !esc:
 | 
					 | 
				
			||||||
			if ttlStart == 0 {
 | 
					 | 
				
			||||||
				ttlStart = i
 | 
					 | 
				
			||||||
				continue
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if ttlEnd == 0 {
 | 
					 | 
				
			||||||
				ttlEnd = i
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		case b[i] >= 'A' && b[i] <= 'Z' && !esc:
 | 
					 | 
				
			||||||
			b[i] += 32
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			esc = false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// remove TTL.
 | 
					 | 
				
			||||||
	copy(b[ttlStart:], b[ttlEnd:])
 | 
					 | 
				
			||||||
	cut := ttlEnd - ttlStart
 | 
					 | 
				
			||||||
	return string(b[:len(b)-cut])
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										1352
									
								
								vendor/github.com/miekg/dns/scan.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1352
									
								
								vendor/github.com/miekg/dns/scan.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1742
									
								
								vendor/github.com/miekg/dns/scan_rr.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1742
									
								
								vendor/github.com/miekg/dns/scan_rr.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										122
									
								
								vendor/github.com/miekg/dns/serve_mux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										122
									
								
								vendor/github.com/miekg/dns/serve_mux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,122 +0,0 @@
 | 
				
			|||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"sync"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ServeMux is an DNS request multiplexer. It matches the zone name of
 | 
					 | 
				
			||||||
// each incoming request against a list of registered patterns add calls
 | 
					 | 
				
			||||||
// the handler for the pattern that most closely matches the zone name.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// ServeMux is DNSSEC aware, meaning that queries for the DS record are
 | 
					 | 
				
			||||||
// redirected to the parent zone (if that is also registered), otherwise
 | 
					 | 
				
			||||||
// the child gets the query.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// ServeMux is also safe for concurrent access from multiple goroutines.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// The zero ServeMux is empty and ready for use.
 | 
					 | 
				
			||||||
type ServeMux struct {
 | 
					 | 
				
			||||||
	z map[string]Handler
 | 
					 | 
				
			||||||
	m sync.RWMutex
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NewServeMux allocates and returns a new ServeMux.
 | 
					 | 
				
			||||||
func NewServeMux() *ServeMux {
 | 
					 | 
				
			||||||
	return new(ServeMux)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// DefaultServeMux is the default ServeMux used by Serve.
 | 
					 | 
				
			||||||
var DefaultServeMux = NewServeMux()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (mux *ServeMux) match(q string, t uint16) Handler {
 | 
					 | 
				
			||||||
	mux.m.RLock()
 | 
					 | 
				
			||||||
	defer mux.m.RUnlock()
 | 
					 | 
				
			||||||
	if mux.z == nil {
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	q = CanonicalName(q)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var handler Handler
 | 
					 | 
				
			||||||
	for off, end := 0, false; !end; off, end = NextLabel(q, off) {
 | 
					 | 
				
			||||||
		if h, ok := mux.z[q[off:]]; ok {
 | 
					 | 
				
			||||||
			if t != TypeDS {
 | 
					 | 
				
			||||||
				return h
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			// Continue for DS to see if we have a parent too, if so delegate to the parent
 | 
					 | 
				
			||||||
			handler = h
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Wildcard match, if we have found nothing try the root zone as a last resort.
 | 
					 | 
				
			||||||
	if h, ok := mux.z["."]; ok {
 | 
					 | 
				
			||||||
		return h
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return handler
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Handle adds a handler to the ServeMux for pattern.
 | 
					 | 
				
			||||||
func (mux *ServeMux) Handle(pattern string, handler Handler) {
 | 
					 | 
				
			||||||
	if pattern == "" {
 | 
					 | 
				
			||||||
		panic("dns: invalid pattern " + pattern)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	mux.m.Lock()
 | 
					 | 
				
			||||||
	if mux.z == nil {
 | 
					 | 
				
			||||||
		mux.z = make(map[string]Handler)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	mux.z[CanonicalName(pattern)] = handler
 | 
					 | 
				
			||||||
	mux.m.Unlock()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// HandleFunc adds a handler function to the ServeMux for pattern.
 | 
					 | 
				
			||||||
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) {
 | 
					 | 
				
			||||||
	mux.Handle(pattern, HandlerFunc(handler))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// HandleRemove deregisters the handler specific for pattern from the ServeMux.
 | 
					 | 
				
			||||||
func (mux *ServeMux) HandleRemove(pattern string) {
 | 
					 | 
				
			||||||
	if pattern == "" {
 | 
					 | 
				
			||||||
		panic("dns: invalid pattern " + pattern)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	mux.m.Lock()
 | 
					 | 
				
			||||||
	delete(mux.z, CanonicalName(pattern))
 | 
					 | 
				
			||||||
	mux.m.Unlock()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ServeDNS dispatches the request to the handler whose pattern most
 | 
					 | 
				
			||||||
// closely matches the request message.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// ServeDNS is DNSSEC aware, meaning that queries for the DS record
 | 
					 | 
				
			||||||
// are redirected to the parent zone (if that is also registered),
 | 
					 | 
				
			||||||
// otherwise the child gets the query.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// If no handler is found, or there is no question, a standard REFUSED
 | 
					 | 
				
			||||||
// message is returned
 | 
					 | 
				
			||||||
func (mux *ServeMux) ServeDNS(w ResponseWriter, req *Msg) {
 | 
					 | 
				
			||||||
	var h Handler
 | 
					 | 
				
			||||||
	if len(req.Question) >= 1 { // allow more than one question
 | 
					 | 
				
			||||||
		h = mux.match(req.Question[0].Name, req.Question[0].Qtype)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if h != nil {
 | 
					 | 
				
			||||||
		h.ServeDNS(w, req)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		handleRefused(w, req)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Handle registers the handler with the given pattern
 | 
					 | 
				
			||||||
// in the DefaultServeMux. The documentation for
 | 
					 | 
				
			||||||
// ServeMux explains how patterns are matched.
 | 
					 | 
				
			||||||
func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// HandleRemove deregisters the handle with the given pattern
 | 
					 | 
				
			||||||
// in the DefaultServeMux.
 | 
					 | 
				
			||||||
func HandleRemove(pattern string) { DefaultServeMux.HandleRemove(pattern) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// HandleFunc registers the handler function with the given pattern
 | 
					 | 
				
			||||||
// in the DefaultServeMux.
 | 
					 | 
				
			||||||
func HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) {
 | 
					 | 
				
			||||||
	DefaultServeMux.HandleFunc(pattern, handler)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										828
									
								
								vendor/github.com/miekg/dns/server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										828
									
								
								vendor/github.com/miekg/dns/server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,828 +0,0 @@
 | 
				
			|||||||
// DNS server implementation.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"context"
 | 
					 | 
				
			||||||
	"crypto/tls"
 | 
					 | 
				
			||||||
	"encoding/binary"
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"io"
 | 
					 | 
				
			||||||
	"net"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
	"sync"
 | 
					 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Default maximum number of TCP queries before we close the socket.
 | 
					 | 
				
			||||||
const maxTCPQueries = 128
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// aLongTimeAgo is a non-zero time, far in the past, used for
 | 
					 | 
				
			||||||
// immediate cancelation of network operations.
 | 
					 | 
				
			||||||
var aLongTimeAgo = time.Unix(1, 0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Handler is implemented by any value that implements ServeDNS.
 | 
					 | 
				
			||||||
type Handler interface {
 | 
					 | 
				
			||||||
	ServeDNS(w ResponseWriter, r *Msg)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// The HandlerFunc type is an adapter to allow the use of
 | 
					 | 
				
			||||||
// ordinary functions as DNS handlers.  If f is a function
 | 
					 | 
				
			||||||
// with the appropriate signature, HandlerFunc(f) is a
 | 
					 | 
				
			||||||
// Handler object that calls f.
 | 
					 | 
				
			||||||
type HandlerFunc func(ResponseWriter, *Msg)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ServeDNS calls f(w, r).
 | 
					 | 
				
			||||||
func (f HandlerFunc) ServeDNS(w ResponseWriter, r *Msg) {
 | 
					 | 
				
			||||||
	f(w, r)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// A ResponseWriter interface is used by an DNS handler to
 | 
					 | 
				
			||||||
// construct an DNS response.
 | 
					 | 
				
			||||||
type ResponseWriter interface {
 | 
					 | 
				
			||||||
	// LocalAddr returns the net.Addr of the server
 | 
					 | 
				
			||||||
	LocalAddr() net.Addr
 | 
					 | 
				
			||||||
	// RemoteAddr returns the net.Addr of the client that sent the current request.
 | 
					 | 
				
			||||||
	RemoteAddr() net.Addr
 | 
					 | 
				
			||||||
	// WriteMsg writes a reply back to the client.
 | 
					 | 
				
			||||||
	WriteMsg(*Msg) error
 | 
					 | 
				
			||||||
	// Write writes a raw buffer back to the client.
 | 
					 | 
				
			||||||
	Write([]byte) (int, error)
 | 
					 | 
				
			||||||
	// Close closes the connection.
 | 
					 | 
				
			||||||
	Close() error
 | 
					 | 
				
			||||||
	// TsigStatus returns the status of the Tsig.
 | 
					 | 
				
			||||||
	TsigStatus() error
 | 
					 | 
				
			||||||
	// TsigTimersOnly sets the tsig timers only boolean.
 | 
					 | 
				
			||||||
	TsigTimersOnly(bool)
 | 
					 | 
				
			||||||
	// Hijack lets the caller take over the connection.
 | 
					 | 
				
			||||||
	// After a call to Hijack(), the DNS package will not do anything with the connection.
 | 
					 | 
				
			||||||
	Hijack()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// A ConnectionStater interface is used by a DNS Handler to access TLS connection state
 | 
					 | 
				
			||||||
// when available.
 | 
					 | 
				
			||||||
type ConnectionStater interface {
 | 
					 | 
				
			||||||
	ConnectionState() *tls.ConnectionState
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type response struct {
 | 
					 | 
				
			||||||
	closed         bool // connection has been closed
 | 
					 | 
				
			||||||
	hijacked       bool // connection has been hijacked by handler
 | 
					 | 
				
			||||||
	tsigTimersOnly bool
 | 
					 | 
				
			||||||
	tsigStatus     error
 | 
					 | 
				
			||||||
	tsigRequestMAC string
 | 
					 | 
				
			||||||
	tsigSecret     map[string]string // the tsig secrets
 | 
					 | 
				
			||||||
	udp            net.PacketConn    // i/o connection if UDP was used
 | 
					 | 
				
			||||||
	tcp            net.Conn          // i/o connection if TCP was used
 | 
					 | 
				
			||||||
	udpSession     *SessionUDP       // oob data to get egress interface right
 | 
					 | 
				
			||||||
	pcSession      net.Addr          // address to use when writing to a generic net.PacketConn
 | 
					 | 
				
			||||||
	writer         Writer            // writer to output the raw DNS bits
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// handleRefused returns a HandlerFunc that returns REFUSED for every request it gets.
 | 
					 | 
				
			||||||
func handleRefused(w ResponseWriter, r *Msg) {
 | 
					 | 
				
			||||||
	m := new(Msg)
 | 
					 | 
				
			||||||
	m.SetRcode(r, RcodeRefused)
 | 
					 | 
				
			||||||
	w.WriteMsg(m)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// HandleFailed returns a HandlerFunc that returns SERVFAIL for every request it gets.
 | 
					 | 
				
			||||||
// Deprecated: This function is going away.
 | 
					 | 
				
			||||||
func HandleFailed(w ResponseWriter, r *Msg) {
 | 
					 | 
				
			||||||
	m := new(Msg)
 | 
					 | 
				
			||||||
	m.SetRcode(r, RcodeServerFailure)
 | 
					 | 
				
			||||||
	// does not matter if this write fails
 | 
					 | 
				
			||||||
	w.WriteMsg(m)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ListenAndServe Starts a server on address and network specified Invoke handler
 | 
					 | 
				
			||||||
// for incoming queries.
 | 
					 | 
				
			||||||
func ListenAndServe(addr string, network string, handler Handler) error {
 | 
					 | 
				
			||||||
	server := &Server{Addr: addr, Net: network, Handler: handler}
 | 
					 | 
				
			||||||
	return server.ListenAndServe()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ListenAndServeTLS acts like http.ListenAndServeTLS, more information in
 | 
					 | 
				
			||||||
// http://golang.org/pkg/net/http/#ListenAndServeTLS
 | 
					 | 
				
			||||||
func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error {
 | 
					 | 
				
			||||||
	cert, err := tls.LoadX509KeyPair(certFile, keyFile)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	config := tls.Config{
 | 
					 | 
				
			||||||
		Certificates: []tls.Certificate{cert},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	server := &Server{
 | 
					 | 
				
			||||||
		Addr:      addr,
 | 
					 | 
				
			||||||
		Net:       "tcp-tls",
 | 
					 | 
				
			||||||
		TLSConfig: &config,
 | 
					 | 
				
			||||||
		Handler:   handler,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return server.ListenAndServe()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ActivateAndServe activates a server with a listener from systemd,
 | 
					 | 
				
			||||||
// l and p should not both be non-nil.
 | 
					 | 
				
			||||||
// If both l and p are not nil only p will be used.
 | 
					 | 
				
			||||||
// Invoke handler for incoming queries.
 | 
					 | 
				
			||||||
func ActivateAndServe(l net.Listener, p net.PacketConn, handler Handler) error {
 | 
					 | 
				
			||||||
	server := &Server{Listener: l, PacketConn: p, Handler: handler}
 | 
					 | 
				
			||||||
	return server.ActivateAndServe()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Writer writes raw DNS messages; each call to Write should send an entire message.
 | 
					 | 
				
			||||||
type Writer interface {
 | 
					 | 
				
			||||||
	io.Writer
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Reader reads raw DNS messages; each call to ReadTCP or ReadUDP should return an entire message.
 | 
					 | 
				
			||||||
type Reader interface {
 | 
					 | 
				
			||||||
	// ReadTCP reads a raw message from a TCP connection. Implementations may alter
 | 
					 | 
				
			||||||
	// connection properties, for example the read-deadline.
 | 
					 | 
				
			||||||
	ReadTCP(conn net.Conn, timeout time.Duration) ([]byte, error)
 | 
					 | 
				
			||||||
	// ReadUDP reads a raw message from a UDP connection. Implementations may alter
 | 
					 | 
				
			||||||
	// connection properties, for example the read-deadline.
 | 
					 | 
				
			||||||
	ReadUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// PacketConnReader is an optional interface that Readers can implement to support using generic net.PacketConns.
 | 
					 | 
				
			||||||
type PacketConnReader interface {
 | 
					 | 
				
			||||||
	Reader
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// ReadPacketConn reads a raw message from a generic net.PacketConn UDP connection. Implementations may
 | 
					 | 
				
			||||||
	// alter connection properties, for example the read-deadline.
 | 
					 | 
				
			||||||
	ReadPacketConn(conn net.PacketConn, timeout time.Duration) ([]byte, net.Addr, error)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// defaultReader is an adapter for the Server struct that implements the Reader and
 | 
					 | 
				
			||||||
// PacketConnReader interfaces using the readTCP, readUDP and readPacketConn funcs
 | 
					 | 
				
			||||||
// of the embedded Server.
 | 
					 | 
				
			||||||
type defaultReader struct {
 | 
					 | 
				
			||||||
	*Server
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var _ PacketConnReader = defaultReader{}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (dr defaultReader) ReadTCP(conn net.Conn, timeout time.Duration) ([]byte, error) {
 | 
					 | 
				
			||||||
	return dr.readTCP(conn, timeout)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (dr defaultReader) ReadUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error) {
 | 
					 | 
				
			||||||
	return dr.readUDP(conn, timeout)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (dr defaultReader) ReadPacketConn(conn net.PacketConn, timeout time.Duration) ([]byte, net.Addr, error) {
 | 
					 | 
				
			||||||
	return dr.readPacketConn(conn, timeout)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// DecorateReader is a decorator hook for extending or supplanting the functionality of a Reader.
 | 
					 | 
				
			||||||
// Implementations should never return a nil Reader.
 | 
					 | 
				
			||||||
// Readers should also implement the optional PacketConnReader interface.
 | 
					 | 
				
			||||||
// PacketConnReader is required to use a generic net.PacketConn.
 | 
					 | 
				
			||||||
type DecorateReader func(Reader) Reader
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// DecorateWriter is a decorator hook for extending or supplanting the functionality of a Writer.
 | 
					 | 
				
			||||||
// Implementations should never return a nil Writer.
 | 
					 | 
				
			||||||
type DecorateWriter func(Writer) Writer
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// A Server defines parameters for running an DNS server.
 | 
					 | 
				
			||||||
type Server struct {
 | 
					 | 
				
			||||||
	// Address to listen on, ":dns" if empty.
 | 
					 | 
				
			||||||
	Addr string
 | 
					 | 
				
			||||||
	// if "tcp" or "tcp-tls" (DNS over TLS) it will invoke a TCP listener, otherwise an UDP one
 | 
					 | 
				
			||||||
	Net string
 | 
					 | 
				
			||||||
	// TCP Listener to use, this is to aid in systemd's socket activation.
 | 
					 | 
				
			||||||
	Listener net.Listener
 | 
					 | 
				
			||||||
	// TLS connection configuration
 | 
					 | 
				
			||||||
	TLSConfig *tls.Config
 | 
					 | 
				
			||||||
	// UDP "Listener" to use, this is to aid in systemd's socket activation.
 | 
					 | 
				
			||||||
	PacketConn net.PacketConn
 | 
					 | 
				
			||||||
	// Handler to invoke, dns.DefaultServeMux if nil.
 | 
					 | 
				
			||||||
	Handler Handler
 | 
					 | 
				
			||||||
	// Default buffer size to use to read incoming UDP messages. If not set
 | 
					 | 
				
			||||||
	// it defaults to MinMsgSize (512 B).
 | 
					 | 
				
			||||||
	UDPSize int
 | 
					 | 
				
			||||||
	// The net.Conn.SetReadTimeout value for new connections, defaults to 2 * time.Second.
 | 
					 | 
				
			||||||
	ReadTimeout time.Duration
 | 
					 | 
				
			||||||
	// The net.Conn.SetWriteTimeout value for new connections, defaults to 2 * time.Second.
 | 
					 | 
				
			||||||
	WriteTimeout time.Duration
 | 
					 | 
				
			||||||
	// TCP idle timeout for multiple queries, if nil, defaults to 8 * time.Second (RFC 5966).
 | 
					 | 
				
			||||||
	IdleTimeout func() time.Duration
 | 
					 | 
				
			||||||
	// Secret(s) for Tsig map[<zonename>]<base64 secret>. The zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2).
 | 
					 | 
				
			||||||
	TsigSecret map[string]string
 | 
					 | 
				
			||||||
	// If NotifyStartedFunc is set it is called once the server has started listening.
 | 
					 | 
				
			||||||
	NotifyStartedFunc func()
 | 
					 | 
				
			||||||
	// DecorateReader is optional, allows customization of the process that reads raw DNS messages.
 | 
					 | 
				
			||||||
	DecorateReader DecorateReader
 | 
					 | 
				
			||||||
	// DecorateWriter is optional, allows customization of the process that writes raw DNS messages.
 | 
					 | 
				
			||||||
	DecorateWriter DecorateWriter
 | 
					 | 
				
			||||||
	// Maximum number of TCP queries before we close the socket. Default is maxTCPQueries (unlimited if -1).
 | 
					 | 
				
			||||||
	MaxTCPQueries int
 | 
					 | 
				
			||||||
	// Whether to set the SO_REUSEPORT socket option, allowing multiple listeners to be bound to a single address.
 | 
					 | 
				
			||||||
	// It is only supported on go1.11+ and when using ListenAndServe.
 | 
					 | 
				
			||||||
	ReusePort bool
 | 
					 | 
				
			||||||
	// AcceptMsgFunc will check the incoming message and will reject it early in the process.
 | 
					 | 
				
			||||||
	// By default DefaultMsgAcceptFunc will be used.
 | 
					 | 
				
			||||||
	MsgAcceptFunc MsgAcceptFunc
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Shutdown handling
 | 
					 | 
				
			||||||
	lock     sync.RWMutex
 | 
					 | 
				
			||||||
	started  bool
 | 
					 | 
				
			||||||
	shutdown chan struct{}
 | 
					 | 
				
			||||||
	conns    map[net.Conn]struct{}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// A pool for UDP message buffers.
 | 
					 | 
				
			||||||
	udpPool sync.Pool
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (srv *Server) isStarted() bool {
 | 
					 | 
				
			||||||
	srv.lock.RLock()
 | 
					 | 
				
			||||||
	started := srv.started
 | 
					 | 
				
			||||||
	srv.lock.RUnlock()
 | 
					 | 
				
			||||||
	return started
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func makeUDPBuffer(size int) func() interface{} {
 | 
					 | 
				
			||||||
	return func() interface{} {
 | 
					 | 
				
			||||||
		return make([]byte, size)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (srv *Server) init() {
 | 
					 | 
				
			||||||
	srv.shutdown = make(chan struct{})
 | 
					 | 
				
			||||||
	srv.conns = make(map[net.Conn]struct{})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if srv.UDPSize == 0 {
 | 
					 | 
				
			||||||
		srv.UDPSize = MinMsgSize
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if srv.MsgAcceptFunc == nil {
 | 
					 | 
				
			||||||
		srv.MsgAcceptFunc = DefaultMsgAcceptFunc
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if srv.Handler == nil {
 | 
					 | 
				
			||||||
		srv.Handler = DefaultServeMux
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	srv.udpPool.New = makeUDPBuffer(srv.UDPSize)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func unlockOnce(l sync.Locker) func() {
 | 
					 | 
				
			||||||
	var once sync.Once
 | 
					 | 
				
			||||||
	return func() { once.Do(l.Unlock) }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ListenAndServe starts a nameserver on the configured address in *Server.
 | 
					 | 
				
			||||||
func (srv *Server) ListenAndServe() error {
 | 
					 | 
				
			||||||
	unlock := unlockOnce(&srv.lock)
 | 
					 | 
				
			||||||
	srv.lock.Lock()
 | 
					 | 
				
			||||||
	defer unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if srv.started {
 | 
					 | 
				
			||||||
		return &Error{err: "server already started"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	addr := srv.Addr
 | 
					 | 
				
			||||||
	if addr == "" {
 | 
					 | 
				
			||||||
		addr = ":domain"
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	srv.init()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch srv.Net {
 | 
					 | 
				
			||||||
	case "tcp", "tcp4", "tcp6":
 | 
					 | 
				
			||||||
		l, err := listenTCP(srv.Net, addr, srv.ReusePort)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		srv.Listener = l
 | 
					 | 
				
			||||||
		srv.started = true
 | 
					 | 
				
			||||||
		unlock()
 | 
					 | 
				
			||||||
		return srv.serveTCP(l)
 | 
					 | 
				
			||||||
	case "tcp-tls", "tcp4-tls", "tcp6-tls":
 | 
					 | 
				
			||||||
		if srv.TLSConfig == nil || (len(srv.TLSConfig.Certificates) == 0 && srv.TLSConfig.GetCertificate == nil) {
 | 
					 | 
				
			||||||
			return errors.New("dns: neither Certificates nor GetCertificate set in Config")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		network := strings.TrimSuffix(srv.Net, "-tls")
 | 
					 | 
				
			||||||
		l, err := listenTCP(network, addr, srv.ReusePort)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		l = tls.NewListener(l, srv.TLSConfig)
 | 
					 | 
				
			||||||
		srv.Listener = l
 | 
					 | 
				
			||||||
		srv.started = true
 | 
					 | 
				
			||||||
		unlock()
 | 
					 | 
				
			||||||
		return srv.serveTCP(l)
 | 
					 | 
				
			||||||
	case "udp", "udp4", "udp6":
 | 
					 | 
				
			||||||
		l, err := listenUDP(srv.Net, addr, srv.ReusePort)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		u := l.(*net.UDPConn)
 | 
					 | 
				
			||||||
		if e := setUDPSocketOptions(u); e != nil {
 | 
					 | 
				
			||||||
			return e
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		srv.PacketConn = l
 | 
					 | 
				
			||||||
		srv.started = true
 | 
					 | 
				
			||||||
		unlock()
 | 
					 | 
				
			||||||
		return srv.serveUDP(u)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &Error{err: "bad network"}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ActivateAndServe starts a nameserver with the PacketConn or Listener
 | 
					 | 
				
			||||||
// configured in *Server. Its main use is to start a server from systemd.
 | 
					 | 
				
			||||||
func (srv *Server) ActivateAndServe() error {
 | 
					 | 
				
			||||||
	unlock := unlockOnce(&srv.lock)
 | 
					 | 
				
			||||||
	srv.lock.Lock()
 | 
					 | 
				
			||||||
	defer unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if srv.started {
 | 
					 | 
				
			||||||
		return &Error{err: "server already started"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	srv.init()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if srv.PacketConn != nil {
 | 
					 | 
				
			||||||
		// Check PacketConn interface's type is valid and value
 | 
					 | 
				
			||||||
		// is not nil
 | 
					 | 
				
			||||||
		if t, ok := srv.PacketConn.(*net.UDPConn); ok && t != nil {
 | 
					 | 
				
			||||||
			if e := setUDPSocketOptions(t); e != nil {
 | 
					 | 
				
			||||||
				return e
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		srv.started = true
 | 
					 | 
				
			||||||
		unlock()
 | 
					 | 
				
			||||||
		return srv.serveUDP(srv.PacketConn)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if srv.Listener != nil {
 | 
					 | 
				
			||||||
		srv.started = true
 | 
					 | 
				
			||||||
		unlock()
 | 
					 | 
				
			||||||
		return srv.serveTCP(srv.Listener)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &Error{err: "bad listeners"}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Shutdown shuts down a server. After a call to Shutdown, ListenAndServe and
 | 
					 | 
				
			||||||
// ActivateAndServe will return.
 | 
					 | 
				
			||||||
func (srv *Server) Shutdown() error {
 | 
					 | 
				
			||||||
	return srv.ShutdownContext(context.Background())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ShutdownContext shuts down a server. After a call to ShutdownContext,
 | 
					 | 
				
			||||||
// ListenAndServe and ActivateAndServe will return.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// A context.Context may be passed to limit how long to wait for connections
 | 
					 | 
				
			||||||
// to terminate.
 | 
					 | 
				
			||||||
func (srv *Server) ShutdownContext(ctx context.Context) error {
 | 
					 | 
				
			||||||
	srv.lock.Lock()
 | 
					 | 
				
			||||||
	if !srv.started {
 | 
					 | 
				
			||||||
		srv.lock.Unlock()
 | 
					 | 
				
			||||||
		return &Error{err: "server not started"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	srv.started = false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if srv.PacketConn != nil {
 | 
					 | 
				
			||||||
		srv.PacketConn.SetReadDeadline(aLongTimeAgo) // Unblock reads
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if srv.Listener != nil {
 | 
					 | 
				
			||||||
		srv.Listener.Close()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for rw := range srv.conns {
 | 
					 | 
				
			||||||
		rw.SetReadDeadline(aLongTimeAgo) // Unblock reads
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	srv.lock.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if testShutdownNotify != nil {
 | 
					 | 
				
			||||||
		testShutdownNotify.Broadcast()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var ctxErr error
 | 
					 | 
				
			||||||
	select {
 | 
					 | 
				
			||||||
	case <-srv.shutdown:
 | 
					 | 
				
			||||||
	case <-ctx.Done():
 | 
					 | 
				
			||||||
		ctxErr = ctx.Err()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if srv.PacketConn != nil {
 | 
					 | 
				
			||||||
		srv.PacketConn.Close()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return ctxErr
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var testShutdownNotify *sync.Cond
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// getReadTimeout is a helper func to use system timeout if server did not intend to change it.
 | 
					 | 
				
			||||||
func (srv *Server) getReadTimeout() time.Duration {
 | 
					 | 
				
			||||||
	if srv.ReadTimeout != 0 {
 | 
					 | 
				
			||||||
		return srv.ReadTimeout
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return dnsTimeout
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// serveTCP starts a TCP listener for the server.
 | 
					 | 
				
			||||||
func (srv *Server) serveTCP(l net.Listener) error {
 | 
					 | 
				
			||||||
	defer l.Close()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if srv.NotifyStartedFunc != nil {
 | 
					 | 
				
			||||||
		srv.NotifyStartedFunc()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var wg sync.WaitGroup
 | 
					 | 
				
			||||||
	defer func() {
 | 
					 | 
				
			||||||
		wg.Wait()
 | 
					 | 
				
			||||||
		close(srv.shutdown)
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for srv.isStarted() {
 | 
					 | 
				
			||||||
		rw, err := l.Accept()
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			if !srv.isStarted() {
 | 
					 | 
				
			||||||
				return nil
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if neterr, ok := err.(net.Error); ok && neterr.Temporary() {
 | 
					 | 
				
			||||||
				continue
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		srv.lock.Lock()
 | 
					 | 
				
			||||||
		// Track the connection to allow unblocking reads on shutdown.
 | 
					 | 
				
			||||||
		srv.conns[rw] = struct{}{}
 | 
					 | 
				
			||||||
		srv.lock.Unlock()
 | 
					 | 
				
			||||||
		wg.Add(1)
 | 
					 | 
				
			||||||
		go srv.serveTCPConn(&wg, rw)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// serveUDP starts a UDP listener for the server.
 | 
					 | 
				
			||||||
func (srv *Server) serveUDP(l net.PacketConn) error {
 | 
					 | 
				
			||||||
	defer l.Close()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	reader := Reader(defaultReader{srv})
 | 
					 | 
				
			||||||
	if srv.DecorateReader != nil {
 | 
					 | 
				
			||||||
		reader = srv.DecorateReader(reader)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	lUDP, isUDP := l.(*net.UDPConn)
 | 
					 | 
				
			||||||
	readerPC, canPacketConn := reader.(PacketConnReader)
 | 
					 | 
				
			||||||
	if !isUDP && !canPacketConn {
 | 
					 | 
				
			||||||
		return &Error{err: "PacketConnReader was not implemented on Reader returned from DecorateReader but is required for net.PacketConn"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if srv.NotifyStartedFunc != nil {
 | 
					 | 
				
			||||||
		srv.NotifyStartedFunc()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var wg sync.WaitGroup
 | 
					 | 
				
			||||||
	defer func() {
 | 
					 | 
				
			||||||
		wg.Wait()
 | 
					 | 
				
			||||||
		close(srv.shutdown)
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rtimeout := srv.getReadTimeout()
 | 
					 | 
				
			||||||
	// deadline is not used here
 | 
					 | 
				
			||||||
	for srv.isStarted() {
 | 
					 | 
				
			||||||
		var (
 | 
					 | 
				
			||||||
			m    []byte
 | 
					 | 
				
			||||||
			sPC  net.Addr
 | 
					 | 
				
			||||||
			sUDP *SessionUDP
 | 
					 | 
				
			||||||
			err  error
 | 
					 | 
				
			||||||
		)
 | 
					 | 
				
			||||||
		if isUDP {
 | 
					 | 
				
			||||||
			m, sUDP, err = reader.ReadUDP(lUDP, rtimeout)
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			m, sPC, err = readerPC.ReadPacketConn(l, rtimeout)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			if !srv.isStarted() {
 | 
					 | 
				
			||||||
				return nil
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if netErr, ok := err.(net.Error); ok && netErr.Temporary() {
 | 
					 | 
				
			||||||
				continue
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if len(m) < headerSize {
 | 
					 | 
				
			||||||
			if cap(m) == srv.UDPSize {
 | 
					 | 
				
			||||||
				srv.udpPool.Put(m[:srv.UDPSize])
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		wg.Add(1)
 | 
					 | 
				
			||||||
		go srv.serveUDPPacket(&wg, m, l, sUDP, sPC)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Serve a new TCP connection.
 | 
					 | 
				
			||||||
func (srv *Server) serveTCPConn(wg *sync.WaitGroup, rw net.Conn) {
 | 
					 | 
				
			||||||
	w := &response{tsigSecret: srv.TsigSecret, tcp: rw}
 | 
					 | 
				
			||||||
	if srv.DecorateWriter != nil {
 | 
					 | 
				
			||||||
		w.writer = srv.DecorateWriter(w)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		w.writer = w
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	reader := Reader(defaultReader{srv})
 | 
					 | 
				
			||||||
	if srv.DecorateReader != nil {
 | 
					 | 
				
			||||||
		reader = srv.DecorateReader(reader)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	idleTimeout := tcpIdleTimeout
 | 
					 | 
				
			||||||
	if srv.IdleTimeout != nil {
 | 
					 | 
				
			||||||
		idleTimeout = srv.IdleTimeout()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	timeout := srv.getReadTimeout()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	limit := srv.MaxTCPQueries
 | 
					 | 
				
			||||||
	if limit == 0 {
 | 
					 | 
				
			||||||
		limit = maxTCPQueries
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for q := 0; (q < limit || limit == -1) && srv.isStarted(); q++ {
 | 
					 | 
				
			||||||
		m, err := reader.ReadTCP(w.tcp, timeout)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			// TODO(tmthrgd): handle error
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		srv.serveDNS(m, w)
 | 
					 | 
				
			||||||
		if w.closed {
 | 
					 | 
				
			||||||
			break // Close() was called
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if w.hijacked {
 | 
					 | 
				
			||||||
			break // client will call Close() themselves
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		// The first read uses the read timeout, the rest use the
 | 
					 | 
				
			||||||
		// idle timeout.
 | 
					 | 
				
			||||||
		timeout = idleTimeout
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if !w.hijacked {
 | 
					 | 
				
			||||||
		w.Close()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	srv.lock.Lock()
 | 
					 | 
				
			||||||
	delete(srv.conns, w.tcp)
 | 
					 | 
				
			||||||
	srv.lock.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	wg.Done()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Serve a new UDP request.
 | 
					 | 
				
			||||||
func (srv *Server) serveUDPPacket(wg *sync.WaitGroup, m []byte, u net.PacketConn, udpSession *SessionUDP, pcSession net.Addr) {
 | 
					 | 
				
			||||||
	w := &response{tsigSecret: srv.TsigSecret, udp: u, udpSession: udpSession, pcSession: pcSession}
 | 
					 | 
				
			||||||
	if srv.DecorateWriter != nil {
 | 
					 | 
				
			||||||
		w.writer = srv.DecorateWriter(w)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		w.writer = w
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	srv.serveDNS(m, w)
 | 
					 | 
				
			||||||
	wg.Done()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (srv *Server) serveDNS(m []byte, w *response) {
 | 
					 | 
				
			||||||
	dh, off, err := unpackMsgHdr(m, 0)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		// Let client hang, they are sending crap; any reply can be used to amplify.
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	req := new(Msg)
 | 
					 | 
				
			||||||
	req.setHdr(dh)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch action := srv.MsgAcceptFunc(dh); action {
 | 
					 | 
				
			||||||
	case MsgAccept:
 | 
					 | 
				
			||||||
		if req.unpack(dh, m, off) == nil {
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		fallthrough
 | 
					 | 
				
			||||||
	case MsgReject, MsgRejectNotImplemented:
 | 
					 | 
				
			||||||
		opcode := req.Opcode
 | 
					 | 
				
			||||||
		req.SetRcodeFormatError(req)
 | 
					 | 
				
			||||||
		req.Zero = false
 | 
					 | 
				
			||||||
		if action == MsgRejectNotImplemented {
 | 
					 | 
				
			||||||
			req.Opcode = opcode
 | 
					 | 
				
			||||||
			req.Rcode = RcodeNotImplemented
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Are we allowed to delete any OPT records here?
 | 
					 | 
				
			||||||
		req.Ns, req.Answer, req.Extra = nil, nil, nil
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		w.WriteMsg(req)
 | 
					 | 
				
			||||||
		fallthrough
 | 
					 | 
				
			||||||
	case MsgIgnore:
 | 
					 | 
				
			||||||
		if w.udp != nil && cap(m) == srv.UDPSize {
 | 
					 | 
				
			||||||
			srv.udpPool.Put(m[:srv.UDPSize])
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	w.tsigStatus = nil
 | 
					 | 
				
			||||||
	if w.tsigSecret != nil {
 | 
					 | 
				
			||||||
		if t := req.IsTsig(); t != nil {
 | 
					 | 
				
			||||||
			if secret, ok := w.tsigSecret[t.Hdr.Name]; ok {
 | 
					 | 
				
			||||||
				w.tsigStatus = TsigVerify(m, secret, "", false)
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				w.tsigStatus = ErrSecret
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			w.tsigTimersOnly = false
 | 
					 | 
				
			||||||
			w.tsigRequestMAC = req.Extra[len(req.Extra)-1].(*TSIG).MAC
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if w.udp != nil && cap(m) == srv.UDPSize {
 | 
					 | 
				
			||||||
		srv.udpPool.Put(m[:srv.UDPSize])
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	srv.Handler.ServeDNS(w, req) // Writes back to the client
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (srv *Server) readTCP(conn net.Conn, timeout time.Duration) ([]byte, error) {
 | 
					 | 
				
			||||||
	// If we race with ShutdownContext, the read deadline may
 | 
					 | 
				
			||||||
	// have been set in the distant past to unblock the read
 | 
					 | 
				
			||||||
	// below. We must not override it, otherwise we may block
 | 
					 | 
				
			||||||
	// ShutdownContext.
 | 
					 | 
				
			||||||
	srv.lock.RLock()
 | 
					 | 
				
			||||||
	if srv.started {
 | 
					 | 
				
			||||||
		conn.SetReadDeadline(time.Now().Add(timeout))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	srv.lock.RUnlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var length uint16
 | 
					 | 
				
			||||||
	if err := binary.Read(conn, binary.BigEndian, &length); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	m := make([]byte, length)
 | 
					 | 
				
			||||||
	if _, err := io.ReadFull(conn, m); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return m, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (srv *Server) readUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error) {
 | 
					 | 
				
			||||||
	srv.lock.RLock()
 | 
					 | 
				
			||||||
	if srv.started {
 | 
					 | 
				
			||||||
		// See the comment in readTCP above.
 | 
					 | 
				
			||||||
		conn.SetReadDeadline(time.Now().Add(timeout))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	srv.lock.RUnlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	m := srv.udpPool.Get().([]byte)
 | 
					 | 
				
			||||||
	n, s, err := ReadFromSessionUDP(conn, m)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		srv.udpPool.Put(m)
 | 
					 | 
				
			||||||
		return nil, nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	m = m[:n]
 | 
					 | 
				
			||||||
	return m, s, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (srv *Server) readPacketConn(conn net.PacketConn, timeout time.Duration) ([]byte, net.Addr, error) {
 | 
					 | 
				
			||||||
	srv.lock.RLock()
 | 
					 | 
				
			||||||
	if srv.started {
 | 
					 | 
				
			||||||
		// See the comment in readTCP above.
 | 
					 | 
				
			||||||
		conn.SetReadDeadline(time.Now().Add(timeout))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	srv.lock.RUnlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	m := srv.udpPool.Get().([]byte)
 | 
					 | 
				
			||||||
	n, addr, err := conn.ReadFrom(m)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		srv.udpPool.Put(m)
 | 
					 | 
				
			||||||
		return nil, nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	m = m[:n]
 | 
					 | 
				
			||||||
	return m, addr, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// WriteMsg implements the ResponseWriter.WriteMsg method.
 | 
					 | 
				
			||||||
func (w *response) WriteMsg(m *Msg) (err error) {
 | 
					 | 
				
			||||||
	if w.closed {
 | 
					 | 
				
			||||||
		return &Error{err: "WriteMsg called after Close"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var data []byte
 | 
					 | 
				
			||||||
	if w.tsigSecret != nil { // if no secrets, dont check for the tsig (which is a longer check)
 | 
					 | 
				
			||||||
		if t := m.IsTsig(); t != nil {
 | 
					 | 
				
			||||||
			data, w.tsigRequestMAC, err = TsigGenerate(m, w.tsigSecret[t.Hdr.Name], w.tsigRequestMAC, w.tsigTimersOnly)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			_, err = w.writer.Write(data)
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	data, err = m.Pack()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	_, err = w.writer.Write(data)
 | 
					 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Write implements the ResponseWriter.Write method.
 | 
					 | 
				
			||||||
func (w *response) Write(m []byte) (int, error) {
 | 
					 | 
				
			||||||
	if w.closed {
 | 
					 | 
				
			||||||
		return 0, &Error{err: "Write called after Close"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch {
 | 
					 | 
				
			||||||
	case w.udp != nil:
 | 
					 | 
				
			||||||
		if u, ok := w.udp.(*net.UDPConn); ok {
 | 
					 | 
				
			||||||
			return WriteToSessionUDP(u, m, w.udpSession)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return w.udp.WriteTo(m, w.pcSession)
 | 
					 | 
				
			||||||
	case w.tcp != nil:
 | 
					 | 
				
			||||||
		if len(m) > MaxMsgSize {
 | 
					 | 
				
			||||||
			return 0, &Error{err: "message too large"}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		l := make([]byte, 2)
 | 
					 | 
				
			||||||
		binary.BigEndian.PutUint16(l, uint16(len(m)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		n, err := (&net.Buffers{l, m}).WriteTo(w.tcp)
 | 
					 | 
				
			||||||
		return int(n), err
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		panic("dns: internal error: udp and tcp both nil")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// LocalAddr implements the ResponseWriter.LocalAddr method.
 | 
					 | 
				
			||||||
func (w *response) LocalAddr() net.Addr {
 | 
					 | 
				
			||||||
	switch {
 | 
					 | 
				
			||||||
	case w.udp != nil:
 | 
					 | 
				
			||||||
		return w.udp.LocalAddr()
 | 
					 | 
				
			||||||
	case w.tcp != nil:
 | 
					 | 
				
			||||||
		return w.tcp.LocalAddr()
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		panic("dns: internal error: udp and tcp both nil")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// RemoteAddr implements the ResponseWriter.RemoteAddr method.
 | 
					 | 
				
			||||||
func (w *response) RemoteAddr() net.Addr {
 | 
					 | 
				
			||||||
	switch {
 | 
					 | 
				
			||||||
	case w.udpSession != nil:
 | 
					 | 
				
			||||||
		return w.udpSession.RemoteAddr()
 | 
					 | 
				
			||||||
	case w.pcSession != nil:
 | 
					 | 
				
			||||||
		return w.pcSession
 | 
					 | 
				
			||||||
	case w.tcp != nil:
 | 
					 | 
				
			||||||
		return w.tcp.RemoteAddr()
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		panic("dns: internal error: udpSession, pcSession and tcp are all nil")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// TsigStatus implements the ResponseWriter.TsigStatus method.
 | 
					 | 
				
			||||||
func (w *response) TsigStatus() error { return w.tsigStatus }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// TsigTimersOnly implements the ResponseWriter.TsigTimersOnly method.
 | 
					 | 
				
			||||||
func (w *response) TsigTimersOnly(b bool) { w.tsigTimersOnly = b }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Hijack implements the ResponseWriter.Hijack method.
 | 
					 | 
				
			||||||
func (w *response) Hijack() { w.hijacked = true }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Close implements the ResponseWriter.Close method
 | 
					 | 
				
			||||||
func (w *response) Close() error {
 | 
					 | 
				
			||||||
	if w.closed {
 | 
					 | 
				
			||||||
		return &Error{err: "connection already closed"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	w.closed = true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch {
 | 
					 | 
				
			||||||
	case w.udp != nil:
 | 
					 | 
				
			||||||
		// Can't close the udp conn, as that is actually the listener.
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	case w.tcp != nil:
 | 
					 | 
				
			||||||
		return w.tcp.Close()
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		panic("dns: internal error: udp and tcp both nil")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ConnectionState() implements the ConnectionStater.ConnectionState() interface.
 | 
					 | 
				
			||||||
func (w *response) ConnectionState() *tls.ConnectionState {
 | 
					 | 
				
			||||||
	type tlsConnectionStater interface {
 | 
					 | 
				
			||||||
		ConnectionState() tls.ConnectionState
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if v, ok := w.tcp.(tlsConnectionStater); ok {
 | 
					 | 
				
			||||||
		t := v.ConnectionState()
 | 
					 | 
				
			||||||
		return &t
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										197
									
								
								vendor/github.com/miekg/dns/sig0.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										197
									
								
								vendor/github.com/miekg/dns/sig0.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,197 +0,0 @@
 | 
				
			|||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"crypto"
 | 
					 | 
				
			||||||
	"crypto/ecdsa"
 | 
					 | 
				
			||||||
	"crypto/rsa"
 | 
					 | 
				
			||||||
	"encoding/binary"
 | 
					 | 
				
			||||||
	"math/big"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Sign signs a dns.Msg. It fills the signature with the appropriate data.
 | 
					 | 
				
			||||||
// The SIG record should have the SignerName, KeyTag, Algorithm, Inception
 | 
					 | 
				
			||||||
// and Expiration set.
 | 
					 | 
				
			||||||
func (rr *SIG) Sign(k crypto.Signer, m *Msg) ([]byte, error) {
 | 
					 | 
				
			||||||
	if k == nil {
 | 
					 | 
				
			||||||
		return nil, ErrPrivKey
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 {
 | 
					 | 
				
			||||||
		return nil, ErrKey
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rr.Hdr = RR_Header{Name: ".", Rrtype: TypeSIG, Class: ClassANY, Ttl: 0}
 | 
					 | 
				
			||||||
	rr.OrigTtl, rr.TypeCovered, rr.Labels = 0, 0, 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	buf := make([]byte, m.Len()+Len(rr))
 | 
					 | 
				
			||||||
	mbuf, err := m.PackBuffer(buf)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if &buf[0] != &mbuf[0] {
 | 
					 | 
				
			||||||
		return nil, ErrBuf
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	off, err := PackRR(rr, buf, len(mbuf), nil, false)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	buf = buf[:off:cap(buf)]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	hash, ok := AlgorithmToHash[rr.Algorithm]
 | 
					 | 
				
			||||||
	if !ok {
 | 
					 | 
				
			||||||
		return nil, ErrAlg
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	hasher := hash.New()
 | 
					 | 
				
			||||||
	// Write SIG rdata
 | 
					 | 
				
			||||||
	hasher.Write(buf[len(mbuf)+1+2+2+4+2:])
 | 
					 | 
				
			||||||
	// Write message
 | 
					 | 
				
			||||||
	hasher.Write(buf[:len(mbuf)])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	signature, err := sign(k, hasher.Sum(nil), hash, rr.Algorithm)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rr.Signature = toBase64(signature)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	buf = append(buf, signature...)
 | 
					 | 
				
			||||||
	if len(buf) > int(^uint16(0)) {
 | 
					 | 
				
			||||||
		return nil, ErrBuf
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// Adjust sig data length
 | 
					 | 
				
			||||||
	rdoff := len(mbuf) + 1 + 2 + 2 + 4
 | 
					 | 
				
			||||||
	rdlen := binary.BigEndian.Uint16(buf[rdoff:])
 | 
					 | 
				
			||||||
	rdlen += uint16(len(signature))
 | 
					 | 
				
			||||||
	binary.BigEndian.PutUint16(buf[rdoff:], rdlen)
 | 
					 | 
				
			||||||
	// Adjust additional count
 | 
					 | 
				
			||||||
	adc := binary.BigEndian.Uint16(buf[10:])
 | 
					 | 
				
			||||||
	adc++
 | 
					 | 
				
			||||||
	binary.BigEndian.PutUint16(buf[10:], adc)
 | 
					 | 
				
			||||||
	return buf, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Verify validates the message buf using the key k.
 | 
					 | 
				
			||||||
// It's assumed that buf is a valid message from which rr was unpacked.
 | 
					 | 
				
			||||||
func (rr *SIG) Verify(k *KEY, buf []byte) error {
 | 
					 | 
				
			||||||
	if k == nil {
 | 
					 | 
				
			||||||
		return ErrKey
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 {
 | 
					 | 
				
			||||||
		return ErrKey
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var hash crypto.Hash
 | 
					 | 
				
			||||||
	switch rr.Algorithm {
 | 
					 | 
				
			||||||
	case RSASHA1:
 | 
					 | 
				
			||||||
		hash = crypto.SHA1
 | 
					 | 
				
			||||||
	case RSASHA256, ECDSAP256SHA256:
 | 
					 | 
				
			||||||
		hash = crypto.SHA256
 | 
					 | 
				
			||||||
	case ECDSAP384SHA384:
 | 
					 | 
				
			||||||
		hash = crypto.SHA384
 | 
					 | 
				
			||||||
	case RSASHA512:
 | 
					 | 
				
			||||||
		hash = crypto.SHA512
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return ErrAlg
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	hasher := hash.New()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	buflen := len(buf)
 | 
					 | 
				
			||||||
	qdc := binary.BigEndian.Uint16(buf[4:])
 | 
					 | 
				
			||||||
	anc := binary.BigEndian.Uint16(buf[6:])
 | 
					 | 
				
			||||||
	auc := binary.BigEndian.Uint16(buf[8:])
 | 
					 | 
				
			||||||
	adc := binary.BigEndian.Uint16(buf[10:])
 | 
					 | 
				
			||||||
	offset := headerSize
 | 
					 | 
				
			||||||
	var err error
 | 
					 | 
				
			||||||
	for i := uint16(0); i < qdc && offset < buflen; i++ {
 | 
					 | 
				
			||||||
		_, offset, err = UnpackDomainName(buf, offset)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		// Skip past Type and Class
 | 
					 | 
				
			||||||
		offset += 2 + 2
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for i := uint16(1); i < anc+auc+adc && offset < buflen; i++ {
 | 
					 | 
				
			||||||
		_, offset, err = UnpackDomainName(buf, offset)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		// Skip past Type, Class and TTL
 | 
					 | 
				
			||||||
		offset += 2 + 2 + 4
 | 
					 | 
				
			||||||
		if offset+1 >= buflen {
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		rdlen := binary.BigEndian.Uint16(buf[offset:])
 | 
					 | 
				
			||||||
		offset += 2
 | 
					 | 
				
			||||||
		offset += int(rdlen)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if offset >= buflen {
 | 
					 | 
				
			||||||
		return &Error{err: "overflowing unpacking signed message"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// offset should be just prior to SIG
 | 
					 | 
				
			||||||
	bodyend := offset
 | 
					 | 
				
			||||||
	// owner name SHOULD be root
 | 
					 | 
				
			||||||
	_, offset, err = UnpackDomainName(buf, offset)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// Skip Type, Class, TTL, RDLen
 | 
					 | 
				
			||||||
	offset += 2 + 2 + 4 + 2
 | 
					 | 
				
			||||||
	sigstart := offset
 | 
					 | 
				
			||||||
	// Skip Type Covered, Algorithm, Labels, Original TTL
 | 
					 | 
				
			||||||
	offset += 2 + 1 + 1 + 4
 | 
					 | 
				
			||||||
	if offset+4+4 >= buflen {
 | 
					 | 
				
			||||||
		return &Error{err: "overflow unpacking signed message"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	expire := binary.BigEndian.Uint32(buf[offset:])
 | 
					 | 
				
			||||||
	offset += 4
 | 
					 | 
				
			||||||
	incept := binary.BigEndian.Uint32(buf[offset:])
 | 
					 | 
				
			||||||
	offset += 4
 | 
					 | 
				
			||||||
	now := uint32(time.Now().Unix())
 | 
					 | 
				
			||||||
	if now < incept || now > expire {
 | 
					 | 
				
			||||||
		return ErrTime
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// Skip key tag
 | 
					 | 
				
			||||||
	offset += 2
 | 
					 | 
				
			||||||
	var signername string
 | 
					 | 
				
			||||||
	signername, offset, err = UnpackDomainName(buf, offset)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// If key has come from the DNS name compression might
 | 
					 | 
				
			||||||
	// have mangled the case of the name
 | 
					 | 
				
			||||||
	if !strings.EqualFold(signername, k.Header().Name) {
 | 
					 | 
				
			||||||
		return &Error{err: "signer name doesn't match key name"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	sigend := offset
 | 
					 | 
				
			||||||
	hasher.Write(buf[sigstart:sigend])
 | 
					 | 
				
			||||||
	hasher.Write(buf[:10])
 | 
					 | 
				
			||||||
	hasher.Write([]byte{
 | 
					 | 
				
			||||||
		byte((adc - 1) << 8),
 | 
					 | 
				
			||||||
		byte(adc - 1),
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
	hasher.Write(buf[12:bodyend])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	hashed := hasher.Sum(nil)
 | 
					 | 
				
			||||||
	sig := buf[sigend:]
 | 
					 | 
				
			||||||
	switch k.Algorithm {
 | 
					 | 
				
			||||||
	case RSASHA1, RSASHA256, RSASHA512:
 | 
					 | 
				
			||||||
		pk := k.publicKeyRSA()
 | 
					 | 
				
			||||||
		if pk != nil {
 | 
					 | 
				
			||||||
			return rsa.VerifyPKCS1v15(pk, hash, hashed, sig)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	case ECDSAP256SHA256, ECDSAP384SHA384:
 | 
					 | 
				
			||||||
		pk := k.publicKeyECDSA()
 | 
					 | 
				
			||||||
		r := new(big.Int).SetBytes(sig[:len(sig)/2])
 | 
					 | 
				
			||||||
		s := new(big.Int).SetBytes(sig[len(sig)/2:])
 | 
					 | 
				
			||||||
		if pk != nil {
 | 
					 | 
				
			||||||
			if ecdsa.Verify(pk, hashed, r, s) {
 | 
					 | 
				
			||||||
				return nil
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return ErrSig
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return ErrKeyAlg
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										61
									
								
								vendor/github.com/miekg/dns/singleinflight.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										61
									
								
								vendor/github.com/miekg/dns/singleinflight.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,61 +0,0 @@
 | 
				
			|||||||
// Copyright 2013 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Adapted for dns package usage by Miek Gieben.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "sync"
 | 
					 | 
				
			||||||
import "time"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// call is an in-flight or completed singleflight.Do call
 | 
					 | 
				
			||||||
type call struct {
 | 
					 | 
				
			||||||
	wg   sync.WaitGroup
 | 
					 | 
				
			||||||
	val  *Msg
 | 
					 | 
				
			||||||
	rtt  time.Duration
 | 
					 | 
				
			||||||
	err  error
 | 
					 | 
				
			||||||
	dups int
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// singleflight represents a class of work and forms a namespace in
 | 
					 | 
				
			||||||
// which units of work can be executed with duplicate suppression.
 | 
					 | 
				
			||||||
type singleflight struct {
 | 
					 | 
				
			||||||
	sync.Mutex                  // protects m
 | 
					 | 
				
			||||||
	m          map[string]*call // lazily initialized
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dontDeleteForTesting bool // this is only to be used by TestConcurrentExchanges
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Do executes and returns the results of the given function, making
 | 
					 | 
				
			||||||
// sure that only one execution is in-flight for a given key at a
 | 
					 | 
				
			||||||
// time. If a duplicate comes in, the duplicate caller waits for the
 | 
					 | 
				
			||||||
// original to complete and receives the same results.
 | 
					 | 
				
			||||||
// The return value shared indicates whether v was given to multiple callers.
 | 
					 | 
				
			||||||
func (g *singleflight) Do(key string, fn func() (*Msg, time.Duration, error)) (v *Msg, rtt time.Duration, err error, shared bool) {
 | 
					 | 
				
			||||||
	g.Lock()
 | 
					 | 
				
			||||||
	if g.m == nil {
 | 
					 | 
				
			||||||
		g.m = make(map[string]*call)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if c, ok := g.m[key]; ok {
 | 
					 | 
				
			||||||
		c.dups++
 | 
					 | 
				
			||||||
		g.Unlock()
 | 
					 | 
				
			||||||
		c.wg.Wait()
 | 
					 | 
				
			||||||
		return c.val, c.rtt, c.err, true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	c := new(call)
 | 
					 | 
				
			||||||
	c.wg.Add(1)
 | 
					 | 
				
			||||||
	g.m[key] = c
 | 
					 | 
				
			||||||
	g.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	c.val, c.rtt, c.err = fn()
 | 
					 | 
				
			||||||
	c.wg.Done()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if !g.dontDeleteForTesting {
 | 
					 | 
				
			||||||
		g.Lock()
 | 
					 | 
				
			||||||
		delete(g.m, key)
 | 
					 | 
				
			||||||
		g.Unlock()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return c.val, c.rtt, c.err, c.dups > 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										44
									
								
								vendor/github.com/miekg/dns/smimea.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										44
									
								
								vendor/github.com/miekg/dns/smimea.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,44 +0,0 @@
 | 
				
			|||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"crypto/sha256"
 | 
					 | 
				
			||||||
	"crypto/x509"
 | 
					 | 
				
			||||||
	"encoding/hex"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Sign creates a SMIMEA record from an SSL certificate.
 | 
					 | 
				
			||||||
func (r *SMIMEA) Sign(usage, selector, matchingType int, cert *x509.Certificate) (err error) {
 | 
					 | 
				
			||||||
	r.Hdr.Rrtype = TypeSMIMEA
 | 
					 | 
				
			||||||
	r.Usage = uint8(usage)
 | 
					 | 
				
			||||||
	r.Selector = uint8(selector)
 | 
					 | 
				
			||||||
	r.MatchingType = uint8(matchingType)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	r.Certificate, err = CertificateToDANE(r.Selector, r.MatchingType, cert)
 | 
					 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Verify verifies a SMIMEA record against an SSL certificate. If it is OK
 | 
					 | 
				
			||||||
// a nil error is returned.
 | 
					 | 
				
			||||||
func (r *SMIMEA) Verify(cert *x509.Certificate) error {
 | 
					 | 
				
			||||||
	c, err := CertificateToDANE(r.Selector, r.MatchingType, cert)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err // Not also ErrSig?
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if r.Certificate == c {
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return ErrSig // ErrSig, really?
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SMIMEAName returns the ownername of a SMIMEA resource record as per the
 | 
					 | 
				
			||||||
// format specified in RFC 'draft-ietf-dane-smime-12' Section 2 and 3
 | 
					 | 
				
			||||||
func SMIMEAName(email, domain string) (string, error) {
 | 
					 | 
				
			||||||
	hasher := sha256.New()
 | 
					 | 
				
			||||||
	hasher.Write([]byte(email))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// RFC Section 3: "The local-part is hashed using the SHA2-256
 | 
					 | 
				
			||||||
	// algorithm with the hash truncated to 28 octets and
 | 
					 | 
				
			||||||
	// represented in its hexadecimal representation to become the
 | 
					 | 
				
			||||||
	// left-most label in the prepared domain name"
 | 
					 | 
				
			||||||
	return hex.EncodeToString(hasher.Sum(nil)[:28]) + "." + "_smimecert." + domain, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										744
									
								
								vendor/github.com/miekg/dns/svcb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										744
									
								
								vendor/github.com/miekg/dns/svcb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,744 +0,0 @@
 | 
				
			|||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"encoding/binary"
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"net"
 | 
					 | 
				
			||||||
	"sort"
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type SVCBKey uint16
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Keys defined in draft-ietf-dnsop-svcb-https-01 Section 12.3.2.
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	SVCB_MANDATORY       SVCBKey = 0
 | 
					 | 
				
			||||||
	SVCB_ALPN            SVCBKey = 1
 | 
					 | 
				
			||||||
	SVCB_NO_DEFAULT_ALPN SVCBKey = 2
 | 
					 | 
				
			||||||
	SVCB_PORT            SVCBKey = 3
 | 
					 | 
				
			||||||
	SVCB_IPV4HINT        SVCBKey = 4
 | 
					 | 
				
			||||||
	SVCB_ECHCONFIG       SVCBKey = 5
 | 
					 | 
				
			||||||
	SVCB_IPV6HINT        SVCBKey = 6
 | 
					 | 
				
			||||||
	svcb_RESERVED        SVCBKey = 65535
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var svcbKeyToStringMap = map[SVCBKey]string{
 | 
					 | 
				
			||||||
	SVCB_MANDATORY:       "mandatory",
 | 
					 | 
				
			||||||
	SVCB_ALPN:            "alpn",
 | 
					 | 
				
			||||||
	SVCB_NO_DEFAULT_ALPN: "no-default-alpn",
 | 
					 | 
				
			||||||
	SVCB_PORT:            "port",
 | 
					 | 
				
			||||||
	SVCB_IPV4HINT:        "ipv4hint",
 | 
					 | 
				
			||||||
	SVCB_ECHCONFIG:       "echconfig",
 | 
					 | 
				
			||||||
	SVCB_IPV6HINT:        "ipv6hint",
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var svcbStringToKeyMap = reverseSVCBKeyMap(svcbKeyToStringMap)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func reverseSVCBKeyMap(m map[SVCBKey]string) map[string]SVCBKey {
 | 
					 | 
				
			||||||
	n := make(map[string]SVCBKey, len(m))
 | 
					 | 
				
			||||||
	for u, s := range m {
 | 
					 | 
				
			||||||
		n[s] = u
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return n
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// String takes the numerical code of an SVCB key and returns its name.
 | 
					 | 
				
			||||||
// Returns an empty string for reserved keys.
 | 
					 | 
				
			||||||
// Accepts unassigned keys as well as experimental/private keys.
 | 
					 | 
				
			||||||
func (key SVCBKey) String() string {
 | 
					 | 
				
			||||||
	if x := svcbKeyToStringMap[key]; x != "" {
 | 
					 | 
				
			||||||
		return x
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if key == svcb_RESERVED {
 | 
					 | 
				
			||||||
		return ""
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return "key" + strconv.FormatUint(uint64(key), 10)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// svcbStringToKey returns the numerical code of an SVCB key.
 | 
					 | 
				
			||||||
// Returns svcb_RESERVED for reserved/invalid keys.
 | 
					 | 
				
			||||||
// Accepts unassigned keys as well as experimental/private keys.
 | 
					 | 
				
			||||||
func svcbStringToKey(s string) SVCBKey {
 | 
					 | 
				
			||||||
	if strings.HasPrefix(s, "key") {
 | 
					 | 
				
			||||||
		a, err := strconv.ParseUint(s[3:], 10, 16)
 | 
					 | 
				
			||||||
		// no leading zeros
 | 
					 | 
				
			||||||
		// key shouldn't be registered
 | 
					 | 
				
			||||||
		if err != nil || a == 65535 || s[3] == '0' || svcbKeyToStringMap[SVCBKey(a)] != "" {
 | 
					 | 
				
			||||||
			return svcb_RESERVED
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return SVCBKey(a)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if key, ok := svcbStringToKeyMap[s]; ok {
 | 
					 | 
				
			||||||
		return key
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return svcb_RESERVED
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (rr *SVCB) parse(c *zlexer, o string) *ParseError {
 | 
					 | 
				
			||||||
	l, _ := c.Next()
 | 
					 | 
				
			||||||
	i, e := strconv.ParseUint(l.token, 10, 16)
 | 
					 | 
				
			||||||
	if e != nil || l.err {
 | 
					 | 
				
			||||||
		return &ParseError{l.token, "bad SVCB priority", l}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	rr.Priority = uint16(i)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	c.Next()        // zBlank
 | 
					 | 
				
			||||||
	l, _ = c.Next() // zString
 | 
					 | 
				
			||||||
	rr.Target = l.token
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	name, nameOk := toAbsoluteName(l.token, o)
 | 
					 | 
				
			||||||
	if l.err || !nameOk {
 | 
					 | 
				
			||||||
		return &ParseError{l.token, "bad SVCB Target", l}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	rr.Target = name
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Values (if any)
 | 
					 | 
				
			||||||
	l, _ = c.Next()
 | 
					 | 
				
			||||||
	var xs []SVCBKeyValue
 | 
					 | 
				
			||||||
	// Helps require whitespace between pairs.
 | 
					 | 
				
			||||||
	// Prevents key1000="a"key1001=...
 | 
					 | 
				
			||||||
	canHaveNextKey := true
 | 
					 | 
				
			||||||
	for l.value != zNewline && l.value != zEOF {
 | 
					 | 
				
			||||||
		switch l.value {
 | 
					 | 
				
			||||||
		case zString:
 | 
					 | 
				
			||||||
			if !canHaveNextKey {
 | 
					 | 
				
			||||||
				// The key we can now read was probably meant to be
 | 
					 | 
				
			||||||
				// a part of the last value.
 | 
					 | 
				
			||||||
				return &ParseError{l.token, "bad SVCB value quotation", l}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			// In key=value pairs, value does not have to be quoted unless value
 | 
					 | 
				
			||||||
			// contains whitespace. And keys don't need to have values.
 | 
					 | 
				
			||||||
			// Similarly, keys with an equality signs after them don't need values.
 | 
					 | 
				
			||||||
			// l.token includes at least up to the first equality sign.
 | 
					 | 
				
			||||||
			idx := strings.IndexByte(l.token, '=')
 | 
					 | 
				
			||||||
			var key, value string
 | 
					 | 
				
			||||||
			if idx < 0 {
 | 
					 | 
				
			||||||
				// Key with no value and no equality sign
 | 
					 | 
				
			||||||
				key = l.token
 | 
					 | 
				
			||||||
			} else if idx == 0 {
 | 
					 | 
				
			||||||
				return &ParseError{l.token, "bad SVCB key", l}
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				key, value = l.token[:idx], l.token[idx+1:]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				if value == "" {
 | 
					 | 
				
			||||||
					// We have a key and an equality sign. Maybe we have nothing
 | 
					 | 
				
			||||||
					// after "=" or we have a double quote.
 | 
					 | 
				
			||||||
					l, _ = c.Next()
 | 
					 | 
				
			||||||
					if l.value == zQuote {
 | 
					 | 
				
			||||||
						// Only needed when value ends with double quotes.
 | 
					 | 
				
			||||||
						// Any value starting with zQuote ends with it.
 | 
					 | 
				
			||||||
						canHaveNextKey = false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
						l, _ = c.Next()
 | 
					 | 
				
			||||||
						switch l.value {
 | 
					 | 
				
			||||||
						case zString:
 | 
					 | 
				
			||||||
							// We have a value in double quotes.
 | 
					 | 
				
			||||||
							value = l.token
 | 
					 | 
				
			||||||
							l, _ = c.Next()
 | 
					 | 
				
			||||||
							if l.value != zQuote {
 | 
					 | 
				
			||||||
								return &ParseError{l.token, "SVCB unterminated value", l}
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
						case zQuote:
 | 
					 | 
				
			||||||
							// There's nothing in double quotes.
 | 
					 | 
				
			||||||
						default:
 | 
					 | 
				
			||||||
							return &ParseError{l.token, "bad SVCB value", l}
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			kv := makeSVCBKeyValue(svcbStringToKey(key))
 | 
					 | 
				
			||||||
			if kv == nil {
 | 
					 | 
				
			||||||
				return &ParseError{l.token, "bad SVCB key", l}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if err := kv.parse(value); err != nil {
 | 
					 | 
				
			||||||
				return &ParseError{l.token, err.Error(), l}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			xs = append(xs, kv)
 | 
					 | 
				
			||||||
		case zQuote:
 | 
					 | 
				
			||||||
			return &ParseError{l.token, "SVCB key can't contain double quotes", l}
 | 
					 | 
				
			||||||
		case zBlank:
 | 
					 | 
				
			||||||
			canHaveNextKey = true
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			return &ParseError{l.token, "bad SVCB values", l}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		l, _ = c.Next()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	rr.Value = xs
 | 
					 | 
				
			||||||
	if rr.Priority == 0 && len(xs) > 0 {
 | 
					 | 
				
			||||||
		return &ParseError{l.token, "SVCB aliasform can't have values", l}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// makeSVCBKeyValue returns an SVCBKeyValue struct with the key or nil for reserved keys.
 | 
					 | 
				
			||||||
func makeSVCBKeyValue(key SVCBKey) SVCBKeyValue {
 | 
					 | 
				
			||||||
	switch key {
 | 
					 | 
				
			||||||
	case SVCB_MANDATORY:
 | 
					 | 
				
			||||||
		return new(SVCBMandatory)
 | 
					 | 
				
			||||||
	case SVCB_ALPN:
 | 
					 | 
				
			||||||
		return new(SVCBAlpn)
 | 
					 | 
				
			||||||
	case SVCB_NO_DEFAULT_ALPN:
 | 
					 | 
				
			||||||
		return new(SVCBNoDefaultAlpn)
 | 
					 | 
				
			||||||
	case SVCB_PORT:
 | 
					 | 
				
			||||||
		return new(SVCBPort)
 | 
					 | 
				
			||||||
	case SVCB_IPV4HINT:
 | 
					 | 
				
			||||||
		return new(SVCBIPv4Hint)
 | 
					 | 
				
			||||||
	case SVCB_ECHCONFIG:
 | 
					 | 
				
			||||||
		return new(SVCBECHConfig)
 | 
					 | 
				
			||||||
	case SVCB_IPV6HINT:
 | 
					 | 
				
			||||||
		return new(SVCBIPv6Hint)
 | 
					 | 
				
			||||||
	case svcb_RESERVED:
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		e := new(SVCBLocal)
 | 
					 | 
				
			||||||
		e.KeyCode = key
 | 
					 | 
				
			||||||
		return e
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SVCB RR. See RFC xxxx (https://tools.ietf.org/html/draft-ietf-dnsop-svcb-https-01).
 | 
					 | 
				
			||||||
type SVCB struct {
 | 
					 | 
				
			||||||
	Hdr      RR_Header
 | 
					 | 
				
			||||||
	Priority uint16
 | 
					 | 
				
			||||||
	Target   string         `dns:"domain-name"`
 | 
					 | 
				
			||||||
	Value    []SVCBKeyValue `dns:"pairs"` // Value must be empty if Priority is non-zero.
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// HTTPS RR. Everything valid for SVCB applies to HTTPS as well.
 | 
					 | 
				
			||||||
// Except that the HTTPS record is intended for use with the HTTP and HTTPS protocols.
 | 
					 | 
				
			||||||
type HTTPS struct {
 | 
					 | 
				
			||||||
	SVCB
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (rr *HTTPS) String() string {
 | 
					 | 
				
			||||||
	return rr.SVCB.String()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (rr *HTTPS) parse(c *zlexer, o string) *ParseError {
 | 
					 | 
				
			||||||
	return rr.SVCB.parse(c, o)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SVCBKeyValue defines a key=value pair for the SVCB RR type.
 | 
					 | 
				
			||||||
// An SVCB RR can have multiple SVCBKeyValues appended to it.
 | 
					 | 
				
			||||||
type SVCBKeyValue interface {
 | 
					 | 
				
			||||||
	Key() SVCBKey          // Key returns the numerical key code.
 | 
					 | 
				
			||||||
	pack() ([]byte, error) // pack returns the encoded value.
 | 
					 | 
				
			||||||
	unpack([]byte) error   // unpack sets the value.
 | 
					 | 
				
			||||||
	String() string        // String returns the string representation of the value.
 | 
					 | 
				
			||||||
	parse(string) error    // parse sets the value to the given string representation of the value.
 | 
					 | 
				
			||||||
	copy() SVCBKeyValue    // copy returns a deep-copy of the pair.
 | 
					 | 
				
			||||||
	len() int              // len returns the length of value in the wire format.
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SVCBMandatory pair adds to required keys that must be interpreted for the RR
 | 
					 | 
				
			||||||
// to be functional.
 | 
					 | 
				
			||||||
// Basic use pattern for creating a mandatory option:
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//	s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}}
 | 
					 | 
				
			||||||
//	e := new(dns.SVCBMandatory)
 | 
					 | 
				
			||||||
//	e.Code = []uint16{65403}
 | 
					 | 
				
			||||||
//	s.Value = append(s.Value, e)
 | 
					 | 
				
			||||||
type SVCBMandatory struct {
 | 
					 | 
				
			||||||
	Code []SVCBKey // Must not include mandatory
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (*SVCBMandatory) Key() SVCBKey { return SVCB_MANDATORY }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBMandatory) String() string {
 | 
					 | 
				
			||||||
	str := make([]string, len(s.Code))
 | 
					 | 
				
			||||||
	for i, e := range s.Code {
 | 
					 | 
				
			||||||
		str[i] = e.String()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return strings.Join(str, ",")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBMandatory) pack() ([]byte, error) {
 | 
					 | 
				
			||||||
	codes := append([]SVCBKey(nil), s.Code...)
 | 
					 | 
				
			||||||
	sort.Slice(codes, func(i, j int) bool {
 | 
					 | 
				
			||||||
		return codes[i] < codes[j]
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
	b := make([]byte, 2*len(codes))
 | 
					 | 
				
			||||||
	for i, e := range codes {
 | 
					 | 
				
			||||||
		binary.BigEndian.PutUint16(b[2*i:], uint16(e))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return b, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBMandatory) unpack(b []byte) error {
 | 
					 | 
				
			||||||
	if len(b)%2 != 0 {
 | 
					 | 
				
			||||||
		return errors.New("dns: svcbmandatory: value length is not a multiple of 2")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	codes := make([]SVCBKey, 0, len(b)/2)
 | 
					 | 
				
			||||||
	for i := 0; i < len(b); i += 2 {
 | 
					 | 
				
			||||||
		// We assume strictly increasing order.
 | 
					 | 
				
			||||||
		codes = append(codes, SVCBKey(binary.BigEndian.Uint16(b[i:])))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	s.Code = codes
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBMandatory) parse(b string) error {
 | 
					 | 
				
			||||||
	str := strings.Split(b, ",")
 | 
					 | 
				
			||||||
	codes := make([]SVCBKey, 0, len(str))
 | 
					 | 
				
			||||||
	for _, e := range str {
 | 
					 | 
				
			||||||
		codes = append(codes, svcbStringToKey(e))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	s.Code = codes
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBMandatory) len() int {
 | 
					 | 
				
			||||||
	return 2 * len(s.Code)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBMandatory) copy() SVCBKeyValue {
 | 
					 | 
				
			||||||
	return &SVCBMandatory{
 | 
					 | 
				
			||||||
		append([]SVCBKey(nil), s.Code...),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SVCBAlpn pair is used to list supported connection protocols.
 | 
					 | 
				
			||||||
// Protocol ids can be found at:
 | 
					 | 
				
			||||||
// https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
 | 
					 | 
				
			||||||
// Basic use pattern for creating an alpn option:
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//	h := new(dns.HTTPS)
 | 
					 | 
				
			||||||
//	h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
 | 
					 | 
				
			||||||
//	e := new(dns.SVCBAlpn)
 | 
					 | 
				
			||||||
//	e.Alpn = []string{"h2", "http/1.1"}
 | 
					 | 
				
			||||||
//	h.Value = append(o.Value, e)
 | 
					 | 
				
			||||||
type SVCBAlpn struct {
 | 
					 | 
				
			||||||
	Alpn []string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (*SVCBAlpn) Key() SVCBKey     { return SVCB_ALPN }
 | 
					 | 
				
			||||||
func (s *SVCBAlpn) String() string { return strings.Join(s.Alpn, ",") }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBAlpn) pack() ([]byte, error) {
 | 
					 | 
				
			||||||
	// Liberally estimate the size of an alpn as 10 octets
 | 
					 | 
				
			||||||
	b := make([]byte, 0, 10*len(s.Alpn))
 | 
					 | 
				
			||||||
	for _, e := range s.Alpn {
 | 
					 | 
				
			||||||
		if len(e) == 0 {
 | 
					 | 
				
			||||||
			return nil, errors.New("dns: svcbalpn: empty alpn-id")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if len(e) > 255 {
 | 
					 | 
				
			||||||
			return nil, errors.New("dns: svcbalpn: alpn-id too long")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		b = append(b, byte(len(e)))
 | 
					 | 
				
			||||||
		b = append(b, e...)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return b, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBAlpn) unpack(b []byte) error {
 | 
					 | 
				
			||||||
	// Estimate the size of the smallest alpn as 4 bytes
 | 
					 | 
				
			||||||
	alpn := make([]string, 0, len(b)/4)
 | 
					 | 
				
			||||||
	for i := 0; i < len(b); {
 | 
					 | 
				
			||||||
		length := int(b[i])
 | 
					 | 
				
			||||||
		i++
 | 
					 | 
				
			||||||
		if i+length > len(b) {
 | 
					 | 
				
			||||||
			return errors.New("dns: svcbalpn: alpn array overflowing")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		alpn = append(alpn, string(b[i:i+length]))
 | 
					 | 
				
			||||||
		i += length
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	s.Alpn = alpn
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBAlpn) parse(b string) error {
 | 
					 | 
				
			||||||
	s.Alpn = strings.Split(b, ",")
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBAlpn) len() int {
 | 
					 | 
				
			||||||
	var l int
 | 
					 | 
				
			||||||
	for _, e := range s.Alpn {
 | 
					 | 
				
			||||||
		l += 1 + len(e)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBAlpn) copy() SVCBKeyValue {
 | 
					 | 
				
			||||||
	return &SVCBAlpn{
 | 
					 | 
				
			||||||
		append([]string(nil), s.Alpn...),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SVCBNoDefaultAlpn pair signifies no support for default connection protocols.
 | 
					 | 
				
			||||||
// Basic use pattern for creating a no-default-alpn option:
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//	s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}}
 | 
					 | 
				
			||||||
//	e := new(dns.SVCBNoDefaultAlpn)
 | 
					 | 
				
			||||||
//	s.Value = append(s.Value, e)
 | 
					 | 
				
			||||||
type SVCBNoDefaultAlpn struct{}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (*SVCBNoDefaultAlpn) Key() SVCBKey          { return SVCB_NO_DEFAULT_ALPN }
 | 
					 | 
				
			||||||
func (*SVCBNoDefaultAlpn) copy() SVCBKeyValue    { return &SVCBNoDefaultAlpn{} }
 | 
					 | 
				
			||||||
func (*SVCBNoDefaultAlpn) pack() ([]byte, error) { return []byte{}, nil }
 | 
					 | 
				
			||||||
func (*SVCBNoDefaultAlpn) String() string        { return "" }
 | 
					 | 
				
			||||||
func (*SVCBNoDefaultAlpn) len() int              { return 0 }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (*SVCBNoDefaultAlpn) unpack(b []byte) error {
 | 
					 | 
				
			||||||
	if len(b) != 0 {
 | 
					 | 
				
			||||||
		return errors.New("dns: svcbnodefaultalpn: no_default_alpn must have no value")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (*SVCBNoDefaultAlpn) parse(b string) error {
 | 
					 | 
				
			||||||
	if len(b) != 0 {
 | 
					 | 
				
			||||||
		return errors.New("dns: svcbnodefaultalpn: no_default_alpn must have no value")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SVCBPort pair defines the port for connection.
 | 
					 | 
				
			||||||
// Basic use pattern for creating a port option:
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//	s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}}
 | 
					 | 
				
			||||||
//	e := new(dns.SVCBPort)
 | 
					 | 
				
			||||||
//	e.Port = 80
 | 
					 | 
				
			||||||
//	s.Value = append(s.Value, e)
 | 
					 | 
				
			||||||
type SVCBPort struct {
 | 
					 | 
				
			||||||
	Port uint16
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (*SVCBPort) Key() SVCBKey         { return SVCB_PORT }
 | 
					 | 
				
			||||||
func (*SVCBPort) len() int             { return 2 }
 | 
					 | 
				
			||||||
func (s *SVCBPort) String() string     { return strconv.FormatUint(uint64(s.Port), 10) }
 | 
					 | 
				
			||||||
func (s *SVCBPort) copy() SVCBKeyValue { return &SVCBPort{s.Port} }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBPort) unpack(b []byte) error {
 | 
					 | 
				
			||||||
	if len(b) != 2 {
 | 
					 | 
				
			||||||
		return errors.New("dns: svcbport: port length is not exactly 2 octets")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	s.Port = binary.BigEndian.Uint16(b)
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBPort) pack() ([]byte, error) {
 | 
					 | 
				
			||||||
	b := make([]byte, 2)
 | 
					 | 
				
			||||||
	binary.BigEndian.PutUint16(b, s.Port)
 | 
					 | 
				
			||||||
	return b, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBPort) parse(b string) error {
 | 
					 | 
				
			||||||
	port, err := strconv.ParseUint(b, 10, 16)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return errors.New("dns: svcbport: port out of range")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	s.Port = uint16(port)
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SVCBIPv4Hint pair suggests an IPv4 address which may be used to open connections
 | 
					 | 
				
			||||||
// if A and AAAA record responses for SVCB's Target domain haven't been received.
 | 
					 | 
				
			||||||
// In that case, optionally, A and AAAA requests can be made, after which the connection
 | 
					 | 
				
			||||||
// to the hinted IP address may be terminated and a new connection may be opened.
 | 
					 | 
				
			||||||
// Basic use pattern for creating an ipv4hint option:
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//	h := new(dns.HTTPS)
 | 
					 | 
				
			||||||
//	h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
 | 
					 | 
				
			||||||
//	e := new(dns.SVCBIPv4Hint)
 | 
					 | 
				
			||||||
//	e.Hint = []net.IP{net.IPv4(1,1,1,1).To4()}
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//  Or
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//	e.Hint = []net.IP{net.ParseIP("1.1.1.1").To4()}
 | 
					 | 
				
			||||||
//	h.Value = append(h.Value, e)
 | 
					 | 
				
			||||||
type SVCBIPv4Hint struct {
 | 
					 | 
				
			||||||
	Hint []net.IP
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (*SVCBIPv4Hint) Key() SVCBKey { return SVCB_IPV4HINT }
 | 
					 | 
				
			||||||
func (s *SVCBIPv4Hint) len() int   { return 4 * len(s.Hint) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBIPv4Hint) pack() ([]byte, error) {
 | 
					 | 
				
			||||||
	b := make([]byte, 0, 4*len(s.Hint))
 | 
					 | 
				
			||||||
	for _, e := range s.Hint {
 | 
					 | 
				
			||||||
		x := e.To4()
 | 
					 | 
				
			||||||
		if x == nil {
 | 
					 | 
				
			||||||
			return nil, errors.New("dns: svcbipv4hint: expected ipv4, hint is ipv6")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		b = append(b, x...)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return b, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBIPv4Hint) unpack(b []byte) error {
 | 
					 | 
				
			||||||
	if len(b) == 0 || len(b)%4 != 0 {
 | 
					 | 
				
			||||||
		return errors.New("dns: svcbipv4hint: ipv4 address byte array length is not a multiple of 4")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	x := make([]net.IP, 0, len(b)/4)
 | 
					 | 
				
			||||||
	for i := 0; i < len(b); i += 4 {
 | 
					 | 
				
			||||||
		x = append(x, net.IP(b[i:i+4]))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	s.Hint = x
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBIPv4Hint) String() string {
 | 
					 | 
				
			||||||
	str := make([]string, len(s.Hint))
 | 
					 | 
				
			||||||
	for i, e := range s.Hint {
 | 
					 | 
				
			||||||
		x := e.To4()
 | 
					 | 
				
			||||||
		if x == nil {
 | 
					 | 
				
			||||||
			return "<nil>"
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		str[i] = x.String()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return strings.Join(str, ",")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBIPv4Hint) parse(b string) error {
 | 
					 | 
				
			||||||
	if strings.Contains(b, ":") {
 | 
					 | 
				
			||||||
		return errors.New("dns: svcbipv4hint: expected ipv4, got ipv6")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	str := strings.Split(b, ",")
 | 
					 | 
				
			||||||
	dst := make([]net.IP, len(str))
 | 
					 | 
				
			||||||
	for i, e := range str {
 | 
					 | 
				
			||||||
		ip := net.ParseIP(e).To4()
 | 
					 | 
				
			||||||
		if ip == nil {
 | 
					 | 
				
			||||||
			return errors.New("dns: svcbipv4hint: bad ip")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		dst[i] = ip
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	s.Hint = dst
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBIPv4Hint) copy() SVCBKeyValue {
 | 
					 | 
				
			||||||
	return &SVCBIPv4Hint{
 | 
					 | 
				
			||||||
		append([]net.IP(nil), s.Hint...),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SVCBECHConfig pair contains the ECHConfig structure defined in draft-ietf-tls-esni [RFC xxxx].
 | 
					 | 
				
			||||||
// Basic use pattern for creating an echconfig option:
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//	h := new(dns.HTTPS)
 | 
					 | 
				
			||||||
//	h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
 | 
					 | 
				
			||||||
//	e := new(dns.SVCBECHConfig)
 | 
					 | 
				
			||||||
//	e.ECH = []byte{0xfe, 0x08, ...}
 | 
					 | 
				
			||||||
//	h.Value = append(h.Value, e)
 | 
					 | 
				
			||||||
type SVCBECHConfig struct {
 | 
					 | 
				
			||||||
	ECH []byte
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (*SVCBECHConfig) Key() SVCBKey     { return SVCB_ECHCONFIG }
 | 
					 | 
				
			||||||
func (s *SVCBECHConfig) String() string { return toBase64(s.ECH) }
 | 
					 | 
				
			||||||
func (s *SVCBECHConfig) len() int       { return len(s.ECH) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBECHConfig) pack() ([]byte, error) {
 | 
					 | 
				
			||||||
	return append([]byte(nil), s.ECH...), nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBECHConfig) copy() SVCBKeyValue {
 | 
					 | 
				
			||||||
	return &SVCBECHConfig{
 | 
					 | 
				
			||||||
		append([]byte(nil), s.ECH...),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBECHConfig) unpack(b []byte) error {
 | 
					 | 
				
			||||||
	s.ECH = append([]byte(nil), b...)
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (s *SVCBECHConfig) parse(b string) error {
 | 
					 | 
				
			||||||
	x, err := fromBase64([]byte(b))
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return errors.New("dns: svcbechconfig: bad base64 echconfig")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	s.ECH = x
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SVCBIPv6Hint pair suggests an IPv6 address which may be used to open connections
 | 
					 | 
				
			||||||
// if A and AAAA record responses for SVCB's Target domain haven't been received.
 | 
					 | 
				
			||||||
// In that case, optionally, A and AAAA requests can be made, after which the
 | 
					 | 
				
			||||||
// connection to the hinted IP address may be terminated and a new connection may be opened.
 | 
					 | 
				
			||||||
// Basic use pattern for creating an ipv6hint option:
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//	h := new(dns.HTTPS)
 | 
					 | 
				
			||||||
//	h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
 | 
					 | 
				
			||||||
//	e := new(dns.SVCBIPv6Hint)
 | 
					 | 
				
			||||||
//	e.Hint = []net.IP{net.ParseIP("2001:db8::1")}
 | 
					 | 
				
			||||||
//	h.Value = append(h.Value, e)
 | 
					 | 
				
			||||||
type SVCBIPv6Hint struct {
 | 
					 | 
				
			||||||
	Hint []net.IP
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (*SVCBIPv6Hint) Key() SVCBKey { return SVCB_IPV6HINT }
 | 
					 | 
				
			||||||
func (s *SVCBIPv6Hint) len() int   { return 16 * len(s.Hint) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBIPv6Hint) pack() ([]byte, error) {
 | 
					 | 
				
			||||||
	b := make([]byte, 0, 16*len(s.Hint))
 | 
					 | 
				
			||||||
	for _, e := range s.Hint {
 | 
					 | 
				
			||||||
		if len(e) != net.IPv6len || e.To4() != nil {
 | 
					 | 
				
			||||||
			return nil, errors.New("dns: svcbipv6hint: expected ipv6, hint is ipv4")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		b = append(b, e...)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return b, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBIPv6Hint) unpack(b []byte) error {
 | 
					 | 
				
			||||||
	if len(b) == 0 || len(b)%16 != 0 {
 | 
					 | 
				
			||||||
		return errors.New("dns: svcbipv6hint: ipv6 address byte array length not a multiple of 16")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	x := make([]net.IP, 0, len(b)/16)
 | 
					 | 
				
			||||||
	for i := 0; i < len(b); i += 16 {
 | 
					 | 
				
			||||||
		ip := net.IP(b[i : i+16])
 | 
					 | 
				
			||||||
		if ip.To4() != nil {
 | 
					 | 
				
			||||||
			return errors.New("dns: svcbipv6hint: expected ipv6, got ipv4")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		x = append(x, ip)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	s.Hint = x
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBIPv6Hint) String() string {
 | 
					 | 
				
			||||||
	str := make([]string, len(s.Hint))
 | 
					 | 
				
			||||||
	for i, e := range s.Hint {
 | 
					 | 
				
			||||||
		if x := e.To4(); x != nil {
 | 
					 | 
				
			||||||
			return "<nil>"
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		str[i] = e.String()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return strings.Join(str, ",")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBIPv6Hint) parse(b string) error {
 | 
					 | 
				
			||||||
	if strings.Contains(b, ".") {
 | 
					 | 
				
			||||||
		return errors.New("dns: svcbipv6hint: expected ipv6, got ipv4")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	str := strings.Split(b, ",")
 | 
					 | 
				
			||||||
	dst := make([]net.IP, len(str))
 | 
					 | 
				
			||||||
	for i, e := range str {
 | 
					 | 
				
			||||||
		ip := net.ParseIP(e)
 | 
					 | 
				
			||||||
		if ip == nil {
 | 
					 | 
				
			||||||
			return errors.New("dns: svcbipv6hint: bad ip")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		dst[i] = ip
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	s.Hint = dst
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBIPv6Hint) copy() SVCBKeyValue {
 | 
					 | 
				
			||||||
	return &SVCBIPv6Hint{
 | 
					 | 
				
			||||||
		append([]net.IP(nil), s.Hint...),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SVCBLocal pair is intended for experimental/private use. The key is recommended
 | 
					 | 
				
			||||||
// to be in the range [SVCB_PRIVATE_LOWER, SVCB_PRIVATE_UPPER].
 | 
					 | 
				
			||||||
// Basic use pattern for creating a keyNNNNN option:
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//	h := new(dns.HTTPS)
 | 
					 | 
				
			||||||
//	h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
 | 
					 | 
				
			||||||
//	e := new(dns.SVCBLocal)
 | 
					 | 
				
			||||||
//	e.KeyCode = 65400
 | 
					 | 
				
			||||||
//	e.Data = []byte("abc")
 | 
					 | 
				
			||||||
//	h.Value = append(h.Value, e)
 | 
					 | 
				
			||||||
type SVCBLocal struct {
 | 
					 | 
				
			||||||
	KeyCode SVCBKey // Never 65535 or any assigned keys.
 | 
					 | 
				
			||||||
	Data    []byte  // All byte sequences are allowed.
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBLocal) Key() SVCBKey          { return s.KeyCode }
 | 
					 | 
				
			||||||
func (s *SVCBLocal) pack() ([]byte, error) { return append([]byte(nil), s.Data...), nil }
 | 
					 | 
				
			||||||
func (s *SVCBLocal) len() int              { return len(s.Data) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBLocal) unpack(b []byte) error {
 | 
					 | 
				
			||||||
	s.Data = append([]byte(nil), b...)
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBLocal) String() string {
 | 
					 | 
				
			||||||
	var str strings.Builder
 | 
					 | 
				
			||||||
	str.Grow(4 * len(s.Data))
 | 
					 | 
				
			||||||
	for _, e := range s.Data {
 | 
					 | 
				
			||||||
		if ' ' <= e && e <= '~' {
 | 
					 | 
				
			||||||
			switch e {
 | 
					 | 
				
			||||||
			case '"', ';', ' ', '\\':
 | 
					 | 
				
			||||||
				str.WriteByte('\\')
 | 
					 | 
				
			||||||
				str.WriteByte(e)
 | 
					 | 
				
			||||||
			default:
 | 
					 | 
				
			||||||
				str.WriteByte(e)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			str.WriteString(escapeByte(e))
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return str.String()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBLocal) parse(b string) error {
 | 
					 | 
				
			||||||
	data := make([]byte, 0, len(b))
 | 
					 | 
				
			||||||
	for i := 0; i < len(b); {
 | 
					 | 
				
			||||||
		if b[i] != '\\' {
 | 
					 | 
				
			||||||
			data = append(data, b[i])
 | 
					 | 
				
			||||||
			i++
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if i+1 == len(b) {
 | 
					 | 
				
			||||||
			return errors.New("dns: svcblocal: svcb private/experimental key escape unterminated")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if isDigit(b[i+1]) {
 | 
					 | 
				
			||||||
			if i+3 < len(b) && isDigit(b[i+2]) && isDigit(b[i+3]) {
 | 
					 | 
				
			||||||
				a, err := strconv.ParseUint(b[i+1:i+4], 10, 8)
 | 
					 | 
				
			||||||
				if err == nil {
 | 
					 | 
				
			||||||
					i += 4
 | 
					 | 
				
			||||||
					data = append(data, byte(a))
 | 
					 | 
				
			||||||
					continue
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return errors.New("dns: svcblocal: svcb private/experimental key bad escaped octet")
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			data = append(data, b[i+1])
 | 
					 | 
				
			||||||
			i += 2
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	s.Data = data
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SVCBLocal) copy() SVCBKeyValue {
 | 
					 | 
				
			||||||
	return &SVCBLocal{s.KeyCode,
 | 
					 | 
				
			||||||
		append([]byte(nil), s.Data...),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (rr *SVCB) String() string {
 | 
					 | 
				
			||||||
	s := rr.Hdr.String() +
 | 
					 | 
				
			||||||
		strconv.Itoa(int(rr.Priority)) + " " +
 | 
					 | 
				
			||||||
		sprintName(rr.Target)
 | 
					 | 
				
			||||||
	for _, e := range rr.Value {
 | 
					 | 
				
			||||||
		s += " " + e.Key().String() + "=\"" + e.String() + "\""
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return s
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// areSVCBPairArraysEqual checks if SVCBKeyValue arrays are equal after sorting their
 | 
					 | 
				
			||||||
// copies. arrA and arrB have equal lengths, otherwise zduplicate.go wouldn't call this function.
 | 
					 | 
				
			||||||
func areSVCBPairArraysEqual(a []SVCBKeyValue, b []SVCBKeyValue) bool {
 | 
					 | 
				
			||||||
	a = append([]SVCBKeyValue(nil), a...)
 | 
					 | 
				
			||||||
	b = append([]SVCBKeyValue(nil), b...)
 | 
					 | 
				
			||||||
	sort.Slice(a, func(i, j int) bool { return a[i].Key() < a[j].Key() })
 | 
					 | 
				
			||||||
	sort.Slice(b, func(i, j int) bool { return b[i].Key() < b[j].Key() })
 | 
					 | 
				
			||||||
	for i, e := range a {
 | 
					 | 
				
			||||||
		if e.Key() != b[i].Key() {
 | 
					 | 
				
			||||||
			return false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		b1, err1 := e.pack()
 | 
					 | 
				
			||||||
		b2, err2 := b[i].pack()
 | 
					 | 
				
			||||||
		if err1 != nil || err2 != nil || !bytes.Equal(b1, b2) {
 | 
					 | 
				
			||||||
			return false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										44
									
								
								vendor/github.com/miekg/dns/tlsa.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										44
									
								
								vendor/github.com/miekg/dns/tlsa.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,44 +0,0 @@
 | 
				
			|||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"crypto/x509"
 | 
					 | 
				
			||||||
	"net"
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Sign creates a TLSA record from an SSL certificate.
 | 
					 | 
				
			||||||
func (r *TLSA) Sign(usage, selector, matchingType int, cert *x509.Certificate) (err error) {
 | 
					 | 
				
			||||||
	r.Hdr.Rrtype = TypeTLSA
 | 
					 | 
				
			||||||
	r.Usage = uint8(usage)
 | 
					 | 
				
			||||||
	r.Selector = uint8(selector)
 | 
					 | 
				
			||||||
	r.MatchingType = uint8(matchingType)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	r.Certificate, err = CertificateToDANE(r.Selector, r.MatchingType, cert)
 | 
					 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Verify verifies a TLSA record against an SSL certificate. If it is OK
 | 
					 | 
				
			||||||
// a nil error is returned.
 | 
					 | 
				
			||||||
func (r *TLSA) Verify(cert *x509.Certificate) error {
 | 
					 | 
				
			||||||
	c, err := CertificateToDANE(r.Selector, r.MatchingType, cert)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err // Not also ErrSig?
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if r.Certificate == c {
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return ErrSig // ErrSig, really?
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// TLSAName returns the ownername of a TLSA resource record as per the
 | 
					 | 
				
			||||||
// rules specified in RFC 6698, Section 3.
 | 
					 | 
				
			||||||
func TLSAName(name, service, network string) (string, error) {
 | 
					 | 
				
			||||||
	if !IsFqdn(name) {
 | 
					 | 
				
			||||||
		return "", ErrFqdn
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	p, err := net.LookupPort(network, service)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return "", err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return "_" + strconv.Itoa(p) + "._" + network + "." + name, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										413
									
								
								vendor/github.com/miekg/dns/tsig.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										413
									
								
								vendor/github.com/miekg/dns/tsig.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,413 +0,0 @@
 | 
				
			|||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"crypto/hmac"
 | 
					 | 
				
			||||||
	"crypto/sha1"
 | 
					 | 
				
			||||||
	"crypto/sha256"
 | 
					 | 
				
			||||||
	"crypto/sha512"
 | 
					 | 
				
			||||||
	"encoding/binary"
 | 
					 | 
				
			||||||
	"encoding/hex"
 | 
					 | 
				
			||||||
	"hash"
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// HMAC hashing codes. These are transmitted as domain names.
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	HmacSHA1   = "hmac-sha1."
 | 
					 | 
				
			||||||
	HmacSHA224 = "hmac-sha224."
 | 
					 | 
				
			||||||
	HmacSHA256 = "hmac-sha256."
 | 
					 | 
				
			||||||
	HmacSHA384 = "hmac-sha384."
 | 
					 | 
				
			||||||
	HmacSHA512 = "hmac-sha512."
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	HmacMD5 = "hmac-md5.sig-alg.reg.int." // Deprecated: HmacMD5 is no longer supported.
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// TSIG is the RR the holds the transaction signature of a message.
 | 
					 | 
				
			||||||
// See RFC 2845 and RFC 4635.
 | 
					 | 
				
			||||||
type TSIG struct {
 | 
					 | 
				
			||||||
	Hdr        RR_Header
 | 
					 | 
				
			||||||
	Algorithm  string `dns:"domain-name"`
 | 
					 | 
				
			||||||
	TimeSigned uint64 `dns:"uint48"`
 | 
					 | 
				
			||||||
	Fudge      uint16
 | 
					 | 
				
			||||||
	MACSize    uint16
 | 
					 | 
				
			||||||
	MAC        string `dns:"size-hex:MACSize"`
 | 
					 | 
				
			||||||
	OrigId     uint16
 | 
					 | 
				
			||||||
	Error      uint16
 | 
					 | 
				
			||||||
	OtherLen   uint16
 | 
					 | 
				
			||||||
	OtherData  string `dns:"size-hex:OtherLen"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// TSIG has no official presentation format, but this will suffice.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (rr *TSIG) String() string {
 | 
					 | 
				
			||||||
	s := "\n;; TSIG PSEUDOSECTION:\n; " // add another semi-colon to signify TSIG does not have a presentation format
 | 
					 | 
				
			||||||
	s += rr.Hdr.String() +
 | 
					 | 
				
			||||||
		" " + rr.Algorithm +
 | 
					 | 
				
			||||||
		" " + tsigTimeToString(rr.TimeSigned) +
 | 
					 | 
				
			||||||
		" " + strconv.Itoa(int(rr.Fudge)) +
 | 
					 | 
				
			||||||
		" " + strconv.Itoa(int(rr.MACSize)) +
 | 
					 | 
				
			||||||
		" " + strings.ToUpper(rr.MAC) +
 | 
					 | 
				
			||||||
		" " + strconv.Itoa(int(rr.OrigId)) +
 | 
					 | 
				
			||||||
		" " + strconv.Itoa(int(rr.Error)) + // BIND prints NOERROR
 | 
					 | 
				
			||||||
		" " + strconv.Itoa(int(rr.OtherLen)) +
 | 
					 | 
				
			||||||
		" " + rr.OtherData
 | 
					 | 
				
			||||||
	return s
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (rr *TSIG) parse(c *zlexer, origin string) *ParseError {
 | 
					 | 
				
			||||||
	panic("dns: internal error: parse should never be called on TSIG")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// The following values must be put in wireformat, so that the MAC can be calculated.
 | 
					 | 
				
			||||||
// RFC 2845, section 3.4.2. TSIG Variables.
 | 
					 | 
				
			||||||
type tsigWireFmt struct {
 | 
					 | 
				
			||||||
	// From RR_Header
 | 
					 | 
				
			||||||
	Name  string `dns:"domain-name"`
 | 
					 | 
				
			||||||
	Class uint16
 | 
					 | 
				
			||||||
	Ttl   uint32
 | 
					 | 
				
			||||||
	// Rdata of the TSIG
 | 
					 | 
				
			||||||
	Algorithm  string `dns:"domain-name"`
 | 
					 | 
				
			||||||
	TimeSigned uint64 `dns:"uint48"`
 | 
					 | 
				
			||||||
	Fudge      uint16
 | 
					 | 
				
			||||||
	// MACSize, MAC and OrigId excluded
 | 
					 | 
				
			||||||
	Error     uint16
 | 
					 | 
				
			||||||
	OtherLen  uint16
 | 
					 | 
				
			||||||
	OtherData string `dns:"size-hex:OtherLen"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// If we have the MAC use this type to convert it to wiredata. Section 3.4.3. Request MAC
 | 
					 | 
				
			||||||
type macWireFmt struct {
 | 
					 | 
				
			||||||
	MACSize uint16
 | 
					 | 
				
			||||||
	MAC     string `dns:"size-hex:MACSize"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 3.3. Time values used in TSIG calculations
 | 
					 | 
				
			||||||
type timerWireFmt struct {
 | 
					 | 
				
			||||||
	TimeSigned uint64 `dns:"uint48"`
 | 
					 | 
				
			||||||
	Fudge      uint16
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// TsigGenerate fills out the TSIG record attached to the message.
 | 
					 | 
				
			||||||
// The message should contain
 | 
					 | 
				
			||||||
// a "stub" TSIG RR with the algorithm, key name (owner name of the RR),
 | 
					 | 
				
			||||||
// time fudge (defaults to 300 seconds) and the current time
 | 
					 | 
				
			||||||
// The TSIG MAC is saved in that Tsig RR.
 | 
					 | 
				
			||||||
// When TsigGenerate is called for the first time requestMAC is set to the empty string and
 | 
					 | 
				
			||||||
// timersOnly is false.
 | 
					 | 
				
			||||||
// If something goes wrong an error is returned, otherwise it is nil.
 | 
					 | 
				
			||||||
func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, string, error) {
 | 
					 | 
				
			||||||
	if m.IsTsig() == nil {
 | 
					 | 
				
			||||||
		panic("dns: TSIG not last RR in additional")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// If we barf here, the caller is to blame
 | 
					 | 
				
			||||||
	rawsecret, err := fromBase64([]byte(secret))
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, "", err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rr := m.Extra[len(m.Extra)-1].(*TSIG)
 | 
					 | 
				
			||||||
	m.Extra = m.Extra[0 : len(m.Extra)-1] // kill the TSIG from the msg
 | 
					 | 
				
			||||||
	mbuf, err := m.Pack()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, "", err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	buf, err := tsigBuffer(mbuf, rr, requestMAC, timersOnly)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, "", err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	t := new(TSIG)
 | 
					 | 
				
			||||||
	var h hash.Hash
 | 
					 | 
				
			||||||
	switch CanonicalName(rr.Algorithm) {
 | 
					 | 
				
			||||||
	case HmacSHA1:
 | 
					 | 
				
			||||||
		h = hmac.New(sha1.New, rawsecret)
 | 
					 | 
				
			||||||
	case HmacSHA224:
 | 
					 | 
				
			||||||
		h = hmac.New(sha256.New224, rawsecret)
 | 
					 | 
				
			||||||
	case HmacSHA256:
 | 
					 | 
				
			||||||
		h = hmac.New(sha256.New, rawsecret)
 | 
					 | 
				
			||||||
	case HmacSHA384:
 | 
					 | 
				
			||||||
		h = hmac.New(sha512.New384, rawsecret)
 | 
					 | 
				
			||||||
	case HmacSHA512:
 | 
					 | 
				
			||||||
		h = hmac.New(sha512.New, rawsecret)
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return nil, "", ErrKeyAlg
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	h.Write(buf)
 | 
					 | 
				
			||||||
	// Copy all TSIG fields except MAC and its size, which are filled using the computed digest.
 | 
					 | 
				
			||||||
	*t = *rr
 | 
					 | 
				
			||||||
	t.MAC = hex.EncodeToString(h.Sum(nil))
 | 
					 | 
				
			||||||
	t.MACSize = uint16(len(t.MAC) / 2) // Size is half!
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	tbuf := make([]byte, Len(t))
 | 
					 | 
				
			||||||
	off, err := PackRR(t, tbuf, 0, nil, false)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, "", err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	mbuf = append(mbuf, tbuf[:off]...)
 | 
					 | 
				
			||||||
	// Update the ArCount directly in the buffer.
 | 
					 | 
				
			||||||
	binary.BigEndian.PutUint16(mbuf[10:], uint16(len(m.Extra)+1))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return mbuf, t.MAC, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// TsigVerify verifies the TSIG on a message.
 | 
					 | 
				
			||||||
// If the signature does not validate err contains the
 | 
					 | 
				
			||||||
// error, otherwise it is nil.
 | 
					 | 
				
			||||||
func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error {
 | 
					 | 
				
			||||||
	return tsigVerify(msg, secret, requestMAC, timersOnly, uint64(time.Now().Unix()))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// actual implementation of TsigVerify, taking the current time ('now') as a parameter for the convenience of tests.
 | 
					 | 
				
			||||||
func tsigVerify(msg []byte, secret, requestMAC string, timersOnly bool, now uint64) error {
 | 
					 | 
				
			||||||
	rawsecret, err := fromBase64([]byte(secret))
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// Strip the TSIG from the incoming msg
 | 
					 | 
				
			||||||
	stripped, tsig, err := stripTsig(msg)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	msgMAC, err := hex.DecodeString(tsig.MAC)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	buf, err := tsigBuffer(stripped, tsig, requestMAC, timersOnly)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var h hash.Hash
 | 
					 | 
				
			||||||
	switch CanonicalName(tsig.Algorithm) {
 | 
					 | 
				
			||||||
	case HmacSHA1:
 | 
					 | 
				
			||||||
		h = hmac.New(sha1.New, rawsecret)
 | 
					 | 
				
			||||||
	case HmacSHA224:
 | 
					 | 
				
			||||||
		h = hmac.New(sha256.New224, rawsecret)
 | 
					 | 
				
			||||||
	case HmacSHA256:
 | 
					 | 
				
			||||||
		h = hmac.New(sha256.New, rawsecret)
 | 
					 | 
				
			||||||
	case HmacSHA384:
 | 
					 | 
				
			||||||
		h = hmac.New(sha512.New384, rawsecret)
 | 
					 | 
				
			||||||
	case HmacSHA512:
 | 
					 | 
				
			||||||
		h = hmac.New(sha512.New, rawsecret)
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return ErrKeyAlg
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	h.Write(buf)
 | 
					 | 
				
			||||||
	if !hmac.Equal(h.Sum(nil), msgMAC) {
 | 
					 | 
				
			||||||
		return ErrSig
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Fudge factor works both ways. A message can arrive before it was signed because
 | 
					 | 
				
			||||||
	// of clock skew.
 | 
					 | 
				
			||||||
	// We check this after verifying the signature, following draft-ietf-dnsop-rfc2845bis
 | 
					 | 
				
			||||||
	// instead of RFC2845, in order to prevent a security vulnerability as reported in CVE-2017-3142/3143.
 | 
					 | 
				
			||||||
	ti := now - tsig.TimeSigned
 | 
					 | 
				
			||||||
	if now < tsig.TimeSigned {
 | 
					 | 
				
			||||||
		ti = tsig.TimeSigned - now
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if uint64(tsig.Fudge) < ti {
 | 
					 | 
				
			||||||
		return ErrTime
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Create a wiredata buffer for the MAC calculation.
 | 
					 | 
				
			||||||
func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) ([]byte, error) {
 | 
					 | 
				
			||||||
	var buf []byte
 | 
					 | 
				
			||||||
	if rr.TimeSigned == 0 {
 | 
					 | 
				
			||||||
		rr.TimeSigned = uint64(time.Now().Unix())
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if rr.Fudge == 0 {
 | 
					 | 
				
			||||||
		rr.Fudge = 300 // Standard (RFC) default.
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Replace message ID in header with original ID from TSIG
 | 
					 | 
				
			||||||
	binary.BigEndian.PutUint16(msgbuf[0:2], rr.OrigId)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if requestMAC != "" {
 | 
					 | 
				
			||||||
		m := new(macWireFmt)
 | 
					 | 
				
			||||||
		m.MACSize = uint16(len(requestMAC) / 2)
 | 
					 | 
				
			||||||
		m.MAC = requestMAC
 | 
					 | 
				
			||||||
		buf = make([]byte, len(requestMAC)) // long enough
 | 
					 | 
				
			||||||
		n, err := packMacWire(m, buf)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		buf = buf[:n]
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	tsigvar := make([]byte, DefaultMsgSize)
 | 
					 | 
				
			||||||
	if timersOnly {
 | 
					 | 
				
			||||||
		tsig := new(timerWireFmt)
 | 
					 | 
				
			||||||
		tsig.TimeSigned = rr.TimeSigned
 | 
					 | 
				
			||||||
		tsig.Fudge = rr.Fudge
 | 
					 | 
				
			||||||
		n, err := packTimerWire(tsig, tsigvar)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		tsigvar = tsigvar[:n]
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		tsig := new(tsigWireFmt)
 | 
					 | 
				
			||||||
		tsig.Name = CanonicalName(rr.Hdr.Name)
 | 
					 | 
				
			||||||
		tsig.Class = ClassANY
 | 
					 | 
				
			||||||
		tsig.Ttl = rr.Hdr.Ttl
 | 
					 | 
				
			||||||
		tsig.Algorithm = CanonicalName(rr.Algorithm)
 | 
					 | 
				
			||||||
		tsig.TimeSigned = rr.TimeSigned
 | 
					 | 
				
			||||||
		tsig.Fudge = rr.Fudge
 | 
					 | 
				
			||||||
		tsig.Error = rr.Error
 | 
					 | 
				
			||||||
		tsig.OtherLen = rr.OtherLen
 | 
					 | 
				
			||||||
		tsig.OtherData = rr.OtherData
 | 
					 | 
				
			||||||
		n, err := packTsigWire(tsig, tsigvar)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		tsigvar = tsigvar[:n]
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if requestMAC != "" {
 | 
					 | 
				
			||||||
		x := append(buf, msgbuf...)
 | 
					 | 
				
			||||||
		buf = append(x, tsigvar...)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		buf = append(msgbuf, tsigvar...)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return buf, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Strip the TSIG from the raw message.
 | 
					 | 
				
			||||||
func stripTsig(msg []byte) ([]byte, *TSIG, error) {
 | 
					 | 
				
			||||||
	// Copied from msg.go's Unpack() Header, but modified.
 | 
					 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		dh  Header
 | 
					 | 
				
			||||||
		err error
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	off, tsigoff := 0, 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if dh, off, err = unpackMsgHdr(msg, off); err != nil {
 | 
					 | 
				
			||||||
		return nil, nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if dh.Arcount == 0 {
 | 
					 | 
				
			||||||
		return nil, nil, ErrNoSig
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Rcode, see msg.go Unpack()
 | 
					 | 
				
			||||||
	if int(dh.Bits&0xF) == RcodeNotAuth {
 | 
					 | 
				
			||||||
		return nil, nil, ErrAuth
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for i := 0; i < int(dh.Qdcount); i++ {
 | 
					 | 
				
			||||||
		_, off, err = unpackQuestion(msg, off)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, nil, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	_, off, err = unpackRRslice(int(dh.Ancount), msg, off)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	_, off, err = unpackRRslice(int(dh.Nscount), msg, off)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rr := new(TSIG)
 | 
					 | 
				
			||||||
	var extra RR
 | 
					 | 
				
			||||||
	for i := 0; i < int(dh.Arcount); i++ {
 | 
					 | 
				
			||||||
		tsigoff = off
 | 
					 | 
				
			||||||
		extra, off, err = UnpackRR(msg, off)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, nil, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if extra.Header().Rrtype == TypeTSIG {
 | 
					 | 
				
			||||||
			rr = extra.(*TSIG)
 | 
					 | 
				
			||||||
			// Adjust Arcount.
 | 
					 | 
				
			||||||
			arcount := binary.BigEndian.Uint16(msg[10:])
 | 
					 | 
				
			||||||
			binary.BigEndian.PutUint16(msg[10:], arcount-1)
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if rr == nil {
 | 
					 | 
				
			||||||
		return nil, nil, ErrNoSig
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return msg[:tsigoff], rr, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Translate the TSIG time signed into a date. There is no
 | 
					 | 
				
			||||||
// need for RFC1982 calculations as this date is 48 bits.
 | 
					 | 
				
			||||||
func tsigTimeToString(t uint64) string {
 | 
					 | 
				
			||||||
	ti := time.Unix(int64(t), 0).UTC()
 | 
					 | 
				
			||||||
	return ti.Format("20060102150405")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func packTsigWire(tw *tsigWireFmt, msg []byte) (int, error) {
 | 
					 | 
				
			||||||
	// copied from zmsg.go TSIG packing
 | 
					 | 
				
			||||||
	// RR_Header
 | 
					 | 
				
			||||||
	off, err := PackDomainName(tw.Name, msg, 0, nil, false)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return off, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	off, err = packUint16(tw.Class, msg, off)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return off, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	off, err = packUint32(tw.Ttl, msg, off)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return off, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	off, err = PackDomainName(tw.Algorithm, msg, off, nil, false)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return off, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	off, err = packUint48(tw.TimeSigned, msg, off)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return off, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	off, err = packUint16(tw.Fudge, msg, off)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return off, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	off, err = packUint16(tw.Error, msg, off)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return off, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	off, err = packUint16(tw.OtherLen, msg, off)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return off, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	off, err = packStringHex(tw.OtherData, msg, off)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return off, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func packMacWire(mw *macWireFmt, msg []byte) (int, error) {
 | 
					 | 
				
			||||||
	off, err := packUint16(mw.MACSize, msg, 0)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return off, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	off, err = packStringHex(mw.MAC, msg, off)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return off, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func packTimerWire(tw *timerWireFmt, msg []byte) (int, error) {
 | 
					 | 
				
			||||||
	off, err := packUint48(tw.TimeSigned, msg, 0)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return off, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	off, err = packUint16(tw.Fudge, msg, off)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return off, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return off, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										1533
									
								
								vendor/github.com/miekg/dns/types.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1533
									
								
								vendor/github.com/miekg/dns/types.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										102
									
								
								vendor/github.com/miekg/dns/udp.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										102
									
								
								vendor/github.com/miekg/dns/udp.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,102 +0,0 @@
 | 
				
			|||||||
// +build !windows
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"net"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"golang.org/x/net/ipv4"
 | 
					 | 
				
			||||||
	"golang.org/x/net/ipv6"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// This is the required size of the OOB buffer to pass to ReadMsgUDP.
 | 
					 | 
				
			||||||
var udpOOBSize = func() int {
 | 
					 | 
				
			||||||
	// We can't know whether we'll get an IPv4 control message or an
 | 
					 | 
				
			||||||
	// IPv6 control message ahead of time. To get around this, we size
 | 
					 | 
				
			||||||
	// the buffer equal to the largest of the two.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	oob4 := ipv4.NewControlMessage(ipv4.FlagDst | ipv4.FlagInterface)
 | 
					 | 
				
			||||||
	oob6 := ipv6.NewControlMessage(ipv6.FlagDst | ipv6.FlagInterface)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if len(oob4) > len(oob6) {
 | 
					 | 
				
			||||||
		return len(oob4)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return len(oob6)
 | 
					 | 
				
			||||||
}()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SessionUDP holds the remote address and the associated
 | 
					 | 
				
			||||||
// out-of-band data.
 | 
					 | 
				
			||||||
type SessionUDP struct {
 | 
					 | 
				
			||||||
	raddr   *net.UDPAddr
 | 
					 | 
				
			||||||
	context []byte
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// RemoteAddr returns the remote network address.
 | 
					 | 
				
			||||||
func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a
 | 
					 | 
				
			||||||
// net.UDPAddr.
 | 
					 | 
				
			||||||
func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {
 | 
					 | 
				
			||||||
	oob := make([]byte, udpOOBSize)
 | 
					 | 
				
			||||||
	n, oobn, _, raddr, err := conn.ReadMsgUDP(b, oob)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return n, nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return n, &SessionUDP{raddr, oob[:oobn]}, err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// WriteToSessionUDP acts just like net.UDPConn.WriteTo(), but uses a *SessionUDP instead of a net.Addr.
 | 
					 | 
				
			||||||
func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) {
 | 
					 | 
				
			||||||
	oob := correctSource(session.context)
 | 
					 | 
				
			||||||
	n, _, err := conn.WriteMsgUDP(b, oob, session.raddr)
 | 
					 | 
				
			||||||
	return n, err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func setUDPSocketOptions(conn *net.UDPConn) error {
 | 
					 | 
				
			||||||
	// Try setting the flags for both families and ignore the errors unless they
 | 
					 | 
				
			||||||
	// both error.
 | 
					 | 
				
			||||||
	err6 := ipv6.NewPacketConn(conn).SetControlMessage(ipv6.FlagDst|ipv6.FlagInterface, true)
 | 
					 | 
				
			||||||
	err4 := ipv4.NewPacketConn(conn).SetControlMessage(ipv4.FlagDst|ipv4.FlagInterface, true)
 | 
					 | 
				
			||||||
	if err6 != nil && err4 != nil {
 | 
					 | 
				
			||||||
		return err4
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// parseDstFromOOB takes oob data and returns the destination IP.
 | 
					 | 
				
			||||||
func parseDstFromOOB(oob []byte) net.IP {
 | 
					 | 
				
			||||||
	// Start with IPv6 and then fallback to IPv4
 | 
					 | 
				
			||||||
	// TODO(fastest963): Figure out a way to prefer one or the other. Looking at
 | 
					 | 
				
			||||||
	// the lvl of the header for a 0 or 41 isn't cross-platform.
 | 
					 | 
				
			||||||
	cm6 := new(ipv6.ControlMessage)
 | 
					 | 
				
			||||||
	if cm6.Parse(oob) == nil && cm6.Dst != nil {
 | 
					 | 
				
			||||||
		return cm6.Dst
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	cm4 := new(ipv4.ControlMessage)
 | 
					 | 
				
			||||||
	if cm4.Parse(oob) == nil && cm4.Dst != nil {
 | 
					 | 
				
			||||||
		return cm4.Dst
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// correctSource takes oob data and returns new oob data with the Src equal to the Dst
 | 
					 | 
				
			||||||
func correctSource(oob []byte) []byte {
 | 
					 | 
				
			||||||
	dst := parseDstFromOOB(oob)
 | 
					 | 
				
			||||||
	if dst == nil {
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// If the dst is definitely an IPv6, then use ipv6's ControlMessage to
 | 
					 | 
				
			||||||
	// respond otherwise use ipv4's because ipv6's marshal ignores ipv4
 | 
					 | 
				
			||||||
	// addresses.
 | 
					 | 
				
			||||||
	if dst.To4() == nil {
 | 
					 | 
				
			||||||
		cm := new(ipv6.ControlMessage)
 | 
					 | 
				
			||||||
		cm.Src = dst
 | 
					 | 
				
			||||||
		oob = cm.Marshal()
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		cm := new(ipv4.ControlMessage)
 | 
					 | 
				
			||||||
		cm.Src = dst
 | 
					 | 
				
			||||||
		oob = cm.Marshal()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return oob
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										35
									
								
								vendor/github.com/miekg/dns/udp_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										35
									
								
								vendor/github.com/miekg/dns/udp_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,35 +0,0 @@
 | 
				
			|||||||
// +build windows
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "net"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SessionUDP holds the remote address
 | 
					 | 
				
			||||||
type SessionUDP struct {
 | 
					 | 
				
			||||||
	raddr *net.UDPAddr
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// RemoteAddr returns the remote network address.
 | 
					 | 
				
			||||||
func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a
 | 
					 | 
				
			||||||
// net.UDPAddr.
 | 
					 | 
				
			||||||
// TODO(fastest963): Once go1.10 is released, use ReadMsgUDP.
 | 
					 | 
				
			||||||
func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {
 | 
					 | 
				
			||||||
	n, raddr, err := conn.ReadFrom(b)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return n, nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return n, &SessionUDP{raddr.(*net.UDPAddr)}, err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// WriteToSessionUDP acts just like net.UDPConn.WriteTo(), but uses a *SessionUDP instead of a net.Addr.
 | 
					 | 
				
			||||||
// TODO(fastest963): Once go1.10 is released, use WriteMsgUDP.
 | 
					 | 
				
			||||||
func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) {
 | 
					 | 
				
			||||||
	return conn.WriteTo(b, session.raddr)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// TODO(fastest963): Once go1.10 is released and we can use *MsgUDP methods
 | 
					 | 
				
			||||||
// use the standard method in udp.go for these.
 | 
					 | 
				
			||||||
func setUDPSocketOptions(*net.UDPConn) error { return nil }
 | 
					 | 
				
			||||||
func parseDstFromOOB([]byte, net.IP) net.IP  { return nil }
 | 
					 | 
				
			||||||
							
								
								
									
										110
									
								
								vendor/github.com/miekg/dns/update.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										110
									
								
								vendor/github.com/miekg/dns/update.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,110 +0,0 @@
 | 
				
			|||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NameUsed sets the RRs in the prereq section to
 | 
					 | 
				
			||||||
// "Name is in use" RRs. RFC 2136 section 2.4.4.
 | 
					 | 
				
			||||||
func (u *Msg) NameUsed(rr []RR) {
 | 
					 | 
				
			||||||
	if u.Answer == nil {
 | 
					 | 
				
			||||||
		u.Answer = make([]RR, 0, len(rr))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for _, r := range rr {
 | 
					 | 
				
			||||||
		u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: TypeANY, Class: ClassANY}})
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NameNotUsed sets the RRs in the prereq section to
 | 
					 | 
				
			||||||
// "Name is in not use" RRs. RFC 2136 section 2.4.5.
 | 
					 | 
				
			||||||
func (u *Msg) NameNotUsed(rr []RR) {
 | 
					 | 
				
			||||||
	if u.Answer == nil {
 | 
					 | 
				
			||||||
		u.Answer = make([]RR, 0, len(rr))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for _, r := range rr {
 | 
					 | 
				
			||||||
		u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: TypeANY, Class: ClassNONE}})
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Used sets the RRs in the prereq section to
 | 
					 | 
				
			||||||
// "RRset exists (value dependent -- with rdata)" RRs. RFC 2136 section 2.4.2.
 | 
					 | 
				
			||||||
func (u *Msg) Used(rr []RR) {
 | 
					 | 
				
			||||||
	if len(u.Question) == 0 {
 | 
					 | 
				
			||||||
		panic("dns: empty question section")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if u.Answer == nil {
 | 
					 | 
				
			||||||
		u.Answer = make([]RR, 0, len(rr))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for _, r := range rr {
 | 
					 | 
				
			||||||
		r.Header().Class = u.Question[0].Qclass
 | 
					 | 
				
			||||||
		u.Answer = append(u.Answer, r)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// RRsetUsed sets the RRs in the prereq section to
 | 
					 | 
				
			||||||
// "RRset exists (value independent -- no rdata)" RRs. RFC 2136 section 2.4.1.
 | 
					 | 
				
			||||||
func (u *Msg) RRsetUsed(rr []RR) {
 | 
					 | 
				
			||||||
	if u.Answer == nil {
 | 
					 | 
				
			||||||
		u.Answer = make([]RR, 0, len(rr))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for _, r := range rr {
 | 
					 | 
				
			||||||
		h := r.Header()
 | 
					 | 
				
			||||||
		u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: h.Name, Ttl: 0, Rrtype: h.Rrtype, Class: ClassANY}})
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// RRsetNotUsed sets the RRs in the prereq section to
 | 
					 | 
				
			||||||
// "RRset does not exist" RRs. RFC 2136 section 2.4.3.
 | 
					 | 
				
			||||||
func (u *Msg) RRsetNotUsed(rr []RR) {
 | 
					 | 
				
			||||||
	if u.Answer == nil {
 | 
					 | 
				
			||||||
		u.Answer = make([]RR, 0, len(rr))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for _, r := range rr {
 | 
					 | 
				
			||||||
		h := r.Header()
 | 
					 | 
				
			||||||
		u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: h.Name, Ttl: 0, Rrtype: h.Rrtype, Class: ClassNONE}})
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Insert creates a dynamic update packet that adds an complete RRset, see RFC 2136 section 2.5.1.
 | 
					 | 
				
			||||||
func (u *Msg) Insert(rr []RR) {
 | 
					 | 
				
			||||||
	if len(u.Question) == 0 {
 | 
					 | 
				
			||||||
		panic("dns: empty question section")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if u.Ns == nil {
 | 
					 | 
				
			||||||
		u.Ns = make([]RR, 0, len(rr))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for _, r := range rr {
 | 
					 | 
				
			||||||
		r.Header().Class = u.Question[0].Qclass
 | 
					 | 
				
			||||||
		u.Ns = append(u.Ns, r)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// RemoveRRset creates a dynamic update packet that deletes an RRset, see RFC 2136 section 2.5.2.
 | 
					 | 
				
			||||||
func (u *Msg) RemoveRRset(rr []RR) {
 | 
					 | 
				
			||||||
	if u.Ns == nil {
 | 
					 | 
				
			||||||
		u.Ns = make([]RR, 0, len(rr))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for _, r := range rr {
 | 
					 | 
				
			||||||
		h := r.Header()
 | 
					 | 
				
			||||||
		u.Ns = append(u.Ns, &ANY{Hdr: RR_Header{Name: h.Name, Ttl: 0, Rrtype: h.Rrtype, Class: ClassANY}})
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// RemoveName creates a dynamic update packet that deletes all RRsets of a name, see RFC 2136 section 2.5.3
 | 
					 | 
				
			||||||
func (u *Msg) RemoveName(rr []RR) {
 | 
					 | 
				
			||||||
	if u.Ns == nil {
 | 
					 | 
				
			||||||
		u.Ns = make([]RR, 0, len(rr))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for _, r := range rr {
 | 
					 | 
				
			||||||
		u.Ns = append(u.Ns, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: TypeANY, Class: ClassANY}})
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Remove creates a dynamic update packet deletes RR from a RRSset, see RFC 2136 section 2.5.4
 | 
					 | 
				
			||||||
func (u *Msg) Remove(rr []RR) {
 | 
					 | 
				
			||||||
	if u.Ns == nil {
 | 
					 | 
				
			||||||
		u.Ns = make([]RR, 0, len(rr))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for _, r := range rr {
 | 
					 | 
				
			||||||
		h := r.Header()
 | 
					 | 
				
			||||||
		h.Class = ClassNONE
 | 
					 | 
				
			||||||
		h.Ttl = 0
 | 
					 | 
				
			||||||
		u.Ns = append(u.Ns, r)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										15
									
								
								vendor/github.com/miekg/dns/version.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								vendor/github.com/miekg/dns/version.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,15 +0,0 @@
 | 
				
			|||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "fmt"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Version is current version of this library.
 | 
					 | 
				
			||||||
var Version = v{1, 1, 35}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// v holds the version of this library.
 | 
					 | 
				
			||||||
type v struct {
 | 
					 | 
				
			||||||
	Major, Minor, Patch int
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (v v) String() string {
 | 
					 | 
				
			||||||
	return fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										266
									
								
								vendor/github.com/miekg/dns/xfr.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										266
									
								
								vendor/github.com/miekg/dns/xfr.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,266 +0,0 @@
 | 
				
			|||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Envelope is used when doing a zone transfer with a remote server.
 | 
					 | 
				
			||||||
type Envelope struct {
 | 
					 | 
				
			||||||
	RR    []RR  // The set of RRs in the answer section of the xfr reply message.
 | 
					 | 
				
			||||||
	Error error // If something went wrong, this contains the error.
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// A Transfer defines parameters that are used during a zone transfer.
 | 
					 | 
				
			||||||
type Transfer struct {
 | 
					 | 
				
			||||||
	*Conn
 | 
					 | 
				
			||||||
	DialTimeout    time.Duration     // net.DialTimeout, defaults to 2 seconds
 | 
					 | 
				
			||||||
	ReadTimeout    time.Duration     // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds
 | 
					 | 
				
			||||||
	WriteTimeout   time.Duration     // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds
 | 
					 | 
				
			||||||
	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)
 | 
					 | 
				
			||||||
	tsigTimersOnly bool
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Think we need to away to stop the transfer
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// In performs an incoming transfer with the server in a.
 | 
					 | 
				
			||||||
// If you would like to set the source IP, or some other attribute
 | 
					 | 
				
			||||||
// of a Dialer for a Transfer, you can do so by specifying the attributes
 | 
					 | 
				
			||||||
// in the Transfer.Conn:
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//	d := net.Dialer{LocalAddr: transfer_source}
 | 
					 | 
				
			||||||
//	con, err := d.Dial("tcp", master)
 | 
					 | 
				
			||||||
//	dnscon := &dns.Conn{Conn:con}
 | 
					 | 
				
			||||||
//	transfer = &dns.Transfer{Conn: dnscon}
 | 
					 | 
				
			||||||
//	channel, err := transfer.In(message, master)
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
func (t *Transfer) In(q *Msg, a string) (env chan *Envelope, err error) {
 | 
					 | 
				
			||||||
	switch q.Question[0].Qtype {
 | 
					 | 
				
			||||||
	case TypeAXFR, TypeIXFR:
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return nil, &Error{"unsupported question type"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	timeout := dnsTimeout
 | 
					 | 
				
			||||||
	if t.DialTimeout != 0 {
 | 
					 | 
				
			||||||
		timeout = t.DialTimeout
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if t.Conn == nil {
 | 
					 | 
				
			||||||
		t.Conn, err = DialTimeout("tcp", a, timeout)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err := t.WriteMsg(q); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	env = make(chan *Envelope)
 | 
					 | 
				
			||||||
	switch q.Question[0].Qtype {
 | 
					 | 
				
			||||||
	case TypeAXFR:
 | 
					 | 
				
			||||||
		go t.inAxfr(q, env)
 | 
					 | 
				
			||||||
	case TypeIXFR:
 | 
					 | 
				
			||||||
		go t.inIxfr(q, env)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return env, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (t *Transfer) inAxfr(q *Msg, c chan *Envelope) {
 | 
					 | 
				
			||||||
	first := true
 | 
					 | 
				
			||||||
	defer t.Close()
 | 
					 | 
				
			||||||
	defer close(c)
 | 
					 | 
				
			||||||
	timeout := dnsTimeout
 | 
					 | 
				
			||||||
	if t.ReadTimeout != 0 {
 | 
					 | 
				
			||||||
		timeout = t.ReadTimeout
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for {
 | 
					 | 
				
			||||||
		t.Conn.SetReadDeadline(time.Now().Add(timeout))
 | 
					 | 
				
			||||||
		in, err := t.ReadMsg()
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			c <- &Envelope{nil, err}
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if q.Id != in.Id {
 | 
					 | 
				
			||||||
			c <- &Envelope{in.Answer, ErrId}
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if first {
 | 
					 | 
				
			||||||
			if in.Rcode != RcodeSuccess {
 | 
					 | 
				
			||||||
				c <- &Envelope{in.Answer, &Error{err: fmt.Sprintf(errXFR, in.Rcode)}}
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if !isSOAFirst(in) {
 | 
					 | 
				
			||||||
				c <- &Envelope{in.Answer, ErrSoa}
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			first = !first
 | 
					 | 
				
			||||||
			// only one answer that is SOA, receive more
 | 
					 | 
				
			||||||
			if len(in.Answer) == 1 {
 | 
					 | 
				
			||||||
				t.tsigTimersOnly = true
 | 
					 | 
				
			||||||
				c <- &Envelope{in.Answer, nil}
 | 
					 | 
				
			||||||
				continue
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if !first {
 | 
					 | 
				
			||||||
			t.tsigTimersOnly = true // Subsequent envelopes use this.
 | 
					 | 
				
			||||||
			if isSOALast(in) {
 | 
					 | 
				
			||||||
				c <- &Envelope{in.Answer, nil}
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			c <- &Envelope{in.Answer, nil}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (t *Transfer) inIxfr(q *Msg, c chan *Envelope) {
 | 
					 | 
				
			||||||
	var serial uint32 // The first serial seen is the current server serial
 | 
					 | 
				
			||||||
	axfr := true
 | 
					 | 
				
			||||||
	n := 0
 | 
					 | 
				
			||||||
	qser := q.Ns[0].(*SOA).Serial
 | 
					 | 
				
			||||||
	defer t.Close()
 | 
					 | 
				
			||||||
	defer close(c)
 | 
					 | 
				
			||||||
	timeout := dnsTimeout
 | 
					 | 
				
			||||||
	if t.ReadTimeout != 0 {
 | 
					 | 
				
			||||||
		timeout = t.ReadTimeout
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for {
 | 
					 | 
				
			||||||
		t.SetReadDeadline(time.Now().Add(timeout))
 | 
					 | 
				
			||||||
		in, err := t.ReadMsg()
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			c <- &Envelope{nil, err}
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if q.Id != in.Id {
 | 
					 | 
				
			||||||
			c <- &Envelope{in.Answer, ErrId}
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if in.Rcode != RcodeSuccess {
 | 
					 | 
				
			||||||
			c <- &Envelope{in.Answer, &Error{err: fmt.Sprintf(errXFR, in.Rcode)}}
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if n == 0 {
 | 
					 | 
				
			||||||
			// Check if the returned answer is ok
 | 
					 | 
				
			||||||
			if !isSOAFirst(in) {
 | 
					 | 
				
			||||||
				c <- &Envelope{in.Answer, ErrSoa}
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			// This serial is important
 | 
					 | 
				
			||||||
			serial = in.Answer[0].(*SOA).Serial
 | 
					 | 
				
			||||||
			// Check if there are no changes in zone
 | 
					 | 
				
			||||||
			if qser >= serial {
 | 
					 | 
				
			||||||
				c <- &Envelope{in.Answer, nil}
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		// Now we need to check each message for SOA records, to see what we need to do
 | 
					 | 
				
			||||||
		t.tsigTimersOnly = true
 | 
					 | 
				
			||||||
		for _, rr := range in.Answer {
 | 
					 | 
				
			||||||
			if v, ok := rr.(*SOA); ok {
 | 
					 | 
				
			||||||
				if v.Serial == serial {
 | 
					 | 
				
			||||||
					n++
 | 
					 | 
				
			||||||
					// quit if it's a full axfr or the the servers' SOA is repeated the third time
 | 
					 | 
				
			||||||
					if axfr && n == 2 || n == 3 {
 | 
					 | 
				
			||||||
						c <- &Envelope{in.Answer, nil}
 | 
					 | 
				
			||||||
						return
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				} else if axfr {
 | 
					 | 
				
			||||||
					// it's an ixfr
 | 
					 | 
				
			||||||
					axfr = false
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		c <- &Envelope{in.Answer, nil}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Out performs an outgoing transfer with the client connecting in w.
 | 
					 | 
				
			||||||
// Basic use pattern:
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//	ch := make(chan *dns.Envelope)
 | 
					 | 
				
			||||||
//	tr := new(dns.Transfer)
 | 
					 | 
				
			||||||
//	var wg sync.WaitGroup
 | 
					 | 
				
			||||||
//	go func() {
 | 
					 | 
				
			||||||
//		tr.Out(w, r, ch)
 | 
					 | 
				
			||||||
//		wg.Done()
 | 
					 | 
				
			||||||
//	}()
 | 
					 | 
				
			||||||
//	ch <- &dns.Envelope{RR: []dns.RR{soa, rr1, rr2, rr3, soa}}
 | 
					 | 
				
			||||||
//	close(ch)
 | 
					 | 
				
			||||||
//	wg.Wait() // wait until everything is written out
 | 
					 | 
				
			||||||
//	w.Close() // close connection
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// The server is responsible for sending the correct sequence of RRs through the channel ch.
 | 
					 | 
				
			||||||
func (t *Transfer) Out(w ResponseWriter, q *Msg, ch chan *Envelope) error {
 | 
					 | 
				
			||||||
	for x := range ch {
 | 
					 | 
				
			||||||
		r := new(Msg)
 | 
					 | 
				
			||||||
		// Compress?
 | 
					 | 
				
			||||||
		r.SetReply(q)
 | 
					 | 
				
			||||||
		r.Authoritative = true
 | 
					 | 
				
			||||||
		// assume it fits TODO(miek): fix
 | 
					 | 
				
			||||||
		r.Answer = append(r.Answer, x.RR...)
 | 
					 | 
				
			||||||
		if tsig := q.IsTsig(); tsig != nil && w.TsigStatus() == nil {
 | 
					 | 
				
			||||||
			r.SetTsig(tsig.Hdr.Name, tsig.Algorithm, tsig.Fudge, time.Now().Unix())
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if err := w.WriteMsg(r); err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		w.TsigTimersOnly(true)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ReadMsg reads a message from the transfer connection t.
 | 
					 | 
				
			||||||
func (t *Transfer) ReadMsg() (*Msg, error) {
 | 
					 | 
				
			||||||
	m := new(Msg)
 | 
					 | 
				
			||||||
	p := make([]byte, MaxMsgSize)
 | 
					 | 
				
			||||||
	n, err := t.Read(p)
 | 
					 | 
				
			||||||
	if err != nil && n == 0 {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	p = p[:n]
 | 
					 | 
				
			||||||
	if err := m.Unpack(p); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if ts := m.IsTsig(); ts != nil && t.TsigSecret != nil {
 | 
					 | 
				
			||||||
		if _, ok := t.TsigSecret[ts.Hdr.Name]; !ok {
 | 
					 | 
				
			||||||
			return m, ErrSecret
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		// Need to work on the original message p, as that was used to calculate the tsig.
 | 
					 | 
				
			||||||
		err = TsigVerify(p, t.TsigSecret[ts.Hdr.Name], t.tsigRequestMAC, t.tsigTimersOnly)
 | 
					 | 
				
			||||||
		t.tsigRequestMAC = ts.MAC
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return m, err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// WriteMsg writes a message through the transfer connection t.
 | 
					 | 
				
			||||||
func (t *Transfer) WriteMsg(m *Msg) (err error) {
 | 
					 | 
				
			||||||
	var out []byte
 | 
					 | 
				
			||||||
	if ts := m.IsTsig(); ts != nil && t.TsigSecret != nil {
 | 
					 | 
				
			||||||
		if _, ok := t.TsigSecret[ts.Hdr.Name]; !ok {
 | 
					 | 
				
			||||||
			return ErrSecret
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		out, t.tsigRequestMAC, err = TsigGenerate(m, t.TsigSecret[ts.Hdr.Name], t.tsigRequestMAC, t.tsigTimersOnly)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		out, err = m.Pack()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	_, err = t.Write(out)
 | 
					 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func isSOAFirst(in *Msg) bool {
 | 
					 | 
				
			||||||
	return len(in.Answer) > 0 &&
 | 
					 | 
				
			||||||
		in.Answer[0].Header().Rrtype == TypeSOA
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func isSOALast(in *Msg) bool {
 | 
					 | 
				
			||||||
	return len(in.Answer) > 0 &&
 | 
					 | 
				
			||||||
		in.Answer[len(in.Answer)-1].Header().Rrtype == TypeSOA
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const errXFR = "bad xfr rcode: %d"
 | 
					 | 
				
			||||||
							
								
								
									
										1319
									
								
								vendor/github.com/miekg/dns/zduplicate.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1319
									
								
								vendor/github.com/miekg/dns/zduplicate.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2823
									
								
								vendor/github.com/miekg/dns/zmsg.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2823
									
								
								vendor/github.com/miekg/dns/zmsg.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										938
									
								
								vendor/github.com/miekg/dns/ztypes.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										938
									
								
								vendor/github.com/miekg/dns/ztypes.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,938 +0,0 @@
 | 
				
			|||||||
// Code generated by "go run types_generate.go"; DO NOT EDIT.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package dns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/base64"
 | 
					 | 
				
			||||||
	"net"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// TypeToRR is a map of constructors for each RR type.
 | 
					 | 
				
			||||||
var TypeToRR = map[uint16]func() RR{
 | 
					 | 
				
			||||||
	TypeA:          func() RR { return new(A) },
 | 
					 | 
				
			||||||
	TypeAAAA:       func() RR { return new(AAAA) },
 | 
					 | 
				
			||||||
	TypeAFSDB:      func() RR { return new(AFSDB) },
 | 
					 | 
				
			||||||
	TypeANY:        func() RR { return new(ANY) },
 | 
					 | 
				
			||||||
	TypeAPL:        func() RR { return new(APL) },
 | 
					 | 
				
			||||||
	TypeAVC:        func() RR { return new(AVC) },
 | 
					 | 
				
			||||||
	TypeCAA:        func() RR { return new(CAA) },
 | 
					 | 
				
			||||||
	TypeCDNSKEY:    func() RR { return new(CDNSKEY) },
 | 
					 | 
				
			||||||
	TypeCDS:        func() RR { return new(CDS) },
 | 
					 | 
				
			||||||
	TypeCERT:       func() RR { return new(CERT) },
 | 
					 | 
				
			||||||
	TypeCNAME:      func() RR { return new(CNAME) },
 | 
					 | 
				
			||||||
	TypeCSYNC:      func() RR { return new(CSYNC) },
 | 
					 | 
				
			||||||
	TypeDHCID:      func() RR { return new(DHCID) },
 | 
					 | 
				
			||||||
	TypeDLV:        func() RR { return new(DLV) },
 | 
					 | 
				
			||||||
	TypeDNAME:      func() RR { return new(DNAME) },
 | 
					 | 
				
			||||||
	TypeDNSKEY:     func() RR { return new(DNSKEY) },
 | 
					 | 
				
			||||||
	TypeDS:         func() RR { return new(DS) },
 | 
					 | 
				
			||||||
	TypeEID:        func() RR { return new(EID) },
 | 
					 | 
				
			||||||
	TypeEUI48:      func() RR { return new(EUI48) },
 | 
					 | 
				
			||||||
	TypeEUI64:      func() RR { return new(EUI64) },
 | 
					 | 
				
			||||||
	TypeGID:        func() RR { return new(GID) },
 | 
					 | 
				
			||||||
	TypeGPOS:       func() RR { return new(GPOS) },
 | 
					 | 
				
			||||||
	TypeHINFO:      func() RR { return new(HINFO) },
 | 
					 | 
				
			||||||
	TypeHIP:        func() RR { return new(HIP) },
 | 
					 | 
				
			||||||
	TypeHTTPS:      func() RR { return new(HTTPS) },
 | 
					 | 
				
			||||||
	TypeKEY:        func() RR { return new(KEY) },
 | 
					 | 
				
			||||||
	TypeKX:         func() RR { return new(KX) },
 | 
					 | 
				
			||||||
	TypeL32:        func() RR { return new(L32) },
 | 
					 | 
				
			||||||
	TypeL64:        func() RR { return new(L64) },
 | 
					 | 
				
			||||||
	TypeLOC:        func() RR { return new(LOC) },
 | 
					 | 
				
			||||||
	TypeLP:         func() RR { return new(LP) },
 | 
					 | 
				
			||||||
	TypeMB:         func() RR { return new(MB) },
 | 
					 | 
				
			||||||
	TypeMD:         func() RR { return new(MD) },
 | 
					 | 
				
			||||||
	TypeMF:         func() RR { return new(MF) },
 | 
					 | 
				
			||||||
	TypeMG:         func() RR { return new(MG) },
 | 
					 | 
				
			||||||
	TypeMINFO:      func() RR { return new(MINFO) },
 | 
					 | 
				
			||||||
	TypeMR:         func() RR { return new(MR) },
 | 
					 | 
				
			||||||
	TypeMX:         func() RR { return new(MX) },
 | 
					 | 
				
			||||||
	TypeNAPTR:      func() RR { return new(NAPTR) },
 | 
					 | 
				
			||||||
	TypeNID:        func() RR { return new(NID) },
 | 
					 | 
				
			||||||
	TypeNIMLOC:     func() RR { return new(NIMLOC) },
 | 
					 | 
				
			||||||
	TypeNINFO:      func() RR { return new(NINFO) },
 | 
					 | 
				
			||||||
	TypeNS:         func() RR { return new(NS) },
 | 
					 | 
				
			||||||
	TypeNSAPPTR:    func() RR { return new(NSAPPTR) },
 | 
					 | 
				
			||||||
	TypeNSEC:       func() RR { return new(NSEC) },
 | 
					 | 
				
			||||||
	TypeNSEC3:      func() RR { return new(NSEC3) },
 | 
					 | 
				
			||||||
	TypeNSEC3PARAM: func() RR { return new(NSEC3PARAM) },
 | 
					 | 
				
			||||||
	TypeNULL:       func() RR { return new(NULL) },
 | 
					 | 
				
			||||||
	TypeOPENPGPKEY: func() RR { return new(OPENPGPKEY) },
 | 
					 | 
				
			||||||
	TypeOPT:        func() RR { return new(OPT) },
 | 
					 | 
				
			||||||
	TypePTR:        func() RR { return new(PTR) },
 | 
					 | 
				
			||||||
	TypePX:         func() RR { return new(PX) },
 | 
					 | 
				
			||||||
	TypeRKEY:       func() RR { return new(RKEY) },
 | 
					 | 
				
			||||||
	TypeRP:         func() RR { return new(RP) },
 | 
					 | 
				
			||||||
	TypeRRSIG:      func() RR { return new(RRSIG) },
 | 
					 | 
				
			||||||
	TypeRT:         func() RR { return new(RT) },
 | 
					 | 
				
			||||||
	TypeSIG:        func() RR { return new(SIG) },
 | 
					 | 
				
			||||||
	TypeSMIMEA:     func() RR { return new(SMIMEA) },
 | 
					 | 
				
			||||||
	TypeSOA:        func() RR { return new(SOA) },
 | 
					 | 
				
			||||||
	TypeSPF:        func() RR { return new(SPF) },
 | 
					 | 
				
			||||||
	TypeSRV:        func() RR { return new(SRV) },
 | 
					 | 
				
			||||||
	TypeSSHFP:      func() RR { return new(SSHFP) },
 | 
					 | 
				
			||||||
	TypeSVCB:       func() RR { return new(SVCB) },
 | 
					 | 
				
			||||||
	TypeTA:         func() RR { return new(TA) },
 | 
					 | 
				
			||||||
	TypeTALINK:     func() RR { return new(TALINK) },
 | 
					 | 
				
			||||||
	TypeTKEY:       func() RR { return new(TKEY) },
 | 
					 | 
				
			||||||
	TypeTLSA:       func() RR { return new(TLSA) },
 | 
					 | 
				
			||||||
	TypeTSIG:       func() RR { return new(TSIG) },
 | 
					 | 
				
			||||||
	TypeTXT:        func() RR { return new(TXT) },
 | 
					 | 
				
			||||||
	TypeUID:        func() RR { return new(UID) },
 | 
					 | 
				
			||||||
	TypeUINFO:      func() RR { return new(UINFO) },
 | 
					 | 
				
			||||||
	TypeURI:        func() RR { return new(URI) },
 | 
					 | 
				
			||||||
	TypeX25:        func() RR { return new(X25) },
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// TypeToString is a map of strings for each RR type.
 | 
					 | 
				
			||||||
var TypeToString = map[uint16]string{
 | 
					 | 
				
			||||||
	TypeA:          "A",
 | 
					 | 
				
			||||||
	TypeAAAA:       "AAAA",
 | 
					 | 
				
			||||||
	TypeAFSDB:      "AFSDB",
 | 
					 | 
				
			||||||
	TypeANY:        "ANY",
 | 
					 | 
				
			||||||
	TypeAPL:        "APL",
 | 
					 | 
				
			||||||
	TypeATMA:       "ATMA",
 | 
					 | 
				
			||||||
	TypeAVC:        "AVC",
 | 
					 | 
				
			||||||
	TypeAXFR:       "AXFR",
 | 
					 | 
				
			||||||
	TypeCAA:        "CAA",
 | 
					 | 
				
			||||||
	TypeCDNSKEY:    "CDNSKEY",
 | 
					 | 
				
			||||||
	TypeCDS:        "CDS",
 | 
					 | 
				
			||||||
	TypeCERT:       "CERT",
 | 
					 | 
				
			||||||
	TypeCNAME:      "CNAME",
 | 
					 | 
				
			||||||
	TypeCSYNC:      "CSYNC",
 | 
					 | 
				
			||||||
	TypeDHCID:      "DHCID",
 | 
					 | 
				
			||||||
	TypeDLV:        "DLV",
 | 
					 | 
				
			||||||
	TypeDNAME:      "DNAME",
 | 
					 | 
				
			||||||
	TypeDNSKEY:     "DNSKEY",
 | 
					 | 
				
			||||||
	TypeDS:         "DS",
 | 
					 | 
				
			||||||
	TypeEID:        "EID",
 | 
					 | 
				
			||||||
	TypeEUI48:      "EUI48",
 | 
					 | 
				
			||||||
	TypeEUI64:      "EUI64",
 | 
					 | 
				
			||||||
	TypeGID:        "GID",
 | 
					 | 
				
			||||||
	TypeGPOS:       "GPOS",
 | 
					 | 
				
			||||||
	TypeHINFO:      "HINFO",
 | 
					 | 
				
			||||||
	TypeHIP:        "HIP",
 | 
					 | 
				
			||||||
	TypeHTTPS:      "HTTPS",
 | 
					 | 
				
			||||||
	TypeISDN:       "ISDN",
 | 
					 | 
				
			||||||
	TypeIXFR:       "IXFR",
 | 
					 | 
				
			||||||
	TypeKEY:        "KEY",
 | 
					 | 
				
			||||||
	TypeKX:         "KX",
 | 
					 | 
				
			||||||
	TypeL32:        "L32",
 | 
					 | 
				
			||||||
	TypeL64:        "L64",
 | 
					 | 
				
			||||||
	TypeLOC:        "LOC",
 | 
					 | 
				
			||||||
	TypeLP:         "LP",
 | 
					 | 
				
			||||||
	TypeMAILA:      "MAILA",
 | 
					 | 
				
			||||||
	TypeMAILB:      "MAILB",
 | 
					 | 
				
			||||||
	TypeMB:         "MB",
 | 
					 | 
				
			||||||
	TypeMD:         "MD",
 | 
					 | 
				
			||||||
	TypeMF:         "MF",
 | 
					 | 
				
			||||||
	TypeMG:         "MG",
 | 
					 | 
				
			||||||
	TypeMINFO:      "MINFO",
 | 
					 | 
				
			||||||
	TypeMR:         "MR",
 | 
					 | 
				
			||||||
	TypeMX:         "MX",
 | 
					 | 
				
			||||||
	TypeNAPTR:      "NAPTR",
 | 
					 | 
				
			||||||
	TypeNID:        "NID",
 | 
					 | 
				
			||||||
	TypeNIMLOC:     "NIMLOC",
 | 
					 | 
				
			||||||
	TypeNINFO:      "NINFO",
 | 
					 | 
				
			||||||
	TypeNS:         "NS",
 | 
					 | 
				
			||||||
	TypeNSEC:       "NSEC",
 | 
					 | 
				
			||||||
	TypeNSEC3:      "NSEC3",
 | 
					 | 
				
			||||||
	TypeNSEC3PARAM: "NSEC3PARAM",
 | 
					 | 
				
			||||||
	TypeNULL:       "NULL",
 | 
					 | 
				
			||||||
	TypeNXT:        "NXT",
 | 
					 | 
				
			||||||
	TypeNone:       "None",
 | 
					 | 
				
			||||||
	TypeOPENPGPKEY: "OPENPGPKEY",
 | 
					 | 
				
			||||||
	TypeOPT:        "OPT",
 | 
					 | 
				
			||||||
	TypePTR:        "PTR",
 | 
					 | 
				
			||||||
	TypePX:         "PX",
 | 
					 | 
				
			||||||
	TypeRKEY:       "RKEY",
 | 
					 | 
				
			||||||
	TypeRP:         "RP",
 | 
					 | 
				
			||||||
	TypeRRSIG:      "RRSIG",
 | 
					 | 
				
			||||||
	TypeRT:         "RT",
 | 
					 | 
				
			||||||
	TypeReserved:   "Reserved",
 | 
					 | 
				
			||||||
	TypeSIG:        "SIG",
 | 
					 | 
				
			||||||
	TypeSMIMEA:     "SMIMEA",
 | 
					 | 
				
			||||||
	TypeSOA:        "SOA",
 | 
					 | 
				
			||||||
	TypeSPF:        "SPF",
 | 
					 | 
				
			||||||
	TypeSRV:        "SRV",
 | 
					 | 
				
			||||||
	TypeSSHFP:      "SSHFP",
 | 
					 | 
				
			||||||
	TypeSVCB:       "SVCB",
 | 
					 | 
				
			||||||
	TypeTA:         "TA",
 | 
					 | 
				
			||||||
	TypeTALINK:     "TALINK",
 | 
					 | 
				
			||||||
	TypeTKEY:       "TKEY",
 | 
					 | 
				
			||||||
	TypeTLSA:       "TLSA",
 | 
					 | 
				
			||||||
	TypeTSIG:       "TSIG",
 | 
					 | 
				
			||||||
	TypeTXT:        "TXT",
 | 
					 | 
				
			||||||
	TypeUID:        "UID",
 | 
					 | 
				
			||||||
	TypeUINFO:      "UINFO",
 | 
					 | 
				
			||||||
	TypeUNSPEC:     "UNSPEC",
 | 
					 | 
				
			||||||
	TypeURI:        "URI",
 | 
					 | 
				
			||||||
	TypeX25:        "X25",
 | 
					 | 
				
			||||||
	TypeNSAPPTR:    "NSAP-PTR",
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (rr *A) Header() *RR_Header          { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *AAAA) Header() *RR_Header       { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *AFSDB) Header() *RR_Header      { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *ANY) Header() *RR_Header        { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *APL) Header() *RR_Header        { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *AVC) Header() *RR_Header        { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *CAA) Header() *RR_Header        { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *CDNSKEY) Header() *RR_Header    { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *CDS) Header() *RR_Header        { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *CERT) Header() *RR_Header       { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *CNAME) Header() *RR_Header      { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *CSYNC) Header() *RR_Header      { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *DHCID) Header() *RR_Header      { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *DLV) Header() *RR_Header        { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *DNAME) Header() *RR_Header      { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *DNSKEY) Header() *RR_Header     { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *DS) Header() *RR_Header         { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *EID) Header() *RR_Header        { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *EUI48) Header() *RR_Header      { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *EUI64) Header() *RR_Header      { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *GID) Header() *RR_Header        { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *GPOS) Header() *RR_Header       { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *HINFO) Header() *RR_Header      { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *HIP) Header() *RR_Header        { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *HTTPS) Header() *RR_Header      { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *KEY) Header() *RR_Header        { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *KX) Header() *RR_Header         { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *L32) Header() *RR_Header        { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *L64) Header() *RR_Header        { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *LOC) Header() *RR_Header        { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *LP) Header() *RR_Header         { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *MB) Header() *RR_Header         { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *MD) Header() *RR_Header         { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *MF) Header() *RR_Header         { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *MG) Header() *RR_Header         { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *MINFO) Header() *RR_Header      { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *MR) Header() *RR_Header         { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *MX) Header() *RR_Header         { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *NAPTR) Header() *RR_Header      { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *NID) Header() *RR_Header        { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *NIMLOC) Header() *RR_Header     { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *NINFO) Header() *RR_Header      { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *NS) Header() *RR_Header         { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *NSAPPTR) Header() *RR_Header    { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *NSEC) Header() *RR_Header       { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *NSEC3) Header() *RR_Header      { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *NSEC3PARAM) Header() *RR_Header { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *NULL) Header() *RR_Header       { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *OPENPGPKEY) Header() *RR_Header { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *OPT) Header() *RR_Header        { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *PTR) Header() *RR_Header        { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *PX) Header() *RR_Header         { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *RFC3597) Header() *RR_Header    { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *RKEY) Header() *RR_Header       { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *RP) Header() *RR_Header         { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *RRSIG) Header() *RR_Header      { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *RT) Header() *RR_Header         { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *SIG) Header() *RR_Header        { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *SMIMEA) Header() *RR_Header     { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *SOA) Header() *RR_Header        { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *SPF) Header() *RR_Header        { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *SRV) Header() *RR_Header        { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *SSHFP) Header() *RR_Header      { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *SVCB) Header() *RR_Header       { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *TA) Header() *RR_Header         { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *TALINK) Header() *RR_Header     { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *TKEY) Header() *RR_Header       { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *TLSA) Header() *RR_Header       { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *TSIG) Header() *RR_Header       { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *TXT) Header() *RR_Header        { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *UID) Header() *RR_Header        { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *UINFO) Header() *RR_Header      { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *URI) Header() *RR_Header        { return &rr.Hdr }
 | 
					 | 
				
			||||||
func (rr *X25) Header() *RR_Header        { return &rr.Hdr }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// len() functions
 | 
					 | 
				
			||||||
func (rr *A) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	if len(rr.A) != 0 {
 | 
					 | 
				
			||||||
		l += net.IPv4len
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *AAAA) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	if len(rr.AAAA) != 0 {
 | 
					 | 
				
			||||||
		l += net.IPv6len
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *AFSDB) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += 2 // Subtype
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Hostname, off+l, compression, false)
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *ANY) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *APL) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	for _, x := range rr.Prefixes {
 | 
					 | 
				
			||||||
		l += x.len()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *AVC) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	for _, x := range rr.Txt {
 | 
					 | 
				
			||||||
		l += len(x) + 1
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *CAA) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l++ // Flag
 | 
					 | 
				
			||||||
	l += len(rr.Tag) + 1
 | 
					 | 
				
			||||||
	l += len(rr.Value)
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *CERT) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += 2 // Type
 | 
					 | 
				
			||||||
	l += 2 // KeyTag
 | 
					 | 
				
			||||||
	l++    // Algorithm
 | 
					 | 
				
			||||||
	l += base64.StdEncoding.DecodedLen(len(rr.Certificate))
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *CNAME) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Target, off+l, compression, true)
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *DHCID) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += base64.StdEncoding.DecodedLen(len(rr.Digest))
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *DNAME) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Target, off+l, compression, false)
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *DNSKEY) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += 2 // Flags
 | 
					 | 
				
			||||||
	l++    // Protocol
 | 
					 | 
				
			||||||
	l++    // Algorithm
 | 
					 | 
				
			||||||
	l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *DS) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += 2 // KeyTag
 | 
					 | 
				
			||||||
	l++    // Algorithm
 | 
					 | 
				
			||||||
	l++    // DigestType
 | 
					 | 
				
			||||||
	l += len(rr.Digest) / 2
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *EID) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += len(rr.Endpoint) / 2
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *EUI48) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += 6 // Address
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *EUI64) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += 8 // Address
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *GID) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += 4 // Gid
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *GPOS) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += len(rr.Longitude) + 1
 | 
					 | 
				
			||||||
	l += len(rr.Latitude) + 1
 | 
					 | 
				
			||||||
	l += len(rr.Altitude) + 1
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *HINFO) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += len(rr.Cpu) + 1
 | 
					 | 
				
			||||||
	l += len(rr.Os) + 1
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *HIP) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l++    // HitLength
 | 
					 | 
				
			||||||
	l++    // PublicKeyAlgorithm
 | 
					 | 
				
			||||||
	l += 2 // PublicKeyLength
 | 
					 | 
				
			||||||
	l += len(rr.Hit) / 2
 | 
					 | 
				
			||||||
	l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
 | 
					 | 
				
			||||||
	for _, x := range rr.RendezvousServers {
 | 
					 | 
				
			||||||
		l += domainNameLen(x, off+l, compression, false)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *KX) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += 2 // Preference
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Exchanger, off+l, compression, false)
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *L32) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += 2 // Preference
 | 
					 | 
				
			||||||
	if len(rr.Locator32) != 0 {
 | 
					 | 
				
			||||||
		l += net.IPv4len
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *L64) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += 2 // Preference
 | 
					 | 
				
			||||||
	l += 8 // Locator64
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *LOC) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l++    // Version
 | 
					 | 
				
			||||||
	l++    // Size
 | 
					 | 
				
			||||||
	l++    // HorizPre
 | 
					 | 
				
			||||||
	l++    // VertPre
 | 
					 | 
				
			||||||
	l += 4 // Latitude
 | 
					 | 
				
			||||||
	l += 4 // Longitude
 | 
					 | 
				
			||||||
	l += 4 // Altitude
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *LP) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += 2 // Preference
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Fqdn, off+l, compression, false)
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *MB) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Mb, off+l, compression, true)
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *MD) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Md, off+l, compression, true)
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *MF) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Mf, off+l, compression, true)
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *MG) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Mg, off+l, compression, true)
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *MINFO) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Rmail, off+l, compression, true)
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Email, off+l, compression, true)
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *MR) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Mr, off+l, compression, true)
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *MX) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += 2 // Preference
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Mx, off+l, compression, true)
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *NAPTR) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += 2 // Order
 | 
					 | 
				
			||||||
	l += 2 // Preference
 | 
					 | 
				
			||||||
	l += len(rr.Flags) + 1
 | 
					 | 
				
			||||||
	l += len(rr.Service) + 1
 | 
					 | 
				
			||||||
	l += len(rr.Regexp) + 1
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Replacement, off+l, compression, false)
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *NID) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += 2 // Preference
 | 
					 | 
				
			||||||
	l += 8 // NodeID
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *NIMLOC) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += len(rr.Locator) / 2
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *NINFO) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	for _, x := range rr.ZSData {
 | 
					 | 
				
			||||||
		l += len(x) + 1
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *NS) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Ns, off+l, compression, true)
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *NSAPPTR) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Ptr, off+l, compression, false)
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *NSEC3PARAM) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l++    // Hash
 | 
					 | 
				
			||||||
	l++    // Flags
 | 
					 | 
				
			||||||
	l += 2 // Iterations
 | 
					 | 
				
			||||||
	l++    // SaltLength
 | 
					 | 
				
			||||||
	l += len(rr.Salt) / 2
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *NULL) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += len(rr.Data)
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *OPENPGPKEY) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *PTR) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Ptr, off+l, compression, true)
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *PX) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += 2 // Preference
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Map822, off+l, compression, false)
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Mapx400, off+l, compression, false)
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *RFC3597) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += len(rr.Rdata) / 2
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *RKEY) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += 2 // Flags
 | 
					 | 
				
			||||||
	l++    // Protocol
 | 
					 | 
				
			||||||
	l++    // Algorithm
 | 
					 | 
				
			||||||
	l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *RP) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Mbox, off+l, compression, false)
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Txt, off+l, compression, false)
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *RRSIG) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += 2 // TypeCovered
 | 
					 | 
				
			||||||
	l++    // Algorithm
 | 
					 | 
				
			||||||
	l++    // Labels
 | 
					 | 
				
			||||||
	l += 4 // OrigTtl
 | 
					 | 
				
			||||||
	l += 4 // Expiration
 | 
					 | 
				
			||||||
	l += 4 // Inception
 | 
					 | 
				
			||||||
	l += 2 // KeyTag
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.SignerName, off+l, compression, false)
 | 
					 | 
				
			||||||
	l += base64.StdEncoding.DecodedLen(len(rr.Signature))
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *RT) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += 2 // Preference
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Host, off+l, compression, false)
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *SMIMEA) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l++ // Usage
 | 
					 | 
				
			||||||
	l++ // Selector
 | 
					 | 
				
			||||||
	l++ // MatchingType
 | 
					 | 
				
			||||||
	l += len(rr.Certificate) / 2
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *SOA) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Ns, off+l, compression, true)
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Mbox, off+l, compression, true)
 | 
					 | 
				
			||||||
	l += 4 // Serial
 | 
					 | 
				
			||||||
	l += 4 // Refresh
 | 
					 | 
				
			||||||
	l += 4 // Retry
 | 
					 | 
				
			||||||
	l += 4 // Expire
 | 
					 | 
				
			||||||
	l += 4 // Minttl
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *SPF) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	for _, x := range rr.Txt {
 | 
					 | 
				
			||||||
		l += len(x) + 1
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *SRV) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += 2 // Priority
 | 
					 | 
				
			||||||
	l += 2 // Weight
 | 
					 | 
				
			||||||
	l += 2 // Port
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Target, off+l, compression, false)
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *SSHFP) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l++ // Algorithm
 | 
					 | 
				
			||||||
	l++ // Type
 | 
					 | 
				
			||||||
	l += len(rr.FingerPrint) / 2
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *SVCB) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += 2 // Priority
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Target, off+l, compression, false)
 | 
					 | 
				
			||||||
	for _, x := range rr.Value {
 | 
					 | 
				
			||||||
		l += 4 + int(x.len())
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *TA) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += 2 // KeyTag
 | 
					 | 
				
			||||||
	l++    // Algorithm
 | 
					 | 
				
			||||||
	l++    // DigestType
 | 
					 | 
				
			||||||
	l += len(rr.Digest) / 2
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *TALINK) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.PreviousName, off+l, compression, false)
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.NextName, off+l, compression, false)
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *TKEY) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Algorithm, off+l, compression, false)
 | 
					 | 
				
			||||||
	l += 4 // Inception
 | 
					 | 
				
			||||||
	l += 4 // Expiration
 | 
					 | 
				
			||||||
	l += 2 // Mode
 | 
					 | 
				
			||||||
	l += 2 // Error
 | 
					 | 
				
			||||||
	l += 2 // KeySize
 | 
					 | 
				
			||||||
	l += len(rr.Key) / 2
 | 
					 | 
				
			||||||
	l += 2 // OtherLen
 | 
					 | 
				
			||||||
	l += len(rr.OtherData) / 2
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *TLSA) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l++ // Usage
 | 
					 | 
				
			||||||
	l++ // Selector
 | 
					 | 
				
			||||||
	l++ // MatchingType
 | 
					 | 
				
			||||||
	l += len(rr.Certificate) / 2
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *TSIG) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += domainNameLen(rr.Algorithm, off+l, compression, false)
 | 
					 | 
				
			||||||
	l += 6 // TimeSigned
 | 
					 | 
				
			||||||
	l += 2 // Fudge
 | 
					 | 
				
			||||||
	l += 2 // MACSize
 | 
					 | 
				
			||||||
	l += len(rr.MAC) / 2
 | 
					 | 
				
			||||||
	l += 2 // OrigId
 | 
					 | 
				
			||||||
	l += 2 // Error
 | 
					 | 
				
			||||||
	l += 2 // OtherLen
 | 
					 | 
				
			||||||
	l += len(rr.OtherData) / 2
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *TXT) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	for _, x := range rr.Txt {
 | 
					 | 
				
			||||||
		l += len(x) + 1
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *UID) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += 4 // Uid
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *UINFO) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += len(rr.Uinfo) + 1
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *URI) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += 2 // Priority
 | 
					 | 
				
			||||||
	l += 2 // Weight
 | 
					 | 
				
			||||||
	l += len(rr.Target)
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *X25) len(off int, compression map[string]struct{}) int {
 | 
					 | 
				
			||||||
	l := rr.Hdr.len(off, compression)
 | 
					 | 
				
			||||||
	l += len(rr.PSDNAddress) + 1
 | 
					 | 
				
			||||||
	return l
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// copy() functions
 | 
					 | 
				
			||||||
func (rr *A) copy() RR {
 | 
					 | 
				
			||||||
	return &A{rr.Hdr, copyIP(rr.A)}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *AAAA) copy() RR {
 | 
					 | 
				
			||||||
	return &AAAA{rr.Hdr, copyIP(rr.AAAA)}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *AFSDB) copy() RR {
 | 
					 | 
				
			||||||
	return &AFSDB{rr.Hdr, rr.Subtype, rr.Hostname}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *ANY) copy() RR {
 | 
					 | 
				
			||||||
	return &ANY{rr.Hdr}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *APL) copy() RR {
 | 
					 | 
				
			||||||
	Prefixes := make([]APLPrefix, len(rr.Prefixes))
 | 
					 | 
				
			||||||
	for i, e := range rr.Prefixes {
 | 
					 | 
				
			||||||
		Prefixes[i] = e.copy()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &APL{rr.Hdr, Prefixes}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *AVC) copy() RR {
 | 
					 | 
				
			||||||
	Txt := make([]string, len(rr.Txt))
 | 
					 | 
				
			||||||
	copy(Txt, rr.Txt)
 | 
					 | 
				
			||||||
	return &AVC{rr.Hdr, Txt}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *CAA) copy() RR {
 | 
					 | 
				
			||||||
	return &CAA{rr.Hdr, rr.Flag, rr.Tag, rr.Value}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *CDNSKEY) copy() RR {
 | 
					 | 
				
			||||||
	return &CDNSKEY{*rr.DNSKEY.copy().(*DNSKEY)}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *CDS) copy() RR {
 | 
					 | 
				
			||||||
	return &CDS{*rr.DS.copy().(*DS)}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *CERT) copy() RR {
 | 
					 | 
				
			||||||
	return &CERT{rr.Hdr, rr.Type, rr.KeyTag, rr.Algorithm, rr.Certificate}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *CNAME) copy() RR {
 | 
					 | 
				
			||||||
	return &CNAME{rr.Hdr, rr.Target}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *CSYNC) copy() RR {
 | 
					 | 
				
			||||||
	TypeBitMap := make([]uint16, len(rr.TypeBitMap))
 | 
					 | 
				
			||||||
	copy(TypeBitMap, rr.TypeBitMap)
 | 
					 | 
				
			||||||
	return &CSYNC{rr.Hdr, rr.Serial, rr.Flags, TypeBitMap}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *DHCID) copy() RR {
 | 
					 | 
				
			||||||
	return &DHCID{rr.Hdr, rr.Digest}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *DLV) copy() RR {
 | 
					 | 
				
			||||||
	return &DLV{*rr.DS.copy().(*DS)}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *DNAME) copy() RR {
 | 
					 | 
				
			||||||
	return &DNAME{rr.Hdr, rr.Target}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *DNSKEY) copy() RR {
 | 
					 | 
				
			||||||
	return &DNSKEY{rr.Hdr, rr.Flags, rr.Protocol, rr.Algorithm, rr.PublicKey}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *DS) copy() RR {
 | 
					 | 
				
			||||||
	return &DS{rr.Hdr, rr.KeyTag, rr.Algorithm, rr.DigestType, rr.Digest}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *EID) copy() RR {
 | 
					 | 
				
			||||||
	return &EID{rr.Hdr, rr.Endpoint}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *EUI48) copy() RR {
 | 
					 | 
				
			||||||
	return &EUI48{rr.Hdr, rr.Address}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *EUI64) copy() RR {
 | 
					 | 
				
			||||||
	return &EUI64{rr.Hdr, rr.Address}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *GID) copy() RR {
 | 
					 | 
				
			||||||
	return &GID{rr.Hdr, rr.Gid}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *GPOS) copy() RR {
 | 
					 | 
				
			||||||
	return &GPOS{rr.Hdr, rr.Longitude, rr.Latitude, rr.Altitude}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *HINFO) copy() RR {
 | 
					 | 
				
			||||||
	return &HINFO{rr.Hdr, rr.Cpu, rr.Os}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *HIP) copy() RR {
 | 
					 | 
				
			||||||
	RendezvousServers := make([]string, len(rr.RendezvousServers))
 | 
					 | 
				
			||||||
	copy(RendezvousServers, rr.RendezvousServers)
 | 
					 | 
				
			||||||
	return &HIP{rr.Hdr, rr.HitLength, rr.PublicKeyAlgorithm, rr.PublicKeyLength, rr.Hit, rr.PublicKey, RendezvousServers}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *HTTPS) copy() RR {
 | 
					 | 
				
			||||||
	return &HTTPS{*rr.SVCB.copy().(*SVCB)}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *KEY) copy() RR {
 | 
					 | 
				
			||||||
	return &KEY{*rr.DNSKEY.copy().(*DNSKEY)}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *KX) copy() RR {
 | 
					 | 
				
			||||||
	return &KX{rr.Hdr, rr.Preference, rr.Exchanger}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *L32) copy() RR {
 | 
					 | 
				
			||||||
	return &L32{rr.Hdr, rr.Preference, copyIP(rr.Locator32)}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *L64) copy() RR {
 | 
					 | 
				
			||||||
	return &L64{rr.Hdr, rr.Preference, rr.Locator64}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *LOC) copy() RR {
 | 
					 | 
				
			||||||
	return &LOC{rr.Hdr, rr.Version, rr.Size, rr.HorizPre, rr.VertPre, rr.Latitude, rr.Longitude, rr.Altitude}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *LP) copy() RR {
 | 
					 | 
				
			||||||
	return &LP{rr.Hdr, rr.Preference, rr.Fqdn}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *MB) copy() RR {
 | 
					 | 
				
			||||||
	return &MB{rr.Hdr, rr.Mb}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *MD) copy() RR {
 | 
					 | 
				
			||||||
	return &MD{rr.Hdr, rr.Md}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *MF) copy() RR {
 | 
					 | 
				
			||||||
	return &MF{rr.Hdr, rr.Mf}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *MG) copy() RR {
 | 
					 | 
				
			||||||
	return &MG{rr.Hdr, rr.Mg}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *MINFO) copy() RR {
 | 
					 | 
				
			||||||
	return &MINFO{rr.Hdr, rr.Rmail, rr.Email}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *MR) copy() RR {
 | 
					 | 
				
			||||||
	return &MR{rr.Hdr, rr.Mr}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *MX) copy() RR {
 | 
					 | 
				
			||||||
	return &MX{rr.Hdr, rr.Preference, rr.Mx}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *NAPTR) copy() RR {
 | 
					 | 
				
			||||||
	return &NAPTR{rr.Hdr, rr.Order, rr.Preference, rr.Flags, rr.Service, rr.Regexp, rr.Replacement}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *NID) copy() RR {
 | 
					 | 
				
			||||||
	return &NID{rr.Hdr, rr.Preference, rr.NodeID}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *NIMLOC) copy() RR {
 | 
					 | 
				
			||||||
	return &NIMLOC{rr.Hdr, rr.Locator}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *NINFO) copy() RR {
 | 
					 | 
				
			||||||
	ZSData := make([]string, len(rr.ZSData))
 | 
					 | 
				
			||||||
	copy(ZSData, rr.ZSData)
 | 
					 | 
				
			||||||
	return &NINFO{rr.Hdr, ZSData}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *NS) copy() RR {
 | 
					 | 
				
			||||||
	return &NS{rr.Hdr, rr.Ns}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *NSAPPTR) copy() RR {
 | 
					 | 
				
			||||||
	return &NSAPPTR{rr.Hdr, rr.Ptr}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *NSEC) copy() RR {
 | 
					 | 
				
			||||||
	TypeBitMap := make([]uint16, len(rr.TypeBitMap))
 | 
					 | 
				
			||||||
	copy(TypeBitMap, rr.TypeBitMap)
 | 
					 | 
				
			||||||
	return &NSEC{rr.Hdr, rr.NextDomain, TypeBitMap}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *NSEC3) copy() RR {
 | 
					 | 
				
			||||||
	TypeBitMap := make([]uint16, len(rr.TypeBitMap))
 | 
					 | 
				
			||||||
	copy(TypeBitMap, rr.TypeBitMap)
 | 
					 | 
				
			||||||
	return &NSEC3{rr.Hdr, rr.Hash, rr.Flags, rr.Iterations, rr.SaltLength, rr.Salt, rr.HashLength, rr.NextDomain, TypeBitMap}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *NSEC3PARAM) copy() RR {
 | 
					 | 
				
			||||||
	return &NSEC3PARAM{rr.Hdr, rr.Hash, rr.Flags, rr.Iterations, rr.SaltLength, rr.Salt}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *NULL) copy() RR {
 | 
					 | 
				
			||||||
	return &NULL{rr.Hdr, rr.Data}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *OPENPGPKEY) copy() RR {
 | 
					 | 
				
			||||||
	return &OPENPGPKEY{rr.Hdr, rr.PublicKey}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *OPT) copy() RR {
 | 
					 | 
				
			||||||
	Option := make([]EDNS0, len(rr.Option))
 | 
					 | 
				
			||||||
	for i, e := range rr.Option {
 | 
					 | 
				
			||||||
		Option[i] = e.copy()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &OPT{rr.Hdr, Option}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *PTR) copy() RR {
 | 
					 | 
				
			||||||
	return &PTR{rr.Hdr, rr.Ptr}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *PX) copy() RR {
 | 
					 | 
				
			||||||
	return &PX{rr.Hdr, rr.Preference, rr.Map822, rr.Mapx400}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *RFC3597) copy() RR {
 | 
					 | 
				
			||||||
	return &RFC3597{rr.Hdr, rr.Rdata}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *RKEY) copy() RR {
 | 
					 | 
				
			||||||
	return &RKEY{rr.Hdr, rr.Flags, rr.Protocol, rr.Algorithm, rr.PublicKey}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *RP) copy() RR {
 | 
					 | 
				
			||||||
	return &RP{rr.Hdr, rr.Mbox, rr.Txt}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *RRSIG) copy() RR {
 | 
					 | 
				
			||||||
	return &RRSIG{rr.Hdr, rr.TypeCovered, rr.Algorithm, rr.Labels, rr.OrigTtl, rr.Expiration, rr.Inception, rr.KeyTag, rr.SignerName, rr.Signature}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *RT) copy() RR {
 | 
					 | 
				
			||||||
	return &RT{rr.Hdr, rr.Preference, rr.Host}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *SIG) copy() RR {
 | 
					 | 
				
			||||||
	return &SIG{*rr.RRSIG.copy().(*RRSIG)}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *SMIMEA) copy() RR {
 | 
					 | 
				
			||||||
	return &SMIMEA{rr.Hdr, rr.Usage, rr.Selector, rr.MatchingType, rr.Certificate}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *SOA) copy() RR {
 | 
					 | 
				
			||||||
	return &SOA{rr.Hdr, rr.Ns, rr.Mbox, rr.Serial, rr.Refresh, rr.Retry, rr.Expire, rr.Minttl}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *SPF) copy() RR {
 | 
					 | 
				
			||||||
	Txt := make([]string, len(rr.Txt))
 | 
					 | 
				
			||||||
	copy(Txt, rr.Txt)
 | 
					 | 
				
			||||||
	return &SPF{rr.Hdr, Txt}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *SRV) copy() RR {
 | 
					 | 
				
			||||||
	return &SRV{rr.Hdr, rr.Priority, rr.Weight, rr.Port, rr.Target}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *SSHFP) copy() RR {
 | 
					 | 
				
			||||||
	return &SSHFP{rr.Hdr, rr.Algorithm, rr.Type, rr.FingerPrint}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *SVCB) copy() RR {
 | 
					 | 
				
			||||||
	Value := make([]SVCBKeyValue, len(rr.Value))
 | 
					 | 
				
			||||||
	for i, e := range rr.Value {
 | 
					 | 
				
			||||||
		Value[i] = e.copy()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &SVCB{rr.Hdr, rr.Priority, rr.Target, Value}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *TA) copy() RR {
 | 
					 | 
				
			||||||
	return &TA{rr.Hdr, rr.KeyTag, rr.Algorithm, rr.DigestType, rr.Digest}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *TALINK) copy() RR {
 | 
					 | 
				
			||||||
	return &TALINK{rr.Hdr, rr.PreviousName, rr.NextName}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *TKEY) copy() RR {
 | 
					 | 
				
			||||||
	return &TKEY{rr.Hdr, rr.Algorithm, rr.Inception, rr.Expiration, rr.Mode, rr.Error, rr.KeySize, rr.Key, rr.OtherLen, rr.OtherData}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *TLSA) copy() RR {
 | 
					 | 
				
			||||||
	return &TLSA{rr.Hdr, rr.Usage, rr.Selector, rr.MatchingType, rr.Certificate}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *TSIG) copy() RR {
 | 
					 | 
				
			||||||
	return &TSIG{rr.Hdr, rr.Algorithm, rr.TimeSigned, rr.Fudge, rr.MACSize, rr.MAC, rr.OrigId, rr.Error, rr.OtherLen, rr.OtherData}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *TXT) copy() RR {
 | 
					 | 
				
			||||||
	Txt := make([]string, len(rr.Txt))
 | 
					 | 
				
			||||||
	copy(Txt, rr.Txt)
 | 
					 | 
				
			||||||
	return &TXT{rr.Hdr, Txt}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *UID) copy() RR {
 | 
					 | 
				
			||||||
	return &UID{rr.Hdr, rr.Uid}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *UINFO) copy() RR {
 | 
					 | 
				
			||||||
	return &UINFO{rr.Hdr, rr.Uinfo}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *URI) copy() RR {
 | 
					 | 
				
			||||||
	return &URI{rr.Hdr, rr.Priority, rr.Weight, rr.Target}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (rr *X25) copy() RR {
 | 
					 | 
				
			||||||
	return &X25{rr.Hdr, rr.PSDNAddress}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										223
									
								
								vendor/golang.org/x/net/internal/iana/const.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										223
									
								
								vendor/golang.org/x/net/internal/iana/const.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,223 +0,0 @@
 | 
				
			|||||||
// go generate gen.go
 | 
					 | 
				
			||||||
// Code generated by the command above; DO NOT EDIT.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Package iana provides protocol number resources managed by the Internet Assigned Numbers Authority (IANA).
 | 
					 | 
				
			||||||
package iana // import "golang.org/x/net/internal/iana"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Differentiated Services Field Codepoints (DSCP), Updated: 2018-05-04
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	DiffServCS0           = 0x00 // CS0
 | 
					 | 
				
			||||||
	DiffServCS1           = 0x20 // CS1
 | 
					 | 
				
			||||||
	DiffServCS2           = 0x40 // CS2
 | 
					 | 
				
			||||||
	DiffServCS3           = 0x60 // CS3
 | 
					 | 
				
			||||||
	DiffServCS4           = 0x80 // CS4
 | 
					 | 
				
			||||||
	DiffServCS5           = 0xa0 // CS5
 | 
					 | 
				
			||||||
	DiffServCS6           = 0xc0 // CS6
 | 
					 | 
				
			||||||
	DiffServCS7           = 0xe0 // CS7
 | 
					 | 
				
			||||||
	DiffServAF11          = 0x28 // AF11
 | 
					 | 
				
			||||||
	DiffServAF12          = 0x30 // AF12
 | 
					 | 
				
			||||||
	DiffServAF13          = 0x38 // AF13
 | 
					 | 
				
			||||||
	DiffServAF21          = 0x48 // AF21
 | 
					 | 
				
			||||||
	DiffServAF22          = 0x50 // AF22
 | 
					 | 
				
			||||||
	DiffServAF23          = 0x58 // AF23
 | 
					 | 
				
			||||||
	DiffServAF31          = 0x68 // AF31
 | 
					 | 
				
			||||||
	DiffServAF32          = 0x70 // AF32
 | 
					 | 
				
			||||||
	DiffServAF33          = 0x78 // AF33
 | 
					 | 
				
			||||||
	DiffServAF41          = 0x88 // AF41
 | 
					 | 
				
			||||||
	DiffServAF42          = 0x90 // AF42
 | 
					 | 
				
			||||||
	DiffServAF43          = 0x98 // AF43
 | 
					 | 
				
			||||||
	DiffServEF            = 0xb8 // EF
 | 
					 | 
				
			||||||
	DiffServVOICEADMIT    = 0xb0 // VOICE-ADMIT
 | 
					 | 
				
			||||||
	NotECNTransport       = 0x00 // Not-ECT (Not ECN-Capable Transport)
 | 
					 | 
				
			||||||
	ECNTransport1         = 0x01 // ECT(1) (ECN-Capable Transport(1))
 | 
					 | 
				
			||||||
	ECNTransport0         = 0x02 // ECT(0) (ECN-Capable Transport(0))
 | 
					 | 
				
			||||||
	CongestionExperienced = 0x03 // CE (Congestion Experienced)
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Protocol Numbers, Updated: 2017-10-13
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	ProtocolIP             = 0   // IPv4 encapsulation, pseudo protocol number
 | 
					 | 
				
			||||||
	ProtocolHOPOPT         = 0   // IPv6 Hop-by-Hop Option
 | 
					 | 
				
			||||||
	ProtocolICMP           = 1   // Internet Control Message
 | 
					 | 
				
			||||||
	ProtocolIGMP           = 2   // Internet Group Management
 | 
					 | 
				
			||||||
	ProtocolGGP            = 3   // Gateway-to-Gateway
 | 
					 | 
				
			||||||
	ProtocolIPv4           = 4   // IPv4 encapsulation
 | 
					 | 
				
			||||||
	ProtocolST             = 5   // Stream
 | 
					 | 
				
			||||||
	ProtocolTCP            = 6   // Transmission Control
 | 
					 | 
				
			||||||
	ProtocolCBT            = 7   // CBT
 | 
					 | 
				
			||||||
	ProtocolEGP            = 8   // Exterior Gateway Protocol
 | 
					 | 
				
			||||||
	ProtocolIGP            = 9   // any private interior gateway (used by Cisco for their IGRP)
 | 
					 | 
				
			||||||
	ProtocolBBNRCCMON      = 10  // BBN RCC Monitoring
 | 
					 | 
				
			||||||
	ProtocolNVPII          = 11  // Network Voice Protocol
 | 
					 | 
				
			||||||
	ProtocolPUP            = 12  // PUP
 | 
					 | 
				
			||||||
	ProtocolEMCON          = 14  // EMCON
 | 
					 | 
				
			||||||
	ProtocolXNET           = 15  // Cross Net Debugger
 | 
					 | 
				
			||||||
	ProtocolCHAOS          = 16  // Chaos
 | 
					 | 
				
			||||||
	ProtocolUDP            = 17  // User Datagram
 | 
					 | 
				
			||||||
	ProtocolMUX            = 18  // Multiplexing
 | 
					 | 
				
			||||||
	ProtocolDCNMEAS        = 19  // DCN Measurement Subsystems
 | 
					 | 
				
			||||||
	ProtocolHMP            = 20  // Host Monitoring
 | 
					 | 
				
			||||||
	ProtocolPRM            = 21  // Packet Radio Measurement
 | 
					 | 
				
			||||||
	ProtocolXNSIDP         = 22  // XEROX NS IDP
 | 
					 | 
				
			||||||
	ProtocolTRUNK1         = 23  // Trunk-1
 | 
					 | 
				
			||||||
	ProtocolTRUNK2         = 24  // Trunk-2
 | 
					 | 
				
			||||||
	ProtocolLEAF1          = 25  // Leaf-1
 | 
					 | 
				
			||||||
	ProtocolLEAF2          = 26  // Leaf-2
 | 
					 | 
				
			||||||
	ProtocolRDP            = 27  // Reliable Data Protocol
 | 
					 | 
				
			||||||
	ProtocolIRTP           = 28  // Internet Reliable Transaction
 | 
					 | 
				
			||||||
	ProtocolISOTP4         = 29  // ISO Transport Protocol Class 4
 | 
					 | 
				
			||||||
	ProtocolNETBLT         = 30  // Bulk Data Transfer Protocol
 | 
					 | 
				
			||||||
	ProtocolMFENSP         = 31  // MFE Network Services Protocol
 | 
					 | 
				
			||||||
	ProtocolMERITINP       = 32  // MERIT Internodal Protocol
 | 
					 | 
				
			||||||
	ProtocolDCCP           = 33  // Datagram Congestion Control Protocol
 | 
					 | 
				
			||||||
	Protocol3PC            = 34  // Third Party Connect Protocol
 | 
					 | 
				
			||||||
	ProtocolIDPR           = 35  // Inter-Domain Policy Routing Protocol
 | 
					 | 
				
			||||||
	ProtocolXTP            = 36  // XTP
 | 
					 | 
				
			||||||
	ProtocolDDP            = 37  // Datagram Delivery Protocol
 | 
					 | 
				
			||||||
	ProtocolIDPRCMTP       = 38  // IDPR Control Message Transport Proto
 | 
					 | 
				
			||||||
	ProtocolTPPP           = 39  // TP++ Transport Protocol
 | 
					 | 
				
			||||||
	ProtocolIL             = 40  // IL Transport Protocol
 | 
					 | 
				
			||||||
	ProtocolIPv6           = 41  // IPv6 encapsulation
 | 
					 | 
				
			||||||
	ProtocolSDRP           = 42  // Source Demand Routing Protocol
 | 
					 | 
				
			||||||
	ProtocolIPv6Route      = 43  // Routing Header for IPv6
 | 
					 | 
				
			||||||
	ProtocolIPv6Frag       = 44  // Fragment Header for IPv6
 | 
					 | 
				
			||||||
	ProtocolIDRP           = 45  // Inter-Domain Routing Protocol
 | 
					 | 
				
			||||||
	ProtocolRSVP           = 46  // Reservation Protocol
 | 
					 | 
				
			||||||
	ProtocolGRE            = 47  // Generic Routing Encapsulation
 | 
					 | 
				
			||||||
	ProtocolDSR            = 48  // Dynamic Source Routing Protocol
 | 
					 | 
				
			||||||
	ProtocolBNA            = 49  // BNA
 | 
					 | 
				
			||||||
	ProtocolESP            = 50  // Encap Security Payload
 | 
					 | 
				
			||||||
	ProtocolAH             = 51  // Authentication Header
 | 
					 | 
				
			||||||
	ProtocolINLSP          = 52  // Integrated Net Layer Security  TUBA
 | 
					 | 
				
			||||||
	ProtocolNARP           = 54  // NBMA Address Resolution Protocol
 | 
					 | 
				
			||||||
	ProtocolMOBILE         = 55  // IP Mobility
 | 
					 | 
				
			||||||
	ProtocolTLSP           = 56  // Transport Layer Security Protocol using Kryptonet key management
 | 
					 | 
				
			||||||
	ProtocolSKIP           = 57  // SKIP
 | 
					 | 
				
			||||||
	ProtocolIPv6ICMP       = 58  // ICMP for IPv6
 | 
					 | 
				
			||||||
	ProtocolIPv6NoNxt      = 59  // No Next Header for IPv6
 | 
					 | 
				
			||||||
	ProtocolIPv6Opts       = 60  // Destination Options for IPv6
 | 
					 | 
				
			||||||
	ProtocolCFTP           = 62  // CFTP
 | 
					 | 
				
			||||||
	ProtocolSATEXPAK       = 64  // SATNET and Backroom EXPAK
 | 
					 | 
				
			||||||
	ProtocolKRYPTOLAN      = 65  // Kryptolan
 | 
					 | 
				
			||||||
	ProtocolRVD            = 66  // MIT Remote Virtual Disk Protocol
 | 
					 | 
				
			||||||
	ProtocolIPPC           = 67  // Internet Pluribus Packet Core
 | 
					 | 
				
			||||||
	ProtocolSATMON         = 69  // SATNET Monitoring
 | 
					 | 
				
			||||||
	ProtocolVISA           = 70  // VISA Protocol
 | 
					 | 
				
			||||||
	ProtocolIPCV           = 71  // Internet Packet Core Utility
 | 
					 | 
				
			||||||
	ProtocolCPNX           = 72  // Computer Protocol Network Executive
 | 
					 | 
				
			||||||
	ProtocolCPHB           = 73  // Computer Protocol Heart Beat
 | 
					 | 
				
			||||||
	ProtocolWSN            = 74  // Wang Span Network
 | 
					 | 
				
			||||||
	ProtocolPVP            = 75  // Packet Video Protocol
 | 
					 | 
				
			||||||
	ProtocolBRSATMON       = 76  // Backroom SATNET Monitoring
 | 
					 | 
				
			||||||
	ProtocolSUNND          = 77  // SUN ND PROTOCOL-Temporary
 | 
					 | 
				
			||||||
	ProtocolWBMON          = 78  // WIDEBAND Monitoring
 | 
					 | 
				
			||||||
	ProtocolWBEXPAK        = 79  // WIDEBAND EXPAK
 | 
					 | 
				
			||||||
	ProtocolISOIP          = 80  // ISO Internet Protocol
 | 
					 | 
				
			||||||
	ProtocolVMTP           = 81  // VMTP
 | 
					 | 
				
			||||||
	ProtocolSECUREVMTP     = 82  // SECURE-VMTP
 | 
					 | 
				
			||||||
	ProtocolVINES          = 83  // VINES
 | 
					 | 
				
			||||||
	ProtocolTTP            = 84  // Transaction Transport Protocol
 | 
					 | 
				
			||||||
	ProtocolIPTM           = 84  // Internet Protocol Traffic Manager
 | 
					 | 
				
			||||||
	ProtocolNSFNETIGP      = 85  // NSFNET-IGP
 | 
					 | 
				
			||||||
	ProtocolDGP            = 86  // Dissimilar Gateway Protocol
 | 
					 | 
				
			||||||
	ProtocolTCF            = 87  // TCF
 | 
					 | 
				
			||||||
	ProtocolEIGRP          = 88  // EIGRP
 | 
					 | 
				
			||||||
	ProtocolOSPFIGP        = 89  // OSPFIGP
 | 
					 | 
				
			||||||
	ProtocolSpriteRPC      = 90  // Sprite RPC Protocol
 | 
					 | 
				
			||||||
	ProtocolLARP           = 91  // Locus Address Resolution Protocol
 | 
					 | 
				
			||||||
	ProtocolMTP            = 92  // Multicast Transport Protocol
 | 
					 | 
				
			||||||
	ProtocolAX25           = 93  // AX.25 Frames
 | 
					 | 
				
			||||||
	ProtocolIPIP           = 94  // IP-within-IP Encapsulation Protocol
 | 
					 | 
				
			||||||
	ProtocolSCCSP          = 96  // Semaphore Communications Sec. Pro.
 | 
					 | 
				
			||||||
	ProtocolETHERIP        = 97  // Ethernet-within-IP Encapsulation
 | 
					 | 
				
			||||||
	ProtocolENCAP          = 98  // Encapsulation Header
 | 
					 | 
				
			||||||
	ProtocolGMTP           = 100 // GMTP
 | 
					 | 
				
			||||||
	ProtocolIFMP           = 101 // Ipsilon Flow Management Protocol
 | 
					 | 
				
			||||||
	ProtocolPNNI           = 102 // PNNI over IP
 | 
					 | 
				
			||||||
	ProtocolPIM            = 103 // Protocol Independent Multicast
 | 
					 | 
				
			||||||
	ProtocolARIS           = 104 // ARIS
 | 
					 | 
				
			||||||
	ProtocolSCPS           = 105 // SCPS
 | 
					 | 
				
			||||||
	ProtocolQNX            = 106 // QNX
 | 
					 | 
				
			||||||
	ProtocolAN             = 107 // Active Networks
 | 
					 | 
				
			||||||
	ProtocolIPComp         = 108 // IP Payload Compression Protocol
 | 
					 | 
				
			||||||
	ProtocolSNP            = 109 // Sitara Networks Protocol
 | 
					 | 
				
			||||||
	ProtocolCompaqPeer     = 110 // Compaq Peer Protocol
 | 
					 | 
				
			||||||
	ProtocolIPXinIP        = 111 // IPX in IP
 | 
					 | 
				
			||||||
	ProtocolVRRP           = 112 // Virtual Router Redundancy Protocol
 | 
					 | 
				
			||||||
	ProtocolPGM            = 113 // PGM Reliable Transport Protocol
 | 
					 | 
				
			||||||
	ProtocolL2TP           = 115 // Layer Two Tunneling Protocol
 | 
					 | 
				
			||||||
	ProtocolDDX            = 116 // D-II Data Exchange (DDX)
 | 
					 | 
				
			||||||
	ProtocolIATP           = 117 // Interactive Agent Transfer Protocol
 | 
					 | 
				
			||||||
	ProtocolSTP            = 118 // Schedule Transfer Protocol
 | 
					 | 
				
			||||||
	ProtocolSRP            = 119 // SpectraLink Radio Protocol
 | 
					 | 
				
			||||||
	ProtocolUTI            = 120 // UTI
 | 
					 | 
				
			||||||
	ProtocolSMP            = 121 // Simple Message Protocol
 | 
					 | 
				
			||||||
	ProtocolPTP            = 123 // Performance Transparency Protocol
 | 
					 | 
				
			||||||
	ProtocolISIS           = 124 // ISIS over IPv4
 | 
					 | 
				
			||||||
	ProtocolFIRE           = 125 // FIRE
 | 
					 | 
				
			||||||
	ProtocolCRTP           = 126 // Combat Radio Transport Protocol
 | 
					 | 
				
			||||||
	ProtocolCRUDP          = 127 // Combat Radio User Datagram
 | 
					 | 
				
			||||||
	ProtocolSSCOPMCE       = 128 // SSCOPMCE
 | 
					 | 
				
			||||||
	ProtocolIPLT           = 129 // IPLT
 | 
					 | 
				
			||||||
	ProtocolSPS            = 130 // Secure Packet Shield
 | 
					 | 
				
			||||||
	ProtocolPIPE           = 131 // Private IP Encapsulation within IP
 | 
					 | 
				
			||||||
	ProtocolSCTP           = 132 // Stream Control Transmission Protocol
 | 
					 | 
				
			||||||
	ProtocolFC             = 133 // Fibre Channel
 | 
					 | 
				
			||||||
	ProtocolRSVPE2EIGNORE  = 134 // RSVP-E2E-IGNORE
 | 
					 | 
				
			||||||
	ProtocolMobilityHeader = 135 // Mobility Header
 | 
					 | 
				
			||||||
	ProtocolUDPLite        = 136 // UDPLite
 | 
					 | 
				
			||||||
	ProtocolMPLSinIP       = 137 // MPLS-in-IP
 | 
					 | 
				
			||||||
	ProtocolMANET          = 138 // MANET Protocols
 | 
					 | 
				
			||||||
	ProtocolHIP            = 139 // Host Identity Protocol
 | 
					 | 
				
			||||||
	ProtocolShim6          = 140 // Shim6 Protocol
 | 
					 | 
				
			||||||
	ProtocolWESP           = 141 // Wrapped Encapsulating Security Payload
 | 
					 | 
				
			||||||
	ProtocolROHC           = 142 // Robust Header Compression
 | 
					 | 
				
			||||||
	ProtocolReserved       = 255 // Reserved
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Address Family Numbers, Updated: 2018-04-02
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	AddrFamilyIPv4                          = 1     // IP (IP version 4)
 | 
					 | 
				
			||||||
	AddrFamilyIPv6                          = 2     // IP6 (IP version 6)
 | 
					 | 
				
			||||||
	AddrFamilyNSAP                          = 3     // NSAP
 | 
					 | 
				
			||||||
	AddrFamilyHDLC                          = 4     // HDLC (8-bit multidrop)
 | 
					 | 
				
			||||||
	AddrFamilyBBN1822                       = 5     // BBN 1822
 | 
					 | 
				
			||||||
	AddrFamily802                           = 6     // 802 (includes all 802 media plus Ethernet "canonical format")
 | 
					 | 
				
			||||||
	AddrFamilyE163                          = 7     // E.163
 | 
					 | 
				
			||||||
	AddrFamilyE164                          = 8     // E.164 (SMDS, Frame Relay, ATM)
 | 
					 | 
				
			||||||
	AddrFamilyF69                           = 9     // F.69 (Telex)
 | 
					 | 
				
			||||||
	AddrFamilyX121                          = 10    // X.121 (X.25, Frame Relay)
 | 
					 | 
				
			||||||
	AddrFamilyIPX                           = 11    // IPX
 | 
					 | 
				
			||||||
	AddrFamilyAppletalk                     = 12    // Appletalk
 | 
					 | 
				
			||||||
	AddrFamilyDecnetIV                      = 13    // Decnet IV
 | 
					 | 
				
			||||||
	AddrFamilyBanyanVines                   = 14    // Banyan Vines
 | 
					 | 
				
			||||||
	AddrFamilyE164withSubaddress            = 15    // E.164 with NSAP format subaddress
 | 
					 | 
				
			||||||
	AddrFamilyDNS                           = 16    // DNS (Domain Name System)
 | 
					 | 
				
			||||||
	AddrFamilyDistinguishedName             = 17    // Distinguished Name
 | 
					 | 
				
			||||||
	AddrFamilyASNumber                      = 18    // AS Number
 | 
					 | 
				
			||||||
	AddrFamilyXTPoverIPv4                   = 19    // XTP over IP version 4
 | 
					 | 
				
			||||||
	AddrFamilyXTPoverIPv6                   = 20    // XTP over IP version 6
 | 
					 | 
				
			||||||
	AddrFamilyXTPnativemodeXTP              = 21    // XTP native mode XTP
 | 
					 | 
				
			||||||
	AddrFamilyFibreChannelWorldWidePortName = 22    // Fibre Channel World-Wide Port Name
 | 
					 | 
				
			||||||
	AddrFamilyFibreChannelWorldWideNodeName = 23    // Fibre Channel World-Wide Node Name
 | 
					 | 
				
			||||||
	AddrFamilyGWID                          = 24    // GWID
 | 
					 | 
				
			||||||
	AddrFamilyL2VPN                         = 25    // AFI for L2VPN information
 | 
					 | 
				
			||||||
	AddrFamilyMPLSTPSectionEndpointID       = 26    // MPLS-TP Section Endpoint Identifier
 | 
					 | 
				
			||||||
	AddrFamilyMPLSTPLSPEndpointID           = 27    // MPLS-TP LSP Endpoint Identifier
 | 
					 | 
				
			||||||
	AddrFamilyMPLSTPPseudowireEndpointID    = 28    // MPLS-TP Pseudowire Endpoint Identifier
 | 
					 | 
				
			||||||
	AddrFamilyMTIPv4                        = 29    // MT IP: Multi-Topology IP version 4
 | 
					 | 
				
			||||||
	AddrFamilyMTIPv6                        = 30    // MT IPv6: Multi-Topology IP version 6
 | 
					 | 
				
			||||||
	AddrFamilyEIGRPCommonServiceFamily      = 16384 // EIGRP Common Service Family
 | 
					 | 
				
			||||||
	AddrFamilyEIGRPIPv4ServiceFamily        = 16385 // EIGRP IPv4 Service Family
 | 
					 | 
				
			||||||
	AddrFamilyEIGRPIPv6ServiceFamily        = 16386 // EIGRP IPv6 Service Family
 | 
					 | 
				
			||||||
	AddrFamilyLISPCanonicalAddressFormat    = 16387 // LISP Canonical Address Format (LCAF)
 | 
					 | 
				
			||||||
	AddrFamilyBGPLS                         = 16388 // BGP-LS
 | 
					 | 
				
			||||||
	AddrFamily48bitMAC                      = 16389 // 48-bit MAC
 | 
					 | 
				
			||||||
	AddrFamily64bitMAC                      = 16390 // 64-bit MAC
 | 
					 | 
				
			||||||
	AddrFamilyOUI                           = 16391 // OUI
 | 
					 | 
				
			||||||
	AddrFamilyMACFinal24bits                = 16392 // MAC/24
 | 
					 | 
				
			||||||
	AddrFamilyMACFinal40bits                = 16393 // MAC/40
 | 
					 | 
				
			||||||
	AddrFamilyIPv6Initial64bits             = 16394 // IPv6/64
 | 
					 | 
				
			||||||
	AddrFamilyRBridgePortID                 = 16395 // RBridge Port ID
 | 
					 | 
				
			||||||
	AddrFamilyTRILLNickname                 = 16396 // TRILL Nickname
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
							
								
								
									
										12
									
								
								vendor/golang.org/x/net/internal/socket/cmsghdr.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								vendor/golang.org/x/net/internal/socket/cmsghdr.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,12 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
 | 
					 | 
				
			||||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *cmsghdr) len() int { return int(h.Len) }
 | 
					 | 
				
			||||||
func (h *cmsghdr) lvl() int { return int(h.Level) }
 | 
					 | 
				
			||||||
func (h *cmsghdr) typ() int { return int(h.Type) }
 | 
					 | 
				
			||||||
							
								
								
									
										14
									
								
								vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,14 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd
 | 
					 | 
				
			||||||
// +build aix darwin dragonfly freebsd netbsd openbsd
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *cmsghdr) set(l, lvl, typ int) {
 | 
					 | 
				
			||||||
	h.Len = uint32(l)
 | 
					 | 
				
			||||||
	h.Level = int32(lvl)
 | 
					 | 
				
			||||||
	h.Type = int32(typ)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										15
									
								
								vendor/golang.org/x/net/internal/socket/cmsghdr_linux_32bit.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								vendor/golang.org/x/net/internal/socket/cmsghdr_linux_32bit.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,15 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build (arm || mips || mipsle || 386) && linux
 | 
					 | 
				
			||||||
// +build arm mips mipsle 386
 | 
					 | 
				
			||||||
// +build linux
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *cmsghdr) set(l, lvl, typ int) {
 | 
					 | 
				
			||||||
	h.Len = uint32(l)
 | 
					 | 
				
			||||||
	h.Level = int32(lvl)
 | 
					 | 
				
			||||||
	h.Type = int32(typ)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										15
									
								
								vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,15 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build (arm64 || amd64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && linux
 | 
					 | 
				
			||||||
// +build arm64 amd64 ppc64 ppc64le mips64 mips64le riscv64 s390x
 | 
					 | 
				
			||||||
// +build linux
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *cmsghdr) set(l, lvl, typ int) {
 | 
					 | 
				
			||||||
	h.Len = uint64(l)
 | 
					 | 
				
			||||||
	h.Level = int32(lvl)
 | 
					 | 
				
			||||||
	h.Type = int32(typ)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										14
									
								
								vendor/golang.org/x/net/internal/socket/cmsghdr_solaris_64bit.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								vendor/golang.org/x/net/internal/socket/cmsghdr_solaris_64bit.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,14 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build amd64 && solaris
 | 
					 | 
				
			||||||
// +build amd64,solaris
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *cmsghdr) set(l, lvl, typ int) {
 | 
					 | 
				
			||||||
	h.Len = uint32(l)
 | 
					 | 
				
			||||||
	h.Level = int32(lvl)
 | 
					 | 
				
			||||||
	h.Type = int32(typ)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										28
									
								
								vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										28
									
								
								vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,28 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
 | 
					 | 
				
			||||||
// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func controlHeaderLen() int {
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func controlMessageLen(dataLen int) int {
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func controlMessageSpace(dataLen int) int {
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type cmsghdr struct{}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *cmsghdr) len() int { return 0 }
 | 
					 | 
				
			||||||
func (h *cmsghdr) lvl() int { return 0 }
 | 
					 | 
				
			||||||
func (h *cmsghdr) typ() int { return 0 }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *cmsghdr) set(l, lvl, typ int) {}
 | 
					 | 
				
			||||||
							
								
								
									
										22
									
								
								vendor/golang.org/x/net/internal/socket/cmsghdr_unix.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								vendor/golang.org/x/net/internal/socket/cmsghdr_unix.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,22 +0,0 @@
 | 
				
			|||||||
// Copyright 2020 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 | 
					 | 
				
			||||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "golang.org/x/sys/unix"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func controlHeaderLen() int {
 | 
					 | 
				
			||||||
	return unix.CmsgLen(0)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func controlMessageLen(dataLen int) int {
 | 
					 | 
				
			||||||
	return unix.CmsgLen(dataLen)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func controlMessageSpace(dataLen int) int {
 | 
					 | 
				
			||||||
	return unix.CmsgSpace(dataLen)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										25
									
								
								vendor/golang.org/x/net/internal/socket/cmsghdr_zos_s390x.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								vendor/golang.org/x/net/internal/socket/cmsghdr_zos_s390x.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,25 +0,0 @@
 | 
				
			|||||||
// Copyright 2020 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "syscall"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *cmsghdr) set(l, lvl, typ int) {
 | 
					 | 
				
			||||||
	h.Len = int32(l)
 | 
					 | 
				
			||||||
	h.Level = int32(lvl)
 | 
					 | 
				
			||||||
	h.Type = int32(typ)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func controlHeaderLen() int {
 | 
					 | 
				
			||||||
	return syscall.CmsgLen(0)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func controlMessageLen(dataLen int) int {
 | 
					 | 
				
			||||||
	return syscall.CmsgLen(dataLen)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func controlMessageSpace(dataLen int) int {
 | 
					 | 
				
			||||||
	return syscall.CmsgSpace(dataLen)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										7
									
								
								vendor/golang.org/x/net/internal/socket/empty.s
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								vendor/golang.org/x/net/internal/socket/empty.s
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,7 +0,0 @@
 | 
				
			|||||||
// Copyright 2018 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// +build darwin,go1.12
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// This exists solely so we can linkname in symbols from syscall.
 | 
					 | 
				
			||||||
							
								
								
									
										32
									
								
								vendor/golang.org/x/net/internal/socket/error_unix.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								vendor/golang.org/x/net/internal/socket/error_unix.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,32 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
 | 
					 | 
				
			||||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "syscall"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	errEAGAIN error = syscall.EAGAIN
 | 
					 | 
				
			||||||
	errEINVAL error = syscall.EINVAL
 | 
					 | 
				
			||||||
	errENOENT error = syscall.ENOENT
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// errnoErr returns common boxed Errno values, to prevent allocations
 | 
					 | 
				
			||||||
// at runtime.
 | 
					 | 
				
			||||||
func errnoErr(errno syscall.Errno) error {
 | 
					 | 
				
			||||||
	switch errno {
 | 
					 | 
				
			||||||
	case 0:
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	case syscall.EAGAIN:
 | 
					 | 
				
			||||||
		return errEAGAIN
 | 
					 | 
				
			||||||
	case syscall.EINVAL:
 | 
					 | 
				
			||||||
		return errEINVAL
 | 
					 | 
				
			||||||
	case syscall.ENOENT:
 | 
					 | 
				
			||||||
		return errENOENT
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return errno
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										26
									
								
								vendor/golang.org/x/net/internal/socket/error_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										26
									
								
								vendor/golang.org/x/net/internal/socket/error_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,26 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "syscall"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	errERROR_IO_PENDING error = syscall.ERROR_IO_PENDING
 | 
					 | 
				
			||||||
	errEINVAL           error = syscall.EINVAL
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// errnoErr returns common boxed Errno values, to prevent allocations
 | 
					 | 
				
			||||||
// at runtime.
 | 
					 | 
				
			||||||
func errnoErr(errno syscall.Errno) error {
 | 
					 | 
				
			||||||
	switch errno {
 | 
					 | 
				
			||||||
	case 0:
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	case syscall.ERROR_IO_PENDING:
 | 
					 | 
				
			||||||
		return errERROR_IO_PENDING
 | 
					 | 
				
			||||||
	case syscall.EINVAL:
 | 
					 | 
				
			||||||
		return errEINVAL
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return errno
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										20
									
								
								vendor/golang.org/x/net/internal/socket/iovec_32bit.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								vendor/golang.org/x/net/internal/socket/iovec_32bit.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,20 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build (arm || mips || mipsle || 386) && (darwin || dragonfly || freebsd || linux || netbsd || openbsd)
 | 
					 | 
				
			||||||
// +build arm mips mipsle 386
 | 
					 | 
				
			||||||
// +build darwin dragonfly freebsd linux netbsd openbsd
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "unsafe"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (v *iovec) set(b []byte) {
 | 
					 | 
				
			||||||
	l := len(b)
 | 
					 | 
				
			||||||
	if l == 0 {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	v.Base = (*byte)(unsafe.Pointer(&b[0]))
 | 
					 | 
				
			||||||
	v.Len = uint32(l)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										20
									
								
								vendor/golang.org/x/net/internal/socket/iovec_64bit.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								vendor/golang.org/x/net/internal/socket/iovec_64bit.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,20 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build (arm64 || amd64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || zos)
 | 
					 | 
				
			||||||
// +build arm64 amd64 ppc64 ppc64le mips64 mips64le riscv64 s390x
 | 
					 | 
				
			||||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd zos
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "unsafe"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (v *iovec) set(b []byte) {
 | 
					 | 
				
			||||||
	l := len(b)
 | 
					 | 
				
			||||||
	if l == 0 {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	v.Base = (*byte)(unsafe.Pointer(&b[0]))
 | 
					 | 
				
			||||||
	v.Len = uint64(l)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										19
									
								
								vendor/golang.org/x/net/internal/socket/iovec_solaris_64bit.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								vendor/golang.org/x/net/internal/socket/iovec_solaris_64bit.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,19 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build amd64 && solaris
 | 
					 | 
				
			||||||
// +build amd64,solaris
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "unsafe"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (v *iovec) set(b []byte) {
 | 
					 | 
				
			||||||
	l := len(b)
 | 
					 | 
				
			||||||
	if l == 0 {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	v.Base = (*int8)(unsafe.Pointer(&b[0]))
 | 
					 | 
				
			||||||
	v.Len = uint64(l)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										12
									
								
								vendor/golang.org/x/net/internal/socket/iovec_stub.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								vendor/golang.org/x/net/internal/socket/iovec_stub.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,12 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
 | 
					 | 
				
			||||||
// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type iovec struct{}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (v *iovec) set(b []byte) {}
 | 
					 | 
				
			||||||
							
								
								
									
										22
									
								
								vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,22 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build !aix && !linux && !netbsd
 | 
					 | 
				
			||||||
// +build !aix,!linux,!netbsd
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "net"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type mmsghdr struct{}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type mmsghdrs []mmsghdr
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (hs mmsghdrs) pack(ms []Message, parseFn func([]byte, string) (net.Addr, error), marshalFn func(net.Addr) []byte) error {
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (hs mmsghdrs) unpack(ms []Message, parseFn func([]byte, string) (net.Addr, error), hint string) error {
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										43
									
								
								vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										43
									
								
								vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,43 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build aix || linux || netbsd
 | 
					 | 
				
			||||||
// +build aix linux netbsd
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "net"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type mmsghdrs []mmsghdr
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (hs mmsghdrs) pack(ms []Message, parseFn func([]byte, string) (net.Addr, error), marshalFn func(net.Addr) []byte) error {
 | 
					 | 
				
			||||||
	for i := range hs {
 | 
					 | 
				
			||||||
		vs := make([]iovec, len(ms[i].Buffers))
 | 
					 | 
				
			||||||
		var sa []byte
 | 
					 | 
				
			||||||
		if parseFn != nil {
 | 
					 | 
				
			||||||
			sa = make([]byte, sizeofSockaddrInet6)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if marshalFn != nil {
 | 
					 | 
				
			||||||
			sa = marshalFn(ms[i].Addr)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		hs[i].Hdr.pack(vs, ms[i].Buffers, ms[i].OOB, sa)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (hs mmsghdrs) unpack(ms []Message, parseFn func([]byte, string) (net.Addr, error), hint string) error {
 | 
					 | 
				
			||||||
	for i := range hs {
 | 
					 | 
				
			||||||
		ms[i].N = int(hs[i].Len)
 | 
					 | 
				
			||||||
		ms[i].NN = hs[i].Hdr.controllen()
 | 
					 | 
				
			||||||
		ms[i].Flags = hs[i].Hdr.flags()
 | 
					 | 
				
			||||||
		if parseFn != nil {
 | 
					 | 
				
			||||||
			var err error
 | 
					 | 
				
			||||||
			ms[i].Addr, err = parseFn(hs[i].Hdr.name(), hint)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										40
									
								
								vendor/golang.org/x/net/internal/socket/msghdr_bsd.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										40
									
								
								vendor/golang.org/x/net/internal/socket/msghdr_bsd.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,40 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd
 | 
					 | 
				
			||||||
// +build aix darwin dragonfly freebsd netbsd openbsd
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "unsafe"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {
 | 
					 | 
				
			||||||
	for i := range vs {
 | 
					 | 
				
			||||||
		vs[i].set(bs[i])
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	h.setIov(vs)
 | 
					 | 
				
			||||||
	if len(oob) > 0 {
 | 
					 | 
				
			||||||
		h.Control = (*byte)(unsafe.Pointer(&oob[0]))
 | 
					 | 
				
			||||||
		h.Controllen = uint32(len(oob))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if sa != nil {
 | 
					 | 
				
			||||||
		h.Name = (*byte)(unsafe.Pointer(&sa[0]))
 | 
					 | 
				
			||||||
		h.Namelen = uint32(len(sa))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *msghdr) name() []byte {
 | 
					 | 
				
			||||||
	if h.Name != nil && h.Namelen > 0 {
 | 
					 | 
				
			||||||
		return (*[sizeofSockaddrInet6]byte)(unsafe.Pointer(h.Name))[:h.Namelen]
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *msghdr) controllen() int {
 | 
					 | 
				
			||||||
	return int(h.Controllen)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *msghdr) flags() int {
 | 
					 | 
				
			||||||
	return int(h.Flags)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										17
									
								
								vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,17 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build aix || darwin || dragonfly || freebsd || netbsd
 | 
					 | 
				
			||||||
// +build aix darwin dragonfly freebsd netbsd
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *msghdr) setIov(vs []iovec) {
 | 
					 | 
				
			||||||
	l := len(vs)
 | 
					 | 
				
			||||||
	if l == 0 {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	h.Iov = &vs[0]
 | 
					 | 
				
			||||||
	h.Iovlen = int32(l)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										36
									
								
								vendor/golang.org/x/net/internal/socket/msghdr_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										36
									
								
								vendor/golang.org/x/net/internal/socket/msghdr_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,36 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "unsafe"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {
 | 
					 | 
				
			||||||
	for i := range vs {
 | 
					 | 
				
			||||||
		vs[i].set(bs[i])
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	h.setIov(vs)
 | 
					 | 
				
			||||||
	if len(oob) > 0 {
 | 
					 | 
				
			||||||
		h.setControl(oob)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if sa != nil {
 | 
					 | 
				
			||||||
		h.Name = (*byte)(unsafe.Pointer(&sa[0]))
 | 
					 | 
				
			||||||
		h.Namelen = uint32(len(sa))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *msghdr) name() []byte {
 | 
					 | 
				
			||||||
	if h.Name != nil && h.Namelen > 0 {
 | 
					 | 
				
			||||||
		return (*[sizeofSockaddrInet6]byte)(unsafe.Pointer(h.Name))[:h.Namelen]
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *msghdr) controllen() int {
 | 
					 | 
				
			||||||
	return int(h.Controllen)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *msghdr) flags() int {
 | 
					 | 
				
			||||||
	return int(h.Flags)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										25
									
								
								vendor/golang.org/x/net/internal/socket/msghdr_linux_32bit.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								vendor/golang.org/x/net/internal/socket/msghdr_linux_32bit.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,25 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build (arm || mips || mipsle || 386) && linux
 | 
					 | 
				
			||||||
// +build arm mips mipsle 386
 | 
					 | 
				
			||||||
// +build linux
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "unsafe"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *msghdr) setIov(vs []iovec) {
 | 
					 | 
				
			||||||
	l := len(vs)
 | 
					 | 
				
			||||||
	if l == 0 {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	h.Iov = &vs[0]
 | 
					 | 
				
			||||||
	h.Iovlen = uint32(l)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *msghdr) setControl(b []byte) {
 | 
					 | 
				
			||||||
	h.Control = (*byte)(unsafe.Pointer(&b[0]))
 | 
					 | 
				
			||||||
	h.Controllen = uint32(len(b))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										25
									
								
								vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,25 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build (arm64 || amd64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && linux
 | 
					 | 
				
			||||||
// +build arm64 amd64 ppc64 ppc64le mips64 mips64le riscv64 s390x
 | 
					 | 
				
			||||||
// +build linux
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "unsafe"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *msghdr) setIov(vs []iovec) {
 | 
					 | 
				
			||||||
	l := len(vs)
 | 
					 | 
				
			||||||
	if l == 0 {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	h.Iov = &vs[0]
 | 
					 | 
				
			||||||
	h.Iovlen = uint64(l)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *msghdr) setControl(b []byte) {
 | 
					 | 
				
			||||||
	h.Control = (*byte)(unsafe.Pointer(&b[0]))
 | 
					 | 
				
			||||||
	h.Controllen = uint64(len(b))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										14
									
								
								vendor/golang.org/x/net/internal/socket/msghdr_openbsd.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								vendor/golang.org/x/net/internal/socket/msghdr_openbsd.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,14 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *msghdr) setIov(vs []iovec) {
 | 
					 | 
				
			||||||
	l := len(vs)
 | 
					 | 
				
			||||||
	if l == 0 {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	h.Iov = &vs[0]
 | 
					 | 
				
			||||||
	h.Iovlen = uint32(l)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										36
									
								
								vendor/golang.org/x/net/internal/socket/msghdr_solaris_64bit.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										36
									
								
								vendor/golang.org/x/net/internal/socket/msghdr_solaris_64bit.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,36 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build amd64 && solaris
 | 
					 | 
				
			||||||
// +build amd64,solaris
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "unsafe"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {
 | 
					 | 
				
			||||||
	for i := range vs {
 | 
					 | 
				
			||||||
		vs[i].set(bs[i])
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(vs) > 0 {
 | 
					 | 
				
			||||||
		h.Iov = &vs[0]
 | 
					 | 
				
			||||||
		h.Iovlen = int32(len(vs))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(oob) > 0 {
 | 
					 | 
				
			||||||
		h.Accrights = (*int8)(unsafe.Pointer(&oob[0]))
 | 
					 | 
				
			||||||
		h.Accrightslen = int32(len(oob))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if sa != nil {
 | 
					 | 
				
			||||||
		h.Name = (*byte)(unsafe.Pointer(&sa[0]))
 | 
					 | 
				
			||||||
		h.Namelen = uint32(len(sa))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *msghdr) controllen() int {
 | 
					 | 
				
			||||||
	return int(h.Accrightslen)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *msghdr) flags() int {
 | 
					 | 
				
			||||||
	return int(NativeEndian.Uint32(h.Pad_cgo_2[:]))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										15
									
								
								vendor/golang.org/x/net/internal/socket/msghdr_stub.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								vendor/golang.org/x/net/internal/socket/msghdr_stub.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,15 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
 | 
					 | 
				
			||||||
// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type msghdr struct{}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {}
 | 
					 | 
				
			||||||
func (h *msghdr) name() []byte                                        { return nil }
 | 
					 | 
				
			||||||
func (h *msghdr) controllen() int                                     { return 0 }
 | 
					 | 
				
			||||||
func (h *msghdr) flags() int                                          { return 0 }
 | 
					 | 
				
			||||||
							
								
								
									
										36
									
								
								vendor/golang.org/x/net/internal/socket/msghdr_zos_s390x.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										36
									
								
								vendor/golang.org/x/net/internal/socket/msghdr_zos_s390x.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,36 +0,0 @@
 | 
				
			|||||||
// Copyright 2020 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build s390x && zos
 | 
					 | 
				
			||||||
// +build s390x,zos
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "unsafe"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {
 | 
					 | 
				
			||||||
	for i := range vs {
 | 
					 | 
				
			||||||
		vs[i].set(bs[i])
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(vs) > 0 {
 | 
					 | 
				
			||||||
		h.Iov = &vs[0]
 | 
					 | 
				
			||||||
		h.Iovlen = int32(len(vs))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(oob) > 0 {
 | 
					 | 
				
			||||||
		h.Control = (*byte)(unsafe.Pointer(&oob[0]))
 | 
					 | 
				
			||||||
		h.Controllen = uint32(len(oob))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if sa != nil {
 | 
					 | 
				
			||||||
		h.Name = (*byte)(unsafe.Pointer(&sa[0]))
 | 
					 | 
				
			||||||
		h.Namelen = uint32(len(sa))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *msghdr) controllen() int {
 | 
					 | 
				
			||||||
	return int(h.Controllen)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *msghdr) flags() int {
 | 
					 | 
				
			||||||
	return int(h.Flags)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										13
									
								
								vendor/golang.org/x/net/internal/socket/norace.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								vendor/golang.org/x/net/internal/socket/norace.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,13 +0,0 @@
 | 
				
			|||||||
// Copyright 2019 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build !race
 | 
					 | 
				
			||||||
// +build !race
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (m *Message) raceRead() {
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (m *Message) raceWrite() {
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										38
									
								
								vendor/golang.org/x/net/internal/socket/race.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										38
									
								
								vendor/golang.org/x/net/internal/socket/race.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,38 +0,0 @@
 | 
				
			|||||||
// Copyright 2019 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build race
 | 
					 | 
				
			||||||
// +build race
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"runtime"
 | 
					 | 
				
			||||||
	"unsafe"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// This package reads and writes the Message buffers using a
 | 
					 | 
				
			||||||
// direct system call, which the race detector can't see.
 | 
					 | 
				
			||||||
// These functions tell the race detector what is going on during the syscall.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (m *Message) raceRead() {
 | 
					 | 
				
			||||||
	for _, b := range m.Buffers {
 | 
					 | 
				
			||||||
		if len(b) > 0 {
 | 
					 | 
				
			||||||
			runtime.RaceReadRange(unsafe.Pointer(&b[0]), len(b))
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if b := m.OOB; len(b) > 0 {
 | 
					 | 
				
			||||||
		runtime.RaceReadRange(unsafe.Pointer(&b[0]), len(b))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (m *Message) raceWrite() {
 | 
					 | 
				
			||||||
	for _, b := range m.Buffers {
 | 
					 | 
				
			||||||
		if len(b) > 0 {
 | 
					 | 
				
			||||||
			runtime.RaceWriteRange(unsafe.Pointer(&b[0]), len(b))
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if b := m.OOB; len(b) > 0 {
 | 
					 | 
				
			||||||
		runtime.RaceWriteRange(unsafe.Pointer(&b[0]), len(b))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										91
									
								
								vendor/golang.org/x/net/internal/socket/rawconn.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										91
									
								
								vendor/golang.org/x/net/internal/socket/rawconn.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,91 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"net"
 | 
					 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
	"syscall"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// A Conn represents a raw connection.
 | 
					 | 
				
			||||||
type Conn struct {
 | 
					 | 
				
			||||||
	network string
 | 
					 | 
				
			||||||
	c       syscall.RawConn
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// tcpConn is an interface implemented by net.TCPConn.
 | 
					 | 
				
			||||||
// It can be used for interface assertions to check if a net.Conn is a TCP connection.
 | 
					 | 
				
			||||||
type tcpConn interface {
 | 
					 | 
				
			||||||
	SyscallConn() (syscall.RawConn, error)
 | 
					 | 
				
			||||||
	SetLinger(int) error
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var _ tcpConn = (*net.TCPConn)(nil)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// udpConn is an interface implemented by net.UDPConn.
 | 
					 | 
				
			||||||
// It can be used for interface assertions to check if a net.Conn is a UDP connection.
 | 
					 | 
				
			||||||
type udpConn interface {
 | 
					 | 
				
			||||||
	SyscallConn() (syscall.RawConn, error)
 | 
					 | 
				
			||||||
	ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *net.UDPAddr, err error)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var _ udpConn = (*net.UDPConn)(nil)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ipConn is an interface implemented by net.IPConn.
 | 
					 | 
				
			||||||
// It can be used for interface assertions to check if a net.Conn is an IP connection.
 | 
					 | 
				
			||||||
type ipConn interface {
 | 
					 | 
				
			||||||
	SyscallConn() (syscall.RawConn, error)
 | 
					 | 
				
			||||||
	ReadMsgIP(b, oob []byte) (n, oobn, flags int, addr *net.IPAddr, err error)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var _ ipConn = (*net.IPConn)(nil)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NewConn returns a new raw connection.
 | 
					 | 
				
			||||||
func NewConn(c net.Conn) (*Conn, error) {
 | 
					 | 
				
			||||||
	var err error
 | 
					 | 
				
			||||||
	var cc Conn
 | 
					 | 
				
			||||||
	switch c := c.(type) {
 | 
					 | 
				
			||||||
	case tcpConn:
 | 
					 | 
				
			||||||
		cc.network = "tcp"
 | 
					 | 
				
			||||||
		cc.c, err = c.SyscallConn()
 | 
					 | 
				
			||||||
	case udpConn:
 | 
					 | 
				
			||||||
		cc.network = "udp"
 | 
					 | 
				
			||||||
		cc.c, err = c.SyscallConn()
 | 
					 | 
				
			||||||
	case ipConn:
 | 
					 | 
				
			||||||
		cc.network = "ip"
 | 
					 | 
				
			||||||
		cc.c, err = c.SyscallConn()
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return nil, errors.New("unknown connection type")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &cc, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (o *Option) get(c *Conn, b []byte) (int, error) {
 | 
					 | 
				
			||||||
	var operr error
 | 
					 | 
				
			||||||
	var n int
 | 
					 | 
				
			||||||
	fn := func(s uintptr) {
 | 
					 | 
				
			||||||
		n, operr = getsockopt(s, o.Level, o.Name, b)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := c.c.Control(fn); err != nil {
 | 
					 | 
				
			||||||
		return 0, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return n, os.NewSyscallError("getsockopt", operr)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (o *Option) set(c *Conn, b []byte) error {
 | 
					 | 
				
			||||||
	var operr error
 | 
					 | 
				
			||||||
	fn := func(s uintptr) {
 | 
					 | 
				
			||||||
		operr = setsockopt(s, o.Level, o.Name, b)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := c.c.Control(fn); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return os.NewSyscallError("setsockopt", operr)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										80
									
								
								vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										80
									
								
								vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,80 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build linux
 | 
					 | 
				
			||||||
// +build linux
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"net"
 | 
					 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
	"syscall"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (c *Conn) recvMsgs(ms []Message, flags int) (int, error) {
 | 
					 | 
				
			||||||
	for i := range ms {
 | 
					 | 
				
			||||||
		ms[i].raceWrite()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	hs := make(mmsghdrs, len(ms))
 | 
					 | 
				
			||||||
	var parseFn func([]byte, string) (net.Addr, error)
 | 
					 | 
				
			||||||
	if c.network != "tcp" {
 | 
					 | 
				
			||||||
		parseFn = parseInetAddr
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := hs.pack(ms, parseFn, nil); err != nil {
 | 
					 | 
				
			||||||
		return 0, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	var operr error
 | 
					 | 
				
			||||||
	var n int
 | 
					 | 
				
			||||||
	fn := func(s uintptr) bool {
 | 
					 | 
				
			||||||
		n, operr = recvmmsg(s, hs, flags)
 | 
					 | 
				
			||||||
		if operr == syscall.EAGAIN {
 | 
					 | 
				
			||||||
			return false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := c.c.Read(fn); err != nil {
 | 
					 | 
				
			||||||
		return n, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if operr != nil {
 | 
					 | 
				
			||||||
		return n, os.NewSyscallError("recvmmsg", operr)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := hs[:n].unpack(ms[:n], parseFn, c.network); err != nil {
 | 
					 | 
				
			||||||
		return n, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return n, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (c *Conn) sendMsgs(ms []Message, flags int) (int, error) {
 | 
					 | 
				
			||||||
	for i := range ms {
 | 
					 | 
				
			||||||
		ms[i].raceRead()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	hs := make(mmsghdrs, len(ms))
 | 
					 | 
				
			||||||
	var marshalFn func(net.Addr) []byte
 | 
					 | 
				
			||||||
	if c.network != "tcp" {
 | 
					 | 
				
			||||||
		marshalFn = marshalInetAddr
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := hs.pack(ms, nil, marshalFn); err != nil {
 | 
					 | 
				
			||||||
		return 0, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	var operr error
 | 
					 | 
				
			||||||
	var n int
 | 
					 | 
				
			||||||
	fn := func(s uintptr) bool {
 | 
					 | 
				
			||||||
		n, operr = sendmmsg(s, hs, flags)
 | 
					 | 
				
			||||||
		if operr == syscall.EAGAIN {
 | 
					 | 
				
			||||||
			return false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := c.c.Write(fn); err != nil {
 | 
					 | 
				
			||||||
		return n, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if operr != nil {
 | 
					 | 
				
			||||||
		return n, os.NewSyscallError("sendmmsg", operr)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := hs[:n].unpack(ms[:n], nil, ""); err != nil {
 | 
					 | 
				
			||||||
		return n, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return n, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										79
									
								
								vendor/golang.org/x/net/internal/socket/rawconn_msg.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										79
									
								
								vendor/golang.org/x/net/internal/socket/rawconn_msg.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,79 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows || zos
 | 
					 | 
				
			||||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows zos
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
	"syscall"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (c *Conn) recvMsg(m *Message, flags int) error {
 | 
					 | 
				
			||||||
	m.raceWrite()
 | 
					 | 
				
			||||||
	var h msghdr
 | 
					 | 
				
			||||||
	vs := make([]iovec, len(m.Buffers))
 | 
					 | 
				
			||||||
	var sa []byte
 | 
					 | 
				
			||||||
	if c.network != "tcp" {
 | 
					 | 
				
			||||||
		sa = make([]byte, sizeofSockaddrInet6)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	h.pack(vs, m.Buffers, m.OOB, sa)
 | 
					 | 
				
			||||||
	var operr error
 | 
					 | 
				
			||||||
	var n int
 | 
					 | 
				
			||||||
	fn := func(s uintptr) bool {
 | 
					 | 
				
			||||||
		n, operr = recvmsg(s, &h, flags)
 | 
					 | 
				
			||||||
		if operr == syscall.EAGAIN || operr == syscall.EWOULDBLOCK {
 | 
					 | 
				
			||||||
			return false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := c.c.Read(fn); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if operr != nil {
 | 
					 | 
				
			||||||
		return os.NewSyscallError("recvmsg", operr)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if c.network != "tcp" {
 | 
					 | 
				
			||||||
		var err error
 | 
					 | 
				
			||||||
		m.Addr, err = parseInetAddr(sa[:], c.network)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	m.N = n
 | 
					 | 
				
			||||||
	m.NN = h.controllen()
 | 
					 | 
				
			||||||
	m.Flags = h.flags()
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (c *Conn) sendMsg(m *Message, flags int) error {
 | 
					 | 
				
			||||||
	m.raceRead()
 | 
					 | 
				
			||||||
	var h msghdr
 | 
					 | 
				
			||||||
	vs := make([]iovec, len(m.Buffers))
 | 
					 | 
				
			||||||
	var sa []byte
 | 
					 | 
				
			||||||
	if m.Addr != nil {
 | 
					 | 
				
			||||||
		sa = marshalInetAddr(m.Addr)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	h.pack(vs, m.Buffers, m.OOB, sa)
 | 
					 | 
				
			||||||
	var operr error
 | 
					 | 
				
			||||||
	var n int
 | 
					 | 
				
			||||||
	fn := func(s uintptr) bool {
 | 
					 | 
				
			||||||
		n, operr = sendmsg(s, &h, flags)
 | 
					 | 
				
			||||||
		if operr == syscall.EAGAIN || operr == syscall.EWOULDBLOCK {
 | 
					 | 
				
			||||||
			return false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := c.c.Write(fn); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if operr != nil {
 | 
					 | 
				
			||||||
		return os.NewSyscallError("sendmsg", operr)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	m.N = n
 | 
					 | 
				
			||||||
	m.NN = len(m.OOB)
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										16
									
								
								vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,16 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build !linux
 | 
					 | 
				
			||||||
// +build !linux
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (c *Conn) recvMsgs(ms []Message, flags int) (int, error) {
 | 
					 | 
				
			||||||
	return 0, errNotImplemented
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (c *Conn) sendMsgs(ms []Message, flags int) (int, error) {
 | 
					 | 
				
			||||||
	return 0, errNotImplemented
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										16
									
								
								vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,16 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
 | 
					 | 
				
			||||||
// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (c *Conn) recvMsg(m *Message, flags int) error {
 | 
					 | 
				
			||||||
	return errNotImplemented
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (c *Conn) sendMsg(m *Message, flags int) error {
 | 
					 | 
				
			||||||
	return errNotImplemented
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										280
									
								
								vendor/golang.org/x/net/internal/socket/socket.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										280
									
								
								vendor/golang.org/x/net/internal/socket/socket.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,280 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Package socket provides a portable interface for socket system
 | 
					 | 
				
			||||||
// calls.
 | 
					 | 
				
			||||||
package socket // import "golang.org/x/net/internal/socket"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"net"
 | 
					 | 
				
			||||||
	"runtime"
 | 
					 | 
				
			||||||
	"unsafe"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var errNotImplemented = errors.New("not implemented on " + runtime.GOOS + "/" + runtime.GOARCH)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// An Option represents a sticky socket option.
 | 
					 | 
				
			||||||
type Option struct {
 | 
					 | 
				
			||||||
	Level int // level
 | 
					 | 
				
			||||||
	Name  int // name; must be equal or greater than 1
 | 
					 | 
				
			||||||
	Len   int // length of value in bytes; must be equal or greater than 1
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Get reads a value for the option from the kernel.
 | 
					 | 
				
			||||||
// It returns the number of bytes written into b.
 | 
					 | 
				
			||||||
func (o *Option) Get(c *Conn, b []byte) (int, error) {
 | 
					 | 
				
			||||||
	if o.Name < 1 || o.Len < 1 {
 | 
					 | 
				
			||||||
		return 0, errors.New("invalid option")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(b) < o.Len {
 | 
					 | 
				
			||||||
		return 0, errors.New("short buffer")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return o.get(c, b)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// GetInt returns an integer value for the option.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// The Len field of Option must be either 1 or 4.
 | 
					 | 
				
			||||||
func (o *Option) GetInt(c *Conn) (int, error) {
 | 
					 | 
				
			||||||
	if o.Len != 1 && o.Len != 4 {
 | 
					 | 
				
			||||||
		return 0, errors.New("invalid option")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	var b []byte
 | 
					 | 
				
			||||||
	var bb [4]byte
 | 
					 | 
				
			||||||
	if o.Len == 1 {
 | 
					 | 
				
			||||||
		b = bb[:1]
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		b = bb[:4]
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	n, err := o.get(c, b)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return 0, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if n != o.Len {
 | 
					 | 
				
			||||||
		return 0, errors.New("invalid option length")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if o.Len == 1 {
 | 
					 | 
				
			||||||
		return int(b[0]), nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return int(NativeEndian.Uint32(b[:4])), nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Set writes the option and value to the kernel.
 | 
					 | 
				
			||||||
func (o *Option) Set(c *Conn, b []byte) error {
 | 
					 | 
				
			||||||
	if o.Name < 1 || o.Len < 1 {
 | 
					 | 
				
			||||||
		return errors.New("invalid option")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(b) < o.Len {
 | 
					 | 
				
			||||||
		return errors.New("short buffer")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return o.set(c, b)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SetInt writes the option and value to the kernel.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// The Len field of Option must be either 1 or 4.
 | 
					 | 
				
			||||||
func (o *Option) SetInt(c *Conn, v int) error {
 | 
					 | 
				
			||||||
	if o.Len != 1 && o.Len != 4 {
 | 
					 | 
				
			||||||
		return errors.New("invalid option")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	var b []byte
 | 
					 | 
				
			||||||
	if o.Len == 1 {
 | 
					 | 
				
			||||||
		b = []byte{byte(v)}
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		var bb [4]byte
 | 
					 | 
				
			||||||
		NativeEndian.PutUint32(bb[:o.Len], uint32(v))
 | 
					 | 
				
			||||||
		b = bb[:4]
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return o.set(c, b)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ControlMessageSpace returns the whole length of control message.
 | 
					 | 
				
			||||||
func ControlMessageSpace(dataLen int) int {
 | 
					 | 
				
			||||||
	return controlMessageSpace(dataLen)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// A ControlMessage represents the head message in a stream of control
 | 
					 | 
				
			||||||
// messages.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// A control message comprises of a header, data and a few padding
 | 
					 | 
				
			||||||
// fields to conform to the interface to the kernel.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// See RFC 3542 for further information.
 | 
					 | 
				
			||||||
type ControlMessage []byte
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Data returns the data field of the control message at the head on
 | 
					 | 
				
			||||||
// m.
 | 
					 | 
				
			||||||
func (m ControlMessage) Data(dataLen int) []byte {
 | 
					 | 
				
			||||||
	l := controlHeaderLen()
 | 
					 | 
				
			||||||
	if len(m) < l || len(m) < l+dataLen {
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return m[l : l+dataLen]
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Next returns the control message at the next on m.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Next works only for standard control messages.
 | 
					 | 
				
			||||||
func (m ControlMessage) Next(dataLen int) ControlMessage {
 | 
					 | 
				
			||||||
	l := ControlMessageSpace(dataLen)
 | 
					 | 
				
			||||||
	if len(m) < l {
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return m[l:]
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// MarshalHeader marshals the header fields of the control message at
 | 
					 | 
				
			||||||
// the head on m.
 | 
					 | 
				
			||||||
func (m ControlMessage) MarshalHeader(lvl, typ, dataLen int) error {
 | 
					 | 
				
			||||||
	if len(m) < controlHeaderLen() {
 | 
					 | 
				
			||||||
		return errors.New("short message")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	h := (*cmsghdr)(unsafe.Pointer(&m[0]))
 | 
					 | 
				
			||||||
	h.set(controlMessageLen(dataLen), lvl, typ)
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ParseHeader parses and returns the header fields of the control
 | 
					 | 
				
			||||||
// message at the head on m.
 | 
					 | 
				
			||||||
func (m ControlMessage) ParseHeader() (lvl, typ, dataLen int, err error) {
 | 
					 | 
				
			||||||
	l := controlHeaderLen()
 | 
					 | 
				
			||||||
	if len(m) < l {
 | 
					 | 
				
			||||||
		return 0, 0, 0, errors.New("short message")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	h := (*cmsghdr)(unsafe.Pointer(&m[0]))
 | 
					 | 
				
			||||||
	return h.lvl(), h.typ(), int(uint64(h.len()) - uint64(l)), nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Marshal marshals the control message at the head on m, and returns
 | 
					 | 
				
			||||||
// the next control message.
 | 
					 | 
				
			||||||
func (m ControlMessage) Marshal(lvl, typ int, data []byte) (ControlMessage, error) {
 | 
					 | 
				
			||||||
	l := len(data)
 | 
					 | 
				
			||||||
	if len(m) < ControlMessageSpace(l) {
 | 
					 | 
				
			||||||
		return nil, errors.New("short message")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	h := (*cmsghdr)(unsafe.Pointer(&m[0]))
 | 
					 | 
				
			||||||
	h.set(controlMessageLen(l), lvl, typ)
 | 
					 | 
				
			||||||
	if l > 0 {
 | 
					 | 
				
			||||||
		copy(m.Data(l), data)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return m.Next(l), nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Parse parses m as a single or multiple control messages.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Parse works for both standard and compatible messages.
 | 
					 | 
				
			||||||
func (m ControlMessage) Parse() ([]ControlMessage, error) {
 | 
					 | 
				
			||||||
	var ms []ControlMessage
 | 
					 | 
				
			||||||
	for len(m) >= controlHeaderLen() {
 | 
					 | 
				
			||||||
		h := (*cmsghdr)(unsafe.Pointer(&m[0]))
 | 
					 | 
				
			||||||
		l := h.len()
 | 
					 | 
				
			||||||
		if l <= 0 {
 | 
					 | 
				
			||||||
			return nil, errors.New("invalid header length")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if uint64(l) < uint64(controlHeaderLen()) {
 | 
					 | 
				
			||||||
			return nil, errors.New("invalid message length")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if uint64(l) > uint64(len(m)) {
 | 
					 | 
				
			||||||
			return nil, errors.New("short buffer")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		// On message reception:
 | 
					 | 
				
			||||||
		//
 | 
					 | 
				
			||||||
		// |<- ControlMessageSpace --------------->|
 | 
					 | 
				
			||||||
		// |<- controlMessageLen ---------->|      |
 | 
					 | 
				
			||||||
		// |<- controlHeaderLen ->|         |      |
 | 
					 | 
				
			||||||
		// +---------------+------+---------+------+
 | 
					 | 
				
			||||||
		// |    Header     | PadH |  Data   | PadD |
 | 
					 | 
				
			||||||
		// +---------------+------+---------+------+
 | 
					 | 
				
			||||||
		//
 | 
					 | 
				
			||||||
		// On compatible message reception:
 | 
					 | 
				
			||||||
		//
 | 
					 | 
				
			||||||
		// | ... |<- controlMessageLen ----------->|
 | 
					 | 
				
			||||||
		// | ... |<- controlHeaderLen ->|          |
 | 
					 | 
				
			||||||
		// +-----+---------------+------+----------+
 | 
					 | 
				
			||||||
		// | ... |    Header     | PadH |   Data   |
 | 
					 | 
				
			||||||
		// +-----+---------------+------+----------+
 | 
					 | 
				
			||||||
		ms = append(ms, ControlMessage(m[:l]))
 | 
					 | 
				
			||||||
		ll := l - controlHeaderLen()
 | 
					 | 
				
			||||||
		if len(m) >= ControlMessageSpace(ll) {
 | 
					 | 
				
			||||||
			m = m[ControlMessageSpace(ll):]
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			m = m[controlMessageLen(ll):]
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return ms, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NewControlMessage returns a new stream of control messages.
 | 
					 | 
				
			||||||
func NewControlMessage(dataLen []int) ControlMessage {
 | 
					 | 
				
			||||||
	var l int
 | 
					 | 
				
			||||||
	for i := range dataLen {
 | 
					 | 
				
			||||||
		l += ControlMessageSpace(dataLen[i])
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return make([]byte, l)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// A Message represents an IO message.
 | 
					 | 
				
			||||||
type Message struct {
 | 
					 | 
				
			||||||
	// When writing, the Buffers field must contain at least one
 | 
					 | 
				
			||||||
	// byte to write.
 | 
					 | 
				
			||||||
	// When reading, the Buffers field will always contain a byte
 | 
					 | 
				
			||||||
	// to read.
 | 
					 | 
				
			||||||
	Buffers [][]byte
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// OOB contains protocol-specific control or miscellaneous
 | 
					 | 
				
			||||||
	// ancillary data known as out-of-band data.
 | 
					 | 
				
			||||||
	OOB []byte
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Addr specifies a destination address when writing.
 | 
					 | 
				
			||||||
	// It can be nil when the underlying protocol of the raw
 | 
					 | 
				
			||||||
	// connection uses connection-oriented communication.
 | 
					 | 
				
			||||||
	// After a successful read, it may contain the source address
 | 
					 | 
				
			||||||
	// on the received packet.
 | 
					 | 
				
			||||||
	Addr net.Addr
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	N     int // # of bytes read or written from/to Buffers
 | 
					 | 
				
			||||||
	NN    int // # of bytes read or written from/to OOB
 | 
					 | 
				
			||||||
	Flags int // protocol-specific information on the received message
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// RecvMsg wraps recvmsg system call.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// The provided flags is a set of platform-dependent flags, such as
 | 
					 | 
				
			||||||
// syscall.MSG_PEEK.
 | 
					 | 
				
			||||||
func (c *Conn) RecvMsg(m *Message, flags int) error {
 | 
					 | 
				
			||||||
	return c.recvMsg(m, flags)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SendMsg wraps sendmsg system call.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// The provided flags is a set of platform-dependent flags, such as
 | 
					 | 
				
			||||||
// syscall.MSG_DONTROUTE.
 | 
					 | 
				
			||||||
func (c *Conn) SendMsg(m *Message, flags int) error {
 | 
					 | 
				
			||||||
	return c.sendMsg(m, flags)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// RecvMsgs wraps recvmmsg system call.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// It returns the number of processed messages.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// The provided flags is a set of platform-dependent flags, such as
 | 
					 | 
				
			||||||
// syscall.MSG_PEEK.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Only Linux supports this.
 | 
					 | 
				
			||||||
func (c *Conn) RecvMsgs(ms []Message, flags int) (int, error) {
 | 
					 | 
				
			||||||
	return c.recvMsgs(ms, flags)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SendMsgs wraps sendmmsg system call.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// It returns the number of processed messages.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// The provided flags is a set of platform-dependent flags, such as
 | 
					 | 
				
			||||||
// syscall.MSG_DONTROUTE.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Only Linux supports this.
 | 
					 | 
				
			||||||
func (c *Conn) SendMsgs(ms []Message, flags int) (int, error) {
 | 
					 | 
				
			||||||
	return c.sendMsgs(ms, flags)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										23
									
								
								vendor/golang.org/x/net/internal/socket/sys.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								vendor/golang.org/x/net/internal/socket/sys.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,23 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/binary"
 | 
					 | 
				
			||||||
	"unsafe"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NativeEndian is the machine native endian implementation of ByteOrder.
 | 
					 | 
				
			||||||
var NativeEndian binary.ByteOrder
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func init() {
 | 
					 | 
				
			||||||
	i := uint32(1)
 | 
					 | 
				
			||||||
	b := (*[4]byte)(unsafe.Pointer(&i))
 | 
					 | 
				
			||||||
	if b[0] == 1 {
 | 
					 | 
				
			||||||
		NativeEndian = binary.LittleEndian
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		NativeEndian = binary.BigEndian
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										16
									
								
								vendor/golang.org/x/net/internal/socket/sys_bsd.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								vendor/golang.org/x/net/internal/socket/sys_bsd.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,16 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:build aix || darwin || dragonfly || freebsd || openbsd
 | 
					 | 
				
			||||||
// +build aix darwin dragonfly freebsd openbsd
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
 | 
					 | 
				
			||||||
	return 0, errNotImplemented
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
 | 
					 | 
				
			||||||
	return 0, errNotImplemented
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user