aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/miekg
diff options
context:
space:
mode:
authortechknowlogick <techknowlogick@gitea.io>2021-02-28 18:08:33 -0500
committerGitHub <noreply@github.com>2021-02-28 18:08:33 -0500
commit47f6a4ec3f058f69b65fb6501d6ac98994b8f8da (patch)
tree4d1421a4c836de9de4014117419c151035c17eec /vendor/github.com/miekg
parent030646eea41e17e58e11e73b19339630b6d6148e (diff)
downloadgitea-47f6a4ec3f058f69b65fb6501d6ac98994b8f8da.tar.gz
gitea-47f6a4ec3f058f69b65fb6501d6ac98994b8f8da.zip
go1.16 (#14783)
Diffstat (limited to 'vendor/github.com/miekg')
-rw-r--r--vendor/github.com/miekg/dns/.travis.yml17
-rw-r--r--vendor/github.com/miekg/dns/README.md17
-rw-r--r--vendor/github.com/miekg/dns/client.go57
-rw-r--r--vendor/github.com/miekg/dns/dns.go30
-rw-r--r--vendor/github.com/miekg/dns/dnssec.go46
-rw-r--r--vendor/github.com/miekg/dns/dnssec_keygen.go4
-rw-r--r--vendor/github.com/miekg/dns/dnssec_keyscan.go18
-rw-r--r--vendor/github.com/miekg/dns/dnssec_privkey.go20
-rw-r--r--vendor/github.com/miekg/dns/doc.go26
-rw-r--r--vendor/github.com/miekg/dns/edns.go4
-rw-r--r--vendor/github.com/miekg/dns/generate.go26
-rw-r--r--vendor/github.com/miekg/dns/msg.go11
-rw-r--r--vendor/github.com/miekg/dns/msg_helpers.go67
-rw-r--r--vendor/github.com/miekg/dns/msg_truncate.go16
-rw-r--r--vendor/github.com/miekg/dns/scan.go76
-rw-r--r--vendor/github.com/miekg/dns/scan_rr.go23
-rw-r--r--vendor/github.com/miekg/dns/serve_mux.go4
-rw-r--r--vendor/github.com/miekg/dns/server.go120
-rw-r--r--vendor/github.com/miekg/dns/sig0.go14
-rw-r--r--vendor/github.com/miekg/dns/svcb.go744
-rw-r--r--vendor/github.com/miekg/dns/tsig.go158
-rw-r--r--vendor/github.com/miekg/dns/types.go10
-rw-r--r--vendor/github.com/miekg/dns/version.go2
-rw-r--r--vendor/github.com/miekg/dns/zduplicate.go42
-rw-r--r--vendor/github.com/miekg/dns/zmsg.go82
-rw-r--r--vendor/github.com/miekg/dns/ztypes.go25
26 files changed, 1375 insertions, 284 deletions
diff --git a/vendor/github.com/miekg/dns/.travis.yml b/vendor/github.com/miekg/dns/.travis.yml
deleted file mode 100644
index 8eaa064290..0000000000
--- a/vendor/github.com/miekg/dns/.travis.yml
+++ /dev/null
@@ -1,17 +0,0 @@
-language: go
-sudo: false
-
-go:
- - "1.12.x"
- - "1.13.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)
diff --git a/vendor/github.com/miekg/dns/README.md b/vendor/github.com/miekg/dns/README.md
index c324bc05d8..3594492b7c 100644
--- a/vendor/github.com/miekg/dns/README.md
+++ b/vendor/github.com/miekg/dns/README.md
@@ -26,7 +26,6 @@ avoiding breaking changes wherever reasonable. We support the last two versions
A not-so-up-to-date-list-that-may-be-actually-current:
* https://github.com/coredns/coredns
-* https://cloudflare.com
* https://github.com/abh/geodns
* https://github.com/baidu/bfe
* http://www.statdns.com/
@@ -42,11 +41,9 @@ A not-so-up-to-date-list-that-may-be-actually-current:
* https://github.com/StalkR/dns-reverse-proxy
* https://github.com/tianon/rawdns
* https://mesosphere.github.io/mesos-dns/
-* https://pulse.turbobytes.com/
* https://github.com/fcambus/statzone
* https://github.com/benschw/dns-clb-go
* https://github.com/corny/dnscheck for <http://public-dns.info/>
-* https://namesmith.io
* https://github.com/miekg/unbound
* https://github.com/miekg/exdns
* https://dnslookup.org
@@ -55,22 +52,28 @@ A not-so-up-to-date-list-that-may-be-actually-current:
* https://github.com/mehrdadrad/mylg
* https://github.com/bamarni/dockness
* https://github.com/fffaraz/microdns
-* http://kelda.io
* https://github.com/ipdcode/hades <https://jd.com>
* https://github.com/StackExchange/dnscontrol/
* https://www.dnsperf.com/
* https://dnssectest.net/
-* https://dns.apebits.com
* 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://github.com/semihalev/sdns
* https://render.com
* https://github.com/peterzen/goresolver
* https://github.com/folbricht/routedns
+* https://domainr.com/
+* https://zonedb.org/
+* https://router7.org/
+* https://github.com/fortio/dnsping
+* https://github.com/Luzilla/dnsbl_exporter
+* https://github.com/bodgit/tsig
+* https://github.com/v2fly/v2ray-core (test only)
+* https://kuma.io/
+
Send pull request if you want to be listed here.
@@ -167,6 +170,8 @@ Example programs can be found in the `github.com/miekg/exdns` repository.
* 7873 - Domain Name System (DNS) Cookies
* 8080 - EdDSA for DNSSEC
* 8499 - DNS Terminology
+* 8659 - DNS Certification Authority Authorization (CAA) Resource Record
+* 8976 - Message Digest for DNS Zones (ZONEMD RR)
## Loosely Based Upon
diff --git a/vendor/github.com/miekg/dns/client.go b/vendor/github.com/miekg/dns/client.go
index bb8667fd68..000dc013cf 100644
--- a/vendor/github.com/miekg/dns/client.go
+++ b/vendor/github.com/miekg/dns/client.go
@@ -23,6 +23,7 @@ type Conn struct {
net.Conn // a net.Conn holding the connection
UDPSize uint16 // minimum receive buffer for UDP messages
TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2)
+ TsigProvider TsigProvider // An implementation of the TsigProvider interface. If defined it replaces TsigSecret and is used for all TSIG operations.
tsigRequestMAC string
}
@@ -34,12 +35,13 @@ type Client struct {
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 the deprecated ExchangeContext)
+ // 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)
+ TsigProvider TsigProvider // An implementation of the TsigProvider interface. If defined it replaces TsigSecret and is used for all TSIG operations.
SingleInflight bool // if true suppress multiple outstanding queries for the same Qname, Qtype and Qclass
group singleflight
}
@@ -106,7 +108,7 @@ func (c *Client) Dial(address string) (conn *Conn, err error) {
if err != nil {
return nil, err
}
-
+ conn.UDPSize = c.UDPSize
return conn, nil
}
@@ -124,7 +126,6 @@ func (c *Client) Dial(address string) (conn *Conn, err error) {
// 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)
@@ -176,7 +177,7 @@ func (c *Client) exchange(m *Msg, co *Conn) (r *Msg, rtt time.Duration, err erro
co.UDPSize = c.UDPSize
}
- co.TsigSecret = c.TsigSecret
+ co.TsigSecret, co.TsigProvider = c.TsigSecret, c.TsigProvider
t := time.Now()
// write with the appropriate write timeout
co.SetWriteDeadline(t.Add(c.getTimeoutForRequest(c.writeTimeout())))
@@ -185,9 +186,20 @@ func (c *Client) exchange(m *Msg, co *Conn) (r *Msg, rtt time.Duration, err erro
}
co.SetReadDeadline(time.Now().Add(c.getTimeoutForRequest(c.readTimeout())))
- r, err = co.ReadMsg()
- if err == nil && r.Id != m.Id {
- err = ErrId
+ 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
@@ -212,11 +224,15 @@ func (co *Conn) ReadMsg() (*Msg, error) {
return m, err
}
if t := m.IsTsig(); t != nil {
- if _, ok := co.TsigSecret[t.Hdr.Name]; !ok {
- return m, ErrSecret
+ if co.TsigProvider != nil {
+ err = tsigVerifyProvider(p, co.TsigProvider, co.tsigRequestMAC, false)
+ } else {
+ 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)
}
- // 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
}
@@ -294,10 +310,14 @@ 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
+ if co.TsigProvider != nil {
+ out, mac, err = tsigGenerateProvider(m, co.TsigProvider, co.tsigRequestMAC, false)
+ } else {
+ if _, ok := co.TsigSecret[t.Hdr.Name]; !ok {
+ return ErrSecret
+ }
+ out, mac, err = TsigGenerate(m, co.TsigSecret[t.Hdr.Name], co.tsigRequestMAC, false)
}
- 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 {
@@ -320,11 +340,10 @@ func (co *Conn) Write(p []byte) (int, error) {
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
+ msg := make([]byte, 2+len(p))
+ binary.BigEndian.PutUint16(msg, uint16(len(p)))
+ copy(msg[2:], p)
+ return co.Conn.Write(msg)
}
// Return the appropriate timeout for a specific request
diff --git a/vendor/github.com/miekg/dns/dns.go b/vendor/github.com/miekg/dns/dns.go
index ad83a27ecf..a88484b062 100644
--- a/vendor/github.com/miekg/dns/dns.go
+++ b/vendor/github.com/miekg/dns/dns.go
@@ -1,6 +1,9 @@
package dns
-import "strconv"
+import (
+ "encoding/hex"
+ "strconv"
+)
const (
year68 = 1 << 31 // For RFC1982 (Serial Arithmetic) calculations in 32 bits.
@@ -111,7 +114,7 @@ func (h *RR_Header) parse(c *zlexer, origin string) *ParseError {
// 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)
+ buf := make([]byte, Len(r))
headerEnd, off, err := packRR(r, buf, 0, compressionMap{}, false)
if err != nil {
return err
@@ -126,9 +129,30 @@ func (rr *RFC3597) ToRFC3597(r RR) error {
}
_, err = rr.unpack(buf, headerEnd)
+ return err
+}
+
+// fromRFC3597 converts an unknown RR representation from RFC 3597 to the known RR type.
+func (rr *RFC3597) fromRFC3597(r RR) error {
+ hdr := r.Header()
+ *hdr = rr.Hdr
+
+ // Can't overflow uint16 as the length of Rdata is validated in (*RFC3597).parse.
+ // We can only get here when rr was constructed with that method.
+ hdr.Rdlength = uint16(hex.DecodedLen(len(rr.Rdata)))
+
+ if noRdata(*hdr) {
+ // Dynamic update.
+ return nil
+ }
+
+ // rr.pack requires an extra allocation and a copy so we just decode Rdata
+ // manually, it's simpler anyway.
+ msg, err := hex.DecodeString(rr.Rdata)
if err != nil {
return err
}
- return nil
+ _, err = r.unpack(msg, 0)
+ return err
}
diff --git a/vendor/github.com/miekg/dns/dnssec.go b/vendor/github.com/miekg/dns/dnssec.go
index 68c0bd74d0..900f6e059d 100644
--- a/vendor/github.com/miekg/dns/dnssec.go
+++ b/vendor/github.com/miekg/dns/dnssec.go
@@ -3,10 +3,8 @@ package dns
import (
"bytes"
"crypto"
- "crypto/dsa"
"crypto/ecdsa"
"crypto/elliptic"
- _ "crypto/md5"
"crypto/rand"
"crypto/rsa"
_ "crypto/sha1"
@@ -318,6 +316,7 @@ func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error {
}
rr.Signature = toBase64(signature)
+ return nil
case RSAMD5, DSA, DSANSEC3SHA1:
// See RFC 6944.
return ErrAlg
@@ -332,9 +331,8 @@ func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error {
}
rr.Signature = toBase64(signature)
+ return nil
}
-
- return nil
}
func sign(k crypto.Signer, hashed []byte, hash crypto.Hash, alg uint8) ([]byte, error) {
@@ -346,7 +344,6 @@ func sign(k crypto.Signer, hashed []byte, hash crypto.Hash, alg uint8) ([]byte,
switch alg {
case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512:
return signature, nil
-
case ECDSAP256SHA256, ECDSAP384SHA384:
ecdsaSignature := &struct {
R, S *big.Int
@@ -366,20 +363,11 @@ func sign(k crypto.Signer, hashed []byte, hash crypto.Hash, alg uint8) ([]byte,
signature := intToBytes(ecdsaSignature.R, intlen)
signature = append(signature, intToBytes(ecdsaSignature.S, intlen)...)
return signature, nil
-
- // There is no defined interface for what a DSA backed crypto.Signer returns
- case DSA, DSANSEC3SHA1:
- // t := divRoundUp(divRoundUp(p.PublicKey.Y.BitLen(), 8)-64, 8)
- // signature := []byte{byte(t)}
- // signature = append(signature, intToBytes(r1, 20)...)
- // signature = append(signature, intToBytes(s1, 20)...)
- // rr.Signature = signature
-
case ED25519:
return signature, nil
+ default:
+ return nil, ErrAlg
}
-
- return nil, ErrAlg
}
// Verify validates an RRSet with the signature and key. This is only the
@@ -448,7 +436,7 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
}
switch rr.Algorithm {
- case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512, RSAMD5:
+ 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 {
@@ -600,30 +588,6 @@ func (k *DNSKEY) publicKeyECDSA() *ecdsa.PublicKey {
return pubkey
}
-func (k *DNSKEY) publicKeyDSA() *dsa.PublicKey {
- keybuf, err := fromBase64([]byte(k.PublicKey))
- if err != nil {
- return nil
- }
- if len(keybuf) < 22 {
- return nil
- }
- t, keybuf := int(keybuf[0]), keybuf[1:]
- size := 64 + t*8
- q, keybuf := keybuf[:20], keybuf[20:]
- if len(keybuf) != 3*size {
- return nil
- }
- p, keybuf := keybuf[:size], keybuf[size:]
- g, y := keybuf[:size], keybuf[size:]
- pubkey := new(dsa.PublicKey)
- pubkey.Parameters.Q = new(big.Int).SetBytes(q)
- pubkey.Parameters.P = new(big.Int).SetBytes(p)
- pubkey.Parameters.G = new(big.Int).SetBytes(g)
- pubkey.Y = new(big.Int).SetBytes(y)
- return pubkey
-}
-
func (k *DNSKEY) publicKeyED25519() ed25519.PublicKey {
keybuf, err := fromBase64([]byte(k.PublicKey))
if err != nil {
diff --git a/vendor/github.com/miekg/dns/dnssec_keygen.go b/vendor/github.com/miekg/dns/dnssec_keygen.go
index 60737e5b2b..2ab7b6d73b 100644
--- a/vendor/github.com/miekg/dns/dnssec_keygen.go
+++ b/vendor/github.com/miekg/dns/dnssec_keygen.go
@@ -19,8 +19,6 @@ import (
// bits should be set to the size of the algorithm.
func (k *DNSKEY) Generate(bits int) (crypto.PrivateKey, error) {
switch k.Algorithm {
- case RSAMD5, DSA, DSANSEC3SHA1:
- return nil, ErrAlg
case RSASHA1, RSASHA256, RSASHA1NSEC3SHA1:
if bits < 512 || bits > 4096 {
return nil, ErrKeySize
@@ -41,6 +39,8 @@ func (k *DNSKEY) Generate(bits int) (crypto.PrivateKey, error) {
if bits != 256 {
return nil, ErrKeySize
}
+ default:
+ return nil, ErrAlg
}
switch k.Algorithm {
diff --git a/vendor/github.com/miekg/dns/dnssec_keyscan.go b/vendor/github.com/miekg/dns/dnssec_keyscan.go
index 0e6f320165..6cbc28483f 100644
--- a/vendor/github.com/miekg/dns/dnssec_keyscan.go
+++ b/vendor/github.com/miekg/dns/dnssec_keyscan.go
@@ -43,15 +43,7 @@ func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, er
return nil, ErrPrivKey
}
switch uint8(algo) {
- case RSAMD5, DSA, DSANSEC3SHA1:
- return nil, ErrAlg
- case RSASHA1:
- fallthrough
- case RSASHA1NSEC3SHA1:
- fallthrough
- case RSASHA256:
- fallthrough
- case RSASHA512:
+ case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512:
priv, err := readPrivateKeyRSA(m)
if err != nil {
return nil, err
@@ -62,11 +54,7 @@ func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, er
}
priv.PublicKey = *pub
return priv, nil
- case ECCGOST:
- return nil, ErrPrivKey
- case ECDSAP256SHA256:
- fallthrough
- case ECDSAP384SHA384:
+ case ECDSAP256SHA256, ECDSAP384SHA384:
priv, err := readPrivateKeyECDSA(m)
if err != nil {
return nil, err
@@ -80,7 +68,7 @@ func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, er
case ED25519:
return readPrivateKeyED25519(m)
default:
- return nil, ErrPrivKey
+ return nil, ErrAlg
}
}
diff --git a/vendor/github.com/miekg/dns/dnssec_privkey.go b/vendor/github.com/miekg/dns/dnssec_privkey.go
index 4493c9d574..072e445dad 100644
--- a/vendor/github.com/miekg/dns/dnssec_privkey.go
+++ b/vendor/github.com/miekg/dns/dnssec_privkey.go
@@ -2,7 +2,6 @@ package dns
import (
"crypto"
- "crypto/dsa"
"crypto/ecdsa"
"crypto/rsa"
"math/big"
@@ -17,8 +16,8 @@ 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 dsa.PrivateKey
+// 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] + ")"
@@ -67,21 +66,6 @@ func (r *DNSKEY) PrivateKeyString(p crypto.PrivateKey) string {
"Algorithm: " + algorithm + "\n" +
"PrivateKey: " + private + "\n"
- case *dsa.PrivateKey:
- T := divRoundUp(divRoundUp(p.PublicKey.Parameters.G.BitLen(), 8)-64, 8)
- prime := toBase64(intToBytes(p.PublicKey.Parameters.P, 64+T*8))
- subprime := toBase64(intToBytes(p.PublicKey.Parameters.Q, 20))
- base := toBase64(intToBytes(p.PublicKey.Parameters.G, 64+T*8))
- priv := toBase64(intToBytes(p.X, 20))
- pub := toBase64(intToBytes(p.PublicKey.Y, 64+T*8))
- return format +
- "Algorithm: " + algorithm + "\n" +
- "Prime(p): " + prime + "\n" +
- "Subprime(q): " + subprime + "\n" +
- "Base(g): " + base + "\n" +
- "Private_value(x): " + priv + "\n" +
- "Public_value(y): " + pub + "\n"
-
case ed25519.PrivateKey:
private := toBase64(p.Seed())
return format +
diff --git a/vendor/github.com/miekg/dns/doc.go b/vendor/github.com/miekg/dns/doc.go
index 92421681f9..f7629ec3ff 100644
--- a/vendor/github.com/miekg/dns/doc.go
+++ b/vendor/github.com/miekg/dns/doc.go
@@ -194,6 +194,30 @@ request an AXFR for miek.nl. with TSIG key named "axfr." and secret
You can now read the records from the transfer as they come in. Each envelope
is checked with TSIG. If something is not correct an error is returned.
+A custom TSIG implementation can be used. This requires additional code to
+perform any session establishment and signature generation/verification. The
+client must be configured with an implementation of the TsigProvider interface:
+
+ type Provider struct{}
+
+ func (*Provider) Generate(msg []byte, tsig *dns.TSIG) ([]byte, error) {
+ // Use tsig.Hdr.Name and tsig.Algorithm in your code to
+ // generate the MAC using msg as the payload.
+ }
+
+ func (*Provider) Verify(msg []byte, tsig *dns.TSIG) error {
+ // Use tsig.Hdr.Name and tsig.Algorithm in your code to verify
+ // that msg matches the value in tsig.MAC.
+ }
+
+ c := new(dns.Client)
+ c.TsigProvider = new(Provider)
+ m := new(dns.Msg)
+ m.SetQuestion("miek.nl.", dns.TypeMX)
+ m.SetTsig(keyname, dns.HmacSHA1, 300, time.Now().Unix())
+ ...
+ // TSIG RR is calculated by calling your Generate method
+
Basic use pattern validating and replying to a message that has TSIG set.
server := &dns.Server{Addr: ":53", Net: "udp"}
@@ -260,7 +284,7 @@ From RFC 2931:
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: DSA, ECDSAP256SHA256,
+the shared secret approach in TSIG. Supported algorithms: ECDSAP256SHA256,
ECDSAP384SHA384, RSASHA1, RSASHA256 and RSASHA512.
Signing subsequent messages in multi-message sessions is not implemented.
diff --git a/vendor/github.com/miekg/dns/edns.go b/vendor/github.com/miekg/dns/edns.go
index 04808d5789..f3fb1c6849 100644
--- a/vendor/github.com/miekg/dns/edns.go
+++ b/vendor/github.com/miekg/dns/edns.go
@@ -88,8 +88,8 @@ func (rr *OPT) len(off int, compression map[string]struct{}) int {
return l
}
-func (rr *OPT) parse(c *zlexer, origin string) *ParseError {
- panic("dns: internal error: parse should never be called on OPT")
+func (*OPT) parse(c *zlexer, origin string) *ParseError {
+ return &ParseError{err: "OPT records do not have a presentation format"}
}
func (r1 *OPT) isDuplicate(r2 RR) bool { return false }
diff --git a/vendor/github.com/miekg/dns/generate.go b/vendor/github.com/miekg/dns/generate.go
index f713074a18..ac8df34dd5 100644
--- a/vendor/github.com/miekg/dns/generate.go
+++ b/vendor/github.com/miekg/dns/generate.go
@@ -75,10 +75,10 @@ func (zp *ZoneParser) generate(l lex) (RR, bool) {
r := &generateReader{
s: s,
- cur: int(start),
- start: int(start),
- end: int(end),
- step: int(step),
+ cur: start,
+ start: start,
+ end: end,
+ step: step,
file: zp.file,
lex: &l,
@@ -94,10 +94,10 @@ type generateReader struct {
s string
si int
- cur int
- start int
- end int
- step int
+ cur int64
+ start int64
+ end int64
+ step int64
mod bytes.Buffer
@@ -173,7 +173,7 @@ func (r *generateReader) ReadByte() (byte, error) {
return '$', nil
}
- var offset int
+ var offset int64
// Search for { and }
if r.s[si+1] == '{' {
@@ -188,7 +188,7 @@ func (r *generateReader) ReadByte() (byte, error) {
if errMsg != "" {
return 0, r.parseError(errMsg, si+3+sep)
}
- if r.start+offset < 0 || int64(r.end) + int64(offset) > 1<<31-1 {
+ if r.start+offset < 0 || r.end+offset > 1<<31-1 {
return 0, r.parseError("bad offset in $GENERATE", si+3+sep)
}
@@ -208,7 +208,7 @@ func (r *generateReader) ReadByte() (byte, error) {
}
// 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, int64, string) {
// Modifier is { offset [ ,width [ ,base ] ] } - provide default
// values for optional width and type, if necessary.
var offStr, widthStr, base string
@@ -240,8 +240,8 @@ func modToPrintf(s string) (string, int, string) {
}
if width == 0 {
- return "%" + base, int(offset), ""
+ return "%" + base, offset, ""
}
- return "%0" + widthStr + base, int(offset), ""
+ return "%0" + widthStr + base, offset, ""
}
diff --git a/vendor/github.com/miekg/dns/msg.go b/vendor/github.com/miekg/dns/msg.go
index 7001f6da79..1728a98b7d 100644
--- a/vendor/github.com/miekg/dns/msg.go
+++ b/vendor/github.com/miekg/dns/msg.go
@@ -624,11 +624,18 @@ func UnpackRRWithHeader(h RR_Header, msg []byte, off int) (rr RR, off1 int, err
rr = &RFC3597{Hdr: h}
}
- if noRdata(h) {
- return rr, off, nil
+ if off < 0 || off > len(msg) {
+ return &h, off, &Error{err: "bad off"}
}
end := off + int(h.Rdlength)
+ if end < off || end > len(msg) {
+ return &h, end, &Error{err: "bad rdlength"}
+ }
+
+ if noRdata(h) {
+ return rr, off, nil
+ }
off, err = rr.unpack(msg, off)
if err != nil {
diff --git a/vendor/github.com/miekg/dns/msg_helpers.go b/vendor/github.com/miekg/dns/msg_helpers.go
index cbcab57bcd..47625ed090 100644
--- a/vendor/github.com/miekg/dns/msg_helpers.go
+++ b/vendor/github.com/miekg/dns/msg_helpers.go
@@ -6,6 +6,7 @@ import (
"encoding/binary"
"encoding/hex"
"net"
+ "sort"
"strings"
)
@@ -612,6 +613,65 @@ func packDataNsec(bitmap []uint16, msg []byte, off int) (int, error) {
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
@@ -683,6 +743,13 @@ func packDataAplPrefix(p *APLPrefix, msg []byte, off int) (int, error) {
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 {
diff --git a/vendor/github.com/miekg/dns/msg_truncate.go b/vendor/github.com/miekg/dns/msg_truncate.go
index a76150a861..2ddc9a7da8 100644
--- a/vendor/github.com/miekg/dns/msg_truncate.go
+++ b/vendor/github.com/miekg/dns/msg_truncate.go
@@ -8,8 +8,14 @@ package dns
// record adding as many records as possible without exceeding the
// requested buffer size.
//
+// If the message fits within the requested size without compression,
+// Truncate will set the message's Compress attribute to false. It is
+// the caller's responsibility to set it back to true if they wish to
+// compress the payload regardless of size.
+//
// The TC bit will be set if any records were excluded from the message.
-// This indicates to that the client should retry over TCP.
+// 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
@@ -28,11 +34,11 @@ func (dns *Msg) Truncate(size int) {
}
// RFC 6891 mandates that the payload size in an OPT record
- // less than 512 bytes must be treated as equal to 512 bytes.
+ // less than 512 (MinMsgSize) bytes must be treated as equal to 512 bytes.
//
// For ease of use, we impose that restriction here.
- if size < 512 {
- size = 512
+ if size < MinMsgSize {
+ size = MinMsgSize
}
l := msgLenWithCompressionMap(dns, nil) // uncompressed length
@@ -77,7 +83,7 @@ func (dns *Msg) Truncate(size int) {
}
// See the function documentation for when we set this.
- dns.Truncated = len(dns.Answer) > numAnswer ||
+ dns.Truncated = dns.Truncated || len(dns.Answer) > numAnswer ||
len(dns.Ns) > numNS || len(dns.Extra) > numExtra
dns.Answer = dns.Answer[:numAnswer]
diff --git a/vendor/github.com/miekg/dns/scan.go b/vendor/github.com/miekg/dns/scan.go
index e18566fc87..67161de29c 100644
--- a/vendor/github.com/miekg/dns/scan.go
+++ b/vendor/github.com/miekg/dns/scan.go
@@ -577,10 +577,23 @@ func (zp *ZoneParser) Next() (RR, bool) {
st = zExpectRdata
case zExpectRdata:
- var rr RR
- if newFn, ok := TypeToRR[h.Rrtype]; ok && canParseAsRR(h.Rrtype) {
+ var (
+ rr RR
+ parseAsRFC3597 bool
+ )
+ if newFn, ok := TypeToRR[h.Rrtype]; ok {
rr = newFn()
*rr.Header() = *h
+
+ // We may be parsing a known RR type using the RFC3597 format.
+ // If so, we handle that here in a generic way.
+ //
+ // This is also true for PrivateRR types which will have the
+ // RFC3597 parsing done for them and the Unpack method called
+ // to populate the RR instead of simply deferring to Parse.
+ if zp.c.Peek().token == "\\#" {
+ parseAsRFC3597 = true
+ }
} else {
rr = &RFC3597{Hdr: *h}
}
@@ -600,13 +613,18 @@ func (zp *ZoneParser) Next() (RR, bool) {
return zp.setParseError("unexpected newline", l)
}
- if err := rr.parse(zp.c, zp.origin); err != nil {
+ parseAsRR := rr
+ if parseAsRFC3597 {
+ parseAsRR = &RFC3597{Hdr: *h}
+ }
+
+ if err := parseAsRR.parse(zp.c, zp.origin); err != nil {
// err is a concrete *ParseError without the file field set.
// The setParseError call below will construct a new
// *ParseError with file set to zp.file.
- // If err.lex is nil than we have encounter an unknown RR type
- // in that case we substitute our current lex token.
+ // err.lex may be nil in which case we substitute our current
+ // lex token.
if err.lex == (lex{}) {
return zp.setParseError(err.err, l)
}
@@ -614,6 +632,13 @@ func (zp *ZoneParser) Next() (RR, bool) {
return zp.setParseError(err.err, err.lex)
}
+ if parseAsRFC3597 {
+ err := parseAsRR.(*RFC3597).fromRFC3597(rr)
+ if err != nil {
+ return zp.setParseError(err.Error(), l)
+ }
+ }
+
return rr, true
}
}
@@ -623,18 +648,6 @@ func (zp *ZoneParser) Next() (RR, bool) {
return nil, false
}
-// canParseAsRR returns true if the record type can be parsed as a
-// concrete RR. It blacklists certain record types that must be parsed
-// according to RFC 3597 because they lack a presentation format.
-func canParseAsRR(rrtype uint16) bool {
- switch rrtype {
- case TypeANY, TypeNULL, TypeOPT, TypeTSIG:
- return false
- default:
- return true
- }
-}
-
type zlexer struct {
br io.ByteReader
@@ -1210,11 +1223,29 @@ func stringToCm(token string) (e, m uint8, ok bool) {
if cmeters, err = strconv.Atoi(s[1]); err != nil {
return
}
+ // There's no point in having more than 2 digits in this part, and would rather make the implementation complicated ('123' should be treated as '12').
+ // So we simply reject it.
+ // We also make sure the first character is a digit to reject '+-' signs.
+ if len(s[1]) > 2 || s[1][0] < '0' || s[1][0] > '9' {
+ return
+ }
+ if len(s[1]) == 1 {
+ // 'nn.1' must be treated as 'nn-meters and 10cm, not 1cm.
+ cmeters *= 10
+ }
+ if len(s[0]) == 0 {
+ // This will allow omitting the 'meter' part, like .01 (meaning 0.01m = 1cm).
+ break
+ }
fallthrough
case 1:
if meters, err = strconv.Atoi(s[0]); err != nil {
return
}
+ // RFC1876 states the max value is 90000000.00. The latter two conditions enforce it.
+ if s[0][0] < '0' || s[0][0] > '9' || meters > 90000000 || (meters == 90000000 && cmeters != 0) {
+ return
+ }
case 0:
// huh?
return 0, 0, false
@@ -1227,13 +1258,10 @@ func stringToCm(token string) (e, m uint8, ok bool) {
e = 0
val = cmeters
}
- for val > 10 {
+ for val >= 10 {
e++
val /= 10
}
- if e > 9 {
- ok = false
- }
m = uint8(val)
return
}
@@ -1275,6 +1303,9 @@ func appendOrigin(name, origin string) string {
// LOC record helper function
func locCheckNorth(token string, latitude uint32) (uint32, bool) {
+ if latitude > 90*1000*60*60 {
+ return latitude, false
+ }
switch token {
case "n", "N":
return LOC_EQUATOR + latitude, true
@@ -1286,6 +1317,9 @@ func locCheckNorth(token string, latitude uint32) (uint32, bool) {
// LOC record helper function
func locCheckEast(token string, longitude uint32) (uint32, bool) {
+ if longitude > 180*1000*60*60 {
+ return longitude, false
+ }
switch token {
case "e", "E":
return LOC_EQUATOR + longitude, true
diff --git a/vendor/github.com/miekg/dns/scan_rr.go b/vendor/github.com/miekg/dns/scan_rr.go
index 11b08ad1d1..23b4043bcd 100644
--- a/vendor/github.com/miekg/dns/scan_rr.go
+++ b/vendor/github.com/miekg/dns/scan_rr.go
@@ -590,7 +590,7 @@ func (rr *LOC) parse(c *zlexer, o string) *ParseError {
// North
l, _ := c.Next()
i, e := strconv.ParseUint(l.token, 10, 32)
- if e != nil || l.err {
+ if e != nil || l.err || i > 90 {
return &ParseError{"", "bad LOC Latitude", l}
}
rr.Latitude = 1000 * 60 * 60 * uint32(i)
@@ -601,7 +601,7 @@ func (rr *LOC) parse(c *zlexer, o string) *ParseError {
if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok {
goto East
}
- if i, err := strconv.ParseUint(l.token, 10, 32); err != nil || l.err {
+ if i, err := strconv.ParseUint(l.token, 10, 32); err != nil || l.err || i > 59 {
return &ParseError{"", "bad LOC Latitude minutes", l}
} else {
rr.Latitude += 1000 * 60 * uint32(i)
@@ -609,7 +609,7 @@ func (rr *LOC) parse(c *zlexer, o string) *ParseError {
c.Next() // zBlank
l, _ = c.Next()
- if i, err := strconv.ParseFloat(l.token, 32); err != nil || l.err {
+ if i, err := strconv.ParseFloat(l.token, 32); err != nil || l.err || i < 0 || i >= 60 {
return &ParseError{"", "bad LOC Latitude seconds", l}
} else {
rr.Latitude += uint32(1000 * i)
@@ -627,7 +627,7 @@ East:
// East
c.Next() // zBlank
l, _ = c.Next()
- if i, err := strconv.ParseUint(l.token, 10, 32); err != nil || l.err {
+ if i, err := strconv.ParseUint(l.token, 10, 32); err != nil || l.err || i > 180 {
return &ParseError{"", "bad LOC Longitude", l}
} else {
rr.Longitude = 1000 * 60 * 60 * uint32(i)
@@ -638,14 +638,14 @@ East:
if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok {
goto Altitude
}
- if i, err := strconv.ParseUint(l.token, 10, 32); err != nil || l.err {
+ if i, err := strconv.ParseUint(l.token, 10, 32); err != nil || l.err || i > 59 {
return &ParseError{"", "bad LOC Longitude minutes", l}
} else {
rr.Longitude += 1000 * 60 * uint32(i)
}
c.Next() // zBlank
l, _ = c.Next()
- if i, err := strconv.ParseFloat(l.token, 32); err != nil || l.err {
+ if i, err := strconv.ParseFloat(l.token, 32); err != nil || l.err || i < 0 || i >= 60 {
return &ParseError{"", "bad LOC Longitude seconds", l}
} else {
rr.Longitude += uint32(1000 * i)
@@ -668,7 +668,7 @@ Altitude:
if l.token[len(l.token)-1] == 'M' || l.token[len(l.token)-1] == 'm' {
l.token = l.token[0 : len(l.token)-1]
}
- if i, err := strconv.ParseFloat(l.token, 32); err != nil {
+ if i, err := strconv.ParseFloat(l.token, 64); err != nil {
return &ParseError{"", "bad LOC Altitude", l}
} else {
rr.Altitude = uint32(i*100.0 + 10000000.0 + 0.5)
@@ -893,8 +893,7 @@ func (rr *RRSIG) parse(c *zlexer, o string) *ParseError {
l, _ = c.Next()
if i, err := StringToTime(l.token); err != nil {
// Try to see if all numeric and use it as epoch
- if i, err := strconv.ParseInt(l.token, 10, 64); err == nil {
- // TODO(miek): error out on > MAX_UINT32, same below
+ if i, err := strconv.ParseUint(l.token, 10, 32); err == nil {
rr.Expiration = uint32(i)
} else {
return &ParseError{"", "bad RRSIG Expiration", l}
@@ -906,7 +905,7 @@ func (rr *RRSIG) parse(c *zlexer, o string) *ParseError {
c.Next() // zBlank
l, _ = c.Next()
if i, err := StringToTime(l.token); err != nil {
- if i, err := strconv.ParseInt(l.token, 10, 64); err == nil {
+ if i, err := strconv.ParseUint(l.token, 10, 32); err == nil {
rr.Inception = uint32(i)
} else {
return &ParseError{"", "bad RRSIG Inception", l}
@@ -1388,7 +1387,7 @@ func (rr *RFC3597) parse(c *zlexer, o string) *ParseError {
c.Next() // zBlank
l, _ = c.Next()
- rdlength, e := strconv.Atoi(l.token)
+ rdlength, e := strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err {
return &ParseError{"", "bad RFC3597 Rdata ", l}
}
@@ -1397,7 +1396,7 @@ func (rr *RFC3597) parse(c *zlexer, o string) *ParseError {
if e1 != nil {
return e1
}
- if rdlength*2 != len(s) {
+ if int(rdlength)*2 != len(s) {
return &ParseError{"", "bad RFC3597 Rdata", l}
}
rr.Rdata = s
diff --git a/vendor/github.com/miekg/dns/serve_mux.go b/vendor/github.com/miekg/dns/serve_mux.go
index aadb0bf072..e7f36e2218 100644
--- a/vendor/github.com/miekg/dns/serve_mux.go
+++ b/vendor/github.com/miekg/dns/serve_mux.go
@@ -91,7 +91,7 @@ func (mux *ServeMux) HandleRemove(pattern string) {
// 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 SERVFAIL
+// 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
@@ -102,7 +102,7 @@ func (mux *ServeMux) ServeDNS(w ResponseWriter, req *Msg) {
if h != nil {
h.ServeDNS(w, req)
} else {
- HandleFailed(w, req)
+ handleRefused(w, req)
}
}
diff --git a/vendor/github.com/miekg/dns/server.go b/vendor/github.com/miekg/dns/server.go
index 3cf1a02401..b2a63bda49 100644
--- a/vendor/github.com/miekg/dns/server.go
+++ b/vendor/github.com/miekg/dns/server.go
@@ -72,13 +72,22 @@ type response struct {
tsigStatus error
tsigRequestMAC string
tsigSecret map[string]string // the tsig secrets
- udp *net.UDPConn // i/o connection if UDP was used
+ 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)
@@ -139,12 +148,24 @@ type Reader interface {
ReadUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error)
}
-// defaultReader is an adapter for the Server struct that implements the Reader interface
-// using the readTCP and readUDP func of the embedded Server.
+// 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)
}
@@ -153,8 +174,14 @@ func (dr defaultReader) ReadUDP(conn *net.UDPConn, timeout time.Duration) ([]byt
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.
@@ -294,6 +321,7 @@ func (srv *Server) ListenAndServe() error {
}
u := l.(*net.UDPConn)
if e := setUDPSocketOptions(u); e != nil {
+ u.Close()
return e
}
srv.PacketConn = l
@@ -317,24 +345,22 @@ func (srv *Server) ActivateAndServe() error {
srv.init()
- pConn := srv.PacketConn
- l := srv.Listener
- if pConn != nil {
+ if srv.PacketConn != nil {
// Check PacketConn interface's type is valid and value
// is not nil
- if t, ok := pConn.(*net.UDPConn); ok && t != 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(t)
}
+ srv.started = true
+ unlock()
+ return srv.serveUDP(srv.PacketConn)
}
- if l != nil {
+ if srv.Listener != nil {
srv.started = true
unlock()
- return srv.serveTCP(l)
+ return srv.serveTCP(srv.Listener)
}
return &Error{err: "bad listeners"}
}
@@ -438,18 +464,24 @@ func (srv *Server) serveTCP(l net.Listener) error {
}
// serveUDP starts a UDP listener for the server.
-func (srv *Server) serveUDP(l *net.UDPConn) error {
+func (srv *Server) serveUDP(l net.PacketConn) error {
defer l.Close()
- if srv.NotifyStartedFunc != nil {
- srv.NotifyStartedFunc()
- }
-
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()
@@ -459,7 +491,17 @@ func (srv *Server) serveUDP(l *net.UDPConn) error {
rtimeout := srv.getReadTimeout()
// deadline is not used here
for srv.isStarted() {
- m, s, err := reader.ReadUDP(l, rtimeout)
+ 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
@@ -476,7 +518,7 @@ func (srv *Server) serveUDP(l *net.UDPConn) error {
continue
}
wg.Add(1)
- go srv.serveUDPPacket(&wg, m, l, s)
+ go srv.serveUDPPacket(&wg, m, l, sUDP, sPC)
}
return nil
@@ -538,8 +580,8 @@ func (srv *Server) serveTCPConn(wg *sync.WaitGroup, rw net.Conn) {
}
// Serve a new UDP request.
-func (srv *Server) serveUDPPacket(wg *sync.WaitGroup, m []byte, u *net.UDPConn, s *SessionUDP) {
- w := &response{tsigSecret: srv.TsigSecret, udp: u, udpSession: s}
+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 {
@@ -651,6 +693,24 @@ func (srv *Server) readUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *S
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 {
@@ -684,17 +744,19 @@ func (w *response) Write(m []byte) (int, error) {
switch {
case w.udp != nil:
- return WriteToSessionUDP(w.udp, m, w.udpSession)
+ 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
+ msg := make([]byte, 2+len(m))
+ binary.BigEndian.PutUint16(msg, uint16(len(m)))
+ copy(msg[2:], m)
+ return w.tcp.Write(msg)
default:
panic("dns: internal error: udp and tcp both nil")
}
@@ -717,10 +779,12 @@ 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 and tcp both nil")
+ panic("dns: internal error: udpSession, pcSession and tcp are all nil")
}
}
diff --git a/vendor/github.com/miekg/dns/sig0.go b/vendor/github.com/miekg/dns/sig0.go
index 55cf1c3863..9ef13ccf39 100644
--- a/vendor/github.com/miekg/dns/sig0.go
+++ b/vendor/github.com/miekg/dns/sig0.go
@@ -2,7 +2,6 @@ package dns
import (
"crypto"
- "crypto/dsa"
"crypto/ecdsa"
"crypto/rsa"
"encoding/binary"
@@ -85,7 +84,7 @@ func (rr *SIG) Verify(k *KEY, buf []byte) error {
var hash crypto.Hash
switch rr.Algorithm {
- case DSA, RSASHA1:
+ case RSASHA1:
hash = crypto.SHA1
case RSASHA256, ECDSAP256SHA256:
hash = crypto.SHA256
@@ -178,17 +177,6 @@ func (rr *SIG) Verify(k *KEY, buf []byte) error {
hashed := hasher.Sum(nil)
sig := buf[sigend:]
switch k.Algorithm {
- case DSA:
- pk := k.publicKeyDSA()
- sig = sig[1:]
- r := new(big.Int).SetBytes(sig[:len(sig)/2])
- s := new(big.Int).SetBytes(sig[len(sig)/2:])
- if pk != nil {
- if dsa.Verify(pk, hashed, r, s) {
- return nil
- }
- return ErrSig
- }
case RSASHA1, RSASHA256, RSASHA512:
pk := k.publicKeyRSA()
if pk != nil {
diff --git a/vendor/github.com/miekg/dns/svcb.go b/vendor/github.com/miekg/dns/svcb.go
new file mode 100644
index 0000000000..1373fe21b7
--- /dev/null
+++ b/vendor/github.com/miekg/dns/svcb.go
@@ -0,0 +1,744 @@
+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 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
+}
diff --git a/vendor/github.com/miekg/dns/tsig.go b/vendor/github.com/miekg/dns/tsig.go
index 9451f1a86c..b49562d847 100644
--- a/vendor/github.com/miekg/dns/tsig.go
+++ b/vendor/github.com/miekg/dns/tsig.go
@@ -2,7 +2,6 @@ package dns
import (
"crypto/hmac"
- "crypto/md5"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
@@ -16,12 +15,65 @@ import (
// HMAC hashing codes. These are transmitted as domain names.
const (
- HmacMD5 = "hmac-md5.sig-alg.reg.int."
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.
)
+// TsigProvider provides the API to plug-in a custom TSIG implementation.
+type TsigProvider interface {
+ // Generate is passed the DNS message to be signed and the partial TSIG RR. It returns the signature and nil, otherwise an error.
+ Generate(msg []byte, t *TSIG) ([]byte, error)
+ // Verify is passed the DNS message to be verified and the TSIG RR. If the signature is valid it will return nil, otherwise an error.
+ Verify(msg []byte, t *TSIG) error
+}
+
+type tsigHMACProvider string
+
+func (key tsigHMACProvider) Generate(msg []byte, t *TSIG) ([]byte, error) {
+ // If we barf here, the caller is to blame
+ rawsecret, err := fromBase64([]byte(key))
+ if err != nil {
+ return nil, err
+ }
+ var h hash.Hash
+ switch CanonicalName(t.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(msg)
+ return h.Sum(nil), nil
+}
+
+func (key tsigHMACProvider) Verify(msg []byte, t *TSIG) error {
+ b, err := key.Generate(msg, t)
+ if err != nil {
+ return err
+ }
+ mac, err := hex.DecodeString(t.MAC)
+ if err != nil {
+ return err
+ }
+ if !hmac.Equal(b, mac) {
+ return ErrSig
+ }
+ return nil
+}
+
// TSIG is the RR the holds the transaction signature of a message.
// See RFC 2845 and RFC 4635.
type TSIG struct {
@@ -54,8 +106,8 @@ func (rr *TSIG) String() string {
return s
}
-func (rr *TSIG) parse(c *zlexer, origin string) *ParseError {
- panic("dns: internal error: parse should never be called on TSIG")
+func (*TSIG) parse(c *zlexer, origin string) *ParseError {
+ return &ParseError{err: "TSIG records do not have a presentation format"}
}
// The following values must be put in wireformat, so that the MAC can be calculated.
@@ -96,14 +148,13 @@ type timerWireFmt struct {
// 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) {
+ return tsigGenerateProvider(m, tsigHMACProvider(secret), requestMAC, timersOnly)
+}
+
+func tsigGenerateProvider(m *Msg, provider TsigProvider, 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
@@ -111,32 +162,21 @@ func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, s
if err != nil {
return nil, "", err
}
- buf := tsigBuffer(mbuf, rr, requestMAC, timersOnly)
+ 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 HmacMD5:
- h = hmac.New(md5.New, rawsecret)
- case HmacSHA1:
- h = hmac.New(sha1.New, rawsecret)
- case HmacSHA256:
- h = hmac.New(sha256.New, rawsecret)
- case HmacSHA512:
- h = hmac.New(sha512.New, rawsecret)
- default:
- return nil, "", ErrKeyAlg
+ // Copy all TSIG fields except MAC and its size, which are filled using the computed digest.
+ *t = *rr
+ mac, err := provider.Generate(buf, rr)
+ if err != nil {
+ return nil, "", err
}
- h.Write(buf)
- t.MAC = hex.EncodeToString(h.Sum(nil))
+ t.MAC = hex.EncodeToString(mac)
t.MACSize = uint16(len(t.MAC) / 2) // Size is half!
- t.Hdr = RR_Header{Name: rr.Hdr.Name, Rrtype: TypeTSIG, Class: ClassANY, Ttl: 0}
- t.Fudge = rr.Fudge
- t.TimeSigned = rr.TimeSigned
- t.Algorithm = rr.Algorithm
- t.OrigId = m.Id
-
tbuf := make([]byte, Len(t))
off, err := PackRR(t, tbuf, 0, nil, false)
if err != nil {
@@ -153,26 +193,34 @@ func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, s
// If the signature does not validate err contains the
// error, otherwise it is nil.
func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error {
- rawsecret, err := fromBase64([]byte(secret))
- if err != nil {
- return err
- }
+ return tsigVerify(msg, tsigHMACProvider(secret), requestMAC, timersOnly, uint64(time.Now().Unix()))
+}
+
+func tsigVerifyProvider(msg []byte, provider TsigProvider, requestMAC string, timersOnly bool) error {
+ return tsigVerify(msg, provider, 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, provider TsigProvider, requestMAC string, timersOnly bool, now uint64) error {
// Strip the TSIG from the incoming msg
stripped, tsig, err := stripTsig(msg)
if err != nil {
return err
}
- msgMAC, err := hex.DecodeString(tsig.MAC)
+ buf, err := tsigBuffer(stripped, tsig, requestMAC, timersOnly)
if err != nil {
return err
}
- buf := tsigBuffer(stripped, tsig, requestMAC, timersOnly)
+ if err := provider.Verify(buf, tsig); err != nil {
+ return err
+ }
// Fudge factor works both ways. A message can arrive before it was signed because
// of clock skew.
- now := uint64(time.Now().Unix())
+ // 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
@@ -181,28 +229,11 @@ func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error {
return ErrTime
}
- var h hash.Hash
- switch CanonicalName(tsig.Algorithm) {
- case HmacMD5:
- h = hmac.New(md5.New, rawsecret)
- case HmacSHA1:
- h = hmac.New(sha1.New, rawsecret)
- case HmacSHA256:
- h = hmac.New(sha256.New, rawsecret)
- case HmacSHA512:
- h = hmac.New(sha512.New, rawsecret)
- default:
- return ErrKeyAlg
- }
- h.Write(buf)
- if !hmac.Equal(h.Sum(nil), msgMAC) {
- return ErrSig
- }
return nil
}
// Create a wiredata buffer for the MAC calculation.
-func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []byte {
+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())
@@ -219,7 +250,10 @@ func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []b
m.MACSize = uint16(len(requestMAC) / 2)
m.MAC = requestMAC
buf = make([]byte, len(requestMAC)) // long enough
- n, _ := packMacWire(m, buf)
+ n, err := packMacWire(m, buf)
+ if err != nil {
+ return nil, err
+ }
buf = buf[:n]
}
@@ -228,7 +262,10 @@ func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []b
tsig := new(timerWireFmt)
tsig.TimeSigned = rr.TimeSigned
tsig.Fudge = rr.Fudge
- n, _ := packTimerWire(tsig, tsigvar)
+ n, err := packTimerWire(tsig, tsigvar)
+ if err != nil {
+ return nil, err
+ }
tsigvar = tsigvar[:n]
} else {
tsig := new(tsigWireFmt)
@@ -241,7 +278,10 @@ func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []b
tsig.Error = rr.Error
tsig.OtherLen = rr.OtherLen
tsig.OtherData = rr.OtherData
- n, _ := packTsigWire(tsig, tsigvar)
+ n, err := packTsigWire(tsig, tsigvar)
+ if err != nil {
+ return nil, err
+ }
tsigvar = tsigvar[:n]
}
@@ -251,7 +291,7 @@ func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []b
} else {
buf = append(msgbuf, tsigvar...)
}
- return buf
+ return buf, nil
}
// Strip the TSIG from the raw message.
diff --git a/vendor/github.com/miekg/dns/types.go b/vendor/github.com/miekg/dns/types.go
index 7776b4f066..9e379eb351 100644
--- a/vendor/github.com/miekg/dns/types.go
+++ b/vendor/github.com/miekg/dns/types.go
@@ -81,6 +81,8 @@ const (
TypeCDNSKEY uint16 = 60
TypeOPENPGPKEY uint16 = 61
TypeCSYNC uint16 = 62
+ TypeSVCB uint16 = 64
+ TypeHTTPS uint16 = 65
TypeSPF uint16 = 99
TypeUINFO uint16 = 100
TypeUID uint16 = 101
@@ -243,8 +245,8 @@ type ANY struct {
func (rr *ANY) String() string { return rr.Hdr.String() }
-func (rr *ANY) parse(c *zlexer, origin string) *ParseError {
- panic("dns: internal error: parse should never be called on ANY")
+func (*ANY) parse(c *zlexer, origin string) *ParseError {
+ return &ParseError{err: "ANY records do not have a presentation format"}
}
// NULL RR. See RFC 1035.
@@ -258,8 +260,8 @@ func (rr *NULL) String() string {
return ";" + rr.Hdr.String() + rr.Data
}
-func (rr *NULL) parse(c *zlexer, origin string) *ParseError {
- panic("dns: internal error: parse should never be called on NULL")
+func (*NULL) parse(c *zlexer, origin string) *ParseError {
+ return &ParseError{err: "NULL records do not have a presentation format"}
}
// CNAME RR. See RFC 1034.
diff --git a/vendor/github.com/miekg/dns/version.go b/vendor/github.com/miekg/dns/version.go
index 7dd9bbc09e..8f7cf76881 100644
--- a/vendor/github.com/miekg/dns/version.go
+++ b/vendor/github.com/miekg/dns/version.go
@@ -3,7 +3,7 @@ package dns
import "fmt"
// Version is current version of this library.
-var Version = v{1, 1, 30}
+var Version = v{1, 1, 40}
// v holds the version of this library.
type v struct {
diff --git a/vendor/github.com/miekg/dns/zduplicate.go b/vendor/github.com/miekg/dns/zduplicate.go
index d7ec2d9743..0d3b34bd9b 100644
--- a/vendor/github.com/miekg/dns/zduplicate.go
+++ b/vendor/github.com/miekg/dns/zduplicate.go
@@ -402,6 +402,27 @@ func (r1 *HIP) isDuplicate(_r2 RR) bool {
return true
}
+func (r1 *HTTPS) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*HTTPS)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Priority != r2.Priority {
+ return false
+ }
+ if !isDuplicateName(r1.Target, r2.Target) {
+ return false
+ }
+ if len(r1.Value) != len(r2.Value) {
+ return false
+ }
+ if !areSVCBPairArraysEqual(r1.Value, r2.Value) {
+ return false
+ }
+ return true
+}
+
func (r1 *KEY) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*KEY)
if !ok {
@@ -1076,6 +1097,27 @@ func (r1 *SSHFP) isDuplicate(_r2 RR) bool {
return true
}
+func (r1 *SVCB) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*SVCB)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Priority != r2.Priority {
+ return false
+ }
+ if !isDuplicateName(r1.Target, r2.Target) {
+ return false
+ }
+ if len(r1.Value) != len(r2.Value) {
+ return false
+ }
+ if !areSVCBPairArraysEqual(r1.Value, r2.Value) {
+ return false
+ }
+ return true
+}
+
func (r1 *TA) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*TA)
if !ok {
diff --git a/vendor/github.com/miekg/dns/zmsg.go b/vendor/github.com/miekg/dns/zmsg.go
index 02a5dfa4a2..d24a10fa24 100644
--- a/vendor/github.com/miekg/dns/zmsg.go
+++ b/vendor/github.com/miekg/dns/zmsg.go
@@ -316,6 +316,22 @@ func (rr *HIP) pack(msg []byte, off int, compression compressionMap, compress bo
return off, nil
}
+func (rr *HTTPS) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint16(rr.Priority, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packDomainName(rr.Target, msg, off, compression, false)
+ if err != nil {
+ return off, err
+ }
+ off, err = packDataSVCB(rr.Value, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
func (rr *KEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.Flags, msg, off)
if err != nil {
@@ -906,6 +922,22 @@ func (rr *SSHFP) pack(msg []byte, off int, compression compressionMap, compress
return off, nil
}
+func (rr *SVCB) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint16(rr.Priority, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packDomainName(rr.Target, msg, off, compression, false)
+ if err != nil {
+ return off, err
+ }
+ off, err = packDataSVCB(rr.Value, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
func (rr *TA) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.KeyTag, msg, off)
if err != nil {
@@ -1559,6 +1591,31 @@ func (rr *HIP) unpack(msg []byte, off int) (off1 int, err error) {
return off, nil
}
+func (rr *HTTPS) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Priority, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Target, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Value, off, err = unpackDataSVCB(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
func (rr *KEY) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
@@ -2461,6 +2518,31 @@ func (rr *SSHFP) unpack(msg []byte, off int) (off1 int, err error) {
return off, nil
}
+func (rr *SVCB) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Priority, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Target, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Value, off, err = unpackDataSVCB(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
func (rr *TA) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
diff --git a/vendor/github.com/miekg/dns/ztypes.go b/vendor/github.com/miekg/dns/ztypes.go
index 5bb59fa601..11b51bf217 100644
--- a/vendor/github.com/miekg/dns/ztypes.go
+++ b/vendor/github.com/miekg/dns/ztypes.go
@@ -33,6 +33,7 @@ var TypeToRR = map[uint16]func() RR{
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) },
@@ -70,6 +71,7 @@ var TypeToRR = map[uint16]func() RR{
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) },
@@ -110,6 +112,7 @@ var TypeToString = map[uint16]string{
TypeGPOS: "GPOS",
TypeHINFO: "HINFO",
TypeHIP: "HIP",
+ TypeHTTPS: "HTTPS",
TypeISDN: "ISDN",
TypeIXFR: "IXFR",
TypeKEY: "KEY",
@@ -153,6 +156,7 @@ var TypeToString = map[uint16]string{
TypeSPF: "SPF",
TypeSRV: "SRV",
TypeSSHFP: "SSHFP",
+ TypeSVCB: "SVCB",
TypeTA: "TA",
TypeTALINK: "TALINK",
TypeTKEY: "TKEY",
@@ -191,6 +195,7 @@ 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 }
@@ -229,6 +234,7 @@ 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 }
@@ -592,6 +598,15 @@ func (rr *SSHFP) len(off int, compression map[string]struct{}) int {
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
@@ -753,6 +768,9 @@ func (rr *HIP) copy() RR {
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)}
}
@@ -879,6 +897,13 @@ func (rr *SRV) copy() RR {
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}
}