build(deps): bump github.com/miekg/dns from 1.1.50 to 1.1.55 (#7067)
Bumps github.com/miekg/dns from 1.1.50 to 1.1.55. Changelog: https://github.com/miekg/dns/compare/v1.1.50...v1.1.55
This commit is contained in:
		
							parent
							
								
									b13174538d
								
							
						
					
					
						commit
						6d76a0f91e
					
				
							
								
								
									
										2
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										2
									
								
								go.mod
								
								
								
								
							|  | @ -19,7 +19,7 @@ require ( | |||
| 	github.com/letsencrypt/challtestsrv v1.2.1 | ||||
| 	github.com/letsencrypt/pkcs11key/v4 v4.0.0 | ||||
| 	github.com/letsencrypt/validator/v10 v10.0.0-20230215210743-a0c7dfc17158 | ||||
| 	github.com/miekg/dns v1.1.50 | ||||
| 	github.com/miekg/dns v1.1.55 | ||||
| 	github.com/miekg/pkcs11 v1.1.1 | ||||
| 	github.com/prometheus/client_golang v1.15.1 | ||||
| 	github.com/prometheus/client_model v0.4.0 | ||||
|  |  | |||
							
								
								
									
										11
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										11
									
								
								go.sum
								
								
								
								
							|  | @ -282,8 +282,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5 | |||
| github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= | ||||
| github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= | ||||
| github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= | ||||
| github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= | ||||
| github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= | ||||
| github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= | ||||
| github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= | ||||
| github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= | ||||
| github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= | ||||
| github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= | ||||
|  | @ -365,7 +365,6 @@ github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1: | |||
| github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||||
| github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||||
| github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||||
| github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= | ||||
| github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= | ||||
| github.com/zmap/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE= | ||||
| github.com/zmap/rc2 v0.0.0-20190804163417-abaa70531248/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE= | ||||
|  | @ -453,7 +452,6 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB | |||
| golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/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/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= | ||||
| golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= | ||||
| golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= | ||||
| golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= | ||||
|  | @ -491,7 +489,6 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY | |||
| golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | ||||
| golang.org/x/net v0.0.0-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-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | ||||
| golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= | ||||
| golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= | ||||
| golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= | ||||
|  | @ -556,10 +553,8 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w | |||
| golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
|  | @ -586,7 +581,6 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= | |||
| golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||
| golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||
| golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||
| golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||
| golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= | ||||
| golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= | ||||
| golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= | ||||
|  | @ -638,7 +632,6 @@ golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roY | |||
| golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= | ||||
| golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= | ||||
| golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= | ||||
| golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= | ||||
| golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= | ||||
| golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= | ||||
| golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= | ||||
|  |  | |||
|  | @ -1,30 +1,29 @@ | |||
| Copyright (c) 2009 The Go Authors. All rights reserved. | ||||
| BSD 3-Clause License | ||||
| 
 | ||||
| Copyright (c) 2009, The Go Authors. Extensions copyright (c) 2011, Miek Gieben.  | ||||
| All rights reserved. | ||||
| 
 | ||||
| Redistribution and use in source and binary forms, with or without | ||||
| modification, are permitted provided that the following conditions are | ||||
| met: | ||||
| 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. | ||||
| 1. Redistributions of source code must retain the above copyright notice, this | ||||
|    list of conditions and the following disclaimer. | ||||
| 
 | ||||
| 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 | ||||
| 2. 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. | ||||
| 
 | ||||
| 3. Neither the name of the copyright holder 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 HOLDER OR CONTRIBUTORS BE LIABLE | ||||
| FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
| DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||||
| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||||
| CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||||
| OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
| 
 | ||||
| As this is fork of the official Go code the same license applies. | ||||
| Extensions of the original work are copyright (c) 2011 Miek Gieben | ||||
|  |  | |||
|  | @ -77,6 +77,10 @@ A not-so-up-to-date-list-that-may-be-actually-current: | |||
| * https://ping.sx/dig | ||||
| * https://fleetdeck.io/ | ||||
| * https://github.com/markdingo/autoreverse | ||||
| * https://github.com/slackhq/nebula | ||||
| * https://addr.tools/ | ||||
| * https://dnscheck.tools/ | ||||
| * https://github.com/egbakou/domainverifier | ||||
| 
 | ||||
| 
 | ||||
| Send pull request if you want to be listed here. | ||||
|  | @ -140,6 +144,7 @@ Example programs can be found in the `github.com/miekg/exdns` repository. | |||
| * 340{1,2,3} - NAPTR record | ||||
| * 3445 - Limiting the scope of (DNS)KEY | ||||
| * 3597 - Unknown RRs | ||||
| * 4025 - A Method for Storing IPsec Keying Material in DNS | ||||
| * 403{3,4,5} - DNSSEC + validation functions | ||||
| * 4255 - SSHFP record | ||||
| * 4343 - Case insensitivity | ||||
|  | @ -175,6 +180,7 @@ Example programs can be found in the `github.com/miekg/exdns` repository. | |||
| * 8080 - EdDSA for DNSSEC | ||||
| * 8499 - DNS Terminology | ||||
| * 8659 - DNS Certification Authority Authorization (CAA) Resource Record | ||||
| * 8777 - DNS Reverse IP Automatic Multicast Tunneling (AMT) Discovery | ||||
| * 8914 - Extended DNS Errors | ||||
| * 8976 - Message Digest for DNS Zones (ZONEMD RR) | ||||
| 
 | ||||
|  |  | |||
|  | @ -19,7 +19,6 @@ type MsgAcceptFunc func(dh Header) MsgAcceptAction | |||
| // * has more than 0 RRs in the Authority section
 | ||||
| //
 | ||||
| // * has more than 2 RRs in the Additional section
 | ||||
| //
 | ||||
| var DefaultMsgAcceptFunc MsgAcceptFunc = defaultMsgAcceptFunc | ||||
| 
 | ||||
| // MsgAcceptAction represents the action to be taken.
 | ||||
|  |  | |||
|  | @ -6,7 +6,6 @@ import ( | |||
| 	"context" | ||||
| 	"crypto/tls" | ||||
| 	"encoding/binary" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"net" | ||||
| 	"strings" | ||||
|  | @ -56,14 +55,20 @@ type Client struct { | |||
| 	// Timeout is a cumulative timeout for dial, write and read, defaults to 0 (disabled) - overrides DialTimeout, ReadTimeout,
 | ||||
| 	// WriteTimeout when non-zero. Can be overridden with net.Dialer.Timeout (see Client.ExchangeWithDialer and
 | ||||
| 	// Client.Dialer) or context.Context.Deadline (see ExchangeContext)
 | ||||
| 	Timeout        time.Duration | ||||
| 	DialTimeout    time.Duration     // net.DialTimeout, defaults to 2 seconds, or net.Dialer.Timeout if expiring earlier - overridden by Timeout when that value is non-zero
 | ||||
| 	ReadTimeout    time.Duration     // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero
 | ||||
| 	WriteTimeout   time.Duration     // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero
 | ||||
| 	TsigSecret     map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2)
 | ||||
| 	TsigProvider   TsigProvider      // An implementation of the TsigProvider interface. If defined it replaces TsigSecret and is used for all TSIG operations.
 | ||||
| 	SingleInflight bool              // if true suppress multiple outstanding queries for the same Qname, Qtype and Qclass
 | ||||
| 	group          singleflight | ||||
| 	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 previously serialised multiple concurrent queries for the
 | ||||
| 	// same Qname, Qtype and Qclass to ensure only one would be in flight at a
 | ||||
| 	// time.
 | ||||
| 	//
 | ||||
| 	// Deprecated: This is a no-op. Callers should implement their own in flight
 | ||||
| 	// query caching if needed. See github.com/miekg/dns/issues/1449.
 | ||||
| 	SingleInflight bool | ||||
| } | ||||
| 
 | ||||
| // Exchange performs a synchronous UDP query. It sends the message m to the address
 | ||||
|  | @ -106,7 +111,6 @@ func (c *Client) Dial(address string) (conn *Conn, err error) { | |||
| } | ||||
| 
 | ||||
| // 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 | ||||
|  | @ -127,15 +131,11 @@ func (c *Client) DialContext(ctx context.Context, address string) (conn *Conn, e | |||
| 	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) | ||||
| 		tlsDialer := tls.Dialer{ | ||||
| 			NetDialer: &d, | ||||
| 			Config:    c.TLSConfig, | ||||
| 		} | ||||
| 		conn.Conn, err = tlsDialer.DialContext(ctx, network, address) | ||||
| 	} else { | ||||
| 		conn.Conn, err = d.DialContext(ctx, network, address) | ||||
| 	} | ||||
|  | @ -183,33 +183,13 @@ func (c *Client) Exchange(m *Msg, address string) (r *Msg, rtt time.Duration, er | |||
| // 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) | ||||
| 	return c.ExchangeWithConnContext(context.Background(), m, conn) | ||||
| } | ||||
| 
 | ||||
| func (c *Client) exchangeWithConnContext(ctx context.Context, m *Msg, conn *Conn) (r *Msg, rtt time.Duration, err error) { | ||||
| 	if !c.SingleInflight { | ||||
| 		return c.exchangeContext(ctx, m, conn) | ||||
| 	} | ||||
| 
 | ||||
| 	q := m.Question[0] | ||||
| 	key := fmt.Sprintf("%s:%d:%d", q.Name, q.Qtype, q.Qclass) | ||||
| 	r, rtt, err, shared := c.group.Do(key, func() (*Msg, time.Duration, error) { | ||||
| 		// When we're doing singleflight we don't want one context cancelation, cancel _all_ outstanding queries.
 | ||||
| 		// Hence we ignore the context and use Background().
 | ||||
| 		return c.exchangeContext(context.Background(), m, conn) | ||||
| 	}) | ||||
| 	if r != nil && shared { | ||||
| 		r = r.Copy() | ||||
| 	} | ||||
| 
 | ||||
| 	return r, rtt, err | ||||
| } | ||||
| 
 | ||||
| func (c *Client) exchangeContext(ctx context.Context, m *Msg, co *Conn) (r *Msg, rtt time.Duration, err error) { | ||||
| // ExchangeWithConnContext has the same behaviour as ExchangeWithConn and
 | ||||
| // additionally obeys deadlines from the passed Context.
 | ||||
| func (c *Client) ExchangeWithConnContext(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 { | ||||
|  | @ -431,7 +411,6 @@ func ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, err error) | |||
| //	co.WriteMsg(m)
 | ||||
| //	in, _  := co.ReadMsg()
 | ||||
| //	co.Close()
 | ||||
| //
 | ||||
| func ExchangeConn(c net.Conn, m *Msg) (r *Msg, err error) { | ||||
| 	println("dns: ExchangeConn: this function is deprecated") | ||||
| 	co := new(Conn) | ||||
|  | @ -480,5 +459,5 @@ func (c *Client) ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, | |||
| 	} | ||||
| 	defer conn.Close() | ||||
| 
 | ||||
| 	return c.exchangeWithConnContext(ctx, m, conn) | ||||
| 	return c.ExchangeWithConnContext(ctx, m, conn) | ||||
| } | ||||
|  |  | |||
|  | @ -68,7 +68,7 @@ func ClientConfigFromReader(resolvconf io.Reader) (*ClientConfig, error) { | |||
| 			} | ||||
| 
 | ||||
| 		case "search": // set search path to given servers
 | ||||
| 			c.Search = append([]string(nil), f[1:]...) | ||||
| 			c.Search = cloneSlice(f[1:]) | ||||
| 
 | ||||
| 		case "options": // magic options
 | ||||
| 			for _, s := range f[1:] { | ||||
|  |  | |||
|  | @ -208,7 +208,7 @@ func IsDomainName(s string) (labels int, ok bool) { | |||
| 			} | ||||
| 
 | ||||
| 			// check for \DDD
 | ||||
| 			if i+3 < len(s) && isDigit(s[i+1]) && isDigit(s[i+2]) && isDigit(s[i+3]) { | ||||
| 			if isDDD(s[i+1:]) { | ||||
| 				i += 3 | ||||
| 				begin += 3 | ||||
| 			} else { | ||||
|  | @ -272,18 +272,24 @@ func IsMsg(buf []byte) error { | |||
| 
 | ||||
| // IsFqdn checks if a domain name is fully qualified.
 | ||||
| func IsFqdn(s string) bool { | ||||
| 	s2 := strings.TrimSuffix(s, ".") | ||||
| 	if s == s2 { | ||||
| 	// Check for (and remove) a trailing dot, returning if there isn't one.
 | ||||
| 	if s == "" || s[len(s)-1] != '.' { | ||||
| 		return false | ||||
| 	} | ||||
| 	s = s[:len(s)-1] | ||||
| 
 | ||||
| 	i := strings.LastIndexFunc(s2, func(r rune) bool { | ||||
| 	// If we don't have an escape sequence before the final dot, we know it's
 | ||||
| 	// fully qualified and can return here.
 | ||||
| 	if s == "" || s[len(s)-1] != '\\' { | ||||
| 		return true | ||||
| 	} | ||||
| 
 | ||||
| 	// Otherwise we have to check if the dot is escaped or not by checking if
 | ||||
| 	// there are an odd or even number of escape sequences before the dot.
 | ||||
| 	i := strings.LastIndexFunc(s, func(r rune) bool { | ||||
| 		return r != '\\' | ||||
| 	}) | ||||
| 
 | ||||
| 	// Test whether we have an even number of escape sequences before
 | ||||
| 	// the dot or none.
 | ||||
| 	return (len(s2)-i)%2 != 0 | ||||
| 	return (len(s)-i)%2 != 0 | ||||
| } | ||||
| 
 | ||||
| // IsRRset checks if a set of RRs is a valid RRset as defined by RFC 2181.
 | ||||
|  |  | |||
|  | @ -128,10 +128,6 @@ type dnskeyWireFmt struct { | |||
| 	/* Nothing is left out */ | ||||
| } | ||||
| 
 | ||||
| func divRoundUp(a, b int) int { | ||||
| 	return (a + b - 1) / b | ||||
| } | ||||
| 
 | ||||
| // KeyTag calculates the keytag (or key-id) of the DNSKEY.
 | ||||
| func (k *DNSKEY) KeyTag() uint16 { | ||||
| 	if k == nil { | ||||
|  | @ -417,11 +413,11 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error { | |||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	sigbuf := rr.sigBuf()           // Get the binary signature data
 | ||||
| 	if rr.Algorithm == PRIVATEDNS { // PRIVATEOID
 | ||||
| 		// TODO(miek)
 | ||||
| 		// remove the domain name and assume its ours?
 | ||||
| 	} | ||||
| 	sigbuf := rr.sigBuf() // Get the binary signature data
 | ||||
| 	// TODO(miek)
 | ||||
| 	// remove the domain name and assume its ours?
 | ||||
| 	// if rr.Algorithm == PRIVATEDNS { // PRIVATEOID
 | ||||
| 	// }
 | ||||
| 
 | ||||
| 	h, cryptohash, err := hashFromAlgorithm(rr.Algorithm) | ||||
| 	if err != nil { | ||||
|  |  | |||
|  | @ -13,28 +13,28 @@ names in a message will result in a packing failure. | |||
| Resource records are native types. They are not stored in wire format. Basic | ||||
| usage pattern for creating a new resource record: | ||||
| 
 | ||||
|      r := new(dns.MX) | ||||
|      r.Hdr = dns.RR_Header{Name: "miek.nl.", Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: 3600} | ||||
|      r.Preference = 10 | ||||
|      r.Mx = "mx.miek.nl." | ||||
| 	r := new(dns.MX) | ||||
| 	r.Hdr = dns.RR_Header{Name: "miek.nl.", Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: 3600} | ||||
| 	r.Preference = 10 | ||||
| 	r.Mx = "mx.miek.nl." | ||||
| 
 | ||||
| Or directly from a string: | ||||
| 
 | ||||
|      mx, err := dns.NewRR("miek.nl. 3600 IN MX 10 mx.miek.nl.") | ||||
| 	mx, err := dns.NewRR("miek.nl. 3600 IN MX 10 mx.miek.nl.") | ||||
| 
 | ||||
| Or when the default origin (.) and TTL (3600) and class (IN) suit you: | ||||
| 
 | ||||
|      mx, err := dns.NewRR("miek.nl MX 10 mx.miek.nl") | ||||
| 	mx, err := dns.NewRR("miek.nl MX 10 mx.miek.nl") | ||||
| 
 | ||||
| Or even: | ||||
| 
 | ||||
|      mx, err := dns.NewRR("$ORIGIN nl.\nmiek 1H IN MX 10 mx.miek") | ||||
| 	mx, err := dns.NewRR("$ORIGIN nl.\nmiek 1H IN MX 10 mx.miek") | ||||
| 
 | ||||
| In the DNS messages are exchanged, these messages contain resource records | ||||
| (sets). Use pattern for creating a message: | ||||
| 
 | ||||
|      m := new(dns.Msg) | ||||
|      m.SetQuestion("miek.nl.", dns.TypeMX) | ||||
| 	m := new(dns.Msg) | ||||
| 	m.SetQuestion("miek.nl.", dns.TypeMX) | ||||
| 
 | ||||
| Or when not certain if the domain name is fully qualified: | ||||
| 
 | ||||
|  | @ -45,17 +45,17 @@ records for the miek.nl. zone. | |||
| 
 | ||||
| The following is slightly more verbose, but more flexible: | ||||
| 
 | ||||
|      m1 := new(dns.Msg) | ||||
|      m1.Id = dns.Id() | ||||
|      m1.RecursionDesired = true | ||||
|      m1.Question = make([]dns.Question, 1) | ||||
|      m1.Question[0] = dns.Question{"miek.nl.", dns.TypeMX, dns.ClassINET} | ||||
| 	m1 := new(dns.Msg) | ||||
| 	m1.Id = dns.Id() | ||||
| 	m1.RecursionDesired = true | ||||
| 	m1.Question = make([]dns.Question, 1) | ||||
| 	m1.Question[0] = dns.Question{"miek.nl.", dns.TypeMX, dns.ClassINET} | ||||
| 
 | ||||
| After creating a message it can be sent. Basic use pattern for synchronous | ||||
| querying the DNS at a server configured on 127.0.0.1 and port 53: | ||||
| 
 | ||||
|      c := new(dns.Client) | ||||
|      in, rtt, err := c.Exchange(m1, "127.0.0.1:53") | ||||
| 	c := new(dns.Client) | ||||
| 	in, rtt, err := c.Exchange(m1, "127.0.0.1:53") | ||||
| 
 | ||||
| Suppressing multiple outstanding queries (with the same question, type and | ||||
| class) is as easy as setting: | ||||
|  | @ -72,7 +72,7 @@ and port to use for the connection: | |||
| 		Port: 12345, | ||||
| 		Zone: "", | ||||
| 	} | ||||
| 	c.Dialer := &net.Dialer{ | ||||
| 	c.Dialer = &net.Dialer{ | ||||
| 		Timeout: 200 * time.Millisecond, | ||||
| 		LocalAddr: &laddr, | ||||
| 	} | ||||
|  | @ -96,7 +96,7 @@ the Answer section: | |||
| 		// do something with t.Txt
 | ||||
| 	} | ||||
| 
 | ||||
| Domain Name and TXT Character String Representations | ||||
| # Domain Name and TXT Character String Representations | ||||
| 
 | ||||
| Both domain names and TXT character strings are converted to presentation form | ||||
| both when unpacked and when converted to strings. | ||||
|  | @ -108,7 +108,7 @@ be escaped. Bytes below 32 and above 127 will be converted to \DDD form. | |||
| For domain names, in addition to the above rules brackets, periods, spaces, | ||||
| semicolons and the at symbol are escaped. | ||||
| 
 | ||||
| DNSSEC | ||||
| # DNSSEC | ||||
| 
 | ||||
| DNSSEC (DNS Security Extension) adds a layer of security to the DNS. It uses | ||||
| public key cryptography to sign resource records. The public keys are stored in | ||||
|  | @ -117,12 +117,12 @@ DNSKEY records and the signatures in RRSIG records. | |||
| Requesting DNSSEC information for a zone is done by adding the DO (DNSSEC OK) | ||||
| bit to a request. | ||||
| 
 | ||||
|      m := new(dns.Msg) | ||||
|      m.SetEdns0(4096, true) | ||||
| 	m := new(dns.Msg) | ||||
| 	m.SetEdns0(4096, true) | ||||
| 
 | ||||
| Signature generation, signature verification and key generation are all supported. | ||||
| 
 | ||||
| DYNAMIC UPDATES | ||||
| # DYNAMIC UPDATES | ||||
| 
 | ||||
| Dynamic updates reuses the DNS message format, but renames three of the | ||||
| sections. Question is Zone, Answer is Prerequisite, Authority is Update, only | ||||
|  | @ -133,30 +133,30 @@ certain resource records or names in a zone to specify if resource records | |||
| should be added or removed. The table from RFC 2136 supplemented with the Go | ||||
| DNS function shows which functions exist to specify the prerequisites. | ||||
| 
 | ||||
|  3.2.4 - Table Of Metavalues Used In Prerequisite Section | ||||
| 	3.2.4 - Table Of Metavalues Used In Prerequisite Section | ||||
| 
 | ||||
|   CLASS    TYPE     RDATA    Meaning                    Function | ||||
|   -------------------------------------------------------------- | ||||
|   ANY      ANY      empty    Name is in use             dns.NameUsed | ||||
|   ANY      rrset    empty    RRset exists (value indep) dns.RRsetUsed | ||||
|   NONE     ANY      empty    Name is not in use         dns.NameNotUsed | ||||
|   NONE     rrset    empty    RRset does not exist       dns.RRsetNotUsed | ||||
|   zone     rrset    rr       RRset exists (value dep)   dns.Used | ||||
| 	 CLASS    TYPE     RDATA    Meaning                    Function | ||||
| 	 -------------------------------------------------------------- | ||||
| 	 ANY      ANY      empty    Name is in use             dns.NameUsed | ||||
| 	 ANY      rrset    empty    RRset exists (value indep) dns.RRsetUsed | ||||
| 	 NONE     ANY      empty    Name is not in use         dns.NameNotUsed | ||||
| 	 NONE     rrset    empty    RRset does not exist       dns.RRsetNotUsed | ||||
| 	 zone     rrset    rr       RRset exists (value dep)   dns.Used | ||||
| 
 | ||||
| The prerequisite section can also be left empty. If you have decided on the | ||||
| prerequisites you can tell what RRs should be added or deleted. The next table | ||||
| shows the options you have and what functions to call. | ||||
| 
 | ||||
|  3.4.2.6 - Table Of Metavalues Used In Update Section | ||||
| 	3.4.2.6 - Table Of Metavalues Used In Update Section | ||||
| 
 | ||||
|   CLASS    TYPE     RDATA    Meaning                     Function | ||||
|   --------------------------------------------------------------- | ||||
|   ANY      ANY      empty    Delete all RRsets from name dns.RemoveName | ||||
|   ANY      rrset    empty    Delete an RRset             dns.RemoveRRset | ||||
|   NONE     rrset    rr       Delete an RR from RRset     dns.Remove | ||||
|   zone     rrset    rr       Add to an RRset             dns.Insert | ||||
| 	 CLASS    TYPE     RDATA    Meaning                     Function | ||||
| 	 --------------------------------------------------------------- | ||||
| 	 ANY      ANY      empty    Delete all RRsets from name dns.RemoveName | ||||
| 	 ANY      rrset    empty    Delete an RRset             dns.RemoveRRset | ||||
| 	 NONE     rrset    rr       Delete an RR from RRset     dns.Remove | ||||
| 	 zone     rrset    rr       Add to an RRset             dns.Insert | ||||
| 
 | ||||
| TRANSACTION SIGNATURE | ||||
| # TRANSACTION SIGNATURE | ||||
| 
 | ||||
| An TSIG or transaction signature adds a HMAC TSIG record to each message sent. | ||||
| The supported algorithms include: HmacSHA1, HmacSHA256 and HmacSHA512. | ||||
|  | @ -239,7 +239,7 @@ Basic use pattern validating and replying to a message that has TSIG set. | |||
| 		w.WriteMsg(m) | ||||
| 	} | ||||
| 
 | ||||
| PRIVATE RRS | ||||
| # PRIVATE RRS | ||||
| 
 | ||||
| RFC 6895 sets aside a range of type codes for private use. This range is 65,280 | ||||
| - 65,534 (0xFF00 - 0xFFFE). When experimenting with new Resource Records these | ||||
|  | @ -248,7 +248,7 @@ can be used, before requesting an official type code from IANA. | |||
| See https://miek.nl/2014/september/21/idn-and-private-rr-in-go-dns/ for more
 | ||||
| information. | ||||
| 
 | ||||
| EDNS0 | ||||
| # EDNS0 | ||||
| 
 | ||||
| EDNS0 is an extension mechanism for the DNS defined in RFC 2671 and updated by | ||||
| RFC 6891. It defines a new RR type, the OPT RR, which is then completely | ||||
|  | @ -279,9 +279,9 @@ SIG(0) | |||
| 
 | ||||
| From RFC 2931: | ||||
| 
 | ||||
|     SIG(0) provides protection for DNS transactions and requests .... | ||||
|     ... protection for glue records, DNS requests, protection for message headers | ||||
|     on requests and responses, and protection of the overall integrity of a response. | ||||
| 	SIG(0) provides protection for DNS transactions and requests .... | ||||
| 	... protection for glue records, DNS requests, protection for message headers | ||||
| 	on requests and responses, and protection of the overall integrity of a response. | ||||
| 
 | ||||
| It works like TSIG, except that SIG(0) uses public key cryptography, instead of | ||||
| the shared secret approach in TSIG. Supported algorithms: ECDSAP256SHA256, | ||||
|  |  | |||
|  | @ -78,7 +78,10 @@ func (rr *OPT) String() string { | |||
| 	if rr.Do() { | ||||
| 		s += "flags: do; " | ||||
| 	} else { | ||||
| 		s += "flags: ; " | ||||
| 		s += "flags:; " | ||||
| 	} | ||||
| 	if rr.Hdr.Ttl&0x7FFF != 0 { | ||||
| 		s += fmt.Sprintf("MBZ: 0x%04x, ", rr.Hdr.Ttl&0x7FFF) | ||||
| 	} | ||||
| 	s += "udp: " + strconv.Itoa(int(rr.UDPSize())) | ||||
| 
 | ||||
|  | @ -98,6 +101,8 @@ func (rr *OPT) String() string { | |||
| 			s += "\n; SUBNET: " + o.String() | ||||
| 		case *EDNS0_COOKIE: | ||||
| 			s += "\n; COOKIE: " + o.String() | ||||
| 		case *EDNS0_EXPIRE: | ||||
| 			s += "\n; EXPIRE: " + o.String() | ||||
| 		case *EDNS0_TCP_KEEPALIVE: | ||||
| 			s += "\n; KEEPALIVE: " + o.String() | ||||
| 		case *EDNS0_UL: | ||||
|  | @ -258,7 +263,7 @@ func (e *EDNS0_NSID) copy() EDNS0           { return &EDNS0_NSID{e.Code, e.Nsid} | |||
| //	o.Hdr.Name = "."
 | ||||
| //	o.Hdr.Rrtype = dns.TypeOPT
 | ||||
| //	e := new(dns.EDNS0_SUBNET)
 | ||||
| //	e.Code = dns.EDNS0SUBNET
 | ||||
| //	e.Code = dns.EDNS0SUBNET // by default this is filled in through unpacking OPT packets (unpackDataOpt)
 | ||||
| //	e.Family = 1	// 1 for IPv4 source address, 2 for IPv6
 | ||||
| //	e.SourceNetmask = 32	// 32 for IPV4, 128 for IPv6
 | ||||
| //	e.SourceScope = 0
 | ||||
|  | @ -515,8 +520,8 @@ type EDNS0_DAU struct { | |||
| 
 | ||||
| // Option implements the EDNS0 interface.
 | ||||
| func (e *EDNS0_DAU) Option() uint16        { return EDNS0DAU } | ||||
| func (e *EDNS0_DAU) pack() ([]byte, error) { return e.AlgCode, nil } | ||||
| func (e *EDNS0_DAU) unpack(b []byte) error { e.AlgCode = b; return nil } | ||||
| func (e *EDNS0_DAU) pack() ([]byte, error) { return cloneSlice(e.AlgCode), nil } | ||||
| func (e *EDNS0_DAU) unpack(b []byte) error { e.AlgCode = cloneSlice(b); return nil } | ||||
| 
 | ||||
| func (e *EDNS0_DAU) String() string { | ||||
| 	s := "" | ||||
|  | @ -539,8 +544,8 @@ type EDNS0_DHU struct { | |||
| 
 | ||||
| // Option implements the EDNS0 interface.
 | ||||
| func (e *EDNS0_DHU) Option() uint16        { return EDNS0DHU } | ||||
| func (e *EDNS0_DHU) pack() ([]byte, error) { return e.AlgCode, nil } | ||||
| func (e *EDNS0_DHU) unpack(b []byte) error { e.AlgCode = b; return nil } | ||||
| func (e *EDNS0_DHU) pack() ([]byte, error) { return cloneSlice(e.AlgCode), nil } | ||||
| func (e *EDNS0_DHU) unpack(b []byte) error { e.AlgCode = cloneSlice(b); return nil } | ||||
| 
 | ||||
| func (e *EDNS0_DHU) String() string { | ||||
| 	s := "" | ||||
|  | @ -563,8 +568,8 @@ type EDNS0_N3U struct { | |||
| 
 | ||||
| // Option implements the EDNS0 interface.
 | ||||
| func (e *EDNS0_N3U) Option() uint16        { return EDNS0N3U } | ||||
| func (e *EDNS0_N3U) pack() ([]byte, error) { return e.AlgCode, nil } | ||||
| func (e *EDNS0_N3U) unpack(b []byte) error { e.AlgCode = b; return nil } | ||||
| func (e *EDNS0_N3U) pack() ([]byte, error) { return cloneSlice(e.AlgCode), nil } | ||||
| func (e *EDNS0_N3U) unpack(b []byte) error { e.AlgCode = cloneSlice(b); return nil } | ||||
| 
 | ||||
| func (e *EDNS0_N3U) String() string { | ||||
| 	// Re-use the hash map
 | ||||
|  | @ -641,30 +646,21 @@ type EDNS0_LOCAL struct { | |||
| 
 | ||||
| // Option implements the EDNS0 interface.
 | ||||
| func (e *EDNS0_LOCAL) Option() uint16 { return e.Code } | ||||
| 
 | ||||
| func (e *EDNS0_LOCAL) String() string { | ||||
| 	return strconv.FormatInt(int64(e.Code), 10) + ":0x" + hex.EncodeToString(e.Data) | ||||
| } | ||||
| 
 | ||||
| func (e *EDNS0_LOCAL) copy() EDNS0 { | ||||
| 	b := make([]byte, len(e.Data)) | ||||
| 	copy(b, e.Data) | ||||
| 	return &EDNS0_LOCAL{e.Code, b} | ||||
| 	return &EDNS0_LOCAL{e.Code, cloneSlice(e.Data)} | ||||
| } | ||||
| 
 | ||||
| func (e *EDNS0_LOCAL) pack() ([]byte, error) { | ||||
| 	b := make([]byte, len(e.Data)) | ||||
| 	copied := copy(b, e.Data) | ||||
| 	if copied != len(e.Data) { | ||||
| 		return nil, ErrBuf | ||||
| 	} | ||||
| 	return b, nil | ||||
| 	return cloneSlice(e.Data), nil | ||||
| } | ||||
| 
 | ||||
| func (e *EDNS0_LOCAL) unpack(b []byte) error { | ||||
| 	e.Data = make([]byte, len(b)) | ||||
| 	copied := copy(e.Data, b) | ||||
| 	if copied != len(b) { | ||||
| 		return ErrBuf | ||||
| 	} | ||||
| 	e.Data = cloneSlice(b) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
|  | @ -727,14 +723,10 @@ type EDNS0_PADDING struct { | |||
| 
 | ||||
| // Option implements the EDNS0 interface.
 | ||||
| func (e *EDNS0_PADDING) Option() uint16        { return EDNS0PADDING } | ||||
| func (e *EDNS0_PADDING) pack() ([]byte, error) { return e.Padding, nil } | ||||
| func (e *EDNS0_PADDING) unpack(b []byte) error { e.Padding = b; return nil } | ||||
| func (e *EDNS0_PADDING) pack() ([]byte, error) { return cloneSlice(e.Padding), nil } | ||||
| func (e *EDNS0_PADDING) unpack(b []byte) error { e.Padding = cloneSlice(b); return nil } | ||||
| func (e *EDNS0_PADDING) String() string        { return fmt.Sprintf("%0X", e.Padding) } | ||||
| func (e *EDNS0_PADDING) copy() EDNS0 { | ||||
| 	b := make([]byte, len(e.Padding)) | ||||
| 	copy(b, e.Padding) | ||||
| 	return &EDNS0_PADDING{b} | ||||
| } | ||||
| func (e *EDNS0_PADDING) copy() EDNS0           { return &EDNS0_PADDING{cloneSlice(e.Padding)} } | ||||
| 
 | ||||
| // Extended DNS Error Codes (RFC 8914).
 | ||||
| const ( | ||||
|  | @ -821,7 +813,7 @@ func (e *EDNS0_EDE) String() string { | |||
| 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)) | ||||
| 	copy(b[2:], e.ExtraText) | ||||
| 	return b, nil | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| //go:build fuzz
 | ||||
| // +build fuzz
 | ||||
| 
 | ||||
| package dns | ||||
|  |  | |||
|  | @ -122,7 +122,7 @@ func Split(s string) []int { | |||
| } | ||||
| 
 | ||||
| // NextLabel returns the index of the start of the next label in the
 | ||||
| // string s starting at offset.
 | ||||
| // string s starting at offset. A negative offset will cause a panic.
 | ||||
| // The bool end is true when the end of the string has been reached.
 | ||||
| // Also see PrevLabel.
 | ||||
| func NextLabel(s string, offset int) (i int, end bool) { | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| // +build !go1.11 !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd
 | ||||
| //go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd
 | ||||
| // +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd
 | ||||
| 
 | ||||
| package dns | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| // +build go1.11
 | ||||
| //go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd
 | ||||
| // +build aix darwin dragonfly freebsd linux netbsd openbsd
 | ||||
| 
 | ||||
| package dns | ||||
|  |  | |||
|  | @ -252,7 +252,7 @@ loop: | |||
| 			} | ||||
| 
 | ||||
| 			// check for \DDD
 | ||||
| 			if i+3 < ls && isDigit(bs[i+1]) && isDigit(bs[i+2]) && isDigit(bs[i+3]) { | ||||
| 			if isDDD(bs[i+1:]) { | ||||
| 				bs[i] = dddToByte(bs[i+1:]) | ||||
| 				copy(bs[i+1:ls-3], bs[i+4:]) | ||||
| 				ls -= 3 | ||||
|  | @ -448,7 +448,7 @@ Loop: | |||
| 	return string(s), off1, nil | ||||
| } | ||||
| 
 | ||||
| func packTxt(txt []string, msg []byte, offset int, tmp []byte) (int, error) { | ||||
| func packTxt(txt []string, msg []byte, offset int) (int, error) { | ||||
| 	if len(txt) == 0 { | ||||
| 		if offset >= len(msg) { | ||||
| 			return offset, ErrBuf | ||||
|  | @ -458,10 +458,7 @@ func packTxt(txt []string, msg []byte, offset int, tmp []byte) (int, error) { | |||
| 	} | ||||
| 	var err error | ||||
| 	for _, s := range txt { | ||||
| 		if len(s) > len(tmp) { | ||||
| 			return offset, ErrBuf | ||||
| 		} | ||||
| 		offset, err = packTxtString(s, msg, offset, tmp) | ||||
| 		offset, err = packTxtString(s, msg, offset) | ||||
| 		if err != nil { | ||||
| 			return offset, err | ||||
| 		} | ||||
|  | @ -469,32 +466,30 @@ func packTxt(txt []string, msg []byte, offset int, tmp []byte) (int, error) { | |||
| 	return offset, nil | ||||
| } | ||||
| 
 | ||||
| func packTxtString(s string, msg []byte, offset int, tmp []byte) (int, error) { | ||||
| func packTxtString(s string, msg []byte, offset int) (int, error) { | ||||
| 	lenByteOffset := offset | ||||
| 	if offset >= len(msg) || len(s) > len(tmp) { | ||||
| 	if offset >= len(msg) || len(s) > 256*4+1 /* If all \DDD */ { | ||||
| 		return offset, ErrBuf | ||||
| 	} | ||||
| 	offset++ | ||||
| 	bs := tmp[:len(s)] | ||||
| 	copy(bs, s) | ||||
| 	for i := 0; i < len(bs); i++ { | ||||
| 	for i := 0; i < len(s); i++ { | ||||
| 		if len(msg) <= offset { | ||||
| 			return offset, ErrBuf | ||||
| 		} | ||||
| 		if bs[i] == '\\' { | ||||
| 		if s[i] == '\\' { | ||||
| 			i++ | ||||
| 			if i == len(bs) { | ||||
| 			if i == len(s) { | ||||
| 				break | ||||
| 			} | ||||
| 			// check for \DDD
 | ||||
| 			if i+2 < len(bs) && isDigit(bs[i]) && isDigit(bs[i+1]) && isDigit(bs[i+2]) { | ||||
| 				msg[offset] = dddToByte(bs[i:]) | ||||
| 			if isDDD(s[i:]) { | ||||
| 				msg[offset] = dddToByte(s[i:]) | ||||
| 				i += 2 | ||||
| 			} else { | ||||
| 				msg[offset] = bs[i] | ||||
| 				msg[offset] = s[i] | ||||
| 			} | ||||
| 		} else { | ||||
| 			msg[offset] = bs[i] | ||||
| 			msg[offset] = s[i] | ||||
| 		} | ||||
| 		offset++ | ||||
| 	} | ||||
|  | @ -522,7 +517,7 @@ func packOctetString(s string, msg []byte, offset int, tmp []byte) (int, error) | |||
| 				break | ||||
| 			} | ||||
| 			// check for \DDD
 | ||||
| 			if i+2 < len(bs) && isDigit(bs[i]) && isDigit(bs[i+1]) && isDigit(bs[i+2]) { | ||||
| 			if isDDD(bs[i:]) { | ||||
| 				msg[offset] = dddToByte(bs[i:]) | ||||
| 				i += 2 | ||||
| 			} else { | ||||
|  | @ -551,12 +546,11 @@ func unpackTxt(msg []byte, off0 int) (ss []string, off int, err error) { | |||
| // Helpers for dealing with escaped bytes
 | ||||
| func isDigit(b byte) bool { return b >= '0' && b <= '9' } | ||||
| 
 | ||||
| func dddToByte(s []byte) byte { | ||||
| 	_ = s[2] // bounds check hint to compiler; see golang.org/issue/14808
 | ||||
| 	return byte((s[0]-'0')*100 + (s[1]-'0')*10 + (s[2] - '0')) | ||||
| func isDDD[T ~[]byte | ~string](s T) bool { | ||||
| 	return len(s) >= 3 && isDigit(s[0]) && isDigit(s[1]) && isDigit(s[2]) | ||||
| } | ||||
| 
 | ||||
| func dddStringToByte(s string) byte { | ||||
| func dddToByte[T ~[]byte | ~string](s T) byte { | ||||
| 	_ = s[2] // bounds check hint to compiler; see golang.org/issue/14808
 | ||||
| 	return byte((s[0]-'0')*100 + (s[1]-'0')*10 + (s[2] - '0')) | ||||
| } | ||||
|  | @ -680,9 +674,9 @@ func unpackRRslice(l int, msg []byte, off int) (dst1 []RR, off1 int, err error) | |||
| 
 | ||||
| // Convert a MsgHdr to a string, with dig-like headers:
 | ||||
| //
 | ||||
| //;; opcode: QUERY, status: NOERROR, id: 48404
 | ||||
| // ;; opcode: QUERY, status: NOERROR, id: 48404
 | ||||
| //
 | ||||
| //;; flags: qr aa rd ra;
 | ||||
| // ;; flags: qr aa rd ra;
 | ||||
| func (h *MsgHdr) String() string { | ||||
| 	if h == nil { | ||||
| 		return "<nil> MsgHdr" | ||||
|  | @ -866,7 +860,7 @@ func (dns *Msg) unpack(dh Header, msg []byte, off int) (err error) { | |||
| 	// The header counts might have been wrong so we need to update it
 | ||||
| 	dh.Nscount = uint16(len(dns.Ns)) | ||||
| 	if err == nil { | ||||
| 		dns.Extra, off, err = unpackRRslice(int(dh.Arcount), msg, off) | ||||
| 		dns.Extra, _, err = unpackRRslice(int(dh.Arcount), msg, off) | ||||
| 	} | ||||
| 	// The header counts might have been wrong so we need to update it
 | ||||
| 	dh.Arcount = uint16(len(dns.Extra)) | ||||
|  | @ -876,11 +870,11 @@ func (dns *Msg) unpack(dh Header, msg []byte, off int) (err error) { | |||
| 		dns.Rcode |= opt.ExtendedRcode() | ||||
| 	} | ||||
| 
 | ||||
| 	if off != len(msg) { | ||||
| 		// TODO(miek) make this an error?
 | ||||
| 		// use PackOpt to let people tell how detailed the error reporting should be?
 | ||||
| 		// println("dns: extra bytes in dns packet", off, "<", len(msg))
 | ||||
| 	} | ||||
| 	// TODO(miek) make this an error?
 | ||||
| 	// use PackOpt to let people tell how detailed the error reporting should be?
 | ||||
| 	// if off != len(msg) {
 | ||||
| 	// 	// println("dns: extra bytes in dns packet", off, "<", len(msg))
 | ||||
| 	// }
 | ||||
| 	return err | ||||
| 
 | ||||
| } | ||||
|  | @ -1024,7 +1018,7 @@ func escapedNameLen(s string) int { | |||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		if i+3 < len(s) && isDigit(s[i+1]) && isDigit(s[i+2]) && isDigit(s[i+3]) { | ||||
| 		if isDDD(s[i+1:]) { | ||||
| 			nameLen -= 3 | ||||
| 			i += 3 | ||||
| 		} else { | ||||
|  | @ -1065,8 +1059,8 @@ func (dns *Msg) CopyTo(r1 *Msg) *Msg { | |||
| 	r1.Compress = dns.Compress | ||||
| 
 | ||||
| 	if len(dns.Question) > 0 { | ||||
| 		r1.Question = make([]Question, len(dns.Question)) | ||||
| 		copy(r1.Question, dns.Question) // TODO(miek): Question is an immutable value, ok to do a shallow-copy
 | ||||
| 		// TODO(miek): Question is an immutable value, ok to do a shallow-copy
 | ||||
| 		r1.Question = cloneSlice(dns.Question) | ||||
| 	} | ||||
| 
 | ||||
| 	rrArr := make([]RR, len(dns.Answer)+len(dns.Ns)+len(dns.Extra)) | ||||
|  |  | |||
|  | @ -299,8 +299,7 @@ func unpackString(msg []byte, off int) (string, int, error) { | |||
| } | ||||
| 
 | ||||
| func packString(s string, msg []byte, off int) (int, error) { | ||||
| 	txtTmp := make([]byte, 256*4+1) | ||||
| 	off, err := packTxtString(s, msg, off, txtTmp) | ||||
| 	off, err := packTxtString(s, msg, off) | ||||
| 	if err != nil { | ||||
| 		return len(msg), err | ||||
| 	} | ||||
|  | @ -402,8 +401,7 @@ func unpackStringTxt(msg []byte, off int) ([]string, int, error) { | |||
| } | ||||
| 
 | ||||
| func packStringTxt(s []string, msg []byte, off int) (int, error) { | ||||
| 	txtTmp := make([]byte, 256*4+1) // If the whole string consists out of \DDD we need this many.
 | ||||
| 	off, err := packTxt(s, msg, off, txtTmp) | ||||
| 	off, err := packTxt(s, msg, off) | ||||
| 	if err != nil { | ||||
| 		return len(msg), err | ||||
| 	} | ||||
|  | @ -625,7 +623,7 @@ func unpackDataSVCB(msg []byte, off int) ([]SVCBKeyValue, int, error) { | |||
| } | ||||
| 
 | ||||
| func packDataSVCB(pairs []SVCBKeyValue, msg []byte, off int) (int, error) { | ||||
| 	pairs = append([]SVCBKeyValue(nil), pairs...) | ||||
| 	pairs = cloneSlice(pairs) | ||||
| 	sort.Slice(pairs, func(i, j int) bool { | ||||
| 		return pairs[i].Key() < pairs[j].Key() | ||||
| 	}) | ||||
|  | @ -810,3 +808,37 @@ func unpackDataAplPrefix(msg []byte, off int) (APLPrefix, int, error) { | |||
| 		Network:  ipnet, | ||||
| 	}, off, nil | ||||
| } | ||||
| 
 | ||||
| func unpackIPSECGateway(msg []byte, off int, gatewayType uint8) (net.IP, string, int, error) { | ||||
| 	var retAddr net.IP | ||||
| 	var retString string | ||||
| 	var err error | ||||
| 
 | ||||
| 	switch gatewayType { | ||||
| 	case IPSECGatewayNone: // do nothing
 | ||||
| 	case IPSECGatewayIPv4: | ||||
| 		retAddr, off, err = unpackDataA(msg, off) | ||||
| 	case IPSECGatewayIPv6: | ||||
| 		retAddr, off, err = unpackDataAAAA(msg, off) | ||||
| 	case IPSECGatewayHost: | ||||
| 		retString, off, err = UnpackDomainName(msg, off) | ||||
| 	} | ||||
| 
 | ||||
| 	return retAddr, retString, off, err | ||||
| } | ||||
| 
 | ||||
| func packIPSECGateway(gatewayAddr net.IP, gatewayString string, msg []byte, off int, gatewayType uint8, compression compressionMap, compress bool) (int, error) { | ||||
| 	var err error | ||||
| 
 | ||||
| 	switch gatewayType { | ||||
| 	case IPSECGatewayNone: // do nothing
 | ||||
| 	case IPSECGatewayIPv4: | ||||
| 		off, err = packDataA(gatewayAddr, msg, off) | ||||
| 	case IPSECGatewayIPv6: | ||||
| 		off, err = packDataAAAA(gatewayAddr, msg, off) | ||||
| 	case IPSECGatewayHost: | ||||
| 		off, err = packDomainName(gatewayString, msg, off, compression, compress) | ||||
| 	} | ||||
| 
 | ||||
| 	return off, err | ||||
| } | ||||
|  |  | |||
|  | @ -10,13 +10,13 @@ import ( | |||
| 	"strings" | ||||
| ) | ||||
| 
 | ||||
| const maxTok = 2048 // Largest token we can return.
 | ||||
| const maxTok = 512 // Token buffer start size, and growth size amount.
 | ||||
| 
 | ||||
| // The maximum depth of $INCLUDE directives supported by the
 | ||||
| // ZoneParser API.
 | ||||
| const maxIncludeDepth = 7 | ||||
| 
 | ||||
| // Tokinize a RFC 1035 zone file. The tokenizer will normalize it:
 | ||||
| // Tokenize a RFC 1035 zone file. The tokenizer will normalize it:
 | ||||
| // * Add ownernames if they are left blank;
 | ||||
| // * Suppress sequences of spaces;
 | ||||
| // * Make each RR fit on one line (_NEWLINE is send as last)
 | ||||
|  | @ -765,8 +765,8 @@ func (zl *zlexer) Next() (lex, bool) { | |||
| 	} | ||||
| 
 | ||||
| 	var ( | ||||
| 		str [maxTok]byte // Hold string text
 | ||||
| 		com [maxTok]byte // Hold comment text
 | ||||
| 		str = make([]byte, maxTok) // Hold string text
 | ||||
| 		com = make([]byte, maxTok) // Hold comment text
 | ||||
| 
 | ||||
| 		stri int // Offset in str (0 means empty)
 | ||||
| 		comi int // Offset in com (0 means empty)
 | ||||
|  | @ -785,14 +785,12 @@ func (zl *zlexer) Next() (lex, bool) { | |||
| 		l.line, l.column = zl.line, zl.column | ||||
| 
 | ||||
| 		if stri >= len(str) { | ||||
| 			l.token = "token length insufficient for parsing" | ||||
| 			l.err = true | ||||
| 			return *l, true | ||||
| 			// if buffer length is insufficient, increase it.
 | ||||
| 			str = append(str[:], make([]byte, maxTok)...) | ||||
| 		} | ||||
| 		if comi >= len(com) { | ||||
| 			l.token = "comment length insufficient for parsing" | ||||
| 			l.err = true | ||||
| 			return *l, true | ||||
| 			// if buffer length is insufficient, increase it.
 | ||||
| 			com = append(com[:], make([]byte, maxTok)...) | ||||
| 		} | ||||
| 
 | ||||
| 		switch x { | ||||
|  | @ -816,7 +814,7 @@ func (zl *zlexer) Next() (lex, bool) { | |||
| 			if stri == 0 { | ||||
| 				// Space directly in the beginning, handled in the grammar
 | ||||
| 			} else if zl.owner { | ||||
| 				// If we have a string and its the first, make it an owner
 | ||||
| 				// If we have a string and it's the first, make it an owner
 | ||||
| 				l.value = zOwner | ||||
| 				l.token = string(str[:stri]) | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ package dns | |||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/base64" | ||||
| 	"errors" | ||||
| 	"net" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
|  | @ -903,11 +904,18 @@ func (rr *RRSIG) parse(c *zlexer, o string) *ParseError { | |||
| 
 | ||||
| 	c.Next() // zBlank
 | ||||
| 	l, _ = c.Next() | ||||
| 	i, e := strconv.ParseUint(l.token, 10, 8) | ||||
| 	if e != nil || l.err { | ||||
| 	if l.err { | ||||
| 		return &ParseError{"", "bad RRSIG Algorithm", l} | ||||
| 	} | ||||
| 	rr.Algorithm = uint8(i) | ||||
| 	i, e := strconv.ParseUint(l.token, 10, 8) | ||||
| 	rr.Algorithm = uint8(i) // if 0 we'll check the mnemonic in the if
 | ||||
| 	if e != nil { | ||||
| 		v, ok := StringToAlgorithm[l.token] | ||||
| 		if !ok { | ||||
| 			return &ParseError{"", "bad RRSIG Algorithm", l} | ||||
| 		} | ||||
| 		rr.Algorithm = v | ||||
| 	} | ||||
| 
 | ||||
| 	c.Next() // zBlank
 | ||||
| 	l, _ = c.Next() | ||||
|  | @ -1216,6 +1224,117 @@ func (rr *DS) parse(c *zlexer, o string) *ParseError      { return rr.parseDS(c, | |||
| func (rr *DLV) parse(c *zlexer, o string) *ParseError     { return rr.parseDS(c, o, "DLV") } | ||||
| func (rr *CDS) parse(c *zlexer, o string) *ParseError     { return rr.parseDS(c, o, "CDS") } | ||||
| 
 | ||||
| func (rr *IPSECKEY) parse(c *zlexer, o string) *ParseError { | ||||
| 	l, _ := c.Next() | ||||
| 	num, err := strconv.ParseUint(l.token, 10, 8) | ||||
| 	if err != nil || l.err { | ||||
| 		return &ParseError{"", "bad IPSECKEY value", l} | ||||
| 	} | ||||
| 	rr.Precedence = uint8(num) | ||||
| 	c.Next() // zBlank
 | ||||
| 
 | ||||
| 	l, _ = c.Next() | ||||
| 	num, err = strconv.ParseUint(l.token, 10, 8) | ||||
| 	if err != nil || l.err { | ||||
| 		return &ParseError{"", "bad IPSECKEY value", l} | ||||
| 	} | ||||
| 	rr.GatewayType = uint8(num) | ||||
| 	c.Next() // zBlank
 | ||||
| 
 | ||||
| 	l, _ = c.Next() | ||||
| 	num, err = strconv.ParseUint(l.token, 10, 8) | ||||
| 	if err != nil || l.err { | ||||
| 		return &ParseError{"", "bad IPSECKEY value", l} | ||||
| 	} | ||||
| 	rr.Algorithm = uint8(num) | ||||
| 	c.Next() // zBlank
 | ||||
| 
 | ||||
| 	l, _ = c.Next() | ||||
| 	if l.err { | ||||
| 		return &ParseError{"", "bad IPSECKEY gateway", l} | ||||
| 	} | ||||
| 
 | ||||
| 	rr.GatewayAddr, rr.GatewayHost, err = parseAddrHostUnion(l.token, o, rr.GatewayType) | ||||
| 	if err != nil { | ||||
| 		return &ParseError{"", "IPSECKEY " + err.Error(), l} | ||||
| 	} | ||||
| 
 | ||||
| 	c.Next() // zBlank
 | ||||
| 
 | ||||
| 	s, pErr := endingToString(c, "bad IPSECKEY PublicKey") | ||||
| 	if pErr != nil { | ||||
| 		return pErr | ||||
| 	} | ||||
| 	rr.PublicKey = s | ||||
| 	return slurpRemainder(c) | ||||
| } | ||||
| 
 | ||||
| func (rr *AMTRELAY) parse(c *zlexer, o string) *ParseError { | ||||
| 	l, _ := c.Next() | ||||
| 	num, err := strconv.ParseUint(l.token, 10, 8) | ||||
| 	if err != nil || l.err { | ||||
| 		return &ParseError{"", "bad AMTRELAY value", l} | ||||
| 	} | ||||
| 	rr.Precedence = uint8(num) | ||||
| 	c.Next() // zBlank
 | ||||
| 
 | ||||
| 	l, _ = c.Next() | ||||
| 	if l.err || !(l.token == "0" || l.token == "1") { | ||||
| 		return &ParseError{"", "bad discovery value", l} | ||||
| 	} | ||||
| 	if l.token == "1" { | ||||
| 		rr.GatewayType = 0x80 | ||||
| 	} | ||||
| 
 | ||||
| 	c.Next() // zBlank
 | ||||
| 
 | ||||
| 	l, _ = c.Next() | ||||
| 	num, err = strconv.ParseUint(l.token, 10, 8) | ||||
| 	if err != nil || l.err { | ||||
| 		return &ParseError{"", "bad AMTRELAY value", l} | ||||
| 	} | ||||
| 	rr.GatewayType |= uint8(num) | ||||
| 	c.Next() // zBlank
 | ||||
| 
 | ||||
| 	l, _ = c.Next() | ||||
| 	if l.err { | ||||
| 		return &ParseError{"", "bad AMTRELAY gateway", l} | ||||
| 	} | ||||
| 
 | ||||
| 	rr.GatewayAddr, rr.GatewayHost, err = parseAddrHostUnion(l.token, o, rr.GatewayType&0x7f) | ||||
| 	if err != nil { | ||||
| 		return &ParseError{"", "AMTRELAY " + err.Error(), l} | ||||
| 	} | ||||
| 
 | ||||
| 	return slurpRemainder(c) | ||||
| } | ||||
| 
 | ||||
| // same constants and parsing between IPSECKEY and AMTRELAY
 | ||||
| func parseAddrHostUnion(token, o string, gatewayType uint8) (addr net.IP, host string, err error) { | ||||
| 	switch gatewayType { | ||||
| 	case IPSECGatewayNone: | ||||
| 		if token != "." { | ||||
| 			return addr, host, errors.New("gateway type none with gateway set") | ||||
| 		} | ||||
| 	case IPSECGatewayIPv4, IPSECGatewayIPv6: | ||||
| 		addr = net.ParseIP(token) | ||||
| 		if addr == nil { | ||||
| 			return addr, host, errors.New("gateway IP invalid") | ||||
| 		} | ||||
| 		if (addr.To4() == nil) == (gatewayType == IPSECGatewayIPv4) { | ||||
| 			return addr, host, errors.New("gateway IP family mismatch") | ||||
| 		} | ||||
| 	case IPSECGatewayHost: | ||||
| 		var ok bool | ||||
| 		host, ok = toAbsoluteName(token, o) | ||||
| 		if !ok { | ||||
| 			return addr, host, errors.New("invalid gateway host") | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return addr, host, nil | ||||
| } | ||||
| 
 | ||||
| func (rr *RKEY) parse(c *zlexer, o string) *ParseError { | ||||
| 	l, _ := c.Next() | ||||
| 	i, e := strconv.ParseUint(l.token, 10, 16) | ||||
|  |  | |||
|  | @ -18,7 +18,7 @@ import ( | |||
| const maxTCPQueries = 128 | ||||
| 
 | ||||
| // aLongTimeAgo is a non-zero time, far in the past, used for
 | ||||
| // immediate cancelation of network operations.
 | ||||
| // immediate cancellation of network operations.
 | ||||
| var aLongTimeAgo = time.Unix(1, 0) | ||||
| 
 | ||||
| // Handler is implemented by any value that implements ServeDNS.
 | ||||
|  | @ -224,7 +224,7 @@ type Server struct { | |||
| 	// Maximum number of TCP queries before we close the socket. Default is maxTCPQueries (unlimited if -1).
 | ||||
| 	MaxTCPQueries int | ||||
| 	// Whether to set the SO_REUSEPORT socket option, allowing multiple listeners to be bound to a single address.
 | ||||
| 	// It is only supported on go1.11+ and when using ListenAndServe.
 | ||||
| 	// It is only supported on certain GOOSes and when using ListenAndServe.
 | ||||
| 	ReusePort bool | ||||
| 	// AcceptMsgFunc will check the incoming message and will reject it early in the process.
 | ||||
| 	// By default DefaultMsgAcceptFunc will be used.
 | ||||
|  |  | |||
|  | @ -1,61 +0,0 @@ | |||
| // Copyright 2013 The Go Authors.  All rights reserved.
 | ||||
| // Use of this source code is governed by a BSD-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
| // Adapted for dns package usage by Miek Gieben.
 | ||||
| 
 | ||||
| package dns | ||||
| 
 | ||||
| import "sync" | ||||
| import "time" | ||||
| 
 | ||||
| // call is an in-flight or completed singleflight.Do call
 | ||||
| type call struct { | ||||
| 	wg   sync.WaitGroup | ||||
| 	val  *Msg | ||||
| 	rtt  time.Duration | ||||
| 	err  error | ||||
| 	dups int | ||||
| } | ||||
| 
 | ||||
| // singleflight represents a class of work and forms a namespace in
 | ||||
| // which units of work can be executed with duplicate suppression.
 | ||||
| type singleflight struct { | ||||
| 	sync.Mutex                  // protects m
 | ||||
| 	m          map[string]*call // lazily initialized
 | ||||
| 
 | ||||
| 	dontDeleteForTesting bool // this is only to be used by TestConcurrentExchanges
 | ||||
| } | ||||
| 
 | ||||
| // Do executes and returns the results of the given function, making
 | ||||
| // sure that only one execution is in-flight for a given key at a
 | ||||
| // time. If a duplicate comes in, the duplicate caller waits for the
 | ||||
| // original to complete and receives the same results.
 | ||||
| // The return value shared indicates whether v was given to multiple callers.
 | ||||
| func (g *singleflight) Do(key string, fn func() (*Msg, time.Duration, error)) (v *Msg, rtt time.Duration, err error, shared bool) { | ||||
| 	g.Lock() | ||||
| 	if g.m == nil { | ||||
| 		g.m = make(map[string]*call) | ||||
| 	} | ||||
| 	if c, ok := g.m[key]; ok { | ||||
| 		c.dups++ | ||||
| 		g.Unlock() | ||||
| 		c.wg.Wait() | ||||
| 		return c.val, c.rtt, c.err, true | ||||
| 	} | ||||
| 	c := new(call) | ||||
| 	c.wg.Add(1) | ||||
| 	g.m[key] = c | ||||
| 	g.Unlock() | ||||
| 
 | ||||
| 	c.val, c.rtt, c.err = fn() | ||||
| 	c.wg.Done() | ||||
| 
 | ||||
| 	if !g.dontDeleteForTesting { | ||||
| 		g.Lock() | ||||
| 		delete(g.m, key) | ||||
| 		g.Unlock() | ||||
| 	} | ||||
| 
 | ||||
| 	return c.val, c.rtt, c.err, c.dups > 0 | ||||
| } | ||||
|  | @ -289,7 +289,7 @@ func (s *SVCBMandatory) String() string { | |||
| } | ||||
| 
 | ||||
| func (s *SVCBMandatory) pack() ([]byte, error) { | ||||
| 	codes := append([]SVCBKey(nil), s.Code...) | ||||
| 	codes := cloneSlice(s.Code) | ||||
| 	sort.Slice(codes, func(i, j int) bool { | ||||
| 		return codes[i] < codes[j] | ||||
| 	}) | ||||
|  | @ -328,9 +328,7 @@ func (s *SVCBMandatory) len() int { | |||
| } | ||||
| 
 | ||||
| func (s *SVCBMandatory) copy() SVCBKeyValue { | ||||
| 	return &SVCBMandatory{ | ||||
| 		append([]SVCBKey(nil), s.Code...), | ||||
| 	} | ||||
| 	return &SVCBMandatory{cloneSlice(s.Code)} | ||||
| } | ||||
| 
 | ||||
| // SVCBAlpn pair is used to list supported connection protocols.
 | ||||
|  | @ -353,7 +351,7 @@ func (*SVCBAlpn) Key() SVCBKey { return SVCB_ALPN } | |||
| func (s *SVCBAlpn) String() string { | ||||
| 	// An ALPN value is a comma-separated list of values, each of which can be
 | ||||
| 	// an arbitrary binary value. In order to allow parsing, the comma and
 | ||||
| 	// backslash characters are themselves excaped.
 | ||||
| 	// backslash characters are themselves escaped.
 | ||||
| 	//
 | ||||
| 	// However, this escaping is done in addition to the normal escaping which
 | ||||
| 	// happens in zone files, meaning that these values must be
 | ||||
|  | @ -481,9 +479,7 @@ func (s *SVCBAlpn) len() int { | |||
| } | ||||
| 
 | ||||
| func (s *SVCBAlpn) copy() SVCBKeyValue { | ||||
| 	return &SVCBAlpn{ | ||||
| 		append([]string(nil), s.Alpn...), | ||||
| 	} | ||||
| 	return &SVCBAlpn{cloneSlice(s.Alpn)} | ||||
| } | ||||
| 
 | ||||
| // SVCBNoDefaultAlpn pair signifies no support for default connection protocols.
 | ||||
|  | @ -563,15 +559,15 @@ func (s *SVCBPort) parse(b string) error { | |||
| // 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()}
 | ||||
| //		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
 | ||||
| //	 Or
 | ||||
| //
 | ||||
| //	e.Hint = []net.IP{net.ParseIP("1.1.1.1").To4()}
 | ||||
| //	h.Value = append(h.Value, e)
 | ||||
| //		e.Hint = []net.IP{net.ParseIP("1.1.1.1").To4()}
 | ||||
| //		h.Value = append(h.Value, e)
 | ||||
| type SVCBIPv4Hint struct { | ||||
| 	Hint []net.IP | ||||
| } | ||||
|  | @ -595,6 +591,7 @@ 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") | ||||
| 	} | ||||
| 	b = cloneSlice(b) | ||||
| 	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])) | ||||
|  | @ -635,12 +632,9 @@ func (s *SVCBIPv4Hint) parse(b string) error { | |||
| 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, | ||||
| 		hint[i] = cloneSlice(ip) | ||||
| 	} | ||||
| 	return &SVCBIPv4Hint{Hint: hint} | ||||
| } | ||||
| 
 | ||||
| // SVCBECHConfig pair contains the ECHConfig structure defined in draft-ietf-tls-esni [RFC xxxx].
 | ||||
|  | @ -660,19 +654,18 @@ 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 | ||||
| 	return cloneSlice(s.ECH), nil | ||||
| } | ||||
| 
 | ||||
| func (s *SVCBECHConfig) copy() SVCBKeyValue { | ||||
| 	return &SVCBECHConfig{ | ||||
| 		append([]byte(nil), s.ECH...), | ||||
| 	} | ||||
| 	return &SVCBECHConfig{cloneSlice(s.ECH)} | ||||
| } | ||||
| 
 | ||||
| func (s *SVCBECHConfig) unpack(b []byte) error { | ||||
| 	s.ECH = append([]byte(nil), b...) | ||||
| 	s.ECH = cloneSlice(b) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (s *SVCBECHConfig) parse(b string) error { | ||||
| 	x, err := fromBase64([]byte(b)) | ||||
| 	if err != nil { | ||||
|  | @ -715,6 +708,7 @@ 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") | ||||
| 	} | ||||
| 	b = cloneSlice(b) | ||||
| 	x := make([]net.IP, 0, len(b)/16) | ||||
| 	for i := 0; i < len(b); i += 16 { | ||||
| 		ip := net.IP(b[i : i+16]) | ||||
|  | @ -758,12 +752,9 @@ func (s *SVCBIPv6Hint) parse(b string) error { | |||
| 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, | ||||
| 		hint[i] = cloneSlice(ip) | ||||
| 	} | ||||
| 	return &SVCBIPv6Hint{Hint: hint} | ||||
| } | ||||
| 
 | ||||
| // SVCBDoHPath pair is used to indicate the URI template that the
 | ||||
|  | @ -831,11 +822,11 @@ type SVCBLocal struct { | |||
| 
 | ||||
| func (s *SVCBLocal) Key() SVCBKey          { return s.KeyCode } | ||||
| func (s *SVCBLocal) String() string        { return svcbParamToStr(s.Data) } | ||||
| func (s *SVCBLocal) pack() ([]byte, error) { return append([]byte(nil), s.Data...), nil } | ||||
| func (s *SVCBLocal) pack() ([]byte, error) { return cloneSlice(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...) | ||||
| 	s.Data = cloneSlice(b) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
|  | @ -849,9 +840,7 @@ func (s *SVCBLocal) parse(b string) error { | |||
| } | ||||
| 
 | ||||
| func (s *SVCBLocal) copy() SVCBKeyValue { | ||||
| 	return &SVCBLocal{s.KeyCode, | ||||
| 		append([]byte(nil), s.Data...), | ||||
| 	} | ||||
| 	return &SVCBLocal{s.KeyCode, cloneSlice(s.Data)} | ||||
| } | ||||
| 
 | ||||
| func (rr *SVCB) String() string { | ||||
|  | @ -867,8 +856,8 @@ func (rr *SVCB) String() string { | |||
| // 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...) | ||||
| 	a = cloneSlice(a) | ||||
| 	b = cloneSlice(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 { | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| //go:build tools
 | ||||
| // +build tools
 | ||||
| 
 | ||||
| // We include our tool dependencies for `go generate` here to ensure they're
 | ||||
|  |  | |||
|  | @ -65,6 +65,7 @@ const ( | |||
| 	TypeAPL        uint16 = 42 | ||||
| 	TypeDS         uint16 = 43 | ||||
| 	TypeSSHFP      uint16 = 44 | ||||
| 	TypeIPSECKEY   uint16 = 45 | ||||
| 	TypeRRSIG      uint16 = 46 | ||||
| 	TypeNSEC       uint16 = 47 | ||||
| 	TypeDNSKEY     uint16 = 48 | ||||
|  | @ -98,6 +99,7 @@ const ( | |||
| 	TypeURI        uint16 = 256 | ||||
| 	TypeCAA        uint16 = 257 | ||||
| 	TypeAVC        uint16 = 258 | ||||
| 	TypeAMTRELAY   uint16 = 260 | ||||
| 
 | ||||
| 	TypeTKEY uint16 = 249 | ||||
| 	TypeTSIG uint16 = 250 | ||||
|  | @ -159,6 +161,22 @@ const ( | |||
| 	ZoneMDHashAlgSHA512 = 2 | ||||
| ) | ||||
| 
 | ||||
| // Used in IPSEC https://datatracker.ietf.org/doc/html/rfc4025#section-2.3
 | ||||
| const ( | ||||
| 	IPSECGatewayNone uint8 = iota | ||||
| 	IPSECGatewayIPv4 | ||||
| 	IPSECGatewayIPv6 | ||||
| 	IPSECGatewayHost | ||||
| ) | ||||
| 
 | ||||
| // Used in AMTRELAY https://datatracker.ietf.org/doc/html/rfc8777#section-4.2.3
 | ||||
| const ( | ||||
| 	AMTRELAYNone = IPSECGatewayNone | ||||
| 	AMTRELAYIPv4 = IPSECGatewayIPv4 | ||||
| 	AMTRELAYIPv6 = IPSECGatewayIPv6 | ||||
| 	AMTRELAYHost = IPSECGatewayHost | ||||
| ) | ||||
| 
 | ||||
| // Header is the wire format for the DNS packet header.
 | ||||
| type Header struct { | ||||
| 	Id                                 uint16 | ||||
|  | @ -180,7 +198,7 @@ const ( | |||
| 	_CD = 1 << 4  // checking disabled
 | ||||
| ) | ||||
| 
 | ||||
| // Various constants used in the LOC RR. See RFC 1887.
 | ||||
| // Various constants used in the LOC RR. See RFC 1876.
 | ||||
| const ( | ||||
| 	LOC_EQUATOR       = 1 << 31 // RFC 1876, Section 2.
 | ||||
| 	LOC_PRIMEMERIDIAN = 1 << 31 // RFC 1876, Section 2.
 | ||||
|  | @ -613,8 +631,8 @@ func nextByte(s string, offset int) (byte, int) { | |||
| 		return 0, 0 | ||||
| 	case 2, 3: // too short to be \ddd
 | ||||
| 	default: // maybe \ddd
 | ||||
| 		if isDigit(s[offset+1]) && isDigit(s[offset+2]) && isDigit(s[offset+3]) { | ||||
| 			return dddStringToByte(s[offset+1:]), 4 | ||||
| 		if isDDD(s[offset+1:]) { | ||||
| 			return dddToByte(s[offset+1:]), 4 | ||||
| 		} | ||||
| 	} | ||||
| 	// not \ddd, just an RFC 1035 "quoted" character
 | ||||
|  | @ -774,7 +792,10 @@ type LOC struct { | |||
| 
 | ||||
| // cmToM takes a cm value expressed in RFC 1876 SIZE mantissa/exponent
 | ||||
| // format and returns a string in m (two decimals for the cm).
 | ||||
| func cmToM(m, e uint8) string { | ||||
| func cmToM(x uint8) string { | ||||
| 	m := x & 0xf0 >> 4 | ||||
| 	e := x & 0x0f | ||||
| 
 | ||||
| 	if e < 2 { | ||||
| 		if e == 1 { | ||||
| 			m *= 10 | ||||
|  | @ -830,10 +851,9 @@ func (rr *LOC) String() string { | |||
| 		s += fmt.Sprintf("%.0fm ", alt) | ||||
| 	} | ||||
| 
 | ||||
| 	s += cmToM(rr.Size&0xf0>>4, rr.Size&0x0f) + "m " | ||||
| 	s += cmToM(rr.HorizPre&0xf0>>4, rr.HorizPre&0x0f) + "m " | ||||
| 	s += cmToM(rr.VertPre&0xf0>>4, rr.VertPre&0x0f) + "m" | ||||
| 
 | ||||
| 	s += cmToM(rr.Size) + "m " | ||||
| 	s += cmToM(rr.HorizPre) + "m " | ||||
| 	s += cmToM(rr.VertPre) + "m" | ||||
| 	return s | ||||
| } | ||||
| 
 | ||||
|  | @ -994,6 +1014,69 @@ func (rr *DNSKEY) String() string { | |||
| 		" " + rr.PublicKey | ||||
| } | ||||
| 
 | ||||
| // IPSECKEY RR. See RFC 4025.
 | ||||
| type IPSECKEY struct { | ||||
| 	Hdr         RR_Header | ||||
| 	Precedence  uint8 | ||||
| 	GatewayType uint8 | ||||
| 	Algorithm   uint8 | ||||
| 	GatewayAddr net.IP `dns:"-"` // packing/unpacking/parsing/etc handled together with GatewayHost
 | ||||
| 	GatewayHost string `dns:"ipsechost"` | ||||
| 	PublicKey   string `dns:"base64"` | ||||
| } | ||||
| 
 | ||||
| func (rr *IPSECKEY) String() string { | ||||
| 	var gateway string | ||||
| 	switch rr.GatewayType { | ||||
| 	case IPSECGatewayIPv4, IPSECGatewayIPv6: | ||||
| 		gateway = rr.GatewayAddr.String() | ||||
| 	case IPSECGatewayHost: | ||||
| 		gateway = rr.GatewayHost | ||||
| 	case IPSECGatewayNone: | ||||
| 		fallthrough | ||||
| 	default: | ||||
| 		gateway = "." | ||||
| 	} | ||||
| 
 | ||||
| 	return rr.Hdr.String() + strconv.Itoa(int(rr.Precedence)) + | ||||
| 		" " + strconv.Itoa(int(rr.GatewayType)) + | ||||
| 		" " + strconv.Itoa(int(rr.Algorithm)) + | ||||
| 		" " + gateway + | ||||
| 		" " + rr.PublicKey | ||||
| } | ||||
| 
 | ||||
| // AMTRELAY RR. See RFC 8777.
 | ||||
| type AMTRELAY struct { | ||||
| 	Hdr         RR_Header | ||||
| 	Precedence  uint8 | ||||
| 	GatewayType uint8  // discovery is packed in here at bit 0x80
 | ||||
| 	GatewayAddr net.IP `dns:"-"` // packing/unpacking/parsing/etc handled together with GatewayHost
 | ||||
| 	GatewayHost string `dns:"amtrelayhost"` | ||||
| } | ||||
| 
 | ||||
| func (rr *AMTRELAY) String() string { | ||||
| 	var gateway string | ||||
| 	switch rr.GatewayType & 0x7f { | ||||
| 	case AMTRELAYIPv4, AMTRELAYIPv6: | ||||
| 		gateway = rr.GatewayAddr.String() | ||||
| 	case AMTRELAYHost: | ||||
| 		gateway = rr.GatewayHost | ||||
| 	case AMTRELAYNone: | ||||
| 		fallthrough | ||||
| 	default: | ||||
| 		gateway = "." | ||||
| 	} | ||||
| 	boolS := "0" | ||||
| 	if rr.GatewayType&0x80 == 0x80 { | ||||
| 		boolS = "1" | ||||
| 	} | ||||
| 
 | ||||
| 	return rr.Hdr.String() + strconv.Itoa(int(rr.Precedence)) + | ||||
| 		" " + boolS + | ||||
| 		" " + strconv.Itoa(int(rr.GatewayType&0x7f)) + | ||||
| 		" " + gateway | ||||
| } | ||||
| 
 | ||||
| // RKEY RR. See https://www.iana.org/assignments/dns-parameters/RKEY/rkey-completed-template.
 | ||||
| type RKEY struct { | ||||
| 	Hdr       RR_Header | ||||
|  | @ -1450,7 +1533,7 @@ func (a *APLPrefix) str() string { | |||
| // equals reports whether two APL prefixes are identical.
 | ||||
| func (a *APLPrefix) equals(b *APLPrefix) bool { | ||||
| 	return a.Negation == b.Negation && | ||||
| 		bytes.Equal(a.Network.IP, b.Network.IP) && | ||||
| 		a.Network.IP.Equal(b.Network.IP) && | ||||
| 		bytes.Equal(a.Network.Mask, b.Network.Mask) | ||||
| } | ||||
| 
 | ||||
|  | @ -1518,21 +1601,19 @@ func euiToString(eui uint64, bits int) (hex string) { | |||
| 	return | ||||
| } | ||||
| 
 | ||||
| // copyIP returns a copy of ip.
 | ||||
| func copyIP(ip net.IP) net.IP { | ||||
| 	p := make(net.IP, len(ip)) | ||||
| 	copy(p, ip) | ||||
| 	return p | ||||
| // cloneSlice returns a shallow copy of s.
 | ||||
| func cloneSlice[E any, S ~[]E](s S) S { | ||||
| 	if s == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 	return append(S(nil), s...) | ||||
| } | ||||
| 
 | ||||
| // copyNet returns a copy of a subnet.
 | ||||
| func copyNet(n net.IPNet) net.IPNet { | ||||
| 	m := make(net.IPMask, len(n.Mask)) | ||||
| 	copy(m, n.Mask) | ||||
| 
 | ||||
| 	return net.IPNet{ | ||||
| 		IP:   copyIP(n.IP), | ||||
| 		Mask: m, | ||||
| 		IP:   cloneSlice(n.IP), | ||||
| 		Mask: cloneSlice(n.Mask), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| //go:build !windows
 | ||||
| // +build !windows
 | ||||
| 
 | ||||
| package dns | ||||
|  |  | |||
|  | @ -1,5 +1,9 @@ | |||
| //go:build windows
 | ||||
| // +build windows
 | ||||
| 
 | ||||
| // TODO(tmthrgd): Remove this Windows-specific code if go.dev/issue/7175 and
 | ||||
| //   go.dev/issue/7174 are ever fixed.
 | ||||
| 
 | ||||
| package dns | ||||
| 
 | ||||
| import "net" | ||||
|  | @ -14,7 +18,6 @@ func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr } | |||
| 
 | ||||
| // ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a
 | ||||
| // net.UDPAddr.
 | ||||
| // TODO(fastest963): Once go1.10 is released, use ReadMsgUDP.
 | ||||
| func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) { | ||||
| 	n, raddr, err := conn.ReadFrom(b) | ||||
| 	if err != nil { | ||||
|  | @ -24,12 +27,9 @@ func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) { | |||
| } | ||||
| 
 | ||||
| // WriteToSessionUDP acts just like net.UDPConn.WriteTo(), but uses a *SessionUDP instead of a net.Addr.
 | ||||
| // TODO(fastest963): Once go1.10 is released, use WriteMsgUDP.
 | ||||
| func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) { | ||||
| 	return conn.WriteTo(b, session.raddr) | ||||
| } | ||||
| 
 | ||||
| // TODO(fastest963): Once go1.10 is released and we can use *MsgUDP methods
 | ||||
| // use the standard method in udp.go for these.
 | ||||
| func setUDPSocketOptions(*net.UDPConn) error { return nil } | ||||
| func parseDstFromOOB([]byte, net.IP) net.IP  { return nil } | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ package dns | |||
| import "fmt" | ||||
| 
 | ||||
| // Version is current version of this library.
 | ||||
| var Version = v{1, 1, 50} | ||||
| var Version = v{1, 1, 55} | ||||
| 
 | ||||
| // v holds the version of this library.
 | ||||
| type v struct { | ||||
|  |  | |||
|  | @ -44,7 +44,6 @@ func (t *Transfer) tsigProvider() TsigProvider { | |||
| //	dnscon := &dns.Conn{Conn:con}
 | ||||
| //	transfer = &dns.Transfer{Conn: dnscon}
 | ||||
| //	channel, err := transfer.In(message, master)
 | ||||
| //
 | ||||
| func (t *Transfer) In(q *Msg, a string) (env chan *Envelope, err error) { | ||||
| 	switch q.Question[0].Qtype { | ||||
| 	case TypeAXFR, TypeIXFR: | ||||
|  |  | |||
|  | @ -43,6 +43,32 @@ func (r1 *AFSDB) isDuplicate(_r2 RR) bool { | |||
| 	return true | ||||
| } | ||||
| 
 | ||||
| func (r1 *AMTRELAY) isDuplicate(_r2 RR) bool { | ||||
| 	r2, ok := _r2.(*AMTRELAY) | ||||
| 	if !ok { | ||||
| 		return false | ||||
| 	} | ||||
| 	_ = r2 | ||||
| 	if r1.Precedence != r2.Precedence { | ||||
| 		return false | ||||
| 	} | ||||
| 	if r1.GatewayType != r2.GatewayType { | ||||
| 		return false | ||||
| 	} | ||||
| 	switch r1.GatewayType { | ||||
| 	case IPSECGatewayIPv4, IPSECGatewayIPv6: | ||||
| 		if !r1.GatewayAddr.Equal(r2.GatewayAddr) { | ||||
| 			return false | ||||
| 		} | ||||
| 	case IPSECGatewayHost: | ||||
| 		if !isDuplicateName(r1.GatewayHost, r2.GatewayHost) { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return true | ||||
| } | ||||
| 
 | ||||
| func (r1 *ANY) isDuplicate(_r2 RR) bool { | ||||
| 	r2, ok := _r2.(*ANY) | ||||
| 	if !ok { | ||||
|  | @ -423,6 +449,38 @@ func (r1 *HTTPS) isDuplicate(_r2 RR) bool { | |||
| 	return true | ||||
| } | ||||
| 
 | ||||
| func (r1 *IPSECKEY) isDuplicate(_r2 RR) bool { | ||||
| 	r2, ok := _r2.(*IPSECKEY) | ||||
| 	if !ok { | ||||
| 		return false | ||||
| 	} | ||||
| 	_ = r2 | ||||
| 	if r1.Precedence != r2.Precedence { | ||||
| 		return false | ||||
| 	} | ||||
| 	if r1.GatewayType != r2.GatewayType { | ||||
| 		return false | ||||
| 	} | ||||
| 	if r1.Algorithm != r2.Algorithm { | ||||
| 		return false | ||||
| 	} | ||||
| 	switch r1.GatewayType { | ||||
| 	case IPSECGatewayIPv4, IPSECGatewayIPv6: | ||||
| 		if !r1.GatewayAddr.Equal(r2.GatewayAddr) { | ||||
| 			return false | ||||
| 		} | ||||
| 	case IPSECGatewayHost: | ||||
| 		if !isDuplicateName(r1.GatewayHost, r2.GatewayHost) { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if r1.PublicKey != r2.PublicKey { | ||||
| 		return false | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
| 
 | ||||
| func (r1 *KEY) isDuplicate(_r2 RR) bool { | ||||
| 	r2, ok := _r2.(*KEY) | ||||
| 	if !ok { | ||||
|  |  | |||
|  | @ -32,6 +32,22 @@ func (rr *AFSDB) pack(msg []byte, off int, compression compressionMap, compress | |||
| 	return off, nil | ||||
| } | ||||
| 
 | ||||
| func (rr *AMTRELAY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { | ||||
| 	off, err = packUint8(rr.Precedence, msg, off) | ||||
| 	if err != nil { | ||||
| 		return off, err | ||||
| 	} | ||||
| 	off, err = packUint8(rr.GatewayType, msg, off) | ||||
| 	if err != nil { | ||||
| 		return off, err | ||||
| 	} | ||||
| 	off, err = packIPSECGateway(rr.GatewayAddr, rr.GatewayHost, msg, off, rr.GatewayType, compression, false) | ||||
| 	if err != nil { | ||||
| 		return off, err | ||||
| 	} | ||||
| 	return off, nil | ||||
| } | ||||
| 
 | ||||
| func (rr *ANY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { | ||||
| 	return off, nil | ||||
| } | ||||
|  | @ -332,6 +348,30 @@ func (rr *HTTPS) pack(msg []byte, off int, compression compressionMap, compress | |||
| 	return off, nil | ||||
| } | ||||
| 
 | ||||
| func (rr *IPSECKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { | ||||
| 	off, err = packUint8(rr.Precedence, msg, off) | ||||
| 	if err != nil { | ||||
| 		return off, err | ||||
| 	} | ||||
| 	off, err = packUint8(rr.GatewayType, msg, off) | ||||
| 	if err != nil { | ||||
| 		return off, err | ||||
| 	} | ||||
| 	off, err = packUint8(rr.Algorithm, msg, off) | ||||
| 	if err != nil { | ||||
| 		return off, err | ||||
| 	} | ||||
| 	off, err = packIPSECGateway(rr.GatewayAddr, rr.GatewayHost, msg, off, rr.GatewayType, compression, false) | ||||
| 	if err != nil { | ||||
| 		return off, err | ||||
| 	} | ||||
| 	off, err = packStringBase64(rr.PublicKey, 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 { | ||||
|  | @ -1180,6 +1220,34 @@ func (rr *AFSDB) unpack(msg []byte, off int) (off1 int, err error) { | |||
| 	return off, nil | ||||
| } | ||||
| 
 | ||||
| func (rr *AMTRELAY) unpack(msg []byte, off int) (off1 int, err error) { | ||||
| 	rdStart := off | ||||
| 	_ = rdStart | ||||
| 
 | ||||
| 	rr.Precedence, off, err = unpackUint8(msg, off) | ||||
| 	if err != nil { | ||||
| 		return off, err | ||||
| 	} | ||||
| 	if off == len(msg) { | ||||
| 		return off, nil | ||||
| 	} | ||||
| 	rr.GatewayType, off, err = unpackUint8(msg, off) | ||||
| 	if err != nil { | ||||
| 		return off, err | ||||
| 	} | ||||
| 	if off == len(msg) { | ||||
| 		return off, nil | ||||
| 	} | ||||
| 	if off == len(msg) { | ||||
| 		return off, nil | ||||
| 	} | ||||
| 	rr.GatewayAddr, rr.GatewayHost, off, err = unpackIPSECGateway(msg, off, rr.GatewayType) | ||||
| 	if err != nil { | ||||
| 		return off, err | ||||
| 	} | ||||
| 	return off, nil | ||||
| } | ||||
| 
 | ||||
| func (rr *ANY) unpack(msg []byte, off int) (off1 int, err error) { | ||||
| 	rdStart := off | ||||
| 	_ = rdStart | ||||
|  | @ -1636,6 +1704,48 @@ func (rr *HTTPS) unpack(msg []byte, off int) (off1 int, err error) { | |||
| 	return off, nil | ||||
| } | ||||
| 
 | ||||
| func (rr *IPSECKEY) unpack(msg []byte, off int) (off1 int, err error) { | ||||
| 	rdStart := off | ||||
| 	_ = rdStart | ||||
| 
 | ||||
| 	rr.Precedence, off, err = unpackUint8(msg, off) | ||||
| 	if err != nil { | ||||
| 		return off, err | ||||
| 	} | ||||
| 	if off == len(msg) { | ||||
| 		return off, nil | ||||
| 	} | ||||
| 	rr.GatewayType, off, err = unpackUint8(msg, off) | ||||
| 	if err != nil { | ||||
| 		return off, err | ||||
| 	} | ||||
| 	if off == len(msg) { | ||||
| 		return off, nil | ||||
| 	} | ||||
| 	rr.Algorithm, off, err = unpackUint8(msg, off) | ||||
| 	if err != nil { | ||||
| 		return off, err | ||||
| 	} | ||||
| 	if off == len(msg) { | ||||
| 		return off, nil | ||||
| 	} | ||||
| 	if off == len(msg) { | ||||
| 		return off, nil | ||||
| 	} | ||||
| 	rr.GatewayAddr, rr.GatewayHost, off, err = unpackIPSECGateway(msg, off, rr.GatewayType) | ||||
| 	if err != nil { | ||||
| 		return off, err | ||||
| 	} | ||||
| 	if off == len(msg) { | ||||
| 		return off, nil | ||||
| 	} | ||||
| 	rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) | ||||
| 	if err != nil { | ||||
| 		return off, err | ||||
| 	} | ||||
| 	return off, nil | ||||
| } | ||||
| 
 | ||||
| func (rr *KEY) unpack(msg []byte, off int) (off1 int, err error) { | ||||
| 	rdStart := off | ||||
| 	_ = rdStart | ||||
|  |  | |||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -203,8 +203,8 @@ github.com/letsencrypt/validator/v10 | |||
| # github.com/matttproud/golang_protobuf_extensions v1.0.4 | ||||
| ## explicit; go 1.9 | ||||
| github.com/matttproud/golang_protobuf_extensions/pbutil | ||||
| # github.com/miekg/dns v1.1.50 | ||||
| ## explicit; go 1.14 | ||||
| # github.com/miekg/dns v1.1.55 | ||||
| ## explicit; go 1.19 | ||||
| github.com/miekg/dns | ||||
| # github.com/miekg/pkcs11 v1.1.1 | ||||
| ## explicit; go 1.12 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue