Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge upstream changes #3

Merged
merged 33 commits into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
3d593a6
Swap closing order in `inAxfr` and `inIxfr` (#1511)
noxer Nov 13, 2023
257e89e
feat: add support for ReuseAddr (#1510)
jimlambrt Nov 15, 2023
836bea2
Release 1.1.57
miekg Nov 15, 2023
9bbcd24
Try explaining duplicate RCODEs
miekg Dec 13, 2023
f206faa
docs: added ninedos to readme (#1522)
wintbiit Jan 9, 2024
50fbccd
Allow use of fs.FS for $INCLUDE and wrap errors (#1526)
dpifke Jan 15, 2024
be7d6e5
Bump golang.org/x/net from 0.17.0 to 0.19.0 (#1520)
dependabot[bot] Jan 18, 2024
e7aed24
Bump golang.org/x/sys from 0.13.0 to 0.15.0 (#1518)
dependabot[bot] Jan 18, 2024
4c06a1b
Add NXT record (#1516)
miekg Jan 18, 2024
8ad6d5b
Add ISDN record (#1515)
miekg Jan 18, 2024
fd91c6a
Bump golang.org/x/tools from 0.13.0 to 0.17.0 (#1529)
dependabot[bot] Jan 18, 2024
a493770
Release 1.1.58
miekg Jan 18, 2024
21ba49c
Improve NewRR documentation (#1531)
gibson042 Jan 21, 2024
982d149
Add incus to the list of users (#1535)
montag451 Feb 10, 2024
57dcd27
Add option to do a zone transfer via TLS (#1533)
cesarkuroiwa Feb 14, 2024
2230854
IsDomainName: check for escape as last character (#1532)
miekg Feb 15, 2024
d51366b
Bump golang.org/x/sys from 0.16.0 to 0.17.0 (#1541)
dependabot[bot] Mar 29, 2024
ad46f23
Bump golang.org/x/net from 0.20.0 to 0.21.0 (#1542)
dependabot[bot] Mar 29, 2024
96cf8ba
Bump golang.org/x/tools from 0.17.0 to 0.19.0 (#1551)
dependabot[bot] Mar 29, 2024
1c6c796
chore: fix some comments (#1547)
xiaoxiangxianzi Mar 29, 2024
ba039c8
Add ifconfig.es to the list of users (#1554)
dcarrillo Apr 17, 2024
e4ef594
Fix counting of escape sequences when splitting TXT strings (#1540)
janik-cloudflare Apr 17, 2024
76926c7
Fix possible out-of-bounds read in endingToTxtSlice (#1557)
janik-cloudflare Jun 13, 2024
d945412
Bump golang.org/x/sys from 0.18.0 to 0.20.0 (#1571)
dependabot[bot] Jun 13, 2024
f89100d
Bump golang.org/x/net from 0.22.0 to 0.25.0 (#1569)
dependabot[bot] Jun 13, 2024
32f0e18
Bump golang.org/x/tools from 0.19.0 to 0.22.0 (#1574)
dependabot[bot] Jun 13, 2024
2b89f28
(*Transfer) Out: Increment WaitGroup in example (#1572)
eest Jun 13, 2024
eada9c9
Add a hook to catch invalid messages (#1568)
bemasc Jun 13, 2024
c3301c3
These two too
miekg Jun 13, 2024
a1ef7a6
Add RFC 9540 oblivious services via service binding records (#1567)
steffsas Jun 13, 2024
e5a40bc
update list of RFCs
miekg Jun 13, 2024
870b1c1
add rfc3596 to the list (#1577)
Infinoid Jun 21, 2024
f46bd31
Merge remote-tracking branch 'upstream/master' into jbrandhorst-merge…
johanbrandhorst Jun 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ A not-so-up-to-date-list-that-may-be-actually-current:
* https://dnscheck.tools/
* https://github.com/egbakou/domainverifier
* https://github.com/semihalev/sdns
* https://github.com/wintbiit/NineDNS
* https://linuxcontainers.org/incus/
* https://ifconfig.es


Send pull request if you want to be listed here.
Expand Down Expand Up @@ -125,6 +128,7 @@ Example programs can be found in the `github.com/miekg/exdns` repository.
*all of them*

* 103{4,5} - DNS standard
* 1183 - ISDN, X25 and other deprecated records
* 1348 - NSAP record (removed the record)
* 1982 - Serial Arithmetic
* 1876 - LOC record
Expand All @@ -144,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 @@ -184,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)
}
8 changes: 7 additions & 1 deletion defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,10 +198,12 @@ func IsDomainName(s string) (labels int, ok bool) {
off int
begin int
wasDot bool
escape bool
)
for i := 0; i < len(s); i++ {
switch s[i] {
case '\\':
escape = !escape
if off+1 > lenmsg {
return labels, false
}
Expand All @@ -217,6 +219,7 @@ func IsDomainName(s string) (labels int, ok bool) {

wasDot = false
case '.':
escape = false
if i == 0 && len(s) > 1 {
// leading dots are not legal except for the root zone
return labels, false
Expand All @@ -243,10 +246,13 @@ func IsDomainName(s string) (labels int, ok bool) {
labels++
begin = i + 1
default:
escape = false
wasDot = false
}
}

if escape {
return labels, false
}
return labels, true
}

Expand Down
2 changes: 1 addition & 1 deletion dnssec_keyscan.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ func parseKey(r io.Reader, file string) (map[string]string, error) {
k = l.token
case zValue:
if k == "" {
return nil, &ParseError{file, "no private key seen", l}
return nil, &ParseError{file: file, err: "no private key seen", lex: l}
}

m[strings.ToLower(k)] = l.token
Expand Down
2 changes: 1 addition & 1 deletion generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ func (r *generateReader) parseError(msg string, end int) *ParseError {
l.token = r.s[r.si-1 : end]
l.column += r.si // l.column starts one zBLANK before r.s

return &ParseError{r.file, msg, l}
return &ParseError{file: r.file, err: msg, lex: l}
}

func (r *generateReader) Read(p []byte) (int, error) {
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/miekg/dns
go 1.19

require (
golang.org/x/net v0.17.0
golang.org/x/sync v0.4.0
golang.org/x/sys v0.13.0
golang.org/x/tools v0.13.0
golang.org/x/net v0.26.0
golang.org/x/sync v0.7.0
golang.org/x/sys v0.21.0
golang.org/x/tools v0.22.0
)

require golang.org/x/mod v0.12.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.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
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.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
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.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.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=
2 changes: 2 additions & 0 deletions listen_no_reuseport.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ func listenTCP(network, addr string, reuseport, reuseaddr bool) (net.Listener, e
return net.Listen(network, addr)
}

const supportsReuseAddr = false

func listenUDP(network, addr string, reuseport, reuseaddr bool) (net.PacketConn, error) {
if reuseport || reuseaddr {
// TODO(tmthrgd): return an error?
Expand Down
6 changes: 4 additions & 2 deletions listen_reuseport.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ func reuseportControl(network, address string, c syscall.RawConn) error {
return opErr
}

const supportsReuseAddr = true

func reuseaddrControl(network, address string, c syscall.RawConn) error {
var opErr error
err := c.Control(func(fd uintptr) {
Expand All @@ -37,7 +39,7 @@ func reuseaddrControl(network, address string, c syscall.RawConn) error {
return opErr
}

func listenTCP(network, addr string, reuseport bool, reuseaddr bool) (net.Listener, error) {
func listenTCP(network, addr string, reuseport, reuseaddr bool) (net.Listener, error) {
var lc net.ListenConfig
switch {
case reuseaddr && reuseport:
Expand All @@ -50,7 +52,7 @@ func listenTCP(network, addr string, reuseport bool, reuseaddr bool) (net.Listen
return lc.Listen(context.Background(), network, addr)
}

func listenUDP(network, addr string, reuseport bool, reuseaddr bool) (net.PacketConn, error) {
func listenUDP(network, addr string, reuseport, reuseaddr bool) (net.PacketConn, error) {
var lc net.ListenConfig
switch {
case reuseaddr && reuseport:
Expand Down
2 changes: 1 addition & 1 deletion msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@ func (h *MsgHdr) String() string {
return s
}

// Pack packs a Msg: it is converted to to wire format.
// Pack packs a Msg: it is converted to wire format.
// If the dns.Compress is true the message will be in compressed wire format.
func (dns *Msg) Pack() (msg []byte, err error) {
return dns.PackBuffer(nil)
Expand Down
67 changes: 59 additions & 8 deletions parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1098,18 +1098,41 @@ func TestTXT(t *testing.T) {
}
}

// Test TXT record with chunk larger than 255 bytes, they should be split up, by the parser
s := ""
for i := 0; i < 255; i++ {
s += "a"
// Test TXT record with string larger than 255 bytes that should be split
// up by the parser. Add some escape sequences too to ensure their length
// is counted correctly.
s := `"\;\\\120` + strings.Repeat("a", 255) + `b"`
rr, err = NewRR(`test.local. 60 IN TXT ` + s)
if err != nil {
t.Error("failed to parse empty-string TXT record", err)
}
if rr.(*TXT).Txt[1] != "aaab" {
t.Errorf("Txt should have two strings, last one must be 'aaab', but is %s", rr.(*TXT).Txt[1])
}
s += "b"
rr, err = NewRR(`test.local. 60 IN TXT "` + s + `"`)
rrContent := strings.Replace(rr.String(), rr.Header().String(), "", 1)
expectedRRContent := `";\\x` + strings.Repeat("a", 252) + `" "aaab"`
if expectedRRContent != rrContent {
t.Errorf("Expected TXT RR content to be %#q but got %#q", expectedRRContent, rrContent)
}

// Test TXT record that is already split up into strings of len <= 255.
s = fmt.Sprintf(
"%q %q %q %q %q %q",
strings.Repeat(`a`, 255),
strings.Repeat("b", 255),
strings.Repeat("c", 255),
strings.Repeat("d", 0),
strings.Repeat("e", 1),
strings.Repeat("f", 123),
)
rr, err = NewRR(`test.local. 60 IN TXT ` + s)
if err != nil {
t.Error("failed to parse empty-string TXT record", err)
}
if rr.(*TXT).Txt[1] != "b" {
t.Errorf("Txt should have two chunk, last one my be 'b', but is %s", rr.(*TXT).Txt[1])
rrContent = strings.Replace(rr.String(), rr.Header().String(), "", 1)
expectedRRContent = s // same as input
if expectedRRContent != rrContent {
t.Errorf("Expected TXT RR content to be %#q but got %#q", expectedRRContent, rrContent)
}
}

Expand Down Expand Up @@ -1450,6 +1473,23 @@ func TestParseHINFO(t *testing.T) {
}
}

func TestParseISDN(t *testing.T) {
dt := map[string]string{
"example.net. ISDN A B": "example.net. 3600 IN ISDN \"A\" \"B\"",
"example.net. ISDN \"A\" \"B\"": "example.net. 3600 IN ISDN \"A\" \"B\"",
}
for i, o := range dt {
rr, err := NewRR(i)
if err != nil {
t.Error("failed to parse RR: ", err)
continue
}
if rr.String() != o {
t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String())
}
}
}

func TestParseCAA(t *testing.T) {
lt := map[string]string{
"example.net. CAA 0 issue \"symantec.com\"": "example.net.\t3600\tIN\tCAA\t0 issue \"symantec.com\"",
Expand Down Expand Up @@ -1569,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
2 changes: 1 addition & 1 deletion privaterr.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ Fetch:

err := r.Data.Parse(text)
if err != nil {
return &ParseError{"", err.Error(), l}
return &ParseError{wrappedErr: err, lex: l}
}

return nil
Expand Down
Loading