Update miekg/dns from v1.1.30 to v1.1.45 (#5972)
Changelog: https://github.com/miekg/dns/compare/v1.1.30...v1.1.45 Brings in several small changes, but more importantly brings Boulder up to (and past) the version used by pebble/challtestsrv.
This commit is contained in:
parent
745e69e7f9
commit
e15bb89347
7
go.mod
7
go.mod
|
|
@ -16,7 +16,7 @@ require (
|
|||
github.com/jmhodges/clock v0.0.0-20160418191101-880ee4c33548
|
||||
github.com/letsencrypt/challtestsrv v1.2.0
|
||||
github.com/letsencrypt/pkcs11key/v4 v4.0.0
|
||||
github.com/miekg/dns v1.1.30
|
||||
github.com/miekg/dns v1.1.45
|
||||
github.com/miekg/pkcs11 v1.0.3
|
||||
github.com/prometheus/client_golang v1.7.1
|
||||
github.com/prometheus/client_model v0.2.0
|
||||
|
|
@ -54,7 +54,10 @@ require (
|
|||
go.opentelemetry.io/contrib/propagators v0.19.0 // indirect
|
||||
go.opentelemetry.io/otel v0.19.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v0.19.0 // indirect
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da // indirect
|
||||
golang.org/x/mod v0.4.2 // indirect
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
|
||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
google.golang.org/appengine v1.6.5 // indirect
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect
|
||||
gopkg.in/alexcesaro/statsd.v2 v2.0.0 // indirect
|
||||
|
|
|
|||
20
go.sum
20
go.sum
|
|
@ -258,8 +258,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0j
|
|||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
|
||||
github.com/miekg/dns v1.1.1/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.30 h1:Qww6FseFn8PRfw07jueqIXqodm0JKiiKuK0DeXSqfyo=
|
||||
github.com/miekg/dns v1.1.30/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/miekg/dns v1.1.45 h1:g5fRIhm9nx7g8osrAvgb16QJfmyMsyOCb+J7LSv+Qzk=
|
||||
github.com/miekg/dns v1.1.45/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
||||
github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||
github.com/miekg/pkcs11 v1.0.3 h1:iMwmD7I5225wv84WxIG/bmxz9AXjWvTWIbM/TYHvWtw=
|
||||
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||
|
|
@ -375,6 +375,7 @@ github.com/weppos/publicsuffix-go v0.15.1-0.20211029155132-7594db4f858a/go.mod h
|
|||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
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/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
|
||||
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
||||
|
|
@ -421,6 +422,8 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl
|
|||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
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.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
|
@ -435,7 +438,6 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR
|
|||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
|
|
@ -446,6 +448,7 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY
|
|||
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-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211029224645-99673261e6eb h1:pirldcYWx7rx7kE5r+9WsOXPXK0+WH5+uZ7uPmJ44uM=
|
||||
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
|
|
@ -454,8 +457,9 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
|
|||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||
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=
|
||||
|
|
@ -470,7 +474,6 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
@ -485,8 +488,10 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/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-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
|
@ -506,10 +511,11 @@ golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBn
|
|||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117220505-0cba7a3a9ee9/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200308013534-11ec41452d41/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 h1:BonxutuHCTL0rBDnZlKjpGIQFTjyUVTexFOdWkB6Fg0=
|
||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
language: go
|
||||
sudo: false
|
||||
|
||||
go:
|
||||
- "1.12.x"
|
||||
- "1.13.x"
|
||||
- tip
|
||||
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
|
||||
script:
|
||||
- go generate ./... && test `git ls-files --modified | wc -l` = 0
|
||||
- go test -race -v -bench=. -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
# Makefile for releasing.
|
||||
#
|
||||
# The release is controlled from version.go. The version found there is
|
||||
# used to tag the git repo, we're not building any artifects so there is nothing
|
||||
# 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
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ avoiding breaking changes wherever reasonable. We support the last two versions
|
|||
A not-so-up-to-date-list-that-may-be-actually-current:
|
||||
|
||||
* https://github.com/coredns/coredns
|
||||
* https://cloudflare.com
|
||||
* https://github.com/abh/geodns
|
||||
* https://github.com/baidu/bfe
|
||||
* http://www.statdns.com/
|
||||
|
|
@ -42,11 +41,9 @@ A not-so-up-to-date-list-that-may-be-actually-current:
|
|||
* https://github.com/StalkR/dns-reverse-proxy
|
||||
* https://github.com/tianon/rawdns
|
||||
* https://mesosphere.github.io/mesos-dns/
|
||||
* https://pulse.turbobytes.com/
|
||||
* https://github.com/fcambus/statzone
|
||||
* https://github.com/benschw/dns-clb-go
|
||||
* https://github.com/corny/dnscheck for <http://public-dns.info/>
|
||||
* https://namesmith.io
|
||||
* https://github.com/miekg/unbound
|
||||
* https://github.com/miekg/exdns
|
||||
* https://dnslookup.org
|
||||
|
|
@ -55,22 +52,31 @@ A not-so-up-to-date-list-that-may-be-actually-current:
|
|||
* https://github.com/mehrdadrad/mylg
|
||||
* https://github.com/bamarni/dockness
|
||||
* https://github.com/fffaraz/microdns
|
||||
* http://kelda.io
|
||||
* https://github.com/ipdcode/hades <https://jd.com>
|
||||
* https://github.com/StackExchange/dnscontrol/
|
||||
* https://www.dnsperf.com/
|
||||
* https://dnssectest.net/
|
||||
* https://dns.apebits.com
|
||||
* https://github.com/oif/apex
|
||||
* https://github.com/jedisct1/dnscrypt-proxy
|
||||
* https://github.com/jedisct1/rpdns
|
||||
* https://github.com/xor-gate/sshfp
|
||||
* https://github.com/rs/dnstrace
|
||||
* https://blitiri.com.ar/p/dnss ([github mirror](https://github.com/albertito/dnss))
|
||||
* https://github.com/semihalev/sdns
|
||||
* https://render.com
|
||||
* https://github.com/peterzen/goresolver
|
||||
* https://github.com/folbricht/routedns
|
||||
* https://domainr.com/
|
||||
* https://zonedb.org/
|
||||
* https://router7.org/
|
||||
* https://github.com/fortio/dnsping
|
||||
* https://github.com/Luzilla/dnsbl_exporter
|
||||
* https://github.com/bodgit/tsig
|
||||
* https://github.com/v2fly/v2ray-core (test only)
|
||||
* https://kuma.io/
|
||||
* https://www.misaka.io/services/dns
|
||||
* https://ping.sx/dig
|
||||
* https://fleetdeck.io/
|
||||
|
||||
|
||||
Send pull request if you want to be listed here.
|
||||
|
||||
|
|
@ -167,6 +173,9 @@ Example programs can be found in the `github.com/miekg/exdns` repository.
|
|||
* 7873 - Domain Name System (DNS) Cookies
|
||||
* 8080 - EdDSA for DNSSEC
|
||||
* 8499 - DNS Terminology
|
||||
* 8659 - DNS Certification Authority Authorization (CAA) Resource Record
|
||||
* 8914 - Extended DNS Errors
|
||||
* 8976 - Message Digest for DNS Zones (ZONEMD RR)
|
||||
|
||||
## Loosely Based Upon
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ type MsgAcceptFunc func(dh Header) MsgAcceptAction
|
|||
//
|
||||
// * Zero bit isn't zero
|
||||
//
|
||||
// * has more than 1 question in the question section
|
||||
// * does not have exactly 1 question in the question section
|
||||
//
|
||||
// * has more than 1 RR in the Answer section
|
||||
//
|
||||
|
|
@ -25,6 +25,7 @@ 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
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ type Conn struct {
|
|||
net.Conn // a net.Conn holding the connection
|
||||
UDPSize uint16 // minimum receive buffer for UDP messages
|
||||
TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2)
|
||||
TsigProvider TsigProvider // An implementation of the TsigProvider interface. If defined it replaces TsigSecret and is used for all TSIG operations.
|
||||
tsigRequestMAC string
|
||||
}
|
||||
|
||||
|
|
@ -34,12 +35,13 @@ type Client struct {
|
|||
Dialer *net.Dialer // a net.Dialer used to set local address, timeouts and more
|
||||
// Timeout is a cumulative timeout for dial, write and read, defaults to 0 (disabled) - overrides DialTimeout, ReadTimeout,
|
||||
// WriteTimeout when non-zero. Can be overridden with net.Dialer.Timeout (see Client.ExchangeWithDialer and
|
||||
// Client.Dialer) or context.Context.Deadline (see the deprecated ExchangeContext)
|
||||
// Client.Dialer) or context.Context.Deadline (see ExchangeContext)
|
||||
Timeout time.Duration
|
||||
DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds, or net.Dialer.Timeout if expiring earlier - overridden by Timeout when that value is non-zero
|
||||
ReadTimeout time.Duration // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero
|
||||
WriteTimeout time.Duration // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero
|
||||
TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2)
|
||||
TsigProvider TsigProvider // An implementation of the TsigProvider interface. If defined it replaces TsigSecret and is used for all TSIG operations.
|
||||
SingleInflight bool // if true suppress multiple outstanding queries for the same Qname, Qtype and Qclass
|
||||
group singleflight
|
||||
}
|
||||
|
|
@ -80,6 +82,12 @@ func (c *Client) writeTimeout() time.Duration {
|
|||
|
||||
// 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 {
|
||||
|
|
@ -99,14 +107,22 @@ func (c *Client) Dial(address string) (conn *Conn, err error) {
|
|||
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.Dial(network, address)
|
||||
conn.Conn, err = d.DialContext(ctx, network, address)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
conn.UDPSize = c.UDPSize
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
|
|
@ -124,7 +140,6 @@ func (c *Client) Dial(address string) (conn *Conn, err error) {
|
|||
// of 512 bytes
|
||||
// To specify a local address or a timeout, the caller has to set the `Client.Dialer`
|
||||
// attribute appropriately
|
||||
|
||||
func (c *Client) Exchange(m *Msg, address string) (r *Msg, rtt time.Duration, err error) {
|
||||
co, err := c.Dial(address)
|
||||
|
||||
|
|
@ -138,24 +153,34 @@ func (c *Client) Exchange(m *Msg, address string) (r *Msg, rtt time.Duration, er
|
|||
// 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.
|
||||
// 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.exchange(m, conn)
|
||||
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) {
|
||||
return c.exchange(m, conn)
|
||||
// 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()
|
||||
|
|
@ -164,8 +189,7 @@ func (c *Client) ExchangeWithConn(m *Msg, conn *Conn) (r *Msg, rtt time.Duration
|
|||
return r, rtt, err
|
||||
}
|
||||
|
||||
func (c *Client) exchange(m *Msg, co *Conn) (r *Msg, rtt time.Duration, err error) {
|
||||
|
||||
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 {
|
||||
|
|
@ -176,18 +200,41 @@ func (c *Client) exchange(m *Msg, co *Conn) (r *Msg, rtt time.Duration, err erro
|
|||
co.UDPSize = c.UDPSize
|
||||
}
|
||||
|
||||
co.TsigSecret = c.TsigSecret
|
||||
t := time.Now()
|
||||
// write with the appropriate write timeout
|
||||
co.SetWriteDeadline(t.Add(c.getTimeoutForRequest(c.writeTimeout())))
|
||||
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
|
||||
}
|
||||
|
||||
co.SetReadDeadline(time.Now().Add(c.getTimeoutForRequest(c.readTimeout())))
|
||||
r, err = co.ReadMsg()
|
||||
if err == nil && r.Id != m.Id {
|
||||
err = ErrId
|
||||
if _, ok := co.Conn.(net.PacketConn); ok {
|
||||
for {
|
||||
r, err = co.ReadMsg()
|
||||
// Ignore replies with mismatched IDs because they might be
|
||||
// responses to earlier queries that timed out.
|
||||
if err != nil || r.Id == m.Id {
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
r, err = co.ReadMsg()
|
||||
if err == nil && r.Id != m.Id {
|
||||
err = ErrId
|
||||
}
|
||||
}
|
||||
rtt = time.Since(t)
|
||||
return r, rtt, err
|
||||
|
|
@ -212,11 +259,15 @@ func (co *Conn) ReadMsg() (*Msg, error) {
|
|||
return m, err
|
||||
}
|
||||
if t := m.IsTsig(); t != nil {
|
||||
if _, ok := co.TsigSecret[t.Hdr.Name]; !ok {
|
||||
return m, ErrSecret
|
||||
if co.TsigProvider != nil {
|
||||
err = tsigVerifyProvider(p, co.TsigProvider, co.tsigRequestMAC, false)
|
||||
} else {
|
||||
if _, ok := co.TsigSecret[t.Hdr.Name]; !ok {
|
||||
return m, ErrSecret
|
||||
}
|
||||
// Need to work on the original message p, as that was used to calculate the tsig.
|
||||
err = TsigVerify(p, co.TsigSecret[t.Hdr.Name], co.tsigRequestMAC, false)
|
||||
}
|
||||
// Need to work on the original message p, as that was used to calculate the tsig.
|
||||
err = TsigVerify(p, co.TsigSecret[t.Hdr.Name], co.tsigRequestMAC, false)
|
||||
}
|
||||
return m, err
|
||||
}
|
||||
|
|
@ -294,10 +345,14 @@ func (co *Conn) WriteMsg(m *Msg) (err error) {
|
|||
var out []byte
|
||||
if t := m.IsTsig(); t != nil {
|
||||
mac := ""
|
||||
if _, ok := co.TsigSecret[t.Hdr.Name]; !ok {
|
||||
return ErrSecret
|
||||
if co.TsigProvider != nil {
|
||||
out, mac, err = tsigGenerateProvider(m, co.TsigProvider, co.tsigRequestMAC, false)
|
||||
} else {
|
||||
if _, ok := co.TsigSecret[t.Hdr.Name]; !ok {
|
||||
return ErrSecret
|
||||
}
|
||||
out, mac, err = TsigGenerate(m, co.TsigSecret[t.Hdr.Name], co.tsigRequestMAC, false)
|
||||
}
|
||||
out, mac, err = TsigGenerate(m, co.TsigSecret[t.Hdr.Name], co.tsigRequestMAC, false)
|
||||
// Set for the next read, although only used in zone transfers
|
||||
co.tsigRequestMAC = mac
|
||||
} else {
|
||||
|
|
@ -320,11 +375,10 @@ func (co *Conn) Write(p []byte) (int, error) {
|
|||
return co.Conn.Write(p)
|
||||
}
|
||||
|
||||
l := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(l, uint16(len(p)))
|
||||
|
||||
n, err := (&net.Buffers{l, p}).WriteTo(co.Conn)
|
||||
return int(n), err
|
||||
msg := make([]byte, 2+len(p))
|
||||
binary.BigEndian.PutUint16(msg, uint16(len(p)))
|
||||
copy(msg[2:], p)
|
||||
return co.Conn.Write(msg)
|
||||
}
|
||||
|
||||
// Return the appropriate timeout for a specific request
|
||||
|
|
@ -360,7 +414,7 @@ func Dial(network, address string) (conn *Conn, err error) {
|
|||
func ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, err error) {
|
||||
client := Client{Net: "udp"}
|
||||
r, _, err = client.ExchangeContext(ctx, m, a)
|
||||
// ignorint rtt to leave the original ExchangeContext API unchanged, but
|
||||
// ignoring rtt to leave the original ExchangeContext API unchanged, but
|
||||
// this function will go away
|
||||
return r, err
|
||||
}
|
||||
|
|
@ -416,15 +470,11 @@ func DialTimeoutWithTLS(network, address string, tlsConfig *tls.Config, timeout
|
|||
// context, if present. If there is both a context deadline and a configured
|
||||
// timeout on the client, the earliest of the two takes effect.
|
||||
func (c *Client) ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
|
||||
var timeout time.Duration
|
||||
if deadline, ok := ctx.Deadline(); !ok {
|
||||
timeout = 0
|
||||
} else {
|
||||
timeout = time.Until(deadline)
|
||||
conn, err := c.DialContext(ctx, a)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
// not passing the context to the underlying calls, as the API does not support
|
||||
// context. For timeouts you should set up Client.Dialer and call Client.Exchange.
|
||||
// TODO(tmthrgd,miekg): this is a race condition.
|
||||
c.Dialer = &net.Dialer{Timeout: timeout}
|
||||
return c.Exchange(m, a)
|
||||
defer conn.Close()
|
||||
|
||||
return c.exchangeWithConnContext(ctx, m, conn)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -349,10 +349,7 @@ func ReverseAddr(addr string) (arpa string, err error) {
|
|||
// Add it, in reverse, to the buffer
|
||||
for i := len(ip) - 1; i >= 0; i-- {
|
||||
v := ip[i]
|
||||
buf = append(buf, hexDigit[v&0xF])
|
||||
buf = append(buf, '.')
|
||||
buf = append(buf, hexDigit[v>>4])
|
||||
buf = append(buf, '.')
|
||||
buf = append(buf, hexDigit[v&0xF], '.', hexDigit[v>>4], '.')
|
||||
}
|
||||
// Append "ip6.arpa." and return (buf already has the final .)
|
||||
buf = append(buf, "ip6.arpa."...)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
package dns
|
||||
|
||||
import "strconv"
|
||||
import (
|
||||
"encoding/hex"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
year68 = 1 << 31 // For RFC1982 (Serial Arithmetic) calculations in 32 bits.
|
||||
|
|
@ -111,7 +114,7 @@ func (h *RR_Header) parse(c *zlexer, origin string) *ParseError {
|
|||
|
||||
// ToRFC3597 converts a known RR to the unknown RR representation from RFC 3597.
|
||||
func (rr *RFC3597) ToRFC3597(r RR) error {
|
||||
buf := make([]byte, Len(r)*2)
|
||||
buf := make([]byte, Len(r))
|
||||
headerEnd, off, err := packRR(r, buf, 0, compressionMap{}, false)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -126,9 +129,30 @@ func (rr *RFC3597) ToRFC3597(r RR) error {
|
|||
}
|
||||
|
||||
_, err = rr.unpack(buf, headerEnd)
|
||||
return err
|
||||
}
|
||||
|
||||
// fromRFC3597 converts an unknown RR representation from RFC 3597 to the known RR type.
|
||||
func (rr *RFC3597) fromRFC3597(r RR) error {
|
||||
hdr := r.Header()
|
||||
*hdr = rr.Hdr
|
||||
|
||||
// Can't overflow uint16 as the length of Rdata is validated in (*RFC3597).parse.
|
||||
// We can only get here when rr was constructed with that method.
|
||||
hdr.Rdlength = uint16(hex.DecodedLen(len(rr.Rdata)))
|
||||
|
||||
if noRdata(*hdr) {
|
||||
// Dynamic update.
|
||||
return nil
|
||||
}
|
||||
|
||||
// rr.pack requires an extra allocation and a copy so we just decode Rdata
|
||||
// manually, it's simpler anyway.
|
||||
msg, err := hex.DecodeString(rr.Rdata)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
_, err = r.unpack(msg, 0)
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,15 +3,14 @@ package dns
|
|||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"crypto/dsa"
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
"crypto/elliptic"
|
||||
_ "crypto/md5"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
_ "crypto/sha1"
|
||||
_ "crypto/sha256"
|
||||
_ "crypto/sha512"
|
||||
_ "crypto/sha1" // need its init function
|
||||
_ "crypto/sha256" // need its init function
|
||||
_ "crypto/sha512" // need its init function
|
||||
"encoding/asn1"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
|
|
@ -19,8 +18,6 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/ed25519"
|
||||
)
|
||||
|
||||
// DNSSEC encryption algorithm codes.
|
||||
|
|
@ -318,6 +315,7 @@ func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error {
|
|||
}
|
||||
|
||||
rr.Signature = toBase64(signature)
|
||||
return nil
|
||||
case RSAMD5, DSA, DSANSEC3SHA1:
|
||||
// See RFC 6944.
|
||||
return ErrAlg
|
||||
|
|
@ -332,9 +330,8 @@ func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error {
|
|||
}
|
||||
|
||||
rr.Signature = toBase64(signature)
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func sign(k crypto.Signer, hashed []byte, hash crypto.Hash, alg uint8) ([]byte, error) {
|
||||
|
|
@ -346,7 +343,6 @@ func sign(k crypto.Signer, hashed []byte, hash crypto.Hash, alg uint8) ([]byte,
|
|||
switch alg {
|
||||
case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512:
|
||||
return signature, nil
|
||||
|
||||
case ECDSAP256SHA256, ECDSAP384SHA384:
|
||||
ecdsaSignature := &struct {
|
||||
R, S *big.Int
|
||||
|
|
@ -366,25 +362,18 @@ func sign(k crypto.Signer, hashed []byte, hash crypto.Hash, alg uint8) ([]byte,
|
|||
signature := intToBytes(ecdsaSignature.R, intlen)
|
||||
signature = append(signature, intToBytes(ecdsaSignature.S, intlen)...)
|
||||
return signature, nil
|
||||
|
||||
// There is no defined interface for what a DSA backed crypto.Signer returns
|
||||
case DSA, DSANSEC3SHA1:
|
||||
// t := divRoundUp(divRoundUp(p.PublicKey.Y.BitLen(), 8)-64, 8)
|
||||
// signature := []byte{byte(t)}
|
||||
// signature = append(signature, intToBytes(r1, 20)...)
|
||||
// signature = append(signature, intToBytes(s1, 20)...)
|
||||
// rr.Signature = signature
|
||||
|
||||
case ED25519:
|
||||
return signature, nil
|
||||
default:
|
||||
return nil, ErrAlg
|
||||
}
|
||||
|
||||
return nil, ErrAlg
|
||||
}
|
||||
|
||||
// Verify validates an RRSet with the signature and key. This is only the
|
||||
// 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) {
|
||||
|
|
@ -405,6 +394,12 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
|
|||
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
|
||||
|
|
@ -448,7 +443,7 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
|
|||
}
|
||||
|
||||
switch rr.Algorithm {
|
||||
case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512, RSAMD5:
|
||||
case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512:
|
||||
// TODO(mg): this can be done quicker, ie. cache the pubkey data somewhere??
|
||||
pubkey := k.publicKeyRSA() // Get the key
|
||||
if pubkey == nil {
|
||||
|
|
@ -512,7 +507,7 @@ func (rr *RRSIG) ValidityPeriod(t time.Time) bool {
|
|||
return ti <= utc && utc <= te
|
||||
}
|
||||
|
||||
// Return the signatures base64 encodedig sigdata as a byte slice.
|
||||
// Return the signatures base64 encoding sigdata as a byte slice.
|
||||
func (rr *RRSIG) sigBuf() []byte {
|
||||
sigbuf, err := fromBase64([]byte(rr.Signature))
|
||||
if err != nil {
|
||||
|
|
@ -600,30 +595,6 @@ func (k *DNSKEY) publicKeyECDSA() *ecdsa.PublicKey {
|
|||
return pubkey
|
||||
}
|
||||
|
||||
func (k *DNSKEY) publicKeyDSA() *dsa.PublicKey {
|
||||
keybuf, err := fromBase64([]byte(k.PublicKey))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if len(keybuf) < 22 {
|
||||
return nil
|
||||
}
|
||||
t, keybuf := int(keybuf[0]), keybuf[1:]
|
||||
size := 64 + t*8
|
||||
q, keybuf := keybuf[:20], keybuf[20:]
|
||||
if len(keybuf) != 3*size {
|
||||
return nil
|
||||
}
|
||||
p, keybuf := keybuf[:size], keybuf[size:]
|
||||
g, y := keybuf[:size], keybuf[size:]
|
||||
pubkey := new(dsa.PublicKey)
|
||||
pubkey.Parameters.Q = new(big.Int).SetBytes(q)
|
||||
pubkey.Parameters.P = new(big.Int).SetBytes(p)
|
||||
pubkey.Parameters.G = new(big.Int).SetBytes(g)
|
||||
pubkey.Y = new(big.Int).SetBytes(y)
|
||||
return pubkey
|
||||
}
|
||||
|
||||
func (k *DNSKEY) publicKeyED25519() ed25519.PublicKey {
|
||||
keybuf, err := fromBase64([]byte(k.PublicKey))
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -3,12 +3,11 @@ package dns
|
|||
import (
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"math/big"
|
||||
|
||||
"golang.org/x/crypto/ed25519"
|
||||
)
|
||||
|
||||
// Generate generates a DNSKEY of the given bit size.
|
||||
|
|
@ -19,8 +18,6 @@ import (
|
|||
// bits should be set to the size of the algorithm.
|
||||
func (k *DNSKEY) Generate(bits int) (crypto.PrivateKey, error) {
|
||||
switch k.Algorithm {
|
||||
case RSAMD5, DSA, DSANSEC3SHA1:
|
||||
return nil, ErrAlg
|
||||
case RSASHA1, RSASHA256, RSASHA1NSEC3SHA1:
|
||||
if bits < 512 || bits > 4096 {
|
||||
return nil, ErrKeySize
|
||||
|
|
@ -41,6 +38,8 @@ func (k *DNSKEY) Generate(bits int) (crypto.PrivateKey, error) {
|
|||
if bits != 256 {
|
||||
return nil, ErrKeySize
|
||||
}
|
||||
default:
|
||||
return nil, ErrAlg
|
||||
}
|
||||
|
||||
switch k.Algorithm {
|
||||
|
|
|
|||
|
|
@ -4,13 +4,12 @@ import (
|
|||
"bufio"
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
"crypto/rsa"
|
||||
"io"
|
||||
"math/big"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/crypto/ed25519"
|
||||
)
|
||||
|
||||
// NewPrivateKey returns a PrivateKey by parsing the string s.
|
||||
|
|
@ -43,15 +42,7 @@ func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, er
|
|||
return nil, ErrPrivKey
|
||||
}
|
||||
switch uint8(algo) {
|
||||
case RSAMD5, DSA, DSANSEC3SHA1:
|
||||
return nil, ErrAlg
|
||||
case RSASHA1:
|
||||
fallthrough
|
||||
case RSASHA1NSEC3SHA1:
|
||||
fallthrough
|
||||
case RSASHA256:
|
||||
fallthrough
|
||||
case RSASHA512:
|
||||
case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512:
|
||||
priv, err := readPrivateKeyRSA(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -62,11 +53,7 @@ func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, er
|
|||
}
|
||||
priv.PublicKey = *pub
|
||||
return priv, nil
|
||||
case ECCGOST:
|
||||
return nil, ErrPrivKey
|
||||
case ECDSAP256SHA256:
|
||||
fallthrough
|
||||
case ECDSAP384SHA384:
|
||||
case ECDSAP256SHA256, ECDSAP384SHA384:
|
||||
priv, err := readPrivateKeyECDSA(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -80,7 +67,7 @@ func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, er
|
|||
case ED25519:
|
||||
return readPrivateKeyED25519(m)
|
||||
default:
|
||||
return nil, ErrPrivKey
|
||||
return nil, ErrAlg
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,13 +2,11 @@ package dns
|
|||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/dsa"
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
"crypto/rsa"
|
||||
"math/big"
|
||||
"strconv"
|
||||
|
||||
"golang.org/x/crypto/ed25519"
|
||||
)
|
||||
|
||||
const format = "Private-key-format: v1.3\n"
|
||||
|
|
@ -17,8 +15,8 @@ var bigIntOne = big.NewInt(1)
|
|||
|
||||
// PrivateKeyString converts a PrivateKey to a string. This string has the same
|
||||
// format as the private-key-file of BIND9 (Private-key-format: v1.3).
|
||||
// It needs some info from the key (the algorithm), so its a method of the DNSKEY
|
||||
// It supports rsa.PrivateKey, ecdsa.PrivateKey and dsa.PrivateKey
|
||||
// It needs some info from the key (the algorithm), so its a method of the DNSKEY.
|
||||
// It supports *rsa.PrivateKey, *ecdsa.PrivateKey and ed25519.PrivateKey.
|
||||
func (r *DNSKEY) PrivateKeyString(p crypto.PrivateKey) string {
|
||||
algorithm := strconv.Itoa(int(r.Algorithm))
|
||||
algorithm += " (" + AlgorithmToString[r.Algorithm] + ")"
|
||||
|
|
@ -67,21 +65,6 @@ func (r *DNSKEY) PrivateKeyString(p crypto.PrivateKey) string {
|
|||
"Algorithm: " + algorithm + "\n" +
|
||||
"PrivateKey: " + private + "\n"
|
||||
|
||||
case *dsa.PrivateKey:
|
||||
T := divRoundUp(divRoundUp(p.PublicKey.Parameters.G.BitLen(), 8)-64, 8)
|
||||
prime := toBase64(intToBytes(p.PublicKey.Parameters.P, 64+T*8))
|
||||
subprime := toBase64(intToBytes(p.PublicKey.Parameters.Q, 20))
|
||||
base := toBase64(intToBytes(p.PublicKey.Parameters.G, 64+T*8))
|
||||
priv := toBase64(intToBytes(p.X, 20))
|
||||
pub := toBase64(intToBytes(p.PublicKey.Y, 64+T*8))
|
||||
return format +
|
||||
"Algorithm: " + algorithm + "\n" +
|
||||
"Prime(p): " + prime + "\n" +
|
||||
"Subprime(q): " + subprime + "\n" +
|
||||
"Base(g): " + base + "\n" +
|
||||
"Private_value(x): " + priv + "\n" +
|
||||
"Public_value(y): " + pub + "\n"
|
||||
|
||||
case ed25519.PrivateKey:
|
||||
private := toBase64(p.Seed())
|
||||
return format +
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ shows the options you have and what functions to call.
|
|||
TRANSACTION SIGNATURE
|
||||
|
||||
An TSIG or transaction signature adds a HMAC TSIG record to each message sent.
|
||||
The supported algorithms include: HmacMD5, HmacSHA1, HmacSHA256 and HmacSHA512.
|
||||
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
|
||||
|
|
@ -174,7 +174,7 @@ changes to the RRset after calling SetTsig() the signature will be incorrect.
|
|||
c.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
|
||||
m := new(dns.Msg)
|
||||
m.SetQuestion("miek.nl.", dns.TypeMX)
|
||||
m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix())
|
||||
m.SetTsig("axfr.", dns.HmacSHA256, 300, time.Now().Unix())
|
||||
...
|
||||
// When sending the TSIG RR is calculated and filled in before sending
|
||||
|
||||
|
|
@ -187,13 +187,37 @@ request an AXFR for miek.nl. with TSIG key named "axfr." and secret
|
|||
m := new(dns.Msg)
|
||||
t.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
|
||||
m.SetAxfr("miek.nl.")
|
||||
m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix())
|
||||
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"}
|
||||
|
|
@ -207,7 +231,7 @@ Basic use pattern validating and replying to a message that has TSIG set.
|
|||
if r.IsTsig() != nil {
|
||||
if w.TsigStatus() == nil {
|
||||
// *Msg r has an TSIG record and it was validated
|
||||
m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix())
|
||||
m.SetTsig("axfr.", dns.HmacSHA256, 300, time.Now().Unix())
|
||||
} else {
|
||||
// *Msg r has an TSIG records and it was not validated
|
||||
}
|
||||
|
|
@ -260,7 +284,7 @@ From RFC 2931:
|
|||
on requests and responses, and protection of the overall integrity of a response.
|
||||
|
||||
It works like TSIG, except that SIG(0) uses public key cryptography, instead of
|
||||
the shared secret approach in TSIG. Supported algorithms: DSA, ECDSAP256SHA256,
|
||||
the shared secret approach in TSIG. Supported algorithms: ECDSAP256SHA256,
|
||||
ECDSAP384SHA384, RSASHA1, RSASHA256 and RSASHA512.
|
||||
|
||||
Signing subsequent messages in multi-message sessions is not implemented.
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ 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
|
||||
|
|
@ -22,11 +23,49 @@ const (
|
|||
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 {
|
||||
|
|
@ -59,6 +98,8 @@ func (rr *OPT) String() string {
|
|||
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:
|
||||
|
|
@ -73,6 +114,10 @@ func (rr *OPT) String() string {
|
|||
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
|
||||
|
|
@ -88,11 +133,11 @@ func (rr *OPT) len(off int, compression map[string]struct{}) int {
|
|||
return l
|
||||
}
|
||||
|
||||
func (rr *OPT) parse(c *zlexer, origin string) *ParseError {
|
||||
panic("dns: internal error: parse should never be called on OPT")
|
||||
func (*OPT) parse(c *zlexer, origin string) *ParseError {
|
||||
return &ParseError{err: "OPT records do not have a presentation format"}
|
||||
}
|
||||
|
||||
func (r1 *OPT) isDuplicate(r2 RR) bool { return false }
|
||||
func (rr *OPT) isDuplicate(r2 RR) bool { return false }
|
||||
|
||||
// return the old value -> delete SetVersion?
|
||||
|
||||
|
|
@ -148,6 +193,16 @@ func (rr *OPT) SetDo(do ...bool) {
|
|||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
|
@ -452,7 +507,7 @@ func (e *EDNS0_LLQ) copy() EDNS0 {
|
|||
return &EDNS0_LLQ{e.Code, e.Version, e.Opcode, e.Error, e.Id, e.LeaseLife}
|
||||
}
|
||||
|
||||
// EDNS0_DUA implements the EDNS0 "DNSSEC Algorithm Understood" option. See RFC 6975.
|
||||
// EDNS0_DAU implements the EDNS0 "DNSSEC Algorithm Understood" option. See RFC 6975.
|
||||
type EDNS0_DAU struct {
|
||||
Code uint16 // Always EDNS0DAU
|
||||
AlgCode []uint8
|
||||
|
|
@ -525,7 +580,7 @@ func (e *EDNS0_N3U) String() string {
|
|||
}
|
||||
func (e *EDNS0_N3U) copy() EDNS0 { return &EDNS0_N3U{e.Code, e.AlgCode} }
|
||||
|
||||
// EDNS0_EXPIRE implementes the EDNS0 option as described in RFC 7314.
|
||||
// EDNS0_EXPIRE implements the EDNS0 option as described in RFC 7314.
|
||||
type EDNS0_EXPIRE struct {
|
||||
Code uint16 // Always EDNS0EXPIRE
|
||||
Expire uint32
|
||||
|
|
@ -604,57 +659,52 @@ func (e *EDNS0_LOCAL) unpack(b []byte) error {
|
|||
// EDNS0_TCP_KEEPALIVE is an EDNS0 option that instructs the server to keep
|
||||
// the TCP connection alive. See RFC 7828.
|
||||
type EDNS0_TCP_KEEPALIVE struct {
|
||||
Code uint16 // Always EDNSTCPKEEPALIVE
|
||||
Length uint16 // the value 0 if the TIMEOUT is omitted, the value 2 if it is present;
|
||||
Timeout uint16 // an idle timeout value for the TCP connection, specified in units of 100 milliseconds, encoded in network byte order.
|
||||
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 && e.Length != 2 {
|
||||
return nil, errors.New("dns: timeout specified but length is not 2")
|
||||
if e.Timeout > 0 {
|
||||
b := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(b, e.Timeout)
|
||||
return b, nil
|
||||
}
|
||||
if e.Timeout == 0 && e.Length != 0 {
|
||||
return nil, errors.New("dns: timeout not specified but length is not 0")
|
||||
}
|
||||
b := make([]byte, 4+e.Length)
|
||||
binary.BigEndian.PutUint16(b[0:], e.Code)
|
||||
binary.BigEndian.PutUint16(b[2:], e.Length)
|
||||
if e.Length == 2 {
|
||||
binary.BigEndian.PutUint16(b[4:], e.Timeout)
|
||||
}
|
||||
return b, nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (e *EDNS0_TCP_KEEPALIVE) unpack(b []byte) error {
|
||||
if len(b) < 4 {
|
||||
return ErrBuf
|
||||
}
|
||||
e.Length = binary.BigEndian.Uint16(b[2:4])
|
||||
if e.Length != 0 && e.Length != 2 {
|
||||
return errors.New("dns: length mismatch, want 0/2 but got " + strconv.FormatUint(uint64(e.Length), 10))
|
||||
}
|
||||
if e.Length == 2 {
|
||||
if len(b) < 6 {
|
||||
return ErrBuf
|
||||
}
|
||||
e.Timeout = binary.BigEndian.Uint16(b[4:6])
|
||||
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() (s string) {
|
||||
s = "use tcp keep-alive"
|
||||
if e.Length == 0 {
|
||||
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
|
||||
return s
|
||||
}
|
||||
func (e *EDNS0_TCP_KEEPALIVE) copy() EDNS0 { return &EDNS0_TCP_KEEPALIVE{e.Code, e.Length, e.Timeout} }
|
||||
|
||||
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
|
||||
|
|
@ -673,3 +723,117 @@ func (e *EDNS0_PADDING) copy() EDNS0 {
|
|||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,10 +75,10 @@ func (zp *ZoneParser) generate(l lex) (RR, bool) {
|
|||
r := &generateReader{
|
||||
s: s,
|
||||
|
||||
cur: int(start),
|
||||
start: int(start),
|
||||
end: int(end),
|
||||
step: int(step),
|
||||
cur: start,
|
||||
start: start,
|
||||
end: end,
|
||||
step: step,
|
||||
|
||||
file: zp.file,
|
||||
lex: &l,
|
||||
|
|
@ -94,10 +94,10 @@ type generateReader struct {
|
|||
s string
|
||||
si int
|
||||
|
||||
cur int
|
||||
start int
|
||||
end int
|
||||
step int
|
||||
cur int64
|
||||
start int64
|
||||
end int64
|
||||
step int64
|
||||
|
||||
mod bytes.Buffer
|
||||
|
||||
|
|
@ -173,7 +173,7 @@ func (r *generateReader) ReadByte() (byte, error) {
|
|||
return '$', nil
|
||||
}
|
||||
|
||||
var offset int
|
||||
var offset int64
|
||||
|
||||
// Search for { and }
|
||||
if r.s[si+1] == '{' {
|
||||
|
|
@ -188,7 +188,7 @@ func (r *generateReader) ReadByte() (byte, error) {
|
|||
if errMsg != "" {
|
||||
return 0, r.parseError(errMsg, si+3+sep)
|
||||
}
|
||||
if r.start+offset < 0 || int64(r.end) + int64(offset) > 1<<31-1 {
|
||||
if r.start+offset < 0 || r.end+offset > 1<<31-1 {
|
||||
return 0, r.parseError("bad offset in $GENERATE", si+3+sep)
|
||||
}
|
||||
|
||||
|
|
@ -208,7 +208,7 @@ func (r *generateReader) ReadByte() (byte, error) {
|
|||
}
|
||||
|
||||
// Convert a $GENERATE modifier 0,0,d to something Printf can deal with.
|
||||
func modToPrintf(s string) (string, int, string) {
|
||||
func modToPrintf(s string) (string, int64, string) {
|
||||
// Modifier is { offset [ ,width [ ,base ] ] } - provide default
|
||||
// values for optional width and type, if necessary.
|
||||
var offStr, widthStr, base string
|
||||
|
|
@ -240,8 +240,8 @@ func modToPrintf(s string) (string, int, string) {
|
|||
}
|
||||
|
||||
if width == 0 {
|
||||
return "%" + base, int(offset), ""
|
||||
return "%" + base, offset, ""
|
||||
}
|
||||
|
||||
return "%0" + widthStr + base, int(offset), ""
|
||||
return "%0" + widthStr + base, offset, ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ package dns
|
|||
// escaped dots (\.) for instance.
|
||||
// s must be a syntactically valid domain name, see IsDomainName.
|
||||
func SplitDomainName(s string) (labels []string) {
|
||||
if len(s) == 0 {
|
||||
if s == "" {
|
||||
return nil
|
||||
}
|
||||
fqdnEnd := 0 // offset of the final '.' or the length of the name
|
||||
|
|
|
|||
|
|
@ -624,11 +624,18 @@ func UnpackRRWithHeader(h RR_Header, msg []byte, off int) (rr RR, off1 int, err
|
|||
rr = &RFC3597{Hdr: h}
|
||||
}
|
||||
|
||||
if noRdata(h) {
|
||||
return rr, off, nil
|
||||
if off < 0 || off > len(msg) {
|
||||
return &h, off, &Error{err: "bad off"}
|
||||
}
|
||||
|
||||
end := off + int(h.Rdlength)
|
||||
if end < off || end > len(msg) {
|
||||
return &h, end, &Error{err: "bad rdlength"}
|
||||
}
|
||||
|
||||
if noRdata(h) {
|
||||
return rr, off, nil
|
||||
}
|
||||
|
||||
off, err = rr.unpack(msg, off)
|
||||
if err != nil {
|
||||
|
|
@ -735,7 +742,7 @@ func (dns *Msg) packBufferWithCompressionMap(buf []byte, compression compression
|
|||
}
|
||||
|
||||
// Set extended rcode unconditionally if we have an opt, this will allow
|
||||
// reseting the extended rcode bits if they need to.
|
||||
// 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 {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"net"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
|
@ -437,35 +438,6 @@ Option:
|
|||
return edns, off, nil
|
||||
}
|
||||
|
||||
func makeDataOpt(code uint16) EDNS0 {
|
||||
switch code {
|
||||
case EDNS0NSID:
|
||||
return new(EDNS0_NSID)
|
||||
case EDNS0SUBNET:
|
||||
return new(EDNS0_SUBNET)
|
||||
case EDNS0COOKIE:
|
||||
return new(EDNS0_COOKIE)
|
||||
case EDNS0EXPIRE:
|
||||
return new(EDNS0_EXPIRE)
|
||||
case EDNS0UL:
|
||||
return new(EDNS0_UL)
|
||||
case EDNS0LLQ:
|
||||
return new(EDNS0_LLQ)
|
||||
case EDNS0DAU:
|
||||
return new(EDNS0_DAU)
|
||||
case EDNS0DHU:
|
||||
return new(EDNS0_DHU)
|
||||
case EDNS0N3U:
|
||||
return new(EDNS0_N3U)
|
||||
case EDNS0PADDING:
|
||||
return new(EDNS0_PADDING)
|
||||
default:
|
||||
e := new(EDNS0_LOCAL)
|
||||
e.Code = code
|
||||
return e
|
||||
}
|
||||
}
|
||||
|
||||
func packDataOpt(options []EDNS0, msg []byte, off int) (int, error) {
|
||||
for _, el := range options {
|
||||
b, err := el.pack()
|
||||
|
|
@ -612,6 +584,65 @@ func packDataNsec(bitmap []uint16, msg []byte, off int) (int, error) {
|
|||
return off, nil
|
||||
}
|
||||
|
||||
func unpackDataSVCB(msg []byte, off int) ([]SVCBKeyValue, int, error) {
|
||||
var xs []SVCBKeyValue
|
||||
var code uint16
|
||||
var length uint16
|
||||
var err error
|
||||
for off < len(msg) {
|
||||
code, off, err = unpackUint16(msg, off)
|
||||
if err != nil {
|
||||
return nil, len(msg), &Error{err: "overflow unpacking SVCB"}
|
||||
}
|
||||
length, off, err = unpackUint16(msg, off)
|
||||
if err != nil || off+int(length) > len(msg) {
|
||||
return nil, len(msg), &Error{err: "overflow unpacking SVCB"}
|
||||
}
|
||||
e := makeSVCBKeyValue(SVCBKey(code))
|
||||
if e == nil {
|
||||
return nil, len(msg), &Error{err: "bad SVCB key"}
|
||||
}
|
||||
if err := e.unpack(msg[off : off+int(length)]); err != nil {
|
||||
return nil, len(msg), err
|
||||
}
|
||||
if len(xs) > 0 && e.Key() <= xs[len(xs)-1].Key() {
|
||||
return nil, len(msg), &Error{err: "SVCB keys not in strictly increasing order"}
|
||||
}
|
||||
xs = append(xs, e)
|
||||
off += int(length)
|
||||
}
|
||||
return xs, off, nil
|
||||
}
|
||||
|
||||
func packDataSVCB(pairs []SVCBKeyValue, msg []byte, off int) (int, error) {
|
||||
pairs = append([]SVCBKeyValue(nil), pairs...)
|
||||
sort.Slice(pairs, func(i, j int) bool {
|
||||
return pairs[i].Key() < pairs[j].Key()
|
||||
})
|
||||
prev := svcb_RESERVED
|
||||
for _, el := range pairs {
|
||||
if el.Key() == prev {
|
||||
return len(msg), &Error{err: "repeated SVCB keys are not allowed"}
|
||||
}
|
||||
prev = el.Key()
|
||||
packed, err := el.pack()
|
||||
if err != nil {
|
||||
return len(msg), err
|
||||
}
|
||||
off, err = packUint16(uint16(el.Key()), msg, off)
|
||||
if err != nil {
|
||||
return len(msg), &Error{err: "overflow packing SVCB"}
|
||||
}
|
||||
off, err = packUint16(uint16(len(packed)), msg, off)
|
||||
if err != nil || off+len(packed) > len(msg) {
|
||||
return len(msg), &Error{err: "overflow packing SVCB"}
|
||||
}
|
||||
copy(msg[off:off+len(packed)], packed)
|
||||
off += len(packed)
|
||||
}
|
||||
return off, nil
|
||||
}
|
||||
|
||||
func unpackDataDomainNames(msg []byte, off, end int) ([]string, int, error) {
|
||||
var (
|
||||
servers []string
|
||||
|
|
@ -683,6 +714,13 @@ func packDataAplPrefix(p *APLPrefix, msg []byte, off int) (int, error) {
|
|||
if p.Negation {
|
||||
n = 0x80
|
||||
}
|
||||
|
||||
// trim trailing zero bytes as specified in RFC3123 Sections 4.1 and 4.2.
|
||||
i := len(addr) - 1
|
||||
for ; i >= 0 && addr[i] == 0; i-- {
|
||||
}
|
||||
addr = addr[:i+1]
|
||||
|
||||
adflen := uint8(len(addr)) & 0x7f
|
||||
off, err = packUint8(n|adflen, msg, off)
|
||||
if err != nil {
|
||||
|
|
@ -743,6 +781,8 @@ func unpackDataAplPrefix(msg []byte, off int) (APLPrefix, int, error) {
|
|||
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]
|
||||
|
|
@ -754,10 +794,6 @@ func unpackDataAplPrefix(msg []byte, off int) (APLPrefix, int, error) {
|
|||
IP: ip,
|
||||
Mask: net.CIDRMask(int(prefix), 8*len(ip)),
|
||||
}
|
||||
network := ipnet.IP.Mask(ipnet.Mask)
|
||||
if !network.Equal(ipnet.IP) {
|
||||
return APLPrefix{}, len(msg), &Error{err: "invalid APL address length"}
|
||||
}
|
||||
|
||||
return APLPrefix{
|
||||
Negation: (nlen & 0x80) != 0,
|
||||
|
|
|
|||
|
|
@ -8,8 +8,14 @@ package dns
|
|||
// record adding as many records as possible without exceeding the
|
||||
// requested buffer size.
|
||||
//
|
||||
// If the message fits within the requested size without compression,
|
||||
// Truncate will set the message's Compress attribute to false. It is
|
||||
// the caller's responsibility to set it back to true if they wish to
|
||||
// compress the payload regardless of size.
|
||||
//
|
||||
// The TC bit will be set if any records were excluded from the message.
|
||||
// This indicates to that the client should retry over TCP.
|
||||
// If the TC bit is already set on the message it will be retained.
|
||||
// TC indicates that the client should retry over TCP.
|
||||
//
|
||||
// According to RFC 2181, the TC bit should only be set if not all of the
|
||||
// "required" RRs can be included in the response. Unfortunately, we have
|
||||
|
|
@ -28,11 +34,11 @@ func (dns *Msg) Truncate(size int) {
|
|||
}
|
||||
|
||||
// RFC 6891 mandates that the payload size in an OPT record
|
||||
// less than 512 bytes must be treated as equal to 512 bytes.
|
||||
// less than 512 (MinMsgSize) bytes must be treated as equal to 512 bytes.
|
||||
//
|
||||
// For ease of use, we impose that restriction here.
|
||||
if size < 512 {
|
||||
size = 512
|
||||
if size < MinMsgSize {
|
||||
size = MinMsgSize
|
||||
}
|
||||
|
||||
l := msgLenWithCompressionMap(dns, nil) // uncompressed length
|
||||
|
|
@ -77,7 +83,7 @@ func (dns *Msg) Truncate(size int) {
|
|||
}
|
||||
|
||||
// See the function documentation for when we set this.
|
||||
dns.Truncated = len(dns.Answer) > numAnswer ||
|
||||
dns.Truncated = dns.Truncated || len(dns.Answer) > numAnswer ||
|
||||
len(dns.Ns) > numNS || len(dns.Extra) > numExtra
|
||||
|
||||
dns.Answer = dns.Answer[:numAnswer]
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import "strings"
|
|||
// RFC 6895. This allows one to experiment with new RR types, without requesting an
|
||||
// official type code. Also see dns.PrivateHandle and dns.PrivateHandleRemove.
|
||||
type PrivateRdata interface {
|
||||
// String returns the text presentaton of the Rdata of the Private RR.
|
||||
// String returns the text presentation of the Rdata of the Private RR.
|
||||
String() string
|
||||
// Parse parses the Rdata of the private RR.
|
||||
Parse([]string) error
|
||||
|
|
@ -90,7 +90,7 @@ Fetch:
|
|||
return nil
|
||||
}
|
||||
|
||||
func (r1 *PrivateRR) isDuplicate(r2 RR) bool { return false }
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -150,6 +150,9 @@ func ReadRR(r io.Reader, file string) (RR, error) {
|
|||
// 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
|
||||
|
||||
|
|
@ -577,10 +580,23 @@ func (zp *ZoneParser) Next() (RR, bool) {
|
|||
|
||||
st = zExpectRdata
|
||||
case zExpectRdata:
|
||||
var rr RR
|
||||
if newFn, ok := TypeToRR[h.Rrtype]; ok && canParseAsRR(h.Rrtype) {
|
||||
var (
|
||||
rr RR
|
||||
parseAsRFC3597 bool
|
||||
)
|
||||
if newFn, ok := TypeToRR[h.Rrtype]; ok {
|
||||
rr = newFn()
|
||||
*rr.Header() = *h
|
||||
|
||||
// We may be parsing a known RR type using the RFC3597 format.
|
||||
// If so, we handle that here in a generic way.
|
||||
//
|
||||
// This is also true for PrivateRR types which will have the
|
||||
// RFC3597 parsing done for them and the Unpack method called
|
||||
// to populate the RR instead of simply deferring to Parse.
|
||||
if zp.c.Peek().token == "\\#" {
|
||||
parseAsRFC3597 = true
|
||||
}
|
||||
} else {
|
||||
rr = &RFC3597{Hdr: *h}
|
||||
}
|
||||
|
|
@ -600,13 +616,18 @@ func (zp *ZoneParser) Next() (RR, bool) {
|
|||
return zp.setParseError("unexpected newline", l)
|
||||
}
|
||||
|
||||
if err := rr.parse(zp.c, zp.origin); err != nil {
|
||||
parseAsRR := rr
|
||||
if parseAsRFC3597 {
|
||||
parseAsRR = &RFC3597{Hdr: *h}
|
||||
}
|
||||
|
||||
if err := parseAsRR.parse(zp.c, zp.origin); err != nil {
|
||||
// err is a concrete *ParseError without the file field set.
|
||||
// The setParseError call below will construct a new
|
||||
// *ParseError with file set to zp.file.
|
||||
|
||||
// If err.lex is nil than we have encounter an unknown RR type
|
||||
// in that case we substitute our current lex token.
|
||||
// err.lex may be nil in which case we substitute our current
|
||||
// lex token.
|
||||
if err.lex == (lex{}) {
|
||||
return zp.setParseError(err.err, l)
|
||||
}
|
||||
|
|
@ -614,6 +635,13 @@ func (zp *ZoneParser) Next() (RR, bool) {
|
|||
return zp.setParseError(err.err, err.lex)
|
||||
}
|
||||
|
||||
if parseAsRFC3597 {
|
||||
err := parseAsRR.(*RFC3597).fromRFC3597(rr)
|
||||
if err != nil {
|
||||
return zp.setParseError(err.Error(), l)
|
||||
}
|
||||
}
|
||||
|
||||
return rr, true
|
||||
}
|
||||
}
|
||||
|
|
@ -623,18 +651,6 @@ func (zp *ZoneParser) Next() (RR, bool) {
|
|||
return nil, false
|
||||
}
|
||||
|
||||
// canParseAsRR returns true if the record type can be parsed as a
|
||||
// concrete RR. It blacklists certain record types that must be parsed
|
||||
// according to RFC 3597 because they lack a presentation format.
|
||||
func canParseAsRR(rrtype uint16) bool {
|
||||
switch rrtype {
|
||||
case TypeANY, TypeNULL, TypeOPT, TypeTSIG:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
type zlexer struct {
|
||||
br io.ByteReader
|
||||
|
||||
|
|
@ -1210,11 +1226,29 @@ func stringToCm(token string) (e, m uint8, ok bool) {
|
|||
if cmeters, err = strconv.Atoi(s[1]); err != nil {
|
||||
return
|
||||
}
|
||||
// There's no point in having more than 2 digits in this part, and would rather make the implementation complicated ('123' should be treated as '12').
|
||||
// So we simply reject it.
|
||||
// We also make sure the first character is a digit to reject '+-' signs.
|
||||
if len(s[1]) > 2 || s[1][0] < '0' || s[1][0] > '9' {
|
||||
return
|
||||
}
|
||||
if len(s[1]) == 1 {
|
||||
// 'nn.1' must be treated as 'nn-meters and 10cm, not 1cm.
|
||||
cmeters *= 10
|
||||
}
|
||||
if 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
|
||||
|
|
@ -1227,13 +1261,10 @@ func stringToCm(token string) (e, m uint8, ok bool) {
|
|||
e = 0
|
||||
val = cmeters
|
||||
}
|
||||
for val > 10 {
|
||||
for val >= 10 {
|
||||
e++
|
||||
val /= 10
|
||||
}
|
||||
if e > 9 {
|
||||
ok = false
|
||||
}
|
||||
m = uint8(val)
|
||||
return
|
||||
}
|
||||
|
|
@ -1275,6 +1306,9 @@ func appendOrigin(name, origin string) string {
|
|||
|
||||
// LOC record helper function
|
||||
func locCheckNorth(token string, latitude uint32) (uint32, bool) {
|
||||
if latitude > 90*1000*60*60 {
|
||||
return latitude, false
|
||||
}
|
||||
switch token {
|
||||
case "n", "N":
|
||||
return LOC_EQUATOR + latitude, true
|
||||
|
|
@ -1286,6 +1320,9 @@ func locCheckNorth(token string, latitude uint32) (uint32, bool) {
|
|||
|
||||
// LOC record helper function
|
||||
func locCheckEast(token string, longitude uint32) (uint32, bool) {
|
||||
if longitude > 180*1000*60*60 {
|
||||
return longitude, false
|
||||
}
|
||||
switch token {
|
||||
case "e", "E":
|
||||
return LOC_EQUATOR + longitude, true
|
||||
|
|
@ -1318,7 +1355,7 @@ 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 postitions, if not its a parse error
|
||||
// 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}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -590,7 +590,7 @@ func (rr *LOC) parse(c *zlexer, o string) *ParseError {
|
|||
// North
|
||||
l, _ := c.Next()
|
||||
i, e := strconv.ParseUint(l.token, 10, 32)
|
||||
if e != nil || l.err {
|
||||
if e != nil || l.err || i > 90 {
|
||||
return &ParseError{"", "bad LOC Latitude", l}
|
||||
}
|
||||
rr.Latitude = 1000 * 60 * 60 * uint32(i)
|
||||
|
|
@ -601,7 +601,7 @@ func (rr *LOC) parse(c *zlexer, o string) *ParseError {
|
|||
if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok {
|
||||
goto East
|
||||
}
|
||||
if i, err := strconv.ParseUint(l.token, 10, 32); err != nil || l.err {
|
||||
if i, err := strconv.ParseUint(l.token, 10, 32); err != nil || l.err || i > 59 {
|
||||
return &ParseError{"", "bad LOC Latitude minutes", l}
|
||||
} else {
|
||||
rr.Latitude += 1000 * 60 * uint32(i)
|
||||
|
|
@ -609,7 +609,7 @@ func (rr *LOC) parse(c *zlexer, o string) *ParseError {
|
|||
|
||||
c.Next() // zBlank
|
||||
l, _ = c.Next()
|
||||
if i, err := strconv.ParseFloat(l.token, 32); err != nil || l.err {
|
||||
if i, err := strconv.ParseFloat(l.token, 64); err != nil || l.err || i < 0 || i >= 60 {
|
||||
return &ParseError{"", "bad LOC Latitude seconds", l}
|
||||
} else {
|
||||
rr.Latitude += uint32(1000 * i)
|
||||
|
|
@ -627,7 +627,7 @@ East:
|
|||
// East
|
||||
c.Next() // zBlank
|
||||
l, _ = c.Next()
|
||||
if i, err := strconv.ParseUint(l.token, 10, 32); err != nil || l.err {
|
||||
if i, err := strconv.ParseUint(l.token, 10, 32); err != nil || l.err || i > 180 {
|
||||
return &ParseError{"", "bad LOC Longitude", l}
|
||||
} else {
|
||||
rr.Longitude = 1000 * 60 * 60 * uint32(i)
|
||||
|
|
@ -638,14 +638,14 @@ East:
|
|||
if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok {
|
||||
goto Altitude
|
||||
}
|
||||
if i, err := strconv.ParseUint(l.token, 10, 32); err != nil || l.err {
|
||||
if i, err := strconv.ParseUint(l.token, 10, 32); err != nil || l.err || i > 59 {
|
||||
return &ParseError{"", "bad LOC Longitude minutes", l}
|
||||
} else {
|
||||
rr.Longitude += 1000 * 60 * uint32(i)
|
||||
}
|
||||
c.Next() // zBlank
|
||||
l, _ = c.Next()
|
||||
if i, err := strconv.ParseFloat(l.token, 32); err != nil || l.err {
|
||||
if i, err := strconv.ParseFloat(l.token, 64); err != nil || l.err || i < 0 || i >= 60 {
|
||||
return &ParseError{"", "bad LOC Longitude seconds", l}
|
||||
} else {
|
||||
rr.Longitude += uint32(1000 * i)
|
||||
|
|
@ -662,13 +662,13 @@ East:
|
|||
Altitude:
|
||||
c.Next() // zBlank
|
||||
l, _ = c.Next()
|
||||
if len(l.token) == 0 || l.err {
|
||||
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, 32); err != nil {
|
||||
if i, err := strconv.ParseFloat(l.token, 64); err != nil {
|
||||
return &ParseError{"", "bad LOC Altitude", l}
|
||||
} else {
|
||||
rr.Altitude = uint32(i*100.0 + 10000000.0 + 0.5)
|
||||
|
|
@ -722,7 +722,7 @@ func (rr *HIP) parse(c *zlexer, o string) *ParseError {
|
|||
|
||||
c.Next() // zBlank
|
||||
l, _ = c.Next() // zString
|
||||
if len(l.token) == 0 || l.err {
|
||||
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.
|
||||
|
|
@ -730,11 +730,15 @@ func (rr *HIP) parse(c *zlexer, o string) *ParseError {
|
|||
|
||||
c.Next() // zBlank
|
||||
l, _ = c.Next() // zString
|
||||
if len(l.token) == 0 || l.err {
|
||||
if l.token == "" || l.err {
|
||||
return &ParseError{"", "bad HIP PublicKey", l}
|
||||
}
|
||||
rr.PublicKey = l.token // This cannot contain spaces
|
||||
rr.PublicKeyLength = uint16(base64.StdEncoding.DecodedLen(len(rr.PublicKey)))
|
||||
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()
|
||||
|
|
@ -846,6 +850,38 @@ func (rr *CSYNC) parse(c *zlexer, o string) *ParseError {
|
|||
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 {
|
||||
|
|
@ -893,8 +929,7 @@ func (rr *RRSIG) parse(c *zlexer, o string) *ParseError {
|
|||
l, _ = c.Next()
|
||||
if i, err := StringToTime(l.token); err != nil {
|
||||
// Try to see if all numeric and use it as epoch
|
||||
if i, err := strconv.ParseInt(l.token, 10, 64); err == nil {
|
||||
// TODO(miek): error out on > MAX_UINT32, same below
|
||||
if i, err := strconv.ParseUint(l.token, 10, 32); err == nil {
|
||||
rr.Expiration = uint32(i)
|
||||
} else {
|
||||
return &ParseError{"", "bad RRSIG Expiration", l}
|
||||
|
|
@ -906,7 +941,7 @@ func (rr *RRSIG) parse(c *zlexer, o string) *ParseError {
|
|||
c.Next() // zBlank
|
||||
l, _ = c.Next()
|
||||
if i, err := StringToTime(l.token); err != nil {
|
||||
if i, err := strconv.ParseInt(l.token, 10, 64); err == nil {
|
||||
if i, err := strconv.ParseUint(l.token, 10, 32); err == nil {
|
||||
rr.Inception = uint32(i)
|
||||
} else {
|
||||
return &ParseError{"", "bad RRSIG Inception", l}
|
||||
|
|
@ -998,7 +1033,7 @@ func (rr *NSEC3) parse(c *zlexer, o string) *ParseError {
|
|||
rr.Iterations = uint16(i)
|
||||
c.Next()
|
||||
l, _ = c.Next()
|
||||
if len(l.token) == 0 || l.err {
|
||||
if l.token == "" || l.err {
|
||||
return &ParseError{"", "bad NSEC3 Salt", l}
|
||||
}
|
||||
if l.token != "-" {
|
||||
|
|
@ -1008,7 +1043,7 @@ func (rr *NSEC3) parse(c *zlexer, o string) *ParseError {
|
|||
|
||||
c.Next()
|
||||
l, _ = c.Next()
|
||||
if len(l.token) == 0 || l.err {
|
||||
if l.token == "" || l.err {
|
||||
return &ParseError{"", "bad NSEC3 NextDomain", l}
|
||||
}
|
||||
rr.HashLength = 20 // Fix for NSEC3 (sha1 160 bits)
|
||||
|
|
@ -1388,7 +1423,7 @@ func (rr *RFC3597) parse(c *zlexer, o string) *ParseError {
|
|||
|
||||
c.Next() // zBlank
|
||||
l, _ = c.Next()
|
||||
rdlength, e := strconv.Atoi(l.token)
|
||||
rdlength, e := strconv.ParseUint(l.token, 10, 16)
|
||||
if e != nil || l.err {
|
||||
return &ParseError{"", "bad RFC3597 Rdata ", l}
|
||||
}
|
||||
|
|
@ -1397,7 +1432,7 @@ func (rr *RFC3597) parse(c *zlexer, o string) *ParseError {
|
|||
if e1 != nil {
|
||||
return e1
|
||||
}
|
||||
if rdlength*2 != len(s) {
|
||||
if int(rdlength)*2 != len(s) {
|
||||
return &ParseError{"", "bad RFC3597 Rdata", l}
|
||||
}
|
||||
rr.Rdata = s
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ func (mux *ServeMux) HandleRemove(pattern string) {
|
|||
// are redirected to the parent zone (if that is also registered),
|
||||
// otherwise the child gets the query.
|
||||
//
|
||||
// If no handler is found, or there is no question, a standard SERVFAIL
|
||||
// If no handler is found, or there is no question, a standard REFUSED
|
||||
// message is returned
|
||||
func (mux *ServeMux) ServeDNS(w ResponseWriter, req *Msg) {
|
||||
var h Handler
|
||||
|
|
@ -102,7 +102,7 @@ func (mux *ServeMux) ServeDNS(w ResponseWriter, req *Msg) {
|
|||
if h != nil {
|
||||
h.ServeDNS(w, req)
|
||||
} else {
|
||||
HandleFailed(w, req)
|
||||
handleRefused(w, req)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -72,13 +72,22 @@ type response struct {
|
|||
tsigStatus error
|
||||
tsigRequestMAC string
|
||||
tsigSecret map[string]string // the tsig secrets
|
||||
udp *net.UDPConn // i/o connection if UDP was used
|
||||
udp net.PacketConn // i/o connection if UDP was used
|
||||
tcp net.Conn // i/o connection if TCP was used
|
||||
udpSession *SessionUDP // oob data to get egress interface right
|
||||
pcSession net.Addr // address to use when writing to a generic net.PacketConn
|
||||
writer Writer // writer to output the raw DNS bits
|
||||
}
|
||||
|
||||
// handleRefused returns a HandlerFunc that returns REFUSED for every request it gets.
|
||||
func handleRefused(w ResponseWriter, r *Msg) {
|
||||
m := new(Msg)
|
||||
m.SetRcode(r, RcodeRefused)
|
||||
w.WriteMsg(m)
|
||||
}
|
||||
|
||||
// HandleFailed returns a HandlerFunc that returns SERVFAIL for every request it gets.
|
||||
// Deprecated: This function is going away.
|
||||
func HandleFailed(w ResponseWriter, r *Msg) {
|
||||
m := new(Msg)
|
||||
m.SetRcode(r, RcodeServerFailure)
|
||||
|
|
@ -139,12 +148,24 @@ type Reader interface {
|
|||
ReadUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error)
|
||||
}
|
||||
|
||||
// defaultReader is an adapter for the Server struct that implements the Reader interface
|
||||
// using the readTCP and readUDP func of the embedded Server.
|
||||
// PacketConnReader is an optional interface that Readers can implement to support using generic net.PacketConns.
|
||||
type PacketConnReader interface {
|
||||
Reader
|
||||
|
||||
// ReadPacketConn reads a raw message from a generic net.PacketConn UDP connection. Implementations may
|
||||
// alter connection properties, for example the read-deadline.
|
||||
ReadPacketConn(conn net.PacketConn, timeout time.Duration) ([]byte, net.Addr, error)
|
||||
}
|
||||
|
||||
// defaultReader is an adapter for the Server struct that implements the Reader and
|
||||
// PacketConnReader interfaces using the readTCP, readUDP and readPacketConn funcs
|
||||
// of the embedded Server.
|
||||
type defaultReader struct {
|
||||
*Server
|
||||
}
|
||||
|
||||
var _ PacketConnReader = defaultReader{}
|
||||
|
||||
func (dr defaultReader) ReadTCP(conn net.Conn, timeout time.Duration) ([]byte, error) {
|
||||
return dr.readTCP(conn, timeout)
|
||||
}
|
||||
|
|
@ -153,8 +174,14 @@ func (dr defaultReader) ReadUDP(conn *net.UDPConn, timeout time.Duration) ([]byt
|
|||
return dr.readUDP(conn, timeout)
|
||||
}
|
||||
|
||||
func (dr defaultReader) ReadPacketConn(conn net.PacketConn, timeout time.Duration) ([]byte, net.Addr, error) {
|
||||
return dr.readPacketConn(conn, timeout)
|
||||
}
|
||||
|
||||
// DecorateReader is a decorator hook for extending or supplanting the functionality of a Reader.
|
||||
// Implementations should never return a nil Reader.
|
||||
// Readers should also implement the optional PacketConnReader interface.
|
||||
// PacketConnReader is required to use a generic net.PacketConn.
|
||||
type DecorateReader func(Reader) Reader
|
||||
|
||||
// DecorateWriter is a decorator hook for extending or supplanting the functionality of a Writer.
|
||||
|
|
@ -294,6 +321,7 @@ func (srv *Server) ListenAndServe() error {
|
|||
}
|
||||
u := l.(*net.UDPConn)
|
||||
if e := setUDPSocketOptions(u); e != nil {
|
||||
u.Close()
|
||||
return e
|
||||
}
|
||||
srv.PacketConn = l
|
||||
|
|
@ -317,24 +345,22 @@ func (srv *Server) ActivateAndServe() error {
|
|||
|
||||
srv.init()
|
||||
|
||||
pConn := srv.PacketConn
|
||||
l := srv.Listener
|
||||
if pConn != nil {
|
||||
if srv.PacketConn != nil {
|
||||
// Check PacketConn interface's type is valid and value
|
||||
// is not nil
|
||||
if t, ok := pConn.(*net.UDPConn); ok && t != nil {
|
||||
if t, ok := srv.PacketConn.(*net.UDPConn); ok && t != nil {
|
||||
if e := setUDPSocketOptions(t); e != nil {
|
||||
return e
|
||||
}
|
||||
srv.started = true
|
||||
unlock()
|
||||
return srv.serveUDP(t)
|
||||
}
|
||||
}
|
||||
if l != nil {
|
||||
srv.started = true
|
||||
unlock()
|
||||
return srv.serveTCP(l)
|
||||
return srv.serveUDP(srv.PacketConn)
|
||||
}
|
||||
if srv.Listener != nil {
|
||||
srv.started = true
|
||||
unlock()
|
||||
return srv.serveTCP(srv.Listener)
|
||||
}
|
||||
return &Error{err: "bad listeners"}
|
||||
}
|
||||
|
|
@ -438,18 +464,24 @@ func (srv *Server) serveTCP(l net.Listener) error {
|
|||
}
|
||||
|
||||
// serveUDP starts a UDP listener for the server.
|
||||
func (srv *Server) serveUDP(l *net.UDPConn) error {
|
||||
func (srv *Server) serveUDP(l net.PacketConn) error {
|
||||
defer l.Close()
|
||||
|
||||
if srv.NotifyStartedFunc != nil {
|
||||
srv.NotifyStartedFunc()
|
||||
}
|
||||
|
||||
reader := Reader(defaultReader{srv})
|
||||
if srv.DecorateReader != nil {
|
||||
reader = srv.DecorateReader(reader)
|
||||
}
|
||||
|
||||
lUDP, isUDP := l.(*net.UDPConn)
|
||||
readerPC, canPacketConn := reader.(PacketConnReader)
|
||||
if !isUDP && !canPacketConn {
|
||||
return &Error{err: "PacketConnReader was not implemented on Reader returned from DecorateReader but is required for net.PacketConn"}
|
||||
}
|
||||
|
||||
if srv.NotifyStartedFunc != nil {
|
||||
srv.NotifyStartedFunc()
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
defer func() {
|
||||
wg.Wait()
|
||||
|
|
@ -459,7 +491,17 @@ func (srv *Server) serveUDP(l *net.UDPConn) error {
|
|||
rtimeout := srv.getReadTimeout()
|
||||
// deadline is not used here
|
||||
for srv.isStarted() {
|
||||
m, s, err := reader.ReadUDP(l, rtimeout)
|
||||
var (
|
||||
m []byte
|
||||
sPC net.Addr
|
||||
sUDP *SessionUDP
|
||||
err error
|
||||
)
|
||||
if isUDP {
|
||||
m, sUDP, err = reader.ReadUDP(lUDP, rtimeout)
|
||||
} else {
|
||||
m, sPC, err = readerPC.ReadPacketConn(l, rtimeout)
|
||||
}
|
||||
if err != nil {
|
||||
if !srv.isStarted() {
|
||||
return nil
|
||||
|
|
@ -476,7 +518,7 @@ func (srv *Server) serveUDP(l *net.UDPConn) error {
|
|||
continue
|
||||
}
|
||||
wg.Add(1)
|
||||
go srv.serveUDPPacket(&wg, m, l, s)
|
||||
go srv.serveUDPPacket(&wg, m, l, sUDP, sPC)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
@ -538,8 +580,8 @@ func (srv *Server) serveTCPConn(wg *sync.WaitGroup, rw net.Conn) {
|
|||
}
|
||||
|
||||
// Serve a new UDP request.
|
||||
func (srv *Server) serveUDPPacket(wg *sync.WaitGroup, m []byte, u *net.UDPConn, s *SessionUDP) {
|
||||
w := &response{tsigSecret: srv.TsigSecret, udp: u, udpSession: s}
|
||||
func (srv *Server) serveUDPPacket(wg *sync.WaitGroup, m []byte, u net.PacketConn, udpSession *SessionUDP, pcSession net.Addr) {
|
||||
w := &response{tsigSecret: srv.TsigSecret, udp: u, udpSession: udpSession, pcSession: pcSession}
|
||||
if srv.DecorateWriter != nil {
|
||||
w.writer = srv.DecorateWriter(w)
|
||||
} else {
|
||||
|
|
@ -651,6 +693,24 @@ func (srv *Server) readUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *S
|
|||
return m, s, nil
|
||||
}
|
||||
|
||||
func (srv *Server) readPacketConn(conn net.PacketConn, timeout time.Duration) ([]byte, net.Addr, error) {
|
||||
srv.lock.RLock()
|
||||
if srv.started {
|
||||
// See the comment in readTCP above.
|
||||
conn.SetReadDeadline(time.Now().Add(timeout))
|
||||
}
|
||||
srv.lock.RUnlock()
|
||||
|
||||
m := srv.udpPool.Get().([]byte)
|
||||
n, addr, err := conn.ReadFrom(m)
|
||||
if err != nil {
|
||||
srv.udpPool.Put(m)
|
||||
return nil, nil, err
|
||||
}
|
||||
m = m[:n]
|
||||
return m, addr, nil
|
||||
}
|
||||
|
||||
// WriteMsg implements the ResponseWriter.WriteMsg method.
|
||||
func (w *response) WriteMsg(m *Msg) (err error) {
|
||||
if w.closed {
|
||||
|
|
@ -684,17 +744,19 @@ func (w *response) Write(m []byte) (int, error) {
|
|||
|
||||
switch {
|
||||
case w.udp != nil:
|
||||
return WriteToSessionUDP(w.udp, m, w.udpSession)
|
||||
if u, ok := w.udp.(*net.UDPConn); ok {
|
||||
return WriteToSessionUDP(u, m, w.udpSession)
|
||||
}
|
||||
return w.udp.WriteTo(m, w.pcSession)
|
||||
case w.tcp != nil:
|
||||
if len(m) > MaxMsgSize {
|
||||
return 0, &Error{err: "message too large"}
|
||||
}
|
||||
|
||||
l := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(l, uint16(len(m)))
|
||||
|
||||
n, err := (&net.Buffers{l, m}).WriteTo(w.tcp)
|
||||
return int(n), err
|
||||
msg := make([]byte, 2+len(m))
|
||||
binary.BigEndian.PutUint16(msg, uint16(len(m)))
|
||||
copy(msg[2:], m)
|
||||
return w.tcp.Write(msg)
|
||||
default:
|
||||
panic("dns: internal error: udp and tcp both nil")
|
||||
}
|
||||
|
|
@ -717,10 +779,12 @@ func (w *response) RemoteAddr() net.Addr {
|
|||
switch {
|
||||
case w.udpSession != nil:
|
||||
return w.udpSession.RemoteAddr()
|
||||
case w.pcSession != nil:
|
||||
return w.pcSession
|
||||
case w.tcp != nil:
|
||||
return w.tcp.RemoteAddr()
|
||||
default:
|
||||
panic("dns: internal error: udpSession and tcp both nil")
|
||||
panic("dns: internal error: udpSession, pcSession and tcp are all nil")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package dns
|
|||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/dsa"
|
||||
"crypto/ecdsa"
|
||||
"crypto/rsa"
|
||||
"encoding/binary"
|
||||
|
|
@ -18,7 +17,7 @@ func (rr *SIG) Sign(k crypto.Signer, m *Msg) ([]byte, error) {
|
|||
if k == nil {
|
||||
return nil, ErrPrivKey
|
||||
}
|
||||
if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 {
|
||||
if rr.KeyTag == 0 || rr.SignerName == "" || rr.Algorithm == 0 {
|
||||
return nil, ErrKey
|
||||
}
|
||||
|
||||
|
|
@ -79,13 +78,13 @@ func (rr *SIG) Verify(k *KEY, buf []byte) error {
|
|||
if k == nil {
|
||||
return ErrKey
|
||||
}
|
||||
if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 {
|
||||
if rr.KeyTag == 0 || rr.SignerName == "" || rr.Algorithm == 0 {
|
||||
return ErrKey
|
||||
}
|
||||
|
||||
var hash crypto.Hash
|
||||
switch rr.Algorithm {
|
||||
case DSA, RSASHA1:
|
||||
case RSASHA1:
|
||||
hash = crypto.SHA1
|
||||
case RSASHA256, ECDSAP256SHA256:
|
||||
hash = crypto.SHA256
|
||||
|
|
@ -178,17 +177,6 @@ func (rr *SIG) Verify(k *KEY, buf []byte) error {
|
|||
hashed := hasher.Sum(nil)
|
||||
sig := buf[sigend:]
|
||||
switch k.Algorithm {
|
||||
case DSA:
|
||||
pk := k.publicKeyDSA()
|
||||
sig = sig[1:]
|
||||
r := new(big.Int).SetBytes(sig[:len(sig)/2])
|
||||
s := new(big.Int).SetBytes(sig[len(sig)/2:])
|
||||
if pk != nil {
|
||||
if dsa.Verify(pk, hashed, r, s) {
|
||||
return nil
|
||||
}
|
||||
return ErrSig
|
||||
}
|
||||
case RSASHA1, RSASHA256, RSASHA512:
|
||||
pk := k.publicKeyRSA()
|
||||
if pk != nil {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,755 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"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-01 Section 12.3.2.
|
||||
const (
|
||||
SVCB_MANDATORY SVCBKey = 0
|
||||
SVCB_ALPN SVCBKey = 1
|
||||
SVCB_NO_DEFAULT_ALPN SVCBKey = 2
|
||||
SVCB_PORT SVCBKey = 3
|
||||
SVCB_IPV4HINT SVCBKey = 4
|
||||
SVCB_ECHCONFIG SVCBKey = 5
|
||||
SVCB_IPV6HINT SVCBKey = 6
|
||||
svcb_RESERVED SVCBKey = 65535
|
||||
)
|
||||
|
||||
var svcbKeyToStringMap = map[SVCBKey]string{
|
||||
SVCB_MANDATORY: "mandatory",
|
||||
SVCB_ALPN: "alpn",
|
||||
SVCB_NO_DEFAULT_ALPN: "no-default-alpn",
|
||||
SVCB_PORT: "port",
|
||||
SVCB_IPV4HINT: "ipv4hint",
|
||||
SVCB_ECHCONFIG: "echconfig",
|
||||
SVCB_IPV6HINT: "ipv6hint",
|
||||
}
|
||||
|
||||
var svcbStringToKeyMap = reverseSVCBKeyMap(svcbKeyToStringMap)
|
||||
|
||||
func reverseSVCBKeyMap(m map[SVCBKey]string) map[string]SVCBKey {
|
||||
n := make(map[string]SVCBKey, len(m))
|
||||
for u, s := range m {
|
||||
n[s] = u
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// String takes the numerical code of an SVCB key and returns its name.
|
||||
// Returns an empty string for reserved keys.
|
||||
// Accepts unassigned keys as well as experimental/private keys.
|
||||
func (key SVCBKey) String() string {
|
||||
if x := svcbKeyToStringMap[key]; x != "" {
|
||||
return x
|
||||
}
|
||||
if key == svcb_RESERVED {
|
||||
return ""
|
||||
}
|
||||
return "key" + strconv.FormatUint(uint64(key), 10)
|
||||
}
|
||||
|
||||
// svcbStringToKey returns the numerical code of an SVCB key.
|
||||
// Returns svcb_RESERVED for reserved/invalid keys.
|
||||
// Accepts unassigned keys as well as experimental/private keys.
|
||||
func svcbStringToKey(s string) SVCBKey {
|
||||
if strings.HasPrefix(s, "key") {
|
||||
a, err := strconv.ParseUint(s[3:], 10, 16)
|
||||
// no leading zeros
|
||||
// key shouldn't be registered
|
||||
if err != nil || a == 65535 || s[3] == '0' || svcbKeyToStringMap[SVCBKey(a)] != "" {
|
||||
return svcb_RESERVED
|
||||
}
|
||||
return SVCBKey(a)
|
||||
}
|
||||
if key, ok := svcbStringToKeyMap[s]; ok {
|
||||
return key
|
||||
}
|
||||
return svcb_RESERVED
|
||||
}
|
||||
|
||||
func (rr *SVCB) parse(c *zlexer, o string) *ParseError {
|
||||
l, _ := c.Next()
|
||||
i, e := strconv.ParseUint(l.token, 10, 16)
|
||||
if e != nil || l.err {
|
||||
return &ParseError{l.token, "bad SVCB priority", l}
|
||||
}
|
||||
rr.Priority = uint16(i)
|
||||
|
||||
c.Next() // zBlank
|
||||
l, _ = c.Next() // zString
|
||||
rr.Target = l.token
|
||||
|
||||
name, nameOk := toAbsoluteName(l.token, o)
|
||||
if l.err || !nameOk {
|
||||
return &ParseError{l.token, "bad SVCB Target", l}
|
||||
}
|
||||
rr.Target = name
|
||||
|
||||
// Values (if any)
|
||||
l, _ = c.Next()
|
||||
var xs []SVCBKeyValue
|
||||
// Helps require whitespace between pairs.
|
||||
// Prevents key1000="a"key1001=...
|
||||
canHaveNextKey := true
|
||||
for l.value != zNewline && l.value != zEOF {
|
||||
switch l.value {
|
||||
case zString:
|
||||
if !canHaveNextKey {
|
||||
// The key we can now read was probably meant to be
|
||||
// a part of the last value.
|
||||
return &ParseError{l.token, "bad SVCB value quotation", l}
|
||||
}
|
||||
|
||||
// In key=value pairs, value does not have to be quoted unless value
|
||||
// contains whitespace. And keys don't need to have values.
|
||||
// Similarly, keys with an equality signs after them don't need values.
|
||||
// l.token includes at least up to the first equality sign.
|
||||
idx := strings.IndexByte(l.token, '=')
|
||||
var key, value string
|
||||
if idx < 0 {
|
||||
// Key with no value and no equality sign
|
||||
key = l.token
|
||||
} else if idx == 0 {
|
||||
return &ParseError{l.token, "bad SVCB key", l}
|
||||
} else {
|
||||
key, value = l.token[:idx], l.token[idx+1:]
|
||||
|
||||
if value == "" {
|
||||
// We have a key and an equality sign. Maybe we have nothing
|
||||
// after "=" or we have a double quote.
|
||||
l, _ = c.Next()
|
||||
if l.value == zQuote {
|
||||
// Only needed when value ends with double quotes.
|
||||
// Any value starting with zQuote ends with it.
|
||||
canHaveNextKey = false
|
||||
|
||||
l, _ = c.Next()
|
||||
switch l.value {
|
||||
case zString:
|
||||
// We have a value in double quotes.
|
||||
value = l.token
|
||||
l, _ = c.Next()
|
||||
if l.value != zQuote {
|
||||
return &ParseError{l.token, "SVCB unterminated value", l}
|
||||
}
|
||||
case zQuote:
|
||||
// There's nothing in double quotes.
|
||||
default:
|
||||
return &ParseError{l.token, "bad SVCB value", l}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
kv := makeSVCBKeyValue(svcbStringToKey(key))
|
||||
if kv == nil {
|
||||
return &ParseError{l.token, "bad SVCB key", l}
|
||||
}
|
||||
if err := kv.parse(value); err != nil {
|
||||
return &ParseError{l.token, err.Error(), l}
|
||||
}
|
||||
xs = append(xs, kv)
|
||||
case zQuote:
|
||||
return &ParseError{l.token, "SVCB key can't contain double quotes", l}
|
||||
case zBlank:
|
||||
canHaveNextKey = true
|
||||
default:
|
||||
return &ParseError{l.token, "bad SVCB values", l}
|
||||
}
|
||||
l, _ = c.Next()
|
||||
}
|
||||
rr.Value = xs
|
||||
if rr.Priority == 0 && len(xs) > 0 {
|
||||
return &ParseError{l.token, "SVCB aliasform can't have values", l}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// makeSVCBKeyValue returns an SVCBKeyValue struct with the key or nil for reserved keys.
|
||||
func makeSVCBKeyValue(key SVCBKey) SVCBKeyValue {
|
||||
switch key {
|
||||
case SVCB_MANDATORY:
|
||||
return new(SVCBMandatory)
|
||||
case SVCB_ALPN:
|
||||
return new(SVCBAlpn)
|
||||
case SVCB_NO_DEFAULT_ALPN:
|
||||
return new(SVCBNoDefaultAlpn)
|
||||
case SVCB_PORT:
|
||||
return new(SVCBPort)
|
||||
case SVCB_IPV4HINT:
|
||||
return new(SVCBIPv4Hint)
|
||||
case SVCB_ECHCONFIG:
|
||||
return new(SVCBECHConfig)
|
||||
case SVCB_IPV6HINT:
|
||||
return new(SVCBIPv6Hint)
|
||||
case svcb_RESERVED:
|
||||
return nil
|
||||
default:
|
||||
e := new(SVCBLocal)
|
||||
e.KeyCode = key
|
||||
return e
|
||||
}
|
||||
}
|
||||
|
||||
// SVCB RR. See RFC xxxx (https://tools.ietf.org/html/draft-ietf-dnsop-svcb-https-01).
|
||||
type SVCB struct {
|
||||
Hdr RR_Header
|
||||
Priority uint16
|
||||
Target string `dns:"domain-name"`
|
||||
Value []SVCBKeyValue `dns:"pairs"` // Value must be empty if Priority is zero.
|
||||
}
|
||||
|
||||
// HTTPS RR. Everything valid for SVCB applies to HTTPS as well.
|
||||
// Except that the HTTPS record is intended for use with the HTTP and HTTPS protocols.
|
||||
type HTTPS struct {
|
||||
SVCB
|
||||
}
|
||||
|
||||
func (rr *HTTPS) String() string {
|
||||
return rr.SVCB.String()
|
||||
}
|
||||
|
||||
func (rr *HTTPS) parse(c *zlexer, o string) *ParseError {
|
||||
return rr.SVCB.parse(c, o)
|
||||
}
|
||||
|
||||
// SVCBKeyValue defines a key=value pair for the SVCB RR type.
|
||||
// An SVCB RR can have multiple SVCBKeyValues appended to it.
|
||||
type SVCBKeyValue interface {
|
||||
Key() SVCBKey // Key returns the numerical key code.
|
||||
pack() ([]byte, error) // pack returns the encoded value.
|
||||
unpack([]byte) error // unpack sets the value.
|
||||
String() string // String returns the string representation of the value.
|
||||
parse(string) error // parse sets the value to the given string representation of the value.
|
||||
copy() SVCBKeyValue // copy returns a deep-copy of the pair.
|
||||
len() int // len returns the length of value in the wire format.
|
||||
}
|
||||
|
||||
// SVCBMandatory pair adds to required keys that must be interpreted for the RR
|
||||
// to be functional.
|
||||
// Basic use pattern for creating a mandatory option:
|
||||
//
|
||||
// s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}}
|
||||
// e := new(dns.SVCBMandatory)
|
||||
// e.Code = []uint16{65403}
|
||||
// s.Value = append(s.Value, e)
|
||||
type SVCBMandatory struct {
|
||||
Code []SVCBKey // Must not include mandatory
|
||||
}
|
||||
|
||||
func (*SVCBMandatory) Key() SVCBKey { return SVCB_MANDATORY }
|
||||
|
||||
func (s *SVCBMandatory) String() string {
|
||||
str := make([]string, len(s.Code))
|
||||
for i, e := range s.Code {
|
||||
str[i] = e.String()
|
||||
}
|
||||
return strings.Join(str, ",")
|
||||
}
|
||||
|
||||
func (s *SVCBMandatory) pack() ([]byte, error) {
|
||||
codes := append([]SVCBKey(nil), s.Code...)
|
||||
sort.Slice(codes, func(i, j int) bool {
|
||||
return codes[i] < codes[j]
|
||||
})
|
||||
b := make([]byte, 2*len(codes))
|
||||
for i, e := range codes {
|
||||
binary.BigEndian.PutUint16(b[2*i:], uint16(e))
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (s *SVCBMandatory) unpack(b []byte) error {
|
||||
if len(b)%2 != 0 {
|
||||
return errors.New("dns: svcbmandatory: value length is not a multiple of 2")
|
||||
}
|
||||
codes := make([]SVCBKey, 0, len(b)/2)
|
||||
for i := 0; i < len(b); i += 2 {
|
||||
// We assume strictly increasing order.
|
||||
codes = append(codes, SVCBKey(binary.BigEndian.Uint16(b[i:])))
|
||||
}
|
||||
s.Code = codes
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SVCBMandatory) parse(b string) error {
|
||||
str := strings.Split(b, ",")
|
||||
codes := make([]SVCBKey, 0, len(str))
|
||||
for _, e := range str {
|
||||
codes = append(codes, svcbStringToKey(e))
|
||||
}
|
||||
s.Code = codes
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SVCBMandatory) len() int {
|
||||
return 2 * len(s.Code)
|
||||
}
|
||||
|
||||
func (s *SVCBMandatory) copy() SVCBKeyValue {
|
||||
return &SVCBMandatory{
|
||||
append([]SVCBKey(nil), s.Code...),
|
||||
}
|
||||
}
|
||||
|
||||
// SVCBAlpn pair is used to list supported connection protocols.
|
||||
// Protocol ids can be found at:
|
||||
// https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
|
||||
// Basic use pattern for creating an alpn option:
|
||||
//
|
||||
// h := new(dns.HTTPS)
|
||||
// h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
|
||||
// e := new(dns.SVCBAlpn)
|
||||
// e.Alpn = []string{"h2", "http/1.1"}
|
||||
// h.Value = append(o.Value, e)
|
||||
type SVCBAlpn struct {
|
||||
Alpn []string
|
||||
}
|
||||
|
||||
func (*SVCBAlpn) Key() SVCBKey { return SVCB_ALPN }
|
||||
func (s *SVCBAlpn) String() string { return strings.Join(s.Alpn, ",") }
|
||||
|
||||
func (s *SVCBAlpn) pack() ([]byte, error) {
|
||||
// Liberally estimate the size of an alpn as 10 octets
|
||||
b := make([]byte, 0, 10*len(s.Alpn))
|
||||
for _, e := range s.Alpn {
|
||||
if 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 {
|
||||
s.Alpn = strings.Split(b, ",")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SVCBAlpn) len() int {
|
||||
var l int
|
||||
for _, e := range s.Alpn {
|
||||
l += 1 + len(e)
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
func (s *SVCBAlpn) copy() SVCBKeyValue {
|
||||
return &SVCBAlpn{
|
||||
append([]string(nil), s.Alpn...),
|
||||
}
|
||||
}
|
||||
|
||||
// SVCBNoDefaultAlpn pair signifies no support for default connection protocols.
|
||||
// Basic use pattern for creating a no-default-alpn option:
|
||||
//
|
||||
// s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}}
|
||||
// e := new(dns.SVCBNoDefaultAlpn)
|
||||
// s.Value = append(s.Value, e)
|
||||
type SVCBNoDefaultAlpn struct{}
|
||||
|
||||
func (*SVCBNoDefaultAlpn) Key() SVCBKey { return SVCB_NO_DEFAULT_ALPN }
|
||||
func (*SVCBNoDefaultAlpn) copy() SVCBKeyValue { return &SVCBNoDefaultAlpn{} }
|
||||
func (*SVCBNoDefaultAlpn) pack() ([]byte, error) { return []byte{}, nil }
|
||||
func (*SVCBNoDefaultAlpn) String() string { return "" }
|
||||
func (*SVCBNoDefaultAlpn) len() int { return 0 }
|
||||
|
||||
func (*SVCBNoDefaultAlpn) unpack(b []byte) error {
|
||||
if len(b) != 0 {
|
||||
return errors.New("dns: svcbnodefaultalpn: no_default_alpn must have no value")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*SVCBNoDefaultAlpn) parse(b string) error {
|
||||
if 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 echconfig option:
|
||||
//
|
||||
// h := new(dns.HTTPS)
|
||||
// h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
|
||||
// e := new(dns.SVCBECHConfig)
|
||||
// e.ECH = []byte{0xfe, 0x08, ...}
|
||||
// h.Value = append(h.Value, e)
|
||||
type SVCBECHConfig struct {
|
||||
ECH []byte
|
||||
}
|
||||
|
||||
func (*SVCBECHConfig) Key() SVCBKey { return SVCB_ECHCONFIG }
|
||||
func (s *SVCBECHConfig) String() string { return toBase64(s.ECH) }
|
||||
func (s *SVCBECHConfig) len() int { return len(s.ECH) }
|
||||
|
||||
func (s *SVCBECHConfig) pack() ([]byte, error) {
|
||||
return append([]byte(nil), s.ECH...), nil
|
||||
}
|
||||
|
||||
func (s *SVCBECHConfig) copy() SVCBKeyValue {
|
||||
return &SVCBECHConfig{
|
||||
append([]byte(nil), s.ECH...),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SVCBECHConfig) unpack(b []byte) error {
|
||||
s.ECH = append([]byte(nil), b...)
|
||||
return nil
|
||||
}
|
||||
func (s *SVCBECHConfig) parse(b string) error {
|
||||
x, err := fromBase64([]byte(b))
|
||||
if err != nil {
|
||||
return errors.New("dns: svcbechconfig: bad base64 echconfig")
|
||||
}
|
||||
s.ECH = x
|
||||
return nil
|
||||
}
|
||||
|
||||
// SVCBIPv6Hint pair suggests an IPv6 address which may be used to open connections
|
||||
// if A and AAAA record responses for SVCB's Target domain haven't been received.
|
||||
// In that case, optionally, A and AAAA requests can be made, after which the
|
||||
// connection to the hinted IP address may be terminated and a new connection may be opened.
|
||||
// Basic use pattern for creating an ipv6hint option:
|
||||
//
|
||||
// h := new(dns.HTTPS)
|
||||
// h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
|
||||
// e := new(dns.SVCBIPv6Hint)
|
||||
// e.Hint = []net.IP{net.ParseIP("2001:db8::1")}
|
||||
// h.Value = append(h.Value, e)
|
||||
type SVCBIPv6Hint struct {
|
||||
Hint []net.IP
|
||||
}
|
||||
|
||||
func (*SVCBIPv6Hint) Key() SVCBKey { return SVCB_IPV6HINT }
|
||||
func (s *SVCBIPv6Hint) len() int { return 16 * len(s.Hint) }
|
||||
|
||||
func (s *SVCBIPv6Hint) pack() ([]byte, error) {
|
||||
b := make([]byte, 0, 16*len(s.Hint))
|
||||
for _, e := range s.Hint {
|
||||
if len(e) != net.IPv6len || e.To4() != nil {
|
||||
return nil, errors.New("dns: svcbipv6hint: expected ipv6, hint is ipv4")
|
||||
}
|
||||
b = append(b, e...)
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (s *SVCBIPv6Hint) unpack(b []byte) error {
|
||||
if len(b) == 0 || len(b)%16 != 0 {
|
||||
return errors.New("dns: svcbipv6hint: ipv6 address byte array length not a multiple of 16")
|
||||
}
|
||||
x := make([]net.IP, 0, len(b)/16)
|
||||
for i := 0; i < len(b); i += 16 {
|
||||
ip := net.IP(b[i : i+16])
|
||||
if ip.To4() != nil {
|
||||
return errors.New("dns: svcbipv6hint: expected ipv6, got ipv4")
|
||||
}
|
||||
x = append(x, ip)
|
||||
}
|
||||
s.Hint = x
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SVCBIPv6Hint) String() string {
|
||||
str := make([]string, len(s.Hint))
|
||||
for i, e := range s.Hint {
|
||||
if x := e.To4(); x != nil {
|
||||
return "<nil>"
|
||||
}
|
||||
str[i] = e.String()
|
||||
}
|
||||
return strings.Join(str, ",")
|
||||
}
|
||||
|
||||
func (s *SVCBIPv6Hint) parse(b string) error {
|
||||
if strings.Contains(b, ".") {
|
||||
return errors.New("dns: svcbipv6hint: expected ipv6, got ipv4")
|
||||
}
|
||||
str := strings.Split(b, ",")
|
||||
dst := make([]net.IP, len(str))
|
||||
for i, e := range str {
|
||||
ip := net.ParseIP(e)
|
||||
if ip == nil {
|
||||
return errors.New("dns: svcbipv6hint: bad ip")
|
||||
}
|
||||
dst[i] = ip
|
||||
}
|
||||
s.Hint = dst
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SVCBIPv6Hint) copy() SVCBKeyValue {
|
||||
hint := make([]net.IP, len(s.Hint))
|
||||
for i, ip := range s.Hint {
|
||||
hint[i] = copyIP(ip)
|
||||
}
|
||||
|
||||
return &SVCBIPv6Hint{
|
||||
Hint: hint,
|
||||
}
|
||||
}
|
||||
|
||||
// SVCBLocal pair is intended for experimental/private use. The key is recommended
|
||||
// to be in the range [SVCB_PRIVATE_LOWER, SVCB_PRIVATE_UPPER].
|
||||
// Basic use pattern for creating a keyNNNNN option:
|
||||
//
|
||||
// h := new(dns.HTTPS)
|
||||
// h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
|
||||
// e := new(dns.SVCBLocal)
|
||||
// e.KeyCode = 65400
|
||||
// e.Data = []byte("abc")
|
||||
// h.Value = append(h.Value, e)
|
||||
type SVCBLocal struct {
|
||||
KeyCode SVCBKey // Never 65535 or any assigned keys.
|
||||
Data []byte // All byte sequences are allowed.
|
||||
}
|
||||
|
||||
func (s *SVCBLocal) Key() SVCBKey { return s.KeyCode }
|
||||
func (s *SVCBLocal) pack() ([]byte, error) { return append([]byte(nil), s.Data...), nil }
|
||||
func (s *SVCBLocal) len() int { return len(s.Data) }
|
||||
|
||||
func (s *SVCBLocal) unpack(b []byte) error {
|
||||
s.Data = append([]byte(nil), b...)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SVCBLocal) String() string {
|
||||
var str strings.Builder
|
||||
str.Grow(4 * len(s.Data))
|
||||
for _, e := range s.Data {
|
||||
if ' ' <= e && e <= '~' {
|
||||
switch e {
|
||||
case '"', ';', ' ', '\\':
|
||||
str.WriteByte('\\')
|
||||
str.WriteByte(e)
|
||||
default:
|
||||
str.WriteByte(e)
|
||||
}
|
||||
} else {
|
||||
str.WriteString(escapeByte(e))
|
||||
}
|
||||
}
|
||||
return str.String()
|
||||
}
|
||||
|
||||
func (s *SVCBLocal) parse(b string) error {
|
||||
data := make([]byte, 0, len(b))
|
||||
for i := 0; i < len(b); {
|
||||
if b[i] != '\\' {
|
||||
data = append(data, b[i])
|
||||
i++
|
||||
continue
|
||||
}
|
||||
if i+1 == len(b) {
|
||||
return errors.New("dns: svcblocal: svcb private/experimental key escape unterminated")
|
||||
}
|
||||
if isDigit(b[i+1]) {
|
||||
if i+3 < len(b) && isDigit(b[i+2]) && isDigit(b[i+3]) {
|
||||
a, err := strconv.ParseUint(b[i+1:i+4], 10, 8)
|
||||
if err == nil {
|
||||
i += 4
|
||||
data = append(data, byte(a))
|
||||
continue
|
||||
}
|
||||
}
|
||||
return errors.New("dns: svcblocal: svcb private/experimental key bad escaped octet")
|
||||
} else {
|
||||
data = append(data, b[i+1])
|
||||
i += 2
|
||||
}
|
||||
}
|
||||
s.Data = data
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SVCBLocal) copy() SVCBKeyValue {
|
||||
return &SVCBLocal{s.KeyCode,
|
||||
append([]byte(nil), s.Data...),
|
||||
}
|
||||
}
|
||||
|
||||
func (rr *SVCB) String() string {
|
||||
s := rr.Hdr.String() +
|
||||
strconv.Itoa(int(rr.Priority)) + " " +
|
||||
sprintName(rr.Target)
|
||||
for _, e := range rr.Value {
|
||||
s += " " + e.Key().String() + "=\"" + e.String() + "\""
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// areSVCBPairArraysEqual checks if SVCBKeyValue arrays are equal after sorting their
|
||||
// copies. arrA and arrB have equal lengths, otherwise zduplicate.go wouldn't call this function.
|
||||
func areSVCBPairArraysEqual(a []SVCBKeyValue, b []SVCBKeyValue) bool {
|
||||
a = append([]SVCBKeyValue(nil), a...)
|
||||
b = append([]SVCBKeyValue(nil), b...)
|
||||
sort.Slice(a, func(i, j int) bool { return a[i].Key() < a[j].Key() })
|
||||
sort.Slice(b, func(i, j int) bool { return b[i].Key() < b[j].Key() })
|
||||
for i, e := range a {
|
||||
if e.Key() != b[i].Key() {
|
||||
return false
|
||||
}
|
||||
b1, err1 := e.pack()
|
||||
b2, err2 := b[i].pack()
|
||||
if err1 != nil || err2 != nil || !bytes.Equal(b1, b2) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
@ -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"
|
||||
|
|
@ -2,7 +2,6 @@ package dns
|
|||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/md5"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
|
|
@ -16,12 +15,65 @@ import (
|
|||
|
||||
// HMAC hashing codes. These are transmitted as domain names.
|
||||
const (
|
||||
HmacMD5 = "hmac-md5.sig-alg.reg.int."
|
||||
HmacSHA1 = "hmac-sha1."
|
||||
HmacSHA224 = "hmac-sha224."
|
||||
HmacSHA256 = "hmac-sha256."
|
||||
HmacSHA384 = "hmac-sha384."
|
||||
HmacSHA512 = "hmac-sha512."
|
||||
|
||||
HmacMD5 = "hmac-md5.sig-alg.reg.int." // Deprecated: HmacMD5 is no longer supported.
|
||||
)
|
||||
|
||||
// TsigProvider provides the API to plug-in a custom TSIG implementation.
|
||||
type TsigProvider interface {
|
||||
// Generate is passed the DNS message to be signed and the partial TSIG RR. It returns the signature and nil, otherwise an error.
|
||||
Generate(msg []byte, t *TSIG) ([]byte, error)
|
||||
// Verify is passed the DNS message to be verified and the TSIG RR. If the signature is valid it will return nil, otherwise an error.
|
||||
Verify(msg []byte, t *TSIG) error
|
||||
}
|
||||
|
||||
type tsigHMACProvider string
|
||||
|
||||
func (key tsigHMACProvider) Generate(msg []byte, t *TSIG) ([]byte, error) {
|
||||
// If we barf here, the caller is to blame
|
||||
rawsecret, err := fromBase64([]byte(key))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var h hash.Hash
|
||||
switch CanonicalName(t.Algorithm) {
|
||||
case HmacSHA1:
|
||||
h = hmac.New(sha1.New, rawsecret)
|
||||
case HmacSHA224:
|
||||
h = hmac.New(sha256.New224, rawsecret)
|
||||
case HmacSHA256:
|
||||
h = hmac.New(sha256.New, rawsecret)
|
||||
case HmacSHA384:
|
||||
h = hmac.New(sha512.New384, rawsecret)
|
||||
case HmacSHA512:
|
||||
h = hmac.New(sha512.New, rawsecret)
|
||||
default:
|
||||
return nil, ErrKeyAlg
|
||||
}
|
||||
h.Write(msg)
|
||||
return h.Sum(nil), nil
|
||||
}
|
||||
|
||||
func (key tsigHMACProvider) Verify(msg []byte, t *TSIG) error {
|
||||
b, err := key.Generate(msg, t)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mac, err := hex.DecodeString(t.MAC)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !hmac.Equal(b, mac) {
|
||||
return ErrSig
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TSIG is the RR the holds the transaction signature of a message.
|
||||
// See RFC 2845 and RFC 4635.
|
||||
type TSIG struct {
|
||||
|
|
@ -54,8 +106,8 @@ func (rr *TSIG) String() string {
|
|||
return s
|
||||
}
|
||||
|
||||
func (rr *TSIG) parse(c *zlexer, origin string) *ParseError {
|
||||
panic("dns: internal error: parse should never be called on TSIG")
|
||||
func (*TSIG) parse(c *zlexer, origin string) *ParseError {
|
||||
return &ParseError{err: "TSIG records do not have a presentation format"}
|
||||
}
|
||||
|
||||
// The following values must be put in wireformat, so that the MAC can be calculated.
|
||||
|
|
@ -96,14 +148,13 @@ type timerWireFmt struct {
|
|||
// timersOnly is false.
|
||||
// If something goes wrong an error is returned, otherwise it is nil.
|
||||
func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, string, error) {
|
||||
return tsigGenerateProvider(m, tsigHMACProvider(secret), requestMAC, timersOnly)
|
||||
}
|
||||
|
||||
func tsigGenerateProvider(m *Msg, provider TsigProvider, requestMAC string, timersOnly bool) ([]byte, string, error) {
|
||||
if m.IsTsig() == nil {
|
||||
panic("dns: TSIG not last RR in additional")
|
||||
}
|
||||
// If we barf here, the caller is to blame
|
||||
rawsecret, err := fromBase64([]byte(secret))
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
rr := m.Extra[len(m.Extra)-1].(*TSIG)
|
||||
m.Extra = m.Extra[0 : len(m.Extra)-1] // kill the TSIG from the msg
|
||||
|
|
@ -111,31 +162,29 @@ func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, s
|
|||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
buf := tsigBuffer(mbuf, rr, requestMAC, timersOnly)
|
||||
|
||||
buf, err := tsigBuffer(mbuf, rr, requestMAC, timersOnly)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
t := new(TSIG)
|
||||
var h hash.Hash
|
||||
switch CanonicalName(rr.Algorithm) {
|
||||
case HmacMD5:
|
||||
h = hmac.New(md5.New, rawsecret)
|
||||
case HmacSHA1:
|
||||
h = hmac.New(sha1.New, rawsecret)
|
||||
case HmacSHA256:
|
||||
h = hmac.New(sha256.New, rawsecret)
|
||||
case HmacSHA512:
|
||||
h = hmac.New(sha512.New, rawsecret)
|
||||
default:
|
||||
return nil, "", ErrKeyAlg
|
||||
}
|
||||
h.Write(buf)
|
||||
t.MAC = hex.EncodeToString(h.Sum(nil))
|
||||
t.MACSize = uint16(len(t.MAC) / 2) // Size is half!
|
||||
// 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
|
||||
|
||||
t.Hdr = RR_Header{Name: rr.Hdr.Name, Rrtype: TypeTSIG, Class: ClassANY, Ttl: 0}
|
||||
t.Fudge = rr.Fudge
|
||||
t.TimeSigned = rr.TimeSigned
|
||||
t.Algorithm = rr.Algorithm
|
||||
t.OrigId = m.Id
|
||||
// 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)
|
||||
|
|
@ -153,26 +202,34 @@ func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, s
|
|||
// If the signature does not validate err contains the
|
||||
// error, otherwise it is nil.
|
||||
func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error {
|
||||
rawsecret, err := fromBase64([]byte(secret))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tsigVerify(msg, tsigHMACProvider(secret), requestMAC, timersOnly, uint64(time.Now().Unix()))
|
||||
}
|
||||
|
||||
func tsigVerifyProvider(msg []byte, provider TsigProvider, requestMAC string, timersOnly bool) error {
|
||||
return tsigVerify(msg, provider, requestMAC, timersOnly, uint64(time.Now().Unix()))
|
||||
}
|
||||
|
||||
// actual implementation of TsigVerify, taking the current time ('now') as a parameter for the convenience of tests.
|
||||
func tsigVerify(msg []byte, provider TsigProvider, requestMAC string, timersOnly bool, now uint64) error {
|
||||
// Strip the TSIG from the incoming msg
|
||||
stripped, tsig, err := stripTsig(msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgMAC, err := hex.DecodeString(tsig.MAC)
|
||||
buf, err := tsigBuffer(stripped, tsig, requestMAC, timersOnly)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
buf := tsigBuffer(stripped, tsig, requestMAC, timersOnly)
|
||||
if err := provider.Verify(buf, tsig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Fudge factor works both ways. A message can arrive before it was signed because
|
||||
// of clock skew.
|
||||
now := uint64(time.Now().Unix())
|
||||
// We check this after verifying the signature, following draft-ietf-dnsop-rfc2845bis
|
||||
// instead of RFC2845, in order to prevent a security vulnerability as reported in CVE-2017-3142/3143.
|
||||
ti := now - tsig.TimeSigned
|
||||
if now < tsig.TimeSigned {
|
||||
ti = tsig.TimeSigned - now
|
||||
|
|
@ -181,28 +238,11 @@ func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error {
|
|||
return ErrTime
|
||||
}
|
||||
|
||||
var h hash.Hash
|
||||
switch CanonicalName(tsig.Algorithm) {
|
||||
case HmacMD5:
|
||||
h = hmac.New(md5.New, rawsecret)
|
||||
case HmacSHA1:
|
||||
h = hmac.New(sha1.New, rawsecret)
|
||||
case HmacSHA256:
|
||||
h = hmac.New(sha256.New, rawsecret)
|
||||
case HmacSHA512:
|
||||
h = hmac.New(sha512.New, rawsecret)
|
||||
default:
|
||||
return ErrKeyAlg
|
||||
}
|
||||
h.Write(buf)
|
||||
if !hmac.Equal(h.Sum(nil), msgMAC) {
|
||||
return ErrSig
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create a wiredata buffer for the MAC calculation.
|
||||
func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []byte {
|
||||
func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) ([]byte, error) {
|
||||
var buf []byte
|
||||
if rr.TimeSigned == 0 {
|
||||
rr.TimeSigned = uint64(time.Now().Unix())
|
||||
|
|
@ -219,7 +259,10 @@ func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []b
|
|||
m.MACSize = uint16(len(requestMAC) / 2)
|
||||
m.MAC = requestMAC
|
||||
buf = make([]byte, len(requestMAC)) // long enough
|
||||
n, _ := packMacWire(m, buf)
|
||||
n, err := packMacWire(m, buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
buf = buf[:n]
|
||||
}
|
||||
|
||||
|
|
@ -228,7 +271,10 @@ func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []b
|
|||
tsig := new(timerWireFmt)
|
||||
tsig.TimeSigned = rr.TimeSigned
|
||||
tsig.Fudge = rr.Fudge
|
||||
n, _ := packTimerWire(tsig, tsigvar)
|
||||
n, err := packTimerWire(tsig, tsigvar)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tsigvar = tsigvar[:n]
|
||||
} else {
|
||||
tsig := new(tsigWireFmt)
|
||||
|
|
@ -241,7 +287,10 @@ func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []b
|
|||
tsig.Error = rr.Error
|
||||
tsig.OtherLen = rr.OtherLen
|
||||
tsig.OtherData = rr.OtherData
|
||||
n, _ := packTsigWire(tsig, tsigvar)
|
||||
n, err := packTsigWire(tsig, tsigvar)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tsigvar = tsigvar[:n]
|
||||
}
|
||||
|
||||
|
|
@ -251,7 +300,7 @@ func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []b
|
|||
} else {
|
||||
buf = append(msgbuf, tsigvar...)
|
||||
}
|
||||
return buf
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
// Strip the TSIG from the raw message.
|
||||
|
|
|
|||
|
|
@ -81,6 +81,9 @@ const (
|
|||
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
|
||||
|
|
@ -148,6 +151,14 @@ const (
|
|||
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
|
||||
|
|
@ -243,8 +254,8 @@ type ANY struct {
|
|||
|
||||
func (rr *ANY) String() string { return rr.Hdr.String() }
|
||||
|
||||
func (rr *ANY) parse(c *zlexer, origin string) *ParseError {
|
||||
panic("dns: internal error: parse should never be called on ANY")
|
||||
func (*ANY) parse(c *zlexer, origin string) *ParseError {
|
||||
return &ParseError{err: "ANY records do not have a presentation format"}
|
||||
}
|
||||
|
||||
// NULL RR. See RFC 1035.
|
||||
|
|
@ -258,8 +269,8 @@ func (rr *NULL) String() string {
|
|||
return ";" + rr.Hdr.String() + rr.Data
|
||||
}
|
||||
|
||||
func (rr *NULL) parse(c *zlexer, origin string) *ParseError {
|
||||
panic("dns: internal error: parse should never be called on NULL")
|
||||
func (*NULL) parse(c *zlexer, origin string) *ParseError {
|
||||
return &ParseError{err: "NULL records do not have a presentation format"}
|
||||
}
|
||||
|
||||
// CNAME RR. See RFC 1034.
|
||||
|
|
@ -1359,6 +1370,23 @@ func (rr *CSYNC) len(off int, compression map[string]struct{}) int {
|
|||
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
|
||||
|
|
@ -1385,13 +1413,13 @@ func (rr *APL) String() string {
|
|||
}
|
||||
|
||||
// str returns presentation form of the APL prefix.
|
||||
func (p *APLPrefix) str() string {
|
||||
func (a *APLPrefix) str() string {
|
||||
var sb strings.Builder
|
||||
if p.Negation {
|
||||
if a.Negation {
|
||||
sb.WriteByte('!')
|
||||
}
|
||||
|
||||
switch len(p.Network.IP) {
|
||||
switch len(a.Network.IP) {
|
||||
case net.IPv4len:
|
||||
sb.WriteByte('1')
|
||||
case net.IPv6len:
|
||||
|
|
@ -1400,20 +1428,20 @@ func (p *APLPrefix) str() string {
|
|||
|
||||
sb.WriteByte(':')
|
||||
|
||||
switch len(p.Network.IP) {
|
||||
switch len(a.Network.IP) {
|
||||
case net.IPv4len:
|
||||
sb.WriteString(p.Network.IP.String())
|
||||
sb.WriteString(a.Network.IP.String())
|
||||
case net.IPv6len:
|
||||
// add prefix for IPv4-mapped IPv6
|
||||
if v4 := p.Network.IP.To4(); v4 != nil {
|
||||
if v4 := a.Network.IP.To4(); v4 != nil {
|
||||
sb.WriteString("::ffff:")
|
||||
}
|
||||
sb.WriteString(p.Network.IP.String())
|
||||
sb.WriteString(a.Network.IP.String())
|
||||
}
|
||||
|
||||
sb.WriteByte('/')
|
||||
|
||||
prefix, _ := p.Network.Mask.Size()
|
||||
prefix, _ := a.Network.Mask.Size()
|
||||
sb.WriteString(strconv.Itoa(prefix))
|
||||
|
||||
return sb.String()
|
||||
|
|
@ -1427,17 +1455,17 @@ func (a *APLPrefix) equals(b *APLPrefix) bool {
|
|||
}
|
||||
|
||||
// copy returns a copy of the APL prefix.
|
||||
func (p *APLPrefix) copy() APLPrefix {
|
||||
func (a *APLPrefix) copy() APLPrefix {
|
||||
return APLPrefix{
|
||||
Negation: p.Negation,
|
||||
Network: copyNet(p.Network),
|
||||
Negation: a.Negation,
|
||||
Network: copyNet(a.Network),
|
||||
}
|
||||
}
|
||||
|
||||
// len returns size of the prefix in wire format.
|
||||
func (p *APLPrefix) len() int {
|
||||
func (a *APLPrefix) len() int {
|
||||
// 4-byte header and the network address prefix (see Section 4 of RFC 3123)
|
||||
prefix, _ := p.Network.Mask.Size()
|
||||
prefix, _ := a.Network.Mask.Size()
|
||||
return 4 + (prefix+7)/8
|
||||
}
|
||||
|
||||
|
|
@ -1470,7 +1498,7 @@ func StringToTime(s string) (uint32, error) {
|
|||
|
||||
// saltToString converts a NSECX salt to uppercase and returns "-" when it is empty.
|
||||
func saltToString(s string) string {
|
||||
if len(s) == 0 {
|
||||
if s == "" {
|
||||
return "-"
|
||||
}
|
||||
return strings.ToUpper(s)
|
||||
|
|
|
|||
|
|
@ -32,7 +32,9 @@ func (u *Msg) Used(rr []RR) {
|
|||
u.Answer = make([]RR, 0, len(rr))
|
||||
}
|
||||
for _, r := range rr {
|
||||
r.Header().Class = u.Question[0].Qclass
|
||||
hdr := r.Header()
|
||||
hdr.Class = u.Question[0].Qclass
|
||||
hdr.Ttl = 0
|
||||
u.Answer = append(u.Answer, r)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package dns
|
|||
import "fmt"
|
||||
|
||||
// Version is current version of this library.
|
||||
var Version = v{1, 1, 30}
|
||||
var Version = v{1, 1, 45}
|
||||
|
||||
// v holds the version of this library.
|
||||
type v struct {
|
||||
|
|
|
|||
|
|
@ -402,6 +402,27 @@ func (r1 *HIP) isDuplicate(_r2 RR) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (r1 *HTTPS) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*HTTPS)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Priority != r2.Priority {
|
||||
return false
|
||||
}
|
||||
if !isDuplicateName(r1.Target, r2.Target) {
|
||||
return false
|
||||
}
|
||||
if len(r1.Value) != len(r2.Value) {
|
||||
return false
|
||||
}
|
||||
if !areSVCBPairArraysEqual(r1.Value, r2.Value) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (r1 *KEY) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*KEY)
|
||||
if !ok {
|
||||
|
|
@ -1076,6 +1097,27 @@ func (r1 *SSHFP) isDuplicate(_r2 RR) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (r1 *SVCB) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*SVCB)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Priority != r2.Priority {
|
||||
return false
|
||||
}
|
||||
if !isDuplicateName(r1.Target, r2.Target) {
|
||||
return false
|
||||
}
|
||||
if len(r1.Value) != len(r2.Value) {
|
||||
return false
|
||||
}
|
||||
if !areSVCBPairArraysEqual(r1.Value, r2.Value) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (r1 *TA) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*TA)
|
||||
if !ok {
|
||||
|
|
@ -1275,3 +1317,24 @@ func (r1 *X25) isDuplicate(_r2 RR) bool {
|
|||
}
|
||||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -316,6 +316,22 @@ func (rr *HIP) pack(msg []byte, off int, compression compressionMap, compress bo
|
|||
return off, nil
|
||||
}
|
||||
|
||||
func (rr *HTTPS) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
|
||||
off, err = packUint16(rr.Priority, msg, off)
|
||||
if err != nil {
|
||||
return off, err
|
||||
}
|
||||
off, err = packDomainName(rr.Target, msg, off, compression, false)
|
||||
if err != nil {
|
||||
return off, err
|
||||
}
|
||||
off, err = packDataSVCB(rr.Value, msg, off)
|
||||
if err != nil {
|
||||
return off, err
|
||||
}
|
||||
return off, nil
|
||||
}
|
||||
|
||||
func (rr *KEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
|
||||
off, err = packUint16(rr.Flags, msg, off)
|
||||
if err != nil {
|
||||
|
|
@ -906,6 +922,22 @@ func (rr *SSHFP) pack(msg []byte, off int, compression compressionMap, compress
|
|||
return off, nil
|
||||
}
|
||||
|
||||
func (rr *SVCB) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
|
||||
off, err = packUint16(rr.Priority, msg, off)
|
||||
if err != nil {
|
||||
return off, err
|
||||
}
|
||||
off, err = packDomainName(rr.Target, msg, off, compression, false)
|
||||
if err != nil {
|
||||
return off, err
|
||||
}
|
||||
off, err = packDataSVCB(rr.Value, msg, off)
|
||||
if err != nil {
|
||||
return off, err
|
||||
}
|
||||
return off, nil
|
||||
}
|
||||
|
||||
func (rr *TA) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
|
||||
off, err = packUint16(rr.KeyTag, msg, off)
|
||||
if err != nil {
|
||||
|
|
@ -1086,6 +1118,26 @@ func (rr *X25) pack(msg []byte, off int, compression compressionMap, compress bo
|
|||
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) {
|
||||
|
|
@ -1559,6 +1611,31 @@ func (rr *HIP) unpack(msg []byte, off int) (off1 int, err error) {
|
|||
return off, nil
|
||||
}
|
||||
|
||||
func (rr *HTTPS) unpack(msg []byte, off int) (off1 int, err error) {
|
||||
rdStart := off
|
||||
_ = rdStart
|
||||
|
||||
rr.Priority, off, err = unpackUint16(msg, off)
|
||||
if err != nil {
|
||||
return off, err
|
||||
}
|
||||
if off == len(msg) {
|
||||
return off, nil
|
||||
}
|
||||
rr.Target, off, err = UnpackDomainName(msg, off)
|
||||
if err != nil {
|
||||
return off, err
|
||||
}
|
||||
if off == len(msg) {
|
||||
return off, nil
|
||||
}
|
||||
rr.Value, off, err = unpackDataSVCB(msg, off)
|
||||
if err != nil {
|
||||
return off, err
|
||||
}
|
||||
return off, nil
|
||||
}
|
||||
|
||||
func (rr *KEY) unpack(msg []byte, off int) (off1 int, err error) {
|
||||
rdStart := off
|
||||
_ = rdStart
|
||||
|
|
@ -2461,6 +2538,31 @@ func (rr *SSHFP) unpack(msg []byte, off int) (off1 int, err error) {
|
|||
return off, nil
|
||||
}
|
||||
|
||||
func (rr *SVCB) unpack(msg []byte, off int) (off1 int, err error) {
|
||||
rdStart := off
|
||||
_ = rdStart
|
||||
|
||||
rr.Priority, off, err = unpackUint16(msg, off)
|
||||
if err != nil {
|
||||
return off, err
|
||||
}
|
||||
if off == len(msg) {
|
||||
return off, nil
|
||||
}
|
||||
rr.Target, off, err = UnpackDomainName(msg, off)
|
||||
if err != nil {
|
||||
return off, err
|
||||
}
|
||||
if off == len(msg) {
|
||||
return off, nil
|
||||
}
|
||||
rr.Value, off, err = unpackDataSVCB(msg, off)
|
||||
if err != nil {
|
||||
return off, err
|
||||
}
|
||||
return off, nil
|
||||
}
|
||||
|
||||
func (rr *TA) unpack(msg []byte, off int) (off1 int, err error) {
|
||||
rdStart := off
|
||||
_ = rdStart
|
||||
|
|
@ -2739,3 +2841,35 @@ func (rr *X25) unpack(msg []byte, off int) (off1 int, err error) {
|
|||
}
|
||||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ var TypeToRR = map[uint16]func() RR{
|
|||
TypeGPOS: func() RR { return new(GPOS) },
|
||||
TypeHINFO: func() RR { return new(HINFO) },
|
||||
TypeHIP: func() RR { return new(HIP) },
|
||||
TypeHTTPS: func() RR { return new(HTTPS) },
|
||||
TypeKEY: func() RR { return new(KEY) },
|
||||
TypeKX: func() RR { return new(KX) },
|
||||
TypeL32: func() RR { return new(L32) },
|
||||
|
|
@ -70,6 +71,7 @@ var TypeToRR = map[uint16]func() RR{
|
|||
TypeSPF: func() RR { return new(SPF) },
|
||||
TypeSRV: func() RR { return new(SRV) },
|
||||
TypeSSHFP: func() RR { return new(SSHFP) },
|
||||
TypeSVCB: func() RR { return new(SVCB) },
|
||||
TypeTA: func() RR { return new(TA) },
|
||||
TypeTALINK: func() RR { return new(TALINK) },
|
||||
TypeTKEY: func() RR { return new(TKEY) },
|
||||
|
|
@ -80,6 +82,7 @@ var TypeToRR = map[uint16]func() RR{
|
|||
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.
|
||||
|
|
@ -110,6 +113,7 @@ var TypeToString = map[uint16]string{
|
|||
TypeGPOS: "GPOS",
|
||||
TypeHINFO: "HINFO",
|
||||
TypeHIP: "HIP",
|
||||
TypeHTTPS: "HTTPS",
|
||||
TypeISDN: "ISDN",
|
||||
TypeIXFR: "IXFR",
|
||||
TypeKEY: "KEY",
|
||||
|
|
@ -153,6 +157,7 @@ var TypeToString = map[uint16]string{
|
|||
TypeSPF: "SPF",
|
||||
TypeSRV: "SRV",
|
||||
TypeSSHFP: "SSHFP",
|
||||
TypeSVCB: "SVCB",
|
||||
TypeTA: "TA",
|
||||
TypeTALINK: "TALINK",
|
||||
TypeTKEY: "TKEY",
|
||||
|
|
@ -164,6 +169,7 @@ var TypeToString = map[uint16]string{
|
|||
TypeUNSPEC: "UNSPEC",
|
||||
TypeURI: "URI",
|
||||
TypeX25: "X25",
|
||||
TypeZONEMD: "ZONEMD",
|
||||
TypeNSAPPTR: "NSAP-PTR",
|
||||
}
|
||||
|
||||
|
|
@ -191,6 +197,7 @@ func (rr *GID) Header() *RR_Header { return &rr.Hdr }
|
|||
func (rr *GPOS) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *HINFO) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *HIP) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *HTTPS) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *KEY) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *KX) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *L32) Header() *RR_Header { return &rr.Hdr }
|
||||
|
|
@ -229,6 +236,7 @@ func (rr *SOA) Header() *RR_Header { return &rr.Hdr }
|
|||
func (rr *SPF) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *SRV) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *SSHFP) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *SVCB) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *TA) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *TALINK) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *TKEY) Header() *RR_Header { return &rr.Hdr }
|
||||
|
|
@ -239,6 +247,7 @@ 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 {
|
||||
|
|
@ -592,6 +601,15 @@ func (rr *SSHFP) len(off int, compression map[string]struct{}) int {
|
|||
l += len(rr.FingerPrint) / 2
|
||||
return l
|
||||
}
|
||||
func (rr *SVCB) len(off int, compression map[string]struct{}) int {
|
||||
l := rr.Hdr.len(off, compression)
|
||||
l += 2 // Priority
|
||||
l += domainNameLen(rr.Target, off+l, compression, false)
|
||||
for _, x := range rr.Value {
|
||||
l += 4 + int(x.len())
|
||||
}
|
||||
return l
|
||||
}
|
||||
func (rr *TA) len(off int, compression map[string]struct{}) int {
|
||||
l := rr.Hdr.len(off, compression)
|
||||
l += 2 // KeyTag
|
||||
|
|
@ -669,6 +687,14 @@ func (rr *X25) len(off int, compression map[string]struct{}) int {
|
|||
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 {
|
||||
|
|
@ -753,6 +779,9 @@ func (rr *HIP) copy() RR {
|
|||
copy(RendezvousServers, rr.RendezvousServers)
|
||||
return &HIP{rr.Hdr, rr.HitLength, rr.PublicKeyAlgorithm, rr.PublicKeyLength, rr.Hit, rr.PublicKey, RendezvousServers}
|
||||
}
|
||||
func (rr *HTTPS) copy() RR {
|
||||
return &HTTPS{*rr.SVCB.copy().(*SVCB)}
|
||||
}
|
||||
func (rr *KEY) copy() RR {
|
||||
return &KEY{*rr.DNSKEY.copy().(*DNSKEY)}
|
||||
}
|
||||
|
|
@ -879,6 +908,13 @@ func (rr *SRV) copy() RR {
|
|||
func (rr *SSHFP) copy() RR {
|
||||
return &SSHFP{rr.Hdr, rr.Algorithm, rr.Type, rr.FingerPrint}
|
||||
}
|
||||
func (rr *SVCB) copy() RR {
|
||||
Value := make([]SVCBKeyValue, len(rr.Value))
|
||||
for i, e := range rr.Value {
|
||||
Value[i] = e.copy()
|
||||
}
|
||||
return &SVCB{rr.Hdr, rr.Priority, rr.Target, Value}
|
||||
}
|
||||
func (rr *TA) copy() RR {
|
||||
return &TA{rr.Hdr, rr.KeyTag, rr.Algorithm, rr.DigestType, rr.Digest}
|
||||
}
|
||||
|
|
@ -911,3 +947,6 @@ func (rr *URI) copy() RR {
|
|||
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}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
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.
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
Additional IP Rights Grant (Patents)
|
||||
|
||||
"This implementation" means the copyrightable works distributed by
|
||||
Google as part of the Go project.
|
||||
|
||||
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||
no-charge, royalty-free, irrevocable (except as stated in this section)
|
||||
patent license to make, have made, use, offer to sell, sell, import,
|
||||
transfer and otherwise run, modify and propagate the contents of this
|
||||
implementation of Go, where such license applies only to those patent
|
||||
claims, both currently owned or controlled by Google and acquired in
|
||||
the future, licensable by Google that are necessarily infringed by this
|
||||
implementation of Go. This grant does not include claims that would be
|
||||
infringed only as a consequence of further modification of this
|
||||
implementation. If you or your agent or exclusive licensee institute or
|
||||
order or agree to the institution of patent litigation against any
|
||||
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||
that this implementation of Go or any code incorporated within this
|
||||
implementation of Go constitutes direct or contributory patent
|
||||
infringement, or inducement of patent infringement, then any patent
|
||||
rights granted to you under this License for this implementation of Go
|
||||
shall terminate as of the date such litigation is filed.
|
||||
|
|
@ -0,0 +1,391 @@
|
|||
// 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.
|
||||
|
||||
// Package semver implements comparison of semantic version strings.
|
||||
// In this package, semantic version strings must begin with a leading "v",
|
||||
// as in "v1.0.0".
|
||||
//
|
||||
// The general form of a semantic version string accepted by this package is
|
||||
//
|
||||
// vMAJOR[.MINOR[.PATCH[-PRERELEASE][+BUILD]]]
|
||||
//
|
||||
// where square brackets indicate optional parts of the syntax;
|
||||
// MAJOR, MINOR, and PATCH are decimal integers without extra leading zeros;
|
||||
// PRERELEASE and BUILD are each a series of non-empty dot-separated identifiers
|
||||
// using only alphanumeric characters and hyphens; and
|
||||
// all-numeric PRERELEASE identifiers must not have leading zeros.
|
||||
//
|
||||
// This package follows Semantic Versioning 2.0.0 (see semver.org)
|
||||
// with two exceptions. First, it requires the "v" prefix. Second, it recognizes
|
||||
// vMAJOR and vMAJOR.MINOR (with no prerelease or build suffixes)
|
||||
// as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0.
|
||||
package semver
|
||||
|
||||
// parsed returns the parsed form of a semantic version string.
|
||||
type parsed struct {
|
||||
major string
|
||||
minor string
|
||||
patch string
|
||||
short string
|
||||
prerelease string
|
||||
build string
|
||||
err string
|
||||
}
|
||||
|
||||
// IsValid reports whether v is a valid semantic version string.
|
||||
func IsValid(v string) bool {
|
||||
_, ok := parse(v)
|
||||
return ok
|
||||
}
|
||||
|
||||
// Canonical returns the canonical formatting of the semantic version v.
|
||||
// It fills in any missing .MINOR or .PATCH and discards build metadata.
|
||||
// Two semantic versions compare equal only if their canonical formattings
|
||||
// are identical strings.
|
||||
// The canonical invalid semantic version is the empty string.
|
||||
func Canonical(v string) string {
|
||||
p, ok := parse(v)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
if p.build != "" {
|
||||
return v[:len(v)-len(p.build)]
|
||||
}
|
||||
if p.short != "" {
|
||||
return v + p.short
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Major returns the major version prefix of the semantic version v.
|
||||
// For example, Major("v2.1.0") == "v2".
|
||||
// If v is an invalid semantic version string, Major returns the empty string.
|
||||
func Major(v string) string {
|
||||
pv, ok := parse(v)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return v[:1+len(pv.major)]
|
||||
}
|
||||
|
||||
// MajorMinor returns the major.minor version prefix of the semantic version v.
|
||||
// For example, MajorMinor("v2.1.0") == "v2.1".
|
||||
// If v is an invalid semantic version string, MajorMinor returns the empty string.
|
||||
func MajorMinor(v string) string {
|
||||
pv, ok := parse(v)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
i := 1 + len(pv.major)
|
||||
if j := i + 1 + len(pv.minor); j <= len(v) && v[i] == '.' && v[i+1:j] == pv.minor {
|
||||
return v[:j]
|
||||
}
|
||||
return v[:i] + "." + pv.minor
|
||||
}
|
||||
|
||||
// Prerelease returns the prerelease suffix of the semantic version v.
|
||||
// For example, Prerelease("v2.1.0-pre+meta") == "-pre".
|
||||
// If v is an invalid semantic version string, Prerelease returns the empty string.
|
||||
func Prerelease(v string) string {
|
||||
pv, ok := parse(v)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return pv.prerelease
|
||||
}
|
||||
|
||||
// Build returns the build suffix of the semantic version v.
|
||||
// For example, Build("v2.1.0+meta") == "+meta".
|
||||
// If v is an invalid semantic version string, Build returns the empty string.
|
||||
func Build(v string) string {
|
||||
pv, ok := parse(v)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return pv.build
|
||||
}
|
||||
|
||||
// Compare returns an integer comparing two versions according to
|
||||
// semantic version precedence.
|
||||
// The result will be 0 if v == w, -1 if v < w, or +1 if v > w.
|
||||
//
|
||||
// An invalid semantic version string is considered less than a valid one.
|
||||
// All invalid semantic version strings compare equal to each other.
|
||||
func Compare(v, w string) int {
|
||||
pv, ok1 := parse(v)
|
||||
pw, ok2 := parse(w)
|
||||
if !ok1 && !ok2 {
|
||||
return 0
|
||||
}
|
||||
if !ok1 {
|
||||
return -1
|
||||
}
|
||||
if !ok2 {
|
||||
return +1
|
||||
}
|
||||
if c := compareInt(pv.major, pw.major); c != 0 {
|
||||
return c
|
||||
}
|
||||
if c := compareInt(pv.minor, pw.minor); c != 0 {
|
||||
return c
|
||||
}
|
||||
if c := compareInt(pv.patch, pw.patch); c != 0 {
|
||||
return c
|
||||
}
|
||||
return comparePrerelease(pv.prerelease, pw.prerelease)
|
||||
}
|
||||
|
||||
// Max canonicalizes its arguments and then returns the version string
|
||||
// that compares greater.
|
||||
//
|
||||
// Deprecated: use Compare instead. In most cases, returning a canonicalized
|
||||
// version is not expected or desired.
|
||||
func Max(v, w string) string {
|
||||
v = Canonical(v)
|
||||
w = Canonical(w)
|
||||
if Compare(v, w) > 0 {
|
||||
return v
|
||||
}
|
||||
return w
|
||||
}
|
||||
|
||||
func parse(v string) (p parsed, ok bool) {
|
||||
if v == "" || v[0] != 'v' {
|
||||
p.err = "missing v prefix"
|
||||
return
|
||||
}
|
||||
p.major, v, ok = parseInt(v[1:])
|
||||
if !ok {
|
||||
p.err = "bad major version"
|
||||
return
|
||||
}
|
||||
if v == "" {
|
||||
p.minor = "0"
|
||||
p.patch = "0"
|
||||
p.short = ".0.0"
|
||||
return
|
||||
}
|
||||
if v[0] != '.' {
|
||||
p.err = "bad minor prefix"
|
||||
ok = false
|
||||
return
|
||||
}
|
||||
p.minor, v, ok = parseInt(v[1:])
|
||||
if !ok {
|
||||
p.err = "bad minor version"
|
||||
return
|
||||
}
|
||||
if v == "" {
|
||||
p.patch = "0"
|
||||
p.short = ".0"
|
||||
return
|
||||
}
|
||||
if v[0] != '.' {
|
||||
p.err = "bad patch prefix"
|
||||
ok = false
|
||||
return
|
||||
}
|
||||
p.patch, v, ok = parseInt(v[1:])
|
||||
if !ok {
|
||||
p.err = "bad patch version"
|
||||
return
|
||||
}
|
||||
if len(v) > 0 && v[0] == '-' {
|
||||
p.prerelease, v, ok = parsePrerelease(v)
|
||||
if !ok {
|
||||
p.err = "bad prerelease"
|
||||
return
|
||||
}
|
||||
}
|
||||
if len(v) > 0 && v[0] == '+' {
|
||||
p.build, v, ok = parseBuild(v)
|
||||
if !ok {
|
||||
p.err = "bad build"
|
||||
return
|
||||
}
|
||||
}
|
||||
if v != "" {
|
||||
p.err = "junk on end"
|
||||
ok = false
|
||||
return
|
||||
}
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
|
||||
func parseInt(v string) (t, rest string, ok bool) {
|
||||
if v == "" {
|
||||
return
|
||||
}
|
||||
if v[0] < '0' || '9' < v[0] {
|
||||
return
|
||||
}
|
||||
i := 1
|
||||
for i < len(v) && '0' <= v[i] && v[i] <= '9' {
|
||||
i++
|
||||
}
|
||||
if v[0] == '0' && i != 1 {
|
||||
return
|
||||
}
|
||||
return v[:i], v[i:], true
|
||||
}
|
||||
|
||||
func parsePrerelease(v string) (t, rest string, ok bool) {
|
||||
// "A pre-release version MAY be denoted by appending a hyphen and
|
||||
// a series of dot separated identifiers immediately following the patch version.
|
||||
// Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-].
|
||||
// Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes."
|
||||
if v == "" || v[0] != '-' {
|
||||
return
|
||||
}
|
||||
i := 1
|
||||
start := 1
|
||||
for i < len(v) && v[i] != '+' {
|
||||
if !isIdentChar(v[i]) && v[i] != '.' {
|
||||
return
|
||||
}
|
||||
if v[i] == '.' {
|
||||
if start == i || isBadNum(v[start:i]) {
|
||||
return
|
||||
}
|
||||
start = i + 1
|
||||
}
|
||||
i++
|
||||
}
|
||||
if start == i || isBadNum(v[start:i]) {
|
||||
return
|
||||
}
|
||||
return v[:i], v[i:], true
|
||||
}
|
||||
|
||||
func parseBuild(v string) (t, rest string, ok bool) {
|
||||
if v == "" || v[0] != '+' {
|
||||
return
|
||||
}
|
||||
i := 1
|
||||
start := 1
|
||||
for i < len(v) {
|
||||
if !isIdentChar(v[i]) && v[i] != '.' {
|
||||
return
|
||||
}
|
||||
if v[i] == '.' {
|
||||
if start == i {
|
||||
return
|
||||
}
|
||||
start = i + 1
|
||||
}
|
||||
i++
|
||||
}
|
||||
if start == i {
|
||||
return
|
||||
}
|
||||
return v[:i], v[i:], true
|
||||
}
|
||||
|
||||
func isIdentChar(c byte) bool {
|
||||
return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '-'
|
||||
}
|
||||
|
||||
func isBadNum(v string) bool {
|
||||
i := 0
|
||||
for i < len(v) && '0' <= v[i] && v[i] <= '9' {
|
||||
i++
|
||||
}
|
||||
return i == len(v) && i > 1 && v[0] == '0'
|
||||
}
|
||||
|
||||
func isNum(v string) bool {
|
||||
i := 0
|
||||
for i < len(v) && '0' <= v[i] && v[i] <= '9' {
|
||||
i++
|
||||
}
|
||||
return i == len(v)
|
||||
}
|
||||
|
||||
func compareInt(x, y string) int {
|
||||
if x == y {
|
||||
return 0
|
||||
}
|
||||
if len(x) < len(y) {
|
||||
return -1
|
||||
}
|
||||
if len(x) > len(y) {
|
||||
return +1
|
||||
}
|
||||
if x < y {
|
||||
return -1
|
||||
} else {
|
||||
return +1
|
||||
}
|
||||
}
|
||||
|
||||
func comparePrerelease(x, y string) int {
|
||||
// "When major, minor, and patch are equal, a pre-release version has
|
||||
// lower precedence than a normal version.
|
||||
// Example: 1.0.0-alpha < 1.0.0.
|
||||
// Precedence for two pre-release versions with the same major, minor,
|
||||
// and patch version MUST be determined by comparing each dot separated
|
||||
// identifier from left to right until a difference is found as follows:
|
||||
// identifiers consisting of only digits are compared numerically and
|
||||
// identifiers with letters or hyphens are compared lexically in ASCII
|
||||
// sort order. Numeric identifiers always have lower precedence than
|
||||
// non-numeric identifiers. A larger set of pre-release fields has a
|
||||
// higher precedence than a smaller set, if all of the preceding
|
||||
// identifiers are equal.
|
||||
// Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta <
|
||||
// 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0."
|
||||
if x == y {
|
||||
return 0
|
||||
}
|
||||
if x == "" {
|
||||
return +1
|
||||
}
|
||||
if y == "" {
|
||||
return -1
|
||||
}
|
||||
for x != "" && y != "" {
|
||||
x = x[1:] // skip - or .
|
||||
y = y[1:] // skip - or .
|
||||
var dx, dy string
|
||||
dx, x = nextIdent(x)
|
||||
dy, y = nextIdent(y)
|
||||
if dx != dy {
|
||||
ix := isNum(dx)
|
||||
iy := isNum(dy)
|
||||
if ix != iy {
|
||||
if ix {
|
||||
return -1
|
||||
} else {
|
||||
return +1
|
||||
}
|
||||
}
|
||||
if ix {
|
||||
if len(dx) < len(dy) {
|
||||
return -1
|
||||
}
|
||||
if len(dx) > len(dy) {
|
||||
return +1
|
||||
}
|
||||
}
|
||||
if dx < dy {
|
||||
return -1
|
||||
} else {
|
||||
return +1
|
||||
}
|
||||
}
|
||||
}
|
||||
if x == "" {
|
||||
return -1
|
||||
} else {
|
||||
return +1
|
||||
}
|
||||
}
|
||||
|
||||
func nextIdent(x string) (dx, rest string) {
|
||||
i := 0
|
||||
for i < len(x) && x[i] != '.' {
|
||||
i++
|
||||
}
|
||||
return x[:i], x[i:]
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
// 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 execabs is a drop-in replacement for os/exec
|
||||
// that requires PATH lookups to find absolute paths.
|
||||
// That is, execabs.Command("cmd") runs the same PATH lookup
|
||||
// as exec.Command("cmd"), but if the result is a path
|
||||
// which is relative, the Run and Start methods will report
|
||||
// an error instead of running the executable.
|
||||
//
|
||||
// See https://blog.golang.org/path-security for more information
|
||||
// about when it may be necessary or appropriate to use this package.
|
||||
package execabs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// ErrNotFound is the error resulting if a path search failed to find an executable file.
|
||||
// It is an alias for exec.ErrNotFound.
|
||||
var ErrNotFound = exec.ErrNotFound
|
||||
|
||||
// Cmd represents an external command being prepared or run.
|
||||
// It is an alias for exec.Cmd.
|
||||
type Cmd = exec.Cmd
|
||||
|
||||
// Error is returned by LookPath when it fails to classify a file as an executable.
|
||||
// It is an alias for exec.Error.
|
||||
type Error = exec.Error
|
||||
|
||||
// An ExitError reports an unsuccessful exit by a command.
|
||||
// It is an alias for exec.ExitError.
|
||||
type ExitError = exec.ExitError
|
||||
|
||||
func relError(file, path string) error {
|
||||
return fmt.Errorf("%s resolves to executable in current directory (.%c%s)", file, filepath.Separator, path)
|
||||
}
|
||||
|
||||
// LookPath searches for an executable named file in the directories
|
||||
// named by the PATH environment variable. If file contains a slash,
|
||||
// it is tried directly and the PATH is not consulted. The result will be
|
||||
// an absolute path.
|
||||
//
|
||||
// LookPath differs from exec.LookPath in its handling of PATH lookups,
|
||||
// which are used for file names without slashes. If exec.LookPath's
|
||||
// PATH lookup would have returned an executable from the current directory,
|
||||
// LookPath instead returns an error.
|
||||
func LookPath(file string) (string, error) {
|
||||
path, err := exec.LookPath(file)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if filepath.Base(file) == file && !filepath.IsAbs(path) {
|
||||
return "", relError(file, path)
|
||||
}
|
||||
return path, nil
|
||||
}
|
||||
|
||||
func fixCmd(name string, cmd *exec.Cmd) {
|
||||
if filepath.Base(name) == name && !filepath.IsAbs(cmd.Path) {
|
||||
// exec.Command was called with a bare binary name and
|
||||
// exec.LookPath returned a path which is not absolute.
|
||||
// Set cmd.lookPathErr and clear cmd.Path so that it
|
||||
// cannot be run.
|
||||
lookPathErr := (*error)(unsafe.Pointer(reflect.ValueOf(cmd).Elem().FieldByName("lookPathErr").Addr().Pointer()))
|
||||
if *lookPathErr == nil {
|
||||
*lookPathErr = relError(name, cmd.Path)
|
||||
}
|
||||
cmd.Path = ""
|
||||
}
|
||||
}
|
||||
|
||||
// CommandContext is like Command but includes a context.
|
||||
//
|
||||
// The provided context is used to kill the process (by calling os.Process.Kill)
|
||||
// if the context becomes done before the command completes on its own.
|
||||
func CommandContext(ctx context.Context, name string, arg ...string) *exec.Cmd {
|
||||
cmd := exec.CommandContext(ctx, name, arg...)
|
||||
fixCmd(name, cmd)
|
||||
return cmd
|
||||
|
||||
}
|
||||
|
||||
// Command returns the Cmd struct to execute the named program with the given arguments.
|
||||
// See exec.Command for most details.
|
||||
//
|
||||
// Command differs from exec.Command in its handling of PATH lookups,
|
||||
// which are used when the program name contains no slashes.
|
||||
// If exec.Command would have returned an exec.Cmd configured to run an
|
||||
// executable from the current directory, Command instead
|
||||
// returns an exec.Cmd that will return an error from Start or Run.
|
||||
func Command(name string, arg ...string) *exec.Cmd {
|
||||
cmd := exec.Command(name, arg...)
|
||||
fixCmd(name, cmd)
|
||||
return cmd
|
||||
}
|
||||
|
|
@ -76,7 +76,7 @@ arguments can be passed to the kernel. The third is for low-level use by the
|
|||
ForkExec wrapper. Unlike the first two, it does not call into the scheduler to
|
||||
let it know that a system call is running.
|
||||
|
||||
When porting Go to an new architecture/OS, this file must be implemented for
|
||||
When porting Go to a new architecture/OS, this file must be implemented for
|
||||
each GOOS/GOARCH pair.
|
||||
|
||||
### mksysnum
|
||||
|
|
@ -107,7 +107,7 @@ prototype can be exported (capitalized) or not.
|
|||
Adding a new syscall often just requires adding a new `//sys` function prototype
|
||||
with the desired arguments and a capitalized name so it is exported. However, if
|
||||
you want the interface to the syscall to be different, often one will make an
|
||||
unexported `//sys` prototype, an then write a custom wrapper in
|
||||
unexported `//sys` prototype, and then write a custom wrapper in
|
||||
`syscall_${GOOS}.go`.
|
||||
|
||||
### types files
|
||||
|
|
@ -137,7 +137,7 @@ some `#if/#elif` macros in your include statements.
|
|||
|
||||
This script is used to generate the system's various constants. This doesn't
|
||||
just include the error numbers and error strings, but also the signal numbers
|
||||
an a wide variety of miscellaneous constants. The constants come from the list
|
||||
and a wide variety of miscellaneous constants. The constants come from the list
|
||||
of include files in the `includes_${uname}` variable. A regex then picks out
|
||||
the desired `#define` statements, and generates the corresponding Go constants.
|
||||
The error numbers and strings are generated from `#include <errno.h>`, and the
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build gc
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build (darwin || freebsd || netbsd || openbsd) && gc
|
||||
// +build darwin freebsd netbsd openbsd
|
||||
//go:build (freebsd || netbsd || openbsd) && gc
|
||||
// +build freebsd netbsd openbsd
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build (darwin || freebsd || netbsd || openbsd) && gc
|
||||
// +build darwin freebsd netbsd openbsd
|
||||
//go:build (freebsd || netbsd || openbsd) && gc
|
||||
// +build freebsd netbsd openbsd
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build gc
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build gc
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build gc
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build linux && arm64 && gc
|
||||
// +build linux
|
||||
// +build arm64
|
||||
// +build gc
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build linux && (mips64 || mips64le) && gc
|
||||
// +build linux
|
||||
// +build mips64 mips64le
|
||||
// +build gc
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build linux && (mips || mipsle) && gc
|
||||
// +build linux
|
||||
// +build mips mipsle
|
||||
// +build gc
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build linux && (ppc64 || ppc64le) && gc
|
||||
// +build linux
|
||||
// +build ppc64 ppc64le
|
||||
// +build gc
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build riscv64,gc
|
||||
//go:build riscv64 && gc
|
||||
// +build riscv64
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build s390x
|
||||
//go:build linux && s390x && gc
|
||||
// +build linux
|
||||
// +build s390x
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build gc
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build gc
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
// 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
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
|
||||
|
||||
package unix
|
||||
|
||||
|
|
|
|||
|
|
@ -70,23 +70,11 @@ aix_ppc64)
|
|||
mksyscall="go run mksyscall_aix_ppc64.go -aix"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
darwin_386)
|
||||
mkerrors="$mkerrors -m32"
|
||||
mksyscall="go run mksyscall.go -l32"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
mkasm="go run mkasm_darwin.go"
|
||||
;;
|
||||
darwin_amd64)
|
||||
mkerrors="$mkerrors -m64"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
mkasm="go run mkasm_darwin.go"
|
||||
;;
|
||||
darwin_arm)
|
||||
mkerrors="$mkerrors"
|
||||
mksyscall="go run mksyscall.go -l32"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
mkasm="go run mkasm_darwin.go"
|
||||
;;
|
||||
darwin_arm64)
|
||||
mkerrors="$mkerrors -m64"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
|
|
|
|||
|
|
@ -239,6 +239,7 @@ struct ltchars {
|
|||
#include <linux/netfilter/nfnetlink.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/net_namespace.h>
|
||||
#include <linux/nfc.h>
|
||||
#include <linux/nsfs.h>
|
||||
#include <linux/perf_event.h>
|
||||
#include <linux/pps.h>
|
||||
|
|
@ -258,6 +259,7 @@ struct ltchars {
|
|||
#include <linux/watchdog.h>
|
||||
|
||||
#include <mtd/ubi-user.h>
|
||||
#include <mtd/mtd-user.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#if defined(__sparc__)
|
||||
|
|
@ -501,6 +503,9 @@ ccflags="$@"
|
|||
$2 ~ /^LO_(KEY|NAME)_SIZE$/ ||
|
||||
$2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ ||
|
||||
$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL)_/ ||
|
||||
$2 ~ /^NFC_(GENL|PROTO|COMM|RF|SE|DIRECTION|LLCP|SOCKPROTO)_/ ||
|
||||
$2 ~ /^NFC_.*_(MAX)?SIZE$/ ||
|
||||
$2 ~ /^RAW_PAYLOAD_/ ||
|
||||
$2 ~ /^TP_STATUS_/ ||
|
||||
$2 ~ /^FALLOC_/ ||
|
||||
$2 ~ /^ICMPV?6?_(FILTER|SEC)/ ||
|
||||
|
|
@ -558,6 +563,7 @@ ccflags="$@"
|
|||
$2 ~ /^KEYCTL_/ ||
|
||||
$2 ~ /^PERF_/ ||
|
||||
$2 ~ /^SECCOMP_MODE_/ ||
|
||||
$2 ~ /^SEEK_/ ||
|
||||
$2 ~ /^SPLICE_/ ||
|
||||
$2 ~ /^SYNC_FILE_RANGE_/ ||
|
||||
$2 !~ /^AUDIT_RECORD_MAGIC/ &&
|
||||
|
|
@ -593,6 +599,9 @@ ccflags="$@"
|
|||
$2 == "HID_MAX_DESCRIPTOR_SIZE" ||
|
||||
$2 ~ /^_?HIDIOC/ ||
|
||||
$2 ~ /^BUS_(USB|HIL|BLUETOOTH|VIRTUAL)$/ ||
|
||||
$2 ~ /^MTD/ ||
|
||||
$2 ~ /^OTP/ ||
|
||||
$2 ~ /^MEM/ ||
|
||||
$2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)}
|
||||
$2 ~ /^__WCOREFLAG$/ {next}
|
||||
$2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import (
|
|||
//sys readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno)
|
||||
|
||||
func fdopendir(fd int) (dir uintptr, err error) {
|
||||
r0, _, e1 := syscall_syscallPtr(funcPC(libc_fdopendir_trampoline), uintptr(fd), 0, 0)
|
||||
r0, _, e1 := syscall_syscallPtr(libc_fdopendir_trampoline_addr, uintptr(fd), 0, 0)
|
||||
dir = uintptr(r0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
|
|
@ -25,7 +25,7 @@ func fdopendir(fd int) (dir uintptr, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func libc_fdopendir_trampoline()
|
||||
var libc_fdopendir_trampoline_addr uintptr
|
||||
|
||||
//go:cgo_import_dynamic libc_fdopendir fdopendir "/usr/lib/libSystem.B.dylib"
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
package unix
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
|
@ -398,6 +399,38 @@ func GetsockoptXucred(fd, level, opt int) (*Xucred, error) {
|
|||
return x, err
|
||||
}
|
||||
|
||||
func SysctlKinfoProcSlice(name string) ([]KinfoProc, error) {
|
||||
mib, err := sysctlmib(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Find size.
|
||||
n := uintptr(0)
|
||||
if err := sysctl(mib, nil, &n, nil, 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if n == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
if n%SizeofKinfoProc != 0 {
|
||||
return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc)
|
||||
}
|
||||
|
||||
// Read into buffer of that size.
|
||||
buf := make([]KinfoProc, n/SizeofKinfoProc)
|
||||
if err := sysctl(mib, (*byte)(unsafe.Pointer(&buf[0])), &n, nil, 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if n%SizeofKinfoProc != 0 {
|
||||
return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc)
|
||||
}
|
||||
|
||||
// The actual call may return less than the original reported required
|
||||
// size so ensure we deal with that.
|
||||
return buf[:n/SizeofKinfoProc], nil
|
||||
}
|
||||
|
||||
//sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error)
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1,51 +0,0 @@
|
|||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build 386 && darwin
|
||||
// +build 386,darwin
|
||||
|
||||
package unix
|
||||
|
||||
import "syscall"
|
||||
|
||||
func setTimespec(sec, nsec int64) Timespec {
|
||||
return Timespec{Sec: int32(sec), Nsec: int32(nsec)}
|
||||
}
|
||||
|
||||
func setTimeval(sec, usec int64) Timeval {
|
||||
return Timeval{Sec: int32(sec), Usec: int32(usec)}
|
||||
}
|
||||
|
||||
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||
k.Ident = uint32(fd)
|
||||
k.Filter = int16(mode)
|
||||
k.Flags = uint16(flags)
|
||||
}
|
||||
|
||||
func (iov *Iovec) SetLen(length int) {
|
||||
iov.Len = uint32(length)
|
||||
}
|
||||
|
||||
func (msghdr *Msghdr) SetControllen(length int) {
|
||||
msghdr.Controllen = uint32(length)
|
||||
}
|
||||
|
||||
func (msghdr *Msghdr) SetIovlen(length int) {
|
||||
msghdr.Iovlen = int32(length)
|
||||
}
|
||||
|
||||
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||
cmsg.Len = uint32(length)
|
||||
}
|
||||
|
||||
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
|
||||
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
|
||||
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
|
||||
//sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64
|
||||
//sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT64
|
||||
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
|
||||
//sys ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) = SYS_ptrace
|
||||
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
|
||||
//sys Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
// Copyright 2015 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 unix
|
||||
|
||||
import "syscall"
|
||||
|
||||
func ptrace1(request int, pid int, addr uintptr, data uintptr) error {
|
||||
return ENOTSUP
|
||||
}
|
||||
|
||||
func setTimespec(sec, nsec int64) Timespec {
|
||||
return Timespec{Sec: int32(sec), Nsec: int32(nsec)}
|
||||
}
|
||||
|
||||
func setTimeval(sec, usec int64) Timeval {
|
||||
return Timeval{Sec: int32(sec), Usec: int32(usec)}
|
||||
}
|
||||
|
||||
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||
k.Ident = uint32(fd)
|
||||
k.Filter = int16(mode)
|
||||
k.Flags = uint16(flags)
|
||||
}
|
||||
|
||||
func (iov *Iovec) SetLen(length int) {
|
||||
iov.Len = uint32(length)
|
||||
}
|
||||
|
||||
func (msghdr *Msghdr) SetControllen(length int) {
|
||||
msghdr.Controllen = uint32(length)
|
||||
}
|
||||
|
||||
func (msghdr *Msghdr) SetIovlen(length int) {
|
||||
msghdr.Iovlen = int32(length)
|
||||
}
|
||||
|
||||
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||
cmsg.Len = uint32(length)
|
||||
}
|
||||
|
||||
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) // sic
|
||||
|
||||
//sys Fstat(fd int, stat *Stat_t) (err error)
|
||||
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
|
||||
//sys Fstatfs(fd int, stat *Statfs_t) (err error)
|
||||
//sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT
|
||||
//sys Lstat(path string, stat *Stat_t) (err error)
|
||||
//sys Stat(path string, stat *Stat_t) (err error)
|
||||
//sys Statfs(path string, stat *Statfs_t) (err error)
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
package unix
|
||||
|
||||
import "unsafe"
|
||||
import _ "unsafe"
|
||||
|
||||
// Implemented in the runtime package (runtime/sys_darwin.go)
|
||||
func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
||||
|
|
@ -25,10 +25,3 @@ func syscall_syscallPtr(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
|||
//go:linkname syscall_rawSyscall syscall.rawSyscall
|
||||
//go:linkname syscall_rawSyscall6 syscall.rawSyscall6
|
||||
//go:linkname syscall_syscallPtr syscall.syscallPtr
|
||||
|
||||
// Find the entry point for f. See comments in runtime/proc.go for the
|
||||
// function of the same name.
|
||||
//go:nosplit
|
||||
func funcPC(f func()) uintptr {
|
||||
return **(**uintptr)(unsafe.Pointer(&f))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// 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.
|
||||
|
||||
|
|
@ -10,6 +10,8 @@
|
|||
package unix
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
|
|
@ -127,3 +129,50 @@ func Getmsg(fd int, cl []byte, data []byte) (retCl []byte, retData []byte, flags
|
|||
}
|
||||
return retCl, retData, flags, nil
|
||||
}
|
||||
|
||||
func IoctlSetIntRetInt(fd int, req uint, arg int) (int, error) {
|
||||
return ioctlRet(fd, req, uintptr(arg))
|
||||
}
|
||||
|
||||
func IoctlSetString(fd int, req uint, val string) error {
|
||||
bs := make([]byte, len(val)+1)
|
||||
copy(bs[:len(bs)-1], val)
|
||||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&bs[0])))
|
||||
runtime.KeepAlive(&bs[0])
|
||||
return err
|
||||
}
|
||||
|
||||
// Lifreq Helpers
|
||||
|
||||
func (l *Lifreq) SetName(name string) error {
|
||||
if len(name) >= len(l.Name) {
|
||||
return fmt.Errorf("name cannot be more than %d characters", len(l.Name)-1)
|
||||
}
|
||||
for i := range name {
|
||||
l.Name[i] = int8(name[i])
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *Lifreq) SetLifruInt(d int) {
|
||||
*(*int)(unsafe.Pointer(&l.Lifru[0])) = d
|
||||
}
|
||||
|
||||
func (l *Lifreq) GetLifruInt() int {
|
||||
return *(*int)(unsafe.Pointer(&l.Lifru[0]))
|
||||
}
|
||||
|
||||
func IoctlLifreq(fd int, req uint, l *Lifreq) error {
|
||||
return ioctl(fd, req, uintptr(unsafe.Pointer(l)))
|
||||
}
|
||||
|
||||
// Strioctl Helpers
|
||||
|
||||
func (s *Strioctl) SetInt(i int) {
|
||||
s.Len = int32(unsafe.Sizeof(i))
|
||||
s.Dp = (*int8)(unsafe.Pointer(&i))
|
||||
}
|
||||
|
||||
func IoctlSetStrioctlRetInt(fd int, req uint, s *Strioctl) (int, error) {
|
||||
return ioctlRet(fd, req, uintptr(unsafe.Pointer(s)))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -904,6 +904,46 @@ func (sa *SockaddrIUCV) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
|||
return unsafe.Pointer(&sa.raw), SizeofSockaddrIUCV, nil
|
||||
}
|
||||
|
||||
type SockaddrNFC struct {
|
||||
DeviceIdx uint32
|
||||
TargetIdx uint32
|
||||
NFCProtocol uint32
|
||||
raw RawSockaddrNFC
|
||||
}
|
||||
|
||||
func (sa *SockaddrNFC) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||
sa.raw.Sa_family = AF_NFC
|
||||
sa.raw.Dev_idx = sa.DeviceIdx
|
||||
sa.raw.Target_idx = sa.TargetIdx
|
||||
sa.raw.Nfc_protocol = sa.NFCProtocol
|
||||
return unsafe.Pointer(&sa.raw), SizeofSockaddrNFC, nil
|
||||
}
|
||||
|
||||
type SockaddrNFCLLCP struct {
|
||||
DeviceIdx uint32
|
||||
TargetIdx uint32
|
||||
NFCProtocol uint32
|
||||
DestinationSAP uint8
|
||||
SourceSAP uint8
|
||||
ServiceName string
|
||||
raw RawSockaddrNFCLLCP
|
||||
}
|
||||
|
||||
func (sa *SockaddrNFCLLCP) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||
sa.raw.Sa_family = AF_NFC
|
||||
sa.raw.Dev_idx = sa.DeviceIdx
|
||||
sa.raw.Target_idx = sa.TargetIdx
|
||||
sa.raw.Nfc_protocol = sa.NFCProtocol
|
||||
sa.raw.Dsap = sa.DestinationSAP
|
||||
sa.raw.Ssap = sa.SourceSAP
|
||||
if len(sa.ServiceName) > len(sa.raw.Service_name) {
|
||||
return nil, 0, EINVAL
|
||||
}
|
||||
copy(sa.raw.Service_name[:], sa.ServiceName)
|
||||
sa.raw.SetServiceNameLen(len(sa.ServiceName))
|
||||
return unsafe.Pointer(&sa.raw), SizeofSockaddrNFCLLCP, nil
|
||||
}
|
||||
|
||||
var socketProtocol = func(fd int) (int, error) {
|
||||
return GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL)
|
||||
}
|
||||
|
|
@ -1144,6 +1184,37 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
|||
}
|
||||
return sa, nil
|
||||
}
|
||||
case AF_NFC:
|
||||
proto, err := socketProtocol(fd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch proto {
|
||||
case NFC_SOCKPROTO_RAW:
|
||||
pp := (*RawSockaddrNFC)(unsafe.Pointer(rsa))
|
||||
sa := &SockaddrNFC{
|
||||
DeviceIdx: pp.Dev_idx,
|
||||
TargetIdx: pp.Target_idx,
|
||||
NFCProtocol: pp.Nfc_protocol,
|
||||
}
|
||||
return sa, nil
|
||||
case NFC_SOCKPROTO_LLCP:
|
||||
pp := (*RawSockaddrNFCLLCP)(unsafe.Pointer(rsa))
|
||||
if uint64(pp.Service_name_len) > uint64(len(pp.Service_name)) {
|
||||
return nil, EINVAL
|
||||
}
|
||||
sa := &SockaddrNFCLLCP{
|
||||
DeviceIdx: pp.Dev_idx,
|
||||
TargetIdx: pp.Target_idx,
|
||||
NFCProtocol: pp.Nfc_protocol,
|
||||
DestinationSAP: pp.Dsap,
|
||||
SourceSAP: pp.Ssap,
|
||||
ServiceName: string(pp.Service_name[:pp.Service_name_len]),
|
||||
}
|
||||
return sa, nil
|
||||
default:
|
||||
return nil, EINVAL
|
||||
}
|
||||
}
|
||||
return nil, EAFNOSUPPORT
|
||||
}
|
||||
|
|
@ -1151,7 +1222,11 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
|||
func Accept(fd int) (nfd int, sa Sockaddr, err error) {
|
||||
var rsa RawSockaddrAny
|
||||
var len _Socklen = SizeofSockaddrAny
|
||||
nfd, err = accept(fd, &rsa, &len)
|
||||
// Try accept4 first for Android, then try accept for kernel older than 2.6.28
|
||||
nfd, err = accept4(fd, &rsa, &len, 0)
|
||||
if err == ENOSYS {
|
||||
nfd, err = accept(fd, &rsa, &len)
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -378,6 +378,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
|
|||
cmsg.Len = uint32(length)
|
||||
}
|
||||
|
||||
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
|
||||
rsa.Service_name_len = uint32(length)
|
||||
}
|
||||
|
||||
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
|
||||
|
||||
func Poll(fds []PollFd, timeout int) (n int, err error) {
|
||||
|
|
|
|||
|
|
@ -172,6 +172,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
|
|||
cmsg.Len = uint64(length)
|
||||
}
|
||||
|
||||
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
|
||||
rsa.Service_name_len = uint64(length)
|
||||
}
|
||||
|
||||
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
|
||||
|
||||
func Poll(fds []PollFd, timeout int) (n int, err error) {
|
||||
|
|
|
|||
|
|
@ -256,6 +256,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
|
|||
cmsg.Len = uint32(length)
|
||||
}
|
||||
|
||||
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
|
||||
rsa.Service_name_len = uint32(length)
|
||||
}
|
||||
|
||||
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
|
||||
|
||||
func Poll(fds []PollFd, timeout int) (n int, err error) {
|
||||
|
|
|
|||
|
|
@ -207,6 +207,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
|
|||
cmsg.Len = uint64(length)
|
||||
}
|
||||
|
||||
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
|
||||
rsa.Service_name_len = uint64(length)
|
||||
}
|
||||
|
||||
func InotifyInit() (fd int, err error) {
|
||||
return InotifyInit1(0)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -217,6 +217,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
|
|||
cmsg.Len = uint64(length)
|
||||
}
|
||||
|
||||
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
|
||||
rsa.Service_name_len = uint64(length)
|
||||
}
|
||||
|
||||
func InotifyInit() (fd int, err error) {
|
||||
return InotifyInit1(0)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -229,6 +229,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
|
|||
cmsg.Len = uint32(length)
|
||||
}
|
||||
|
||||
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
|
||||
rsa.Service_name_len = uint32(length)
|
||||
}
|
||||
|
||||
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
|
||||
|
||||
func Poll(fds []PollFd, timeout int) (n int, err error) {
|
||||
|
|
|
|||
|
|
@ -215,6 +215,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
|
|||
cmsg.Len = uint32(length)
|
||||
}
|
||||
|
||||
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
|
||||
rsa.Service_name_len = uint32(length)
|
||||
}
|
||||
|
||||
//sysnb pipe(p *[2]_C_int) (err error)
|
||||
|
||||
func Pipe(p []int) (err error) {
|
||||
|
|
|
|||
|
|
@ -100,6 +100,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
|
|||
cmsg.Len = uint64(length)
|
||||
}
|
||||
|
||||
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
|
||||
rsa.Service_name_len = uint64(length)
|
||||
}
|
||||
|
||||
//sysnb pipe(p *[2]_C_int) (err error)
|
||||
|
||||
func Pipe(p []int) (err error) {
|
||||
|
|
|
|||
|
|
@ -188,6 +188,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
|
|||
cmsg.Len = uint64(length)
|
||||
}
|
||||
|
||||
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
|
||||
rsa.Service_name_len = uint64(length)
|
||||
}
|
||||
|
||||
func InotifyInit() (fd int, err error) {
|
||||
return InotifyInit1(0)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,6 +129,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
|
|||
cmsg.Len = uint64(length)
|
||||
}
|
||||
|
||||
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
|
||||
rsa.Service_name_len = uint64(length)
|
||||
}
|
||||
|
||||
// Linux on s390x uses the old mmap interface, which requires arguments to be passed in a struct.
|
||||
// mmap2 also requires arguments to be passed in a struct; it is currently not exposed in <asm/unistd.h>.
|
||||
func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
|
||||
|
|
|
|||
|
|
@ -116,6 +116,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
|
|||
cmsg.Len = uint64(length)
|
||||
}
|
||||
|
||||
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
|
||||
rsa.Service_name_len = uint64(length)
|
||||
}
|
||||
|
||||
//sysnb pipe(p *[2]_C_int) (err error)
|
||||
|
||||
func Pipe(p []int) (err error) {
|
||||
|
|
|
|||
|
|
@ -222,6 +222,8 @@ func (cmsg *Cmsghdr) SetLen(length int) {
|
|||
//sys Creat(path string, mode uint32) (fd int, err error) = SYS___CREAT_A
|
||||
//sys Dup(oldfd int) (fd int, err error)
|
||||
//sys Dup2(oldfd int, newfd int) (err error)
|
||||
//sys Errno2() (er2 int) = SYS___ERRNO2
|
||||
//sys Err2ad() (eadd *int) = SYS___ERR2AD
|
||||
//sys Exit(code int)
|
||||
//sys Fchdir(fd int) (err error)
|
||||
//sys Fchmod(fd int, mode uint32) (err error)
|
||||
|
|
@ -245,10 +247,12 @@ func Fstat(fd int, stat *Stat_t) (err error) {
|
|||
//sys Poll(fds []PollFd, timeout int) (n int, err error) = SYS_POLL
|
||||
//sys Times(tms *Tms) (ticks uintptr, err error) = SYS_TIMES
|
||||
//sys W_Getmntent(buff *byte, size int) (lastsys int, err error) = SYS_W_GETMNTENT
|
||||
//sys W_Getmntent_A(buff *byte, size int) (lastsys int, err error) = SYS___W_GETMNTENT_A
|
||||
|
||||
//sys Mount(path string, filesystem string, fstype string, mtm uint32, parmlen int32, parm string) (err error) = SYS___MOUNT_A
|
||||
//sys Unmount(filesystem string, mtm int) (err error) = SYS___UMOUNT_A
|
||||
//sys mount_LE(path string, filesystem string, fstype string, mtm uint32, parmlen int32, parm string) (err error) = SYS___MOUNT_A
|
||||
//sys unmount(filesystem string, mtm int) (err error) = SYS___UMOUNT_A
|
||||
//sys Chroot(path string) (err error) = SYS___CHROOT_A
|
||||
//sys Select(nmsgsfds int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (ret int, err error) = SYS_SELECT
|
||||
//sysnb Uname(buf *Utsname) (err error) = SYS___UNAME_A
|
||||
|
||||
func Ptsname(fd int) (name string, err error) {
|
||||
|
|
@ -1779,3 +1783,47 @@ func SetNonblock(fd int, nonblocking bool) (err error) {
|
|||
func Exec(argv0 string, argv []string, envv []string) error {
|
||||
return syscall.Exec(argv0, argv, envv)
|
||||
}
|
||||
|
||||
func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
|
||||
if needspace := 8 - len(fstype); needspace <= 0 {
|
||||
fstype = fstype[:8]
|
||||
} else {
|
||||
fstype += " "[:needspace]
|
||||
}
|
||||
return mount_LE(target, source, fstype, uint32(flags), int32(len(data)), data)
|
||||
}
|
||||
|
||||
func Unmount(name string, mtm int) (err error) {
|
||||
// mountpoint is always a full path and starts with a '/'
|
||||
// check if input string is not a mountpoint but a filesystem name
|
||||
if name[0] != '/' {
|
||||
return unmount(name, mtm)
|
||||
}
|
||||
// treat name as mountpoint
|
||||
b2s := func(arr []byte) string {
|
||||
nulli := bytes.IndexByte(arr, 0)
|
||||
if nulli == -1 {
|
||||
return string(arr)
|
||||
} else {
|
||||
return string(arr[:nulli])
|
||||
}
|
||||
}
|
||||
var buffer struct {
|
||||
header W_Mnth
|
||||
fsinfo [64]W_Mntent
|
||||
}
|
||||
fsCount, err := W_Getmntent_A((*byte)(unsafe.Pointer(&buffer)), int(unsafe.Sizeof(buffer)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if fsCount == 0 {
|
||||
return EINVAL
|
||||
}
|
||||
for i := 0; i < fsCount; i++ {
|
||||
if b2s(buffer.fsinfo[i].Mountpoint[:]) == name {
|
||||
err = unmount(b2s(buffer.fsinfo[i].Fsname[:]), mtm)
|
||||
break
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1262,6 +1262,11 @@ const (
|
|||
SCM_RIGHTS = 0x1
|
||||
SCM_TIMESTAMP = 0x2
|
||||
SCM_TIMESTAMP_MONOTONIC = 0x4
|
||||
SEEK_CUR = 0x1
|
||||
SEEK_DATA = 0x4
|
||||
SEEK_END = 0x2
|
||||
SEEK_HOLE = 0x3
|
||||
SEEK_SET = 0x0
|
||||
SHUT_RD = 0x0
|
||||
SHUT_RDWR = 0x2
|
||||
SHUT_WR = 0x1
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1262,6 +1262,11 @@ const (
|
|||
SCM_RIGHTS = 0x1
|
||||
SCM_TIMESTAMP = 0x2
|
||||
SCM_TIMESTAMP_MONOTONIC = 0x4
|
||||
SEEK_CUR = 0x1
|
||||
SEEK_DATA = 0x4
|
||||
SEEK_END = 0x2
|
||||
SEEK_HOLE = 0x3
|
||||
SEEK_SET = 0x0
|
||||
SHUT_RD = 0x0
|
||||
SHUT_RDWR = 0x2
|
||||
SHUT_WR = 0x1
|
||||
|
|
|
|||
|
|
@ -1297,6 +1297,11 @@ const (
|
|||
SCM_RIGHTS = 0x1
|
||||
SCM_TIMESTAMP = 0x2
|
||||
SCM_TIME_INFO = 0x7
|
||||
SEEK_CUR = 0x1
|
||||
SEEK_DATA = 0x3
|
||||
SEEK_END = 0x2
|
||||
SEEK_HOLE = 0x4
|
||||
SEEK_SET = 0x0
|
||||
SHUT_RD = 0x0
|
||||
SHUT_RDWR = 0x2
|
||||
SHUT_WR = 0x1
|
||||
|
|
|
|||
|
|
@ -1298,6 +1298,11 @@ const (
|
|||
SCM_RIGHTS = 0x1
|
||||
SCM_TIMESTAMP = 0x2
|
||||
SCM_TIME_INFO = 0x7
|
||||
SEEK_CUR = 0x1
|
||||
SEEK_DATA = 0x3
|
||||
SEEK_END = 0x2
|
||||
SEEK_HOLE = 0x4
|
||||
SEEK_SET = 0x0
|
||||
SHUT_RD = 0x0
|
||||
SHUT_RDWR = 0x2
|
||||
SHUT_WR = 0x1
|
||||
|
|
|
|||
|
|
@ -1276,6 +1276,11 @@ const (
|
|||
SCM_CREDS = 0x3
|
||||
SCM_RIGHTS = 0x1
|
||||
SCM_TIMESTAMP = 0x2
|
||||
SEEK_CUR = 0x1
|
||||
SEEK_DATA = 0x3
|
||||
SEEK_END = 0x2
|
||||
SEEK_HOLE = 0x4
|
||||
SEEK_SET = 0x0
|
||||
SHUT_RD = 0x0
|
||||
SHUT_RDWR = 0x2
|
||||
SHUT_WR = 0x1
|
||||
|
|
|
|||
|
|
@ -1298,6 +1298,11 @@ const (
|
|||
SCM_RIGHTS = 0x1
|
||||
SCM_TIMESTAMP = 0x2
|
||||
SCM_TIME_INFO = 0x7
|
||||
SEEK_CUR = 0x1
|
||||
SEEK_DATA = 0x3
|
||||
SEEK_END = 0x2
|
||||
SEEK_HOLE = 0x4
|
||||
SEEK_SET = 0x0
|
||||
SHUT_RD = 0x0
|
||||
SHUT_RDWR = 0x2
|
||||
SHUT_WR = 0x1
|
||||
|
|
|
|||
|
|
@ -166,13 +166,16 @@ const (
|
|||
BPF_ALU64 = 0x7
|
||||
BPF_AND = 0x50
|
||||
BPF_ARSH = 0xc0
|
||||
BPF_ATOMIC = 0xc0
|
||||
BPF_B = 0x10
|
||||
BPF_BUILD_ID_SIZE = 0x14
|
||||
BPF_CALL = 0x80
|
||||
BPF_CMPXCHG = 0xf1
|
||||
BPF_DIV = 0x30
|
||||
BPF_DW = 0x18
|
||||
BPF_END = 0xd0
|
||||
BPF_EXIT = 0x90
|
||||
BPF_FETCH = 0x1
|
||||
BPF_FROM_BE = 0x8
|
||||
BPF_FROM_LE = 0x0
|
||||
BPF_FS_MAGIC = 0xcafe4a11
|
||||
|
|
@ -240,6 +243,7 @@ const (
|
|||
BPF_W = 0x0
|
||||
BPF_X = 0x8
|
||||
BPF_XADD = 0xc0
|
||||
BPF_XCHG = 0xe1
|
||||
BPF_XOR = 0xa0
|
||||
BRKINT = 0x2
|
||||
BS0 = 0x0
|
||||
|
|
@ -490,9 +494,9 @@ const (
|
|||
DM_UUID_FLAG = 0x4000
|
||||
DM_UUID_LEN = 0x81
|
||||
DM_VERSION = 0xc138fd00
|
||||
DM_VERSION_EXTRA = "-ioctl (2020-10-01)"
|
||||
DM_VERSION_EXTRA = "-ioctl (2021-02-01)"
|
||||
DM_VERSION_MAJOR = 0x4
|
||||
DM_VERSION_MINOR = 0x2b
|
||||
DM_VERSION_MINOR = 0x2c
|
||||
DM_VERSION_PATCHLEVEL = 0x0
|
||||
DT_BLK = 0x6
|
||||
DT_CHR = 0x2
|
||||
|
|
@ -860,6 +864,7 @@ const (
|
|||
FS_IOC_GET_ENCRYPTION_KEY_STATUS = 0xc080661a
|
||||
FS_IOC_GET_ENCRYPTION_POLICY_EX = 0xc0096616
|
||||
FS_IOC_MEASURE_VERITY = 0xc0046686
|
||||
FS_IOC_READ_VERITY_METADATA = 0xc0286687
|
||||
FS_IOC_REMOVE_ENCRYPTION_KEY = 0xc0406618
|
||||
FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS = 0xc0406619
|
||||
FS_KEY_DESCRIPTOR_SIZE = 0x8
|
||||
|
|
@ -875,6 +880,9 @@ const (
|
|||
FS_VERITY_FL = 0x100000
|
||||
FS_VERITY_HASH_ALG_SHA256 = 0x1
|
||||
FS_VERITY_HASH_ALG_SHA512 = 0x2
|
||||
FS_VERITY_METADATA_TYPE_DESCRIPTOR = 0x2
|
||||
FS_VERITY_METADATA_TYPE_MERKLE_TREE = 0x1
|
||||
FS_VERITY_METADATA_TYPE_SIGNATURE = 0x3
|
||||
FUTEXFS_SUPER_MAGIC = 0xbad1dea
|
||||
F_ADD_SEALS = 0x409
|
||||
F_DUPFD = 0x0
|
||||
|
|
@ -1398,6 +1406,10 @@ const (
|
|||
MCAST_LEAVE_SOURCE_GROUP = 0x2f
|
||||
MCAST_MSFILTER = 0x30
|
||||
MCAST_UNBLOCK_SOURCE = 0x2c
|
||||
MEMGETREGIONINFO = 0xc0104d08
|
||||
MEMREADOOB64 = 0xc0184d16
|
||||
MEMWRITE = 0xc0304d18
|
||||
MEMWRITEOOB64 = 0xc0184d15
|
||||
MFD_ALLOW_SEALING = 0x2
|
||||
MFD_CLOEXEC = 0x1
|
||||
MFD_HUGETLB = 0x4
|
||||
|
|
@ -1486,7 +1498,35 @@ const (
|
|||
MS_SYNCHRONOUS = 0x10
|
||||
MS_UNBINDABLE = 0x20000
|
||||
MS_VERBOSE = 0x8000
|
||||
MTD_ABSENT = 0x0
|
||||
MTD_BIT_WRITEABLE = 0x800
|
||||
MTD_CAP_NANDFLASH = 0x400
|
||||
MTD_CAP_NORFLASH = 0xc00
|
||||
MTD_CAP_NVRAM = 0x1c00
|
||||
MTD_CAP_RAM = 0x1c00
|
||||
MTD_CAP_ROM = 0x0
|
||||
MTD_DATAFLASH = 0x6
|
||||
MTD_INODE_FS_MAGIC = 0x11307854
|
||||
MTD_MAX_ECCPOS_ENTRIES = 0x40
|
||||
MTD_MAX_OOBFREE_ENTRIES = 0x8
|
||||
MTD_MLCNANDFLASH = 0x8
|
||||
MTD_NANDECC_AUTOPLACE = 0x2
|
||||
MTD_NANDECC_AUTOPL_USR = 0x4
|
||||
MTD_NANDECC_OFF = 0x0
|
||||
MTD_NANDECC_PLACE = 0x1
|
||||
MTD_NANDECC_PLACEONLY = 0x3
|
||||
MTD_NANDFLASH = 0x4
|
||||
MTD_NORFLASH = 0x3
|
||||
MTD_NO_ERASE = 0x1000
|
||||
MTD_OTP_FACTORY = 0x1
|
||||
MTD_OTP_OFF = 0x0
|
||||
MTD_OTP_USER = 0x2
|
||||
MTD_POWERUP_LOCK = 0x2000
|
||||
MTD_RAM = 0x1
|
||||
MTD_ROM = 0x2
|
||||
MTD_SLC_ON_MLC_EMULATION = 0x4000
|
||||
MTD_UBIVOLUME = 0x7
|
||||
MTD_WRITEABLE = 0x400
|
||||
NAME_MAX = 0xff
|
||||
NCP_SUPER_MAGIC = 0x564c
|
||||
NETLINK_ADD_MEMBERSHIP = 0x1
|
||||
|
|
@ -1526,6 +1566,59 @@ const (
|
|||
NETLINK_XFRM = 0x6
|
||||
NETNSA_MAX = 0x5
|
||||
NETNSA_NSID_NOT_ASSIGNED = -0x1
|
||||
NFC_ATR_REQ_GB_MAXSIZE = 0x30
|
||||
NFC_ATR_REQ_MAXSIZE = 0x40
|
||||
NFC_ATR_RES_GB_MAXSIZE = 0x2f
|
||||
NFC_ATR_RES_MAXSIZE = 0x40
|
||||
NFC_COMM_ACTIVE = 0x0
|
||||
NFC_COMM_PASSIVE = 0x1
|
||||
NFC_DEVICE_NAME_MAXSIZE = 0x8
|
||||
NFC_DIRECTION_RX = 0x0
|
||||
NFC_DIRECTION_TX = 0x1
|
||||
NFC_FIRMWARE_NAME_MAXSIZE = 0x20
|
||||
NFC_GB_MAXSIZE = 0x30
|
||||
NFC_GENL_MCAST_EVENT_NAME = "events"
|
||||
NFC_GENL_NAME = "nfc"
|
||||
NFC_GENL_VERSION = 0x1
|
||||
NFC_HEADER_SIZE = 0x1
|
||||
NFC_ISO15693_UID_MAXSIZE = 0x8
|
||||
NFC_LLCP_MAX_SERVICE_NAME = 0x3f
|
||||
NFC_LLCP_MIUX = 0x1
|
||||
NFC_LLCP_REMOTE_LTO = 0x3
|
||||
NFC_LLCP_REMOTE_MIU = 0x2
|
||||
NFC_LLCP_REMOTE_RW = 0x4
|
||||
NFC_LLCP_RW = 0x0
|
||||
NFC_NFCID1_MAXSIZE = 0xa
|
||||
NFC_NFCID2_MAXSIZE = 0x8
|
||||
NFC_NFCID3_MAXSIZE = 0xa
|
||||
NFC_PROTO_FELICA = 0x3
|
||||
NFC_PROTO_FELICA_MASK = 0x8
|
||||
NFC_PROTO_ISO14443 = 0x4
|
||||
NFC_PROTO_ISO14443_B = 0x6
|
||||
NFC_PROTO_ISO14443_B_MASK = 0x40
|
||||
NFC_PROTO_ISO14443_MASK = 0x10
|
||||
NFC_PROTO_ISO15693 = 0x7
|
||||
NFC_PROTO_ISO15693_MASK = 0x80
|
||||
NFC_PROTO_JEWEL = 0x1
|
||||
NFC_PROTO_JEWEL_MASK = 0x2
|
||||
NFC_PROTO_MAX = 0x8
|
||||
NFC_PROTO_MIFARE = 0x2
|
||||
NFC_PROTO_MIFARE_MASK = 0x4
|
||||
NFC_PROTO_NFC_DEP = 0x5
|
||||
NFC_PROTO_NFC_DEP_MASK = 0x20
|
||||
NFC_RAW_HEADER_SIZE = 0x2
|
||||
NFC_RF_INITIATOR = 0x0
|
||||
NFC_RF_NONE = 0x2
|
||||
NFC_RF_TARGET = 0x1
|
||||
NFC_SENSB_RES_MAXSIZE = 0xc
|
||||
NFC_SENSF_RES_MAXSIZE = 0x12
|
||||
NFC_SE_DISABLED = 0x0
|
||||
NFC_SE_EMBEDDED = 0x2
|
||||
NFC_SE_ENABLED = 0x1
|
||||
NFC_SE_UICC = 0x1
|
||||
NFC_SOCKPROTO_LLCP = 0x1
|
||||
NFC_SOCKPROTO_MAX = 0x2
|
||||
NFC_SOCKPROTO_RAW = 0x0
|
||||
NFNETLINK_V0 = 0x0
|
||||
NFNLGRP_ACCT_QUOTA = 0x8
|
||||
NFNLGRP_CONNTRACK_DESTROY = 0x3
|
||||
|
|
@ -1673,6 +1766,10 @@ const (
|
|||
PERF_FLAG_PID_CGROUP = 0x4
|
||||
PERF_MAX_CONTEXTS_PER_STACK = 0x8
|
||||
PERF_MAX_STACK_DEPTH = 0x7f
|
||||
PERF_MEM_BLK_ADDR = 0x4
|
||||
PERF_MEM_BLK_DATA = 0x2
|
||||
PERF_MEM_BLK_NA = 0x1
|
||||
PERF_MEM_BLK_SHIFT = 0x28
|
||||
PERF_MEM_LOCK_LOCKED = 0x2
|
||||
PERF_MEM_LOCK_NA = 0x1
|
||||
PERF_MEM_LOCK_SHIFT = 0x18
|
||||
|
|
@ -1736,12 +1833,14 @@ const (
|
|||
PERF_RECORD_MISC_GUEST_USER = 0x5
|
||||
PERF_RECORD_MISC_HYPERVISOR = 0x3
|
||||
PERF_RECORD_MISC_KERNEL = 0x1
|
||||
PERF_RECORD_MISC_MMAP_BUILD_ID = 0x4000
|
||||
PERF_RECORD_MISC_MMAP_DATA = 0x2000
|
||||
PERF_RECORD_MISC_PROC_MAP_PARSE_TIMEOUT = 0x1000
|
||||
PERF_RECORD_MISC_SWITCH_OUT = 0x2000
|
||||
PERF_RECORD_MISC_SWITCH_OUT_PREEMPT = 0x4000
|
||||
PERF_RECORD_MISC_USER = 0x2
|
||||
PERF_SAMPLE_BRANCH_PLM_ALL = 0x7
|
||||
PERF_SAMPLE_WEIGHT_TYPE = 0x1004000
|
||||
PIPEFS_MAGIC = 0x50495045
|
||||
PPC_CMM_MAGIC = 0xc7571590
|
||||
PPPIOCGNPMODE = 0xc008744c
|
||||
|
|
@ -1945,6 +2044,11 @@ const (
|
|||
QNX4_SUPER_MAGIC = 0x2f
|
||||
QNX6_SUPER_MAGIC = 0x68191122
|
||||
RAMFS_MAGIC = 0x858458f6
|
||||
RAW_PAYLOAD_DIGITAL = 0x3
|
||||
RAW_PAYLOAD_HCI = 0x2
|
||||
RAW_PAYLOAD_LLCP = 0x0
|
||||
RAW_PAYLOAD_NCI = 0x1
|
||||
RAW_PAYLOAD_PROPRIETARY = 0x4
|
||||
RDTGROUP_SUPER_MAGIC = 0x7655821
|
||||
REISERFS_SUPER_MAGIC = 0x52654973
|
||||
RENAME_EXCHANGE = 0x2
|
||||
|
|
@ -1995,6 +2099,10 @@ const (
|
|||
RTCF_NAT = 0x800000
|
||||
RTCF_VALVE = 0x200000
|
||||
RTC_AF = 0x20
|
||||
RTC_FEATURE_ALARM = 0x0
|
||||
RTC_FEATURE_ALARM_RES_MINUTE = 0x1
|
||||
RTC_FEATURE_CNT = 0x3
|
||||
RTC_FEATURE_NEED_WEEK_DAY = 0x2
|
||||
RTC_IRQF = 0x80
|
||||
RTC_MAX_FREQ = 0x2000
|
||||
RTC_PF = 0x40
|
||||
|
|
@ -2068,6 +2176,7 @@ const (
|
|||
RTM_F_LOOKUP_TABLE = 0x1000
|
||||
RTM_F_NOTIFY = 0x100
|
||||
RTM_F_OFFLOAD = 0x4000
|
||||
RTM_F_OFFLOAD_FAILED = 0x20000000
|
||||
RTM_F_PREFIX = 0x800
|
||||
RTM_F_TRAP = 0x8000
|
||||
RTM_GETACTION = 0x32
|
||||
|
|
@ -2175,6 +2284,12 @@ const (
|
|||
SECCOMP_MODE_FILTER = 0x2
|
||||
SECCOMP_MODE_STRICT = 0x1
|
||||
SECURITYFS_MAGIC = 0x73636673
|
||||
SEEK_CUR = 0x1
|
||||
SEEK_DATA = 0x3
|
||||
SEEK_END = 0x2
|
||||
SEEK_HOLE = 0x4
|
||||
SEEK_MAX = 0x4
|
||||
SEEK_SET = 0x0
|
||||
SELINUX_MAGIC = 0xf97cff8c
|
||||
SHUT_RD = 0x0
|
||||
SHUT_RDWR = 0x2
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ const (
|
|||
CS8 = 0x30
|
||||
CSIZE = 0x30
|
||||
CSTOPB = 0x40
|
||||
ECCGETLAYOUT = 0x81484d11
|
||||
ECCGETSTATS = 0x80104d12
|
||||
ECHOCTL = 0x200
|
||||
ECHOE = 0x10
|
||||
ECHOK = 0x20
|
||||
|
|
@ -123,6 +125,19 @@ const (
|
|||
MCL_CURRENT = 0x1
|
||||
MCL_FUTURE = 0x2
|
||||
MCL_ONFAULT = 0x4
|
||||
MEMERASE = 0x40084d02
|
||||
MEMERASE64 = 0x40104d14
|
||||
MEMGETBADBLOCK = 0x40084d0b
|
||||
MEMGETINFO = 0x80204d01
|
||||
MEMGETOOBSEL = 0x80c84d0a
|
||||
MEMGETREGIONCOUNT = 0x80044d07
|
||||
MEMISLOCKED = 0x80084d17
|
||||
MEMLOCK = 0x40084d05
|
||||
MEMREADOOB = 0xc00c4d04
|
||||
MEMSETBADBLOCK = 0x40084d0c
|
||||
MEMUNLOCK = 0x40084d06
|
||||
MEMWRITEOOB = 0xc00c4d03
|
||||
MTDFILEMODE = 0x4d13
|
||||
NFDBITS = 0x20
|
||||
NLDLY = 0x100
|
||||
NOFLSH = 0x80
|
||||
|
|
@ -132,6 +147,10 @@ const (
|
|||
NS_GET_USERNS = 0xb701
|
||||
OLCUC = 0x2
|
||||
ONLCR = 0x4
|
||||
OTPGETREGIONCOUNT = 0x40044d0e
|
||||
OTPGETREGIONINFO = 0x400c4d0f
|
||||
OTPLOCK = 0x800c4d10
|
||||
OTPSELECT = 0x80044d0d
|
||||
O_APPEND = 0x400
|
||||
O_ASYNC = 0x2000
|
||||
O_CLOEXEC = 0x80000
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ const (
|
|||
CS8 = 0x30
|
||||
CSIZE = 0x30
|
||||
CSTOPB = 0x40
|
||||
ECCGETLAYOUT = 0x81484d11
|
||||
ECCGETSTATS = 0x80104d12
|
||||
ECHOCTL = 0x200
|
||||
ECHOE = 0x10
|
||||
ECHOK = 0x20
|
||||
|
|
@ -123,6 +125,19 @@ const (
|
|||
MCL_CURRENT = 0x1
|
||||
MCL_FUTURE = 0x2
|
||||
MCL_ONFAULT = 0x4
|
||||
MEMERASE = 0x40084d02
|
||||
MEMERASE64 = 0x40104d14
|
||||
MEMGETBADBLOCK = 0x40084d0b
|
||||
MEMGETINFO = 0x80204d01
|
||||
MEMGETOOBSEL = 0x80c84d0a
|
||||
MEMGETREGIONCOUNT = 0x80044d07
|
||||
MEMISLOCKED = 0x80084d17
|
||||
MEMLOCK = 0x40084d05
|
||||
MEMREADOOB = 0xc0104d04
|
||||
MEMSETBADBLOCK = 0x40084d0c
|
||||
MEMUNLOCK = 0x40084d06
|
||||
MEMWRITEOOB = 0xc0104d03
|
||||
MTDFILEMODE = 0x4d13
|
||||
NFDBITS = 0x40
|
||||
NLDLY = 0x100
|
||||
NOFLSH = 0x80
|
||||
|
|
@ -132,6 +147,10 @@ const (
|
|||
NS_GET_USERNS = 0xb701
|
||||
OLCUC = 0x2
|
||||
ONLCR = 0x4
|
||||
OTPGETREGIONCOUNT = 0x40044d0e
|
||||
OTPGETREGIONINFO = 0x400c4d0f
|
||||
OTPLOCK = 0x800c4d10
|
||||
OTPSELECT = 0x80044d0d
|
||||
O_APPEND = 0x400
|
||||
O_ASYNC = 0x2000
|
||||
O_CLOEXEC = 0x80000
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ const (
|
|||
CS8 = 0x30
|
||||
CSIZE = 0x30
|
||||
CSTOPB = 0x40
|
||||
ECCGETLAYOUT = 0x81484d11
|
||||
ECCGETSTATS = 0x80104d12
|
||||
ECHOCTL = 0x200
|
||||
ECHOE = 0x10
|
||||
ECHOK = 0x20
|
||||
|
|
@ -121,6 +123,19 @@ const (
|
|||
MCL_CURRENT = 0x1
|
||||
MCL_FUTURE = 0x2
|
||||
MCL_ONFAULT = 0x4
|
||||
MEMERASE = 0x40084d02
|
||||
MEMERASE64 = 0x40104d14
|
||||
MEMGETBADBLOCK = 0x40084d0b
|
||||
MEMGETINFO = 0x80204d01
|
||||
MEMGETOOBSEL = 0x80c84d0a
|
||||
MEMGETREGIONCOUNT = 0x80044d07
|
||||
MEMISLOCKED = 0x80084d17
|
||||
MEMLOCK = 0x40084d05
|
||||
MEMREADOOB = 0xc00c4d04
|
||||
MEMSETBADBLOCK = 0x40084d0c
|
||||
MEMUNLOCK = 0x40084d06
|
||||
MEMWRITEOOB = 0xc00c4d03
|
||||
MTDFILEMODE = 0x4d13
|
||||
NFDBITS = 0x20
|
||||
NLDLY = 0x100
|
||||
NOFLSH = 0x80
|
||||
|
|
@ -130,6 +145,10 @@ const (
|
|||
NS_GET_USERNS = 0xb701
|
||||
OLCUC = 0x2
|
||||
ONLCR = 0x4
|
||||
OTPGETREGIONCOUNT = 0x40044d0e
|
||||
OTPGETREGIONINFO = 0x400c4d0f
|
||||
OTPLOCK = 0x800c4d10
|
||||
OTPSELECT = 0x80044d0d
|
||||
O_APPEND = 0x400
|
||||
O_ASYNC = 0x2000
|
||||
O_CLOEXEC = 0x80000
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ const (
|
|||
CS8 = 0x30
|
||||
CSIZE = 0x30
|
||||
CSTOPB = 0x40
|
||||
ECCGETLAYOUT = 0x81484d11
|
||||
ECCGETSTATS = 0x80104d12
|
||||
ECHOCTL = 0x200
|
||||
ECHOE = 0x10
|
||||
ECHOK = 0x20
|
||||
|
|
@ -124,6 +126,19 @@ const (
|
|||
MCL_CURRENT = 0x1
|
||||
MCL_FUTURE = 0x2
|
||||
MCL_ONFAULT = 0x4
|
||||
MEMERASE = 0x40084d02
|
||||
MEMERASE64 = 0x40104d14
|
||||
MEMGETBADBLOCK = 0x40084d0b
|
||||
MEMGETINFO = 0x80204d01
|
||||
MEMGETOOBSEL = 0x80c84d0a
|
||||
MEMGETREGIONCOUNT = 0x80044d07
|
||||
MEMISLOCKED = 0x80084d17
|
||||
MEMLOCK = 0x40084d05
|
||||
MEMREADOOB = 0xc0104d04
|
||||
MEMSETBADBLOCK = 0x40084d0c
|
||||
MEMUNLOCK = 0x40084d06
|
||||
MEMWRITEOOB = 0xc0104d03
|
||||
MTDFILEMODE = 0x4d13
|
||||
NFDBITS = 0x40
|
||||
NLDLY = 0x100
|
||||
NOFLSH = 0x80
|
||||
|
|
@ -133,6 +148,10 @@ const (
|
|||
NS_GET_USERNS = 0xb701
|
||||
OLCUC = 0x2
|
||||
ONLCR = 0x4
|
||||
OTPGETREGIONCOUNT = 0x40044d0e
|
||||
OTPGETREGIONINFO = 0x400c4d0f
|
||||
OTPLOCK = 0x800c4d10
|
||||
OTPSELECT = 0x80044d0d
|
||||
O_APPEND = 0x400
|
||||
O_ASYNC = 0x2000
|
||||
O_CLOEXEC = 0x80000
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ const (
|
|||
CS8 = 0x30
|
||||
CSIZE = 0x30
|
||||
CSTOPB = 0x40
|
||||
ECCGETLAYOUT = 0x41484d11
|
||||
ECCGETSTATS = 0x40104d12
|
||||
ECHOCTL = 0x200
|
||||
ECHOE = 0x10
|
||||
ECHOK = 0x20
|
||||
|
|
@ -121,6 +123,19 @@ const (
|
|||
MCL_CURRENT = 0x1
|
||||
MCL_FUTURE = 0x2
|
||||
MCL_ONFAULT = 0x4
|
||||
MEMERASE = 0x80084d02
|
||||
MEMERASE64 = 0x80104d14
|
||||
MEMGETBADBLOCK = 0x80084d0b
|
||||
MEMGETINFO = 0x40204d01
|
||||
MEMGETOOBSEL = 0x40c84d0a
|
||||
MEMGETREGIONCOUNT = 0x40044d07
|
||||
MEMISLOCKED = 0x40084d17
|
||||
MEMLOCK = 0x80084d05
|
||||
MEMREADOOB = 0xc00c4d04
|
||||
MEMSETBADBLOCK = 0x80084d0c
|
||||
MEMUNLOCK = 0x80084d06
|
||||
MEMWRITEOOB = 0xc00c4d03
|
||||
MTDFILEMODE = 0x20004d13
|
||||
NFDBITS = 0x20
|
||||
NLDLY = 0x100
|
||||
NOFLSH = 0x80
|
||||
|
|
@ -130,6 +145,10 @@ const (
|
|||
NS_GET_USERNS = 0x2000b701
|
||||
OLCUC = 0x2
|
||||
ONLCR = 0x4
|
||||
OTPGETREGIONCOUNT = 0x80044d0e
|
||||
OTPGETREGIONINFO = 0x800c4d0f
|
||||
OTPLOCK = 0x400c4d10
|
||||
OTPSELECT = 0x40044d0d
|
||||
O_APPEND = 0x8
|
||||
O_ASYNC = 0x1000
|
||||
O_CLOEXEC = 0x80000
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ const (
|
|||
CS8 = 0x30
|
||||
CSIZE = 0x30
|
||||
CSTOPB = 0x40
|
||||
ECCGETLAYOUT = 0x41484d11
|
||||
ECCGETSTATS = 0x40104d12
|
||||
ECHOCTL = 0x200
|
||||
ECHOE = 0x10
|
||||
ECHOK = 0x20
|
||||
|
|
@ -121,6 +123,19 @@ const (
|
|||
MCL_CURRENT = 0x1
|
||||
MCL_FUTURE = 0x2
|
||||
MCL_ONFAULT = 0x4
|
||||
MEMERASE = 0x80084d02
|
||||
MEMERASE64 = 0x80104d14
|
||||
MEMGETBADBLOCK = 0x80084d0b
|
||||
MEMGETINFO = 0x40204d01
|
||||
MEMGETOOBSEL = 0x40c84d0a
|
||||
MEMGETREGIONCOUNT = 0x40044d07
|
||||
MEMISLOCKED = 0x40084d17
|
||||
MEMLOCK = 0x80084d05
|
||||
MEMREADOOB = 0xc0104d04
|
||||
MEMSETBADBLOCK = 0x80084d0c
|
||||
MEMUNLOCK = 0x80084d06
|
||||
MEMWRITEOOB = 0xc0104d03
|
||||
MTDFILEMODE = 0x20004d13
|
||||
NFDBITS = 0x40
|
||||
NLDLY = 0x100
|
||||
NOFLSH = 0x80
|
||||
|
|
@ -130,6 +145,10 @@ const (
|
|||
NS_GET_USERNS = 0x2000b701
|
||||
OLCUC = 0x2
|
||||
ONLCR = 0x4
|
||||
OTPGETREGIONCOUNT = 0x80044d0e
|
||||
OTPGETREGIONINFO = 0x800c4d0f
|
||||
OTPLOCK = 0x400c4d10
|
||||
OTPSELECT = 0x40044d0d
|
||||
O_APPEND = 0x8
|
||||
O_ASYNC = 0x1000
|
||||
O_CLOEXEC = 0x80000
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ const (
|
|||
CS8 = 0x30
|
||||
CSIZE = 0x30
|
||||
CSTOPB = 0x40
|
||||
ECCGETLAYOUT = 0x41484d11
|
||||
ECCGETSTATS = 0x40104d12
|
||||
ECHOCTL = 0x200
|
||||
ECHOE = 0x10
|
||||
ECHOK = 0x20
|
||||
|
|
@ -121,6 +123,19 @@ const (
|
|||
MCL_CURRENT = 0x1
|
||||
MCL_FUTURE = 0x2
|
||||
MCL_ONFAULT = 0x4
|
||||
MEMERASE = 0x80084d02
|
||||
MEMERASE64 = 0x80104d14
|
||||
MEMGETBADBLOCK = 0x80084d0b
|
||||
MEMGETINFO = 0x40204d01
|
||||
MEMGETOOBSEL = 0x40c84d0a
|
||||
MEMGETREGIONCOUNT = 0x40044d07
|
||||
MEMISLOCKED = 0x40084d17
|
||||
MEMLOCK = 0x80084d05
|
||||
MEMREADOOB = 0xc0104d04
|
||||
MEMSETBADBLOCK = 0x80084d0c
|
||||
MEMUNLOCK = 0x80084d06
|
||||
MEMWRITEOOB = 0xc0104d03
|
||||
MTDFILEMODE = 0x20004d13
|
||||
NFDBITS = 0x40
|
||||
NLDLY = 0x100
|
||||
NOFLSH = 0x80
|
||||
|
|
@ -130,6 +145,10 @@ const (
|
|||
NS_GET_USERNS = 0x2000b701
|
||||
OLCUC = 0x2
|
||||
ONLCR = 0x4
|
||||
OTPGETREGIONCOUNT = 0x80044d0e
|
||||
OTPGETREGIONINFO = 0x800c4d0f
|
||||
OTPLOCK = 0x400c4d10
|
||||
OTPSELECT = 0x40044d0d
|
||||
O_APPEND = 0x8
|
||||
O_ASYNC = 0x1000
|
||||
O_CLOEXEC = 0x80000
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ const (
|
|||
CS8 = 0x30
|
||||
CSIZE = 0x30
|
||||
CSTOPB = 0x40
|
||||
ECCGETLAYOUT = 0x41484d11
|
||||
ECCGETSTATS = 0x40104d12
|
||||
ECHOCTL = 0x200
|
||||
ECHOE = 0x10
|
||||
ECHOK = 0x20
|
||||
|
|
@ -121,6 +123,19 @@ const (
|
|||
MCL_CURRENT = 0x1
|
||||
MCL_FUTURE = 0x2
|
||||
MCL_ONFAULT = 0x4
|
||||
MEMERASE = 0x80084d02
|
||||
MEMERASE64 = 0x80104d14
|
||||
MEMGETBADBLOCK = 0x80084d0b
|
||||
MEMGETINFO = 0x40204d01
|
||||
MEMGETOOBSEL = 0x40c84d0a
|
||||
MEMGETREGIONCOUNT = 0x40044d07
|
||||
MEMISLOCKED = 0x40084d17
|
||||
MEMLOCK = 0x80084d05
|
||||
MEMREADOOB = 0xc00c4d04
|
||||
MEMSETBADBLOCK = 0x80084d0c
|
||||
MEMUNLOCK = 0x80084d06
|
||||
MEMWRITEOOB = 0xc00c4d03
|
||||
MTDFILEMODE = 0x20004d13
|
||||
NFDBITS = 0x20
|
||||
NLDLY = 0x100
|
||||
NOFLSH = 0x80
|
||||
|
|
@ -130,6 +145,10 @@ const (
|
|||
NS_GET_USERNS = 0x2000b701
|
||||
OLCUC = 0x2
|
||||
ONLCR = 0x4
|
||||
OTPGETREGIONCOUNT = 0x80044d0e
|
||||
OTPGETREGIONINFO = 0x800c4d0f
|
||||
OTPLOCK = 0x400c4d10
|
||||
OTPSELECT = 0x40044d0d
|
||||
O_APPEND = 0x8
|
||||
O_ASYNC = 0x1000
|
||||
O_CLOEXEC = 0x80000
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ const (
|
|||
CS8 = 0x300
|
||||
CSIZE = 0x300
|
||||
CSTOPB = 0x400
|
||||
ECCGETLAYOUT = 0x41484d11
|
||||
ECCGETSTATS = 0x40104d12
|
||||
ECHOCTL = 0x40
|
||||
ECHOE = 0x2
|
||||
ECHOK = 0x4
|
||||
|
|
@ -121,6 +123,19 @@ const (
|
|||
MCL_CURRENT = 0x2000
|
||||
MCL_FUTURE = 0x4000
|
||||
MCL_ONFAULT = 0x8000
|
||||
MEMERASE = 0x80084d02
|
||||
MEMERASE64 = 0x80104d14
|
||||
MEMGETBADBLOCK = 0x80084d0b
|
||||
MEMGETINFO = 0x40204d01
|
||||
MEMGETOOBSEL = 0x40c84d0a
|
||||
MEMGETREGIONCOUNT = 0x40044d07
|
||||
MEMISLOCKED = 0x40084d17
|
||||
MEMLOCK = 0x80084d05
|
||||
MEMREADOOB = 0xc00c4d04
|
||||
MEMSETBADBLOCK = 0x80084d0c
|
||||
MEMUNLOCK = 0x80084d06
|
||||
MEMWRITEOOB = 0xc00c4d03
|
||||
MTDFILEMODE = 0x20004d13
|
||||
NFDBITS = 0x20
|
||||
NL2 = 0x200
|
||||
NL3 = 0x300
|
||||
|
|
@ -132,6 +147,10 @@ const (
|
|||
NS_GET_USERNS = 0x2000b701
|
||||
OLCUC = 0x4
|
||||
ONLCR = 0x2
|
||||
OTPGETREGIONCOUNT = 0x80044d0e
|
||||
OTPGETREGIONINFO = 0x800c4d0f
|
||||
OTPLOCK = 0x400c4d10
|
||||
OTPSELECT = 0x40044d0d
|
||||
O_APPEND = 0x400
|
||||
O_ASYNC = 0x2000
|
||||
O_CLOEXEC = 0x80000
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ const (
|
|||
CS8 = 0x300
|
||||
CSIZE = 0x300
|
||||
CSTOPB = 0x400
|
||||
ECCGETLAYOUT = 0x41484d11
|
||||
ECCGETSTATS = 0x40104d12
|
||||
ECHOCTL = 0x40
|
||||
ECHOE = 0x2
|
||||
ECHOK = 0x4
|
||||
|
|
@ -121,6 +123,19 @@ const (
|
|||
MCL_CURRENT = 0x2000
|
||||
MCL_FUTURE = 0x4000
|
||||
MCL_ONFAULT = 0x8000
|
||||
MEMERASE = 0x80084d02
|
||||
MEMERASE64 = 0x80104d14
|
||||
MEMGETBADBLOCK = 0x80084d0b
|
||||
MEMGETINFO = 0x40204d01
|
||||
MEMGETOOBSEL = 0x40c84d0a
|
||||
MEMGETREGIONCOUNT = 0x40044d07
|
||||
MEMISLOCKED = 0x40084d17
|
||||
MEMLOCK = 0x80084d05
|
||||
MEMREADOOB = 0xc0104d04
|
||||
MEMSETBADBLOCK = 0x80084d0c
|
||||
MEMUNLOCK = 0x80084d06
|
||||
MEMWRITEOOB = 0xc0104d03
|
||||
MTDFILEMODE = 0x20004d13
|
||||
NFDBITS = 0x40
|
||||
NL2 = 0x200
|
||||
NL3 = 0x300
|
||||
|
|
@ -132,6 +147,10 @@ const (
|
|||
NS_GET_USERNS = 0x2000b701
|
||||
OLCUC = 0x4
|
||||
ONLCR = 0x2
|
||||
OTPGETREGIONCOUNT = 0x80044d0e
|
||||
OTPGETREGIONINFO = 0x800c4d0f
|
||||
OTPLOCK = 0x400c4d10
|
||||
OTPSELECT = 0x40044d0d
|
||||
O_APPEND = 0x400
|
||||
O_ASYNC = 0x2000
|
||||
O_CLOEXEC = 0x80000
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ const (
|
|||
CS8 = 0x300
|
||||
CSIZE = 0x300
|
||||
CSTOPB = 0x400
|
||||
ECCGETLAYOUT = 0x41484d11
|
||||
ECCGETSTATS = 0x40104d12
|
||||
ECHOCTL = 0x40
|
||||
ECHOE = 0x2
|
||||
ECHOK = 0x4
|
||||
|
|
@ -121,6 +123,19 @@ const (
|
|||
MCL_CURRENT = 0x2000
|
||||
MCL_FUTURE = 0x4000
|
||||
MCL_ONFAULT = 0x8000
|
||||
MEMERASE = 0x80084d02
|
||||
MEMERASE64 = 0x80104d14
|
||||
MEMGETBADBLOCK = 0x80084d0b
|
||||
MEMGETINFO = 0x40204d01
|
||||
MEMGETOOBSEL = 0x40c84d0a
|
||||
MEMGETREGIONCOUNT = 0x40044d07
|
||||
MEMISLOCKED = 0x40084d17
|
||||
MEMLOCK = 0x80084d05
|
||||
MEMREADOOB = 0xc0104d04
|
||||
MEMSETBADBLOCK = 0x80084d0c
|
||||
MEMUNLOCK = 0x80084d06
|
||||
MEMWRITEOOB = 0xc0104d03
|
||||
MTDFILEMODE = 0x20004d13
|
||||
NFDBITS = 0x40
|
||||
NL2 = 0x200
|
||||
NL3 = 0x300
|
||||
|
|
@ -132,6 +147,10 @@ const (
|
|||
NS_GET_USERNS = 0x2000b701
|
||||
OLCUC = 0x4
|
||||
ONLCR = 0x2
|
||||
OTPGETREGIONCOUNT = 0x80044d0e
|
||||
OTPGETREGIONINFO = 0x800c4d0f
|
||||
OTPLOCK = 0x400c4d10
|
||||
OTPSELECT = 0x40044d0d
|
||||
O_APPEND = 0x400
|
||||
O_ASYNC = 0x2000
|
||||
O_CLOEXEC = 0x80000
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ const (
|
|||
CS8 = 0x30
|
||||
CSIZE = 0x30
|
||||
CSTOPB = 0x40
|
||||
ECCGETLAYOUT = 0x81484d11
|
||||
ECCGETSTATS = 0x80104d12
|
||||
ECHOCTL = 0x200
|
||||
ECHOE = 0x10
|
||||
ECHOK = 0x20
|
||||
|
|
@ -121,6 +123,19 @@ const (
|
|||
MCL_CURRENT = 0x1
|
||||
MCL_FUTURE = 0x2
|
||||
MCL_ONFAULT = 0x4
|
||||
MEMERASE = 0x40084d02
|
||||
MEMERASE64 = 0x40104d14
|
||||
MEMGETBADBLOCK = 0x40084d0b
|
||||
MEMGETINFO = 0x80204d01
|
||||
MEMGETOOBSEL = 0x80c84d0a
|
||||
MEMGETREGIONCOUNT = 0x80044d07
|
||||
MEMISLOCKED = 0x80084d17
|
||||
MEMLOCK = 0x40084d05
|
||||
MEMREADOOB = 0xc0104d04
|
||||
MEMSETBADBLOCK = 0x40084d0c
|
||||
MEMUNLOCK = 0x40084d06
|
||||
MEMWRITEOOB = 0xc0104d03
|
||||
MTDFILEMODE = 0x4d13
|
||||
NFDBITS = 0x40
|
||||
NLDLY = 0x100
|
||||
NOFLSH = 0x80
|
||||
|
|
@ -130,6 +145,10 @@ const (
|
|||
NS_GET_USERNS = 0xb701
|
||||
OLCUC = 0x2
|
||||
ONLCR = 0x4
|
||||
OTPGETREGIONCOUNT = 0x40044d0e
|
||||
OTPGETREGIONINFO = 0x400c4d0f
|
||||
OTPLOCK = 0x800c4d10
|
||||
OTPSELECT = 0x80044d0d
|
||||
O_APPEND = 0x400
|
||||
O_ASYNC = 0x2000
|
||||
O_CLOEXEC = 0x80000
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ const (
|
|||
CS8 = 0x30
|
||||
CSIZE = 0x30
|
||||
CSTOPB = 0x40
|
||||
ECCGETLAYOUT = 0x81484d11
|
||||
ECCGETSTATS = 0x80104d12
|
||||
ECHOCTL = 0x200
|
||||
ECHOE = 0x10
|
||||
ECHOK = 0x20
|
||||
|
|
@ -121,6 +123,19 @@ const (
|
|||
MCL_CURRENT = 0x1
|
||||
MCL_FUTURE = 0x2
|
||||
MCL_ONFAULT = 0x4
|
||||
MEMERASE = 0x40084d02
|
||||
MEMERASE64 = 0x40104d14
|
||||
MEMGETBADBLOCK = 0x40084d0b
|
||||
MEMGETINFO = 0x80204d01
|
||||
MEMGETOOBSEL = 0x80c84d0a
|
||||
MEMGETREGIONCOUNT = 0x80044d07
|
||||
MEMISLOCKED = 0x80084d17
|
||||
MEMLOCK = 0x40084d05
|
||||
MEMREADOOB = 0xc0104d04
|
||||
MEMSETBADBLOCK = 0x40084d0c
|
||||
MEMUNLOCK = 0x40084d06
|
||||
MEMWRITEOOB = 0xc0104d03
|
||||
MTDFILEMODE = 0x4d13
|
||||
NFDBITS = 0x40
|
||||
NLDLY = 0x100
|
||||
NOFLSH = 0x80
|
||||
|
|
@ -130,6 +145,10 @@ const (
|
|||
NS_GET_USERNS = 0xb701
|
||||
OLCUC = 0x2
|
||||
ONLCR = 0x4
|
||||
OTPGETREGIONCOUNT = 0x40044d0e
|
||||
OTPGETREGIONINFO = 0x400c4d0f
|
||||
OTPLOCK = 0x800c4d10
|
||||
OTPSELECT = 0x80044d0d
|
||||
O_APPEND = 0x400
|
||||
O_ASYNC = 0x2000
|
||||
O_CLOEXEC = 0x80000
|
||||
|
|
@ -212,6 +231,8 @@ const (
|
|||
PTRACE_POKE_SYSTEM_CALL = 0x5008
|
||||
PTRACE_PROT = 0x15
|
||||
PTRACE_SINGLEBLOCK = 0xc
|
||||
PTRACE_SYSEMU = 0x1f
|
||||
PTRACE_SYSEMU_SINGLESTEP = 0x20
|
||||
PTRACE_TE_ABORT_RAND = 0x5011
|
||||
PT_ACR0 = 0x90
|
||||
PT_ACR1 = 0x94
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue