commit cf5c6d724d381a867a7ff5d82fb9432e26c395e8
parent dfdc473cefa255c5d0fb6c2e90e2b90815305c2f
Author: tobi <31960611+tsmethurst@users.noreply.github.com>
Date: Sat, 11 Jun 2022 11:09:31 +0200
[chore] Validate/set account domain (#619)
* add miekg/dns dependency
* set/validate accountDomain
Diffstat:
304 files changed, 34218 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
@@ -224,6 +224,7 @@ The following libraries and frameworks are used by GoToSocial, with gratitude
- [jackc/pgx](https://github.com/jackc/pgx); Postgres driver. [MIT License](https://spdx.org/licenses/MIT.html).
- [mcuadros/go-syslog](https://github.com/mcuadros/go-syslog); Syslog server library. [MIT License](https://spdx.org/licenses/MIT.html).
- [microcosm-cc/bluemonday](https://github.com/microcosm-cc/bluemonday); HTML user-input sanitization. [BSD-3-Clause License](https://spdx.org/licenses/BSD-3-Clause.html).
+- [miekg/dns](https://github.com/miekg/dns); DNS utilities. [Go License](https://go.dev/LICENSE).
- [mitchellh/mapstructure](https://github.com/mitchellh/mapstructure); Go interface => struct parsing. [MIT License](https://spdx.org/licenses/MIT.html).
- [modernc.org/sqlite](https://gitlab.com/cznic/sqlite); cgo-free port of SQLite. [Other License](https://gitlab.com/cznic/sqlite/-/blob/master/LICENSE).
- [modernc.org/ccgo](https://gitlab.com/cznic/ccgo); c99 AST -> Go translater. [BSD-3-Clause License](https://spdx.org/licenses/BSD-3-Clause.html).
diff --git a/go.mod b/go.mod
@@ -94,6 +94,7 @@ require (
github.com/leodido/go-urn v1.2.1 // indirect
github.com/magiconair/properties v1.8.6 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
+ github.com/miekg/dns v1.1.49 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
diff --git a/go.sum b/go.sum
@@ -391,6 +391,8 @@ github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
github.com/microcosm-cc/bluemonday v1.0.18 h1:6HcxvXDAi3ARt3slx6nTesbvorIc3QeTzBNRvWktHBo=
github.com/microcosm-cc/bluemonday v1.0.18/go.mod h1:Z0r70sCuXHig8YpBzCc5eGHAap2K7e/u082ZUpDRRqM=
+github.com/miekg/dns v1.1.49 h1:qe0mQU3Z/XpFeE+AEBo2rqaS1IPBJ3anmqZ4XiZJVG8=
+github.com/miekg/dns v1.1.49/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -551,6 +553,7 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
github.com/zeebo/blake3 v0.2.1/go.mod h1:TSQ0KjMH+pht+bRyvVooJ1rBpvvngSGaPISafq9MxJk=
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
@@ -622,6 +625,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -660,7 +664,9 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220524220425-1d687d428aca h1:xTaFYiPROfpPhqrfTIDXj0ri1SpfueYT951s4bAuDO8=
@@ -687,6 +693,7 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -732,8 +739,10 @@ golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -812,6 +821,7 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
+golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20=
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/internal/config/validate.go b/internal/config/validate.go
@@ -23,6 +23,7 @@ import (
"fmt"
"strings"
+ "github.com/miekg/dns"
"github.com/sirupsen/logrus"
)
@@ -31,10 +32,23 @@ func Validate() error {
errs := []error{}
// host
- if GetHost() == "" {
+ host := GetHost()
+ if host == "" {
errs = append(errs, fmt.Errorf("%s must be set", HostFlag()))
}
+ // accountDomain; only check if host was set, otherwise there's no point
+ if host != "" {
+ switch ad := GetAccountDomain(); ad {
+ case "":
+ SetAccountDomain(GetHost())
+ default:
+ if !dns.IsSubDomain(ad, host) {
+ errs = append(errs, fmt.Errorf("%s was %s and %s was %s, but %s is not a valid subdomain of %s", HostFlag(), host, AccountDomainFlag(), ad, host, ad))
+ }
+ }
+ }
+
// protocol
switch proto := GetProtocol(); proto {
case "https":
diff --git a/internal/config/validate_test.go b/internal/config/validate_test.go
@@ -46,6 +46,54 @@ func (suite *ConfigValidateTestSuite) TestValidateConfigNoHost() {
suite.EqualError(err, "host must be set")
}
+func (suite *ConfigValidateTestSuite) TestValidateAccountDomainOK1() {
+ testrig.InitTestConfig()
+
+ err := config.Validate()
+ suite.NoError(err)
+
+ suite.Equal(config.GetHost(), config.GetAccountDomain())
+}
+
+func (suite *ConfigValidateTestSuite) TestValidateAccountDomainOK2() {
+ testrig.InitTestConfig()
+
+ config.SetAccountDomain("localhost:8080")
+
+ err := config.Validate()
+ suite.NoError(err)
+}
+
+func (suite *ConfigValidateTestSuite) TestValidateAccountDomainOK3() {
+ testrig.InitTestConfig()
+
+ config.SetHost("gts.example.org")
+ config.SetAccountDomain("example.org")
+
+ err := config.Validate()
+ suite.NoError(err)
+}
+
+func (suite *ConfigValidateTestSuite) TestValidateAccountDomainNotSubdomain1() {
+ testrig.InitTestConfig()
+
+ config.SetHost("gts.example.org")
+ config.SetAccountDomain("example.com")
+
+ err := config.Validate()
+ suite.EqualError(err, "host was gts.example.org and account-domain was example.com, but gts.example.org is not a valid subdomain of example.com")
+}
+
+func (suite *ConfigValidateTestSuite) TestValidateAccountDomainNotSubdomain2() {
+ testrig.InitTestConfig()
+
+ config.SetHost("example.org")
+ config.SetAccountDomain("gts.example.org")
+
+ err := config.Validate()
+ suite.EqualError(err, "host was example.org and account-domain was gts.example.org, but example.org is not a valid subdomain of gts.example.org")
+}
+
func (suite *ConfigValidateTestSuite) TestValidateConfigNoProtocol() {
testrig.InitTestConfig()
diff --git a/vendor/github.com/miekg/dns/.codecov.yml b/vendor/github.com/miekg/dns/.codecov.yml
@@ -0,0 +1,8 @@
+coverage:
+ status:
+ project:
+ default:
+ target: 40%
+ threshold: null
+ patch: false
+ changes: false
diff --git a/vendor/github.com/miekg/dns/.gitignore b/vendor/github.com/miekg/dns/.gitignore
@@ -0,0 +1,4 @@
+*.6
+tags
+test.out
+a.out
diff --git a/vendor/github.com/miekg/dns/AUTHORS b/vendor/github.com/miekg/dns/AUTHORS
@@ -0,0 +1 @@
+Miek Gieben <miek@miek.nl>
diff --git a/vendor/github.com/miekg/dns/CODEOWNERS b/vendor/github.com/miekg/dns/CODEOWNERS
@@ -0,0 +1 @@
+* @miekg @tmthrgd
diff --git a/vendor/github.com/miekg/dns/CONTRIBUTORS b/vendor/github.com/miekg/dns/CONTRIBUTORS
@@ -0,0 +1,10 @@
+Alex A. Skinner
+Andrew Tunnell-Jones
+Ask Bjørn Hansen
+Dave Cheney
+Dusty Wilson
+Marek Majkowski
+Peter van Dijk
+Omri Bahumi
+Alex Sergeyev
+James Hartig
diff --git a/vendor/github.com/miekg/dns/COPYRIGHT b/vendor/github.com/miekg/dns/COPYRIGHT
@@ -0,0 +1,9 @@
+Copyright 2009 The Go Authors. All rights reserved. Use of this source code
+is governed by a BSD-style license that can be found in the LICENSE file.
+Extensions of the original work are copyright (c) 2011 Miek Gieben
+
+Copyright 2011 Miek Gieben. All rights reserved. Use of this source code is
+governed by a BSD-style license that can be found in the LICENSE file.
+
+Copyright 2014 CloudFlare. All rights reserved. Use of this source code is
+governed by a BSD-style license that can be found in the LICENSE file.
diff --git a/vendor/github.com/miekg/dns/LICENSE b/vendor/github.com/miekg/dns/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+As this is fork of the official Go code the same license applies.
+Extensions of the original work are copyright (c) 2011 Miek Gieben
diff --git a/vendor/github.com/miekg/dns/Makefile.fuzz b/vendor/github.com/miekg/dns/Makefile.fuzz
@@ -0,0 +1,33 @@
+# Makefile for fuzzing
+#
+# Use go-fuzz and needs the tools installed.
+# See https://blog.cloudflare.com/dns-parser-meet-go-fuzzer/
+#
+# Installing go-fuzz:
+# $ make -f Makefile.fuzz get
+# Installs:
+# * github.com/dvyukov/go-fuzz/go-fuzz
+# * get github.com/dvyukov/go-fuzz/go-fuzz-build
+
+all: build
+
+.PHONY: build
+build:
+ go-fuzz-build -tags fuzz github.com/miekg/dns
+
+.PHONY: build-newrr
+build-newrr:
+ go-fuzz-build -func FuzzNewRR -tags fuzz github.com/miekg/dns
+
+.PHONY: fuzz
+fuzz:
+ go-fuzz -bin=dns-fuzz.zip -workdir=fuzz
+
+.PHONY: get
+get:
+ go get github.com/dvyukov/go-fuzz/go-fuzz
+ go get github.com/dvyukov/go-fuzz/go-fuzz-build
+
+.PHONY: clean
+clean:
+ rm *-fuzz.zip
diff --git a/vendor/github.com/miekg/dns/Makefile.release b/vendor/github.com/miekg/dns/Makefile.release
@@ -0,0 +1,52 @@
+# Makefile for releasing.
+#
+# The release is controlled from version.go. The version found there is
+# used to tag the git repo, we're not building any artifacts so there is nothing
+# to upload to github.
+#
+# * Up the version in version.go
+# * Run: make -f Makefile.release release
+# * will *commit* your change with 'Release $VERSION'
+# * push to github
+#
+
+define GO
+//+build ignore
+
+package main
+
+import (
+ "fmt"
+
+ "github.com/miekg/dns"
+)
+
+func main() {
+ fmt.Println(dns.Version.String())
+}
+endef
+
+$(file > version_release.go,$(GO))
+VERSION:=$(shell go run version_release.go)
+TAG="v$(VERSION)"
+
+all:
+ @echo Use the \'release\' target to start a release $(VERSION)
+ rm -f version_release.go
+
+.PHONY: release
+release: commit push
+ @echo Released $(VERSION)
+ rm -f version_release.go
+
+.PHONY: commit
+commit:
+ @echo Committing release $(VERSION)
+ git commit -am"Release $(VERSION)"
+ git tag $(TAG)
+
+.PHONY: push
+push:
+ @echo Pushing release $(VERSION) to master
+ git push --tags
+ git push
diff --git a/vendor/github.com/miekg/dns/README.md b/vendor/github.com/miekg/dns/README.md
@@ -0,0 +1,186 @@
+[![Build Status](https://travis-ci.org/miekg/dns.svg?branch=master)](https://travis-ci.org/miekg/dns)
+[![Code Coverage](https://img.shields.io/codecov/c/github/miekg/dns/master.svg)](https://codecov.io/github/miekg/dns?branch=master)
+[![Go Report Card](https://goreportcard.com/badge/github.com/miekg/dns)](https://goreportcard.com/report/miekg/dns)
+[![](https://godoc.org/github.com/miekg/dns?status.svg)](https://godoc.org/github.com/miekg/dns)
+
+# Alternative (more granular) approach to a DNS library
+
+> Less is more.
+
+Complete and usable DNS library. All Resource Records are supported, including the DNSSEC types.
+It follows a lean and mean philosophy. If there is stuff you should know as a DNS programmer there
+isn't a convenience function for it. Server side and client side programming is supported, i.e. you
+can build servers and resolvers with it.
+
+We try to keep the "master" branch as sane as possible and at the bleeding edge of standards,
+avoiding breaking changes wherever reasonable. We support the last two versions of Go.
+
+# Goals
+
+* KISS;
+* Fast;
+* Small API. If it's easy to code in Go, don't make a function for it.
+
+# Users
+
+A not-so-up-to-date-list-that-may-be-actually-current:
+
+* https://github.com/coredns/coredns
+* https://github.com/abh/geodns
+* https://github.com/baidu/bfe
+* http://www.statdns.com/
+* http://www.dnsinspect.com/
+* https://github.com/chuangbo/jianbing-dictionary-dns
+* http://www.dns-lg.com/
+* https://github.com/fcambus/rrda
+* https://github.com/kenshinx/godns
+* https://github.com/skynetservices/skydns
+* https://github.com/hashicorp/consul
+* https://github.com/DevelopersPL/godnsagent
+* https://github.com/duedil-ltd/discodns
+* https://github.com/StalkR/dns-reverse-proxy
+* https://github.com/tianon/rawdns
+* https://mesosphere.github.io/mesos-dns/
+* https://github.com/fcambus/statzone
+* https://github.com/benschw/dns-clb-go
+* https://github.com/corny/dnscheck for <http://public-dns.info/>
+* https://github.com/miekg/unbound
+* https://github.com/miekg/exdns
+* https://dnslookup.org
+* https://github.com/looterz/grimd
+* https://github.com/phamhongviet/serf-dns
+* https://github.com/mehrdadrad/mylg
+* https://github.com/bamarni/dockness
+* https://github.com/fffaraz/microdns
+* https://github.com/ipdcode/hades <https://jd.com>
+* https://github.com/StackExchange/dnscontrol/
+* https://www.dnsperf.com/
+* https://dnssectest.net/
+* https://github.com/oif/apex
+* https://github.com/jedisct1/dnscrypt-proxy
+* https://github.com/jedisct1/rpdns
+* https://github.com/xor-gate/sshfp
+* https://github.com/rs/dnstrace
+* https://blitiri.com.ar/p/dnss ([github mirror](https://github.com/albertito/dnss))
+* https://render.com
+* https://github.com/peterzen/goresolver
+* https://github.com/folbricht/routedns
+* https://domainr.com/
+* https://zonedb.org/
+* https://router7.org/
+* https://github.com/fortio/dnsping
+* https://github.com/Luzilla/dnsbl_exporter
+* https://github.com/bodgit/tsig
+* https://github.com/v2fly/v2ray-core (test only)
+* https://kuma.io/
+* https://www.misaka.io/services/dns
+* https://ping.sx/dig
+* https://fleetdeck.io/
+* https://github.com/markdingo/autoreverse
+
+
+Send pull request if you want to be listed here.
+
+# Features
+
+* UDP/TCP queries, IPv4 and IPv6
+* RFC 1035 zone file parsing ($INCLUDE, $ORIGIN, $TTL and $GENERATE (for all record types) are supported
+* Fast
+* Server side programming (mimicking the net/http package)
+* Client side programming
+* DNSSEC: signing, validating and key generation for DSA, RSA, ECDSA and Ed25519
+* EDNS0, NSID, Cookies
+* AXFR/IXFR
+* TSIG, SIG(0)
+* DNS over TLS (DoT): encrypted connection between client and server over TCP
+* DNS name compression
+
+Have fun!
+
+Miek Gieben - 2010-2012 - <miek@miek.nl>
+DNS Authors 2012-
+
+# Building
+
+This library uses Go modules and uses semantic versioning. Building is done with the `go` tool, so
+the following should work:
+
+ go get github.com/miekg/dns
+ go build github.com/miekg/dns
+
+## Examples
+
+A short "how to use the API" is at the beginning of doc.go (this also will show when you call `godoc
+github.com/miekg/dns`).
+
+Example programs can be found in the `github.com/miekg/exdns` repository.
+
+## Supported RFCs
+
+*all of them*
+
+* 103{4,5} - DNS standard
+* 1348 - NSAP record (removed the record)
+* 1982 - Serial Arithmetic
+* 1876 - LOC record
+* 1995 - IXFR
+* 1996 - DNS notify
+* 2136 - DNS Update (dynamic updates)
+* 2181 - RRset definition - there is no RRset type though, just []RR
+* 2537 - RSAMD5 DNS keys
+* 2065 - DNSSEC (updated in later RFCs)
+* 2671 - EDNS record
+* 2782 - SRV record
+* 2845 - TSIG record
+* 2915 - NAPTR record
+* 2929 - DNS IANA Considerations
+* 3110 - RSASHA1 DNS keys
+* 3123 - APL record
+* 3225 - DO bit (DNSSEC OK)
+* 340{1,2,3} - NAPTR record
+* 3445 - Limiting the scope of (DNS)KEY
+* 3597 - Unknown RRs
+* 403{3,4,5} - DNSSEC + validation functions
+* 4255 - SSHFP record
+* 4343 - Case insensitivity
+* 4408 - SPF record
+* 4509 - SHA256 Hash in DS
+* 4592 - Wildcards in the DNS
+* 4635 - HMAC SHA TSIG
+* 4701 - DHCID
+* 4892 - id.server
+* 5001 - NSID
+* 5155 - NSEC3 record
+* 5205 - HIP record
+* 5702 - SHA2 in the DNS
+* 5936 - AXFR
+* 5966 - TCP implementation recommendations
+* 6605 - ECDSA
+* 6725 - IANA Registry Update
+* 6742 - ILNP DNS
+* 6840 - Clarifications and Implementation Notes for DNS Security
+* 6844 - CAA record
+* 6891 - EDNS0 update
+* 6895 - DNS IANA considerations
+* 6944 - DNSSEC DNSKEY Algorithm Status
+* 6975 - Algorithm Understanding in DNSSEC
+* 7043 - EUI48/EUI64 records
+* 7314 - DNS (EDNS) EXPIRE Option
+* 7477 - CSYNC RR
+* 7828 - edns-tcp-keepalive EDNS0 Option
+* 7553 - URI record
+* 7858 - DNS over TLS: Initiation and Performance Considerations
+* 7871 - EDNS0 Client Subnet
+* 7873 - Domain Name System (DNS) Cookies
+* 8080 - EdDSA for DNSSEC
+* 8499 - DNS Terminology
+* 8659 - DNS Certification Authority Authorization (CAA) Resource Record
+* 8914 - Extended DNS Errors
+* 8976 - Message Digest for DNS Zones (ZONEMD RR)
+
+## Loosely Based Upon
+
+* ldns - <https://nlnetlabs.nl/projects/ldns/about/>
+* NSD - <https://nlnetlabs.nl/projects/nsd/about/>
+* Net::DNS - <http://www.net-dns.org/>
+* GRONG - <https://github.com/bortzmeyer/grong>
diff --git a/vendor/github.com/miekg/dns/acceptfunc.go b/vendor/github.com/miekg/dns/acceptfunc.go
@@ -0,0 +1,62 @@
+package dns
+
+// MsgAcceptFunc is used early in the server code to accept or reject a message with RcodeFormatError.
+// It returns a MsgAcceptAction to indicate what should happen with the message.
+type MsgAcceptFunc func(dh Header) MsgAcceptAction
+
+// DefaultMsgAcceptFunc checks the request and will reject if:
+//
+// * isn't a request (don't respond in that case)
+//
+// * opcode isn't OpcodeQuery or OpcodeNotify
+//
+// * Zero bit isn't zero
+//
+// * does not have exactly 1 question in the question section
+//
+// * has more than 1 RR in the Answer section
+//
+// * has more than 0 RRs in the Authority section
+//
+// * has more than 2 RRs in the Additional section
+//
+var DefaultMsgAcceptFunc MsgAcceptFunc = defaultMsgAcceptFunc
+
+// MsgAcceptAction represents the action to be taken.
+type MsgAcceptAction int
+
+// Allowed returned values from a MsgAcceptFunc.
+const (
+ MsgAccept MsgAcceptAction = iota // Accept the message
+ MsgReject // Reject the message with a RcodeFormatError
+ MsgIgnore // Ignore the error and send nothing back.
+ MsgRejectNotImplemented // Reject the message with a RcodeNotImplemented
+)
+
+func defaultMsgAcceptFunc(dh Header) MsgAcceptAction {
+ if isResponse := dh.Bits&_QR != 0; isResponse {
+ return MsgIgnore
+ }
+
+ // Don't allow dynamic updates, because then the sections can contain a whole bunch of RRs.
+ opcode := int(dh.Bits>>11) & 0xF
+ if opcode != OpcodeQuery && opcode != OpcodeNotify {
+ return MsgRejectNotImplemented
+ }
+
+ if dh.Qdcount != 1 {
+ return MsgReject
+ }
+ // NOTIFY requests can have a SOA in the ANSWER section. See RFC 1996 Section 3.7 and 3.11.
+ if dh.Ancount > 1 {
+ return MsgReject
+ }
+ // IXFR request could have one SOA RR in the NS section. See RFC 1995, section 3.
+ if dh.Nscount > 1 {
+ return MsgReject
+ }
+ if dh.Arcount > 2 {
+ return MsgReject
+ }
+ return MsgAccept
+}
diff --git a/vendor/github.com/miekg/dns/client.go b/vendor/github.com/miekg/dns/client.go
@@ -0,0 +1,484 @@
+package dns
+
+// A client implementation.
+
+import (
+ "context"
+ "crypto/tls"
+ "encoding/binary"
+ "fmt"
+ "io"
+ "net"
+ "strings"
+ "time"
+)
+
+const (
+ dnsTimeout time.Duration = 2 * time.Second
+ tcpIdleTimeout time.Duration = 8 * time.Second
+)
+
+func isPacketConn(c net.Conn) bool {
+ if _, ok := c.(net.PacketConn); !ok {
+ return false
+ }
+
+ if ua, ok := c.LocalAddr().(*net.UnixAddr); ok {
+ return ua.Net == "unixgram"
+ }
+
+ return true
+}
+
+// A Conn represents a connection to a DNS server.
+type Conn struct {
+ net.Conn // a net.Conn holding the connection
+ UDPSize uint16 // minimum receive buffer for UDP messages
+ TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2)
+ TsigProvider TsigProvider // An implementation of the TsigProvider interface. If defined it replaces TsigSecret and is used for all TSIG operations.
+ tsigRequestMAC string
+}
+
+func (co *Conn) tsigProvider() TsigProvider {
+ if co.TsigProvider != nil {
+ return co.TsigProvider
+ }
+ // tsigSecretProvider will return ErrSecret if co.TsigSecret is nil.
+ return tsigSecretProvider(co.TsigSecret)
+}
+
+// A Client defines parameters for a DNS client.
+type Client struct {
+ Net string // if "tcp" or "tcp-tls" (DNS over TLS) a TCP query will be initiated, otherwise an UDP one (default is "" for UDP)
+ UDPSize uint16 // minimum receive buffer for UDP messages
+ TLSConfig *tls.Config // TLS connection configuration
+ Dialer *net.Dialer // a net.Dialer used to set local address, timeouts and more
+ // Timeout is a cumulative timeout for dial, write and read, defaults to 0 (disabled) - overrides DialTimeout, ReadTimeout,
+ // WriteTimeout when non-zero. Can be overridden with net.Dialer.Timeout (see Client.ExchangeWithDialer and
+ // Client.Dialer) or context.Context.Deadline (see ExchangeContext)
+ Timeout time.Duration
+ DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds, or net.Dialer.Timeout if expiring earlier - overridden by Timeout when that value is non-zero
+ ReadTimeout time.Duration // net.Conn.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
+}
+
+// Exchange performs a synchronous UDP query. It sends the message m to the address
+// contained in a and waits for a reply. Exchange does not retry a failed query, nor
+// will it fall back to TCP in case of truncation.
+// See client.Exchange for more information on setting larger buffer sizes.
+func Exchange(m *Msg, a string) (r *Msg, err error) {
+ client := Client{Net: "udp"}
+ r, _, err = client.Exchange(m, a)
+ return r, err
+}
+
+func (c *Client) dialTimeout() time.Duration {
+ if c.Timeout != 0 {
+ return c.Timeout
+ }
+ if c.DialTimeout != 0 {
+ return c.DialTimeout
+ }
+ return dnsTimeout
+}
+
+func (c *Client) readTimeout() time.Duration {
+ if c.ReadTimeout != 0 {
+ return c.ReadTimeout
+ }
+ return dnsTimeout
+}
+
+func (c *Client) writeTimeout() time.Duration {
+ if c.WriteTimeout != 0 {
+ return c.WriteTimeout
+ }
+ return dnsTimeout
+}
+
+// Dial connects to the address on the named network.
+func (c *Client) Dial(address string) (conn *Conn, err error) {
+ return c.DialContext(context.Background(), address)
+}
+
+// DialContext connects to the address on the named network, with a context.Context.
+// For TLS over TCP (DoT) the context isn't used yet. This will be enabled when Go 1.18 is released.
+func (c *Client) DialContext(ctx context.Context, address string) (conn *Conn, err error) {
+ // create a new dialer with the appropriate timeout
+ var d net.Dialer
+ if c.Dialer == nil {
+ d = net.Dialer{Timeout: c.getTimeoutForRequest(c.dialTimeout())}
+ } else {
+ d = *c.Dialer
+ }
+
+ network := c.Net
+ if network == "" {
+ network = "udp"
+ }
+
+ useTLS := strings.HasPrefix(network, "tcp") && strings.HasSuffix(network, "-tls")
+
+ conn = new(Conn)
+ if useTLS {
+ network = strings.TrimSuffix(network, "-tls")
+
+ // TODO(miekg): Enable after Go 1.18 is released, to be able to support two prev. releases.
+ /*
+ tlsDialer := tls.Dialer{
+ NetDialer: &d,
+ Config: c.TLSConfig,
+ }
+ conn.Conn, err = tlsDialer.DialContext(ctx, network, address)
+ */
+ conn.Conn, err = tls.DialWithDialer(&d, network, address, c.TLSConfig)
+ } else {
+ conn.Conn, err = d.DialContext(ctx, network, address)
+ }
+ if err != nil {
+ return nil, err
+ }
+ conn.UDPSize = c.UDPSize
+ return conn, nil
+}
+
+// Exchange performs a synchronous query. It sends the message m to the address
+// contained in a and waits for a reply. Basic use pattern with a *dns.Client:
+//
+// c := new(dns.Client)
+// in, rtt, err := c.Exchange(message, "127.0.0.1:53")
+//
+// Exchange does not retry a failed query, nor will it fall back to TCP in
+// case of truncation.
+// It is up to the caller to create a message that allows for larger responses to be
+// returned. Specifically this means adding an EDNS0 OPT RR that will advertise a larger
+// buffer, see SetEdns0. Messages without an OPT RR will fallback to the historic limit
+// of 512 bytes
+// To specify a local address or a timeout, the caller has to set the `Client.Dialer`
+// attribute appropriately
+func (c *Client) Exchange(m *Msg, address string) (r *Msg, rtt time.Duration, err error) {
+ co, err := c.Dial(address)
+
+ if err != nil {
+ return nil, 0, err
+ }
+ defer co.Close()
+ return c.ExchangeWithConn(m, co)
+}
+
+// ExchangeWithConn has the same behavior as Exchange, just with a predetermined connection
+// that will be used instead of creating a new one.
+// Usage pattern with a *dns.Client:
+//
+// c := new(dns.Client)
+// // connection management logic goes here
+//
+// conn := c.Dial(address)
+// in, rtt, err := c.ExchangeWithConn(message, conn)
+//
+// This allows users of the library to implement their own connection management,
+// as opposed to Exchange, which will always use new connections and incur the added overhead
+// that entails when using "tcp" and especially "tcp-tls" clients.
+//
+// When the singleflight is set for this client the context is _not_ forwarded to the (shared) exchange, to
+// prevent one cancelation from canceling all outstanding requests.
+func (c *Client) ExchangeWithConn(m *Msg, conn *Conn) (r *Msg, rtt time.Duration, err error) {
+ return c.exchangeWithConnContext(context.Background(), m, conn)
+}
+
+func (c *Client) exchangeWithConnContext(ctx context.Context, m *Msg, conn *Conn) (r *Msg, rtt time.Duration, err error) {
+ if !c.SingleInflight {
+ return c.exchangeContext(ctx, m, conn)
+ }
+
+ q := m.Question[0]
+ key := fmt.Sprintf("%s:%d:%d", q.Name, q.Qtype, q.Qclass)
+ r, rtt, err, shared := c.group.Do(key, func() (*Msg, time.Duration, error) {
+ // When we're doing singleflight we don't want one context cancelation, cancel _all_ outstanding queries.
+ // Hence we ignore the context and use Background().
+ return c.exchangeContext(context.Background(), m, conn)
+ })
+ if r != nil && shared {
+ r = r.Copy()
+ }
+
+ return r, rtt, err
+}
+
+func (c *Client) exchangeContext(ctx context.Context, m *Msg, co *Conn) (r *Msg, rtt time.Duration, err error) {
+ opt := m.IsEdns0()
+ // If EDNS0 is used use that for size.
+ if opt != nil && opt.UDPSize() >= MinMsgSize {
+ co.UDPSize = opt.UDPSize()
+ }
+ // Otherwise use the client's configured UDP size.
+ if opt == nil && c.UDPSize >= MinMsgSize {
+ co.UDPSize = c.UDPSize
+ }
+
+ // write with the appropriate write timeout
+ t := time.Now()
+ writeDeadline := t.Add(c.getTimeoutForRequest(c.writeTimeout()))
+ readDeadline := t.Add(c.getTimeoutForRequest(c.readTimeout()))
+ if deadline, ok := ctx.Deadline(); ok {
+ if deadline.Before(writeDeadline) {
+ writeDeadline = deadline
+ }
+ if deadline.Before(readDeadline) {
+ readDeadline = deadline
+ }
+ }
+ co.SetWriteDeadline(writeDeadline)
+ co.SetReadDeadline(readDeadline)
+
+ co.TsigSecret, co.TsigProvider = c.TsigSecret, c.TsigProvider
+
+ if err = co.WriteMsg(m); err != nil {
+ return nil, 0, err
+ }
+
+ if isPacketConn(co.Conn) {
+ for {
+ r, err = co.ReadMsg()
+ // Ignore replies with mismatched IDs because they might be
+ // responses to earlier queries that timed out.
+ if err != nil || r.Id == m.Id {
+ break
+ }
+ }
+ } else {
+ r, err = co.ReadMsg()
+ if err == nil && r.Id != m.Id {
+ err = ErrId
+ }
+ }
+ rtt = time.Since(t)
+ return r, rtt, err
+}
+
+// ReadMsg reads a message from the connection co.
+// If the received message contains a TSIG record the transaction signature
+// is verified. This method always tries to return the message, however if an
+// error is returned there are no guarantees that the returned message is a
+// valid representation of the packet read.
+func (co *Conn) ReadMsg() (*Msg, error) {
+ p, err := co.ReadMsgHeader(nil)
+ if err != nil {
+ return nil, err
+ }
+
+ m := new(Msg)
+ if err := m.Unpack(p); err != nil {
+ // If an error was returned, we still want to allow the user to use
+ // the message, but naively they can just check err if they don't want
+ // to use an erroneous message
+ return m, err
+ }
+ if t := m.IsTsig(); t != nil {
+ // Need to work on the original message p, as that was used to calculate the tsig.
+ err = tsigVerifyProvider(p, co.tsigProvider(), co.tsigRequestMAC, false)
+ }
+ return m, err
+}
+
+// ReadMsgHeader reads a DNS message, parses and populates hdr (when hdr is not nil).
+// Returns message as a byte slice to be parsed with Msg.Unpack later on.
+// Note that error handling on the message body is not possible as only the header is parsed.
+func (co *Conn) ReadMsgHeader(hdr *Header) ([]byte, error) {
+ var (
+ p []byte
+ n int
+ err error
+ )
+
+ if isPacketConn(co.Conn) {
+ if co.UDPSize > MinMsgSize {
+ p = make([]byte, co.UDPSize)
+ } else {
+ p = make([]byte, MinMsgSize)
+ }
+ n, err = co.Read(p)
+ } else {
+ var length uint16
+ if err := binary.Read(co.Conn, binary.BigEndian, &length); err != nil {
+ return nil, err
+ }
+
+ p = make([]byte, length)
+ n, err = io.ReadFull(co.Conn, p)
+ }
+
+ if err != nil {
+ return nil, err
+ } else if n < headerSize {
+ return nil, ErrShortRead
+ }
+
+ p = p[:n]
+ if hdr != nil {
+ dh, _, err := unpackMsgHdr(p, 0)
+ if err != nil {
+ return nil, err
+ }
+ *hdr = dh
+ }
+ return p, err
+}
+
+// Read implements the net.Conn read method.
+func (co *Conn) Read(p []byte) (n int, err error) {
+ if co.Conn == nil {
+ return 0, ErrConnEmpty
+ }
+
+ if isPacketConn(co.Conn) {
+ // UDP connection
+ return co.Conn.Read(p)
+ }
+
+ var length uint16
+ if err := binary.Read(co.Conn, binary.BigEndian, &length); err != nil {
+ return 0, err
+ }
+ if int(length) > len(p) {
+ return 0, io.ErrShortBuffer
+ }
+
+ return io.ReadFull(co.Conn, p[:length])
+}
+
+// WriteMsg sends a message through the connection co.
+// If the message m contains a TSIG record the transaction
+// signature is calculated.
+func (co *Conn) WriteMsg(m *Msg) (err error) {
+ var out []byte
+ if t := m.IsTsig(); t != nil {
+ // Set tsigRequestMAC for the next read, although only used in zone transfers.
+ out, co.tsigRequestMAC, err = tsigGenerateProvider(m, co.tsigProvider(), co.tsigRequestMAC, false)
+ } else {
+ out, err = m.Pack()
+ }
+ if err != nil {
+ return err
+ }
+ _, err = co.Write(out)
+ return err
+}
+
+// Write implements the net.Conn Write method.
+func (co *Conn) Write(p []byte) (int, error) {
+ if len(p) > MaxMsgSize {
+ return 0, &Error{err: "message too large"}
+ }
+
+ if isPacketConn(co.Conn) {
+ return co.Conn.Write(p)
+ }
+
+ msg := make([]byte, 2+len(p))
+ binary.BigEndian.PutUint16(msg, uint16(len(p)))
+ copy(msg[2:], p)
+ return co.Conn.Write(msg)
+}
+
+// Return the appropriate timeout for a specific request
+func (c *Client) getTimeoutForRequest(timeout time.Duration) time.Duration {
+ var requestTimeout time.Duration
+ if c.Timeout != 0 {
+ requestTimeout = c.Timeout
+ } else {
+ requestTimeout = timeout
+ }
+ // net.Dialer.Timeout has priority if smaller than the timeouts computed so
+ // far
+ if c.Dialer != nil && c.Dialer.Timeout != 0 {
+ if c.Dialer.Timeout < requestTimeout {
+ requestTimeout = c.Dialer.Timeout
+ }
+ }
+ return requestTimeout
+}
+
+// Dial connects to the address on the named network.
+func Dial(network, address string) (conn *Conn, err error) {
+ conn = new(Conn)
+ conn.Conn, err = net.Dial(network, address)
+ if err != nil {
+ return nil, err
+ }
+ return conn, nil
+}
+
+// ExchangeContext performs a synchronous UDP query, like Exchange. It
+// additionally obeys deadlines from the passed Context.
+func ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, err error) {
+ client := Client{Net: "udp"}
+ r, _, err = client.ExchangeContext(ctx, m, a)
+ // ignoring rtt to leave the original ExchangeContext API unchanged, but
+ // this function will go away
+ return r, err
+}
+
+// ExchangeConn performs a synchronous query. It sends the message m via the connection
+// c and waits for a reply. The connection c is not closed by ExchangeConn.
+// Deprecated: This function is going away, but can easily be mimicked:
+//
+// co := &dns.Conn{Conn: c} // c is your net.Conn
+// co.WriteMsg(m)
+// in, _ := co.ReadMsg()
+// co.Close()
+//
+func ExchangeConn(c net.Conn, m *Msg) (r *Msg, err error) {
+ println("dns: ExchangeConn: this function is deprecated")
+ co := new(Conn)
+ co.Conn = c
+ if err = co.WriteMsg(m); err != nil {
+ return nil, err
+ }
+ r, err = co.ReadMsg()
+ if err == nil && r.Id != m.Id {
+ err = ErrId
+ }
+ return r, err
+}
+
+// DialTimeout acts like Dial but takes a timeout.
+func DialTimeout(network, address string, timeout time.Duration) (conn *Conn, err error) {
+ client := Client{Net: network, Dialer: &net.Dialer{Timeout: timeout}}
+ return client.Dial(address)
+}
+
+// DialWithTLS connects to the address on the named network with TLS.
+func DialWithTLS(network, address string, tlsConfig *tls.Config) (conn *Conn, err error) {
+ if !strings.HasSuffix(network, "-tls") {
+ network += "-tls"
+ }
+ client := Client{Net: network, TLSConfig: tlsConfig}
+ return client.Dial(address)
+}
+
+// DialTimeoutWithTLS acts like DialWithTLS but takes a timeout.
+func DialTimeoutWithTLS(network, address string, tlsConfig *tls.Config, timeout time.Duration) (conn *Conn, err error) {
+ if !strings.HasSuffix(network, "-tls") {
+ network += "-tls"
+ }
+ client := Client{Net: network, Dialer: &net.Dialer{Timeout: timeout}, TLSConfig: tlsConfig}
+ return client.Dial(address)
+}
+
+// ExchangeContext acts like Exchange, but honors the deadline on the provided
+// context, if present. If there is both a context deadline and a configured
+// timeout on the client, the earliest of the two takes effect.
+func (c *Client) ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
+ conn, err := c.DialContext(ctx, a)
+ if err != nil {
+ return nil, 0, err
+ }
+ defer conn.Close()
+
+ return c.exchangeWithConnContext(ctx, m, conn)
+}
diff --git a/vendor/github.com/miekg/dns/clientconfig.go b/vendor/github.com/miekg/dns/clientconfig.go
@@ -0,0 +1,135 @@
+package dns
+
+import (
+ "bufio"
+ "io"
+ "os"
+ "strconv"
+ "strings"
+)
+
+// ClientConfig wraps the contents of the /etc/resolv.conf file.
+type ClientConfig struct {
+ Servers []string // servers to use
+ Search []string // suffixes to append to local name
+ Port string // what port to use
+ Ndots int // number of dots in name to trigger absolute lookup
+ Timeout int // seconds before giving up on packet
+ Attempts int // lost packets before giving up on server, not used in the package dns
+}
+
+// ClientConfigFromFile parses a resolv.conf(5) like file and returns
+// a *ClientConfig.
+func ClientConfigFromFile(resolvconf string) (*ClientConfig, error) {
+ file, err := os.Open(resolvconf)
+ if err != nil {
+ return nil, err
+ }
+ defer file.Close()
+ return ClientConfigFromReader(file)
+}
+
+// ClientConfigFromReader works like ClientConfigFromFile but takes an io.Reader as argument
+func ClientConfigFromReader(resolvconf io.Reader) (*ClientConfig, error) {
+ c := new(ClientConfig)
+ scanner := bufio.NewScanner(resolvconf)
+ c.Servers = make([]string, 0)
+ c.Search = make([]string, 0)
+ c.Port = "53"
+ c.Ndots = 1
+ c.Timeout = 5
+ c.Attempts = 2
+
+ for scanner.Scan() {
+ if err := scanner.Err(); err != nil {
+ return nil, err
+ }
+ line := scanner.Text()
+ f := strings.Fields(line)
+ if len(f) < 1 {
+ continue
+ }
+ switch f[0] {
+ case "nameserver": // add one name server
+ if len(f) > 1 {
+ // One more check: make sure server name is
+ // just an IP address. Otherwise we need DNS
+ // to look it up.
+ name := f[1]
+ c.Servers = append(c.Servers, name)
+ }
+
+ case "domain": // set search path to just this domain
+ if len(f) > 1 {
+ c.Search = make([]string, 1)
+ c.Search[0] = f[1]
+ } else {
+ c.Search = make([]string, 0)
+ }
+
+ case "search": // set search path to given servers
+ c.Search = append([]string(nil), f[1:]...)
+
+ case "options": // magic options
+ for _, s := range f[1:] {
+ switch {
+ case len(s) >= 6 && s[:6] == "ndots:":
+ n, _ := strconv.Atoi(s[6:])
+ if n < 0 {
+ n = 0
+ } else if n > 15 {
+ n = 15
+ }
+ c.Ndots = n
+ case len(s) >= 8 && s[:8] == "timeout:":
+ n, _ := strconv.Atoi(s[8:])
+ if n < 1 {
+ n = 1
+ }
+ c.Timeout = n
+ case len(s) >= 9 && s[:9] == "attempts:":
+ n, _ := strconv.Atoi(s[9:])
+ if n < 1 {
+ n = 1
+ }
+ c.Attempts = n
+ case s == "rotate":
+ /* not imp */
+ }
+ }
+ }
+ }
+ return c, nil
+}
+
+// NameList returns all of the names that should be queried based on the
+// config. It is based off of go's net/dns name building, but it does not
+// check the length of the resulting names.
+func (c *ClientConfig) NameList(name string) []string {
+ // if this domain is already fully qualified, no append needed.
+ if IsFqdn(name) {
+ return []string{name}
+ }
+
+ // Check to see if the name has more labels than Ndots. Do this before making
+ // the domain fully qualified.
+ hasNdots := CountLabel(name) > c.Ndots
+ // Make the domain fully qualified.
+ name = Fqdn(name)
+
+ // Make a list of names based off search.
+ names := []string{}
+
+ // If name has enough dots, try that first.
+ if hasNdots {
+ names = append(names, name)
+ }
+ for _, s := range c.Search {
+ names = append(names, Fqdn(name+s))
+ }
+ // If we didn't have enough dots, try after suffixes.
+ if !hasNdots {
+ names = append(names, name)
+ }
+ return names
+}
diff --git a/vendor/github.com/miekg/dns/dane.go b/vendor/github.com/miekg/dns/dane.go
@@ -0,0 +1,43 @@
+package dns
+
+import (
+ "crypto/sha256"
+ "crypto/sha512"
+ "crypto/x509"
+ "encoding/hex"
+ "errors"
+)
+
+// CertificateToDANE converts a certificate to a hex string as used in the TLSA or SMIMEA records.
+func CertificateToDANE(selector, matchingType uint8, cert *x509.Certificate) (string, error) {
+ switch matchingType {
+ case 0:
+ switch selector {
+ case 0:
+ return hex.EncodeToString(cert.Raw), nil
+ case 1:
+ return hex.EncodeToString(cert.RawSubjectPublicKeyInfo), nil
+ }
+ case 1:
+ h := sha256.New()
+ switch selector {
+ case 0:
+ h.Write(cert.Raw)
+ return hex.EncodeToString(h.Sum(nil)), nil
+ case 1:
+ h.Write(cert.RawSubjectPublicKeyInfo)
+ return hex.EncodeToString(h.Sum(nil)), nil
+ }
+ case 2:
+ h := sha512.New()
+ switch selector {
+ case 0:
+ h.Write(cert.Raw)
+ return hex.EncodeToString(h.Sum(nil)), nil
+ case 1:
+ h.Write(cert.RawSubjectPublicKeyInfo)
+ return hex.EncodeToString(h.Sum(nil)), nil
+ }
+ }
+ return "", errors.New("dns: bad MatchingType or Selector")
+}
diff --git a/vendor/github.com/miekg/dns/defaults.go b/vendor/github.com/miekg/dns/defaults.go
@@ -0,0 +1,381 @@
+package dns
+
+import (
+ "errors"
+ "net"
+ "strconv"
+ "strings"
+)
+
+const hexDigit = "0123456789abcdef"
+
+// Everything is assumed in ClassINET.
+
+// SetReply creates a reply message from a request message.
+func (dns *Msg) SetReply(request *Msg) *Msg {
+ dns.Id = request.Id
+ dns.Response = true
+ dns.Opcode = request.Opcode
+ if dns.Opcode == OpcodeQuery {
+ dns.RecursionDesired = request.RecursionDesired // Copy rd bit
+ dns.CheckingDisabled = request.CheckingDisabled // Copy cd bit
+ }
+ dns.Rcode = RcodeSuccess
+ if len(request.Question) > 0 {
+ dns.Question = make([]Question, 1)
+ dns.Question[0] = request.Question[0]
+ }
+ return dns
+}
+
+// SetQuestion creates a question message, it sets the Question
+// section, generates an Id and sets the RecursionDesired (RD)
+// bit to true.
+func (dns *Msg) SetQuestion(z string, t uint16) *Msg {
+ dns.Id = Id()
+ dns.RecursionDesired = true
+ dns.Question = make([]Question, 1)
+ dns.Question[0] = Question{z, t, ClassINET}
+ return dns
+}
+
+// SetNotify creates a notify message, it sets the Question
+// section, generates an Id and sets the Authoritative (AA)
+// bit to true.
+func (dns *Msg) SetNotify(z string) *Msg {
+ dns.Opcode = OpcodeNotify
+ dns.Authoritative = true
+ dns.Id = Id()
+ dns.Question = make([]Question, 1)
+ dns.Question[0] = Question{z, TypeSOA, ClassINET}
+ return dns
+}
+
+// SetRcode creates an error message suitable for the request.
+func (dns *Msg) SetRcode(request *Msg, rcode int) *Msg {
+ dns.SetReply(request)
+ dns.Rcode = rcode
+ return dns
+}
+
+// SetRcodeFormatError creates a message with FormError set.
+func (dns *Msg) SetRcodeFormatError(request *Msg) *Msg {
+ dns.Rcode = RcodeFormatError
+ dns.Opcode = OpcodeQuery
+ dns.Response = true
+ dns.Authoritative = false
+ dns.Id = request.Id
+ return dns
+}
+
+// SetUpdate makes the message a dynamic update message. It
+// sets the ZONE section to: z, TypeSOA, ClassINET.
+func (dns *Msg) SetUpdate(z string) *Msg {
+ dns.Id = Id()
+ dns.Response = false
+ dns.Opcode = OpcodeUpdate
+ dns.Compress = false // BIND9 cannot handle compression
+ dns.Question = make([]Question, 1)
+ dns.Question[0] = Question{z, TypeSOA, ClassINET}
+ return dns
+}
+
+// SetIxfr creates message for requesting an IXFR.
+func (dns *Msg) SetIxfr(z string, serial uint32, ns, mbox string) *Msg {
+ dns.Id = Id()
+ dns.Question = make([]Question, 1)
+ dns.Ns = make([]RR, 1)
+ s := new(SOA)
+ s.Hdr = RR_Header{z, TypeSOA, ClassINET, defaultTtl, 0}
+ s.Serial = serial
+ s.Ns = ns
+ s.Mbox = mbox
+ dns.Question[0] = Question{z, TypeIXFR, ClassINET}
+ dns.Ns[0] = s
+ return dns
+}
+
+// SetAxfr creates message for requesting an AXFR.
+func (dns *Msg) SetAxfr(z string) *Msg {
+ dns.Id = Id()
+ dns.Question = make([]Question, 1)
+ dns.Question[0] = Question{z, TypeAXFR, ClassINET}
+ return dns
+}
+
+// SetTsig appends a TSIG RR to the message.
+// This is only a skeleton TSIG RR that is added as the last RR in the
+// additional section. The TSIG is calculated when the message is being send.
+func (dns *Msg) SetTsig(z, algo string, fudge uint16, timesigned int64) *Msg {
+ t := new(TSIG)
+ t.Hdr = RR_Header{z, TypeTSIG, ClassANY, 0, 0}
+ t.Algorithm = algo
+ t.Fudge = fudge
+ t.TimeSigned = uint64(timesigned)
+ t.OrigId = dns.Id
+ dns.Extra = append(dns.Extra, t)
+ return dns
+}
+
+// SetEdns0 appends a EDNS0 OPT RR to the message.
+// TSIG should always the last RR in a message.
+func (dns *Msg) SetEdns0(udpsize uint16, do bool) *Msg {
+ e := new(OPT)
+ e.Hdr.Name = "."
+ e.Hdr.Rrtype = TypeOPT
+ e.SetUDPSize(udpsize)
+ if do {
+ e.SetDo()
+ }
+ dns.Extra = append(dns.Extra, e)
+ return dns
+}
+
+// IsTsig checks if the message has a TSIG record as the last record
+// in the additional section. It returns the TSIG record found or nil.
+func (dns *Msg) IsTsig() *TSIG {
+ if len(dns.Extra) > 0 {
+ if dns.Extra[len(dns.Extra)-1].Header().Rrtype == TypeTSIG {
+ return dns.Extra[len(dns.Extra)-1].(*TSIG)
+ }
+ }
+ return nil
+}
+
+// IsEdns0 checks if the message has a EDNS0 (OPT) record, any EDNS0
+// record in the additional section will do. It returns the OPT record
+// found or nil.
+func (dns *Msg) IsEdns0() *OPT {
+ // RFC 6891, Section 6.1.1 allows the OPT record to appear
+ // anywhere in the additional record section, but it's usually at
+ // the end so start there.
+ for i := len(dns.Extra) - 1; i >= 0; i-- {
+ if dns.Extra[i].Header().Rrtype == TypeOPT {
+ return dns.Extra[i].(*OPT)
+ }
+ }
+ return nil
+}
+
+// popEdns0 is like IsEdns0, but it removes the record from the message.
+func (dns *Msg) popEdns0() *OPT {
+ // RFC 6891, Section 6.1.1 allows the OPT record to appear
+ // anywhere in the additional record section, but it's usually at
+ // the end so start there.
+ for i := len(dns.Extra) - 1; i >= 0; i-- {
+ if dns.Extra[i].Header().Rrtype == TypeOPT {
+ opt := dns.Extra[i].(*OPT)
+ dns.Extra = append(dns.Extra[:i], dns.Extra[i+1:]...)
+ return opt
+ }
+ }
+ return nil
+}
+
+// IsDomainName checks if s is a valid domain name, it returns the number of
+// labels and true, when a domain name is valid. Note that non fully qualified
+// domain name is considered valid, in this case the last label is counted in
+// the number of labels. When false is returned the number of labels is not
+// defined. Also note that this function is extremely liberal; almost any
+// string is a valid domain name as the DNS is 8 bit protocol. It checks if each
+// label fits in 63 characters and that the entire name will fit into the 255
+// octet wire format limit.
+func IsDomainName(s string) (labels int, ok bool) {
+ // XXX: The logic in this function was copied from packDomainName and
+ // should be kept in sync with that function.
+
+ const lenmsg = 256
+
+ if len(s) == 0 { // Ok, for instance when dealing with update RR without any rdata.
+ return 0, false
+ }
+
+ s = Fqdn(s)
+
+ // Each dot ends a segment of the name. Except for escaped dots (\.), which
+ // are normal dots.
+
+ var (
+ off int
+ begin int
+ wasDot bool
+ )
+ for i := 0; i < len(s); i++ {
+ switch s[i] {
+ case '\\':
+ if off+1 > lenmsg {
+ return labels, false
+ }
+
+ // check for \DDD
+ if i+3 < len(s) && isDigit(s[i+1]) && isDigit(s[i+2]) && isDigit(s[i+3]) {
+ i += 3
+ begin += 3
+ } else {
+ i++
+ begin++
+ }
+
+ wasDot = false
+ case '.':
+ if wasDot {
+ // two dots back to back is not legal
+ return labels, false
+ }
+ wasDot = true
+
+ labelLen := i - begin
+ if labelLen >= 1<<6 { // top two bits of length must be clear
+ return labels, false
+ }
+
+ // off can already (we're in a loop) be bigger than lenmsg
+ // this happens when a name isn't fully qualified
+ off += 1 + labelLen
+ if off > lenmsg {
+ return labels, false
+ }
+
+ labels++
+ begin = i + 1
+ default:
+ wasDot = false
+ }
+ }
+
+ return labels, true
+}
+
+// IsSubDomain checks if child is indeed a child of the parent. If child and parent
+// are the same domain true is returned as well.
+func IsSubDomain(parent, child string) bool {
+ // Entire child is contained in parent
+ return CompareDomainName(parent, child) == CountLabel(parent)
+}
+
+// IsMsg sanity checks buf and returns an error if it isn't a valid DNS packet.
+// The checking is performed on the binary payload.
+func IsMsg(buf []byte) error {
+ // Header
+ if len(buf) < headerSize {
+ return errors.New("dns: bad message header")
+ }
+ // Header: Opcode
+ // TODO(miek): more checks here, e.g. check all header bits.
+ return nil
+}
+
+// IsFqdn checks if a domain name is fully qualified.
+func IsFqdn(s string) bool {
+ s2 := strings.TrimSuffix(s, ".")
+ if s == s2 {
+ return false
+ }
+
+ i := strings.LastIndexFunc(s2, func(r rune) bool {
+ return r != '\\'
+ })
+
+ // Test whether we have an even number of escape sequences before
+ // the dot or none.
+ return (len(s2)-i)%2 != 0
+}
+
+// IsRRset checks if a set of RRs is a valid RRset as defined by RFC 2181.
+// This means the RRs need to have the same type, name, and class. Returns true
+// if the RR set is valid, otherwise false.
+func IsRRset(rrset []RR) bool {
+ if len(rrset) == 0 {
+ return false
+ }
+ if len(rrset) == 1 {
+ return true
+ }
+ rrHeader := rrset[0].Header()
+ rrType := rrHeader.Rrtype
+ rrClass := rrHeader.Class
+ rrName := rrHeader.Name
+
+ for _, rr := range rrset[1:] {
+ curRRHeader := rr.Header()
+ if curRRHeader.Rrtype != rrType || curRRHeader.Class != rrClass || curRRHeader.Name != rrName {
+ // Mismatch between the records, so this is not a valid rrset for
+ //signing/verifying
+ return false
+ }
+ }
+
+ return true
+}
+
+// Fqdn return the fully qualified domain name from s.
+// If s is already fully qualified, it behaves as the identity function.
+func Fqdn(s string) string {
+ if IsFqdn(s) {
+ return s
+ }
+ return s + "."
+}
+
+// CanonicalName returns the domain name in canonical form. A name in canonical
+// form is lowercase and fully qualified. See Section 6.2 in RFC 4034.
+func CanonicalName(s string) string {
+ return strings.ToLower(Fqdn(s))
+}
+
+// Copied from the official Go code.
+
+// ReverseAddr returns the in-addr.arpa. or ip6.arpa. hostname of the IP
+// address suitable for reverse DNS (PTR) record lookups or an error if it fails
+// to parse the IP address.
+func ReverseAddr(addr string) (arpa string, err error) {
+ ip := net.ParseIP(addr)
+ if ip == nil {
+ return "", &Error{err: "unrecognized address: " + addr}
+ }
+ if v4 := ip.To4(); v4 != nil {
+ buf := make([]byte, 0, net.IPv4len*4+len("in-addr.arpa."))
+ // Add it, in reverse, to the buffer
+ for i := len(v4) - 1; i >= 0; i-- {
+ buf = strconv.AppendInt(buf, int64(v4[i]), 10)
+ buf = append(buf, '.')
+ }
+ // Append "in-addr.arpa." and return (buf already has the final .)
+ buf = append(buf, "in-addr.arpa."...)
+ return string(buf), nil
+ }
+ // Must be IPv6
+ buf := make([]byte, 0, net.IPv6len*4+len("ip6.arpa."))
+ // Add it, in reverse, to the buffer
+ for i := len(ip) - 1; i >= 0; i-- {
+ v := ip[i]
+ buf = append(buf, hexDigit[v&0xF], '.', hexDigit[v>>4], '.')
+ }
+ // Append "ip6.arpa." and return (buf already has the final .)
+ buf = append(buf, "ip6.arpa."...)
+ return string(buf), nil
+}
+
+// String returns the string representation for the type t.
+func (t Type) String() string {
+ if t1, ok := TypeToString[uint16(t)]; ok {
+ return t1
+ }
+ return "TYPE" + strconv.Itoa(int(t))
+}
+
+// String returns the string representation for the class c.
+func (c Class) String() string {
+ if s, ok := ClassToString[uint16(c)]; ok {
+ // Only emit mnemonics when they are unambiguous, specially ANY is in both.
+ if _, ok := StringToType[s]; !ok {
+ return s
+ }
+ }
+ return "CLASS" + strconv.Itoa(int(c))
+}
+
+// String returns the string representation for the name n.
+func (n Name) String() string {
+ return sprintName(string(n))
+}
diff --git a/vendor/github.com/miekg/dns/dns.go b/vendor/github.com/miekg/dns/dns.go
@@ -0,0 +1,158 @@
+package dns
+
+import (
+ "encoding/hex"
+ "strconv"
+)
+
+const (
+ year68 = 1 << 31 // For RFC1982 (Serial Arithmetic) calculations in 32 bits.
+ defaultTtl = 3600 // Default internal TTL.
+
+ // DefaultMsgSize is the standard default for messages larger than 512 bytes.
+ DefaultMsgSize = 4096
+ // MinMsgSize is the minimal size of a DNS packet.
+ MinMsgSize = 512
+ // MaxMsgSize is the largest possible DNS packet.
+ MaxMsgSize = 65535
+)
+
+// Error represents a DNS error.
+type Error struct{ err string }
+
+func (e *Error) Error() string {
+ if e == nil {
+ return "dns: <nil>"
+ }
+ return "dns: " + e.err
+}
+
+// An RR represents a resource record.
+type RR interface {
+ // Header returns the header of an resource record. The header contains
+ // everything up to the rdata.
+ Header() *RR_Header
+ // String returns the text representation of the resource record.
+ String() string
+
+ // copy returns a copy of the RR
+ copy() RR
+
+ // len returns the length (in octets) of the compressed or uncompressed RR in wire format.
+ //
+ // If compression is nil, the uncompressed size will be returned, otherwise the compressed
+ // size will be returned and domain names will be added to the map for future compression.
+ len(off int, compression map[string]struct{}) int
+
+ // pack packs the records RDATA into wire format. The header will
+ // already have been packed into msg.
+ pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error)
+
+ // unpack unpacks an RR from wire format.
+ //
+ // This will only be called on a new and empty RR type with only the header populated. It
+ // will only be called if the record's RDATA is non-empty.
+ unpack(msg []byte, off int) (off1 int, err error)
+
+ // parse parses an RR from zone file format.
+ //
+ // This will only be called on a new and empty RR type with only the header populated.
+ parse(c *zlexer, origin string) *ParseError
+
+ // isDuplicate returns whether the two RRs are duplicates.
+ isDuplicate(r2 RR) bool
+}
+
+// RR_Header is the header all DNS resource records share.
+type RR_Header struct {
+ Name string `dns:"cdomain-name"`
+ Rrtype uint16
+ Class uint16
+ Ttl uint32
+ Rdlength uint16 // Length of data after header.
+}
+
+// Header returns itself. This is here to make RR_Header implements the RR interface.
+func (h *RR_Header) Header() *RR_Header { return h }
+
+// Just to implement the RR interface.
+func (h *RR_Header) copy() RR { return nil }
+
+func (h *RR_Header) String() string {
+ var s string
+
+ if h.Rrtype == TypeOPT {
+ s = ";"
+ // and maybe other things
+ }
+
+ s += sprintName(h.Name) + "\t"
+ s += strconv.FormatInt(int64(h.Ttl), 10) + "\t"
+ s += Class(h.Class).String() + "\t"
+ s += Type(h.Rrtype).String() + "\t"
+ return s
+}
+
+func (h *RR_Header) len(off int, compression map[string]struct{}) int {
+ l := domainNameLen(h.Name, off, compression, true)
+ l += 10 // rrtype(2) + class(2) + ttl(4) + rdlength(2)
+ return l
+}
+
+func (h *RR_Header) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ // RR_Header has no RDATA to pack.
+ return off, nil
+}
+
+func (h *RR_Header) unpack(msg []byte, off int) (int, error) {
+ panic("dns: internal error: unpack should never be called on RR_Header")
+}
+
+func (h *RR_Header) parse(c *zlexer, origin string) *ParseError {
+ panic("dns: internal error: parse should never be called on RR_Header")
+}
+
+// ToRFC3597 converts a known RR to the unknown RR representation from RFC 3597.
+func (rr *RFC3597) ToRFC3597(r RR) error {
+ buf := make([]byte, Len(r))
+ headerEnd, off, err := packRR(r, buf, 0, compressionMap{}, false)
+ if err != nil {
+ return err
+ }
+ buf = buf[:off]
+
+ *rr = RFC3597{Hdr: *r.Header()}
+ rr.Hdr.Rdlength = uint16(off - headerEnd)
+
+ if noRdata(rr.Hdr) {
+ return nil
+ }
+
+ _, err = rr.unpack(buf, headerEnd)
+ return err
+}
+
+// fromRFC3597 converts an unknown RR representation from RFC 3597 to the known RR type.
+func (rr *RFC3597) fromRFC3597(r RR) error {
+ hdr := r.Header()
+ *hdr = rr.Hdr
+
+ // Can't overflow uint16 as the length of Rdata is validated in (*RFC3597).parse.
+ // We can only get here when rr was constructed with that method.
+ hdr.Rdlength = uint16(hex.DecodedLen(len(rr.Rdata)))
+
+ if noRdata(*hdr) {
+ // Dynamic update.
+ return nil
+ }
+
+ // rr.pack requires an extra allocation and a copy so we just decode Rdata
+ // manually, it's simpler anyway.
+ msg, err := hex.DecodeString(rr.Rdata)
+ if err != nil {
+ return err
+ }
+
+ _, err = r.unpack(msg, 0)
+ return err
+}
diff --git a/vendor/github.com/miekg/dns/dnssec.go b/vendor/github.com/miekg/dns/dnssec.go
@@ -0,0 +1,749 @@
+package dns
+
+import (
+ "bytes"
+ "crypto"
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/elliptic"
+ "crypto/rand"
+ "crypto/rsa"
+ _ "crypto/sha1" // need its init function
+ _ "crypto/sha256" // need its init function
+ _ "crypto/sha512" // need its init function
+ "encoding/asn1"
+ "encoding/binary"
+ "encoding/hex"
+ "math/big"
+ "sort"
+ "strings"
+ "time"
+)
+
+// DNSSEC encryption algorithm codes.
+const (
+ _ uint8 = iota
+ RSAMD5
+ DH
+ DSA
+ _ // Skip 4, RFC 6725, section 2.1
+ RSASHA1
+ DSANSEC3SHA1
+ RSASHA1NSEC3SHA1
+ RSASHA256
+ _ // Skip 9, RFC 6725, section 2.1
+ RSASHA512
+ _ // Skip 11, RFC 6725, section 2.1
+ ECCGOST
+ ECDSAP256SHA256
+ ECDSAP384SHA384
+ ED25519
+ ED448
+ INDIRECT uint8 = 252
+ PRIVATEDNS uint8 = 253 // Private (experimental keys)
+ PRIVATEOID uint8 = 254
+)
+
+// AlgorithmToString is a map of algorithm IDs to algorithm names.
+var AlgorithmToString = map[uint8]string{
+ RSAMD5: "RSAMD5",
+ DH: "DH",
+ DSA: "DSA",
+ RSASHA1: "RSASHA1",
+ DSANSEC3SHA1: "DSA-NSEC3-SHA1",
+ RSASHA1NSEC3SHA1: "RSASHA1-NSEC3-SHA1",
+ RSASHA256: "RSASHA256",
+ RSASHA512: "RSASHA512",
+ ECCGOST: "ECC-GOST",
+ ECDSAP256SHA256: "ECDSAP256SHA256",
+ ECDSAP384SHA384: "ECDSAP384SHA384",
+ ED25519: "ED25519",
+ ED448: "ED448",
+ INDIRECT: "INDIRECT",
+ PRIVATEDNS: "PRIVATEDNS",
+ PRIVATEOID: "PRIVATEOID",
+}
+
+// AlgorithmToHash is a map of algorithm crypto hash IDs to crypto.Hash's.
+// For newer algorithm that do their own hashing (i.e. ED25519) the returned value
+// is 0, implying no (external) hashing should occur. The non-exported identityHash is then
+// used.
+var AlgorithmToHash = map[uint8]crypto.Hash{
+ RSAMD5: crypto.MD5, // Deprecated in RFC 6725
+ DSA: crypto.SHA1,
+ RSASHA1: crypto.SHA1,
+ RSASHA1NSEC3SHA1: crypto.SHA1,
+ RSASHA256: crypto.SHA256,
+ ECDSAP256SHA256: crypto.SHA256,
+ ECDSAP384SHA384: crypto.SHA384,
+ RSASHA512: crypto.SHA512,
+ ED25519: 0,
+}
+
+// DNSSEC hashing algorithm codes.
+const (
+ _ uint8 = iota
+ SHA1 // RFC 4034
+ SHA256 // RFC 4509
+ GOST94 // RFC 5933
+ SHA384 // Experimental
+ SHA512 // Experimental
+)
+
+// HashToString is a map of hash IDs to names.
+var HashToString = map[uint8]string{
+ SHA1: "SHA1",
+ SHA256: "SHA256",
+ GOST94: "GOST94",
+ SHA384: "SHA384",
+ SHA512: "SHA512",
+}
+
+// DNSKEY flag values.
+const (
+ SEP = 1
+ REVOKE = 1 << 7
+ ZONE = 1 << 8
+)
+
+// The RRSIG needs to be converted to wireformat with some of the rdata (the signature) missing.
+type rrsigWireFmt struct {
+ TypeCovered uint16
+ Algorithm uint8
+ Labels uint8
+ OrigTtl uint32
+ Expiration uint32
+ Inception uint32
+ KeyTag uint16
+ SignerName string `dns:"domain-name"`
+ /* No Signature */
+}
+
+// Used for converting DNSKEY's rdata to wirefmt.
+type dnskeyWireFmt struct {
+ Flags uint16
+ Protocol uint8
+ Algorithm uint8
+ PublicKey string `dns:"base64"`
+ /* Nothing is left out */
+}
+
+func divRoundUp(a, b int) int {
+ return (a + b - 1) / b
+}
+
+// KeyTag calculates the keytag (or key-id) of the DNSKEY.
+func (k *DNSKEY) KeyTag() uint16 {
+ if k == nil {
+ return 0
+ }
+ var keytag int
+ switch k.Algorithm {
+ case RSAMD5:
+ // This algorithm has been deprecated, but keep this key-tag calculation.
+ // Look at the bottom two bytes of the modules, which the last item in the pubkey.
+ // See https://www.rfc-editor.org/errata/eid193 .
+ modulus, _ := fromBase64([]byte(k.PublicKey))
+ if len(modulus) > 1 {
+ x := binary.BigEndian.Uint16(modulus[len(modulus)-3:])
+ keytag = int(x)
+ }
+ default:
+ keywire := new(dnskeyWireFmt)
+ keywire.Flags = k.Flags
+ keywire.Protocol = k.Protocol
+ keywire.Algorithm = k.Algorithm
+ keywire.PublicKey = k.PublicKey
+ wire := make([]byte, DefaultMsgSize)
+ n, err := packKeyWire(keywire, wire)
+ if err != nil {
+ return 0
+ }
+ wire = wire[:n]
+ for i, v := range wire {
+ if i&1 != 0 {
+ keytag += int(v) // must be larger than uint32
+ } else {
+ keytag += int(v) << 8
+ }
+ }
+ keytag += keytag >> 16 & 0xFFFF
+ keytag &= 0xFFFF
+ }
+ return uint16(keytag)
+}
+
+// ToDS converts a DNSKEY record to a DS record.
+func (k *DNSKEY) ToDS(h uint8) *DS {
+ if k == nil {
+ return nil
+ }
+ ds := new(DS)
+ ds.Hdr.Name = k.Hdr.Name
+ ds.Hdr.Class = k.Hdr.Class
+ ds.Hdr.Rrtype = TypeDS
+ ds.Hdr.Ttl = k.Hdr.Ttl
+ ds.Algorithm = k.Algorithm
+ ds.DigestType = h
+ ds.KeyTag = k.KeyTag()
+
+ keywire := new(dnskeyWireFmt)
+ keywire.Flags = k.Flags
+ keywire.Protocol = k.Protocol
+ keywire.Algorithm = k.Algorithm
+ keywire.PublicKey = k.PublicKey
+ wire := make([]byte, DefaultMsgSize)
+ n, err := packKeyWire(keywire, wire)
+ if err != nil {
+ return nil
+ }
+ wire = wire[:n]
+
+ owner := make([]byte, 255)
+ off, err1 := PackDomainName(CanonicalName(k.Hdr.Name), owner, 0, nil, false)
+ if err1 != nil {
+ return nil
+ }
+ owner = owner[:off]
+ // RFC4034:
+ // digest = digest_algorithm( DNSKEY owner name | DNSKEY RDATA);
+ // "|" denotes concatenation
+ // DNSKEY RDATA = Flags | Protocol | Algorithm | Public Key.
+
+ var hash crypto.Hash
+ switch h {
+ case SHA1:
+ hash = crypto.SHA1
+ case SHA256:
+ hash = crypto.SHA256
+ case SHA384:
+ hash = crypto.SHA384
+ case SHA512:
+ hash = crypto.SHA512
+ default:
+ return nil
+ }
+
+ s := hash.New()
+ s.Write(owner)
+ s.Write(wire)
+ ds.Digest = hex.EncodeToString(s.Sum(nil))
+ return ds
+}
+
+// ToCDNSKEY converts a DNSKEY record to a CDNSKEY record.
+func (k *DNSKEY) ToCDNSKEY() *CDNSKEY {
+ c := &CDNSKEY{DNSKEY: *k}
+ c.Hdr = k.Hdr
+ c.Hdr.Rrtype = TypeCDNSKEY
+ return c
+}
+
+// ToCDS converts a DS record to a CDS record.
+func (d *DS) ToCDS() *CDS {
+ c := &CDS{DS: *d}
+ c.Hdr = d.Hdr
+ c.Hdr.Rrtype = TypeCDS
+ return c
+}
+
+// Sign signs an RRSet. The signature needs to be filled in with the values:
+// Inception, Expiration, KeyTag, SignerName and Algorithm. The rest is copied
+// from the RRset. Sign returns a non-nill error when the signing went OK.
+// There is no check if RRSet is a proper (RFC 2181) RRSet. If OrigTTL is non
+// zero, it is used as-is, otherwise the TTL of the RRset is used as the
+// OrigTTL.
+func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error {
+ if k == nil {
+ return ErrPrivKey
+ }
+ // s.Inception and s.Expiration may be 0 (rollover etc.), the rest must be set
+ if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 {
+ return ErrKey
+ }
+
+ h0 := rrset[0].Header()
+ rr.Hdr.Rrtype = TypeRRSIG
+ rr.Hdr.Name = h0.Name
+ rr.Hdr.Class = h0.Class
+ if rr.OrigTtl == 0 { // If set don't override
+ rr.OrigTtl = h0.Ttl
+ }
+ rr.TypeCovered = h0.Rrtype
+ rr.Labels = uint8(CountLabel(h0.Name))
+
+ if strings.HasPrefix(h0.Name, "*") {
+ rr.Labels-- // wildcard, remove from label count
+ }
+
+ sigwire := new(rrsigWireFmt)
+ sigwire.TypeCovered = rr.TypeCovered
+ sigwire.Algorithm = rr.Algorithm
+ sigwire.Labels = rr.Labels
+ sigwire.OrigTtl = rr.OrigTtl
+ sigwire.Expiration = rr.Expiration
+ sigwire.Inception = rr.Inception
+ sigwire.KeyTag = rr.KeyTag
+ // For signing, lowercase this name
+ sigwire.SignerName = CanonicalName(rr.SignerName)
+
+ // Create the desired binary blob
+ signdata := make([]byte, DefaultMsgSize)
+ n, err := packSigWire(sigwire, signdata)
+ if err != nil {
+ return err
+ }
+ signdata = signdata[:n]
+ wire, err := rawSignatureData(rrset, rr)
+ if err != nil {
+ return err
+ }
+
+ h, cryptohash, err := hashFromAlgorithm(rr.Algorithm)
+ if err != nil {
+ return err
+ }
+
+ switch rr.Algorithm {
+ case RSAMD5, DSA, DSANSEC3SHA1:
+ // See RFC 6944.
+ return ErrAlg
+ default:
+ h.Write(signdata)
+ h.Write(wire)
+
+ signature, err := sign(k, h.Sum(nil), cryptohash, rr.Algorithm)
+ if err != nil {
+ return err
+ }
+
+ rr.Signature = toBase64(signature)
+ return nil
+ }
+}
+
+func sign(k crypto.Signer, hashed []byte, hash crypto.Hash, alg uint8) ([]byte, error) {
+ signature, err := k.Sign(rand.Reader, hashed, hash)
+ if err != nil {
+ return nil, err
+ }
+
+ switch alg {
+ case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512, ED25519:
+ return signature, nil
+ case ECDSAP256SHA256, ECDSAP384SHA384:
+ ecdsaSignature := &struct {
+ R, S *big.Int
+ }{}
+ if _, err := asn1.Unmarshal(signature, ecdsaSignature); err != nil {
+ return nil, err
+ }
+
+ var intlen int
+ switch alg {
+ case ECDSAP256SHA256:
+ intlen = 32
+ case ECDSAP384SHA384:
+ intlen = 48
+ }
+
+ signature := intToBytes(ecdsaSignature.R, intlen)
+ signature = append(signature, intToBytes(ecdsaSignature.S, intlen)...)
+ return signature, nil
+ default:
+ return nil, ErrAlg
+ }
+}
+
+// Verify validates an RRSet with the signature and key. This is only the
+// cryptographic test, the signature validity period must be checked separately.
+// This function copies the rdata of some RRs (to lowercase domain names) for the validation to work.
+// It also checks that the Zone Key bit (RFC 4034 2.1.1) is set on the DNSKEY
+// and that the Protocol field is set to 3 (RFC 4034 2.1.2).
+func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
+ // First the easy checks
+ if !IsRRset(rrset) {
+ return ErrRRset
+ }
+ if rr.KeyTag != k.KeyTag() {
+ return ErrKey
+ }
+ if rr.Hdr.Class != k.Hdr.Class {
+ return ErrKey
+ }
+ if rr.Algorithm != k.Algorithm {
+ return ErrKey
+ }
+ if !strings.EqualFold(rr.SignerName, k.Hdr.Name) {
+ return ErrKey
+ }
+ if k.Protocol != 3 {
+ return ErrKey
+ }
+ // RFC 4034 2.1.1 If bit 7 has value 0, then the DNSKEY record holds some
+ // other type of DNS public key and MUST NOT be used to verify RRSIGs that
+ // cover RRsets.
+ if k.Flags&ZONE == 0 {
+ return ErrKey
+ }
+
+ // IsRRset checked that we have at least one RR and that the RRs in
+ // the set have consistent type, class, and name. Also check that type and
+ // class matches the RRSIG record.
+ if h0 := rrset[0].Header(); h0.Class != rr.Hdr.Class || h0.Rrtype != rr.TypeCovered {
+ return ErrRRset
+ }
+
+ // RFC 4035 5.3.2. Reconstructing the Signed Data
+ // Copy the sig, except the rrsig data
+ sigwire := new(rrsigWireFmt)
+ sigwire.TypeCovered = rr.TypeCovered
+ sigwire.Algorithm = rr.Algorithm
+ sigwire.Labels = rr.Labels
+ sigwire.OrigTtl = rr.OrigTtl
+ sigwire.Expiration = rr.Expiration
+ sigwire.Inception = rr.Inception
+ sigwire.KeyTag = rr.KeyTag
+ sigwire.SignerName = CanonicalName(rr.SignerName)
+ // Create the desired binary blob
+ signeddata := make([]byte, DefaultMsgSize)
+ n, err := packSigWire(sigwire, signeddata)
+ if err != nil {
+ return err
+ }
+ signeddata = signeddata[:n]
+ wire, err := rawSignatureData(rrset, rr)
+ if err != nil {
+ return err
+ }
+
+ sigbuf := rr.sigBuf() // Get the binary signature data
+ if rr.Algorithm == PRIVATEDNS { // PRIVATEOID
+ // TODO(miek)
+ // remove the domain name and assume its ours?
+ }
+
+ h, cryptohash, err := hashFromAlgorithm(rr.Algorithm)
+ if err != nil {
+ return err
+ }
+
+ switch rr.Algorithm {
+ case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512:
+ // TODO(mg): this can be done quicker, ie. cache the pubkey data somewhere??
+ pubkey := k.publicKeyRSA() // Get the key
+ if pubkey == nil {
+ return ErrKey
+ }
+
+ h.Write(signeddata)
+ h.Write(wire)
+ return rsa.VerifyPKCS1v15(pubkey, cryptohash, h.Sum(nil), sigbuf)
+
+ case ECDSAP256SHA256, ECDSAP384SHA384:
+ pubkey := k.publicKeyECDSA()
+ if pubkey == nil {
+ return ErrKey
+ }
+
+ // Split sigbuf into the r and s coordinates
+ r := new(big.Int).SetBytes(sigbuf[:len(sigbuf)/2])
+ s := new(big.Int).SetBytes(sigbuf[len(sigbuf)/2:])
+
+ h.Write(signeddata)
+ h.Write(wire)
+ if ecdsa.Verify(pubkey, h.Sum(nil), r, s) {
+ return nil
+ }
+ return ErrSig
+
+ case ED25519:
+ pubkey := k.publicKeyED25519()
+ if pubkey == nil {
+ return ErrKey
+ }
+
+ if ed25519.Verify(pubkey, append(signeddata, wire...), sigbuf) {
+ return nil
+ }
+ return ErrSig
+
+ default:
+ return ErrAlg
+ }
+}
+
+// ValidityPeriod uses RFC1982 serial arithmetic to calculate
+// if a signature period is valid. If t is the zero time, the
+// current time is taken other t is. Returns true if the signature
+// is valid at the given time, otherwise returns false.
+func (rr *RRSIG) ValidityPeriod(t time.Time) bool {
+ var utc int64
+ if t.IsZero() {
+ utc = time.Now().UTC().Unix()
+ } else {
+ utc = t.UTC().Unix()
+ }
+ modi := (int64(rr.Inception) - utc) / year68
+ mode := (int64(rr.Expiration) - utc) / year68
+ ti := int64(rr.Inception) + modi*year68
+ te := int64(rr.Expiration) + mode*year68
+ return ti <= utc && utc <= te
+}
+
+// Return the signatures base64 encoding sigdata as a byte slice.
+func (rr *RRSIG) sigBuf() []byte {
+ sigbuf, err := fromBase64([]byte(rr.Signature))
+ if err != nil {
+ return nil
+ }
+ return sigbuf
+}
+
+// publicKeyRSA returns the RSA public key from a DNSKEY record.
+func (k *DNSKEY) publicKeyRSA() *rsa.PublicKey {
+ keybuf, err := fromBase64([]byte(k.PublicKey))
+ if err != nil {
+ return nil
+ }
+
+ if len(keybuf) < 1+1+64 {
+ // Exponent must be at least 1 byte and modulus at least 64
+ return nil
+ }
+
+ // RFC 2537/3110, section 2. RSA Public KEY Resource Records
+ // Length is in the 0th byte, unless its zero, then it
+ // it in bytes 1 and 2 and its a 16 bit number
+ explen := uint16(keybuf[0])
+ keyoff := 1
+ if explen == 0 {
+ explen = uint16(keybuf[1])<<8 | uint16(keybuf[2])
+ keyoff = 3
+ }
+
+ if explen > 4 || explen == 0 || keybuf[keyoff] == 0 {
+ // Exponent larger than supported by the crypto package,
+ // empty, or contains prohibited leading zero.
+ return nil
+ }
+
+ modoff := keyoff + int(explen)
+ modlen := len(keybuf) - modoff
+ if modlen < 64 || modlen > 512 || keybuf[modoff] == 0 {
+ // Modulus is too small, large, or contains prohibited leading zero.
+ return nil
+ }
+
+ pubkey := new(rsa.PublicKey)
+
+ var expo uint64
+ // The exponent of length explen is between keyoff and modoff.
+ for _, v := range keybuf[keyoff:modoff] {
+ expo <<= 8
+ expo |= uint64(v)
+ }
+ if expo > 1<<31-1 {
+ // Larger exponent than supported by the crypto package.
+ return nil
+ }
+
+ pubkey.E = int(expo)
+ pubkey.N = new(big.Int).SetBytes(keybuf[modoff:])
+ return pubkey
+}
+
+// publicKeyECDSA returns the Curve public key from the DNSKEY record.
+func (k *DNSKEY) publicKeyECDSA() *ecdsa.PublicKey {
+ keybuf, err := fromBase64([]byte(k.PublicKey))
+ if err != nil {
+ return nil
+ }
+ pubkey := new(ecdsa.PublicKey)
+ switch k.Algorithm {
+ case ECDSAP256SHA256:
+ pubkey.Curve = elliptic.P256()
+ if len(keybuf) != 64 {
+ // wrongly encoded key
+ return nil
+ }
+ case ECDSAP384SHA384:
+ pubkey.Curve = elliptic.P384()
+ if len(keybuf) != 96 {
+ // Wrongly encoded key
+ return nil
+ }
+ }
+ pubkey.X = new(big.Int).SetBytes(keybuf[:len(keybuf)/2])
+ pubkey.Y = new(big.Int).SetBytes(keybuf[len(keybuf)/2:])
+ return pubkey
+}
+
+func (k *DNSKEY) publicKeyED25519() ed25519.PublicKey {
+ keybuf, err := fromBase64([]byte(k.PublicKey))
+ if err != nil {
+ return nil
+ }
+ if len(keybuf) != ed25519.PublicKeySize {
+ return nil
+ }
+ return keybuf
+}
+
+type wireSlice [][]byte
+
+func (p wireSlice) Len() int { return len(p) }
+func (p wireSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
+func (p wireSlice) Less(i, j int) bool {
+ _, ioff, _ := UnpackDomainName(p[i], 0)
+ _, joff, _ := UnpackDomainName(p[j], 0)
+ return bytes.Compare(p[i][ioff+10:], p[j][joff+10:]) < 0
+}
+
+// Return the raw signature data.
+func rawSignatureData(rrset []RR, s *RRSIG) (buf []byte, err error) {
+ wires := make(wireSlice, len(rrset))
+ for i, r := range rrset {
+ r1 := r.copy()
+ h := r1.Header()
+ h.Ttl = s.OrigTtl
+ labels := SplitDomainName(h.Name)
+ // 6.2. Canonical RR Form. (4) - wildcards
+ if len(labels) > int(s.Labels) {
+ // Wildcard
+ h.Name = "*." + strings.Join(labels[len(labels)-int(s.Labels):], ".") + "."
+ }
+ // RFC 4034: 6.2. Canonical RR Form. (2) - domain name to lowercase
+ h.Name = CanonicalName(h.Name)
+ // 6.2. Canonical RR Form. (3) - domain rdata to lowercase.
+ // NS, MD, MF, CNAME, SOA, MB, MG, MR, PTR,
+ // HINFO, MINFO, MX, RP, AFSDB, RT, SIG, PX, NXT, NAPTR, KX,
+ // SRV, DNAME, A6
+ //
+ // RFC 6840 - Clarifications and Implementation Notes for DNS Security (DNSSEC):
+ // Section 6.2 of [RFC4034] also erroneously lists HINFO as a record
+ // that needs conversion to lowercase, and twice at that. Since HINFO
+ // records contain no domain names, they are not subject to case
+ // conversion.
+ switch x := r1.(type) {
+ case *NS:
+ x.Ns = CanonicalName(x.Ns)
+ case *MD:
+ x.Md = CanonicalName(x.Md)
+ case *MF:
+ x.Mf = CanonicalName(x.Mf)
+ case *CNAME:
+ x.Target = CanonicalName(x.Target)
+ case *SOA:
+ x.Ns = CanonicalName(x.Ns)
+ x.Mbox = CanonicalName(x.Mbox)
+ case *MB:
+ x.Mb = CanonicalName(x.Mb)
+ case *MG:
+ x.Mg = CanonicalName(x.Mg)
+ case *MR:
+ x.Mr = CanonicalName(x.Mr)
+ case *PTR:
+ x.Ptr = CanonicalName(x.Ptr)
+ case *MINFO:
+ x.Rmail = CanonicalName(x.Rmail)
+ x.Email = CanonicalName(x.Email)
+ case *MX:
+ x.Mx = CanonicalName(x.Mx)
+ case *RP:
+ x.Mbox = CanonicalName(x.Mbox)
+ x.Txt = CanonicalName(x.Txt)
+ case *AFSDB:
+ x.Hostname = CanonicalName(x.Hostname)
+ case *RT:
+ x.Host = CanonicalName(x.Host)
+ case *SIG:
+ x.SignerName = CanonicalName(x.SignerName)
+ case *PX:
+ x.Map822 = CanonicalName(x.Map822)
+ x.Mapx400 = CanonicalName(x.Mapx400)
+ case *NAPTR:
+ x.Replacement = CanonicalName(x.Replacement)
+ case *KX:
+ x.Exchanger = CanonicalName(x.Exchanger)
+ case *SRV:
+ x.Target = CanonicalName(x.Target)
+ case *DNAME:
+ x.Target = CanonicalName(x.Target)
+ }
+ // 6.2. Canonical RR Form. (5) - origTTL
+ wire := make([]byte, Len(r1)+1) // +1 to be safe(r)
+ off, err1 := PackRR(r1, wire, 0, nil, false)
+ if err1 != nil {
+ return nil, err1
+ }
+ wire = wire[:off]
+ wires[i] = wire
+ }
+ sort.Sort(wires)
+ for i, wire := range wires {
+ if i > 0 && bytes.Equal(wire, wires[i-1]) {
+ continue
+ }
+ buf = append(buf, wire...)
+ }
+ return buf, nil
+}
+
+func packSigWire(sw *rrsigWireFmt, msg []byte) (int, error) {
+ // copied from zmsg.go RRSIG packing
+ off, err := packUint16(sw.TypeCovered, msg, 0)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(sw.Algorithm, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(sw.Labels, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint32(sw.OrigTtl, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint32(sw.Expiration, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint32(sw.Inception, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(sw.KeyTag, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = PackDomainName(sw.SignerName, msg, off, nil, false)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func packKeyWire(dw *dnskeyWireFmt, msg []byte) (int, error) {
+ // copied from zmsg.go DNSKEY packing
+ off, err := packUint16(dw.Flags, msg, 0)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(dw.Protocol, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(dw.Algorithm, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringBase64(dw.PublicKey, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
diff --git a/vendor/github.com/miekg/dns/dnssec_keygen.go b/vendor/github.com/miekg/dns/dnssec_keygen.go
@@ -0,0 +1,139 @@
+package dns
+
+import (
+ "crypto"
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/elliptic"
+ "crypto/rand"
+ "crypto/rsa"
+ "math/big"
+)
+
+// Generate generates a DNSKEY of the given bit size.
+// The public part is put inside the DNSKEY record.
+// The Algorithm in the key must be set as this will define
+// what kind of DNSKEY will be generated.
+// The ECDSA algorithms imply a fixed keysize, in that case
+// bits should be set to the size of the algorithm.
+func (k *DNSKEY) Generate(bits int) (crypto.PrivateKey, error) {
+ switch k.Algorithm {
+ case RSASHA1, RSASHA256, RSASHA1NSEC3SHA1:
+ if bits < 512 || bits > 4096 {
+ return nil, ErrKeySize
+ }
+ case RSASHA512:
+ if bits < 1024 || bits > 4096 {
+ return nil, ErrKeySize
+ }
+ case ECDSAP256SHA256:
+ if bits != 256 {
+ return nil, ErrKeySize
+ }
+ case ECDSAP384SHA384:
+ if bits != 384 {
+ return nil, ErrKeySize
+ }
+ case ED25519:
+ if bits != 256 {
+ return nil, ErrKeySize
+ }
+ default:
+ return nil, ErrAlg
+ }
+
+ switch k.Algorithm {
+ case RSASHA1, RSASHA256, RSASHA512, RSASHA1NSEC3SHA1:
+ priv, err := rsa.GenerateKey(rand.Reader, bits)
+ if err != nil {
+ return nil, err
+ }
+ k.setPublicKeyRSA(priv.PublicKey.E, priv.PublicKey.N)
+ return priv, nil
+ case ECDSAP256SHA256, ECDSAP384SHA384:
+ var c elliptic.Curve
+ switch k.Algorithm {
+ case ECDSAP256SHA256:
+ c = elliptic.P256()
+ case ECDSAP384SHA384:
+ c = elliptic.P384()
+ }
+ priv, err := ecdsa.GenerateKey(c, rand.Reader)
+ if err != nil {
+ return nil, err
+ }
+ k.setPublicKeyECDSA(priv.PublicKey.X, priv.PublicKey.Y)
+ return priv, nil
+ case ED25519:
+ pub, priv, err := ed25519.GenerateKey(rand.Reader)
+ if err != nil {
+ return nil, err
+ }
+ k.setPublicKeyED25519(pub)
+ return priv, nil
+ default:
+ return nil, ErrAlg
+ }
+}
+
+// Set the public key (the value E and N)
+func (k *DNSKEY) setPublicKeyRSA(_E int, _N *big.Int) bool {
+ if _E == 0 || _N == nil {
+ return false
+ }
+ buf := exponentToBuf(_E)
+ buf = append(buf, _N.Bytes()...)
+ k.PublicKey = toBase64(buf)
+ return true
+}
+
+// Set the public key for Elliptic Curves
+func (k *DNSKEY) setPublicKeyECDSA(_X, _Y *big.Int) bool {
+ if _X == nil || _Y == nil {
+ return false
+ }
+ var intlen int
+ switch k.Algorithm {
+ case ECDSAP256SHA256:
+ intlen = 32
+ case ECDSAP384SHA384:
+ intlen = 48
+ }
+ k.PublicKey = toBase64(curveToBuf(_X, _Y, intlen))
+ return true
+}
+
+// Set the public key for Ed25519
+func (k *DNSKEY) setPublicKeyED25519(_K ed25519.PublicKey) bool {
+ if _K == nil {
+ return false
+ }
+ k.PublicKey = toBase64(_K)
+ return true
+}
+
+// Set the public key (the values E and N) for RSA
+// RFC 3110: Section 2. RSA Public KEY Resource Records
+func exponentToBuf(_E int) []byte {
+ var buf []byte
+ i := big.NewInt(int64(_E)).Bytes()
+ if len(i) < 256 {
+ buf = make([]byte, 1, 1+len(i))
+ buf[0] = uint8(len(i))
+ } else {
+ buf = make([]byte, 3, 3+len(i))
+ buf[0] = 0
+ buf[1] = uint8(len(i) >> 8)
+ buf[2] = uint8(len(i))
+ }
+ buf = append(buf, i...)
+ return buf
+}
+
+// Set the public key for X and Y for Curve. The two
+// values are just concatenated.
+func curveToBuf(_X, _Y *big.Int, intlen int) []byte {
+ buf := intToBytes(_X, intlen)
+ buf = append(buf, intToBytes(_Y, intlen)...)
+ return buf
+}
diff --git a/vendor/github.com/miekg/dns/dnssec_keyscan.go b/vendor/github.com/miekg/dns/dnssec_keyscan.go
@@ -0,0 +1,309 @@
+package dns
+
+import (
+ "bufio"
+ "crypto"
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/rsa"
+ "io"
+ "math/big"
+ "strconv"
+ "strings"
+)
+
+// NewPrivateKey returns a PrivateKey by parsing the string s.
+// s should be in the same form of the BIND private key files.
+func (k *DNSKEY) NewPrivateKey(s string) (crypto.PrivateKey, error) {
+ if s == "" || s[len(s)-1] != '\n' { // We need a closing newline
+ return k.ReadPrivateKey(strings.NewReader(s+"\n"), "")
+ }
+ return k.ReadPrivateKey(strings.NewReader(s), "")
+}
+
+// ReadPrivateKey reads a private key from the io.Reader q. The string file is
+// only used in error reporting.
+// The public key must be known, because some cryptographic algorithms embed
+// the public inside the privatekey.
+func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, error) {
+ m, err := parseKey(q, file)
+ if m == nil {
+ return nil, err
+ }
+ if _, ok := m["private-key-format"]; !ok {
+ return nil, ErrPrivKey
+ }
+ if m["private-key-format"] != "v1.2" && m["private-key-format"] != "v1.3" {
+ return nil, ErrPrivKey
+ }
+ // TODO(mg): check if the pubkey matches the private key
+ algo, err := strconv.ParseUint(strings.SplitN(m["algorithm"], " ", 2)[0], 10, 8)
+ if err != nil {
+ return nil, ErrPrivKey
+ }
+ switch uint8(algo) {
+ case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512:
+ priv, err := readPrivateKeyRSA(m)
+ if err != nil {
+ return nil, err
+ }
+ pub := k.publicKeyRSA()
+ if pub == nil {
+ return nil, ErrKey
+ }
+ priv.PublicKey = *pub
+ return priv, nil
+ case ECDSAP256SHA256, ECDSAP384SHA384:
+ priv, err := readPrivateKeyECDSA(m)
+ if err != nil {
+ return nil, err
+ }
+ pub := k.publicKeyECDSA()
+ if pub == nil {
+ return nil, ErrKey
+ }
+ priv.PublicKey = *pub
+ return priv, nil
+ case ED25519:
+ return readPrivateKeyED25519(m)
+ default:
+ return nil, ErrAlg
+ }
+}
+
+// Read a private key (file) string and create a public key. Return the private key.
+func readPrivateKeyRSA(m map[string]string) (*rsa.PrivateKey, error) {
+ p := new(rsa.PrivateKey)
+ p.Primes = []*big.Int{nil, nil}
+ for k, v := range m {
+ switch k {
+ case "modulus", "publicexponent", "privateexponent", "prime1", "prime2":
+ v1, err := fromBase64([]byte(v))
+ if err != nil {
+ return nil, err
+ }
+ switch k {
+ case "modulus":
+ p.PublicKey.N = new(big.Int).SetBytes(v1)
+ case "publicexponent":
+ i := new(big.Int).SetBytes(v1)
+ p.PublicKey.E = int(i.Int64()) // int64 should be large enough
+ case "privateexponent":
+ p.D = new(big.Int).SetBytes(v1)
+ case "prime1":
+ p.Primes[0] = new(big.Int).SetBytes(v1)
+ case "prime2":
+ p.Primes[1] = new(big.Int).SetBytes(v1)
+ }
+ case "exponent1", "exponent2", "coefficient":
+ // not used in Go (yet)
+ case "created", "publish", "activate":
+ // not used in Go (yet)
+ }
+ }
+ return p, nil
+}
+
+func readPrivateKeyECDSA(m map[string]string) (*ecdsa.PrivateKey, error) {
+ p := new(ecdsa.PrivateKey)
+ p.D = new(big.Int)
+ // TODO: validate that the required flags are present
+ for k, v := range m {
+ switch k {
+ case "privatekey":
+ v1, err := fromBase64([]byte(v))
+ if err != nil {
+ return nil, err
+ }
+ p.D.SetBytes(v1)
+ case "created", "publish", "activate":
+ /* not used in Go (yet) */
+ }
+ }
+ return p, nil
+}
+
+func readPrivateKeyED25519(m map[string]string) (ed25519.PrivateKey, error) {
+ var p ed25519.PrivateKey
+ // TODO: validate that the required flags are present
+ for k, v := range m {
+ switch k {
+ case "privatekey":
+ p1, err := fromBase64([]byte(v))
+ if err != nil {
+ return nil, err
+ }
+ if len(p1) != ed25519.SeedSize {
+ return nil, ErrPrivKey
+ }
+ p = ed25519.NewKeyFromSeed(p1)
+ case "created", "publish", "activate":
+ /* not used in Go (yet) */
+ }
+ }
+ return p, nil
+}
+
+// parseKey reads a private key from r. It returns a map[string]string,
+// with the key-value pairs, or an error when the file is not correct.
+func parseKey(r io.Reader, file string) (map[string]string, error) {
+ m := make(map[string]string)
+ var k string
+
+ c := newKLexer(r)
+
+ for l, ok := c.Next(); ok; l, ok = c.Next() {
+ // It should alternate
+ switch l.value {
+ case zKey:
+ k = l.token
+ case zValue:
+ if k == "" {
+ return nil, &ParseError{file, "no private key seen", l}
+ }
+
+ m[strings.ToLower(k)] = l.token
+ k = ""
+ }
+ }
+
+ // Surface any read errors from r.
+ if err := c.Err(); err != nil {
+ return nil, &ParseError{file: file, err: err.Error()}
+ }
+
+ return m, nil
+}
+
+type klexer struct {
+ br io.ByteReader
+
+ readErr error
+
+ line int
+ column int
+
+ key bool
+
+ eol bool // end-of-line
+}
+
+func newKLexer(r io.Reader) *klexer {
+ br, ok := r.(io.ByteReader)
+ if !ok {
+ br = bufio.NewReaderSize(r, 1024)
+ }
+
+ return &klexer{
+ br: br,
+
+ line: 1,
+
+ key: true,
+ }
+}
+
+func (kl *klexer) Err() error {
+ if kl.readErr == io.EOF {
+ return nil
+ }
+
+ return kl.readErr
+}
+
+// readByte returns the next byte from the input
+func (kl *klexer) readByte() (byte, bool) {
+ if kl.readErr != nil {
+ return 0, false
+ }
+
+ c, err := kl.br.ReadByte()
+ if err != nil {
+ kl.readErr = err
+ return 0, false
+ }
+
+ // delay the newline handling until the next token is delivered,
+ // fixes off-by-one errors when reporting a parse error.
+ if kl.eol {
+ kl.line++
+ kl.column = 0
+ kl.eol = false
+ }
+
+ if c == '\n' {
+ kl.eol = true
+ } else {
+ kl.column++
+ }
+
+ return c, true
+}
+
+func (kl *klexer) Next() (lex, bool) {
+ var (
+ l lex
+
+ str strings.Builder
+
+ commt bool
+ )
+
+ for x, ok := kl.readByte(); ok; x, ok = kl.readByte() {
+ l.line, l.column = kl.line, kl.column
+
+ switch x {
+ case ':':
+ if commt || !kl.key {
+ break
+ }
+
+ kl.key = false
+
+ // Next token is a space, eat it
+ kl.readByte()
+
+ l.value = zKey
+ l.token = str.String()
+ return l, true
+ case ';':
+ commt = true
+ case '\n':
+ if commt {
+ // Reset a comment
+ commt = false
+ }
+
+ if kl.key && str.Len() == 0 {
+ // ignore empty lines
+ break
+ }
+
+ kl.key = true
+
+ l.value = zValue
+ l.token = str.String()
+ return l, true
+ default:
+ if commt {
+ break
+ }
+
+ str.WriteByte(x)
+ }
+ }
+
+ if kl.readErr != nil && kl.readErr != io.EOF {
+ // Don't return any tokens after a read error occurs.
+ return lex{value: zEOF}, false
+ }
+
+ if str.Len() > 0 {
+ // Send remainder
+ l.value = zValue
+ l.token = str.String()
+ return l, true
+ }
+
+ return lex{value: zEOF}, false
+}
diff --git a/vendor/github.com/miekg/dns/dnssec_privkey.go b/vendor/github.com/miekg/dns/dnssec_privkey.go
@@ -0,0 +1,77 @@
+package dns
+
+import (
+ "crypto"
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/rsa"
+ "math/big"
+ "strconv"
+)
+
+const format = "Private-key-format: v1.3\n"
+
+var bigIntOne = big.NewInt(1)
+
+// PrivateKeyString converts a PrivateKey to a string. This string has the same
+// format as the private-key-file of BIND9 (Private-key-format: v1.3).
+// It needs some info from the key (the algorithm), so its a method of the DNSKEY.
+// It supports *rsa.PrivateKey, *ecdsa.PrivateKey and ed25519.PrivateKey.
+func (r *DNSKEY) PrivateKeyString(p crypto.PrivateKey) string {
+ algorithm := strconv.Itoa(int(r.Algorithm))
+ algorithm += " (" + AlgorithmToString[r.Algorithm] + ")"
+
+ switch p := p.(type) {
+ case *rsa.PrivateKey:
+ modulus := toBase64(p.PublicKey.N.Bytes())
+ e := big.NewInt(int64(p.PublicKey.E))
+ publicExponent := toBase64(e.Bytes())
+ privateExponent := toBase64(p.D.Bytes())
+ prime1 := toBase64(p.Primes[0].Bytes())
+ prime2 := toBase64(p.Primes[1].Bytes())
+ // Calculate Exponent1/2 and Coefficient as per: http://en.wikipedia.org/wiki/RSA#Using_the_Chinese_remainder_algorithm
+ // and from: http://code.google.com/p/go/issues/detail?id=987
+ p1 := new(big.Int).Sub(p.Primes[0], bigIntOne)
+ q1 := new(big.Int).Sub(p.Primes[1], bigIntOne)
+ exp1 := new(big.Int).Mod(p.D, p1)
+ exp2 := new(big.Int).Mod(p.D, q1)
+ coeff := new(big.Int).ModInverse(p.Primes[1], p.Primes[0])
+
+ exponent1 := toBase64(exp1.Bytes())
+ exponent2 := toBase64(exp2.Bytes())
+ coefficient := toBase64(coeff.Bytes())
+
+ return format +
+ "Algorithm: " + algorithm + "\n" +
+ "Modulus: " + modulus + "\n" +
+ "PublicExponent: " + publicExponent + "\n" +
+ "PrivateExponent: " + privateExponent + "\n" +
+ "Prime1: " + prime1 + "\n" +
+ "Prime2: " + prime2 + "\n" +
+ "Exponent1: " + exponent1 + "\n" +
+ "Exponent2: " + exponent2 + "\n" +
+ "Coefficient: " + coefficient + "\n"
+
+ case *ecdsa.PrivateKey:
+ var intlen int
+ switch r.Algorithm {
+ case ECDSAP256SHA256:
+ intlen = 32
+ case ECDSAP384SHA384:
+ intlen = 48
+ }
+ private := toBase64(intToBytes(p.D, intlen))
+ return format +
+ "Algorithm: " + algorithm + "\n" +
+ "PrivateKey: " + private + "\n"
+
+ case ed25519.PrivateKey:
+ private := toBase64(p.Seed())
+ return format +
+ "Algorithm: " + algorithm + "\n" +
+ "PrivateKey: " + private + "\n"
+
+ default:
+ return ""
+ }
+}
diff --git a/vendor/github.com/miekg/dns/doc.go b/vendor/github.com/miekg/dns/doc.go
@@ -0,0 +1,292 @@
+/*
+Package dns implements a full featured interface to the Domain Name System.
+Both server- and client-side programming is supported. The package allows
+complete control over what is sent out to the DNS. The API follows the
+less-is-more principle, by presenting a small, clean interface.
+
+It supports (asynchronous) querying/replying, incoming/outgoing zone transfers,
+TSIG, EDNS0, dynamic updates, notifies and DNSSEC validation/signing.
+
+Note that domain names MUST be fully qualified before sending them, unqualified
+names in a message will result in a packing failure.
+
+Resource records are native types. They are not stored in wire format. Basic
+usage pattern for creating a new resource record:
+
+ r := new(dns.MX)
+ r.Hdr = dns.RR_Header{Name: "miek.nl.", Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: 3600}
+ r.Preference = 10
+ r.Mx = "mx.miek.nl."
+
+Or directly from a string:
+
+ mx, err := dns.NewRR("miek.nl. 3600 IN MX 10 mx.miek.nl.")
+
+Or when the default origin (.) and TTL (3600) and class (IN) suit you:
+
+ mx, err := dns.NewRR("miek.nl MX 10 mx.miek.nl")
+
+Or even:
+
+ mx, err := dns.NewRR("$ORIGIN nl.\nmiek 1H IN MX 10 mx.miek")
+
+In the DNS messages are exchanged, these messages contain resource records
+(sets). Use pattern for creating a message:
+
+ m := new(dns.Msg)
+ m.SetQuestion("miek.nl.", dns.TypeMX)
+
+Or when not certain if the domain name is fully qualified:
+
+ m.SetQuestion(dns.Fqdn("miek.nl"), dns.TypeMX)
+
+The message m is now a message with the question section set to ask the MX
+records for the miek.nl. zone.
+
+The following is slightly more verbose, but more flexible:
+
+ m1 := new(dns.Msg)
+ m1.Id = dns.Id()
+ m1.RecursionDesired = true
+ m1.Question = make([]dns.Question, 1)
+ m1.Question[0] = dns.Question{"miek.nl.", dns.TypeMX, dns.ClassINET}
+
+After creating a message it can be sent. Basic use pattern for synchronous
+querying the DNS at a server configured on 127.0.0.1 and port 53:
+
+ c := new(dns.Client)
+ in, rtt, err := c.Exchange(m1, "127.0.0.1:53")
+
+Suppressing multiple outstanding queries (with the same question, type and
+class) is as easy as setting:
+
+ c.SingleInflight = true
+
+More advanced options are available using a net.Dialer and the corresponding API.
+For example it is possible to set a timeout, or to specify a source IP address
+and port to use for the connection:
+
+ c := new(dns.Client)
+ laddr := net.UDPAddr{
+ IP: net.ParseIP("[::1]"),
+ Port: 12345,
+ Zone: "",
+ }
+ c.Dialer := &net.Dialer{
+ Timeout: 200 * time.Millisecond,
+ LocalAddr: &laddr,
+ }
+ in, rtt, err := c.Exchange(m1, "8.8.8.8:53")
+
+If these "advanced" features are not needed, a simple UDP query can be sent,
+with:
+
+ in, err := dns.Exchange(m1, "127.0.0.1:53")
+
+When this functions returns you will get DNS message. A DNS message consists
+out of four sections.
+The question section: in.Question, the answer section: in.Answer,
+the authority section: in.Ns and the additional section: in.Extra.
+
+Each of these sections (except the Question section) contain a []RR. Basic
+use pattern for accessing the rdata of a TXT RR as the first RR in
+the Answer section:
+
+ if t, ok := in.Answer[0].(*dns.TXT); ok {
+ // do something with t.Txt
+ }
+
+Domain Name and TXT Character String Representations
+
+Both domain names and TXT character strings are converted to presentation form
+both when unpacked and when converted to strings.
+
+For TXT character strings, tabs, carriage returns and line feeds will be
+converted to \t, \r and \n respectively. Back slashes and quotations marks will
+be escaped. Bytes below 32 and above 127 will be converted to \DDD form.
+
+For domain names, in addition to the above rules brackets, periods, spaces,
+semicolons and the at symbol are escaped.
+
+DNSSEC
+
+DNSSEC (DNS Security Extension) adds a layer of security to the DNS. It uses
+public key cryptography to sign resource records. The public keys are stored in
+DNSKEY records and the signatures in RRSIG records.
+
+Requesting DNSSEC information for a zone is done by adding the DO (DNSSEC OK)
+bit to a request.
+
+ m := new(dns.Msg)
+ m.SetEdns0(4096, true)
+
+Signature generation, signature verification and key generation are all supported.
+
+DYNAMIC UPDATES
+
+Dynamic updates reuses the DNS message format, but renames three of the
+sections. Question is Zone, Answer is Prerequisite, Authority is Update, only
+the Additional is not renamed. See RFC 2136 for the gory details.
+
+You can set a rather complex set of rules for the existence of absence of
+certain resource records or names in a zone to specify if resource records
+should be added or removed. The table from RFC 2136 supplemented with the Go
+DNS function shows which functions exist to specify the prerequisites.
+
+ 3.2.4 - Table Of Metavalues Used In Prerequisite Section
+
+ CLASS TYPE RDATA Meaning Function
+ --------------------------------------------------------------
+ ANY ANY empty Name is in use dns.NameUsed
+ ANY rrset empty RRset exists (value indep) dns.RRsetUsed
+ NONE ANY empty Name is not in use dns.NameNotUsed
+ NONE rrset empty RRset does not exist dns.RRsetNotUsed
+ zone rrset rr RRset exists (value dep) dns.Used
+
+The prerequisite section can also be left empty. If you have decided on the
+prerequisites you can tell what RRs should be added or deleted. The next table
+shows the options you have and what functions to call.
+
+ 3.4.2.6 - Table Of Metavalues Used In Update Section
+
+ CLASS TYPE RDATA Meaning Function
+ ---------------------------------------------------------------
+ ANY ANY empty Delete all RRsets from name dns.RemoveName
+ ANY rrset empty Delete an RRset dns.RemoveRRset
+ NONE rrset rr Delete an RR from RRset dns.Remove
+ zone rrset rr Add to an RRset dns.Insert
+
+TRANSACTION SIGNATURE
+
+An TSIG or transaction signature adds a HMAC TSIG record to each message sent.
+The supported algorithms include: HmacSHA1, HmacSHA256 and HmacSHA512.
+
+Basic use pattern when querying with a TSIG name "axfr." (note that these key names
+must be fully qualified - as they are domain names) and the base64 secret
+"so6ZGir4GPAqINNh9U5c3A==":
+
+If an incoming message contains a TSIG record it MUST be the last record in
+the additional section (RFC2845 3.2). This means that you should make the
+call to SetTsig last, right before executing the query. If you make any
+changes to the RRset after calling SetTsig() the signature will be incorrect.
+
+ c := new(dns.Client)
+ c.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
+ m := new(dns.Msg)
+ m.SetQuestion("miek.nl.", dns.TypeMX)
+ m.SetTsig("axfr.", dns.HmacSHA256, 300, time.Now().Unix())
+ ...
+ // When sending the TSIG RR is calculated and filled in before sending
+
+When requesting an zone transfer (almost all TSIG usage is when requesting zone
+transfers), with TSIG, this is the basic use pattern. In this example we
+request an AXFR for miek.nl. with TSIG key named "axfr." and secret
+"so6ZGir4GPAqINNh9U5c3A==" and using the server 176.58.119.54:
+
+ t := new(dns.Transfer)
+ m := new(dns.Msg)
+ t.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
+ m.SetAxfr("miek.nl.")
+ m.SetTsig("axfr.", dns.HmacSHA256, 300, time.Now().Unix())
+ c, err := t.In(m, "176.58.119.54:53")
+ for r := range c { ... }
+
+You can now read the records from the transfer as they come in. Each envelope
+is checked with TSIG. If something is not correct an error is returned.
+
+A custom TSIG implementation can be used. This requires additional code to
+perform any session establishment and signature generation/verification. The
+client must be configured with an implementation of the TsigProvider interface:
+
+ type Provider struct{}
+
+ func (*Provider) Generate(msg []byte, tsig *dns.TSIG) ([]byte, error) {
+ // Use tsig.Hdr.Name and tsig.Algorithm in your code to
+ // generate the MAC using msg as the payload.
+ }
+
+ func (*Provider) Verify(msg []byte, tsig *dns.TSIG) error {
+ // Use tsig.Hdr.Name and tsig.Algorithm in your code to verify
+ // that msg matches the value in tsig.MAC.
+ }
+
+ c := new(dns.Client)
+ c.TsigProvider = new(Provider)
+ m := new(dns.Msg)
+ m.SetQuestion("miek.nl.", dns.TypeMX)
+ m.SetTsig(keyname, dns.HmacSHA256, 300, time.Now().Unix())
+ ...
+ // TSIG RR is calculated by calling your Generate method
+
+Basic use pattern validating and replying to a message that has TSIG set.
+
+ server := &dns.Server{Addr: ":53", Net: "udp"}
+ server.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
+ go server.ListenAndServe()
+ dns.HandleFunc(".", handleRequest)
+
+ func handleRequest(w dns.ResponseWriter, r *dns.Msg) {
+ m := new(dns.Msg)
+ m.SetReply(r)
+ if r.IsTsig() != nil {
+ if w.TsigStatus() == nil {
+ // *Msg r has an TSIG record and it was validated
+ m.SetTsig("axfr.", dns.HmacSHA256, 300, time.Now().Unix())
+ } else {
+ // *Msg r has an TSIG records and it was not validated
+ }
+ }
+ w.WriteMsg(m)
+ }
+
+PRIVATE RRS
+
+RFC 6895 sets aside a range of type codes for private use. This range is 65,280
+- 65,534 (0xFF00 - 0xFFFE). When experimenting with new Resource Records these
+can be used, before requesting an official type code from IANA.
+
+See https://miek.nl/2014/september/21/idn-and-private-rr-in-go-dns/ for more
+information.
+
+EDNS0
+
+EDNS0 is an extension mechanism for the DNS defined in RFC 2671 and updated by
+RFC 6891. It defines a new RR type, the OPT RR, which is then completely
+abused.
+
+Basic use pattern for creating an (empty) OPT RR:
+
+ o := new(dns.OPT)
+ o.Hdr.Name = "." // MUST be the root zone, per definition.
+ o.Hdr.Rrtype = dns.TypeOPT
+
+The rdata of an OPT RR consists out of a slice of EDNS0 (RFC 6891) interfaces.
+Currently only a few have been standardized: EDNS0_NSID (RFC 5001) and
+EDNS0_SUBNET (RFC 7871). Note that these options may be combined in an OPT RR.
+Basic use pattern for a server to check if (and which) options are set:
+
+ // o is a dns.OPT
+ for _, s := range o.Option {
+ switch e := s.(type) {
+ case *dns.EDNS0_NSID:
+ // do stuff with e.Nsid
+ case *dns.EDNS0_SUBNET:
+ // access e.Family, e.Address, etc.
+ }
+ }
+
+SIG(0)
+
+From RFC 2931:
+
+ SIG(0) provides protection for DNS transactions and requests ....
+ ... protection for glue records, DNS requests, protection for message headers
+ on requests and responses, and protection of the overall integrity of a response.
+
+It works like TSIG, except that SIG(0) uses public key cryptography, instead of
+the shared secret approach in TSIG. Supported algorithms: ECDSAP256SHA256,
+ECDSAP384SHA384, RSASHA1, RSASHA256 and RSASHA512.
+
+Signing subsequent messages in multi-message sessions is not implemented.
+*/
+package dns
diff --git a/vendor/github.com/miekg/dns/duplicate.go b/vendor/github.com/miekg/dns/duplicate.go
@@ -0,0 +1,37 @@
+package dns
+
+//go:generate go run duplicate_generate.go
+
+// IsDuplicate checks of r1 and r2 are duplicates of each other, excluding the TTL.
+// So this means the header data is equal *and* the RDATA is the same. Returns true
+// if so, otherwise false. It's a protocol violation to have identical RRs in a message.
+func IsDuplicate(r1, r2 RR) bool {
+ // Check whether the record header is identical.
+ if !r1.Header().isDuplicate(r2.Header()) {
+ return false
+ }
+
+ // Check whether the RDATA is identical.
+ return r1.isDuplicate(r2)
+}
+
+func (r1 *RR_Header) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*RR_Header)
+ if !ok {
+ return false
+ }
+ if r1.Class != r2.Class {
+ return false
+ }
+ if r1.Rrtype != r2.Rrtype {
+ return false
+ }
+ if !isDuplicateName(r1.Name, r2.Name) {
+ return false
+ }
+ // ignore TTL
+ return true
+}
+
+// isDuplicateName checks if the domain names s1 and s2 are equal.
+func isDuplicateName(s1, s2 string) bool { return equal(s1, s2) }
diff --git a/vendor/github.com/miekg/dns/edns.go b/vendor/github.com/miekg/dns/edns.go
@@ -0,0 +1,851 @@
+package dns
+
+import (
+ "encoding/binary"
+ "encoding/hex"
+ "errors"
+ "fmt"
+ "net"
+ "strconv"
+)
+
+// EDNS0 Option codes.
+const (
+ EDNS0LLQ = 0x1 // long lived queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01
+ EDNS0UL = 0x2 // update lease draft: http://files.dns-sd.org/draft-sekar-dns-ul.txt
+ EDNS0NSID = 0x3 // nsid (See RFC 5001)
+ EDNS0ESU = 0x4 // ENUM Source-URI draft: https://datatracker.ietf.org/doc/html/draft-kaplan-enum-source-uri-00
+ EDNS0DAU = 0x5 // DNSSEC Algorithm Understood
+ EDNS0DHU = 0x6 // DS Hash Understood
+ EDNS0N3U = 0x7 // NSEC3 Hash Understood
+ EDNS0SUBNET = 0x8 // client-subnet (See RFC 7871)
+ EDNS0EXPIRE = 0x9 // EDNS0 expire
+ EDNS0COOKIE = 0xa // EDNS0 Cookie
+ EDNS0TCPKEEPALIVE = 0xb // EDNS0 tcp keep alive (See RFC 7828)
+ EDNS0PADDING = 0xc // EDNS0 padding (See RFC 7830)
+ EDNS0EDE = 0xf // EDNS0 extended DNS errors (See RFC 8914)
+ EDNS0LOCALSTART = 0xFDE9 // Beginning of range reserved for local/experimental use (See RFC 6891)
+ EDNS0LOCALEND = 0xFFFE // End of range reserved for local/experimental use (See RFC 6891)
+ _DO = 1 << 15 // DNSSEC OK
+)
+
+// makeDataOpt is used to unpack the EDNS0 option(s) from a message.
+func makeDataOpt(code uint16) EDNS0 {
+ // All the EDNS0.* constants above need to be in this switch.
+ switch code {
+ case EDNS0LLQ:
+ return new(EDNS0_LLQ)
+ case EDNS0UL:
+ return new(EDNS0_UL)
+ case EDNS0NSID:
+ return new(EDNS0_NSID)
+ case EDNS0DAU:
+ return new(EDNS0_DAU)
+ case EDNS0DHU:
+ return new(EDNS0_DHU)
+ case EDNS0N3U:
+ return new(EDNS0_N3U)
+ case EDNS0SUBNET:
+ return new(EDNS0_SUBNET)
+ case EDNS0EXPIRE:
+ return new(EDNS0_EXPIRE)
+ case EDNS0COOKIE:
+ return new(EDNS0_COOKIE)
+ case EDNS0TCPKEEPALIVE:
+ return new(EDNS0_TCP_KEEPALIVE)
+ case EDNS0PADDING:
+ return new(EDNS0_PADDING)
+ case EDNS0EDE:
+ return new(EDNS0_EDE)
+ case EDNS0ESU:
+ return &EDNS0_ESU{Code: EDNS0ESU}
+ default:
+ e := new(EDNS0_LOCAL)
+ e.Code = code
+ return e
+ }
+}
+
+// OPT is the EDNS0 RR appended to messages to convey extra (meta) information.
+// See RFC 6891.
+type OPT struct {
+ Hdr RR_Header
+ Option []EDNS0 `dns:"opt"`
+}
+
+func (rr *OPT) String() string {
+ s := "\n;; OPT PSEUDOSECTION:\n; EDNS: version " + strconv.Itoa(int(rr.Version())) + "; "
+ if rr.Do() {
+ s += "flags: do; "
+ } else {
+ s += "flags: ; "
+ }
+ s += "udp: " + strconv.Itoa(int(rr.UDPSize()))
+
+ for _, o := range rr.Option {
+ switch o.(type) {
+ case *EDNS0_NSID:
+ s += "\n; NSID: " + o.String()
+ h, e := o.pack()
+ var r string
+ if e == nil {
+ for _, c := range h {
+ r += "(" + string(c) + ")"
+ }
+ s += " " + r
+ }
+ case *EDNS0_SUBNET:
+ s += "\n; SUBNET: " + o.String()
+ case *EDNS0_COOKIE:
+ s += "\n; COOKIE: " + o.String()
+ case *EDNS0_TCP_KEEPALIVE:
+ s += "\n; KEEPALIVE: " + o.String()
+ case *EDNS0_UL:
+ s += "\n; UPDATE LEASE: " + o.String()
+ case *EDNS0_LLQ:
+ s += "\n; LONG LIVED QUERIES: " + o.String()
+ case *EDNS0_DAU:
+ s += "\n; DNSSEC ALGORITHM UNDERSTOOD: " + o.String()
+ case *EDNS0_DHU:
+ s += "\n; DS HASH UNDERSTOOD: " + o.String()
+ case *EDNS0_N3U:
+ s += "\n; NSEC3 HASH UNDERSTOOD: " + o.String()
+ case *EDNS0_LOCAL:
+ s += "\n; LOCAL OPT: " + o.String()
+ case *EDNS0_PADDING:
+ s += "\n; PADDING: " + o.String()
+ case *EDNS0_EDE:
+ s += "\n; EDE: " + o.String()
+ case *EDNS0_ESU:
+ s += "\n; ESU: " + o.String()
+ }
+ }
+ return s
+}
+
+func (rr *OPT) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ for _, o := range rr.Option {
+ l += 4 // Account for 2-byte option code and 2-byte option length.
+ lo, _ := o.pack()
+ l += len(lo)
+ }
+ return l
+}
+
+func (*OPT) parse(c *zlexer, origin string) *ParseError {
+ return &ParseError{err: "OPT records do not have a presentation format"}
+}
+
+func (rr *OPT) isDuplicate(r2 RR) bool { return false }
+
+// return the old value -> delete SetVersion?
+
+// Version returns the EDNS version used. Only zero is defined.
+func (rr *OPT) Version() uint8 {
+ return uint8(rr.Hdr.Ttl & 0x00FF0000 >> 16)
+}
+
+// SetVersion sets the version of EDNS. This is usually zero.
+func (rr *OPT) SetVersion(v uint8) {
+ rr.Hdr.Ttl = rr.Hdr.Ttl&0xFF00FFFF | uint32(v)<<16
+}
+
+// ExtendedRcode returns the EDNS extended RCODE field (the upper 8 bits of the TTL).
+func (rr *OPT) ExtendedRcode() int {
+ return int(rr.Hdr.Ttl&0xFF000000>>24) << 4
+}
+
+// SetExtendedRcode sets the EDNS extended RCODE field.
+//
+// If the RCODE is not an extended RCODE, will reset the extended RCODE field to 0.
+func (rr *OPT) SetExtendedRcode(v uint16) {
+ rr.Hdr.Ttl = rr.Hdr.Ttl&0x00FFFFFF | uint32(v>>4)<<24
+}
+
+// UDPSize returns the UDP buffer size.
+func (rr *OPT) UDPSize() uint16 {
+ return rr.Hdr.Class
+}
+
+// SetUDPSize sets the UDP buffer size.
+func (rr *OPT) SetUDPSize(size uint16) {
+ rr.Hdr.Class = size
+}
+
+// Do returns the value of the DO (DNSSEC OK) bit.
+func (rr *OPT) Do() bool {
+ return rr.Hdr.Ttl&_DO == _DO
+}
+
+// SetDo sets the DO (DNSSEC OK) bit.
+// If we pass an argument, set the DO bit to that value.
+// It is possible to pass 2 or more arguments. Any arguments after the 1st is silently ignored.
+func (rr *OPT) SetDo(do ...bool) {
+ if len(do) == 1 {
+ if do[0] {
+ rr.Hdr.Ttl |= _DO
+ } else {
+ rr.Hdr.Ttl &^= _DO
+ }
+ } else {
+ rr.Hdr.Ttl |= _DO
+ }
+}
+
+// Z returns the Z part of the OPT RR as a uint16 with only the 15 least significant bits used.
+func (rr *OPT) Z() uint16 {
+ return uint16(rr.Hdr.Ttl & 0x7FFF)
+}
+
+// SetZ sets the Z part of the OPT RR, note only the 15 least significant bits of z are used.
+func (rr *OPT) SetZ(z uint16) {
+ rr.Hdr.Ttl = rr.Hdr.Ttl&^0x7FFF | uint32(z&0x7FFF)
+}
+
+// EDNS0 defines an EDNS0 Option. An OPT RR can have multiple options appended to it.
+type EDNS0 interface {
+ // Option returns the option code for the option.
+ Option() uint16
+ // pack returns the bytes of the option data.
+ pack() ([]byte, error)
+ // unpack sets the data as found in the buffer. Is also sets
+ // the length of the slice as the length of the option data.
+ unpack([]byte) error
+ // String returns the string representation of the option.
+ String() string
+ // copy returns a deep-copy of the option.
+ copy() EDNS0
+}
+
+// EDNS0_NSID option is used to retrieve a nameserver
+// identifier. When sending a request Nsid must be set to the empty string
+// The identifier is an opaque string encoded as hex.
+// Basic use pattern for creating an nsid option:
+//
+// o := new(dns.OPT)
+// o.Hdr.Name = "."
+// o.Hdr.Rrtype = dns.TypeOPT
+// e := new(dns.EDNS0_NSID)
+// e.Code = dns.EDNS0NSID
+// e.Nsid = "AA"
+// o.Option = append(o.Option, e)
+type EDNS0_NSID struct {
+ Code uint16 // Always EDNS0NSID
+ Nsid string // This string needs to be hex encoded
+}
+
+func (e *EDNS0_NSID) pack() ([]byte, error) {
+ h, err := hex.DecodeString(e.Nsid)
+ if err != nil {
+ return nil, err
+ }
+ return h, nil
+}
+
+// Option implements the EDNS0 interface.
+func (e *EDNS0_NSID) Option() uint16 { return EDNS0NSID } // Option returns the option code.
+func (e *EDNS0_NSID) unpack(b []byte) error { e.Nsid = hex.EncodeToString(b); return nil }
+func (e *EDNS0_NSID) String() string { return e.Nsid }
+func (e *EDNS0_NSID) copy() EDNS0 { return &EDNS0_NSID{e.Code, e.Nsid} }
+
+// EDNS0_SUBNET is the subnet option that is used to give the remote nameserver
+// an idea of where the client lives. See RFC 7871. It can then give back a different
+// answer depending on the location or network topology.
+// Basic use pattern for creating an subnet option:
+//
+// o := new(dns.OPT)
+// o.Hdr.Name = "."
+// o.Hdr.Rrtype = dns.TypeOPT
+// e := new(dns.EDNS0_SUBNET)
+// e.Code = dns.EDNS0SUBNET
+// e.Family = 1 // 1 for IPv4 source address, 2 for IPv6
+// e.SourceNetmask = 32 // 32 for IPV4, 128 for IPv6
+// e.SourceScope = 0
+// e.Address = net.ParseIP("127.0.0.1").To4() // for IPv4
+// // e.Address = net.ParseIP("2001:7b8:32a::2") // for IPV6
+// o.Option = append(o.Option, e)
+//
+// This code will parse all the available bits when unpacking (up to optlen).
+// When packing it will apply SourceNetmask. If you need more advanced logic,
+// patches welcome and good luck.
+type EDNS0_SUBNET struct {
+ Code uint16 // Always EDNS0SUBNET
+ Family uint16 // 1 for IP, 2 for IP6
+ SourceNetmask uint8
+ SourceScope uint8
+ Address net.IP
+}
+
+// Option implements the EDNS0 interface.
+func (e *EDNS0_SUBNET) Option() uint16 { return EDNS0SUBNET }
+
+func (e *EDNS0_SUBNET) pack() ([]byte, error) {
+ b := make([]byte, 4)
+ binary.BigEndian.PutUint16(b[0:], e.Family)
+ b[2] = e.SourceNetmask
+ b[3] = e.SourceScope
+ switch e.Family {
+ case 0:
+ // "dig" sets AddressFamily to 0 if SourceNetmask is also 0
+ // We might don't need to complain either
+ if e.SourceNetmask != 0 {
+ return nil, errors.New("dns: bad address family")
+ }
+ case 1:
+ if e.SourceNetmask > net.IPv4len*8 {
+ return nil, errors.New("dns: bad netmask")
+ }
+ if len(e.Address.To4()) != net.IPv4len {
+ return nil, errors.New("dns: bad address")
+ }
+ ip := e.Address.To4().Mask(net.CIDRMask(int(e.SourceNetmask), net.IPv4len*8))
+ needLength := (e.SourceNetmask + 8 - 1) / 8 // division rounding up
+ b = append(b, ip[:needLength]...)
+ case 2:
+ if e.SourceNetmask > net.IPv6len*8 {
+ return nil, errors.New("dns: bad netmask")
+ }
+ if len(e.Address) != net.IPv6len {
+ return nil, errors.New("dns: bad address")
+ }
+ ip := e.Address.Mask(net.CIDRMask(int(e.SourceNetmask), net.IPv6len*8))
+ needLength := (e.SourceNetmask + 8 - 1) / 8 // division rounding up
+ b = append(b, ip[:needLength]...)
+ default:
+ return nil, errors.New("dns: bad address family")
+ }
+ return b, nil
+}
+
+func (e *EDNS0_SUBNET) unpack(b []byte) error {
+ if len(b) < 4 {
+ return ErrBuf
+ }
+ e.Family = binary.BigEndian.Uint16(b)
+ e.SourceNetmask = b[2]
+ e.SourceScope = b[3]
+ switch e.Family {
+ case 0:
+ // "dig" sets AddressFamily to 0 if SourceNetmask is also 0
+ // It's okay to accept such a packet
+ if e.SourceNetmask != 0 {
+ return errors.New("dns: bad address family")
+ }
+ e.Address = net.IPv4(0, 0, 0, 0)
+ case 1:
+ if e.SourceNetmask > net.IPv4len*8 || e.SourceScope > net.IPv4len*8 {
+ return errors.New("dns: bad netmask")
+ }
+ addr := make(net.IP, net.IPv4len)
+ copy(addr, b[4:])
+ e.Address = addr.To16()
+ case 2:
+ if e.SourceNetmask > net.IPv6len*8 || e.SourceScope > net.IPv6len*8 {
+ return errors.New("dns: bad netmask")
+ }
+ addr := make(net.IP, net.IPv6len)
+ copy(addr, b[4:])
+ e.Address = addr
+ default:
+ return errors.New("dns: bad address family")
+ }
+ return nil
+}
+
+func (e *EDNS0_SUBNET) String() (s string) {
+ if e.Address == nil {
+ s = "<nil>"
+ } else if e.Address.To4() != nil {
+ s = e.Address.String()
+ } else {
+ s = "[" + e.Address.String() + "]"
+ }
+ s += "/" + strconv.Itoa(int(e.SourceNetmask)) + "/" + strconv.Itoa(int(e.SourceScope))
+ return
+}
+
+func (e *EDNS0_SUBNET) copy() EDNS0 {
+ return &EDNS0_SUBNET{
+ e.Code,
+ e.Family,
+ e.SourceNetmask,
+ e.SourceScope,
+ e.Address,
+ }
+}
+
+// The EDNS0_COOKIE option is used to add a DNS Cookie to a message.
+//
+// o := new(dns.OPT)
+// o.Hdr.Name = "."
+// o.Hdr.Rrtype = dns.TypeOPT
+// e := new(dns.EDNS0_COOKIE)
+// e.Code = dns.EDNS0COOKIE
+// e.Cookie = "24a5ac.."
+// o.Option = append(o.Option, e)
+//
+// The Cookie field consists out of a client cookie (RFC 7873 Section 4), that is
+// always 8 bytes. It may then optionally be followed by the server cookie. The server
+// cookie is of variable length, 8 to a maximum of 32 bytes. In other words:
+//
+// cCookie := o.Cookie[:16]
+// sCookie := o.Cookie[16:]
+//
+// There is no guarantee that the Cookie string has a specific length.
+type EDNS0_COOKIE struct {
+ Code uint16 // Always EDNS0COOKIE
+ Cookie string // Hex-encoded cookie data
+}
+
+func (e *EDNS0_COOKIE) pack() ([]byte, error) {
+ h, err := hex.DecodeString(e.Cookie)
+ if err != nil {
+ return nil, err
+ }
+ return h, nil
+}
+
+// Option implements the EDNS0 interface.
+func (e *EDNS0_COOKIE) Option() uint16 { return EDNS0COOKIE }
+func (e *EDNS0_COOKIE) unpack(b []byte) error { e.Cookie = hex.EncodeToString(b); return nil }
+func (e *EDNS0_COOKIE) String() string { return e.Cookie }
+func (e *EDNS0_COOKIE) copy() EDNS0 { return &EDNS0_COOKIE{e.Code, e.Cookie} }
+
+// The EDNS0_UL (Update Lease) (draft RFC) option is used to tell the server to set
+// an expiration on an update RR. This is helpful for clients that cannot clean
+// up after themselves. This is a draft RFC and more information can be found at
+// https://tools.ietf.org/html/draft-sekar-dns-ul-02
+//
+// o := new(dns.OPT)
+// o.Hdr.Name = "."
+// o.Hdr.Rrtype = dns.TypeOPT
+// e := new(dns.EDNS0_UL)
+// e.Code = dns.EDNS0UL
+// e.Lease = 120 // in seconds
+// o.Option = append(o.Option, e)
+type EDNS0_UL struct {
+ Code uint16 // Always EDNS0UL
+ Lease uint32
+ KeyLease uint32
+}
+
+// Option implements the EDNS0 interface.
+func (e *EDNS0_UL) Option() uint16 { return EDNS0UL }
+func (e *EDNS0_UL) String() string { return fmt.Sprintf("%d %d", e.Lease, e.KeyLease) }
+func (e *EDNS0_UL) copy() EDNS0 { return &EDNS0_UL{e.Code, e.Lease, e.KeyLease} }
+
+// Copied: http://golang.org/src/pkg/net/dnsmsg.go
+func (e *EDNS0_UL) pack() ([]byte, error) {
+ var b []byte
+ if e.KeyLease == 0 {
+ b = make([]byte, 4)
+ } else {
+ b = make([]byte, 8)
+ binary.BigEndian.PutUint32(b[4:], e.KeyLease)
+ }
+ binary.BigEndian.PutUint32(b, e.Lease)
+ return b, nil
+}
+
+func (e *EDNS0_UL) unpack(b []byte) error {
+ switch len(b) {
+ case 4:
+ e.KeyLease = 0
+ case 8:
+ e.KeyLease = binary.BigEndian.Uint32(b[4:])
+ default:
+ return ErrBuf
+ }
+ e.Lease = binary.BigEndian.Uint32(b)
+ return nil
+}
+
+// EDNS0_LLQ stands for Long Lived Queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01
+// Implemented for completeness, as the EDNS0 type code is assigned.
+type EDNS0_LLQ struct {
+ Code uint16 // Always EDNS0LLQ
+ Version uint16
+ Opcode uint16
+ Error uint16
+ Id uint64
+ LeaseLife uint32
+}
+
+// Option implements the EDNS0 interface.
+func (e *EDNS0_LLQ) Option() uint16 { return EDNS0LLQ }
+
+func (e *EDNS0_LLQ) pack() ([]byte, error) {
+ b := make([]byte, 18)
+ binary.BigEndian.PutUint16(b[0:], e.Version)
+ binary.BigEndian.PutUint16(b[2:], e.Opcode)
+ binary.BigEndian.PutUint16(b[4:], e.Error)
+ binary.BigEndian.PutUint64(b[6:], e.Id)
+ binary.BigEndian.PutUint32(b[14:], e.LeaseLife)
+ return b, nil
+}
+
+func (e *EDNS0_LLQ) unpack(b []byte) error {
+ if len(b) < 18 {
+ return ErrBuf
+ }
+ e.Version = binary.BigEndian.Uint16(b[0:])
+ e.Opcode = binary.BigEndian.Uint16(b[2:])
+ e.Error = binary.BigEndian.Uint16(b[4:])
+ e.Id = binary.BigEndian.Uint64(b[6:])
+ e.LeaseLife = binary.BigEndian.Uint32(b[14:])
+ return nil
+}
+
+func (e *EDNS0_LLQ) String() string {
+ s := strconv.FormatUint(uint64(e.Version), 10) + " " + strconv.FormatUint(uint64(e.Opcode), 10) +
+ " " + strconv.FormatUint(uint64(e.Error), 10) + " " + strconv.FormatUint(e.Id, 10) +
+ " " + strconv.FormatUint(uint64(e.LeaseLife), 10)
+ return s
+}
+func (e *EDNS0_LLQ) copy() EDNS0 {
+ return &EDNS0_LLQ{e.Code, e.Version, e.Opcode, e.Error, e.Id, e.LeaseLife}
+}
+
+// EDNS0_DAU implements the EDNS0 "DNSSEC Algorithm Understood" option. See RFC 6975.
+type EDNS0_DAU struct {
+ Code uint16 // Always EDNS0DAU
+ AlgCode []uint8
+}
+
+// Option implements the EDNS0 interface.
+func (e *EDNS0_DAU) Option() uint16 { return EDNS0DAU }
+func (e *EDNS0_DAU) pack() ([]byte, error) { return e.AlgCode, nil }
+func (e *EDNS0_DAU) unpack(b []byte) error { e.AlgCode = b; return nil }
+
+func (e *EDNS0_DAU) String() string {
+ s := ""
+ for _, alg := range e.AlgCode {
+ if a, ok := AlgorithmToString[alg]; ok {
+ s += " " + a
+ } else {
+ s += " " + strconv.Itoa(int(alg))
+ }
+ }
+ return s
+}
+func (e *EDNS0_DAU) copy() EDNS0 { return &EDNS0_DAU{e.Code, e.AlgCode} }
+
+// EDNS0_DHU implements the EDNS0 "DS Hash Understood" option. See RFC 6975.
+type EDNS0_DHU struct {
+ Code uint16 // Always EDNS0DHU
+ AlgCode []uint8
+}
+
+// Option implements the EDNS0 interface.
+func (e *EDNS0_DHU) Option() uint16 { return EDNS0DHU }
+func (e *EDNS0_DHU) pack() ([]byte, error) { return e.AlgCode, nil }
+func (e *EDNS0_DHU) unpack(b []byte) error { e.AlgCode = b; return nil }
+
+func (e *EDNS0_DHU) String() string {
+ s := ""
+ for _, alg := range e.AlgCode {
+ if a, ok := HashToString[alg]; ok {
+ s += " " + a
+ } else {
+ s += " " + strconv.Itoa(int(alg))
+ }
+ }
+ return s
+}
+func (e *EDNS0_DHU) copy() EDNS0 { return &EDNS0_DHU{e.Code, e.AlgCode} }
+
+// EDNS0_N3U implements the EDNS0 "NSEC3 Hash Understood" option. See RFC 6975.
+type EDNS0_N3U struct {
+ Code uint16 // Always EDNS0N3U
+ AlgCode []uint8
+}
+
+// Option implements the EDNS0 interface.
+func (e *EDNS0_N3U) Option() uint16 { return EDNS0N3U }
+func (e *EDNS0_N3U) pack() ([]byte, error) { return e.AlgCode, nil }
+func (e *EDNS0_N3U) unpack(b []byte) error { e.AlgCode = b; return nil }
+
+func (e *EDNS0_N3U) String() string {
+ // Re-use the hash map
+ s := ""
+ for _, alg := range e.AlgCode {
+ if a, ok := HashToString[alg]; ok {
+ s += " " + a
+ } else {
+ s += " " + strconv.Itoa(int(alg))
+ }
+ }
+ return s
+}
+func (e *EDNS0_N3U) copy() EDNS0 { return &EDNS0_N3U{e.Code, e.AlgCode} }
+
+// EDNS0_EXPIRE implements the EDNS0 option as described in RFC 7314.
+type EDNS0_EXPIRE struct {
+ Code uint16 // Always EDNS0EXPIRE
+ Expire uint32
+ Empty bool // Empty is used to signal an empty Expire option in a backwards compatible way, it's not used on the wire.
+}
+
+// Option implements the EDNS0 interface.
+func (e *EDNS0_EXPIRE) Option() uint16 { return EDNS0EXPIRE }
+func (e *EDNS0_EXPIRE) copy() EDNS0 { return &EDNS0_EXPIRE{e.Code, e.Expire, e.Empty} }
+
+func (e *EDNS0_EXPIRE) pack() ([]byte, error) {
+ if e.Empty {
+ return []byte{}, nil
+ }
+ b := make([]byte, 4)
+ binary.BigEndian.PutUint32(b, e.Expire)
+ return b, nil
+}
+
+func (e *EDNS0_EXPIRE) unpack(b []byte) error {
+ if len(b) == 0 {
+ // zero-length EXPIRE query, see RFC 7314 Section 2
+ e.Empty = true
+ return nil
+ }
+ if len(b) < 4 {
+ return ErrBuf
+ }
+ e.Expire = binary.BigEndian.Uint32(b)
+ e.Empty = false
+ return nil
+}
+
+func (e *EDNS0_EXPIRE) String() (s string) {
+ if e.Empty {
+ return ""
+ }
+ return strconv.FormatUint(uint64(e.Expire), 10)
+}
+
+// The EDNS0_LOCAL option is used for local/experimental purposes. The option
+// code is recommended to be within the range [EDNS0LOCALSTART, EDNS0LOCALEND]
+// (RFC6891), although any unassigned code can actually be used. The content of
+// the option is made available in Data, unaltered.
+// Basic use pattern for creating a local option:
+//
+// o := new(dns.OPT)
+// o.Hdr.Name = "."
+// o.Hdr.Rrtype = dns.TypeOPT
+// e := new(dns.EDNS0_LOCAL)
+// e.Code = dns.EDNS0LOCALSTART
+// e.Data = []byte{72, 82, 74}
+// o.Option = append(o.Option, e)
+type EDNS0_LOCAL struct {
+ Code uint16
+ Data []byte
+}
+
+// Option implements the EDNS0 interface.
+func (e *EDNS0_LOCAL) Option() uint16 { return e.Code }
+func (e *EDNS0_LOCAL) String() string {
+ return strconv.FormatInt(int64(e.Code), 10) + ":0x" + hex.EncodeToString(e.Data)
+}
+func (e *EDNS0_LOCAL) copy() EDNS0 {
+ b := make([]byte, len(e.Data))
+ copy(b, e.Data)
+ return &EDNS0_LOCAL{e.Code, b}
+}
+
+func (e *EDNS0_LOCAL) pack() ([]byte, error) {
+ b := make([]byte, len(e.Data))
+ copied := copy(b, e.Data)
+ if copied != len(e.Data) {
+ return nil, ErrBuf
+ }
+ return b, nil
+}
+
+func (e *EDNS0_LOCAL) unpack(b []byte) error {
+ e.Data = make([]byte, len(b))
+ copied := copy(e.Data, b)
+ if copied != len(b) {
+ return ErrBuf
+ }
+ return nil
+}
+
+// EDNS0_TCP_KEEPALIVE is an EDNS0 option that instructs the server to keep
+// the TCP connection alive. See RFC 7828.
+type EDNS0_TCP_KEEPALIVE struct {
+ Code uint16 // Always EDNSTCPKEEPALIVE
+
+ // Timeout is an idle timeout value for the TCP connection, specified in
+ // units of 100 milliseconds, encoded in network byte order. If set to 0,
+ // pack will return a nil slice.
+ Timeout uint16
+
+ // Length is the option's length.
+ // Deprecated: this field is deprecated and is always equal to 0.
+ Length uint16
+}
+
+// Option implements the EDNS0 interface.
+func (e *EDNS0_TCP_KEEPALIVE) Option() uint16 { return EDNS0TCPKEEPALIVE }
+
+func (e *EDNS0_TCP_KEEPALIVE) pack() ([]byte, error) {
+ if e.Timeout > 0 {
+ b := make([]byte, 2)
+ binary.BigEndian.PutUint16(b, e.Timeout)
+ return b, nil
+ }
+ return nil, nil
+}
+
+func (e *EDNS0_TCP_KEEPALIVE) unpack(b []byte) error {
+ switch len(b) {
+ case 0:
+ case 2:
+ e.Timeout = binary.BigEndian.Uint16(b)
+ default:
+ return fmt.Errorf("dns: length mismatch, want 0/2 but got %d", len(b))
+ }
+ return nil
+}
+
+func (e *EDNS0_TCP_KEEPALIVE) String() string {
+ s := "use tcp keep-alive"
+ if e.Timeout == 0 {
+ s += ", timeout omitted"
+ } else {
+ s += fmt.Sprintf(", timeout %dms", e.Timeout*100)
+ }
+ return s
+}
+
+func (e *EDNS0_TCP_KEEPALIVE) copy() EDNS0 { return &EDNS0_TCP_KEEPALIVE{e.Code, e.Timeout, e.Length} }
+
+// EDNS0_PADDING option is used to add padding to a request/response. The default
+// value of padding SHOULD be 0x0 but other values MAY be used, for instance if
+// compression is applied before encryption which may break signatures.
+type EDNS0_PADDING struct {
+ Padding []byte
+}
+
+// Option implements the EDNS0 interface.
+func (e *EDNS0_PADDING) Option() uint16 { return EDNS0PADDING }
+func (e *EDNS0_PADDING) pack() ([]byte, error) { return e.Padding, nil }
+func (e *EDNS0_PADDING) unpack(b []byte) error { e.Padding = b; return nil }
+func (e *EDNS0_PADDING) String() string { return fmt.Sprintf("%0X", e.Padding) }
+func (e *EDNS0_PADDING) copy() EDNS0 {
+ b := make([]byte, len(e.Padding))
+ copy(b, e.Padding)
+ return &EDNS0_PADDING{b}
+}
+
+// Extended DNS Error Codes (RFC 8914).
+const (
+ ExtendedErrorCodeOther uint16 = iota
+ ExtendedErrorCodeUnsupportedDNSKEYAlgorithm
+ ExtendedErrorCodeUnsupportedDSDigestType
+ ExtendedErrorCodeStaleAnswer
+ ExtendedErrorCodeForgedAnswer
+ ExtendedErrorCodeDNSSECIndeterminate
+ ExtendedErrorCodeDNSBogus
+ ExtendedErrorCodeSignatureExpired
+ ExtendedErrorCodeSignatureNotYetValid
+ ExtendedErrorCodeDNSKEYMissing
+ ExtendedErrorCodeRRSIGsMissing
+ ExtendedErrorCodeNoZoneKeyBitSet
+ ExtendedErrorCodeNSECMissing
+ ExtendedErrorCodeCachedError
+ ExtendedErrorCodeNotReady
+ ExtendedErrorCodeBlocked
+ ExtendedErrorCodeCensored
+ ExtendedErrorCodeFiltered
+ ExtendedErrorCodeProhibited
+ ExtendedErrorCodeStaleNXDOMAINAnswer
+ ExtendedErrorCodeNotAuthoritative
+ ExtendedErrorCodeNotSupported
+ ExtendedErrorCodeNoReachableAuthority
+ ExtendedErrorCodeNetworkError
+ ExtendedErrorCodeInvalidData
+)
+
+// ExtendedErrorCodeToString maps extended error info codes to a human readable
+// description.
+var ExtendedErrorCodeToString = map[uint16]string{
+ ExtendedErrorCodeOther: "Other",
+ ExtendedErrorCodeUnsupportedDNSKEYAlgorithm: "Unsupported DNSKEY Algorithm",
+ ExtendedErrorCodeUnsupportedDSDigestType: "Unsupported DS Digest Type",
+ ExtendedErrorCodeStaleAnswer: "Stale Answer",
+ ExtendedErrorCodeForgedAnswer: "Forged Answer",
+ ExtendedErrorCodeDNSSECIndeterminate: "DNSSEC Indeterminate",
+ ExtendedErrorCodeDNSBogus: "DNSSEC Bogus",
+ ExtendedErrorCodeSignatureExpired: "Signature Expired",
+ ExtendedErrorCodeSignatureNotYetValid: "Signature Not Yet Valid",
+ ExtendedErrorCodeDNSKEYMissing: "DNSKEY Missing",
+ ExtendedErrorCodeRRSIGsMissing: "RRSIGs Missing",
+ ExtendedErrorCodeNoZoneKeyBitSet: "No Zone Key Bit Set",
+ ExtendedErrorCodeNSECMissing: "NSEC Missing",
+ ExtendedErrorCodeCachedError: "Cached Error",
+ ExtendedErrorCodeNotReady: "Not Ready",
+ ExtendedErrorCodeBlocked: "Blocked",
+ ExtendedErrorCodeCensored: "Censored",
+ ExtendedErrorCodeFiltered: "Filtered",
+ ExtendedErrorCodeProhibited: "Prohibited",
+ ExtendedErrorCodeStaleNXDOMAINAnswer: "Stale NXDOMAIN Answer",
+ ExtendedErrorCodeNotAuthoritative: "Not Authoritative",
+ ExtendedErrorCodeNotSupported: "Not Supported",
+ ExtendedErrorCodeNoReachableAuthority: "No Reachable Authority",
+ ExtendedErrorCodeNetworkError: "Network Error",
+ ExtendedErrorCodeInvalidData: "Invalid Data",
+}
+
+// StringToExtendedErrorCode is a map from human readable descriptions to
+// extended error info codes.
+var StringToExtendedErrorCode = reverseInt16(ExtendedErrorCodeToString)
+
+// EDNS0_EDE option is used to return additional information about the cause of
+// DNS errors.
+type EDNS0_EDE struct {
+ InfoCode uint16
+ ExtraText string
+}
+
+// Option implements the EDNS0 interface.
+func (e *EDNS0_EDE) Option() uint16 { return EDNS0EDE }
+func (e *EDNS0_EDE) copy() EDNS0 { return &EDNS0_EDE{e.InfoCode, e.ExtraText} }
+
+func (e *EDNS0_EDE) String() string {
+ info := strconv.FormatUint(uint64(e.InfoCode), 10)
+ if s, ok := ExtendedErrorCodeToString[e.InfoCode]; ok {
+ info += fmt.Sprintf(" (%s)", s)
+ }
+ return fmt.Sprintf("%s: (%s)", info, e.ExtraText)
+}
+
+func (e *EDNS0_EDE) pack() ([]byte, error) {
+ b := make([]byte, 2+len(e.ExtraText))
+ binary.BigEndian.PutUint16(b[0:], e.InfoCode)
+ copy(b[2:], []byte(e.ExtraText))
+ return b, nil
+}
+
+func (e *EDNS0_EDE) unpack(b []byte) error {
+ if len(b) < 2 {
+ return ErrBuf
+ }
+ e.InfoCode = binary.BigEndian.Uint16(b[0:])
+ e.ExtraText = string(b[2:])
+ return nil
+}
+
+// The EDNS0_ESU option for ENUM Source-URI Extension
+type EDNS0_ESU struct {
+ Code uint16
+ Uri string
+}
+
+// Option implements the EDNS0 interface.
+func (e *EDNS0_ESU) Option() uint16 { return EDNS0ESU }
+func (e *EDNS0_ESU) String() string { return e.Uri }
+func (e *EDNS0_ESU) copy() EDNS0 { return &EDNS0_ESU{e.Code, e.Uri} }
+func (e *EDNS0_ESU) pack() ([]byte, error) { return []byte(e.Uri), nil }
+func (e *EDNS0_ESU) unpack(b []byte) error {
+ e.Uri = string(b)
+ return nil
+}
diff --git a/vendor/github.com/miekg/dns/format.go b/vendor/github.com/miekg/dns/format.go
@@ -0,0 +1,93 @@
+package dns
+
+import (
+ "net"
+ "reflect"
+ "strconv"
+)
+
+// NumField returns the number of rdata fields r has.
+func NumField(r RR) int {
+ return reflect.ValueOf(r).Elem().NumField() - 1 // Remove RR_Header
+}
+
+// Field returns the rdata field i as a string. Fields are indexed starting from 1.
+// RR types that holds slice data, for instance the NSEC type bitmap will return a single
+// string where the types are concatenated using a space.
+// Accessing non existing fields will cause a panic.
+func Field(r RR, i int) string {
+ if i == 0 {
+ return ""
+ }
+ d := reflect.ValueOf(r).Elem().Field(i)
+ switch d.Kind() {
+ case reflect.String:
+ return d.String()
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return strconv.FormatInt(d.Int(), 10)
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ return strconv.FormatUint(d.Uint(), 10)
+ case reflect.Slice:
+ switch reflect.ValueOf(r).Elem().Type().Field(i).Tag {
+ case `dns:"a"`:
+ // TODO(miek): Hmm store this as 16 bytes
+ if d.Len() < net.IPv4len {
+ return ""
+ }
+ if d.Len() < net.IPv6len {
+ return net.IPv4(byte(d.Index(0).Uint()),
+ byte(d.Index(1).Uint()),
+ byte(d.Index(2).Uint()),
+ byte(d.Index(3).Uint())).String()
+ }
+ return net.IPv4(byte(d.Index(12).Uint()),
+ byte(d.Index(13).Uint()),
+ byte(d.Index(14).Uint()),
+ byte(d.Index(15).Uint())).String()
+ case `dns:"aaaa"`:
+ if d.Len() < net.IPv6len {
+ return ""
+ }
+ return net.IP{
+ byte(d.Index(0).Uint()),
+ byte(d.Index(1).Uint()),
+ byte(d.Index(2).Uint()),
+ byte(d.Index(3).Uint()),
+ byte(d.Index(4).Uint()),
+ byte(d.Index(5).Uint()),
+ byte(d.Index(6).Uint()),
+ byte(d.Index(7).Uint()),
+ byte(d.Index(8).Uint()),
+ byte(d.Index(9).Uint()),
+ byte(d.Index(10).Uint()),
+ byte(d.Index(11).Uint()),
+ byte(d.Index(12).Uint()),
+ byte(d.Index(13).Uint()),
+ byte(d.Index(14).Uint()),
+ byte(d.Index(15).Uint()),
+ }.String()
+ case `dns:"nsec"`:
+ if d.Len() == 0 {
+ return ""
+ }
+ s := Type(d.Index(0).Uint()).String()
+ for i := 1; i < d.Len(); i++ {
+ s += " " + Type(d.Index(i).Uint()).String()
+ }
+ return s
+ default:
+ // if it does not have a tag its a string slice
+ fallthrough
+ case `dns:"txt"`:
+ if d.Len() == 0 {
+ return ""
+ }
+ s := d.Index(0).String()
+ for i := 1; i < d.Len(); i++ {
+ s += " " + d.Index(i).String()
+ }
+ return s
+ }
+ }
+ return ""
+}
diff --git a/vendor/github.com/miekg/dns/fuzz.go b/vendor/github.com/miekg/dns/fuzz.go
@@ -0,0 +1,32 @@
+// +build fuzz
+
+package dns
+
+import "strings"
+
+func Fuzz(data []byte) int {
+ msg := new(Msg)
+
+ if err := msg.Unpack(data); err != nil {
+ return 0
+ }
+ if _, err := msg.Pack(); err != nil {
+ return 0
+ }
+
+ return 1
+}
+
+func FuzzNewRR(data []byte) int {
+ str := string(data)
+ // Do not fuzz lines that include the $INCLUDE keyword and hint the fuzzer
+ // at avoiding them.
+ // See GH#1025 for context.
+ if strings.Contains(strings.ToUpper(str), "$INCLUDE") {
+ return -1
+ }
+ if _, err := NewRR(str); err != nil {
+ return 0
+ }
+ return 1
+}
diff --git a/vendor/github.com/miekg/dns/generate.go b/vendor/github.com/miekg/dns/generate.go
@@ -0,0 +1,247 @@
+package dns
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "strconv"
+ "strings"
+)
+
+// Parse the $GENERATE statement as used in BIND9 zones.
+// See http://www.zytrax.com/books/dns/ch8/generate.html for instance.
+// We are called after '$GENERATE '. After which we expect:
+// * the range (12-24/2)
+// * lhs (ownername)
+// * [[ttl][class]]
+// * type
+// * rhs (rdata)
+// But we are lazy here, only the range is parsed *all* occurrences
+// of $ after that are interpreted.
+func (zp *ZoneParser) generate(l lex) (RR, bool) {
+ token := l.token
+ step := int64(1)
+ if i := strings.IndexByte(token, '/'); i >= 0 {
+ if i+1 == len(token) {
+ return zp.setParseError("bad step in $GENERATE range", l)
+ }
+
+ s, err := strconv.ParseInt(token[i+1:], 10, 64)
+ if err != nil || s <= 0 {
+ return zp.setParseError("bad step in $GENERATE range", l)
+ }
+
+ step = s
+ token = token[:i]
+ }
+
+ sx := strings.SplitN(token, "-", 2)
+ if len(sx) != 2 {
+ return zp.setParseError("bad start-stop in $GENERATE range", l)
+ }
+
+ start, err := strconv.ParseInt(sx[0], 10, 64)
+ if err != nil {
+ return zp.setParseError("bad start in $GENERATE range", l)
+ }
+
+ end, err := strconv.ParseInt(sx[1], 10, 64)
+ if err != nil {
+ return zp.setParseError("bad stop in $GENERATE range", l)
+ }
+ if end < 0 || start < 0 || end < start || (end-start)/step > 65535 {
+ return zp.setParseError("bad range in $GENERATE range", l)
+ }
+
+ // _BLANK
+ l, ok := zp.c.Next()
+ if !ok || l.value != zBlank {
+ return zp.setParseError("garbage after $GENERATE range", l)
+ }
+
+ // Create a complete new string, which we then parse again.
+ var s string
+ for l, ok := zp.c.Next(); ok; l, ok = zp.c.Next() {
+ if l.err {
+ return zp.setParseError("bad data in $GENERATE directive", l)
+ }
+ if l.value == zNewline {
+ break
+ }
+
+ s += l.token
+ }
+
+ r := &generateReader{
+ s: s,
+
+ cur: start,
+ start: start,
+ end: end,
+ step: step,
+
+ file: zp.file,
+ lex: &l,
+ }
+ zp.sub = NewZoneParser(r, zp.origin, zp.file)
+ zp.sub.includeDepth, zp.sub.includeAllowed = zp.includeDepth, zp.includeAllowed
+ zp.sub.generateDisallowed = true
+ zp.sub.SetDefaultTTL(defaultTtl)
+ return zp.subNext()
+}
+
+type generateReader struct {
+ s string
+ si int
+
+ cur int64
+ start int64
+ end int64
+ step int64
+
+ mod bytes.Buffer
+
+ escape bool
+
+ eof bool
+
+ file string
+ lex *lex
+}
+
+func (r *generateReader) parseError(msg string, end int) *ParseError {
+ r.eof = true // Make errors sticky.
+
+ l := *r.lex
+ l.token = r.s[r.si-1 : end]
+ l.column += r.si // l.column starts one zBLANK before r.s
+
+ return &ParseError{r.file, msg, l}
+}
+
+func (r *generateReader) Read(p []byte) (int, error) {
+ // NewZLexer, through NewZoneParser, should use ReadByte and
+ // not end up here.
+
+ panic("not implemented")
+}
+
+func (r *generateReader) ReadByte() (byte, error) {
+ if r.eof {
+ return 0, io.EOF
+ }
+ if r.mod.Len() > 0 {
+ return r.mod.ReadByte()
+ }
+
+ if r.si >= len(r.s) {
+ r.si = 0
+ r.cur += r.step
+
+ r.eof = r.cur > r.end || r.cur < 0
+ return '\n', nil
+ }
+
+ si := r.si
+ r.si++
+
+ switch r.s[si] {
+ case '\\':
+ if r.escape {
+ r.escape = false
+ return '\\', nil
+ }
+
+ r.escape = true
+ return r.ReadByte()
+ case '$':
+ if r.escape {
+ r.escape = false
+ return '$', nil
+ }
+
+ mod := "%d"
+
+ if si >= len(r.s)-1 {
+ // End of the string
+ fmt.Fprintf(&r.mod, mod, r.cur)
+ return r.mod.ReadByte()
+ }
+
+ if r.s[si+1] == '$' {
+ r.si++
+ return '$', nil
+ }
+
+ var offset int64
+
+ // Search for { and }
+ if r.s[si+1] == '{' {
+ // Modifier block
+ sep := strings.Index(r.s[si+2:], "}")
+ if sep < 0 {
+ return 0, r.parseError("bad modifier in $GENERATE", len(r.s))
+ }
+
+ var errMsg string
+ mod, offset, errMsg = modToPrintf(r.s[si+2 : si+2+sep])
+ if errMsg != "" {
+ return 0, r.parseError(errMsg, si+3+sep)
+ }
+ if r.start+offset < 0 || r.end+offset > 1<<31-1 {
+ return 0, r.parseError("bad offset in $GENERATE", si+3+sep)
+ }
+
+ r.si += 2 + sep // Jump to it
+ }
+
+ fmt.Fprintf(&r.mod, mod, r.cur+offset)
+ return r.mod.ReadByte()
+ default:
+ if r.escape { // Pretty useless here
+ r.escape = false
+ return r.ReadByte()
+ }
+
+ return r.s[si], nil
+ }
+}
+
+// Convert a $GENERATE modifier 0,0,d to something Printf can deal with.
+func modToPrintf(s string) (string, int64, string) {
+ // Modifier is { offset [ ,width [ ,base ] ] } - provide default
+ // values for optional width and type, if necessary.
+ var offStr, widthStr, base string
+ switch xs := strings.Split(s, ","); len(xs) {
+ case 1:
+ offStr, widthStr, base = xs[0], "0", "d"
+ case 2:
+ offStr, widthStr, base = xs[0], xs[1], "d"
+ case 3:
+ offStr, widthStr, base = xs[0], xs[1], xs[2]
+ default:
+ return "", 0, "bad modifier in $GENERATE"
+ }
+
+ switch base {
+ case "o", "d", "x", "X":
+ default:
+ return "", 0, "bad base in $GENERATE"
+ }
+
+ offset, err := strconv.ParseInt(offStr, 10, 64)
+ if err != nil {
+ return "", 0, "bad offset in $GENERATE"
+ }
+
+ width, err := strconv.ParseInt(widthStr, 10, 64)
+ if err != nil || width < 0 || width > 255 {
+ return "", 0, "bad width in $GENERATE"
+ }
+
+ if width == 0 {
+ return "%" + base, offset, ""
+ }
+
+ return "%0" + widthStr + base, offset, ""
+}
diff --git a/vendor/github.com/miekg/dns/hash.go b/vendor/github.com/miekg/dns/hash.go
@@ -0,0 +1,31 @@
+package dns
+
+import (
+ "bytes"
+ "crypto"
+ "hash"
+)
+
+// identityHash will not hash, it only buffers the data written into it and returns it as-is.
+type identityHash struct {
+ b *bytes.Buffer
+}
+
+// Implement the hash.Hash interface.
+
+func (i identityHash) Write(b []byte) (int, error) { return i.b.Write(b) }
+func (i identityHash) Size() int { return i.b.Len() }
+func (i identityHash) BlockSize() int { return 1024 }
+func (i identityHash) Reset() { i.b.Reset() }
+func (i identityHash) Sum(b []byte) []byte { return append(b, i.b.Bytes()...) }
+
+func hashFromAlgorithm(alg uint8) (hash.Hash, crypto.Hash, error) {
+ hashnumber, ok := AlgorithmToHash[alg]
+ if !ok {
+ return nil, 0, ErrAlg
+ }
+ if hashnumber == 0 {
+ return identityHash{b: &bytes.Buffer{}}, hashnumber, nil
+ }
+ return hashnumber.New(), hashnumber, nil
+}
diff --git a/vendor/github.com/miekg/dns/labels.go b/vendor/github.com/miekg/dns/labels.go
@@ -0,0 +1,212 @@
+package dns
+
+// Holds a bunch of helper functions for dealing with labels.
+
+// SplitDomainName splits a name string into it's labels.
+// www.miek.nl. returns []string{"www", "miek", "nl"}
+// .www.miek.nl. returns []string{"", "www", "miek", "nl"},
+// The root label (.) returns nil. Note that using
+// strings.Split(s) will work in most cases, but does not handle
+// escaped dots (\.) for instance.
+// s must be a syntactically valid domain name, see IsDomainName.
+func SplitDomainName(s string) (labels []string) {
+ if s == "" {
+ return nil
+ }
+ fqdnEnd := 0 // offset of the final '.' or the length of the name
+ idx := Split(s)
+ begin := 0
+ if IsFqdn(s) {
+ fqdnEnd = len(s) - 1
+ } else {
+ fqdnEnd = len(s)
+ }
+
+ switch len(idx) {
+ case 0:
+ return nil
+ case 1:
+ // no-op
+ default:
+ for _, end := range idx[1:] {
+ labels = append(labels, s[begin:end-1])
+ begin = end
+ }
+ }
+
+ return append(labels, s[begin:fqdnEnd])
+}
+
+// CompareDomainName compares the names s1 and s2 and
+// returns how many labels they have in common starting from the *right*.
+// The comparison stops at the first inequality. The names are downcased
+// before the comparison.
+//
+// www.miek.nl. and miek.nl. have two labels in common: miek and nl
+// www.miek.nl. and www.bla.nl. have one label in common: nl
+//
+// s1 and s2 must be syntactically valid domain names.
+func CompareDomainName(s1, s2 string) (n int) {
+ // the first check: root label
+ if s1 == "." || s2 == "." {
+ return 0
+ }
+
+ l1 := Split(s1)
+ l2 := Split(s2)
+
+ j1 := len(l1) - 1 // end
+ i1 := len(l1) - 2 // start
+ j2 := len(l2) - 1
+ i2 := len(l2) - 2
+ // the second check can be done here: last/only label
+ // before we fall through into the for-loop below
+ if equal(s1[l1[j1]:], s2[l2[j2]:]) {
+ n++
+ } else {
+ return
+ }
+ for {
+ if i1 < 0 || i2 < 0 {
+ break
+ }
+ if equal(s1[l1[i1]:l1[j1]], s2[l2[i2]:l2[j2]]) {
+ n++
+ } else {
+ break
+ }
+ j1--
+ i1--
+ j2--
+ i2--
+ }
+ return
+}
+
+// CountLabel counts the number of labels in the string s.
+// s must be a syntactically valid domain name.
+func CountLabel(s string) (labels int) {
+ if s == "." {
+ return
+ }
+ off := 0
+ end := false
+ for {
+ off, end = NextLabel(s, off)
+ labels++
+ if end {
+ return
+ }
+ }
+}
+
+// Split splits a name s into its label indexes.
+// www.miek.nl. returns []int{0, 4, 9}, www.miek.nl also returns []int{0, 4, 9}.
+// The root name (.) returns nil. Also see SplitDomainName.
+// s must be a syntactically valid domain name.
+func Split(s string) []int {
+ if s == "." {
+ return nil
+ }
+ idx := make([]int, 1, 3)
+ off := 0
+ end := false
+
+ for {
+ off, end = NextLabel(s, off)
+ if end {
+ return idx
+ }
+ idx = append(idx, off)
+ }
+}
+
+// NextLabel returns the index of the start of the next label in the
+// string s starting at offset.
+// The bool end is true when the end of the string has been reached.
+// Also see PrevLabel.
+func NextLabel(s string, offset int) (i int, end bool) {
+ if s == "" {
+ return 0, true
+ }
+ for i = offset; i < len(s)-1; i++ {
+ if s[i] != '.' {
+ continue
+ }
+ j := i - 1
+ for j >= 0 && s[j] == '\\' {
+ j--
+ }
+
+ if (j-i)%2 == 0 {
+ continue
+ }
+
+ return i + 1, false
+ }
+ return i + 1, true
+}
+
+// PrevLabel returns the index of the label when starting from the right and
+// jumping n labels to the left.
+// The bool start is true when the start of the string has been overshot.
+// Also see NextLabel.
+func PrevLabel(s string, n int) (i int, start bool) {
+ if s == "" {
+ return 0, true
+ }
+ if n == 0 {
+ return len(s), false
+ }
+
+ l := len(s) - 1
+ if s[l] == '.' {
+ l--
+ }
+
+ for ; l >= 0 && n > 0; l-- {
+ if s[l] != '.' {
+ continue
+ }
+ j := l - 1
+ for j >= 0 && s[j] == '\\' {
+ j--
+ }
+
+ if (j-l)%2 == 0 {
+ continue
+ }
+
+ n--
+ if n == 0 {
+ return l + 1, false
+ }
+ }
+
+ return 0, n > 1
+}
+
+// equal compares a and b while ignoring case. It returns true when equal otherwise false.
+func equal(a, b string) bool {
+ // might be lifted into API function.
+ la := len(a)
+ lb := len(b)
+ if la != lb {
+ return false
+ }
+
+ for i := la - 1; i >= 0; i-- {
+ ai := a[i]
+ bi := b[i]
+ if ai >= 'A' && ai <= 'Z' {
+ ai |= 'a' - 'A'
+ }
+ if bi >= 'A' && bi <= 'Z' {
+ bi |= 'a' - 'A'
+ }
+ if ai != bi {
+ return false
+ }
+ }
+ return true
+}
diff --git a/vendor/github.com/miekg/dns/listen_no_reuseport.go b/vendor/github.com/miekg/dns/listen_no_reuseport.go
@@ -0,0 +1,23 @@
+// +build !go1.11 !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd
+
+package dns
+
+import "net"
+
+const supportsReusePort = false
+
+func listenTCP(network, addr string, reuseport bool) (net.Listener, error) {
+ if reuseport {
+ // TODO(tmthrgd): return an error?
+ }
+
+ return net.Listen(network, addr)
+}
+
+func listenUDP(network, addr string, reuseport bool) (net.PacketConn, error) {
+ if reuseport {
+ // TODO(tmthrgd): return an error?
+ }
+
+ return net.ListenPacket(network, addr)
+}
diff --git a/vendor/github.com/miekg/dns/listen_reuseport.go b/vendor/github.com/miekg/dns/listen_reuseport.go
@@ -0,0 +1,44 @@
+// +build go1.11
+// +build aix darwin dragonfly freebsd linux netbsd openbsd
+
+package dns
+
+import (
+ "context"
+ "net"
+ "syscall"
+
+ "golang.org/x/sys/unix"
+)
+
+const supportsReusePort = true
+
+func reuseportControl(network, address string, c syscall.RawConn) error {
+ var opErr error
+ err := c.Control(func(fd uintptr) {
+ opErr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1)
+ })
+ if err != nil {
+ return err
+ }
+
+ return opErr
+}
+
+func listenTCP(network, addr string, reuseport bool) (net.Listener, error) {
+ var lc net.ListenConfig
+ if reuseport {
+ lc.Control = reuseportControl
+ }
+
+ return lc.Listen(context.Background(), network, addr)
+}
+
+func listenUDP(network, addr string, reuseport bool) (net.PacketConn, error) {
+ var lc net.ListenConfig
+ if reuseport {
+ lc.Control = reuseportControl
+ }
+
+ return lc.ListenPacket(context.Background(), network, addr)
+}
diff --git a/vendor/github.com/miekg/dns/msg.go b/vendor/github.com/miekg/dns/msg.go
@@ -0,0 +1,1202 @@
+// DNS packet assembly, see RFC 1035. Converting from - Unpack() -
+// and to - Pack() - wire format.
+// All the packers and unpackers take a (msg []byte, off int)
+// and return (off1 int, ok bool). If they return ok==false, they
+// also return off1==len(msg), so that the next unpacker will
+// also fail. This lets us avoid checks of ok until the end of a
+// packing sequence.
+
+package dns
+
+//go:generate go run msg_generate.go
+
+import (
+ "crypto/rand"
+ "encoding/binary"
+ "fmt"
+ "math/big"
+ "strconv"
+ "strings"
+)
+
+const (
+ maxCompressionOffset = 2 << 13 // We have 14 bits for the compression pointer
+ maxDomainNameWireOctets = 255 // See RFC 1035 section 2.3.4
+
+ // This is the maximum number of compression pointers that should occur in a
+ // semantically valid message. Each label in a domain name must be at least one
+ // octet and is separated by a period. The root label won't be represented by a
+ // compression pointer to a compression pointer, hence the -2 to exclude the
+ // smallest valid root label.
+ //
+ // It is possible to construct a valid message that has more compression pointers
+ // than this, and still doesn't loop, by pointing to a previous pointer. This is
+ // not something a well written implementation should ever do, so we leave them
+ // to trip the maximum compression pointer check.
+ maxCompressionPointers = (maxDomainNameWireOctets+1)/2 - 2
+
+ // This is the maximum length of a domain name in presentation format. The
+ // maximum wire length of a domain name is 255 octets (see above), with the
+ // maximum label length being 63. The wire format requires one extra byte over
+ // the presentation format, reducing the number of octets by 1. Each label in
+ // the name will be separated by a single period, with each octet in the label
+ // expanding to at most 4 bytes (\DDD). If all other labels are of the maximum
+ // length, then the final label can only be 61 octets long to not exceed the
+ // maximum allowed wire length.
+ maxDomainNamePresentationLength = 61*4 + 1 + 63*4 + 1 + 63*4 + 1 + 63*4 + 1
+)
+
+// Errors defined in this package.
+var (
+ ErrAlg error = &Error{err: "bad algorithm"} // ErrAlg indicates an error with the (DNSSEC) algorithm.
+ ErrAuth error = &Error{err: "bad authentication"} // ErrAuth indicates an error in the TSIG authentication.
+ ErrBuf error = &Error{err: "buffer size too small"} // ErrBuf indicates that the buffer used is too small for the message.
+ ErrConnEmpty error = &Error{err: "conn has no connection"} // ErrConnEmpty indicates a connection is being used before it is initialized.
+ ErrExtendedRcode error = &Error{err: "bad extended rcode"} // ErrExtendedRcode ...
+ ErrFqdn error = &Error{err: "domain must be fully qualified"} // ErrFqdn indicates that a domain name does not have a closing dot.
+ ErrId error = &Error{err: "id mismatch"} // ErrId indicates there is a mismatch with the message's ID.
+ ErrKeyAlg error = &Error{err: "bad key algorithm"} // ErrKeyAlg indicates that the algorithm in the key is not valid.
+ ErrKey error = &Error{err: "bad key"}
+ ErrKeySize error = &Error{err: "bad key size"}
+ ErrLongDomain error = &Error{err: fmt.Sprintf("domain name exceeded %d wire-format octets", maxDomainNameWireOctets)}
+ ErrNoSig error = &Error{err: "no signature found"}
+ ErrPrivKey error = &Error{err: "bad private key"}
+ ErrRcode error = &Error{err: "bad rcode"}
+ ErrRdata error = &Error{err: "bad rdata"}
+ ErrRRset error = &Error{err: "bad rrset"}
+ ErrSecret error = &Error{err: "no secrets defined"}
+ ErrShortRead error = &Error{err: "short read"}
+ ErrSig error = &Error{err: "bad signature"} // ErrSig indicates that a signature can not be cryptographically validated.
+ ErrSoa error = &Error{err: "no SOA"} // ErrSOA indicates that no SOA RR was seen when doing zone transfers.
+ ErrTime error = &Error{err: "bad time"} // ErrTime indicates a timing error in TSIG authentication.
+)
+
+// Id by default returns a 16-bit random number to be used as a message id. The
+// number is drawn from a cryptographically secure random number generator.
+// This being a variable the function can be reassigned to a custom function.
+// For instance, to make it return a static value for testing:
+//
+// dns.Id = func() uint16 { return 3 }
+var Id = id
+
+// id returns a 16 bits random number to be used as a
+// message id. The random provided should be good enough.
+func id() uint16 {
+ var output uint16
+ err := binary.Read(rand.Reader, binary.BigEndian, &output)
+ if err != nil {
+ panic("dns: reading random id failed: " + err.Error())
+ }
+ return output
+}
+
+// MsgHdr is a a manually-unpacked version of (id, bits).
+type MsgHdr struct {
+ Id uint16
+ Response bool
+ Opcode int
+ Authoritative bool
+ Truncated bool
+ RecursionDesired bool
+ RecursionAvailable bool
+ Zero bool
+ AuthenticatedData bool
+ CheckingDisabled bool
+ Rcode int
+}
+
+// Msg contains the layout of a DNS message.
+type Msg struct {
+ MsgHdr
+ Compress bool `json:"-"` // If true, the message will be compressed when converted to wire format.
+ Question []Question // Holds the RR(s) of the question section.
+ Answer []RR // Holds the RR(s) of the answer section.
+ Ns []RR // Holds the RR(s) of the authority section.
+ Extra []RR // Holds the RR(s) of the additional section.
+}
+
+// ClassToString is a maps Classes to strings for each CLASS wire type.
+var ClassToString = map[uint16]string{
+ ClassINET: "IN",
+ ClassCSNET: "CS",
+ ClassCHAOS: "CH",
+ ClassHESIOD: "HS",
+ ClassNONE: "NONE",
+ ClassANY: "ANY",
+}
+
+// OpcodeToString maps Opcodes to strings.
+var OpcodeToString = map[int]string{
+ OpcodeQuery: "QUERY",
+ OpcodeIQuery: "IQUERY",
+ OpcodeStatus: "STATUS",
+ OpcodeNotify: "NOTIFY",
+ OpcodeUpdate: "UPDATE",
+}
+
+// RcodeToString maps Rcodes to strings.
+var RcodeToString = map[int]string{
+ RcodeSuccess: "NOERROR",
+ RcodeFormatError: "FORMERR",
+ RcodeServerFailure: "SERVFAIL",
+ RcodeNameError: "NXDOMAIN",
+ RcodeNotImplemented: "NOTIMP",
+ RcodeRefused: "REFUSED",
+ RcodeYXDomain: "YXDOMAIN", // See RFC 2136
+ RcodeYXRrset: "YXRRSET",
+ RcodeNXRrset: "NXRRSET",
+ RcodeNotAuth: "NOTAUTH",
+ RcodeNotZone: "NOTZONE",
+ RcodeBadSig: "BADSIG", // Also known as RcodeBadVers, see RFC 6891
+ // RcodeBadVers: "BADVERS",
+ RcodeBadKey: "BADKEY",
+ RcodeBadTime: "BADTIME",
+ RcodeBadMode: "BADMODE",
+ RcodeBadName: "BADNAME",
+ RcodeBadAlg: "BADALG",
+ RcodeBadTrunc: "BADTRUNC",
+ RcodeBadCookie: "BADCOOKIE",
+}
+
+// compressionMap is used to allow a more efficient compression map
+// to be used for internal packDomainName calls without changing the
+// signature or functionality of public API.
+//
+// In particular, map[string]uint16 uses 25% less per-entry memory
+// than does map[string]int.
+type compressionMap struct {
+ ext map[string]int // external callers
+ int map[string]uint16 // internal callers
+}
+
+func (m compressionMap) valid() bool {
+ return m.int != nil || m.ext != nil
+}
+
+func (m compressionMap) insert(s string, pos int) {
+ if m.ext != nil {
+ m.ext[s] = pos
+ } else {
+ m.int[s] = uint16(pos)
+ }
+}
+
+func (m compressionMap) find(s string) (int, bool) {
+ if m.ext != nil {
+ pos, ok := m.ext[s]
+ return pos, ok
+ }
+
+ pos, ok := m.int[s]
+ return int(pos), ok
+}
+
+// Domain names are a sequence of counted strings
+// split at the dots. They end with a zero-length string.
+
+// PackDomainName packs a domain name s into msg[off:].
+// If compression is wanted compress must be true and the compression
+// map needs to hold a mapping between domain names and offsets
+// pointing into msg.
+func PackDomainName(s string, msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error) {
+ return packDomainName(s, msg, off, compressionMap{ext: compression}, compress)
+}
+
+func packDomainName(s string, msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ // XXX: A logical copy of this function exists in IsDomainName and
+ // should be kept in sync with this function.
+
+ ls := len(s)
+ if ls == 0 { // Ok, for instance when dealing with update RR without any rdata.
+ return off, nil
+ }
+
+ // If not fully qualified, error out.
+ if !IsFqdn(s) {
+ return len(msg), ErrFqdn
+ }
+
+ // Each dot ends a segment of the name.
+ // We trade each dot byte for a length byte.
+ // Except for escaped dots (\.), which are normal dots.
+ // There is also a trailing zero.
+
+ // Compression
+ pointer := -1
+
+ // Emit sequence of counted strings, chopping at dots.
+ var (
+ begin int
+ compBegin int
+ compOff int
+ bs []byte
+ wasDot bool
+ )
+loop:
+ for i := 0; i < ls; i++ {
+ var c byte
+ if bs == nil {
+ c = s[i]
+ } else {
+ c = bs[i]
+ }
+
+ switch c {
+ case '\\':
+ if off+1 > len(msg) {
+ return len(msg), ErrBuf
+ }
+
+ if bs == nil {
+ bs = []byte(s)
+ }
+
+ // check for \DDD
+ if i+3 < ls && isDigit(bs[i+1]) && isDigit(bs[i+2]) && isDigit(bs[i+3]) {
+ bs[i] = dddToByte(bs[i+1:])
+ copy(bs[i+1:ls-3], bs[i+4:])
+ ls -= 3
+ compOff += 3
+ } else {
+ copy(bs[i:ls-1], bs[i+1:])
+ ls--
+ compOff++
+ }
+
+ wasDot = false
+ case '.':
+ if wasDot {
+ // two dots back to back is not legal
+ return len(msg), ErrRdata
+ }
+ wasDot = true
+
+ labelLen := i - begin
+ if labelLen >= 1<<6 { // top two bits of length must be clear
+ return len(msg), ErrRdata
+ }
+
+ // off can already (we're in a loop) be bigger than len(msg)
+ // this happens when a name isn't fully qualified
+ if off+1+labelLen > len(msg) {
+ return len(msg), ErrBuf
+ }
+
+ // Don't try to compress '.'
+ // We should only compress when compress is true, but we should also still pick
+ // up names that can be used for *future* compression(s).
+ if compression.valid() && !isRootLabel(s, bs, begin, ls) {
+ if p, ok := compression.find(s[compBegin:]); ok {
+ // The first hit is the longest matching dname
+ // keep the pointer offset we get back and store
+ // the offset of the current name, because that's
+ // where we need to insert the pointer later
+
+ // If compress is true, we're allowed to compress this dname
+ if compress {
+ pointer = p // Where to point to
+ break loop
+ }
+ } else if off < maxCompressionOffset {
+ // Only offsets smaller than maxCompressionOffset can be used.
+ compression.insert(s[compBegin:], off)
+ }
+ }
+
+ // The following is covered by the length check above.
+ msg[off] = byte(labelLen)
+
+ if bs == nil {
+ copy(msg[off+1:], s[begin:i])
+ } else {
+ copy(msg[off+1:], bs[begin:i])
+ }
+ off += 1 + labelLen
+
+ begin = i + 1
+ compBegin = begin + compOff
+ default:
+ wasDot = false
+ }
+ }
+
+ // Root label is special
+ if isRootLabel(s, bs, 0, ls) {
+ return off, nil
+ }
+
+ // If we did compression and we find something add the pointer here
+ if pointer != -1 {
+ // We have two bytes (14 bits) to put the pointer in
+ binary.BigEndian.PutUint16(msg[off:], uint16(pointer^0xC000))
+ return off + 2, nil
+ }
+
+ if off < len(msg) {
+ msg[off] = 0
+ }
+
+ return off + 1, nil
+}
+
+// isRootLabel returns whether s or bs, from off to end, is the root
+// label ".".
+//
+// If bs is nil, s will be checked, otherwise bs will be checked.
+func isRootLabel(s string, bs []byte, off, end int) bool {
+ if bs == nil {
+ return s[off:end] == "."
+ }
+
+ return end-off == 1 && bs[off] == '.'
+}
+
+// Unpack a domain name.
+// In addition to the simple sequences of counted strings above,
+// domain names are allowed to refer to strings elsewhere in the
+// packet, to avoid repeating common suffixes when returning
+// many entries in a single domain. The pointers are marked
+// by a length byte with the top two bits set. Ignoring those
+// two bits, that byte and the next give a 14 bit offset from msg[0]
+// where we should pick up the trail.
+// Note that if we jump elsewhere in the packet,
+// we return off1 == the offset after the first pointer we found,
+// which is where the next record will start.
+// In theory, the pointers are only allowed to jump backward.
+// We let them jump anywhere and stop jumping after a while.
+
+// UnpackDomainName unpacks a domain name into a string. It returns
+// the name, the new offset into msg and any error that occurred.
+//
+// When an error is encountered, the unpacked name will be discarded
+// and len(msg) will be returned as the offset.
+func UnpackDomainName(msg []byte, off int) (string, int, error) {
+ s := make([]byte, 0, maxDomainNamePresentationLength)
+ off1 := 0
+ lenmsg := len(msg)
+ budget := maxDomainNameWireOctets
+ ptr := 0 // number of pointers followed
+Loop:
+ for {
+ if off >= lenmsg {
+ return "", lenmsg, ErrBuf
+ }
+ c := int(msg[off])
+ off++
+ switch c & 0xC0 {
+ case 0x00:
+ if c == 0x00 {
+ // end of name
+ break Loop
+ }
+ // literal string
+ if off+c > lenmsg {
+ return "", lenmsg, ErrBuf
+ }
+ budget -= c + 1 // +1 for the label separator
+ if budget <= 0 {
+ return "", lenmsg, ErrLongDomain
+ }
+ for _, b := range msg[off : off+c] {
+ if isDomainNameLabelSpecial(b) {
+ s = append(s, '\\', b)
+ } else if b < ' ' || b > '~' {
+ s = append(s, escapeByte(b)...)
+ } else {
+ s = append(s, b)
+ }
+ }
+ s = append(s, '.')
+ off += c
+ case 0xC0:
+ // pointer to somewhere else in msg.
+ // remember location after first ptr,
+ // since that's how many bytes we consumed.
+ // also, don't follow too many pointers --
+ // maybe there's a loop.
+ if off >= lenmsg {
+ return "", lenmsg, ErrBuf
+ }
+ c1 := msg[off]
+ off++
+ if ptr == 0 {
+ off1 = off
+ }
+ if ptr++; ptr > maxCompressionPointers {
+ return "", lenmsg, &Error{err: "too many compression pointers"}
+ }
+ // pointer should guarantee that it advances and points forwards at least
+ // but the condition on previous three lines guarantees that it's
+ // at least loop-free
+ off = (c^0xC0)<<8 | int(c1)
+ default:
+ // 0x80 and 0x40 are reserved
+ return "", lenmsg, ErrRdata
+ }
+ }
+ if ptr == 0 {
+ off1 = off
+ }
+ if len(s) == 0 {
+ return ".", off1, nil
+ }
+ return string(s), off1, nil
+}
+
+func packTxt(txt []string, msg []byte, offset int, tmp []byte) (int, error) {
+ if len(txt) == 0 {
+ if offset >= len(msg) {
+ return offset, ErrBuf
+ }
+ msg[offset] = 0
+ return offset, nil
+ }
+ var err error
+ for _, s := range txt {
+ if len(s) > len(tmp) {
+ return offset, ErrBuf
+ }
+ offset, err = packTxtString(s, msg, offset, tmp)
+ if err != nil {
+ return offset, err
+ }
+ }
+ return offset, nil
+}
+
+func packTxtString(s string, msg []byte, offset int, tmp []byte) (int, error) {
+ lenByteOffset := offset
+ if offset >= len(msg) || len(s) > len(tmp) {
+ return offset, ErrBuf
+ }
+ offset++
+ bs := tmp[:len(s)]
+ copy(bs, s)
+ for i := 0; i < len(bs); i++ {
+ if len(msg) <= offset {
+ return offset, ErrBuf
+ }
+ if bs[i] == '\\' {
+ i++
+ if i == len(bs) {
+ break
+ }
+ // check for \DDD
+ if i+2 < len(bs) && isDigit(bs[i]) && isDigit(bs[i+1]) && isDigit(bs[i+2]) {
+ msg[offset] = dddToByte(bs[i:])
+ i += 2
+ } else {
+ msg[offset] = bs[i]
+ }
+ } else {
+ msg[offset] = bs[i]
+ }
+ offset++
+ }
+ l := offset - lenByteOffset - 1
+ if l > 255 {
+ return offset, &Error{err: "string exceeded 255 bytes in txt"}
+ }
+ msg[lenByteOffset] = byte(l)
+ return offset, nil
+}
+
+func packOctetString(s string, msg []byte, offset int, tmp []byte) (int, error) {
+ if offset >= len(msg) || len(s) > len(tmp) {
+ return offset, ErrBuf
+ }
+ bs := tmp[:len(s)]
+ copy(bs, s)
+ for i := 0; i < len(bs); i++ {
+ if len(msg) <= offset {
+ return offset, ErrBuf
+ }
+ if bs[i] == '\\' {
+ i++
+ if i == len(bs) {
+ break
+ }
+ // check for \DDD
+ if i+2 < len(bs) && isDigit(bs[i]) && isDigit(bs[i+1]) && isDigit(bs[i+2]) {
+ msg[offset] = dddToByte(bs[i:])
+ i += 2
+ } else {
+ msg[offset] = bs[i]
+ }
+ } else {
+ msg[offset] = bs[i]
+ }
+ offset++
+ }
+ return offset, nil
+}
+
+func unpackTxt(msg []byte, off0 int) (ss []string, off int, err error) {
+ off = off0
+ var s string
+ for off < len(msg) && err == nil {
+ s, off, err = unpackString(msg, off)
+ if err == nil {
+ ss = append(ss, s)
+ }
+ }
+ return
+}
+
+// Helpers for dealing with escaped bytes
+func isDigit(b byte) bool { return b >= '0' && b <= '9' }
+
+func dddToByte(s []byte) byte {
+ _ = s[2] // bounds check hint to compiler; see golang.org/issue/14808
+ return byte((s[0]-'0')*100 + (s[1]-'0')*10 + (s[2] - '0'))
+}
+
+func dddStringToByte(s string) byte {
+ _ = s[2] // bounds check hint to compiler; see golang.org/issue/14808
+ return byte((s[0]-'0')*100 + (s[1]-'0')*10 + (s[2] - '0'))
+}
+
+// Helper function for packing and unpacking
+func intToBytes(i *big.Int, length int) []byte {
+ buf := i.Bytes()
+ if len(buf) < length {
+ b := make([]byte, length)
+ copy(b[length-len(buf):], buf)
+ return b
+ }
+ return buf
+}
+
+// PackRR packs a resource record rr into msg[off:].
+// See PackDomainName for documentation about the compression.
+func PackRR(rr RR, msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error) {
+ headerEnd, off1, err := packRR(rr, msg, off, compressionMap{ext: compression}, compress)
+ if err == nil {
+ // packRR no longer sets the Rdlength field on the rr, but
+ // callers might be expecting it so we set it here.
+ rr.Header().Rdlength = uint16(off1 - headerEnd)
+ }
+ return off1, err
+}
+
+func packRR(rr RR, msg []byte, off int, compression compressionMap, compress bool) (headerEnd int, off1 int, err error) {
+ if rr == nil {
+ return len(msg), len(msg), &Error{err: "nil rr"}
+ }
+
+ headerEnd, err = rr.Header().packHeader(msg, off, compression, compress)
+ if err != nil {
+ return headerEnd, len(msg), err
+ }
+
+ off1, err = rr.pack(msg, headerEnd, compression, compress)
+ if err != nil {
+ return headerEnd, len(msg), err
+ }
+
+ rdlength := off1 - headerEnd
+ if int(uint16(rdlength)) != rdlength { // overflow
+ return headerEnd, len(msg), ErrRdata
+ }
+
+ // The RDLENGTH field is the last field in the header and we set it here.
+ binary.BigEndian.PutUint16(msg[headerEnd-2:], uint16(rdlength))
+ return headerEnd, off1, nil
+}
+
+// UnpackRR unpacks msg[off:] into an RR.
+func UnpackRR(msg []byte, off int) (rr RR, off1 int, err error) {
+ h, off, msg, err := unpackHeader(msg, off)
+ if err != nil {
+ return nil, len(msg), err
+ }
+
+ return UnpackRRWithHeader(h, msg, off)
+}
+
+// UnpackRRWithHeader unpacks the record type specific payload given an existing
+// RR_Header.
+func UnpackRRWithHeader(h RR_Header, msg []byte, off int) (rr RR, off1 int, err error) {
+ if newFn, ok := TypeToRR[h.Rrtype]; ok {
+ rr = newFn()
+ *rr.Header() = h
+ } else {
+ rr = &RFC3597{Hdr: h}
+ }
+
+ 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 {
+ return nil, end, err
+ }
+ if off != end {
+ return &h, end, &Error{err: "bad rdlength"}
+ }
+
+ return rr, off, nil
+}
+
+// unpackRRslice unpacks msg[off:] into an []RR.
+// If we cannot unpack the whole array, then it will return nil
+func unpackRRslice(l int, msg []byte, off int) (dst1 []RR, off1 int, err error) {
+ var r RR
+ // Don't pre-allocate, l may be under attacker control
+ var dst []RR
+ for i := 0; i < l; i++ {
+ off1 := off
+ r, off, err = UnpackRR(msg, off)
+ if err != nil {
+ off = len(msg)
+ break
+ }
+ // If offset does not increase anymore, l is a lie
+ if off1 == off {
+ break
+ }
+ dst = append(dst, r)
+ }
+ if err != nil && off == len(msg) {
+ dst = nil
+ }
+ return dst, off, err
+}
+
+// Convert a MsgHdr to a string, with dig-like headers:
+//
+//;; opcode: QUERY, status: NOERROR, id: 48404
+//
+//;; flags: qr aa rd ra;
+func (h *MsgHdr) String() string {
+ if h == nil {
+ return "<nil> MsgHdr"
+ }
+
+ s := ";; opcode: " + OpcodeToString[h.Opcode]
+ s += ", status: " + RcodeToString[h.Rcode]
+ s += ", id: " + strconv.Itoa(int(h.Id)) + "\n"
+
+ s += ";; flags:"
+ if h.Response {
+ s += " qr"
+ }
+ if h.Authoritative {
+ s += " aa"
+ }
+ if h.Truncated {
+ s += " tc"
+ }
+ if h.RecursionDesired {
+ s += " rd"
+ }
+ if h.RecursionAvailable {
+ s += " ra"
+ }
+ if h.Zero { // Hmm
+ s += " z"
+ }
+ if h.AuthenticatedData {
+ s += " ad"
+ }
+ if h.CheckingDisabled {
+ s += " cd"
+ }
+
+ s += ";"
+ return s
+}
+
+// Pack packs a Msg: it is converted to to wire format.
+// If the dns.Compress is true the message will be in compressed wire format.
+func (dns *Msg) Pack() (msg []byte, err error) {
+ return dns.PackBuffer(nil)
+}
+
+// PackBuffer packs a Msg, using the given buffer buf. If buf is too small a new buffer is allocated.
+func (dns *Msg) PackBuffer(buf []byte) (msg []byte, err error) {
+ // If this message can't be compressed, avoid filling the
+ // compression map and creating garbage.
+ if dns.Compress && dns.isCompressible() {
+ compression := make(map[string]uint16) // Compression pointer mappings.
+ return dns.packBufferWithCompressionMap(buf, compressionMap{int: compression}, true)
+ }
+
+ return dns.packBufferWithCompressionMap(buf, compressionMap{}, false)
+}
+
+// packBufferWithCompressionMap packs a Msg, using the given buffer buf.
+func (dns *Msg) packBufferWithCompressionMap(buf []byte, compression compressionMap, compress bool) (msg []byte, err error) {
+ if dns.Rcode < 0 || dns.Rcode > 0xFFF {
+ return nil, ErrRcode
+ }
+
+ // Set extended rcode unconditionally if we have an opt, this will allow
+ // resetting the extended rcode bits if they need to.
+ if opt := dns.IsEdns0(); opt != nil {
+ opt.SetExtendedRcode(uint16(dns.Rcode))
+ } else if dns.Rcode > 0xF {
+ // If Rcode is an extended one and opt is nil, error out.
+ return nil, ErrExtendedRcode
+ }
+
+ // Convert convenient Msg into wire-like Header.
+ var dh Header
+ dh.Id = dns.Id
+ dh.Bits = uint16(dns.Opcode)<<11 | uint16(dns.Rcode&0xF)
+ if dns.Response {
+ dh.Bits |= _QR
+ }
+ if dns.Authoritative {
+ dh.Bits |= _AA
+ }
+ if dns.Truncated {
+ dh.Bits |= _TC
+ }
+ if dns.RecursionDesired {
+ dh.Bits |= _RD
+ }
+ if dns.RecursionAvailable {
+ dh.Bits |= _RA
+ }
+ if dns.Zero {
+ dh.Bits |= _Z
+ }
+ if dns.AuthenticatedData {
+ dh.Bits |= _AD
+ }
+ if dns.CheckingDisabled {
+ dh.Bits |= _CD
+ }
+
+ dh.Qdcount = uint16(len(dns.Question))
+ dh.Ancount = uint16(len(dns.Answer))
+ dh.Nscount = uint16(len(dns.Ns))
+ dh.Arcount = uint16(len(dns.Extra))
+
+ // We need the uncompressed length here, because we first pack it and then compress it.
+ msg = buf
+ uncompressedLen := msgLenWithCompressionMap(dns, nil)
+ if packLen := uncompressedLen + 1; len(msg) < packLen {
+ msg = make([]byte, packLen)
+ }
+
+ // Pack it in: header and then the pieces.
+ off := 0
+ off, err = dh.pack(msg, off, compression, compress)
+ if err != nil {
+ return nil, err
+ }
+ for _, r := range dns.Question {
+ off, err = r.pack(msg, off, compression, compress)
+ if err != nil {
+ return nil, err
+ }
+ }
+ for _, r := range dns.Answer {
+ _, off, err = packRR(r, msg, off, compression, compress)
+ if err != nil {
+ return nil, err
+ }
+ }
+ for _, r := range dns.Ns {
+ _, off, err = packRR(r, msg, off, compression, compress)
+ if err != nil {
+ return nil, err
+ }
+ }
+ for _, r := range dns.Extra {
+ _, off, err = packRR(r, msg, off, compression, compress)
+ if err != nil {
+ return nil, err
+ }
+ }
+ return msg[:off], nil
+}
+
+func (dns *Msg) unpack(dh Header, msg []byte, off int) (err error) {
+ // If we are at the end of the message we should return *just* the
+ // header. This can still be useful to the caller. 9.9.9.9 sends these
+ // when responding with REFUSED for instance.
+ if off == len(msg) {
+ // reset sections before returning
+ dns.Question, dns.Answer, dns.Ns, dns.Extra = nil, nil, nil, nil
+ return nil
+ }
+
+ // Qdcount, Ancount, Nscount, Arcount can't be trusted, as they are
+ // attacker controlled. This means we can't use them to pre-allocate
+ // slices.
+ dns.Question = nil
+ for i := 0; i < int(dh.Qdcount); i++ {
+ off1 := off
+ var q Question
+ q, off, err = unpackQuestion(msg, off)
+ if err != nil {
+ return err
+ }
+ if off1 == off { // Offset does not increase anymore, dh.Qdcount is a lie!
+ dh.Qdcount = uint16(i)
+ break
+ }
+ dns.Question = append(dns.Question, q)
+ }
+
+ dns.Answer, off, err = unpackRRslice(int(dh.Ancount), msg, off)
+ // The header counts might have been wrong so we need to update it
+ dh.Ancount = uint16(len(dns.Answer))
+ if err == nil {
+ dns.Ns, off, err = unpackRRslice(int(dh.Nscount), msg, off)
+ }
+ // The header counts might have been wrong so we need to update it
+ dh.Nscount = uint16(len(dns.Ns))
+ if err == nil {
+ dns.Extra, off, err = unpackRRslice(int(dh.Arcount), msg, off)
+ }
+ // The header counts might have been wrong so we need to update it
+ dh.Arcount = uint16(len(dns.Extra))
+
+ // Set extended Rcode
+ if opt := dns.IsEdns0(); opt != nil {
+ dns.Rcode |= opt.ExtendedRcode()
+ }
+
+ if off != len(msg) {
+ // TODO(miek) make this an error?
+ // use PackOpt to let people tell how detailed the error reporting should be?
+ // println("dns: extra bytes in dns packet", off, "<", len(msg))
+ }
+ return err
+
+}
+
+// Unpack unpacks a binary message to a Msg structure.
+func (dns *Msg) Unpack(msg []byte) (err error) {
+ dh, off, err := unpackMsgHdr(msg, 0)
+ if err != nil {
+ return err
+ }
+
+ dns.setHdr(dh)
+ return dns.unpack(dh, msg, off)
+}
+
+// Convert a complete message to a string with dig-like output.
+func (dns *Msg) String() string {
+ if dns == nil {
+ return "<nil> MsgHdr"
+ }
+ s := dns.MsgHdr.String() + " "
+ s += "QUERY: " + strconv.Itoa(len(dns.Question)) + ", "
+ s += "ANSWER: " + strconv.Itoa(len(dns.Answer)) + ", "
+ s += "AUTHORITY: " + strconv.Itoa(len(dns.Ns)) + ", "
+ s += "ADDITIONAL: " + strconv.Itoa(len(dns.Extra)) + "\n"
+ opt := dns.IsEdns0()
+ if opt != nil {
+ // OPT PSEUDOSECTION
+ s += opt.String() + "\n"
+ }
+ if len(dns.Question) > 0 {
+ s += "\n;; QUESTION SECTION:\n"
+ for _, r := range dns.Question {
+ s += r.String() + "\n"
+ }
+ }
+ if len(dns.Answer) > 0 {
+ s += "\n;; ANSWER SECTION:\n"
+ for _, r := range dns.Answer {
+ if r != nil {
+ s += r.String() + "\n"
+ }
+ }
+ }
+ if len(dns.Ns) > 0 {
+ s += "\n;; AUTHORITY SECTION:\n"
+ for _, r := range dns.Ns {
+ if r != nil {
+ s += r.String() + "\n"
+ }
+ }
+ }
+ if len(dns.Extra) > 0 && (opt == nil || len(dns.Extra) > 1) {
+ s += "\n;; ADDITIONAL SECTION:\n"
+ for _, r := range dns.Extra {
+ if r != nil && r.Header().Rrtype != TypeOPT {
+ s += r.String() + "\n"
+ }
+ }
+ }
+ return s
+}
+
+// isCompressible returns whether the msg may be compressible.
+func (dns *Msg) isCompressible() bool {
+ // If we only have one question, there is nothing we can ever compress.
+ return len(dns.Question) > 1 || len(dns.Answer) > 0 ||
+ len(dns.Ns) > 0 || len(dns.Extra) > 0
+}
+
+// Len returns the message length when in (un)compressed wire format.
+// If dns.Compress is true compression it is taken into account. Len()
+// is provided to be a faster way to get the size of the resulting packet,
+// than packing it, measuring the size and discarding the buffer.
+func (dns *Msg) Len() int {
+ // If this message can't be compressed, avoid filling the
+ // compression map and creating garbage.
+ if dns.Compress && dns.isCompressible() {
+ compression := make(map[string]struct{})
+ return msgLenWithCompressionMap(dns, compression)
+ }
+
+ return msgLenWithCompressionMap(dns, nil)
+}
+
+func msgLenWithCompressionMap(dns *Msg, compression map[string]struct{}) int {
+ l := headerSize
+
+ for _, r := range dns.Question {
+ l += r.len(l, compression)
+ }
+ for _, r := range dns.Answer {
+ if r != nil {
+ l += r.len(l, compression)
+ }
+ }
+ for _, r := range dns.Ns {
+ if r != nil {
+ l += r.len(l, compression)
+ }
+ }
+ for _, r := range dns.Extra {
+ if r != nil {
+ l += r.len(l, compression)
+ }
+ }
+
+ return l
+}
+
+func domainNameLen(s string, off int, compression map[string]struct{}, compress bool) int {
+ if s == "" || s == "." {
+ return 1
+ }
+
+ escaped := strings.Contains(s, "\\")
+
+ if compression != nil && (compress || off < maxCompressionOffset) {
+ // compressionLenSearch will insert the entry into the compression
+ // map if it doesn't contain it.
+ if l, ok := compressionLenSearch(compression, s, off); ok && compress {
+ if escaped {
+ return escapedNameLen(s[:l]) + 2
+ }
+
+ return l + 2
+ }
+ }
+
+ if escaped {
+ return escapedNameLen(s) + 1
+ }
+
+ return len(s) + 1
+}
+
+func escapedNameLen(s string) int {
+ nameLen := len(s)
+ for i := 0; i < len(s); i++ {
+ if s[i] != '\\' {
+ continue
+ }
+
+ if i+3 < len(s) && isDigit(s[i+1]) && isDigit(s[i+2]) && isDigit(s[i+3]) {
+ nameLen -= 3
+ i += 3
+ } else {
+ nameLen--
+ i++
+ }
+ }
+
+ return nameLen
+}
+
+func compressionLenSearch(c map[string]struct{}, s string, msgOff int) (int, bool) {
+ for off, end := 0, false; !end; off, end = NextLabel(s, off) {
+ if _, ok := c[s[off:]]; ok {
+ return off, true
+ }
+
+ if msgOff+off < maxCompressionOffset {
+ c[s[off:]] = struct{}{}
+ }
+ }
+
+ return 0, false
+}
+
+// Copy returns a new RR which is a deep-copy of r.
+func Copy(r RR) RR { return r.copy() }
+
+// Len returns the length (in octets) of the uncompressed RR in wire format.
+func Len(r RR) int { return r.len(0, nil) }
+
+// Copy returns a new *Msg which is a deep-copy of dns.
+func (dns *Msg) Copy() *Msg { return dns.CopyTo(new(Msg)) }
+
+// CopyTo copies the contents to the provided message using a deep-copy and returns the copy.
+func (dns *Msg) CopyTo(r1 *Msg) *Msg {
+ r1.MsgHdr = dns.MsgHdr
+ r1.Compress = dns.Compress
+
+ if len(dns.Question) > 0 {
+ r1.Question = make([]Question, len(dns.Question))
+ copy(r1.Question, dns.Question) // TODO(miek): Question is an immutable value, ok to do a shallow-copy
+ }
+
+ rrArr := make([]RR, len(dns.Answer)+len(dns.Ns)+len(dns.Extra))
+ r1.Answer, rrArr = rrArr[:0:len(dns.Answer)], rrArr[len(dns.Answer):]
+ r1.Ns, rrArr = rrArr[:0:len(dns.Ns)], rrArr[len(dns.Ns):]
+ r1.Extra = rrArr[:0:len(dns.Extra)]
+
+ for _, r := range dns.Answer {
+ r1.Answer = append(r1.Answer, r.copy())
+ }
+
+ for _, r := range dns.Ns {
+ r1.Ns = append(r1.Ns, r.copy())
+ }
+
+ for _, r := range dns.Extra {
+ r1.Extra = append(r1.Extra, r.copy())
+ }
+
+ return r1
+}
+
+func (q *Question) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) {
+ off, err := packDomainName(q.Name, msg, off, compression, compress)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(q.Qtype, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(q.Qclass, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func unpackQuestion(msg []byte, off int) (Question, int, error) {
+ var (
+ q Question
+ err error
+ )
+ q.Name, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return q, off, err
+ }
+ if off == len(msg) {
+ return q, off, nil
+ }
+ q.Qtype, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return q, off, err
+ }
+ if off == len(msg) {
+ return q, off, nil
+ }
+ q.Qclass, off, err = unpackUint16(msg, off)
+ if off == len(msg) {
+ return q, off, nil
+ }
+ return q, off, err
+}
+
+func (dh *Header) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) {
+ off, err := packUint16(dh.Id, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(dh.Bits, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(dh.Qdcount, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(dh.Ancount, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(dh.Nscount, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(dh.Arcount, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func unpackMsgHdr(msg []byte, off int) (Header, int, error) {
+ var (
+ dh Header
+ err error
+ )
+ dh.Id, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return dh, off, err
+ }
+ dh.Bits, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return dh, off, err
+ }
+ dh.Qdcount, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return dh, off, err
+ }
+ dh.Ancount, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return dh, off, err
+ }
+ dh.Nscount, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return dh, off, err
+ }
+ dh.Arcount, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return dh, off, err
+ }
+ return dh, off, nil
+}
+
+// setHdr set the header in the dns using the binary data in dh.
+func (dns *Msg) setHdr(dh Header) {
+ dns.Id = dh.Id
+ dns.Response = dh.Bits&_QR != 0
+ dns.Opcode = int(dh.Bits>>11) & 0xF
+ dns.Authoritative = dh.Bits&_AA != 0
+ dns.Truncated = dh.Bits&_TC != 0
+ dns.RecursionDesired = dh.Bits&_RD != 0
+ dns.RecursionAvailable = dh.Bits&_RA != 0
+ dns.Zero = dh.Bits&_Z != 0 // _Z covers the zero bit, which should be zero; not sure why we set it to the opposite.
+ dns.AuthenticatedData = dh.Bits&_AD != 0
+ dns.CheckingDisabled = dh.Bits&_CD != 0
+ dns.Rcode = int(dh.Bits & 0xF)
+}
diff --git a/vendor/github.com/miekg/dns/msg_helpers.go b/vendor/github.com/miekg/dns/msg_helpers.go
@@ -0,0 +1,812 @@
+package dns
+
+import (
+ "encoding/base32"
+ "encoding/base64"
+ "encoding/binary"
+ "encoding/hex"
+ "net"
+ "sort"
+ "strings"
+)
+
+// helper functions called from the generated zmsg.go
+
+// These function are named after the tag to help pack/unpack, if there is no tag it is the name
+// of the type they pack/unpack (string, int, etc). We prefix all with unpackData or packData, so packDataA or
+// packDataDomainName.
+
+func unpackDataA(msg []byte, off int) (net.IP, int, error) {
+ if off+net.IPv4len > len(msg) {
+ return nil, len(msg), &Error{err: "overflow unpacking a"}
+ }
+ a := append(make(net.IP, 0, net.IPv4len), msg[off:off+net.IPv4len]...)
+ off += net.IPv4len
+ return a, off, nil
+}
+
+func packDataA(a net.IP, msg []byte, off int) (int, error) {
+ switch len(a) {
+ case net.IPv4len, net.IPv6len:
+ // It must be a slice of 4, even if it is 16, we encode only the first 4
+ if off+net.IPv4len > len(msg) {
+ return len(msg), &Error{err: "overflow packing a"}
+ }
+
+ copy(msg[off:], a.To4())
+ off += net.IPv4len
+ case 0:
+ // Allowed, for dynamic updates.
+ default:
+ return len(msg), &Error{err: "overflow packing a"}
+ }
+ return off, nil
+}
+
+func unpackDataAAAA(msg []byte, off int) (net.IP, int, error) {
+ if off+net.IPv6len > len(msg) {
+ return nil, len(msg), &Error{err: "overflow unpacking aaaa"}
+ }
+ aaaa := append(make(net.IP, 0, net.IPv6len), msg[off:off+net.IPv6len]...)
+ off += net.IPv6len
+ return aaaa, off, nil
+}
+
+func packDataAAAA(aaaa net.IP, msg []byte, off int) (int, error) {
+ switch len(aaaa) {
+ case net.IPv6len:
+ if off+net.IPv6len > len(msg) {
+ return len(msg), &Error{err: "overflow packing aaaa"}
+ }
+
+ copy(msg[off:], aaaa)
+ off += net.IPv6len
+ case 0:
+ // Allowed, dynamic updates.
+ default:
+ return len(msg), &Error{err: "overflow packing aaaa"}
+ }
+ return off, nil
+}
+
+// unpackHeader unpacks an RR header, returning the offset to the end of the header and a
+// re-sliced msg according to the expected length of the RR.
+func unpackHeader(msg []byte, off int) (rr RR_Header, off1 int, truncmsg []byte, err error) {
+ hdr := RR_Header{}
+ if off == len(msg) {
+ return hdr, off, msg, nil
+ }
+
+ hdr.Name, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return hdr, len(msg), msg, err
+ }
+ hdr.Rrtype, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return hdr, len(msg), msg, err
+ }
+ hdr.Class, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return hdr, len(msg), msg, err
+ }
+ hdr.Ttl, off, err = unpackUint32(msg, off)
+ if err != nil {
+ return hdr, len(msg), msg, err
+ }
+ hdr.Rdlength, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return hdr, len(msg), msg, err
+ }
+ msg, err = truncateMsgFromRdlength(msg, off, hdr.Rdlength)
+ return hdr, off, msg, err
+}
+
+// packHeader packs an RR header, returning the offset to the end of the header.
+// See PackDomainName for documentation about the compression.
+func (hdr RR_Header) packHeader(msg []byte, off int, compression compressionMap, compress bool) (int, error) {
+ if off == len(msg) {
+ return off, nil
+ }
+
+ off, err := packDomainName(hdr.Name, msg, off, compression, compress)
+ if err != nil {
+ return len(msg), err
+ }
+ off, err = packUint16(hdr.Rrtype, msg, off)
+ if err != nil {
+ return len(msg), err
+ }
+ off, err = packUint16(hdr.Class, msg, off)
+ if err != nil {
+ return len(msg), err
+ }
+ off, err = packUint32(hdr.Ttl, msg, off)
+ if err != nil {
+ return len(msg), err
+ }
+ off, err = packUint16(0, msg, off) // The RDLENGTH field will be set later in packRR.
+ if err != nil {
+ return len(msg), err
+ }
+ return off, nil
+}
+
+// helper helper functions.
+
+// truncateMsgFromRdLength truncates msg to match the expected length of the RR.
+// Returns an error if msg is smaller than the expected size.
+func truncateMsgFromRdlength(msg []byte, off int, rdlength uint16) (truncmsg []byte, err error) {
+ lenrd := off + int(rdlength)
+ if lenrd > len(msg) {
+ return msg, &Error{err: "overflowing header size"}
+ }
+ return msg[:lenrd], nil
+}
+
+var base32HexNoPadEncoding = base32.HexEncoding.WithPadding(base32.NoPadding)
+
+func fromBase32(s []byte) (buf []byte, err error) {
+ for i, b := range s {
+ if b >= 'a' && b <= 'z' {
+ s[i] = b - 32
+ }
+ }
+ buflen := base32HexNoPadEncoding.DecodedLen(len(s))
+ buf = make([]byte, buflen)
+ n, err := base32HexNoPadEncoding.Decode(buf, s)
+ buf = buf[:n]
+ return
+}
+
+func toBase32(b []byte) string {
+ return base32HexNoPadEncoding.EncodeToString(b)
+}
+
+func fromBase64(s []byte) (buf []byte, err error) {
+ buflen := base64.StdEncoding.DecodedLen(len(s))
+ buf = make([]byte, buflen)
+ n, err := base64.StdEncoding.Decode(buf, s)
+ buf = buf[:n]
+ return
+}
+
+func toBase64(b []byte) string { return base64.StdEncoding.EncodeToString(b) }
+
+// dynamicUpdate returns true if the Rdlength is zero.
+func noRdata(h RR_Header) bool { return h.Rdlength == 0 }
+
+func unpackUint8(msg []byte, off int) (i uint8, off1 int, err error) {
+ if off+1 > len(msg) {
+ return 0, len(msg), &Error{err: "overflow unpacking uint8"}
+ }
+ return msg[off], off + 1, nil
+}
+
+func packUint8(i uint8, msg []byte, off int) (off1 int, err error) {
+ if off+1 > len(msg) {
+ return len(msg), &Error{err: "overflow packing uint8"}
+ }
+ msg[off] = i
+ return off + 1, nil
+}
+
+func unpackUint16(msg []byte, off int) (i uint16, off1 int, err error) {
+ if off+2 > len(msg) {
+ return 0, len(msg), &Error{err: "overflow unpacking uint16"}
+ }
+ return binary.BigEndian.Uint16(msg[off:]), off + 2, nil
+}
+
+func packUint16(i uint16, msg []byte, off int) (off1 int, err error) {
+ if off+2 > len(msg) {
+ return len(msg), &Error{err: "overflow packing uint16"}
+ }
+ binary.BigEndian.PutUint16(msg[off:], i)
+ return off + 2, nil
+}
+
+func unpackUint32(msg []byte, off int) (i uint32, off1 int, err error) {
+ if off+4 > len(msg) {
+ return 0, len(msg), &Error{err: "overflow unpacking uint32"}
+ }
+ return binary.BigEndian.Uint32(msg[off:]), off + 4, nil
+}
+
+func packUint32(i uint32, msg []byte, off int) (off1 int, err error) {
+ if off+4 > len(msg) {
+ return len(msg), &Error{err: "overflow packing uint32"}
+ }
+ binary.BigEndian.PutUint32(msg[off:], i)
+ return off + 4, nil
+}
+
+func unpackUint48(msg []byte, off int) (i uint64, off1 int, err error) {
+ if off+6 > len(msg) {
+ return 0, len(msg), &Error{err: "overflow unpacking uint64 as uint48"}
+ }
+ // Used in TSIG where the last 48 bits are occupied, so for now, assume a uint48 (6 bytes)
+ i = uint64(msg[off])<<40 | uint64(msg[off+1])<<32 | uint64(msg[off+2])<<24 | uint64(msg[off+3])<<16 |
+ uint64(msg[off+4])<<8 | uint64(msg[off+5])
+ off += 6
+ return i, off, nil
+}
+
+func packUint48(i uint64, msg []byte, off int) (off1 int, err error) {
+ if off+6 > len(msg) {
+ return len(msg), &Error{err: "overflow packing uint64 as uint48"}
+ }
+ msg[off] = byte(i >> 40)
+ msg[off+1] = byte(i >> 32)
+ msg[off+2] = byte(i >> 24)
+ msg[off+3] = byte(i >> 16)
+ msg[off+4] = byte(i >> 8)
+ msg[off+5] = byte(i)
+ off += 6
+ return off, nil
+}
+
+func unpackUint64(msg []byte, off int) (i uint64, off1 int, err error) {
+ if off+8 > len(msg) {
+ return 0, len(msg), &Error{err: "overflow unpacking uint64"}
+ }
+ return binary.BigEndian.Uint64(msg[off:]), off + 8, nil
+}
+
+func packUint64(i uint64, msg []byte, off int) (off1 int, err error) {
+ if off+8 > len(msg) {
+ return len(msg), &Error{err: "overflow packing uint64"}
+ }
+ binary.BigEndian.PutUint64(msg[off:], i)
+ off += 8
+ return off, nil
+}
+
+func unpackString(msg []byte, off int) (string, int, error) {
+ if off+1 > len(msg) {
+ return "", off, &Error{err: "overflow unpacking txt"}
+ }
+ l := int(msg[off])
+ off++
+ if off+l > len(msg) {
+ return "", off, &Error{err: "overflow unpacking txt"}
+ }
+ var s strings.Builder
+ consumed := 0
+ for i, b := range msg[off : off+l] {
+ switch {
+ case b == '"' || b == '\\':
+ if consumed == 0 {
+ s.Grow(l * 2)
+ }
+ s.Write(msg[off+consumed : off+i])
+ s.WriteByte('\\')
+ s.WriteByte(b)
+ consumed = i + 1
+ case b < ' ' || b > '~': // unprintable
+ if consumed == 0 {
+ s.Grow(l * 2)
+ }
+ s.Write(msg[off+consumed : off+i])
+ s.WriteString(escapeByte(b))
+ consumed = i + 1
+ }
+ }
+ if consumed == 0 { // no escaping needed
+ return string(msg[off : off+l]), off + l, nil
+ }
+ s.Write(msg[off+consumed : off+l])
+ return s.String(), off + l, nil
+}
+
+func packString(s string, msg []byte, off int) (int, error) {
+ txtTmp := make([]byte, 256*4+1)
+ off, err := packTxtString(s, msg, off, txtTmp)
+ if err != nil {
+ return len(msg), err
+ }
+ return off, nil
+}
+
+func unpackStringBase32(msg []byte, off, end int) (string, int, error) {
+ if end > len(msg) {
+ return "", len(msg), &Error{err: "overflow unpacking base32"}
+ }
+ s := toBase32(msg[off:end])
+ return s, end, nil
+}
+
+func packStringBase32(s string, msg []byte, off int) (int, error) {
+ b32, err := fromBase32([]byte(s))
+ if err != nil {
+ return len(msg), err
+ }
+ if off+len(b32) > len(msg) {
+ return len(msg), &Error{err: "overflow packing base32"}
+ }
+ copy(msg[off:off+len(b32)], b32)
+ off += len(b32)
+ return off, nil
+}
+
+func unpackStringBase64(msg []byte, off, end int) (string, int, error) {
+ // Rest of the RR is base64 encoded value, so we don't need an explicit length
+ // to be set. Thus far all RR's that have base64 encoded fields have those as their
+ // last one. What we do need is the end of the RR!
+ if end > len(msg) {
+ return "", len(msg), &Error{err: "overflow unpacking base64"}
+ }
+ s := toBase64(msg[off:end])
+ return s, end, nil
+}
+
+func packStringBase64(s string, msg []byte, off int) (int, error) {
+ b64, err := fromBase64([]byte(s))
+ if err != nil {
+ return len(msg), err
+ }
+ if off+len(b64) > len(msg) {
+ return len(msg), &Error{err: "overflow packing base64"}
+ }
+ copy(msg[off:off+len(b64)], b64)
+ off += len(b64)
+ return off, nil
+}
+
+func unpackStringHex(msg []byte, off, end int) (string, int, error) {
+ // Rest of the RR is hex encoded value, so we don't need an explicit length
+ // to be set. NSEC and TSIG have hex fields with a length field.
+ // What we do need is the end of the RR!
+ if end > len(msg) {
+ return "", len(msg), &Error{err: "overflow unpacking hex"}
+ }
+
+ s := hex.EncodeToString(msg[off:end])
+ return s, end, nil
+}
+
+func packStringHex(s string, msg []byte, off int) (int, error) {
+ h, err := hex.DecodeString(s)
+ if err != nil {
+ return len(msg), err
+ }
+ if off+len(h) > len(msg) {
+ return len(msg), &Error{err: "overflow packing hex"}
+ }
+ copy(msg[off:off+len(h)], h)
+ off += len(h)
+ return off, nil
+}
+
+func unpackStringAny(msg []byte, off, end int) (string, int, error) {
+ if end > len(msg) {
+ return "", len(msg), &Error{err: "overflow unpacking anything"}
+ }
+ return string(msg[off:end]), end, nil
+}
+
+func packStringAny(s string, msg []byte, off int) (int, error) {
+ if off+len(s) > len(msg) {
+ return len(msg), &Error{err: "overflow packing anything"}
+ }
+ copy(msg[off:off+len(s)], s)
+ off += len(s)
+ return off, nil
+}
+
+func unpackStringTxt(msg []byte, off int) ([]string, int, error) {
+ txt, off, err := unpackTxt(msg, off)
+ if err != nil {
+ return nil, len(msg), err
+ }
+ return txt, off, nil
+}
+
+func packStringTxt(s []string, msg []byte, off int) (int, error) {
+ txtTmp := make([]byte, 256*4+1) // If the whole string consists out of \DDD we need this many.
+ off, err := packTxt(s, msg, off, txtTmp)
+ if err != nil {
+ return len(msg), err
+ }
+ return off, nil
+}
+
+func unpackDataOpt(msg []byte, off int) ([]EDNS0, int, error) {
+ var edns []EDNS0
+Option:
+ var code uint16
+ if off+4 > len(msg) {
+ return nil, len(msg), &Error{err: "overflow unpacking opt"}
+ }
+ code = binary.BigEndian.Uint16(msg[off:])
+ off += 2
+ optlen := binary.BigEndian.Uint16(msg[off:])
+ off += 2
+ if off+int(optlen) > len(msg) {
+ return nil, len(msg), &Error{err: "overflow unpacking opt"}
+ }
+ e := makeDataOpt(code)
+ if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
+ return nil, len(msg), err
+ }
+ edns = append(edns, e)
+ off += int(optlen)
+
+ if off < len(msg) {
+ goto Option
+ }
+
+ return edns, off, nil
+}
+
+func packDataOpt(options []EDNS0, msg []byte, off int) (int, error) {
+ for _, el := range options {
+ b, err := el.pack()
+ if err != nil || off+4 > len(msg) {
+ return len(msg), &Error{err: "overflow packing opt"}
+ }
+ binary.BigEndian.PutUint16(msg[off:], el.Option()) // Option code
+ binary.BigEndian.PutUint16(msg[off+2:], uint16(len(b))) // Length
+ off += 4
+ if off+len(b) > len(msg) {
+ return len(msg), &Error{err: "overflow packing opt"}
+ }
+ // Actual data
+ copy(msg[off:off+len(b)], b)
+ off += len(b)
+ }
+ return off, nil
+}
+
+func unpackStringOctet(msg []byte, off int) (string, int, error) {
+ s := string(msg[off:])
+ return s, len(msg), nil
+}
+
+func packStringOctet(s string, msg []byte, off int) (int, error) {
+ txtTmp := make([]byte, 256*4+1)
+ off, err := packOctetString(s, msg, off, txtTmp)
+ if err != nil {
+ return len(msg), err
+ }
+ return off, nil
+}
+
+func unpackDataNsec(msg []byte, off int) ([]uint16, int, error) {
+ var nsec []uint16
+ length, window, lastwindow := 0, 0, -1
+ for off < len(msg) {
+ if off+2 > len(msg) {
+ return nsec, len(msg), &Error{err: "overflow unpacking nsecx"}
+ }
+ window = int(msg[off])
+ length = int(msg[off+1])
+ off += 2
+ if window <= lastwindow {
+ // RFC 4034: Blocks are present in the NSEC RR RDATA in
+ // increasing numerical order.
+ return nsec, len(msg), &Error{err: "out of order NSEC block"}
+ }
+ if length == 0 {
+ // RFC 4034: Blocks with no types present MUST NOT be included.
+ return nsec, len(msg), &Error{err: "empty NSEC block"}
+ }
+ if length > 32 {
+ return nsec, len(msg), &Error{err: "NSEC block too long"}
+ }
+ if off+length > len(msg) {
+ return nsec, len(msg), &Error{err: "overflowing NSEC block"}
+ }
+
+ // Walk the bytes in the window and extract the type bits
+ for j, b := range msg[off : off+length] {
+ // Check the bits one by one, and set the type
+ if b&0x80 == 0x80 {
+ nsec = append(nsec, uint16(window*256+j*8+0))
+ }
+ if b&0x40 == 0x40 {
+ nsec = append(nsec, uint16(window*256+j*8+1))
+ }
+ if b&0x20 == 0x20 {
+ nsec = append(nsec, uint16(window*256+j*8+2))
+ }
+ if b&0x10 == 0x10 {
+ nsec = append(nsec, uint16(window*256+j*8+3))
+ }
+ if b&0x8 == 0x8 {
+ nsec = append(nsec, uint16(window*256+j*8+4))
+ }
+ if b&0x4 == 0x4 {
+ nsec = append(nsec, uint16(window*256+j*8+5))
+ }
+ if b&0x2 == 0x2 {
+ nsec = append(nsec, uint16(window*256+j*8+6))
+ }
+ if b&0x1 == 0x1 {
+ nsec = append(nsec, uint16(window*256+j*8+7))
+ }
+ }
+ off += length
+ lastwindow = window
+ }
+ return nsec, off, nil
+}
+
+// typeBitMapLen is a helper function which computes the "maximum" length of
+// a the NSEC Type BitMap field.
+func typeBitMapLen(bitmap []uint16) int {
+ var l int
+ var lastwindow, lastlength uint16
+ for _, t := range bitmap {
+ window := t / 256
+ length := (t-window*256)/8 + 1
+ if window > lastwindow && lastlength != 0 { // New window, jump to the new offset
+ l += int(lastlength) + 2
+ lastlength = 0
+ }
+ if window < lastwindow || length < lastlength {
+ // packDataNsec would return Error{err: "nsec bits out of order"} here, but
+ // when computing the length, we want do be liberal.
+ continue
+ }
+ lastwindow, lastlength = window, length
+ }
+ l += int(lastlength) + 2
+ return l
+}
+
+func packDataNsec(bitmap []uint16, msg []byte, off int) (int, error) {
+ if len(bitmap) == 0 {
+ return off, nil
+ }
+ if off > len(msg) {
+ return off, &Error{err: "overflow packing nsec"}
+ }
+ toZero := msg[off:]
+ if maxLen := typeBitMapLen(bitmap); maxLen < len(toZero) {
+ toZero = toZero[:maxLen]
+ }
+ for i := range toZero {
+ toZero[i] = 0
+ }
+ var lastwindow, lastlength uint16
+ for _, t := range bitmap {
+ window := t / 256
+ length := (t-window*256)/8 + 1
+ if window > lastwindow && lastlength != 0 { // New window, jump to the new offset
+ off += int(lastlength) + 2
+ lastlength = 0
+ }
+ if window < lastwindow || length < lastlength {
+ return len(msg), &Error{err: "nsec bits out of order"}
+ }
+ if off+2+int(length) > len(msg) {
+ return len(msg), &Error{err: "overflow packing nsec"}
+ }
+ // Setting the window #
+ msg[off] = byte(window)
+ // Setting the octets length
+ msg[off+1] = byte(length)
+ // Setting the bit value for the type in the right octet
+ msg[off+1+int(length)] |= byte(1 << (7 - t%8))
+ lastwindow, lastlength = window, length
+ }
+ off += int(lastlength) + 2
+ return off, nil
+}
+
+func unpackDataSVCB(msg []byte, off int) ([]SVCBKeyValue, int, error) {
+ var xs []SVCBKeyValue
+ var code uint16
+ var length uint16
+ var err error
+ for off < len(msg) {
+ code, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return nil, len(msg), &Error{err: "overflow unpacking SVCB"}
+ }
+ length, off, err = unpackUint16(msg, off)
+ if err != nil || off+int(length) > len(msg) {
+ return nil, len(msg), &Error{err: "overflow unpacking SVCB"}
+ }
+ e := makeSVCBKeyValue(SVCBKey(code))
+ if e == nil {
+ return nil, len(msg), &Error{err: "bad SVCB key"}
+ }
+ if err := e.unpack(msg[off : off+int(length)]); err != nil {
+ return nil, len(msg), err
+ }
+ if len(xs) > 0 && e.Key() <= xs[len(xs)-1].Key() {
+ return nil, len(msg), &Error{err: "SVCB keys not in strictly increasing order"}
+ }
+ xs = append(xs, e)
+ off += int(length)
+ }
+ return xs, off, nil
+}
+
+func packDataSVCB(pairs []SVCBKeyValue, msg []byte, off int) (int, error) {
+ pairs = append([]SVCBKeyValue(nil), pairs...)
+ sort.Slice(pairs, func(i, j int) bool {
+ return pairs[i].Key() < pairs[j].Key()
+ })
+ prev := svcb_RESERVED
+ for _, el := range pairs {
+ if el.Key() == prev {
+ return len(msg), &Error{err: "repeated SVCB keys are not allowed"}
+ }
+ prev = el.Key()
+ packed, err := el.pack()
+ if err != nil {
+ return len(msg), err
+ }
+ off, err = packUint16(uint16(el.Key()), msg, off)
+ if err != nil {
+ return len(msg), &Error{err: "overflow packing SVCB"}
+ }
+ off, err = packUint16(uint16(len(packed)), msg, off)
+ if err != nil || off+len(packed) > len(msg) {
+ return len(msg), &Error{err: "overflow packing SVCB"}
+ }
+ copy(msg[off:off+len(packed)], packed)
+ off += len(packed)
+ }
+ return off, nil
+}
+
+func unpackDataDomainNames(msg []byte, off, end int) ([]string, int, error) {
+ var (
+ servers []string
+ s string
+ err error
+ )
+ if end > len(msg) {
+ return nil, len(msg), &Error{err: "overflow unpacking domain names"}
+ }
+ for off < end {
+ s, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return servers, len(msg), err
+ }
+ servers = append(servers, s)
+ }
+ return servers, off, nil
+}
+
+func packDataDomainNames(names []string, msg []byte, off int, compression compressionMap, compress bool) (int, error) {
+ var err error
+ for _, name := range names {
+ off, err = packDomainName(name, msg, off, compression, compress)
+ if err != nil {
+ return len(msg), err
+ }
+ }
+ return off, nil
+}
+
+func packDataApl(data []APLPrefix, msg []byte, off int) (int, error) {
+ var err error
+ for i := range data {
+ off, err = packDataAplPrefix(&data[i], msg, off)
+ if err != nil {
+ return len(msg), err
+ }
+ }
+ return off, nil
+}
+
+func packDataAplPrefix(p *APLPrefix, msg []byte, off int) (int, error) {
+ if len(p.Network.IP) != len(p.Network.Mask) {
+ return len(msg), &Error{err: "address and mask lengths don't match"}
+ }
+
+ var err error
+ prefix, _ := p.Network.Mask.Size()
+ addr := p.Network.IP.Mask(p.Network.Mask)[:(prefix+7)/8]
+
+ switch len(p.Network.IP) {
+ case net.IPv4len:
+ off, err = packUint16(1, msg, off)
+ case net.IPv6len:
+ off, err = packUint16(2, msg, off)
+ default:
+ err = &Error{err: "unrecognized address family"}
+ }
+ if err != nil {
+ return len(msg), err
+ }
+
+ off, err = packUint8(uint8(prefix), msg, off)
+ if err != nil {
+ return len(msg), err
+ }
+
+ var n uint8
+ if p.Negation {
+ n = 0x80
+ }
+
+ // trim trailing zero bytes as specified in RFC3123 Sections 4.1 and 4.2.
+ i := len(addr) - 1
+ for ; i >= 0 && addr[i] == 0; i-- {
+ }
+ addr = addr[:i+1]
+
+ adflen := uint8(len(addr)) & 0x7f
+ off, err = packUint8(n|adflen, msg, off)
+ if err != nil {
+ return len(msg), err
+ }
+
+ if off+len(addr) > len(msg) {
+ return len(msg), &Error{err: "overflow packing APL prefix"}
+ }
+ off += copy(msg[off:], addr)
+
+ return off, nil
+}
+
+func unpackDataApl(msg []byte, off int) ([]APLPrefix, int, error) {
+ var result []APLPrefix
+ for off < len(msg) {
+ prefix, end, err := unpackDataAplPrefix(msg, off)
+ if err != nil {
+ return nil, len(msg), err
+ }
+ off = end
+ result = append(result, prefix)
+ }
+ return result, off, nil
+}
+
+func unpackDataAplPrefix(msg []byte, off int) (APLPrefix, int, error) {
+ family, off, err := unpackUint16(msg, off)
+ if err != nil {
+ return APLPrefix{}, len(msg), &Error{err: "overflow unpacking APL prefix"}
+ }
+ prefix, off, err := unpackUint8(msg, off)
+ if err != nil {
+ return APLPrefix{}, len(msg), &Error{err: "overflow unpacking APL prefix"}
+ }
+ nlen, off, err := unpackUint8(msg, off)
+ if err != nil {
+ return APLPrefix{}, len(msg), &Error{err: "overflow unpacking APL prefix"}
+ }
+
+ var ip []byte
+ switch family {
+ case 1:
+ ip = make([]byte, net.IPv4len)
+ case 2:
+ ip = make([]byte, net.IPv6len)
+ default:
+ return APLPrefix{}, len(msg), &Error{err: "unrecognized APL address family"}
+ }
+ if int(prefix) > 8*len(ip) {
+ return APLPrefix{}, len(msg), &Error{err: "APL prefix too long"}
+ }
+ afdlen := int(nlen & 0x7f)
+ if afdlen > len(ip) {
+ return APLPrefix{}, len(msg), &Error{err: "APL length too long"}
+ }
+ if off+afdlen > len(msg) {
+ return APLPrefix{}, len(msg), &Error{err: "overflow unpacking APL address"}
+ }
+
+ // Address MUST NOT contain trailing zero bytes per RFC3123 Sections 4.1 and 4.2.
+ off += copy(ip, msg[off:off+afdlen])
+ if afdlen > 0 {
+ last := ip[afdlen-1]
+ if last == 0 {
+ return APLPrefix{}, len(msg), &Error{err: "extra APL address bits"}
+ }
+ }
+ ipnet := net.IPNet{
+ IP: ip,
+ Mask: net.CIDRMask(int(prefix), 8*len(ip)),
+ }
+
+ return APLPrefix{
+ Negation: (nlen & 0x80) != 0,
+ Network: ipnet,
+ }, off, nil
+}
diff --git a/vendor/github.com/miekg/dns/msg_truncate.go b/vendor/github.com/miekg/dns/msg_truncate.go
@@ -0,0 +1,117 @@
+package dns
+
+// Truncate ensures the reply message will fit into the requested buffer
+// size by removing records that exceed the requested size.
+//
+// It will first check if the reply fits without compression and then with
+// compression. If it won't fit with compression, Truncate then walks the
+// record adding as many records as possible without exceeding the
+// requested buffer size.
+//
+// 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.
+// If the TC bit is already set on the message it will be retained.
+// TC indicates that the client should retry over TCP.
+//
+// According to RFC 2181, the TC bit should only be set if not all of the
+// "required" RRs can be included in the response. Unfortunately, we have
+// no way of knowing which RRs are required so we set the TC bit if any RR
+// had to be omitted from the response.
+//
+// The appropriate buffer size can be retrieved from the requests OPT
+// record, if present, and is transport specific otherwise. dns.MinMsgSize
+// should be used for UDP requests without an OPT record, and
+// dns.MaxMsgSize for TCP requests without an OPT record.
+func (dns *Msg) Truncate(size int) {
+ if dns.IsTsig() != nil {
+ // To simplify this implementation, we don't perform
+ // truncation on responses with a TSIG record.
+ return
+ }
+
+ // RFC 6891 mandates that the payload size in an OPT record
+ // less than 512 (MinMsgSize) bytes must be treated as equal to 512 bytes.
+ //
+ // For ease of use, we impose that restriction here.
+ if size < MinMsgSize {
+ size = MinMsgSize
+ }
+
+ l := msgLenWithCompressionMap(dns, nil) // uncompressed length
+ if l <= size {
+ // Don't waste effort compressing this message.
+ dns.Compress = false
+ return
+ }
+
+ dns.Compress = true
+
+ edns0 := dns.popEdns0()
+ if edns0 != nil {
+ // Account for the OPT record that gets added at the end,
+ // by subtracting that length from our budget.
+ //
+ // The EDNS(0) OPT record must have the root domain and
+ // it's length is thus unaffected by compression.
+ size -= Len(edns0)
+ }
+
+ compression := make(map[string]struct{})
+
+ l = headerSize
+ for _, r := range dns.Question {
+ l += r.len(l, compression)
+ }
+
+ var numAnswer int
+ if l < size {
+ l, numAnswer = truncateLoop(dns.Answer, size, l, compression)
+ }
+
+ var numNS int
+ if l < size {
+ l, numNS = truncateLoop(dns.Ns, size, l, compression)
+ }
+
+ var numExtra int
+ if l < size {
+ _, numExtra = truncateLoop(dns.Extra, size, l, compression)
+ }
+
+ // See the function documentation for when we set this.
+ dns.Truncated = dns.Truncated || len(dns.Answer) > numAnswer ||
+ len(dns.Ns) > numNS || len(dns.Extra) > numExtra
+
+ dns.Answer = dns.Answer[:numAnswer]
+ dns.Ns = dns.Ns[:numNS]
+ dns.Extra = dns.Extra[:numExtra]
+
+ if edns0 != nil {
+ // Add the OPT record back onto the additional section.
+ dns.Extra = append(dns.Extra, edns0)
+ }
+}
+
+func truncateLoop(rrs []RR, size, l int, compression map[string]struct{}) (int, int) {
+ for i, r := range rrs {
+ if r == nil {
+ continue
+ }
+
+ l += r.len(l, compression)
+ if l > size {
+ // Return size, rather than l prior to this record,
+ // to prevent any further records being added.
+ return size, i
+ }
+ if l == size {
+ return l, i + 1
+ }
+ }
+
+ return l, len(rrs)
+}
diff --git a/vendor/github.com/miekg/dns/nsecx.go b/vendor/github.com/miekg/dns/nsecx.go
@@ -0,0 +1,95 @@
+package dns
+
+import (
+ "crypto/sha1"
+ "encoding/hex"
+ "strings"
+)
+
+// HashName hashes a string (label) according to RFC 5155. It returns the hashed string in uppercase.
+func HashName(label string, ha uint8, iter uint16, salt string) string {
+ if ha != SHA1 {
+ return ""
+ }
+
+ wireSalt := make([]byte, hex.DecodedLen(len(salt)))
+ n, err := packStringHex(salt, wireSalt, 0)
+ if err != nil {
+ return ""
+ }
+ wireSalt = wireSalt[:n]
+
+ name := make([]byte, 255)
+ off, err := PackDomainName(strings.ToLower(label), name, 0, nil, false)
+ if err != nil {
+ return ""
+ }
+ name = name[:off]
+
+ s := sha1.New()
+ // k = 0
+ s.Write(name)
+ s.Write(wireSalt)
+ nsec3 := s.Sum(nil)
+
+ // k > 0
+ for k := uint16(0); k < iter; k++ {
+ s.Reset()
+ s.Write(nsec3)
+ s.Write(wireSalt)
+ nsec3 = s.Sum(nsec3[:0])
+ }
+
+ return toBase32(nsec3)
+}
+
+// Cover returns true if a name is covered by the NSEC3 record.
+func (rr *NSEC3) Cover(name string) bool {
+ nameHash := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
+ owner := strings.ToUpper(rr.Hdr.Name)
+ labelIndices := Split(owner)
+ if len(labelIndices) < 2 {
+ return false
+ }
+ ownerHash := owner[:labelIndices[1]-1]
+ ownerZone := owner[labelIndices[1]:]
+ if !IsSubDomain(ownerZone, strings.ToUpper(name)) { // name is outside owner zone
+ return false
+ }
+
+ nextHash := rr.NextDomain
+
+ // if empty interval found, try cover wildcard hashes so nameHash shouldn't match with ownerHash
+ if ownerHash == nextHash && nameHash != ownerHash { // empty interval
+ return true
+ }
+ if ownerHash > nextHash { // end of zone
+ if nameHash > ownerHash { // covered since there is nothing after ownerHash
+ return true
+ }
+ return nameHash < nextHash // if nameHash is before beginning of zone it is covered
+ }
+ if nameHash < ownerHash { // nameHash is before ownerHash, not covered
+ return false
+ }
+ return nameHash < nextHash // if nameHash is before nextHash is it covered (between ownerHash and nextHash)
+}
+
+// Match returns true if a name matches the NSEC3 record
+func (rr *NSEC3) Match(name string) bool {
+ nameHash := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
+ owner := strings.ToUpper(rr.Hdr.Name)
+ labelIndices := Split(owner)
+ if len(labelIndices) < 2 {
+ return false
+ }
+ ownerHash := owner[:labelIndices[1]-1]
+ ownerZone := owner[labelIndices[1]:]
+ if !IsSubDomain(ownerZone, strings.ToUpper(name)) { // name is outside owner zone
+ return false
+ }
+ if ownerHash == nameHash {
+ return true
+ }
+ return false
+}
diff --git a/vendor/github.com/miekg/dns/privaterr.go b/vendor/github.com/miekg/dns/privaterr.go
@@ -0,0 +1,113 @@
+package dns
+
+import "strings"
+
+// PrivateRdata is an interface used for implementing "Private Use" RR types, see
+// RFC 6895. This allows one to experiment with new RR types, without requesting an
+// official type code. Also see dns.PrivateHandle and dns.PrivateHandleRemove.
+type PrivateRdata interface {
+ // String returns the text presentation of the Rdata of the Private RR.
+ String() string
+ // Parse parses the Rdata of the private RR.
+ Parse([]string) error
+ // Pack is used when packing a private RR into a buffer.
+ Pack([]byte) (int, error)
+ // Unpack is used when unpacking a private RR from a buffer.
+ Unpack([]byte) (int, error)
+ // Copy copies the Rdata into the PrivateRdata argument.
+ Copy(PrivateRdata) error
+ // Len returns the length in octets of the Rdata.
+ Len() int
+}
+
+// PrivateRR represents an RR that uses a PrivateRdata user-defined type.
+// It mocks normal RRs and implements dns.RR interface.
+type PrivateRR struct {
+ Hdr RR_Header
+ Data PrivateRdata
+
+ generator func() PrivateRdata // for copy
+}
+
+// Header return the RR header of r.
+func (r *PrivateRR) Header() *RR_Header { return &r.Hdr }
+
+func (r *PrivateRR) String() string { return r.Hdr.String() + r.Data.String() }
+
+// Private len and copy parts to satisfy RR interface.
+func (r *PrivateRR) len(off int, compression map[string]struct{}) int {
+ l := r.Hdr.len(off, compression)
+ l += r.Data.Len()
+ return l
+}
+
+func (r *PrivateRR) copy() RR {
+ // make new RR like this:
+ rr := &PrivateRR{r.Hdr, r.generator(), r.generator}
+
+ if err := r.Data.Copy(rr.Data); err != nil {
+ panic("dns: got value that could not be used to copy Private rdata: " + err.Error())
+ }
+
+ return rr
+}
+
+func (r *PrivateRR) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) {
+ n, err := r.Data.Pack(msg[off:])
+ if err != nil {
+ return len(msg), err
+ }
+ off += n
+ return off, nil
+}
+
+func (r *PrivateRR) unpack(msg []byte, off int) (int, error) {
+ off1, err := r.Data.Unpack(msg[off:])
+ off += off1
+ return off, err
+}
+
+func (r *PrivateRR) parse(c *zlexer, origin string) *ParseError {
+ var l lex
+ text := make([]string, 0, 2) // could be 0..N elements, median is probably 1
+Fetch:
+ for {
+ // TODO(miek): we could also be returning _QUOTE, this might or might not
+ // be an issue (basically parsing TXT becomes hard)
+ switch l, _ = c.Next(); l.value {
+ case zNewline, zEOF:
+ break Fetch
+ case zString:
+ text = append(text, l.token)
+ }
+ }
+
+ err := r.Data.Parse(text)
+ if err != nil {
+ return &ParseError{"", err.Error(), l}
+ }
+
+ return nil
+}
+
+func (r *PrivateRR) isDuplicate(r2 RR) bool { return false }
+
+// PrivateHandle registers a private resource record type. It requires
+// string and numeric representation of private RR type and generator function as argument.
+func PrivateHandle(rtypestr string, rtype uint16, generator func() PrivateRdata) {
+ rtypestr = strings.ToUpper(rtypestr)
+
+ TypeToRR[rtype] = func() RR { return &PrivateRR{RR_Header{}, generator(), generator} }
+ TypeToString[rtype] = rtypestr
+ StringToType[rtypestr] = rtype
+}
+
+// PrivateHandleRemove removes definitions required to support private RR type.
+func PrivateHandleRemove(rtype uint16) {
+ rtypestr, ok := TypeToString[rtype]
+ if ok {
+ delete(TypeToRR, rtype)
+ delete(TypeToString, rtype)
+ delete(StringToType, rtypestr)
+ }
+}
diff --git a/vendor/github.com/miekg/dns/reverse.go b/vendor/github.com/miekg/dns/reverse.go
@@ -0,0 +1,52 @@
+package dns
+
+// StringToType is the reverse of TypeToString, needed for string parsing.
+var StringToType = reverseInt16(TypeToString)
+
+// StringToClass is the reverse of ClassToString, needed for string parsing.
+var StringToClass = reverseInt16(ClassToString)
+
+// StringToOpcode is a map of opcodes to strings.
+var StringToOpcode = reverseInt(OpcodeToString)
+
+// StringToRcode is a map of rcodes to strings.
+var StringToRcode = reverseInt(RcodeToString)
+
+func init() {
+ // Preserve previous NOTIMP typo, see github.com/miekg/dns/issues/733.
+ StringToRcode["NOTIMPL"] = RcodeNotImplemented
+}
+
+// StringToAlgorithm is the reverse of AlgorithmToString.
+var StringToAlgorithm = reverseInt8(AlgorithmToString)
+
+// StringToHash is a map of names to hash IDs.
+var StringToHash = reverseInt8(HashToString)
+
+// StringToCertType is the reverseof CertTypeToString.
+var StringToCertType = reverseInt16(CertTypeToString)
+
+// Reverse a map
+func reverseInt8(m map[uint8]string) map[string]uint8 {
+ n := make(map[string]uint8, len(m))
+ for u, s := range m {
+ n[s] = u
+ }
+ return n
+}
+
+func reverseInt16(m map[uint16]string) map[string]uint16 {
+ n := make(map[string]uint16, len(m))
+ for u, s := range m {
+ n[s] = u
+ }
+ return n
+}
+
+func reverseInt(m map[int]string) map[string]int {
+ n := make(map[string]int, len(m))
+ for u, s := range m {
+ n[s] = u
+ }
+ return n
+}
diff --git a/vendor/github.com/miekg/dns/sanitize.go b/vendor/github.com/miekg/dns/sanitize.go
@@ -0,0 +1,86 @@
+package dns
+
+// Dedup removes identical RRs from rrs. It preserves the original ordering.
+// The lowest TTL of any duplicates is used in the remaining one. Dedup modifies
+// rrs.
+// m is used to store the RRs temporary. If it is nil a new map will be allocated.
+func Dedup(rrs []RR, m map[string]RR) []RR {
+
+ if m == nil {
+ m = make(map[string]RR)
+ }
+ // Save the keys, so we don't have to call normalizedString twice.
+ keys := make([]*string, 0, len(rrs))
+
+ for _, r := range rrs {
+ key := normalizedString(r)
+ keys = append(keys, &key)
+ if mr, ok := m[key]; ok {
+ // Shortest TTL wins.
+ rh, mrh := r.Header(), mr.Header()
+ if mrh.Ttl > rh.Ttl {
+ mrh.Ttl = rh.Ttl
+ }
+ continue
+ }
+
+ m[key] = r
+ }
+ // If the length of the result map equals the amount of RRs we got,
+ // it means they were all different. We can then just return the original rrset.
+ if len(m) == len(rrs) {
+ return rrs
+ }
+
+ j := 0
+ for i, r := range rrs {
+ // If keys[i] lives in the map, we should copy and remove it.
+ if _, ok := m[*keys[i]]; ok {
+ delete(m, *keys[i])
+ rrs[j] = r
+ j++
+ }
+
+ if len(m) == 0 {
+ break
+ }
+ }
+
+ return rrs[:j]
+}
+
+// normalizedString returns a normalized string from r. The TTL
+// is removed and the domain name is lowercased. We go from this:
+// DomainName<TAB>TTL<TAB>CLASS<TAB>TYPE<TAB>RDATA to:
+// lowercasename<TAB>CLASS<TAB>TYPE...
+func normalizedString(r RR) string {
+ // A string Go DNS makes has: domainname<TAB>TTL<TAB>...
+ b := []byte(r.String())
+
+ // find the first non-escaped tab, then another, so we capture where the TTL lives.
+ esc := false
+ ttlStart, ttlEnd := 0, 0
+ for i := 0; i < len(b) && ttlEnd == 0; i++ {
+ switch {
+ case b[i] == '\\':
+ esc = !esc
+ case b[i] == '\t' && !esc:
+ if ttlStart == 0 {
+ ttlStart = i
+ continue
+ }
+ if ttlEnd == 0 {
+ ttlEnd = i
+ }
+ case b[i] >= 'A' && b[i] <= 'Z' && !esc:
+ b[i] += 32
+ default:
+ esc = false
+ }
+ }
+
+ // remove TTL.
+ copy(b[ttlStart:], b[ttlEnd:])
+ cut := ttlEnd - ttlStart
+ return string(b[:len(b)-cut])
+}
diff --git a/vendor/github.com/miekg/dns/scan.go b/vendor/github.com/miekg/dns/scan.go
@@ -0,0 +1,1368 @@
+package dns
+
+import (
+ "bufio"
+ "fmt"
+ "io"
+ "os"
+ "path/filepath"
+ "strconv"
+ "strings"
+)
+
+const maxTok = 2048 // Largest token we can return.
+
+// The maximum depth of $INCLUDE directives supported by the
+// ZoneParser API.
+const maxIncludeDepth = 7
+
+// Tokinize a RFC 1035 zone file. The tokenizer will normalize it:
+// * Add ownernames if they are left blank;
+// * Suppress sequences of spaces;
+// * Make each RR fit on one line (_NEWLINE is send as last)
+// * Handle comments: ;
+// * Handle braces - anywhere.
+const (
+ // Zonefile
+ zEOF = iota
+ zString
+ zBlank
+ zQuote
+ zNewline
+ zRrtpe
+ zOwner
+ zClass
+ zDirOrigin // $ORIGIN
+ zDirTTL // $TTL
+ zDirInclude // $INCLUDE
+ zDirGenerate // $GENERATE
+
+ // Privatekey file
+ zValue
+ zKey
+
+ zExpectOwnerDir // Ownername
+ zExpectOwnerBl // Whitespace after the ownername
+ zExpectAny // Expect rrtype, ttl or class
+ zExpectAnyNoClass // Expect rrtype or ttl
+ zExpectAnyNoClassBl // The whitespace after _EXPECT_ANY_NOCLASS
+ zExpectAnyNoTTL // Expect rrtype or class
+ zExpectAnyNoTTLBl // Whitespace after _EXPECT_ANY_NOTTL
+ zExpectRrtype // Expect rrtype
+ zExpectRrtypeBl // Whitespace BEFORE rrtype
+ zExpectRdata // The first element of the rdata
+ zExpectDirTTLBl // Space after directive $TTL
+ zExpectDirTTL // Directive $TTL
+ zExpectDirOriginBl // Space after directive $ORIGIN
+ zExpectDirOrigin // Directive $ORIGIN
+ zExpectDirIncludeBl // Space after directive $INCLUDE
+ zExpectDirInclude // Directive $INCLUDE
+ zExpectDirGenerate // Directive $GENERATE
+ zExpectDirGenerateBl // Space after directive $GENERATE
+)
+
+// ParseError is a parsing error. It contains the parse error and the location in the io.Reader
+// where the error occurred.
+type ParseError struct {
+ file string
+ err string
+ lex lex
+}
+
+func (e *ParseError) Error() (s string) {
+ if e.file != "" {
+ s = e.file + ": "
+ }
+ s += "dns: " + e.err + ": " + strconv.QuoteToASCII(e.lex.token) + " at line: " +
+ strconv.Itoa(e.lex.line) + ":" + strconv.Itoa(e.lex.column)
+ return
+}
+
+type lex struct {
+ token string // text of the token
+ err bool // when true, token text has lexer error
+ value uint8 // value: zString, _BLANK, etc.
+ torc uint16 // type or class as parsed in the lexer, we only need to look this up in the grammar
+ line int // line in the file
+ column int // column in the file
+}
+
+// ttlState describes the state necessary to fill in an omitted RR TTL
+type ttlState struct {
+ ttl uint32 // ttl is the current default TTL
+ isByDirective bool // isByDirective indicates whether ttl was set by a $TTL directive
+}
+
+// NewRR reads the RR contained in the string s. Only the first RR is returned.
+// If s contains no records, NewRR will return nil with no error.
+//
+// The class defaults to IN and TTL defaults to 3600. The full zone file syntax
+// like $TTL, $ORIGIN, etc. is supported. All fields of the returned RR are
+// set, except RR.Header().Rdlength which is set to 0.
+func NewRR(s string) (RR, error) {
+ if len(s) > 0 && s[len(s)-1] != '\n' { // We need a closing newline
+ return ReadRR(strings.NewReader(s+"\n"), "")
+ }
+ return ReadRR(strings.NewReader(s), "")
+}
+
+// ReadRR reads the RR contained in r.
+//
+// The string file is used in error reporting and to resolve relative
+// $INCLUDE directives.
+//
+// See NewRR for more documentation.
+func ReadRR(r io.Reader, file string) (RR, error) {
+ zp := NewZoneParser(r, ".", file)
+ zp.SetDefaultTTL(defaultTtl)
+ zp.SetIncludeAllowed(true)
+ rr, _ := zp.Next()
+ return rr, zp.Err()
+}
+
+// ZoneParser is a parser for an RFC 1035 style zonefile.
+//
+// Each parsed RR in the zone is returned sequentially from Next. An
+// optional comment can be retrieved with Comment.
+//
+// The directives $INCLUDE, $ORIGIN, $TTL and $GENERATE are all
+// supported. Although $INCLUDE is disabled by default.
+// Note that $GENERATE's range support up to a maximum of 65535 steps.
+//
+// Basic usage pattern when reading from a string (z) containing the
+// zone data:
+//
+// zp := NewZoneParser(strings.NewReader(z), "", "")
+//
+// for rr, ok := zp.Next(); ok; rr, ok = zp.Next() {
+// // Do something with rr
+// }
+//
+// if err := zp.Err(); err != nil {
+// // log.Println(err)
+// }
+//
+// Comments specified after an RR (and on the same line!) are
+// returned too:
+//
+// foo. IN A 10.0.0.1 ; this is a comment
+//
+// The text "; this is comment" is returned from Comment. Comments inside
+// the RR are returned concatenated along with the RR. Comments on a line
+// by themselves are discarded.
+//
+// Callers should not assume all returned data in an Resource Record is
+// syntactically correct, e.g. illegal base64 in RRSIGs will be returned as-is.
+type ZoneParser struct {
+ c *zlexer
+
+ parseErr *ParseError
+
+ origin string
+ file string
+
+ defttl *ttlState
+
+ h RR_Header
+
+ // sub is used to parse $INCLUDE files and $GENERATE directives.
+ // Next, by calling subNext, forwards the resulting RRs from this
+ // sub parser to the calling code.
+ sub *ZoneParser
+ osFile *os.File
+
+ includeDepth uint8
+
+ includeAllowed bool
+ generateDisallowed bool
+}
+
+// NewZoneParser returns an RFC 1035 style zonefile parser that reads
+// from r.
+//
+// The string file is used in error reporting and to resolve relative
+// $INCLUDE directives. The string origin is used as the initial
+// origin, as if the file would start with an $ORIGIN directive.
+func NewZoneParser(r io.Reader, origin, file string) *ZoneParser {
+ var pe *ParseError
+ if origin != "" {
+ origin = Fqdn(origin)
+ if _, ok := IsDomainName(origin); !ok {
+ pe = &ParseError{file, "bad initial origin name", lex{}}
+ }
+ }
+
+ return &ZoneParser{
+ c: newZLexer(r),
+
+ parseErr: pe,
+
+ origin: origin,
+ file: file,
+ }
+}
+
+// SetDefaultTTL sets the parsers default TTL to ttl.
+func (zp *ZoneParser) SetDefaultTTL(ttl uint32) {
+ zp.defttl = &ttlState{ttl, false}
+}
+
+// SetIncludeAllowed controls whether $INCLUDE directives are
+// allowed. $INCLUDE directives are not supported by default.
+//
+// The $INCLUDE directive will open and read from a user controlled
+// file on the system. Even if the file is not a valid zonefile, the
+// contents of the file may be revealed in error messages, such as:
+//
+// /etc/passwd: dns: not a TTL: "root:x:0:0:root:/root:/bin/bash" at line: 1:31
+// /etc/shadow: dns: not a TTL: "root:$6$<redacted>::0:99999:7:::" at line: 1:125
+func (zp *ZoneParser) SetIncludeAllowed(v bool) {
+ zp.includeAllowed = v
+}
+
+// Err returns the first non-EOF error that was encountered by the
+// ZoneParser.
+func (zp *ZoneParser) Err() error {
+ if zp.parseErr != nil {
+ return zp.parseErr
+ }
+
+ if zp.sub != nil {
+ if err := zp.sub.Err(); err != nil {
+ return err
+ }
+ }
+
+ return zp.c.Err()
+}
+
+func (zp *ZoneParser) setParseError(err string, l lex) (RR, bool) {
+ zp.parseErr = &ParseError{zp.file, err, l}
+ return nil, false
+}
+
+// Comment returns an optional text comment that occurred alongside
+// the RR.
+func (zp *ZoneParser) Comment() string {
+ if zp.parseErr != nil {
+ return ""
+ }
+
+ if zp.sub != nil {
+ return zp.sub.Comment()
+ }
+
+ return zp.c.Comment()
+}
+
+func (zp *ZoneParser) subNext() (RR, bool) {
+ if rr, ok := zp.sub.Next(); ok {
+ return rr, true
+ }
+
+ if zp.sub.osFile != nil {
+ zp.sub.osFile.Close()
+ zp.sub.osFile = nil
+ }
+
+ if zp.sub.Err() != nil {
+ // We have errors to surface.
+ return nil, false
+ }
+
+ zp.sub = nil
+ return zp.Next()
+}
+
+// Next advances the parser to the next RR in the zonefile and
+// returns the (RR, true). It will return (nil, false) when the
+// parsing stops, either by reaching the end of the input or an
+// error. After Next returns (nil, false), the Err method will return
+// any error that occurred during parsing.
+func (zp *ZoneParser) Next() (RR, bool) {
+ if zp.parseErr != nil {
+ return nil, false
+ }
+ if zp.sub != nil {
+ return zp.subNext()
+ }
+
+ // 6 possible beginnings of a line (_ is a space):
+ //
+ // 0. zRRTYPE -> all omitted until the rrtype
+ // 1. zOwner _ zRrtype -> class/ttl omitted
+ // 2. zOwner _ zString _ zRrtype -> class omitted
+ // 3. zOwner _ zString _ zClass _ zRrtype -> ttl/class
+ // 4. zOwner _ zClass _ zRrtype -> ttl omitted
+ // 5. zOwner _ zClass _ zString _ zRrtype -> class/ttl (reversed)
+ //
+ // After detecting these, we know the zRrtype so we can jump to functions
+ // handling the rdata for each of these types.
+
+ st := zExpectOwnerDir // initial state
+ h := &zp.h
+
+ for l, ok := zp.c.Next(); ok; l, ok = zp.c.Next() {
+ // zlexer spotted an error already
+ if l.err {
+ return zp.setParseError(l.token, l)
+ }
+
+ switch st {
+ case zExpectOwnerDir:
+ // We can also expect a directive, like $TTL or $ORIGIN
+ if zp.defttl != nil {
+ h.Ttl = zp.defttl.ttl
+ }
+
+ h.Class = ClassINET
+
+ switch l.value {
+ case zNewline:
+ st = zExpectOwnerDir
+ case zOwner:
+ name, ok := toAbsoluteName(l.token, zp.origin)
+ if !ok {
+ return zp.setParseError("bad owner name", l)
+ }
+
+ h.Name = name
+
+ st = zExpectOwnerBl
+ case zDirTTL:
+ st = zExpectDirTTLBl
+ case zDirOrigin:
+ st = zExpectDirOriginBl
+ case zDirInclude:
+ st = zExpectDirIncludeBl
+ case zDirGenerate:
+ st = zExpectDirGenerateBl
+ case zRrtpe:
+ h.Rrtype = l.torc
+
+ st = zExpectRdata
+ case zClass:
+ h.Class = l.torc
+
+ st = zExpectAnyNoClassBl
+ case zBlank:
+ // Discard, can happen when there is nothing on the
+ // line except the RR type
+ case zString:
+ ttl, ok := stringToTTL(l.token)
+ if !ok {
+ return zp.setParseError("not a TTL", l)
+ }
+
+ h.Ttl = ttl
+
+ if zp.defttl == nil || !zp.defttl.isByDirective {
+ zp.defttl = &ttlState{ttl, false}
+ }
+
+ st = zExpectAnyNoTTLBl
+ default:
+ return zp.setParseError("syntax error at beginning", l)
+ }
+ case zExpectDirIncludeBl:
+ if l.value != zBlank {
+ return zp.setParseError("no blank after $INCLUDE-directive", l)
+ }
+
+ st = zExpectDirInclude
+ case zExpectDirInclude:
+ if l.value != zString {
+ return zp.setParseError("expecting $INCLUDE value, not this...", l)
+ }
+
+ neworigin := zp.origin // There may be optionally a new origin set after the filename, if not use current one
+ switch l, _ := zp.c.Next(); l.value {
+ case zBlank:
+ l, _ := zp.c.Next()
+ if l.value == zString {
+ name, ok := toAbsoluteName(l.token, zp.origin)
+ if !ok {
+ return zp.setParseError("bad origin name", l)
+ }
+
+ neworigin = name
+ }
+ case zNewline, zEOF:
+ // Ok
+ default:
+ return zp.setParseError("garbage after $INCLUDE", l)
+ }
+
+ if !zp.includeAllowed {
+ return zp.setParseError("$INCLUDE directive not allowed", l)
+ }
+ if zp.includeDepth >= maxIncludeDepth {
+ return zp.setParseError("too deeply nested $INCLUDE", l)
+ }
+
+ // Start with the new file
+ includePath := l.token
+ if !filepath.IsAbs(includePath) {
+ includePath = filepath.Join(filepath.Dir(zp.file), includePath)
+ }
+
+ r1, e1 := os.Open(includePath)
+ if e1 != nil {
+ var as string
+ if !filepath.IsAbs(l.token) {
+ as = fmt.Sprintf(" as `%s'", includePath)
+ }
+
+ msg := fmt.Sprintf("failed to open `%s'%s: %v", l.token, as, e1)
+ return zp.setParseError(msg, l)
+ }
+
+ zp.sub = NewZoneParser(r1, neworigin, includePath)
+ zp.sub.defttl, zp.sub.includeDepth, zp.sub.osFile = zp.defttl, zp.includeDepth+1, r1
+ zp.sub.SetIncludeAllowed(true)
+ return zp.subNext()
+ case zExpectDirTTLBl:
+ if l.value != zBlank {
+ return zp.setParseError("no blank after $TTL-directive", l)
+ }
+
+ st = zExpectDirTTL
+ case zExpectDirTTL:
+ if l.value != zString {
+ return zp.setParseError("expecting $TTL value, not this...", l)
+ }
+
+ if err := slurpRemainder(zp.c); err != nil {
+ return zp.setParseError(err.err, err.lex)
+ }
+
+ ttl, ok := stringToTTL(l.token)
+ if !ok {
+ return zp.setParseError("expecting $TTL value, not this...", l)
+ }
+
+ zp.defttl = &ttlState{ttl, true}
+
+ st = zExpectOwnerDir
+ case zExpectDirOriginBl:
+ if l.value != zBlank {
+ return zp.setParseError("no blank after $ORIGIN-directive", l)
+ }
+
+ st = zExpectDirOrigin
+ case zExpectDirOrigin:
+ if l.value != zString {
+ return zp.setParseError("expecting $ORIGIN value, not this...", l)
+ }
+
+ if err := slurpRemainder(zp.c); err != nil {
+ return zp.setParseError(err.err, err.lex)
+ }
+
+ name, ok := toAbsoluteName(l.token, zp.origin)
+ if !ok {
+ return zp.setParseError("bad origin name", l)
+ }
+
+ zp.origin = name
+
+ st = zExpectOwnerDir
+ case zExpectDirGenerateBl:
+ if l.value != zBlank {
+ return zp.setParseError("no blank after $GENERATE-directive", l)
+ }
+
+ st = zExpectDirGenerate
+ case zExpectDirGenerate:
+ if zp.generateDisallowed {
+ return zp.setParseError("nested $GENERATE directive not allowed", l)
+ }
+ if l.value != zString {
+ return zp.setParseError("expecting $GENERATE value, not this...", l)
+ }
+
+ return zp.generate(l)
+ case zExpectOwnerBl:
+ if l.value != zBlank {
+ return zp.setParseError("no blank after owner", l)
+ }
+
+ st = zExpectAny
+ case zExpectAny:
+ switch l.value {
+ case zRrtpe:
+ if zp.defttl == nil {
+ return zp.setParseError("missing TTL with no previous value", l)
+ }
+
+ h.Rrtype = l.torc
+
+ st = zExpectRdata
+ case zClass:
+ h.Class = l.torc
+
+ st = zExpectAnyNoClassBl
+ case zString:
+ ttl, ok := stringToTTL(l.token)
+ if !ok {
+ return zp.setParseError("not a TTL", l)
+ }
+
+ h.Ttl = ttl
+
+ if zp.defttl == nil || !zp.defttl.isByDirective {
+ zp.defttl = &ttlState{ttl, false}
+ }
+
+ st = zExpectAnyNoTTLBl
+ default:
+ return zp.setParseError("expecting RR type, TTL or class, not this...", l)
+ }
+ case zExpectAnyNoClassBl:
+ if l.value != zBlank {
+ return zp.setParseError("no blank before class", l)
+ }
+
+ st = zExpectAnyNoClass
+ case zExpectAnyNoTTLBl:
+ if l.value != zBlank {
+ return zp.setParseError("no blank before TTL", l)
+ }
+
+ st = zExpectAnyNoTTL
+ case zExpectAnyNoTTL:
+ switch l.value {
+ case zClass:
+ h.Class = l.torc
+
+ st = zExpectRrtypeBl
+ case zRrtpe:
+ h.Rrtype = l.torc
+
+ st = zExpectRdata
+ default:
+ return zp.setParseError("expecting RR type or class, not this...", l)
+ }
+ case zExpectAnyNoClass:
+ switch l.value {
+ case zString:
+ ttl, ok := stringToTTL(l.token)
+ if !ok {
+ return zp.setParseError("not a TTL", l)
+ }
+
+ h.Ttl = ttl
+
+ if zp.defttl == nil || !zp.defttl.isByDirective {
+ zp.defttl = &ttlState{ttl, false}
+ }
+
+ st = zExpectRrtypeBl
+ case zRrtpe:
+ h.Rrtype = l.torc
+
+ st = zExpectRdata
+ default:
+ return zp.setParseError("expecting RR type or TTL, not this...", l)
+ }
+ case zExpectRrtypeBl:
+ if l.value != zBlank {
+ return zp.setParseError("no blank before RR type", l)
+ }
+
+ st = zExpectRrtype
+ case zExpectRrtype:
+ if l.value != zRrtpe {
+ return zp.setParseError("unknown RR type", l)
+ }
+
+ h.Rrtype = l.torc
+
+ st = zExpectRdata
+ case zExpectRdata:
+ 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}
+ }
+
+ _, isPrivate := rr.(*PrivateRR)
+ if !isPrivate && zp.c.Peek().token == "" {
+ // This is a dynamic update rr.
+
+ // TODO(tmthrgd): Previously slurpRemainder was only called
+ // for certain RR types, which may have been important.
+ if err := slurpRemainder(zp.c); err != nil {
+ return zp.setParseError(err.err, err.lex)
+ }
+
+ return rr, true
+ } else if l.value == zNewline {
+ return zp.setParseError("unexpected newline", l)
+ }
+
+ 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.
+
+ // err.lex may be nil in which case we substitute our current
+ // lex token.
+ if err.lex == (lex{}) {
+ return zp.setParseError(err.err, l)
+ }
+
+ 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
+ }
+ }
+
+ // If we get here, we and the h.Rrtype is still zero, we haven't parsed anything, this
+ // is not an error, because an empty zone file is still a zone file.
+ return nil, false
+}
+
+type zlexer struct {
+ br io.ByteReader
+
+ readErr error
+
+ line int
+ column int
+
+ comBuf string
+ comment string
+
+ l lex
+ cachedL *lex
+
+ brace int
+ quote bool
+ space bool
+ commt bool
+ rrtype bool
+ owner bool
+
+ nextL bool
+
+ eol bool // end-of-line
+}
+
+func newZLexer(r io.Reader) *zlexer {
+ br, ok := r.(io.ByteReader)
+ if !ok {
+ br = bufio.NewReaderSize(r, 1024)
+ }
+
+ return &zlexer{
+ br: br,
+
+ line: 1,
+
+ owner: true,
+ }
+}
+
+func (zl *zlexer) Err() error {
+ if zl.readErr == io.EOF {
+ return nil
+ }
+
+ return zl.readErr
+}
+
+// readByte returns the next byte from the input
+func (zl *zlexer) readByte() (byte, bool) {
+ if zl.readErr != nil {
+ return 0, false
+ }
+
+ c, err := zl.br.ReadByte()
+ if err != nil {
+ zl.readErr = err
+ return 0, false
+ }
+
+ // delay the newline handling until the next token is delivered,
+ // fixes off-by-one errors when reporting a parse error.
+ if zl.eol {
+ zl.line++
+ zl.column = 0
+ zl.eol = false
+ }
+
+ if c == '\n' {
+ zl.eol = true
+ } else {
+ zl.column++
+ }
+
+ return c, true
+}
+
+func (zl *zlexer) Peek() lex {
+ if zl.nextL {
+ return zl.l
+ }
+
+ l, ok := zl.Next()
+ if !ok {
+ return l
+ }
+
+ if zl.nextL {
+ // Cache l. Next returns zl.cachedL then zl.l.
+ zl.cachedL = &l
+ } else {
+ // In this case l == zl.l, so we just tell Next to return zl.l.
+ zl.nextL = true
+ }
+
+ return l
+}
+
+func (zl *zlexer) Next() (lex, bool) {
+ l := &zl.l
+ switch {
+ case zl.cachedL != nil:
+ l, zl.cachedL = zl.cachedL, nil
+ return *l, true
+ case zl.nextL:
+ zl.nextL = false
+ return *l, true
+ case l.err:
+ // Parsing errors should be sticky.
+ return lex{value: zEOF}, false
+ }
+
+ var (
+ str [maxTok]byte // Hold string text
+ com [maxTok]byte // Hold comment text
+
+ stri int // Offset in str (0 means empty)
+ comi int // Offset in com (0 means empty)
+
+ escape bool
+ )
+
+ if zl.comBuf != "" {
+ comi = copy(com[:], zl.comBuf)
+ zl.comBuf = ""
+ }
+
+ zl.comment = ""
+
+ for x, ok := zl.readByte(); ok; x, ok = zl.readByte() {
+ l.line, l.column = zl.line, zl.column
+
+ if stri >= len(str) {
+ l.token = "token length insufficient for parsing"
+ l.err = true
+ return *l, true
+ }
+ if comi >= len(com) {
+ l.token = "comment length insufficient for parsing"
+ l.err = true
+ return *l, true
+ }
+
+ switch x {
+ case ' ', '\t':
+ if escape || zl.quote {
+ // Inside quotes or escaped this is legal.
+ str[stri] = x
+ stri++
+
+ escape = false
+ break
+ }
+
+ if zl.commt {
+ com[comi] = x
+ comi++
+ break
+ }
+
+ var retL lex
+ if stri == 0 {
+ // Space directly in the beginning, handled in the grammar
+ } else if zl.owner {
+ // If we have a string and its the first, make it an owner
+ l.value = zOwner
+ l.token = string(str[:stri])
+
+ // escape $... start with a \ not a $, so this will work
+ switch strings.ToUpper(l.token) {
+ case "$TTL":
+ l.value = zDirTTL
+ case "$ORIGIN":
+ l.value = zDirOrigin
+ case "$INCLUDE":
+ l.value = zDirInclude
+ case "$GENERATE":
+ l.value = zDirGenerate
+ }
+
+ retL = *l
+ } else {
+ l.value = zString
+ l.token = string(str[:stri])
+
+ if !zl.rrtype {
+ tokenUpper := strings.ToUpper(l.token)
+ if t, ok := StringToType[tokenUpper]; ok {
+ l.value = zRrtpe
+ l.torc = t
+
+ zl.rrtype = true
+ } else if strings.HasPrefix(tokenUpper, "TYPE") {
+ t, ok := typeToInt(l.token)
+ if !ok {
+ l.token = "unknown RR type"
+ l.err = true
+ return *l, true
+ }
+
+ l.value = zRrtpe
+ l.torc = t
+
+ zl.rrtype = true
+ }
+
+ if t, ok := StringToClass[tokenUpper]; ok {
+ l.value = zClass
+ l.torc = t
+ } else if strings.HasPrefix(tokenUpper, "CLASS") {
+ t, ok := classToInt(l.token)
+ if !ok {
+ l.token = "unknown class"
+ l.err = true
+ return *l, true
+ }
+
+ l.value = zClass
+ l.torc = t
+ }
+ }
+
+ retL = *l
+ }
+
+ zl.owner = false
+
+ if !zl.space {
+ zl.space = true
+
+ l.value = zBlank
+ l.token = " "
+
+ if retL == (lex{}) {
+ return *l, true
+ }
+
+ zl.nextL = true
+ }
+
+ if retL != (lex{}) {
+ return retL, true
+ }
+ case ';':
+ if escape || zl.quote {
+ // Inside quotes or escaped this is legal.
+ str[stri] = x
+ stri++
+
+ escape = false
+ break
+ }
+
+ zl.commt = true
+ zl.comBuf = ""
+
+ if comi > 1 {
+ // A newline was previously seen inside a comment that
+ // was inside braces and we delayed adding it until now.
+ com[comi] = ' ' // convert newline to space
+ comi++
+ if comi >= len(com) {
+ l.token = "comment length insufficient for parsing"
+ l.err = true
+ return *l, true
+ }
+ }
+
+ com[comi] = ';'
+ comi++
+
+ if stri > 0 {
+ zl.comBuf = string(com[:comi])
+
+ l.value = zString
+ l.token = string(str[:stri])
+ return *l, true
+ }
+ case '\r':
+ escape = false
+
+ if zl.quote {
+ str[stri] = x
+ stri++
+ }
+
+ // discard if outside of quotes
+ case '\n':
+ escape = false
+
+ // Escaped newline
+ if zl.quote {
+ str[stri] = x
+ stri++
+ break
+ }
+
+ if zl.commt {
+ // Reset a comment
+ zl.commt = false
+ zl.rrtype = false
+
+ // If not in a brace this ends the comment AND the RR
+ if zl.brace == 0 {
+ zl.owner = true
+
+ l.value = zNewline
+ l.token = "\n"
+ zl.comment = string(com[:comi])
+ return *l, true
+ }
+
+ zl.comBuf = string(com[:comi])
+ break
+ }
+
+ if zl.brace == 0 {
+ // If there is previous text, we should output it here
+ var retL lex
+ if stri != 0 {
+ l.value = zString
+ l.token = string(str[:stri])
+
+ if !zl.rrtype {
+ tokenUpper := strings.ToUpper(l.token)
+ if t, ok := StringToType[tokenUpper]; ok {
+ zl.rrtype = true
+
+ l.value = zRrtpe
+ l.torc = t
+ }
+ }
+
+ retL = *l
+ }
+
+ l.value = zNewline
+ l.token = "\n"
+
+ zl.comment = zl.comBuf
+ zl.comBuf = ""
+ zl.rrtype = false
+ zl.owner = true
+
+ if retL != (lex{}) {
+ zl.nextL = true
+ return retL, true
+ }
+
+ return *l, true
+ }
+ case '\\':
+ // comments do not get escaped chars, everything is copied
+ if zl.commt {
+ com[comi] = x
+ comi++
+ break
+ }
+
+ // something already escaped must be in string
+ if escape {
+ str[stri] = x
+ stri++
+
+ escape = false
+ break
+ }
+
+ // something escaped outside of string gets added to string
+ str[stri] = x
+ stri++
+
+ escape = true
+ case '"':
+ if zl.commt {
+ com[comi] = x
+ comi++
+ break
+ }
+
+ if escape {
+ str[stri] = x
+ stri++
+
+ escape = false
+ break
+ }
+
+ zl.space = false
+
+ // send previous gathered text and the quote
+ var retL lex
+ if stri != 0 {
+ l.value = zString
+ l.token = string(str[:stri])
+
+ retL = *l
+ }
+
+ // send quote itself as separate token
+ l.value = zQuote
+ l.token = "\""
+
+ zl.quote = !zl.quote
+
+ if retL != (lex{}) {
+ zl.nextL = true
+ return retL, true
+ }
+
+ return *l, true
+ case '(', ')':
+ if zl.commt {
+ com[comi] = x
+ comi++
+ break
+ }
+
+ if escape || zl.quote {
+ // Inside quotes or escaped this is legal.
+ str[stri] = x
+ stri++
+
+ escape = false
+ break
+ }
+
+ switch x {
+ case ')':
+ zl.brace--
+
+ if zl.brace < 0 {
+ l.token = "extra closing brace"
+ l.err = true
+ return *l, true
+ }
+ case '(':
+ zl.brace++
+ }
+ default:
+ escape = false
+
+ if zl.commt {
+ com[comi] = x
+ comi++
+ break
+ }
+
+ str[stri] = x
+ stri++
+
+ zl.space = false
+ }
+ }
+
+ if zl.readErr != nil && zl.readErr != io.EOF {
+ // Don't return any tokens after a read error occurs.
+ return lex{value: zEOF}, false
+ }
+
+ var retL lex
+ if stri > 0 {
+ // Send remainder of str
+ l.value = zString
+ l.token = string(str[:stri])
+ retL = *l
+
+ if comi <= 0 {
+ return retL, true
+ }
+ }
+
+ if comi > 0 {
+ // Send remainder of com
+ l.value = zNewline
+ l.token = "\n"
+ zl.comment = string(com[:comi])
+
+ if retL != (lex{}) {
+ zl.nextL = true
+ return retL, true
+ }
+
+ return *l, true
+ }
+
+ if zl.brace != 0 {
+ l.token = "unbalanced brace"
+ l.err = true
+ return *l, true
+ }
+
+ return lex{value: zEOF}, false
+}
+
+func (zl *zlexer) Comment() string {
+ if zl.l.err {
+ return ""
+ }
+
+ return zl.comment
+}
+
+// Extract the class number from CLASSxx
+func classToInt(token string) (uint16, bool) {
+ offset := 5
+ if len(token) < offset+1 {
+ return 0, false
+ }
+ class, err := strconv.ParseUint(token[offset:], 10, 16)
+ if err != nil {
+ return 0, false
+ }
+ return uint16(class), true
+}
+
+// Extract the rr number from TYPExxx
+func typeToInt(token string) (uint16, bool) {
+ offset := 4
+ if len(token) < offset+1 {
+ return 0, false
+ }
+ typ, err := strconv.ParseUint(token[offset:], 10, 16)
+ if err != nil {
+ return 0, false
+ }
+ return uint16(typ), true
+}
+
+// stringToTTL parses things like 2w, 2m, etc, and returns the time in seconds.
+func stringToTTL(token string) (uint32, bool) {
+ var s, i uint32
+ for _, c := range token {
+ switch c {
+ case 's', 'S':
+ s += i
+ i = 0
+ case 'm', 'M':
+ s += i * 60
+ i = 0
+ case 'h', 'H':
+ s += i * 60 * 60
+ i = 0
+ case 'd', 'D':
+ s += i * 60 * 60 * 24
+ i = 0
+ case 'w', 'W':
+ s += i * 60 * 60 * 24 * 7
+ i = 0
+ case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ i *= 10
+ i += uint32(c) - '0'
+ default:
+ return 0, false
+ }
+ }
+ return s + i, true
+}
+
+// Parse LOC records' <digits>[.<digits>][mM] into a
+// mantissa exponent format. Token should contain the entire
+// string (i.e. no spaces allowed)
+func stringToCm(token string) (e, m uint8, ok bool) {
+ if token[len(token)-1] == 'M' || token[len(token)-1] == 'm' {
+ token = token[0 : len(token)-1]
+ }
+ s := strings.SplitN(token, ".", 2)
+ var meters, cmeters, val int
+ var err error
+ switch len(s) {
+ case 2:
+ 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 s[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
+ }
+ ok = true
+ if meters > 0 {
+ e = 2
+ val = meters
+ } else {
+ e = 0
+ val = cmeters
+ }
+ for val >= 10 {
+ e++
+ val /= 10
+ }
+ m = uint8(val)
+ return
+}
+
+func toAbsoluteName(name, origin string) (absolute string, ok bool) {
+ // check for an explicit origin reference
+ if name == "@" {
+ // require a nonempty origin
+ if origin == "" {
+ return "", false
+ }
+ return origin, true
+ }
+
+ // require a valid domain name
+ _, ok = IsDomainName(name)
+ if !ok || name == "" {
+ return "", false
+ }
+
+ // check if name is already absolute
+ if IsFqdn(name) {
+ return name, true
+ }
+
+ // require a nonempty origin
+ if origin == "" {
+ return "", false
+ }
+ return appendOrigin(name, origin), true
+}
+
+func appendOrigin(name, origin string) string {
+ if origin == "." {
+ return name + origin
+ }
+ return name + "." + origin
+}
+
+// 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
+ case "s", "S":
+ return LOC_EQUATOR - latitude, true
+ }
+ return latitude, false
+}
+
+// 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
+ case "w", "W":
+ return LOC_EQUATOR - longitude, true
+ }
+ return longitude, false
+}
+
+// "Eat" the rest of the "line"
+func slurpRemainder(c *zlexer) *ParseError {
+ l, _ := c.Next()
+ switch l.value {
+ case zBlank:
+ l, _ = c.Next()
+ if l.value != zNewline && l.value != zEOF {
+ return &ParseError{"", "garbage after rdata", l}
+ }
+ case zNewline:
+ case zEOF:
+ default:
+ return &ParseError{"", "garbage after rdata", l}
+ }
+ return nil
+}
+
+// Parse a 64 bit-like ipv6 address: "0014:4fff:ff20:ee64"
+// Used for NID and L64 record.
+func stringToNodeID(l lex) (uint64, *ParseError) {
+ if len(l.token) < 19 {
+ return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l}
+ }
+ // There must be three colons at fixes positions, if not its a parse error
+ if l.token[4] != ':' && l.token[9] != ':' && l.token[14] != ':' {
+ 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]
+ u, err := strconv.ParseUint(s, 16, 64)
+ if err != nil {
+ return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l}
+ }
+ return u, nil
+}
diff --git a/vendor/github.com/miekg/dns/scan_rr.go b/vendor/github.com/miekg/dns/scan_rr.go
@@ -0,0 +1,1778 @@
+package dns
+
+import (
+ "bytes"
+ "encoding/base64"
+ "net"
+ "strconv"
+ "strings"
+)
+
+// A remainder of the rdata with embedded spaces, return the parsed string (sans the spaces)
+// or an error
+func endingToString(c *zlexer, errstr string) (string, *ParseError) {
+ var buffer bytes.Buffer
+ l, _ := c.Next() // zString
+ for l.value != zNewline && l.value != zEOF {
+ if l.err {
+ return buffer.String(), &ParseError{"", errstr, l}
+ }
+ switch l.value {
+ case zString:
+ buffer.WriteString(l.token)
+ case zBlank: // Ok
+ default:
+ return "", &ParseError{"", errstr, l}
+ }
+ l, _ = c.Next()
+ }
+
+ return buffer.String(), nil
+}
+
+// A remainder of the rdata with embedded spaces, split on unquoted whitespace
+// and return the parsed string slice or an error
+func endingToTxtSlice(c *zlexer, errstr string) ([]string, *ParseError) {
+ // Get the remaining data until we see a zNewline
+ l, _ := c.Next()
+ if l.err {
+ return nil, &ParseError{"", errstr, l}
+ }
+
+ // Build the slice
+ s := make([]string, 0)
+ quote := false
+ empty := false
+ for l.value != zNewline && l.value != zEOF {
+ if l.err {
+ return nil, &ParseError{"", errstr, l}
+ }
+ switch l.value {
+ case zString:
+ empty = false
+ if len(l.token) > 255 {
+ // split up tokens that are larger than 255 into 255-chunks
+ sx := []string{}
+ p, i := 0, 255
+ for {
+ if i <= len(l.token) {
+ sx = append(sx, l.token[p:i])
+ } else {
+ sx = append(sx, l.token[p:])
+ break
+
+ }
+ p, i = p+255, i+255
+ }
+ s = append(s, sx...)
+ break
+ }
+
+ s = append(s, l.token)
+ case zBlank:
+ if quote {
+ // zBlank can only be seen in between txt parts.
+ return nil, &ParseError{"", errstr, l}
+ }
+ case zQuote:
+ if empty && quote {
+ s = append(s, "")
+ }
+ quote = !quote
+ empty = true
+ default:
+ return nil, &ParseError{"", errstr, l}
+ }
+ l, _ = c.Next()
+ }
+
+ if quote {
+ return nil, &ParseError{"", errstr, l}
+ }
+
+ return s, nil
+}
+
+func (rr *A) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ rr.A = net.ParseIP(l.token)
+ // IPv4 addresses cannot include ":".
+ // We do this rather than use net.IP's To4() because
+ // To4() treats IPv4-mapped IPv6 addresses as being
+ // IPv4.
+ isIPv4 := !strings.Contains(l.token, ":")
+ if rr.A == nil || !isIPv4 || l.err {
+ return &ParseError{"", "bad A A", l}
+ }
+ return slurpRemainder(c)
+}
+
+func (rr *AAAA) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ rr.AAAA = net.ParseIP(l.token)
+ // IPv6 addresses must include ":", and IPv4
+ // addresses cannot include ":".
+ isIPv6 := strings.Contains(l.token, ":")
+ if rr.AAAA == nil || !isIPv6 || l.err {
+ return &ParseError{"", "bad AAAA AAAA", l}
+ }
+ return slurpRemainder(c)
+}
+
+func (rr *NS) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ name, nameOk := toAbsoluteName(l.token, o)
+ if l.err || !nameOk {
+ return &ParseError{"", "bad NS Ns", l}
+ }
+ rr.Ns = name
+ return slurpRemainder(c)
+}
+
+func (rr *PTR) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ name, nameOk := toAbsoluteName(l.token, o)
+ if l.err || !nameOk {
+ return &ParseError{"", "bad PTR Ptr", l}
+ }
+ rr.Ptr = name
+ return slurpRemainder(c)
+}
+
+func (rr *NSAPPTR) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ name, nameOk := toAbsoluteName(l.token, o)
+ if l.err || !nameOk {
+ return &ParseError{"", "bad NSAP-PTR Ptr", l}
+ }
+ rr.Ptr = name
+ return slurpRemainder(c)
+}
+
+func (rr *RP) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ mbox, mboxOk := toAbsoluteName(l.token, o)
+ if l.err || !mboxOk {
+ return &ParseError{"", "bad RP Mbox", l}
+ }
+ rr.Mbox = mbox
+
+ c.Next() // zBlank
+ l, _ = c.Next()
+ rr.Txt = l.token
+
+ txt, txtOk := toAbsoluteName(l.token, o)
+ if l.err || !txtOk {
+ return &ParseError{"", "bad RP Txt", l}
+ }
+ rr.Txt = txt
+
+ return slurpRemainder(c)
+}
+
+func (rr *MR) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ name, nameOk := toAbsoluteName(l.token, o)
+ if l.err || !nameOk {
+ return &ParseError{"", "bad MR Mr", l}
+ }
+ rr.Mr = name
+ return slurpRemainder(c)
+}
+
+func (rr *MB) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ name, nameOk := toAbsoluteName(l.token, o)
+ if l.err || !nameOk {
+ return &ParseError{"", "bad MB Mb", l}
+ }
+ rr.Mb = name
+ return slurpRemainder(c)
+}
+
+func (rr *MG) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ name, nameOk := toAbsoluteName(l.token, o)
+ if l.err || !nameOk {
+ return &ParseError{"", "bad MG Mg", l}
+ }
+ rr.Mg = name
+ return slurpRemainder(c)
+}
+
+func (rr *HINFO) parse(c *zlexer, o string) *ParseError {
+ chunks, e := endingToTxtSlice(c, "bad HINFO Fields")
+ if e != nil {
+ return e
+ }
+
+ if ln := len(chunks); ln == 0 {
+ return nil
+ } else if ln == 1 {
+ // Can we split it?
+ if out := strings.Fields(chunks[0]); len(out) > 1 {
+ chunks = out
+ } else {
+ chunks = append(chunks, "")
+ }
+ }
+
+ rr.Cpu = chunks[0]
+ rr.Os = strings.Join(chunks[1:], " ")
+
+ return nil
+}
+
+func (rr *MINFO) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ rmail, rmailOk := toAbsoluteName(l.token, o)
+ if l.err || !rmailOk {
+ return &ParseError{"", "bad MINFO Rmail", l}
+ }
+ rr.Rmail = rmail
+
+ c.Next() // zBlank
+ l, _ = c.Next()
+ rr.Email = l.token
+
+ email, emailOk := toAbsoluteName(l.token, o)
+ if l.err || !emailOk {
+ return &ParseError{"", "bad MINFO Email", l}
+ }
+ rr.Email = email
+
+ return slurpRemainder(c)
+}
+
+func (rr *MF) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ name, nameOk := toAbsoluteName(l.token, o)
+ if l.err || !nameOk {
+ return &ParseError{"", "bad MF Mf", l}
+ }
+ rr.Mf = name
+ return slurpRemainder(c)
+}
+
+func (rr *MD) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ name, nameOk := toAbsoluteName(l.token, o)
+ if l.err || !nameOk {
+ return &ParseError{"", "bad MD Md", l}
+ }
+ rr.Md = name
+ return slurpRemainder(c)
+}
+
+func (rr *MX) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 16)
+ if e != nil || l.err {
+ return &ParseError{"", "bad MX Pref", l}
+ }
+ rr.Preference = uint16(i)
+
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
+ rr.Mx = l.token
+
+ name, nameOk := toAbsoluteName(l.token, o)
+ if l.err || !nameOk {
+ return &ParseError{"", "bad MX Mx", l}
+ }
+ rr.Mx = name
+
+ return slurpRemainder(c)
+}
+
+func (rr *RT) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 16)
+ if e != nil {
+ return &ParseError{"", "bad RT Preference", l}
+ }
+ rr.Preference = uint16(i)
+
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
+ rr.Host = l.token
+
+ name, nameOk := toAbsoluteName(l.token, o)
+ if l.err || !nameOk {
+ return &ParseError{"", "bad RT Host", l}
+ }
+ rr.Host = name
+
+ return slurpRemainder(c)
+}
+
+func (rr *AFSDB) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 16)
+ if e != nil || l.err {
+ return &ParseError{"", "bad AFSDB Subtype", l}
+ }
+ rr.Subtype = uint16(i)
+
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
+ rr.Hostname = l.token
+
+ name, nameOk := toAbsoluteName(l.token, o)
+ if l.err || !nameOk {
+ return &ParseError{"", "bad AFSDB Hostname", l}
+ }
+ rr.Hostname = name
+ return slurpRemainder(c)
+}
+
+func (rr *X25) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ if l.err {
+ return &ParseError{"", "bad X25 PSDNAddress", l}
+ }
+ rr.PSDNAddress = l.token
+ return slurpRemainder(c)
+}
+
+func (rr *KX) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 16)
+ if e != nil || l.err {
+ return &ParseError{"", "bad KX Pref", l}
+ }
+ rr.Preference = uint16(i)
+
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
+ rr.Exchanger = l.token
+
+ name, nameOk := toAbsoluteName(l.token, o)
+ if l.err || !nameOk {
+ return &ParseError{"", "bad KX Exchanger", l}
+ }
+ rr.Exchanger = name
+ return slurpRemainder(c)
+}
+
+func (rr *CNAME) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ name, nameOk := toAbsoluteName(l.token, o)
+ if l.err || !nameOk {
+ return &ParseError{"", "bad CNAME Target", l}
+ }
+ rr.Target = name
+ return slurpRemainder(c)
+}
+
+func (rr *DNAME) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ name, nameOk := toAbsoluteName(l.token, o)
+ if l.err || !nameOk {
+ return &ParseError{"", "bad DNAME Target", l}
+ }
+ rr.Target = name
+ return slurpRemainder(c)
+}
+
+func (rr *SOA) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ ns, nsOk := toAbsoluteName(l.token, o)
+ if l.err || !nsOk {
+ return &ParseError{"", "bad SOA Ns", l}
+ }
+ rr.Ns = ns
+
+ c.Next() // zBlank
+ l, _ = c.Next()
+ rr.Mbox = l.token
+
+ mbox, mboxOk := toAbsoluteName(l.token, o)
+ if l.err || !mboxOk {
+ return &ParseError{"", "bad SOA Mbox", l}
+ }
+ rr.Mbox = mbox
+
+ c.Next() // zBlank
+
+ var (
+ v uint32
+ ok bool
+ )
+ for i := 0; i < 5; i++ {
+ l, _ = c.Next()
+ if l.err {
+ return &ParseError{"", "bad SOA zone parameter", l}
+ }
+ if j, err := strconv.ParseUint(l.token, 10, 32); err != nil {
+ if i == 0 {
+ // Serial must be a number
+ return &ParseError{"", "bad SOA zone parameter", l}
+ }
+ // We allow other fields to be unitful duration strings
+ if v, ok = stringToTTL(l.token); !ok {
+ return &ParseError{"", "bad SOA zone parameter", l}
+
+ }
+ } else {
+ v = uint32(j)
+ }
+ switch i {
+ case 0:
+ rr.Serial = v
+ c.Next() // zBlank
+ case 1:
+ rr.Refresh = v
+ c.Next() // zBlank
+ case 2:
+ rr.Retry = v
+ c.Next() // zBlank
+ case 3:
+ rr.Expire = v
+ c.Next() // zBlank
+ case 4:
+ rr.Minttl = v
+ }
+ }
+ return slurpRemainder(c)
+}
+
+func (rr *SRV) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 16)
+ if e != nil || l.err {
+ return &ParseError{"", "bad SRV Priority", l}
+ }
+ rr.Priority = uint16(i)
+
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
+ i, e1 := strconv.ParseUint(l.token, 10, 16)
+ if e1 != nil || l.err {
+ return &ParseError{"", "bad SRV Weight", l}
+ }
+ rr.Weight = uint16(i)
+
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
+ i, e2 := strconv.ParseUint(l.token, 10, 16)
+ if e2 != nil || l.err {
+ return &ParseError{"", "bad SRV Port", l}
+ }
+ rr.Port = 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{"", "bad SRV Target", l}
+ }
+ rr.Target = name
+ return slurpRemainder(c)
+}
+
+func (rr *NAPTR) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 16)
+ if e != nil || l.err {
+ return &ParseError{"", "bad NAPTR Order", l}
+ }
+ rr.Order = uint16(i)
+
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
+ i, e1 := strconv.ParseUint(l.token, 10, 16)
+ if e1 != nil || l.err {
+ return &ParseError{"", "bad NAPTR Preference", l}
+ }
+ rr.Preference = uint16(i)
+
+ // Flags
+ c.Next() // zBlank
+ l, _ = c.Next() // _QUOTE
+ if l.value != zQuote {
+ return &ParseError{"", "bad NAPTR Flags", l}
+ }
+ l, _ = c.Next() // Either String or Quote
+ if l.value == zString {
+ rr.Flags = l.token
+ l, _ = c.Next() // _QUOTE
+ if l.value != zQuote {
+ return &ParseError{"", "bad NAPTR Flags", l}
+ }
+ } else if l.value == zQuote {
+ rr.Flags = ""
+ } else {
+ return &ParseError{"", "bad NAPTR Flags", l}
+ }
+
+ // Service
+ c.Next() // zBlank
+ l, _ = c.Next() // _QUOTE
+ if l.value != zQuote {
+ return &ParseError{"", "bad NAPTR Service", l}
+ }
+ l, _ = c.Next() // Either String or Quote
+ if l.value == zString {
+ rr.Service = l.token
+ l, _ = c.Next() // _QUOTE
+ if l.value != zQuote {
+ return &ParseError{"", "bad NAPTR Service", l}
+ }
+ } else if l.value == zQuote {
+ rr.Service = ""
+ } else {
+ return &ParseError{"", "bad NAPTR Service", l}
+ }
+
+ // Regexp
+ c.Next() // zBlank
+ l, _ = c.Next() // _QUOTE
+ if l.value != zQuote {
+ return &ParseError{"", "bad NAPTR Regexp", l}
+ }
+ l, _ = c.Next() // Either String or Quote
+ if l.value == zString {
+ rr.Regexp = l.token
+ l, _ = c.Next() // _QUOTE
+ if l.value != zQuote {
+ return &ParseError{"", "bad NAPTR Regexp", l}
+ }
+ } else if l.value == zQuote {
+ rr.Regexp = ""
+ } else {
+ return &ParseError{"", "bad NAPTR Regexp", l}
+ }
+
+ // After quote no space??
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
+ rr.Replacement = l.token
+
+ name, nameOk := toAbsoluteName(l.token, o)
+ if l.err || !nameOk {
+ return &ParseError{"", "bad NAPTR Replacement", l}
+ }
+ rr.Replacement = name
+ return slurpRemainder(c)
+}
+
+func (rr *TALINK) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ previousName, previousNameOk := toAbsoluteName(l.token, o)
+ if l.err || !previousNameOk {
+ return &ParseError{"", "bad TALINK PreviousName", l}
+ }
+ rr.PreviousName = previousName
+
+ c.Next() // zBlank
+ l, _ = c.Next()
+ rr.NextName = l.token
+
+ nextName, nextNameOk := toAbsoluteName(l.token, o)
+ if l.err || !nextNameOk {
+ return &ParseError{"", "bad TALINK NextName", l}
+ }
+ rr.NextName = nextName
+
+ return slurpRemainder(c)
+}
+
+func (rr *LOC) parse(c *zlexer, o string) *ParseError {
+ // Non zero defaults for LOC record, see RFC 1876, Section 3.
+ rr.Size = 0x12 // 1e2 cm (1m)
+ rr.HorizPre = 0x16 // 1e6 cm (10000m)
+ rr.VertPre = 0x13 // 1e3 cm (10m)
+ ok := false
+
+ // North
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 32)
+ if e != nil || l.err || i > 90 {
+ return &ParseError{"", "bad LOC Latitude", l}
+ }
+ rr.Latitude = 1000 * 60 * 60 * uint32(i)
+
+ c.Next() // zBlank
+ // Either number, 'N' or 'S'
+ l, _ = c.Next()
+ 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 || i > 59 {
+ return &ParseError{"", "bad LOC Latitude minutes", l}
+ } else {
+ rr.Latitude += 1000 * 60 * uint32(i)
+ }
+
+ c.Next() // zBlank
+ l, _ = c.Next()
+ if i, err := strconv.ParseFloat(l.token, 64); err != nil || l.err || i < 0 || i >= 60 {
+ return &ParseError{"", "bad LOC Latitude seconds", l}
+ } else {
+ rr.Latitude += uint32(1000 * i)
+ }
+ c.Next() // zBlank
+ // Either number, 'N' or 'S'
+ l, _ = c.Next()
+ if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok {
+ goto East
+ }
+ // If still alive, flag an error
+ return &ParseError{"", "bad LOC Latitude North/South", l}
+
+East:
+ // East
+ c.Next() // zBlank
+ l, _ = c.Next()
+ 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)
+ }
+ c.Next() // zBlank
+ // Either number, 'E' or 'W'
+ l, _ = c.Next()
+ 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 || 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, 64); err != nil || l.err || i < 0 || i >= 60 {
+ return &ParseError{"", "bad LOC Longitude seconds", l}
+ } else {
+ rr.Longitude += uint32(1000 * i)
+ }
+ c.Next() // zBlank
+ // Either number, 'E' or 'W'
+ l, _ = c.Next()
+ if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok {
+ goto Altitude
+ }
+ // If still alive, flag an error
+ return &ParseError{"", "bad LOC Longitude East/West", l}
+
+Altitude:
+ c.Next() // zBlank
+ l, _ = c.Next()
+ if l.token == "" || l.err {
+ return &ParseError{"", "bad LOC Altitude", l}
+ }
+ 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, 64); err != nil {
+ return &ParseError{"", "bad LOC Altitude", l}
+ } else {
+ rr.Altitude = uint32(i*100.0 + 10000000.0 + 0.5)
+ }
+
+ // And now optionally the other values
+ l, _ = c.Next()
+ count := 0
+ for l.value != zNewline && l.value != zEOF {
+ switch l.value {
+ case zString:
+ switch count {
+ case 0: // Size
+ exp, m, ok := stringToCm(l.token)
+ if !ok {
+ return &ParseError{"", "bad LOC Size", l}
+ }
+ rr.Size = exp&0x0f | m<<4&0xf0
+ case 1: // HorizPre
+ exp, m, ok := stringToCm(l.token)
+ if !ok {
+ return &ParseError{"", "bad LOC HorizPre", l}
+ }
+ rr.HorizPre = exp&0x0f | m<<4&0xf0
+ case 2: // VertPre
+ exp, m, ok := stringToCm(l.token)
+ if !ok {
+ return &ParseError{"", "bad LOC VertPre", l}
+ }
+ rr.VertPre = exp&0x0f | m<<4&0xf0
+ }
+ count++
+ case zBlank:
+ // Ok
+ default:
+ return &ParseError{"", "bad LOC Size, HorizPre or VertPre", l}
+ }
+ l, _ = c.Next()
+ }
+ return nil
+}
+
+func (rr *HIP) parse(c *zlexer, o string) *ParseError {
+ // HitLength is not represented
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 8)
+ if e != nil || l.err {
+ return &ParseError{"", "bad HIP PublicKeyAlgorithm", l}
+ }
+ rr.PublicKeyAlgorithm = uint8(i)
+
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
+ if l.token == "" || l.err {
+ return &ParseError{"", "bad HIP Hit", l}
+ }
+ rr.Hit = l.token // This can not contain spaces, see RFC 5205 Section 6.
+ rr.HitLength = uint8(len(rr.Hit)) / 2
+
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
+ if l.token == "" || l.err {
+ return &ParseError{"", "bad HIP PublicKey", l}
+ }
+ rr.PublicKey = l.token // This cannot contain spaces
+ decodedPK, decodedPKerr := base64.StdEncoding.DecodeString(rr.PublicKey)
+ if decodedPKerr != nil {
+ return &ParseError{"", "bad HIP PublicKey", l}
+ }
+ rr.PublicKeyLength = uint16(len(decodedPK))
+
+ // RendezvousServers (if any)
+ l, _ = c.Next()
+ var xs []string
+ for l.value != zNewline && l.value != zEOF {
+ switch l.value {
+ case zString:
+ name, nameOk := toAbsoluteName(l.token, o)
+ if l.err || !nameOk {
+ return &ParseError{"", "bad HIP RendezvousServers", l}
+ }
+ xs = append(xs, name)
+ case zBlank:
+ // Ok
+ default:
+ return &ParseError{"", "bad HIP RendezvousServers", l}
+ }
+ l, _ = c.Next()
+ }
+
+ rr.RendezvousServers = xs
+ return nil
+}
+
+func (rr *CERT) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ if v, ok := StringToCertType[l.token]; ok {
+ rr.Type = v
+ } else if i, err := strconv.ParseUint(l.token, 10, 16); err != nil {
+ return &ParseError{"", "bad CERT Type", l}
+ } else {
+ rr.Type = uint16(i)
+ }
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
+ i, e := strconv.ParseUint(l.token, 10, 16)
+ if e != nil || l.err {
+ return &ParseError{"", "bad CERT KeyTag", l}
+ }
+ rr.KeyTag = uint16(i)
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
+ if v, ok := StringToAlgorithm[l.token]; ok {
+ rr.Algorithm = v
+ } else if i, err := strconv.ParseUint(l.token, 10, 8); err != nil {
+ return &ParseError{"", "bad CERT Algorithm", l}
+ } else {
+ rr.Algorithm = uint8(i)
+ }
+ s, e1 := endingToString(c, "bad CERT Certificate")
+ if e1 != nil {
+ return e1
+ }
+ rr.Certificate = s
+ return nil
+}
+
+func (rr *OPENPGPKEY) parse(c *zlexer, o string) *ParseError {
+ s, e := endingToString(c, "bad OPENPGPKEY PublicKey")
+ if e != nil {
+ return e
+ }
+ rr.PublicKey = s
+ return nil
+}
+
+func (rr *CSYNC) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ j, e := strconv.ParseUint(l.token, 10, 32)
+ if e != nil {
+ // Serial must be a number
+ return &ParseError{"", "bad CSYNC serial", l}
+ }
+ rr.Serial = uint32(j)
+
+ c.Next() // zBlank
+
+ l, _ = c.Next()
+ j, e1 := strconv.ParseUint(l.token, 10, 16)
+ if e1 != nil {
+ // Serial must be a number
+ return &ParseError{"", "bad CSYNC flags", l}
+ }
+ rr.Flags = uint16(j)
+
+ rr.TypeBitMap = make([]uint16, 0)
+ var (
+ k uint16
+ ok bool
+ )
+ l, _ = c.Next()
+ for l.value != zNewline && l.value != zEOF {
+ switch l.value {
+ case zBlank:
+ // Ok
+ case zString:
+ tokenUpper := strings.ToUpper(l.token)
+ if k, ok = StringToType[tokenUpper]; !ok {
+ if k, ok = typeToInt(l.token); !ok {
+ return &ParseError{"", "bad CSYNC TypeBitMap", l}
+ }
+ }
+ rr.TypeBitMap = append(rr.TypeBitMap, k)
+ default:
+ return &ParseError{"", "bad CSYNC TypeBitMap", l}
+ }
+ l, _ = c.Next()
+ }
+ return nil
+}
+
+func (rr *ZONEMD) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 32)
+ if e != nil || l.err {
+ return &ParseError{"", "bad ZONEMD Serial", l}
+ }
+ rr.Serial = uint32(i)
+
+ c.Next() // zBlank
+ l, _ = c.Next()
+ i, e1 := strconv.ParseUint(l.token, 10, 8)
+ if e1 != nil || l.err {
+ return &ParseError{"", "bad ZONEMD Scheme", l}
+ }
+ rr.Scheme = uint8(i)
+
+ c.Next() // zBlank
+ l, _ = c.Next()
+ i, err := strconv.ParseUint(l.token, 10, 8)
+ if err != nil || l.err {
+ return &ParseError{"", "bad ZONEMD Hash Algorithm", l}
+ }
+ rr.Hash = uint8(i)
+
+ s, e2 := endingToString(c, "bad ZONEMD Digest")
+ if e2 != nil {
+ return e2
+ }
+ rr.Digest = s
+ return nil
+}
+
+func (rr *SIG) parse(c *zlexer, o string) *ParseError { return rr.RRSIG.parse(c, o) }
+
+func (rr *RRSIG) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ tokenUpper := strings.ToUpper(l.token)
+ if t, ok := StringToType[tokenUpper]; !ok {
+ if strings.HasPrefix(tokenUpper, "TYPE") {
+ t, ok = typeToInt(l.token)
+ if !ok {
+ return &ParseError{"", "bad RRSIG Typecovered", l}
+ }
+ rr.TypeCovered = t
+ } else {
+ return &ParseError{"", "bad RRSIG Typecovered", l}
+ }
+ } else {
+ rr.TypeCovered = t
+ }
+
+ c.Next() // zBlank
+ l, _ = c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 8)
+ if e != nil || l.err {
+ return &ParseError{"", "bad RRSIG Algorithm", l}
+ }
+ rr.Algorithm = uint8(i)
+
+ c.Next() // zBlank
+ l, _ = c.Next()
+ i, e1 := strconv.ParseUint(l.token, 10, 8)
+ if e1 != nil || l.err {
+ return &ParseError{"", "bad RRSIG Labels", l}
+ }
+ rr.Labels = uint8(i)
+
+ c.Next() // zBlank
+ l, _ = c.Next()
+ i, e2 := strconv.ParseUint(l.token, 10, 32)
+ if e2 != nil || l.err {
+ return &ParseError{"", "bad RRSIG OrigTtl", l}
+ }
+ rr.OrigTtl = uint32(i)
+
+ c.Next() // zBlank
+ 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.ParseUint(l.token, 10, 32); err == nil {
+ rr.Expiration = uint32(i)
+ } else {
+ return &ParseError{"", "bad RRSIG Expiration", l}
+ }
+ } else {
+ rr.Expiration = i
+ }
+
+ c.Next() // zBlank
+ l, _ = c.Next()
+ if i, err := StringToTime(l.token); err != nil {
+ if i, err := strconv.ParseUint(l.token, 10, 32); err == nil {
+ rr.Inception = uint32(i)
+ } else {
+ return &ParseError{"", "bad RRSIG Inception", l}
+ }
+ } else {
+ rr.Inception = i
+ }
+
+ c.Next() // zBlank
+ l, _ = c.Next()
+ i, e3 := strconv.ParseUint(l.token, 10, 16)
+ if e3 != nil || l.err {
+ return &ParseError{"", "bad RRSIG KeyTag", l}
+ }
+ rr.KeyTag = uint16(i)
+
+ c.Next() // zBlank
+ l, _ = c.Next()
+ rr.SignerName = l.token
+ name, nameOk := toAbsoluteName(l.token, o)
+ if l.err || !nameOk {
+ return &ParseError{"", "bad RRSIG SignerName", l}
+ }
+ rr.SignerName = name
+
+ s, e4 := endingToString(c, "bad RRSIG Signature")
+ if e4 != nil {
+ return e4
+ }
+ rr.Signature = s
+
+ return nil
+}
+
+func (rr *NSEC) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ name, nameOk := toAbsoluteName(l.token, o)
+ if l.err || !nameOk {
+ return &ParseError{"", "bad NSEC NextDomain", l}
+ }
+ rr.NextDomain = name
+
+ rr.TypeBitMap = make([]uint16, 0)
+ var (
+ k uint16
+ ok bool
+ )
+ l, _ = c.Next()
+ for l.value != zNewline && l.value != zEOF {
+ switch l.value {
+ case zBlank:
+ // Ok
+ case zString:
+ tokenUpper := strings.ToUpper(l.token)
+ if k, ok = StringToType[tokenUpper]; !ok {
+ if k, ok = typeToInt(l.token); !ok {
+ return &ParseError{"", "bad NSEC TypeBitMap", l}
+ }
+ }
+ rr.TypeBitMap = append(rr.TypeBitMap, k)
+ default:
+ return &ParseError{"", "bad NSEC TypeBitMap", l}
+ }
+ l, _ = c.Next()
+ }
+ return nil
+}
+
+func (rr *NSEC3) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 8)
+ if e != nil || l.err {
+ return &ParseError{"", "bad NSEC3 Hash", l}
+ }
+ rr.Hash = uint8(i)
+ c.Next() // zBlank
+ l, _ = c.Next()
+ i, e1 := strconv.ParseUint(l.token, 10, 8)
+ if e1 != nil || l.err {
+ return &ParseError{"", "bad NSEC3 Flags", l}
+ }
+ rr.Flags = uint8(i)
+ c.Next() // zBlank
+ l, _ = c.Next()
+ i, e2 := strconv.ParseUint(l.token, 10, 16)
+ if e2 != nil || l.err {
+ return &ParseError{"", "bad NSEC3 Iterations", l}
+ }
+ rr.Iterations = uint16(i)
+ c.Next()
+ l, _ = c.Next()
+ if l.token == "" || l.err {
+ return &ParseError{"", "bad NSEC3 Salt", l}
+ }
+ if l.token != "-" {
+ rr.SaltLength = uint8(len(l.token)) / 2
+ rr.Salt = l.token
+ }
+
+ c.Next()
+ l, _ = c.Next()
+ if l.token == "" || l.err {
+ return &ParseError{"", "bad NSEC3 NextDomain", l}
+ }
+ rr.HashLength = 20 // Fix for NSEC3 (sha1 160 bits)
+ rr.NextDomain = l.token
+
+ rr.TypeBitMap = make([]uint16, 0)
+ var (
+ k uint16
+ ok bool
+ )
+ l, _ = c.Next()
+ for l.value != zNewline && l.value != zEOF {
+ switch l.value {
+ case zBlank:
+ // Ok
+ case zString:
+ tokenUpper := strings.ToUpper(l.token)
+ if k, ok = StringToType[tokenUpper]; !ok {
+ if k, ok = typeToInt(l.token); !ok {
+ return &ParseError{"", "bad NSEC3 TypeBitMap", l}
+ }
+ }
+ rr.TypeBitMap = append(rr.TypeBitMap, k)
+ default:
+ return &ParseError{"", "bad NSEC3 TypeBitMap", l}
+ }
+ l, _ = c.Next()
+ }
+ return nil
+}
+
+func (rr *NSEC3PARAM) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 8)
+ if e != nil || l.err {
+ return &ParseError{"", "bad NSEC3PARAM Hash", l}
+ }
+ rr.Hash = uint8(i)
+ c.Next() // zBlank
+ l, _ = c.Next()
+ i, e1 := strconv.ParseUint(l.token, 10, 8)
+ if e1 != nil || l.err {
+ return &ParseError{"", "bad NSEC3PARAM Flags", l}
+ }
+ rr.Flags = uint8(i)
+ c.Next() // zBlank
+ l, _ = c.Next()
+ i, e2 := strconv.ParseUint(l.token, 10, 16)
+ if e2 != nil || l.err {
+ return &ParseError{"", "bad NSEC3PARAM Iterations", l}
+ }
+ rr.Iterations = uint16(i)
+ c.Next()
+ l, _ = c.Next()
+ if l.token != "-" {
+ rr.SaltLength = uint8(len(l.token) / 2)
+ rr.Salt = l.token
+ }
+ return slurpRemainder(c)
+}
+
+func (rr *EUI48) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ if len(l.token) != 17 || l.err {
+ return &ParseError{"", "bad EUI48 Address", l}
+ }
+ addr := make([]byte, 12)
+ dash := 0
+ for i := 0; i < 10; i += 2 {
+ addr[i] = l.token[i+dash]
+ addr[i+1] = l.token[i+1+dash]
+ dash++
+ if l.token[i+1+dash] != '-' {
+ return &ParseError{"", "bad EUI48 Address", l}
+ }
+ }
+ addr[10] = l.token[15]
+ addr[11] = l.token[16]
+
+ i, e := strconv.ParseUint(string(addr), 16, 48)
+ if e != nil {
+ return &ParseError{"", "bad EUI48 Address", l}
+ }
+ rr.Address = i
+ return slurpRemainder(c)
+}
+
+func (rr *EUI64) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ if len(l.token) != 23 || l.err {
+ return &ParseError{"", "bad EUI64 Address", l}
+ }
+ addr := make([]byte, 16)
+ dash := 0
+ for i := 0; i < 14; i += 2 {
+ addr[i] = l.token[i+dash]
+ addr[i+1] = l.token[i+1+dash]
+ dash++
+ if l.token[i+1+dash] != '-' {
+ return &ParseError{"", "bad EUI64 Address", l}
+ }
+ }
+ addr[14] = l.token[21]
+ addr[15] = l.token[22]
+
+ i, e := strconv.ParseUint(string(addr), 16, 64)
+ if e != nil {
+ return &ParseError{"", "bad EUI68 Address", l}
+ }
+ rr.Address = i
+ return slurpRemainder(c)
+}
+
+func (rr *SSHFP) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 8)
+ if e != nil || l.err {
+ return &ParseError{"", "bad SSHFP Algorithm", l}
+ }
+ rr.Algorithm = uint8(i)
+ c.Next() // zBlank
+ l, _ = c.Next()
+ i, e1 := strconv.ParseUint(l.token, 10, 8)
+ if e1 != nil || l.err {
+ return &ParseError{"", "bad SSHFP Type", l}
+ }
+ rr.Type = uint8(i)
+ c.Next() // zBlank
+ s, e2 := endingToString(c, "bad SSHFP Fingerprint")
+ if e2 != nil {
+ return e2
+ }
+ rr.FingerPrint = s
+ return nil
+}
+
+func (rr *DNSKEY) parseDNSKEY(c *zlexer, o, typ string) *ParseError {
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 16)
+ if e != nil || l.err {
+ return &ParseError{"", "bad " + typ + " Flags", l}
+ }
+ rr.Flags = uint16(i)
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
+ i, e1 := strconv.ParseUint(l.token, 10, 8)
+ if e1 != nil || l.err {
+ return &ParseError{"", "bad " + typ + " Protocol", l}
+ }
+ rr.Protocol = uint8(i)
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
+ i, e2 := strconv.ParseUint(l.token, 10, 8)
+ if e2 != nil || l.err {
+ return &ParseError{"", "bad " + typ + " Algorithm", l}
+ }
+ rr.Algorithm = uint8(i)
+ s, e3 := endingToString(c, "bad "+typ+" PublicKey")
+ if e3 != nil {
+ return e3
+ }
+ rr.PublicKey = s
+ return nil
+}
+
+func (rr *DNSKEY) parse(c *zlexer, o string) *ParseError { return rr.parseDNSKEY(c, o, "DNSKEY") }
+func (rr *KEY) parse(c *zlexer, o string) *ParseError { return rr.parseDNSKEY(c, o, "KEY") }
+func (rr *CDNSKEY) parse(c *zlexer, o string) *ParseError { return rr.parseDNSKEY(c, o, "CDNSKEY") }
+func (rr *DS) parse(c *zlexer, o string) *ParseError { return rr.parseDS(c, o, "DS") }
+func (rr *DLV) parse(c *zlexer, o string) *ParseError { return rr.parseDS(c, o, "DLV") }
+func (rr *CDS) parse(c *zlexer, o string) *ParseError { return rr.parseDS(c, o, "CDS") }
+
+func (rr *RKEY) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 16)
+ if e != nil || l.err {
+ return &ParseError{"", "bad RKEY Flags", l}
+ }
+ rr.Flags = uint16(i)
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
+ i, e1 := strconv.ParseUint(l.token, 10, 8)
+ if e1 != nil || l.err {
+ return &ParseError{"", "bad RKEY Protocol", l}
+ }
+ rr.Protocol = uint8(i)
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
+ i, e2 := strconv.ParseUint(l.token, 10, 8)
+ if e2 != nil || l.err {
+ return &ParseError{"", "bad RKEY Algorithm", l}
+ }
+ rr.Algorithm = uint8(i)
+ s, e3 := endingToString(c, "bad RKEY PublicKey")
+ if e3 != nil {
+ return e3
+ }
+ rr.PublicKey = s
+ return nil
+}
+
+func (rr *EID) parse(c *zlexer, o string) *ParseError {
+ s, e := endingToString(c, "bad EID Endpoint")
+ if e != nil {
+ return e
+ }
+ rr.Endpoint = s
+ return nil
+}
+
+func (rr *NIMLOC) parse(c *zlexer, o string) *ParseError {
+ s, e := endingToString(c, "bad NIMLOC Locator")
+ if e != nil {
+ return e
+ }
+ rr.Locator = s
+ return nil
+}
+
+func (rr *GPOS) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ _, e := strconv.ParseFloat(l.token, 64)
+ if e != nil || l.err {
+ return &ParseError{"", "bad GPOS Longitude", l}
+ }
+ rr.Longitude = l.token
+ c.Next() // zBlank
+ l, _ = c.Next()
+ _, e1 := strconv.ParseFloat(l.token, 64)
+ if e1 != nil || l.err {
+ return &ParseError{"", "bad GPOS Latitude", l}
+ }
+ rr.Latitude = l.token
+ c.Next() // zBlank
+ l, _ = c.Next()
+ _, e2 := strconv.ParseFloat(l.token, 64)
+ if e2 != nil || l.err {
+ return &ParseError{"", "bad GPOS Altitude", l}
+ }
+ rr.Altitude = l.token
+ return slurpRemainder(c)
+}
+
+func (rr *DS) parseDS(c *zlexer, o, typ string) *ParseError {
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 16)
+ if e != nil || l.err {
+ return &ParseError{"", "bad " + typ + " KeyTag", l}
+ }
+ rr.KeyTag = uint16(i)
+ c.Next() // zBlank
+ l, _ = c.Next()
+ if i, err := strconv.ParseUint(l.token, 10, 8); err != nil {
+ tokenUpper := strings.ToUpper(l.token)
+ i, ok := StringToAlgorithm[tokenUpper]
+ if !ok || l.err {
+ return &ParseError{"", "bad " + typ + " Algorithm", l}
+ }
+ rr.Algorithm = i
+ } else {
+ rr.Algorithm = uint8(i)
+ }
+ c.Next() // zBlank
+ l, _ = c.Next()
+ i, e1 := strconv.ParseUint(l.token, 10, 8)
+ if e1 != nil || l.err {
+ return &ParseError{"", "bad " + typ + " DigestType", l}
+ }
+ rr.DigestType = uint8(i)
+ s, e2 := endingToString(c, "bad "+typ+" Digest")
+ if e2 != nil {
+ return e2
+ }
+ rr.Digest = s
+ return nil
+}
+
+func (rr *TA) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 16)
+ if e != nil || l.err {
+ return &ParseError{"", "bad TA KeyTag", l}
+ }
+ rr.KeyTag = uint16(i)
+ c.Next() // zBlank
+ l, _ = c.Next()
+ if i, err := strconv.ParseUint(l.token, 10, 8); err != nil {
+ tokenUpper := strings.ToUpper(l.token)
+ i, ok := StringToAlgorithm[tokenUpper]
+ if !ok || l.err {
+ return &ParseError{"", "bad TA Algorithm", l}
+ }
+ rr.Algorithm = i
+ } else {
+ rr.Algorithm = uint8(i)
+ }
+ c.Next() // zBlank
+ l, _ = c.Next()
+ i, e1 := strconv.ParseUint(l.token, 10, 8)
+ if e1 != nil || l.err {
+ return &ParseError{"", "bad TA DigestType", l}
+ }
+ rr.DigestType = uint8(i)
+ s, e2 := endingToString(c, "bad TA Digest")
+ if e2 != nil {
+ return e2
+ }
+ rr.Digest = s
+ return nil
+}
+
+func (rr *TLSA) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 8)
+ if e != nil || l.err {
+ return &ParseError{"", "bad TLSA Usage", l}
+ }
+ rr.Usage = uint8(i)
+ c.Next() // zBlank
+ l, _ = c.Next()
+ i, e1 := strconv.ParseUint(l.token, 10, 8)
+ if e1 != nil || l.err {
+ return &ParseError{"", "bad TLSA Selector", l}
+ }
+ rr.Selector = uint8(i)
+ c.Next() // zBlank
+ l, _ = c.Next()
+ i, e2 := strconv.ParseUint(l.token, 10, 8)
+ if e2 != nil || l.err {
+ return &ParseError{"", "bad TLSA MatchingType", l}
+ }
+ rr.MatchingType = uint8(i)
+ // So this needs be e2 (i.e. different than e), because...??t
+ s, e3 := endingToString(c, "bad TLSA Certificate")
+ if e3 != nil {
+ return e3
+ }
+ rr.Certificate = s
+ return nil
+}
+
+func (rr *SMIMEA) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 8)
+ if e != nil || l.err {
+ return &ParseError{"", "bad SMIMEA Usage", l}
+ }
+ rr.Usage = uint8(i)
+ c.Next() // zBlank
+ l, _ = c.Next()
+ i, e1 := strconv.ParseUint(l.token, 10, 8)
+ if e1 != nil || l.err {
+ return &ParseError{"", "bad SMIMEA Selector", l}
+ }
+ rr.Selector = uint8(i)
+ c.Next() // zBlank
+ l, _ = c.Next()
+ i, e2 := strconv.ParseUint(l.token, 10, 8)
+ if e2 != nil || l.err {
+ return &ParseError{"", "bad SMIMEA MatchingType", l}
+ }
+ rr.MatchingType = uint8(i)
+ // So this needs be e2 (i.e. different than e), because...??t
+ s, e3 := endingToString(c, "bad SMIMEA Certificate")
+ if e3 != nil {
+ return e3
+ }
+ rr.Certificate = s
+ return nil
+}
+
+func (rr *RFC3597) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ if l.token != "\\#" {
+ return &ParseError{"", "bad RFC3597 Rdata", l}
+ }
+
+ c.Next() // zBlank
+ l, _ = c.Next()
+ rdlength, e := strconv.ParseUint(l.token, 10, 16)
+ if e != nil || l.err {
+ return &ParseError{"", "bad RFC3597 Rdata ", l}
+ }
+
+ s, e1 := endingToString(c, "bad RFC3597 Rdata")
+ if e1 != nil {
+ return e1
+ }
+ if int(rdlength)*2 != len(s) {
+ return &ParseError{"", "bad RFC3597 Rdata", l}
+ }
+ rr.Rdata = s
+ return nil
+}
+
+func (rr *SPF) parse(c *zlexer, o string) *ParseError {
+ s, e := endingToTxtSlice(c, "bad SPF Txt")
+ if e != nil {
+ return e
+ }
+ rr.Txt = s
+ return nil
+}
+
+func (rr *AVC) parse(c *zlexer, o string) *ParseError {
+ s, e := endingToTxtSlice(c, "bad AVC Txt")
+ if e != nil {
+ return e
+ }
+ rr.Txt = s
+ return nil
+}
+
+func (rr *TXT) parse(c *zlexer, o string) *ParseError {
+ // no zBlank reading here, because all this rdata is TXT
+ s, e := endingToTxtSlice(c, "bad TXT Txt")
+ if e != nil {
+ return e
+ }
+ rr.Txt = s
+ return nil
+}
+
+// identical to setTXT
+func (rr *NINFO) parse(c *zlexer, o string) *ParseError {
+ s, e := endingToTxtSlice(c, "bad NINFO ZSData")
+ if e != nil {
+ return e
+ }
+ rr.ZSData = s
+ return nil
+}
+
+func (rr *URI) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 16)
+ if e != nil || l.err {
+ return &ParseError{"", "bad URI Priority", l}
+ }
+ rr.Priority = uint16(i)
+ c.Next() // zBlank
+ l, _ = c.Next()
+ i, e1 := strconv.ParseUint(l.token, 10, 16)
+ if e1 != nil || l.err {
+ return &ParseError{"", "bad URI Weight", l}
+ }
+ rr.Weight = uint16(i)
+
+ c.Next() // zBlank
+ s, e2 := endingToTxtSlice(c, "bad URI Target")
+ if e2 != nil {
+ return e2
+ }
+ if len(s) != 1 {
+ return &ParseError{"", "bad URI Target", l}
+ }
+ rr.Target = s[0]
+ return nil
+}
+
+func (rr *DHCID) parse(c *zlexer, o string) *ParseError {
+ // awesome record to parse!
+ s, e := endingToString(c, "bad DHCID Digest")
+ if e != nil {
+ return e
+ }
+ rr.Digest = s
+ return nil
+}
+
+func (rr *NID) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 16)
+ if e != nil || l.err {
+ return &ParseError{"", "bad NID Preference", l}
+ }
+ rr.Preference = uint16(i)
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
+ u, e1 := stringToNodeID(l)
+ if e1 != nil || l.err {
+ return e1
+ }
+ rr.NodeID = u
+ return slurpRemainder(c)
+}
+
+func (rr *L32) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 16)
+ if e != nil || l.err {
+ return &ParseError{"", "bad L32 Preference", l}
+ }
+ rr.Preference = uint16(i)
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
+ rr.Locator32 = net.ParseIP(l.token)
+ if rr.Locator32 == nil || l.err {
+ return &ParseError{"", "bad L32 Locator", l}
+ }
+ return slurpRemainder(c)
+}
+
+func (rr *LP) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 16)
+ if e != nil || l.err {
+ return &ParseError{"", "bad LP Preference", l}
+ }
+ rr.Preference = uint16(i)
+
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
+ rr.Fqdn = l.token
+ name, nameOk := toAbsoluteName(l.token, o)
+ if l.err || !nameOk {
+ return &ParseError{"", "bad LP Fqdn", l}
+ }
+ rr.Fqdn = name
+ return slurpRemainder(c)
+}
+
+func (rr *L64) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 16)
+ if e != nil || l.err {
+ return &ParseError{"", "bad L64 Preference", l}
+ }
+ rr.Preference = uint16(i)
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
+ u, e1 := stringToNodeID(l)
+ if e1 != nil || l.err {
+ return e1
+ }
+ rr.Locator64 = u
+ return slurpRemainder(c)
+}
+
+func (rr *UID) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 32)
+ if e != nil || l.err {
+ return &ParseError{"", "bad UID Uid", l}
+ }
+ rr.Uid = uint32(i)
+ return slurpRemainder(c)
+}
+
+func (rr *GID) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 32)
+ if e != nil || l.err {
+ return &ParseError{"", "bad GID Gid", l}
+ }
+ rr.Gid = uint32(i)
+ return slurpRemainder(c)
+}
+
+func (rr *UINFO) parse(c *zlexer, o string) *ParseError {
+ s, e := endingToTxtSlice(c, "bad UINFO Uinfo")
+ if e != nil {
+ return e
+ }
+ if ln := len(s); ln == 0 {
+ return nil
+ }
+ rr.Uinfo = s[0] // silently discard anything after the first character-string
+ return nil
+}
+
+func (rr *PX) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 16)
+ if e != nil || l.err {
+ return &ParseError{"", "bad PX Preference", l}
+ }
+ rr.Preference = uint16(i)
+
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
+ rr.Map822 = l.token
+ map822, map822Ok := toAbsoluteName(l.token, o)
+ if l.err || !map822Ok {
+ return &ParseError{"", "bad PX Map822", l}
+ }
+ rr.Map822 = map822
+
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
+ rr.Mapx400 = l.token
+ mapx400, mapx400Ok := toAbsoluteName(l.token, o)
+ if l.err || !mapx400Ok {
+ return &ParseError{"", "bad PX Mapx400", l}
+ }
+ rr.Mapx400 = mapx400
+ return slurpRemainder(c)
+}
+
+func (rr *CAA) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 8)
+ if e != nil || l.err {
+ return &ParseError{"", "bad CAA Flag", l}
+ }
+ rr.Flag = uint8(i)
+
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
+ if l.value != zString {
+ return &ParseError{"", "bad CAA Tag", l}
+ }
+ rr.Tag = l.token
+
+ c.Next() // zBlank
+ s, e1 := endingToTxtSlice(c, "bad CAA Value")
+ if e1 != nil {
+ return e1
+ }
+ if len(s) != 1 {
+ return &ParseError{"", "bad CAA Value", l}
+ }
+ rr.Value = s[0]
+ return nil
+}
+
+func (rr *TKEY) parse(c *zlexer, o string) *ParseError {
+ l, _ := c.Next()
+
+ // Algorithm
+ if l.value != zString {
+ return &ParseError{"", "bad TKEY algorithm", l}
+ }
+ rr.Algorithm = l.token
+ c.Next() // zBlank
+
+ // Get the key length and key values
+ l, _ = c.Next()
+ i, e := strconv.ParseUint(l.token, 10, 8)
+ if e != nil || l.err {
+ return &ParseError{"", "bad TKEY key length", l}
+ }
+ rr.KeySize = uint16(i)
+ c.Next() // zBlank
+ l, _ = c.Next()
+ if l.value != zString {
+ return &ParseError{"", "bad TKEY key", l}
+ }
+ rr.Key = l.token
+ c.Next() // zBlank
+
+ // Get the otherdata length and string data
+ l, _ = c.Next()
+ i, e1 := strconv.ParseUint(l.token, 10, 8)
+ if e1 != nil || l.err {
+ return &ParseError{"", "bad TKEY otherdata length", l}
+ }
+ rr.OtherLen = uint16(i)
+ c.Next() // zBlank
+ l, _ = c.Next()
+ if l.value != zString {
+ return &ParseError{"", "bad TKEY otherday", l}
+ }
+ rr.OtherData = l.token
+ return nil
+}
+
+func (rr *APL) parse(c *zlexer, o string) *ParseError {
+ var prefixes []APLPrefix
+
+ for {
+ l, _ := c.Next()
+ if l.value == zNewline || l.value == zEOF {
+ break
+ }
+ if l.value == zBlank && prefixes != nil {
+ continue
+ }
+ if l.value != zString {
+ return &ParseError{"", "unexpected APL field", l}
+ }
+
+ // Expected format: [!]afi:address/prefix
+
+ colon := strings.IndexByte(l.token, ':')
+ if colon == -1 {
+ return &ParseError{"", "missing colon in APL field", l}
+ }
+
+ family, cidr := l.token[:colon], l.token[colon+1:]
+
+ var negation bool
+ if family != "" && family[0] == '!' {
+ negation = true
+ family = family[1:]
+ }
+
+ afi, e := strconv.ParseUint(family, 10, 16)
+ if e != nil {
+ return &ParseError{"", "failed to parse APL family: " + e.Error(), l}
+ }
+ var addrLen int
+ switch afi {
+ case 1:
+ addrLen = net.IPv4len
+ case 2:
+ addrLen = net.IPv6len
+ default:
+ return &ParseError{"", "unrecognized APL family", l}
+ }
+
+ ip, subnet, e1 := net.ParseCIDR(cidr)
+ if e1 != nil {
+ return &ParseError{"", "failed to parse APL address: " + e1.Error(), l}
+ }
+ if !ip.Equal(subnet.IP) {
+ return &ParseError{"", "extra bits in APL address", l}
+ }
+
+ if len(subnet.IP) != addrLen {
+ return &ParseError{"", "address mismatch with the APL family", l}
+ }
+
+ prefixes = append(prefixes, APLPrefix{
+ Negation: negation,
+ Network: *subnet,
+ })
+ }
+
+ rr.Prefixes = prefixes
+ return nil
+}
diff --git a/vendor/github.com/miekg/dns/serve_mux.go b/vendor/github.com/miekg/dns/serve_mux.go
@@ -0,0 +1,122 @@
+package dns
+
+import (
+ "sync"
+)
+
+// ServeMux is an DNS request multiplexer. It matches the zone name of
+// each incoming request against a list of registered patterns add calls
+// the handler for the pattern that most closely matches the zone name.
+//
+// ServeMux is DNSSEC aware, meaning that queries for the DS record are
+// redirected to the parent zone (if that is also registered), otherwise
+// the child gets the query.
+//
+// ServeMux is also safe for concurrent access from multiple goroutines.
+//
+// The zero ServeMux is empty and ready for use.
+type ServeMux struct {
+ z map[string]Handler
+ m sync.RWMutex
+}
+
+// NewServeMux allocates and returns a new ServeMux.
+func NewServeMux() *ServeMux {
+ return new(ServeMux)
+}
+
+// DefaultServeMux is the default ServeMux used by Serve.
+var DefaultServeMux = NewServeMux()
+
+func (mux *ServeMux) match(q string, t uint16) Handler {
+ mux.m.RLock()
+ defer mux.m.RUnlock()
+ if mux.z == nil {
+ return nil
+ }
+
+ q = CanonicalName(q)
+
+ var handler Handler
+ for off, end := 0, false; !end; off, end = NextLabel(q, off) {
+ if h, ok := mux.z[q[off:]]; ok {
+ if t != TypeDS {
+ return h
+ }
+ // Continue for DS to see if we have a parent too, if so delegate to the parent
+ handler = h
+ }
+ }
+
+ // Wildcard match, if we have found nothing try the root zone as a last resort.
+ if h, ok := mux.z["."]; ok {
+ return h
+ }
+
+ return handler
+}
+
+// Handle adds a handler to the ServeMux for pattern.
+func (mux *ServeMux) Handle(pattern string, handler Handler) {
+ if pattern == "" {
+ panic("dns: invalid pattern " + pattern)
+ }
+ mux.m.Lock()
+ if mux.z == nil {
+ mux.z = make(map[string]Handler)
+ }
+ mux.z[CanonicalName(pattern)] = handler
+ mux.m.Unlock()
+}
+
+// HandleFunc adds a handler function to the ServeMux for pattern.
+func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) {
+ mux.Handle(pattern, HandlerFunc(handler))
+}
+
+// HandleRemove deregisters the handler specific for pattern from the ServeMux.
+func (mux *ServeMux) HandleRemove(pattern string) {
+ if pattern == "" {
+ panic("dns: invalid pattern " + pattern)
+ }
+ mux.m.Lock()
+ delete(mux.z, CanonicalName(pattern))
+ mux.m.Unlock()
+}
+
+// ServeDNS dispatches the request to the handler whose pattern most
+// closely matches the request message.
+//
+// ServeDNS is DNSSEC aware, meaning that queries for the DS record
+// are redirected to the parent zone (if that is also registered),
+// otherwise the child gets the query.
+//
+// If no handler is found, or there is no question, a standard REFUSED
+// message is returned
+func (mux *ServeMux) ServeDNS(w ResponseWriter, req *Msg) {
+ var h Handler
+ if len(req.Question) >= 1 { // allow more than one question
+ h = mux.match(req.Question[0].Name, req.Question[0].Qtype)
+ }
+
+ if h != nil {
+ h.ServeDNS(w, req)
+ } else {
+ handleRefused(w, req)
+ }
+}
+
+// Handle registers the handler with the given pattern
+// in the DefaultServeMux. The documentation for
+// ServeMux explains how patterns are matched.
+func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
+
+// HandleRemove deregisters the handle with the given pattern
+// in the DefaultServeMux.
+func HandleRemove(pattern string) { DefaultServeMux.HandleRemove(pattern) }
+
+// HandleFunc registers the handler function with the given pattern
+// in the DefaultServeMux.
+func HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) {
+ DefaultServeMux.HandleFunc(pattern, handler)
+}
diff --git a/vendor/github.com/miekg/dns/server.go b/vendor/github.com/miekg/dns/server.go
@@ -0,0 +1,836 @@
+// DNS server implementation.
+
+package dns
+
+import (
+ "context"
+ "crypto/tls"
+ "encoding/binary"
+ "errors"
+ "io"
+ "net"
+ "strings"
+ "sync"
+ "time"
+)
+
+// Default maximum number of TCP queries before we close the socket.
+const maxTCPQueries = 128
+
+// aLongTimeAgo is a non-zero time, far in the past, used for
+// immediate cancelation of network operations.
+var aLongTimeAgo = time.Unix(1, 0)
+
+// Handler is implemented by any value that implements ServeDNS.
+type Handler interface {
+ ServeDNS(w ResponseWriter, r *Msg)
+}
+
+// The HandlerFunc type is an adapter to allow the use of
+// ordinary functions as DNS handlers. If f is a function
+// with the appropriate signature, HandlerFunc(f) is a
+// Handler object that calls f.
+type HandlerFunc func(ResponseWriter, *Msg)
+
+// ServeDNS calls f(w, r).
+func (f HandlerFunc) ServeDNS(w ResponseWriter, r *Msg) {
+ f(w, r)
+}
+
+// A ResponseWriter interface is used by an DNS handler to
+// construct an DNS response.
+type ResponseWriter interface {
+ // LocalAddr returns the net.Addr of the server
+ LocalAddr() net.Addr
+ // RemoteAddr returns the net.Addr of the client that sent the current request.
+ RemoteAddr() net.Addr
+ // WriteMsg writes a reply back to the client.
+ WriteMsg(*Msg) error
+ // Write writes a raw buffer back to the client.
+ Write([]byte) (int, error)
+ // Close closes the connection.
+ Close() error
+ // TsigStatus returns the status of the Tsig.
+ TsigStatus() error
+ // TsigTimersOnly sets the tsig timers only boolean.
+ TsigTimersOnly(bool)
+ // Hijack lets the caller take over the connection.
+ // After a call to Hijack(), the DNS package will not do anything with the connection.
+ Hijack()
+}
+
+// A ConnectionStater interface is used by a DNS Handler to access TLS connection state
+// when available.
+type ConnectionStater interface {
+ ConnectionState() *tls.ConnectionState
+}
+
+type response struct {
+ closed bool // connection has been closed
+ hijacked bool // connection has been hijacked by handler
+ tsigTimersOnly bool
+ tsigStatus error
+ tsigRequestMAC string
+ tsigProvider TsigProvider
+ udp net.PacketConn // i/o connection if UDP was used
+ tcp net.Conn // i/o connection if TCP was used
+ udpSession *SessionUDP // oob data to get egress interface right
+ pcSession net.Addr // address to use when writing to a generic net.PacketConn
+ writer Writer // writer to output the raw DNS bits
+}
+
+// handleRefused returns a HandlerFunc that returns REFUSED for every request it gets.
+func handleRefused(w ResponseWriter, r *Msg) {
+ m := new(Msg)
+ m.SetRcode(r, RcodeRefused)
+ w.WriteMsg(m)
+}
+
+// HandleFailed returns a HandlerFunc that returns SERVFAIL for every request it gets.
+// Deprecated: This function is going away.
+func HandleFailed(w ResponseWriter, r *Msg) {
+ m := new(Msg)
+ m.SetRcode(r, RcodeServerFailure)
+ // does not matter if this write fails
+ w.WriteMsg(m)
+}
+
+// ListenAndServe Starts a server on address and network specified Invoke handler
+// for incoming queries.
+func ListenAndServe(addr string, network string, handler Handler) error {
+ server := &Server{Addr: addr, Net: network, Handler: handler}
+ return server.ListenAndServe()
+}
+
+// ListenAndServeTLS acts like http.ListenAndServeTLS, more information in
+// http://golang.org/pkg/net/http/#ListenAndServeTLS
+func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error {
+ cert, err := tls.LoadX509KeyPair(certFile, keyFile)
+ if err != nil {
+ return err
+ }
+
+ config := tls.Config{
+ Certificates: []tls.Certificate{cert},
+ }
+
+ server := &Server{
+ Addr: addr,
+ Net: "tcp-tls",
+ TLSConfig: &config,
+ Handler: handler,
+ }
+
+ return server.ListenAndServe()
+}
+
+// ActivateAndServe activates a server with a listener from systemd,
+// l and p should not both be non-nil.
+// If both l and p are not nil only p will be used.
+// Invoke handler for incoming queries.
+func ActivateAndServe(l net.Listener, p net.PacketConn, handler Handler) error {
+ server := &Server{Listener: l, PacketConn: p, Handler: handler}
+ return server.ActivateAndServe()
+}
+
+// Writer writes raw DNS messages; each call to Write should send an entire message.
+type Writer interface {
+ io.Writer
+}
+
+// Reader reads raw DNS messages; each call to ReadTCP or ReadUDP should return an entire message.
+type Reader interface {
+ // ReadTCP reads a raw message from a TCP connection. Implementations may alter
+ // connection properties, for example the read-deadline.
+ ReadTCP(conn net.Conn, timeout time.Duration) ([]byte, error)
+ // ReadUDP reads a raw message from a UDP connection. Implementations may alter
+ // connection properties, for example the read-deadline.
+ ReadUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error)
+}
+
+// PacketConnReader is an optional interface that Readers can implement to support using generic net.PacketConns.
+type PacketConnReader interface {
+ Reader
+
+ // ReadPacketConn reads a raw message from a generic net.PacketConn UDP connection. Implementations may
+ // alter connection properties, for example the read-deadline.
+ ReadPacketConn(conn net.PacketConn, timeout time.Duration) ([]byte, net.Addr, error)
+}
+
+// defaultReader is an adapter for the Server struct that implements the Reader and
+// PacketConnReader interfaces using the readTCP, readUDP and readPacketConn funcs
+// of the embedded Server.
+type defaultReader struct {
+ *Server
+}
+
+var _ PacketConnReader = defaultReader{}
+
+func (dr defaultReader) ReadTCP(conn net.Conn, timeout time.Duration) ([]byte, error) {
+ return dr.readTCP(conn, timeout)
+}
+
+func (dr defaultReader) ReadUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error) {
+ return dr.readUDP(conn, timeout)
+}
+
+func (dr defaultReader) ReadPacketConn(conn net.PacketConn, timeout time.Duration) ([]byte, net.Addr, error) {
+ return dr.readPacketConn(conn, timeout)
+}
+
+// DecorateReader is a decorator hook for extending or supplanting the functionality of a Reader.
+// Implementations should never return a nil Reader.
+// Readers should also implement the optional PacketConnReader interface.
+// PacketConnReader is required to use a generic net.PacketConn.
+type DecorateReader func(Reader) Reader
+
+// DecorateWriter is a decorator hook for extending or supplanting the functionality of a Writer.
+// Implementations should never return a nil Writer.
+type DecorateWriter func(Writer) Writer
+
+// A Server defines parameters for running an DNS server.
+type Server struct {
+ // Address to listen on, ":dns" if empty.
+ Addr string
+ // if "tcp" or "tcp-tls" (DNS over TLS) it will invoke a TCP listener, otherwise an UDP one
+ Net string
+ // TCP Listener to use, this is to aid in systemd's socket activation.
+ Listener net.Listener
+ // TLS connection configuration
+ TLSConfig *tls.Config
+ // UDP "Listener" to use, this is to aid in systemd's socket activation.
+ PacketConn net.PacketConn
+ // Handler to invoke, dns.DefaultServeMux if nil.
+ Handler Handler
+ // Default buffer size to use to read incoming UDP messages. If not set
+ // it defaults to MinMsgSize (512 B).
+ UDPSize int
+ // The net.Conn.SetReadTimeout value for new connections, defaults to 2 * time.Second.
+ ReadTimeout time.Duration
+ // The net.Conn.SetWriteTimeout value for new connections, defaults to 2 * time.Second.
+ WriteTimeout time.Duration
+ // TCP idle timeout for multiple queries, if nil, defaults to 8 * time.Second (RFC 5966).
+ IdleTimeout func() time.Duration
+ // An implementation of the TsigProvider interface. If defined it replaces TsigSecret and is used for all TSIG operations.
+ TsigProvider TsigProvider
+ // Secret(s) for Tsig map[<zonename>]<base64 secret>. The zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2).
+ TsigSecret map[string]string
+ // If NotifyStartedFunc is set it is called once the server has started listening.
+ NotifyStartedFunc func()
+ // DecorateReader is optional, allows customization of the process that reads raw DNS messages.
+ DecorateReader DecorateReader
+ // DecorateWriter is optional, allows customization of the process that writes raw DNS messages.
+ DecorateWriter DecorateWriter
+ // Maximum number of TCP queries before we close the socket. Default is maxTCPQueries (unlimited if -1).
+ MaxTCPQueries int
+ // Whether to set the SO_REUSEPORT socket option, allowing multiple listeners to be bound to a single address.
+ // It is only supported on go1.11+ and when using ListenAndServe.
+ ReusePort bool
+ // AcceptMsgFunc will check the incoming message and will reject it early in the process.
+ // By default DefaultMsgAcceptFunc will be used.
+ MsgAcceptFunc MsgAcceptFunc
+
+ // Shutdown handling
+ lock sync.RWMutex
+ started bool
+ shutdown chan struct{}
+ conns map[net.Conn]struct{}
+
+ // A pool for UDP message buffers.
+ udpPool sync.Pool
+}
+
+func (srv *Server) tsigProvider() TsigProvider {
+ if srv.TsigProvider != nil {
+ return srv.TsigProvider
+ }
+ if srv.TsigSecret != nil {
+ return tsigSecretProvider(srv.TsigSecret)
+ }
+ return nil
+}
+
+func (srv *Server) isStarted() bool {
+ srv.lock.RLock()
+ started := srv.started
+ srv.lock.RUnlock()
+ return started
+}
+
+func makeUDPBuffer(size int) func() interface{} {
+ return func() interface{} {
+ return make([]byte, size)
+ }
+}
+
+func (srv *Server) init() {
+ srv.shutdown = make(chan struct{})
+ srv.conns = make(map[net.Conn]struct{})
+
+ if srv.UDPSize == 0 {
+ srv.UDPSize = MinMsgSize
+ }
+ if srv.MsgAcceptFunc == nil {
+ srv.MsgAcceptFunc = DefaultMsgAcceptFunc
+ }
+ if srv.Handler == nil {
+ srv.Handler = DefaultServeMux
+ }
+
+ srv.udpPool.New = makeUDPBuffer(srv.UDPSize)
+}
+
+func unlockOnce(l sync.Locker) func() {
+ var once sync.Once
+ return func() { once.Do(l.Unlock) }
+}
+
+// ListenAndServe starts a nameserver on the configured address in *Server.
+func (srv *Server) ListenAndServe() error {
+ unlock := unlockOnce(&srv.lock)
+ srv.lock.Lock()
+ defer unlock()
+
+ if srv.started {
+ return &Error{err: "server already started"}
+ }
+
+ addr := srv.Addr
+ if addr == "" {
+ addr = ":domain"
+ }
+
+ srv.init()
+
+ switch srv.Net {
+ case "tcp", "tcp4", "tcp6":
+ l, err := listenTCP(srv.Net, addr, srv.ReusePort)
+ if err != nil {
+ return err
+ }
+ srv.Listener = l
+ srv.started = true
+ unlock()
+ return srv.serveTCP(l)
+ case "tcp-tls", "tcp4-tls", "tcp6-tls":
+ if srv.TLSConfig == nil || (len(srv.TLSConfig.Certificates) == 0 && srv.TLSConfig.GetCertificate == nil) {
+ return errors.New("dns: neither Certificates nor GetCertificate set in Config")
+ }
+ network := strings.TrimSuffix(srv.Net, "-tls")
+ l, err := listenTCP(network, addr, srv.ReusePort)
+ if err != nil {
+ return err
+ }
+ l = tls.NewListener(l, srv.TLSConfig)
+ srv.Listener = l
+ srv.started = true
+ unlock()
+ return srv.serveTCP(l)
+ case "udp", "udp4", "udp6":
+ l, err := listenUDP(srv.Net, addr, srv.ReusePort)
+ if err != nil {
+ return err
+ }
+ u := l.(*net.UDPConn)
+ if e := setUDPSocketOptions(u); e != nil {
+ u.Close()
+ return e
+ }
+ srv.PacketConn = l
+ srv.started = true
+ unlock()
+ return srv.serveUDP(u)
+ }
+ return &Error{err: "bad network"}
+}
+
+// ActivateAndServe starts a nameserver with the PacketConn or Listener
+// configured in *Server. Its main use is to start a server from systemd.
+func (srv *Server) ActivateAndServe() error {
+ unlock := unlockOnce(&srv.lock)
+ srv.lock.Lock()
+ defer unlock()
+
+ if srv.started {
+ return &Error{err: "server already started"}
+ }
+
+ srv.init()
+
+ if srv.PacketConn != nil {
+ // Check PacketConn interface's type is valid and value
+ // is not nil
+ if t, ok := srv.PacketConn.(*net.UDPConn); ok && t != nil {
+ if e := setUDPSocketOptions(t); e != nil {
+ return e
+ }
+ }
+ srv.started = true
+ unlock()
+ return srv.serveUDP(srv.PacketConn)
+ }
+ if srv.Listener != nil {
+ srv.started = true
+ unlock()
+ return srv.serveTCP(srv.Listener)
+ }
+ return &Error{err: "bad listeners"}
+}
+
+// Shutdown shuts down a server. After a call to Shutdown, ListenAndServe and
+// ActivateAndServe will return.
+func (srv *Server) Shutdown() error {
+ return srv.ShutdownContext(context.Background())
+}
+
+// ShutdownContext shuts down a server. After a call to ShutdownContext,
+// ListenAndServe and ActivateAndServe will return.
+//
+// A context.Context may be passed to limit how long to wait for connections
+// to terminate.
+func (srv *Server) ShutdownContext(ctx context.Context) error {
+ srv.lock.Lock()
+ if !srv.started {
+ srv.lock.Unlock()
+ return &Error{err: "server not started"}
+ }
+
+ srv.started = false
+
+ if srv.PacketConn != nil {
+ srv.PacketConn.SetReadDeadline(aLongTimeAgo) // Unblock reads
+ }
+
+ if srv.Listener != nil {
+ srv.Listener.Close()
+ }
+
+ for rw := range srv.conns {
+ rw.SetReadDeadline(aLongTimeAgo) // Unblock reads
+ }
+
+ srv.lock.Unlock()
+
+ if testShutdownNotify != nil {
+ testShutdownNotify.Broadcast()
+ }
+
+ var ctxErr error
+ select {
+ case <-srv.shutdown:
+ case <-ctx.Done():
+ ctxErr = ctx.Err()
+ }
+
+ if srv.PacketConn != nil {
+ srv.PacketConn.Close()
+ }
+
+ return ctxErr
+}
+
+var testShutdownNotify *sync.Cond
+
+// getReadTimeout is a helper func to use system timeout if server did not intend to change it.
+func (srv *Server) getReadTimeout() time.Duration {
+ if srv.ReadTimeout != 0 {
+ return srv.ReadTimeout
+ }
+ return dnsTimeout
+}
+
+// serveTCP starts a TCP listener for the server.
+func (srv *Server) serveTCP(l net.Listener) error {
+ defer l.Close()
+
+ if srv.NotifyStartedFunc != nil {
+ srv.NotifyStartedFunc()
+ }
+
+ var wg sync.WaitGroup
+ defer func() {
+ wg.Wait()
+ close(srv.shutdown)
+ }()
+
+ for srv.isStarted() {
+ rw, err := l.Accept()
+ if err != nil {
+ if !srv.isStarted() {
+ return nil
+ }
+ if neterr, ok := err.(net.Error); ok && neterr.Temporary() {
+ continue
+ }
+ return err
+ }
+ srv.lock.Lock()
+ // Track the connection to allow unblocking reads on shutdown.
+ srv.conns[rw] = struct{}{}
+ srv.lock.Unlock()
+ wg.Add(1)
+ go srv.serveTCPConn(&wg, rw)
+ }
+
+ return nil
+}
+
+// serveUDP starts a UDP listener for the server.
+func (srv *Server) serveUDP(l net.PacketConn) error {
+ defer l.Close()
+
+ reader := Reader(defaultReader{srv})
+ if srv.DecorateReader != nil {
+ reader = srv.DecorateReader(reader)
+ }
+
+ lUDP, isUDP := l.(*net.UDPConn)
+ readerPC, canPacketConn := reader.(PacketConnReader)
+ if !isUDP && !canPacketConn {
+ return &Error{err: "PacketConnReader was not implemented on Reader returned from DecorateReader but is required for net.PacketConn"}
+ }
+
+ if srv.NotifyStartedFunc != nil {
+ srv.NotifyStartedFunc()
+ }
+
+ var wg sync.WaitGroup
+ defer func() {
+ wg.Wait()
+ close(srv.shutdown)
+ }()
+
+ rtimeout := srv.getReadTimeout()
+ // deadline is not used here
+ for srv.isStarted() {
+ var (
+ m []byte
+ sPC net.Addr
+ sUDP *SessionUDP
+ err error
+ )
+ if isUDP {
+ m, sUDP, err = reader.ReadUDP(lUDP, rtimeout)
+ } else {
+ m, sPC, err = readerPC.ReadPacketConn(l, rtimeout)
+ }
+ if err != nil {
+ if !srv.isStarted() {
+ return nil
+ }
+ if netErr, ok := err.(net.Error); ok && netErr.Temporary() {
+ continue
+ }
+ return err
+ }
+ if len(m) < headerSize {
+ if cap(m) == srv.UDPSize {
+ srv.udpPool.Put(m[:srv.UDPSize])
+ }
+ continue
+ }
+ wg.Add(1)
+ go srv.serveUDPPacket(&wg, m, l, sUDP, sPC)
+ }
+
+ return nil
+}
+
+// Serve a new TCP connection.
+func (srv *Server) serveTCPConn(wg *sync.WaitGroup, rw net.Conn) {
+ w := &response{tsigProvider: srv.tsigProvider(), tcp: rw}
+ if srv.DecorateWriter != nil {
+ w.writer = srv.DecorateWriter(w)
+ } else {
+ w.writer = w
+ }
+
+ reader := Reader(defaultReader{srv})
+ if srv.DecorateReader != nil {
+ reader = srv.DecorateReader(reader)
+ }
+
+ idleTimeout := tcpIdleTimeout
+ if srv.IdleTimeout != nil {
+ idleTimeout = srv.IdleTimeout()
+ }
+
+ timeout := srv.getReadTimeout()
+
+ limit := srv.MaxTCPQueries
+ if limit == 0 {
+ limit = maxTCPQueries
+ }
+
+ for q := 0; (q < limit || limit == -1) && srv.isStarted(); q++ {
+ m, err := reader.ReadTCP(w.tcp, timeout)
+ if err != nil {
+ // TODO(tmthrgd): handle error
+ break
+ }
+ srv.serveDNS(m, w)
+ if w.closed {
+ break // Close() was called
+ }
+ if w.hijacked {
+ break // client will call Close() themselves
+ }
+ // The first read uses the read timeout, the rest use the
+ // idle timeout.
+ timeout = idleTimeout
+ }
+
+ if !w.hijacked {
+ w.Close()
+ }
+
+ srv.lock.Lock()
+ delete(srv.conns, w.tcp)
+ srv.lock.Unlock()
+
+ wg.Done()
+}
+
+// Serve a new UDP request.
+func (srv *Server) serveUDPPacket(wg *sync.WaitGroup, m []byte, u net.PacketConn, udpSession *SessionUDP, pcSession net.Addr) {
+ w := &response{tsigProvider: srv.tsigProvider(), udp: u, udpSession: udpSession, pcSession: pcSession}
+ if srv.DecorateWriter != nil {
+ w.writer = srv.DecorateWriter(w)
+ } else {
+ w.writer = w
+ }
+
+ srv.serveDNS(m, w)
+ wg.Done()
+}
+
+func (srv *Server) serveDNS(m []byte, w *response) {
+ dh, off, err := unpackMsgHdr(m, 0)
+ if err != nil {
+ // Let client hang, they are sending crap; any reply can be used to amplify.
+ return
+ }
+
+ req := new(Msg)
+ req.setHdr(dh)
+
+ switch action := srv.MsgAcceptFunc(dh); action {
+ case MsgAccept:
+ if req.unpack(dh, m, off) == nil {
+ break
+ }
+
+ fallthrough
+ case MsgReject, MsgRejectNotImplemented:
+ opcode := req.Opcode
+ req.SetRcodeFormatError(req)
+ req.Zero = false
+ if action == MsgRejectNotImplemented {
+ req.Opcode = opcode
+ req.Rcode = RcodeNotImplemented
+ }
+
+ // Are we allowed to delete any OPT records here?
+ req.Ns, req.Answer, req.Extra = nil, nil, nil
+
+ w.WriteMsg(req)
+ fallthrough
+ case MsgIgnore:
+ if w.udp != nil && cap(m) == srv.UDPSize {
+ srv.udpPool.Put(m[:srv.UDPSize])
+ }
+
+ return
+ }
+
+ w.tsigStatus = nil
+ if w.tsigProvider != nil {
+ if t := req.IsTsig(); t != nil {
+ w.tsigStatus = tsigVerifyProvider(m, w.tsigProvider, "", false)
+ w.tsigTimersOnly = false
+ w.tsigRequestMAC = t.MAC
+ }
+ }
+
+ if w.udp != nil && cap(m) == srv.UDPSize {
+ srv.udpPool.Put(m[:srv.UDPSize])
+ }
+
+ srv.Handler.ServeDNS(w, req) // Writes back to the client
+}
+
+func (srv *Server) readTCP(conn net.Conn, timeout time.Duration) ([]byte, error) {
+ // If we race with ShutdownContext, the read deadline may
+ // have been set in the distant past to unblock the read
+ // below. We must not override it, otherwise we may block
+ // ShutdownContext.
+ srv.lock.RLock()
+ if srv.started {
+ conn.SetReadDeadline(time.Now().Add(timeout))
+ }
+ srv.lock.RUnlock()
+
+ var length uint16
+ if err := binary.Read(conn, binary.BigEndian, &length); err != nil {
+ return nil, err
+ }
+
+ m := make([]byte, length)
+ if _, err := io.ReadFull(conn, m); err != nil {
+ return nil, err
+ }
+
+ return m, nil
+}
+
+func (srv *Server) readUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error) {
+ srv.lock.RLock()
+ if srv.started {
+ // See the comment in readTCP above.
+ conn.SetReadDeadline(time.Now().Add(timeout))
+ }
+ srv.lock.RUnlock()
+
+ m := srv.udpPool.Get().([]byte)
+ n, s, err := ReadFromSessionUDP(conn, m)
+ if err != nil {
+ srv.udpPool.Put(m)
+ return nil, nil, err
+ }
+ m = m[:n]
+ return m, s, nil
+}
+
+func (srv *Server) readPacketConn(conn net.PacketConn, timeout time.Duration) ([]byte, net.Addr, error) {
+ srv.lock.RLock()
+ if srv.started {
+ // See the comment in readTCP above.
+ conn.SetReadDeadline(time.Now().Add(timeout))
+ }
+ srv.lock.RUnlock()
+
+ m := srv.udpPool.Get().([]byte)
+ n, addr, err := conn.ReadFrom(m)
+ if err != nil {
+ srv.udpPool.Put(m)
+ return nil, nil, err
+ }
+ m = m[:n]
+ return m, addr, nil
+}
+
+// WriteMsg implements the ResponseWriter.WriteMsg method.
+func (w *response) WriteMsg(m *Msg) (err error) {
+ if w.closed {
+ return &Error{err: "WriteMsg called after Close"}
+ }
+
+ var data []byte
+ if w.tsigProvider != nil { // if no provider, dont check for the tsig (which is a longer check)
+ if t := m.IsTsig(); t != nil {
+ data, w.tsigRequestMAC, err = tsigGenerateProvider(m, w.tsigProvider, w.tsigRequestMAC, w.tsigTimersOnly)
+ if err != nil {
+ return err
+ }
+ _, err = w.writer.Write(data)
+ return err
+ }
+ }
+ data, err = m.Pack()
+ if err != nil {
+ return err
+ }
+ _, err = w.writer.Write(data)
+ return err
+}
+
+// Write implements the ResponseWriter.Write method.
+func (w *response) Write(m []byte) (int, error) {
+ if w.closed {
+ return 0, &Error{err: "Write called after Close"}
+ }
+
+ switch {
+ case w.udp != nil:
+ if u, ok := w.udp.(*net.UDPConn); ok {
+ return WriteToSessionUDP(u, m, w.udpSession)
+ }
+ return w.udp.WriteTo(m, w.pcSession)
+ case w.tcp != nil:
+ if len(m) > MaxMsgSize {
+ return 0, &Error{err: "message too large"}
+ }
+
+ 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")
+ }
+}
+
+// LocalAddr implements the ResponseWriter.LocalAddr method.
+func (w *response) LocalAddr() net.Addr {
+ switch {
+ case w.udp != nil:
+ return w.udp.LocalAddr()
+ case w.tcp != nil:
+ return w.tcp.LocalAddr()
+ default:
+ panic("dns: internal error: udp and tcp both nil")
+ }
+}
+
+// RemoteAddr implements the ResponseWriter.RemoteAddr method.
+func (w *response) RemoteAddr() net.Addr {
+ switch {
+ case w.udpSession != nil:
+ return w.udpSession.RemoteAddr()
+ case w.pcSession != nil:
+ return w.pcSession
+ case w.tcp != nil:
+ return w.tcp.RemoteAddr()
+ default:
+ panic("dns: internal error: udpSession, pcSession and tcp are all nil")
+ }
+}
+
+// TsigStatus implements the ResponseWriter.TsigStatus method.
+func (w *response) TsigStatus() error { return w.tsigStatus }
+
+// TsigTimersOnly implements the ResponseWriter.TsigTimersOnly method.
+func (w *response) TsigTimersOnly(b bool) { w.tsigTimersOnly = b }
+
+// Hijack implements the ResponseWriter.Hijack method.
+func (w *response) Hijack() { w.hijacked = true }
+
+// Close implements the ResponseWriter.Close method
+func (w *response) Close() error {
+ if w.closed {
+ return &Error{err: "connection already closed"}
+ }
+ w.closed = true
+
+ switch {
+ case w.udp != nil:
+ // Can't close the udp conn, as that is actually the listener.
+ return nil
+ case w.tcp != nil:
+ return w.tcp.Close()
+ default:
+ panic("dns: internal error: udp and tcp both nil")
+ }
+}
+
+// ConnectionState() implements the ConnectionStater.ConnectionState() interface.
+func (w *response) ConnectionState() *tls.ConnectionState {
+ type tlsConnectionStater interface {
+ ConnectionState() tls.ConnectionState
+ }
+ if v, ok := w.tcp.(tlsConnectionStater); ok {
+ t := v.ConnectionState()
+ return &t
+ }
+ return nil
+}
diff --git a/vendor/github.com/miekg/dns/sig0.go b/vendor/github.com/miekg/dns/sig0.go
@@ -0,0 +1,194 @@
+package dns
+
+import (
+ "crypto"
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/rsa"
+ "encoding/binary"
+ "math/big"
+ "strings"
+ "time"
+)
+
+// Sign signs a dns.Msg. It fills the signature with the appropriate data.
+// The SIG record should have the SignerName, KeyTag, Algorithm, Inception
+// and Expiration set.
+func (rr *SIG) Sign(k crypto.Signer, m *Msg) ([]byte, error) {
+ if k == nil {
+ return nil, ErrPrivKey
+ }
+ if rr.KeyTag == 0 || rr.SignerName == "" || rr.Algorithm == 0 {
+ return nil, ErrKey
+ }
+
+ rr.Hdr = RR_Header{Name: ".", Rrtype: TypeSIG, Class: ClassANY, Ttl: 0}
+ rr.OrigTtl, rr.TypeCovered, rr.Labels = 0, 0, 0
+
+ buf := make([]byte, m.Len()+Len(rr))
+ mbuf, err := m.PackBuffer(buf)
+ if err != nil {
+ return nil, err
+ }
+ if &buf[0] != &mbuf[0] {
+ return nil, ErrBuf
+ }
+ off, err := PackRR(rr, buf, len(mbuf), nil, false)
+ if err != nil {
+ return nil, err
+ }
+ buf = buf[:off:cap(buf)]
+
+ h, cryptohash, err := hashFromAlgorithm(rr.Algorithm)
+ if err != nil {
+ return nil, err
+ }
+
+ // Write SIG rdata
+ h.Write(buf[len(mbuf)+1+2+2+4+2:])
+ // Write message
+ h.Write(buf[:len(mbuf)])
+
+ signature, err := sign(k, h.Sum(nil), cryptohash, rr.Algorithm)
+ if err != nil {
+ return nil, err
+ }
+
+ rr.Signature = toBase64(signature)
+
+ buf = append(buf, signature...)
+ if len(buf) > int(^uint16(0)) {
+ return nil, ErrBuf
+ }
+ // Adjust sig data length
+ rdoff := len(mbuf) + 1 + 2 + 2 + 4
+ rdlen := binary.BigEndian.Uint16(buf[rdoff:])
+ rdlen += uint16(len(signature))
+ binary.BigEndian.PutUint16(buf[rdoff:], rdlen)
+ // Adjust additional count
+ adc := binary.BigEndian.Uint16(buf[10:])
+ adc++
+ binary.BigEndian.PutUint16(buf[10:], adc)
+ return buf, nil
+}
+
+// Verify validates the message buf using the key k.
+// It's assumed that buf is a valid message from which rr was unpacked.
+func (rr *SIG) Verify(k *KEY, buf []byte) error {
+ if k == nil {
+ return ErrKey
+ }
+ if rr.KeyTag == 0 || rr.SignerName == "" || rr.Algorithm == 0 {
+ return ErrKey
+ }
+
+ h, cryptohash, err := hashFromAlgorithm(rr.Algorithm)
+ if err != nil {
+ return err
+ }
+
+ buflen := len(buf)
+ qdc := binary.BigEndian.Uint16(buf[4:])
+ anc := binary.BigEndian.Uint16(buf[6:])
+ auc := binary.BigEndian.Uint16(buf[8:])
+ adc := binary.BigEndian.Uint16(buf[10:])
+ offset := headerSize
+ for i := uint16(0); i < qdc && offset < buflen; i++ {
+ _, offset, err = UnpackDomainName(buf, offset)
+ if err != nil {
+ return err
+ }
+ // Skip past Type and Class
+ offset += 2 + 2
+ }
+ for i := uint16(1); i < anc+auc+adc && offset < buflen; i++ {
+ _, offset, err = UnpackDomainName(buf, offset)
+ if err != nil {
+ return err
+ }
+ // Skip past Type, Class and TTL
+ offset += 2 + 2 + 4
+ if offset+1 >= buflen {
+ continue
+ }
+ rdlen := binary.BigEndian.Uint16(buf[offset:])
+ offset += 2
+ offset += int(rdlen)
+ }
+ if offset >= buflen {
+ return &Error{err: "overflowing unpacking signed message"}
+ }
+
+ // offset should be just prior to SIG
+ bodyend := offset
+ // owner name SHOULD be root
+ _, offset, err = UnpackDomainName(buf, offset)
+ if err != nil {
+ return err
+ }
+ // Skip Type, Class, TTL, RDLen
+ offset += 2 + 2 + 4 + 2
+ sigstart := offset
+ // Skip Type Covered, Algorithm, Labels, Original TTL
+ offset += 2 + 1 + 1 + 4
+ if offset+4+4 >= buflen {
+ return &Error{err: "overflow unpacking signed message"}
+ }
+ expire := binary.BigEndian.Uint32(buf[offset:])
+ offset += 4
+ incept := binary.BigEndian.Uint32(buf[offset:])
+ offset += 4
+ now := uint32(time.Now().Unix())
+ if now < incept || now > expire {
+ return ErrTime
+ }
+ // Skip key tag
+ offset += 2
+ var signername string
+ signername, offset, err = UnpackDomainName(buf, offset)
+ if err != nil {
+ return err
+ }
+ // If key has come from the DNS name compression might
+ // have mangled the case of the name
+ if !strings.EqualFold(signername, k.Header().Name) {
+ return &Error{err: "signer name doesn't match key name"}
+ }
+ sigend := offset
+ h.Write(buf[sigstart:sigend])
+ h.Write(buf[:10])
+ h.Write([]byte{
+ byte((adc - 1) << 8),
+ byte(adc - 1),
+ })
+ h.Write(buf[12:bodyend])
+
+ hashed := h.Sum(nil)
+ sig := buf[sigend:]
+ switch k.Algorithm {
+ case RSASHA1, RSASHA256, RSASHA512:
+ pk := k.publicKeyRSA()
+ if pk != nil {
+ return rsa.VerifyPKCS1v15(pk, cryptohash, hashed, sig)
+ }
+ case ECDSAP256SHA256, ECDSAP384SHA384:
+ pk := k.publicKeyECDSA()
+ r := new(big.Int).SetBytes(sig[:len(sig)/2])
+ s := new(big.Int).SetBytes(sig[len(sig)/2:])
+ if pk != nil {
+ if ecdsa.Verify(pk, hashed, r, s) {
+ return nil
+ }
+ return ErrSig
+ }
+ case ED25519:
+ pk := k.publicKeyED25519()
+ if pk != nil {
+ if ed25519.Verify(pk, hashed, sig) {
+ return nil
+ }
+ return ErrSig
+ }
+ }
+ return ErrKeyAlg
+}
diff --git a/vendor/github.com/miekg/dns/singleinflight.go b/vendor/github.com/miekg/dns/singleinflight.go
@@ -0,0 +1,61 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Adapted for dns package usage by Miek Gieben.
+
+package dns
+
+import "sync"
+import "time"
+
+// call is an in-flight or completed singleflight.Do call
+type call struct {
+ wg sync.WaitGroup
+ val *Msg
+ rtt time.Duration
+ err error
+ dups int
+}
+
+// singleflight represents a class of work and forms a namespace in
+// which units of work can be executed with duplicate suppression.
+type singleflight struct {
+ sync.Mutex // protects m
+ m map[string]*call // lazily initialized
+
+ dontDeleteForTesting bool // this is only to be used by TestConcurrentExchanges
+}
+
+// Do executes and returns the results of the given function, making
+// sure that only one execution is in-flight for a given key at a
+// time. If a duplicate comes in, the duplicate caller waits for the
+// original to complete and receives the same results.
+// The return value shared indicates whether v was given to multiple callers.
+func (g *singleflight) Do(key string, fn func() (*Msg, time.Duration, error)) (v *Msg, rtt time.Duration, err error, shared bool) {
+ g.Lock()
+ if g.m == nil {
+ g.m = make(map[string]*call)
+ }
+ if c, ok := g.m[key]; ok {
+ c.dups++
+ g.Unlock()
+ c.wg.Wait()
+ return c.val, c.rtt, c.err, true
+ }
+ c := new(call)
+ c.wg.Add(1)
+ g.m[key] = c
+ g.Unlock()
+
+ c.val, c.rtt, c.err = fn()
+ c.wg.Done()
+
+ if !g.dontDeleteForTesting {
+ g.Lock()
+ delete(g.m, key)
+ g.Unlock()
+ }
+
+ return c.val, c.rtt, c.err, c.dups > 0
+}
diff --git a/vendor/github.com/miekg/dns/smimea.go b/vendor/github.com/miekg/dns/smimea.go
@@ -0,0 +1,44 @@
+package dns
+
+import (
+ "crypto/sha256"
+ "crypto/x509"
+ "encoding/hex"
+)
+
+// Sign creates a SMIMEA record from an SSL certificate.
+func (r *SMIMEA) Sign(usage, selector, matchingType int, cert *x509.Certificate) (err error) {
+ r.Hdr.Rrtype = TypeSMIMEA
+ r.Usage = uint8(usage)
+ r.Selector = uint8(selector)
+ r.MatchingType = uint8(matchingType)
+
+ r.Certificate, err = CertificateToDANE(r.Selector, r.MatchingType, cert)
+ return err
+}
+
+// Verify verifies a SMIMEA record against an SSL certificate. If it is OK
+// a nil error is returned.
+func (r *SMIMEA) Verify(cert *x509.Certificate) error {
+ c, err := CertificateToDANE(r.Selector, r.MatchingType, cert)
+ if err != nil {
+ return err // Not also ErrSig?
+ }
+ if r.Certificate == c {
+ return nil
+ }
+ return ErrSig // ErrSig, really?
+}
+
+// SMIMEAName returns the ownername of a SMIMEA resource record as per the
+// format specified in RFC 'draft-ietf-dane-smime-12' Section 2 and 3
+func SMIMEAName(email, domain string) (string, error) {
+ hasher := sha256.New()
+ hasher.Write([]byte(email))
+
+ // RFC Section 3: "The local-part is hashed using the SHA2-256
+ // algorithm with the hash truncated to 28 octets and
+ // represented in its hexadecimal representation to become the
+ // left-most label in the prepared domain name"
+ return hex.EncodeToString(hasher.Sum(nil)[:28]) + "." + "_smimecert." + domain, nil
+}
diff --git a/vendor/github.com/miekg/dns/svcb.go b/vendor/github.com/miekg/dns/svcb.go
@@ -0,0 +1,935 @@
+package dns
+
+import (
+ "bytes"
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "net"
+ "sort"
+ "strconv"
+ "strings"
+)
+
+// SVCBKey is the type of the keys used in the SVCB RR.
+type SVCBKey uint16
+
+// Keys defined in draft-ietf-dnsop-svcb-https-08 Section 14.3.2.
+const (
+ SVCB_MANDATORY SVCBKey = iota
+ SVCB_ALPN
+ SVCB_NO_DEFAULT_ALPN
+ SVCB_PORT
+ SVCB_IPV4HINT
+ SVCB_ECHCONFIG
+ SVCB_IPV6HINT
+ SVCB_DOHPATH // draft-ietf-add-svcb-dns-02 Section 9
+
+ 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: "ech",
+ SVCB_IPV6HINT: "ipv6hint",
+ SVCB_DOHPATH: "dohpath",
+}
+
+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()
+ }
+
+ // "In AliasMode, records SHOULD NOT include any SvcParams, and recipients MUST
+ // ignore any SvcParams that are present."
+ // However, we don't check rr.Priority == 0 && len(xs) > 0 here
+ // It is the responsibility of the user of the library to check this.
+ // This is to encourage the fixing of the source of this error.
+
+ rr.Value = xs
+ 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_DOHPATH:
+ return new(SVCBDoHPath)
+ 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-08).
+//
+// NOTE: The HTTPS/SVCB RFCs are in the draft stage.
+// The API, including constants and types related to SVCBKeyValues, may
+// change in future versions in accordance with the latest drafts.
+type SVCB struct {
+ Hdr RR_Header
+ Priority uint16 // If zero, Value must be empty or discarded by the user of this library
+ Target string `dns:"domain-name"`
+ Value []SVCBKeyValue `dns:"pairs"`
+}
+
+// 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.
+//
+// NOTE: The HTTPS/SVCB RFCs are in the draft stage.
+// The API, including constants and types related to SVCBKeyValues, may
+// change in future versions in accordance with the latest drafts.
+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. If ignored, the whole RRSet must be ignored.
+// "port" and "no-default-alpn" are mandatory by default if present,
+// so they shouldn't be included here.
+//
+// It is incumbent upon the user of this library to reject the RRSet if
+// or avoid constructing such an RRSet that:
+// - "mandatory" is included as one of the keys of mandatory
+// - no key is listed multiple times in mandatory
+// - all keys listed in mandatory are present
+// - escape sequences are not used in mandatory
+// - mandatory, when present, lists at least one key
+//
+// 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{dns.SVCB_ALPN}
+// s.Value = append(s.Value, e)
+// t := new(dns.SVCBAlpn)
+// t.Alpn = []string{"xmpp-client"}
+// s.Value = append(s.Value, t)
+type SVCBMandatory struct {
+ Code []SVCBKey
+}
+
+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.
+// The user of this library must ensure that at least one protocol is listed when alpn is present.
+// 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(h.Value, e)
+type SVCBAlpn struct {
+ Alpn []string
+}
+
+func (*SVCBAlpn) Key() SVCBKey { return SVCB_ALPN }
+
+func (s *SVCBAlpn) String() string {
+ // An ALPN value is a comma-separated list of values, each of which can be
+ // an arbitrary binary value. In order to allow parsing, the comma and
+ // backslash characters are themselves excaped.
+ //
+ // However, this escaping is done in addition to the normal escaping which
+ // happens in zone files, meaning that these values must be
+ // double-escaped. This looks terrible, so if you see a never-ending
+ // sequence of backslash in a zone file this may be why.
+ //
+ // https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-08#appendix-A.1
+ var str strings.Builder
+ for i, alpn := range s.Alpn {
+ // 4*len(alpn) is the worst case where we escape every character in the alpn as \123, plus 1 byte for the ',' separating the alpn from others
+ str.Grow(4*len(alpn) + 1)
+ if i > 0 {
+ str.WriteByte(',')
+ }
+ for j := 0; j < len(alpn); j++ {
+ e := alpn[j]
+ if ' ' > e || e > '~' {
+ str.WriteString(escapeByte(e))
+ continue
+ }
+ switch e {
+ // We escape a few characters which may confuse humans or parsers.
+ case '"', ';', ' ':
+ str.WriteByte('\\')
+ str.WriteByte(e)
+ // The comma and backslash characters themselves must be
+ // doubly-escaped. We use `\\` for the first backslash and
+ // the escaped numeric value for the other value. We especially
+ // don't want a comma in the output.
+ case ',':
+ str.WriteString(`\\\044`)
+ case '\\':
+ str.WriteString(`\\\092`)
+ default:
+ str.WriteByte(e)
+ }
+ }
+ }
+ return str.String()
+}
+
+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 e == "" {
+ 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 {
+ if len(b) == 0 {
+ s.Alpn = []string{}
+ return nil
+ }
+
+ alpn := []string{}
+ a := []byte{}
+ for p := 0; p < len(b); {
+ c, q := nextByte(b, p)
+ if q == 0 {
+ return errors.New("dns: svcbalpn: unterminated escape")
+ }
+ p += q
+ // If we find a comma, we have finished reading an alpn.
+ if c == ',' {
+ if len(a) == 0 {
+ return errors.New("dns: svcbalpn: empty protocol identifier")
+ }
+ alpn = append(alpn, string(a))
+ a = []byte{}
+ continue
+ }
+ // If it's a backslash, we need to handle a comma-separated list.
+ if c == '\\' {
+ dc, dq := nextByte(b, p)
+ if dq == 0 {
+ return errors.New("dns: svcbalpn: unterminated escape decoding comma-separated list")
+ }
+ if dc != '\\' && dc != ',' {
+ return errors.New("dns: svcbalpn: bad escaped character decoding comma-separated list")
+ }
+ p += dq
+ c = dc
+ }
+ a = append(a, c)
+ }
+ // Add the final alpn.
+ if len(a) == 0 {
+ return errors.New("dns: svcbalpn: last protocol identifier empty")
+ }
+ s.Alpn = append(alpn, string(a))
+ 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.
+// Should be used in conjunction with alpn.
+// Basic use pattern for creating a no-default-alpn option:
+//
+// s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}}
+// t := new(dns.SVCBAlpn)
+// t.Alpn = []string{"xmpp-client"}
+// s.Value = append(s.Value, t)
+// 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 b != "" {
+ 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 {
+ hint := make([]net.IP, len(s.Hint))
+ for i, ip := range s.Hint {
+ hint[i] = copyIP(ip)
+ }
+
+ return &SVCBIPv4Hint{
+ Hint: hint,
+ }
+}
+
+// SVCBECHConfig pair contains the ECHConfig structure defined in draft-ietf-tls-esni [RFC xxxx].
+// Basic use pattern for creating an ech 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 // Specifically ECHConfigList including the redundant length prefix
+}
+
+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: svcbech: bad base64 ech")
+ }
+ 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 {
+ 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")
+ }
+ if ip.To4() != nil {
+ return errors.New("dns: svcbipv6hint: expected ipv6, got ipv4-mapped-ipv6")
+ }
+ dst[i] = ip
+ }
+ s.Hint = dst
+ return nil
+}
+
+func (s *SVCBIPv6Hint) copy() SVCBKeyValue {
+ hint := make([]net.IP, len(s.Hint))
+ for i, ip := range s.Hint {
+ hint[i] = copyIP(ip)
+ }
+
+ return &SVCBIPv6Hint{
+ Hint: hint,
+ }
+}
+
+// SVCBDoHPath pair is used to indicate the URI template that the
+// clients may use to construct a DNS over HTTPS URI.
+//
+// See RFC xxxx (https://datatracker.ietf.org/doc/html/draft-ietf-add-svcb-dns-02)
+// and RFC yyyy (https://datatracker.ietf.org/doc/html/draft-ietf-add-ddr-06).
+//
+// A basic example of using the dohpath option together with the alpn
+// option to indicate support for DNS over HTTPS on a certain path:
+//
+// s := new(dns.SVCB)
+// s.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}
+// e := new(dns.SVCBAlpn)
+// e.Alpn = []string{"h2", "h3"}
+// p := new(dns.SVCBDoHPath)
+// p.Template = "/dns-query{?dns}"
+// s.Value = append(s.Value, e, p)
+//
+// The parsing currently doesn't validate that Template is a valid
+// RFC 6570 URI template.
+type SVCBDoHPath struct {
+ Template string
+}
+
+func (*SVCBDoHPath) Key() SVCBKey { return SVCB_DOHPATH }
+func (s *SVCBDoHPath) String() string { return svcbParamToStr([]byte(s.Template)) }
+func (s *SVCBDoHPath) len() int { return len(s.Template) }
+func (s *SVCBDoHPath) pack() ([]byte, error) { return []byte(s.Template), nil }
+
+func (s *SVCBDoHPath) unpack(b []byte) error {
+ s.Template = string(b)
+ return nil
+}
+
+func (s *SVCBDoHPath) parse(b string) error {
+ template, err := svcbParseParam(b)
+ if err != nil {
+ return fmt.Errorf("dns: svcbdohpath: %w", err)
+ }
+ s.Template = string(template)
+ return nil
+}
+
+func (s *SVCBDoHPath) copy() SVCBKeyValue {
+ return &SVCBDoHPath{
+ Template: s.Template,
+ }
+}
+
+// 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) String() string { return svcbParamToStr(s.Data) }
+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) parse(b string) error {
+ data, err := svcbParseParam(b)
+ if err != nil {
+ return fmt.Errorf("dns: svcblocal: svcb private/experimental key %w", err)
+ }
+ 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
+}
+
+// svcbParamStr converts the value of an SVCB parameter into a DNS presentation-format string.
+func svcbParamToStr(s []byte) string {
+ var str strings.Builder
+ str.Grow(4 * len(s))
+ for _, e := range s {
+ if ' ' <= e && e <= '~' {
+ switch e {
+ case '"', ';', ' ', '\\':
+ str.WriteByte('\\')
+ str.WriteByte(e)
+ default:
+ str.WriteByte(e)
+ }
+ } else {
+ str.WriteString(escapeByte(e))
+ }
+ }
+ return str.String()
+}
+
+// svcbParseParam parses a DNS presentation-format string into an SVCB parameter value.
+func svcbParseParam(b string) ([]byte, 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 nil, errors.New("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 nil, errors.New("bad escaped octet")
+ } else {
+ data = append(data, b[i+1])
+ i += 2
+ }
+ }
+ return data, nil
+}
diff --git a/vendor/github.com/miekg/dns/tlsa.go b/vendor/github.com/miekg/dns/tlsa.go
@@ -0,0 +1,44 @@
+package dns
+
+import (
+ "crypto/x509"
+ "net"
+ "strconv"
+)
+
+// Sign creates a TLSA record from an SSL certificate.
+func (r *TLSA) Sign(usage, selector, matchingType int, cert *x509.Certificate) (err error) {
+ r.Hdr.Rrtype = TypeTLSA
+ r.Usage = uint8(usage)
+ r.Selector = uint8(selector)
+ r.MatchingType = uint8(matchingType)
+
+ r.Certificate, err = CertificateToDANE(r.Selector, r.MatchingType, cert)
+ return err
+}
+
+// Verify verifies a TLSA record against an SSL certificate. If it is OK
+// a nil error is returned.
+func (r *TLSA) Verify(cert *x509.Certificate) error {
+ c, err := CertificateToDANE(r.Selector, r.MatchingType, cert)
+ if err != nil {
+ return err // Not also ErrSig?
+ }
+ if r.Certificate == c {
+ return nil
+ }
+ return ErrSig // ErrSig, really?
+}
+
+// TLSAName returns the ownername of a TLSA resource record as per the
+// rules specified in RFC 6698, Section 3.
+func TLSAName(name, service, network string) (string, error) {
+ if !IsFqdn(name) {
+ return "", ErrFqdn
+ }
+ p, err := net.LookupPort(network, service)
+ if err != nil {
+ return "", err
+ }
+ return "_" + strconv.Itoa(p) + "._" + network + "." + name, nil
+}
diff --git a/vendor/github.com/miekg/dns/tools.go b/vendor/github.com/miekg/dns/tools.go
@@ -0,0 +1,9 @@
+// +build tools
+
+// We include our tool dependencies for `go generate` here to ensure they're
+// properly tracked by the go tool. See the Go Wiki for the rationale behind this:
+// https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module.
+
+package dns
+
+import _ "golang.org/x/tools/go/packages"
diff --git a/vendor/github.com/miekg/dns/tsig.go b/vendor/github.com/miekg/dns/tsig.go
@@ -0,0 +1,456 @@
+package dns
+
+import (
+ "crypto/hmac"
+ "crypto/sha1"
+ "crypto/sha256"
+ "crypto/sha512"
+ "encoding/binary"
+ "encoding/hex"
+ "hash"
+ "strconv"
+ "strings"
+ "time"
+)
+
+// HMAC hashing codes. These are transmitted as domain names.
+const (
+ HmacSHA1 = "hmac-sha1."
+ HmacSHA224 = "hmac-sha224."
+ HmacSHA256 = "hmac-sha256."
+ HmacSHA384 = "hmac-sha384."
+ HmacSHA512 = "hmac-sha512."
+
+ HmacMD5 = "hmac-md5.sig-alg.reg.int." // Deprecated: HmacMD5 is no longer supported.
+)
+
+// 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
+}
+
+type tsigSecretProvider map[string]string
+
+func (ts tsigSecretProvider) Generate(msg []byte, t *TSIG) ([]byte, error) {
+ key, ok := ts[t.Hdr.Name]
+ if !ok {
+ return nil, ErrSecret
+ }
+ return tsigHMACProvider(key).Generate(msg, t)
+}
+
+func (ts tsigSecretProvider) Verify(msg []byte, t *TSIG) error {
+ key, ok := ts[t.Hdr.Name]
+ if !ok {
+ return ErrSecret
+ }
+ return tsigHMACProvider(key).Verify(msg, t)
+}
+
+// TSIG is the RR the holds the transaction signature of a message.
+// See RFC 2845 and RFC 4635.
+type TSIG struct {
+ Hdr RR_Header
+ Algorithm string `dns:"domain-name"`
+ TimeSigned uint64 `dns:"uint48"`
+ Fudge uint16
+ MACSize uint16
+ MAC string `dns:"size-hex:MACSize"`
+ OrigId uint16
+ Error uint16
+ OtherLen uint16
+ OtherData string `dns:"size-hex:OtherLen"`
+}
+
+// TSIG has no official presentation format, but this will suffice.
+
+func (rr *TSIG) String() string {
+ s := "\n;; TSIG PSEUDOSECTION:\n; " // add another semi-colon to signify TSIG does not have a presentation format
+ s += rr.Hdr.String() +
+ " " + rr.Algorithm +
+ " " + tsigTimeToString(rr.TimeSigned) +
+ " " + strconv.Itoa(int(rr.Fudge)) +
+ " " + strconv.Itoa(int(rr.MACSize)) +
+ " " + strings.ToUpper(rr.MAC) +
+ " " + strconv.Itoa(int(rr.OrigId)) +
+ " " + strconv.Itoa(int(rr.Error)) + // BIND prints NOERROR
+ " " + strconv.Itoa(int(rr.OtherLen)) +
+ " " + rr.OtherData
+ return s
+}
+
+func (*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.
+// RFC 2845, section 3.4.2. TSIG Variables.
+type tsigWireFmt struct {
+ // From RR_Header
+ Name string `dns:"domain-name"`
+ Class uint16
+ Ttl uint32
+ // Rdata of the TSIG
+ Algorithm string `dns:"domain-name"`
+ TimeSigned uint64 `dns:"uint48"`
+ Fudge uint16
+ // MACSize, MAC and OrigId excluded
+ Error uint16
+ OtherLen uint16
+ OtherData string `dns:"size-hex:OtherLen"`
+}
+
+// If we have the MAC use this type to convert it to wiredata. Section 3.4.3. Request MAC
+type macWireFmt struct {
+ MACSize uint16
+ MAC string `dns:"size-hex:MACSize"`
+}
+
+// 3.3. Time values used in TSIG calculations
+type timerWireFmt struct {
+ TimeSigned uint64 `dns:"uint48"`
+ Fudge uint16
+}
+
+// TsigGenerate fills out the TSIG record attached to the message.
+// The message should contain
+// a "stub" TSIG RR with the algorithm, key name (owner name of the RR),
+// time fudge (defaults to 300 seconds) and the current time
+// The TSIG MAC is saved in that Tsig RR.
+// When TsigGenerate is called for the first time requestMAC is set to the empty string and
+// timersOnly is false.
+// If something goes wrong an error is returned, otherwise it is nil.
+func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, string, error) {
+ 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")
+ }
+
+ rr := m.Extra[len(m.Extra)-1].(*TSIG)
+ m.Extra = m.Extra[0 : len(m.Extra)-1] // kill the TSIG from the msg
+ mbuf, err := m.Pack()
+ if err != nil {
+ return nil, "", err
+ }
+
+ buf, err := tsigBuffer(mbuf, rr, requestMAC, timersOnly)
+ if err != nil {
+ return nil, "", err
+ }
+
+ t := new(TSIG)
+ // Copy all TSIG fields except MAC, its size, and time signed which are filled when signing.
+ *t = *rr
+ t.TimeSigned = 0
+ t.MAC = ""
+ t.MACSize = 0
+
+ // Sign unless there is a key or MAC validation error (RFC 8945 5.3.2)
+ if rr.Error != RcodeBadKey && rr.Error != RcodeBadSig {
+ mac, err := provider.Generate(buf, rr)
+ if err != nil {
+ return nil, "", err
+ }
+ t.TimeSigned = rr.TimeSigned
+ t.MAC = hex.EncodeToString(mac)
+ t.MACSize = uint16(len(t.MAC) / 2) // Size is half!
+ }
+
+ tbuf := make([]byte, Len(t))
+ off, err := PackRR(t, tbuf, 0, nil, false)
+ if err != nil {
+ return nil, "", err
+ }
+ mbuf = append(mbuf, tbuf[:off]...)
+ // Update the ArCount directly in the buffer.
+ binary.BigEndian.PutUint16(mbuf[10:], uint16(len(m.Extra)+1))
+
+ return mbuf, t.MAC, nil
+}
+
+// TsigVerify verifies the TSIG on a message.
+// If the signature does not validate err contains the
+// error, otherwise it is nil.
+func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error {
+ return tsigVerify(msg, 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
+ }
+
+ buf, err := tsigBuffer(stripped, tsig, requestMAC, timersOnly)
+ if err != nil {
+ return err
+ }
+
+ 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.
+ // We check this after verifying the signature, following draft-ietf-dnsop-rfc2845bis
+ // instead of RFC2845, in order to prevent a security vulnerability as reported in CVE-2017-3142/3143.
+ ti := now - tsig.TimeSigned
+ if now < tsig.TimeSigned {
+ ti = tsig.TimeSigned - now
+ }
+ if uint64(tsig.Fudge) < ti {
+ return ErrTime
+ }
+
+ return nil
+}
+
+// Create a wiredata buffer for the MAC calculation.
+func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) ([]byte, error) {
+ var buf []byte
+ if rr.TimeSigned == 0 {
+ rr.TimeSigned = uint64(time.Now().Unix())
+ }
+ if rr.Fudge == 0 {
+ rr.Fudge = 300 // Standard (RFC) default.
+ }
+
+ // Replace message ID in header with original ID from TSIG
+ binary.BigEndian.PutUint16(msgbuf[0:2], rr.OrigId)
+
+ if requestMAC != "" {
+ m := new(macWireFmt)
+ m.MACSize = uint16(len(requestMAC) / 2)
+ m.MAC = requestMAC
+ buf = make([]byte, len(requestMAC)) // long enough
+ n, err := packMacWire(m, buf)
+ if err != nil {
+ return nil, err
+ }
+ buf = buf[:n]
+ }
+
+ tsigvar := make([]byte, DefaultMsgSize)
+ if timersOnly {
+ tsig := new(timerWireFmt)
+ tsig.TimeSigned = rr.TimeSigned
+ tsig.Fudge = rr.Fudge
+ n, err := packTimerWire(tsig, tsigvar)
+ if err != nil {
+ return nil, err
+ }
+ tsigvar = tsigvar[:n]
+ } else {
+ tsig := new(tsigWireFmt)
+ tsig.Name = CanonicalName(rr.Hdr.Name)
+ tsig.Class = ClassANY
+ tsig.Ttl = rr.Hdr.Ttl
+ tsig.Algorithm = CanonicalName(rr.Algorithm)
+ tsig.TimeSigned = rr.TimeSigned
+ tsig.Fudge = rr.Fudge
+ tsig.Error = rr.Error
+ tsig.OtherLen = rr.OtherLen
+ tsig.OtherData = rr.OtherData
+ n, err := packTsigWire(tsig, tsigvar)
+ if err != nil {
+ return nil, err
+ }
+ tsigvar = tsigvar[:n]
+ }
+
+ if requestMAC != "" {
+ x := append(buf, msgbuf...)
+ buf = append(x, tsigvar...)
+ } else {
+ buf = append(msgbuf, tsigvar...)
+ }
+ return buf, nil
+}
+
+// Strip the TSIG from the raw message.
+func stripTsig(msg []byte) ([]byte, *TSIG, error) {
+ // Copied from msg.go's Unpack() Header, but modified.
+ var (
+ dh Header
+ err error
+ )
+ off, tsigoff := 0, 0
+
+ if dh, off, err = unpackMsgHdr(msg, off); err != nil {
+ return nil, nil, err
+ }
+ if dh.Arcount == 0 {
+ return nil, nil, ErrNoSig
+ }
+
+ // Rcode, see msg.go Unpack()
+ if int(dh.Bits&0xF) == RcodeNotAuth {
+ return nil, nil, ErrAuth
+ }
+
+ for i := 0; i < int(dh.Qdcount); i++ {
+ _, off, err = unpackQuestion(msg, off)
+ if err != nil {
+ return nil, nil, err
+ }
+ }
+
+ _, off, err = unpackRRslice(int(dh.Ancount), msg, off)
+ if err != nil {
+ return nil, nil, err
+ }
+ _, off, err = unpackRRslice(int(dh.Nscount), msg, off)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ rr := new(TSIG)
+ var extra RR
+ for i := 0; i < int(dh.Arcount); i++ {
+ tsigoff = off
+ extra, off, err = UnpackRR(msg, off)
+ if err != nil {
+ return nil, nil, err
+ }
+ if extra.Header().Rrtype == TypeTSIG {
+ rr = extra.(*TSIG)
+ // Adjust Arcount.
+ arcount := binary.BigEndian.Uint16(msg[10:])
+ binary.BigEndian.PutUint16(msg[10:], arcount-1)
+ break
+ }
+ }
+ if rr == nil {
+ return nil, nil, ErrNoSig
+ }
+ return msg[:tsigoff], rr, nil
+}
+
+// Translate the TSIG time signed into a date. There is no
+// need for RFC1982 calculations as this date is 48 bits.
+func tsigTimeToString(t uint64) string {
+ ti := time.Unix(int64(t), 0).UTC()
+ return ti.Format("20060102150405")
+}
+
+func packTsigWire(tw *tsigWireFmt, msg []byte) (int, error) {
+ // copied from zmsg.go TSIG packing
+ // RR_Header
+ off, err := PackDomainName(tw.Name, msg, 0, nil, false)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(tw.Class, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint32(tw.Ttl, msg, off)
+ if err != nil {
+ return off, err
+ }
+
+ off, err = PackDomainName(tw.Algorithm, msg, off, nil, false)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint48(tw.TimeSigned, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(tw.Fudge, msg, off)
+ if err != nil {
+ return off, err
+ }
+
+ off, err = packUint16(tw.Error, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(tw.OtherLen, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringHex(tw.OtherData, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func packMacWire(mw *macWireFmt, msg []byte) (int, error) {
+ off, err := packUint16(mw.MACSize, msg, 0)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringHex(mw.MAC, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func packTimerWire(tw *timerWireFmt, msg []byte) (int, error) {
+ off, err := packUint48(tw.TimeSigned, msg, 0)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(tw.Fudge, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
diff --git a/vendor/github.com/miekg/dns/types.go b/vendor/github.com/miekg/dns/types.go
@@ -0,0 +1,1559 @@
+package dns
+
+import (
+ "bytes"
+ "fmt"
+ "net"
+ "strconv"
+ "strings"
+ "time"
+)
+
+type (
+ // Type is a DNS type.
+ Type uint16
+ // Class is a DNS class.
+ Class uint16
+ // Name is a DNS domain name.
+ Name string
+)
+
+// Packet formats
+
+// Wire constants and supported types.
+const (
+ // valid RR_Header.Rrtype and Question.qtype
+
+ TypeNone uint16 = 0
+ TypeA uint16 = 1
+ TypeNS uint16 = 2
+ TypeMD uint16 = 3
+ TypeMF uint16 = 4
+ TypeCNAME uint16 = 5
+ TypeSOA uint16 = 6
+ TypeMB uint16 = 7
+ TypeMG uint16 = 8
+ TypeMR uint16 = 9
+ TypeNULL uint16 = 10
+ TypePTR uint16 = 12
+ TypeHINFO uint16 = 13
+ TypeMINFO uint16 = 14
+ TypeMX uint16 = 15
+ TypeTXT uint16 = 16
+ TypeRP uint16 = 17
+ TypeAFSDB uint16 = 18
+ TypeX25 uint16 = 19
+ TypeISDN uint16 = 20
+ TypeRT uint16 = 21
+ TypeNSAPPTR uint16 = 23
+ TypeSIG uint16 = 24
+ TypeKEY uint16 = 25
+ TypePX uint16 = 26
+ TypeGPOS uint16 = 27
+ TypeAAAA uint16 = 28
+ TypeLOC uint16 = 29
+ TypeNXT uint16 = 30
+ TypeEID uint16 = 31
+ TypeNIMLOC uint16 = 32
+ TypeSRV uint16 = 33
+ TypeATMA uint16 = 34
+ TypeNAPTR uint16 = 35
+ TypeKX uint16 = 36
+ TypeCERT uint16 = 37
+ TypeDNAME uint16 = 39
+ TypeOPT uint16 = 41 // EDNS
+ TypeAPL uint16 = 42
+ TypeDS uint16 = 43
+ TypeSSHFP uint16 = 44
+ TypeRRSIG uint16 = 46
+ TypeNSEC uint16 = 47
+ TypeDNSKEY uint16 = 48
+ TypeDHCID uint16 = 49
+ TypeNSEC3 uint16 = 50
+ TypeNSEC3PARAM uint16 = 51
+ TypeTLSA uint16 = 52
+ TypeSMIMEA uint16 = 53
+ TypeHIP uint16 = 55
+ TypeNINFO uint16 = 56
+ TypeRKEY uint16 = 57
+ TypeTALINK uint16 = 58
+ TypeCDS uint16 = 59
+ TypeCDNSKEY uint16 = 60
+ TypeOPENPGPKEY uint16 = 61
+ TypeCSYNC uint16 = 62
+ TypeZONEMD uint16 = 63
+ TypeSVCB uint16 = 64
+ TypeHTTPS uint16 = 65
+ TypeSPF uint16 = 99
+ TypeUINFO uint16 = 100
+ TypeUID uint16 = 101
+ TypeGID uint16 = 102
+ TypeUNSPEC uint16 = 103
+ TypeNID uint16 = 104
+ TypeL32 uint16 = 105
+ TypeL64 uint16 = 106
+ TypeLP uint16 = 107
+ TypeEUI48 uint16 = 108
+ TypeEUI64 uint16 = 109
+ TypeURI uint16 = 256
+ TypeCAA uint16 = 257
+ TypeAVC uint16 = 258
+
+ TypeTKEY uint16 = 249
+ TypeTSIG uint16 = 250
+
+ // valid Question.Qtype only
+ TypeIXFR uint16 = 251
+ TypeAXFR uint16 = 252
+ TypeMAILB uint16 = 253
+ TypeMAILA uint16 = 254
+ TypeANY uint16 = 255
+
+ TypeTA uint16 = 32768
+ TypeDLV uint16 = 32769
+ TypeReserved uint16 = 65535
+
+ // valid Question.Qclass
+ ClassINET = 1
+ ClassCSNET = 2
+ ClassCHAOS = 3
+ ClassHESIOD = 4
+ ClassNONE = 254
+ ClassANY = 255
+
+ // Message Response Codes, see https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml
+ RcodeSuccess = 0 // NoError - No Error [DNS]
+ RcodeFormatError = 1 // FormErr - Format Error [DNS]
+ RcodeServerFailure = 2 // ServFail - Server Failure [DNS]
+ RcodeNameError = 3 // NXDomain - Non-Existent Domain [DNS]
+ RcodeNotImplemented = 4 // NotImp - Not Implemented [DNS]
+ RcodeRefused = 5 // Refused - Query Refused [DNS]
+ RcodeYXDomain = 6 // YXDomain - Name Exists when it should not [DNS Update]
+ RcodeYXRrset = 7 // YXRRSet - RR Set Exists when it should not [DNS Update]
+ RcodeNXRrset = 8 // NXRRSet - RR Set that should exist does not [DNS Update]
+ RcodeNotAuth = 9 // NotAuth - Server Not Authoritative for zone [DNS Update]
+ RcodeNotZone = 10 // NotZone - Name not contained in zone [DNS Update/TSIG]
+ RcodeBadSig = 16 // BADSIG - TSIG Signature Failure [TSIG]
+ RcodeBadVers = 16 // BADVERS - Bad OPT Version [EDNS0]
+ RcodeBadKey = 17 // BADKEY - Key not recognized [TSIG]
+ RcodeBadTime = 18 // BADTIME - Signature out of time window [TSIG]
+ RcodeBadMode = 19 // BADMODE - Bad TKEY Mode [TKEY]
+ RcodeBadName = 20 // BADNAME - Duplicate key name [TKEY]
+ RcodeBadAlg = 21 // BADALG - Algorithm not supported [TKEY]
+ RcodeBadTrunc = 22 // BADTRUNC - Bad Truncation [TSIG]
+ RcodeBadCookie = 23 // BADCOOKIE - Bad/missing Server Cookie [DNS Cookies]
+
+ // Message Opcodes. There is no 3.
+ OpcodeQuery = 0
+ OpcodeIQuery = 1
+ OpcodeStatus = 2
+ OpcodeNotify = 4
+ OpcodeUpdate = 5
+)
+
+// Used in ZONEMD https://tools.ietf.org/html/rfc8976
+const (
+ ZoneMDSchemeSimple = 1
+
+ ZoneMDHashAlgSHA384 = 1
+ ZoneMDHashAlgSHA512 = 2
+)
+
+// Header is the wire format for the DNS packet header.
+type Header struct {
+ Id uint16
+ Bits uint16
+ Qdcount, Ancount, Nscount, Arcount uint16
+}
+
+const (
+ headerSize = 12
+
+ // Header.Bits
+ _QR = 1 << 15 // query/response (response=1)
+ _AA = 1 << 10 // authoritative
+ _TC = 1 << 9 // truncated
+ _RD = 1 << 8 // recursion desired
+ _RA = 1 << 7 // recursion available
+ _Z = 1 << 6 // Z
+ _AD = 1 << 5 // authenticated data
+ _CD = 1 << 4 // checking disabled
+)
+
+// Various constants used in the LOC RR. See RFC 1887.
+const (
+ LOC_EQUATOR = 1 << 31 // RFC 1876, Section 2.
+ LOC_PRIMEMERIDIAN = 1 << 31 // RFC 1876, Section 2.
+ LOC_HOURS = 60 * 1000
+ LOC_DEGREES = 60 * LOC_HOURS
+ LOC_ALTITUDEBASE = 100000
+)
+
+// Different Certificate Types, see RFC 4398, Section 2.1
+const (
+ CertPKIX = 1 + iota
+ CertSPKI
+ CertPGP
+ CertIPIX
+ CertISPKI
+ CertIPGP
+ CertACPKIX
+ CertIACPKIX
+ CertURI = 253
+ CertOID = 254
+)
+
+// CertTypeToString converts the Cert Type to its string representation.
+// See RFC 4398 and RFC 6944.
+var CertTypeToString = map[uint16]string{
+ CertPKIX: "PKIX",
+ CertSPKI: "SPKI",
+ CertPGP: "PGP",
+ CertIPIX: "IPIX",
+ CertISPKI: "ISPKI",
+ CertIPGP: "IPGP",
+ CertACPKIX: "ACPKIX",
+ CertIACPKIX: "IACPKIX",
+ CertURI: "URI",
+ CertOID: "OID",
+}
+
+//go:generate go run types_generate.go
+
+// Question holds a DNS question. Usually there is just one. While the
+// original DNS RFCs allow multiple questions in the question section of a
+// message, in practice it never works. Because most DNS servers see multiple
+// questions as an error, it is recommended to only have one question per
+// message.
+type Question struct {
+ Name string `dns:"cdomain-name"` // "cdomain-name" specifies encoding (and may be compressed)
+ Qtype uint16
+ Qclass uint16
+}
+
+func (q *Question) len(off int, compression map[string]struct{}) int {
+ l := domainNameLen(q.Name, off, compression, true)
+ l += 2 + 2
+ return l
+}
+
+func (q *Question) String() (s string) {
+ // prefix with ; (as in dig)
+ s = ";" + sprintName(q.Name) + "\t"
+ s += Class(q.Qclass).String() + "\t"
+ s += " " + Type(q.Qtype).String()
+ return s
+}
+
+// ANY is a wild card record. See RFC 1035, Section 3.2.3. ANY
+// is named "*" there.
+type ANY struct {
+ Hdr RR_Header
+ // Does not have any rdata
+}
+
+func (rr *ANY) String() string { return rr.Hdr.String() }
+
+func (*ANY) parse(c *zlexer, origin string) *ParseError {
+ return &ParseError{err: "ANY records do not have a presentation format"}
+}
+
+// NULL RR. See RFC 1035.
+type NULL struct {
+ Hdr RR_Header
+ Data string `dns:"any"`
+}
+
+func (rr *NULL) String() string {
+ // There is no presentation format; prefix string with a comment.
+ return ";" + rr.Hdr.String() + rr.Data
+}
+
+func (*NULL) parse(c *zlexer, origin string) *ParseError {
+ return &ParseError{err: "NULL records do not have a presentation format"}
+}
+
+// CNAME RR. See RFC 1034.
+type CNAME struct {
+ Hdr RR_Header
+ Target string `dns:"cdomain-name"`
+}
+
+func (rr *CNAME) String() string { return rr.Hdr.String() + sprintName(rr.Target) }
+
+// HINFO RR. See RFC 1034.
+type HINFO struct {
+ Hdr RR_Header
+ Cpu string
+ Os string
+}
+
+func (rr *HINFO) String() string {
+ return rr.Hdr.String() + sprintTxt([]string{rr.Cpu, rr.Os})
+}
+
+// MB RR. See RFC 1035.
+type MB struct {
+ Hdr RR_Header
+ Mb string `dns:"cdomain-name"`
+}
+
+func (rr *MB) String() string { return rr.Hdr.String() + sprintName(rr.Mb) }
+
+// MG RR. See RFC 1035.
+type MG struct {
+ Hdr RR_Header
+ Mg string `dns:"cdomain-name"`
+}
+
+func (rr *MG) String() string { return rr.Hdr.String() + sprintName(rr.Mg) }
+
+// MINFO RR. See RFC 1035.
+type MINFO struct {
+ Hdr RR_Header
+ Rmail string `dns:"cdomain-name"`
+ Email string `dns:"cdomain-name"`
+}
+
+func (rr *MINFO) String() string {
+ return rr.Hdr.String() + sprintName(rr.Rmail) + " " + sprintName(rr.Email)
+}
+
+// MR RR. See RFC 1035.
+type MR struct {
+ Hdr RR_Header
+ Mr string `dns:"cdomain-name"`
+}
+
+func (rr *MR) String() string {
+ return rr.Hdr.String() + sprintName(rr.Mr)
+}
+
+// MF RR. See RFC 1035.
+type MF struct {
+ Hdr RR_Header
+ Mf string `dns:"cdomain-name"`
+}
+
+func (rr *MF) String() string {
+ return rr.Hdr.String() + sprintName(rr.Mf)
+}
+
+// MD RR. See RFC 1035.
+type MD struct {
+ Hdr RR_Header
+ Md string `dns:"cdomain-name"`
+}
+
+func (rr *MD) String() string {
+ return rr.Hdr.String() + sprintName(rr.Md)
+}
+
+// MX RR. See RFC 1035.
+type MX struct {
+ Hdr RR_Header
+ Preference uint16
+ Mx string `dns:"cdomain-name"`
+}
+
+func (rr *MX) String() string {
+ return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Mx)
+}
+
+// AFSDB RR. See RFC 1183.
+type AFSDB struct {
+ Hdr RR_Header
+ Subtype uint16
+ Hostname string `dns:"domain-name"`
+}
+
+func (rr *AFSDB) String() string {
+ return rr.Hdr.String() + strconv.Itoa(int(rr.Subtype)) + " " + sprintName(rr.Hostname)
+}
+
+// X25 RR. See RFC 1183, Section 3.1.
+type X25 struct {
+ Hdr RR_Header
+ PSDNAddress string
+}
+
+func (rr *X25) String() string {
+ return rr.Hdr.String() + rr.PSDNAddress
+}
+
+// RT RR. See RFC 1183, Section 3.3.
+type RT struct {
+ Hdr RR_Header
+ Preference uint16
+ Host string `dns:"domain-name"` // RFC 3597 prohibits compressing records not defined in RFC 1035.
+}
+
+func (rr *RT) String() string {
+ return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Host)
+}
+
+// NS RR. See RFC 1035.
+type NS struct {
+ Hdr RR_Header
+ Ns string `dns:"cdomain-name"`
+}
+
+func (rr *NS) String() string {
+ return rr.Hdr.String() + sprintName(rr.Ns)
+}
+
+// PTR RR. See RFC 1035.
+type PTR struct {
+ Hdr RR_Header
+ Ptr string `dns:"cdomain-name"`
+}
+
+func (rr *PTR) String() string {
+ return rr.Hdr.String() + sprintName(rr.Ptr)
+}
+
+// RP RR. See RFC 1138, Section 2.2.
+type RP struct {
+ Hdr RR_Header
+ Mbox string `dns:"domain-name"`
+ Txt string `dns:"domain-name"`
+}
+
+func (rr *RP) String() string {
+ return rr.Hdr.String() + sprintName(rr.Mbox) + " " + sprintName(rr.Txt)
+}
+
+// SOA RR. See RFC 1035.
+type SOA struct {
+ Hdr RR_Header
+ Ns string `dns:"cdomain-name"`
+ Mbox string `dns:"cdomain-name"`
+ Serial uint32
+ Refresh uint32
+ Retry uint32
+ Expire uint32
+ Minttl uint32
+}
+
+func (rr *SOA) String() string {
+ return rr.Hdr.String() + sprintName(rr.Ns) + " " + sprintName(rr.Mbox) +
+ " " + strconv.FormatInt(int64(rr.Serial), 10) +
+ " " + strconv.FormatInt(int64(rr.Refresh), 10) +
+ " " + strconv.FormatInt(int64(rr.Retry), 10) +
+ " " + strconv.FormatInt(int64(rr.Expire), 10) +
+ " " + strconv.FormatInt(int64(rr.Minttl), 10)
+}
+
+// TXT RR. See RFC 1035.
+type TXT struct {
+ Hdr RR_Header
+ Txt []string `dns:"txt"`
+}
+
+func (rr *TXT) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) }
+
+func sprintName(s string) string {
+ var dst strings.Builder
+
+ for i := 0; i < len(s); {
+ if s[i] == '.' {
+ if dst.Len() != 0 {
+ dst.WriteByte('.')
+ }
+ i++
+ continue
+ }
+
+ b, n := nextByte(s, i)
+ if n == 0 {
+ // Drop "dangling" incomplete escapes.
+ if dst.Len() == 0 {
+ return s[:i]
+ }
+ break
+ }
+ if isDomainNameLabelSpecial(b) {
+ if dst.Len() == 0 {
+ dst.Grow(len(s) * 2)
+ dst.WriteString(s[:i])
+ }
+ dst.WriteByte('\\')
+ dst.WriteByte(b)
+ } else if b < ' ' || b > '~' { // unprintable, use \DDD
+ if dst.Len() == 0 {
+ dst.Grow(len(s) * 2)
+ dst.WriteString(s[:i])
+ }
+ dst.WriteString(escapeByte(b))
+ } else {
+ if dst.Len() != 0 {
+ dst.WriteByte(b)
+ }
+ }
+ i += n
+ }
+ if dst.Len() == 0 {
+ return s
+ }
+ return dst.String()
+}
+
+func sprintTxtOctet(s string) string {
+ var dst strings.Builder
+ dst.Grow(2 + len(s))
+ dst.WriteByte('"')
+ for i := 0; i < len(s); {
+ if i+1 < len(s) && s[i] == '\\' && s[i+1] == '.' {
+ dst.WriteString(s[i : i+2])
+ i += 2
+ continue
+ }
+
+ b, n := nextByte(s, i)
+ if n == 0 {
+ i++ // dangling back slash
+ } else {
+ writeTXTStringByte(&dst, b)
+ }
+ i += n
+ }
+ dst.WriteByte('"')
+ return dst.String()
+}
+
+func sprintTxt(txt []string) string {
+ var out strings.Builder
+ for i, s := range txt {
+ out.Grow(3 + len(s))
+ if i > 0 {
+ out.WriteString(` "`)
+ } else {
+ out.WriteByte('"')
+ }
+ for j := 0; j < len(s); {
+ b, n := nextByte(s, j)
+ if n == 0 {
+ break
+ }
+ writeTXTStringByte(&out, b)
+ j += n
+ }
+ out.WriteByte('"')
+ }
+ return out.String()
+}
+
+func writeTXTStringByte(s *strings.Builder, b byte) {
+ switch {
+ case b == '"' || b == '\\':
+ s.WriteByte('\\')
+ s.WriteByte(b)
+ case b < ' ' || b > '~':
+ s.WriteString(escapeByte(b))
+ default:
+ s.WriteByte(b)
+ }
+}
+
+const (
+ escapedByteSmall = "" +
+ `\000\001\002\003\004\005\006\007\008\009` +
+ `\010\011\012\013\014\015\016\017\018\019` +
+ `\020\021\022\023\024\025\026\027\028\029` +
+ `\030\031`
+ escapedByteLarge = `\127\128\129` +
+ `\130\131\132\133\134\135\136\137\138\139` +
+ `\140\141\142\143\144\145\146\147\148\149` +
+ `\150\151\152\153\154\155\156\157\158\159` +
+ `\160\161\162\163\164\165\166\167\168\169` +
+ `\170\171\172\173\174\175\176\177\178\179` +
+ `\180\181\182\183\184\185\186\187\188\189` +
+ `\190\191\192\193\194\195\196\197\198\199` +
+ `\200\201\202\203\204\205\206\207\208\209` +
+ `\210\211\212\213\214\215\216\217\218\219` +
+ `\220\221\222\223\224\225\226\227\228\229` +
+ `\230\231\232\233\234\235\236\237\238\239` +
+ `\240\241\242\243\244\245\246\247\248\249` +
+ `\250\251\252\253\254\255`
+)
+
+// escapeByte returns the \DDD escaping of b which must
+// satisfy b < ' ' || b > '~'.
+func escapeByte(b byte) string {
+ if b < ' ' {
+ return escapedByteSmall[b*4 : b*4+4]
+ }
+
+ b -= '~' + 1
+ // The cast here is needed as b*4 may overflow byte.
+ return escapedByteLarge[int(b)*4 : int(b)*4+4]
+}
+
+// isDomainNameLabelSpecial returns true if
+// a domain name label byte should be prefixed
+// with an escaping backslash.
+func isDomainNameLabelSpecial(b byte) bool {
+ switch b {
+ case '.', ' ', '\'', '@', ';', '(', ')', '"', '\\':
+ return true
+ }
+ return false
+}
+
+func nextByte(s string, offset int) (byte, int) {
+ if offset >= len(s) {
+ return 0, 0
+ }
+ if s[offset] != '\\' {
+ // not an escape sequence
+ return s[offset], 1
+ }
+ switch len(s) - offset {
+ case 1: // dangling escape
+ return 0, 0
+ case 2, 3: // too short to be \ddd
+ default: // maybe \ddd
+ if isDigit(s[offset+1]) && isDigit(s[offset+2]) && isDigit(s[offset+3]) {
+ return dddStringToByte(s[offset+1:]), 4
+ }
+ }
+ // not \ddd, just an RFC 1035 "quoted" character
+ return s[offset+1], 2
+}
+
+// SPF RR. See RFC 4408, Section 3.1.1.
+type SPF struct {
+ Hdr RR_Header
+ Txt []string `dns:"txt"`
+}
+
+func (rr *SPF) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) }
+
+// AVC RR. See https://www.iana.org/assignments/dns-parameters/AVC/avc-completed-template.
+type AVC struct {
+ Hdr RR_Header
+ Txt []string `dns:"txt"`
+}
+
+func (rr *AVC) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) }
+
+// SRV RR. See RFC 2782.
+type SRV struct {
+ Hdr RR_Header
+ Priority uint16
+ Weight uint16
+ Port uint16
+ Target string `dns:"domain-name"`
+}
+
+func (rr *SRV) String() string {
+ return rr.Hdr.String() +
+ strconv.Itoa(int(rr.Priority)) + " " +
+ strconv.Itoa(int(rr.Weight)) + " " +
+ strconv.Itoa(int(rr.Port)) + " " + sprintName(rr.Target)
+}
+
+// NAPTR RR. See RFC 2915.
+type NAPTR struct {
+ Hdr RR_Header
+ Order uint16
+ Preference uint16
+ Flags string
+ Service string
+ Regexp string
+ Replacement string `dns:"domain-name"`
+}
+
+func (rr *NAPTR) String() string {
+ return rr.Hdr.String() +
+ strconv.Itoa(int(rr.Order)) + " " +
+ strconv.Itoa(int(rr.Preference)) + " " +
+ "\"" + rr.Flags + "\" " +
+ "\"" + rr.Service + "\" " +
+ "\"" + rr.Regexp + "\" " +
+ rr.Replacement
+}
+
+// CERT RR. See RFC 4398.
+type CERT struct {
+ Hdr RR_Header
+ Type uint16
+ KeyTag uint16
+ Algorithm uint8
+ Certificate string `dns:"base64"`
+}
+
+func (rr *CERT) String() string {
+ var (
+ ok bool
+ certtype, algorithm string
+ )
+ if certtype, ok = CertTypeToString[rr.Type]; !ok {
+ certtype = strconv.Itoa(int(rr.Type))
+ }
+ if algorithm, ok = AlgorithmToString[rr.Algorithm]; !ok {
+ algorithm = strconv.Itoa(int(rr.Algorithm))
+ }
+ return rr.Hdr.String() + certtype +
+ " " + strconv.Itoa(int(rr.KeyTag)) +
+ " " + algorithm +
+ " " + rr.Certificate
+}
+
+// DNAME RR. See RFC 2672.
+type DNAME struct {
+ Hdr RR_Header
+ Target string `dns:"domain-name"`
+}
+
+func (rr *DNAME) String() string {
+ return rr.Hdr.String() + sprintName(rr.Target)
+}
+
+// A RR. See RFC 1035.
+type A struct {
+ Hdr RR_Header
+ A net.IP `dns:"a"`
+}
+
+func (rr *A) String() string {
+ if rr.A == nil {
+ return rr.Hdr.String()
+ }
+ return rr.Hdr.String() + rr.A.String()
+}
+
+// AAAA RR. See RFC 3596.
+type AAAA struct {
+ Hdr RR_Header
+ AAAA net.IP `dns:"aaaa"`
+}
+
+func (rr *AAAA) String() string {
+ if rr.AAAA == nil {
+ return rr.Hdr.String()
+ }
+ return rr.Hdr.String() + rr.AAAA.String()
+}
+
+// PX RR. See RFC 2163.
+type PX struct {
+ Hdr RR_Header
+ Preference uint16
+ Map822 string `dns:"domain-name"`
+ Mapx400 string `dns:"domain-name"`
+}
+
+func (rr *PX) String() string {
+ return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Map822) + " " + sprintName(rr.Mapx400)
+}
+
+// GPOS RR. See RFC 1712.
+type GPOS struct {
+ Hdr RR_Header
+ Longitude string
+ Latitude string
+ Altitude string
+}
+
+func (rr *GPOS) String() string {
+ return rr.Hdr.String() + rr.Longitude + " " + rr.Latitude + " " + rr.Altitude
+}
+
+// LOC RR. See RFC RFC 1876.
+type LOC struct {
+ Hdr RR_Header
+ Version uint8
+ Size uint8
+ HorizPre uint8
+ VertPre uint8
+ Latitude uint32
+ Longitude uint32
+ Altitude uint32
+}
+
+// cmToM takes a cm value expressed in RFC 1876 SIZE mantissa/exponent
+// format and returns a string in m (two decimals for the cm).
+func cmToM(m, e uint8) string {
+ if e < 2 {
+ if e == 1 {
+ m *= 10
+ }
+
+ return fmt.Sprintf("0.%02d", m)
+ }
+
+ s := fmt.Sprintf("%d", m)
+ for e > 2 {
+ s += "0"
+ e--
+ }
+ return s
+}
+
+func (rr *LOC) String() string {
+ s := rr.Hdr.String()
+
+ lat := rr.Latitude
+ ns := "N"
+ if lat > LOC_EQUATOR {
+ lat = lat - LOC_EQUATOR
+ } else {
+ ns = "S"
+ lat = LOC_EQUATOR - lat
+ }
+ h := lat / LOC_DEGREES
+ lat = lat % LOC_DEGREES
+ m := lat / LOC_HOURS
+ lat = lat % LOC_HOURS
+ s += fmt.Sprintf("%02d %02d %0.3f %s ", h, m, float64(lat)/1000, ns)
+
+ lon := rr.Longitude
+ ew := "E"
+ if lon > LOC_PRIMEMERIDIAN {
+ lon = lon - LOC_PRIMEMERIDIAN
+ } else {
+ ew = "W"
+ lon = LOC_PRIMEMERIDIAN - lon
+ }
+ h = lon / LOC_DEGREES
+ lon = lon % LOC_DEGREES
+ m = lon / LOC_HOURS
+ lon = lon % LOC_HOURS
+ s += fmt.Sprintf("%02d %02d %0.3f %s ", h, m, float64(lon)/1000, ew)
+
+ var alt = float64(rr.Altitude) / 100
+ alt -= LOC_ALTITUDEBASE
+ if rr.Altitude%100 != 0 {
+ s += fmt.Sprintf("%.2fm ", alt)
+ } else {
+ s += fmt.Sprintf("%.0fm ", alt)
+ }
+
+ s += cmToM(rr.Size&0xf0>>4, rr.Size&0x0f) + "m "
+ s += cmToM(rr.HorizPre&0xf0>>4, rr.HorizPre&0x0f) + "m "
+ s += cmToM(rr.VertPre&0xf0>>4, rr.VertPre&0x0f) + "m"
+
+ return s
+}
+
+// SIG RR. See RFC 2535. The SIG RR is identical to RRSIG and nowadays only used for SIG(0), See RFC 2931.
+type SIG struct {
+ RRSIG
+}
+
+// RRSIG RR. See RFC 4034 and RFC 3755.
+type RRSIG struct {
+ Hdr RR_Header
+ TypeCovered uint16
+ Algorithm uint8
+ Labels uint8
+ OrigTtl uint32
+ Expiration uint32
+ Inception uint32
+ KeyTag uint16
+ SignerName string `dns:"domain-name"`
+ Signature string `dns:"base64"`
+}
+
+func (rr *RRSIG) String() string {
+ s := rr.Hdr.String()
+ s += Type(rr.TypeCovered).String()
+ s += " " + strconv.Itoa(int(rr.Algorithm)) +
+ " " + strconv.Itoa(int(rr.Labels)) +
+ " " + strconv.FormatInt(int64(rr.OrigTtl), 10) +
+ " " + TimeToString(rr.Expiration) +
+ " " + TimeToString(rr.Inception) +
+ " " + strconv.Itoa(int(rr.KeyTag)) +
+ " " + sprintName(rr.SignerName) +
+ " " + rr.Signature
+ return s
+}
+
+// NSEC RR. See RFC 4034 and RFC 3755.
+type NSEC struct {
+ Hdr RR_Header
+ NextDomain string `dns:"domain-name"`
+ TypeBitMap []uint16 `dns:"nsec"`
+}
+
+func (rr *NSEC) String() string {
+ s := rr.Hdr.String() + sprintName(rr.NextDomain)
+ for _, t := range rr.TypeBitMap {
+ s += " " + Type(t).String()
+ }
+ return s
+}
+
+func (rr *NSEC) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += domainNameLen(rr.NextDomain, off+l, compression, false)
+ l += typeBitMapLen(rr.TypeBitMap)
+ return l
+}
+
+// DLV RR. See RFC 4431.
+type DLV struct{ DS }
+
+// CDS RR. See RFC 7344.
+type CDS struct{ DS }
+
+// DS RR. See RFC 4034 and RFC 3658.
+type DS struct {
+ Hdr RR_Header
+ KeyTag uint16
+ Algorithm uint8
+ DigestType uint8
+ Digest string `dns:"hex"`
+}
+
+func (rr *DS) String() string {
+ return rr.Hdr.String() + strconv.Itoa(int(rr.KeyTag)) +
+ " " + strconv.Itoa(int(rr.Algorithm)) +
+ " " + strconv.Itoa(int(rr.DigestType)) +
+ " " + strings.ToUpper(rr.Digest)
+}
+
+// KX RR. See RFC 2230.
+type KX struct {
+ Hdr RR_Header
+ Preference uint16
+ Exchanger string `dns:"domain-name"`
+}
+
+func (rr *KX) String() string {
+ return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) +
+ " " + sprintName(rr.Exchanger)
+}
+
+// TA RR. See http://www.watson.org/~weiler/INI1999-19.pdf.
+type TA struct {
+ Hdr RR_Header
+ KeyTag uint16
+ Algorithm uint8
+ DigestType uint8
+ Digest string `dns:"hex"`
+}
+
+func (rr *TA) String() string {
+ return rr.Hdr.String() + strconv.Itoa(int(rr.KeyTag)) +
+ " " + strconv.Itoa(int(rr.Algorithm)) +
+ " " + strconv.Itoa(int(rr.DigestType)) +
+ " " + strings.ToUpper(rr.Digest)
+}
+
+// TALINK RR. See https://www.iana.org/assignments/dns-parameters/TALINK/talink-completed-template.
+type TALINK struct {
+ Hdr RR_Header
+ PreviousName string `dns:"domain-name"`
+ NextName string `dns:"domain-name"`
+}
+
+func (rr *TALINK) String() string {
+ return rr.Hdr.String() +
+ sprintName(rr.PreviousName) + " " + sprintName(rr.NextName)
+}
+
+// SSHFP RR. See RFC RFC 4255.
+type SSHFP struct {
+ Hdr RR_Header
+ Algorithm uint8
+ Type uint8
+ FingerPrint string `dns:"hex"`
+}
+
+func (rr *SSHFP) String() string {
+ return rr.Hdr.String() + strconv.Itoa(int(rr.Algorithm)) +
+ " " + strconv.Itoa(int(rr.Type)) +
+ " " + strings.ToUpper(rr.FingerPrint)
+}
+
+// KEY RR. See RFC RFC 2535.
+type KEY struct {
+ DNSKEY
+}
+
+// CDNSKEY RR. See RFC 7344.
+type CDNSKEY struct {
+ DNSKEY
+}
+
+// DNSKEY RR. See RFC 4034 and RFC 3755.
+type DNSKEY struct {
+ Hdr RR_Header
+ Flags uint16
+ Protocol uint8
+ Algorithm uint8
+ PublicKey string `dns:"base64"`
+}
+
+func (rr *DNSKEY) String() string {
+ return rr.Hdr.String() + strconv.Itoa(int(rr.Flags)) +
+ " " + strconv.Itoa(int(rr.Protocol)) +
+ " " + strconv.Itoa(int(rr.Algorithm)) +
+ " " + rr.PublicKey
+}
+
+// RKEY RR. See https://www.iana.org/assignments/dns-parameters/RKEY/rkey-completed-template.
+type RKEY struct {
+ Hdr RR_Header
+ Flags uint16
+ Protocol uint8
+ Algorithm uint8
+ PublicKey string `dns:"base64"`
+}
+
+func (rr *RKEY) String() string {
+ return rr.Hdr.String() + strconv.Itoa(int(rr.Flags)) +
+ " " + strconv.Itoa(int(rr.Protocol)) +
+ " " + strconv.Itoa(int(rr.Algorithm)) +
+ " " + rr.PublicKey
+}
+
+// NSAPPTR RR. See RFC 1348.
+type NSAPPTR struct {
+ Hdr RR_Header
+ Ptr string `dns:"domain-name"`
+}
+
+func (rr *NSAPPTR) String() string { return rr.Hdr.String() + sprintName(rr.Ptr) }
+
+// NSEC3 RR. See RFC 5155.
+type NSEC3 struct {
+ Hdr RR_Header
+ Hash uint8
+ Flags uint8
+ Iterations uint16
+ SaltLength uint8
+ Salt string `dns:"size-hex:SaltLength"`
+ HashLength uint8
+ NextDomain string `dns:"size-base32:HashLength"`
+ TypeBitMap []uint16 `dns:"nsec"`
+}
+
+func (rr *NSEC3) String() string {
+ s := rr.Hdr.String()
+ s += strconv.Itoa(int(rr.Hash)) +
+ " " + strconv.Itoa(int(rr.Flags)) +
+ " " + strconv.Itoa(int(rr.Iterations)) +
+ " " + saltToString(rr.Salt) +
+ " " + rr.NextDomain
+ for _, t := range rr.TypeBitMap {
+ s += " " + Type(t).String()
+ }
+ return s
+}
+
+func (rr *NSEC3) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 6 + len(rr.Salt)/2 + 1 + len(rr.NextDomain) + 1
+ l += typeBitMapLen(rr.TypeBitMap)
+ return l
+}
+
+// NSEC3PARAM RR. See RFC 5155.
+type NSEC3PARAM struct {
+ Hdr RR_Header
+ Hash uint8
+ Flags uint8
+ Iterations uint16
+ SaltLength uint8
+ Salt string `dns:"size-hex:SaltLength"`
+}
+
+func (rr *NSEC3PARAM) String() string {
+ s := rr.Hdr.String()
+ s += strconv.Itoa(int(rr.Hash)) +
+ " " + strconv.Itoa(int(rr.Flags)) +
+ " " + strconv.Itoa(int(rr.Iterations)) +
+ " " + saltToString(rr.Salt)
+ return s
+}
+
+// TKEY RR. See RFC 2930.
+type TKEY struct {
+ Hdr RR_Header
+ Algorithm string `dns:"domain-name"`
+ Inception uint32
+ Expiration uint32
+ Mode uint16
+ Error uint16
+ KeySize uint16
+ Key string `dns:"size-hex:KeySize"`
+ OtherLen uint16
+ OtherData string `dns:"size-hex:OtherLen"`
+}
+
+// TKEY has no official presentation format, but this will suffice.
+func (rr *TKEY) String() string {
+ s := ";" + rr.Hdr.String() +
+ " " + rr.Algorithm +
+ " " + TimeToString(rr.Inception) +
+ " " + TimeToString(rr.Expiration) +
+ " " + strconv.Itoa(int(rr.Mode)) +
+ " " + strconv.Itoa(int(rr.Error)) +
+ " " + strconv.Itoa(int(rr.KeySize)) +
+ " " + rr.Key +
+ " " + strconv.Itoa(int(rr.OtherLen)) +
+ " " + rr.OtherData
+ return s
+}
+
+// RFC3597 represents an unknown/generic RR. See RFC 3597.
+type RFC3597 struct {
+ Hdr RR_Header
+ Rdata string `dns:"hex"`
+}
+
+func (rr *RFC3597) String() string {
+ // Let's call it a hack
+ s := rfc3597Header(rr.Hdr)
+
+ s += "\\# " + strconv.Itoa(len(rr.Rdata)/2) + " " + rr.Rdata
+ return s
+}
+
+func rfc3597Header(h RR_Header) string {
+ var s string
+
+ s += sprintName(h.Name) + "\t"
+ s += strconv.FormatInt(int64(h.Ttl), 10) + "\t"
+ s += "CLASS" + strconv.Itoa(int(h.Class)) + "\t"
+ s += "TYPE" + strconv.Itoa(int(h.Rrtype)) + "\t"
+ return s
+}
+
+// URI RR. See RFC 7553.
+type URI struct {
+ Hdr RR_Header
+ Priority uint16
+ Weight uint16
+ Target string `dns:"octet"`
+}
+
+// rr.Target to be parsed as a sequence of character encoded octets according to RFC 3986
+func (rr *URI) String() string {
+ return rr.Hdr.String() + strconv.Itoa(int(rr.Priority)) +
+ " " + strconv.Itoa(int(rr.Weight)) + " " + sprintTxtOctet(rr.Target)
+}
+
+// DHCID RR. See RFC 4701.
+type DHCID struct {
+ Hdr RR_Header
+ Digest string `dns:"base64"`
+}
+
+func (rr *DHCID) String() string { return rr.Hdr.String() + rr.Digest }
+
+// TLSA RR. See RFC 6698.
+type TLSA struct {
+ Hdr RR_Header
+ Usage uint8
+ Selector uint8
+ MatchingType uint8
+ Certificate string `dns:"hex"`
+}
+
+func (rr *TLSA) String() string {
+ return rr.Hdr.String() +
+ strconv.Itoa(int(rr.Usage)) +
+ " " + strconv.Itoa(int(rr.Selector)) +
+ " " + strconv.Itoa(int(rr.MatchingType)) +
+ " " + rr.Certificate
+}
+
+// SMIMEA RR. See RFC 8162.
+type SMIMEA struct {
+ Hdr RR_Header
+ Usage uint8
+ Selector uint8
+ MatchingType uint8
+ Certificate string `dns:"hex"`
+}
+
+func (rr *SMIMEA) String() string {
+ s := rr.Hdr.String() +
+ strconv.Itoa(int(rr.Usage)) +
+ " " + strconv.Itoa(int(rr.Selector)) +
+ " " + strconv.Itoa(int(rr.MatchingType))
+
+ // Every Nth char needs a space on this output. If we output
+ // this as one giant line, we can't read it can in because in some cases
+ // the cert length overflows scan.maxTok (2048).
+ sx := splitN(rr.Certificate, 1024) // conservative value here
+ s += " " + strings.Join(sx, " ")
+ return s
+}
+
+// HIP RR. See RFC 8005.
+type HIP struct {
+ Hdr RR_Header
+ HitLength uint8
+ PublicKeyAlgorithm uint8
+ PublicKeyLength uint16
+ Hit string `dns:"size-hex:HitLength"`
+ PublicKey string `dns:"size-base64:PublicKeyLength"`
+ RendezvousServers []string `dns:"domain-name"`
+}
+
+func (rr *HIP) String() string {
+ s := rr.Hdr.String() +
+ strconv.Itoa(int(rr.PublicKeyAlgorithm)) +
+ " " + rr.Hit +
+ " " + rr.PublicKey
+ for _, d := range rr.RendezvousServers {
+ s += " " + sprintName(d)
+ }
+ return s
+}
+
+// NINFO RR. See https://www.iana.org/assignments/dns-parameters/NINFO/ninfo-completed-template.
+type NINFO struct {
+ Hdr RR_Header
+ ZSData []string `dns:"txt"`
+}
+
+func (rr *NINFO) String() string { return rr.Hdr.String() + sprintTxt(rr.ZSData) }
+
+// NID RR. See RFC RFC 6742.
+type NID struct {
+ Hdr RR_Header
+ Preference uint16
+ NodeID uint64
+}
+
+func (rr *NID) String() string {
+ s := rr.Hdr.String() + strconv.Itoa(int(rr.Preference))
+ node := fmt.Sprintf("%0.16x", rr.NodeID)
+ s += " " + node[0:4] + ":" + node[4:8] + ":" + node[8:12] + ":" + node[12:16]
+ return s
+}
+
+// L32 RR, See RFC 6742.
+type L32 struct {
+ Hdr RR_Header
+ Preference uint16
+ Locator32 net.IP `dns:"a"`
+}
+
+func (rr *L32) String() string {
+ if rr.Locator32 == nil {
+ return rr.Hdr.String() + strconv.Itoa(int(rr.Preference))
+ }
+ return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) +
+ " " + rr.Locator32.String()
+}
+
+// L64 RR, See RFC 6742.
+type L64 struct {
+ Hdr RR_Header
+ Preference uint16
+ Locator64 uint64
+}
+
+func (rr *L64) String() string {
+ s := rr.Hdr.String() + strconv.Itoa(int(rr.Preference))
+ node := fmt.Sprintf("%0.16X", rr.Locator64)
+ s += " " + node[0:4] + ":" + node[4:8] + ":" + node[8:12] + ":" + node[12:16]
+ return s
+}
+
+// LP RR. See RFC 6742.
+type LP struct {
+ Hdr RR_Header
+ Preference uint16
+ Fqdn string `dns:"domain-name"`
+}
+
+func (rr *LP) String() string {
+ return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Fqdn)
+}
+
+// EUI48 RR. See RFC 7043.
+type EUI48 struct {
+ Hdr RR_Header
+ Address uint64 `dns:"uint48"`
+}
+
+func (rr *EUI48) String() string { return rr.Hdr.String() + euiToString(rr.Address, 48) }
+
+// EUI64 RR. See RFC 7043.
+type EUI64 struct {
+ Hdr RR_Header
+ Address uint64
+}
+
+func (rr *EUI64) String() string { return rr.Hdr.String() + euiToString(rr.Address, 64) }
+
+// CAA RR. See RFC 6844.
+type CAA struct {
+ Hdr RR_Header
+ Flag uint8
+ Tag string
+ Value string `dns:"octet"`
+}
+
+// rr.Value Is the character-string encoding of the value field as specified in RFC 1035, Section 5.1.
+func (rr *CAA) String() string {
+ return rr.Hdr.String() + strconv.Itoa(int(rr.Flag)) + " " + rr.Tag + " " + sprintTxtOctet(rr.Value)
+}
+
+// UID RR. Deprecated, IANA-Reserved.
+type UID struct {
+ Hdr RR_Header
+ Uid uint32
+}
+
+func (rr *UID) String() string { return rr.Hdr.String() + strconv.FormatInt(int64(rr.Uid), 10) }
+
+// GID RR. Deprecated, IANA-Reserved.
+type GID struct {
+ Hdr RR_Header
+ Gid uint32
+}
+
+func (rr *GID) String() string { return rr.Hdr.String() + strconv.FormatInt(int64(rr.Gid), 10) }
+
+// UINFO RR. Deprecated, IANA-Reserved.
+type UINFO struct {
+ Hdr RR_Header
+ Uinfo string
+}
+
+func (rr *UINFO) String() string { return rr.Hdr.String() + sprintTxt([]string{rr.Uinfo}) }
+
+// EID RR. See http://ana-3.lcs.mit.edu/~jnc/nimrod/dns.txt.
+type EID struct {
+ Hdr RR_Header
+ Endpoint string `dns:"hex"`
+}
+
+func (rr *EID) String() string { return rr.Hdr.String() + strings.ToUpper(rr.Endpoint) }
+
+// NIMLOC RR. See http://ana-3.lcs.mit.edu/~jnc/nimrod/dns.txt.
+type NIMLOC struct {
+ Hdr RR_Header
+ Locator string `dns:"hex"`
+}
+
+func (rr *NIMLOC) String() string { return rr.Hdr.String() + strings.ToUpper(rr.Locator) }
+
+// OPENPGPKEY RR. See RFC 7929.
+type OPENPGPKEY struct {
+ Hdr RR_Header
+ PublicKey string `dns:"base64"`
+}
+
+func (rr *OPENPGPKEY) String() string { return rr.Hdr.String() + rr.PublicKey }
+
+// CSYNC RR. See RFC 7477.
+type CSYNC struct {
+ Hdr RR_Header
+ Serial uint32
+ Flags uint16
+ TypeBitMap []uint16 `dns:"nsec"`
+}
+
+func (rr *CSYNC) String() string {
+ s := rr.Hdr.String() + strconv.FormatInt(int64(rr.Serial), 10) + " " + strconv.Itoa(int(rr.Flags))
+
+ for _, t := range rr.TypeBitMap {
+ s += " " + Type(t).String()
+ }
+ return s
+}
+
+func (rr *CSYNC) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 4 + 2
+ l += typeBitMapLen(rr.TypeBitMap)
+ return l
+}
+
+// ZONEMD RR, from draft-ietf-dnsop-dns-zone-digest
+type ZONEMD struct {
+ Hdr RR_Header
+ Serial uint32
+ Scheme uint8
+ Hash uint8
+ Digest string `dns:"hex"`
+}
+
+func (rr *ZONEMD) String() string {
+ return rr.Hdr.String() +
+ strconv.Itoa(int(rr.Serial)) +
+ " " + strconv.Itoa(int(rr.Scheme)) +
+ " " + strconv.Itoa(int(rr.Hash)) +
+ " " + rr.Digest
+}
+
+// APL RR. See RFC 3123.
+type APL struct {
+ Hdr RR_Header
+ Prefixes []APLPrefix `dns:"apl"`
+}
+
+// APLPrefix is an address prefix hold by an APL record.
+type APLPrefix struct {
+ Negation bool
+ Network net.IPNet
+}
+
+// String returns presentation form of the APL record.
+func (rr *APL) String() string {
+ var sb strings.Builder
+ sb.WriteString(rr.Hdr.String())
+ for i, p := range rr.Prefixes {
+ if i > 0 {
+ sb.WriteByte(' ')
+ }
+ sb.WriteString(p.str())
+ }
+ return sb.String()
+}
+
+// str returns presentation form of the APL prefix.
+func (a *APLPrefix) str() string {
+ var sb strings.Builder
+ if a.Negation {
+ sb.WriteByte('!')
+ }
+
+ switch len(a.Network.IP) {
+ case net.IPv4len:
+ sb.WriteByte('1')
+ case net.IPv6len:
+ sb.WriteByte('2')
+ }
+
+ sb.WriteByte(':')
+
+ switch len(a.Network.IP) {
+ case net.IPv4len:
+ sb.WriteString(a.Network.IP.String())
+ case net.IPv6len:
+ // add prefix for IPv4-mapped IPv6
+ if v4 := a.Network.IP.To4(); v4 != nil {
+ sb.WriteString("::ffff:")
+ }
+ sb.WriteString(a.Network.IP.String())
+ }
+
+ sb.WriteByte('/')
+
+ prefix, _ := a.Network.Mask.Size()
+ sb.WriteString(strconv.Itoa(prefix))
+
+ return sb.String()
+}
+
+// equals reports whether two APL prefixes are identical.
+func (a *APLPrefix) equals(b *APLPrefix) bool {
+ return a.Negation == b.Negation &&
+ bytes.Equal(a.Network.IP, b.Network.IP) &&
+ bytes.Equal(a.Network.Mask, b.Network.Mask)
+}
+
+// copy returns a copy of the APL prefix.
+func (a *APLPrefix) copy() APLPrefix {
+ return APLPrefix{
+ Negation: a.Negation,
+ Network: copyNet(a.Network),
+ }
+}
+
+// len returns size of the prefix in wire format.
+func (a *APLPrefix) len() int {
+ // 4-byte header and the network address prefix (see Section 4 of RFC 3123)
+ prefix, _ := a.Network.Mask.Size()
+ return 4 + (prefix+7)/8
+}
+
+// TimeToString translates the RRSIG's incep. and expir. times to the
+// string representation used when printing the record.
+// It takes serial arithmetic (RFC 1982) into account.
+func TimeToString(t uint32) string {
+ mod := (int64(t)-time.Now().Unix())/year68 - 1
+ if mod < 0 {
+ mod = 0
+ }
+ ti := time.Unix(int64(t)-mod*year68, 0).UTC()
+ return ti.Format("20060102150405")
+}
+
+// StringToTime translates the RRSIG's incep. and expir. times from
+// string values like "20110403154150" to an 32 bit integer.
+// It takes serial arithmetic (RFC 1982) into account.
+func StringToTime(s string) (uint32, error) {
+ t, err := time.Parse("20060102150405", s)
+ if err != nil {
+ return 0, err
+ }
+ mod := t.Unix()/year68 - 1
+ if mod < 0 {
+ mod = 0
+ }
+ return uint32(t.Unix() - mod*year68), nil
+}
+
+// saltToString converts a NSECX salt to uppercase and returns "-" when it is empty.
+func saltToString(s string) string {
+ if s == "" {
+ return "-"
+ }
+ return strings.ToUpper(s)
+}
+
+func euiToString(eui uint64, bits int) (hex string) {
+ switch bits {
+ case 64:
+ hex = fmt.Sprintf("%16.16x", eui)
+ hex = hex[0:2] + "-" + hex[2:4] + "-" + hex[4:6] + "-" + hex[6:8] +
+ "-" + hex[8:10] + "-" + hex[10:12] + "-" + hex[12:14] + "-" + hex[14:16]
+ case 48:
+ hex = fmt.Sprintf("%12.12x", eui)
+ hex = hex[0:2] + "-" + hex[2:4] + "-" + hex[4:6] + "-" + hex[6:8] +
+ "-" + hex[8:10] + "-" + hex[10:12]
+ }
+ return
+}
+
+// copyIP returns a copy of ip.
+func copyIP(ip net.IP) net.IP {
+ p := make(net.IP, len(ip))
+ copy(p, ip)
+ return p
+}
+
+// copyNet returns a copy of a subnet.
+func copyNet(n net.IPNet) net.IPNet {
+ m := make(net.IPMask, len(n.Mask))
+ copy(m, n.Mask)
+
+ return net.IPNet{
+ IP: copyIP(n.IP),
+ Mask: m,
+ }
+}
+
+// SplitN splits a string into N sized string chunks.
+// This might become an exported function once.
+func splitN(s string, n int) []string {
+ if len(s) < n {
+ return []string{s}
+ }
+ sx := []string{}
+ p, i := 0, n
+ for {
+ if i <= len(s) {
+ sx = append(sx, s[p:i])
+ } else {
+ sx = append(sx, s[p:])
+ break
+
+ }
+ p, i = p+n, i+n
+ }
+
+ return sx
+}
diff --git a/vendor/github.com/miekg/dns/udp.go b/vendor/github.com/miekg/dns/udp.go
@@ -0,0 +1,102 @@
+// +build !windows
+
+package dns
+
+import (
+ "net"
+
+ "golang.org/x/net/ipv4"
+ "golang.org/x/net/ipv6"
+)
+
+// This is the required size of the OOB buffer to pass to ReadMsgUDP.
+var udpOOBSize = func() int {
+ // We can't know whether we'll get an IPv4 control message or an
+ // IPv6 control message ahead of time. To get around this, we size
+ // the buffer equal to the largest of the two.
+
+ oob4 := ipv4.NewControlMessage(ipv4.FlagDst | ipv4.FlagInterface)
+ oob6 := ipv6.NewControlMessage(ipv6.FlagDst | ipv6.FlagInterface)
+
+ if len(oob4) > len(oob6) {
+ return len(oob4)
+ }
+
+ return len(oob6)
+}()
+
+// SessionUDP holds the remote address and the associated
+// out-of-band data.
+type SessionUDP struct {
+ raddr *net.UDPAddr
+ context []byte
+}
+
+// RemoteAddr returns the remote network address.
+func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr }
+
+// ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a
+// net.UDPAddr.
+func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {
+ oob := make([]byte, udpOOBSize)
+ n, oobn, _, raddr, err := conn.ReadMsgUDP(b, oob)
+ if err != nil {
+ return n, nil, err
+ }
+ return n, &SessionUDP{raddr, oob[:oobn]}, err
+}
+
+// WriteToSessionUDP acts just like net.UDPConn.WriteTo(), but uses a *SessionUDP instead of a net.Addr.
+func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) {
+ oob := correctSource(session.context)
+ n, _, err := conn.WriteMsgUDP(b, oob, session.raddr)
+ return n, err
+}
+
+func setUDPSocketOptions(conn *net.UDPConn) error {
+ // Try setting the flags for both families and ignore the errors unless they
+ // both error.
+ err6 := ipv6.NewPacketConn(conn).SetControlMessage(ipv6.FlagDst|ipv6.FlagInterface, true)
+ err4 := ipv4.NewPacketConn(conn).SetControlMessage(ipv4.FlagDst|ipv4.FlagInterface, true)
+ if err6 != nil && err4 != nil {
+ return err4
+ }
+ return nil
+}
+
+// parseDstFromOOB takes oob data and returns the destination IP.
+func parseDstFromOOB(oob []byte) net.IP {
+ // Start with IPv6 and then fallback to IPv4
+ // TODO(fastest963): Figure out a way to prefer one or the other. Looking at
+ // the lvl of the header for a 0 or 41 isn't cross-platform.
+ cm6 := new(ipv6.ControlMessage)
+ if cm6.Parse(oob) == nil && cm6.Dst != nil {
+ return cm6.Dst
+ }
+ cm4 := new(ipv4.ControlMessage)
+ if cm4.Parse(oob) == nil && cm4.Dst != nil {
+ return cm4.Dst
+ }
+ return nil
+}
+
+// correctSource takes oob data and returns new oob data with the Src equal to the Dst
+func correctSource(oob []byte) []byte {
+ dst := parseDstFromOOB(oob)
+ if dst == nil {
+ return nil
+ }
+ // If the dst is definitely an IPv6, then use ipv6's ControlMessage to
+ // respond otherwise use ipv4's because ipv6's marshal ignores ipv4
+ // addresses.
+ if dst.To4() == nil {
+ cm := new(ipv6.ControlMessage)
+ cm.Src = dst
+ oob = cm.Marshal()
+ } else {
+ cm := new(ipv4.ControlMessage)
+ cm.Src = dst
+ oob = cm.Marshal()
+ }
+ return oob
+}
diff --git a/vendor/github.com/miekg/dns/udp_windows.go b/vendor/github.com/miekg/dns/udp_windows.go
@@ -0,0 +1,35 @@
+// +build windows
+
+package dns
+
+import "net"
+
+// SessionUDP holds the remote address
+type SessionUDP struct {
+ raddr *net.UDPAddr
+}
+
+// RemoteAddr returns the remote network address.
+func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr }
+
+// ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a
+// net.UDPAddr.
+// TODO(fastest963): Once go1.10 is released, use ReadMsgUDP.
+func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {
+ n, raddr, err := conn.ReadFrom(b)
+ if err != nil {
+ return n, nil, err
+ }
+ return n, &SessionUDP{raddr.(*net.UDPAddr)}, err
+}
+
+// WriteToSessionUDP acts just like net.UDPConn.WriteTo(), but uses a *SessionUDP instead of a net.Addr.
+// TODO(fastest963): Once go1.10 is released, use WriteMsgUDP.
+func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) {
+ return conn.WriteTo(b, session.raddr)
+}
+
+// TODO(fastest963): Once go1.10 is released and we can use *MsgUDP methods
+// use the standard method in udp.go for these.
+func setUDPSocketOptions(*net.UDPConn) error { return nil }
+func parseDstFromOOB([]byte, net.IP) net.IP { return nil }
diff --git a/vendor/github.com/miekg/dns/update.go b/vendor/github.com/miekg/dns/update.go
@@ -0,0 +1,112 @@
+package dns
+
+// NameUsed sets the RRs in the prereq section to
+// "Name is in use" RRs. RFC 2136 section 2.4.4.
+func (u *Msg) NameUsed(rr []RR) {
+ if u.Answer == nil {
+ u.Answer = make([]RR, 0, len(rr))
+ }
+ for _, r := range rr {
+ u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: TypeANY, Class: ClassANY}})
+ }
+}
+
+// NameNotUsed sets the RRs in the prereq section to
+// "Name is in not use" RRs. RFC 2136 section 2.4.5.
+func (u *Msg) NameNotUsed(rr []RR) {
+ if u.Answer == nil {
+ u.Answer = make([]RR, 0, len(rr))
+ }
+ for _, r := range rr {
+ u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: TypeANY, Class: ClassNONE}})
+ }
+}
+
+// Used sets the RRs in the prereq section to
+// "RRset exists (value dependent -- with rdata)" RRs. RFC 2136 section 2.4.2.
+func (u *Msg) Used(rr []RR) {
+ if len(u.Question) == 0 {
+ panic("dns: empty question section")
+ }
+ if u.Answer == nil {
+ u.Answer = make([]RR, 0, len(rr))
+ }
+ for _, r := range rr {
+ hdr := r.Header()
+ hdr.Class = u.Question[0].Qclass
+ hdr.Ttl = 0
+ u.Answer = append(u.Answer, r)
+ }
+}
+
+// RRsetUsed sets the RRs in the prereq section to
+// "RRset exists (value independent -- no rdata)" RRs. RFC 2136 section 2.4.1.
+func (u *Msg) RRsetUsed(rr []RR) {
+ if u.Answer == nil {
+ u.Answer = make([]RR, 0, len(rr))
+ }
+ for _, r := range rr {
+ h := r.Header()
+ u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: h.Name, Ttl: 0, Rrtype: h.Rrtype, Class: ClassANY}})
+ }
+}
+
+// RRsetNotUsed sets the RRs in the prereq section to
+// "RRset does not exist" RRs. RFC 2136 section 2.4.3.
+func (u *Msg) RRsetNotUsed(rr []RR) {
+ if u.Answer == nil {
+ u.Answer = make([]RR, 0, len(rr))
+ }
+ for _, r := range rr {
+ h := r.Header()
+ u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: h.Name, Ttl: 0, Rrtype: h.Rrtype, Class: ClassNONE}})
+ }
+}
+
+// Insert creates a dynamic update packet that adds an complete RRset, see RFC 2136 section 2.5.1.
+func (u *Msg) Insert(rr []RR) {
+ if len(u.Question) == 0 {
+ panic("dns: empty question section")
+ }
+ if u.Ns == nil {
+ u.Ns = make([]RR, 0, len(rr))
+ }
+ for _, r := range rr {
+ r.Header().Class = u.Question[0].Qclass
+ u.Ns = append(u.Ns, r)
+ }
+}
+
+// RemoveRRset creates a dynamic update packet that deletes an RRset, see RFC 2136 section 2.5.2.
+func (u *Msg) RemoveRRset(rr []RR) {
+ if u.Ns == nil {
+ u.Ns = make([]RR, 0, len(rr))
+ }
+ for _, r := range rr {
+ h := r.Header()
+ u.Ns = append(u.Ns, &ANY{Hdr: RR_Header{Name: h.Name, Ttl: 0, Rrtype: h.Rrtype, Class: ClassANY}})
+ }
+}
+
+// RemoveName creates a dynamic update packet that deletes all RRsets of a name, see RFC 2136 section 2.5.3
+func (u *Msg) RemoveName(rr []RR) {
+ if u.Ns == nil {
+ u.Ns = make([]RR, 0, len(rr))
+ }
+ for _, r := range rr {
+ u.Ns = append(u.Ns, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: TypeANY, Class: ClassANY}})
+ }
+}
+
+// Remove creates a dynamic update packet deletes RR from a RRSset, see RFC 2136 section 2.5.4
+func (u *Msg) Remove(rr []RR) {
+ if u.Ns == nil {
+ u.Ns = make([]RR, 0, len(rr))
+ }
+ for _, r := range rr {
+ h := r.Header()
+ h.Class = ClassNONE
+ h.Ttl = 0
+ u.Ns = append(u.Ns, r)
+ }
+}
diff --git a/vendor/github.com/miekg/dns/version.go b/vendor/github.com/miekg/dns/version.go
@@ -0,0 +1,15 @@
+package dns
+
+import "fmt"
+
+// Version is current version of this library.
+var Version = v{1, 1, 49}
+
+// v holds the version of this library.
+type v struct {
+ Major, Minor, Patch int
+}
+
+func (v v) String() string {
+ return fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch)
+}
diff --git a/vendor/github.com/miekg/dns/xfr.go b/vendor/github.com/miekg/dns/xfr.go
@@ -0,0 +1,271 @@
+package dns
+
+import (
+ "fmt"
+ "time"
+)
+
+// Envelope is used when doing a zone transfer with a remote server.
+type Envelope struct {
+ RR []RR // The set of RRs in the answer section of the xfr reply message.
+ Error error // If something went wrong, this contains the error.
+}
+
+// A Transfer defines parameters that are used during a zone transfer.
+type Transfer struct {
+ *Conn
+ DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds
+ ReadTimeout time.Duration // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds
+ WriteTimeout time.Duration // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds
+ TsigProvider TsigProvider // An implementation of the TsigProvider interface. If defined it replaces TsigSecret and is used for all TSIG operations.
+ TsigSecret map[string]string // Secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2)
+ tsigTimersOnly bool
+}
+
+func (t *Transfer) tsigProvider() TsigProvider {
+ if t.TsigProvider != nil {
+ return t.TsigProvider
+ }
+ if t.TsigSecret != nil {
+ return tsigSecretProvider(t.TsigSecret)
+ }
+ return nil
+}
+
+// TODO: Think we need to away to stop the transfer
+
+// In performs an incoming transfer with the server in a.
+// If you would like to set the source IP, or some other attribute
+// of a Dialer for a Transfer, you can do so by specifying the attributes
+// in the Transfer.Conn:
+//
+// d := net.Dialer{LocalAddr: transfer_source}
+// con, err := d.Dial("tcp", master)
+// dnscon := &dns.Conn{Conn:con}
+// transfer = &dns.Transfer{Conn: dnscon}
+// channel, err := transfer.In(message, master)
+//
+func (t *Transfer) In(q *Msg, a string) (env chan *Envelope, err error) {
+ switch q.Question[0].Qtype {
+ case TypeAXFR, TypeIXFR:
+ default:
+ return nil, &Error{"unsupported question type"}
+ }
+
+ timeout := dnsTimeout
+ if t.DialTimeout != 0 {
+ timeout = t.DialTimeout
+ }
+
+ if t.Conn == nil {
+ t.Conn, err = DialTimeout("tcp", a, timeout)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ if err := t.WriteMsg(q); err != nil {
+ return nil, err
+ }
+
+ env = make(chan *Envelope)
+ switch q.Question[0].Qtype {
+ case TypeAXFR:
+ go t.inAxfr(q, env)
+ case TypeIXFR:
+ go t.inIxfr(q, env)
+ }
+
+ return env, nil
+}
+
+func (t *Transfer) inAxfr(q *Msg, c chan *Envelope) {
+ first := true
+ defer t.Close()
+ defer close(c)
+ timeout := dnsTimeout
+ if t.ReadTimeout != 0 {
+ timeout = t.ReadTimeout
+ }
+ for {
+ t.Conn.SetReadDeadline(time.Now().Add(timeout))
+ in, err := t.ReadMsg()
+ if err != nil {
+ c <- &Envelope{nil, err}
+ return
+ }
+ if q.Id != in.Id {
+ c <- &Envelope{in.Answer, ErrId}
+ return
+ }
+ if first {
+ if in.Rcode != RcodeSuccess {
+ c <- &Envelope{in.Answer, &Error{err: fmt.Sprintf(errXFR, in.Rcode)}}
+ return
+ }
+ if !isSOAFirst(in) {
+ c <- &Envelope{in.Answer, ErrSoa}
+ return
+ }
+ first = !first
+ // only one answer that is SOA, receive more
+ if len(in.Answer) == 1 {
+ t.tsigTimersOnly = true
+ c <- &Envelope{in.Answer, nil}
+ continue
+ }
+ }
+
+ if !first {
+ t.tsigTimersOnly = true // Subsequent envelopes use this.
+ if isSOALast(in) {
+ c <- &Envelope{in.Answer, nil}
+ return
+ }
+ c <- &Envelope{in.Answer, nil}
+ }
+ }
+}
+
+func (t *Transfer) inIxfr(q *Msg, c chan *Envelope) {
+ var serial uint32 // The first serial seen is the current server serial
+ axfr := true
+ n := 0
+ qser := q.Ns[0].(*SOA).Serial
+ defer t.Close()
+ defer close(c)
+ timeout := dnsTimeout
+ if t.ReadTimeout != 0 {
+ timeout = t.ReadTimeout
+ }
+ for {
+ t.SetReadDeadline(time.Now().Add(timeout))
+ in, err := t.ReadMsg()
+ if err != nil {
+ c <- &Envelope{nil, err}
+ return
+ }
+ if q.Id != in.Id {
+ c <- &Envelope{in.Answer, ErrId}
+ return
+ }
+ if in.Rcode != RcodeSuccess {
+ c <- &Envelope{in.Answer, &Error{err: fmt.Sprintf(errXFR, in.Rcode)}}
+ return
+ }
+ if n == 0 {
+ // Check if the returned answer is ok
+ if !isSOAFirst(in) {
+ c <- &Envelope{in.Answer, ErrSoa}
+ return
+ }
+ // This serial is important
+ serial = in.Answer[0].(*SOA).Serial
+ // Check if there are no changes in zone
+ if qser >= serial {
+ c <- &Envelope{in.Answer, nil}
+ return
+ }
+ }
+ // Now we need to check each message for SOA records, to see what we need to do
+ t.tsigTimersOnly = true
+ for _, rr := range in.Answer {
+ if v, ok := rr.(*SOA); ok {
+ if v.Serial == serial {
+ n++
+ // quit if it's a full axfr or the the servers' SOA is repeated the third time
+ if axfr && n == 2 || n == 3 {
+ c <- &Envelope{in.Answer, nil}
+ return
+ }
+ } else if axfr {
+ // it's an ixfr
+ axfr = false
+ }
+ }
+ }
+ c <- &Envelope{in.Answer, nil}
+ }
+}
+
+// Out performs an outgoing transfer with the client connecting in w.
+// Basic use pattern:
+//
+// ch := make(chan *dns.Envelope)
+// tr := new(dns.Transfer)
+// var wg sync.WaitGroup
+// go func() {
+// tr.Out(w, r, ch)
+// wg.Done()
+// }()
+// ch <- &dns.Envelope{RR: []dns.RR{soa, rr1, rr2, rr3, soa}}
+// close(ch)
+// wg.Wait() // wait until everything is written out
+// w.Close() // close connection
+//
+// The server is responsible for sending the correct sequence of RRs through the channel ch.
+func (t *Transfer) Out(w ResponseWriter, q *Msg, ch chan *Envelope) error {
+ for x := range ch {
+ r := new(Msg)
+ // Compress?
+ r.SetReply(q)
+ r.Authoritative = true
+ // assume it fits TODO(miek): fix
+ r.Answer = append(r.Answer, x.RR...)
+ if tsig := q.IsTsig(); tsig != nil && w.TsigStatus() == nil {
+ r.SetTsig(tsig.Hdr.Name, tsig.Algorithm, tsig.Fudge, time.Now().Unix())
+ }
+ if err := w.WriteMsg(r); err != nil {
+ return err
+ }
+ w.TsigTimersOnly(true)
+ }
+ return nil
+}
+
+// ReadMsg reads a message from the transfer connection t.
+func (t *Transfer) ReadMsg() (*Msg, error) {
+ m := new(Msg)
+ p := make([]byte, MaxMsgSize)
+ n, err := t.Read(p)
+ if err != nil && n == 0 {
+ return nil, err
+ }
+ p = p[:n]
+ if err := m.Unpack(p); err != nil {
+ return nil, err
+ }
+ if ts, tp := m.IsTsig(), t.tsigProvider(); ts != nil && tp != nil {
+ // Need to work on the original message p, as that was used to calculate the tsig.
+ err = tsigVerifyProvider(p, tp, t.tsigRequestMAC, t.tsigTimersOnly)
+ t.tsigRequestMAC = ts.MAC
+ }
+ return m, err
+}
+
+// WriteMsg writes a message through the transfer connection t.
+func (t *Transfer) WriteMsg(m *Msg) (err error) {
+ var out []byte
+ if ts, tp := m.IsTsig(), t.tsigProvider(); ts != nil && tp != nil {
+ out, t.tsigRequestMAC, err = tsigGenerateProvider(m, tp, t.tsigRequestMAC, t.tsigTimersOnly)
+ } else {
+ out, err = m.Pack()
+ }
+ if err != nil {
+ return err
+ }
+ _, err = t.Write(out)
+ return err
+}
+
+func isSOAFirst(in *Msg) bool {
+ return len(in.Answer) > 0 &&
+ in.Answer[0].Header().Rrtype == TypeSOA
+}
+
+func isSOALast(in *Msg) bool {
+ return len(in.Answer) > 0 &&
+ in.Answer[len(in.Answer)-1].Header().Rrtype == TypeSOA
+}
+
+const errXFR = "bad xfr rcode: %d"
diff --git a/vendor/github.com/miekg/dns/zduplicate.go b/vendor/github.com/miekg/dns/zduplicate.go
@@ -0,0 +1,1340 @@
+// Code generated by "go run duplicate_generate.go"; DO NOT EDIT.
+
+package dns
+
+// isDuplicate() functions
+
+func (r1 *A) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*A)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if !r1.A.Equal(r2.A) {
+ return false
+ }
+ return true
+}
+
+func (r1 *AAAA) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*AAAA)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if !r1.AAAA.Equal(r2.AAAA) {
+ return false
+ }
+ return true
+}
+
+func (r1 *AFSDB) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*AFSDB)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Subtype != r2.Subtype {
+ return false
+ }
+ if !isDuplicateName(r1.Hostname, r2.Hostname) {
+ return false
+ }
+ return true
+}
+
+func (r1 *ANY) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*ANY)
+ if !ok {
+ return false
+ }
+ _ = r2
+ return true
+}
+
+func (r1 *APL) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*APL)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if len(r1.Prefixes) != len(r2.Prefixes) {
+ return false
+ }
+ for i := 0; i < len(r1.Prefixes); i++ {
+ if !r1.Prefixes[i].equals(&r2.Prefixes[i]) {
+ return false
+ }
+ }
+ return true
+}
+
+func (r1 *AVC) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*AVC)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if len(r1.Txt) != len(r2.Txt) {
+ return false
+ }
+ for i := 0; i < len(r1.Txt); i++ {
+ if r1.Txt[i] != r2.Txt[i] {
+ return false
+ }
+ }
+ return true
+}
+
+func (r1 *CAA) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*CAA)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Flag != r2.Flag {
+ return false
+ }
+ if r1.Tag != r2.Tag {
+ return false
+ }
+ if r1.Value != r2.Value {
+ return false
+ }
+ return true
+}
+
+func (r1 *CDNSKEY) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*CDNSKEY)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Flags != r2.Flags {
+ return false
+ }
+ if r1.Protocol != r2.Protocol {
+ return false
+ }
+ if r1.Algorithm != r2.Algorithm {
+ return false
+ }
+ if r1.PublicKey != r2.PublicKey {
+ return false
+ }
+ return true
+}
+
+func (r1 *CDS) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*CDS)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.KeyTag != r2.KeyTag {
+ return false
+ }
+ if r1.Algorithm != r2.Algorithm {
+ return false
+ }
+ if r1.DigestType != r2.DigestType {
+ return false
+ }
+ if r1.Digest != r2.Digest {
+ return false
+ }
+ return true
+}
+
+func (r1 *CERT) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*CERT)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Type != r2.Type {
+ return false
+ }
+ if r1.KeyTag != r2.KeyTag {
+ return false
+ }
+ if r1.Algorithm != r2.Algorithm {
+ return false
+ }
+ if r1.Certificate != r2.Certificate {
+ return false
+ }
+ return true
+}
+
+func (r1 *CNAME) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*CNAME)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if !isDuplicateName(r1.Target, r2.Target) {
+ return false
+ }
+ return true
+}
+
+func (r1 *CSYNC) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*CSYNC)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Serial != r2.Serial {
+ return false
+ }
+ if r1.Flags != r2.Flags {
+ return false
+ }
+ if len(r1.TypeBitMap) != len(r2.TypeBitMap) {
+ return false
+ }
+ for i := 0; i < len(r1.TypeBitMap); i++ {
+ if r1.TypeBitMap[i] != r2.TypeBitMap[i] {
+ return false
+ }
+ }
+ return true
+}
+
+func (r1 *DHCID) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*DHCID)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Digest != r2.Digest {
+ return false
+ }
+ return true
+}
+
+func (r1 *DLV) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*DLV)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.KeyTag != r2.KeyTag {
+ return false
+ }
+ if r1.Algorithm != r2.Algorithm {
+ return false
+ }
+ if r1.DigestType != r2.DigestType {
+ return false
+ }
+ if r1.Digest != r2.Digest {
+ return false
+ }
+ return true
+}
+
+func (r1 *DNAME) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*DNAME)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if !isDuplicateName(r1.Target, r2.Target) {
+ return false
+ }
+ return true
+}
+
+func (r1 *DNSKEY) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*DNSKEY)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Flags != r2.Flags {
+ return false
+ }
+ if r1.Protocol != r2.Protocol {
+ return false
+ }
+ if r1.Algorithm != r2.Algorithm {
+ return false
+ }
+ if r1.PublicKey != r2.PublicKey {
+ return false
+ }
+ return true
+}
+
+func (r1 *DS) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*DS)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.KeyTag != r2.KeyTag {
+ return false
+ }
+ if r1.Algorithm != r2.Algorithm {
+ return false
+ }
+ if r1.DigestType != r2.DigestType {
+ return false
+ }
+ if r1.Digest != r2.Digest {
+ return false
+ }
+ return true
+}
+
+func (r1 *EID) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*EID)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Endpoint != r2.Endpoint {
+ return false
+ }
+ return true
+}
+
+func (r1 *EUI48) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*EUI48)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Address != r2.Address {
+ return false
+ }
+ return true
+}
+
+func (r1 *EUI64) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*EUI64)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Address != r2.Address {
+ return false
+ }
+ return true
+}
+
+func (r1 *GID) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*GID)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Gid != r2.Gid {
+ return false
+ }
+ return true
+}
+
+func (r1 *GPOS) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*GPOS)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Longitude != r2.Longitude {
+ return false
+ }
+ if r1.Latitude != r2.Latitude {
+ return false
+ }
+ if r1.Altitude != r2.Altitude {
+ return false
+ }
+ return true
+}
+
+func (r1 *HINFO) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*HINFO)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Cpu != r2.Cpu {
+ return false
+ }
+ if r1.Os != r2.Os {
+ return false
+ }
+ return true
+}
+
+func (r1 *HIP) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*HIP)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.HitLength != r2.HitLength {
+ return false
+ }
+ if r1.PublicKeyAlgorithm != r2.PublicKeyAlgorithm {
+ return false
+ }
+ if r1.PublicKeyLength != r2.PublicKeyLength {
+ return false
+ }
+ if r1.Hit != r2.Hit {
+ return false
+ }
+ if r1.PublicKey != r2.PublicKey {
+ return false
+ }
+ if len(r1.RendezvousServers) != len(r2.RendezvousServers) {
+ return false
+ }
+ for i := 0; i < len(r1.RendezvousServers); i++ {
+ if !isDuplicateName(r1.RendezvousServers[i], r2.RendezvousServers[i]) {
+ return false
+ }
+ }
+ 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 {
+ return false
+ }
+ _ = r2
+ if r1.Flags != r2.Flags {
+ return false
+ }
+ if r1.Protocol != r2.Protocol {
+ return false
+ }
+ if r1.Algorithm != r2.Algorithm {
+ return false
+ }
+ if r1.PublicKey != r2.PublicKey {
+ return false
+ }
+ return true
+}
+
+func (r1 *KX) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*KX)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Preference != r2.Preference {
+ return false
+ }
+ if !isDuplicateName(r1.Exchanger, r2.Exchanger) {
+ return false
+ }
+ return true
+}
+
+func (r1 *L32) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*L32)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Preference != r2.Preference {
+ return false
+ }
+ if !r1.Locator32.Equal(r2.Locator32) {
+ return false
+ }
+ return true
+}
+
+func (r1 *L64) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*L64)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Preference != r2.Preference {
+ return false
+ }
+ if r1.Locator64 != r2.Locator64 {
+ return false
+ }
+ return true
+}
+
+func (r1 *LOC) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*LOC)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Version != r2.Version {
+ return false
+ }
+ if r1.Size != r2.Size {
+ return false
+ }
+ if r1.HorizPre != r2.HorizPre {
+ return false
+ }
+ if r1.VertPre != r2.VertPre {
+ return false
+ }
+ if r1.Latitude != r2.Latitude {
+ return false
+ }
+ if r1.Longitude != r2.Longitude {
+ return false
+ }
+ if r1.Altitude != r2.Altitude {
+ return false
+ }
+ return true
+}
+
+func (r1 *LP) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*LP)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Preference != r2.Preference {
+ return false
+ }
+ if !isDuplicateName(r1.Fqdn, r2.Fqdn) {
+ return false
+ }
+ return true
+}
+
+func (r1 *MB) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*MB)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if !isDuplicateName(r1.Mb, r2.Mb) {
+ return false
+ }
+ return true
+}
+
+func (r1 *MD) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*MD)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if !isDuplicateName(r1.Md, r2.Md) {
+ return false
+ }
+ return true
+}
+
+func (r1 *MF) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*MF)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if !isDuplicateName(r1.Mf, r2.Mf) {
+ return false
+ }
+ return true
+}
+
+func (r1 *MG) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*MG)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if !isDuplicateName(r1.Mg, r2.Mg) {
+ return false
+ }
+ return true
+}
+
+func (r1 *MINFO) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*MINFO)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if !isDuplicateName(r1.Rmail, r2.Rmail) {
+ return false
+ }
+ if !isDuplicateName(r1.Email, r2.Email) {
+ return false
+ }
+ return true
+}
+
+func (r1 *MR) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*MR)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if !isDuplicateName(r1.Mr, r2.Mr) {
+ return false
+ }
+ return true
+}
+
+func (r1 *MX) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*MX)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Preference != r2.Preference {
+ return false
+ }
+ if !isDuplicateName(r1.Mx, r2.Mx) {
+ return false
+ }
+ return true
+}
+
+func (r1 *NAPTR) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*NAPTR)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Order != r2.Order {
+ return false
+ }
+ if r1.Preference != r2.Preference {
+ return false
+ }
+ if r1.Flags != r2.Flags {
+ return false
+ }
+ if r1.Service != r2.Service {
+ return false
+ }
+ if r1.Regexp != r2.Regexp {
+ return false
+ }
+ if !isDuplicateName(r1.Replacement, r2.Replacement) {
+ return false
+ }
+ return true
+}
+
+func (r1 *NID) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*NID)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Preference != r2.Preference {
+ return false
+ }
+ if r1.NodeID != r2.NodeID {
+ return false
+ }
+ return true
+}
+
+func (r1 *NIMLOC) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*NIMLOC)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Locator != r2.Locator {
+ return false
+ }
+ return true
+}
+
+func (r1 *NINFO) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*NINFO)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if len(r1.ZSData) != len(r2.ZSData) {
+ return false
+ }
+ for i := 0; i < len(r1.ZSData); i++ {
+ if r1.ZSData[i] != r2.ZSData[i] {
+ return false
+ }
+ }
+ return true
+}
+
+func (r1 *NS) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*NS)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if !isDuplicateName(r1.Ns, r2.Ns) {
+ return false
+ }
+ return true
+}
+
+func (r1 *NSAPPTR) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*NSAPPTR)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if !isDuplicateName(r1.Ptr, r2.Ptr) {
+ return false
+ }
+ return true
+}
+
+func (r1 *NSEC) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*NSEC)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if !isDuplicateName(r1.NextDomain, r2.NextDomain) {
+ return false
+ }
+ if len(r1.TypeBitMap) != len(r2.TypeBitMap) {
+ return false
+ }
+ for i := 0; i < len(r1.TypeBitMap); i++ {
+ if r1.TypeBitMap[i] != r2.TypeBitMap[i] {
+ return false
+ }
+ }
+ return true
+}
+
+func (r1 *NSEC3) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*NSEC3)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Hash != r2.Hash {
+ return false
+ }
+ if r1.Flags != r2.Flags {
+ return false
+ }
+ if r1.Iterations != r2.Iterations {
+ return false
+ }
+ if r1.SaltLength != r2.SaltLength {
+ return false
+ }
+ if r1.Salt != r2.Salt {
+ return false
+ }
+ if r1.HashLength != r2.HashLength {
+ return false
+ }
+ if r1.NextDomain != r2.NextDomain {
+ return false
+ }
+ if len(r1.TypeBitMap) != len(r2.TypeBitMap) {
+ return false
+ }
+ for i := 0; i < len(r1.TypeBitMap); i++ {
+ if r1.TypeBitMap[i] != r2.TypeBitMap[i] {
+ return false
+ }
+ }
+ return true
+}
+
+func (r1 *NSEC3PARAM) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*NSEC3PARAM)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Hash != r2.Hash {
+ return false
+ }
+ if r1.Flags != r2.Flags {
+ return false
+ }
+ if r1.Iterations != r2.Iterations {
+ return false
+ }
+ if r1.SaltLength != r2.SaltLength {
+ return false
+ }
+ if r1.Salt != r2.Salt {
+ return false
+ }
+ return true
+}
+
+func (r1 *NULL) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*NULL)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Data != r2.Data {
+ return false
+ }
+ return true
+}
+
+func (r1 *OPENPGPKEY) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*OPENPGPKEY)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.PublicKey != r2.PublicKey {
+ return false
+ }
+ return true
+}
+
+func (r1 *PTR) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*PTR)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if !isDuplicateName(r1.Ptr, r2.Ptr) {
+ return false
+ }
+ return true
+}
+
+func (r1 *PX) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*PX)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Preference != r2.Preference {
+ return false
+ }
+ if !isDuplicateName(r1.Map822, r2.Map822) {
+ return false
+ }
+ if !isDuplicateName(r1.Mapx400, r2.Mapx400) {
+ return false
+ }
+ return true
+}
+
+func (r1 *RFC3597) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*RFC3597)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Rdata != r2.Rdata {
+ return false
+ }
+ return true
+}
+
+func (r1 *RKEY) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*RKEY)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Flags != r2.Flags {
+ return false
+ }
+ if r1.Protocol != r2.Protocol {
+ return false
+ }
+ if r1.Algorithm != r2.Algorithm {
+ return false
+ }
+ if r1.PublicKey != r2.PublicKey {
+ return false
+ }
+ return true
+}
+
+func (r1 *RP) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*RP)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if !isDuplicateName(r1.Mbox, r2.Mbox) {
+ return false
+ }
+ if !isDuplicateName(r1.Txt, r2.Txt) {
+ return false
+ }
+ return true
+}
+
+func (r1 *RRSIG) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*RRSIG)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.TypeCovered != r2.TypeCovered {
+ return false
+ }
+ if r1.Algorithm != r2.Algorithm {
+ return false
+ }
+ if r1.Labels != r2.Labels {
+ return false
+ }
+ if r1.OrigTtl != r2.OrigTtl {
+ return false
+ }
+ if r1.Expiration != r2.Expiration {
+ return false
+ }
+ if r1.Inception != r2.Inception {
+ return false
+ }
+ if r1.KeyTag != r2.KeyTag {
+ return false
+ }
+ if !isDuplicateName(r1.SignerName, r2.SignerName) {
+ return false
+ }
+ if r1.Signature != r2.Signature {
+ return false
+ }
+ return true
+}
+
+func (r1 *RT) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*RT)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Preference != r2.Preference {
+ return false
+ }
+ if !isDuplicateName(r1.Host, r2.Host) {
+ return false
+ }
+ return true
+}
+
+func (r1 *SIG) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*SIG)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.TypeCovered != r2.TypeCovered {
+ return false
+ }
+ if r1.Algorithm != r2.Algorithm {
+ return false
+ }
+ if r1.Labels != r2.Labels {
+ return false
+ }
+ if r1.OrigTtl != r2.OrigTtl {
+ return false
+ }
+ if r1.Expiration != r2.Expiration {
+ return false
+ }
+ if r1.Inception != r2.Inception {
+ return false
+ }
+ if r1.KeyTag != r2.KeyTag {
+ return false
+ }
+ if !isDuplicateName(r1.SignerName, r2.SignerName) {
+ return false
+ }
+ if r1.Signature != r2.Signature {
+ return false
+ }
+ return true
+}
+
+func (r1 *SMIMEA) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*SMIMEA)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Usage != r2.Usage {
+ return false
+ }
+ if r1.Selector != r2.Selector {
+ return false
+ }
+ if r1.MatchingType != r2.MatchingType {
+ return false
+ }
+ if r1.Certificate != r2.Certificate {
+ return false
+ }
+ return true
+}
+
+func (r1 *SOA) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*SOA)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if !isDuplicateName(r1.Ns, r2.Ns) {
+ return false
+ }
+ if !isDuplicateName(r1.Mbox, r2.Mbox) {
+ return false
+ }
+ if r1.Serial != r2.Serial {
+ return false
+ }
+ if r1.Refresh != r2.Refresh {
+ return false
+ }
+ if r1.Retry != r2.Retry {
+ return false
+ }
+ if r1.Expire != r2.Expire {
+ return false
+ }
+ if r1.Minttl != r2.Minttl {
+ return false
+ }
+ return true
+}
+
+func (r1 *SPF) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*SPF)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if len(r1.Txt) != len(r2.Txt) {
+ return false
+ }
+ for i := 0; i < len(r1.Txt); i++ {
+ if r1.Txt[i] != r2.Txt[i] {
+ return false
+ }
+ }
+ return true
+}
+
+func (r1 *SRV) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*SRV)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Priority != r2.Priority {
+ return false
+ }
+ if r1.Weight != r2.Weight {
+ return false
+ }
+ if r1.Port != r2.Port {
+ return false
+ }
+ if !isDuplicateName(r1.Target, r2.Target) {
+ return false
+ }
+ return true
+}
+
+func (r1 *SSHFP) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*SSHFP)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Algorithm != r2.Algorithm {
+ return false
+ }
+ if r1.Type != r2.Type {
+ return false
+ }
+ if r1.FingerPrint != r2.FingerPrint {
+ return false
+ }
+ 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 {
+ return false
+ }
+ _ = r2
+ if r1.KeyTag != r2.KeyTag {
+ return false
+ }
+ if r1.Algorithm != r2.Algorithm {
+ return false
+ }
+ if r1.DigestType != r2.DigestType {
+ return false
+ }
+ if r1.Digest != r2.Digest {
+ return false
+ }
+ return true
+}
+
+func (r1 *TALINK) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*TALINK)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if !isDuplicateName(r1.PreviousName, r2.PreviousName) {
+ return false
+ }
+ if !isDuplicateName(r1.NextName, r2.NextName) {
+ return false
+ }
+ return true
+}
+
+func (r1 *TKEY) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*TKEY)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if !isDuplicateName(r1.Algorithm, r2.Algorithm) {
+ return false
+ }
+ if r1.Inception != r2.Inception {
+ return false
+ }
+ if r1.Expiration != r2.Expiration {
+ return false
+ }
+ if r1.Mode != r2.Mode {
+ return false
+ }
+ if r1.Error != r2.Error {
+ return false
+ }
+ if r1.KeySize != r2.KeySize {
+ return false
+ }
+ if r1.Key != r2.Key {
+ return false
+ }
+ if r1.OtherLen != r2.OtherLen {
+ return false
+ }
+ if r1.OtherData != r2.OtherData {
+ return false
+ }
+ return true
+}
+
+func (r1 *TLSA) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*TLSA)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Usage != r2.Usage {
+ return false
+ }
+ if r1.Selector != r2.Selector {
+ return false
+ }
+ if r1.MatchingType != r2.MatchingType {
+ return false
+ }
+ if r1.Certificate != r2.Certificate {
+ return false
+ }
+ return true
+}
+
+func (r1 *TSIG) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*TSIG)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if !isDuplicateName(r1.Algorithm, r2.Algorithm) {
+ return false
+ }
+ if r1.TimeSigned != r2.TimeSigned {
+ return false
+ }
+ if r1.Fudge != r2.Fudge {
+ return false
+ }
+ if r1.MACSize != r2.MACSize {
+ return false
+ }
+ if r1.MAC != r2.MAC {
+ return false
+ }
+ if r1.OrigId != r2.OrigId {
+ return false
+ }
+ if r1.Error != r2.Error {
+ return false
+ }
+ if r1.OtherLen != r2.OtherLen {
+ return false
+ }
+ if r1.OtherData != r2.OtherData {
+ return false
+ }
+ return true
+}
+
+func (r1 *TXT) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*TXT)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if len(r1.Txt) != len(r2.Txt) {
+ return false
+ }
+ for i := 0; i < len(r1.Txt); i++ {
+ if r1.Txt[i] != r2.Txt[i] {
+ return false
+ }
+ }
+ return true
+}
+
+func (r1 *UID) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*UID)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Uid != r2.Uid {
+ return false
+ }
+ return true
+}
+
+func (r1 *UINFO) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*UINFO)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Uinfo != r2.Uinfo {
+ return false
+ }
+ return true
+}
+
+func (r1 *URI) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*URI)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Priority != r2.Priority {
+ return false
+ }
+ if r1.Weight != r2.Weight {
+ return false
+ }
+ if r1.Target != r2.Target {
+ return false
+ }
+ return true
+}
+
+func (r1 *X25) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*X25)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.PSDNAddress != r2.PSDNAddress {
+ return false
+ }
+ return true
+}
+
+func (r1 *ZONEMD) isDuplicate(_r2 RR) bool {
+ r2, ok := _r2.(*ZONEMD)
+ if !ok {
+ return false
+ }
+ _ = r2
+ if r1.Serial != r2.Serial {
+ return false
+ }
+ if r1.Scheme != r2.Scheme {
+ return false
+ }
+ if r1.Hash != r2.Hash {
+ return false
+ }
+ if r1.Digest != r2.Digest {
+ return false
+ }
+ return true
+}
diff --git a/vendor/github.com/miekg/dns/zmsg.go b/vendor/github.com/miekg/dns/zmsg.go
@@ -0,0 +1,2875 @@
+// Code generated by "go run msg_generate.go"; DO NOT EDIT.
+
+package dns
+
+// pack*() functions
+
+func (rr *A) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packDataA(rr.A, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *AAAA) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packDataAAAA(rr.AAAA, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *AFSDB) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint16(rr.Subtype, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packDomainName(rr.Hostname, msg, off, compression, false)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *ANY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ return off, nil
+}
+
+func (rr *APL) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packDataApl(rr.Prefixes, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *AVC) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packStringTxt(rr.Txt, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *CAA) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint8(rr.Flag, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packString(rr.Tag, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringOctet(rr.Value, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *CDNSKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint16(rr.Flags, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.Protocol, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.Algorithm, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringBase64(rr.PublicKey, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *CDS) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint16(rr.KeyTag, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.Algorithm, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.DigestType, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringHex(rr.Digest, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *CERT) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint16(rr.Type, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(rr.KeyTag, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.Algorithm, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringBase64(rr.Certificate, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *CNAME) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packDomainName(rr.Target, msg, off, compression, compress)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *CSYNC) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint32(rr.Serial, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(rr.Flags, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packDataNsec(rr.TypeBitMap, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *DHCID) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packStringBase64(rr.Digest, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *DLV) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint16(rr.KeyTag, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.Algorithm, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.DigestType, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringHex(rr.Digest, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *DNAME) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packDomainName(rr.Target, msg, off, compression, false)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *DNSKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint16(rr.Flags, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.Protocol, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.Algorithm, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringBase64(rr.PublicKey, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *DS) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint16(rr.KeyTag, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.Algorithm, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.DigestType, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringHex(rr.Digest, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *EID) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packStringHex(rr.Endpoint, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *EUI48) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint48(rr.Address, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *EUI64) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint64(rr.Address, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *GID) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint32(rr.Gid, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *GPOS) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packString(rr.Longitude, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packString(rr.Latitude, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packString(rr.Altitude, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *HINFO) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packString(rr.Cpu, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packString(rr.Os, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *HIP) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint8(rr.HitLength, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.PublicKeyAlgorithm, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(rr.PublicKeyLength, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringHex(rr.Hit, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringBase64(rr.PublicKey, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packDataDomainNames(rr.RendezvousServers, msg, off, compression, false)
+ if err != nil {
+ return off, err
+ }
+ 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 {
+ return off, err
+ }
+ off, err = packUint8(rr.Protocol, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.Algorithm, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringBase64(rr.PublicKey, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *KX) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint16(rr.Preference, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packDomainName(rr.Exchanger, msg, off, compression, false)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *L32) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint16(rr.Preference, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packDataA(rr.Locator32, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *L64) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint16(rr.Preference, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint64(rr.Locator64, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *LOC) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint8(rr.Version, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.Size, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.HorizPre, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.VertPre, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint32(rr.Latitude, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint32(rr.Longitude, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint32(rr.Altitude, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *LP) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint16(rr.Preference, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packDomainName(rr.Fqdn, msg, off, compression, false)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *MB) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packDomainName(rr.Mb, msg, off, compression, compress)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *MD) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packDomainName(rr.Md, msg, off, compression, compress)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *MF) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packDomainName(rr.Mf, msg, off, compression, compress)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *MG) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packDomainName(rr.Mg, msg, off, compression, compress)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *MINFO) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packDomainName(rr.Rmail, msg, off, compression, compress)
+ if err != nil {
+ return off, err
+ }
+ off, err = packDomainName(rr.Email, msg, off, compression, compress)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *MR) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packDomainName(rr.Mr, msg, off, compression, compress)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *MX) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint16(rr.Preference, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packDomainName(rr.Mx, msg, off, compression, compress)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *NAPTR) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint16(rr.Order, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(rr.Preference, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packString(rr.Flags, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packString(rr.Service, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packString(rr.Regexp, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packDomainName(rr.Replacement, msg, off, compression, false)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *NID) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint16(rr.Preference, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint64(rr.NodeID, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *NIMLOC) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packStringHex(rr.Locator, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *NINFO) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packStringTxt(rr.ZSData, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *NS) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packDomainName(rr.Ns, msg, off, compression, compress)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *NSAPPTR) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packDomainName(rr.Ptr, msg, off, compression, false)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *NSEC) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packDomainName(rr.NextDomain, msg, off, compression, false)
+ if err != nil {
+ return off, err
+ }
+ off, err = packDataNsec(rr.TypeBitMap, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *NSEC3) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint8(rr.Hash, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.Flags, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(rr.Iterations, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.SaltLength, msg, off)
+ if err != nil {
+ return off, err
+ }
+ // Only pack salt if value is not "-", i.e. empty
+ if rr.Salt != "-" {
+ off, err = packStringHex(rr.Salt, msg, off)
+ if err != nil {
+ return off, err
+ }
+ }
+ off, err = packUint8(rr.HashLength, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringBase32(rr.NextDomain, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packDataNsec(rr.TypeBitMap, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *NSEC3PARAM) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint8(rr.Hash, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.Flags, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(rr.Iterations, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.SaltLength, msg, off)
+ if err != nil {
+ return off, err
+ }
+ // Only pack salt if value is not "-", i.e. empty
+ if rr.Salt != "-" {
+ off, err = packStringHex(rr.Salt, msg, off)
+ if err != nil {
+ return off, err
+ }
+ }
+ return off, nil
+}
+
+func (rr *NULL) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packStringAny(rr.Data, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *OPENPGPKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packStringBase64(rr.PublicKey, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *OPT) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packDataOpt(rr.Option, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *PTR) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packDomainName(rr.Ptr, msg, off, compression, compress)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *PX) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint16(rr.Preference, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packDomainName(rr.Map822, msg, off, compression, false)
+ if err != nil {
+ return off, err
+ }
+ off, err = packDomainName(rr.Mapx400, msg, off, compression, false)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *RFC3597) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packStringHex(rr.Rdata, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *RKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint16(rr.Flags, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.Protocol, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.Algorithm, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringBase64(rr.PublicKey, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *RP) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packDomainName(rr.Mbox, msg, off, compression, false)
+ if err != nil {
+ return off, err
+ }
+ off, err = packDomainName(rr.Txt, msg, off, compression, false)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *RRSIG) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint16(rr.TypeCovered, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.Algorithm, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.Labels, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint32(rr.OrigTtl, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint32(rr.Expiration, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint32(rr.Inception, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(rr.KeyTag, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packDomainName(rr.SignerName, msg, off, compression, false)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringBase64(rr.Signature, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *RT) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint16(rr.Preference, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packDomainName(rr.Host, msg, off, compression, false)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *SIG) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint16(rr.TypeCovered, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.Algorithm, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.Labels, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint32(rr.OrigTtl, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint32(rr.Expiration, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint32(rr.Inception, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(rr.KeyTag, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packDomainName(rr.SignerName, msg, off, compression, false)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringBase64(rr.Signature, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *SMIMEA) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint8(rr.Usage, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.Selector, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.MatchingType, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringHex(rr.Certificate, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *SOA) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packDomainName(rr.Ns, msg, off, compression, compress)
+ if err != nil {
+ return off, err
+ }
+ off, err = packDomainName(rr.Mbox, msg, off, compression, compress)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint32(rr.Serial, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint32(rr.Refresh, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint32(rr.Retry, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint32(rr.Expire, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint32(rr.Minttl, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *SPF) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packStringTxt(rr.Txt, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *SRV) 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 = packUint16(rr.Weight, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(rr.Port, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packDomainName(rr.Target, msg, off, compression, false)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *SSHFP) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint8(rr.Algorithm, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.Type, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringHex(rr.FingerPrint, msg, off)
+ if err != nil {
+ return off, err
+ }
+ 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 {
+ return off, err
+ }
+ off, err = packUint8(rr.Algorithm, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.DigestType, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringHex(rr.Digest, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *TALINK) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packDomainName(rr.PreviousName, msg, off, compression, false)
+ if err != nil {
+ return off, err
+ }
+ off, err = packDomainName(rr.NextName, msg, off, compression, false)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *TKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packDomainName(rr.Algorithm, msg, off, compression, false)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint32(rr.Inception, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint32(rr.Expiration, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(rr.Mode, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(rr.Error, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(rr.KeySize, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringHex(rr.Key, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(rr.OtherLen, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringHex(rr.OtherData, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *TLSA) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint8(rr.Usage, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.Selector, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.MatchingType, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringHex(rr.Certificate, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *TSIG) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packDomainName(rr.Algorithm, msg, off, compression, false)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint48(rr.TimeSigned, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(rr.Fudge, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(rr.MACSize, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringHex(rr.MAC, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(rr.OrigId, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(rr.Error, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint16(rr.OtherLen, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringHex(rr.OtherData, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *TXT) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packStringTxt(rr.Txt, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *UID) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint32(rr.Uid, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *UINFO) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packString(rr.Uinfo, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *URI) 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 = packUint16(rr.Weight, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringOctet(rr.Target, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *X25) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packString(rr.PSDNAddress, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *ZONEMD) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
+ off, err = packUint32(rr.Serial, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.Scheme, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packUint8(rr.Hash, msg, off)
+ if err != nil {
+ return off, err
+ }
+ off, err = packStringHex(rr.Digest, msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+// unpack*() functions
+
+func (rr *A) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.A, off, err = unpackDataA(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *AAAA) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.AAAA, off, err = unpackDataAAAA(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *AFSDB) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Subtype, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Hostname, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *ANY) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ return off, nil
+}
+
+func (rr *APL) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Prefixes, off, err = unpackDataApl(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *AVC) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Txt, off, err = unpackStringTxt(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *CAA) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Flag, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Tag, off, err = unpackString(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Value, off, err = unpackStringOctet(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *CDNSKEY) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Flags, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Protocol, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Algorithm, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *CDS) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.KeyTag, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Algorithm, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.DigestType, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *CERT) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Type, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.KeyTag, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Algorithm, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Certificate, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *CNAME) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Target, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *CSYNC) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Serial, off, err = unpackUint32(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Flags, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.TypeBitMap, off, err = unpackDataNsec(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *DHCID) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Digest, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *DLV) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.KeyTag, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Algorithm, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.DigestType, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *DNAME) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Target, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *DNSKEY) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Flags, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Protocol, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Algorithm, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *DS) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.KeyTag, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Algorithm, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.DigestType, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *EID) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Endpoint, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *EUI48) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Address, off, err = unpackUint48(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *EUI64) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Address, off, err = unpackUint64(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *GID) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Gid, off, err = unpackUint32(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *GPOS) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Longitude, off, err = unpackString(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Latitude, off, err = unpackString(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Altitude, off, err = unpackString(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *HINFO) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Cpu, off, err = unpackString(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Os, off, err = unpackString(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *HIP) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.HitLength, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.PublicKeyAlgorithm, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.PublicKeyLength, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Hit, off, err = unpackStringHex(msg, off, off+int(rr.HitLength))
+ if err != nil {
+ return off, err
+ }
+ rr.PublicKey, off, err = unpackStringBase64(msg, off, off+int(rr.PublicKeyLength))
+ if err != nil {
+ return off, err
+ }
+ rr.RendezvousServers, off, err = unpackDataDomainNames(msg, off, rdStart+int(rr.Hdr.Rdlength))
+ if err != nil {
+ return off, err
+ }
+ 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
+
+ rr.Flags, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Protocol, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Algorithm, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *KX) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Preference, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Exchanger, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *L32) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Preference, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Locator32, off, err = unpackDataA(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *L64) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Preference, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Locator64, off, err = unpackUint64(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *LOC) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Version, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Size, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.HorizPre, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.VertPre, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Latitude, off, err = unpackUint32(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Longitude, off, err = unpackUint32(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Altitude, off, err = unpackUint32(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *LP) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Preference, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Fqdn, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *MB) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Mb, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *MD) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Md, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *MF) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Mf, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *MG) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Mg, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *MINFO) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Rmail, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Email, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *MR) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Mr, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *MX) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Preference, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Mx, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *NAPTR) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Order, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Preference, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Flags, off, err = unpackString(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Service, off, err = unpackString(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Regexp, off, err = unpackString(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Replacement, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *NID) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Preference, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.NodeID, off, err = unpackUint64(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *NIMLOC) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Locator, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *NINFO) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.ZSData, off, err = unpackStringTxt(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *NS) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Ns, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *NSAPPTR) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Ptr, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *NSEC) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.NextDomain, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.TypeBitMap, off, err = unpackDataNsec(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *NSEC3) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Hash, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Flags, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Iterations, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.SaltLength, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Salt, off, err = unpackStringHex(msg, off, off+int(rr.SaltLength))
+ if err != nil {
+ return off, err
+ }
+ rr.HashLength, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.NextDomain, off, err = unpackStringBase32(msg, off, off+int(rr.HashLength))
+ if err != nil {
+ return off, err
+ }
+ rr.TypeBitMap, off, err = unpackDataNsec(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *NSEC3PARAM) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Hash, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Flags, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Iterations, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.SaltLength, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Salt, off, err = unpackStringHex(msg, off, off+int(rr.SaltLength))
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *NULL) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Data, off, err = unpackStringAny(msg, off, rdStart+int(rr.Hdr.Rdlength))
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *OPENPGPKEY) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *OPT) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Option, off, err = unpackDataOpt(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *PTR) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Ptr, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *PX) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Preference, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Map822, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Mapx400, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *RFC3597) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Rdata, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *RKEY) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Flags, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Protocol, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Algorithm, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *RP) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Mbox, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Txt, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *RRSIG) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.TypeCovered, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Algorithm, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Labels, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.OrigTtl, off, err = unpackUint32(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Expiration, off, err = unpackUint32(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Inception, off, err = unpackUint32(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.KeyTag, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.SignerName, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Signature, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *RT) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Preference, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Host, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *SIG) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.TypeCovered, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Algorithm, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Labels, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.OrigTtl, off, err = unpackUint32(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Expiration, off, err = unpackUint32(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Inception, off, err = unpackUint32(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.KeyTag, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.SignerName, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Signature, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *SMIMEA) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Usage, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Selector, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.MatchingType, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Certificate, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *SOA) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Ns, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Mbox, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Serial, off, err = unpackUint32(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Refresh, off, err = unpackUint32(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Retry, off, err = unpackUint32(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Expire, off, err = unpackUint32(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Minttl, off, err = unpackUint32(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *SPF) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Txt, off, err = unpackStringTxt(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *SRV) 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.Weight, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Port, 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
+ }
+ return off, nil
+}
+
+func (rr *SSHFP) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Algorithm, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Type, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.FingerPrint, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
+ if err != nil {
+ return off, err
+ }
+ 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
+
+ rr.KeyTag, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Algorithm, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.DigestType, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *TALINK) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.PreviousName, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.NextName, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *TKEY) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Algorithm, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Inception, off, err = unpackUint32(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Expiration, off, err = unpackUint32(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Mode, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Error, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.KeySize, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Key, off, err = unpackStringHex(msg, off, off+int(rr.KeySize))
+ if err != nil {
+ return off, err
+ }
+ rr.OtherLen, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.OtherData, off, err = unpackStringHex(msg, off, off+int(rr.OtherLen))
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *TLSA) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Usage, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Selector, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.MatchingType, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Certificate, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *TSIG) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Algorithm, off, err = UnpackDomainName(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.TimeSigned, off, err = unpackUint48(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Fudge, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.MACSize, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.MAC, off, err = unpackStringHex(msg, off, off+int(rr.MACSize))
+ if err != nil {
+ return off, err
+ }
+ rr.OrigId, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Error, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.OtherLen, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.OtherData, off, err = unpackStringHex(msg, off, off+int(rr.OtherLen))
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *TXT) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Txt, off, err = unpackStringTxt(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *UID) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Uid, off, err = unpackUint32(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *UINFO) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Uinfo, off, err = unpackString(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *URI) 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.Weight, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Target, off, err = unpackStringOctet(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *X25) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.PSDNAddress, off, err = unpackString(msg, off)
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
+
+func (rr *ZONEMD) unpack(msg []byte, off int) (off1 int, err error) {
+ rdStart := off
+ _ = rdStart
+
+ rr.Serial, off, err = unpackUint32(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Scheme, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Hash, off, err = unpackUint8(msg, off)
+ if err != nil {
+ return off, err
+ }
+ if off == len(msg) {
+ return off, nil
+ }
+ rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
+ if err != nil {
+ return off, err
+ }
+ return off, nil
+}
diff --git a/vendor/github.com/miekg/dns/ztypes.go b/vendor/github.com/miekg/dns/ztypes.go
@@ -0,0 +1,952 @@
+// Code generated by "go run types_generate.go"; DO NOT EDIT.
+
+package dns
+
+import (
+ "encoding/base64"
+ "net"
+)
+
+// TypeToRR is a map of constructors for each RR type.
+var TypeToRR = map[uint16]func() RR{
+ TypeA: func() RR { return new(A) },
+ TypeAAAA: func() RR { return new(AAAA) },
+ TypeAFSDB: func() RR { return new(AFSDB) },
+ TypeANY: func() RR { return new(ANY) },
+ TypeAPL: func() RR { return new(APL) },
+ TypeAVC: func() RR { return new(AVC) },
+ TypeCAA: func() RR { return new(CAA) },
+ TypeCDNSKEY: func() RR { return new(CDNSKEY) },
+ TypeCDS: func() RR { return new(CDS) },
+ TypeCERT: func() RR { return new(CERT) },
+ TypeCNAME: func() RR { return new(CNAME) },
+ TypeCSYNC: func() RR { return new(CSYNC) },
+ TypeDHCID: func() RR { return new(DHCID) },
+ TypeDLV: func() RR { return new(DLV) },
+ TypeDNAME: func() RR { return new(DNAME) },
+ TypeDNSKEY: func() RR { return new(DNSKEY) },
+ TypeDS: func() RR { return new(DS) },
+ TypeEID: func() RR { return new(EID) },
+ TypeEUI48: func() RR { return new(EUI48) },
+ TypeEUI64: func() RR { return new(EUI64) },
+ TypeGID: func() RR { return new(GID) },
+ TypeGPOS: func() RR { return new(GPOS) },
+ TypeHINFO: func() RR { return new(HINFO) },
+ TypeHIP: func() RR { return new(HIP) },
+ TypeHTTPS: func() RR { return new(HTTPS) },
+ TypeKEY: func() RR { return new(KEY) },
+ TypeKX: func() RR { return new(KX) },
+ TypeL32: func() RR { return new(L32) },
+ TypeL64: func() RR { return new(L64) },
+ TypeLOC: func() RR { return new(LOC) },
+ TypeLP: func() RR { return new(LP) },
+ TypeMB: func() RR { return new(MB) },
+ TypeMD: func() RR { return new(MD) },
+ TypeMF: func() RR { return new(MF) },
+ TypeMG: func() RR { return new(MG) },
+ TypeMINFO: func() RR { return new(MINFO) },
+ TypeMR: func() RR { return new(MR) },
+ TypeMX: func() RR { return new(MX) },
+ TypeNAPTR: func() RR { return new(NAPTR) },
+ TypeNID: func() RR { return new(NID) },
+ TypeNIMLOC: func() RR { return new(NIMLOC) },
+ TypeNINFO: func() RR { return new(NINFO) },
+ TypeNS: func() RR { return new(NS) },
+ TypeNSAPPTR: func() RR { return new(NSAPPTR) },
+ TypeNSEC: func() RR { return new(NSEC) },
+ TypeNSEC3: func() RR { return new(NSEC3) },
+ TypeNSEC3PARAM: func() RR { return new(NSEC3PARAM) },
+ TypeNULL: func() RR { return new(NULL) },
+ TypeOPENPGPKEY: func() RR { return new(OPENPGPKEY) },
+ TypeOPT: func() RR { return new(OPT) },
+ TypePTR: func() RR { return new(PTR) },
+ TypePX: func() RR { return new(PX) },
+ TypeRKEY: func() RR { return new(RKEY) },
+ TypeRP: func() RR { return new(RP) },
+ TypeRRSIG: func() RR { return new(RRSIG) },
+ TypeRT: func() RR { return new(RT) },
+ TypeSIG: func() RR { return new(SIG) },
+ TypeSMIMEA: func() RR { return new(SMIMEA) },
+ TypeSOA: func() RR { return new(SOA) },
+ TypeSPF: func() RR { return new(SPF) },
+ TypeSRV: func() RR { return new(SRV) },
+ TypeSSHFP: func() RR { return new(SSHFP) },
+ TypeSVCB: func() RR { return new(SVCB) },
+ TypeTA: func() RR { return new(TA) },
+ TypeTALINK: func() RR { return new(TALINK) },
+ TypeTKEY: func() RR { return new(TKEY) },
+ TypeTLSA: func() RR { return new(TLSA) },
+ TypeTSIG: func() RR { return new(TSIG) },
+ TypeTXT: func() RR { return new(TXT) },
+ TypeUID: func() RR { return new(UID) },
+ TypeUINFO: func() RR { return new(UINFO) },
+ TypeURI: func() RR { return new(URI) },
+ TypeX25: func() RR { return new(X25) },
+ TypeZONEMD: func() RR { return new(ZONEMD) },
+}
+
+// TypeToString is a map of strings for each RR type.
+var TypeToString = map[uint16]string{
+ TypeA: "A",
+ TypeAAAA: "AAAA",
+ TypeAFSDB: "AFSDB",
+ TypeANY: "ANY",
+ TypeAPL: "APL",
+ TypeATMA: "ATMA",
+ TypeAVC: "AVC",
+ TypeAXFR: "AXFR",
+ TypeCAA: "CAA",
+ TypeCDNSKEY: "CDNSKEY",
+ TypeCDS: "CDS",
+ TypeCERT: "CERT",
+ TypeCNAME: "CNAME",
+ TypeCSYNC: "CSYNC",
+ TypeDHCID: "DHCID",
+ TypeDLV: "DLV",
+ TypeDNAME: "DNAME",
+ TypeDNSKEY: "DNSKEY",
+ TypeDS: "DS",
+ TypeEID: "EID",
+ TypeEUI48: "EUI48",
+ TypeEUI64: "EUI64",
+ TypeGID: "GID",
+ TypeGPOS: "GPOS",
+ TypeHINFO: "HINFO",
+ TypeHIP: "HIP",
+ TypeHTTPS: "HTTPS",
+ TypeISDN: "ISDN",
+ TypeIXFR: "IXFR",
+ TypeKEY: "KEY",
+ TypeKX: "KX",
+ TypeL32: "L32",
+ TypeL64: "L64",
+ TypeLOC: "LOC",
+ TypeLP: "LP",
+ TypeMAILA: "MAILA",
+ TypeMAILB: "MAILB",
+ TypeMB: "MB",
+ TypeMD: "MD",
+ TypeMF: "MF",
+ TypeMG: "MG",
+ TypeMINFO: "MINFO",
+ TypeMR: "MR",
+ TypeMX: "MX",
+ TypeNAPTR: "NAPTR",
+ TypeNID: "NID",
+ TypeNIMLOC: "NIMLOC",
+ TypeNINFO: "NINFO",
+ TypeNS: "NS",
+ TypeNSEC: "NSEC",
+ TypeNSEC3: "NSEC3",
+ TypeNSEC3PARAM: "NSEC3PARAM",
+ TypeNULL: "NULL",
+ TypeNXT: "NXT",
+ TypeNone: "None",
+ TypeOPENPGPKEY: "OPENPGPKEY",
+ TypeOPT: "OPT",
+ TypePTR: "PTR",
+ TypePX: "PX",
+ TypeRKEY: "RKEY",
+ TypeRP: "RP",
+ TypeRRSIG: "RRSIG",
+ TypeRT: "RT",
+ TypeReserved: "Reserved",
+ TypeSIG: "SIG",
+ TypeSMIMEA: "SMIMEA",
+ TypeSOA: "SOA",
+ TypeSPF: "SPF",
+ TypeSRV: "SRV",
+ TypeSSHFP: "SSHFP",
+ TypeSVCB: "SVCB",
+ TypeTA: "TA",
+ TypeTALINK: "TALINK",
+ TypeTKEY: "TKEY",
+ TypeTLSA: "TLSA",
+ TypeTSIG: "TSIG",
+ TypeTXT: "TXT",
+ TypeUID: "UID",
+ TypeUINFO: "UINFO",
+ TypeUNSPEC: "UNSPEC",
+ TypeURI: "URI",
+ TypeX25: "X25",
+ TypeZONEMD: "ZONEMD",
+ TypeNSAPPTR: "NSAP-PTR",
+}
+
+func (rr *A) Header() *RR_Header { return &rr.Hdr }
+func (rr *AAAA) Header() *RR_Header { return &rr.Hdr }
+func (rr *AFSDB) Header() *RR_Header { return &rr.Hdr }
+func (rr *ANY) Header() *RR_Header { return &rr.Hdr }
+func (rr *APL) Header() *RR_Header { return &rr.Hdr }
+func (rr *AVC) Header() *RR_Header { return &rr.Hdr }
+func (rr *CAA) Header() *RR_Header { return &rr.Hdr }
+func (rr *CDNSKEY) Header() *RR_Header { return &rr.Hdr }
+func (rr *CDS) Header() *RR_Header { return &rr.Hdr }
+func (rr *CERT) Header() *RR_Header { return &rr.Hdr }
+func (rr *CNAME) Header() *RR_Header { return &rr.Hdr }
+func (rr *CSYNC) Header() *RR_Header { return &rr.Hdr }
+func (rr *DHCID) Header() *RR_Header { return &rr.Hdr }
+func (rr *DLV) Header() *RR_Header { return &rr.Hdr }
+func (rr *DNAME) Header() *RR_Header { return &rr.Hdr }
+func (rr *DNSKEY) Header() *RR_Header { return &rr.Hdr }
+func (rr *DS) Header() *RR_Header { return &rr.Hdr }
+func (rr *EID) Header() *RR_Header { return &rr.Hdr }
+func (rr *EUI48) Header() *RR_Header { return &rr.Hdr }
+func (rr *EUI64) Header() *RR_Header { return &rr.Hdr }
+func (rr *GID) Header() *RR_Header { return &rr.Hdr }
+func (rr *GPOS) Header() *RR_Header { return &rr.Hdr }
+func (rr *HINFO) Header() *RR_Header { return &rr.Hdr }
+func (rr *HIP) Header() *RR_Header { return &rr.Hdr }
+func (rr *HTTPS) Header() *RR_Header { return &rr.Hdr }
+func (rr *KEY) Header() *RR_Header { return &rr.Hdr }
+func (rr *KX) Header() *RR_Header { return &rr.Hdr }
+func (rr *L32) Header() *RR_Header { return &rr.Hdr }
+func (rr *L64) Header() *RR_Header { return &rr.Hdr }
+func (rr *LOC) Header() *RR_Header { return &rr.Hdr }
+func (rr *LP) Header() *RR_Header { return &rr.Hdr }
+func (rr *MB) Header() *RR_Header { return &rr.Hdr }
+func (rr *MD) Header() *RR_Header { return &rr.Hdr }
+func (rr *MF) Header() *RR_Header { return &rr.Hdr }
+func (rr *MG) Header() *RR_Header { return &rr.Hdr }
+func (rr *MINFO) Header() *RR_Header { return &rr.Hdr }
+func (rr *MR) Header() *RR_Header { return &rr.Hdr }
+func (rr *MX) Header() *RR_Header { return &rr.Hdr }
+func (rr *NAPTR) Header() *RR_Header { return &rr.Hdr }
+func (rr *NID) Header() *RR_Header { return &rr.Hdr }
+func (rr *NIMLOC) Header() *RR_Header { return &rr.Hdr }
+func (rr *NINFO) Header() *RR_Header { return &rr.Hdr }
+func (rr *NS) Header() *RR_Header { return &rr.Hdr }
+func (rr *NSAPPTR) Header() *RR_Header { return &rr.Hdr }
+func (rr *NSEC) Header() *RR_Header { return &rr.Hdr }
+func (rr *NSEC3) Header() *RR_Header { return &rr.Hdr }
+func (rr *NSEC3PARAM) Header() *RR_Header { return &rr.Hdr }
+func (rr *NULL) Header() *RR_Header { return &rr.Hdr }
+func (rr *OPENPGPKEY) Header() *RR_Header { return &rr.Hdr }
+func (rr *OPT) Header() *RR_Header { return &rr.Hdr }
+func (rr *PTR) Header() *RR_Header { return &rr.Hdr }
+func (rr *PX) Header() *RR_Header { return &rr.Hdr }
+func (rr *RFC3597) Header() *RR_Header { return &rr.Hdr }
+func (rr *RKEY) Header() *RR_Header { return &rr.Hdr }
+func (rr *RP) Header() *RR_Header { return &rr.Hdr }
+func (rr *RRSIG) Header() *RR_Header { return &rr.Hdr }
+func (rr *RT) Header() *RR_Header { return &rr.Hdr }
+func (rr *SIG) Header() *RR_Header { return &rr.Hdr }
+func (rr *SMIMEA) Header() *RR_Header { return &rr.Hdr }
+func (rr *SOA) Header() *RR_Header { return &rr.Hdr }
+func (rr *SPF) Header() *RR_Header { return &rr.Hdr }
+func (rr *SRV) Header() *RR_Header { return &rr.Hdr }
+func (rr *SSHFP) Header() *RR_Header { return &rr.Hdr }
+func (rr *SVCB) Header() *RR_Header { return &rr.Hdr }
+func (rr *TA) Header() *RR_Header { return &rr.Hdr }
+func (rr *TALINK) Header() *RR_Header { return &rr.Hdr }
+func (rr *TKEY) Header() *RR_Header { return &rr.Hdr }
+func (rr *TLSA) Header() *RR_Header { return &rr.Hdr }
+func (rr *TSIG) Header() *RR_Header { return &rr.Hdr }
+func (rr *TXT) Header() *RR_Header { return &rr.Hdr }
+func (rr *UID) Header() *RR_Header { return &rr.Hdr }
+func (rr *UINFO) Header() *RR_Header { return &rr.Hdr }
+func (rr *URI) Header() *RR_Header { return &rr.Hdr }
+func (rr *X25) Header() *RR_Header { return &rr.Hdr }
+func (rr *ZONEMD) Header() *RR_Header { return &rr.Hdr }
+
+// len() functions
+func (rr *A) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ if len(rr.A) != 0 {
+ l += net.IPv4len
+ }
+ return l
+}
+func (rr *AAAA) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ if len(rr.AAAA) != 0 {
+ l += net.IPv6len
+ }
+ return l
+}
+func (rr *AFSDB) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 2 // Subtype
+ l += domainNameLen(rr.Hostname, off+l, compression, false)
+ return l
+}
+func (rr *ANY) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ return l
+}
+func (rr *APL) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ for _, x := range rr.Prefixes {
+ l += x.len()
+ }
+ return l
+}
+func (rr *AVC) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ for _, x := range rr.Txt {
+ l += len(x) + 1
+ }
+ return l
+}
+func (rr *CAA) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l++ // Flag
+ l += len(rr.Tag) + 1
+ l += len(rr.Value)
+ return l
+}
+func (rr *CERT) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 2 // Type
+ l += 2 // KeyTag
+ l++ // Algorithm
+ l += base64.StdEncoding.DecodedLen(len(rr.Certificate))
+ return l
+}
+func (rr *CNAME) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += domainNameLen(rr.Target, off+l, compression, true)
+ return l
+}
+func (rr *DHCID) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += base64.StdEncoding.DecodedLen(len(rr.Digest))
+ return l
+}
+func (rr *DNAME) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += domainNameLen(rr.Target, off+l, compression, false)
+ return l
+}
+func (rr *DNSKEY) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 2 // Flags
+ l++ // Protocol
+ l++ // Algorithm
+ l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
+ return l
+}
+func (rr *DS) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 2 // KeyTag
+ l++ // Algorithm
+ l++ // DigestType
+ l += len(rr.Digest) / 2
+ return l
+}
+func (rr *EID) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += len(rr.Endpoint) / 2
+ return l
+}
+func (rr *EUI48) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 6 // Address
+ return l
+}
+func (rr *EUI64) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 8 // Address
+ return l
+}
+func (rr *GID) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 4 // Gid
+ return l
+}
+func (rr *GPOS) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += len(rr.Longitude) + 1
+ l += len(rr.Latitude) + 1
+ l += len(rr.Altitude) + 1
+ return l
+}
+func (rr *HINFO) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += len(rr.Cpu) + 1
+ l += len(rr.Os) + 1
+ return l
+}
+func (rr *HIP) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l++ // HitLength
+ l++ // PublicKeyAlgorithm
+ l += 2 // PublicKeyLength
+ l += len(rr.Hit) / 2
+ l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
+ for _, x := range rr.RendezvousServers {
+ l += domainNameLen(x, off+l, compression, false)
+ }
+ return l
+}
+func (rr *KX) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 2 // Preference
+ l += domainNameLen(rr.Exchanger, off+l, compression, false)
+ return l
+}
+func (rr *L32) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 2 // Preference
+ if len(rr.Locator32) != 0 {
+ l += net.IPv4len
+ }
+ return l
+}
+func (rr *L64) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 2 // Preference
+ l += 8 // Locator64
+ return l
+}
+func (rr *LOC) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l++ // Version
+ l++ // Size
+ l++ // HorizPre
+ l++ // VertPre
+ l += 4 // Latitude
+ l += 4 // Longitude
+ l += 4 // Altitude
+ return l
+}
+func (rr *LP) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 2 // Preference
+ l += domainNameLen(rr.Fqdn, off+l, compression, false)
+ return l
+}
+func (rr *MB) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += domainNameLen(rr.Mb, off+l, compression, true)
+ return l
+}
+func (rr *MD) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += domainNameLen(rr.Md, off+l, compression, true)
+ return l
+}
+func (rr *MF) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += domainNameLen(rr.Mf, off+l, compression, true)
+ return l
+}
+func (rr *MG) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += domainNameLen(rr.Mg, off+l, compression, true)
+ return l
+}
+func (rr *MINFO) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += domainNameLen(rr.Rmail, off+l, compression, true)
+ l += domainNameLen(rr.Email, off+l, compression, true)
+ return l
+}
+func (rr *MR) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += domainNameLen(rr.Mr, off+l, compression, true)
+ return l
+}
+func (rr *MX) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 2 // Preference
+ l += domainNameLen(rr.Mx, off+l, compression, true)
+ return l
+}
+func (rr *NAPTR) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 2 // Order
+ l += 2 // Preference
+ l += len(rr.Flags) + 1
+ l += len(rr.Service) + 1
+ l += len(rr.Regexp) + 1
+ l += domainNameLen(rr.Replacement, off+l, compression, false)
+ return l
+}
+func (rr *NID) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 2 // Preference
+ l += 8 // NodeID
+ return l
+}
+func (rr *NIMLOC) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += len(rr.Locator) / 2
+ return l
+}
+func (rr *NINFO) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ for _, x := range rr.ZSData {
+ l += len(x) + 1
+ }
+ return l
+}
+func (rr *NS) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += domainNameLen(rr.Ns, off+l, compression, true)
+ return l
+}
+func (rr *NSAPPTR) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += domainNameLen(rr.Ptr, off+l, compression, false)
+ return l
+}
+func (rr *NSEC3PARAM) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l++ // Hash
+ l++ // Flags
+ l += 2 // Iterations
+ l++ // SaltLength
+ l += len(rr.Salt) / 2
+ return l
+}
+func (rr *NULL) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += len(rr.Data)
+ return l
+}
+func (rr *OPENPGPKEY) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
+ return l
+}
+func (rr *PTR) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += domainNameLen(rr.Ptr, off+l, compression, true)
+ return l
+}
+func (rr *PX) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 2 // Preference
+ l += domainNameLen(rr.Map822, off+l, compression, false)
+ l += domainNameLen(rr.Mapx400, off+l, compression, false)
+ return l
+}
+func (rr *RFC3597) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += len(rr.Rdata) / 2
+ return l
+}
+func (rr *RKEY) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 2 // Flags
+ l++ // Protocol
+ l++ // Algorithm
+ l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
+ return l
+}
+func (rr *RP) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += domainNameLen(rr.Mbox, off+l, compression, false)
+ l += domainNameLen(rr.Txt, off+l, compression, false)
+ return l
+}
+func (rr *RRSIG) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 2 // TypeCovered
+ l++ // Algorithm
+ l++ // Labels
+ l += 4 // OrigTtl
+ l += 4 // Expiration
+ l += 4 // Inception
+ l += 2 // KeyTag
+ l += domainNameLen(rr.SignerName, off+l, compression, false)
+ l += base64.StdEncoding.DecodedLen(len(rr.Signature))
+ return l
+}
+func (rr *RT) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 2 // Preference
+ l += domainNameLen(rr.Host, off+l, compression, false)
+ return l
+}
+func (rr *SMIMEA) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l++ // Usage
+ l++ // Selector
+ l++ // MatchingType
+ l += len(rr.Certificate) / 2
+ return l
+}
+func (rr *SOA) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += domainNameLen(rr.Ns, off+l, compression, true)
+ l += domainNameLen(rr.Mbox, off+l, compression, true)
+ l += 4 // Serial
+ l += 4 // Refresh
+ l += 4 // Retry
+ l += 4 // Expire
+ l += 4 // Minttl
+ return l
+}
+func (rr *SPF) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ for _, x := range rr.Txt {
+ l += len(x) + 1
+ }
+ return l
+}
+func (rr *SRV) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 2 // Priority
+ l += 2 // Weight
+ l += 2 // Port
+ l += domainNameLen(rr.Target, off+l, compression, false)
+ return l
+}
+func (rr *SSHFP) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l++ // Algorithm
+ l++ // Type
+ l += len(rr.FingerPrint) / 2
+ return l
+}
+func (rr *SVCB) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 2 // Priority
+ l += domainNameLen(rr.Target, off+l, compression, false)
+ for _, x := range rr.Value {
+ l += 4 + int(x.len())
+ }
+ return l
+}
+func (rr *TA) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 2 // KeyTag
+ l++ // Algorithm
+ l++ // DigestType
+ l += len(rr.Digest) / 2
+ return l
+}
+func (rr *TALINK) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += domainNameLen(rr.PreviousName, off+l, compression, false)
+ l += domainNameLen(rr.NextName, off+l, compression, false)
+ return l
+}
+func (rr *TKEY) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += domainNameLen(rr.Algorithm, off+l, compression, false)
+ l += 4 // Inception
+ l += 4 // Expiration
+ l += 2 // Mode
+ l += 2 // Error
+ l += 2 // KeySize
+ l += len(rr.Key) / 2
+ l += 2 // OtherLen
+ l += len(rr.OtherData) / 2
+ return l
+}
+func (rr *TLSA) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l++ // Usage
+ l++ // Selector
+ l++ // MatchingType
+ l += len(rr.Certificate) / 2
+ return l
+}
+func (rr *TSIG) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += domainNameLen(rr.Algorithm, off+l, compression, false)
+ l += 6 // TimeSigned
+ l += 2 // Fudge
+ l += 2 // MACSize
+ l += len(rr.MAC) / 2
+ l += 2 // OrigId
+ l += 2 // Error
+ l += 2 // OtherLen
+ l += len(rr.OtherData) / 2
+ return l
+}
+func (rr *TXT) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ for _, x := range rr.Txt {
+ l += len(x) + 1
+ }
+ return l
+}
+func (rr *UID) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 4 // Uid
+ return l
+}
+func (rr *UINFO) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += len(rr.Uinfo) + 1
+ return l
+}
+func (rr *URI) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 2 // Priority
+ l += 2 // Weight
+ l += len(rr.Target)
+ return l
+}
+func (rr *X25) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += len(rr.PSDNAddress) + 1
+ return l
+}
+func (rr *ZONEMD) len(off int, compression map[string]struct{}) int {
+ l := rr.Hdr.len(off, compression)
+ l += 4 // Serial
+ l++ // Scheme
+ l++ // Hash
+ l += len(rr.Digest) / 2
+ return l
+}
+
+// copy() functions
+func (rr *A) copy() RR {
+ return &A{rr.Hdr, copyIP(rr.A)}
+}
+func (rr *AAAA) copy() RR {
+ return &AAAA{rr.Hdr, copyIP(rr.AAAA)}
+}
+func (rr *AFSDB) copy() RR {
+ return &AFSDB{rr.Hdr, rr.Subtype, rr.Hostname}
+}
+func (rr *ANY) copy() RR {
+ return &ANY{rr.Hdr}
+}
+func (rr *APL) copy() RR {
+ Prefixes := make([]APLPrefix, len(rr.Prefixes))
+ for i, e := range rr.Prefixes {
+ Prefixes[i] = e.copy()
+ }
+ return &APL{rr.Hdr, Prefixes}
+}
+func (rr *AVC) copy() RR {
+ Txt := make([]string, len(rr.Txt))
+ copy(Txt, rr.Txt)
+ return &AVC{rr.Hdr, Txt}
+}
+func (rr *CAA) copy() RR {
+ return &CAA{rr.Hdr, rr.Flag, rr.Tag, rr.Value}
+}
+func (rr *CDNSKEY) copy() RR {
+ return &CDNSKEY{*rr.DNSKEY.copy().(*DNSKEY)}
+}
+func (rr *CDS) copy() RR {
+ return &CDS{*rr.DS.copy().(*DS)}
+}
+func (rr *CERT) copy() RR {
+ return &CERT{rr.Hdr, rr.Type, rr.KeyTag, rr.Algorithm, rr.Certificate}
+}
+func (rr *CNAME) copy() RR {
+ return &CNAME{rr.Hdr, rr.Target}
+}
+func (rr *CSYNC) copy() RR {
+ TypeBitMap := make([]uint16, len(rr.TypeBitMap))
+ copy(TypeBitMap, rr.TypeBitMap)
+ return &CSYNC{rr.Hdr, rr.Serial, rr.Flags, TypeBitMap}
+}
+func (rr *DHCID) copy() RR {
+ return &DHCID{rr.Hdr, rr.Digest}
+}
+func (rr *DLV) copy() RR {
+ return &DLV{*rr.DS.copy().(*DS)}
+}
+func (rr *DNAME) copy() RR {
+ return &DNAME{rr.Hdr, rr.Target}
+}
+func (rr *DNSKEY) copy() RR {
+ return &DNSKEY{rr.Hdr, rr.Flags, rr.Protocol, rr.Algorithm, rr.PublicKey}
+}
+func (rr *DS) copy() RR {
+ return &DS{rr.Hdr, rr.KeyTag, rr.Algorithm, rr.DigestType, rr.Digest}
+}
+func (rr *EID) copy() RR {
+ return &EID{rr.Hdr, rr.Endpoint}
+}
+func (rr *EUI48) copy() RR {
+ return &EUI48{rr.Hdr, rr.Address}
+}
+func (rr *EUI64) copy() RR {
+ return &EUI64{rr.Hdr, rr.Address}
+}
+func (rr *GID) copy() RR {
+ return &GID{rr.Hdr, rr.Gid}
+}
+func (rr *GPOS) copy() RR {
+ return &GPOS{rr.Hdr, rr.Longitude, rr.Latitude, rr.Altitude}
+}
+func (rr *HINFO) copy() RR {
+ return &HINFO{rr.Hdr, rr.Cpu, rr.Os}
+}
+func (rr *HIP) copy() RR {
+ RendezvousServers := make([]string, len(rr.RendezvousServers))
+ copy(RendezvousServers, rr.RendezvousServers)
+ return &HIP{rr.Hdr, rr.HitLength, rr.PublicKeyAlgorithm, rr.PublicKeyLength, rr.Hit, rr.PublicKey, RendezvousServers}
+}
+func (rr *HTTPS) copy() RR {
+ return &HTTPS{*rr.SVCB.copy().(*SVCB)}
+}
+func (rr *KEY) copy() RR {
+ return &KEY{*rr.DNSKEY.copy().(*DNSKEY)}
+}
+func (rr *KX) copy() RR {
+ return &KX{rr.Hdr, rr.Preference, rr.Exchanger}
+}
+func (rr *L32) copy() RR {
+ return &L32{rr.Hdr, rr.Preference, copyIP(rr.Locator32)}
+}
+func (rr *L64) copy() RR {
+ return &L64{rr.Hdr, rr.Preference, rr.Locator64}
+}
+func (rr *LOC) copy() RR {
+ return &LOC{rr.Hdr, rr.Version, rr.Size, rr.HorizPre, rr.VertPre, rr.Latitude, rr.Longitude, rr.Altitude}
+}
+func (rr *LP) copy() RR {
+ return &LP{rr.Hdr, rr.Preference, rr.Fqdn}
+}
+func (rr *MB) copy() RR {
+ return &MB{rr.Hdr, rr.Mb}
+}
+func (rr *MD) copy() RR {
+ return &MD{rr.Hdr, rr.Md}
+}
+func (rr *MF) copy() RR {
+ return &MF{rr.Hdr, rr.Mf}
+}
+func (rr *MG) copy() RR {
+ return &MG{rr.Hdr, rr.Mg}
+}
+func (rr *MINFO) copy() RR {
+ return &MINFO{rr.Hdr, rr.Rmail, rr.Email}
+}
+func (rr *MR) copy() RR {
+ return &MR{rr.Hdr, rr.Mr}
+}
+func (rr *MX) copy() RR {
+ return &MX{rr.Hdr, rr.Preference, rr.Mx}
+}
+func (rr *NAPTR) copy() RR {
+ return &NAPTR{rr.Hdr, rr.Order, rr.Preference, rr.Flags, rr.Service, rr.Regexp, rr.Replacement}
+}
+func (rr *NID) copy() RR {
+ return &NID{rr.Hdr, rr.Preference, rr.NodeID}
+}
+func (rr *NIMLOC) copy() RR {
+ return &NIMLOC{rr.Hdr, rr.Locator}
+}
+func (rr *NINFO) copy() RR {
+ ZSData := make([]string, len(rr.ZSData))
+ copy(ZSData, rr.ZSData)
+ return &NINFO{rr.Hdr, ZSData}
+}
+func (rr *NS) copy() RR {
+ return &NS{rr.Hdr, rr.Ns}
+}
+func (rr *NSAPPTR) copy() RR {
+ return &NSAPPTR{rr.Hdr, rr.Ptr}
+}
+func (rr *NSEC) copy() RR {
+ TypeBitMap := make([]uint16, len(rr.TypeBitMap))
+ copy(TypeBitMap, rr.TypeBitMap)
+ return &NSEC{rr.Hdr, rr.NextDomain, TypeBitMap}
+}
+func (rr *NSEC3) copy() RR {
+ TypeBitMap := make([]uint16, len(rr.TypeBitMap))
+ copy(TypeBitMap, rr.TypeBitMap)
+ return &NSEC3{rr.Hdr, rr.Hash, rr.Flags, rr.Iterations, rr.SaltLength, rr.Salt, rr.HashLength, rr.NextDomain, TypeBitMap}
+}
+func (rr *NSEC3PARAM) copy() RR {
+ return &NSEC3PARAM{rr.Hdr, rr.Hash, rr.Flags, rr.Iterations, rr.SaltLength, rr.Salt}
+}
+func (rr *NULL) copy() RR {
+ return &NULL{rr.Hdr, rr.Data}
+}
+func (rr *OPENPGPKEY) copy() RR {
+ return &OPENPGPKEY{rr.Hdr, rr.PublicKey}
+}
+func (rr *OPT) copy() RR {
+ Option := make([]EDNS0, len(rr.Option))
+ for i, e := range rr.Option {
+ Option[i] = e.copy()
+ }
+ return &OPT{rr.Hdr, Option}
+}
+func (rr *PTR) copy() RR {
+ return &PTR{rr.Hdr, rr.Ptr}
+}
+func (rr *PX) copy() RR {
+ return &PX{rr.Hdr, rr.Preference, rr.Map822, rr.Mapx400}
+}
+func (rr *RFC3597) copy() RR {
+ return &RFC3597{rr.Hdr, rr.Rdata}
+}
+func (rr *RKEY) copy() RR {
+ return &RKEY{rr.Hdr, rr.Flags, rr.Protocol, rr.Algorithm, rr.PublicKey}
+}
+func (rr *RP) copy() RR {
+ return &RP{rr.Hdr, rr.Mbox, rr.Txt}
+}
+func (rr *RRSIG) copy() RR {
+ return &RRSIG{rr.Hdr, rr.TypeCovered, rr.Algorithm, rr.Labels, rr.OrigTtl, rr.Expiration, rr.Inception, rr.KeyTag, rr.SignerName, rr.Signature}
+}
+func (rr *RT) copy() RR {
+ return &RT{rr.Hdr, rr.Preference, rr.Host}
+}
+func (rr *SIG) copy() RR {
+ return &SIG{*rr.RRSIG.copy().(*RRSIG)}
+}
+func (rr *SMIMEA) copy() RR {
+ return &SMIMEA{rr.Hdr, rr.Usage, rr.Selector, rr.MatchingType, rr.Certificate}
+}
+func (rr *SOA) copy() RR {
+ return &SOA{rr.Hdr, rr.Ns, rr.Mbox, rr.Serial, rr.Refresh, rr.Retry, rr.Expire, rr.Minttl}
+}
+func (rr *SPF) copy() RR {
+ Txt := make([]string, len(rr.Txt))
+ copy(Txt, rr.Txt)
+ return &SPF{rr.Hdr, Txt}
+}
+func (rr *SRV) copy() RR {
+ return &SRV{rr.Hdr, rr.Priority, rr.Weight, rr.Port, rr.Target}
+}
+func (rr *SSHFP) copy() RR {
+ return &SSHFP{rr.Hdr, rr.Algorithm, rr.Type, rr.FingerPrint}
+}
+func (rr *SVCB) copy() RR {
+ Value := make([]SVCBKeyValue, len(rr.Value))
+ for i, e := range rr.Value {
+ Value[i] = e.copy()
+ }
+ return &SVCB{rr.Hdr, rr.Priority, rr.Target, Value}
+}
+func (rr *TA) copy() RR {
+ return &TA{rr.Hdr, rr.KeyTag, rr.Algorithm, rr.DigestType, rr.Digest}
+}
+func (rr *TALINK) copy() RR {
+ return &TALINK{rr.Hdr, rr.PreviousName, rr.NextName}
+}
+func (rr *TKEY) copy() RR {
+ return &TKEY{rr.Hdr, rr.Algorithm, rr.Inception, rr.Expiration, rr.Mode, rr.Error, rr.KeySize, rr.Key, rr.OtherLen, rr.OtherData}
+}
+func (rr *TLSA) copy() RR {
+ return &TLSA{rr.Hdr, rr.Usage, rr.Selector, rr.MatchingType, rr.Certificate}
+}
+func (rr *TSIG) copy() RR {
+ return &TSIG{rr.Hdr, rr.Algorithm, rr.TimeSigned, rr.Fudge, rr.MACSize, rr.MAC, rr.OrigId, rr.Error, rr.OtherLen, rr.OtherData}
+}
+func (rr *TXT) copy() RR {
+ Txt := make([]string, len(rr.Txt))
+ copy(Txt, rr.Txt)
+ return &TXT{rr.Hdr, Txt}
+}
+func (rr *UID) copy() RR {
+ return &UID{rr.Hdr, rr.Uid}
+}
+func (rr *UINFO) copy() RR {
+ return &UINFO{rr.Hdr, rr.Uinfo}
+}
+func (rr *URI) copy() RR {
+ return &URI{rr.Hdr, rr.Priority, rr.Weight, rr.Target}
+}
+func (rr *X25) copy() RR {
+ return &X25{rr.Hdr, rr.PSDNAddress}
+}
+func (rr *ZONEMD) copy() RR {
+ return &ZONEMD{rr.Hdr, rr.Serial, rr.Scheme, rr.Hash, rr.Digest}
+}
diff --git a/vendor/golang.org/x/net/bpf/asm.go b/vendor/golang.org/x/net/bpf/asm.go
@@ -0,0 +1,41 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package bpf
+
+import "fmt"
+
+// Assemble converts insts into raw instructions suitable for loading
+// into a BPF virtual machine.
+//
+// Currently, no optimization is attempted, the assembled program flow
+// is exactly as provided.
+func Assemble(insts []Instruction) ([]RawInstruction, error) {
+ ret := make([]RawInstruction, len(insts))
+ var err error
+ for i, inst := range insts {
+ ret[i], err = inst.Assemble()
+ if err != nil {
+ return nil, fmt.Errorf("assembling instruction %d: %s", i+1, err)
+ }
+ }
+ return ret, nil
+}
+
+// Disassemble attempts to parse raw back into
+// Instructions. Unrecognized RawInstructions are assumed to be an
+// extension not implemented by this package, and are passed through
+// unchanged to the output. The allDecoded value reports whether insts
+// contains no RawInstructions.
+func Disassemble(raw []RawInstruction) (insts []Instruction, allDecoded bool) {
+ insts = make([]Instruction, len(raw))
+ allDecoded = true
+ for i, r := range raw {
+ insts[i] = r.Disassemble()
+ if _, ok := insts[i].(RawInstruction); ok {
+ allDecoded = false
+ }
+ }
+ return insts, allDecoded
+}
diff --git a/vendor/golang.org/x/net/bpf/constants.go b/vendor/golang.org/x/net/bpf/constants.go
@@ -0,0 +1,222 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package bpf
+
+// A Register is a register of the BPF virtual machine.
+type Register uint16
+
+const (
+ // RegA is the accumulator register. RegA is always the
+ // destination register of ALU operations.
+ RegA Register = iota
+ // RegX is the indirection register, used by LoadIndirect
+ // operations.
+ RegX
+)
+
+// An ALUOp is an arithmetic or logic operation.
+type ALUOp uint16
+
+// ALU binary operation types.
+const (
+ ALUOpAdd ALUOp = iota << 4
+ ALUOpSub
+ ALUOpMul
+ ALUOpDiv
+ ALUOpOr
+ ALUOpAnd
+ ALUOpShiftLeft
+ ALUOpShiftRight
+ aluOpNeg // Not exported because it's the only unary ALU operation, and gets its own instruction type.
+ ALUOpMod
+ ALUOpXor
+)
+
+// A JumpTest is a comparison operator used in conditional jumps.
+type JumpTest uint16
+
+// Supported operators for conditional jumps.
+// K can be RegX for JumpIfX
+const (
+ // K == A
+ JumpEqual JumpTest = iota
+ // K != A
+ JumpNotEqual
+ // K > A
+ JumpGreaterThan
+ // K < A
+ JumpLessThan
+ // K >= A
+ JumpGreaterOrEqual
+ // K <= A
+ JumpLessOrEqual
+ // K & A != 0
+ JumpBitsSet
+ // K & A == 0
+ JumpBitsNotSet
+)
+
+// An Extension is a function call provided by the kernel that
+// performs advanced operations that are expensive or impossible
+// within the BPF virtual machine.
+//
+// Extensions are only implemented by the Linux kernel.
+//
+// TODO: should we prune this list? Some of these extensions seem
+// either broken or near-impossible to use correctly, whereas other
+// (len, random, ifindex) are quite useful.
+type Extension int
+
+// Extension functions available in the Linux kernel.
+const (
+ // extOffset is the negative maximum number of instructions used
+ // to load instructions by overloading the K argument.
+ extOffset = -0x1000
+ // ExtLen returns the length of the packet.
+ ExtLen Extension = 1
+ // ExtProto returns the packet's L3 protocol type.
+ ExtProto Extension = 0
+ // ExtType returns the packet's type (skb->pkt_type in the kernel)
+ //
+ // TODO: better documentation. How nice an API do we want to
+ // provide for these esoteric extensions?
+ ExtType Extension = 4
+ // ExtPayloadOffset returns the offset of the packet payload, or
+ // the first protocol header that the kernel does not know how to
+ // parse.
+ ExtPayloadOffset Extension = 52
+ // ExtInterfaceIndex returns the index of the interface on which
+ // the packet was received.
+ ExtInterfaceIndex Extension = 8
+ // ExtNetlinkAttr returns the netlink attribute of type X at
+ // offset A.
+ ExtNetlinkAttr Extension = 12
+ // ExtNetlinkAttrNested returns the nested netlink attribute of
+ // type X at offset A.
+ ExtNetlinkAttrNested Extension = 16
+ // ExtMark returns the packet's mark value.
+ ExtMark Extension = 20
+ // ExtQueue returns the packet's assigned hardware queue.
+ ExtQueue Extension = 24
+ // ExtLinkLayerType returns the packet's hardware address type
+ // (e.g. Ethernet, Infiniband).
+ ExtLinkLayerType Extension = 28
+ // ExtRXHash returns the packets receive hash.
+ //
+ // TODO: figure out what this rxhash actually is.
+ ExtRXHash Extension = 32
+ // ExtCPUID returns the ID of the CPU processing the current
+ // packet.
+ ExtCPUID Extension = 36
+ // ExtVLANTag returns the packet's VLAN tag.
+ ExtVLANTag Extension = 44
+ // ExtVLANTagPresent returns non-zero if the packet has a VLAN
+ // tag.
+ //
+ // TODO: I think this might be a lie: it reads bit 0x1000 of the
+ // VLAN header, which changed meaning in recent revisions of the
+ // spec - this extension may now return meaningless information.
+ ExtVLANTagPresent Extension = 48
+ // ExtVLANProto returns 0x8100 if the frame has a VLAN header,
+ // 0x88a8 if the frame has a "Q-in-Q" double VLAN header, or some
+ // other value if no VLAN information is present.
+ ExtVLANProto Extension = 60
+ // ExtRand returns a uniformly random uint32.
+ ExtRand Extension = 56
+)
+
+// The following gives names to various bit patterns used in opcode construction.
+
+const (
+ opMaskCls uint16 = 0x7
+ // opClsLoad masks
+ opMaskLoadDest = 0x01
+ opMaskLoadWidth = 0x18
+ opMaskLoadMode = 0xe0
+ // opClsALU & opClsJump
+ opMaskOperand = 0x08
+ opMaskOperator = 0xf0
+)
+
+const (
+ // +---------------+-----------------+---+---+---+
+ // | AddrMode (3b) | LoadWidth (2b) | 0 | 0 | 0 |
+ // +---------------+-----------------+---+---+---+
+ opClsLoadA uint16 = iota
+ // +---------------+-----------------+---+---+---+
+ // | AddrMode (3b) | LoadWidth (2b) | 0 | 0 | 1 |
+ // +---------------+-----------------+---+---+---+
+ opClsLoadX
+ // +---+---+---+---+---+---+---+---+
+ // | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
+ // +---+---+---+---+---+---+---+---+
+ opClsStoreA
+ // +---+---+---+---+---+---+---+---+
+ // | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
+ // +---+---+---+---+---+---+---+---+
+ opClsStoreX
+ // +---------------+-----------------+---+---+---+
+ // | Operator (4b) | OperandSrc (1b) | 1 | 0 | 0 |
+ // +---------------+-----------------+---+---+---+
+ opClsALU
+ // +-----------------------------+---+---+---+---+
+ // | TestOperator (4b) | 0 | 1 | 0 | 1 |
+ // +-----------------------------+---+---+---+---+
+ opClsJump
+ // +---+-------------------------+---+---+---+---+
+ // | 0 | 0 | 0 | RetSrc (1b) | 0 | 1 | 1 | 0 |
+ // +---+-------------------------+---+---+---+---+
+ opClsReturn
+ // +---+-------------------------+---+---+---+---+
+ // | 0 | 0 | 0 | TXAorTAX (1b) | 0 | 1 | 1 | 1 |
+ // +---+-------------------------+---+---+---+---+
+ opClsMisc
+)
+
+const (
+ opAddrModeImmediate uint16 = iota << 5
+ opAddrModeAbsolute
+ opAddrModeIndirect
+ opAddrModeScratch
+ opAddrModePacketLen // actually an extension, not an addressing mode.
+ opAddrModeMemShift
+)
+
+const (
+ opLoadWidth4 uint16 = iota << 3
+ opLoadWidth2
+ opLoadWidth1
+)
+
+// Operand for ALU and Jump instructions
+type opOperand uint16
+
+// Supported operand sources.
+const (
+ opOperandConstant opOperand = iota << 3
+ opOperandX
+)
+
+// An jumpOp is a conditional jump condition.
+type jumpOp uint16
+
+// Supported jump conditions.
+const (
+ opJumpAlways jumpOp = iota << 4
+ opJumpEqual
+ opJumpGT
+ opJumpGE
+ opJumpSet
+)
+
+const (
+ opRetSrcConstant uint16 = iota << 4
+ opRetSrcA
+)
+
+const (
+ opMiscTAX = 0x00
+ opMiscTXA = 0x80
+)
diff --git a/vendor/golang.org/x/net/bpf/doc.go b/vendor/golang.org/x/net/bpf/doc.go
@@ -0,0 +1,80 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package bpf implements marshaling and unmarshaling of programs for the
+Berkeley Packet Filter virtual machine, and provides a Go implementation
+of the virtual machine.
+
+BPF's main use is to specify a packet filter for network taps, so that
+the kernel doesn't have to expensively copy every packet it sees to
+userspace. However, it's been repurposed to other areas where running
+user code in-kernel is needed. For example, Linux's seccomp uses BPF
+to apply security policies to system calls. For simplicity, this
+documentation refers only to packets, but other uses of BPF have their
+own data payloads.
+
+BPF programs run in a restricted virtual machine. It has almost no
+access to kernel functions, and while conditional branches are
+allowed, they can only jump forwards, to guarantee that there are no
+infinite loops.
+
+# The virtual machine
+
+The BPF VM is an accumulator machine. Its main register, called
+register A, is an implicit source and destination in all arithmetic
+and logic operations. The machine also has 16 scratch registers for
+temporary storage, and an indirection register (register X) for
+indirect memory access. All registers are 32 bits wide.
+
+Each run of a BPF program is given one packet, which is placed in the
+VM's read-only "main memory". LoadAbsolute and LoadIndirect
+instructions can fetch up to 32 bits at a time into register A for
+examination.
+
+The goal of a BPF program is to produce and return a verdict (uint32),
+which tells the kernel what to do with the packet. In the context of
+packet filtering, the returned value is the number of bytes of the
+packet to forward to userspace, or 0 to ignore the packet. Other
+contexts like seccomp define their own return values.
+
+In order to simplify programs, attempts to read past the end of the
+packet terminate the program execution with a verdict of 0 (ignore
+packet). This means that the vast majority of BPF programs don't need
+to do any explicit bounds checking.
+
+In addition to the bytes of the packet, some BPF programs have access
+to extensions, which are essentially calls to kernel utility
+functions. Currently, the only extensions supported by this package
+are the Linux packet filter extensions.
+
+# Examples
+
+This packet filter selects all ARP packets.
+
+ bpf.Assemble([]bpf.Instruction{
+ // Load "EtherType" field from the ethernet header.
+ bpf.LoadAbsolute{Off: 12, Size: 2},
+ // Skip over the next instruction if EtherType is not ARP.
+ bpf.JumpIf{Cond: bpf.JumpNotEqual, Val: 0x0806, SkipTrue: 1},
+ // Verdict is "send up to 4k of the packet to userspace."
+ bpf.RetConstant{Val: 4096},
+ // Verdict is "ignore packet."
+ bpf.RetConstant{Val: 0},
+ })
+
+This packet filter captures a random 1% sample of traffic.
+
+ bpf.Assemble([]bpf.Instruction{
+ // Get a 32-bit random number from the Linux kernel.
+ bpf.LoadExtension{Num: bpf.ExtRand},
+ // 1% dice roll?
+ bpf.JumpIf{Cond: bpf.JumpLessThan, Val: 2^32/100, SkipFalse: 1},
+ // Capture.
+ bpf.RetConstant{Val: 4096},
+ // Ignore.
+ bpf.RetConstant{Val: 0},
+ })
+*/
+package bpf // import "golang.org/x/net/bpf"
diff --git a/vendor/golang.org/x/net/bpf/instructions.go b/vendor/golang.org/x/net/bpf/instructions.go
@@ -0,0 +1,726 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package bpf
+
+import "fmt"
+
+// An Instruction is one instruction executed by the BPF virtual
+// machine.
+type Instruction interface {
+ // Assemble assembles the Instruction into a RawInstruction.
+ Assemble() (RawInstruction, error)
+}
+
+// A RawInstruction is a raw BPF virtual machine instruction.
+type RawInstruction struct {
+ // Operation to execute.
+ Op uint16
+ // For conditional jump instructions, the number of instructions
+ // to skip if the condition is true/false.
+ Jt uint8
+ Jf uint8
+ // Constant parameter. The meaning depends on the Op.
+ K uint32
+}
+
+// Assemble implements the Instruction Assemble method.
+func (ri RawInstruction) Assemble() (RawInstruction, error) { return ri, nil }
+
+// Disassemble parses ri into an Instruction and returns it. If ri is
+// not recognized by this package, ri itself is returned.
+func (ri RawInstruction) Disassemble() Instruction {
+ switch ri.Op & opMaskCls {
+ case opClsLoadA, opClsLoadX:
+ reg := Register(ri.Op & opMaskLoadDest)
+ sz := 0
+ switch ri.Op & opMaskLoadWidth {
+ case opLoadWidth4:
+ sz = 4
+ case opLoadWidth2:
+ sz = 2
+ case opLoadWidth1:
+ sz = 1
+ default:
+ return ri
+ }
+ switch ri.Op & opMaskLoadMode {
+ case opAddrModeImmediate:
+ if sz != 4 {
+ return ri
+ }
+ return LoadConstant{Dst: reg, Val: ri.K}
+ case opAddrModeScratch:
+ if sz != 4 || ri.K > 15 {
+ return ri
+ }
+ return LoadScratch{Dst: reg, N: int(ri.K)}
+ case opAddrModeAbsolute:
+ if ri.K > extOffset+0xffffffff {
+ return LoadExtension{Num: Extension(-extOffset + ri.K)}
+ }
+ return LoadAbsolute{Size: sz, Off: ri.K}
+ case opAddrModeIndirect:
+ return LoadIndirect{Size: sz, Off: ri.K}
+ case opAddrModePacketLen:
+ if sz != 4 {
+ return ri
+ }
+ return LoadExtension{Num: ExtLen}
+ case opAddrModeMemShift:
+ return LoadMemShift{Off: ri.K}
+ default:
+ return ri
+ }
+
+ case opClsStoreA:
+ if ri.Op != opClsStoreA || ri.K > 15 {
+ return ri
+ }
+ return StoreScratch{Src: RegA, N: int(ri.K)}
+
+ case opClsStoreX:
+ if ri.Op != opClsStoreX || ri.K > 15 {
+ return ri
+ }
+ return StoreScratch{Src: RegX, N: int(ri.K)}
+
+ case opClsALU:
+ switch op := ALUOp(ri.Op & opMaskOperator); op {
+ case ALUOpAdd, ALUOpSub, ALUOpMul, ALUOpDiv, ALUOpOr, ALUOpAnd, ALUOpShiftLeft, ALUOpShiftRight, ALUOpMod, ALUOpXor:
+ switch operand := opOperand(ri.Op & opMaskOperand); operand {
+ case opOperandX:
+ return ALUOpX{Op: op}
+ case opOperandConstant:
+ return ALUOpConstant{Op: op, Val: ri.K}
+ default:
+ return ri
+ }
+ case aluOpNeg:
+ return NegateA{}
+ default:
+ return ri
+ }
+
+ case opClsJump:
+ switch op := jumpOp(ri.Op & opMaskOperator); op {
+ case opJumpAlways:
+ return Jump{Skip: ri.K}
+ case opJumpEqual, opJumpGT, opJumpGE, opJumpSet:
+ cond, skipTrue, skipFalse := jumpOpToTest(op, ri.Jt, ri.Jf)
+ switch operand := opOperand(ri.Op & opMaskOperand); operand {
+ case opOperandX:
+ return JumpIfX{Cond: cond, SkipTrue: skipTrue, SkipFalse: skipFalse}
+ case opOperandConstant:
+ return JumpIf{Cond: cond, Val: ri.K, SkipTrue: skipTrue, SkipFalse: skipFalse}
+ default:
+ return ri
+ }
+ default:
+ return ri
+ }
+
+ case opClsReturn:
+ switch ri.Op {
+ case opClsReturn | opRetSrcA:
+ return RetA{}
+ case opClsReturn | opRetSrcConstant:
+ return RetConstant{Val: ri.K}
+ default:
+ return ri
+ }
+
+ case opClsMisc:
+ switch ri.Op {
+ case opClsMisc | opMiscTAX:
+ return TAX{}
+ case opClsMisc | opMiscTXA:
+ return TXA{}
+ default:
+ return ri
+ }
+
+ default:
+ panic("unreachable") // switch is exhaustive on the bit pattern
+ }
+}
+
+func jumpOpToTest(op jumpOp, skipTrue uint8, skipFalse uint8) (JumpTest, uint8, uint8) {
+ var test JumpTest
+
+ // Decode "fake" jump conditions that don't appear in machine code
+ // Ensures the Assemble -> Disassemble stage recreates the same instructions
+ // See https://github.com/golang/go/issues/18470
+ if skipTrue == 0 {
+ switch op {
+ case opJumpEqual:
+ test = JumpNotEqual
+ case opJumpGT:
+ test = JumpLessOrEqual
+ case opJumpGE:
+ test = JumpLessThan
+ case opJumpSet:
+ test = JumpBitsNotSet
+ }
+
+ return test, skipFalse, 0
+ }
+
+ switch op {
+ case opJumpEqual:
+ test = JumpEqual
+ case opJumpGT:
+ test = JumpGreaterThan
+ case opJumpGE:
+ test = JumpGreaterOrEqual
+ case opJumpSet:
+ test = JumpBitsSet
+ }
+
+ return test, skipTrue, skipFalse
+}
+
+// LoadConstant loads Val into register Dst.
+type LoadConstant struct {
+ Dst Register
+ Val uint32
+}
+
+// Assemble implements the Instruction Assemble method.
+func (a LoadConstant) Assemble() (RawInstruction, error) {
+ return assembleLoad(a.Dst, 4, opAddrModeImmediate, a.Val)
+}
+
+// String returns the instruction in assembler notation.
+func (a LoadConstant) String() string {
+ switch a.Dst {
+ case RegA:
+ return fmt.Sprintf("ld #%d", a.Val)
+ case RegX:
+ return fmt.Sprintf("ldx #%d", a.Val)
+ default:
+ return fmt.Sprintf("unknown instruction: %#v", a)
+ }
+}
+
+// LoadScratch loads scratch[N] into register Dst.
+type LoadScratch struct {
+ Dst Register
+ N int // 0-15
+}
+
+// Assemble implements the Instruction Assemble method.
+func (a LoadScratch) Assemble() (RawInstruction, error) {
+ if a.N < 0 || a.N > 15 {
+ return RawInstruction{}, fmt.Errorf("invalid scratch slot %d", a.N)
+ }
+ return assembleLoad(a.Dst, 4, opAddrModeScratch, uint32(a.N))
+}
+
+// String returns the instruction in assembler notation.
+func (a LoadScratch) String() string {
+ switch a.Dst {
+ case RegA:
+ return fmt.Sprintf("ld M[%d]", a.N)
+ case RegX:
+ return fmt.Sprintf("ldx M[%d]", a.N)
+ default:
+ return fmt.Sprintf("unknown instruction: %#v", a)
+ }
+}
+
+// LoadAbsolute loads packet[Off:Off+Size] as an integer value into
+// register A.
+type LoadAbsolute struct {
+ Off uint32
+ Size int // 1, 2 or 4
+}
+
+// Assemble implements the Instruction Assemble method.
+func (a LoadAbsolute) Assemble() (RawInstruction, error) {
+ return assembleLoad(RegA, a.Size, opAddrModeAbsolute, a.Off)
+}
+
+// String returns the instruction in assembler notation.
+func (a LoadAbsolute) String() string {
+ switch a.Size {
+ case 1: // byte
+ return fmt.Sprintf("ldb [%d]", a.Off)
+ case 2: // half word
+ return fmt.Sprintf("ldh [%d]", a.Off)
+ case 4: // word
+ if a.Off > extOffset+0xffffffff {
+ return LoadExtension{Num: Extension(a.Off + 0x1000)}.String()
+ }
+ return fmt.Sprintf("ld [%d]", a.Off)
+ default:
+ return fmt.Sprintf("unknown instruction: %#v", a)
+ }
+}
+
+// LoadIndirect loads packet[X+Off:X+Off+Size] as an integer value
+// into register A.
+type LoadIndirect struct {
+ Off uint32
+ Size int // 1, 2 or 4
+}
+
+// Assemble implements the Instruction Assemble method.
+func (a LoadIndirect) Assemble() (RawInstruction, error) {
+ return assembleLoad(RegA, a.Size, opAddrModeIndirect, a.Off)
+}
+
+// String returns the instruction in assembler notation.
+func (a LoadIndirect) String() string {
+ switch a.Size {
+ case 1: // byte
+ return fmt.Sprintf("ldb [x + %d]", a.Off)
+ case 2: // half word
+ return fmt.Sprintf("ldh [x + %d]", a.Off)
+ case 4: // word
+ return fmt.Sprintf("ld [x + %d]", a.Off)
+ default:
+ return fmt.Sprintf("unknown instruction: %#v", a)
+ }
+}
+
+// LoadMemShift multiplies the first 4 bits of the byte at packet[Off]
+// by 4 and stores the result in register X.
+//
+// This instruction is mainly useful to load into X the length of an
+// IPv4 packet header in a single instruction, rather than have to do
+// the arithmetic on the header's first byte by hand.
+type LoadMemShift struct {
+ Off uint32
+}
+
+// Assemble implements the Instruction Assemble method.
+func (a LoadMemShift) Assemble() (RawInstruction, error) {
+ return assembleLoad(RegX, 1, opAddrModeMemShift, a.Off)
+}
+
+// String returns the instruction in assembler notation.
+func (a LoadMemShift) String() string {
+ return fmt.Sprintf("ldx 4*([%d]&0xf)", a.Off)
+}
+
+// LoadExtension invokes a linux-specific extension and stores the
+// result in register A.
+type LoadExtension struct {
+ Num Extension
+}
+
+// Assemble implements the Instruction Assemble method.
+func (a LoadExtension) Assemble() (RawInstruction, error) {
+ if a.Num == ExtLen {
+ return assembleLoad(RegA, 4, opAddrModePacketLen, 0)
+ }
+ return assembleLoad(RegA, 4, opAddrModeAbsolute, uint32(extOffset+a.Num))
+}
+
+// String returns the instruction in assembler notation.
+func (a LoadExtension) String() string {
+ switch a.Num {
+ case ExtLen:
+ return "ld #len"
+ case ExtProto:
+ return "ld #proto"
+ case ExtType:
+ return "ld #type"
+ case ExtPayloadOffset:
+ return "ld #poff"
+ case ExtInterfaceIndex:
+ return "ld #ifidx"
+ case ExtNetlinkAttr:
+ return "ld #nla"
+ case ExtNetlinkAttrNested:
+ return "ld #nlan"
+ case ExtMark:
+ return "ld #mark"
+ case ExtQueue:
+ return "ld #queue"
+ case ExtLinkLayerType:
+ return "ld #hatype"
+ case ExtRXHash:
+ return "ld #rxhash"
+ case ExtCPUID:
+ return "ld #cpu"
+ case ExtVLANTag:
+ return "ld #vlan_tci"
+ case ExtVLANTagPresent:
+ return "ld #vlan_avail"
+ case ExtVLANProto:
+ return "ld #vlan_tpid"
+ case ExtRand:
+ return "ld #rand"
+ default:
+ return fmt.Sprintf("unknown instruction: %#v", a)
+ }
+}
+
+// StoreScratch stores register Src into scratch[N].
+type StoreScratch struct {
+ Src Register
+ N int // 0-15
+}
+
+// Assemble implements the Instruction Assemble method.
+func (a StoreScratch) Assemble() (RawInstruction, error) {
+ if a.N < 0 || a.N > 15 {
+ return RawInstruction{}, fmt.Errorf("invalid scratch slot %d", a.N)
+ }
+ var op uint16
+ switch a.Src {
+ case RegA:
+ op = opClsStoreA
+ case RegX:
+ op = opClsStoreX
+ default:
+ return RawInstruction{}, fmt.Errorf("invalid source register %v", a.Src)
+ }
+
+ return RawInstruction{
+ Op: op,
+ K: uint32(a.N),
+ }, nil
+}
+
+// String returns the instruction in assembler notation.
+func (a StoreScratch) String() string {
+ switch a.Src {
+ case RegA:
+ return fmt.Sprintf("st M[%d]", a.N)
+ case RegX:
+ return fmt.Sprintf("stx M[%d]", a.N)
+ default:
+ return fmt.Sprintf("unknown instruction: %#v", a)
+ }
+}
+
+// ALUOpConstant executes A = A <Op> Val.
+type ALUOpConstant struct {
+ Op ALUOp
+ Val uint32
+}
+
+// Assemble implements the Instruction Assemble method.
+func (a ALUOpConstant) Assemble() (RawInstruction, error) {
+ return RawInstruction{
+ Op: opClsALU | uint16(opOperandConstant) | uint16(a.Op),
+ K: a.Val,
+ }, nil
+}
+
+// String returns the instruction in assembler notation.
+func (a ALUOpConstant) String() string {
+ switch a.Op {
+ case ALUOpAdd:
+ return fmt.Sprintf("add #%d", a.Val)
+ case ALUOpSub:
+ return fmt.Sprintf("sub #%d", a.Val)
+ case ALUOpMul:
+ return fmt.Sprintf("mul #%d", a.Val)
+ case ALUOpDiv:
+ return fmt.Sprintf("div #%d", a.Val)
+ case ALUOpMod:
+ return fmt.Sprintf("mod #%d", a.Val)
+ case ALUOpAnd:
+ return fmt.Sprintf("and #%d", a.Val)
+ case ALUOpOr:
+ return fmt.Sprintf("or #%d", a.Val)
+ case ALUOpXor:
+ return fmt.Sprintf("xor #%d", a.Val)
+ case ALUOpShiftLeft:
+ return fmt.Sprintf("lsh #%d", a.Val)
+ case ALUOpShiftRight:
+ return fmt.Sprintf("rsh #%d", a.Val)
+ default:
+ return fmt.Sprintf("unknown instruction: %#v", a)
+ }
+}
+
+// ALUOpX executes A = A <Op> X
+type ALUOpX struct {
+ Op ALUOp
+}
+
+// Assemble implements the Instruction Assemble method.
+func (a ALUOpX) Assemble() (RawInstruction, error) {
+ return RawInstruction{
+ Op: opClsALU | uint16(opOperandX) | uint16(a.Op),
+ }, nil
+}
+
+// String returns the instruction in assembler notation.
+func (a ALUOpX) String() string {
+ switch a.Op {
+ case ALUOpAdd:
+ return "add x"
+ case ALUOpSub:
+ return "sub x"
+ case ALUOpMul:
+ return "mul x"
+ case ALUOpDiv:
+ return "div x"
+ case ALUOpMod:
+ return "mod x"
+ case ALUOpAnd:
+ return "and x"
+ case ALUOpOr:
+ return "or x"
+ case ALUOpXor:
+ return "xor x"
+ case ALUOpShiftLeft:
+ return "lsh x"
+ case ALUOpShiftRight:
+ return "rsh x"
+ default:
+ return fmt.Sprintf("unknown instruction: %#v", a)
+ }
+}
+
+// NegateA executes A = -A.
+type NegateA struct{}
+
+// Assemble implements the Instruction Assemble method.
+func (a NegateA) Assemble() (RawInstruction, error) {
+ return RawInstruction{
+ Op: opClsALU | uint16(aluOpNeg),
+ }, nil
+}
+
+// String returns the instruction in assembler notation.
+func (a NegateA) String() string {
+ return fmt.Sprintf("neg")
+}
+
+// Jump skips the following Skip instructions in the program.
+type Jump struct {
+ Skip uint32
+}
+
+// Assemble implements the Instruction Assemble method.
+func (a Jump) Assemble() (RawInstruction, error) {
+ return RawInstruction{
+ Op: opClsJump | uint16(opJumpAlways),
+ K: a.Skip,
+ }, nil
+}
+
+// String returns the instruction in assembler notation.
+func (a Jump) String() string {
+ return fmt.Sprintf("ja %d", a.Skip)
+}
+
+// JumpIf skips the following Skip instructions in the program if A
+// <Cond> Val is true.
+type JumpIf struct {
+ Cond JumpTest
+ Val uint32
+ SkipTrue uint8
+ SkipFalse uint8
+}
+
+// Assemble implements the Instruction Assemble method.
+func (a JumpIf) Assemble() (RawInstruction, error) {
+ return jumpToRaw(a.Cond, opOperandConstant, a.Val, a.SkipTrue, a.SkipFalse)
+}
+
+// String returns the instruction in assembler notation.
+func (a JumpIf) String() string {
+ return jumpToString(a.Cond, fmt.Sprintf("#%d", a.Val), a.SkipTrue, a.SkipFalse)
+}
+
+// JumpIfX skips the following Skip instructions in the program if A
+// <Cond> X is true.
+type JumpIfX struct {
+ Cond JumpTest
+ SkipTrue uint8
+ SkipFalse uint8
+}
+
+// Assemble implements the Instruction Assemble method.
+func (a JumpIfX) Assemble() (RawInstruction, error) {
+ return jumpToRaw(a.Cond, opOperandX, 0, a.SkipTrue, a.SkipFalse)
+}
+
+// String returns the instruction in assembler notation.
+func (a JumpIfX) String() string {
+ return jumpToString(a.Cond, "x", a.SkipTrue, a.SkipFalse)
+}
+
+// jumpToRaw assembles a jump instruction into a RawInstruction
+func jumpToRaw(test JumpTest, operand opOperand, k uint32, skipTrue, skipFalse uint8) (RawInstruction, error) {
+ var (
+ cond jumpOp
+ flip bool
+ )
+ switch test {
+ case JumpEqual:
+ cond = opJumpEqual
+ case JumpNotEqual:
+ cond, flip = opJumpEqual, true
+ case JumpGreaterThan:
+ cond = opJumpGT
+ case JumpLessThan:
+ cond, flip = opJumpGE, true
+ case JumpGreaterOrEqual:
+ cond = opJumpGE
+ case JumpLessOrEqual:
+ cond, flip = opJumpGT, true
+ case JumpBitsSet:
+ cond = opJumpSet
+ case JumpBitsNotSet:
+ cond, flip = opJumpSet, true
+ default:
+ return RawInstruction{}, fmt.Errorf("unknown JumpTest %v", test)
+ }
+ jt, jf := skipTrue, skipFalse
+ if flip {
+ jt, jf = jf, jt
+ }
+ return RawInstruction{
+ Op: opClsJump | uint16(cond) | uint16(operand),
+ Jt: jt,
+ Jf: jf,
+ K: k,
+ }, nil
+}
+
+// jumpToString converts a jump instruction to assembler notation
+func jumpToString(cond JumpTest, operand string, skipTrue, skipFalse uint8) string {
+ switch cond {
+ // K == A
+ case JumpEqual:
+ return conditionalJump(operand, skipTrue, skipFalse, "jeq", "jneq")
+ // K != A
+ case JumpNotEqual:
+ return fmt.Sprintf("jneq %s,%d", operand, skipTrue)
+ // K > A
+ case JumpGreaterThan:
+ return conditionalJump(operand, skipTrue, skipFalse, "jgt", "jle")
+ // K < A
+ case JumpLessThan:
+ return fmt.Sprintf("jlt %s,%d", operand, skipTrue)
+ // K >= A
+ case JumpGreaterOrEqual:
+ return conditionalJump(operand, skipTrue, skipFalse, "jge", "jlt")
+ // K <= A
+ case JumpLessOrEqual:
+ return fmt.Sprintf("jle %s,%d", operand, skipTrue)
+ // K & A != 0
+ case JumpBitsSet:
+ if skipFalse > 0 {
+ return fmt.Sprintf("jset %s,%d,%d", operand, skipTrue, skipFalse)
+ }
+ return fmt.Sprintf("jset %s,%d", operand, skipTrue)
+ // K & A == 0, there is no assembler instruction for JumpBitNotSet, use JumpBitSet and invert skips
+ case JumpBitsNotSet:
+ return jumpToString(JumpBitsSet, operand, skipFalse, skipTrue)
+ default:
+ return fmt.Sprintf("unknown JumpTest %#v", cond)
+ }
+}
+
+func conditionalJump(operand string, skipTrue, skipFalse uint8, positiveJump, negativeJump string) string {
+ if skipTrue > 0 {
+ if skipFalse > 0 {
+ return fmt.Sprintf("%s %s,%d,%d", positiveJump, operand, skipTrue, skipFalse)
+ }
+ return fmt.Sprintf("%s %s,%d", positiveJump, operand, skipTrue)
+ }
+ return fmt.Sprintf("%s %s,%d", negativeJump, operand, skipFalse)
+}
+
+// RetA exits the BPF program, returning the value of register A.
+type RetA struct{}
+
+// Assemble implements the Instruction Assemble method.
+func (a RetA) Assemble() (RawInstruction, error) {
+ return RawInstruction{
+ Op: opClsReturn | opRetSrcA,
+ }, nil
+}
+
+// String returns the instruction in assembler notation.
+func (a RetA) String() string {
+ return fmt.Sprintf("ret a")
+}
+
+// RetConstant exits the BPF program, returning a constant value.
+type RetConstant struct {
+ Val uint32
+}
+
+// Assemble implements the Instruction Assemble method.
+func (a RetConstant) Assemble() (RawInstruction, error) {
+ return RawInstruction{
+ Op: opClsReturn | opRetSrcConstant,
+ K: a.Val,
+ }, nil
+}
+
+// String returns the instruction in assembler notation.
+func (a RetConstant) String() string {
+ return fmt.Sprintf("ret #%d", a.Val)
+}
+
+// TXA copies the value of register X to register A.
+type TXA struct{}
+
+// Assemble implements the Instruction Assemble method.
+func (a TXA) Assemble() (RawInstruction, error) {
+ return RawInstruction{
+ Op: opClsMisc | opMiscTXA,
+ }, nil
+}
+
+// String returns the instruction in assembler notation.
+func (a TXA) String() string {
+ return fmt.Sprintf("txa")
+}
+
+// TAX copies the value of register A to register X.
+type TAX struct{}
+
+// Assemble implements the Instruction Assemble method.
+func (a TAX) Assemble() (RawInstruction, error) {
+ return RawInstruction{
+ Op: opClsMisc | opMiscTAX,
+ }, nil
+}
+
+// String returns the instruction in assembler notation.
+func (a TAX) String() string {
+ return fmt.Sprintf("tax")
+}
+
+func assembleLoad(dst Register, loadSize int, mode uint16, k uint32) (RawInstruction, error) {
+ var (
+ cls uint16
+ sz uint16
+ )
+ switch dst {
+ case RegA:
+ cls = opClsLoadA
+ case RegX:
+ cls = opClsLoadX
+ default:
+ return RawInstruction{}, fmt.Errorf("invalid target register %v", dst)
+ }
+ switch loadSize {
+ case 1:
+ sz = opLoadWidth1
+ case 2:
+ sz = opLoadWidth2
+ case 4:
+ sz = opLoadWidth4
+ default:
+ return RawInstruction{}, fmt.Errorf("invalid load byte length %d", sz)
+ }
+ return RawInstruction{
+ Op: cls | sz | mode,
+ K: k,
+ }, nil
+}
diff --git a/vendor/golang.org/x/net/bpf/setter.go b/vendor/golang.org/x/net/bpf/setter.go
@@ -0,0 +1,10 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package bpf
+
+// A Setter is a type which can attach a compiled BPF filter to itself.
+type Setter interface {
+ SetBPF(filter []RawInstruction) error
+}
diff --git a/vendor/golang.org/x/net/bpf/vm.go b/vendor/golang.org/x/net/bpf/vm.go
@@ -0,0 +1,150 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package bpf
+
+import (
+ "errors"
+ "fmt"
+)
+
+// A VM is an emulated BPF virtual machine.
+type VM struct {
+ filter []Instruction
+}
+
+// NewVM returns a new VM using the input BPF program.
+func NewVM(filter []Instruction) (*VM, error) {
+ if len(filter) == 0 {
+ return nil, errors.New("one or more Instructions must be specified")
+ }
+
+ for i, ins := range filter {
+ check := len(filter) - (i + 1)
+ switch ins := ins.(type) {
+ // Check for out-of-bounds jumps in instructions
+ case Jump:
+ if check <= int(ins.Skip) {
+ return nil, fmt.Errorf("cannot jump %d instructions; jumping past program bounds", ins.Skip)
+ }
+ case JumpIf:
+ if check <= int(ins.SkipTrue) {
+ return nil, fmt.Errorf("cannot jump %d instructions in true case; jumping past program bounds", ins.SkipTrue)
+ }
+ if check <= int(ins.SkipFalse) {
+ return nil, fmt.Errorf("cannot jump %d instructions in false case; jumping past program bounds", ins.SkipFalse)
+ }
+ case JumpIfX:
+ if check <= int(ins.SkipTrue) {
+ return nil, fmt.Errorf("cannot jump %d instructions in true case; jumping past program bounds", ins.SkipTrue)
+ }
+ if check <= int(ins.SkipFalse) {
+ return nil, fmt.Errorf("cannot jump %d instructions in false case; jumping past program bounds", ins.SkipFalse)
+ }
+ // Check for division or modulus by zero
+ case ALUOpConstant:
+ if ins.Val != 0 {
+ break
+ }
+
+ switch ins.Op {
+ case ALUOpDiv, ALUOpMod:
+ return nil, errors.New("cannot divide by zero using ALUOpConstant")
+ }
+ // Check for unknown extensions
+ case LoadExtension:
+ switch ins.Num {
+ case ExtLen:
+ default:
+ return nil, fmt.Errorf("extension %d not implemented", ins.Num)
+ }
+ }
+ }
+
+ // Make sure last instruction is a return instruction
+ switch filter[len(filter)-1].(type) {
+ case RetA, RetConstant:
+ default:
+ return nil, errors.New("BPF program must end with RetA or RetConstant")
+ }
+
+ // Though our VM works using disassembled instructions, we
+ // attempt to assemble the input filter anyway to ensure it is compatible
+ // with an operating system VM.
+ _, err := Assemble(filter)
+
+ return &VM{
+ filter: filter,
+ }, err
+}
+
+// Run runs the VM's BPF program against the input bytes.
+// Run returns the number of bytes accepted by the BPF program, and any errors
+// which occurred while processing the program.
+func (v *VM) Run(in []byte) (int, error) {
+ var (
+ // Registers of the virtual machine
+ regA uint32
+ regX uint32
+ regScratch [16]uint32
+
+ // OK is true if the program should continue processing the next
+ // instruction, or false if not, causing the loop to break
+ ok = true
+ )
+
+ // TODO(mdlayher): implement:
+ // - NegateA:
+ // - would require a change from uint32 registers to int32
+ // registers
+
+ // TODO(mdlayher): add interop tests that check signedness of ALU
+ // operations against kernel implementation, and make sure Go
+ // implementation matches behavior
+
+ for i := 0; i < len(v.filter) && ok; i++ {
+ ins := v.filter[i]
+
+ switch ins := ins.(type) {
+ case ALUOpConstant:
+ regA = aluOpConstant(ins, regA)
+ case ALUOpX:
+ regA, ok = aluOpX(ins, regA, regX)
+ case Jump:
+ i += int(ins.Skip)
+ case JumpIf:
+ jump := jumpIf(ins, regA)
+ i += jump
+ case JumpIfX:
+ jump := jumpIfX(ins, regA, regX)
+ i += jump
+ case LoadAbsolute:
+ regA, ok = loadAbsolute(ins, in)
+ case LoadConstant:
+ regA, regX = loadConstant(ins, regA, regX)
+ case LoadExtension:
+ regA = loadExtension(ins, in)
+ case LoadIndirect:
+ regA, ok = loadIndirect(ins, in, regX)
+ case LoadMemShift:
+ regX, ok = loadMemShift(ins, in)
+ case LoadScratch:
+ regA, regX = loadScratch(ins, regScratch, regA, regX)
+ case RetA:
+ return int(regA), nil
+ case RetConstant:
+ return int(ins.Val), nil
+ case StoreScratch:
+ regScratch = storeScratch(ins, regScratch, regA, regX)
+ case TAX:
+ regX = regA
+ case TXA:
+ regA = regX
+ default:
+ return 0, fmt.Errorf("unknown Instruction at index %d: %T", i, ins)
+ }
+ }
+
+ return 0, nil
+}
diff --git a/vendor/golang.org/x/net/bpf/vm_instructions.go b/vendor/golang.org/x/net/bpf/vm_instructions.go
@@ -0,0 +1,182 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package bpf
+
+import (
+ "encoding/binary"
+ "fmt"
+)
+
+func aluOpConstant(ins ALUOpConstant, regA uint32) uint32 {
+ return aluOpCommon(ins.Op, regA, ins.Val)
+}
+
+func aluOpX(ins ALUOpX, regA uint32, regX uint32) (uint32, bool) {
+ // Guard against division or modulus by zero by terminating
+ // the program, as the OS BPF VM does
+ if regX == 0 {
+ switch ins.Op {
+ case ALUOpDiv, ALUOpMod:
+ return 0, false
+ }
+ }
+
+ return aluOpCommon(ins.Op, regA, regX), true
+}
+
+func aluOpCommon(op ALUOp, regA uint32, value uint32) uint32 {
+ switch op {
+ case ALUOpAdd:
+ return regA + value
+ case ALUOpSub:
+ return regA - value
+ case ALUOpMul:
+ return regA * value
+ case ALUOpDiv:
+ // Division by zero not permitted by NewVM and aluOpX checks
+ return regA / value
+ case ALUOpOr:
+ return regA | value
+ case ALUOpAnd:
+ return regA & value
+ case ALUOpShiftLeft:
+ return regA << value
+ case ALUOpShiftRight:
+ return regA >> value
+ case ALUOpMod:
+ // Modulus by zero not permitted by NewVM and aluOpX checks
+ return regA % value
+ case ALUOpXor:
+ return regA ^ value
+ default:
+ return regA
+ }
+}
+
+func jumpIf(ins JumpIf, regA uint32) int {
+ return jumpIfCommon(ins.Cond, ins.SkipTrue, ins.SkipFalse, regA, ins.Val)
+}
+
+func jumpIfX(ins JumpIfX, regA uint32, regX uint32) int {
+ return jumpIfCommon(ins.Cond, ins.SkipTrue, ins.SkipFalse, regA, regX)
+}
+
+func jumpIfCommon(cond JumpTest, skipTrue, skipFalse uint8, regA uint32, value uint32) int {
+ var ok bool
+
+ switch cond {
+ case JumpEqual:
+ ok = regA == value
+ case JumpNotEqual:
+ ok = regA != value
+ case JumpGreaterThan:
+ ok = regA > value
+ case JumpLessThan:
+ ok = regA < value
+ case JumpGreaterOrEqual:
+ ok = regA >= value
+ case JumpLessOrEqual:
+ ok = regA <= value
+ case JumpBitsSet:
+ ok = (regA & value) != 0
+ case JumpBitsNotSet:
+ ok = (regA & value) == 0
+ }
+
+ if ok {
+ return int(skipTrue)
+ }
+
+ return int(skipFalse)
+}
+
+func loadAbsolute(ins LoadAbsolute, in []byte) (uint32, bool) {
+ offset := int(ins.Off)
+ size := int(ins.Size)
+
+ return loadCommon(in, offset, size)
+}
+
+func loadConstant(ins LoadConstant, regA uint32, regX uint32) (uint32, uint32) {
+ switch ins.Dst {
+ case RegA:
+ regA = ins.Val
+ case RegX:
+ regX = ins.Val
+ }
+
+ return regA, regX
+}
+
+func loadExtension(ins LoadExtension, in []byte) uint32 {
+ switch ins.Num {
+ case ExtLen:
+ return uint32(len(in))
+ default:
+ panic(fmt.Sprintf("unimplemented extension: %d", ins.Num))
+ }
+}
+
+func loadIndirect(ins LoadIndirect, in []byte, regX uint32) (uint32, bool) {
+ offset := int(ins.Off) + int(regX)
+ size := int(ins.Size)
+
+ return loadCommon(in, offset, size)
+}
+
+func loadMemShift(ins LoadMemShift, in []byte) (uint32, bool) {
+ offset := int(ins.Off)
+
+ // Size of LoadMemShift is always 1 byte
+ if !inBounds(len(in), offset, 1) {
+ return 0, false
+ }
+
+ // Mask off high 4 bits and multiply low 4 bits by 4
+ return uint32(in[offset]&0x0f) * 4, true
+}
+
+func inBounds(inLen int, offset int, size int) bool {
+ return offset+size <= inLen
+}
+
+func loadCommon(in []byte, offset int, size int) (uint32, bool) {
+ if !inBounds(len(in), offset, size) {
+ return 0, false
+ }
+
+ switch size {
+ case 1:
+ return uint32(in[offset]), true
+ case 2:
+ return uint32(binary.BigEndian.Uint16(in[offset : offset+size])), true
+ case 4:
+ return uint32(binary.BigEndian.Uint32(in[offset : offset+size])), true
+ default:
+ panic(fmt.Sprintf("invalid load size: %d", size))
+ }
+}
+
+func loadScratch(ins LoadScratch, regScratch [16]uint32, regA uint32, regX uint32) (uint32, uint32) {
+ switch ins.Dst {
+ case RegA:
+ regA = regScratch[ins.N]
+ case RegX:
+ regX = regScratch[ins.N]
+ }
+
+ return regA, regX
+}
+
+func storeScratch(ins StoreScratch, regScratch [16]uint32, regA uint32, regX uint32) [16]uint32 {
+ switch ins.Src {
+ case RegA:
+ regScratch[ins.N] = regA
+ case RegX:
+ regScratch[ins.N] = regX
+ }
+
+ return regScratch
+}
diff --git a/vendor/golang.org/x/net/internal/iana/const.go b/vendor/golang.org/x/net/internal/iana/const.go
@@ -0,0 +1,223 @@
+// go generate gen.go
+// Code generated by the command above; DO NOT EDIT.
+
+// Package iana provides protocol number resources managed by the Internet Assigned Numbers Authority (IANA).
+package iana // import "golang.org/x/net/internal/iana"
+
+// Differentiated Services Field Codepoints (DSCP), Updated: 2018-05-04
+const (
+ DiffServCS0 = 0x00 // CS0
+ DiffServCS1 = 0x20 // CS1
+ DiffServCS2 = 0x40 // CS2
+ DiffServCS3 = 0x60 // CS3
+ DiffServCS4 = 0x80 // CS4
+ DiffServCS5 = 0xa0 // CS5
+ DiffServCS6 = 0xc0 // CS6
+ DiffServCS7 = 0xe0 // CS7
+ DiffServAF11 = 0x28 // AF11
+ DiffServAF12 = 0x30 // AF12
+ DiffServAF13 = 0x38 // AF13
+ DiffServAF21 = 0x48 // AF21
+ DiffServAF22 = 0x50 // AF22
+ DiffServAF23 = 0x58 // AF23
+ DiffServAF31 = 0x68 // AF31
+ DiffServAF32 = 0x70 // AF32
+ DiffServAF33 = 0x78 // AF33
+ DiffServAF41 = 0x88 // AF41
+ DiffServAF42 = 0x90 // AF42
+ DiffServAF43 = 0x98 // AF43
+ DiffServEF = 0xb8 // EF
+ DiffServVOICEADMIT = 0xb0 // VOICE-ADMIT
+ NotECNTransport = 0x00 // Not-ECT (Not ECN-Capable Transport)
+ ECNTransport1 = 0x01 // ECT(1) (ECN-Capable Transport(1))
+ ECNTransport0 = 0x02 // ECT(0) (ECN-Capable Transport(0))
+ CongestionExperienced = 0x03 // CE (Congestion Experienced)
+)
+
+// Protocol Numbers, Updated: 2017-10-13
+const (
+ ProtocolIP = 0 // IPv4 encapsulation, pseudo protocol number
+ ProtocolHOPOPT = 0 // IPv6 Hop-by-Hop Option
+ ProtocolICMP = 1 // Internet Control Message
+ ProtocolIGMP = 2 // Internet Group Management
+ ProtocolGGP = 3 // Gateway-to-Gateway
+ ProtocolIPv4 = 4 // IPv4 encapsulation
+ ProtocolST = 5 // Stream
+ ProtocolTCP = 6 // Transmission Control
+ ProtocolCBT = 7 // CBT
+ ProtocolEGP = 8 // Exterior Gateway Protocol
+ ProtocolIGP = 9 // any private interior gateway (used by Cisco for their IGRP)
+ ProtocolBBNRCCMON = 10 // BBN RCC Monitoring
+ ProtocolNVPII = 11 // Network Voice Protocol
+ ProtocolPUP = 12 // PUP
+ ProtocolEMCON = 14 // EMCON
+ ProtocolXNET = 15 // Cross Net Debugger
+ ProtocolCHAOS = 16 // Chaos
+ ProtocolUDP = 17 // User Datagram
+ ProtocolMUX = 18 // Multiplexing
+ ProtocolDCNMEAS = 19 // DCN Measurement Subsystems
+ ProtocolHMP = 20 // Host Monitoring
+ ProtocolPRM = 21 // Packet Radio Measurement
+ ProtocolXNSIDP = 22 // XEROX NS IDP
+ ProtocolTRUNK1 = 23 // Trunk-1
+ ProtocolTRUNK2 = 24 // Trunk-2
+ ProtocolLEAF1 = 25 // Leaf-1
+ ProtocolLEAF2 = 26 // Leaf-2
+ ProtocolRDP = 27 // Reliable Data Protocol
+ ProtocolIRTP = 28 // Internet Reliable Transaction
+ ProtocolISOTP4 = 29 // ISO Transport Protocol Class 4
+ ProtocolNETBLT = 30 // Bulk Data Transfer Protocol
+ ProtocolMFENSP = 31 // MFE Network Services Protocol
+ ProtocolMERITINP = 32 // MERIT Internodal Protocol
+ ProtocolDCCP = 33 // Datagram Congestion Control Protocol
+ Protocol3PC = 34 // Third Party Connect Protocol
+ ProtocolIDPR = 35 // Inter-Domain Policy Routing Protocol
+ ProtocolXTP = 36 // XTP
+ ProtocolDDP = 37 // Datagram Delivery Protocol
+ ProtocolIDPRCMTP = 38 // IDPR Control Message Transport Proto
+ ProtocolTPPP = 39 // TP++ Transport Protocol
+ ProtocolIL = 40 // IL Transport Protocol
+ ProtocolIPv6 = 41 // IPv6 encapsulation
+ ProtocolSDRP = 42 // Source Demand Routing Protocol
+ ProtocolIPv6Route = 43 // Routing Header for IPv6
+ ProtocolIPv6Frag = 44 // Fragment Header for IPv6
+ ProtocolIDRP = 45 // Inter-Domain Routing Protocol
+ ProtocolRSVP = 46 // Reservation Protocol
+ ProtocolGRE = 47 // Generic Routing Encapsulation
+ ProtocolDSR = 48 // Dynamic Source Routing Protocol
+ ProtocolBNA = 49 // BNA
+ ProtocolESP = 50 // Encap Security Payload
+ ProtocolAH = 51 // Authentication Header
+ ProtocolINLSP = 52 // Integrated Net Layer Security TUBA
+ ProtocolNARP = 54 // NBMA Address Resolution Protocol
+ ProtocolMOBILE = 55 // IP Mobility
+ ProtocolTLSP = 56 // Transport Layer Security Protocol using Kryptonet key management
+ ProtocolSKIP = 57 // SKIP
+ ProtocolIPv6ICMP = 58 // ICMP for IPv6
+ ProtocolIPv6NoNxt = 59 // No Next Header for IPv6
+ ProtocolIPv6Opts = 60 // Destination Options for IPv6
+ ProtocolCFTP = 62 // CFTP
+ ProtocolSATEXPAK = 64 // SATNET and Backroom EXPAK
+ ProtocolKRYPTOLAN = 65 // Kryptolan
+ ProtocolRVD = 66 // MIT Remote Virtual Disk Protocol
+ ProtocolIPPC = 67 // Internet Pluribus Packet Core
+ ProtocolSATMON = 69 // SATNET Monitoring
+ ProtocolVISA = 70 // VISA Protocol
+ ProtocolIPCV = 71 // Internet Packet Core Utility
+ ProtocolCPNX = 72 // Computer Protocol Network Executive
+ ProtocolCPHB = 73 // Computer Protocol Heart Beat
+ ProtocolWSN = 74 // Wang Span Network
+ ProtocolPVP = 75 // Packet Video Protocol
+ ProtocolBRSATMON = 76 // Backroom SATNET Monitoring
+ ProtocolSUNND = 77 // SUN ND PROTOCOL-Temporary
+ ProtocolWBMON = 78 // WIDEBAND Monitoring
+ ProtocolWBEXPAK = 79 // WIDEBAND EXPAK
+ ProtocolISOIP = 80 // ISO Internet Protocol
+ ProtocolVMTP = 81 // VMTP
+ ProtocolSECUREVMTP = 82 // SECURE-VMTP
+ ProtocolVINES = 83 // VINES
+ ProtocolTTP = 84 // Transaction Transport Protocol
+ ProtocolIPTM = 84 // Internet Protocol Traffic Manager
+ ProtocolNSFNETIGP = 85 // NSFNET-IGP
+ ProtocolDGP = 86 // Dissimilar Gateway Protocol
+ ProtocolTCF = 87 // TCF
+ ProtocolEIGRP = 88 // EIGRP
+ ProtocolOSPFIGP = 89 // OSPFIGP
+ ProtocolSpriteRPC = 90 // Sprite RPC Protocol
+ ProtocolLARP = 91 // Locus Address Resolution Protocol
+ ProtocolMTP = 92 // Multicast Transport Protocol
+ ProtocolAX25 = 93 // AX.25 Frames
+ ProtocolIPIP = 94 // IP-within-IP Encapsulation Protocol
+ ProtocolSCCSP = 96 // Semaphore Communications Sec. Pro.
+ ProtocolETHERIP = 97 // Ethernet-within-IP Encapsulation
+ ProtocolENCAP = 98 // Encapsulation Header
+ ProtocolGMTP = 100 // GMTP
+ ProtocolIFMP = 101 // Ipsilon Flow Management Protocol
+ ProtocolPNNI = 102 // PNNI over IP
+ ProtocolPIM = 103 // Protocol Independent Multicast
+ ProtocolARIS = 104 // ARIS
+ ProtocolSCPS = 105 // SCPS
+ ProtocolQNX = 106 // QNX
+ ProtocolAN = 107 // Active Networks
+ ProtocolIPComp = 108 // IP Payload Compression Protocol
+ ProtocolSNP = 109 // Sitara Networks Protocol
+ ProtocolCompaqPeer = 110 // Compaq Peer Protocol
+ ProtocolIPXinIP = 111 // IPX in IP
+ ProtocolVRRP = 112 // Virtual Router Redundancy Protocol
+ ProtocolPGM = 113 // PGM Reliable Transport Protocol
+ ProtocolL2TP = 115 // Layer Two Tunneling Protocol
+ ProtocolDDX = 116 // D-II Data Exchange (DDX)
+ ProtocolIATP = 117 // Interactive Agent Transfer Protocol
+ ProtocolSTP = 118 // Schedule Transfer Protocol
+ ProtocolSRP = 119 // SpectraLink Radio Protocol
+ ProtocolUTI = 120 // UTI
+ ProtocolSMP = 121 // Simple Message Protocol
+ ProtocolPTP = 123 // Performance Transparency Protocol
+ ProtocolISIS = 124 // ISIS over IPv4
+ ProtocolFIRE = 125 // FIRE
+ ProtocolCRTP = 126 // Combat Radio Transport Protocol
+ ProtocolCRUDP = 127 // Combat Radio User Datagram
+ ProtocolSSCOPMCE = 128 // SSCOPMCE
+ ProtocolIPLT = 129 // IPLT
+ ProtocolSPS = 130 // Secure Packet Shield
+ ProtocolPIPE = 131 // Private IP Encapsulation within IP
+ ProtocolSCTP = 132 // Stream Control Transmission Protocol
+ ProtocolFC = 133 // Fibre Channel
+ ProtocolRSVPE2EIGNORE = 134 // RSVP-E2E-IGNORE
+ ProtocolMobilityHeader = 135 // Mobility Header
+ ProtocolUDPLite = 136 // UDPLite
+ ProtocolMPLSinIP = 137 // MPLS-in-IP
+ ProtocolMANET = 138 // MANET Protocols
+ ProtocolHIP = 139 // Host Identity Protocol
+ ProtocolShim6 = 140 // Shim6 Protocol
+ ProtocolWESP = 141 // Wrapped Encapsulating Security Payload
+ ProtocolROHC = 142 // Robust Header Compression
+ ProtocolReserved = 255 // Reserved
+)
+
+// Address Family Numbers, Updated: 2018-04-02
+const (
+ AddrFamilyIPv4 = 1 // IP (IP version 4)
+ AddrFamilyIPv6 = 2 // IP6 (IP version 6)
+ AddrFamilyNSAP = 3 // NSAP
+ AddrFamilyHDLC = 4 // HDLC (8-bit multidrop)
+ AddrFamilyBBN1822 = 5 // BBN 1822
+ AddrFamily802 = 6 // 802 (includes all 802 media plus Ethernet "canonical format")
+ AddrFamilyE163 = 7 // E.163
+ AddrFamilyE164 = 8 // E.164 (SMDS, Frame Relay, ATM)
+ AddrFamilyF69 = 9 // F.69 (Telex)
+ AddrFamilyX121 = 10 // X.121 (X.25, Frame Relay)
+ AddrFamilyIPX = 11 // IPX
+ AddrFamilyAppletalk = 12 // Appletalk
+ AddrFamilyDecnetIV = 13 // Decnet IV
+ AddrFamilyBanyanVines = 14 // Banyan Vines
+ AddrFamilyE164withSubaddress = 15 // E.164 with NSAP format subaddress
+ AddrFamilyDNS = 16 // DNS (Domain Name System)
+ AddrFamilyDistinguishedName = 17 // Distinguished Name
+ AddrFamilyASNumber = 18 // AS Number
+ AddrFamilyXTPoverIPv4 = 19 // XTP over IP version 4
+ AddrFamilyXTPoverIPv6 = 20 // XTP over IP version 6
+ AddrFamilyXTPnativemodeXTP = 21 // XTP native mode XTP
+ AddrFamilyFibreChannelWorldWidePortName = 22 // Fibre Channel World-Wide Port Name
+ AddrFamilyFibreChannelWorldWideNodeName = 23 // Fibre Channel World-Wide Node Name
+ AddrFamilyGWID = 24 // GWID
+ AddrFamilyL2VPN = 25 // AFI for L2VPN information
+ AddrFamilyMPLSTPSectionEndpointID = 26 // MPLS-TP Section Endpoint Identifier
+ AddrFamilyMPLSTPLSPEndpointID = 27 // MPLS-TP LSP Endpoint Identifier
+ AddrFamilyMPLSTPPseudowireEndpointID = 28 // MPLS-TP Pseudowire Endpoint Identifier
+ AddrFamilyMTIPv4 = 29 // MT IP: Multi-Topology IP version 4
+ AddrFamilyMTIPv6 = 30 // MT IPv6: Multi-Topology IP version 6
+ AddrFamilyEIGRPCommonServiceFamily = 16384 // EIGRP Common Service Family
+ AddrFamilyEIGRPIPv4ServiceFamily = 16385 // EIGRP IPv4 Service Family
+ AddrFamilyEIGRPIPv6ServiceFamily = 16386 // EIGRP IPv6 Service Family
+ AddrFamilyLISPCanonicalAddressFormat = 16387 // LISP Canonical Address Format (LCAF)
+ AddrFamilyBGPLS = 16388 // BGP-LS
+ AddrFamily48bitMAC = 16389 // 48-bit MAC
+ AddrFamily64bitMAC = 16390 // 64-bit MAC
+ AddrFamilyOUI = 16391 // OUI
+ AddrFamilyMACFinal24bits = 16392 // MAC/24
+ AddrFamilyMACFinal40bits = 16393 // MAC/40
+ AddrFamilyIPv6Initial64bits = 16394 // IPv6/64
+ AddrFamilyRBridgePortID = 16395 // RBridge Port ID
+ AddrFamilyTRILLNickname = 16396 // TRILL Nickname
+)
diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr.go b/vendor/golang.org/x/net/internal/socket/cmsghdr.go
@@ -0,0 +1,12 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
+
+package socket
+
+func (h *cmsghdr) len() int { return int(h.Len) }
+func (h *cmsghdr) lvl() int { return int(h.Level) }
+func (h *cmsghdr) typ() int { return int(h.Type) }
diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go
@@ -0,0 +1,14 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd
+// +build aix darwin dragonfly freebsd netbsd openbsd
+
+package socket
+
+func (h *cmsghdr) set(l, lvl, typ int) {
+ h.Len = uint32(l)
+ h.Level = int32(lvl)
+ h.Type = int32(typ)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_32bit.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_32bit.go
@@ -0,0 +1,15 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (arm || mips || mipsle || 386 || ppc) && linux
+// +build arm mips mipsle 386 ppc
+// +build linux
+
+package socket
+
+func (h *cmsghdr) set(l, lvl, typ int) {
+ h.Len = uint32(l)
+ h.Level = int32(lvl)
+ h.Type = int32(typ)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go
@@ -0,0 +1,15 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (arm64 || amd64 || loong64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && linux
+// +build arm64 amd64 loong64 ppc64 ppc64le mips64 mips64le riscv64 s390x
+// +build linux
+
+package socket
+
+func (h *cmsghdr) set(l, lvl, typ int) {
+ h.Len = uint64(l)
+ h.Level = int32(lvl)
+ h.Type = int32(typ)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_solaris_64bit.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_solaris_64bit.go
@@ -0,0 +1,14 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build amd64 && solaris
+// +build amd64,solaris
+
+package socket
+
+func (h *cmsghdr) set(l, lvl, typ int) {
+ h.Len = uint32(l)
+ h.Level = int32(lvl)
+ h.Type = int32(typ)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go
@@ -0,0 +1,28 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
+
+package socket
+
+func controlHeaderLen() int {
+ return 0
+}
+
+func controlMessageLen(dataLen int) int {
+ return 0
+}
+
+func controlMessageSpace(dataLen int) int {
+ return 0
+}
+
+type cmsghdr struct{}
+
+func (h *cmsghdr) len() int { return 0 }
+func (h *cmsghdr) lvl() int { return 0 }
+func (h *cmsghdr) typ() int { return 0 }
+
+func (h *cmsghdr) set(l, lvl, typ int) {}
diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_unix.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_unix.go
@@ -0,0 +1,22 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
+
+package socket
+
+import "golang.org/x/sys/unix"
+
+func controlHeaderLen() int {
+ return unix.CmsgLen(0)
+}
+
+func controlMessageLen(dataLen int) int {
+ return unix.CmsgLen(dataLen)
+}
+
+func controlMessageSpace(dataLen int) int {
+ return unix.CmsgSpace(dataLen)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_zos_s390x.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_zos_s390x.go
@@ -0,0 +1,11 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package socket
+
+func (h *cmsghdr) set(l, lvl, typ int) {
+ h.Len = int32(l)
+ h.Level = int32(lvl)
+ h.Type = int32(typ)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/complete_dontwait.go b/vendor/golang.org/x/net/internal/socket/complete_dontwait.go
@@ -0,0 +1,26 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package socket
+
+import (
+ "syscall"
+)
+
+// ioComplete checks the flags and result of a syscall, to be used as return
+// value in a syscall.RawConn.Read or Write callback.
+func ioComplete(flags int, operr error) bool {
+ if flags&syscall.MSG_DONTWAIT != 0 {
+ // Caller explicitly said don't wait, so always return immediately.
+ return true
+ }
+ if operr == syscall.EAGAIN || operr == syscall.EWOULDBLOCK {
+ // No data available, block for I/O and try again.
+ return false
+ }
+ return true
+}
diff --git a/vendor/golang.org/x/net/internal/socket/complete_nodontwait.go b/vendor/golang.org/x/net/internal/socket/complete_nodontwait.go
@@ -0,0 +1,22 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || windows || zos
+// +build aix windows zos
+
+package socket
+
+import (
+ "syscall"
+)
+
+// ioComplete checks the flags and result of a syscall, to be used as return
+// value in a syscall.RawConn.Read or Write callback.
+func ioComplete(flags int, operr error) bool {
+ if operr == syscall.EAGAIN || operr == syscall.EWOULDBLOCK {
+ // No data available, block for I/O and try again.
+ return false
+ }
+ return true
+}
diff --git a/vendor/golang.org/x/net/internal/socket/empty.s b/vendor/golang.org/x/net/internal/socket/empty.s
@@ -0,0 +1,8 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build darwin && go1.12
+// +build darwin,go1.12
+
+// This exists solely so we can linkname in symbols from syscall.
diff --git a/vendor/golang.org/x/net/internal/socket/error_unix.go b/vendor/golang.org/x/net/internal/socket/error_unix.go
@@ -0,0 +1,32 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
+
+package socket
+
+import "syscall"
+
+var (
+ errEAGAIN error = syscall.EAGAIN
+ errEINVAL error = syscall.EINVAL
+ errENOENT error = syscall.ENOENT
+)
+
+// errnoErr returns common boxed Errno values, to prevent allocations
+// at runtime.
+func errnoErr(errno syscall.Errno) error {
+ switch errno {
+ case 0:
+ return nil
+ case syscall.EAGAIN:
+ return errEAGAIN
+ case syscall.EINVAL:
+ return errEINVAL
+ case syscall.ENOENT:
+ return errENOENT
+ }
+ return errno
+}
diff --git a/vendor/golang.org/x/net/internal/socket/error_windows.go b/vendor/golang.org/x/net/internal/socket/error_windows.go
@@ -0,0 +1,26 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package socket
+
+import "syscall"
+
+var (
+ errERROR_IO_PENDING error = syscall.ERROR_IO_PENDING
+ errEINVAL error = syscall.EINVAL
+)
+
+// errnoErr returns common boxed Errno values, to prevent allocations
+// at runtime.
+func errnoErr(errno syscall.Errno) error {
+ switch errno {
+ case 0:
+ return nil
+ case syscall.ERROR_IO_PENDING:
+ return errERROR_IO_PENDING
+ case syscall.EINVAL:
+ return errEINVAL
+ }
+ return errno
+}
diff --git a/vendor/golang.org/x/net/internal/socket/iovec_32bit.go b/vendor/golang.org/x/net/internal/socket/iovec_32bit.go
@@ -0,0 +1,20 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (arm || mips || mipsle || 386 || ppc) && (darwin || dragonfly || freebsd || linux || netbsd || openbsd)
+// +build arm mips mipsle 386 ppc
+// +build darwin dragonfly freebsd linux netbsd openbsd
+
+package socket
+
+import "unsafe"
+
+func (v *iovec) set(b []byte) {
+ l := len(b)
+ if l == 0 {
+ return
+ }
+ v.Base = (*byte)(unsafe.Pointer(&b[0]))
+ v.Len = uint32(l)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/iovec_64bit.go b/vendor/golang.org/x/net/internal/socket/iovec_64bit.go
@@ -0,0 +1,20 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (arm64 || amd64 || loong64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || zos)
+// +build arm64 amd64 loong64 ppc64 ppc64le mips64 mips64le riscv64 s390x
+// +build aix darwin dragonfly freebsd linux netbsd openbsd zos
+
+package socket
+
+import "unsafe"
+
+func (v *iovec) set(b []byte) {
+ l := len(b)
+ if l == 0 {
+ return
+ }
+ v.Base = (*byte)(unsafe.Pointer(&b[0]))
+ v.Len = uint64(l)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/iovec_solaris_64bit.go b/vendor/golang.org/x/net/internal/socket/iovec_solaris_64bit.go
@@ -0,0 +1,19 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build amd64 && solaris
+// +build amd64,solaris
+
+package socket
+
+import "unsafe"
+
+func (v *iovec) set(b []byte) {
+ l := len(b)
+ if l == 0 {
+ return
+ }
+ v.Base = (*int8)(unsafe.Pointer(&b[0]))
+ v.Len = uint64(l)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/iovec_stub.go b/vendor/golang.org/x/net/internal/socket/iovec_stub.go
@@ -0,0 +1,12 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
+
+package socket
+
+type iovec struct{}
+
+func (v *iovec) set(b []byte) {}
diff --git a/vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go b/vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go
@@ -0,0 +1,22 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !aix && !linux && !netbsd
+// +build !aix,!linux,!netbsd
+
+package socket
+
+import "net"
+
+type mmsghdr struct{}
+
+type mmsghdrs []mmsghdr
+
+func (hs mmsghdrs) pack(ms []Message, parseFn func([]byte, string) (net.Addr, error), marshalFn func(net.Addr) []byte) error {
+ return nil
+}
+
+func (hs mmsghdrs) unpack(ms []Message, parseFn func([]byte, string) (net.Addr, error), hint string) error {
+ return nil
+}
diff --git a/vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go b/vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go
@@ -0,0 +1,180 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || linux || netbsd
+// +build aix linux netbsd
+
+package socket
+
+import (
+ "net"
+ "os"
+ "sync"
+ "syscall"
+)
+
+type mmsghdrs []mmsghdr
+
+func (hs mmsghdrs) unpack(ms []Message, parseFn func([]byte, string) (net.Addr, error), hint string) error {
+ for i := range hs {
+ ms[i].N = int(hs[i].Len)
+ ms[i].NN = hs[i].Hdr.controllen()
+ ms[i].Flags = hs[i].Hdr.flags()
+ if parseFn != nil {
+ var err error
+ ms[i].Addr, err = parseFn(hs[i].Hdr.name(), hint)
+ if err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+// mmsghdrsPacker packs Message-slices into mmsghdrs (re-)using pre-allocated buffers.
+type mmsghdrsPacker struct {
+ // hs are the pre-allocated mmsghdrs.
+ hs mmsghdrs
+ // sockaddrs is the pre-allocated buffer for the Hdr.Name buffers.
+ // We use one large buffer for all messages and slice it up.
+ sockaddrs []byte
+ // vs are the pre-allocated iovecs.
+ // We allocate one large buffer for all messages and slice it up. This allows to reuse the buffer
+ // if the number of buffers per message is distributed differently between calls.
+ vs []iovec
+}
+
+func (p *mmsghdrsPacker) prepare(ms []Message) {
+ n := len(ms)
+ if n <= cap(p.hs) {
+ p.hs = p.hs[:n]
+ } else {
+ p.hs = make(mmsghdrs, n)
+ }
+ if n*sizeofSockaddrInet6 <= cap(p.sockaddrs) {
+ p.sockaddrs = p.sockaddrs[:n*sizeofSockaddrInet6]
+ } else {
+ p.sockaddrs = make([]byte, n*sizeofSockaddrInet6)
+ }
+
+ nb := 0
+ for _, m := range ms {
+ nb += len(m.Buffers)
+ }
+ if nb <= cap(p.vs) {
+ p.vs = p.vs[:nb]
+ } else {
+ p.vs = make([]iovec, nb)
+ }
+}
+
+func (p *mmsghdrsPacker) pack(ms []Message, parseFn func([]byte, string) (net.Addr, error), marshalFn func(net.Addr, []byte) int) mmsghdrs {
+ p.prepare(ms)
+ hs := p.hs
+ vsRest := p.vs
+ saRest := p.sockaddrs
+ for i := range hs {
+ nvs := len(ms[i].Buffers)
+ vs := vsRest[:nvs]
+ vsRest = vsRest[nvs:]
+
+ var sa []byte
+ if parseFn != nil {
+ sa = saRest[:sizeofSockaddrInet6]
+ saRest = saRest[sizeofSockaddrInet6:]
+ } else if marshalFn != nil {
+ n := marshalFn(ms[i].Addr, saRest)
+ if n > 0 {
+ sa = saRest[:n]
+ saRest = saRest[n:]
+ }
+ }
+ hs[i].Hdr.pack(vs, ms[i].Buffers, ms[i].OOB, sa)
+ }
+ return hs
+}
+
+// syscaller is a helper to invoke recvmmsg and sendmmsg via the RawConn.Read/Write interface.
+// It is reusable, to amortize the overhead of allocating a closure for the function passed to
+// RawConn.Read/Write.
+type syscaller struct {
+ n int
+ operr error
+ hs mmsghdrs
+ flags int
+
+ boundRecvmmsgF func(uintptr) bool
+ boundSendmmsgF func(uintptr) bool
+}
+
+func (r *syscaller) init() {
+ r.boundRecvmmsgF = r.recvmmsgF
+ r.boundSendmmsgF = r.sendmmsgF
+}
+
+func (r *syscaller) recvmmsg(c syscall.RawConn, hs mmsghdrs, flags int) (int, error) {
+ r.n = 0
+ r.operr = nil
+ r.hs = hs
+ r.flags = flags
+ if err := c.Read(r.boundRecvmmsgF); err != nil {
+ return r.n, err
+ }
+ if r.operr != nil {
+ return r.n, os.NewSyscallError("recvmmsg", r.operr)
+ }
+ return r.n, nil
+}
+
+func (r *syscaller) recvmmsgF(s uintptr) bool {
+ r.n, r.operr = recvmmsg(s, r.hs, r.flags)
+ return ioComplete(r.flags, r.operr)
+}
+
+func (r *syscaller) sendmmsg(c syscall.RawConn, hs mmsghdrs, flags int) (int, error) {
+ r.n = 0
+ r.operr = nil
+ r.hs = hs
+ r.flags = flags
+ if err := c.Write(r.boundSendmmsgF); err != nil {
+ return r.n, err
+ }
+ if r.operr != nil {
+ return r.n, os.NewSyscallError("sendmmsg", r.operr)
+ }
+ return r.n, nil
+}
+
+func (r *syscaller) sendmmsgF(s uintptr) bool {
+ r.n, r.operr = sendmmsg(s, r.hs, r.flags)
+ return ioComplete(r.flags, r.operr)
+}
+
+// mmsgTmps holds reusable temporary helpers for recvmmsg and sendmmsg.
+type mmsgTmps struct {
+ packer mmsghdrsPacker
+ syscaller syscaller
+}
+
+var defaultMmsgTmpsPool = mmsgTmpsPool{
+ p: sync.Pool{
+ New: func() interface{} {
+ tmps := new(mmsgTmps)
+ tmps.syscaller.init()
+ return tmps
+ },
+ },
+}
+
+type mmsgTmpsPool struct {
+ p sync.Pool
+}
+
+func (p *mmsgTmpsPool) Get() *mmsgTmps {
+ return p.p.Get().(*mmsgTmps)
+}
+
+func (p *mmsgTmpsPool) Put(tmps *mmsgTmps) {
+ p.p.Put(tmps)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_bsd.go b/vendor/golang.org/x/net/internal/socket/msghdr_bsd.go
@@ -0,0 +1,40 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd
+// +build aix darwin dragonfly freebsd netbsd openbsd
+
+package socket
+
+import "unsafe"
+
+func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {
+ for i := range vs {
+ vs[i].set(bs[i])
+ }
+ h.setIov(vs)
+ if len(oob) > 0 {
+ h.Control = (*byte)(unsafe.Pointer(&oob[0]))
+ h.Controllen = uint32(len(oob))
+ }
+ if sa != nil {
+ h.Name = (*byte)(unsafe.Pointer(&sa[0]))
+ h.Namelen = uint32(len(sa))
+ }
+}
+
+func (h *msghdr) name() []byte {
+ if h.Name != nil && h.Namelen > 0 {
+ return (*[sizeofSockaddrInet6]byte)(unsafe.Pointer(h.Name))[:h.Namelen]
+ }
+ return nil
+}
+
+func (h *msghdr) controllen() int {
+ return int(h.Controllen)
+}
+
+func (h *msghdr) flags() int {
+ return int(h.Flags)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go b/vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go
@@ -0,0 +1,17 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || netbsd
+// +build aix darwin dragonfly freebsd netbsd
+
+package socket
+
+func (h *msghdr) setIov(vs []iovec) {
+ l := len(vs)
+ if l == 0 {
+ return
+ }
+ h.Iov = &vs[0]
+ h.Iovlen = int32(l)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_linux.go b/vendor/golang.org/x/net/internal/socket/msghdr_linux.go
@@ -0,0 +1,39 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package socket
+
+import "unsafe"
+
+func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {
+ for i := range vs {
+ vs[i].set(bs[i])
+ }
+ h.setIov(vs)
+ if len(oob) > 0 {
+ h.setControl(oob)
+ }
+ if sa != nil {
+ h.Name = (*byte)(unsafe.Pointer(&sa[0]))
+ h.Namelen = uint32(len(sa))
+ } else {
+ h.Name = nil
+ h.Namelen = 0
+ }
+}
+
+func (h *msghdr) name() []byte {
+ if h.Name != nil && h.Namelen > 0 {
+ return (*[sizeofSockaddrInet6]byte)(unsafe.Pointer(h.Name))[:h.Namelen]
+ }
+ return nil
+}
+
+func (h *msghdr) controllen() int {
+ return int(h.Controllen)
+}
+
+func (h *msghdr) flags() int {
+ return int(h.Flags)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_linux_32bit.go b/vendor/golang.org/x/net/internal/socket/msghdr_linux_32bit.go
@@ -0,0 +1,25 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (arm || mips || mipsle || 386 || ppc) && linux
+// +build arm mips mipsle 386 ppc
+// +build linux
+
+package socket
+
+import "unsafe"
+
+func (h *msghdr) setIov(vs []iovec) {
+ l := len(vs)
+ if l == 0 {
+ return
+ }
+ h.Iov = &vs[0]
+ h.Iovlen = uint32(l)
+}
+
+func (h *msghdr) setControl(b []byte) {
+ h.Control = (*byte)(unsafe.Pointer(&b[0]))
+ h.Controllen = uint32(len(b))
+}
diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go b/vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go
@@ -0,0 +1,25 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (arm64 || amd64 || loong64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && linux
+// +build arm64 amd64 loong64 ppc64 ppc64le mips64 mips64le riscv64 s390x
+// +build linux
+
+package socket
+
+import "unsafe"
+
+func (h *msghdr) setIov(vs []iovec) {
+ l := len(vs)
+ if l == 0 {
+ return
+ }
+ h.Iov = &vs[0]
+ h.Iovlen = uint64(l)
+}
+
+func (h *msghdr) setControl(b []byte) {
+ h.Control = (*byte)(unsafe.Pointer(&b[0]))
+ h.Controllen = uint64(len(b))
+}
diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_openbsd.go b/vendor/golang.org/x/net/internal/socket/msghdr_openbsd.go
@@ -0,0 +1,14 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package socket
+
+func (h *msghdr) setIov(vs []iovec) {
+ l := len(vs)
+ if l == 0 {
+ return
+ }
+ h.Iov = &vs[0]
+ h.Iovlen = uint32(l)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_solaris_64bit.go b/vendor/golang.org/x/net/internal/socket/msghdr_solaris_64bit.go
@@ -0,0 +1,36 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build amd64 && solaris
+// +build amd64,solaris
+
+package socket
+
+import "unsafe"
+
+func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {
+ for i := range vs {
+ vs[i].set(bs[i])
+ }
+ if len(vs) > 0 {
+ h.Iov = &vs[0]
+ h.Iovlen = int32(len(vs))
+ }
+ if len(oob) > 0 {
+ h.Accrights = (*int8)(unsafe.Pointer(&oob[0]))
+ h.Accrightslen = int32(len(oob))
+ }
+ if sa != nil {
+ h.Name = (*byte)(unsafe.Pointer(&sa[0]))
+ h.Namelen = uint32(len(sa))
+ }
+}
+
+func (h *msghdr) controllen() int {
+ return int(h.Accrightslen)
+}
+
+func (h *msghdr) flags() int {
+ return int(NativeEndian.Uint32(h.Pad_cgo_2[:]))
+}
diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_stub.go b/vendor/golang.org/x/net/internal/socket/msghdr_stub.go
@@ -0,0 +1,15 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
+
+package socket
+
+type msghdr struct{}
+
+func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {}
+func (h *msghdr) name() []byte { return nil }
+func (h *msghdr) controllen() int { return 0 }
+func (h *msghdr) flags() int { return 0 }
diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_zos_s390x.go b/vendor/golang.org/x/net/internal/socket/msghdr_zos_s390x.go
@@ -0,0 +1,36 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build s390x && zos
+// +build s390x,zos
+
+package socket
+
+import "unsafe"
+
+func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {
+ for i := range vs {
+ vs[i].set(bs[i])
+ }
+ if len(vs) > 0 {
+ h.Iov = &vs[0]
+ h.Iovlen = int32(len(vs))
+ }
+ if len(oob) > 0 {
+ h.Control = (*byte)(unsafe.Pointer(&oob[0]))
+ h.Controllen = uint32(len(oob))
+ }
+ if sa != nil {
+ h.Name = (*byte)(unsafe.Pointer(&sa[0]))
+ h.Namelen = uint32(len(sa))
+ }
+}
+
+func (h *msghdr) controllen() int {
+ return int(h.Controllen)
+}
+
+func (h *msghdr) flags() int {
+ return int(h.Flags)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/norace.go b/vendor/golang.org/x/net/internal/socket/norace.go
@@ -0,0 +1,13 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !race
+// +build !race
+
+package socket
+
+func (m *Message) raceRead() {
+}
+func (m *Message) raceWrite() {
+}
diff --git a/vendor/golang.org/x/net/internal/socket/race.go b/vendor/golang.org/x/net/internal/socket/race.go
@@ -0,0 +1,38 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build race
+// +build race
+
+package socket
+
+import (
+ "runtime"
+ "unsafe"
+)
+
+// This package reads and writes the Message buffers using a
+// direct system call, which the race detector can't see.
+// These functions tell the race detector what is going on during the syscall.
+
+func (m *Message) raceRead() {
+ for _, b := range m.Buffers {
+ if len(b) > 0 {
+ runtime.RaceReadRange(unsafe.Pointer(&b[0]), len(b))
+ }
+ }
+ if b := m.OOB; len(b) > 0 {
+ runtime.RaceReadRange(unsafe.Pointer(&b[0]), len(b))
+ }
+}
+func (m *Message) raceWrite() {
+ for _, b := range m.Buffers {
+ if len(b) > 0 {
+ runtime.RaceWriteRange(unsafe.Pointer(&b[0]), len(b))
+ }
+ }
+ if b := m.OOB; len(b) > 0 {
+ runtime.RaceWriteRange(unsafe.Pointer(&b[0]), len(b))
+ }
+}
diff --git a/vendor/golang.org/x/net/internal/socket/rawconn.go b/vendor/golang.org/x/net/internal/socket/rawconn.go
@@ -0,0 +1,91 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package socket
+
+import (
+ "errors"
+ "net"
+ "os"
+ "syscall"
+)
+
+// A Conn represents a raw connection.
+type Conn struct {
+ network string
+ c syscall.RawConn
+}
+
+// tcpConn is an interface implemented by net.TCPConn.
+// It can be used for interface assertions to check if a net.Conn is a TCP connection.
+type tcpConn interface {
+ SyscallConn() (syscall.RawConn, error)
+ SetLinger(int) error
+}
+
+var _ tcpConn = (*net.TCPConn)(nil)
+
+// udpConn is an interface implemented by net.UDPConn.
+// It can be used for interface assertions to check if a net.Conn is a UDP connection.
+type udpConn interface {
+ SyscallConn() (syscall.RawConn, error)
+ ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *net.UDPAddr, err error)
+}
+
+var _ udpConn = (*net.UDPConn)(nil)
+
+// ipConn is an interface implemented by net.IPConn.
+// It can be used for interface assertions to check if a net.Conn is an IP connection.
+type ipConn interface {
+ SyscallConn() (syscall.RawConn, error)
+ ReadMsgIP(b, oob []byte) (n, oobn, flags int, addr *net.IPAddr, err error)
+}
+
+var _ ipConn = (*net.IPConn)(nil)
+
+// NewConn returns a new raw connection.
+func NewConn(c net.Conn) (*Conn, error) {
+ var err error
+ var cc Conn
+ switch c := c.(type) {
+ case tcpConn:
+ cc.network = "tcp"
+ cc.c, err = c.SyscallConn()
+ case udpConn:
+ cc.network = "udp"
+ cc.c, err = c.SyscallConn()
+ case ipConn:
+ cc.network = "ip"
+ cc.c, err = c.SyscallConn()
+ default:
+ return nil, errors.New("unknown connection type")
+ }
+ if err != nil {
+ return nil, err
+ }
+ return &cc, nil
+}
+
+func (o *Option) get(c *Conn, b []byte) (int, error) {
+ var operr error
+ var n int
+ fn := func(s uintptr) {
+ n, operr = getsockopt(s, o.Level, o.Name, b)
+ }
+ if err := c.c.Control(fn); err != nil {
+ return 0, err
+ }
+ return n, os.NewSyscallError("getsockopt", operr)
+}
+
+func (o *Option) set(c *Conn, b []byte) error {
+ var operr error
+ fn := func(s uintptr) {
+ operr = setsockopt(s, o.Level, o.Name, b)
+ }
+ if err := c.c.Control(fn); err != nil {
+ return err
+ }
+ return os.NewSyscallError("setsockopt", operr)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go b/vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go
@@ -0,0 +1,54 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux
+// +build linux
+
+package socket
+
+import (
+ "net"
+)
+
+func (c *Conn) recvMsgs(ms []Message, flags int) (int, error) {
+ for i := range ms {
+ ms[i].raceWrite()
+ }
+ tmps := defaultMmsgTmpsPool.Get()
+ defer defaultMmsgTmpsPool.Put(tmps)
+ var parseFn func([]byte, string) (net.Addr, error)
+ if c.network != "tcp" {
+ parseFn = parseInetAddr
+ }
+ hs := tmps.packer.pack(ms, parseFn, nil)
+ n, err := tmps.syscaller.recvmmsg(c.c, hs, flags)
+ if err != nil {
+ return n, err
+ }
+ if err := hs[:n].unpack(ms[:n], parseFn, c.network); err != nil {
+ return n, err
+ }
+ return n, nil
+}
+
+func (c *Conn) sendMsgs(ms []Message, flags int) (int, error) {
+ for i := range ms {
+ ms[i].raceRead()
+ }
+ tmps := defaultMmsgTmpsPool.Get()
+ defer defaultMmsgTmpsPool.Put(tmps)
+ var marshalFn func(net.Addr, []byte) int
+ if c.network != "tcp" {
+ marshalFn = marshalInetAddr
+ }
+ hs := tmps.packer.pack(ms, nil, marshalFn)
+ n, err := tmps.syscaller.sendmmsg(c.c, hs, flags)
+ if err != nil {
+ return n, err
+ }
+ if err := hs[:n].unpack(ms[:n], nil, ""); err != nil {
+ return n, err
+ }
+ return n, nil
+}
diff --git a/vendor/golang.org/x/net/internal/socket/rawconn_msg.go b/vendor/golang.org/x/net/internal/socket/rawconn_msg.go
@@ -0,0 +1,74 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows zos
+
+package socket
+
+import (
+ "os"
+)
+
+func (c *Conn) recvMsg(m *Message, flags int) error {
+ m.raceWrite()
+ var h msghdr
+ vs := make([]iovec, len(m.Buffers))
+ var sa []byte
+ if c.network != "tcp" {
+ sa = make([]byte, sizeofSockaddrInet6)
+ }
+ h.pack(vs, m.Buffers, m.OOB, sa)
+ var operr error
+ var n int
+ fn := func(s uintptr) bool {
+ n, operr = recvmsg(s, &h, flags)
+ return ioComplete(flags, operr)
+ }
+ if err := c.c.Read(fn); err != nil {
+ return err
+ }
+ if operr != nil {
+ return os.NewSyscallError("recvmsg", operr)
+ }
+ if c.network != "tcp" {
+ var err error
+ m.Addr, err = parseInetAddr(sa[:], c.network)
+ if err != nil {
+ return err
+ }
+ }
+ m.N = n
+ m.NN = h.controllen()
+ m.Flags = h.flags()
+ return nil
+}
+
+func (c *Conn) sendMsg(m *Message, flags int) error {
+ m.raceRead()
+ var h msghdr
+ vs := make([]iovec, len(m.Buffers))
+ var sa []byte
+ if m.Addr != nil {
+ var a [sizeofSockaddrInet6]byte
+ n := marshalInetAddr(m.Addr, a[:])
+ sa = a[:n]
+ }
+ h.pack(vs, m.Buffers, m.OOB, sa)
+ var operr error
+ var n int
+ fn := func(s uintptr) bool {
+ n, operr = sendmsg(s, &h, flags)
+ return ioComplete(flags, operr)
+ }
+ if err := c.c.Write(fn); err != nil {
+ return err
+ }
+ if operr != nil {
+ return os.NewSyscallError("sendmsg", operr)
+ }
+ m.N = n
+ m.NN = len(m.OOB)
+ return nil
+}
diff --git a/vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go b/vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go
@@ -0,0 +1,16 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !linux
+// +build !linux
+
+package socket
+
+func (c *Conn) recvMsgs(ms []Message, flags int) (int, error) {
+ return 0, errNotImplemented
+}
+
+func (c *Conn) sendMsgs(ms []Message, flags int) (int, error) {
+ return 0, errNotImplemented
+}
diff --git a/vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go b/vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go
@@ -0,0 +1,16 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
+
+package socket
+
+func (c *Conn) recvMsg(m *Message, flags int) error {
+ return errNotImplemented
+}
+
+func (c *Conn) sendMsg(m *Message, flags int) error {
+ return errNotImplemented
+}
diff --git a/vendor/golang.org/x/net/internal/socket/socket.go b/vendor/golang.org/x/net/internal/socket/socket.go
@@ -0,0 +1,280 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package socket provides a portable interface for socket system
+// calls.
+package socket // import "golang.org/x/net/internal/socket"
+
+import (
+ "errors"
+ "net"
+ "runtime"
+ "unsafe"
+)
+
+var errNotImplemented = errors.New("not implemented on " + runtime.GOOS + "/" + runtime.GOARCH)
+
+// An Option represents a sticky socket option.
+type Option struct {
+ Level int // level
+ Name int // name; must be equal or greater than 1
+ Len int // length of value in bytes; must be equal or greater than 1
+}
+
+// Get reads a value for the option from the kernel.
+// It returns the number of bytes written into b.
+func (o *Option) Get(c *Conn, b []byte) (int, error) {
+ if o.Name < 1 || o.Len < 1 {
+ return 0, errors.New("invalid option")
+ }
+ if len(b) < o.Len {
+ return 0, errors.New("short buffer")
+ }
+ return o.get(c, b)
+}
+
+// GetInt returns an integer value for the option.
+//
+// The Len field of Option must be either 1 or 4.
+func (o *Option) GetInt(c *Conn) (int, error) {
+ if o.Len != 1 && o.Len != 4 {
+ return 0, errors.New("invalid option")
+ }
+ var b []byte
+ var bb [4]byte
+ if o.Len == 1 {
+ b = bb[:1]
+ } else {
+ b = bb[:4]
+ }
+ n, err := o.get(c, b)
+ if err != nil {
+ return 0, err
+ }
+ if n != o.Len {
+ return 0, errors.New("invalid option length")
+ }
+ if o.Len == 1 {
+ return int(b[0]), nil
+ }
+ return int(NativeEndian.Uint32(b[:4])), nil
+}
+
+// Set writes the option and value to the kernel.
+func (o *Option) Set(c *Conn, b []byte) error {
+ if o.Name < 1 || o.Len < 1 {
+ return errors.New("invalid option")
+ }
+ if len(b) < o.Len {
+ return errors.New("short buffer")
+ }
+ return o.set(c, b)
+}
+
+// SetInt writes the option and value to the kernel.
+//
+// The Len field of Option must be either 1 or 4.
+func (o *Option) SetInt(c *Conn, v int) error {
+ if o.Len != 1 && o.Len != 4 {
+ return errors.New("invalid option")
+ }
+ var b []byte
+ if o.Len == 1 {
+ b = []byte{byte(v)}
+ } else {
+ var bb [4]byte
+ NativeEndian.PutUint32(bb[:o.Len], uint32(v))
+ b = bb[:4]
+ }
+ return o.set(c, b)
+}
+
+// ControlMessageSpace returns the whole length of control message.
+func ControlMessageSpace(dataLen int) int {
+ return controlMessageSpace(dataLen)
+}
+
+// A ControlMessage represents the head message in a stream of control
+// messages.
+//
+// A control message comprises of a header, data and a few padding
+// fields to conform to the interface to the kernel.
+//
+// See RFC 3542 for further information.
+type ControlMessage []byte
+
+// Data returns the data field of the control message at the head on
+// m.
+func (m ControlMessage) Data(dataLen int) []byte {
+ l := controlHeaderLen()
+ if len(m) < l || len(m) < l+dataLen {
+ return nil
+ }
+ return m[l : l+dataLen]
+}
+
+// Next returns the control message at the next on m.
+//
+// Next works only for standard control messages.
+func (m ControlMessage) Next(dataLen int) ControlMessage {
+ l := ControlMessageSpace(dataLen)
+ if len(m) < l {
+ return nil
+ }
+ return m[l:]
+}
+
+// MarshalHeader marshals the header fields of the control message at
+// the head on m.
+func (m ControlMessage) MarshalHeader(lvl, typ, dataLen int) error {
+ if len(m) < controlHeaderLen() {
+ return errors.New("short message")
+ }
+ h := (*cmsghdr)(unsafe.Pointer(&m[0]))
+ h.set(controlMessageLen(dataLen), lvl, typ)
+ return nil
+}
+
+// ParseHeader parses and returns the header fields of the control
+// message at the head on m.
+func (m ControlMessage) ParseHeader() (lvl, typ, dataLen int, err error) {
+ l := controlHeaderLen()
+ if len(m) < l {
+ return 0, 0, 0, errors.New("short message")
+ }
+ h := (*cmsghdr)(unsafe.Pointer(&m[0]))
+ return h.lvl(), h.typ(), int(uint64(h.len()) - uint64(l)), nil
+}
+
+// Marshal marshals the control message at the head on m, and returns
+// the next control message.
+func (m ControlMessage) Marshal(lvl, typ int, data []byte) (ControlMessage, error) {
+ l := len(data)
+ if len(m) < ControlMessageSpace(l) {
+ return nil, errors.New("short message")
+ }
+ h := (*cmsghdr)(unsafe.Pointer(&m[0]))
+ h.set(controlMessageLen(l), lvl, typ)
+ if l > 0 {
+ copy(m.Data(l), data)
+ }
+ return m.Next(l), nil
+}
+
+// Parse parses m as a single or multiple control messages.
+//
+// Parse works for both standard and compatible messages.
+func (m ControlMessage) Parse() ([]ControlMessage, error) {
+ var ms []ControlMessage
+ for len(m) >= controlHeaderLen() {
+ h := (*cmsghdr)(unsafe.Pointer(&m[0]))
+ l := h.len()
+ if l <= 0 {
+ return nil, errors.New("invalid header length")
+ }
+ if uint64(l) < uint64(controlHeaderLen()) {
+ return nil, errors.New("invalid message length")
+ }
+ if uint64(l) > uint64(len(m)) {
+ return nil, errors.New("short buffer")
+ }
+ // On message reception:
+ //
+ // |<- ControlMessageSpace --------------->|
+ // |<- controlMessageLen ---------->| |
+ // |<- controlHeaderLen ->| | |
+ // +---------------+------+---------+------+
+ // | Header | PadH | Data | PadD |
+ // +---------------+------+---------+------+
+ //
+ // On compatible message reception:
+ //
+ // | ... |<- controlMessageLen ----------->|
+ // | ... |<- controlHeaderLen ->| |
+ // +-----+---------------+------+----------+
+ // | ... | Header | PadH | Data |
+ // +-----+---------------+------+----------+
+ ms = append(ms, ControlMessage(m[:l]))
+ ll := l - controlHeaderLen()
+ if len(m) >= ControlMessageSpace(ll) {
+ m = m[ControlMessageSpace(ll):]
+ } else {
+ m = m[controlMessageLen(ll):]
+ }
+ }
+ return ms, nil
+}
+
+// NewControlMessage returns a new stream of control messages.
+func NewControlMessage(dataLen []int) ControlMessage {
+ var l int
+ for i := range dataLen {
+ l += ControlMessageSpace(dataLen[i])
+ }
+ return make([]byte, l)
+}
+
+// A Message represents an IO message.
+type Message struct {
+ // When writing, the Buffers field must contain at least one
+ // byte to write.
+ // When reading, the Buffers field will always contain a byte
+ // to read.
+ Buffers [][]byte
+
+ // OOB contains protocol-specific control or miscellaneous
+ // ancillary data known as out-of-band data.
+ OOB []byte
+
+ // Addr specifies a destination address when writing.
+ // It can be nil when the underlying protocol of the raw
+ // connection uses connection-oriented communication.
+ // After a successful read, it may contain the source address
+ // on the received packet.
+ Addr net.Addr
+
+ N int // # of bytes read or written from/to Buffers
+ NN int // # of bytes read or written from/to OOB
+ Flags int // protocol-specific information on the received message
+}
+
+// RecvMsg wraps recvmsg system call.
+//
+// The provided flags is a set of platform-dependent flags, such as
+// syscall.MSG_PEEK.
+func (c *Conn) RecvMsg(m *Message, flags int) error {
+ return c.recvMsg(m, flags)
+}
+
+// SendMsg wraps sendmsg system call.
+//
+// The provided flags is a set of platform-dependent flags, such as
+// syscall.MSG_DONTROUTE.
+func (c *Conn) SendMsg(m *Message, flags int) error {
+ return c.sendMsg(m, flags)
+}
+
+// RecvMsgs wraps recvmmsg system call.
+//
+// It returns the number of processed messages.
+//
+// The provided flags is a set of platform-dependent flags, such as
+// syscall.MSG_PEEK.
+//
+// Only Linux supports this.
+func (c *Conn) RecvMsgs(ms []Message, flags int) (int, error) {
+ return c.recvMsgs(ms, flags)
+}
+
+// SendMsgs wraps sendmmsg system call.
+//
+// It returns the number of processed messages.
+//
+// The provided flags is a set of platform-dependent flags, such as
+// syscall.MSG_DONTROUTE.
+//
+// Only Linux supports this.
+func (c *Conn) SendMsgs(ms []Message, flags int) (int, error) {
+ return c.sendMsgs(ms, flags)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/sys.go b/vendor/golang.org/x/net/internal/socket/sys.go
@@ -0,0 +1,23 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package socket
+
+import (
+ "encoding/binary"
+ "unsafe"
+)
+
+// NativeEndian is the machine native endian implementation of ByteOrder.
+var NativeEndian binary.ByteOrder
+
+func init() {
+ i := uint32(1)
+ b := (*[4]byte)(unsafe.Pointer(&i))
+ if b[0] == 1 {
+ NativeEndian = binary.LittleEndian
+ } else {
+ NativeEndian = binary.BigEndian
+ }
+}
diff --git a/vendor/golang.org/x/net/internal/socket/sys_bsd.go b/vendor/golang.org/x/net/internal/socket/sys_bsd.go
@@ -0,0 +1,16 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || openbsd || solaris
+// +build aix darwin dragonfly freebsd openbsd solaris
+
+package socket
+
+func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
+ return 0, errNotImplemented
+}
+
+func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
+ return 0, errNotImplemented
+}
diff --git a/vendor/golang.org/x/net/internal/socket/sys_const_unix.go b/vendor/golang.org/x/net/internal/socket/sys_const_unix.go
@@ -0,0 +1,21 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
+
+package socket
+
+import "golang.org/x/sys/unix"
+
+const (
+ sysAF_UNSPEC = unix.AF_UNSPEC
+ sysAF_INET = unix.AF_INET
+ sysAF_INET6 = unix.AF_INET6
+
+ sysSOCK_RAW = unix.SOCK_RAW
+
+ sizeofSockaddrInet4 = unix.SizeofSockaddrInet4
+ sizeofSockaddrInet6 = unix.SizeofSockaddrInet6
+)
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux.go b/vendor/golang.org/x/net/internal/socket/sys_linux.go
@@ -0,0 +1,23 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux && !s390x && !386
+// +build linux,!s390x,!386
+
+package socket
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
+ n, _, errno := syscall.Syscall6(sysRECVMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)
+ return int(n), errnoErr(errno)
+}
+
+func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
+ n, _, errno := syscall.Syscall6(sysSENDMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)
+ return int(n), errnoErr(errno)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_386.go b/vendor/golang.org/x/net/internal/socket/sys_linux_386.go
@@ -0,0 +1,28 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package socket
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+const (
+ sysRECVMMSG = 0x13
+ sysSENDMMSG = 0x14
+)
+
+func socketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno)
+func rawsocketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno)
+
+func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
+ n, errno := socketcall(sysRECVMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)
+ return int(n), errnoErr(errno)
+}
+
+func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
+ n, errno := socketcall(sysSENDMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)
+ return int(n), errnoErr(errno)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_386.s b/vendor/golang.org/x/net/internal/socket/sys_linux_386.s
@@ -0,0 +1,11 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·socketcall(SB),NOSPLIT,$0-36
+ JMP syscall·socketcall(SB)
+
+TEXT ·rawsocketcall(SB),NOSPLIT,$0-36
+ JMP syscall·rawsocketcall(SB)
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_amd64.go b/vendor/golang.org/x/net/internal/socket/sys_linux_amd64.go
@@ -0,0 +1,10 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package socket
+
+const (
+ sysRECVMMSG = 0x12b
+ sysSENDMMSG = 0x133
+)
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_arm.go b/vendor/golang.org/x/net/internal/socket/sys_linux_arm.go
@@ -0,0 +1,10 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package socket
+
+const (
+ sysRECVMMSG = 0x16d
+ sysSENDMMSG = 0x176
+)
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_arm64.go b/vendor/golang.org/x/net/internal/socket/sys_linux_arm64.go
@@ -0,0 +1,10 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package socket
+
+const (
+ sysRECVMMSG = 0xf3
+ sysSENDMMSG = 0x10d
+)
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_loong64.go b/vendor/golang.org/x/net/internal/socket/sys_linux_loong64.go
@@ -0,0 +1,13 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build loong64
+// +build loong64
+
+package socket
+
+const (
+ sysRECVMMSG = 0xf3
+ sysSENDMMSG = 0x10d
+)
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_mips.go b/vendor/golang.org/x/net/internal/socket/sys_linux_mips.go
@@ -0,0 +1,10 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package socket
+
+const (
+ sysRECVMMSG = 0x10ef
+ sysSENDMMSG = 0x10f7
+)
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_mips64.go b/vendor/golang.org/x/net/internal/socket/sys_linux_mips64.go
@@ -0,0 +1,10 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package socket
+
+const (
+ sysRECVMMSG = 0x14ae
+ sysSENDMMSG = 0x14b6
+)
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_mips64le.go b/vendor/golang.org/x/net/internal/socket/sys_linux_mips64le.go
@@ -0,0 +1,10 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package socket
+
+const (
+ sysRECVMMSG = 0x14ae
+ sysSENDMMSG = 0x14b6
+)
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_mipsle.go b/vendor/golang.org/x/net/internal/socket/sys_linux_mipsle.go
@@ -0,0 +1,10 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package socket
+
+const (
+ sysRECVMMSG = 0x10ef
+ sysSENDMMSG = 0x10f7
+)
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_ppc.go b/vendor/golang.org/x/net/internal/socket/sys_linux_ppc.go
@@ -0,0 +1,10 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package socket
+
+const (
+ sysRECVMMSG = 0x157
+ sysSENDMMSG = 0x15d
+)
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_ppc64.go b/vendor/golang.org/x/net/internal/socket/sys_linux_ppc64.go
@@ -0,0 +1,10 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package socket
+
+const (
+ sysRECVMMSG = 0x157
+ sysSENDMMSG = 0x15d
+)
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_ppc64le.go b/vendor/golang.org/x/net/internal/socket/sys_linux_ppc64le.go
@@ -0,0 +1,10 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package socket
+
+const (
+ sysRECVMMSG = 0x157
+ sysSENDMMSG = 0x15d
+)
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go b/vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go
@@ -0,0 +1,13 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build riscv64
+// +build riscv64
+
+package socket
+
+const (
+ sysRECVMMSG = 0xf3
+ sysSENDMMSG = 0x10d
+)
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_s390x.go b/vendor/golang.org/x/net/internal/socket/sys_linux_s390x.go
@@ -0,0 +1,28 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package socket
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+const (
+ sysRECVMMSG = 0x13
+ sysSENDMMSG = 0x14
+)
+
+func socketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno)
+func rawsocketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno)
+
+func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
+ n, errno := socketcall(sysRECVMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)
+ return int(n), errnoErr(errno)
+}
+
+func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
+ n, errno := socketcall(sysSENDMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)
+ return int(n), errnoErr(errno)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_s390x.s b/vendor/golang.org/x/net/internal/socket/sys_linux_s390x.s
@@ -0,0 +1,11 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·socketcall(SB),NOSPLIT,$0-72
+ JMP syscall·socketcall(SB)
+
+TEXT ·rawsocketcall(SB),NOSPLIT,$0-72
+ JMP syscall·rawsocketcall(SB)
diff --git a/vendor/golang.org/x/net/internal/socket/sys_netbsd.go b/vendor/golang.org/x/net/internal/socket/sys_netbsd.go
@@ -0,0 +1,25 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package socket
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+const (
+ sysRECVMMSG = 0x1db
+ sysSENDMMSG = 0x1dc
+)
+
+func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
+ n, _, errno := syscall.Syscall6(sysRECVMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)
+ return int(n), errnoErr(errno)
+}
+
+func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
+ n, _, errno := syscall.Syscall6(sysSENDMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)
+ return int(n), errnoErr(errno)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/sys_posix.go b/vendor/golang.org/x/net/internal/socket/sys_posix.go
@@ -0,0 +1,185 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows zos
+
+package socket
+
+import (
+ "encoding/binary"
+ "errors"
+ "net"
+ "runtime"
+ "strconv"
+ "sync"
+ "time"
+)
+
+// marshalInetAddr writes a in sockaddr format into the buffer b.
+// The buffer must be sufficiently large (sizeofSockaddrInet4/6).
+// Returns the number of bytes written.
+func marshalInetAddr(a net.Addr, b []byte) int {
+ switch a := a.(type) {
+ case *net.TCPAddr:
+ return marshalSockaddr(a.IP, a.Port, a.Zone, b)
+ case *net.UDPAddr:
+ return marshalSockaddr(a.IP, a.Port, a.Zone, b)
+ case *net.IPAddr:
+ return marshalSockaddr(a.IP, 0, a.Zone, b)
+ default:
+ return 0
+ }
+}
+
+func marshalSockaddr(ip net.IP, port int, zone string, b []byte) int {
+ if ip4 := ip.To4(); ip4 != nil {
+ switch runtime.GOOS {
+ case "android", "illumos", "linux", "solaris", "windows":
+ NativeEndian.PutUint16(b[:2], uint16(sysAF_INET))
+ default:
+ b[0] = sizeofSockaddrInet4
+ b[1] = sysAF_INET
+ }
+ binary.BigEndian.PutUint16(b[2:4], uint16(port))
+ copy(b[4:8], ip4)
+ return sizeofSockaddrInet4
+ }
+ if ip6 := ip.To16(); ip6 != nil && ip.To4() == nil {
+ switch runtime.GOOS {
+ case "android", "illumos", "linux", "solaris", "windows":
+ NativeEndian.PutUint16(b[:2], uint16(sysAF_INET6))
+ default:
+ b[0] = sizeofSockaddrInet6
+ b[1] = sysAF_INET6
+ }
+ binary.BigEndian.PutUint16(b[2:4], uint16(port))
+ copy(b[8:24], ip6)
+ if zone != "" {
+ NativeEndian.PutUint32(b[24:28], uint32(zoneCache.index(zone)))
+ }
+ return sizeofSockaddrInet6
+ }
+ return 0
+}
+
+func parseInetAddr(b []byte, network string) (net.Addr, error) {
+ if len(b) < 2 {
+ return nil, errors.New("invalid address")
+ }
+ var af int
+ switch runtime.GOOS {
+ case "android", "illumos", "linux", "solaris", "windows":
+ af = int(NativeEndian.Uint16(b[:2]))
+ default:
+ af = int(b[1])
+ }
+ var ip net.IP
+ var zone string
+ if af == sysAF_INET {
+ if len(b) < sizeofSockaddrInet4 {
+ return nil, errors.New("short address")
+ }
+ ip = make(net.IP, net.IPv4len)
+ copy(ip, b[4:8])
+ }
+ if af == sysAF_INET6 {
+ if len(b) < sizeofSockaddrInet6 {
+ return nil, errors.New("short address")
+ }
+ ip = make(net.IP, net.IPv6len)
+ copy(ip, b[8:24])
+ if id := int(NativeEndian.Uint32(b[24:28])); id > 0 {
+ zone = zoneCache.name(id)
+ }
+ }
+ switch network {
+ case "tcp", "tcp4", "tcp6":
+ return &net.TCPAddr{IP: ip, Port: int(binary.BigEndian.Uint16(b[2:4])), Zone: zone}, nil
+ case "udp", "udp4", "udp6":
+ return &net.UDPAddr{IP: ip, Port: int(binary.BigEndian.Uint16(b[2:4])), Zone: zone}, nil
+ default:
+ return &net.IPAddr{IP: ip, Zone: zone}, nil
+ }
+}
+
+// An ipv6ZoneCache represents a cache holding partial network
+// interface information. It is used for reducing the cost of IPv6
+// addressing scope zone resolution.
+//
+// Multiple names sharing the index are managed by first-come
+// first-served basis for consistency.
+type ipv6ZoneCache struct {
+ sync.RWMutex // guard the following
+ lastFetched time.Time // last time routing information was fetched
+ toIndex map[string]int // interface name to its index
+ toName map[int]string // interface index to its name
+}
+
+var zoneCache = ipv6ZoneCache{
+ toIndex: make(map[string]int),
+ toName: make(map[int]string),
+}
+
+// update refreshes the network interface information if the cache was last
+// updated more than 1 minute ago, or if force is set. It returns whether the
+// cache was updated.
+func (zc *ipv6ZoneCache) update(ift []net.Interface, force bool) (updated bool) {
+ zc.Lock()
+ defer zc.Unlock()
+ now := time.Now()
+ if !force && zc.lastFetched.After(now.Add(-60*time.Second)) {
+ return false
+ }
+ zc.lastFetched = now
+ if len(ift) == 0 {
+ var err error
+ if ift, err = net.Interfaces(); err != nil {
+ return false
+ }
+ }
+ zc.toIndex = make(map[string]int, len(ift))
+ zc.toName = make(map[int]string, len(ift))
+ for _, ifi := range ift {
+ zc.toIndex[ifi.Name] = ifi.Index
+ if _, ok := zc.toName[ifi.Index]; !ok {
+ zc.toName[ifi.Index] = ifi.Name
+ }
+ }
+ return true
+}
+
+func (zc *ipv6ZoneCache) name(zone int) string {
+ updated := zoneCache.update(nil, false)
+ zoneCache.RLock()
+ name, ok := zoneCache.toName[zone]
+ zoneCache.RUnlock()
+ if !ok && !updated {
+ zoneCache.update(nil, true)
+ zoneCache.RLock()
+ name, ok = zoneCache.toName[zone]
+ zoneCache.RUnlock()
+ }
+ if !ok { // last resort
+ name = strconv.Itoa(zone)
+ }
+ return name
+}
+
+func (zc *ipv6ZoneCache) index(zone string) int {
+ updated := zoneCache.update(nil, false)
+ zoneCache.RLock()
+ index, ok := zoneCache.toIndex[zone]
+ zoneCache.RUnlock()
+ if !ok && !updated {
+ zoneCache.update(nil, true)
+ zoneCache.RLock()
+ index, ok = zoneCache.toIndex[zone]
+ zoneCache.RUnlock()
+ }
+ if !ok { // last resort
+ index, _ = strconv.Atoi(zone)
+ }
+ return index
+}
diff --git a/vendor/golang.org/x/net/internal/socket/sys_stub.go b/vendor/golang.org/x/net/internal/socket/sys_stub.go
@@ -0,0 +1,53 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
+
+package socket
+
+import "net"
+
+const (
+ sysAF_UNSPEC = 0x0
+ sysAF_INET = 0x2
+ sysAF_INET6 = 0xa
+
+ sysSOCK_RAW = 0x3
+
+ sizeofSockaddrInet4 = 0x10
+ sizeofSockaddrInet6 = 0x1c
+)
+
+func marshalInetAddr(ip net.IP, port int, zone string) []byte {
+ return nil
+}
+
+func parseInetAddr(b []byte, network string) (net.Addr, error) {
+ return nil, errNotImplemented
+}
+
+func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
+ return 0, errNotImplemented
+}
+
+func setsockopt(s uintptr, level, name int, b []byte) error {
+ return errNotImplemented
+}
+
+func recvmsg(s uintptr, h *msghdr, flags int) (int, error) {
+ return 0, errNotImplemented
+}
+
+func sendmsg(s uintptr, h *msghdr, flags int) (int, error) {
+ return 0, errNotImplemented
+}
+
+func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
+ return 0, errNotImplemented
+}
+
+func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
+ return 0, errNotImplemented
+}
diff --git a/vendor/golang.org/x/net/internal/socket/sys_unix.go b/vendor/golang.org/x/net/internal/socket/sys_unix.go
@@ -0,0 +1,43 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package socket
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+//go:linkname syscall_getsockopt syscall.getsockopt
+func syscall_getsockopt(s, level, name int, val unsafe.Pointer, vallen *uint32) error
+
+//go:linkname syscall_setsockopt syscall.setsockopt
+func syscall_setsockopt(s, level, name int, val unsafe.Pointer, vallen uintptr) error
+
+//go:linkname syscall_recvmsg syscall.recvmsg
+func syscall_recvmsg(s int, msg *syscall.Msghdr, flags int) (int, error)
+
+//go:linkname syscall_sendmsg syscall.sendmsg
+func syscall_sendmsg(s int, msg *syscall.Msghdr, flags int) (int, error)
+
+func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
+ l := uint32(len(b))
+ err := syscall_getsockopt(int(s), level, name, unsafe.Pointer(&b[0]), &l)
+ return int(l), err
+}
+
+func setsockopt(s uintptr, level, name int, b []byte) error {
+ return syscall_setsockopt(int(s), level, name, unsafe.Pointer(&b[0]), uintptr(len(b)))
+}
+
+func recvmsg(s uintptr, h *msghdr, flags int) (int, error) {
+ return syscall_recvmsg(int(s), (*syscall.Msghdr)(unsafe.Pointer(h)), flags)
+}
+
+func sendmsg(s uintptr, h *msghdr, flags int) (int, error) {
+ return syscall_sendmsg(int(s), (*syscall.Msghdr)(unsafe.Pointer(h)), flags)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/sys_windows.go b/vendor/golang.org/x/net/internal/socket/sys_windows.go
@@ -0,0 +1,54 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package socket
+
+import (
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+func probeProtocolStack() int {
+ var p uintptr
+ return int(unsafe.Sizeof(p))
+}
+
+const (
+ sysAF_UNSPEC = windows.AF_UNSPEC
+ sysAF_INET = windows.AF_INET
+ sysAF_INET6 = windows.AF_INET6
+
+ sysSOCK_RAW = windows.SOCK_RAW
+
+ sizeofSockaddrInet4 = 0x10
+ sizeofSockaddrInet6 = 0x1c
+)
+
+func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
+ l := uint32(len(b))
+ err := syscall.Getsockopt(syscall.Handle(s), int32(level), int32(name), (*byte)(unsafe.Pointer(&b[0])), (*int32)(unsafe.Pointer(&l)))
+ return int(l), err
+}
+
+func setsockopt(s uintptr, level, name int, b []byte) error {
+ return syscall.Setsockopt(syscall.Handle(s), int32(level), int32(name), (*byte)(unsafe.Pointer(&b[0])), int32(len(b)))
+}
+
+func recvmsg(s uintptr, h *msghdr, flags int) (int, error) {
+ return 0, errNotImplemented
+}
+
+func sendmsg(s uintptr, h *msghdr, flags int) (int, error) {
+ return 0, errNotImplemented
+}
+
+func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
+ return 0, errNotImplemented
+}
+
+func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
+ return 0, errNotImplemented
+}
diff --git a/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.go b/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.go
@@ -0,0 +1,38 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package socket
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+func syscall_syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
+func syscall_syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
+
+func probeProtocolStack() int {
+ return 4 // sizeof(int) on GOOS=zos GOARCH=s390x
+}
+
+func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
+ l := uint32(len(b))
+ _, _, errno := syscall_syscall6(syscall.SYS_GETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(unsafe.Pointer(&l)), 0)
+ return int(l), errnoErr(errno)
+}
+
+func setsockopt(s uintptr, level, name int, b []byte) error {
+ _, _, errno := syscall_syscall6(syscall.SYS_SETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), 0)
+ return errnoErr(errno)
+}
+
+func recvmsg(s uintptr, h *msghdr, flags int) (int, error) {
+ n, _, errno := syscall_syscall(syscall.SYS___RECVMSG_A, s, uintptr(unsafe.Pointer(h)), uintptr(flags))
+ return int(n), errnoErr(errno)
+}
+
+func sendmsg(s uintptr, h *msghdr, flags int) (int, error) {
+ n, _, errno := syscall_syscall(syscall.SYS___SENDMSG_A, s, uintptr(unsafe.Pointer(h)), uintptr(flags))
+ return int(n), errnoErr(errno)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.s b/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.s
@@ -0,0 +1,11 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·syscall_syscall(SB),NOSPLIT,$0
+ JMP syscall·_syscall(SB)
+
+TEXT ·syscall_syscall6(SB),NOSPLIT,$0
+ JMP syscall·_syscall6(SB)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_aix_ppc64.go b/vendor/golang.org/x/net/internal/socket/zsys_aix_ppc64.go
@@ -0,0 +1,40 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_aix.go
+
+// Added for go1.11 compatibility
+//go:build aix
+// +build aix
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Iov *iovec
+ Iovlen int32
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type mmsghdr struct {
+ Hdr msghdr
+ Len uint32
+ Pad_cgo_0 [4]byte
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_darwin_386.go b/vendor/golang.org/x/net/internal/socket/zsys_darwin_386.go
@@ -0,0 +1,30 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_darwin.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint32
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Iov *iovec
+ Iovlen int32
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x8
+ sizeofMsghdr = 0x1c
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_darwin_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_darwin_amd64.go
@@ -0,0 +1,32 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_darwin.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Pad_cgo_0 [4]byte
+ Iov *iovec
+ Iovlen int32
+ Pad_cgo_1 [4]byte
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm.go b/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm.go
@@ -0,0 +1,30 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_darwin.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint32
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Iov *iovec
+ Iovlen int32
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x8
+ sizeofMsghdr = 0x1c
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm64.go b/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm64.go
@@ -0,0 +1,32 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_darwin.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Pad_cgo_0 [4]byte
+ Iov *iovec
+ Iovlen int32
+ Pad_cgo_1 [4]byte
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_dragonfly_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_dragonfly_amd64.go
@@ -0,0 +1,32 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_dragonfly.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Pad_cgo_0 [4]byte
+ Iov *iovec
+ Iovlen int32
+ Pad_cgo_1 [4]byte
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_386.go b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_386.go
@@ -0,0 +1,30 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_freebsd.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint32
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Iov *iovec
+ Iovlen int32
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x8
+ sizeofMsghdr = 0x1c
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_amd64.go
@@ -0,0 +1,32 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_freebsd.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Pad_cgo_0 [4]byte
+ Iov *iovec
+ Iovlen int32
+ Pad_cgo_1 [4]byte
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm.go b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm.go
@@ -0,0 +1,30 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_freebsd.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint32
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Iov *iovec
+ Iovlen int32
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x8
+ sizeofMsghdr = 0x1c
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm64.go b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm64.go
@@ -0,0 +1,32 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_freebsd.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Pad_cgo_0 [4]byte
+ Iov *iovec
+ Iovlen int32
+ Pad_cgo_1 [4]byte
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_386.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_386.go
@@ -0,0 +1,35 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint32
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Iov *iovec
+ Iovlen uint32
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type mmsghdr struct {
+ Hdr msghdr
+ Len uint32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x8
+ sizeofMsghdr = 0x1c
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_amd64.go
@@ -0,0 +1,38 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Pad_cgo_0 [4]byte
+ Iov *iovec
+ Iovlen uint64
+ Control *byte
+ Controllen uint64
+ Flags int32
+ Pad_cgo_1 [4]byte
+}
+
+type mmsghdr struct {
+ Hdr msghdr
+ Len uint32
+ Pad_cgo_0 [4]byte
+}
+
+type cmsghdr struct {
+ Len uint64
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x38
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_arm.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_arm.go
@@ -0,0 +1,35 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint32
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Iov *iovec
+ Iovlen uint32
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type mmsghdr struct {
+ Hdr msghdr
+ Len uint32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x8
+ sizeofMsghdr = 0x1c
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_arm64.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_arm64.go
@@ -0,0 +1,38 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Pad_cgo_0 [4]byte
+ Iov *iovec
+ Iovlen uint64
+ Control *byte
+ Controllen uint64
+ Flags int32
+ Pad_cgo_1 [4]byte
+}
+
+type mmsghdr struct {
+ Hdr msghdr
+ Len uint32
+ Pad_cgo_0 [4]byte
+}
+
+type cmsghdr struct {
+ Len uint64
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x38
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_loong64.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_loong64.go
@@ -0,0 +1,40 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+//go:build loong64
+// +build loong64
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Iov *iovec
+ Iovlen uint64
+ Control *byte
+ Controllen uint64
+ Flags int32
+ Pad_cgo_0 [4]byte
+}
+
+type mmsghdr struct {
+ Hdr msghdr
+ Len uint32
+ Pad_cgo_0 [4]byte
+}
+
+type cmsghdr struct {
+ Len uint64
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x38
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_mips.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_mips.go
@@ -0,0 +1,35 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint32
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Iov *iovec
+ Iovlen uint32
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type mmsghdr struct {
+ Hdr msghdr
+ Len uint32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x8
+ sizeofMsghdr = 0x1c
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64.go
@@ -0,0 +1,38 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Pad_cgo_0 [4]byte
+ Iov *iovec
+ Iovlen uint64
+ Control *byte
+ Controllen uint64
+ Flags int32
+ Pad_cgo_1 [4]byte
+}
+
+type mmsghdr struct {
+ Hdr msghdr
+ Len uint32
+ Pad_cgo_0 [4]byte
+}
+
+type cmsghdr struct {
+ Len uint64
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x38
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64le.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64le.go
@@ -0,0 +1,38 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Pad_cgo_0 [4]byte
+ Iov *iovec
+ Iovlen uint64
+ Control *byte
+ Controllen uint64
+ Flags int32
+ Pad_cgo_1 [4]byte
+}
+
+type mmsghdr struct {
+ Hdr msghdr
+ Len uint32
+ Pad_cgo_0 [4]byte
+}
+
+type cmsghdr struct {
+ Len uint64
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x38
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_mipsle.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_mipsle.go
@@ -0,0 +1,35 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint32
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Iov *iovec
+ Iovlen uint32
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type mmsghdr struct {
+ Hdr msghdr
+ Len uint32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x8
+ sizeofMsghdr = 0x1c
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc.go
@@ -0,0 +1,35 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint32
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Iov *iovec
+ Iovlen uint32
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type mmsghdr struct {
+ Hdr msghdr
+ Len uint32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x8
+ sizeofMsghdr = 0x1c
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64.go
@@ -0,0 +1,38 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Pad_cgo_0 [4]byte
+ Iov *iovec
+ Iovlen uint64
+ Control *byte
+ Controllen uint64
+ Flags int32
+ Pad_cgo_1 [4]byte
+}
+
+type mmsghdr struct {
+ Hdr msghdr
+ Len uint32
+ Pad_cgo_0 [4]byte
+}
+
+type cmsghdr struct {
+ Len uint64
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x38
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64le.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64le.go
@@ -0,0 +1,38 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Pad_cgo_0 [4]byte
+ Iov *iovec
+ Iovlen uint64
+ Control *byte
+ Controllen uint64
+ Flags int32
+ Pad_cgo_1 [4]byte
+}
+
+type mmsghdr struct {
+ Hdr msghdr
+ Len uint32
+ Pad_cgo_0 [4]byte
+}
+
+type cmsghdr struct {
+ Len uint64
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x38
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_riscv64.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_riscv64.go
@@ -0,0 +1,40 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+//go:build riscv64
+// +build riscv64
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Iov *iovec
+ Iovlen uint64
+ Control *byte
+ Controllen uint64
+ Flags int32
+ Pad_cgo_0 [4]byte
+}
+
+type mmsghdr struct {
+ Hdr msghdr
+ Len uint32
+ Pad_cgo_0 [4]byte
+}
+
+type cmsghdr struct {
+ Len uint64
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x38
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_s390x.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_s390x.go
@@ -0,0 +1,38 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Pad_cgo_0 [4]byte
+ Iov *iovec
+ Iovlen uint64
+ Control *byte
+ Controllen uint64
+ Flags int32
+ Pad_cgo_1 [4]byte
+}
+
+type mmsghdr struct {
+ Hdr msghdr
+ Len uint32
+ Pad_cgo_0 [4]byte
+}
+
+type cmsghdr struct {
+ Len uint64
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x38
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_386.go b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_386.go
@@ -0,0 +1,35 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_netbsd.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint32
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Iov *iovec
+ Iovlen int32
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type mmsghdr struct {
+ Hdr msghdr
+ Len uint32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x8
+ sizeofMsghdr = 0x1c
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_amd64.go
@@ -0,0 +1,38 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_netbsd.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Pad_cgo_0 [4]byte
+ Iov *iovec
+ Iovlen int32
+ Pad_cgo_1 [4]byte
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type mmsghdr struct {
+ Hdr msghdr
+ Len uint32
+ Pad_cgo_0 [4]byte
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm.go b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm.go
@@ -0,0 +1,35 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_netbsd.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint32
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Iov *iovec
+ Iovlen int32
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type mmsghdr struct {
+ Hdr msghdr
+ Len uint32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x8
+ sizeofMsghdr = 0x1c
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm64.go b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm64.go
@@ -0,0 +1,38 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_netbsd.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Pad_cgo_0 [4]byte
+ Iov *iovec
+ Iovlen int32
+ Pad_cgo_1 [4]byte
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type mmsghdr struct {
+ Hdr msghdr
+ Len uint32
+ Pad_cgo_0 [4]byte
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_386.go b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_386.go
@@ -0,0 +1,30 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_openbsd.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint32
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Iov *iovec
+ Iovlen uint32
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x8
+ sizeofMsghdr = 0x1c
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_amd64.go
@@ -0,0 +1,32 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_openbsd.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Pad_cgo_0 [4]byte
+ Iov *iovec
+ Iovlen uint32
+ Pad_cgo_1 [4]byte
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm.go b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm.go
@@ -0,0 +1,30 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_openbsd.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint32
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Iov *iovec
+ Iovlen uint32
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x8
+ sizeofMsghdr = 0x1c
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm64.go b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm64.go
@@ -0,0 +1,32 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_openbsd.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Pad_cgo_0 [4]byte
+ Iov *iovec
+ Iovlen uint32
+ Pad_cgo_1 [4]byte
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_mips64.go b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_mips64.go
@@ -0,0 +1,30 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_openbsd.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Iov *iovec
+ Iovlen uint32
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_solaris_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_solaris_amd64.go
@@ -0,0 +1,32 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_solaris.go
+
+package socket
+
+type iovec struct {
+ Base *int8
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Pad_cgo_0 [4]byte
+ Iov *iovec
+ Iovlen int32
+ Pad_cgo_1 [4]byte
+ Accrights *int8
+ Accrightslen int32
+ Pad_cgo_2 [4]byte
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_zos_s390x.go b/vendor/golang.org/x/net/internal/socket/zsys_zos_s390x.go
@@ -0,0 +1,28 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Iov *iovec
+ Control *byte
+ Flags int32
+ Namelen uint32
+ Iovlen int32
+ Controllen uint32
+}
+
+type cmsghdr struct {
+ Len int32
+ Level int32
+ Type int32
+}
+
+const sizeofCmsghdr = 12
diff --git a/vendor/golang.org/x/net/ipv4/batch.go b/vendor/golang.org/x/net/ipv4/batch.go
@@ -0,0 +1,194 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv4
+
+import (
+ "net"
+ "runtime"
+
+ "golang.org/x/net/internal/socket"
+)
+
+// BUG(mikio): On Windows, the ReadBatch and WriteBatch methods of
+// PacketConn are not implemented.
+
+// BUG(mikio): On Windows, the ReadBatch and WriteBatch methods of
+// RawConn are not implemented.
+
+// A Message represents an IO message.
+//
+// type Message struct {
+// Buffers [][]byte
+// OOB []byte
+// Addr net.Addr
+// N int
+// NN int
+// Flags int
+// }
+//
+// The Buffers fields represents a list of contiguous buffers, which
+// can be used for vectored IO, for example, putting a header and a
+// payload in each slice.
+// When writing, the Buffers field must contain at least one byte to
+// write.
+// When reading, the Buffers field will always contain a byte to read.
+//
+// The OOB field contains protocol-specific control or miscellaneous
+// ancillary data known as out-of-band data.
+// It can be nil when not required.
+//
+// The Addr field specifies a destination address when writing.
+// It can be nil when the underlying protocol of the endpoint uses
+// connection-oriented communication.
+// After a successful read, it may contain the source address on the
+// received packet.
+//
+// The N field indicates the number of bytes read or written from/to
+// Buffers.
+//
+// The NN field indicates the number of bytes read or written from/to
+// OOB.
+//
+// The Flags field contains protocol-specific information on the
+// received message.
+type Message = socket.Message
+
+// ReadBatch reads a batch of messages.
+//
+// The provided flags is a set of platform-dependent flags, such as
+// syscall.MSG_PEEK.
+//
+// On a successful read it returns the number of messages received, up
+// to len(ms).
+//
+// On Linux, a batch read will be optimized.
+// On other platforms, this method will read only a single message.
+//
+// Unlike the ReadFrom method, it doesn't strip the IPv4 header
+// followed by option headers from the received IPv4 datagram when the
+// underlying transport is net.IPConn. Each Buffers field of Message
+// must be large enough to accommodate an IPv4 header and option
+// headers.
+func (c *payloadHandler) ReadBatch(ms []Message, flags int) (int, error) {
+ if !c.ok() {
+ return 0, errInvalidConn
+ }
+ switch runtime.GOOS {
+ case "linux":
+ n, err := c.RecvMsgs([]socket.Message(ms), flags)
+ if err != nil {
+ err = &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
+ }
+ return n, err
+ default:
+ n := 1
+ err := c.RecvMsg(&ms[0], flags)
+ if err != nil {
+ n = 0
+ err = &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
+ }
+ if compatFreeBSD32 && ms[0].NN > 0 {
+ adjustFreeBSD32(&ms[0])
+ }
+ return n, err
+ }
+}
+
+// WriteBatch writes a batch of messages.
+//
+// The provided flags is a set of platform-dependent flags, such as
+// syscall.MSG_DONTROUTE.
+//
+// It returns the number of messages written on a successful write.
+//
+// On Linux, a batch write will be optimized.
+// On other platforms, this method will write only a single message.
+func (c *payloadHandler) WriteBatch(ms []Message, flags int) (int, error) {
+ if !c.ok() {
+ return 0, errInvalidConn
+ }
+ switch runtime.GOOS {
+ case "linux":
+ n, err := c.SendMsgs([]socket.Message(ms), flags)
+ if err != nil {
+ err = &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
+ }
+ return n, err
+ default:
+ n := 1
+ err := c.SendMsg(&ms[0], flags)
+ if err != nil {
+ n = 0
+ err = &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
+ }
+ return n, err
+ }
+}
+
+// ReadBatch reads a batch of messages.
+//
+// The provided flags is a set of platform-dependent flags, such as
+// syscall.MSG_PEEK.
+//
+// On a successful read it returns the number of messages received, up
+// to len(ms).
+//
+// On Linux, a batch read will be optimized.
+// On other platforms, this method will read only a single message.
+func (c *packetHandler) ReadBatch(ms []Message, flags int) (int, error) {
+ if !c.ok() {
+ return 0, errInvalidConn
+ }
+ switch runtime.GOOS {
+ case "linux":
+ n, err := c.RecvMsgs([]socket.Message(ms), flags)
+ if err != nil {
+ err = &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
+ }
+ return n, err
+ default:
+ n := 1
+ err := c.RecvMsg(&ms[0], flags)
+ if err != nil {
+ n = 0
+ err = &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
+ }
+ if compatFreeBSD32 && ms[0].NN > 0 {
+ adjustFreeBSD32(&ms[0])
+ }
+ return n, err
+ }
+}
+
+// WriteBatch writes a batch of messages.
+//
+// The provided flags is a set of platform-dependent flags, such as
+// syscall.MSG_DONTROUTE.
+//
+// It returns the number of messages written on a successful write.
+//
+// On Linux, a batch write will be optimized.
+// On other platforms, this method will write only a single message.
+func (c *packetHandler) WriteBatch(ms []Message, flags int) (int, error) {
+ if !c.ok() {
+ return 0, errInvalidConn
+ }
+ switch runtime.GOOS {
+ case "linux":
+ n, err := c.SendMsgs([]socket.Message(ms), flags)
+ if err != nil {
+ err = &net.OpError{Op: "write", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
+ }
+ return n, err
+ default:
+ n := 1
+ err := c.SendMsg(&ms[0], flags)
+ if err != nil {
+ n = 0
+ err = &net.OpError{Op: "write", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
+ }
+ return n, err
+ }
+}
diff --git a/vendor/golang.org/x/net/ipv4/control.go b/vendor/golang.org/x/net/ipv4/control.go
@@ -0,0 +1,144 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv4
+
+import (
+ "fmt"
+ "net"
+ "sync"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+)
+
+type rawOpt struct {
+ sync.RWMutex
+ cflags ControlFlags
+}
+
+func (c *rawOpt) set(f ControlFlags) { c.cflags |= f }
+func (c *rawOpt) clear(f ControlFlags) { c.cflags &^= f }
+func (c *rawOpt) isset(f ControlFlags) bool { return c.cflags&f != 0 }
+
+type ControlFlags uint
+
+const (
+ FlagTTL ControlFlags = 1 << iota // pass the TTL on the received packet
+ FlagSrc // pass the source address on the received packet
+ FlagDst // pass the destination address on the received packet
+ FlagInterface // pass the interface index on the received packet
+)
+
+// A ControlMessage represents per packet basis IP-level socket options.
+type ControlMessage struct {
+ // Receiving socket options: SetControlMessage allows to
+ // receive the options from the protocol stack using ReadFrom
+ // method of PacketConn or RawConn.
+ //
+ // Specifying socket options: ControlMessage for WriteTo
+ // method of PacketConn or RawConn allows to send the options
+ // to the protocol stack.
+ //
+ TTL int // time-to-live, receiving only
+ Src net.IP // source address, specifying only
+ Dst net.IP // destination address, receiving only
+ IfIndex int // interface index, must be 1 <= value when specifying
+}
+
+func (cm *ControlMessage) String() string {
+ if cm == nil {
+ return "<nil>"
+ }
+ return fmt.Sprintf("ttl=%d src=%v dst=%v ifindex=%d", cm.TTL, cm.Src, cm.Dst, cm.IfIndex)
+}
+
+// Marshal returns the binary encoding of cm.
+func (cm *ControlMessage) Marshal() []byte {
+ if cm == nil {
+ return nil
+ }
+ var m socket.ControlMessage
+ if ctlOpts[ctlPacketInfo].name > 0 && (cm.Src.To4() != nil || cm.IfIndex > 0) {
+ m = socket.NewControlMessage([]int{ctlOpts[ctlPacketInfo].length})
+ }
+ if len(m) > 0 {
+ ctlOpts[ctlPacketInfo].marshal(m, cm)
+ }
+ return m
+}
+
+// Parse parses b as a control message and stores the result in cm.
+func (cm *ControlMessage) Parse(b []byte) error {
+ ms, err := socket.ControlMessage(b).Parse()
+ if err != nil {
+ return err
+ }
+ for _, m := range ms {
+ lvl, typ, l, err := m.ParseHeader()
+ if err != nil {
+ return err
+ }
+ if lvl != iana.ProtocolIP {
+ continue
+ }
+ switch {
+ case typ == ctlOpts[ctlTTL].name && l >= ctlOpts[ctlTTL].length:
+ ctlOpts[ctlTTL].parse(cm, m.Data(l))
+ case typ == ctlOpts[ctlDst].name && l >= ctlOpts[ctlDst].length:
+ ctlOpts[ctlDst].parse(cm, m.Data(l))
+ case typ == ctlOpts[ctlInterface].name && l >= ctlOpts[ctlInterface].length:
+ ctlOpts[ctlInterface].parse(cm, m.Data(l))
+ case typ == ctlOpts[ctlPacketInfo].name && l >= ctlOpts[ctlPacketInfo].length:
+ ctlOpts[ctlPacketInfo].parse(cm, m.Data(l))
+ }
+ }
+ return nil
+}
+
+// NewControlMessage returns a new control message.
+//
+// The returned message is large enough for options specified by cf.
+func NewControlMessage(cf ControlFlags) []byte {
+ opt := rawOpt{cflags: cf}
+ var l int
+ if opt.isset(FlagTTL) && ctlOpts[ctlTTL].name > 0 {
+ l += socket.ControlMessageSpace(ctlOpts[ctlTTL].length)
+ }
+ if ctlOpts[ctlPacketInfo].name > 0 {
+ if opt.isset(FlagSrc | FlagDst | FlagInterface) {
+ l += socket.ControlMessageSpace(ctlOpts[ctlPacketInfo].length)
+ }
+ } else {
+ if opt.isset(FlagDst) && ctlOpts[ctlDst].name > 0 {
+ l += socket.ControlMessageSpace(ctlOpts[ctlDst].length)
+ }
+ if opt.isset(FlagInterface) && ctlOpts[ctlInterface].name > 0 {
+ l += socket.ControlMessageSpace(ctlOpts[ctlInterface].length)
+ }
+ }
+ var b []byte
+ if l > 0 {
+ b = make([]byte, l)
+ }
+ return b
+}
+
+// Ancillary data socket options
+const (
+ ctlTTL = iota // header field
+ ctlSrc // header field
+ ctlDst // header field
+ ctlInterface // inbound or outbound interface
+ ctlPacketInfo // inbound or outbound packet path
+ ctlMax
+)
+
+// A ctlOpt represents a binding for ancillary data socket option.
+type ctlOpt struct {
+ name int // option name, must be equal or greater than 1
+ length int // option length
+ marshal func([]byte, *ControlMessage) []byte
+ parse func(*ControlMessage, []byte)
+}
diff --git a/vendor/golang.org/x/net/ipv4/control_bsd.go b/vendor/golang.org/x/net/ipv4/control_bsd.go
@@ -0,0 +1,44 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd
+// +build aix darwin dragonfly freebsd netbsd openbsd
+
+package ipv4
+
+import (
+ "net"
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
+)
+
+func marshalDst(b []byte, cm *ControlMessage) []byte {
+ m := socket.ControlMessage(b)
+ m.MarshalHeader(iana.ProtocolIP, unix.IP_RECVDSTADDR, net.IPv4len)
+ return m.Next(net.IPv4len)
+}
+
+func parseDst(cm *ControlMessage, b []byte) {
+ if len(cm.Dst) < net.IPv4len {
+ cm.Dst = make(net.IP, net.IPv4len)
+ }
+ copy(cm.Dst, b[:net.IPv4len])
+}
+
+func marshalInterface(b []byte, cm *ControlMessage) []byte {
+ m := socket.ControlMessage(b)
+ m.MarshalHeader(iana.ProtocolIP, sockoptReceiveInterface, syscall.SizeofSockaddrDatalink)
+ return m.Next(syscall.SizeofSockaddrDatalink)
+}
+
+func parseInterface(cm *ControlMessage, b []byte) {
+ var sadl syscall.SockaddrDatalink
+ copy((*[unsafe.Sizeof(sadl)]byte)(unsafe.Pointer(&sadl))[:], b)
+ cm.IfIndex = int(sadl.Index)
+}
diff --git a/vendor/golang.org/x/net/ipv4/control_pktinfo.go b/vendor/golang.org/x/net/ipv4/control_pktinfo.go
@@ -0,0 +1,42 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build darwin || linux || solaris
+// +build darwin linux solaris
+
+package ipv4
+
+import (
+ "net"
+ "unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
+)
+
+func marshalPacketInfo(b []byte, cm *ControlMessage) []byte {
+ m := socket.ControlMessage(b)
+ m.MarshalHeader(iana.ProtocolIP, unix.IP_PKTINFO, sizeofInetPktinfo)
+ if cm != nil {
+ pi := (*inetPktinfo)(unsafe.Pointer(&m.Data(sizeofInetPktinfo)[0]))
+ if ip := cm.Src.To4(); ip != nil {
+ copy(pi.Spec_dst[:], ip)
+ }
+ if cm.IfIndex > 0 {
+ pi.setIfindex(cm.IfIndex)
+ }
+ }
+ return m.Next(sizeofInetPktinfo)
+}
+
+func parsePacketInfo(cm *ControlMessage, b []byte) {
+ pi := (*inetPktinfo)(unsafe.Pointer(&b[0]))
+ cm.IfIndex = int(pi.Ifindex)
+ if len(cm.Dst) < net.IPv4len {
+ cm.Dst = make(net.IP, net.IPv4len)
+ }
+ copy(cm.Dst, pi.Addr[:])
+}
diff --git a/vendor/golang.org/x/net/ipv4/control_stub.go b/vendor/golang.org/x/net/ipv4/control_stub.go
@@ -0,0 +1,14 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
+
+package ipv4
+
+import "golang.org/x/net/internal/socket"
+
+func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
+ return errNotImplemented
+}
diff --git a/vendor/golang.org/x/net/ipv4/control_unix.go b/vendor/golang.org/x/net/ipv4/control_unix.go
@@ -0,0 +1,76 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package ipv4
+
+import (
+ "unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
+)
+
+func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
+ opt.Lock()
+ defer opt.Unlock()
+ if so, ok := sockOpts[ssoReceiveTTL]; ok && cf&FlagTTL != 0 {
+ if err := so.SetInt(c, boolint(on)); err != nil {
+ return err
+ }
+ if on {
+ opt.set(FlagTTL)
+ } else {
+ opt.clear(FlagTTL)
+ }
+ }
+ if so, ok := sockOpts[ssoPacketInfo]; ok {
+ if cf&(FlagSrc|FlagDst|FlagInterface) != 0 {
+ if err := so.SetInt(c, boolint(on)); err != nil {
+ return err
+ }
+ if on {
+ opt.set(cf & (FlagSrc | FlagDst | FlagInterface))
+ } else {
+ opt.clear(cf & (FlagSrc | FlagDst | FlagInterface))
+ }
+ }
+ } else {
+ if so, ok := sockOpts[ssoReceiveDst]; ok && cf&FlagDst != 0 {
+ if err := so.SetInt(c, boolint(on)); err != nil {
+ return err
+ }
+ if on {
+ opt.set(FlagDst)
+ } else {
+ opt.clear(FlagDst)
+ }
+ }
+ if so, ok := sockOpts[ssoReceiveInterface]; ok && cf&FlagInterface != 0 {
+ if err := so.SetInt(c, boolint(on)); err != nil {
+ return err
+ }
+ if on {
+ opt.set(FlagInterface)
+ } else {
+ opt.clear(FlagInterface)
+ }
+ }
+ }
+ return nil
+}
+
+func marshalTTL(b []byte, cm *ControlMessage) []byte {
+ m := socket.ControlMessage(b)
+ m.MarshalHeader(iana.ProtocolIP, unix.IP_RECVTTL, 1)
+ return m.Next(1)
+}
+
+func parseTTL(cm *ControlMessage, b []byte) {
+ cm.TTL = int(*(*byte)(unsafe.Pointer(&b[:1][0])))
+}
diff --git a/vendor/golang.org/x/net/ipv4/control_windows.go b/vendor/golang.org/x/net/ipv4/control_windows.go
@@ -0,0 +1,12 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv4
+
+import "golang.org/x/net/internal/socket"
+
+func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
+ // TODO(mikio): implement this
+ return errNotImplemented
+}
diff --git a/vendor/golang.org/x/net/ipv4/control_zos.go b/vendor/golang.org/x/net/ipv4/control_zos.go
@@ -0,0 +1,88 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv4
+
+import (
+ "net"
+ "unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
+)
+
+func marshalPacketInfo(b []byte, cm *ControlMessage) []byte {
+ m := socket.ControlMessage(b)
+ m.MarshalHeader(iana.ProtocolIP, unix.IP_PKTINFO, sizeofInetPktinfo)
+ if cm != nil {
+ pi := (*inetPktinfo)(unsafe.Pointer(&m.Data(sizeofInetPktinfo)[0]))
+ if ip := cm.Src.To4(); ip != nil {
+ copy(pi.Addr[:], ip)
+ }
+ if cm.IfIndex > 0 {
+ pi.setIfindex(cm.IfIndex)
+ }
+ }
+ return m.Next(sizeofInetPktinfo)
+}
+
+func parsePacketInfo(cm *ControlMessage, b []byte) {
+ pi := (*inetPktinfo)(unsafe.Pointer(&b[0]))
+ cm.IfIndex = int(pi.Ifindex)
+ if len(cm.Dst) < net.IPv4len {
+ cm.Dst = make(net.IP, net.IPv4len)
+ }
+ copy(cm.Dst, pi.Addr[:])
+}
+
+func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
+ opt.Lock()
+ defer opt.Unlock()
+ if so, ok := sockOpts[ssoReceiveTTL]; ok && cf&FlagTTL != 0 {
+ if err := so.SetInt(c, boolint(on)); err != nil {
+ return err
+ }
+ if on {
+ opt.set(FlagTTL)
+ } else {
+ opt.clear(FlagTTL)
+ }
+ }
+ if so, ok := sockOpts[ssoPacketInfo]; ok {
+ if cf&(FlagSrc|FlagDst|FlagInterface) != 0 {
+ if err := so.SetInt(c, boolint(on)); err != nil {
+ return err
+ }
+ if on {
+ opt.set(cf & (FlagSrc | FlagDst | FlagInterface))
+ } else {
+ opt.clear(cf & (FlagSrc | FlagDst | FlagInterface))
+ }
+ }
+ } else {
+ if so, ok := sockOpts[ssoReceiveDst]; ok && cf&FlagDst != 0 {
+ if err := so.SetInt(c, boolint(on)); err != nil {
+ return err
+ }
+ if on {
+ opt.set(FlagDst)
+ } else {
+ opt.clear(FlagDst)
+ }
+ }
+ if so, ok := sockOpts[ssoReceiveInterface]; ok && cf&FlagInterface != 0 {
+ if err := so.SetInt(c, boolint(on)); err != nil {
+ return err
+ }
+ if on {
+ opt.set(FlagInterface)
+ } else {
+ opt.clear(FlagInterface)
+ }
+ }
+ }
+ return nil
+}
diff --git a/vendor/golang.org/x/net/ipv4/dgramopt.go b/vendor/golang.org/x/net/ipv4/dgramopt.go
@@ -0,0 +1,264 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv4
+
+import (
+ "net"
+
+ "golang.org/x/net/bpf"
+)
+
+// MulticastTTL returns the time-to-live field value for outgoing
+// multicast packets.
+func (c *dgramOpt) MulticastTTL() (int, error) {
+ if !c.ok() {
+ return 0, errInvalidConn
+ }
+ so, ok := sockOpts[ssoMulticastTTL]
+ if !ok {
+ return 0, errNotImplemented
+ }
+ return so.GetInt(c.Conn)
+}
+
+// SetMulticastTTL sets the time-to-live field value for future
+// outgoing multicast packets.
+func (c *dgramOpt) SetMulticastTTL(ttl int) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoMulticastTTL]
+ if !ok {
+ return errNotImplemented
+ }
+ return so.SetInt(c.Conn, ttl)
+}
+
+// MulticastInterface returns the default interface for multicast
+// packet transmissions.
+func (c *dgramOpt) MulticastInterface() (*net.Interface, error) {
+ if !c.ok() {
+ return nil, errInvalidConn
+ }
+ so, ok := sockOpts[ssoMulticastInterface]
+ if !ok {
+ return nil, errNotImplemented
+ }
+ return so.getMulticastInterface(c.Conn)
+}
+
+// SetMulticastInterface sets the default interface for future
+// multicast packet transmissions.
+func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoMulticastInterface]
+ if !ok {
+ return errNotImplemented
+ }
+ return so.setMulticastInterface(c.Conn, ifi)
+}
+
+// MulticastLoopback reports whether transmitted multicast packets
+// should be copied and send back to the originator.
+func (c *dgramOpt) MulticastLoopback() (bool, error) {
+ if !c.ok() {
+ return false, errInvalidConn
+ }
+ so, ok := sockOpts[ssoMulticastLoopback]
+ if !ok {
+ return false, errNotImplemented
+ }
+ on, err := so.GetInt(c.Conn)
+ if err != nil {
+ return false, err
+ }
+ return on == 1, nil
+}
+
+// SetMulticastLoopback sets whether transmitted multicast packets
+// should be copied and send back to the originator.
+func (c *dgramOpt) SetMulticastLoopback(on bool) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoMulticastLoopback]
+ if !ok {
+ return errNotImplemented
+ }
+ return so.SetInt(c.Conn, boolint(on))
+}
+
+// JoinGroup joins the group address group on the interface ifi.
+// By default all sources that can cast data to group are accepted.
+// It's possible to mute and unmute data transmission from a specific
+// source by using ExcludeSourceSpecificGroup and
+// IncludeSourceSpecificGroup.
+// JoinGroup uses the system assigned multicast interface when ifi is
+// nil, although this is not recommended because the assignment
+// depends on platforms and sometimes it might require routing
+// configuration.
+func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoJoinGroup]
+ if !ok {
+ return errNotImplemented
+ }
+ grp := netAddrToIP4(group)
+ if grp == nil {
+ return errMissingAddress
+ }
+ return so.setGroup(c.Conn, ifi, grp)
+}
+
+// LeaveGroup leaves the group address group on the interface ifi
+// regardless of whether the group is any-source group or
+// source-specific group.
+func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoLeaveGroup]
+ if !ok {
+ return errNotImplemented
+ }
+ grp := netAddrToIP4(group)
+ if grp == nil {
+ return errMissingAddress
+ }
+ return so.setGroup(c.Conn, ifi, grp)
+}
+
+// JoinSourceSpecificGroup joins the source-specific group comprising
+// group and source on the interface ifi.
+// JoinSourceSpecificGroup uses the system assigned multicast
+// interface when ifi is nil, although this is not recommended because
+// the assignment depends on platforms and sometimes it might require
+// routing configuration.
+func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoJoinSourceGroup]
+ if !ok {
+ return errNotImplemented
+ }
+ grp := netAddrToIP4(group)
+ if grp == nil {
+ return errMissingAddress
+ }
+ src := netAddrToIP4(source)
+ if src == nil {
+ return errMissingAddress
+ }
+ return so.setSourceGroup(c.Conn, ifi, grp, src)
+}
+
+// LeaveSourceSpecificGroup leaves the source-specific group on the
+// interface ifi.
+func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoLeaveSourceGroup]
+ if !ok {
+ return errNotImplemented
+ }
+ grp := netAddrToIP4(group)
+ if grp == nil {
+ return errMissingAddress
+ }
+ src := netAddrToIP4(source)
+ if src == nil {
+ return errMissingAddress
+ }
+ return so.setSourceGroup(c.Conn, ifi, grp, src)
+}
+
+// ExcludeSourceSpecificGroup excludes the source-specific group from
+// the already joined any-source groups by JoinGroup on the interface
+// ifi.
+func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoBlockSourceGroup]
+ if !ok {
+ return errNotImplemented
+ }
+ grp := netAddrToIP4(group)
+ if grp == nil {
+ return errMissingAddress
+ }
+ src := netAddrToIP4(source)
+ if src == nil {
+ return errMissingAddress
+ }
+ return so.setSourceGroup(c.Conn, ifi, grp, src)
+}
+
+// IncludeSourceSpecificGroup includes the excluded source-specific
+// group by ExcludeSourceSpecificGroup again on the interface ifi.
+func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoUnblockSourceGroup]
+ if !ok {
+ return errNotImplemented
+ }
+ grp := netAddrToIP4(group)
+ if grp == nil {
+ return errMissingAddress
+ }
+ src := netAddrToIP4(source)
+ if src == nil {
+ return errMissingAddress
+ }
+ return so.setSourceGroup(c.Conn, ifi, grp, src)
+}
+
+// ICMPFilter returns an ICMP filter.
+// Currently only Linux supports this.
+func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) {
+ if !c.ok() {
+ return nil, errInvalidConn
+ }
+ so, ok := sockOpts[ssoICMPFilter]
+ if !ok {
+ return nil, errNotImplemented
+ }
+ return so.getICMPFilter(c.Conn)
+}
+
+// SetICMPFilter deploys the ICMP filter.
+// Currently only Linux supports this.
+func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoICMPFilter]
+ if !ok {
+ return errNotImplemented
+ }
+ return so.setICMPFilter(c.Conn, f)
+}
+
+// SetBPF attaches a BPF program to the connection.
+//
+// Only supported on Linux.
+func (c *dgramOpt) SetBPF(filter []bpf.RawInstruction) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoAttachFilter]
+ if !ok {
+ return errNotImplemented
+ }
+ return so.setBPF(c.Conn, filter)
+}
diff --git a/vendor/golang.org/x/net/ipv4/doc.go b/vendor/golang.org/x/net/ipv4/doc.go
@@ -0,0 +1,240 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package ipv4 implements IP-level socket options for the Internet
+// Protocol version 4.
+//
+// The package provides IP-level socket options that allow
+// manipulation of IPv4 facilities.
+//
+// The IPv4 protocol and basic host requirements for IPv4 are defined
+// in RFC 791 and RFC 1122.
+// Host extensions for multicasting and socket interface extensions
+// for multicast source filters are defined in RFC 1112 and RFC 3678.
+// IGMPv1, IGMPv2 and IGMPv3 are defined in RFC 1112, RFC 2236 and RFC
+// 3376.
+// Source-specific multicast is defined in RFC 4607.
+//
+// # Unicasting
+//
+// The options for unicasting are available for net.TCPConn,
+// net.UDPConn and net.IPConn which are created as network connections
+// that use the IPv4 transport. When a single TCP connection carrying
+// a data flow of multiple packets needs to indicate the flow is
+// important, Conn is used to set the type-of-service field on the
+// IPv4 header for each packet.
+//
+// ln, err := net.Listen("tcp4", "0.0.0.0:1024")
+// if err != nil {
+// // error handling
+// }
+// defer ln.Close()
+// for {
+// c, err := ln.Accept()
+// if err != nil {
+// // error handling
+// }
+// go func(c net.Conn) {
+// defer c.Close()
+//
+// The outgoing packets will be labeled DiffServ assured forwarding
+// class 1 low drop precedence, known as AF11 packets.
+//
+// if err := ipv4.NewConn(c).SetTOS(0x28); err != nil {
+// // error handling
+// }
+// if _, err := c.Write(data); err != nil {
+// // error handling
+// }
+// }(c)
+// }
+//
+// # Multicasting
+//
+// The options for multicasting are available for net.UDPConn and
+// net.IPConn which are created as network connections that use the
+// IPv4 transport. A few network facilities must be prepared before
+// you begin multicasting, at a minimum joining network interfaces and
+// multicast groups.
+//
+// en0, err := net.InterfaceByName("en0")
+// if err != nil {
+// // error handling
+// }
+// en1, err := net.InterfaceByIndex(911)
+// if err != nil {
+// // error handling
+// }
+// group := net.IPv4(224, 0, 0, 250)
+//
+// First, an application listens to an appropriate address with an
+// appropriate service port.
+//
+// c, err := net.ListenPacket("udp4", "0.0.0.0:1024")
+// if err != nil {
+// // error handling
+// }
+// defer c.Close()
+//
+// Second, the application joins multicast groups, starts listening to
+// the groups on the specified network interfaces. Note that the
+// service port for transport layer protocol does not matter with this
+// operation as joining groups affects only network and link layer
+// protocols, such as IPv4 and Ethernet.
+//
+// p := ipv4.NewPacketConn(c)
+// if err := p.JoinGroup(en0, &net.UDPAddr{IP: group}); err != nil {
+// // error handling
+// }
+// if err := p.JoinGroup(en1, &net.UDPAddr{IP: group}); err != nil {
+// // error handling
+// }
+//
+// The application might set per packet control message transmissions
+// between the protocol stack within the kernel. When the application
+// needs a destination address on an incoming packet,
+// SetControlMessage of PacketConn is used to enable control message
+// transmissions.
+//
+// if err := p.SetControlMessage(ipv4.FlagDst, true); err != nil {
+// // error handling
+// }
+//
+// The application could identify whether the received packets are
+// of interest by using the control message that contains the
+// destination address of the received packet.
+//
+// b := make([]byte, 1500)
+// for {
+// n, cm, src, err := p.ReadFrom(b)
+// if err != nil {
+// // error handling
+// }
+// if cm.Dst.IsMulticast() {
+// if cm.Dst.Equal(group) {
+// // joined group, do something
+// } else {
+// // unknown group, discard
+// continue
+// }
+// }
+//
+// The application can also send both unicast and multicast packets.
+//
+// p.SetTOS(0x0)
+// p.SetTTL(16)
+// if _, err := p.WriteTo(data, nil, src); err != nil {
+// // error handling
+// }
+// dst := &net.UDPAddr{IP: group, Port: 1024}
+// for _, ifi := range []*net.Interface{en0, en1} {
+// if err := p.SetMulticastInterface(ifi); err != nil {
+// // error handling
+// }
+// p.SetMulticastTTL(2)
+// if _, err := p.WriteTo(data, nil, dst); err != nil {
+// // error handling
+// }
+// }
+// }
+//
+// # More multicasting
+//
+// An application that uses PacketConn or RawConn may join multiple
+// multicast groups. For example, a UDP listener with port 1024 might
+// join two different groups across over two different network
+// interfaces by using:
+//
+// c, err := net.ListenPacket("udp4", "0.0.0.0:1024")
+// if err != nil {
+// // error handling
+// }
+// defer c.Close()
+// p := ipv4.NewPacketConn(c)
+// if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 248)}); err != nil {
+// // error handling
+// }
+// if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 249)}); err != nil {
+// // error handling
+// }
+// if err := p.JoinGroup(en1, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 249)}); err != nil {
+// // error handling
+// }
+//
+// It is possible for multiple UDP listeners that listen on the same
+// UDP port to join the same multicast group. The net package will
+// provide a socket that listens to a wildcard address with reusable
+// UDP port when an appropriate multicast address prefix is passed to
+// the net.ListenPacket or net.ListenUDP.
+//
+// c1, err := net.ListenPacket("udp4", "224.0.0.0:1024")
+// if err != nil {
+// // error handling
+// }
+// defer c1.Close()
+// c2, err := net.ListenPacket("udp4", "224.0.0.0:1024")
+// if err != nil {
+// // error handling
+// }
+// defer c2.Close()
+// p1 := ipv4.NewPacketConn(c1)
+// if err := p1.JoinGroup(en0, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 248)}); err != nil {
+// // error handling
+// }
+// p2 := ipv4.NewPacketConn(c2)
+// if err := p2.JoinGroup(en0, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 248)}); err != nil {
+// // error handling
+// }
+//
+// Also it is possible for the application to leave or rejoin a
+// multicast group on the network interface.
+//
+// if err := p.LeaveGroup(en0, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 248)}); err != nil {
+// // error handling
+// }
+// if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 250)}); err != nil {
+// // error handling
+// }
+//
+// # Source-specific multicasting
+//
+// An application that uses PacketConn or RawConn on IGMPv3 supported
+// platform is able to join source-specific multicast groups.
+// The application may use JoinSourceSpecificGroup and
+// LeaveSourceSpecificGroup for the operation known as "include" mode,
+//
+// ssmgroup := net.UDPAddr{IP: net.IPv4(232, 7, 8, 9)}
+// ssmsource := net.UDPAddr{IP: net.IPv4(192, 168, 0, 1)}
+// if err := p.JoinSourceSpecificGroup(en0, &ssmgroup, &ssmsource); err != nil {
+// // error handling
+// }
+// if err := p.LeaveSourceSpecificGroup(en0, &ssmgroup, &ssmsource); err != nil {
+// // error handling
+// }
+//
+// or JoinGroup, ExcludeSourceSpecificGroup,
+// IncludeSourceSpecificGroup and LeaveGroup for the operation known
+// as "exclude" mode.
+//
+// exclsource := net.UDPAddr{IP: net.IPv4(192, 168, 0, 254)}
+// if err := p.JoinGroup(en0, &ssmgroup); err != nil {
+// // error handling
+// }
+// if err := p.ExcludeSourceSpecificGroup(en0, &ssmgroup, &exclsource); err != nil {
+// // error handling
+// }
+// if err := p.LeaveGroup(en0, &ssmgroup); err != nil {
+// // error handling
+// }
+//
+// Note that it depends on each platform implementation what happens
+// when an application which runs on IGMPv3 unsupported platform uses
+// JoinSourceSpecificGroup and LeaveSourceSpecificGroup.
+// In general the platform tries to fall back to conversations using
+// IGMPv1 or IGMPv2 and starts to listen to multicast traffic.
+// In the fallback case, ExcludeSourceSpecificGroup and
+// IncludeSourceSpecificGroup may return an error.
+package ipv4 // import "golang.org/x/net/ipv4"
+
+// BUG(mikio): This package is not implemented on JS, NaCl and Plan 9.
diff --git a/vendor/golang.org/x/net/ipv4/endpoint.go b/vendor/golang.org/x/net/ipv4/endpoint.go
@@ -0,0 +1,186 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv4
+
+import (
+ "net"
+ "time"
+
+ "golang.org/x/net/internal/socket"
+)
+
+// BUG(mikio): On Windows, the JoinSourceSpecificGroup,
+// LeaveSourceSpecificGroup, ExcludeSourceSpecificGroup and
+// IncludeSourceSpecificGroup methods of PacketConn and RawConn are
+// not implemented.
+
+// A Conn represents a network endpoint that uses the IPv4 transport.
+// It is used to control basic IP-level socket options such as TOS and
+// TTL.
+type Conn struct {
+ genericOpt
+}
+
+type genericOpt struct {
+ *socket.Conn
+}
+
+func (c *genericOpt) ok() bool { return c != nil && c.Conn != nil }
+
+// NewConn returns a new Conn.
+func NewConn(c net.Conn) *Conn {
+ cc, _ := socket.NewConn(c)
+ return &Conn{
+ genericOpt: genericOpt{Conn: cc},
+ }
+}
+
+// A PacketConn represents a packet network endpoint that uses the
+// IPv4 transport. It is used to control several IP-level socket
+// options including multicasting. It also provides datagram based
+// network I/O methods specific to the IPv4 and higher layer protocols
+// such as UDP.
+type PacketConn struct {
+ genericOpt
+ dgramOpt
+ payloadHandler
+}
+
+type dgramOpt struct {
+ *socket.Conn
+}
+
+func (c *dgramOpt) ok() bool { return c != nil && c.Conn != nil }
+
+// SetControlMessage sets the per packet IP-level socket options.
+func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error {
+ if !c.payloadHandler.ok() {
+ return errInvalidConn
+ }
+ return setControlMessage(c.dgramOpt.Conn, &c.payloadHandler.rawOpt, cf, on)
+}
+
+// SetDeadline sets the read and write deadlines associated with the
+// endpoint.
+func (c *PacketConn) SetDeadline(t time.Time) error {
+ if !c.payloadHandler.ok() {
+ return errInvalidConn
+ }
+ return c.payloadHandler.PacketConn.SetDeadline(t)
+}
+
+// SetReadDeadline sets the read deadline associated with the
+// endpoint.
+func (c *PacketConn) SetReadDeadline(t time.Time) error {
+ if !c.payloadHandler.ok() {
+ return errInvalidConn
+ }
+ return c.payloadHandler.PacketConn.SetReadDeadline(t)
+}
+
+// SetWriteDeadline sets the write deadline associated with the
+// endpoint.
+func (c *PacketConn) SetWriteDeadline(t time.Time) error {
+ if !c.payloadHandler.ok() {
+ return errInvalidConn
+ }
+ return c.payloadHandler.PacketConn.SetWriteDeadline(t)
+}
+
+// Close closes the endpoint.
+func (c *PacketConn) Close() error {
+ if !c.payloadHandler.ok() {
+ return errInvalidConn
+ }
+ return c.payloadHandler.PacketConn.Close()
+}
+
+// NewPacketConn returns a new PacketConn using c as its underlying
+// transport.
+func NewPacketConn(c net.PacketConn) *PacketConn {
+ cc, _ := socket.NewConn(c.(net.Conn))
+ p := &PacketConn{
+ genericOpt: genericOpt{Conn: cc},
+ dgramOpt: dgramOpt{Conn: cc},
+ payloadHandler: payloadHandler{PacketConn: c, Conn: cc},
+ }
+ return p
+}
+
+// A RawConn represents a packet network endpoint that uses the IPv4
+// transport. It is used to control several IP-level socket options
+// including IPv4 header manipulation. It also provides datagram
+// based network I/O methods specific to the IPv4 and higher layer
+// protocols that handle IPv4 datagram directly such as OSPF, GRE.
+type RawConn struct {
+ genericOpt
+ dgramOpt
+ packetHandler
+}
+
+// SetControlMessage sets the per packet IP-level socket options.
+func (c *RawConn) SetControlMessage(cf ControlFlags, on bool) error {
+ if !c.packetHandler.ok() {
+ return errInvalidConn
+ }
+ return setControlMessage(c.dgramOpt.Conn, &c.packetHandler.rawOpt, cf, on)
+}
+
+// SetDeadline sets the read and write deadlines associated with the
+// endpoint.
+func (c *RawConn) SetDeadline(t time.Time) error {
+ if !c.packetHandler.ok() {
+ return errInvalidConn
+ }
+ return c.packetHandler.IPConn.SetDeadline(t)
+}
+
+// SetReadDeadline sets the read deadline associated with the
+// endpoint.
+func (c *RawConn) SetReadDeadline(t time.Time) error {
+ if !c.packetHandler.ok() {
+ return errInvalidConn
+ }
+ return c.packetHandler.IPConn.SetReadDeadline(t)
+}
+
+// SetWriteDeadline sets the write deadline associated with the
+// endpoint.
+func (c *RawConn) SetWriteDeadline(t time.Time) error {
+ if !c.packetHandler.ok() {
+ return errInvalidConn
+ }
+ return c.packetHandler.IPConn.SetWriteDeadline(t)
+}
+
+// Close closes the endpoint.
+func (c *RawConn) Close() error {
+ if !c.packetHandler.ok() {
+ return errInvalidConn
+ }
+ return c.packetHandler.IPConn.Close()
+}
+
+// NewRawConn returns a new RawConn using c as its underlying
+// transport.
+func NewRawConn(c net.PacketConn) (*RawConn, error) {
+ cc, err := socket.NewConn(c.(net.Conn))
+ if err != nil {
+ return nil, err
+ }
+ r := &RawConn{
+ genericOpt: genericOpt{Conn: cc},
+ dgramOpt: dgramOpt{Conn: cc},
+ packetHandler: packetHandler{IPConn: c.(*net.IPConn), Conn: cc},
+ }
+ so, ok := sockOpts[ssoHeaderPrepend]
+ if !ok {
+ return nil, errNotImplemented
+ }
+ if err := so.SetInt(r.dgramOpt.Conn, boolint(true)); err != nil {
+ return nil, err
+ }
+ return r, nil
+}
diff --git a/vendor/golang.org/x/net/ipv4/genericopt.go b/vendor/golang.org/x/net/ipv4/genericopt.go
@@ -0,0 +1,55 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv4
+
+// TOS returns the type-of-service field value for outgoing packets.
+func (c *genericOpt) TOS() (int, error) {
+ if !c.ok() {
+ return 0, errInvalidConn
+ }
+ so, ok := sockOpts[ssoTOS]
+ if !ok {
+ return 0, errNotImplemented
+ }
+ return so.GetInt(c.Conn)
+}
+
+// SetTOS sets the type-of-service field value for future outgoing
+// packets.
+func (c *genericOpt) SetTOS(tos int) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoTOS]
+ if !ok {
+ return errNotImplemented
+ }
+ return so.SetInt(c.Conn, tos)
+}
+
+// TTL returns the time-to-live field value for outgoing packets.
+func (c *genericOpt) TTL() (int, error) {
+ if !c.ok() {
+ return 0, errInvalidConn
+ }
+ so, ok := sockOpts[ssoTTL]
+ if !ok {
+ return 0, errNotImplemented
+ }
+ return so.GetInt(c.Conn)
+}
+
+// SetTTL sets the time-to-live field value for future outgoing
+// packets.
+func (c *genericOpt) SetTTL(ttl int) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoTTL]
+ if !ok {
+ return errNotImplemented
+ }
+ return so.SetInt(c.Conn, ttl)
+}
diff --git a/vendor/golang.org/x/net/ipv4/header.go b/vendor/golang.org/x/net/ipv4/header.go
@@ -0,0 +1,172 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv4
+
+import (
+ "encoding/binary"
+ "fmt"
+ "net"
+ "runtime"
+
+ "golang.org/x/net/internal/socket"
+)
+
+const (
+ Version = 4 // protocol version
+ HeaderLen = 20 // header length without extension headers
+)
+
+type HeaderFlags int
+
+const (
+ MoreFragments HeaderFlags = 1 << iota // more fragments flag
+ DontFragment // don't fragment flag
+)
+
+// A Header represents an IPv4 header.
+type Header struct {
+ Version int // protocol version
+ Len int // header length
+ TOS int // type-of-service
+ TotalLen int // packet total length
+ ID int // identification
+ Flags HeaderFlags // flags
+ FragOff int // fragment offset
+ TTL int // time-to-live
+ Protocol int // next protocol
+ Checksum int // checksum
+ Src net.IP // source address
+ Dst net.IP // destination address
+ Options []byte // options, extension headers
+}
+
+func (h *Header) String() string {
+ if h == nil {
+ return "<nil>"
+ }
+ return fmt.Sprintf("ver=%d hdrlen=%d tos=%#x totallen=%d id=%#x flags=%#x fragoff=%#x ttl=%d proto=%d cksum=%#x src=%v dst=%v", h.Version, h.Len, h.TOS, h.TotalLen, h.ID, h.Flags, h.FragOff, h.TTL, h.Protocol, h.Checksum, h.Src, h.Dst)
+}
+
+// Marshal returns the binary encoding of h.
+//
+// The returned slice is in the format used by a raw IP socket on the
+// local system.
+// This may differ from the wire format, depending on the system.
+func (h *Header) Marshal() ([]byte, error) {
+ if h == nil {
+ return nil, errNilHeader
+ }
+ if h.Len < HeaderLen {
+ return nil, errHeaderTooShort
+ }
+ hdrlen := HeaderLen + len(h.Options)
+ b := make([]byte, hdrlen)
+ b[0] = byte(Version<<4 | (hdrlen >> 2 & 0x0f))
+ b[1] = byte(h.TOS)
+ flagsAndFragOff := (h.FragOff & 0x1fff) | int(h.Flags<<13)
+ switch runtime.GOOS {
+ case "darwin", "ios", "dragonfly", "netbsd":
+ socket.NativeEndian.PutUint16(b[2:4], uint16(h.TotalLen))
+ socket.NativeEndian.PutUint16(b[6:8], uint16(flagsAndFragOff))
+ case "freebsd":
+ if freebsdVersion < 1100000 {
+ socket.NativeEndian.PutUint16(b[2:4], uint16(h.TotalLen))
+ socket.NativeEndian.PutUint16(b[6:8], uint16(flagsAndFragOff))
+ } else {
+ binary.BigEndian.PutUint16(b[2:4], uint16(h.TotalLen))
+ binary.BigEndian.PutUint16(b[6:8], uint16(flagsAndFragOff))
+ }
+ default:
+ binary.BigEndian.PutUint16(b[2:4], uint16(h.TotalLen))
+ binary.BigEndian.PutUint16(b[6:8], uint16(flagsAndFragOff))
+ }
+ binary.BigEndian.PutUint16(b[4:6], uint16(h.ID))
+ b[8] = byte(h.TTL)
+ b[9] = byte(h.Protocol)
+ binary.BigEndian.PutUint16(b[10:12], uint16(h.Checksum))
+ if ip := h.Src.To4(); ip != nil {
+ copy(b[12:16], ip[:net.IPv4len])
+ }
+ if ip := h.Dst.To4(); ip != nil {
+ copy(b[16:20], ip[:net.IPv4len])
+ } else {
+ return nil, errMissingAddress
+ }
+ if len(h.Options) > 0 {
+ copy(b[HeaderLen:], h.Options)
+ }
+ return b, nil
+}
+
+// Parse parses b as an IPv4 header and stores the result in h.
+//
+// The provided b must be in the format used by a raw IP socket on the
+// local system.
+// This may differ from the wire format, depending on the system.
+func (h *Header) Parse(b []byte) error {
+ if h == nil || b == nil {
+ return errNilHeader
+ }
+ if len(b) < HeaderLen {
+ return errHeaderTooShort
+ }
+ hdrlen := int(b[0]&0x0f) << 2
+ if len(b) < hdrlen {
+ return errExtHeaderTooShort
+ }
+ h.Version = int(b[0] >> 4)
+ h.Len = hdrlen
+ h.TOS = int(b[1])
+ h.ID = int(binary.BigEndian.Uint16(b[4:6]))
+ h.TTL = int(b[8])
+ h.Protocol = int(b[9])
+ h.Checksum = int(binary.BigEndian.Uint16(b[10:12]))
+ h.Src = net.IPv4(b[12], b[13], b[14], b[15])
+ h.Dst = net.IPv4(b[16], b[17], b[18], b[19])
+ switch runtime.GOOS {
+ case "darwin", "ios", "dragonfly", "netbsd":
+ h.TotalLen = int(socket.NativeEndian.Uint16(b[2:4])) + hdrlen
+ h.FragOff = int(socket.NativeEndian.Uint16(b[6:8]))
+ case "freebsd":
+ if freebsdVersion < 1100000 {
+ h.TotalLen = int(socket.NativeEndian.Uint16(b[2:4]))
+ if freebsdVersion < 1000000 {
+ h.TotalLen += hdrlen
+ }
+ h.FragOff = int(socket.NativeEndian.Uint16(b[6:8]))
+ } else {
+ h.TotalLen = int(binary.BigEndian.Uint16(b[2:4]))
+ h.FragOff = int(binary.BigEndian.Uint16(b[6:8]))
+ }
+ default:
+ h.TotalLen = int(binary.BigEndian.Uint16(b[2:4]))
+ h.FragOff = int(binary.BigEndian.Uint16(b[6:8]))
+ }
+ h.Flags = HeaderFlags(h.FragOff&0xe000) >> 13
+ h.FragOff = h.FragOff & 0x1fff
+ optlen := hdrlen - HeaderLen
+ if optlen > 0 && len(b) >= hdrlen {
+ if cap(h.Options) < optlen {
+ h.Options = make([]byte, optlen)
+ } else {
+ h.Options = h.Options[:optlen]
+ }
+ copy(h.Options, b[HeaderLen:hdrlen])
+ }
+ return nil
+}
+
+// ParseHeader parses b as an IPv4 header.
+//
+// The provided b must be in the format used by a raw IP socket on the
+// local system.
+// This may differ from the wire format, depending on the system.
+func ParseHeader(b []byte) (*Header, error) {
+ h := new(Header)
+ if err := h.Parse(b); err != nil {
+ return nil, err
+ }
+ return h, nil
+}
diff --git a/vendor/golang.org/x/net/ipv4/helper.go b/vendor/golang.org/x/net/ipv4/helper.go
@@ -0,0 +1,77 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv4
+
+import (
+ "errors"
+ "net"
+ "runtime"
+
+ "golang.org/x/net/internal/socket"
+)
+
+var (
+ errInvalidConn = errors.New("invalid connection")
+ errMissingAddress = errors.New("missing address")
+ errNilHeader = errors.New("nil header")
+ errHeaderTooShort = errors.New("header too short")
+ errExtHeaderTooShort = errors.New("extension header too short")
+ errInvalidConnType = errors.New("invalid conn type")
+ errNotImplemented = errors.New("not implemented on " + runtime.GOOS + "/" + runtime.GOARCH)
+
+ // See https://www.freebsd.org/doc/en/books/porters-handbook/versions.html.
+ freebsdVersion uint32
+ compatFreeBSD32 bool // 386 emulation on amd64
+)
+
+// See golang.org/issue/30899.
+func adjustFreeBSD32(m *socket.Message) {
+ // FreeBSD 12.0-RELEASE is affected by https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236737
+ if 1200086 <= freebsdVersion && freebsdVersion < 1201000 {
+ l := (m.NN + 4 - 1) &^ (4 - 1)
+ if m.NN < l && l <= len(m.OOB) {
+ m.NN = l
+ }
+ }
+}
+
+func boolint(b bool) int {
+ if b {
+ return 1
+ }
+ return 0
+}
+
+func netAddrToIP4(a net.Addr) net.IP {
+ switch v := a.(type) {
+ case *net.UDPAddr:
+ if ip := v.IP.To4(); ip != nil {
+ return ip
+ }
+ case *net.IPAddr:
+ if ip := v.IP.To4(); ip != nil {
+ return ip
+ }
+ }
+ return nil
+}
+
+func opAddr(a net.Addr) net.Addr {
+ switch a.(type) {
+ case *net.TCPAddr:
+ if a == nil {
+ return nil
+ }
+ case *net.UDPAddr:
+ if a == nil {
+ return nil
+ }
+ case *net.IPAddr:
+ if a == nil {
+ return nil
+ }
+ }
+ return a
+}
diff --git a/vendor/golang.org/x/net/ipv4/iana.go b/vendor/golang.org/x/net/ipv4/iana.go
@@ -0,0 +1,38 @@
+// go generate gen.go
+// Code generated by the command above; DO NOT EDIT.
+
+package ipv4
+
+// Internet Control Message Protocol (ICMP) Parameters, Updated: 2018-02-26
+const (
+ ICMPTypeEchoReply ICMPType = 0 // Echo Reply
+ ICMPTypeDestinationUnreachable ICMPType = 3 // Destination Unreachable
+ ICMPTypeRedirect ICMPType = 5 // Redirect
+ ICMPTypeEcho ICMPType = 8 // Echo
+ ICMPTypeRouterAdvertisement ICMPType = 9 // Router Advertisement
+ ICMPTypeRouterSolicitation ICMPType = 10 // Router Solicitation
+ ICMPTypeTimeExceeded ICMPType = 11 // Time Exceeded
+ ICMPTypeParameterProblem ICMPType = 12 // Parameter Problem
+ ICMPTypeTimestamp ICMPType = 13 // Timestamp
+ ICMPTypeTimestampReply ICMPType = 14 // Timestamp Reply
+ ICMPTypePhoturis ICMPType = 40 // Photuris
+ ICMPTypeExtendedEchoRequest ICMPType = 42 // Extended Echo Request
+ ICMPTypeExtendedEchoReply ICMPType = 43 // Extended Echo Reply
+)
+
+// Internet Control Message Protocol (ICMP) Parameters, Updated: 2018-02-26
+var icmpTypes = map[ICMPType]string{
+ 0: "echo reply",
+ 3: "destination unreachable",
+ 5: "redirect",
+ 8: "echo",
+ 9: "router advertisement",
+ 10: "router solicitation",
+ 11: "time exceeded",
+ 12: "parameter problem",
+ 13: "timestamp",
+ 14: "timestamp reply",
+ 40: "photuris",
+ 42: "extended echo request",
+ 43: "extended echo reply",
+}
diff --git a/vendor/golang.org/x/net/ipv4/icmp.go b/vendor/golang.org/x/net/ipv4/icmp.go
@@ -0,0 +1,57 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv4
+
+import "golang.org/x/net/internal/iana"
+
+// An ICMPType represents a type of ICMP message.
+type ICMPType int
+
+func (typ ICMPType) String() string {
+ s, ok := icmpTypes[typ]
+ if !ok {
+ return "<nil>"
+ }
+ return s
+}
+
+// Protocol returns the ICMPv4 protocol number.
+func (typ ICMPType) Protocol() int {
+ return iana.ProtocolICMP
+}
+
+// An ICMPFilter represents an ICMP message filter for incoming
+// packets. The filter belongs to a packet delivery path on a host and
+// it cannot interact with forwarding packets or tunnel-outer packets.
+//
+// Note: RFC 8200 defines a reasonable role model and it works not
+// only for IPv6 but IPv4. A node means a device that implements IP.
+// A router means a node that forwards IP packets not explicitly
+// addressed to itself, and a host means a node that is not a router.
+type ICMPFilter struct {
+ icmpFilter
+}
+
+// Accept accepts incoming ICMP packets including the type field value
+// typ.
+func (f *ICMPFilter) Accept(typ ICMPType) {
+ f.accept(typ)
+}
+
+// Block blocks incoming ICMP packets including the type field value
+// typ.
+func (f *ICMPFilter) Block(typ ICMPType) {
+ f.block(typ)
+}
+
+// SetAll sets the filter action to the filter.
+func (f *ICMPFilter) SetAll(block bool) {
+ f.setAll(block)
+}
+
+// WillBlock reports whether the ICMP type will be blocked.
+func (f *ICMPFilter) WillBlock(typ ICMPType) bool {
+ return f.willBlock(typ)
+}
diff --git a/vendor/golang.org/x/net/ipv4/icmp_linux.go b/vendor/golang.org/x/net/ipv4/icmp_linux.go
@@ -0,0 +1,25 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv4
+
+func (f *icmpFilter) accept(typ ICMPType) {
+ f.Data &^= 1 << (uint32(typ) & 31)
+}
+
+func (f *icmpFilter) block(typ ICMPType) {
+ f.Data |= 1 << (uint32(typ) & 31)
+}
+
+func (f *icmpFilter) setAll(block bool) {
+ if block {
+ f.Data = 1<<32 - 1
+ } else {
+ f.Data = 0
+ }
+}
+
+func (f *icmpFilter) willBlock(typ ICMPType) bool {
+ return f.Data&(1<<(uint32(typ)&31)) != 0
+}
diff --git a/vendor/golang.org/x/net/ipv4/icmp_stub.go b/vendor/golang.org/x/net/ipv4/icmp_stub.go
@@ -0,0 +1,26 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !linux
+// +build !linux
+
+package ipv4
+
+const sizeofICMPFilter = 0x0
+
+type icmpFilter struct {
+}
+
+func (f *icmpFilter) accept(typ ICMPType) {
+}
+
+func (f *icmpFilter) block(typ ICMPType) {
+}
+
+func (f *icmpFilter) setAll(block bool) {
+}
+
+func (f *icmpFilter) willBlock(typ ICMPType) bool {
+ return false
+}
diff --git a/vendor/golang.org/x/net/ipv4/packet.go b/vendor/golang.org/x/net/ipv4/packet.go
@@ -0,0 +1,117 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv4
+
+import (
+ "net"
+
+ "golang.org/x/net/internal/socket"
+)
+
+// BUG(mikio): On Windows, the ReadFrom and WriteTo methods of RawConn
+// are not implemented.
+
+// A packetHandler represents the IPv4 datagram handler.
+type packetHandler struct {
+ *net.IPConn
+ *socket.Conn
+ rawOpt
+}
+
+func (c *packetHandler) ok() bool { return c != nil && c.IPConn != nil && c.Conn != nil }
+
+// ReadFrom reads an IPv4 datagram from the endpoint c, copying the
+// datagram into b. It returns the received datagram as the IPv4
+// header h, the payload p and the control message cm.
+func (c *packetHandler) ReadFrom(b []byte) (h *Header, p []byte, cm *ControlMessage, err error) {
+ if !c.ok() {
+ return nil, nil, nil, errInvalidConn
+ }
+ c.rawOpt.RLock()
+ m := socket.Message{
+ Buffers: [][]byte{b},
+ OOB: NewControlMessage(c.rawOpt.cflags),
+ }
+ c.rawOpt.RUnlock()
+ if err := c.RecvMsg(&m, 0); err != nil {
+ return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
+ }
+ var hs []byte
+ if hs, p, err = slicePacket(b[:m.N]); err != nil {
+ return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
+ }
+ if h, err = ParseHeader(hs); err != nil {
+ return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
+ }
+ if m.NN > 0 {
+ if compatFreeBSD32 {
+ adjustFreeBSD32(&m)
+ }
+ cm = new(ControlMessage)
+ if err := cm.Parse(m.OOB[:m.NN]); err != nil {
+ return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
+ }
+ }
+ if src, ok := m.Addr.(*net.IPAddr); ok && cm != nil {
+ cm.Src = src.IP
+ }
+ return
+}
+
+func slicePacket(b []byte) (h, p []byte, err error) {
+ if len(b) < HeaderLen {
+ return nil, nil, errHeaderTooShort
+ }
+ hdrlen := int(b[0]&0x0f) << 2
+ return b[:hdrlen], b[hdrlen:], nil
+}
+
+// WriteTo writes an IPv4 datagram through the endpoint c, copying the
+// datagram from the IPv4 header h and the payload p. The control
+// message cm allows the datagram path and the outgoing interface to be
+// specified. Currently only Darwin and Linux support this. The cm
+// may be nil if control of the outgoing datagram is not required.
+//
+// The IPv4 header h must contain appropriate fields that include:
+//
+// Version = <must be specified>
+// Len = <must be specified>
+// TOS = <must be specified>
+// TotalLen = <must be specified>
+// ID = platform sets an appropriate value if ID is zero
+// FragOff = <must be specified>
+// TTL = <must be specified>
+// Protocol = <must be specified>
+// Checksum = platform sets an appropriate value if Checksum is zero
+// Src = platform sets an appropriate value if Src is nil
+// Dst = <must be specified>
+// Options = optional
+func (c *packetHandler) WriteTo(h *Header, p []byte, cm *ControlMessage) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ m := socket.Message{
+ OOB: cm.Marshal(),
+ }
+ wh, err := h.Marshal()
+ if err != nil {
+ return err
+ }
+ m.Buffers = [][]byte{wh, p}
+ dst := new(net.IPAddr)
+ if cm != nil {
+ if ip := cm.Dst.To4(); ip != nil {
+ dst.IP = ip
+ }
+ }
+ if dst.IP == nil {
+ dst.IP = h.Dst
+ }
+ m.Addr = dst
+ if err := c.SendMsg(&m, 0); err != nil {
+ return &net.OpError{Op: "write", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Addr: opAddr(dst), Err: err}
+ }
+ return nil
+}
diff --git a/vendor/golang.org/x/net/ipv4/payload.go b/vendor/golang.org/x/net/ipv4/payload.go
@@ -0,0 +1,23 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv4
+
+import (
+ "net"
+
+ "golang.org/x/net/internal/socket"
+)
+
+// BUG(mikio): On Windows, the ControlMessage for ReadFrom and WriteTo
+// methods of PacketConn is not implemented.
+
+// A payloadHandler represents the IPv4 datagram payload handler.
+type payloadHandler struct {
+ net.PacketConn
+ *socket.Conn
+ rawOpt
+}
+
+func (c *payloadHandler) ok() bool { return c != nil && c.PacketConn != nil && c.Conn != nil }
diff --git a/vendor/golang.org/x/net/ipv4/payload_cmsg.go b/vendor/golang.org/x/net/ipv4/payload_cmsg.go
@@ -0,0 +1,85 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
+
+package ipv4
+
+import (
+ "net"
+
+ "golang.org/x/net/internal/socket"
+)
+
+// ReadFrom reads a payload of the received IPv4 datagram, from the
+// endpoint c, copying the payload into b. It returns the number of
+// bytes copied into b, the control message cm and the source address
+// src of the received datagram.
+func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) {
+ if !c.ok() {
+ return 0, nil, nil, errInvalidConn
+ }
+ c.rawOpt.RLock()
+ m := socket.Message{
+ OOB: NewControlMessage(c.rawOpt.cflags),
+ }
+ c.rawOpt.RUnlock()
+ switch c.PacketConn.(type) {
+ case *net.UDPConn:
+ m.Buffers = [][]byte{b}
+ if err := c.RecvMsg(&m, 0); err != nil {
+ return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
+ }
+ case *net.IPConn:
+ h := make([]byte, HeaderLen)
+ m.Buffers = [][]byte{h, b}
+ if err := c.RecvMsg(&m, 0); err != nil {
+ return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
+ }
+ hdrlen := int(h[0]&0x0f) << 2
+ if hdrlen > len(h) {
+ d := hdrlen - len(h)
+ copy(b, b[d:])
+ m.N -= d
+ } else {
+ m.N -= hdrlen
+ }
+ default:
+ return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: errInvalidConnType}
+ }
+ if m.NN > 0 {
+ if compatFreeBSD32 {
+ adjustFreeBSD32(&m)
+ }
+ cm = new(ControlMessage)
+ if err := cm.Parse(m.OOB[:m.NN]); err != nil {
+ return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
+ }
+ cm.Src = netAddrToIP4(m.Addr)
+ }
+ return m.N, cm, m.Addr, nil
+}
+
+// WriteTo writes a payload of the IPv4 datagram, to the destination
+// address dst through the endpoint c, copying the payload from b. It
+// returns the number of bytes written. The control message cm allows
+// the datagram path and the outgoing interface to be specified.
+// Currently only Darwin and Linux support this. The cm may be nil if
+// control of the outgoing datagram is not required.
+func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) {
+ if !c.ok() {
+ return 0, errInvalidConn
+ }
+ m := socket.Message{
+ Buffers: [][]byte{b},
+ OOB: cm.Marshal(),
+ Addr: dst,
+ }
+ err = c.SendMsg(&m, 0)
+ if err != nil {
+ err = &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Addr: opAddr(dst), Err: err}
+ }
+ return m.N, err
+}
diff --git a/vendor/golang.org/x/net/ipv4/payload_nocmsg.go b/vendor/golang.org/x/net/ipv4/payload_nocmsg.go
@@ -0,0 +1,40 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
+
+package ipv4
+
+import "net"
+
+// ReadFrom reads a payload of the received IPv4 datagram, from the
+// endpoint c, copying the payload into b. It returns the number of
+// bytes copied into b, the control message cm and the source address
+// src of the received datagram.
+func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) {
+ if !c.ok() {
+ return 0, nil, nil, errInvalidConn
+ }
+ if n, src, err = c.PacketConn.ReadFrom(b); err != nil {
+ return 0, nil, nil, err
+ }
+ return
+}
+
+// WriteTo writes a payload of the IPv4 datagram, to the destination
+// address dst through the endpoint c, copying the payload from b. It
+// returns the number of bytes written. The control message cm allows
+// the datagram path and the outgoing interface to be specified.
+// Currently only Darwin and Linux support this. The cm may be nil if
+// control of the outgoing datagram is not required.
+func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) {
+ if !c.ok() {
+ return 0, errInvalidConn
+ }
+ if dst == nil {
+ return 0, errMissingAddress
+ }
+ return c.PacketConn.WriteTo(b, dst)
+}
diff --git a/vendor/golang.org/x/net/ipv4/sockopt.go b/vendor/golang.org/x/net/ipv4/sockopt.go
@@ -0,0 +1,44 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv4
+
+import "golang.org/x/net/internal/socket"
+
+// Sticky socket options
+const (
+ ssoTOS = iota // header field for unicast packet
+ ssoTTL // header field for unicast packet
+ ssoMulticastTTL // header field for multicast packet
+ ssoMulticastInterface // outbound interface for multicast packet
+ ssoMulticastLoopback // loopback for multicast packet
+ ssoReceiveTTL // header field on received packet
+ ssoReceiveDst // header field on received packet
+ ssoReceiveInterface // inbound interface on received packet
+ ssoPacketInfo // incbound or outbound packet path
+ ssoHeaderPrepend // ipv4 header prepend
+ ssoStripHeader // strip ipv4 header
+ ssoICMPFilter // icmp filter
+ ssoJoinGroup // any-source multicast
+ ssoLeaveGroup // any-source multicast
+ ssoJoinSourceGroup // source-specific multicast
+ ssoLeaveSourceGroup // source-specific multicast
+ ssoBlockSourceGroup // any-source or source-specific multicast
+ ssoUnblockSourceGroup // any-source or source-specific multicast
+ ssoAttachFilter // attach BPF for filtering inbound traffic
+)
+
+// Sticky socket option value types
+const (
+ ssoTypeIPMreq = iota + 1
+ ssoTypeIPMreqn
+ ssoTypeGroupReq
+ ssoTypeGroupSourceReq
+)
+
+// A sockOpt represents a binding for sticky socket option.
+type sockOpt struct {
+ socket.Option
+ typ int // hint for option value type; optional
+}
diff --git a/vendor/golang.org/x/net/ipv4/sockopt_posix.go b/vendor/golang.org/x/net/ipv4/sockopt_posix.go
@@ -0,0 +1,72 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows zos
+
+package ipv4
+
+import (
+ "net"
+ "unsafe"
+
+ "golang.org/x/net/bpf"
+ "golang.org/x/net/internal/socket"
+)
+
+func (so *sockOpt) getMulticastInterface(c *socket.Conn) (*net.Interface, error) {
+ switch so.typ {
+ case ssoTypeIPMreqn:
+ return so.getIPMreqn(c)
+ default:
+ return so.getMulticastIf(c)
+ }
+}
+
+func (so *sockOpt) setMulticastInterface(c *socket.Conn, ifi *net.Interface) error {
+ switch so.typ {
+ case ssoTypeIPMreqn:
+ return so.setIPMreqn(c, ifi, nil)
+ default:
+ return so.setMulticastIf(c, ifi)
+ }
+}
+
+func (so *sockOpt) getICMPFilter(c *socket.Conn) (*ICMPFilter, error) {
+ b := make([]byte, so.Len)
+ n, err := so.Get(c, b)
+ if err != nil {
+ return nil, err
+ }
+ if n != sizeofICMPFilter {
+ return nil, errNotImplemented
+ }
+ return (*ICMPFilter)(unsafe.Pointer(&b[0])), nil
+}
+
+func (so *sockOpt) setICMPFilter(c *socket.Conn, f *ICMPFilter) error {
+ b := (*[sizeofICMPFilter]byte)(unsafe.Pointer(f))[:sizeofICMPFilter]
+ return so.Set(c, b)
+}
+
+func (so *sockOpt) setGroup(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
+ switch so.typ {
+ case ssoTypeIPMreq:
+ return so.setIPMreq(c, ifi, grp)
+ case ssoTypeIPMreqn:
+ return so.setIPMreqn(c, ifi, grp)
+ case ssoTypeGroupReq:
+ return so.setGroupReq(c, ifi, grp)
+ default:
+ return errNotImplemented
+ }
+}
+
+func (so *sockOpt) setSourceGroup(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error {
+ return so.setGroupSourceReq(c, ifi, grp, src)
+}
+
+func (so *sockOpt) setBPF(c *socket.Conn, f []bpf.RawInstruction) error {
+ return so.setAttachFilter(c, f)
+}
diff --git a/vendor/golang.org/x/net/ipv4/sockopt_stub.go b/vendor/golang.org/x/net/ipv4/sockopt_stub.go
@@ -0,0 +1,43 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
+
+package ipv4
+
+import (
+ "net"
+
+ "golang.org/x/net/bpf"
+ "golang.org/x/net/internal/socket"
+)
+
+func (so *sockOpt) getMulticastInterface(c *socket.Conn) (*net.Interface, error) {
+ return nil, errNotImplemented
+}
+
+func (so *sockOpt) setMulticastInterface(c *socket.Conn, ifi *net.Interface) error {
+ return errNotImplemented
+}
+
+func (so *sockOpt) getICMPFilter(c *socket.Conn) (*ICMPFilter, error) {
+ return nil, errNotImplemented
+}
+
+func (so *sockOpt) setICMPFilter(c *socket.Conn, f *ICMPFilter) error {
+ return errNotImplemented
+}
+
+func (so *sockOpt) setGroup(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
+ return errNotImplemented
+}
+
+func (so *sockOpt) setSourceGroup(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error {
+ return errNotImplemented
+}
+
+func (so *sockOpt) setBPF(c *socket.Conn, f []bpf.RawInstruction) error {
+ return errNotImplemented
+}
diff --git a/vendor/golang.org/x/net/ipv4/sys_aix.go b/vendor/golang.org/x/net/ipv4/sys_aix.go
@@ -0,0 +1,44 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Added for go1.11 compatibility
+//go:build aix
+// +build aix
+
+package ipv4
+
+import (
+ "net"
+ "syscall"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
+)
+
+// IP_RECVIF is defined on AIX but doesn't work. IP_RECVINTERFACE must be used instead.
+const sockoptReceiveInterface = unix.IP_RECVINTERFACE
+
+var (
+ ctlOpts = [ctlMax]ctlOpt{
+ ctlTTL: {unix.IP_RECVTTL, 1, marshalTTL, parseTTL},
+ ctlDst: {unix.IP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},
+ ctlInterface: {unix.IP_RECVINTERFACE, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
+ }
+
+ sockOpts = map[int]*sockOpt{
+ ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}},
+ ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}},
+ ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 1}},
+ ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}},
+ ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVDSTADDR, Len: 4}},
+ ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVINTERFACE, Len: 4}},
+ ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+ }
+)
diff --git a/vendor/golang.org/x/net/ipv4/sys_asmreq.go b/vendor/golang.org/x/net/ipv4/sys_asmreq.go
@@ -0,0 +1,123 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd || solaris || windows
+// +build aix darwin dragonfly freebsd netbsd openbsd solaris windows
+
+package ipv4
+
+import (
+ "errors"
+ "net"
+ "unsafe"
+
+ "golang.org/x/net/internal/socket"
+)
+
+var errNoSuchInterface = errors.New("no such interface")
+
+func (so *sockOpt) setIPMreq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
+ mreq := ipMreq{Multiaddr: [4]byte{grp[0], grp[1], grp[2], grp[3]}}
+ if err := setIPMreqInterface(&mreq, ifi); err != nil {
+ return err
+ }
+ b := (*[sizeofIPMreq]byte)(unsafe.Pointer(&mreq))[:sizeofIPMreq]
+ return so.Set(c, b)
+}
+
+func (so *sockOpt) getMulticastIf(c *socket.Conn) (*net.Interface, error) {
+ var b [4]byte
+ if _, err := so.Get(c, b[:]); err != nil {
+ return nil, err
+ }
+ ifi, err := netIP4ToInterface(net.IPv4(b[0], b[1], b[2], b[3]))
+ if err != nil {
+ return nil, err
+ }
+ return ifi, nil
+}
+
+func (so *sockOpt) setMulticastIf(c *socket.Conn, ifi *net.Interface) error {
+ ip, err := netInterfaceToIP4(ifi)
+ if err != nil {
+ return err
+ }
+ var b [4]byte
+ copy(b[:], ip)
+ return so.Set(c, b[:])
+}
+
+func setIPMreqInterface(mreq *ipMreq, ifi *net.Interface) error {
+ if ifi == nil {
+ return nil
+ }
+ ifat, err := ifi.Addrs()
+ if err != nil {
+ return err
+ }
+ for _, ifa := range ifat {
+ switch ifa := ifa.(type) {
+ case *net.IPAddr:
+ if ip := ifa.IP.To4(); ip != nil {
+ copy(mreq.Interface[:], ip)
+ return nil
+ }
+ case *net.IPNet:
+ if ip := ifa.IP.To4(); ip != nil {
+ copy(mreq.Interface[:], ip)
+ return nil
+ }
+ }
+ }
+ return errNoSuchInterface
+}
+
+func netIP4ToInterface(ip net.IP) (*net.Interface, error) {
+ ift, err := net.Interfaces()
+ if err != nil {
+ return nil, err
+ }
+ for _, ifi := range ift {
+ ifat, err := ifi.Addrs()
+ if err != nil {
+ return nil, err
+ }
+ for _, ifa := range ifat {
+ switch ifa := ifa.(type) {
+ case *net.IPAddr:
+ if ip.Equal(ifa.IP) {
+ return &ifi, nil
+ }
+ case *net.IPNet:
+ if ip.Equal(ifa.IP) {
+ return &ifi, nil
+ }
+ }
+ }
+ }
+ return nil, errNoSuchInterface
+}
+
+func netInterfaceToIP4(ifi *net.Interface) (net.IP, error) {
+ if ifi == nil {
+ return net.IPv4zero.To4(), nil
+ }
+ ifat, err := ifi.Addrs()
+ if err != nil {
+ return nil, err
+ }
+ for _, ifa := range ifat {
+ switch ifa := ifa.(type) {
+ case *net.IPAddr:
+ if ip := ifa.IP.To4(); ip != nil {
+ return ip, nil
+ }
+ case *net.IPNet:
+ if ip := ifa.IP.To4(); ip != nil {
+ return ip, nil
+ }
+ }
+ }
+ return nil, errNoSuchInterface
+}
diff --git a/vendor/golang.org/x/net/ipv4/sys_asmreq_stub.go b/vendor/golang.org/x/net/ipv4/sys_asmreq_stub.go
@@ -0,0 +1,26 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !aix && !darwin && !dragonfly && !freebsd && !netbsd && !openbsd && !solaris && !windows
+// +build !aix,!darwin,!dragonfly,!freebsd,!netbsd,!openbsd,!solaris,!windows
+
+package ipv4
+
+import (
+ "net"
+
+ "golang.org/x/net/internal/socket"
+)
+
+func (so *sockOpt) setIPMreq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
+ return errNotImplemented
+}
+
+func (so *sockOpt) getMulticastIf(c *socket.Conn) (*net.Interface, error) {
+ return nil, errNotImplemented
+}
+
+func (so *sockOpt) setMulticastIf(c *socket.Conn, ifi *net.Interface) error {
+ return errNotImplemented
+}
diff --git a/vendor/golang.org/x/net/ipv4/sys_asmreqn.go b/vendor/golang.org/x/net/ipv4/sys_asmreqn.go
@@ -0,0 +1,45 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build darwin || freebsd || linux
+// +build darwin freebsd linux
+
+package ipv4
+
+import (
+ "net"
+ "unsafe"
+
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
+)
+
+func (so *sockOpt) getIPMreqn(c *socket.Conn) (*net.Interface, error) {
+ b := make([]byte, so.Len)
+ if _, err := so.Get(c, b); err != nil {
+ return nil, err
+ }
+ mreqn := (*unix.IPMreqn)(unsafe.Pointer(&b[0]))
+ if mreqn.Ifindex == 0 {
+ return nil, nil
+ }
+ ifi, err := net.InterfaceByIndex(int(mreqn.Ifindex))
+ if err != nil {
+ return nil, err
+ }
+ return ifi, nil
+}
+
+func (so *sockOpt) setIPMreqn(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
+ var mreqn unix.IPMreqn
+ if ifi != nil {
+ mreqn.Ifindex = int32(ifi.Index)
+ }
+ if grp != nil {
+ mreqn.Multiaddr = [4]byte{grp[0], grp[1], grp[2], grp[3]}
+ }
+ b := (*[unix.SizeofIPMreqn]byte)(unsafe.Pointer(&mreqn))[:unix.SizeofIPMreqn]
+ return so.Set(c, b)
+}
diff --git a/vendor/golang.org/x/net/ipv4/sys_asmreqn_stub.go b/vendor/golang.org/x/net/ipv4/sys_asmreqn_stub.go
@@ -0,0 +1,22 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !darwin && !freebsd && !linux
+// +build !darwin,!freebsd,!linux
+
+package ipv4
+
+import (
+ "net"
+
+ "golang.org/x/net/internal/socket"
+)
+
+func (so *sockOpt) getIPMreqn(c *socket.Conn) (*net.Interface, error) {
+ return nil, errNotImplemented
+}
+
+func (so *sockOpt) setIPMreqn(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
+ return errNotImplemented
+}
diff --git a/vendor/golang.org/x/net/ipv4/sys_bpf.go b/vendor/golang.org/x/net/ipv4/sys_bpf.go
@@ -0,0 +1,25 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux
+// +build linux
+
+package ipv4
+
+import (
+ "unsafe"
+
+ "golang.org/x/net/bpf"
+ "golang.org/x/net/internal/socket"
+ "golang.org/x/sys/unix"
+)
+
+func (so *sockOpt) setAttachFilter(c *socket.Conn, f []bpf.RawInstruction) error {
+ prog := unix.SockFprog{
+ Len: uint16(len(f)),
+ Filter: (*unix.SockFilter)(unsafe.Pointer(&f[0])),
+ }
+ b := (*[unix.SizeofSockFprog]byte)(unsafe.Pointer(&prog))[:unix.SizeofSockFprog]
+ return so.Set(c, b)
+}
diff --git a/vendor/golang.org/x/net/ipv4/sys_bpf_stub.go b/vendor/golang.org/x/net/ipv4/sys_bpf_stub.go
@@ -0,0 +1,17 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !linux
+// +build !linux
+
+package ipv4
+
+import (
+ "golang.org/x/net/bpf"
+ "golang.org/x/net/internal/socket"
+)
+
+func (so *sockOpt) setAttachFilter(c *socket.Conn, f []bpf.RawInstruction) error {
+ return errNotImplemented
+}
diff --git a/vendor/golang.org/x/net/ipv4/sys_bsd.go b/vendor/golang.org/x/net/ipv4/sys_bsd.go
@@ -0,0 +1,42 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build netbsd || openbsd
+// +build netbsd openbsd
+
+package ipv4
+
+import (
+ "net"
+ "syscall"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
+)
+
+const sockoptReceiveInterface = unix.IP_RECVIF
+
+var (
+ ctlOpts = [ctlMax]ctlOpt{
+ ctlTTL: {unix.IP_RECVTTL, 1, marshalTTL, parseTTL},
+ ctlDst: {unix.IP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},
+ ctlInterface: {unix.IP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
+ }
+
+ sockOpts = map[int]*sockOpt{
+ ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}},
+ ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}},
+ ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 1}},
+ ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}},
+ ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVDSTADDR, Len: 4}},
+ ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVIF, Len: 4}},
+ ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+ }
+)
diff --git a/vendor/golang.org/x/net/ipv4/sys_darwin.go b/vendor/golang.org/x/net/ipv4/sys_darwin.go
@@ -0,0 +1,69 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv4
+
+import (
+ "net"
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
+)
+
+const sockoptReceiveInterface = unix.IP_RECVIF
+
+var (
+ ctlOpts = [ctlMax]ctlOpt{
+ ctlTTL: {unix.IP_RECVTTL, 1, marshalTTL, parseTTL},
+ ctlDst: {unix.IP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},
+ ctlInterface: {unix.IP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
+ ctlPacketInfo: {unix.IP_PKTINFO, sizeofInetPktinfo, marshalPacketInfo, parsePacketInfo},
+ }
+
+ sockOpts = map[int]*sockOpt{
+ ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}},
+ ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}},
+ ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: unix.SizeofIPMreqn}, typ: ssoTypeIPMreqn},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 4}},
+ ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}},
+ ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVDSTADDR, Len: 4}},
+ ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVIF, Len: 4}},
+ ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}},
+ ssoStripHeader: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_STRIPHDR, Len: 4}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoPacketInfo: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVPKTINFO, Len: 4}},
+ }
+)
+
+func (pi *inetPktinfo) setIfindex(i int) {
+ pi.Ifindex = uint32(i)
+}
+
+func (gr *groupReq) setGroup(grp net.IP) {
+ sa := (*sockaddrInet)(unsafe.Pointer(uintptr(unsafe.Pointer(gr)) + 4))
+ sa.Len = sizeofSockaddrInet
+ sa.Family = syscall.AF_INET
+ copy(sa.Addr[:], grp)
+}
+
+func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {
+ sa := (*sockaddrInet)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 4))
+ sa.Len = sizeofSockaddrInet
+ sa.Family = syscall.AF_INET
+ copy(sa.Addr[:], grp)
+ sa = (*sockaddrInet)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 132))
+ sa.Len = sizeofSockaddrInet
+ sa.Family = syscall.AF_INET
+ copy(sa.Addr[:], src)
+}
diff --git a/vendor/golang.org/x/net/ipv4/sys_dragonfly.go b/vendor/golang.org/x/net/ipv4/sys_dragonfly.go
@@ -0,0 +1,39 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv4
+
+import (
+ "net"
+ "syscall"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
+)
+
+const sockoptReceiveInterface = unix.IP_RECVIF
+
+var (
+ ctlOpts = [ctlMax]ctlOpt{
+ ctlTTL: {unix.IP_RECVTTL, 1, marshalTTL, parseTTL},
+ ctlDst: {unix.IP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},
+ ctlInterface: {unix.IP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
+ }
+
+ sockOpts = map[int]*sockOpt{
+ ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}},
+ ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}},
+ ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 4}},
+ ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}},
+ ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVDSTADDR, Len: 4}},
+ ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVIF, Len: 4}},
+ ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+ }
+)
diff --git a/vendor/golang.org/x/net/ipv4/sys_freebsd.go b/vendor/golang.org/x/net/ipv4/sys_freebsd.go
@@ -0,0 +1,80 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv4
+
+import (
+ "net"
+ "runtime"
+ "strings"
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
+)
+
+const sockoptReceiveInterface = unix.IP_RECVIF
+
+var (
+ ctlOpts = [ctlMax]ctlOpt{
+ ctlTTL: {unix.IP_RECVTTL, 1, marshalTTL, parseTTL},
+ ctlDst: {unix.IP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},
+ ctlInterface: {unix.IP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
+ }
+
+ sockOpts = map[int]*sockOpt{
+ ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}},
+ ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}},
+ ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 4}},
+ ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}},
+ ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVDSTADDR, Len: 4}},
+ ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVIF, Len: 4}},
+ ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ }
+)
+
+func init() {
+ freebsdVersion, _ = syscall.SysctlUint32("kern.osreldate")
+ if freebsdVersion >= 1000000 {
+ sockOpts[ssoMulticastInterface] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: unix.SizeofIPMreqn}, typ: ssoTypeIPMreqn}
+ }
+ if runtime.GOOS == "freebsd" && runtime.GOARCH == "386" {
+ archs, _ := syscall.Sysctl("kern.supported_archs")
+ for _, s := range strings.Fields(archs) {
+ if s == "amd64" {
+ compatFreeBSD32 = true
+ break
+ }
+ }
+ }
+}
+
+func (gr *groupReq) setGroup(grp net.IP) {
+ sa := (*sockaddrInet)(unsafe.Pointer(&gr.Group))
+ sa.Len = sizeofSockaddrInet
+ sa.Family = syscall.AF_INET
+ copy(sa.Addr[:], grp)
+}
+
+func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {
+ sa := (*sockaddrInet)(unsafe.Pointer(&gsr.Group))
+ sa.Len = sizeofSockaddrInet
+ sa.Family = syscall.AF_INET
+ copy(sa.Addr[:], grp)
+ sa = (*sockaddrInet)(unsafe.Pointer(&gsr.Source))
+ sa.Len = sizeofSockaddrInet
+ sa.Family = syscall.AF_INET
+ copy(sa.Addr[:], src)
+}
diff --git a/vendor/golang.org/x/net/ipv4/sys_linux.go b/vendor/golang.org/x/net/ipv4/sys_linux.go
@@ -0,0 +1,61 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv4
+
+import (
+ "net"
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
+)
+
+var (
+ ctlOpts = [ctlMax]ctlOpt{
+ ctlTTL: {unix.IP_TTL, 1, marshalTTL, parseTTL},
+ ctlPacketInfo: {unix.IP_PKTINFO, sizeofInetPktinfo, marshalPacketInfo, parsePacketInfo},
+ }
+
+ sockOpts = map[int]*sockOpt{
+ ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}},
+ ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}},
+ ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 4}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: unix.SizeofIPMreqn}, typ: ssoTypeIPMreqn},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 4}},
+ ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}},
+ ssoPacketInfo: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_PKTINFO, Len: 4}},
+ ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}},
+ ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolReserved, Name: unix.ICMP_FILTER, Len: sizeofICMPFilter}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoAttachFilter: {Option: socket.Option{Level: unix.SOL_SOCKET, Name: unix.SO_ATTACH_FILTER, Len: unix.SizeofSockFprog}},
+ }
+)
+
+func (pi *inetPktinfo) setIfindex(i int) {
+ pi.Ifindex = int32(i)
+}
+
+func (gr *groupReq) setGroup(grp net.IP) {
+ sa := (*sockaddrInet)(unsafe.Pointer(&gr.Group))
+ sa.Family = syscall.AF_INET
+ copy(sa.Addr[:], grp)
+}
+
+func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {
+ sa := (*sockaddrInet)(unsafe.Pointer(&gsr.Group))
+ sa.Family = syscall.AF_INET
+ copy(sa.Addr[:], grp)
+ sa = (*sockaddrInet)(unsafe.Pointer(&gsr.Source))
+ sa.Family = syscall.AF_INET
+ copy(sa.Addr[:], src)
+}
diff --git a/vendor/golang.org/x/net/ipv4/sys_solaris.go b/vendor/golang.org/x/net/ipv4/sys_solaris.go
@@ -0,0 +1,61 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv4
+
+import (
+ "net"
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
+)
+
+const sockoptReceiveInterface = unix.IP_RECVIF
+
+var (
+ ctlOpts = [ctlMax]ctlOpt{
+ ctlTTL: {unix.IP_RECVTTL, 4, marshalTTL, parseTTL},
+ ctlPacketInfo: {unix.IP_PKTINFO, sizeofInetPktinfo, marshalPacketInfo, parsePacketInfo},
+ }
+
+ sockOpts = map[int]sockOpt{
+ ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}},
+ ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}},
+ ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 1}},
+ ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}},
+ ssoPacketInfo: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVPKTINFO, Len: 4}},
+ ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ }
+)
+
+func (pi *inetPktinfo) setIfindex(i int) {
+ pi.Ifindex = uint32(i)
+}
+
+func (gr *groupReq) setGroup(grp net.IP) {
+ sa := (*sockaddrInet)(unsafe.Pointer(uintptr(unsafe.Pointer(gr)) + 4))
+ sa.Family = syscall.AF_INET
+ copy(sa.Addr[:], grp)
+}
+
+func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {
+ sa := (*sockaddrInet)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 4))
+ sa.Family = syscall.AF_INET
+ copy(sa.Addr[:], grp)
+ sa = (*sockaddrInet)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 260))
+ sa.Family = syscall.AF_INET
+ copy(sa.Addr[:], src)
+}
diff --git a/vendor/golang.org/x/net/ipv4/sys_ssmreq.go b/vendor/golang.org/x/net/ipv4/sys_ssmreq.go
@@ -0,0 +1,53 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build darwin || freebsd || linux || solaris
+// +build darwin freebsd linux solaris
+
+package ipv4
+
+import (
+ "net"
+ "unsafe"
+
+ "golang.org/x/net/internal/socket"
+)
+
+func (so *sockOpt) setGroupReq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
+ var gr groupReq
+ if ifi != nil {
+ gr.Interface = uint32(ifi.Index)
+ }
+ gr.setGroup(grp)
+ var b []byte
+ if compatFreeBSD32 {
+ var d [sizeofGroupReq + 4]byte
+ s := (*[sizeofGroupReq]byte)(unsafe.Pointer(&gr))
+ copy(d[:4], s[:4])
+ copy(d[8:], s[4:])
+ b = d[:]
+ } else {
+ b = (*[sizeofGroupReq]byte)(unsafe.Pointer(&gr))[:sizeofGroupReq]
+ }
+ return so.Set(c, b)
+}
+
+func (so *sockOpt) setGroupSourceReq(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error {
+ var gsr groupSourceReq
+ if ifi != nil {
+ gsr.Interface = uint32(ifi.Index)
+ }
+ gsr.setSourceGroup(grp, src)
+ var b []byte
+ if compatFreeBSD32 {
+ var d [sizeofGroupSourceReq + 4]byte
+ s := (*[sizeofGroupSourceReq]byte)(unsafe.Pointer(&gsr))
+ copy(d[:4], s[:4])
+ copy(d[8:], s[4:])
+ b = d[:]
+ } else {
+ b = (*[sizeofGroupSourceReq]byte)(unsafe.Pointer(&gsr))[:sizeofGroupSourceReq]
+ }
+ return so.Set(c, b)
+}
diff --git a/vendor/golang.org/x/net/ipv4/sys_ssmreq_stub.go b/vendor/golang.org/x/net/ipv4/sys_ssmreq_stub.go
@@ -0,0 +1,22 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !darwin && !freebsd && !linux && !solaris
+// +build !darwin,!freebsd,!linux,!solaris
+
+package ipv4
+
+import (
+ "net"
+
+ "golang.org/x/net/internal/socket"
+)
+
+func (so *sockOpt) setGroupReq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
+ return errNotImplemented
+}
+
+func (so *sockOpt) setGroupSourceReq(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error {
+ return errNotImplemented
+}
diff --git a/vendor/golang.org/x/net/ipv4/sys_stub.go b/vendor/golang.org/x/net/ipv4/sys_stub.go
@@ -0,0 +1,14 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
+
+package ipv4
+
+var (
+ ctlOpts = [ctlMax]ctlOpt{}
+
+ sockOpts = map[int]*sockOpt{}
+)
diff --git a/vendor/golang.org/x/net/ipv4/sys_windows.go b/vendor/golang.org/x/net/ipv4/sys_windows.go
@@ -0,0 +1,44 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv4
+
+import (
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/windows"
+)
+
+const (
+ sizeofIPMreq = 0x8
+ sizeofIPMreqSource = 0xc
+)
+
+type ipMreq struct {
+ Multiaddr [4]byte
+ Interface [4]byte
+}
+
+type ipMreqSource struct {
+ Multiaddr [4]byte
+ Sourceaddr [4]byte
+ Interface [4]byte
+}
+
+// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms738586(v=vs.85).aspx
+var (
+ ctlOpts = [ctlMax]ctlOpt{}
+
+ sockOpts = map[int]*sockOpt{
+ ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_TOS, Len: 4}},
+ ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_TTL, Len: 4}},
+ ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_MULTICAST_TTL, Len: 4}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_MULTICAST_IF, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_MULTICAST_LOOP, Len: 4}},
+ ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_HDRINCL, Len: 4}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+ }
+)
diff --git a/vendor/golang.org/x/net/ipv4/sys_zos.go b/vendor/golang.org/x/net/ipv4/sys_zos.go
@@ -0,0 +1,57 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv4
+
+import (
+ "net"
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
+)
+
+var (
+ ctlOpts = [ctlMax]ctlOpt{
+ ctlPacketInfo: {unix.IP_PKTINFO, sizeofInetPktinfo, marshalPacketInfo, parsePacketInfo},
+ }
+
+ sockOpts = map[int]*sockOpt{
+ ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 1}},
+ ssoPacketInfo: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVPKTINFO, Len: 4}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ }
+)
+
+func (pi *inetPktinfo) setIfindex(i int) {
+ pi.Ifindex = uint32(i)
+}
+
+func (gr *groupReq) setGroup(grp net.IP) {
+ sa := (*sockaddrInet4)(unsafe.Pointer(&gr.Group))
+ sa.Family = syscall.AF_INET
+ sa.Len = sizeofSockaddrInet4
+ copy(sa.Addr[:], grp)
+}
+
+func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {
+ sa := (*sockaddrInet4)(unsafe.Pointer(&gsr.Group))
+ sa.Family = syscall.AF_INET
+ sa.Len = sizeofSockaddrInet4
+ copy(sa.Addr[:], grp)
+ sa = (*sockaddrInet4)(unsafe.Pointer(&gsr.Source))
+ sa.Family = syscall.AF_INET
+ sa.Len = sizeofSockaddrInet4
+ copy(sa.Addr[:], src)
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_aix_ppc64.go b/vendor/golang.org/x/net/ipv4/zsys_aix_ppc64.go
@@ -0,0 +1,17 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_aix.go
+
+// Added for go1.11 compatibility
+//go:build aix
+// +build aix
+
+package ipv4
+
+const (
+ sizeofIPMreq = 0x8
+)
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_darwin.go b/vendor/golang.org/x/net/ipv4/zsys_darwin.go
@@ -0,0 +1,59 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_darwin.go
+
+package ipv4
+
+const (
+ sizeofSockaddrStorage = 0x80
+ sizeofSockaddrInet = 0x10
+ sizeofInetPktinfo = 0xc
+
+ sizeofIPMreq = 0x8
+ sizeofIPMreqSource = 0xc
+ sizeofGroupReq = 0x84
+ sizeofGroupSourceReq = 0x104
+)
+
+type sockaddrStorage struct {
+ Len uint8
+ Family uint8
+ X__ss_pad1 [6]int8
+ X__ss_align int64
+ X__ss_pad2 [112]int8
+}
+
+type sockaddrInet struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Addr [4]byte /* in_addr */
+ Zero [8]int8
+}
+
+type inetPktinfo struct {
+ Ifindex uint32
+ Spec_dst [4]byte /* in_addr */
+ Addr [4]byte /* in_addr */
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type ipMreqSource struct {
+ Multiaddr [4]byte /* in_addr */
+ Sourceaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [128]byte
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [128]byte
+ Pad_cgo_1 [128]byte
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_dragonfly.go b/vendor/golang.org/x/net/ipv4/zsys_dragonfly.go
@@ -0,0 +1,13 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_dragonfly.go
+
+package ipv4
+
+const (
+ sizeofIPMreq = 0x8
+)
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_freebsd_386.go b/vendor/golang.org/x/net/ipv4/zsys_freebsd_386.go
@@ -0,0 +1,52 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_freebsd.go
+
+package ipv4
+
+const (
+ sizeofSockaddrStorage = 0x80
+ sizeofSockaddrInet = 0x10
+
+ sizeofIPMreq = 0x8
+ sizeofIPMreqSource = 0xc
+ sizeofGroupReq = 0x84
+ sizeofGroupSourceReq = 0x104
+)
+
+type sockaddrStorage struct {
+ Len uint8
+ Family uint8
+ X__ss_pad1 [6]int8
+ X__ss_align int64
+ X__ss_pad2 [112]int8
+}
+
+type sockaddrInet struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Addr [4]byte /* in_addr */
+ Zero [8]int8
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type ipMreqSource struct {
+ Multiaddr [4]byte /* in_addr */
+ Sourceaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type groupReq struct {
+ Interface uint32
+ Group sockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Group sockaddrStorage
+ Source sockaddrStorage
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_freebsd_amd64.go b/vendor/golang.org/x/net/ipv4/zsys_freebsd_amd64.go
@@ -0,0 +1,54 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_freebsd.go
+
+package ipv4
+
+const (
+ sizeofSockaddrStorage = 0x80
+ sizeofSockaddrInet = 0x10
+
+ sizeofIPMreq = 0x8
+ sizeofIPMreqSource = 0xc
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+)
+
+type sockaddrStorage struct {
+ Len uint8
+ Family uint8
+ X__ss_pad1 [6]int8
+ X__ss_align int64
+ X__ss_pad2 [112]int8
+}
+
+type sockaddrInet struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Addr [4]byte /* in_addr */
+ Zero [8]int8
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type ipMreqSource struct {
+ Multiaddr [4]byte /* in_addr */
+ Sourceaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group sockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group sockaddrStorage
+ Source sockaddrStorage
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm.go b/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm.go
@@ -0,0 +1,54 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_freebsd.go
+
+package ipv4
+
+const (
+ sizeofSockaddrStorage = 0x80
+ sizeofSockaddrInet = 0x10
+
+ sizeofIPMreq = 0x8
+ sizeofIPMreqSource = 0xc
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+)
+
+type sockaddrStorage struct {
+ Len uint8
+ Family uint8
+ X__ss_pad1 [6]int8
+ X__ss_align int64
+ X__ss_pad2 [112]int8
+}
+
+type sockaddrInet struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Addr [4]byte /* in_addr */
+ Zero [8]int8
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type ipMreqSource struct {
+ Multiaddr [4]byte /* in_addr */
+ Sourceaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group sockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group sockaddrStorage
+ Source sockaddrStorage
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm64.go b/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm64.go
@@ -0,0 +1,52 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_freebsd.go
+
+package ipv4
+
+const (
+ sizeofSockaddrStorage = 0x80
+ sizeofSockaddrInet = 0x10
+
+ sizeofIPMreq = 0x8
+ sizeofIPMreqSource = 0xc
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+)
+
+type sockaddrStorage struct {
+ Len uint8
+ Family uint8
+ X__ss_pad1 [6]uint8
+ X__ss_align int64
+ X__ss_pad2 [112]uint8
+}
+
+type sockaddrInet struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Addr [4]byte /* in_addr */
+ Zero [8]uint8
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type ipMreqSource struct {
+ Multiaddr [4]byte /* in_addr */
+ Sourceaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type groupReq struct {
+ Interface uint32
+ Group sockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Group sockaddrStorage
+ Source sockaddrStorage
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_386.go b/vendor/golang.org/x/net/ipv4/zsys_linux_386.go
@@ -0,0 +1,72 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package ipv4
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet = 0x10
+ sizeofInetPktinfo = 0xc
+ sizeofSockExtendedErr = 0x10
+
+ sizeofIPMreq = 0x8
+ sizeofIPMreqSource = 0xc
+ sizeofGroupReq = 0x84
+ sizeofGroupSourceReq = 0x104
+
+ sizeofICMPFilter = 0x4
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet struct {
+ Family uint16
+ Port uint16
+ Addr [4]byte /* in_addr */
+ X__pad [8]uint8
+}
+
+type inetPktinfo struct {
+ Ifindex int32
+ Spec_dst [4]byte /* in_addr */
+ Addr [4]byte /* in_addr */
+}
+
+type sockExtendedErr struct {
+ Errno uint32
+ Origin uint8
+ Type uint8
+ Code uint8
+ Pad uint8
+ Info uint32
+ Data uint32
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type ipMreqSource struct {
+ Multiaddr uint32
+ Interface uint32
+ Sourceaddr uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpFilter struct {
+ Data uint32
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_amd64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_amd64.go
@@ -0,0 +1,74 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package ipv4
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet = 0x10
+ sizeofInetPktinfo = 0xc
+ sizeofSockExtendedErr = 0x10
+
+ sizeofIPMreq = 0x8
+ sizeofIPMreqSource = 0xc
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+
+ sizeofICMPFilter = 0x4
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet struct {
+ Family uint16
+ Port uint16
+ Addr [4]byte /* in_addr */
+ X__pad [8]uint8
+}
+
+type inetPktinfo struct {
+ Ifindex int32
+ Spec_dst [4]byte /* in_addr */
+ Addr [4]byte /* in_addr */
+}
+
+type sockExtendedErr struct {
+ Errno uint32
+ Origin uint8
+ Type uint8
+ Code uint8
+ Pad uint8
+ Info uint32
+ Data uint32
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type ipMreqSource struct {
+ Multiaddr uint32
+ Interface uint32
+ Sourceaddr uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpFilter struct {
+ Data uint32
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_arm.go b/vendor/golang.org/x/net/ipv4/zsys_linux_arm.go
@@ -0,0 +1,72 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package ipv4
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet = 0x10
+ sizeofInetPktinfo = 0xc
+ sizeofSockExtendedErr = 0x10
+
+ sizeofIPMreq = 0x8
+ sizeofIPMreqSource = 0xc
+ sizeofGroupReq = 0x84
+ sizeofGroupSourceReq = 0x104
+
+ sizeofICMPFilter = 0x4
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet struct {
+ Family uint16
+ Port uint16
+ Addr [4]byte /* in_addr */
+ X__pad [8]uint8
+}
+
+type inetPktinfo struct {
+ Ifindex int32
+ Spec_dst [4]byte /* in_addr */
+ Addr [4]byte /* in_addr */
+}
+
+type sockExtendedErr struct {
+ Errno uint32
+ Origin uint8
+ Type uint8
+ Code uint8
+ Pad uint8
+ Info uint32
+ Data uint32
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type ipMreqSource struct {
+ Multiaddr uint32
+ Interface uint32
+ Sourceaddr uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpFilter struct {
+ Data uint32
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_arm64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_arm64.go
@@ -0,0 +1,74 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package ipv4
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet = 0x10
+ sizeofInetPktinfo = 0xc
+ sizeofSockExtendedErr = 0x10
+
+ sizeofIPMreq = 0x8
+ sizeofIPMreqSource = 0xc
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+
+ sizeofICMPFilter = 0x4
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet struct {
+ Family uint16
+ Port uint16
+ Addr [4]byte /* in_addr */
+ X__pad [8]uint8
+}
+
+type inetPktinfo struct {
+ Ifindex int32
+ Spec_dst [4]byte /* in_addr */
+ Addr [4]byte /* in_addr */
+}
+
+type sockExtendedErr struct {
+ Errno uint32
+ Origin uint8
+ Type uint8
+ Code uint8
+ Pad uint8
+ Info uint32
+ Data uint32
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type ipMreqSource struct {
+ Multiaddr uint32
+ Interface uint32
+ Sourceaddr uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpFilter struct {
+ Data uint32
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_loong64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_loong64.go
@@ -0,0 +1,77 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+//go:build loong64
+// +build loong64
+
+package ipv4
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet = 0x10
+ sizeofInetPktinfo = 0xc
+ sizeofSockExtendedErr = 0x10
+
+ sizeofIPMreq = 0x8
+ sizeofIPMreqSource = 0xc
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+
+ sizeofICMPFilter = 0x4
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet struct {
+ Family uint16
+ Port uint16
+ Addr [4]byte /* in_addr */
+ X__pad [8]uint8
+}
+
+type inetPktinfo struct {
+ Ifindex int32
+ Spec_dst [4]byte /* in_addr */
+ Addr [4]byte /* in_addr */
+}
+
+type sockExtendedErr struct {
+ Errno uint32
+ Origin uint8
+ Type uint8
+ Code uint8
+ Pad uint8
+ Info uint32
+ Data uint32
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type ipMreqSource struct {
+ Multiaddr uint32
+ Interface uint32
+ Sourceaddr uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpFilter struct {
+ Data uint32
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_mips.go b/vendor/golang.org/x/net/ipv4/zsys_linux_mips.go
@@ -0,0 +1,72 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package ipv4
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet = 0x10
+ sizeofInetPktinfo = 0xc
+ sizeofSockExtendedErr = 0x10
+
+ sizeofIPMreq = 0x8
+ sizeofIPMreqSource = 0xc
+ sizeofGroupReq = 0x84
+ sizeofGroupSourceReq = 0x104
+
+ sizeofICMPFilter = 0x4
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet struct {
+ Family uint16
+ Port uint16
+ Addr [4]byte /* in_addr */
+ X__pad [8]uint8
+}
+
+type inetPktinfo struct {
+ Ifindex int32
+ Spec_dst [4]byte /* in_addr */
+ Addr [4]byte /* in_addr */
+}
+
+type sockExtendedErr struct {
+ Errno uint32
+ Origin uint8
+ Type uint8
+ Code uint8
+ Pad uint8
+ Info uint32
+ Data uint32
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type ipMreqSource struct {
+ Multiaddr uint32
+ Interface uint32
+ Sourceaddr uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpFilter struct {
+ Data uint32
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_mips64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_mips64.go
@@ -0,0 +1,74 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package ipv4
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet = 0x10
+ sizeofInetPktinfo = 0xc
+ sizeofSockExtendedErr = 0x10
+
+ sizeofIPMreq = 0x8
+ sizeofIPMreqSource = 0xc
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+
+ sizeofICMPFilter = 0x4
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet struct {
+ Family uint16
+ Port uint16
+ Addr [4]byte /* in_addr */
+ X__pad [8]uint8
+}
+
+type inetPktinfo struct {
+ Ifindex int32
+ Spec_dst [4]byte /* in_addr */
+ Addr [4]byte /* in_addr */
+}
+
+type sockExtendedErr struct {
+ Errno uint32
+ Origin uint8
+ Type uint8
+ Code uint8
+ Pad uint8
+ Info uint32
+ Data uint32
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type ipMreqSource struct {
+ Multiaddr uint32
+ Interface uint32
+ Sourceaddr uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpFilter struct {
+ Data uint32
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_mips64le.go b/vendor/golang.org/x/net/ipv4/zsys_linux_mips64le.go
@@ -0,0 +1,74 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package ipv4
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet = 0x10
+ sizeofInetPktinfo = 0xc
+ sizeofSockExtendedErr = 0x10
+
+ sizeofIPMreq = 0x8
+ sizeofIPMreqSource = 0xc
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+
+ sizeofICMPFilter = 0x4
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet struct {
+ Family uint16
+ Port uint16
+ Addr [4]byte /* in_addr */
+ X__pad [8]uint8
+}
+
+type inetPktinfo struct {
+ Ifindex int32
+ Spec_dst [4]byte /* in_addr */
+ Addr [4]byte /* in_addr */
+}
+
+type sockExtendedErr struct {
+ Errno uint32
+ Origin uint8
+ Type uint8
+ Code uint8
+ Pad uint8
+ Info uint32
+ Data uint32
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type ipMreqSource struct {
+ Multiaddr uint32
+ Interface uint32
+ Sourceaddr uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpFilter struct {
+ Data uint32
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_mipsle.go b/vendor/golang.org/x/net/ipv4/zsys_linux_mipsle.go
@@ -0,0 +1,72 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package ipv4
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet = 0x10
+ sizeofInetPktinfo = 0xc
+ sizeofSockExtendedErr = 0x10
+
+ sizeofIPMreq = 0x8
+ sizeofIPMreqSource = 0xc
+ sizeofGroupReq = 0x84
+ sizeofGroupSourceReq = 0x104
+
+ sizeofICMPFilter = 0x4
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet struct {
+ Family uint16
+ Port uint16
+ Addr [4]byte /* in_addr */
+ X__pad [8]uint8
+}
+
+type inetPktinfo struct {
+ Ifindex int32
+ Spec_dst [4]byte /* in_addr */
+ Addr [4]byte /* in_addr */
+}
+
+type sockExtendedErr struct {
+ Errno uint32
+ Origin uint8
+ Type uint8
+ Code uint8
+ Pad uint8
+ Info uint32
+ Data uint32
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type ipMreqSource struct {
+ Multiaddr uint32
+ Interface uint32
+ Sourceaddr uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpFilter struct {
+ Data uint32
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_ppc.go b/vendor/golang.org/x/net/ipv4/zsys_linux_ppc.go
@@ -0,0 +1,72 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package ipv4
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet = 0x10
+ sizeofInetPktinfo = 0xc
+ sizeofSockExtendedErr = 0x10
+
+ sizeofIPMreq = 0x8
+ sizeofIPMreqSource = 0xc
+ sizeofGroupReq = 0x84
+ sizeofGroupSourceReq = 0x104
+
+ sizeofICMPFilter = 0x4
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]uint8
+}
+
+type sockaddrInet struct {
+ Family uint16
+ Port uint16
+ Addr [4]byte /* in_addr */
+ X__pad [8]uint8
+}
+
+type inetPktinfo struct {
+ Ifindex int32
+ Spec_dst [4]byte /* in_addr */
+ Addr [4]byte /* in_addr */
+}
+
+type sockExtendedErr struct {
+ Errno uint32
+ Origin uint8
+ Type uint8
+ Code uint8
+ Pad uint8
+ Info uint32
+ Data uint32
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type ipMreqSource struct {
+ Multiaddr uint32
+ Interface uint32
+ Sourceaddr uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpFilter struct {
+ Data uint32
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64.go
@@ -0,0 +1,74 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package ipv4
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet = 0x10
+ sizeofInetPktinfo = 0xc
+ sizeofSockExtendedErr = 0x10
+
+ sizeofIPMreq = 0x8
+ sizeofIPMreqSource = 0xc
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+
+ sizeofICMPFilter = 0x4
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet struct {
+ Family uint16
+ Port uint16
+ Addr [4]byte /* in_addr */
+ X__pad [8]uint8
+}
+
+type inetPktinfo struct {
+ Ifindex int32
+ Spec_dst [4]byte /* in_addr */
+ Addr [4]byte /* in_addr */
+}
+
+type sockExtendedErr struct {
+ Errno uint32
+ Origin uint8
+ Type uint8
+ Code uint8
+ Pad uint8
+ Info uint32
+ Data uint32
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type ipMreqSource struct {
+ Multiaddr uint32
+ Interface uint32
+ Sourceaddr uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpFilter struct {
+ Data uint32
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64le.go b/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64le.go
@@ -0,0 +1,74 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package ipv4
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet = 0x10
+ sizeofInetPktinfo = 0xc
+ sizeofSockExtendedErr = 0x10
+
+ sizeofIPMreq = 0x8
+ sizeofIPMreqSource = 0xc
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+
+ sizeofICMPFilter = 0x4
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet struct {
+ Family uint16
+ Port uint16
+ Addr [4]byte /* in_addr */
+ X__pad [8]uint8
+}
+
+type inetPktinfo struct {
+ Ifindex int32
+ Spec_dst [4]byte /* in_addr */
+ Addr [4]byte /* in_addr */
+}
+
+type sockExtendedErr struct {
+ Errno uint32
+ Origin uint8
+ Type uint8
+ Code uint8
+ Pad uint8
+ Info uint32
+ Data uint32
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type ipMreqSource struct {
+ Multiaddr uint32
+ Interface uint32
+ Sourceaddr uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpFilter struct {
+ Data uint32
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go
@@ -0,0 +1,77 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+//go:build riscv64
+// +build riscv64
+
+package ipv4
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet = 0x10
+ sizeofInetPktinfo = 0xc
+ sizeofSockExtendedErr = 0x10
+
+ sizeofIPMreq = 0x8
+ sizeofIPMreqSource = 0xc
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+
+ sizeofICMPFilter = 0x4
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet struct {
+ Family uint16
+ Port uint16
+ Addr [4]byte /* in_addr */
+ X__pad [8]uint8
+}
+
+type inetPktinfo struct {
+ Ifindex int32
+ Spec_dst [4]byte /* in_addr */
+ Addr [4]byte /* in_addr */
+}
+
+type sockExtendedErr struct {
+ Errno uint32
+ Origin uint8
+ Type uint8
+ Code uint8
+ Pad uint8
+ Info uint32
+ Data uint32
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type ipMreqSource struct {
+ Multiaddr uint32
+ Interface uint32
+ Sourceaddr uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpFilter struct {
+ Data uint32
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_s390x.go b/vendor/golang.org/x/net/ipv4/zsys_linux_s390x.go
@@ -0,0 +1,74 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package ipv4
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet = 0x10
+ sizeofInetPktinfo = 0xc
+ sizeofSockExtendedErr = 0x10
+
+ sizeofIPMreq = 0x8
+ sizeofIPMreqSource = 0xc
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+
+ sizeofICMPFilter = 0x4
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet struct {
+ Family uint16
+ Port uint16
+ Addr [4]byte /* in_addr */
+ X__pad [8]uint8
+}
+
+type inetPktinfo struct {
+ Ifindex int32
+ Spec_dst [4]byte /* in_addr */
+ Addr [4]byte /* in_addr */
+}
+
+type sockExtendedErr struct {
+ Errno uint32
+ Origin uint8
+ Type uint8
+ Code uint8
+ Pad uint8
+ Info uint32
+ Data uint32
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type ipMreqSource struct {
+ Multiaddr uint32
+ Interface uint32
+ Sourceaddr uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpFilter struct {
+ Data uint32
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_netbsd.go b/vendor/golang.org/x/net/ipv4/zsys_netbsd.go
@@ -0,0 +1,13 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_netbsd.go
+
+package ipv4
+
+const (
+ sizeofIPMreq = 0x8
+)
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_openbsd.go b/vendor/golang.org/x/net/ipv4/zsys_openbsd.go
@@ -0,0 +1,13 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_openbsd.go
+
+package ipv4
+
+const (
+ sizeofIPMreq = 0x8
+)
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_solaris.go b/vendor/golang.org/x/net/ipv4/zsys_solaris.go
@@ -0,0 +1,57 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_solaris.go
+
+package ipv4
+
+const (
+ sizeofSockaddrStorage = 0x100
+ sizeofSockaddrInet = 0x10
+ sizeofInetPktinfo = 0xc
+
+ sizeofIPMreq = 0x8
+ sizeofIPMreqSource = 0xc
+ sizeofGroupReq = 0x104
+ sizeofGroupSourceReq = 0x204
+)
+
+type sockaddrStorage struct {
+ Family uint16
+ X_ss_pad1 [6]int8
+ X_ss_align float64
+ X_ss_pad2 [240]int8
+}
+
+type sockaddrInet struct {
+ Family uint16
+ Port uint16
+ Addr [4]byte /* in_addr */
+ Zero [8]int8
+}
+
+type inetPktinfo struct {
+ Ifindex uint32
+ Spec_dst [4]byte /* in_addr */
+ Addr [4]byte /* in_addr */
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type ipMreqSource struct {
+ Multiaddr [4]byte /* in_addr */
+ Sourceaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [256]byte
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [256]byte
+ Pad_cgo_1 [256]byte
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_zos_s390x.go b/vendor/golang.org/x/net/ipv4/zsys_zos_s390x.go
@@ -0,0 +1,56 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Hand edited based on zerrors_zos_s390x.go
+// TODO(Bill O'Farrell): auto-generate.
+
+package ipv4
+
+const (
+ sizeofIPMreq = 8
+ sizeofSockaddrInet4 = 16
+ sizeofSockaddrStorage = 128
+ sizeofGroupReq = 136
+ sizeofGroupSourceReq = 264
+ sizeofInetPktinfo = 8
+)
+
+type sockaddrInet4 struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Addr [4]byte
+ Zero [8]uint8
+}
+
+type inetPktinfo struct {
+ Addr [4]byte
+ Ifindex uint32
+}
+
+type sockaddrStorage struct {
+ Len uint8
+ Family byte
+ ss_pad1 [6]byte
+ ss_align int64
+ ss_pad2 [112]byte
+}
+
+type groupReq struct {
+ Interface uint32
+ reserved uint32
+ Group sockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ reserved uint32
+ Group sockaddrStorage
+ Source sockaddrStorage
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
diff --git a/vendor/golang.org/x/net/ipv6/batch.go b/vendor/golang.org/x/net/ipv6/batch.go
@@ -0,0 +1,116 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+import (
+ "net"
+ "runtime"
+
+ "golang.org/x/net/internal/socket"
+)
+
+// BUG(mikio): On Windows, the ReadBatch and WriteBatch methods of
+// PacketConn are not implemented.
+
+// A Message represents an IO message.
+//
+// type Message struct {
+// Buffers [][]byte
+// OOB []byte
+// Addr net.Addr
+// N int
+// NN int
+// Flags int
+// }
+//
+// The Buffers fields represents a list of contiguous buffers, which
+// can be used for vectored IO, for example, putting a header and a
+// payload in each slice.
+// When writing, the Buffers field must contain at least one byte to
+// write.
+// When reading, the Buffers field will always contain a byte to read.
+//
+// The OOB field contains protocol-specific control or miscellaneous
+// ancillary data known as out-of-band data.
+// It can be nil when not required.
+//
+// The Addr field specifies a destination address when writing.
+// It can be nil when the underlying protocol of the endpoint uses
+// connection-oriented communication.
+// After a successful read, it may contain the source address on the
+// received packet.
+//
+// The N field indicates the number of bytes read or written from/to
+// Buffers.
+//
+// The NN field indicates the number of bytes read or written from/to
+// OOB.
+//
+// The Flags field contains protocol-specific information on the
+// received message.
+type Message = socket.Message
+
+// ReadBatch reads a batch of messages.
+//
+// The provided flags is a set of platform-dependent flags, such as
+// syscall.MSG_PEEK.
+//
+// On a successful read it returns the number of messages received, up
+// to len(ms).
+//
+// On Linux, a batch read will be optimized.
+// On other platforms, this method will read only a single message.
+func (c *payloadHandler) ReadBatch(ms []Message, flags int) (int, error) {
+ if !c.ok() {
+ return 0, errInvalidConn
+ }
+ switch runtime.GOOS {
+ case "linux":
+ n, err := c.RecvMsgs([]socket.Message(ms), flags)
+ if err != nil {
+ err = &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
+ }
+ return n, err
+ default:
+ n := 1
+ err := c.RecvMsg(&ms[0], flags)
+ if err != nil {
+ n = 0
+ err = &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
+ }
+ return n, err
+ }
+}
+
+// WriteBatch writes a batch of messages.
+//
+// The provided flags is a set of platform-dependent flags, such as
+// syscall.MSG_DONTROUTE.
+//
+// It returns the number of messages written on a successful write.
+//
+// On Linux, a batch write will be optimized.
+// On other platforms, this method will write only a single message.
+func (c *payloadHandler) WriteBatch(ms []Message, flags int) (int, error) {
+ if !c.ok() {
+ return 0, errInvalidConn
+ }
+ switch runtime.GOOS {
+ case "linux":
+ n, err := c.SendMsgs([]socket.Message(ms), flags)
+ if err != nil {
+ err = &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
+ }
+ return n, err
+ default:
+ n := 1
+ err := c.SendMsg(&ms[0], flags)
+ if err != nil {
+ n = 0
+ err = &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
+ }
+ return n, err
+ }
+}
diff --git a/vendor/golang.org/x/net/ipv6/control.go b/vendor/golang.org/x/net/ipv6/control.go
@@ -0,0 +1,187 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+import (
+ "fmt"
+ "net"
+ "sync"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+)
+
+// Note that RFC 3542 obsoletes RFC 2292 but OS X Snow Leopard and the
+// former still support RFC 2292 only. Please be aware that almost
+// all protocol implementations prohibit using a combination of RFC
+// 2292 and RFC 3542 for some practical reasons.
+
+type rawOpt struct {
+ sync.RWMutex
+ cflags ControlFlags
+}
+
+func (c *rawOpt) set(f ControlFlags) { c.cflags |= f }
+func (c *rawOpt) clear(f ControlFlags) { c.cflags &^= f }
+func (c *rawOpt) isset(f ControlFlags) bool { return c.cflags&f != 0 }
+
+// A ControlFlags represents per packet basis IP-level socket option
+// control flags.
+type ControlFlags uint
+
+const (
+ FlagTrafficClass ControlFlags = 1 << iota // pass the traffic class on the received packet
+ FlagHopLimit // pass the hop limit on the received packet
+ FlagSrc // pass the source address on the received packet
+ FlagDst // pass the destination address on the received packet
+ FlagInterface // pass the interface index on the received packet
+ FlagPathMTU // pass the path MTU on the received packet path
+)
+
+const flagPacketInfo = FlagDst | FlagInterface
+
+// A ControlMessage represents per packet basis IP-level socket
+// options.
+type ControlMessage struct {
+ // Receiving socket options: SetControlMessage allows to
+ // receive the options from the protocol stack using ReadFrom
+ // method of PacketConn.
+ //
+ // Specifying socket options: ControlMessage for WriteTo
+ // method of PacketConn allows to send the options to the
+ // protocol stack.
+ //
+ TrafficClass int // traffic class, must be 1 <= value <= 255 when specifying
+ HopLimit int // hop limit, must be 1 <= value <= 255 when specifying
+ Src net.IP // source address, specifying only
+ Dst net.IP // destination address, receiving only
+ IfIndex int // interface index, must be 1 <= value when specifying
+ NextHop net.IP // next hop address, specifying only
+ MTU int // path MTU, receiving only
+}
+
+func (cm *ControlMessage) String() string {
+ if cm == nil {
+ return "<nil>"
+ }
+ return fmt.Sprintf("tclass=%#x hoplim=%d src=%v dst=%v ifindex=%d nexthop=%v mtu=%d", cm.TrafficClass, cm.HopLimit, cm.Src, cm.Dst, cm.IfIndex, cm.NextHop, cm.MTU)
+}
+
+// Marshal returns the binary encoding of cm.
+func (cm *ControlMessage) Marshal() []byte {
+ if cm == nil {
+ return nil
+ }
+ var l int
+ tclass := false
+ if ctlOpts[ctlTrafficClass].name > 0 && cm.TrafficClass > 0 {
+ tclass = true
+ l += socket.ControlMessageSpace(ctlOpts[ctlTrafficClass].length)
+ }
+ hoplimit := false
+ if ctlOpts[ctlHopLimit].name > 0 && cm.HopLimit > 0 {
+ hoplimit = true
+ l += socket.ControlMessageSpace(ctlOpts[ctlHopLimit].length)
+ }
+ pktinfo := false
+ if ctlOpts[ctlPacketInfo].name > 0 && (cm.Src.To16() != nil && cm.Src.To4() == nil || cm.IfIndex > 0) {
+ pktinfo = true
+ l += socket.ControlMessageSpace(ctlOpts[ctlPacketInfo].length)
+ }
+ nexthop := false
+ if ctlOpts[ctlNextHop].name > 0 && cm.NextHop.To16() != nil && cm.NextHop.To4() == nil {
+ nexthop = true
+ l += socket.ControlMessageSpace(ctlOpts[ctlNextHop].length)
+ }
+ var b []byte
+ if l > 0 {
+ b = make([]byte, l)
+ bb := b
+ if tclass {
+ bb = ctlOpts[ctlTrafficClass].marshal(bb, cm)
+ }
+ if hoplimit {
+ bb = ctlOpts[ctlHopLimit].marshal(bb, cm)
+ }
+ if pktinfo {
+ bb = ctlOpts[ctlPacketInfo].marshal(bb, cm)
+ }
+ if nexthop {
+ bb = ctlOpts[ctlNextHop].marshal(bb, cm)
+ }
+ }
+ return b
+}
+
+// Parse parses b as a control message and stores the result in cm.
+func (cm *ControlMessage) Parse(b []byte) error {
+ ms, err := socket.ControlMessage(b).Parse()
+ if err != nil {
+ return err
+ }
+ for _, m := range ms {
+ lvl, typ, l, err := m.ParseHeader()
+ if err != nil {
+ return err
+ }
+ if lvl != iana.ProtocolIPv6 {
+ continue
+ }
+ switch {
+ case typ == ctlOpts[ctlTrafficClass].name && l >= ctlOpts[ctlTrafficClass].length:
+ ctlOpts[ctlTrafficClass].parse(cm, m.Data(l))
+ case typ == ctlOpts[ctlHopLimit].name && l >= ctlOpts[ctlHopLimit].length:
+ ctlOpts[ctlHopLimit].parse(cm, m.Data(l))
+ case typ == ctlOpts[ctlPacketInfo].name && l >= ctlOpts[ctlPacketInfo].length:
+ ctlOpts[ctlPacketInfo].parse(cm, m.Data(l))
+ case typ == ctlOpts[ctlPathMTU].name && l >= ctlOpts[ctlPathMTU].length:
+ ctlOpts[ctlPathMTU].parse(cm, m.Data(l))
+ }
+ }
+ return nil
+}
+
+// NewControlMessage returns a new control message.
+//
+// The returned message is large enough for options specified by cf.
+func NewControlMessage(cf ControlFlags) []byte {
+ opt := rawOpt{cflags: cf}
+ var l int
+ if opt.isset(FlagTrafficClass) && ctlOpts[ctlTrafficClass].name > 0 {
+ l += socket.ControlMessageSpace(ctlOpts[ctlTrafficClass].length)
+ }
+ if opt.isset(FlagHopLimit) && ctlOpts[ctlHopLimit].name > 0 {
+ l += socket.ControlMessageSpace(ctlOpts[ctlHopLimit].length)
+ }
+ if opt.isset(flagPacketInfo) && ctlOpts[ctlPacketInfo].name > 0 {
+ l += socket.ControlMessageSpace(ctlOpts[ctlPacketInfo].length)
+ }
+ if opt.isset(FlagPathMTU) && ctlOpts[ctlPathMTU].name > 0 {
+ l += socket.ControlMessageSpace(ctlOpts[ctlPathMTU].length)
+ }
+ var b []byte
+ if l > 0 {
+ b = make([]byte, l)
+ }
+ return b
+}
+
+// Ancillary data socket options
+const (
+ ctlTrafficClass = iota // header field
+ ctlHopLimit // header field
+ ctlPacketInfo // inbound or outbound packet path
+ ctlNextHop // nexthop
+ ctlPathMTU // path mtu
+ ctlMax
+)
+
+// A ctlOpt represents a binding for ancillary data socket option.
+type ctlOpt struct {
+ name int // option name, must be equal or greater than 1
+ length int // option length
+ marshal func([]byte, *ControlMessage) []byte
+ parse func(*ControlMessage, []byte)
+}
diff --git a/vendor/golang.org/x/net/ipv6/control_rfc2292_unix.go b/vendor/golang.org/x/net/ipv6/control_rfc2292_unix.go
@@ -0,0 +1,51 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build darwin
+// +build darwin
+
+package ipv6
+
+import (
+ "unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
+)
+
+func marshal2292HopLimit(b []byte, cm *ControlMessage) []byte {
+ m := socket.ControlMessage(b)
+ m.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_2292HOPLIMIT, 4)
+ if cm != nil {
+ socket.NativeEndian.PutUint32(m.Data(4), uint32(cm.HopLimit))
+ }
+ return m.Next(4)
+}
+
+func marshal2292PacketInfo(b []byte, cm *ControlMessage) []byte {
+ m := socket.ControlMessage(b)
+ m.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_2292PKTINFO, sizeofInet6Pktinfo)
+ if cm != nil {
+ pi := (*inet6Pktinfo)(unsafe.Pointer(&m.Data(sizeofInet6Pktinfo)[0]))
+ if ip := cm.Src.To16(); ip != nil && ip.To4() == nil {
+ copy(pi.Addr[:], ip)
+ }
+ if cm.IfIndex > 0 {
+ pi.setIfindex(cm.IfIndex)
+ }
+ }
+ return m.Next(sizeofInet6Pktinfo)
+}
+
+func marshal2292NextHop(b []byte, cm *ControlMessage) []byte {
+ m := socket.ControlMessage(b)
+ m.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_2292NEXTHOP, sizeofSockaddrInet6)
+ if cm != nil {
+ sa := (*sockaddrInet6)(unsafe.Pointer(&m.Data(sizeofSockaddrInet6)[0]))
+ sa.setSockaddr(cm.NextHop, cm.IfIndex)
+ }
+ return m.Next(sizeofSockaddrInet6)
+}
diff --git a/vendor/golang.org/x/net/ipv6/control_rfc3542_unix.go b/vendor/golang.org/x/net/ipv6/control_rfc3542_unix.go
@@ -0,0 +1,97 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
+
+package ipv6
+
+import (
+ "net"
+ "unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
+)
+
+func marshalTrafficClass(b []byte, cm *ControlMessage) []byte {
+ m := socket.ControlMessage(b)
+ m.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_TCLASS, 4)
+ if cm != nil {
+ socket.NativeEndian.PutUint32(m.Data(4), uint32(cm.TrafficClass))
+ }
+ return m.Next(4)
+}
+
+func parseTrafficClass(cm *ControlMessage, b []byte) {
+ cm.TrafficClass = int(socket.NativeEndian.Uint32(b[:4]))
+}
+
+func marshalHopLimit(b []byte, cm *ControlMessage) []byte {
+ m := socket.ControlMessage(b)
+ m.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_HOPLIMIT, 4)
+ if cm != nil {
+ socket.NativeEndian.PutUint32(m.Data(4), uint32(cm.HopLimit))
+ }
+ return m.Next(4)
+}
+
+func parseHopLimit(cm *ControlMessage, b []byte) {
+ cm.HopLimit = int(socket.NativeEndian.Uint32(b[:4]))
+}
+
+func marshalPacketInfo(b []byte, cm *ControlMessage) []byte {
+ m := socket.ControlMessage(b)
+ m.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_PKTINFO, sizeofInet6Pktinfo)
+ if cm != nil {
+ pi := (*inet6Pktinfo)(unsafe.Pointer(&m.Data(sizeofInet6Pktinfo)[0]))
+ if ip := cm.Src.To16(); ip != nil && ip.To4() == nil {
+ copy(pi.Addr[:], ip)
+ }
+ if cm.IfIndex > 0 {
+ pi.setIfindex(cm.IfIndex)
+ }
+ }
+ return m.Next(sizeofInet6Pktinfo)
+}
+
+func parsePacketInfo(cm *ControlMessage, b []byte) {
+ pi := (*inet6Pktinfo)(unsafe.Pointer(&b[0]))
+ if len(cm.Dst) < net.IPv6len {
+ cm.Dst = make(net.IP, net.IPv6len)
+ }
+ copy(cm.Dst, pi.Addr[:])
+ cm.IfIndex = int(pi.Ifindex)
+}
+
+func marshalNextHop(b []byte, cm *ControlMessage) []byte {
+ m := socket.ControlMessage(b)
+ m.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_NEXTHOP, sizeofSockaddrInet6)
+ if cm != nil {
+ sa := (*sockaddrInet6)(unsafe.Pointer(&m.Data(sizeofSockaddrInet6)[0]))
+ sa.setSockaddr(cm.NextHop, cm.IfIndex)
+ }
+ return m.Next(sizeofSockaddrInet6)
+}
+
+func parseNextHop(cm *ControlMessage, b []byte) {
+}
+
+func marshalPathMTU(b []byte, cm *ControlMessage) []byte {
+ m := socket.ControlMessage(b)
+ m.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_PATHMTU, sizeofIPv6Mtuinfo)
+ return m.Next(sizeofIPv6Mtuinfo)
+}
+
+func parsePathMTU(cm *ControlMessage, b []byte) {
+ mi := (*ipv6Mtuinfo)(unsafe.Pointer(&b[0]))
+ if len(cm.Dst) < net.IPv6len {
+ cm.Dst = make(net.IP, net.IPv6len)
+ }
+ copy(cm.Dst, mi.Addr.Addr[:])
+ cm.IfIndex = int(mi.Addr.Scope_id)
+ cm.MTU = int(mi.Mtu)
+}
diff --git a/vendor/golang.org/x/net/ipv6/control_stub.go b/vendor/golang.org/x/net/ipv6/control_stub.go
@@ -0,0 +1,14 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
+
+package ipv6
+
+import "golang.org/x/net/internal/socket"
+
+func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
+ return errNotImplemented
+}
diff --git a/vendor/golang.org/x/net/ipv6/control_unix.go b/vendor/golang.org/x/net/ipv6/control_unix.go
@@ -0,0 +1,56 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
+
+package ipv6
+
+import "golang.org/x/net/internal/socket"
+
+func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
+ opt.Lock()
+ defer opt.Unlock()
+ if so, ok := sockOpts[ssoReceiveTrafficClass]; ok && cf&FlagTrafficClass != 0 {
+ if err := so.SetInt(c, boolint(on)); err != nil {
+ return err
+ }
+ if on {
+ opt.set(FlagTrafficClass)
+ } else {
+ opt.clear(FlagTrafficClass)
+ }
+ }
+ if so, ok := sockOpts[ssoReceiveHopLimit]; ok && cf&FlagHopLimit != 0 {
+ if err := so.SetInt(c, boolint(on)); err != nil {
+ return err
+ }
+ if on {
+ opt.set(FlagHopLimit)
+ } else {
+ opt.clear(FlagHopLimit)
+ }
+ }
+ if so, ok := sockOpts[ssoReceivePacketInfo]; ok && cf&flagPacketInfo != 0 {
+ if err := so.SetInt(c, boolint(on)); err != nil {
+ return err
+ }
+ if on {
+ opt.set(cf & flagPacketInfo)
+ } else {
+ opt.clear(cf & flagPacketInfo)
+ }
+ }
+ if so, ok := sockOpts[ssoReceivePathMTU]; ok && cf&FlagPathMTU != 0 {
+ if err := so.SetInt(c, boolint(on)); err != nil {
+ return err
+ }
+ if on {
+ opt.set(FlagPathMTU)
+ } else {
+ opt.clear(FlagPathMTU)
+ }
+ }
+ return nil
+}
diff --git a/vendor/golang.org/x/net/ipv6/control_windows.go b/vendor/golang.org/x/net/ipv6/control_windows.go
@@ -0,0 +1,12 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+import "golang.org/x/net/internal/socket"
+
+func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
+ // TODO(mikio): implement this
+ return errNotImplemented
+}
diff --git a/vendor/golang.org/x/net/ipv6/dgramopt.go b/vendor/golang.org/x/net/ipv6/dgramopt.go
@@ -0,0 +1,301 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+import (
+ "net"
+
+ "golang.org/x/net/bpf"
+)
+
+// MulticastHopLimit returns the hop limit field value for outgoing
+// multicast packets.
+func (c *dgramOpt) MulticastHopLimit() (int, error) {
+ if !c.ok() {
+ return 0, errInvalidConn
+ }
+ so, ok := sockOpts[ssoMulticastHopLimit]
+ if !ok {
+ return 0, errNotImplemented
+ }
+ return so.GetInt(c.Conn)
+}
+
+// SetMulticastHopLimit sets the hop limit field value for future
+// outgoing multicast packets.
+func (c *dgramOpt) SetMulticastHopLimit(hoplim int) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoMulticastHopLimit]
+ if !ok {
+ return errNotImplemented
+ }
+ return so.SetInt(c.Conn, hoplim)
+}
+
+// MulticastInterface returns the default interface for multicast
+// packet transmissions.
+func (c *dgramOpt) MulticastInterface() (*net.Interface, error) {
+ if !c.ok() {
+ return nil, errInvalidConn
+ }
+ so, ok := sockOpts[ssoMulticastInterface]
+ if !ok {
+ return nil, errNotImplemented
+ }
+ return so.getMulticastInterface(c.Conn)
+}
+
+// SetMulticastInterface sets the default interface for future
+// multicast packet transmissions.
+func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoMulticastInterface]
+ if !ok {
+ return errNotImplemented
+ }
+ return so.setMulticastInterface(c.Conn, ifi)
+}
+
+// MulticastLoopback reports whether transmitted multicast packets
+// should be copied and send back to the originator.
+func (c *dgramOpt) MulticastLoopback() (bool, error) {
+ if !c.ok() {
+ return false, errInvalidConn
+ }
+ so, ok := sockOpts[ssoMulticastLoopback]
+ if !ok {
+ return false, errNotImplemented
+ }
+ on, err := so.GetInt(c.Conn)
+ if err != nil {
+ return false, err
+ }
+ return on == 1, nil
+}
+
+// SetMulticastLoopback sets whether transmitted multicast packets
+// should be copied and send back to the originator.
+func (c *dgramOpt) SetMulticastLoopback(on bool) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoMulticastLoopback]
+ if !ok {
+ return errNotImplemented
+ }
+ return so.SetInt(c.Conn, boolint(on))
+}
+
+// JoinGroup joins the group address group on the interface ifi.
+// By default all sources that can cast data to group are accepted.
+// It's possible to mute and unmute data transmission from a specific
+// source by using ExcludeSourceSpecificGroup and
+// IncludeSourceSpecificGroup.
+// JoinGroup uses the system assigned multicast interface when ifi is
+// nil, although this is not recommended because the assignment
+// depends on platforms and sometimes it might require routing
+// configuration.
+func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoJoinGroup]
+ if !ok {
+ return errNotImplemented
+ }
+ grp := netAddrToIP16(group)
+ if grp == nil {
+ return errMissingAddress
+ }
+ return so.setGroup(c.Conn, ifi, grp)
+}
+
+// LeaveGroup leaves the group address group on the interface ifi
+// regardless of whether the group is any-source group or
+// source-specific group.
+func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoLeaveGroup]
+ if !ok {
+ return errNotImplemented
+ }
+ grp := netAddrToIP16(group)
+ if grp == nil {
+ return errMissingAddress
+ }
+ return so.setGroup(c.Conn, ifi, grp)
+}
+
+// JoinSourceSpecificGroup joins the source-specific group comprising
+// group and source on the interface ifi.
+// JoinSourceSpecificGroup uses the system assigned multicast
+// interface when ifi is nil, although this is not recommended because
+// the assignment depends on platforms and sometimes it might require
+// routing configuration.
+func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoJoinSourceGroup]
+ if !ok {
+ return errNotImplemented
+ }
+ grp := netAddrToIP16(group)
+ if grp == nil {
+ return errMissingAddress
+ }
+ src := netAddrToIP16(source)
+ if src == nil {
+ return errMissingAddress
+ }
+ return so.setSourceGroup(c.Conn, ifi, grp, src)
+}
+
+// LeaveSourceSpecificGroup leaves the source-specific group on the
+// interface ifi.
+func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoLeaveSourceGroup]
+ if !ok {
+ return errNotImplemented
+ }
+ grp := netAddrToIP16(group)
+ if grp == nil {
+ return errMissingAddress
+ }
+ src := netAddrToIP16(source)
+ if src == nil {
+ return errMissingAddress
+ }
+ return so.setSourceGroup(c.Conn, ifi, grp, src)
+}
+
+// ExcludeSourceSpecificGroup excludes the source-specific group from
+// the already joined any-source groups by JoinGroup on the interface
+// ifi.
+func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoBlockSourceGroup]
+ if !ok {
+ return errNotImplemented
+ }
+ grp := netAddrToIP16(group)
+ if grp == nil {
+ return errMissingAddress
+ }
+ src := netAddrToIP16(source)
+ if src == nil {
+ return errMissingAddress
+ }
+ return so.setSourceGroup(c.Conn, ifi, grp, src)
+}
+
+// IncludeSourceSpecificGroup includes the excluded source-specific
+// group by ExcludeSourceSpecificGroup again on the interface ifi.
+func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoUnblockSourceGroup]
+ if !ok {
+ return errNotImplemented
+ }
+ grp := netAddrToIP16(group)
+ if grp == nil {
+ return errMissingAddress
+ }
+ src := netAddrToIP16(source)
+ if src == nil {
+ return errMissingAddress
+ }
+ return so.setSourceGroup(c.Conn, ifi, grp, src)
+}
+
+// Checksum reports whether the kernel will compute, store or verify a
+// checksum for both incoming and outgoing packets. If on is true, it
+// returns an offset in bytes into the data of where the checksum
+// field is located.
+func (c *dgramOpt) Checksum() (on bool, offset int, err error) {
+ if !c.ok() {
+ return false, 0, errInvalidConn
+ }
+ so, ok := sockOpts[ssoChecksum]
+ if !ok {
+ return false, 0, errNotImplemented
+ }
+ offset, err = so.GetInt(c.Conn)
+ if err != nil {
+ return false, 0, err
+ }
+ if offset < 0 {
+ return false, 0, nil
+ }
+ return true, offset, nil
+}
+
+// SetChecksum enables the kernel checksum processing. If on is ture,
+// the offset should be an offset in bytes into the data of where the
+// checksum field is located.
+func (c *dgramOpt) SetChecksum(on bool, offset int) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoChecksum]
+ if !ok {
+ return errNotImplemented
+ }
+ if !on {
+ offset = -1
+ }
+ return so.SetInt(c.Conn, offset)
+}
+
+// ICMPFilter returns an ICMP filter.
+func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) {
+ if !c.ok() {
+ return nil, errInvalidConn
+ }
+ so, ok := sockOpts[ssoICMPFilter]
+ if !ok {
+ return nil, errNotImplemented
+ }
+ return so.getICMPFilter(c.Conn)
+}
+
+// SetICMPFilter deploys the ICMP filter.
+func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoICMPFilter]
+ if !ok {
+ return errNotImplemented
+ }
+ return so.setICMPFilter(c.Conn, f)
+}
+
+// SetBPF attaches a BPF program to the connection.
+//
+// Only supported on Linux.
+func (c *dgramOpt) SetBPF(filter []bpf.RawInstruction) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoAttachFilter]
+ if !ok {
+ return errNotImplemented
+ }
+ return so.setBPF(c.Conn, filter)
+}
diff --git a/vendor/golang.org/x/net/ipv6/doc.go b/vendor/golang.org/x/net/ipv6/doc.go
@@ -0,0 +1,239 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package ipv6 implements IP-level socket options for the Internet
+// Protocol version 6.
+//
+// The package provides IP-level socket options that allow
+// manipulation of IPv6 facilities.
+//
+// The IPv6 protocol is defined in RFC 8200.
+// Socket interface extensions are defined in RFC 3493, RFC 3542 and
+// RFC 3678.
+// MLDv1 and MLDv2 are defined in RFC 2710 and RFC 3810.
+// Source-specific multicast is defined in RFC 4607.
+//
+// On Darwin, this package requires OS X Mavericks version 10.9 or
+// above, or equivalent.
+//
+// # Unicasting
+//
+// The options for unicasting are available for net.TCPConn,
+// net.UDPConn and net.IPConn which are created as network connections
+// that use the IPv6 transport. When a single TCP connection carrying
+// a data flow of multiple packets needs to indicate the flow is
+// important, Conn is used to set the traffic class field on the IPv6
+// header for each packet.
+//
+// ln, err := net.Listen("tcp6", "[::]:1024")
+// if err != nil {
+// // error handling
+// }
+// defer ln.Close()
+// for {
+// c, err := ln.Accept()
+// if err != nil {
+// // error handling
+// }
+// go func(c net.Conn) {
+// defer c.Close()
+//
+// The outgoing packets will be labeled DiffServ assured forwarding
+// class 1 low drop precedence, known as AF11 packets.
+//
+// if err := ipv6.NewConn(c).SetTrafficClass(0x28); err != nil {
+// // error handling
+// }
+// if _, err := c.Write(data); err != nil {
+// // error handling
+// }
+// }(c)
+// }
+//
+// # Multicasting
+//
+// The options for multicasting are available for net.UDPConn and
+// net.IPConn which are created as network connections that use the
+// IPv6 transport. A few network facilities must be prepared before
+// you begin multicasting, at a minimum joining network interfaces and
+// multicast groups.
+//
+// en0, err := net.InterfaceByName("en0")
+// if err != nil {
+// // error handling
+// }
+// en1, err := net.InterfaceByIndex(911)
+// if err != nil {
+// // error handling
+// }
+// group := net.ParseIP("ff02::114")
+//
+// First, an application listens to an appropriate address with an
+// appropriate service port.
+//
+// c, err := net.ListenPacket("udp6", "[::]:1024")
+// if err != nil {
+// // error handling
+// }
+// defer c.Close()
+//
+// Second, the application joins multicast groups, starts listening to
+// the groups on the specified network interfaces. Note that the
+// service port for transport layer protocol does not matter with this
+// operation as joining groups affects only network and link layer
+// protocols, such as IPv6 and Ethernet.
+//
+// p := ipv6.NewPacketConn(c)
+// if err := p.JoinGroup(en0, &net.UDPAddr{IP: group}); err != nil {
+// // error handling
+// }
+// if err := p.JoinGroup(en1, &net.UDPAddr{IP: group}); err != nil {
+// // error handling
+// }
+//
+// The application might set per packet control message transmissions
+// between the protocol stack within the kernel. When the application
+// needs a destination address on an incoming packet,
+// SetControlMessage of PacketConn is used to enable control message
+// transmissions.
+//
+// if err := p.SetControlMessage(ipv6.FlagDst, true); err != nil {
+// // error handling
+// }
+//
+// The application could identify whether the received packets are
+// of interest by using the control message that contains the
+// destination address of the received packet.
+//
+// b := make([]byte, 1500)
+// for {
+// n, rcm, src, err := p.ReadFrom(b)
+// if err != nil {
+// // error handling
+// }
+// if rcm.Dst.IsMulticast() {
+// if rcm.Dst.Equal(group) {
+// // joined group, do something
+// } else {
+// // unknown group, discard
+// continue
+// }
+// }
+//
+// The application can also send both unicast and multicast packets.
+//
+// p.SetTrafficClass(0x0)
+// p.SetHopLimit(16)
+// if _, err := p.WriteTo(data[:n], nil, src); err != nil {
+// // error handling
+// }
+// dst := &net.UDPAddr{IP: group, Port: 1024}
+// wcm := ipv6.ControlMessage{TrafficClass: 0xe0, HopLimit: 1}
+// for _, ifi := range []*net.Interface{en0, en1} {
+// wcm.IfIndex = ifi.Index
+// if _, err := p.WriteTo(data[:n], &wcm, dst); err != nil {
+// // error handling
+// }
+// }
+// }
+//
+// # More multicasting
+//
+// An application that uses PacketConn may join multiple multicast
+// groups. For example, a UDP listener with port 1024 might join two
+// different groups across over two different network interfaces by
+// using:
+//
+// c, err := net.ListenPacket("udp6", "[::]:1024")
+// if err != nil {
+// // error handling
+// }
+// defer c.Close()
+// p := ipv6.NewPacketConn(c)
+// if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::1:114")}); err != nil {
+// // error handling
+// }
+// if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::2:114")}); err != nil {
+// // error handling
+// }
+// if err := p.JoinGroup(en1, &net.UDPAddr{IP: net.ParseIP("ff02::2:114")}); err != nil {
+// // error handling
+// }
+//
+// It is possible for multiple UDP listeners that listen on the same
+// UDP port to join the same multicast group. The net package will
+// provide a socket that listens to a wildcard address with reusable
+// UDP port when an appropriate multicast address prefix is passed to
+// the net.ListenPacket or net.ListenUDP.
+//
+// c1, err := net.ListenPacket("udp6", "[ff02::]:1024")
+// if err != nil {
+// // error handling
+// }
+// defer c1.Close()
+// c2, err := net.ListenPacket("udp6", "[ff02::]:1024")
+// if err != nil {
+// // error handling
+// }
+// defer c2.Close()
+// p1 := ipv6.NewPacketConn(c1)
+// if err := p1.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::114")}); err != nil {
+// // error handling
+// }
+// p2 := ipv6.NewPacketConn(c2)
+// if err := p2.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::114")}); err != nil {
+// // error handling
+// }
+//
+// Also it is possible for the application to leave or rejoin a
+// multicast group on the network interface.
+//
+// if err := p.LeaveGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::114")}); err != nil {
+// // error handling
+// }
+// if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff01::114")}); err != nil {
+// // error handling
+// }
+//
+// # Source-specific multicasting
+//
+// An application that uses PacketConn on MLDv2 supported platform is
+// able to join source-specific multicast groups.
+// The application may use JoinSourceSpecificGroup and
+// LeaveSourceSpecificGroup for the operation known as "include" mode,
+//
+// ssmgroup := net.UDPAddr{IP: net.ParseIP("ff32::8000:9")}
+// ssmsource := net.UDPAddr{IP: net.ParseIP("fe80::cafe")}
+// if err := p.JoinSourceSpecificGroup(en0, &ssmgroup, &ssmsource); err != nil {
+// // error handling
+// }
+// if err := p.LeaveSourceSpecificGroup(en0, &ssmgroup, &ssmsource); err != nil {
+// // error handling
+// }
+//
+// or JoinGroup, ExcludeSourceSpecificGroup,
+// IncludeSourceSpecificGroup and LeaveGroup for the operation known
+// as "exclude" mode.
+//
+// exclsource := net.UDPAddr{IP: net.ParseIP("fe80::dead")}
+// if err := p.JoinGroup(en0, &ssmgroup); err != nil {
+// // error handling
+// }
+// if err := p.ExcludeSourceSpecificGroup(en0, &ssmgroup, &exclsource); err != nil {
+// // error handling
+// }
+// if err := p.LeaveGroup(en0, &ssmgroup); err != nil {
+// // error handling
+// }
+//
+// Note that it depends on each platform implementation what happens
+// when an application which runs on MLDv2 unsupported platform uses
+// JoinSourceSpecificGroup and LeaveSourceSpecificGroup.
+// In general the platform tries to fall back to conversations using
+// MLDv1 and starts to listen to multicast traffic.
+// In the fallback case, ExcludeSourceSpecificGroup and
+// IncludeSourceSpecificGroup may return an error.
+package ipv6 // import "golang.org/x/net/ipv6"
+
+// BUG(mikio): This package is not implemented on JS, NaCl and Plan 9.
diff --git a/vendor/golang.org/x/net/ipv6/endpoint.go b/vendor/golang.org/x/net/ipv6/endpoint.go
@@ -0,0 +1,127 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+import (
+ "net"
+ "time"
+
+ "golang.org/x/net/internal/socket"
+)
+
+// BUG(mikio): On Windows, the JoinSourceSpecificGroup,
+// LeaveSourceSpecificGroup, ExcludeSourceSpecificGroup and
+// IncludeSourceSpecificGroup methods of PacketConn are not
+// implemented.
+
+// A Conn represents a network endpoint that uses IPv6 transport.
+// It allows to set basic IP-level socket options such as traffic
+// class and hop limit.
+type Conn struct {
+ genericOpt
+}
+
+type genericOpt struct {
+ *socket.Conn
+}
+
+func (c *genericOpt) ok() bool { return c != nil && c.Conn != nil }
+
+// PathMTU returns a path MTU value for the destination associated
+// with the endpoint.
+func (c *Conn) PathMTU() (int, error) {
+ if !c.ok() {
+ return 0, errInvalidConn
+ }
+ so, ok := sockOpts[ssoPathMTU]
+ if !ok {
+ return 0, errNotImplemented
+ }
+ _, mtu, err := so.getMTUInfo(c.Conn)
+ if err != nil {
+ return 0, err
+ }
+ return mtu, nil
+}
+
+// NewConn returns a new Conn.
+func NewConn(c net.Conn) *Conn {
+ cc, _ := socket.NewConn(c)
+ return &Conn{
+ genericOpt: genericOpt{Conn: cc},
+ }
+}
+
+// A PacketConn represents a packet network endpoint that uses IPv6
+// transport. It is used to control several IP-level socket options
+// including IPv6 header manipulation. It also provides datagram
+// based network I/O methods specific to the IPv6 and higher layer
+// protocols such as OSPF, GRE, and UDP.
+type PacketConn struct {
+ genericOpt
+ dgramOpt
+ payloadHandler
+}
+
+type dgramOpt struct {
+ *socket.Conn
+}
+
+func (c *dgramOpt) ok() bool { return c != nil && c.Conn != nil }
+
+// SetControlMessage allows to receive the per packet basis IP-level
+// socket options.
+func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error {
+ if !c.payloadHandler.ok() {
+ return errInvalidConn
+ }
+ return setControlMessage(c.dgramOpt.Conn, &c.payloadHandler.rawOpt, cf, on)
+}
+
+// SetDeadline sets the read and write deadlines associated with the
+// endpoint.
+func (c *PacketConn) SetDeadline(t time.Time) error {
+ if !c.payloadHandler.ok() {
+ return errInvalidConn
+ }
+ return c.payloadHandler.SetDeadline(t)
+}
+
+// SetReadDeadline sets the read deadline associated with the
+// endpoint.
+func (c *PacketConn) SetReadDeadline(t time.Time) error {
+ if !c.payloadHandler.ok() {
+ return errInvalidConn
+ }
+ return c.payloadHandler.SetReadDeadline(t)
+}
+
+// SetWriteDeadline sets the write deadline associated with the
+// endpoint.
+func (c *PacketConn) SetWriteDeadline(t time.Time) error {
+ if !c.payloadHandler.ok() {
+ return errInvalidConn
+ }
+ return c.payloadHandler.SetWriteDeadline(t)
+}
+
+// Close closes the endpoint.
+func (c *PacketConn) Close() error {
+ if !c.payloadHandler.ok() {
+ return errInvalidConn
+ }
+ return c.payloadHandler.Close()
+}
+
+// NewPacketConn returns a new PacketConn using c as its underlying
+// transport.
+func NewPacketConn(c net.PacketConn) *PacketConn {
+ cc, _ := socket.NewConn(c.(net.Conn))
+ return &PacketConn{
+ genericOpt: genericOpt{Conn: cc},
+ dgramOpt: dgramOpt{Conn: cc},
+ payloadHandler: payloadHandler{PacketConn: c, Conn: cc},
+ }
+}
diff --git a/vendor/golang.org/x/net/ipv6/genericopt.go b/vendor/golang.org/x/net/ipv6/genericopt.go
@@ -0,0 +1,56 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+// TrafficClass returns the traffic class field value for outgoing
+// packets.
+func (c *genericOpt) TrafficClass() (int, error) {
+ if !c.ok() {
+ return 0, errInvalidConn
+ }
+ so, ok := sockOpts[ssoTrafficClass]
+ if !ok {
+ return 0, errNotImplemented
+ }
+ return so.GetInt(c.Conn)
+}
+
+// SetTrafficClass sets the traffic class field value for future
+// outgoing packets.
+func (c *genericOpt) SetTrafficClass(tclass int) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoTrafficClass]
+ if !ok {
+ return errNotImplemented
+ }
+ return so.SetInt(c.Conn, tclass)
+}
+
+// HopLimit returns the hop limit field value for outgoing packets.
+func (c *genericOpt) HopLimit() (int, error) {
+ if !c.ok() {
+ return 0, errInvalidConn
+ }
+ so, ok := sockOpts[ssoHopLimit]
+ if !ok {
+ return 0, errNotImplemented
+ }
+ return so.GetInt(c.Conn)
+}
+
+// SetHopLimit sets the hop limit field value for future outgoing
+// packets.
+func (c *genericOpt) SetHopLimit(hoplim int) error {
+ if !c.ok() {
+ return errInvalidConn
+ }
+ so, ok := sockOpts[ssoHopLimit]
+ if !ok {
+ return errNotImplemented
+ }
+ return so.SetInt(c.Conn, hoplim)
+}
diff --git a/vendor/golang.org/x/net/ipv6/header.go b/vendor/golang.org/x/net/ipv6/header.go
@@ -0,0 +1,55 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+import (
+ "encoding/binary"
+ "fmt"
+ "net"
+)
+
+const (
+ Version = 6 // protocol version
+ HeaderLen = 40 // header length
+)
+
+// A Header represents an IPv6 base header.
+type Header struct {
+ Version int // protocol version
+ TrafficClass int // traffic class
+ FlowLabel int // flow label
+ PayloadLen int // payload length
+ NextHeader int // next header
+ HopLimit int // hop limit
+ Src net.IP // source address
+ Dst net.IP // destination address
+}
+
+func (h *Header) String() string {
+ if h == nil {
+ return "<nil>"
+ }
+ return fmt.Sprintf("ver=%d tclass=%#x flowlbl=%#x payloadlen=%d nxthdr=%d hoplim=%d src=%v dst=%v", h.Version, h.TrafficClass, h.FlowLabel, h.PayloadLen, h.NextHeader, h.HopLimit, h.Src, h.Dst)
+}
+
+// ParseHeader parses b as an IPv6 base header.
+func ParseHeader(b []byte) (*Header, error) {
+ if len(b) < HeaderLen {
+ return nil, errHeaderTooShort
+ }
+ h := &Header{
+ Version: int(b[0]) >> 4,
+ TrafficClass: int(b[0]&0x0f)<<4 | int(b[1])>>4,
+ FlowLabel: int(b[1]&0x0f)<<16 | int(b[2])<<8 | int(b[3]),
+ PayloadLen: int(binary.BigEndian.Uint16(b[4:6])),
+ NextHeader: int(b[6]),
+ HopLimit: int(b[7]),
+ }
+ h.Src = make(net.IP, net.IPv6len)
+ copy(h.Src, b[8:24])
+ h.Dst = make(net.IP, net.IPv6len)
+ copy(h.Dst, b[24:40])
+ return h, nil
+}
diff --git a/vendor/golang.org/x/net/ipv6/helper.go b/vendor/golang.org/x/net/ipv6/helper.go
@@ -0,0 +1,58 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+import (
+ "errors"
+ "net"
+ "runtime"
+)
+
+var (
+ errInvalidConn = errors.New("invalid connection")
+ errMissingAddress = errors.New("missing address")
+ errHeaderTooShort = errors.New("header too short")
+ errInvalidConnType = errors.New("invalid conn type")
+ errNotImplemented = errors.New("not implemented on " + runtime.GOOS + "/" + runtime.GOARCH)
+)
+
+func boolint(b bool) int {
+ if b {
+ return 1
+ }
+ return 0
+}
+
+func netAddrToIP16(a net.Addr) net.IP {
+ switch v := a.(type) {
+ case *net.UDPAddr:
+ if ip := v.IP.To16(); ip != nil && ip.To4() == nil {
+ return ip
+ }
+ case *net.IPAddr:
+ if ip := v.IP.To16(); ip != nil && ip.To4() == nil {
+ return ip
+ }
+ }
+ return nil
+}
+
+func opAddr(a net.Addr) net.Addr {
+ switch a.(type) {
+ case *net.TCPAddr:
+ if a == nil {
+ return nil
+ }
+ case *net.UDPAddr:
+ if a == nil {
+ return nil
+ }
+ case *net.IPAddr:
+ if a == nil {
+ return nil
+ }
+ }
+ return a
+}
diff --git a/vendor/golang.org/x/net/ipv6/iana.go b/vendor/golang.org/x/net/ipv6/iana.go
@@ -0,0 +1,86 @@
+// go generate gen.go
+// Code generated by the command above; DO NOT EDIT.
+
+package ipv6
+
+// Internet Control Message Protocol version 6 (ICMPv6) Parameters, Updated: 2018-03-09
+const (
+ ICMPTypeDestinationUnreachable ICMPType = 1 // Destination Unreachable
+ ICMPTypePacketTooBig ICMPType = 2 // Packet Too Big
+ ICMPTypeTimeExceeded ICMPType = 3 // Time Exceeded
+ ICMPTypeParameterProblem ICMPType = 4 // Parameter Problem
+ ICMPTypeEchoRequest ICMPType = 128 // Echo Request
+ ICMPTypeEchoReply ICMPType = 129 // Echo Reply
+ ICMPTypeMulticastListenerQuery ICMPType = 130 // Multicast Listener Query
+ ICMPTypeMulticastListenerReport ICMPType = 131 // Multicast Listener Report
+ ICMPTypeMulticastListenerDone ICMPType = 132 // Multicast Listener Done
+ ICMPTypeRouterSolicitation ICMPType = 133 // Router Solicitation
+ ICMPTypeRouterAdvertisement ICMPType = 134 // Router Advertisement
+ ICMPTypeNeighborSolicitation ICMPType = 135 // Neighbor Solicitation
+ ICMPTypeNeighborAdvertisement ICMPType = 136 // Neighbor Advertisement
+ ICMPTypeRedirect ICMPType = 137 // Redirect Message
+ ICMPTypeRouterRenumbering ICMPType = 138 // Router Renumbering
+ ICMPTypeNodeInformationQuery ICMPType = 139 // ICMP Node Information Query
+ ICMPTypeNodeInformationResponse ICMPType = 140 // ICMP Node Information Response
+ ICMPTypeInverseNeighborDiscoverySolicitation ICMPType = 141 // Inverse Neighbor Discovery Solicitation Message
+ ICMPTypeInverseNeighborDiscoveryAdvertisement ICMPType = 142 // Inverse Neighbor Discovery Advertisement Message
+ ICMPTypeVersion2MulticastListenerReport ICMPType = 143 // Version 2 Multicast Listener Report
+ ICMPTypeHomeAgentAddressDiscoveryRequest ICMPType = 144 // Home Agent Address Discovery Request Message
+ ICMPTypeHomeAgentAddressDiscoveryReply ICMPType = 145 // Home Agent Address Discovery Reply Message
+ ICMPTypeMobilePrefixSolicitation ICMPType = 146 // Mobile Prefix Solicitation
+ ICMPTypeMobilePrefixAdvertisement ICMPType = 147 // Mobile Prefix Advertisement
+ ICMPTypeCertificationPathSolicitation ICMPType = 148 // Certification Path Solicitation Message
+ ICMPTypeCertificationPathAdvertisement ICMPType = 149 // Certification Path Advertisement Message
+ ICMPTypeMulticastRouterAdvertisement ICMPType = 151 // Multicast Router Advertisement
+ ICMPTypeMulticastRouterSolicitation ICMPType = 152 // Multicast Router Solicitation
+ ICMPTypeMulticastRouterTermination ICMPType = 153 // Multicast Router Termination
+ ICMPTypeFMIPv6 ICMPType = 154 // FMIPv6 Messages
+ ICMPTypeRPLControl ICMPType = 155 // RPL Control Message
+ ICMPTypeILNPv6LocatorUpdate ICMPType = 156 // ILNPv6 Locator Update Message
+ ICMPTypeDuplicateAddressRequest ICMPType = 157 // Duplicate Address Request
+ ICMPTypeDuplicateAddressConfirmation ICMPType = 158 // Duplicate Address Confirmation
+ ICMPTypeMPLControl ICMPType = 159 // MPL Control Message
+ ICMPTypeExtendedEchoRequest ICMPType = 160 // Extended Echo Request
+ ICMPTypeExtendedEchoReply ICMPType = 161 // Extended Echo Reply
+)
+
+// Internet Control Message Protocol version 6 (ICMPv6) Parameters, Updated: 2018-03-09
+var icmpTypes = map[ICMPType]string{
+ 1: "destination unreachable",
+ 2: "packet too big",
+ 3: "time exceeded",
+ 4: "parameter problem",
+ 128: "echo request",
+ 129: "echo reply",
+ 130: "multicast listener query",
+ 131: "multicast listener report",
+ 132: "multicast listener done",
+ 133: "router solicitation",
+ 134: "router advertisement",
+ 135: "neighbor solicitation",
+ 136: "neighbor advertisement",
+ 137: "redirect message",
+ 138: "router renumbering",
+ 139: "icmp node information query",
+ 140: "icmp node information response",
+ 141: "inverse neighbor discovery solicitation message",
+ 142: "inverse neighbor discovery advertisement message",
+ 143: "version 2 multicast listener report",
+ 144: "home agent address discovery request message",
+ 145: "home agent address discovery reply message",
+ 146: "mobile prefix solicitation",
+ 147: "mobile prefix advertisement",
+ 148: "certification path solicitation message",
+ 149: "certification path advertisement message",
+ 151: "multicast router advertisement",
+ 152: "multicast router solicitation",
+ 153: "multicast router termination",
+ 154: "fmipv6 messages",
+ 155: "rpl control message",
+ 156: "ilnpv6 locator update message",
+ 157: "duplicate address request",
+ 158: "duplicate address confirmation",
+ 159: "mpl control message",
+ 160: "extended echo request",
+ 161: "extended echo reply",
+}
diff --git a/vendor/golang.org/x/net/ipv6/icmp.go b/vendor/golang.org/x/net/ipv6/icmp.go
@@ -0,0 +1,60 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+import "golang.org/x/net/internal/iana"
+
+// BUG(mikio): On Windows, methods related to ICMPFilter are not
+// implemented.
+
+// An ICMPType represents a type of ICMP message.
+type ICMPType int
+
+func (typ ICMPType) String() string {
+ s, ok := icmpTypes[typ]
+ if !ok {
+ return "<nil>"
+ }
+ return s
+}
+
+// Protocol returns the ICMPv6 protocol number.
+func (typ ICMPType) Protocol() int {
+ return iana.ProtocolIPv6ICMP
+}
+
+// An ICMPFilter represents an ICMP message filter for incoming
+// packets. The filter belongs to a packet delivery path on a host and
+// it cannot interact with forwarding packets or tunnel-outer packets.
+//
+// Note: RFC 8200 defines a reasonable role model. A node means a
+// device that implements IP. A router means a node that forwards IP
+// packets not explicitly addressed to itself, and a host means a node
+// that is not a router.
+type ICMPFilter struct {
+ icmpv6Filter
+}
+
+// Accept accepts incoming ICMP packets including the type field value
+// typ.
+func (f *ICMPFilter) Accept(typ ICMPType) {
+ f.accept(typ)
+}
+
+// Block blocks incoming ICMP packets including the type field value
+// typ.
+func (f *ICMPFilter) Block(typ ICMPType) {
+ f.block(typ)
+}
+
+// SetAll sets the filter action to the filter.
+func (f *ICMPFilter) SetAll(block bool) {
+ f.setAll(block)
+}
+
+// WillBlock reports whether the ICMP type will be blocked.
+func (f *ICMPFilter) WillBlock(typ ICMPType) bool {
+ return f.willBlock(typ)
+}
diff --git a/vendor/golang.org/x/net/ipv6/icmp_bsd.go b/vendor/golang.org/x/net/ipv6/icmp_bsd.go
@@ -0,0 +1,30 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd
+// +build aix darwin dragonfly freebsd netbsd openbsd
+
+package ipv6
+
+func (f *icmpv6Filter) accept(typ ICMPType) {
+ f.Filt[typ>>5] |= 1 << (uint32(typ) & 31)
+}
+
+func (f *icmpv6Filter) block(typ ICMPType) {
+ f.Filt[typ>>5] &^= 1 << (uint32(typ) & 31)
+}
+
+func (f *icmpv6Filter) setAll(block bool) {
+ for i := range f.Filt {
+ if block {
+ f.Filt[i] = 0
+ } else {
+ f.Filt[i] = 1<<32 - 1
+ }
+ }
+}
+
+func (f *icmpv6Filter) willBlock(typ ICMPType) bool {
+ return f.Filt[typ>>5]&(1<<(uint32(typ)&31)) == 0
+}
diff --git a/vendor/golang.org/x/net/ipv6/icmp_linux.go b/vendor/golang.org/x/net/ipv6/icmp_linux.go
@@ -0,0 +1,27 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+func (f *icmpv6Filter) accept(typ ICMPType) {
+ f.Data[typ>>5] &^= 1 << (uint32(typ) & 31)
+}
+
+func (f *icmpv6Filter) block(typ ICMPType) {
+ f.Data[typ>>5] |= 1 << (uint32(typ) & 31)
+}
+
+func (f *icmpv6Filter) setAll(block bool) {
+ for i := range f.Data {
+ if block {
+ f.Data[i] = 1<<32 - 1
+ } else {
+ f.Data[i] = 0
+ }
+ }
+}
+
+func (f *icmpv6Filter) willBlock(typ ICMPType) bool {
+ return f.Data[typ>>5]&(1<<(uint32(typ)&31)) != 0
+}
diff --git a/vendor/golang.org/x/net/ipv6/icmp_solaris.go b/vendor/golang.org/x/net/ipv6/icmp_solaris.go
@@ -0,0 +1,27 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+func (f *icmpv6Filter) accept(typ ICMPType) {
+ f.X__icmp6_filt[typ>>5] |= 1 << (uint32(typ) & 31)
+}
+
+func (f *icmpv6Filter) block(typ ICMPType) {
+ f.X__icmp6_filt[typ>>5] &^= 1 << (uint32(typ) & 31)
+}
+
+func (f *icmpv6Filter) setAll(block bool) {
+ for i := range f.X__icmp6_filt {
+ if block {
+ f.X__icmp6_filt[i] = 0
+ } else {
+ f.X__icmp6_filt[i] = 1<<32 - 1
+ }
+ }
+}
+
+func (f *icmpv6Filter) willBlock(typ ICMPType) bool {
+ return f.X__icmp6_filt[typ>>5]&(1<<(uint32(typ)&31)) == 0
+}
diff --git a/vendor/golang.org/x/net/ipv6/icmp_stub.go b/vendor/golang.org/x/net/ipv6/icmp_stub.go
@@ -0,0 +1,24 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
+
+package ipv6
+
+type icmpv6Filter struct {
+}
+
+func (f *icmpv6Filter) accept(typ ICMPType) {
+}
+
+func (f *icmpv6Filter) block(typ ICMPType) {
+}
+
+func (f *icmpv6Filter) setAll(block bool) {
+}
+
+func (f *icmpv6Filter) willBlock(typ ICMPType) bool {
+ return false
+}
diff --git a/vendor/golang.org/x/net/ipv6/icmp_windows.go b/vendor/golang.org/x/net/ipv6/icmp_windows.go
@@ -0,0 +1,22 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+func (f *icmpv6Filter) accept(typ ICMPType) {
+ // TODO(mikio): implement this
+}
+
+func (f *icmpv6Filter) block(typ ICMPType) {
+ // TODO(mikio): implement this
+}
+
+func (f *icmpv6Filter) setAll(block bool) {
+ // TODO(mikio): implement this
+}
+
+func (f *icmpv6Filter) willBlock(typ ICMPType) bool {
+ // TODO(mikio): implement this
+ return false
+}
diff --git a/vendor/golang.org/x/net/ipv6/icmp_zos.go b/vendor/golang.org/x/net/ipv6/icmp_zos.go
@@ -0,0 +1,29 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+func (f *icmpv6Filter) accept(typ ICMPType) {
+ f.Filt[typ>>5] |= 1 << (uint32(typ) & 31)
+
+}
+
+func (f *icmpv6Filter) block(typ ICMPType) {
+ f.Filt[typ>>5] &^= 1 << (uint32(typ) & 31)
+
+}
+
+func (f *icmpv6Filter) setAll(block bool) {
+ for i := range f.Filt {
+ if block {
+ f.Filt[i] = 0
+ } else {
+ f.Filt[i] = 1<<32 - 1
+ }
+ }
+}
+
+func (f *icmpv6Filter) willBlock(typ ICMPType) bool {
+ return f.Filt[typ>>5]&(1<<(uint32(typ)&31)) == 0
+}
diff --git a/vendor/golang.org/x/net/ipv6/payload.go b/vendor/golang.org/x/net/ipv6/payload.go
@@ -0,0 +1,23 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+import (
+ "net"
+
+ "golang.org/x/net/internal/socket"
+)
+
+// BUG(mikio): On Windows, the ControlMessage for ReadFrom and WriteTo
+// methods of PacketConn is not implemented.
+
+// A payloadHandler represents the IPv6 datagram payload handler.
+type payloadHandler struct {
+ net.PacketConn
+ *socket.Conn
+ rawOpt
+}
+
+func (c *payloadHandler) ok() bool { return c != nil && c.PacketConn != nil && c.Conn != nil }
diff --git a/vendor/golang.org/x/net/ipv6/payload_cmsg.go b/vendor/golang.org/x/net/ipv6/payload_cmsg.go
@@ -0,0 +1,71 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
+
+package ipv6
+
+import (
+ "net"
+
+ "golang.org/x/net/internal/socket"
+)
+
+// ReadFrom reads a payload of the received IPv6 datagram, from the
+// endpoint c, copying the payload into b. It returns the number of
+// bytes copied into b, the control message cm and the source address
+// src of the received datagram.
+func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) {
+ if !c.ok() {
+ return 0, nil, nil, errInvalidConn
+ }
+ c.rawOpt.RLock()
+ m := socket.Message{
+ Buffers: [][]byte{b},
+ OOB: NewControlMessage(c.rawOpt.cflags),
+ }
+ c.rawOpt.RUnlock()
+ switch c.PacketConn.(type) {
+ case *net.UDPConn:
+ if err := c.RecvMsg(&m, 0); err != nil {
+ return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
+ }
+ case *net.IPConn:
+ if err := c.RecvMsg(&m, 0); err != nil {
+ return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
+ }
+ default:
+ return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: errInvalidConnType}
+ }
+ if m.NN > 0 {
+ cm = new(ControlMessage)
+ if err := cm.Parse(m.OOB[:m.NN]); err != nil {
+ return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
+ }
+ cm.Src = netAddrToIP16(m.Addr)
+ }
+ return m.N, cm, m.Addr, nil
+}
+
+// WriteTo writes a payload of the IPv6 datagram, to the destination
+// address dst through the endpoint c, copying the payload from b. It
+// returns the number of bytes written. The control message cm allows
+// the IPv6 header fields and the datagram path to be specified. The
+// cm may be nil if control of the outgoing datagram is not required.
+func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) {
+ if !c.ok() {
+ return 0, errInvalidConn
+ }
+ m := socket.Message{
+ Buffers: [][]byte{b},
+ OOB: cm.Marshal(),
+ Addr: dst,
+ }
+ err = c.SendMsg(&m, 0)
+ if err != nil {
+ err = &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Addr: opAddr(dst), Err: err}
+ }
+ return m.N, err
+}
diff --git a/vendor/golang.org/x/net/ipv6/payload_nocmsg.go b/vendor/golang.org/x/net/ipv6/payload_nocmsg.go
@@ -0,0 +1,39 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
+
+package ipv6
+
+import "net"
+
+// ReadFrom reads a payload of the received IPv6 datagram, from the
+// endpoint c, copying the payload into b. It returns the number of
+// bytes copied into b, the control message cm and the source address
+// src of the received datagram.
+func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) {
+ if !c.ok() {
+ return 0, nil, nil, errInvalidConn
+ }
+ if n, src, err = c.PacketConn.ReadFrom(b); err != nil {
+ return 0, nil, nil, err
+ }
+ return
+}
+
+// WriteTo writes a payload of the IPv6 datagram, to the destination
+// address dst through the endpoint c, copying the payload from b. It
+// returns the number of bytes written. The control message cm allows
+// the IPv6 header fields and the datagram path to be specified. The
+// cm may be nil if control of the outgoing datagram is not required.
+func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) {
+ if !c.ok() {
+ return 0, errInvalidConn
+ }
+ if dst == nil {
+ return 0, errMissingAddress
+ }
+ return c.PacketConn.WriteTo(b, dst)
+}
diff --git a/vendor/golang.org/x/net/ipv6/sockopt.go b/vendor/golang.org/x/net/ipv6/sockopt.go
@@ -0,0 +1,43 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+import "golang.org/x/net/internal/socket"
+
+// Sticky socket options
+const (
+ ssoTrafficClass = iota // header field for unicast packet, RFC 3542
+ ssoHopLimit // header field for unicast packet, RFC 3493
+ ssoMulticastInterface // outbound interface for multicast packet, RFC 3493
+ ssoMulticastHopLimit // header field for multicast packet, RFC 3493
+ ssoMulticastLoopback // loopback for multicast packet, RFC 3493
+ ssoReceiveTrafficClass // header field on received packet, RFC 3542
+ ssoReceiveHopLimit // header field on received packet, RFC 2292 or 3542
+ ssoReceivePacketInfo // incbound or outbound packet path, RFC 2292 or 3542
+ ssoReceivePathMTU // path mtu, RFC 3542
+ ssoPathMTU // path mtu, RFC 3542
+ ssoChecksum // packet checksum, RFC 2292 or 3542
+ ssoICMPFilter // icmp filter, RFC 2292 or 3542
+ ssoJoinGroup // any-source multicast, RFC 3493
+ ssoLeaveGroup // any-source multicast, RFC 3493
+ ssoJoinSourceGroup // source-specific multicast
+ ssoLeaveSourceGroup // source-specific multicast
+ ssoBlockSourceGroup // any-source or source-specific multicast
+ ssoUnblockSourceGroup // any-source or source-specific multicast
+ ssoAttachFilter // attach BPF for filtering inbound traffic
+)
+
+// Sticky socket option value types
+const (
+ ssoTypeIPMreq = iota + 1
+ ssoTypeGroupReq
+ ssoTypeGroupSourceReq
+)
+
+// A sockOpt represents a binding for sticky socket option.
+type sockOpt struct {
+ socket.Option
+ typ int // hint for option value type; optional
+}
diff --git a/vendor/golang.org/x/net/ipv6/sockopt_posix.go b/vendor/golang.org/x/net/ipv6/sockopt_posix.go
@@ -0,0 +1,90 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows zos
+
+package ipv6
+
+import (
+ "net"
+ "runtime"
+ "unsafe"
+
+ "golang.org/x/net/bpf"
+ "golang.org/x/net/internal/socket"
+)
+
+func (so *sockOpt) getMulticastInterface(c *socket.Conn) (*net.Interface, error) {
+ n, err := so.GetInt(c)
+ if err != nil {
+ return nil, err
+ }
+ return net.InterfaceByIndex(n)
+}
+
+func (so *sockOpt) setMulticastInterface(c *socket.Conn, ifi *net.Interface) error {
+ var n int
+ if ifi != nil {
+ n = ifi.Index
+ }
+ return so.SetInt(c, n)
+}
+
+func (so *sockOpt) getICMPFilter(c *socket.Conn) (*ICMPFilter, error) {
+ b := make([]byte, so.Len)
+ n, err := so.Get(c, b)
+ if err != nil {
+ return nil, err
+ }
+ if n != sizeofICMPv6Filter {
+ return nil, errNotImplemented
+ }
+ return (*ICMPFilter)(unsafe.Pointer(&b[0])), nil
+}
+
+func (so *sockOpt) setICMPFilter(c *socket.Conn, f *ICMPFilter) error {
+ b := (*[sizeofICMPv6Filter]byte)(unsafe.Pointer(f))[:sizeofICMPv6Filter]
+ return so.Set(c, b)
+}
+
+func (so *sockOpt) getMTUInfo(c *socket.Conn) (*net.Interface, int, error) {
+ b := make([]byte, so.Len)
+ n, err := so.Get(c, b)
+ if err != nil {
+ return nil, 0, err
+ }
+ if n != sizeofIPv6Mtuinfo {
+ return nil, 0, errNotImplemented
+ }
+ mi := (*ipv6Mtuinfo)(unsafe.Pointer(&b[0]))
+ if mi.Addr.Scope_id == 0 || runtime.GOOS == "aix" {
+ // AIX kernel might return a wrong address.
+ return nil, int(mi.Mtu), nil
+ }
+ ifi, err := net.InterfaceByIndex(int(mi.Addr.Scope_id))
+ if err != nil {
+ return nil, 0, err
+ }
+ return ifi, int(mi.Mtu), nil
+}
+
+func (so *sockOpt) setGroup(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
+ switch so.typ {
+ case ssoTypeIPMreq:
+ return so.setIPMreq(c, ifi, grp)
+ case ssoTypeGroupReq:
+ return so.setGroupReq(c, ifi, grp)
+ default:
+ return errNotImplemented
+ }
+}
+
+func (so *sockOpt) setSourceGroup(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error {
+ return so.setGroupSourceReq(c, ifi, grp, src)
+}
+
+func (so *sockOpt) setBPF(c *socket.Conn, f []bpf.RawInstruction) error {
+ return so.setAttachFilter(c, f)
+}
diff --git a/vendor/golang.org/x/net/ipv6/sockopt_stub.go b/vendor/golang.org/x/net/ipv6/sockopt_stub.go
@@ -0,0 +1,47 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
+
+package ipv6
+
+import (
+ "net"
+
+ "golang.org/x/net/bpf"
+ "golang.org/x/net/internal/socket"
+)
+
+func (so *sockOpt) getMulticastInterface(c *socket.Conn) (*net.Interface, error) {
+ return nil, errNotImplemented
+}
+
+func (so *sockOpt) setMulticastInterface(c *socket.Conn, ifi *net.Interface) error {
+ return errNotImplemented
+}
+
+func (so *sockOpt) getICMPFilter(c *socket.Conn) (*ICMPFilter, error) {
+ return nil, errNotImplemented
+}
+
+func (so *sockOpt) setICMPFilter(c *socket.Conn, f *ICMPFilter) error {
+ return errNotImplemented
+}
+
+func (so *sockOpt) getMTUInfo(c *socket.Conn) (*net.Interface, int, error) {
+ return nil, 0, errNotImplemented
+}
+
+func (so *sockOpt) setGroup(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
+ return errNotImplemented
+}
+
+func (so *sockOpt) setSourceGroup(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error {
+ return errNotImplemented
+}
+
+func (so *sockOpt) setBPF(c *socket.Conn, f []bpf.RawInstruction) error {
+ return errNotImplemented
+}
diff --git a/vendor/golang.org/x/net/ipv6/sys_aix.go b/vendor/golang.org/x/net/ipv6/sys_aix.go
@@ -0,0 +1,80 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Added for go1.11 compatibility
+//go:build aix
+// +build aix
+
+package ipv6
+
+import (
+ "net"
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
+)
+
+var (
+ ctlOpts = [ctlMax]ctlOpt{
+ ctlTrafficClass: {unix.IPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
+ ctlHopLimit: {unix.IPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
+ ctlPacketInfo: {unix.IPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
+ ctlNextHop: {unix.IPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop},
+ ctlPathMTU: {unix.IPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
+ }
+
+ sockOpts = map[int]*sockOpt{
+ ssoTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_TCLASS, Len: 4}},
+ ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_UNICAST_HOPS, Len: 4}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_IF, Len: 4}},
+ ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_HOPS, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_LOOP, Len: 4}},
+ ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVTCLASS, Len: 4}},
+ ssoReceiveHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVHOPLIMIT, Len: 4}},
+ ssoReceivePacketInfo: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPKTINFO, Len: 4}},
+ ssoReceivePathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPATHMTU, Len: 4}},
+ ssoPathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},
+ ssoChecksum: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_CHECKSUM, Len: 4}},
+ ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: unix.ICMP6_FILTER, Len: sizeofICMPv6Filter}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_JOIN_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_LEAVE_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
+ }
+)
+
+func (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {
+ sa.Len = sizeofSockaddrInet6
+ sa.Family = syscall.AF_INET6
+ copy(sa.Addr[:], ip)
+ sa.Scope_id = uint32(i)
+}
+
+func (pi *inet6Pktinfo) setIfindex(i int) {
+ pi.Ifindex = int32(i)
+}
+
+func (mreq *ipv6Mreq) setIfindex(i int) {
+ mreq.Interface = uint32(i)
+}
+
+func (gr *groupReq) setGroup(grp net.IP) {
+ sa := (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gr)) + 4))
+ sa.Len = sizeofSockaddrInet6
+ sa.Family = syscall.AF_INET6
+ copy(sa.Addr[:], grp)
+}
+
+func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {
+ sa := (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 4))
+ sa.Len = sizeofSockaddrInet6
+ sa.Family = syscall.AF_INET6
+ copy(sa.Addr[:], grp)
+ sa = (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 132))
+ sa.Len = sizeofSockaddrInet6
+ sa.Family = syscall.AF_INET6
+ copy(sa.Addr[:], src)
+}
diff --git a/vendor/golang.org/x/net/ipv6/sys_asmreq.go b/vendor/golang.org/x/net/ipv6/sys_asmreq.go
@@ -0,0 +1,25 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
+
+package ipv6
+
+import (
+ "net"
+ "unsafe"
+
+ "golang.org/x/net/internal/socket"
+)
+
+func (so *sockOpt) setIPMreq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
+ var mreq ipv6Mreq
+ copy(mreq.Multiaddr[:], grp)
+ if ifi != nil {
+ mreq.setIfindex(ifi.Index)
+ }
+ b := (*[sizeofIPv6Mreq]byte)(unsafe.Pointer(&mreq))[:sizeofIPv6Mreq]
+ return so.Set(c, b)
+}
diff --git a/vendor/golang.org/x/net/ipv6/sys_asmreq_stub.go b/vendor/golang.org/x/net/ipv6/sys_asmreq_stub.go
@@ -0,0 +1,18 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+
+package ipv6
+
+import (
+ "net"
+
+ "golang.org/x/net/internal/socket"
+)
+
+func (so *sockOpt) setIPMreq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
+ return errNotImplemented
+}
diff --git a/vendor/golang.org/x/net/ipv6/sys_bpf.go b/vendor/golang.org/x/net/ipv6/sys_bpf.go
@@ -0,0 +1,25 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux
+// +build linux
+
+package ipv6
+
+import (
+ "unsafe"
+
+ "golang.org/x/net/bpf"
+ "golang.org/x/net/internal/socket"
+ "golang.org/x/sys/unix"
+)
+
+func (so *sockOpt) setAttachFilter(c *socket.Conn, f []bpf.RawInstruction) error {
+ prog := unix.SockFprog{
+ Len: uint16(len(f)),
+ Filter: (*unix.SockFilter)(unsafe.Pointer(&f[0])),
+ }
+ b := (*[unix.SizeofSockFprog]byte)(unsafe.Pointer(&prog))[:unix.SizeofSockFprog]
+ return so.Set(c, b)
+}
diff --git a/vendor/golang.org/x/net/ipv6/sys_bpf_stub.go b/vendor/golang.org/x/net/ipv6/sys_bpf_stub.go
@@ -0,0 +1,17 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !linux
+// +build !linux
+
+package ipv6
+
+import (
+ "golang.org/x/net/bpf"
+ "golang.org/x/net/internal/socket"
+)
+
+func (so *sockOpt) setAttachFilter(c *socket.Conn, f []bpf.RawInstruction) error {
+ return errNotImplemented
+}
diff --git a/vendor/golang.org/x/net/ipv6/sys_bsd.go b/vendor/golang.org/x/net/ipv6/sys_bsd.go
@@ -0,0 +1,60 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build dragonfly || netbsd || openbsd
+// +build dragonfly netbsd openbsd
+
+package ipv6
+
+import (
+ "net"
+ "syscall"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
+)
+
+var (
+ ctlOpts = [ctlMax]ctlOpt{
+ ctlTrafficClass: {unix.IPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
+ ctlHopLimit: {unix.IPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
+ ctlPacketInfo: {unix.IPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
+ ctlNextHop: {unix.IPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop},
+ ctlPathMTU: {unix.IPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
+ }
+
+ sockOpts = map[int]*sockOpt{
+ ssoTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_TCLASS, Len: 4}},
+ ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_UNICAST_HOPS, Len: 4}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_IF, Len: 4}},
+ ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_HOPS, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_LOOP, Len: 4}},
+ ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVTCLASS, Len: 4}},
+ ssoReceiveHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVHOPLIMIT, Len: 4}},
+ ssoReceivePacketInfo: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPKTINFO, Len: 4}},
+ ssoReceivePathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPATHMTU, Len: 4}},
+ ssoPathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},
+ ssoChecksum: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_CHECKSUM, Len: 4}},
+ ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: unix.ICMP6_FILTER, Len: sizeofICMPv6Filter}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_JOIN_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_LEAVE_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
+ }
+)
+
+func (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {
+ sa.Len = sizeofSockaddrInet6
+ sa.Family = syscall.AF_INET6
+ copy(sa.Addr[:], ip)
+ sa.Scope_id = uint32(i)
+}
+
+func (pi *inet6Pktinfo) setIfindex(i int) {
+ pi.Ifindex = uint32(i)
+}
+
+func (mreq *ipv6Mreq) setIfindex(i int) {
+ mreq.Interface = uint32(i)
+}
diff --git a/vendor/golang.org/x/net/ipv6/sys_darwin.go b/vendor/golang.org/x/net/ipv6/sys_darwin.go
@@ -0,0 +1,80 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+import (
+ "net"
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
+)
+
+var (
+ ctlOpts = [ctlMax]ctlOpt{
+ ctlTrafficClass: {unix.IPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
+ ctlHopLimit: {unix.IPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
+ ctlPacketInfo: {unix.IPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
+ ctlNextHop: {unix.IPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop},
+ ctlPathMTU: {unix.IPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
+ }
+
+ sockOpts = map[int]*sockOpt{
+ ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_UNICAST_HOPS, Len: 4}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_IF, Len: 4}},
+ ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_HOPS, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_LOOP, Len: 4}},
+ ssoTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_TCLASS, Len: 4}},
+ ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVTCLASS, Len: 4}},
+ ssoReceiveHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVHOPLIMIT, Len: 4}},
+ ssoReceivePacketInfo: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPKTINFO, Len: 4}},
+ ssoReceivePathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPATHMTU, Len: 4}},
+ ssoPathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},
+ ssoChecksum: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_CHECKSUM, Len: 4}},
+ ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: unix.ICMP6_FILTER, Len: sizeofICMPv6Filter}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ }
+)
+
+func (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {
+ sa.Len = sizeofSockaddrInet6
+ sa.Family = syscall.AF_INET6
+ copy(sa.Addr[:], ip)
+ sa.Scope_id = uint32(i)
+}
+
+func (pi *inet6Pktinfo) setIfindex(i int) {
+ pi.Ifindex = uint32(i)
+}
+
+func (mreq *ipv6Mreq) setIfindex(i int) {
+ mreq.Interface = uint32(i)
+}
+
+func (gr *groupReq) setGroup(grp net.IP) {
+ sa := (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gr)) + 4))
+ sa.Len = sizeofSockaddrInet6
+ sa.Family = syscall.AF_INET6
+ copy(sa.Addr[:], grp)
+}
+
+func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {
+ sa := (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 4))
+ sa.Len = sizeofSockaddrInet6
+ sa.Family = syscall.AF_INET6
+ copy(sa.Addr[:], grp)
+ sa = (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 132))
+ sa.Len = sizeofSockaddrInet6
+ sa.Family = syscall.AF_INET6
+ copy(sa.Addr[:], src)
+}
diff --git a/vendor/golang.org/x/net/ipv6/sys_freebsd.go b/vendor/golang.org/x/net/ipv6/sys_freebsd.go
@@ -0,0 +1,94 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+import (
+ "net"
+ "runtime"
+ "strings"
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
+)
+
+var (
+ ctlOpts = [ctlMax]ctlOpt{
+ ctlTrafficClass: {unix.IPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
+ ctlHopLimit: {unix.IPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
+ ctlPacketInfo: {unix.IPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
+ ctlNextHop: {unix.IPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop},
+ ctlPathMTU: {unix.IPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
+ }
+
+ sockOpts = map[int]sockOpt{
+ ssoTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_TCLASS, Len: 4}},
+ ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_UNICAST_HOPS, Len: 4}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_IF, Len: 4}},
+ ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_HOPS, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_LOOP, Len: 4}},
+ ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVTCLASS, Len: 4}},
+ ssoReceiveHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVHOPLIMIT, Len: 4}},
+ ssoReceivePacketInfo: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPKTINFO, Len: 4}},
+ ssoReceivePathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPATHMTU, Len: 4}},
+ ssoPathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},
+ ssoChecksum: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_CHECKSUM, Len: 4}},
+ ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: unix.ICMP6_FILTER, Len: sizeofICMPv6Filter}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ }
+)
+
+func init() {
+ if runtime.GOOS == "freebsd" && runtime.GOARCH == "386" {
+ archs, _ := syscall.Sysctl("kern.supported_archs")
+ for _, s := range strings.Fields(archs) {
+ if s == "amd64" {
+ compatFreeBSD32 = true
+ break
+ }
+ }
+ }
+}
+
+func (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {
+ sa.Len = sizeofSockaddrInet6
+ sa.Family = syscall.AF_INET6
+ copy(sa.Addr[:], ip)
+ sa.Scope_id = uint32(i)
+}
+
+func (pi *inet6Pktinfo) setIfindex(i int) {
+ pi.Ifindex = uint32(i)
+}
+
+func (mreq *ipv6Mreq) setIfindex(i int) {
+ mreq.Interface = uint32(i)
+}
+
+func (gr *groupReq) setGroup(grp net.IP) {
+ sa := (*sockaddrInet6)(unsafe.Pointer(&gr.Group))
+ sa.Len = sizeofSockaddrInet6
+ sa.Family = syscall.AF_INET6
+ copy(sa.Addr[:], grp)
+}
+
+func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {
+ sa := (*sockaddrInet6)(unsafe.Pointer(&gsr.Group))
+ sa.Len = sizeofSockaddrInet6
+ sa.Family = syscall.AF_INET6
+ copy(sa.Addr[:], grp)
+ sa = (*sockaddrInet6)(unsafe.Pointer(&gsr.Source))
+ sa.Len = sizeofSockaddrInet6
+ sa.Family = syscall.AF_INET6
+ copy(sa.Addr[:], src)
+}
diff --git a/vendor/golang.org/x/net/ipv6/sys_linux.go b/vendor/golang.org/x/net/ipv6/sys_linux.go
@@ -0,0 +1,76 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+import (
+ "net"
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
+)
+
+var (
+ ctlOpts = [ctlMax]ctlOpt{
+ ctlTrafficClass: {unix.IPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
+ ctlHopLimit: {unix.IPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
+ ctlPacketInfo: {unix.IPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
+ ctlPathMTU: {unix.IPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
+ }
+
+ sockOpts = map[int]*sockOpt{
+ ssoTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_TCLASS, Len: 4}},
+ ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_UNICAST_HOPS, Len: 4}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_IF, Len: 4}},
+ ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_HOPS, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_LOOP, Len: 4}},
+ ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVTCLASS, Len: 4}},
+ ssoReceiveHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVHOPLIMIT, Len: 4}},
+ ssoReceivePacketInfo: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPKTINFO, Len: 4}},
+ ssoReceivePathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPATHMTU, Len: 4}},
+ ssoPathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},
+ ssoChecksum: {Option: socket.Option{Level: iana.ProtocolReserved, Name: unix.IPV6_CHECKSUM, Len: 4}},
+ ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: unix.ICMPV6_FILTER, Len: sizeofICMPv6Filter}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoAttachFilter: {Option: socket.Option{Level: unix.SOL_SOCKET, Name: unix.SO_ATTACH_FILTER, Len: unix.SizeofSockFprog}},
+ }
+)
+
+func (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {
+ sa.Family = syscall.AF_INET6
+ copy(sa.Addr[:], ip)
+ sa.Scope_id = uint32(i)
+}
+
+func (pi *inet6Pktinfo) setIfindex(i int) {
+ pi.Ifindex = int32(i)
+}
+
+func (mreq *ipv6Mreq) setIfindex(i int) {
+ mreq.Ifindex = int32(i)
+}
+
+func (gr *groupReq) setGroup(grp net.IP) {
+ sa := (*sockaddrInet6)(unsafe.Pointer(&gr.Group))
+ sa.Family = syscall.AF_INET6
+ copy(sa.Addr[:], grp)
+}
+
+func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {
+ sa := (*sockaddrInet6)(unsafe.Pointer(&gsr.Group))
+ sa.Family = syscall.AF_INET6
+ copy(sa.Addr[:], grp)
+ sa = (*sockaddrInet6)(unsafe.Pointer(&gsr.Source))
+ sa.Family = syscall.AF_INET6
+ copy(sa.Addr[:], src)
+}
diff --git a/vendor/golang.org/x/net/ipv6/sys_solaris.go b/vendor/golang.org/x/net/ipv6/sys_solaris.go
@@ -0,0 +1,76 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+import (
+ "net"
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
+)
+
+var (
+ ctlOpts = [ctlMax]ctlOpt{
+ ctlTrafficClass: {unix.IPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
+ ctlHopLimit: {unix.IPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
+ ctlPacketInfo: {unix.IPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
+ ctlNextHop: {unix.IPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop},
+ ctlPathMTU: {unix.IPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
+ }
+
+ sockOpts = map[int]*sockOpt{
+ ssoTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_TCLASS, Len: 4}},
+ ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_UNICAST_HOPS, Len: 4}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_IF, Len: 4}},
+ ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_HOPS, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_LOOP, Len: 4}},
+ ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVTCLASS, Len: 4}},
+ ssoReceiveHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVHOPLIMIT, Len: 4}},
+ ssoReceivePacketInfo: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPKTINFO, Len: 4}},
+ ssoReceivePathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPATHMTU, Len: 4}},
+ ssoPathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},
+ ssoChecksum: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_CHECKSUM, Len: 4}},
+ ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: unix.ICMP6_FILTER, Len: sizeofICMPv6Filter}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ }
+)
+
+func (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {
+ sa.Family = syscall.AF_INET6
+ copy(sa.Addr[:], ip)
+ sa.Scope_id = uint32(i)
+}
+
+func (pi *inet6Pktinfo) setIfindex(i int) {
+ pi.Ifindex = uint32(i)
+}
+
+func (mreq *ipv6Mreq) setIfindex(i int) {
+ mreq.Interface = uint32(i)
+}
+
+func (gr *groupReq) setGroup(grp net.IP) {
+ sa := (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gr)) + 4))
+ sa.Family = syscall.AF_INET6
+ copy(sa.Addr[:], grp)
+}
+
+func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {
+ sa := (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 4))
+ sa.Family = syscall.AF_INET6
+ copy(sa.Addr[:], grp)
+ sa = (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 260))
+ sa.Family = syscall.AF_INET6
+ copy(sa.Addr[:], src)
+}
diff --git a/vendor/golang.org/x/net/ipv6/sys_ssmreq.go b/vendor/golang.org/x/net/ipv6/sys_ssmreq.go
@@ -0,0 +1,55 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || freebsd || linux || solaris || zos
+// +build aix darwin freebsd linux solaris zos
+
+package ipv6
+
+import (
+ "net"
+ "unsafe"
+
+ "golang.org/x/net/internal/socket"
+)
+
+var compatFreeBSD32 bool // 386 emulation on amd64
+
+func (so *sockOpt) setGroupReq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
+ var gr groupReq
+ if ifi != nil {
+ gr.Interface = uint32(ifi.Index)
+ }
+ gr.setGroup(grp)
+ var b []byte
+ if compatFreeBSD32 {
+ var d [sizeofGroupReq + 4]byte
+ s := (*[sizeofGroupReq]byte)(unsafe.Pointer(&gr))
+ copy(d[:4], s[:4])
+ copy(d[8:], s[4:])
+ b = d[:]
+ } else {
+ b = (*[sizeofGroupReq]byte)(unsafe.Pointer(&gr))[:sizeofGroupReq]
+ }
+ return so.Set(c, b)
+}
+
+func (so *sockOpt) setGroupSourceReq(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error {
+ var gsr groupSourceReq
+ if ifi != nil {
+ gsr.Interface = uint32(ifi.Index)
+ }
+ gsr.setSourceGroup(grp, src)
+ var b []byte
+ if compatFreeBSD32 {
+ var d [sizeofGroupSourceReq + 4]byte
+ s := (*[sizeofGroupSourceReq]byte)(unsafe.Pointer(&gsr))
+ copy(d[:4], s[:4])
+ copy(d[8:], s[4:])
+ b = d[:]
+ } else {
+ b = (*[sizeofGroupSourceReq]byte)(unsafe.Pointer(&gsr))[:sizeofGroupSourceReq]
+ }
+ return so.Set(c, b)
+}
diff --git a/vendor/golang.org/x/net/ipv6/sys_ssmreq_stub.go b/vendor/golang.org/x/net/ipv6/sys_ssmreq_stub.go
@@ -0,0 +1,22 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !aix && !darwin && !freebsd && !linux && !solaris && !zos
+// +build !aix,!darwin,!freebsd,!linux,!solaris,!zos
+
+package ipv6
+
+import (
+ "net"
+
+ "golang.org/x/net/internal/socket"
+)
+
+func (so *sockOpt) setGroupReq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
+ return errNotImplemented
+}
+
+func (so *sockOpt) setGroupSourceReq(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error {
+ return errNotImplemented
+}
diff --git a/vendor/golang.org/x/net/ipv6/sys_stub.go b/vendor/golang.org/x/net/ipv6/sys_stub.go
@@ -0,0 +1,14 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
+
+package ipv6
+
+var (
+ ctlOpts = [ctlMax]ctlOpt{}
+
+ sockOpts = map[int]*sockOpt{}
+)
diff --git a/vendor/golang.org/x/net/ipv6/sys_windows.go b/vendor/golang.org/x/net/ipv6/sys_windows.go
@@ -0,0 +1,68 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+import (
+ "net"
+ "syscall"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/windows"
+)
+
+const (
+ sizeofSockaddrInet6 = 0x1c
+
+ sizeofIPv6Mreq = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+ sizeofICMPv6Filter = 0
+)
+
+type sockaddrInet6 struct {
+ Family uint16
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Interface uint32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type icmpv6Filter struct {
+ // TODO(mikio): implement this
+}
+
+var (
+ ctlOpts = [ctlMax]ctlOpt{}
+
+ sockOpts = map[int]*sockOpt{
+ ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: windows.IPV6_UNICAST_HOPS, Len: 4}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: windows.IPV6_MULTICAST_IF, Len: 4}},
+ ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: windows.IPV6_MULTICAST_HOPS, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: windows.IPV6_MULTICAST_LOOP, Len: 4}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: windows.IPV6_JOIN_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: windows.IPV6_LEAVE_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
+ }
+)
+
+func (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {
+ sa.Family = syscall.AF_INET6
+ copy(sa.Addr[:], ip)
+ sa.Scope_id = uint32(i)
+}
+
+func (mreq *ipv6Mreq) setIfindex(i int) {
+ mreq.Interface = uint32(i)
+}
diff --git a/vendor/golang.org/x/net/ipv6/sys_zos.go b/vendor/golang.org/x/net/ipv6/sys_zos.go
@@ -0,0 +1,72 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+import (
+ "net"
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
+)
+
+var (
+ ctlOpts = [ctlMax]ctlOpt{
+ ctlHopLimit: {unix.IPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
+ ctlPacketInfo: {unix.IPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
+ ctlPathMTU: {unix.IPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
+ }
+
+ sockOpts = map[int]*sockOpt{
+ ssoTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_TCLASS, Len: 4}},
+ ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_UNICAST_HOPS, Len: 4}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_IF, Len: 4}},
+ ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_HOPS, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_LOOP, Len: 4}},
+ ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVTCLASS, Len: 4}},
+ ssoReceiveHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVHOPLIMIT, Len: 4}},
+ ssoReceivePacketInfo: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPKTINFO, Len: 4}},
+ ssoReceivePathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPATHMTU, Len: 4}},
+ ssoChecksum: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_CHECKSUM, Len: 4}},
+ ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: unix.ICMP6_FILTER, Len: sizeofICMPv6Filter}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ }
+)
+
+func (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {
+ sa.Family = syscall.AF_INET6
+ copy(sa.Addr[:], ip)
+ sa.Scope_id = uint32(i)
+}
+
+func (pi *inet6Pktinfo) setIfindex(i int) {
+ pi.Ifindex = uint32(i)
+}
+
+func (gr *groupReq) setGroup(grp net.IP) {
+ sa := (*sockaddrInet6)(unsafe.Pointer(&gr.Group))
+ sa.Family = syscall.AF_INET6
+ sa.Len = sizeofSockaddrInet6
+ copy(sa.Addr[:], grp)
+}
+
+func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {
+ sa := (*sockaddrInet6)(unsafe.Pointer(&gsr.Group))
+ sa.Family = syscall.AF_INET6
+ sa.Len = sizeofSockaddrInet6
+ copy(sa.Addr[:], grp)
+ sa = (*sockaddrInet6)(unsafe.Pointer(&gsr.Source))
+ sa.Family = syscall.AF_INET6
+ sa.Len = sizeofSockaddrInet6
+ copy(sa.Addr[:], src)
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_aix_ppc64.go b/vendor/golang.org/x/net/ipv6/zsys_aix_ppc64.go
@@ -0,0 +1,69 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_aix.go
+
+// Added for go1.11 compatibility
+//go:build aix
+// +build aix
+
+package ipv6
+
+const (
+ sizeofSockaddrStorage = 0x508
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+
+ sizeofIPv6Mreq = 0x14
+ sizeofGroupReq = 0x510
+ sizeofGroupSourceReq = 0xa18
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type sockaddrStorage struct {
+ X__ss_len uint8
+ Family uint8
+ X__ss_pad1 [6]uint8
+ X__ss_align int64
+ X__ss_pad2 [1265]uint8
+ Pad_cgo_0 [7]byte
+}
+
+type sockaddrInet6 struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Interface uint32
+}
+
+type icmpv6Filter struct {
+ Filt [8]uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ Group sockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Group sockaddrStorage
+ Source sockaddrStorage
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_darwin.go b/vendor/golang.org/x/net/ipv6/zsys_darwin.go
@@ -0,0 +1,64 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_darwin.go
+
+package ipv6
+
+const (
+ sizeofSockaddrStorage = 0x80
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+
+ sizeofIPv6Mreq = 0x14
+ sizeofGroupReq = 0x84
+ sizeofGroupSourceReq = 0x104
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type sockaddrStorage struct {
+ Len uint8
+ Family uint8
+ X__ss_pad1 [6]int8
+ X__ss_align int64
+ X__ss_pad2 [112]int8
+}
+
+type sockaddrInet6 struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex uint32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Interface uint32
+}
+
+type icmpv6Filter struct {
+ Filt [8]uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [128]byte
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [128]byte
+ Pad_cgo_1 [128]byte
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_dragonfly.go b/vendor/golang.org/x/net/ipv6/zsys_dragonfly.go
@@ -0,0 +1,42 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_dragonfly.go
+
+package ipv6
+
+const (
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+
+ sizeofIPv6Mreq = 0x14
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type sockaddrInet6 struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex uint32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Interface uint32
+}
+
+type icmpv6Filter struct {
+ Filt [8]uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_freebsd_386.go b/vendor/golang.org/x/net/ipv6/zsys_freebsd_386.go
@@ -0,0 +1,64 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_freebsd.go
+
+package ipv6
+
+const (
+ sizeofSockaddrStorage = 0x80
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+
+ sizeofIPv6Mreq = 0x14
+ sizeofGroupReq = 0x84
+ sizeofGroupSourceReq = 0x104
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type sockaddrStorage struct {
+ Len uint8
+ Family uint8
+ X__ss_pad1 [6]int8
+ X__ss_align int64
+ X__ss_pad2 [112]int8
+}
+
+type sockaddrInet6 struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex uint32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Interface uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ Group sockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Group sockaddrStorage
+ Source sockaddrStorage
+}
+
+type icmpv6Filter struct {
+ Filt [8]uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_freebsd_amd64.go b/vendor/golang.org/x/net/ipv6/zsys_freebsd_amd64.go
@@ -0,0 +1,66 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_freebsd.go
+
+package ipv6
+
+const (
+ sizeofSockaddrStorage = 0x80
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+
+ sizeofIPv6Mreq = 0x14
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type sockaddrStorage struct {
+ Len uint8
+ Family uint8
+ X__ss_pad1 [6]int8
+ X__ss_align int64
+ X__ss_pad2 [112]int8
+}
+
+type sockaddrInet6 struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex uint32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Interface uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group sockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group sockaddrStorage
+ Source sockaddrStorage
+}
+
+type icmpv6Filter struct {
+ Filt [8]uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_freebsd_arm.go b/vendor/golang.org/x/net/ipv6/zsys_freebsd_arm.go
@@ -0,0 +1,66 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_freebsd.go
+
+package ipv6
+
+const (
+ sizeofSockaddrStorage = 0x80
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+
+ sizeofIPv6Mreq = 0x14
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type sockaddrStorage struct {
+ Len uint8
+ Family uint8
+ X__ss_pad1 [6]int8
+ X__ss_align int64
+ X__ss_pad2 [112]int8
+}
+
+type sockaddrInet6 struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex uint32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Interface uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group sockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group sockaddrStorage
+ Source sockaddrStorage
+}
+
+type icmpv6Filter struct {
+ Filt [8]uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_freebsd_arm64.go b/vendor/golang.org/x/net/ipv6/zsys_freebsd_arm64.go
@@ -0,0 +1,64 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_freebsd.go
+
+package ipv6
+
+const (
+ sizeofSockaddrStorage = 0x80
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+
+ sizeofIPv6Mreq = 0x14
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type sockaddrStorage struct {
+ Len uint8
+ Family uint8
+ X__ss_pad1 [6]uint8
+ X__ss_align int64
+ X__ss_pad2 [112]uint8
+}
+
+type sockaddrInet6 struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex uint32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Interface uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ Group sockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Group sockaddrStorage
+ Source sockaddrStorage
+}
+
+type icmpv6Filter struct {
+ Filt [8]uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_386.go b/vendor/golang.org/x/net/ipv6/zsys_linux_386.go
@@ -0,0 +1,72 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package ipv6
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+ sizeofIPv6FlowlabelReq = 0x20
+
+ sizeofIPv6Mreq = 0x14
+ sizeofGroupReq = 0x84
+ sizeofGroupSourceReq = 0x104
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet6 struct {
+ Family uint16
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6FlowlabelReq struct {
+ Dst [16]byte /* in6_addr */
+ Label uint32
+ Action uint8
+ Share uint8
+ Flags uint16
+ Expires uint16
+ Linger uint16
+ X__flr_pad uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type groupReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpv6Filter struct {
+ Data [8]uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_amd64.go b/vendor/golang.org/x/net/ipv6/zsys_linux_amd64.go
@@ -0,0 +1,74 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package ipv6
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+ sizeofIPv6FlowlabelReq = 0x20
+
+ sizeofIPv6Mreq = 0x14
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet6 struct {
+ Family uint16
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6FlowlabelReq struct {
+ Dst [16]byte /* in6_addr */
+ Label uint32
+ Action uint8
+ Share uint8
+ Flags uint16
+ Expires uint16
+ Linger uint16
+ X__flr_pad uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpv6Filter struct {
+ Data [8]uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_arm.go b/vendor/golang.org/x/net/ipv6/zsys_linux_arm.go
@@ -0,0 +1,72 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package ipv6
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+ sizeofIPv6FlowlabelReq = 0x20
+
+ sizeofIPv6Mreq = 0x14
+ sizeofGroupReq = 0x84
+ sizeofGroupSourceReq = 0x104
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet6 struct {
+ Family uint16
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6FlowlabelReq struct {
+ Dst [16]byte /* in6_addr */
+ Label uint32
+ Action uint8
+ Share uint8
+ Flags uint16
+ Expires uint16
+ Linger uint16
+ X__flr_pad uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type groupReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpv6Filter struct {
+ Data [8]uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_arm64.go b/vendor/golang.org/x/net/ipv6/zsys_linux_arm64.go
@@ -0,0 +1,74 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package ipv6
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+ sizeofIPv6FlowlabelReq = 0x20
+
+ sizeofIPv6Mreq = 0x14
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet6 struct {
+ Family uint16
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6FlowlabelReq struct {
+ Dst [16]byte /* in6_addr */
+ Label uint32
+ Action uint8
+ Share uint8
+ Flags uint16
+ Expires uint16
+ Linger uint16
+ X__flr_pad uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpv6Filter struct {
+ Data [8]uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_loong64.go b/vendor/golang.org/x/net/ipv6/zsys_linux_loong64.go
@@ -0,0 +1,77 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+//go:build loong64
+// +build loong64
+
+package ipv6
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+ sizeofIPv6FlowlabelReq = 0x20
+
+ sizeofIPv6Mreq = 0x14
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet6 struct {
+ Family uint16
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6FlowlabelReq struct {
+ Dst [16]byte /* in6_addr */
+ Label uint32
+ Action uint8
+ Share uint8
+ Flags uint16
+ Expires uint16
+ Linger uint16
+ X__flr_pad uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpv6Filter struct {
+ Data [8]uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_mips.go b/vendor/golang.org/x/net/ipv6/zsys_linux_mips.go
@@ -0,0 +1,72 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package ipv6
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+ sizeofIPv6FlowlabelReq = 0x20
+
+ sizeofIPv6Mreq = 0x14
+ sizeofGroupReq = 0x84
+ sizeofGroupSourceReq = 0x104
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet6 struct {
+ Family uint16
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6FlowlabelReq struct {
+ Dst [16]byte /* in6_addr */
+ Label uint32
+ Action uint8
+ Share uint8
+ Flags uint16
+ Expires uint16
+ Linger uint16
+ X__flr_pad uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type groupReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpv6Filter struct {
+ Data [8]uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_mips64.go b/vendor/golang.org/x/net/ipv6/zsys_linux_mips64.go
@@ -0,0 +1,74 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package ipv6
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+ sizeofIPv6FlowlabelReq = 0x20
+
+ sizeofIPv6Mreq = 0x14
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet6 struct {
+ Family uint16
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6FlowlabelReq struct {
+ Dst [16]byte /* in6_addr */
+ Label uint32
+ Action uint8
+ Share uint8
+ Flags uint16
+ Expires uint16
+ Linger uint16
+ X__flr_pad uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpv6Filter struct {
+ Data [8]uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_mips64le.go b/vendor/golang.org/x/net/ipv6/zsys_linux_mips64le.go
@@ -0,0 +1,74 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package ipv6
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+ sizeofIPv6FlowlabelReq = 0x20
+
+ sizeofIPv6Mreq = 0x14
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet6 struct {
+ Family uint16
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6FlowlabelReq struct {
+ Dst [16]byte /* in6_addr */
+ Label uint32
+ Action uint8
+ Share uint8
+ Flags uint16
+ Expires uint16
+ Linger uint16
+ X__flr_pad uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpv6Filter struct {
+ Data [8]uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_mipsle.go b/vendor/golang.org/x/net/ipv6/zsys_linux_mipsle.go
@@ -0,0 +1,72 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package ipv6
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+ sizeofIPv6FlowlabelReq = 0x20
+
+ sizeofIPv6Mreq = 0x14
+ sizeofGroupReq = 0x84
+ sizeofGroupSourceReq = 0x104
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet6 struct {
+ Family uint16
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6FlowlabelReq struct {
+ Dst [16]byte /* in6_addr */
+ Label uint32
+ Action uint8
+ Share uint8
+ Flags uint16
+ Expires uint16
+ Linger uint16
+ X__flr_pad uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type groupReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpv6Filter struct {
+ Data [8]uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_ppc.go b/vendor/golang.org/x/net/ipv6/zsys_linux_ppc.go
@@ -0,0 +1,72 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package ipv6
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+ sizeofIPv6FlowlabelReq = 0x20
+
+ sizeofIPv6Mreq = 0x14
+ sizeofGroupReq = 0x84
+ sizeofGroupSourceReq = 0x104
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]uint8
+}
+
+type sockaddrInet6 struct {
+ Family uint16
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6FlowlabelReq struct {
+ Dst [16]byte /* in6_addr */
+ Label uint32
+ Action uint8
+ Share uint8
+ Flags uint16
+ Expires uint16
+ Linger uint16
+ X__flr_pad uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type groupReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpv6Filter struct {
+ Data [8]uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_ppc64.go b/vendor/golang.org/x/net/ipv6/zsys_linux_ppc64.go
@@ -0,0 +1,74 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package ipv6
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+ sizeofIPv6FlowlabelReq = 0x20
+
+ sizeofIPv6Mreq = 0x14
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet6 struct {
+ Family uint16
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6FlowlabelReq struct {
+ Dst [16]byte /* in6_addr */
+ Label uint32
+ Action uint8
+ Share uint8
+ Flags uint16
+ Expires uint16
+ Linger uint16
+ X__flr_pad uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpv6Filter struct {
+ Data [8]uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_ppc64le.go b/vendor/golang.org/x/net/ipv6/zsys_linux_ppc64le.go
@@ -0,0 +1,74 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package ipv6
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+ sizeofIPv6FlowlabelReq = 0x20
+
+ sizeofIPv6Mreq = 0x14
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet6 struct {
+ Family uint16
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6FlowlabelReq struct {
+ Dst [16]byte /* in6_addr */
+ Label uint32
+ Action uint8
+ Share uint8
+ Flags uint16
+ Expires uint16
+ Linger uint16
+ X__flr_pad uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpv6Filter struct {
+ Data [8]uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_riscv64.go b/vendor/golang.org/x/net/ipv6/zsys_linux_riscv64.go
@@ -0,0 +1,77 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+//go:build riscv64
+// +build riscv64
+
+package ipv6
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+ sizeofIPv6FlowlabelReq = 0x20
+
+ sizeofIPv6Mreq = 0x14
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet6 struct {
+ Family uint16
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6FlowlabelReq struct {
+ Dst [16]byte /* in6_addr */
+ Label uint32
+ Action uint8
+ Share uint8
+ Flags uint16
+ Expires uint16
+ Linger uint16
+ X__flr_pad uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpv6Filter struct {
+ Data [8]uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_s390x.go b/vendor/golang.org/x/net/ipv6/zsys_linux_s390x.go
@@ -0,0 +1,74 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package ipv6
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+ sizeofIPv6FlowlabelReq = 0x20
+
+ sizeofIPv6Mreq = 0x14
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet6 struct {
+ Family uint16
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6FlowlabelReq struct {
+ Dst [16]byte /* in6_addr */
+ Label uint32
+ Action uint8
+ Share uint8
+ Flags uint16
+ Expires uint16
+ Linger uint16
+ X__flr_pad uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpv6Filter struct {
+ Data [8]uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_netbsd.go b/vendor/golang.org/x/net/ipv6/zsys_netbsd.go
@@ -0,0 +1,42 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_netbsd.go
+
+package ipv6
+
+const (
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+
+ sizeofIPv6Mreq = 0x14
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type sockaddrInet6 struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex uint32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Interface uint32
+}
+
+type icmpv6Filter struct {
+ Filt [8]uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_openbsd.go b/vendor/golang.org/x/net/ipv6/zsys_openbsd.go
@@ -0,0 +1,42 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_openbsd.go
+
+package ipv6
+
+const (
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+
+ sizeofIPv6Mreq = 0x14
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type sockaddrInet6 struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex uint32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Interface uint32
+}
+
+type icmpv6Filter struct {
+ Filt [8]uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_solaris.go b/vendor/golang.org/x/net/ipv6/zsys_solaris.go
@@ -0,0 +1,63 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_solaris.go
+
+package ipv6
+
+const (
+ sizeofSockaddrStorage = 0x100
+ sizeofSockaddrInet6 = 0x20
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x24
+
+ sizeofIPv6Mreq = 0x14
+ sizeofGroupReq = 0x104
+ sizeofGroupSourceReq = 0x204
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type sockaddrStorage struct {
+ Family uint16
+ X_ss_pad1 [6]int8
+ X_ss_align float64
+ X_ss_pad2 [240]int8
+}
+
+type sockaddrInet6 struct {
+ Family uint16
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+ X__sin6_src_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex uint32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Interface uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [256]byte
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [256]byte
+ Pad_cgo_1 [256]byte
+}
+
+type icmpv6Filter struct {
+ X__icmp6_filt [8]uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_zos_s390x.go b/vendor/golang.org/x/net/ipv6/zsys_zos_s390x.go
@@ -0,0 +1,62 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Hand edited based on zerrors_zos_s390x.go
+// TODO(Bill O'Farrell): auto-generate.
+
+package ipv6
+
+const (
+ sizeofSockaddrStorage = 128
+ sizeofICMPv6Filter = 32
+ sizeofInet6Pktinfo = 20
+ sizeofIPv6Mtuinfo = 32
+ sizeofSockaddrInet6 = 28
+ sizeofGroupReq = 136
+ sizeofGroupSourceReq = 264
+)
+
+type sockaddrStorage struct {
+ Len uint8
+ Family byte
+ ss_pad1 [6]byte
+ ss_align int64
+ ss_pad2 [112]byte
+}
+
+type sockaddrInet6 struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte
+ Ifindex uint32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ reserved uint32
+ Group sockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ reserved uint32
+ Group sockaddrStorage
+ Source sockaddrStorage
+}
+
+type icmpv6Filter struct {
+ Filt [8]uint32
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
@@ -224,6 +224,9 @@ github.com/mattn/go-isatty
## explicit; go 1.16
github.com/microcosm-cc/bluemonday
github.com/microcosm-cc/bluemonday/css
+# github.com/miekg/dns v1.1.49
+## explicit; go 1.14
+github.com/miekg/dns
# github.com/mitchellh/mapstructure v1.5.0
## explicit; go 1.14
github.com/mitchellh/mapstructure
@@ -568,12 +571,17 @@ golang.org/x/crypto/ssh/internal/bcrypt_pbkdf
golang.org/x/mod/semver
# golang.org/x/net v0.0.0-20220524220425-1d687d428aca
## explicit; go 1.17
+golang.org/x/net/bpf
golang.org/x/net/context
golang.org/x/net/context/ctxhttp
golang.org/x/net/html
golang.org/x/net/html/atom
golang.org/x/net/http/httpguts
golang.org/x/net/idna
+golang.org/x/net/internal/iana
+golang.org/x/net/internal/socket
+golang.org/x/net/ipv4
+golang.org/x/net/ipv6
# golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5
## explicit; go 1.11
golang.org/x/oauth2