Skip to content

Commit

Permalink
Merge pull request #12 from miekg/master
Browse files Browse the repository at this point in the history
Sync with upstream v1.1.62
  • Loading branch information
zakird authored Sep 28, 2024
2 parents 458e7c0 + b77d1ed commit dd1b978
Show file tree
Hide file tree
Showing 18 changed files with 334 additions and 92 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
go: [ 1.20.x, 1.21.x ]
go: [ 1.22.x, 1.23.x ]
steps:

- name: Set up Go
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ Example programs can be found in the `github.com/miekg/exdns` repository.
* 3225 - DO bit (DNSSEC OK)
* 340{1,2,3} - NAPTR record
* 3445 - Limiting the scope of (DNS)KEY
* 3596 - AAAA record
* 3597 - Unknown RRs
* 4025 - A Method for Storing IPsec Keying Material in DNS
* 403{3,4,5} - DNSSEC + validation functions
Expand Down Expand Up @@ -188,6 +189,9 @@ Example programs can be found in the `github.com/miekg/exdns` repository.
* 8777 - DNS Reverse IP Automatic Multicast Tunneling (AMT) Discovery
* 8914 - Extended DNS Errors
* 8976 - Message Digest for DNS Zones (ZONEMD RR)
* 9460 - Service Binding and Parameter Specification via the DNS
* 9461 - Service Binding Mapping for DNS Servers
* 9462 - Discovery of Designated Resolvers

## Loosely Based Upon

Expand Down
85 changes: 85 additions & 0 deletions acceptfunc_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package dns

import (
"encoding/binary"
"net"
"testing"
)

Expand Down Expand Up @@ -33,3 +35,86 @@ func handleNotify(w ResponseWriter, req *Msg) {
m.SetReply(req)
w.WriteMsg(m)
}

func TestInvalidMsg(t *testing.T) {
HandleFunc("example.org.", func(ResponseWriter, *Msg) {
t.Fatal("the handler must not be called in any of these tests")
})
s, addrstr, _, err := RunLocalTCPServer(":0")
if err != nil {
t.Fatalf("unable to run test server: %v", err)
}
defer s.Shutdown()

s.MsgAcceptFunc = func(dh Header) MsgAcceptAction {
switch dh.Id {
case 0x0001:
return MsgAccept
case 0x0002:
return MsgReject
case 0x0003:
return MsgIgnore
case 0x0004:
return MsgRejectNotImplemented
default:
t.Errorf("unexpected ID %x", dh.Id)
return -1
}
}

invalidErrors := make(chan error)
s.MsgInvalidFunc = func(m []byte, err error) {
invalidErrors <- err
}

c, err := net.Dial("tcp", addrstr)
if err != nil {
t.Fatalf("cannot connect to test server: %v", err)
}

write := func(m []byte) {
var length [2]byte
binary.BigEndian.PutUint16(length[:], uint16(len(m)))
_, err := c.Write(length[:])
if err != nil {
t.Fatalf("length write failed: %v", err)
}
_, err = c.Write(m)
if err != nil {
t.Fatalf("content write failed: %v", err)
}
}

/* Message is too short, so there is no header to accept or reject. */

tooShortMessage := make([]byte, 11)
tooShortMessage[1] = 0x3 // ID = 3, would be ignored if it were parsable.

write(tooShortMessage)
// Expect an error to be reported.
<-invalidErrors

/* Message is accepted but is actually invalid. */

badMessage := make([]byte, 13)
badMessage[1] = 0x1 // ID = 1, Accept.
badMessage[5] = 1 // QDCOUNT = 1
badMessage[12] = 99 // Bad question section. Invalid!

write(badMessage)
// Expect an error to be reported.
<-invalidErrors

/* Message is rejected before it can be determined to be invalid. */

close(invalidErrors) // A call to InvalidMsgFunc would panic due to the closed chan.

badMessage[1] = 0x2 // ID = 2, Reject
write(badMessage)

badMessage[1] = 0x3 // ID = 3, Ignore
write(badMessage)

badMessage[1] = 0x4 // ID = 4, RejectNotImplemented
write(badMessage)
}
98 changes: 53 additions & 45 deletions edns.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,15 @@ func makeDataOpt(code uint16) EDNS0 {
case EDNS0EDE:
return new(EDNS0_EDE)
case EDNS0ESU:
return &EDNS0_ESU{Code: EDNS0ESU}
return new(EDNS0_ESU)
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.
// OPT is the EDNS0 RR appended to messages to convey extra (meta) information. See RFC 6891.
type OPT struct {
Hdr RR_Header
Option []EDNS0 `dns:"opt"`
Expand Down Expand Up @@ -144,8 +143,6 @@ func (*OPT) parse(c *zlexer, origin string) *ParseError {

func (rr *OPT) isDuplicate(r2 RR) bool { return false }

// return the old value -> delete SetVersion?

// Version returns the EDNS version used. Only zero is defined.
func (rr *OPT) Version() uint8 {
return uint8(rr.Hdr.Ttl & 0x00FF0000 >> 16)
Expand Down Expand Up @@ -236,8 +233,8 @@ type EDNS0 interface {
// e.Nsid = "AA"
// o.Option = append(o.Option, e)
type EDNS0_NSID struct {
Code uint16 // Always EDNS0NSID
Nsid string // This string needs to be hex encoded
Code uint16 // always EDNS0NSID
Nsid string // string needs to be hex encoded
}

func (e *EDNS0_NSID) pack() ([]byte, error) {
Expand Down Expand Up @@ -275,7 +272,7 @@ func (e *EDNS0_NSID) copy() EDNS0 { return &EDNS0_NSID{e.Code, e.Nsid}
// When packing it will apply SourceNetmask. If you need more advanced logic,
// patches welcome and good luck.
type EDNS0_SUBNET struct {
Code uint16 // Always EDNS0SUBNET
Code uint16 // always EDNS0SUBNET
Family uint16 // 1 for IP, 2 for IP6
SourceNetmask uint8
SourceScope uint8
Expand Down Expand Up @@ -399,8 +396,8 @@ func (e *EDNS0_SUBNET) copy() EDNS0 {
//
// There is no guarantee that the Cookie string has a specific length.
type EDNS0_COOKIE struct {
Code uint16 // Always EDNS0COOKIE
Cookie string // Hex-encoded cookie data
Code uint16 // always EDNS0COOKIE
Cookie string // hex encoded cookie data
}

func (e *EDNS0_COOKIE) pack() ([]byte, error) {
Expand Down Expand Up @@ -430,7 +427,7 @@ func (e *EDNS0_COOKIE) copy() EDNS0 { return &EDNS0_COOKIE{e.Code, e.C
// e.Lease = 120 // in seconds
// o.Option = append(o.Option, e)
type EDNS0_UL struct {
Code uint16 // Always EDNS0UL
Code uint16 // always EDNS0UL
Lease uint32
KeyLease uint32
}
Expand Down Expand Up @@ -469,7 +466,7 @@ func (e *EDNS0_UL) unpack(b []byte) error {
// EDNS0_LLQ stands for Long Lived Queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01
// Implemented for completeness, as the EDNS0 type code is assigned.
type EDNS0_LLQ struct {
Code uint16 // Always EDNS0LLQ
Code uint16 // always EDNS0LLQ
Version uint16
Opcode uint16
Error uint16
Expand Down Expand Up @@ -515,7 +512,7 @@ func (e *EDNS0_LLQ) copy() EDNS0 {

// EDNS0_DAU implements the EDNS0 "DNSSEC Algorithm Understood" option. See RFC 6975.
type EDNS0_DAU struct {
Code uint16 // Always EDNS0DAU
Code uint16 // always EDNS0DAU
AlgCode []uint8
}

Expand All @@ -539,7 +536,7 @@ func (e *EDNS0_DAU) copy() EDNS0 { return &EDNS0_DAU{e.Code, e.AlgCode} }

// EDNS0_DHU implements the EDNS0 "DS Hash Understood" option. See RFC 6975.
type EDNS0_DHU struct {
Code uint16 // Always EDNS0DHU
Code uint16 // always EDNS0DHU
AlgCode []uint8
}

Expand All @@ -563,7 +560,7 @@ func (e *EDNS0_DHU) copy() EDNS0 { return &EDNS0_DHU{e.Code, e.AlgCode} }

// EDNS0_N3U implements the EDNS0 "NSEC3 Hash Understood" option. See RFC 6975.
type EDNS0_N3U struct {
Code uint16 // Always EDNS0N3U
Code uint16 // always EDNS0N3U
AlgCode []uint8
}

Expand All @@ -588,7 +585,7 @@ func (e *EDNS0_N3U) copy() EDNS0 { return &EDNS0_N3U{e.Code, e.AlgCode} }

// EDNS0_EXPIRE implements the EDNS0 option as described in RFC 7314.
type EDNS0_EXPIRE struct {
Code uint16 // Always EDNS0EXPIRE
Code uint16 // always EDNS0EXPIRE
Expire uint32
Empty bool // Empty is used to signal an empty Expire option in a backwards compatible way, it's not used on the wire.
}
Expand Down Expand Up @@ -668,7 +665,7 @@ 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
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,
Expand Down Expand Up @@ -756,36 +753,48 @@ const (
ExtendedErrorCodeNoReachableAuthority
ExtendedErrorCodeNetworkError
ExtendedErrorCodeInvalidData
ExtendedErrorCodeSignatureExpiredBeforeValid
ExtendedErrorCodeTooEarly
ExtendedErrorCodeUnsupportedNSEC3IterValue
ExtendedErrorCodeUnableToConformToPolicy
ExtendedErrorCodeSynthesized
ExtendedErrorCodeInvalidQueryType
)

// 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",
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",
ExtendedErrorCodeSignatureExpiredBeforeValid: "Signature Expired Before Valid",
ExtendedErrorCodeTooEarly: "Too Early",
ExtendedErrorCodeUnsupportedNSEC3IterValue: "Unsupported NSEC3 Iterations Value",
ExtendedErrorCodeUnableToConformToPolicy: "Unable To Conform To Policy",
ExtendedErrorCodeSynthesized: "Synthesized",
ExtendedErrorCodeInvalidQueryType: "Invalid Query Type",
}

// StringToExtendedErrorCode is a map from human readable descriptions to
Expand Down Expand Up @@ -827,13 +836,12 @@ func (e *EDNS0_EDE) unpack(b []byte) error {
return nil
}

// The EDNS0_ESU option for ENUM Source-URI Extension
// The EDNS0_ESU option for ENUM Source-URI Extension.
type EDNS0_ESU struct {
Code uint16
Code uint16 // always EDNS0ESU
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} }
Expand Down
10 changes: 5 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ module github.com/zmap/dns
go 1.19

require (
golang.org/x/net v0.22.0
golang.org/x/sync v0.6.0
golang.org/x/sys v0.18.0
golang.org/x/tools v0.19.0
golang.org/x/net v0.28.0
golang.org/x/sync v0.7.0
golang.org/x/sys v0.23.0
golang.org/x/tools v0.22.0
)

require golang.org/x/mod v0.16.0 // indirect
require golang.org/x/mod v0.18.0 // indirect
20 changes: 10 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=
golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
11 changes: 11 additions & 0 deletions parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1609,7 +1609,18 @@ func TestParseSVCB(t *testing.T) {
// From draft-ietf-add-ddr-06
`_dns.example.net. SVCB 1 example.net. alpn=h2 dohpath=/dns-query{?dns}`: `_dns.example.net. 3600 IN SVCB 1 example.net. alpn="h2" dohpath="/dns-query{?dns}"`,
`_dns.example.net. SVCB 1 example.net. alpn=h2 dohpath=/dns\045query{\?dns}`: `_dns.example.net. 3600 IN SVCB 1 example.net. alpn="h2" dohpath="/dns-query{?dns}"`,
// From RFC9461 Section 7 (https://datatracker.ietf.org/doc/html/rfc9461#section-7)
`_dns.simple.example. 7200 IN SVCB 1 simple.example. alpn=dot`: `_dns.simple.example. 7200 IN SVCB 1 simple.example. alpn="dot"`,
`_dns.doh.example. 7200 IN SVCB 1 doh.example. alpn=h2 dohpath=/dns-query{?dns}`: `_dns.doh.example. 7200 IN SVCB 1 doh.example. alpn="h2" dohpath="/dns-query{?dns}"`,
`_dns.resolver.example. 7200 IN SVCB 1 resolver.example. alpn=dot,doq,h2,h3 dohpath=/q{?dns}`: `_dns.resolver.example. 7200 IN SVCB 1 resolver.example. alpn="dot,doq,h2,h3" dohpath="/q{?dns}"`,
`_dns.resolver.example. 7200 IN SVCB 2 resolver.example. alpn=dot port=8530`: `_dns.resolver.example. 7200 IN SVCB 2 resolver.example. alpn="dot" port="8530"`,
// From RFC 9540 Section 4.2.1 (https://www.rfc-editor.org/rfc/rfc9540.html#name-the-ohttp-svcparamkey)
`_dns.resolver.arpa 7200 IN SVCB 1 doh.example.net alpn=h2 dohpath=/dns-query{?dns} ohttp`: `_dns.resolver.arpa. 7200 IN SVCB 1 doh.example.net. alpn="h2" dohpath="/dns-query{?dns}" ohttp=""`,
// From RFC 9540 Section 4.1 (HTTPS RR) (https://www.rfc-editor.org/rfc/rfc9540.html#name-use-in-https-service-rrs)
`svc.example.com. 7200 IN HTTPS 1 . alpn=h2 ohttp`: `svc.example.com. 7200 IN HTTPS 1 . alpn="h2" ohttp=""`,
`svc.example.com. 7200 IN HTTPS 1 . mandatory=ohttp ohttp`: `svc.example.com. 7200 IN HTTPS 1 . mandatory="ohttp" ohttp=""`,
}

for s, o := range svcbs {
rr, err := NewRR(s)
if err != nil {
Expand Down
Loading

0 comments on commit dd1b978

Please sign in to comment.