Commit c3e9485d authored by k8s-merge-robot's avatar k8s-merge-robot Committed by GitHub

Merge pull request #28247 from girishkalele/skydns_godep_up

Automatic merge from submit-queue Bump skydns godeps to latest Update Godeps for github.com/skynetservices/skydns and miekg/dns. Bump kubedns version to 1.6 with latest skynetservices/skydns code Built kube-dns for all architectures and pushed containers to gcr.io.
parents 61a9358d 8614be3c
...@@ -1319,7 +1319,7 @@ ...@@ -1319,7 +1319,7 @@
}, },
{ {
"ImportPath": "github.com/miekg/dns", "ImportPath": "github.com/miekg/dns",
"Rev": "c2b278e70f35902fd68b54b69238cd10bb1b7451" "Rev": "5d001d020961ae1c184f9f8152fdc73810481677"
}, },
{ {
"ImportPath": "github.com/mistifyio/go-zfs", "ImportPath": "github.com/mistifyio/go-zfs",
...@@ -1802,28 +1802,28 @@ ...@@ -1802,28 +1802,28 @@
}, },
{ {
"ImportPath": "github.com/skynetservices/skydns/cache", "ImportPath": "github.com/skynetservices/skydns/cache",
"Comment": "2.5.3a-32-gf7b6fb7", "Comment": "2.5.3a-41-g00ade30",
"Rev": "f7b6fb74bcfab300b4e7e0e27b1fe6c0ed555f78" "Rev": "00ade3024f047d26130abf161900e0adb72a06f1"
}, },
{ {
"ImportPath": "github.com/skynetservices/skydns/metrics", "ImportPath": "github.com/skynetservices/skydns/metrics",
"Comment": "2.5.3a-32-gf7b6fb7", "Comment": "2.5.3a-41-g00ade30",
"Rev": "f7b6fb74bcfab300b4e7e0e27b1fe6c0ed555f78" "Rev": "00ade3024f047d26130abf161900e0adb72a06f1"
}, },
{ {
"ImportPath": "github.com/skynetservices/skydns/msg", "ImportPath": "github.com/skynetservices/skydns/msg",
"Comment": "2.5.3a-32-gf7b6fb7", "Comment": "2.5.3a-41-g00ade30",
"Rev": "f7b6fb74bcfab300b4e7e0e27b1fe6c0ed555f78" "Rev": "00ade3024f047d26130abf161900e0adb72a06f1"
}, },
{ {
"ImportPath": "github.com/skynetservices/skydns/server", "ImportPath": "github.com/skynetservices/skydns/server",
"Comment": "2.5.3a-32-gf7b6fb7", "Comment": "2.5.3a-41-g00ade30",
"Rev": "f7b6fb74bcfab300b4e7e0e27b1fe6c0ed555f78" "Rev": "00ade3024f047d26130abf161900e0adb72a06f1"
}, },
{ {
"ImportPath": "github.com/skynetservices/skydns/singleflight", "ImportPath": "github.com/skynetservices/skydns/singleflight",
"Comment": "2.5.3a-32-gf7b6fb7", "Comment": "2.5.3a-41-g00ade30",
"Rev": "f7b6fb74bcfab300b4e7e0e27b1fe6c0ed555f78" "Rev": "00ade3024f047d26130abf161900e0adb72a06f1"
}, },
{ {
"ImportPath": "github.com/spf13/cobra", "ImportPath": "github.com/spf13/cobra",
......
...@@ -17,12 +17,12 @@ ...@@ -17,12 +17,12 @@
# If you update this image please bump the tag value before pushing. # If you update this image please bump the tag value before pushing.
# #
# Usage: # Usage:
# [ARCH=amd64] [TAG=1.5] [REGISTRY=gcr.io/google_containers] [BASEIMAGE=busybox] make (container|push) # [ARCH=amd64] [TAG=1.6] [REGISTRY=gcr.io/google_containers] [BASEIMAGE=busybox] make (container|push)
# Default registry, arch and tag. This can be overwritten by arguments to make # Default registry, arch and tag. This can be overwritten by arguments to make
PLATFORM?=linux PLATFORM?=linux
ARCH?=amd64 ARCH?=amd64
TAG?=1.5 TAG?=1.6
REGISTRY?=gcr.io/google_containers REGISTRY?=gcr.io/google_containers
GOLANG_VERSION=1.6 GOLANG_VERSION=1.6
......
...@@ -21,27 +21,27 @@ ...@@ -21,27 +21,27 @@
apiVersion: v1 apiVersion: v1
kind: ReplicationController kind: ReplicationController
metadata: metadata:
name: kube-dns-v17 name: kube-dns-v18
namespace: kube-system namespace: kube-system
labels: labels:
k8s-app: kube-dns k8s-app: kube-dns
version: v17 version: v18
kubernetes.io/cluster-service: "true" kubernetes.io/cluster-service: "true"
spec: spec:
replicas: __PILLAR__DNS__REPLICAS__ replicas: __PILLAR__DNS__REPLICAS__
selector: selector:
k8s-app: kube-dns k8s-app: kube-dns
version: v17 version: v18
template: template:
metadata: metadata:
labels: labels:
k8s-app: kube-dns k8s-app: kube-dns
version: v17 version: v18
kubernetes.io/cluster-service: "true" kubernetes.io/cluster-service: "true"
spec: spec:
containers: containers:
- name: kubedns - name: kubedns
image: gcr.io/google_containers/kubedns-amd64:1.5 image: gcr.io/google_containers/kubedns-amd64:1.6
resources: resources:
# TODO: Set memory limits when we've profiled the container for large # TODO: Set memory limits when we've profiled the container for large
# clusters, then set request = limit to keep this container in # clusters, then set request = limit to keep this container in
......
...@@ -21,27 +21,27 @@ ...@@ -21,27 +21,27 @@
apiVersion: v1 apiVersion: v1
kind: ReplicationController kind: ReplicationController
metadata: metadata:
name: kube-dns-v17 name: kube-dns-v18
namespace: kube-system namespace: kube-system
labels: labels:
k8s-app: kube-dns k8s-app: kube-dns
version: v17 version: v18
kubernetes.io/cluster-service: "true" kubernetes.io/cluster-service: "true"
spec: spec:
replicas: {{ pillar['dns_replicas'] }} replicas: {{ pillar['dns_replicas'] }}
selector: selector:
k8s-app: kube-dns k8s-app: kube-dns
version: v17 version: v18
template: template:
metadata: metadata:
labels: labels:
k8s-app: kube-dns k8s-app: kube-dns
version: v17 version: v18
kubernetes.io/cluster-service: "true" kubernetes.io/cluster-service: "true"
spec: spec:
containers: containers:
- name: kubedns - name: kubedns
image: gcr.io/google_containers/kubedns-amd64:1.5 image: gcr.io/google_containers/kubedns-amd64:1.6
resources: resources:
# TODO: Set memory limits when we've profiled the container for large # TODO: Set memory limits when we've profiled the container for large
# clusters, then set request = limit to keep this container in # clusters, then set request = limit to keep this container in
......
...@@ -21,27 +21,27 @@ ...@@ -21,27 +21,27 @@
apiVersion: v1 apiVersion: v1
kind: ReplicationController kind: ReplicationController
metadata: metadata:
name: kube-dns-v17 name: kube-dns-v18
namespace: kube-system namespace: kube-system
labels: labels:
k8s-app: kube-dns k8s-app: kube-dns
version: v17 version: v18
kubernetes.io/cluster-service: "true" kubernetes.io/cluster-service: "true"
spec: spec:
replicas: $DNS_REPLICAS replicas: $DNS_REPLICAS
selector: selector:
k8s-app: kube-dns k8s-app: kube-dns
version: v17 version: v18
template: template:
metadata: metadata:
labels: labels:
k8s-app: kube-dns k8s-app: kube-dns
version: v17 version: v18
kubernetes.io/cluster-service: "true" kubernetes.io/cluster-service: "true"
spec: spec:
containers: containers:
- name: kubedns - name: kubedns
image: gcr.io/google_containers/kubedns-amd64:1.5 image: gcr.io/google_containers/kubedns-amd64:1.6
resources: resources:
# TODO: Set memory limits when we've profiled the container for large # TODO: Set memory limits when we've profiled the container for large
# clusters, then set request = limit to keep this container in # clusters, then set request = limit to keep this container in
......
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
...@@ -12,7 +12,7 @@ can build servers and resolvers with it. ...@@ -12,7 +12,7 @@ can build servers and resolvers with it.
We try to keep the "master" branch as sane as possible and at the bleeding edge 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 of standards, avoiding breaking changes wherever reasonable. We support the last
two versions of Go, currently: 1.4 and 1.5. two versions of Go, currently: 1.5 and 1.6.
# Goals # Goals
...@@ -48,6 +48,8 @@ A not-so-up-to-date-list-that-may-be-actually-current: ...@@ -48,6 +48,8 @@ A not-so-up-to-date-list-that-may-be-actually-current:
* https://github.com/miekg/unbound * https://github.com/miekg/unbound
* https://github.com/miekg/exdns * https://github.com/miekg/exdns
* https://dnslookup.org * https://dnslookup.org
* https://github.com/looterz/grimd
* https://github.com/phamhongviet/serf-dns
Send pull request if you want to be listed here. Send pull request if you want to be listed here.
...@@ -61,7 +63,7 @@ Send pull request if you want to be listed here. ...@@ -61,7 +63,7 @@ Send pull request if you want to be listed here.
* Server side programming (mimicking the net/http package); * Server side programming (mimicking the net/http package);
* Client side programming; * Client side programming;
* DNSSEC: signing, validating and key generation for DSA, RSA and ECDSA; * DNSSEC: signing, validating and key generation for DSA, RSA and ECDSA;
* EDNS0, NSID; * EDNS0, NSID, Cookies;
* AXFR/IXFR; * AXFR/IXFR;
* TSIG, SIG(0); * TSIG, SIG(0);
* DNS over TLS: optional encrypted connection between client and server; * DNS over TLS: optional encrypted connection between client and server;
...@@ -111,7 +113,6 @@ Example programs can be found in the `github.com/miekg/exdns` repository. ...@@ -111,7 +113,6 @@ Example programs can be found in the `github.com/miekg/exdns` repository.
* 340{1,2,3} - NAPTR record * 340{1,2,3} - NAPTR record
* 3445 - Limiting the scope of (DNS)KEY * 3445 - Limiting the scope of (DNS)KEY
* 3597 - Unknown RRs * 3597 - Unknown RRs
* 4025 - IPSECKEY
* 403{3,4,5} - DNSSEC + validation functions * 403{3,4,5} - DNSSEC + validation functions
* 4255 - SSHFP record * 4255 - SSHFP record
* 4343 - Case insensitivity * 4343 - Case insensitivity
...@@ -138,8 +139,9 @@ Example programs can be found in the `github.com/miekg/exdns` repository. ...@@ -138,8 +139,9 @@ Example programs can be found in the `github.com/miekg/exdns` repository.
* 7043 - EUI48/EUI64 records * 7043 - EUI48/EUI64 records
* 7314 - DNS (EDNS) EXPIRE Option * 7314 - DNS (EDNS) EXPIRE Option
* 7553 - URI record * 7553 - URI record
* 7858 - DNS over TLS: Initiation and Performance Considerations (draft)
* 7873 - Domain Name System (DNS) Cookies (draft-ietf-dnsop-cookies)
* xxxx - EDNS0 DNS Update Lease (draft) * xxxx - EDNS0 DNS Update Lease (draft)
* yyyy - DNS over TLS: Initiation and Performance Considerations (draft)
## Loosely based upon ## Loosely based upon
...@@ -147,11 +149,3 @@ Example programs can be found in the `github.com/miekg/exdns` repository. ...@@ -147,11 +149,3 @@ Example programs can be found in the `github.com/miekg/exdns` repository.
* `NSD` * `NSD`
* `Net::DNS` * `Net::DNS`
* `GRONG` * `GRONG`
## TODO
* privatekey.Precompute() when signing?
* Last remaining RRs: APL, ATMA, A6, NSAP and NXT.
* Missing in parsing: ISDN, UNSPEC, NSAP and ATMA.
* NSEC(3) cover/match/closest enclose.
* Replies with TC bit are not parsed to the end.
...@@ -5,6 +5,7 @@ package dns ...@@ -5,6 +5,7 @@ package dns
import ( import (
"bytes" "bytes"
"crypto/tls" "crypto/tls"
"encoding/binary"
"io" "io"
"net" "net"
"time" "time"
...@@ -28,9 +29,10 @@ type Client struct { ...@@ -28,9 +29,10 @@ 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) 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 UDPSize uint16 // minimum receive buffer for UDP messages
TLSConfig *tls.Config // TLS connection configuration TLSConfig *tls.Config // TLS connection configuration
DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds Timeout time.Duration // a cumulative timeout for dial, write and read, defaults to 0 (disabled) - overrides DialTimeout, ReadTimeout and WriteTimeout when non-zero
ReadTimeout time.Duration // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds DialTimeout time.Duration // net.DialTimeout, 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 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 fully qualified TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be fully qualified
SingleInflight bool // if true suppress multiple outstanding queries for the same Qname, Qtype and Qclass SingleInflight bool // if true suppress multiple outstanding queries for the same Qname, Qtype and Qclass
group singleflight group singleflight
...@@ -129,6 +131,9 @@ func (c *Client) Exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err erro ...@@ -129,6 +131,9 @@ func (c *Client) Exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err erro
} }
func (c *Client) dialTimeout() time.Duration { func (c *Client) dialTimeout() time.Duration {
if c.Timeout != 0 {
return c.Timeout
}
if c.DialTimeout != 0 { if c.DialTimeout != 0 {
return c.DialTimeout return c.DialTimeout
} }
...@@ -170,6 +175,11 @@ func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err erro ...@@ -170,6 +175,11 @@ func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err erro
} }
} }
var deadline time.Time
if c.Timeout != 0 {
deadline = time.Now().Add(c.Timeout)
}
if tls { if tls {
co, err = DialTimeoutWithTLS(network, a, c.TLSConfig, c.dialTimeout()) co, err = DialTimeoutWithTLS(network, a, c.TLSConfig, c.dialTimeout())
} else { } else {
...@@ -192,12 +202,12 @@ func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err erro ...@@ -192,12 +202,12 @@ func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err erro
} }
co.TsigSecret = c.TsigSecret co.TsigSecret = c.TsigSecret
co.SetWriteDeadline(time.Now().Add(c.writeTimeout())) co.SetWriteDeadline(deadlineOrTimeout(deadline, c.writeTimeout()))
if err = co.WriteMsg(m); err != nil { if err = co.WriteMsg(m); err != nil {
return nil, 0, err return nil, 0, err
} }
co.SetReadDeadline(time.Now().Add(c.readTimeout())) co.SetReadDeadline(deadlineOrTimeout(deadline, c.readTimeout()))
r, err = co.ReadMsg() r, err = co.ReadMsg()
if err == nil && r.Id != m.Id { if err == nil && r.Id != m.Id {
err = ErrId err = ErrId
...@@ -274,9 +284,11 @@ func (co *Conn) ReadMsgHeader(hdr *Header) ([]byte, error) { ...@@ -274,9 +284,11 @@ func (co *Conn) ReadMsgHeader(hdr *Header) ([]byte, error) {
p = p[:n] p = p[:n]
if hdr != nil { if hdr != nil {
if _, err = UnpackStruct(hdr, p, 0); err != nil { dh, _, err := unpackMsgHdr(p, 0)
if err != nil {
return nil, err return nil, err
} }
*hdr = dh
} }
return p, err return p, err
} }
...@@ -291,7 +303,7 @@ func tcpMsgLen(t io.Reader) (int, error) { ...@@ -291,7 +303,7 @@ func tcpMsgLen(t io.Reader) (int, error) {
if n != 2 { if n != 2 {
return 0, ErrShortRead return 0, ErrShortRead
} }
l, _ := unpackUint16(p, 0) l := binary.BigEndian.Uint16(p)
if l == 0 { if l == 0 {
return 0, ErrShortRead return 0, ErrShortRead
} }
...@@ -383,7 +395,7 @@ func (co *Conn) Write(p []byte) (n int, err error) { ...@@ -383,7 +395,7 @@ func (co *Conn) Write(p []byte) (n int, err error) {
return 0, &Error{err: "message too large"} return 0, &Error{err: "message too large"}
} }
l := make([]byte, 2, lp+2) l := make([]byte, 2, lp+2)
l[0], l[1] = packUint16(uint16(lp)) binary.BigEndian.PutUint16(l, uint16(lp))
p = append(l, p...) p = append(l, p...)
n, err := io.Copy(w, bytes.NewReader(p)) n, err := io.Copy(w, bytes.NewReader(p))
return int(n), err return int(n), err
...@@ -434,3 +446,10 @@ func DialTimeoutWithTLS(network, address string, tlsConfig *tls.Config, timeout ...@@ -434,3 +446,10 @@ func DialTimeoutWithTLS(network, address string, tlsConfig *tls.Config, timeout
} }
return conn, nil return conn, nil
} }
func deadlineOrTimeout(deadline time.Time, timeout time.Duration) time.Time {
if deadline.IsZero() {
return time.Now().Add(timeout)
}
return deadline
}
...@@ -142,9 +142,13 @@ func (dns *Msg) IsTsig() *TSIG { ...@@ -142,9 +142,13 @@ func (dns *Msg) IsTsig() *TSIG {
// record in the additional section will do. It returns the OPT record // record in the additional section will do. It returns the OPT record
// found or nil. // found or nil.
func (dns *Msg) IsEdns0() *OPT { func (dns *Msg) IsEdns0() *OPT {
for _, r := range dns.Extra { // EDNS0 is at the end of the additional section, start there.
if r.Header().Rrtype == TypeOPT { // We might want to change this to *only* look at the last two
return r.(*OPT) // records. So we see TSIG and/or OPT - this a slightly bigger
// change though.
for i := len(dns.Extra) - 1; i >= 0; i-- {
if dns.Extra[i].Header().Rrtype == TypeOPT {
return dns.Extra[i].(*OPT)
} }
} }
return nil return nil
...@@ -163,8 +167,8 @@ func IsDomainName(s string) (labels int, ok bool) { ...@@ -163,8 +167,8 @@ func IsDomainName(s string) (labels int, ok bool) {
return labels, err == nil return labels, err == nil
} }
// IsSubDomain checks if child is indeed a child of the parent. Both child and // IsSubDomain checks if child is indeed a child of the parent. If child and parent
// parent are *not* downcased before doing the comparison. // are the same domain true is returned as well.
func IsSubDomain(parent, child string) bool { func IsSubDomain(parent, child string) bool {
// Entire child is contained in parent // Entire child is contained in parent
return CompareDomainName(parent, child) == CountLabel(parent) return CompareDomainName(parent, child) == CountLabel(parent)
......
...@@ -3,17 +3,15 @@ package dns ...@@ -3,17 +3,15 @@ package dns
import "strconv" import "strconv"
const ( const (
year68 = 1 << 31 // For RFC1982 (Serial Arithmetic) calculations in 32 bits. year68 = 1 << 31 // For RFC1982 (Serial Arithmetic) calculations in 32 bits.
// DefaultMsgSize is the standard default for messages larger than 512 bytes. defaultTtl = 3600 // Default internal TTL.
DefaultMsgSize = 4096
// MinMsgSize is the minimal size of a DNS packet. DefaultMsgSize = 4096 // DefaultMsgSize is the standard default for messages larger than 512 bytes.
MinMsgSize = 512 MinMsgSize = 512 // MinMsgSize is the minimal size of a DNS packet.
// MaxMsgSize is the largest possible DNS packet. MaxMsgSize = 65535 // MaxMsgSize is the largest possible DNS packet.
MaxMsgSize = 65535
defaultTtl = 3600 // Default internal TTL.
) )
// Error represents a DNS error // Error represents a DNS error.
type Error struct{ err string } type Error struct{ err string }
func (e *Error) Error() string { func (e *Error) Error() string {
...@@ -30,10 +28,13 @@ type RR interface { ...@@ -30,10 +28,13 @@ type RR interface {
Header() *RR_Header Header() *RR_Header
// String returns the text representation of the resource record. // String returns the text representation of the resource record.
String() string String() string
// copy returns a copy of the RR // copy returns a copy of the RR
copy() RR copy() RR
// len returns the length (in octets) of the uncompressed RR in wire format. // len returns the length (in octets) of the uncompressed RR in wire format.
len() int len() int
// pack packs an RR into wire format.
pack([]byte, int, map[string]int, bool) (int, error)
} }
// RR_Header is the header all DNS resource records share. // RR_Header is the header all DNS resource records share.
...@@ -42,13 +43,13 @@ type RR_Header struct { ...@@ -42,13 +43,13 @@ type RR_Header struct {
Rrtype uint16 Rrtype uint16
Class uint16 Class uint16
Ttl uint32 Ttl uint32
Rdlength uint16 // length of data after header Rdlength uint16 // Length of data after header.
} }
// Header returns itself. This is here to make RR_Header implement the RR interface. // Header returns itself. This is here to make RR_Header implements the RR interface.
func (h *RR_Header) Header() *RR_Header { return h } func (h *RR_Header) Header() *RR_Header { return h }
// Just to imlement the RR interface. // Just to implement the RR interface.
func (h *RR_Header) copy() RR { return nil } func (h *RR_Header) copy() RR { return nil }
func (h *RR_Header) copyHeader() *RR_Header { func (h *RR_Header) copyHeader() *RR_Header {
...@@ -82,19 +83,22 @@ func (h *RR_Header) len() int { ...@@ -82,19 +83,22 @@ func (h *RR_Header) len() int {
return l return l
} }
// ToRFC3597 converts a known RR to the unknown RR representation // ToRFC3597 converts a known RR to the unknown RR representation from RFC 3597.
// from RFC 3597.
func (rr *RFC3597) ToRFC3597(r RR) error { func (rr *RFC3597) ToRFC3597(r RR) error {
buf := make([]byte, r.len()*2) buf := make([]byte, r.len()*2)
off, err := PackStruct(r, buf, 0) off, err := PackRR(r, buf, 0, nil, false)
if err != nil { if err != nil {
return err return err
} }
buf = buf[:off] buf = buf[:off]
rawSetRdlength(buf, 0, off) if int(r.Header().Rdlength) > off {
_, err = UnpackStruct(rr, buf, 0) return ErrBuf
}
rfc3597, _, err := unpackRFC3597(*r.Header(), buf, off-int(r.Header().Rdlength))
if err != nil { if err != nil {
return err return err
} }
*rr = *rfc3597.(*RFC3597)
return nil return nil
} }
...@@ -13,6 +13,7 @@ import ( ...@@ -13,6 +13,7 @@ import (
_ "crypto/sha256" _ "crypto/sha256"
_ "crypto/sha512" _ "crypto/sha512"
"encoding/asn1" "encoding/asn1"
"encoding/binary"
"encoding/hex" "encoding/hex"
"math/big" "math/big"
"sort" "sort"
...@@ -103,9 +104,7 @@ const ( ...@@ -103,9 +104,7 @@ const (
ZONE = 1 << 8 ZONE = 1 << 8
) )
// The RRSIG needs to be converted to wireformat with some of // The RRSIG needs to be converted to wireformat with some of the rdata (the signature) missing.
// the rdata (the signature) missing. Use this struct to ease
// the conversion (and re-use the pack/unpack functions).
type rrsigWireFmt struct { type rrsigWireFmt struct {
TypeCovered uint16 TypeCovered uint16
Algorithm uint8 Algorithm uint8
...@@ -144,7 +143,7 @@ func (k *DNSKEY) KeyTag() uint16 { ...@@ -144,7 +143,7 @@ func (k *DNSKEY) KeyTag() uint16 {
// at the base64 values. But I'm lazy. // at the base64 values. But I'm lazy.
modulus, _ := fromBase64([]byte(k.PublicKey)) modulus, _ := fromBase64([]byte(k.PublicKey))
if len(modulus) > 1 { if len(modulus) > 1 {
x, _ := unpackUint16(modulus, len(modulus)-2) x := binary.BigEndian.Uint16(modulus[len(modulus)-2:])
keytag = int(x) keytag = int(x)
} }
default: default:
...@@ -154,7 +153,7 @@ func (k *DNSKEY) KeyTag() uint16 { ...@@ -154,7 +153,7 @@ func (k *DNSKEY) KeyTag() uint16 {
keywire.Algorithm = k.Algorithm keywire.Algorithm = k.Algorithm
keywire.PublicKey = k.PublicKey keywire.PublicKey = k.PublicKey
wire := make([]byte, DefaultMsgSize) wire := make([]byte, DefaultMsgSize)
n, err := PackStruct(keywire, wire, 0) n, err := packKeyWire(keywire, wire)
if err != nil { if err != nil {
return 0 return 0
} }
...@@ -192,7 +191,7 @@ func (k *DNSKEY) ToDS(h uint8) *DS { ...@@ -192,7 +191,7 @@ func (k *DNSKEY) ToDS(h uint8) *DS {
keywire.Algorithm = k.Algorithm keywire.Algorithm = k.Algorithm
keywire.PublicKey = k.PublicKey keywire.PublicKey = k.PublicKey
wire := make([]byte, DefaultMsgSize) wire := make([]byte, DefaultMsgSize)
n, err := PackStruct(keywire, wire, 0) n, err := packKeyWire(keywire, wire)
if err != nil { if err != nil {
return nil return nil
} }
...@@ -289,7 +288,7 @@ func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error { ...@@ -289,7 +288,7 @@ func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error {
// Create the desired binary blob // Create the desired binary blob
signdata := make([]byte, DefaultMsgSize) signdata := make([]byte, DefaultMsgSize)
n, err := PackStruct(sigwire, signdata, 0) n, err := packSigWire(sigwire, signdata)
if err != nil { if err != nil {
return err return err
} }
...@@ -407,7 +406,7 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error { ...@@ -407,7 +406,7 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
sigwire.SignerName = strings.ToLower(rr.SignerName) sigwire.SignerName = strings.ToLower(rr.SignerName)
// Create the desired binary blob // Create the desired binary blob
signeddata := make([]byte, DefaultMsgSize) signeddata := make([]byte, DefaultMsgSize)
n, err := PackStruct(sigwire, signeddata, 0) n, err := packSigWire(sigwire, signeddata)
if err != nil { if err != nil {
return err return err
} }
...@@ -662,3 +661,61 @@ func rawSignatureData(rrset []RR, s *RRSIG) (buf []byte, err error) { ...@@ -662,3 +661,61 @@ func rawSignatureData(rrset []RR, s *RRSIG) (buf []byte, err error) {
} }
return buf, nil 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
}
...@@ -25,9 +25,9 @@ func (k *DNSKEY) NewPrivateKey(s string) (crypto.PrivateKey, error) { ...@@ -25,9 +25,9 @@ func (k *DNSKEY) NewPrivateKey(s string) (crypto.PrivateKey, error) {
// The public key must be known, because some cryptographic algorithms embed // The public key must be known, because some cryptographic algorithms embed
// the public inside the privatekey. // the public inside the privatekey.
func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, error) { func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, error) {
m, e := parseKey(q, file) m, err := parseKey(q, file)
if m == nil { if m == nil {
return nil, e return nil, err
} }
if _, ok := m["private-key-format"]; !ok { if _, ok := m["private-key-format"]; !ok {
return nil, ErrPrivKey return nil, ErrPrivKey
...@@ -42,16 +42,16 @@ func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, er ...@@ -42,16 +42,16 @@ func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, er
} }
switch uint8(algo) { switch uint8(algo) {
case DSA: case DSA:
priv, e := readPrivateKeyDSA(m) priv, err := readPrivateKeyDSA(m)
if e != nil { if err != nil {
return nil, e return nil, err
} }
pub := k.publicKeyDSA() pub := k.publicKeyDSA()
if pub == nil { if pub == nil {
return nil, ErrKey return nil, ErrKey
} }
priv.PublicKey = *pub priv.PublicKey = *pub
return priv, e return priv, nil
case RSAMD5: case RSAMD5:
fallthrough fallthrough
case RSASHA1: case RSASHA1:
...@@ -61,31 +61,31 @@ func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, er ...@@ -61,31 +61,31 @@ func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, er
case RSASHA256: case RSASHA256:
fallthrough fallthrough
case RSASHA512: case RSASHA512:
priv, e := readPrivateKeyRSA(m) priv, err := readPrivateKeyRSA(m)
if e != nil { if err != nil {
return nil, e return nil, err
} }
pub := k.publicKeyRSA() pub := k.publicKeyRSA()
if pub == nil { if pub == nil {
return nil, ErrKey return nil, ErrKey
} }
priv.PublicKey = *pub priv.PublicKey = *pub
return priv, e return priv, nil
case ECCGOST: case ECCGOST:
return nil, ErrPrivKey return nil, ErrPrivKey
case ECDSAP256SHA256: case ECDSAP256SHA256:
fallthrough fallthrough
case ECDSAP384SHA384: case ECDSAP384SHA384:
priv, e := readPrivateKeyECDSA(m) priv, err := readPrivateKeyECDSA(m)
if e != nil { if err != nil {
return nil, e return nil, err
} }
pub := k.publicKeyECDSA() pub := k.publicKeyECDSA()
if pub == nil { if pub == nil {
return nil, ErrKey return nil, ErrKey
} }
priv.PublicKey = *pub priv.PublicKey = *pub
return priv, e return priv, nil
default: default:
return nil, ErrPrivKey return nil, ErrPrivKey
} }
......
package dns package dns
import ( import (
"encoding/binary"
"encoding/hex" "encoding/hex"
"errors" "errors"
"net" "net"
...@@ -17,6 +18,7 @@ const ( ...@@ -17,6 +18,7 @@ const (
EDNS0N3U = 0x7 // NSEC3 Hash Understood EDNS0N3U = 0x7 // NSEC3 Hash Understood
EDNS0SUBNET = 0x8 // client-subnet (RFC6891) EDNS0SUBNET = 0x8 // client-subnet (RFC6891)
EDNS0EXPIRE = 0x9 // EDNS0 expire EDNS0EXPIRE = 0x9 // EDNS0 expire
EDNS0COOKIE = 0xa // EDNS0 Cookie
EDNS0SUBNETDRAFT = 0x50fa // Don't use! Use EDNS0SUBNET EDNS0SUBNETDRAFT = 0x50fa // Don't use! Use EDNS0SUBNET
EDNS0LOCALSTART = 0xFDE9 // Beginning of range reserved for local/experimental use (RFC6891) EDNS0LOCALSTART = 0xFDE9 // Beginning of range reserved for local/experimental use (RFC6891)
EDNS0LOCALEND = 0xFFFE // End of range reserved for local/experimental use (RFC6891) EDNS0LOCALEND = 0xFFFE // End of range reserved for local/experimental use (RFC6891)
...@@ -56,6 +58,8 @@ func (rr *OPT) String() string { ...@@ -56,6 +58,8 @@ func (rr *OPT) String() string {
if o.(*EDNS0_SUBNET).DraftOption { if o.(*EDNS0_SUBNET).DraftOption {
s += " (draft)" s += " (draft)"
} }
case *EDNS0_COOKIE:
s += "\n; COOKIE: " + o.String()
case *EDNS0_UL: case *EDNS0_UL:
s += "\n; UPDATE LEASE: " + o.String() s += "\n; UPDATE LEASE: " + o.String()
case *EDNS0_LLQ: case *EDNS0_LLQ:
...@@ -96,13 +100,16 @@ func (rr *OPT) SetVersion(v uint8) { ...@@ -96,13 +100,16 @@ func (rr *OPT) SetVersion(v uint8) {
} }
// ExtendedRcode returns the EDNS extended RCODE field (the upper 8 bits of the TTL). // ExtendedRcode returns the EDNS extended RCODE field (the upper 8 bits of the TTL).
func (rr *OPT) ExtendedRcode() uint8 { func (rr *OPT) ExtendedRcode() int {
return uint8((rr.Hdr.Ttl & 0xFF000000) >> 24) return int((rr.Hdr.Ttl&0xFF000000)>>24) + 15
} }
// SetExtendedRcode sets the EDNS extended RCODE field. // SetExtendedRcode sets the EDNS extended RCODE field.
func (rr *OPT) SetExtendedRcode(v uint8) { func (rr *OPT) SetExtendedRcode(v uint8) {
rr.Hdr.Ttl = rr.Hdr.Ttl&0x00FFFFFF | (uint32(v) << 24) if v < RcodeBadVers { // Smaller than 16.. Use the 4 bits you have!
return
}
rr.Hdr.Ttl = rr.Hdr.Ttl&0x00FFFFFF | (uint32(v-15) << 24)
} }
// UDPSize returns the UDP buffer size. // UDPSize returns the UDP buffer size.
...@@ -125,8 +132,7 @@ func (rr *OPT) SetDo() { ...@@ -125,8 +132,7 @@ func (rr *OPT) SetDo() {
rr.Hdr.Ttl |= _DO rr.Hdr.Ttl |= _DO
} }
// EDNS0 defines an EDNS0 Option. An OPT RR can have multiple options appended to // EDNS0 defines an EDNS0 Option. An OPT RR can have multiple options appended to it.
// it.
type EDNS0 interface { type EDNS0 interface {
// Option returns the option code for the option. // Option returns the option code for the option.
Option() uint16 Option() uint16
...@@ -207,7 +213,7 @@ func (e *EDNS0_SUBNET) Option() uint16 { ...@@ -207,7 +213,7 @@ func (e *EDNS0_SUBNET) Option() uint16 {
func (e *EDNS0_SUBNET) pack() ([]byte, error) { func (e *EDNS0_SUBNET) pack() ([]byte, error) {
b := make([]byte, 4) b := make([]byte, 4)
b[0], b[1] = packUint16(e.Family) binary.BigEndian.PutUint16(b[0:], e.Family)
b[2] = e.SourceNetmask b[2] = e.SourceNetmask
b[3] = e.SourceScope b[3] = e.SourceScope
switch e.Family { switch e.Family {
...@@ -241,7 +247,7 @@ func (e *EDNS0_SUBNET) unpack(b []byte) error { ...@@ -241,7 +247,7 @@ func (e *EDNS0_SUBNET) unpack(b []byte) error {
if len(b) < 4 { if len(b) < 4 {
return ErrBuf return ErrBuf
} }
e.Family, _ = unpackUint16(b, 0) e.Family = binary.BigEndian.Uint16(b)
e.SourceNetmask = b[2] e.SourceNetmask = b[2]
e.SourceScope = b[3] e.SourceScope = b[3]
switch e.Family { switch e.Family {
...@@ -283,6 +289,41 @@ func (e *EDNS0_SUBNET) String() (s string) { ...@@ -283,6 +289,41 @@ func (e *EDNS0_SUBNET) String() (s string) {
return return
} }
// The Cookie EDNS0 option
//
// 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
}
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 }
// The EDNS0_UL (Update Lease) (draft RFC) option is used to tell the server to set // 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 // 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 // up after themselves. This is a draft RFC and more information can be found at
...@@ -306,10 +347,7 @@ func (e *EDNS0_UL) String() string { return strconv.FormatUint(uint64(e.Lease), ...@@ -306,10 +347,7 @@ func (e *EDNS0_UL) String() string { return strconv.FormatUint(uint64(e.Lease),
// Copied: http://golang.org/src/pkg/net/dnsmsg.go // Copied: http://golang.org/src/pkg/net/dnsmsg.go
func (e *EDNS0_UL) pack() ([]byte, error) { func (e *EDNS0_UL) pack() ([]byte, error) {
b := make([]byte, 4) b := make([]byte, 4)
b[0] = byte(e.Lease >> 24) binary.BigEndian.PutUint32(b, e.Lease)
b[1] = byte(e.Lease >> 16)
b[2] = byte(e.Lease >> 8)
b[3] = byte(e.Lease)
return b, nil return b, nil
} }
...@@ -317,7 +355,7 @@ func (e *EDNS0_UL) unpack(b []byte) error { ...@@ -317,7 +355,7 @@ func (e *EDNS0_UL) unpack(b []byte) error {
if len(b) < 4 { if len(b) < 4 {
return ErrBuf return ErrBuf
} }
e.Lease = uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3]) e.Lease = binary.BigEndian.Uint32(b)
return nil return nil
} }
...@@ -336,21 +374,11 @@ func (e *EDNS0_LLQ) Option() uint16 { return EDNS0LLQ } ...@@ -336,21 +374,11 @@ func (e *EDNS0_LLQ) Option() uint16 { return EDNS0LLQ }
func (e *EDNS0_LLQ) pack() ([]byte, error) { func (e *EDNS0_LLQ) pack() ([]byte, error) {
b := make([]byte, 18) b := make([]byte, 18)
b[0], b[1] = packUint16(e.Version) binary.BigEndian.PutUint16(b[0:], e.Version)
b[2], b[3] = packUint16(e.Opcode) binary.BigEndian.PutUint16(b[2:], e.Opcode)
b[4], b[5] = packUint16(e.Error) binary.BigEndian.PutUint16(b[4:], e.Error)
b[6] = byte(e.Id >> 56) binary.BigEndian.PutUint64(b[6:], e.Id)
b[7] = byte(e.Id >> 48) binary.BigEndian.PutUint32(b[14:], e.LeaseLife)
b[8] = byte(e.Id >> 40)
b[9] = byte(e.Id >> 32)
b[10] = byte(e.Id >> 24)
b[11] = byte(e.Id >> 16)
b[12] = byte(e.Id >> 8)
b[13] = byte(e.Id)
b[14] = byte(e.LeaseLife >> 24)
b[15] = byte(e.LeaseLife >> 16)
b[16] = byte(e.LeaseLife >> 8)
b[17] = byte(e.LeaseLife)
return b, nil return b, nil
} }
...@@ -358,12 +386,11 @@ func (e *EDNS0_LLQ) unpack(b []byte) error { ...@@ -358,12 +386,11 @@ func (e *EDNS0_LLQ) unpack(b []byte) error {
if len(b) < 18 { if len(b) < 18 {
return ErrBuf return ErrBuf
} }
e.Version, _ = unpackUint16(b, 0) e.Version = binary.BigEndian.Uint16(b[0:])
e.Opcode, _ = unpackUint16(b, 2) e.Opcode = binary.BigEndian.Uint16(b[2:])
e.Error, _ = unpackUint16(b, 4) e.Error = binary.BigEndian.Uint16(b[4:])
e.Id = uint64(b[6])<<56 | uint64(b[6+1])<<48 | uint64(b[6+2])<<40 | e.Id = binary.BigEndian.Uint64(b[6:])
uint64(b[6+3])<<32 | uint64(b[6+4])<<24 | uint64(b[6+5])<<16 | uint64(b[6+6])<<8 | uint64(b[6+7]) e.LeaseLife = binary.BigEndian.Uint32(b[14:])
e.LeaseLife = uint32(b[14])<<24 | uint32(b[14+1])<<16 | uint32(b[14+2])<<8 | uint32(b[14+3])
return nil return nil
} }
...@@ -459,7 +486,7 @@ func (e *EDNS0_EXPIRE) unpack(b []byte) error { ...@@ -459,7 +486,7 @@ func (e *EDNS0_EXPIRE) unpack(b []byte) error {
if len(b) < 4 { if len(b) < 4 {
return ErrBuf return ErrBuf
} }
e.Expire = uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3]) e.Expire = binary.BigEndian.Uint32(b)
return nil return nil
} }
......
...@@ -69,15 +69,6 @@ func Field(r RR, i int) string { ...@@ -69,15 +69,6 @@ func Field(r RR, i int) string {
s += " " + Type(d.Index(i).Uint()).String() s += " " + Type(d.Index(i).Uint()).String()
} }
return s return s
case `dns:"wks"`:
if d.Len() == 0 {
return ""
}
s := strconv.Itoa(int(d.Index(0).Uint()))
for i := 0; i < d.Len(); i++ {
s += " " + strconv.Itoa(int(d.Index(i).Uint()))
}
return s
default: default:
// if it does not have a tag its a string slice // if it does not have a tag its a string slice
fallthrough fallthrough
......
...@@ -2,6 +2,7 @@ package dns ...@@ -2,6 +2,7 @@ package dns
import ( import (
"bytes" "bytes"
"errors"
"fmt" "fmt"
"strconv" "strconv"
"strings" "strings"
...@@ -25,7 +26,7 @@ func generate(l lex, c chan lex, t chan *Token, o string) string { ...@@ -25,7 +26,7 @@ func generate(l lex, c chan lex, t chan *Token, o string) string {
if i+1 == len(l.token) { if i+1 == len(l.token) {
return "bad step in $GENERATE range" return "bad step in $GENERATE range"
} }
if s, e := strconv.Atoi(l.token[i+1:]); e == nil { if s, err := strconv.Atoi(l.token[i+1:]); err == nil {
if s < 0 { if s < 0 {
return "bad step in $GENERATE range" return "bad step in $GENERATE range"
} }
...@@ -65,7 +66,7 @@ BuildRR: ...@@ -65,7 +66,7 @@ BuildRR:
escape bool escape bool
dom bytes.Buffer dom bytes.Buffer
mod string mod string
err string err error
offset int offset int
) )
...@@ -104,8 +105,8 @@ BuildRR: ...@@ -104,8 +105,8 @@ BuildRR:
return "bad modifier in $GENERATE" return "bad modifier in $GENERATE"
} }
mod, offset, err = modToPrintf(s[j+2 : j+2+sep]) mod, offset, err = modToPrintf(s[j+2 : j+2+sep])
if err != "" { if err != nil {
return err return err.Error()
} }
j += 2 + sep // Jump to it j += 2 + sep // Jump to it
} }
...@@ -119,9 +120,9 @@ BuildRR: ...@@ -119,9 +120,9 @@ BuildRR:
} }
} }
// Re-parse the RR and send it on the current channel t // Re-parse the RR and send it on the current channel t
rx, e := NewRR("$ORIGIN " + o + "\n" + dom.String()) rx, err := NewRR("$ORIGIN " + o + "\n" + dom.String())
if e != nil { if err != nil {
return e.(*ParseError).err return err.Error()
} }
t <- &Token{RR: rx} t <- &Token{RR: rx}
// Its more efficient to first built the rrlist and then parse it in // Its more efficient to first built the rrlist and then parse it in
...@@ -131,28 +132,28 @@ BuildRR: ...@@ -131,28 +132,28 @@ BuildRR:
} }
// Convert a $GENERATE modifier 0,0,d to something Printf can deal with. // Convert a $GENERATE modifier 0,0,d to something Printf can deal with.
func modToPrintf(s string) (string, int, string) { func modToPrintf(s string) (string, int, error) {
xs := strings.SplitN(s, ",", 3) xs := strings.SplitN(s, ",", 3)
if len(xs) != 3 { if len(xs) != 3 {
return "", 0, "bad modifier in $GENERATE" return "", 0, errors.New("bad modifier in $GENERATE")
} }
// xs[0] is offset, xs[1] is width, xs[2] is base // xs[0] is offset, xs[1] is width, xs[2] is base
if xs[2] != "o" && xs[2] != "d" && xs[2] != "x" && xs[2] != "X" { if xs[2] != "o" && xs[2] != "d" && xs[2] != "x" && xs[2] != "X" {
return "", 0, "bad base in $GENERATE" return "", 0, errors.New("bad base in $GENERATE")
} }
offset, err := strconv.Atoi(xs[0]) offset, err := strconv.Atoi(xs[0])
if err != nil || offset > 255 { if err != nil || offset > 255 {
return "", 0, "bad offset in $GENERATE" return "", 0, errors.New("bad offset in $GENERATE")
} }
width, err := strconv.Atoi(xs[1]) width, err := strconv.Atoi(xs[1])
if err != nil || width > 255 { if err != nil || width > 255 {
return "", offset, "bad width in $GENERATE" return "", offset, errors.New("bad width in $GENERATE")
} }
switch { switch {
case width < 0: case width < 0:
return "", offset, "bad width in $GENERATE" return "", offset, errors.New("bad width in $GENERATE")
case width == 0: case width == 0:
return "%" + xs[1] + xs[2], offset, "" return "%" + xs[1] + xs[2], offset, nil
} }
return "%0" + xs[1] + xs[2], offset, "" return "%0" + xs[1] + xs[2], offset, nil
} }
...@@ -107,7 +107,7 @@ func CountLabel(s string) (labels int) { ...@@ -107,7 +107,7 @@ func CountLabel(s string) (labels int) {
// Split splits a name s into its label indexes. // 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}. // 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. // The root name (.) returns nil. Also see SplitDomainName.
// s must be a syntactically valid domain name. // s must be a syntactically valid domain name.
func Split(s string) []int { func Split(s string) []int {
if s == "." { if s == "." {
......
...@@ -11,13 +11,12 @@ type saltWireFmt struct { ...@@ -11,13 +11,12 @@ type saltWireFmt struct {
Salt string `dns:"size-hex"` Salt string `dns:"size-hex"`
} }
// HashName hashes a string (label) according to RFC 5155. It returns the hashed string in // HashName hashes a string (label) according to RFC 5155. It returns the hashed string in uppercase.
// uppercase.
func HashName(label string, ha uint8, iter uint16, salt string) string { func HashName(label string, ha uint8, iter uint16, salt string) string {
saltwire := new(saltWireFmt) saltwire := new(saltWireFmt)
saltwire.Salt = salt saltwire.Salt = salt
wire := make([]byte, DefaultMsgSize) wire := make([]byte, DefaultMsgSize)
n, err := PackStruct(saltwire, wire, 0) n, err := packSaltWire(saltwire, wire)
if err != nil { if err != nil {
return "" return ""
} }
...@@ -110,3 +109,11 @@ func (rr *NSEC3) Match(name string) bool { ...@@ -110,3 +109,11 @@ func (rr *NSEC3) Match(name string) bool {
} }
return false return false
} }
func packSaltWire(sw *saltWireFmt, msg []byte) (int, error) {
off, err := packStringHex(sw.Salt, msg, 0)
if err != nil {
return off, err
}
return off, nil
}
...@@ -65,6 +65,20 @@ func (r *PrivateRR) copy() RR { ...@@ -65,6 +65,20 @@ func (r *PrivateRR) copy() RR {
} }
return rr return rr
} }
func (r *PrivateRR) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := r.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
n, err := r.Data.Pack(msg[off:])
if err != nil {
return len(msg), err
}
off += n
r.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
// PrivateHandle registers a private resource record type. It requires // PrivateHandle registers a private resource record type. It requires
// string and numeric representation of private RR type and generator function as argument. // string and numeric representation of private RR type and generator function as argument.
...@@ -75,19 +89,36 @@ func PrivateHandle(rtypestr string, rtype uint16, generator func() PrivateRdata) ...@@ -75,19 +89,36 @@ func PrivateHandle(rtypestr string, rtype uint16, generator func() PrivateRdata)
TypeToString[rtype] = rtypestr TypeToString[rtype] = rtypestr
StringToType[rtypestr] = rtype StringToType[rtypestr] = rtype
typeToUnpack[rtype] = func(h RR_Header, msg []byte, off int) (RR, int, error) {
if noRdata(h) {
return &h, off, nil
}
var err error
rr := mkPrivateRR(h.Rrtype)
rr.Hdr = h
off1, err := rr.Data.Unpack(msg[off:])
off += off1
if err != nil {
return rr, off, err
}
return rr, off, err
}
setPrivateRR := func(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { setPrivateRR := func(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
rr := mkPrivateRR(h.Rrtype) rr := mkPrivateRR(h.Rrtype)
rr.Hdr = h rr.Hdr = h
var l lex var l lex
text := make([]string, 0, 2) // could be 0..N elements, median is probably 1 text := make([]string, 0, 2) // could be 0..N elements, median is probably 1
FETCH: Fetch:
for { for {
// TODO(miek): we could also be returning _QUOTE, this might or might not // TODO(miek): we could also be returning _QUOTE, this might or might not
// be an issue (basically parsing TXT becomes hard) // be an issue (basically parsing TXT becomes hard)
switch l = <-c; l.value { switch l = <-c; l.value {
case zNewline, zEOF: case zNewline, zEOF:
break FETCH break Fetch
case zString: case zString:
text = append(text, l.token) text = append(text, l.token)
} }
...@@ -112,6 +143,7 @@ func PrivateHandleRemove(rtype uint16) { ...@@ -112,6 +143,7 @@ func PrivateHandleRemove(rtype uint16) {
delete(TypeToString, rtype) delete(TypeToString, rtype)
delete(typeToparserFunc, rtype) delete(typeToparserFunc, rtype)
delete(StringToType, rtypestr) delete(StringToType, rtypestr)
delete(typeToUnpack, rtype)
} }
return return
} }
package dns package dns
// These raw* functions do not use reflection, they directly set the values import "encoding/binary"
// in the buffer. There are faster than their reflection counterparts.
// RawSetId sets the message id in buf.
func rawSetId(msg []byte, i uint16) bool {
if len(msg) < 2 {
return false
}
msg[0], msg[1] = packUint16(i)
return true
}
// rawSetQuestionLen sets the length of the question section.
func rawSetQuestionLen(msg []byte, i uint16) bool {
if len(msg) < 6 {
return false
}
msg[4], msg[5] = packUint16(i)
return true
}
// rawSetAnswerLen sets the length of the answer section.
func rawSetAnswerLen(msg []byte, i uint16) bool {
if len(msg) < 8 {
return false
}
msg[6], msg[7] = packUint16(i)
return true
}
// rawSetsNsLen sets the length of the authority section.
func rawSetNsLen(msg []byte, i uint16) bool {
if len(msg) < 10 {
return false
}
msg[8], msg[9] = packUint16(i)
return true
}
// rawSetExtraLen sets the length of the additional section.
func rawSetExtraLen(msg []byte, i uint16) bool {
if len(msg) < 12 {
return false
}
msg[10], msg[11] = packUint16(i)
return true
}
// rawSetRdlength sets the rdlength in the header of // rawSetRdlength sets the rdlength in the header of
// the RR. The offset 'off' must be positioned at the // the RR. The offset 'off' must be positioned at the
...@@ -90,6 +44,6 @@ Loop: ...@@ -90,6 +44,6 @@ Loop:
if rdatalen > 0xFFFF { if rdatalen > 0xFFFF {
return false return false
} }
msg[off], msg[off+1] = packUint16(uint16(rdatalen)) binary.BigEndian.PutUint16(msg[off:], uint16(rdatalen))
return true return true
} }
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)
// Map of opcodes strings.
var StringToOpcode = reverseInt(OpcodeToString)
// Map of rcodes strings.
var StringToRcode = reverseInt(RcodeToString)
// 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
}
...@@ -377,8 +377,8 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) { ...@@ -377,8 +377,8 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
t <- &Token{Error: &ParseError{f, "expecting $GENERATE value, not this...", l}} t <- &Token{Error: &ParseError{f, "expecting $GENERATE value, not this...", l}}
return return
} }
if e := generate(l, c, t, origin); e != "" { if errMsg := generate(l, c, t, origin); errMsg != "" {
t <- &Token{Error: &ParseError{f, e, l}} t <- &Token{Error: &ParseError{f, errMsg, l}}
return return
} }
st = zExpectOwnerDir st = zExpectOwnerDir
...@@ -966,8 +966,8 @@ func stringToNodeID(l lex) (uint64, *ParseError) { ...@@ -966,8 +966,8 @@ func stringToNodeID(l lex) (uint64, *ParseError) {
return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l} return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l}
} }
s := l.token[0:4] + l.token[5:9] + l.token[10:14] + l.token[15:19] s := l.token[0:4] + l.token[5:9] + l.token[10:14] + l.token[15:19]
u, e := strconv.ParseUint(s, 16, 64) u, err := strconv.ParseUint(s, 16, 64)
if e != nil { if err != nil {
return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l} return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l}
} }
return u, nil return u, nil
......
...@@ -1443,64 +1443,6 @@ func setEUI64(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { ...@@ -1443,64 +1443,6 @@ func setEUI64(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, "" return rr, nil, ""
} }
func setWKS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
rr := new(WKS)
rr.Hdr = h
l := <-c
if l.length == 0 {
return rr, nil, l.comment
}
rr.Address = net.ParseIP(l.token)
if rr.Address == nil || l.err {
return nil, &ParseError{f, "bad WKS Address", l}, ""
}
<-c // zBlank
l = <-c
proto := "tcp"
i, e := strconv.Atoi(l.token)
if e != nil || l.err {
return nil, &ParseError{f, "bad WKS Protocol", l}, ""
}
rr.Protocol = uint8(i)
switch rr.Protocol {
case 17:
proto = "udp"
case 6:
proto = "tcp"
default:
return nil, &ParseError{f, "bad WKS Protocol", l}, ""
}
<-c
l = <-c
rr.BitMap = make([]uint16, 0)
var (
k int
err error
)
for l.value != zNewline && l.value != zEOF {
switch l.value {
case zBlank:
// Ok
case zString:
if k, err = net.LookupPort(proto, l.token); err != nil {
i, e := strconv.Atoi(l.token) // If a number use that
if e != nil {
return nil, &ParseError{f, "bad WKS BitMap", l}, ""
}
rr.BitMap = append(rr.BitMap, uint16(i))
}
rr.BitMap = append(rr.BitMap, uint16(k))
default:
return nil, &ParseError{f, "bad WKS BitMap", l}, ""
}
l = <-c
}
return rr, nil, l.comment
}
func setSSHFP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { func setSSHFP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
rr := new(SSHFP) rr := new(SSHFP)
rr.Hdr = h rr.Hdr = h
...@@ -2103,73 +2045,6 @@ func setPX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { ...@@ -2103,73 +2045,6 @@ func setPX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, "" return rr, nil, ""
} }
func setIPSECKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
rr := new(IPSECKEY)
rr.Hdr = h
l := <-c
if l.length == 0 {
return rr, nil, l.comment
}
i, err := strconv.Atoi(l.token)
if err != nil || l.err {
return nil, &ParseError{f, "bad IPSECKEY Precedence", l}, ""
}
rr.Precedence = uint8(i)
<-c // zBlank
l = <-c
i, err = strconv.Atoi(l.token)
if err != nil || l.err {
return nil, &ParseError{f, "bad IPSECKEY GatewayType", l}, ""
}
rr.GatewayType = uint8(i)
<-c // zBlank
l = <-c
i, err = strconv.Atoi(l.token)
if err != nil || l.err {
return nil, &ParseError{f, "bad IPSECKEY Algorithm", l}, ""
}
rr.Algorithm = uint8(i)
// Now according to GatewayType we can have different elements here
<-c // zBlank
l = <-c
switch rr.GatewayType {
case 0:
fallthrough
case 3:
rr.GatewayName = l.token
if l.token == "@" {
rr.GatewayName = o
}
_, ok := IsDomainName(l.token)
if !ok || l.length == 0 || l.err {
return nil, &ParseError{f, "bad IPSECKEY GatewayName", l}, ""
}
if rr.GatewayName[l.length-1] != '.' {
rr.GatewayName = appendOrigin(rr.GatewayName, o)
}
case 1:
rr.GatewayA = net.ParseIP(l.token)
if rr.GatewayA == nil {
return nil, &ParseError{f, "bad IPSECKEY GatewayA", l}, ""
}
case 2:
rr.GatewayAAAA = net.ParseIP(l.token)
if rr.GatewayAAAA == nil {
return nil, &ParseError{f, "bad IPSECKEY GatewayAAAA", l}, ""
}
default:
return nil, &ParseError{f, "bad IPSECKEY GatewayType", l}, ""
}
s, e, c1 := endingToString(c, "bad IPSECKEY PublicKey", f)
if e != nil {
return nil, e, c1
}
rr.PublicKey = s
return rr, nil, c1
}
func setCAA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { func setCAA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
rr := new(CAA) rr := new(CAA)
rr.Hdr = h rr.Hdr = h
...@@ -2224,7 +2099,6 @@ var typeToparserFunc = map[uint16]parserFunc{ ...@@ -2224,7 +2099,6 @@ var typeToparserFunc = map[uint16]parserFunc{
TypeGPOS: {setGPOS, false}, TypeGPOS: {setGPOS, false},
TypeHINFO: {setHINFO, true}, TypeHINFO: {setHINFO, true},
TypeHIP: {setHIP, true}, TypeHIP: {setHIP, true},
TypeIPSECKEY: {setIPSECKEY, true},
TypeKX: {setKX, false}, TypeKX: {setKX, false},
TypeL32: {setL32, false}, TypeL32: {setL32, false},
TypeL64: {setL64, false}, TypeL64: {setL64, false},
...@@ -2265,6 +2139,5 @@ var typeToparserFunc = map[uint16]parserFunc{ ...@@ -2265,6 +2139,5 @@ var typeToparserFunc = map[uint16]parserFunc{
TypeUID: {setUID, false}, TypeUID: {setUID, false},
TypeUINFO: {setUINFO, true}, TypeUINFO: {setUINFO, true},
TypeURI: {setURI, true}, TypeURI: {setURI, true},
TypeWKS: {setWKS, true},
TypeX25: {setX25, false}, TypeX25: {setX25, false},
} }
...@@ -5,6 +5,7 @@ package dns ...@@ -5,6 +5,7 @@ package dns
import ( import (
"bytes" "bytes"
"crypto/tls" "crypto/tls"
"encoding/binary"
"io" "io"
"net" "net"
"sync" "sync"
...@@ -320,20 +321,20 @@ func (srv *Server) ListenAndServe() error { ...@@ -320,20 +321,20 @@ func (srv *Server) ListenAndServe() error {
} }
switch srv.Net { switch srv.Net {
case "tcp", "tcp4", "tcp6": case "tcp", "tcp4", "tcp6":
a, e := net.ResolveTCPAddr(srv.Net, addr) a, err := net.ResolveTCPAddr(srv.Net, addr)
if e != nil { if err != nil {
return e return err
} }
l, e := net.ListenTCP(srv.Net, a) l, err := net.ListenTCP(srv.Net, a)
if e != nil { if err != nil {
return e return err
} }
srv.Listener = l srv.Listener = l
srv.started = true srv.started = true
srv.lock.Unlock() srv.lock.Unlock()
e = srv.serveTCP(l) err = srv.serveTCP(l)
srv.lock.Lock() // to satisfy the defer at the top srv.lock.Lock() // to satisfy the defer at the top
return e return err
case "tcp-tls", "tcp4-tls", "tcp6-tls": case "tcp-tls", "tcp4-tls", "tcp6-tls":
network := "tcp" network := "tcp"
if srv.Net == "tcp4-tls" { if srv.Net == "tcp4-tls" {
...@@ -342,24 +343,24 @@ func (srv *Server) ListenAndServe() error { ...@@ -342,24 +343,24 @@ func (srv *Server) ListenAndServe() error {
network = "tcp6" network = "tcp6"
} }
l, e := tls.Listen(network, addr, srv.TLSConfig) l, err := tls.Listen(network, addr, srv.TLSConfig)
if e != nil { if err != nil {
return e return err
} }
srv.Listener = l srv.Listener = l
srv.started = true srv.started = true
srv.lock.Unlock() srv.lock.Unlock()
e = srv.serveTCP(l) err = srv.serveTCP(l)
srv.lock.Lock() // to satisfy the defer at the top srv.lock.Lock() // to satisfy the defer at the top
return e return err
case "udp", "udp4", "udp6": case "udp", "udp4", "udp6":
a, e := net.ResolveUDPAddr(srv.Net, addr) a, err := net.ResolveUDPAddr(srv.Net, addr)
if e != nil { if err != nil {
return e return err
} }
l, e := net.ListenUDP(srv.Net, a) l, err := net.ListenUDP(srv.Net, a)
if e != nil { if err != nil {
return e return err
} }
if e := setUDPSocketOptions(l); e != nil { if e := setUDPSocketOptions(l); e != nil {
return e return e
...@@ -367,9 +368,9 @@ func (srv *Server) ListenAndServe() error { ...@@ -367,9 +368,9 @@ func (srv *Server) ListenAndServe() error {
srv.PacketConn = l srv.PacketConn = l
srv.started = true srv.started = true
srv.lock.Unlock() srv.lock.Unlock()
e = srv.serveUDP(l) err = srv.serveUDP(l)
srv.lock.Lock() // to satisfy the defer at the top srv.lock.Lock() // to satisfy the defer at the top
return e return err
} }
return &Error{err: "bad network"} return &Error{err: "bad network"}
} }
...@@ -473,21 +474,21 @@ func (srv *Server) serveTCP(l net.Listener) error { ...@@ -473,21 +474,21 @@ func (srv *Server) serveTCP(l net.Listener) error {
rtimeout := srv.getReadTimeout() rtimeout := srv.getReadTimeout()
// deadline is not used here // deadline is not used here
for { for {
rw, e := l.Accept() rw, err := l.Accept()
if e != nil { if err != nil {
if neterr, ok := e.(net.Error); ok && neterr.Temporary() { if neterr, ok := err.(net.Error); ok && neterr.Temporary() {
continue continue
} }
return e return err
} }
m, e := reader.ReadTCP(rw, rtimeout) m, err := reader.ReadTCP(rw, rtimeout)
srv.lock.RLock() srv.lock.RLock()
if !srv.started { if !srv.started {
srv.lock.RUnlock() srv.lock.RUnlock()
return nil return nil
} }
srv.lock.RUnlock() srv.lock.RUnlock()
if e != nil { if err != nil {
continue continue
} }
srv.inFlight.Add(1) srv.inFlight.Add(1)
...@@ -516,14 +517,14 @@ func (srv *Server) serveUDP(l *net.UDPConn) error { ...@@ -516,14 +517,14 @@ func (srv *Server) serveUDP(l *net.UDPConn) error {
rtimeout := srv.getReadTimeout() rtimeout := srv.getReadTimeout()
// deadline is not used here // deadline is not used here
for { for {
m, s, e := reader.ReadUDP(l, rtimeout) m, s, err := reader.ReadUDP(l, rtimeout)
srv.lock.RLock() srv.lock.RLock()
if !srv.started { if !srv.started {
srv.lock.RUnlock() srv.lock.RUnlock()
return nil return nil
} }
srv.lock.RUnlock() srv.lock.RUnlock()
if e != nil { if err != nil {
continue continue
} }
srv.inFlight.Add(1) srv.inFlight.Add(1)
...@@ -596,8 +597,8 @@ Exit: ...@@ -596,8 +597,8 @@ Exit:
if srv.IdleTimeout != nil { if srv.IdleTimeout != nil {
idleTimeout = srv.IdleTimeout() idleTimeout = srv.IdleTimeout()
} }
m, e := reader.ReadTCP(w.tcp, idleTimeout) m, err = reader.ReadTCP(w.tcp, idleTimeout)
if e == nil { if err == nil {
q++ q++
goto Redo goto Redo
} }
...@@ -615,7 +616,7 @@ func (srv *Server) readTCP(conn net.Conn, timeout time.Duration) ([]byte, error) ...@@ -615,7 +616,7 @@ func (srv *Server) readTCP(conn net.Conn, timeout time.Duration) ([]byte, error)
} }
return nil, ErrShortRead return nil, ErrShortRead
} }
length, _ := unpackUint16(l, 0) length := binary.BigEndian.Uint16(l)
if length == 0 { if length == 0 {
return nil, ErrShortRead return nil, ErrShortRead
} }
...@@ -643,10 +644,10 @@ func (srv *Server) readTCP(conn net.Conn, timeout time.Duration) ([]byte, error) ...@@ -643,10 +644,10 @@ func (srv *Server) readTCP(conn net.Conn, timeout time.Duration) ([]byte, error)
func (srv *Server) readUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error) { func (srv *Server) readUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error) {
conn.SetReadDeadline(time.Now().Add(timeout)) conn.SetReadDeadline(time.Now().Add(timeout))
m := make([]byte, srv.UDPSize) m := make([]byte, srv.UDPSize)
n, s, e := ReadFromSessionUDP(conn, m) n, s, err := ReadFromSessionUDP(conn, m)
if e != nil || n == 0 { if err != nil || n == 0 {
if e != nil { if err != nil {
return nil, nil, e return nil, nil, err
} }
return nil, nil, ErrShortRead return nil, nil, ErrShortRead
} }
...@@ -690,7 +691,7 @@ func (w *response) Write(m []byte) (int, error) { ...@@ -690,7 +691,7 @@ func (w *response) Write(m []byte) (int, error) {
return 0, &Error{err: "message too large"} return 0, &Error{err: "message too large"}
} }
l := make([]byte, 2, 2+lm) l := make([]byte, 2, 2+lm)
l[0], l[1] = packUint16(uint16(lm)) binary.BigEndian.PutUint16(l, uint16(lm))
m = append(l, m...) m = append(l, m...)
n, err := io.Copy(w.tcp, bytes.NewReader(m)) n, err := io.Copy(w.tcp, bytes.NewReader(m))
......
...@@ -5,6 +5,7 @@ import ( ...@@ -5,6 +5,7 @@ import (
"crypto/dsa" "crypto/dsa"
"crypto/ecdsa" "crypto/ecdsa"
"crypto/rsa" "crypto/rsa"
"encoding/binary"
"math/big" "math/big"
"strings" "strings"
"time" "time"
...@@ -67,13 +68,13 @@ func (rr *SIG) Sign(k crypto.Signer, m *Msg) ([]byte, error) { ...@@ -67,13 +68,13 @@ func (rr *SIG) Sign(k crypto.Signer, m *Msg) ([]byte, error) {
} }
// Adjust sig data length // Adjust sig data length
rdoff := len(mbuf) + 1 + 2 + 2 + 4 rdoff := len(mbuf) + 1 + 2 + 2 + 4
rdlen, _ := unpackUint16(buf, rdoff) rdlen := binary.BigEndian.Uint16(buf[rdoff:])
rdlen += uint16(len(sig)) rdlen += uint16(len(sig))
buf[rdoff], buf[rdoff+1] = packUint16(rdlen) binary.BigEndian.PutUint16(buf[rdoff:], rdlen)
// Adjust additional count // Adjust additional count
adc, _ := unpackUint16(buf, 10) adc := binary.BigEndian.Uint16(buf[10:])
adc++ adc++
buf[10], buf[11] = packUint16(adc) binary.BigEndian.PutUint16(buf[10:], adc)
return buf, nil return buf, nil
} }
...@@ -103,10 +104,11 @@ func (rr *SIG) Verify(k *KEY, buf []byte) error { ...@@ -103,10 +104,11 @@ func (rr *SIG) Verify(k *KEY, buf []byte) error {
hasher := hash.New() hasher := hash.New()
buflen := len(buf) buflen := len(buf)
qdc, _ := unpackUint16(buf, 4) qdc := binary.BigEndian.Uint16(buf[4:])
anc, _ := unpackUint16(buf, 6) anc := binary.BigEndian.Uint16(buf[6:])
auc, _ := unpackUint16(buf, 8) auc := binary.BigEndian.Uint16(buf[8:])
adc, offset := unpackUint16(buf, 10) adc := binary.BigEndian.Uint16(buf[10:])
offset := 12
var err error var err error
for i := uint16(0); i < qdc && offset < buflen; i++ { for i := uint16(0); i < qdc && offset < buflen; i++ {
_, offset, err = UnpackDomainName(buf, offset) _, offset, err = UnpackDomainName(buf, offset)
...@@ -127,7 +129,8 @@ func (rr *SIG) Verify(k *KEY, buf []byte) error { ...@@ -127,7 +129,8 @@ func (rr *SIG) Verify(k *KEY, buf []byte) error {
continue continue
} }
var rdlen uint16 var rdlen uint16
rdlen, offset = unpackUint16(buf, offset) rdlen = binary.BigEndian.Uint16(buf[offset:])
offset += 2
offset += int(rdlen) offset += int(rdlen)
} }
if offset >= buflen { if offset >= buflen {
...@@ -149,9 +152,9 @@ func (rr *SIG) Verify(k *KEY, buf []byte) error { ...@@ -149,9 +152,9 @@ func (rr *SIG) Verify(k *KEY, buf []byte) error {
if offset+4+4 >= buflen { if offset+4+4 >= buflen {
return &Error{err: "overflow unpacking signed message"} return &Error{err: "overflow unpacking signed message"}
} }
expire := uint32(buf[offset])<<24 | uint32(buf[offset+1])<<16 | uint32(buf[offset+2])<<8 | uint32(buf[offset+3]) expire := binary.BigEndian.Uint32(buf[offset:])
offset += 4 offset += 4
incept := uint32(buf[offset])<<24 | uint32(buf[offset+1])<<16 | uint32(buf[offset+2])<<8 | uint32(buf[offset+3]) incept := binary.BigEndian.Uint32(buf[offset:])
offset += 4 offset += 4
now := uint32(time.Now().Unix()) now := uint32(time.Now().Unix())
if now < incept || now > expire { if now < incept || now > expire {
......
...@@ -78,9 +78,9 @@ func TLSAName(name, service, network string) (string, error) { ...@@ -78,9 +78,9 @@ func TLSAName(name, service, network string) (string, error) {
if !IsFqdn(name) { if !IsFqdn(name) {
return "", ErrFqdn return "", ErrFqdn
} }
p, e := net.LookupPort(network, service) p, err := net.LookupPort(network, service)
if e != nil { if err != nil {
return "", e return "", err
} }
return "_" + strconv.Itoa(p) + "._" + network + "." + name, nil return "_" + strconv.Itoa(p) + "._" + network + "." + name, nil
} }
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
"crypto/sha1" "crypto/sha1"
"crypto/sha256" "crypto/sha256"
"crypto/sha512" "crypto/sha512"
"encoding/binary"
"encoding/hex" "encoding/hex"
"hash" "hash"
"io" "io"
...@@ -30,11 +31,11 @@ type TSIG struct { ...@@ -30,11 +31,11 @@ type TSIG struct {
TimeSigned uint64 `dns:"uint48"` TimeSigned uint64 `dns:"uint48"`
Fudge uint16 Fudge uint16
MACSize uint16 MACSize uint16
MAC string `dns:"size-hex"` MAC string `dns:"size-hex:MACSize"`
OrigId uint16 OrigId uint16
Error uint16 Error uint16
OtherLen uint16 OtherLen uint16
OtherData string `dns:"size-hex"` OtherData string `dns:"size-hex:OtherLen"`
} }
// TSIG has no official presentation format, but this will suffice. // TSIG has no official presentation format, but this will suffice.
...@@ -68,14 +69,13 @@ type tsigWireFmt struct { ...@@ -68,14 +69,13 @@ type tsigWireFmt struct {
// MACSize, MAC and OrigId excluded // MACSize, MAC and OrigId excluded
Error uint16 Error uint16
OtherLen uint16 OtherLen uint16
OtherData string `dns:"size-hex"` OtherData string `dns:"size-hex:OtherLen"`
} }
// If we have the MAC use this type to convert it to wiredata. // If we have the MAC use this type to convert it to wiredata. Section 3.4.3. Request MAC
// Section 3.4.3. Request MAC
type macWireFmt struct { type macWireFmt struct {
MACSize uint16 MACSize uint16
MAC string `dns:"size-hex"` MAC string `dns:"size-hex:MACSize"`
} }
// 3.3. Time values used in TSIG calculations // 3.3. Time values used in TSIG calculations
...@@ -141,7 +141,9 @@ func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, s ...@@ -141,7 +141,9 @@ func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, s
return nil, "", err return nil, "", err
} }
mbuf = append(mbuf, tbuf...) mbuf = append(mbuf, tbuf...)
rawSetExtraLen(mbuf, uint16(len(m.Extra)+1)) // Update the ArCount directly in the buffer.
binary.BigEndian.PutUint16(mbuf[10:], uint16(len(m.Extra)+1))
return mbuf, t.MAC, nil return mbuf, t.MAC, nil
} }
...@@ -212,7 +214,7 @@ func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []b ...@@ -212,7 +214,7 @@ func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []b
m.MACSize = uint16(len(requestMAC) / 2) m.MACSize = uint16(len(requestMAC) / 2)
m.MAC = requestMAC m.MAC = requestMAC
buf = make([]byte, len(requestMAC)) // long enough buf = make([]byte, len(requestMAC)) // long enough
n, _ := PackStruct(m, buf, 0) n, _ := packMacWire(m, buf)
buf = buf[:n] buf = buf[:n]
} }
...@@ -221,7 +223,7 @@ func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []b ...@@ -221,7 +223,7 @@ func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []b
tsig := new(timerWireFmt) tsig := new(timerWireFmt)
tsig.TimeSigned = rr.TimeSigned tsig.TimeSigned = rr.TimeSigned
tsig.Fudge = rr.Fudge tsig.Fudge = rr.Fudge
n, _ := PackStruct(tsig, tsigvar, 0) n, _ := packTimerWire(tsig, tsigvar)
tsigvar = tsigvar[:n] tsigvar = tsigvar[:n]
} else { } else {
tsig := new(tsigWireFmt) tsig := new(tsigWireFmt)
...@@ -234,7 +236,7 @@ func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []b ...@@ -234,7 +236,7 @@ func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []b
tsig.Error = rr.Error tsig.Error = rr.Error
tsig.OtherLen = rr.OtherLen tsig.OtherLen = rr.OtherLen
tsig.OtherData = rr.OtherData tsig.OtherData = rr.OtherData
n, _ := PackStruct(tsig, tsigvar, 0) n, _ := packTsigWire(tsig, tsigvar)
tsigvar = tsigvar[:n] tsigvar = tsigvar[:n]
} }
...@@ -249,60 +251,54 @@ func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []b ...@@ -249,60 +251,54 @@ func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []b
// Strip the TSIG from the raw message. // Strip the TSIG from the raw message.
func stripTsig(msg []byte) ([]byte, *TSIG, error) { func stripTsig(msg []byte) ([]byte, *TSIG, error) {
// Copied from msg.go's Unpack() // Copied from msg.go's Unpack() Header, but modified.
// Header. var (
var dh Header dh Header
var err error err error
dns := new(Msg) )
rr := new(TSIG) off, tsigoff := 0, 0
off := 0
tsigoff := 0 if dh, off, err = unpackMsgHdr(msg, off); err != nil {
if off, err = UnpackStruct(&dh, msg, off); err != nil {
return nil, nil, err return nil, nil, err
} }
if dh.Arcount == 0 { if dh.Arcount == 0 {
return nil, nil, ErrNoSig return nil, nil, ErrNoSig
} }
// Rcode, see msg.go Unpack() // Rcode, see msg.go Unpack()
if int(dh.Bits&0xF) == RcodeNotAuth { if int(dh.Bits&0xF) == RcodeNotAuth {
return nil, nil, ErrAuth return nil, nil, ErrAuth
} }
// Arrays. for i := 0; i < int(dh.Qdcount); i++ {
dns.Question = make([]Question, dh.Qdcount) _, off, err = unpackQuestion(msg, off)
dns.Answer = make([]RR, dh.Ancount)
dns.Ns = make([]RR, dh.Nscount)
dns.Extra = make([]RR, dh.Arcount)
for i := 0; i < len(dns.Question); i++ {
off, err = UnpackStruct(&dns.Question[i], msg, off)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
} }
for i := 0; i < len(dns.Answer); i++ {
dns.Answer[i], off, err = UnpackRR(msg, off) _, off, err = unpackRRslice(int(dh.Ancount), msg, off)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
}
} }
for i := 0; i < len(dns.Ns); i++ { _, off, err = unpackRRslice(int(dh.Nscount), msg, off)
dns.Ns[i], off, err = UnpackRR(msg, off) if err != nil {
if err != nil { return nil, nil, err
return nil, nil, err
}
} }
for i := 0; i < len(dns.Extra); i++ {
rr := new(TSIG)
var extra RR
for i := 0; i < int(dh.Arcount); i++ {
tsigoff = off tsigoff = off
dns.Extra[i], off, err = UnpackRR(msg, off) extra, off, err = UnpackRR(msg, off)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
if dns.Extra[i].Header().Rrtype == TypeTSIG { if extra.Header().Rrtype == TypeTSIG {
rr = dns.Extra[i].(*TSIG) rr = extra.(*TSIG)
// Adjust Arcount. // Adjust Arcount.
arcount, _ := unpackUint16(msg, 10) arcount := binary.BigEndian.Uint16(msg[10:])
msg[10], msg[11] = packUint16(arcount - 1) binary.BigEndian.PutUint16(msg[10:], arcount-1)
break break
} }
} }
...@@ -318,3 +314,71 @@ func tsigTimeToString(t uint64) string { ...@@ -318,3 +314,71 @@ func tsigTimeToString(t uint64) string {
ti := time.Unix(int64(t), 0).UTC() ti := time.Unix(int64(t), 0).UTC()
return ti.Format("20060102150405") 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
}
package dns package dns
import ( import (
"encoding/base64"
"fmt" "fmt"
"net" "net"
"strconv" "strconv"
...@@ -35,7 +34,6 @@ const ( ...@@ -35,7 +34,6 @@ const (
TypeMG uint16 = 8 TypeMG uint16 = 8
TypeMR uint16 = 9 TypeMR uint16 = 9
TypeNULL uint16 = 10 TypeNULL uint16 = 10
TypeWKS uint16 = 11
TypePTR uint16 = 12 TypePTR uint16 = 12
TypeHINFO uint16 = 13 TypeHINFO uint16 = 13
TypeMINFO uint16 = 14 TypeMINFO uint16 = 14
...@@ -65,7 +63,6 @@ const ( ...@@ -65,7 +63,6 @@ const (
TypeOPT uint16 = 41 // EDNS TypeOPT uint16 = 41 // EDNS
TypeDS uint16 = 43 TypeDS uint16 = 43
TypeSSHFP uint16 = 44 TypeSSHFP uint16 = 44
TypeIPSECKEY uint16 = 45
TypeRRSIG uint16 = 46 TypeRRSIG uint16 = 46
TypeNSEC uint16 = 47 TypeNSEC uint16 = 47
TypeDNSKEY uint16 = 48 TypeDNSKEY uint16 = 48
...@@ -136,6 +133,7 @@ const ( ...@@ -136,6 +133,7 @@ const (
RcodeBadName = 20 RcodeBadName = 20
RcodeBadAlg = 21 RcodeBadAlg = 21
RcodeBadTrunc = 22 // TSIG RcodeBadTrunc = 22 // TSIG
RcodeBadCookie = 23 // DNS Cookies
// Message Opcodes. There is no 3. // Message Opcodes. There is no 3.
OpcodeQuery = 0 OpcodeQuery = 0
...@@ -871,57 +869,6 @@ func (rr *SSHFP) String() string { ...@@ -871,57 +869,6 @@ func (rr *SSHFP) String() string {
" " + strings.ToUpper(rr.FingerPrint) " " + strings.ToUpper(rr.FingerPrint)
} }
type IPSECKEY struct {
Hdr RR_Header
Precedence uint8
// GatewayType: 1: A record, 2: AAAA record, 3: domainname.
// 0 is use for no type and GatewayName should be "." then.
GatewayType uint8
Algorithm uint8
// Gateway can be an A record, AAAA record or a domain name.
GatewayA net.IP `dns:"a"`
GatewayAAAA net.IP `dns:"aaaa"`
GatewayName string `dns:"domain-name"`
PublicKey string `dns:"base64"`
}
func (rr *IPSECKEY) String() string {
s := rr.Hdr.String() + strconv.Itoa(int(rr.Precedence)) +
" " + strconv.Itoa(int(rr.GatewayType)) +
" " + strconv.Itoa(int(rr.Algorithm))
switch rr.GatewayType {
case 0:
fallthrough
case 3:
s += " " + rr.GatewayName
case 1:
s += " " + rr.GatewayA.String()
case 2:
s += " " + rr.GatewayAAAA.String()
default:
s += " ."
}
s += " " + rr.PublicKey
return s
}
func (rr *IPSECKEY) len() int {
l := rr.Hdr.len() + 3 + 1
switch rr.GatewayType {
default:
fallthrough
case 0:
fallthrough
case 3:
l += len(rr.GatewayName)
case 1:
l += 4
case 2:
l += 16
}
return l + base64.StdEncoding.DecodedLen(len(rr.PublicKey))
}
type KEY struct { type KEY struct {
DNSKEY DNSKEY
} }
...@@ -973,9 +920,9 @@ type NSEC3 struct { ...@@ -973,9 +920,9 @@ type NSEC3 struct {
Flags uint8 Flags uint8
Iterations uint16 Iterations uint16
SaltLength uint8 SaltLength uint8
Salt string `dns:"size-hex"` Salt string `dns:"size-hex:SaltLength"`
HashLength uint8 HashLength uint8
NextDomain string `dns:"size-base32"` NextDomain string `dns:"size-base32:HashLength"`
TypeBitMap []uint16 `dns:"nsec"` TypeBitMap []uint16 `dns:"nsec"`
} }
...@@ -1105,8 +1052,8 @@ type HIP struct { ...@@ -1105,8 +1052,8 @@ type HIP struct {
HitLength uint8 HitLength uint8
PublicKeyAlgorithm uint8 PublicKeyAlgorithm uint8
PublicKeyLength uint16 PublicKeyLength uint16
Hit string `dns:"hex"` Hit string `dns:"size-hex:HitLength"`
PublicKey string `dns:"base64"` PublicKey string `dns:"size-base64:PublicKeyLength"`
RendezvousServers []string `dns:"domain-name"` RendezvousServers []string `dns:"domain-name"`
} }
...@@ -1128,31 +1075,6 @@ type NINFO struct { ...@@ -1128,31 +1075,6 @@ type NINFO struct {
func (rr *NINFO) String() string { return rr.Hdr.String() + sprintTxt(rr.ZSData) } func (rr *NINFO) String() string { return rr.Hdr.String() + sprintTxt(rr.ZSData) }
type WKS struct {
Hdr RR_Header
Address net.IP `dns:"a"`
Protocol uint8
BitMap []uint16 `dns:"wks"`
}
func (rr *WKS) len() int {
// TODO: this is missing something...
return rr.Hdr.len() + net.IPv4len + 1
}
func (rr *WKS) String() (s string) {
s = rr.Hdr.String()
if rr.Address != nil {
s += rr.Address.String()
}
// TODO(miek): missing protocol here, see /etc/protocols
for i := 0; i < len(rr.BitMap); i++ {
// should lookup the port
s += " " + strconv.Itoa(int(rr.BitMap[i]))
}
return s
}
type NID struct { type NID struct {
Hdr RR_Header Hdr RR_Header
Preference uint16 Preference uint16
...@@ -1286,9 +1208,9 @@ func TimeToString(t uint32) string { ...@@ -1286,9 +1208,9 @@ func TimeToString(t uint32) string {
// string values like "20110403154150" to an 32 bit integer. // string values like "20110403154150" to an 32 bit integer.
// It takes serial arithmetic (RFC 1982) into account. // It takes serial arithmetic (RFC 1982) into account.
func StringToTime(s string) (uint32, error) { func StringToTime(s string) (uint32, error) {
t, e := time.Parse("20060102150405", s) t, err := time.Parse("20060102150405", s)
if e != nil { if err != nil {
return 0, e return 0, err
} }
mod := (t.Unix() / year68) - 1 mod := (t.Unix() / year68) - 1
if mod < 0 { if mod < 0 {
......
...@@ -20,16 +20,14 @@ import ( ...@@ -20,16 +20,14 @@ import (
) )
var skipLen = map[string]struct{}{ var skipLen = map[string]struct{}{
"NSEC": {}, "NSEC": {},
"NSEC3": {}, "NSEC3": {},
"OPT": {}, "OPT": {},
"WKS": {},
"IPSECKEY": {},
} }
var packageHdr = ` var packageHdr = `
// *** DO NOT MODIFY *** // *** DO NOT MODIFY ***
// AUTOGENERATED BY go generate // AUTOGENERATED BY go generate from type_generate.go
package dns package dns
...@@ -173,26 +171,30 @@ func main() { ...@@ -173,26 +171,30 @@ func main() {
continue continue
} }
switch st.Tag(i) { switch {
case `dns:"-"`: case st.Tag(i) == `dns:"-"`:
// ignored // ignored
case `dns:"cdomain-name"`, `dns:"domain-name"`: case st.Tag(i) == `dns:"cdomain-name"`, st.Tag(i) == `dns:"domain-name"`:
o("l += len(rr.%s) + 1\n") o("l += len(rr.%s) + 1\n")
case `dns:"octet"`: case st.Tag(i) == `dns:"octet"`:
o("l += len(rr.%s)\n") o("l += len(rr.%s)\n")
case `dns:"base64"`: case strings.HasPrefix(st.Tag(i), `dns:"size-base64`):
fallthrough
case st.Tag(i) == `dns:"base64"`:
o("l += base64.StdEncoding.DecodedLen(len(rr.%s))\n") o("l += base64.StdEncoding.DecodedLen(len(rr.%s))\n")
case `dns:"size-hex"`, `dns:"hex"`: case strings.HasPrefix(st.Tag(i), `dns:"size-hex`):
fallthrough
case st.Tag(i) == `dns:"hex"`:
o("l += len(rr.%s)/2 + 1\n") o("l += len(rr.%s)/2 + 1\n")
case `dns:"a"`: case st.Tag(i) == `dns:"a"`:
o("l += net.IPv4len // %s\n") o("l += net.IPv4len // %s\n")
case `dns:"aaaa"`: case st.Tag(i) == `dns:"aaaa"`:
o("l += net.IPv6len // %s\n") o("l += net.IPv6len // %s\n")
case `dns:"txt"`: case st.Tag(i) == `dns:"txt"`:
o("for _, t := range rr.%s { l += len(t) + 1 }\n") o("for _, t := range rr.%s { l += len(t) + 1 }\n")
case `dns:"uint48"`: case st.Tag(i) == `dns:"uint48"`:
o("l += 6 // %s\n") o("l += 6 // %s\n")
case "": case st.Tag(i) == "":
switch st.Field(i).Type().(*types.Basic).Kind() { switch st.Field(i).Type().(*types.Basic).Kind() {
case types.Uint8: case types.Uint8:
o("l += 1 // %s\n") o("l += 1 // %s\n")
...@@ -229,7 +231,10 @@ func main() { ...@@ -229,7 +231,10 @@ func main() {
if sl, ok := st.Field(i).Type().(*types.Slice); ok { if sl, ok := st.Field(i).Type().(*types.Slice); ok {
t := sl.Underlying().String() t := sl.Underlying().String()
t = strings.TrimPrefix(t, "[]") t = strings.TrimPrefix(t, "[]")
t = strings.TrimPrefix(t, "github.com/miekg/dns.") if strings.Contains(t, ".") {
splits := strings.Split(t, ".")
t = splits[len(splits)-1]
}
fmt.Fprintf(b, "%s := make([]%s, len(rr.%s)); copy(%s, rr.%s)\n", fmt.Fprintf(b, "%s := make([]%s, len(rr.%s)); copy(%s, rr.%s)\n",
f, t, f, f, f) f, t, f, f, f)
fields = append(fields, f) fields = append(fields, f)
......
...@@ -162,8 +162,8 @@ func (t *Transfer) inIxfr(id uint16, c chan *Envelope) { ...@@ -162,8 +162,8 @@ func (t *Transfer) inIxfr(id uint16, c chan *Envelope) {
// //
// ch := make(chan *dns.Envelope) // ch := make(chan *dns.Envelope)
// tr := new(dns.Transfer) // tr := new(dns.Transfer)
// tr.Out(w, r, ch) // go tr.Out(w, r, ch)
// c <- &dns.Envelope{RR: []dns.RR{soa, rr1, rr2, rr3, soa}} // ch <- &dns.Envelope{RR: []dns.RR{soa, rr1, rr2, rr3, soa}}
// close(ch) // close(ch)
// w.Hijack() // w.Hijack()
// // w.Close() // Client closes connection // // w.Close() // Client closes connection
......
// *** DO NOT MODIFY *** // *** DO NOT MODIFY ***
// AUTOGENERATED BY go generate // AUTOGENERATED BY go generate from type_generate.go
package dns package dns
...@@ -31,7 +31,6 @@ var TypeToRR = map[uint16]func() RR{ ...@@ -31,7 +31,6 @@ var TypeToRR = map[uint16]func() RR{
TypeGPOS: func() RR { return new(GPOS) }, TypeGPOS: func() RR { return new(GPOS) },
TypeHINFO: func() RR { return new(HINFO) }, TypeHINFO: func() RR { return new(HINFO) },
TypeHIP: func() RR { return new(HIP) }, TypeHIP: func() RR { return new(HIP) },
TypeIPSECKEY: func() RR { return new(IPSECKEY) },
TypeKEY: func() RR { return new(KEY) }, TypeKEY: func() RR { return new(KEY) },
TypeKX: func() RR { return new(KX) }, TypeKX: func() RR { return new(KX) },
TypeL32: func() RR { return new(L32) }, TypeL32: func() RR { return new(L32) },
...@@ -76,7 +75,6 @@ var TypeToRR = map[uint16]func() RR{ ...@@ -76,7 +75,6 @@ var TypeToRR = map[uint16]func() RR{
TypeUID: func() RR { return new(UID) }, TypeUID: func() RR { return new(UID) },
TypeUINFO: func() RR { return new(UINFO) }, TypeUINFO: func() RR { return new(UINFO) },
TypeURI: func() RR { return new(URI) }, TypeURI: func() RR { return new(URI) },
TypeWKS: func() RR { return new(WKS) },
TypeX25: func() RR { return new(X25) }, TypeX25: func() RR { return new(X25) },
} }
...@@ -105,7 +103,6 @@ var TypeToString = map[uint16]string{ ...@@ -105,7 +103,6 @@ var TypeToString = map[uint16]string{
TypeGPOS: "GPOS", TypeGPOS: "GPOS",
TypeHINFO: "HINFO", TypeHINFO: "HINFO",
TypeHIP: "HIP", TypeHIP: "HIP",
TypeIPSECKEY: "IPSECKEY",
TypeISDN: "ISDN", TypeISDN: "ISDN",
TypeIXFR: "IXFR", TypeIXFR: "IXFR",
TypeKEY: "KEY", TypeKEY: "KEY",
...@@ -158,7 +155,6 @@ var TypeToString = map[uint16]string{ ...@@ -158,7 +155,6 @@ var TypeToString = map[uint16]string{
TypeUINFO: "UINFO", TypeUINFO: "UINFO",
TypeUNSPEC: "UNSPEC", TypeUNSPEC: "UNSPEC",
TypeURI: "URI", TypeURI: "URI",
TypeWKS: "WKS",
TypeX25: "X25", TypeX25: "X25",
TypeNSAPPTR: "NSAP-PTR", TypeNSAPPTR: "NSAP-PTR",
} }
...@@ -185,7 +181,6 @@ func (rr *GID) Header() *RR_Header { return &rr.Hdr } ...@@ -185,7 +181,6 @@ func (rr *GID) Header() *RR_Header { return &rr.Hdr }
func (rr *GPOS) 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 *HINFO) Header() *RR_Header { return &rr.Hdr }
func (rr *HIP) Header() *RR_Header { return &rr.Hdr } func (rr *HIP) Header() *RR_Header { return &rr.Hdr }
func (rr *IPSECKEY) Header() *RR_Header { return &rr.Hdr }
func (rr *KEY) 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 *KX) Header() *RR_Header { return &rr.Hdr }
func (rr *L32) Header() *RR_Header { return &rr.Hdr } func (rr *L32) Header() *RR_Header { return &rr.Hdr }
...@@ -231,7 +226,6 @@ func (rr *TXT) Header() *RR_Header { return &rr.Hdr } ...@@ -231,7 +226,6 @@ func (rr *TXT) Header() *RR_Header { return &rr.Hdr }
func (rr *UID) 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 *UINFO) Header() *RR_Header { return &rr.Hdr }
func (rr *URI) Header() *RR_Header { return &rr.Hdr } func (rr *URI) Header() *RR_Header { return &rr.Hdr }
func (rr *WKS) Header() *RR_Header { return &rr.Hdr }
func (rr *X25) Header() *RR_Header { return &rr.Hdr } func (rr *X25) Header() *RR_Header { return &rr.Hdr }
// len() functions // len() functions
...@@ -688,9 +682,6 @@ func (rr *HIP) copy() RR { ...@@ -688,9 +682,6 @@ func (rr *HIP) copy() RR {
copy(RendezvousServers, rr.RendezvousServers) copy(RendezvousServers, rr.RendezvousServers)
return &HIP{*rr.Hdr.copyHeader(), rr.HitLength, rr.PublicKeyAlgorithm, rr.PublicKeyLength, rr.Hit, rr.PublicKey, RendezvousServers} return &HIP{*rr.Hdr.copyHeader(), rr.HitLength, rr.PublicKeyAlgorithm, rr.PublicKeyLength, rr.Hit, rr.PublicKey, RendezvousServers}
} }
func (rr *IPSECKEY) copy() RR {
return &IPSECKEY{*rr.Hdr.copyHeader(), rr.Precedence, rr.GatewayType, rr.Algorithm, copyIP(rr.GatewayA), copyIP(rr.GatewayAAAA), rr.GatewayName, rr.PublicKey}
}
func (rr *KX) copy() RR { func (rr *KX) copy() RR {
return &KX{*rr.Hdr.copyHeader(), rr.Preference, rr.Exchanger} return &KX{*rr.Hdr.copyHeader(), rr.Preference, rr.Exchanger}
} }
...@@ -832,11 +823,6 @@ func (rr *UINFO) copy() RR { ...@@ -832,11 +823,6 @@ func (rr *UINFO) copy() RR {
func (rr *URI) copy() RR { func (rr *URI) copy() RR {
return &URI{*rr.Hdr.copyHeader(), rr.Priority, rr.Weight, rr.Target} return &URI{*rr.Hdr.copyHeader(), rr.Priority, rr.Weight, rr.Target}
} }
func (rr *WKS) copy() RR {
BitMap := make([]uint16, len(rr.BitMap))
copy(BitMap, rr.BitMap)
return &WKS{*rr.Hdr.copyHeader(), copyIP(rr.Address), rr.Protocol, BitMap}
}
func (rr *X25) copy() RR { func (rr *X25) copy() RR {
return &X25{*rr.Hdr.copyHeader(), rr.PSDNAddress} return &X25{*rr.Hdr.copyHeader(), rr.PSDNAddress}
} }
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
...@@ -39,7 +39,7 @@ type Config struct { ...@@ -39,7 +39,7 @@ type Config struct {
RoundRobin bool `json:"round_robin,omitempty"` RoundRobin bool `json:"round_robin,omitempty"`
// Round robin selection of nameservers from among those listed, rather than have all forwarded requests try the first listed server first every time. // Round robin selection of nameservers from among those listed, rather than have all forwarded requests try the first listed server first every time.
NSRotate bool `json:"ns_rotate,omitempty"` NSRotate bool `json:"ns_rotate,omitempty"`
// List of ip:port, seperated by commas of recursive nameservers to forward queries to. // List of ip:port, separated by commas of recursive nameservers to forward queries to.
Nameservers []string `json:"nameservers,omitempty"` Nameservers []string `json:"nameservers,omitempty"`
// Never provide a recursive service. // Never provide a recursive service.
NoRec bool `json:"no_rec,omitempty"` NoRec bool `json:"no_rec,omitempty"`
......
...@@ -102,7 +102,7 @@ Redo: ...@@ -102,7 +102,7 @@ Redo:
r, err := exchangeWithRetry(s.dnsUDPclient, m, s.config.Nameservers[nsid]) r, err := exchangeWithRetry(s.dnsUDPclient, m, s.config.Nameservers[nsid])
if err == nil { if err == nil {
if r.Rcode != dns.RcodeSuccess { if r.Rcode != dns.RcodeSuccess {
return nil, fmt.Errorf("rcode is not equal to success") return nil, fmt.Errorf("rcode %d is not equal to success", r.Rcode)
} }
// Reset TTLs to rcache TTL to make some of the other code // Reset TTLs to rcache TTL to make some of the other code
// and the tests not care about TTLs // and the tests not care about TTLs
......
...@@ -200,7 +200,7 @@ func (s *server) ServeDNS(w dns.ResponseWriter, req *dns.Msg) { ...@@ -200,7 +200,7 @@ func (s *server) ServeDNS(w dns.ResponseWriter, req *dns.Msg) {
} }
for zone, ns := range *s.config.stub { for zone, ns := range *s.config.stub {
if strings.HasSuffix(name, zone) { if strings.HasSuffix(name, "." + zone) || name == zone {
metrics.ReportRequestCount(req, metrics.Stub) metrics.ReportRequestCount(req, metrics.Stub)
resp := s.ServeDNSStubForward(w, req, ns) resp := s.ServeDNSStubForward(w, req, ns)
...@@ -232,7 +232,7 @@ func (s *server) ServeDNS(w dns.ResponseWriter, req *dns.Msg) { ...@@ -232,7 +232,7 @@ func (s *server) ServeDNS(w dns.ResponseWriter, req *dns.Msg) {
return return
} }
if q.Qclass != dns.ClassCHAOS && !strings.HasSuffix(name, s.config.Domain) { if q.Qclass != dns.ClassCHAOS && !strings.HasSuffix(name, "." +s.config.Domain) && name != s.config.Domain {
metrics.ReportRequestCount(req, metrics.Rec) metrics.ReportRequestCount(req, metrics.Rec)
resp := s.ServeDNSForward(w, req) resp := s.ServeDNSForward(w, req)
...@@ -431,6 +431,7 @@ func (s *server) AddressRecords(q dns.Question, name string, previousRecords []d ...@@ -431,6 +431,7 @@ func (s *server) AddressRecords(q dns.Question, name string, previousRecords []d
case ip == nil: case ip == nil:
// Try to resolve as CNAME if it's not an IP, but only if we don't create loops. // Try to resolve as CNAME if it's not an IP, but only if we don't create loops.
if q.Name == dns.Fqdn(serv.Host) { if q.Name == dns.Fqdn(serv.Host) {
logf("CNAME loop detected: %q -> %q", q.Name, q.Name)
// x CNAME x is a direct loop, don't add those // x CNAME x is a direct loop, don't add those
continue continue
} }
...@@ -464,7 +465,7 @@ func (s *server) AddressRecords(q dns.Question, name string, previousRecords []d ...@@ -464,7 +465,7 @@ func (s *server) AddressRecords(q dns.Question, name string, previousRecords []d
} }
m1, e1 := s.Lookup(target, q.Qtype, bufsize, dnssec) m1, e1 := s.Lookup(target, q.Qtype, bufsize, dnssec)
if e1 != nil { if e1 != nil {
logf("incomplete CNAME chain: %s", e1) logf("incomplete CNAME chain from %q: %s", target, e1)
continue continue
} }
// Len(m1.Answer) > 0 here is well? // Len(m1.Answer) > 0 here is well?
......
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment