Update deps

This commit is contained in:
Frank Denis
2026-03-02 07:45:36 +01:00
parent 2f9899ed1c
commit 92d457b52d
22 changed files with 229 additions and 237 deletions
+1 -1
View File
@@ -76,7 +76,7 @@ jobs:
ls -l dnscrypt-proxy*
- name: Upload artifacts
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: dnscrypt-proxy-${{ steps.get_version.outputs.VERSION }}
path: |
+2 -2
View File
@@ -5,7 +5,7 @@ go 1.25.0
exclude google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1
require (
codeberg.org/miekg/dns v0.6.57
codeberg.org/miekg/dns v0.6.64
github.com/BurntSushi/toml v1.6.0
github.com/VividCortex/ewma v1.2.0
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
@@ -29,7 +29,7 @@ require (
github.com/powerman/check v1.9.0
github.com/quic-go/quic-go v0.59.0
golang.org/x/crypto v0.48.0
golang.org/x/net v0.50.0
golang.org/x/net v0.51.0
golang.org/x/sys v0.41.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
)
+4 -4
View File
@@ -1,5 +1,5 @@
codeberg.org/miekg/dns v0.6.57 h1:IG9Qmun85ReS8qeFi5DGmOZMNbCzZfkrmJmp9d5Zyjc=
codeberg.org/miekg/dns v0.6.57/go.mod h1:fIxAzBMDPnXWSw0fp8+pfZMRiAqYY4+HHYLzUo/S6Dg=
codeberg.org/miekg/dns v0.6.64 h1:xzvVDL4qhFvU+scxZ2TlV0zhPlCYIps8sUncz2RR7ok=
codeberg.org/miekg/dns v0.6.64/go.mod h1:58Y3ZTg6Z5ZEm/ZAAwHehbZfrD4u5mE4RByHoPEMyKk=
github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk=
github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
@@ -81,8 +81,8 @@ golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=
golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60=
golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM=
golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo=
golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20190529164535-6a60838ec259/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+2
View File
@@ -78,6 +78,7 @@ A not-so-up-to-date-list-that-may-be-actually-current:
[ODOH](https://developers.cloudflare.com/1.1.1.1/encryption/oblivious-dns-over-https/).
- [DNSControl](https://dnscontrol.org/) - DNSControl is an opinionated platform for seamlessly managing your DNS configuration across any number of DNS hosts,
both in the cloud or in your own infrastructure.
- [Gonemaster](https://codeberg.org/pawal/gonemaster) - Gonemaster is a Go implementation of the DNS test framework Zonemaster engine and CLI.
Send pull request if you want to be listed here.
@@ -216,6 +217,7 @@ _all of them_ and _then some_
- 9567 - DNS Error Reporting
- 9606 - DNS Resolver Information
- 9660 - Zone version
- 9715 - IP Fragmentation Avoidance in DNS over UDP
- 9859 - DSYNC RR
- draft-ietf-compact-denial - CO bit
- draft-ietf-deleg - DELEG RR
+6 -5
View File
@@ -25,8 +25,9 @@ import (
//go:generate go run clone_generate.go
const (
// DefaultMsgSize is the standard default for messages larger than 512 bytes.
DefaultMsgSize = 4096
// DefaultMsgSize is the standard default for messages larger than 512 bytes. This limit is the
// recommendation from RFC 9715.
DefaultMsgSize = 1400
// MinMsgSize is the minimal size of a DNS message.
MinMsgSize = 512
// MaxMsgSize is the largest possible DNS message.
@@ -35,8 +36,6 @@ const (
MsgHeaderSize = 12
// MaxSerialIncrement is the maximum difference between two serial numbers. See RFC 1982.
MaxSerialIncrement = math.MaxUint32 / 2 // 2147483647
defaultTTL = 3600 // Default internal TTL.
)
// An RR represents a DNS resource record.
@@ -95,7 +94,9 @@ type Packer interface {
// Parser is used for custom RR types that are parsed from their text presentation.
type Parser interface {
// Scan gets the current origin and a slice of all non-blank tokens left on the current line.
// Parse gets the current origin and a slice of tokens left on the current line. The tokens contains all
// non-blank works and quotes left on the current line, i.e. if your have "this" and "that" tokens will
// contain: " this " " that "
Parse(tokens []string, origin string) error
}
+6 -8
View File
@@ -87,13 +87,16 @@ func (zp *ZoneParser) generate(l dnslex.Lex) (RR, bool) {
zp.sub = NewZoneParser(r, zp.origin, zp.file)
zp.sub.includeDepth, zp.sub.IncludeAllowFunc = zp.includeDepth, zp.IncludeAllowFunc
zp.sub.generateDisallowed = true
zp.sub.SetDefaultTTL(defaultTTL)
zp.sub.SetDefaultTTL(3600)
return zp.subNext()
}
type generateReader struct {
s string
si uint16
lex *dnslex.Lex
s string
si uint16
escape bool
eof bool
cur int64
start int64
@@ -102,12 +105,7 @@ type generateReader struct {
mod bytes.Buffer
escape bool
eof bool
file string
lex *dnslex.Lex
}
func (r *generateReader) parseError(msg string, end uint16) *ParseError {
+3
View File
@@ -145,6 +145,9 @@ func (zl *Lexer) readByte() (byte, bool) {
return c, true
}
// Blank consumes the next token and returns false if the token was not a blacnk
func (zl *Lexer) Blank() bool { l, _ := zl.Next(); return l.Value == Blank }
func (zl *Lexer) Peek() Lex {
if zl.Key(kNextL) {
return zl.l
+22 -7
View File
@@ -149,12 +149,12 @@ func A(a netip.Addr, msg []byte, off int) (int, error) {
if off+net.IPv4len > len(msg) {
return len(msg), &Error{"overflow a"}
}
if !a.Is4() && !a.Is4In6() {
return len(msg), &Error{"invalid a"}
}
val := a.As4()
_ = msg[off+3]
copy(msg[off:off+net.IPv4len], val[:])
_ = msg[off+net.IPv4len-1]
msg[off] = val[0]
msg[off+1] = val[1]
msg[off+2] = val[2]
msg[off+3] = val[3]
return off + net.IPv4len, nil
}
@@ -163,8 +163,23 @@ func AAAA(aaaa netip.Addr, msg []byte, off int) (int, error) {
return len(msg), &Error{"overflow aaaa"}
}
val := aaaa.As16()
_ = msg[off+15]
copy(msg[off:off+net.IPv6len], val[:])
_ = msg[off+net.IPv6len-1]
msg[off] = val[0]
msg[off+1] = val[1]
msg[off+2] = val[2]
msg[off+3] = val[3]
msg[off+4] = val[4]
msg[off+5] = val[5]
msg[off+6] = val[6]
msg[off+7] = val[7]
msg[off+8] = val[8]
msg[off+9] = val[9]
msg[off+10] = val[10]
msg[off+11] = val[11]
msg[off+12] = val[12]
msg[off+13] = val[13]
msg[off+14] = val[14]
msg[off+15] = val[15]
return off + net.IPv6len, nil
}
+64 -63
View File
@@ -204,10 +204,10 @@ func (m *Msg) Pack() error {
}
isPseudo := m.isPseudo()
counts := uint64(len(m.Question)<<48) |
uint64(len(m.Answer)<<32) |
uint64(len(m.Ns)<<16) |
uint64(len(m.Extra)+int(isPseudo))
counts := uint64(len(m.Question))<<48 |
uint64(len(m.Answer))<<32 |
uint64(len(m.Ns))<<16 |
uint64(len(m.Extra)+isPseudo)
off, err = pack.Uint64(counts, m.Data, off)
if err != nil {
@@ -220,12 +220,12 @@ func (m *Msg) Pack() error {
compression = make(map[string]uint16, l+3) // 3 is randomly chosen, as that much rdata might be compressable...
}
for i := range m.Question {
if off, err = packQuestion(m.Question[i], m.Data, off, compression); err != nil {
if len(m.Question) > 0 {
if off, err = packQuestion(m.Question[0], m.Data, off, compression); err != nil {
return err
}
break // allow only one
}
for i := range m.Answer {
if _, off, err = packRR(m.Answer[i], m.Data, off, compression); err != nil {
return err
@@ -267,9 +267,9 @@ func (m *Msg) Pack() error {
opt.SetDelegation(true)
}
for i := range m.Pseudo {
opt.Hdr.Name = "."
switch x := m.Pseudo[i].(type) {
case EDNS0:
opt.Hdr.Name = "."
opt.Options = append(opt.Options, x)
default:
tsigOrsig0 = true
@@ -413,8 +413,10 @@ Rest:
// Check for the OPT RR and remove it entirely, unpack the OPT for option codes and put those in the Pseudo
// section. We will only check one OPT, any others will be left in Extra.
for i := 0; i < len(m.Extra); i++ {
if opt, ok := m.Extra[i].(*OPT); ok {
Extra1:
for i := len(m.Extra) - 1; i >= 0; i-- {
switch opt := m.Extra[i].(type) {
case *OPT:
m.Security = opt.Security()
m.CompactAnswers = opt.CompactAnswers()
m.Delegation = opt.Delegation()
@@ -424,26 +426,22 @@ Rest:
m.UDPSize = max(opt.UDPSize(), MinMsgSize)
m.Pseudo = make([]RR, len(opt.Options), len(opt.Options)+1) // +1 for tsig/sig zero, avoid 2x in a append
for i := range opt.Options {
m.Pseudo[i] = RR(opt.Options[i])
for j := range opt.Options {
m.Pseudo[j] = RR(opt.Options[j])
}
m.Extra[i] = m.Extra[len(m.Extra)-1] // opt's place taken with last rr
m.Extra = m.Extra[:len(m.Extra)-1] // remove the OPT RR
break
m.Extra[i] = m.Extra[len(m.Extra)-1] // opt's place switch with last rr
m.Extra = m.Extra[:len(m.Extra)-1] // remove cruft
break Extra1
}
}
// Check for m.Extra TSIG and SIG(0) and move them to pseudo. This MUST be the the last RR in the extra section.
for i := 0; i < len(m.Extra); i++ {
_, ok1 := m.Extra[i].(*TSIG)
_, ok2 := m.Extra[i].(*SIG)
if ok1 || ok2 {
Extra2:
for i := len(m.Extra) - 1; i >= 0; i-- {
switch m.Extra[i].(type) {
case *TSIG, *SIG:
m.Pseudo = append(m.Pseudo, m.Extra[i])
m.Extra[i] = m.Extra[len(m.Extra)-1] // sig/tsig's place taken with last rr
m.Extra = m.Extra[:len(m.Extra)-1] // remove the sig/tsig RR
break
m.Extra[i] = m.Extra[len(m.Extra)-1] // sig/tsig's place switch with last rr
m.Extra = m.Extra[:len(m.Extra)-1] // remove cruft
break Extra2
}
}
@@ -584,23 +582,27 @@ func (m *Msg) String() string {
return s
}
// isPseudo returns (1) true of we should have a pseudo section in this message, or not (0). It returns an
// isPseudo returns (1 or 2) if we should have a pseudo section in this message, or not (0). It returns an
// int becuse we need that number of the Extra section sizing.
func (m *Msg) isPseudo() uint8 {
if lp := len(m.Pseudo); lp > 0 || m.UDPSize > MinMsgSize || m.Security || m.CompactAnswers || m.Delegation || m.Rcode > 0xF {
if lp == 0 {
return 1 // OPT without options, 1 record
}
switch m.Pseudo[lp-1].(type) {
// OPT + one of these
case *TSIG:
return 2
case *SIG:
return 2
}
return 1 // OPT with options, still 1 record
func (m *Msg) isPseudo() int {
n := 0
if m.UDPSize > MinMsgSize || m.Security || m.CompactAnswers || m.Delegation || m.Rcode > 0xF {
n = 1
}
return 0
lp := len(m.Pseudo)
if lp > 0 {
switch m.Pseudo[lp-1].(type) {
case *TSIG:
n++
case *SIG:
n++
default:
if n == 0 { // not any of the message options are set
n = 1
}
}
}
return n
}
// Len returns the message length when in uncompressed wire format.
@@ -634,6 +636,8 @@ func (m *Msg) Len() int {
// are the extra checks we do here. See [isPseudo] and keep in sync.
if len(m.Pseudo) > 0 || m.UDPSize > MinMsgSize || m.Security || m.CompactAnswers || m.Delegation || m.Rcode > 0xF {
// If we find things in pseudo we get an OPT RR (fix length) plus the length of the option. OPT is always 11, 10 + "." (root label)
// In case of only a TSIG/SIG0 we overestimate, but because of speed we don't want to the full
// i.Pseudo check.
l += minHeaderSize
}
@@ -775,33 +779,30 @@ func (m *Msg) ReadFrom(r io.Reader) (int64, error) {
// sections. See [ZoneParser.RRs] also.
func (m *Msg) RRs() iter.Seq[RR] {
return func(yield func(RR) bool) {
for {
for i := range m.Question {
if !yield(m.Question[i]) {
return
}
for i := range m.Question {
if !yield(m.Question[i]) {
return
}
for i := range m.Answer {
if !yield(m.Answer[i]) {
return
}
}
for i := range m.Answer {
if !yield(m.Answer[i]) {
return
}
for i := range m.Ns {
if !yield(m.Ns[i]) {
return
}
}
for i := range m.Ns {
if !yield(m.Ns[i]) {
return
}
for i := range m.Extra {
if !yield(m.Extra[i]) {
return
}
}
for i := range m.Extra {
if !yield(m.Extra[i]) {
return
}
for i := range m.Pseudo {
if !yield(m.Pseudo[i]) {
return
}
}
for i := range m.Pseudo {
if !yield(m.Pseudo[i]) {
return
}
break
}
}
}
+27 -61
View File
@@ -110,7 +110,7 @@ func Read(r io.Reader) (RR, error) { return read(r, "") }
func read(r io.Reader, file string) (RR, error) {
zp := NewZoneParser(r, ".", file)
zp.SetDefaultTTL(defaultTTL)
zp.SetDefaultTTL(3600)
rr, _ := zp.Next()
return rr, zp.Err()
}
@@ -160,6 +160,10 @@ func readData(r io.Reader, rrtype uint16, origin ...string) (RDATA, error) {
type ZoneParser struct {
h Header // rr header as we parse
t uint16 // type as we parse, not stored in the header
includeDepth uint8
generateDisallowed bool
r io.Reader
c *dnslex.Lexer
@@ -192,9 +196,6 @@ type ZoneParser struct {
// Next, by calling subNext, forwards the resulting RRs from this
// sub parser to the calling code.
sub *ZoneParser
includeDepth uint8
generateDisallowed bool
}
// NewZoneParser returns an RFC 1035 style zone file parser that reads from r.
@@ -298,11 +299,10 @@ func (zp *ZoneParser) Next() (RR, bool) {
// 4. dnslex.Owner _ dnslex.String _ dnslex.Class _ dnslex.Rrtype -> ttl/class
// 5. dnslex.Owner _ dnslex.Class _ dnslex.String _ dnslex.Rrtype -> class/ttl (reversed)
//
// After detecting these, we know the zRrtype so we can jump to functions handling the rdata for each of these types.
// After detecting these, we know the RR type so we can jump to functions handling the rdata for each.
st := zExpectOwnerDir // initial state
Next:
for l, ok := zp.c.Next(); ok; l, ok = zp.c.Next() {
// zlexer spotted an error already
if l.Value == dnslex.Error {
@@ -311,7 +311,7 @@ Next:
switch st {
case zExpectOwnerDir:
// We can also expect a directive, like $TTL or $ORIGIN
// We can also expect a directive, like $TTL or $ORIGIN.
if zp.defttl != nil {
zp.h.TTL = zp.defttl.ttl
}
@@ -330,46 +330,31 @@ Next:
zp.h.Name = name
if l, ok = zp.c.Next(); !ok {
break Next
}
if l.Value != dnslex.Blank {
if !zp.c.Blank() {
return zp.setParseError("no blank after owner", l)
}
st = zExpectAny
case dnslex.DirTTL:
if l, ok = zp.c.Next(); !ok {
break Next
}
if l.Value != dnslex.Blank {
if !zp.c.Blank() {
return zp.setParseError("no blank after $TTL-directive", l)
}
st = zExpectDirTTL
case dnslex.DirOrigin:
if l, ok = zp.c.Next(); !ok {
break Next
}
if l.Value != dnslex.Blank {
if !zp.c.Blank() {
return zp.setParseError("no blank after $ORIGIN-directive", l)
}
st = zExpectDirOrigin
case dnslex.DirInclude:
if l, ok = zp.c.Next(); !ok {
break Next
}
if l.Value != dnslex.Blank {
if !zp.c.Blank() {
return zp.setParseError("no blank after $INCLUDE-directive", l)
}
st = zExpectDirInclude
case dnslex.DirGenerate:
if l, ok = zp.c.Next(); !ok {
break Next
}
if l.Value != dnslex.Blank {
if !zp.c.Blank() {
return zp.setParseError("no blank after $GENERATE-directive", l)
}
@@ -381,25 +366,18 @@ Next:
case dnslex.Class:
zp.h.Class = l.Torc
if l, ok = zp.c.Next(); !ok {
break Next
}
if l.Value != dnslex.Blank {
if !zp.c.Blank() {
return zp.setParseError("no blank after class", l)
}
st = zExpectAnyNoClass
case dnslex.Blank:
// Discard, can happen when there is nothing on the
// line except the RR type
// Discard, can happen when there is nothing on the line except the RR type.
case dnslex.String:
if zp.h.TTL, ok = setTTL(l); !ok {
return zp.setParseError("not a TTL", l)
}
if l, ok = zp.c.Next(); !ok {
break Next
}
if l.Value != dnslex.Blank {
if !zp.c.Blank() {
return zp.setParseError("no blank after TTL", l)
}
@@ -411,9 +389,8 @@ Next:
if l.Value != dnslex.Blank {
return zp.setParseError("no blank before RR type", l)
}
if l, ok = zp.c.Next(); !ok {
break Next
}
l, _ = zp.c.Next()
if l.Value != dnslex.Rrtype {
return zp.setParseError("unknown RR type", l)
}
@@ -431,12 +408,9 @@ Next:
rr = newFn()
*rr.Header() = zp.h
// We may be parsing a known RR type using the RFC3597 format.
// If so, we handle that here in a generic way.
//
// This is also true for PrivateRR types which will have the
// RFC3597 parsing done for them and the Unpack method called
// to populate the RR instead of simply deferring to Parse.
// We may be parsing a known RR type using the RFC3597 format. If so, we handle that here in a generic way.
// Custom RRs will need to be registered and will be called with processed []Tokens in
// parse.
if zp.c.Peek().Token == "\\#" {
parseAsRFC3597 = true
}
@@ -619,10 +593,7 @@ Next:
case dnslex.Class:
zp.h.Class = l.Torc
if l, ok = zp.c.Next(); !ok {
break Next
}
if l.Value != dnslex.Blank {
if !zp.c.Blank() {
return zp.setParseError("no blank after class", l)
}
@@ -631,10 +602,7 @@ Next:
if zp.h.TTL, ok = setTTL(l); !ok {
return zp.setParseError("not a TTL", l)
}
if l, ok = zp.c.Next(); !ok {
break Next
}
if l.Value != dnslex.Blank {
if !zp.c.Blank() {
return zp.setParseError("no blank after TTL", l)
}
@@ -741,9 +709,8 @@ func stringToTTL(token string) (uint32, bool) {
return uint32(s + i), true
}
// Parse LOC records' <digits>[.<digits>][mM] into a
// mantissa exponent format. Token should contain the entire
// string (i.e. no spaces allowed)
// stringgToCm parses LOC records' <digits>[.<digits>][mM] into a mantissa exponent format. Token should contain the entire
// string (i.e. no spaces allowed).
func stringToCm(token string) (e, m uint8, ok bool) {
if token[len(token)-1] == 'M' || token[len(token)-1] == 'm' {
token = token[0 : len(token)-1]
@@ -756,8 +723,7 @@ func stringToCm(token string) (e, m uint8, ok bool) {
mStr, cmStr, hasCM := strings.Cut(token, ".")
if hasCM {
// There's no point in having more than 2 digits in this part, and would rather make the implementation complicated ('123' should be treated as '12').
// So we simply reject it.
// We also make sure the first character is a digit to reject '+-' signs.
// So we simply reject it. We also make sure the first character is a digit to reject '+-' signs.
cmeters, err = strconv.Atoi(cmStr)
if err != nil || len(cmStr) > 2 || cmStr[0] < '0' || cmStr[0] > '9' {
return
@@ -790,7 +756,7 @@ func stringToCm(token string) (e, m uint8, ok bool) {
return e, uint8(val), true
}
// LOC record helper function
// LOC record helper function.
func locCheckNorth(token string, latitude uint32) (uint32, bool) {
if latitude > 90*1000*60*60 {
return latitude, false
@@ -804,7 +770,7 @@ func locCheckNorth(token string, latitude uint32) (uint32, bool) {
return latitude, false
}
// LOC record helper function
// LOC record helper function.
func locCheckEast(token string, longitude uint32) (uint32, bool) {
if longitude > 180*1000*60*60 {
return longitude, false
+16 -16
View File
@@ -17,15 +17,15 @@ func (o *ZONEVERSION) parse(c *dnslex.Lexer, _ string) error {
}
o.Labels = uint8(i)
c.Next() // zBlank
l, _ = c.Next() // zString
c.Next()
l, _ = c.Next()
// type, can be TYPEXXX, or SOA-SERIAL - we only accept SOA-SERIAL
if l.Token == "SOA-SERIAL" {
o.Type = 0
o.Version = make([]byte, 4)
}
c.Next() // zBlank
l, _ = c.Next() // zString
c.Next()
l, _ = c.Next()
i, err = strconv.ParseUint(l.Token, 10, 32)
if err != nil || l.Value == dnslex.Error {
return &ParseError{err: "bad ZONEVERSION Version", lex: l}
@@ -43,30 +43,30 @@ func (o *EDE) parse(c *dnslex.Lexer, _ string) error {
}
o.InfoCode = uint16(i)
c.Next() // zBlank
l, _ = c.Next() // zString, "
c.Next()
l, _ = c.Next() // String, "
// we skip the string because that's the infocode's text
c.Next() // zString
l, _ = c.Next() // zString, "
c.Next() // String
l, _ = c.Next() // String, "
if l.Token != `"` {
return &ParseError{err: "bad EDE InfoCode", lex: l}
}
l, _ = c.Next() // zString, :
l, _ = c.Next() // String, :
if l.Token != ":" {
return &ParseError{err: "bad EDE ExtraText", lex: l}
}
c.Next() // zBlank
l, _ = c.Next() // zString
c.Next()
l, _ = c.Next() // String
if l.Token != `"` {
return &ParseError{err: "bad EDE ExtraText", lex: l}
}
l, _ = c.Next() // zString
l, _ = c.Next() // String
if l.Token == `"` { // no extra text
return toParseError(dnslex.Discard(c))
}
o.ExtraText = l.Token
l, _ = c.Next() // Zstring, quote
l, _ = c.Next() // String, quote
if l.Token != `"` {
return &ParseError{err: "bad EDE ExtraText", lex: l}
}
@@ -84,13 +84,13 @@ func (o *NSID) parse(c *dnslex.Lexer, _ string) error {
}
o.Nsid = l.Token[:len(l.Token)-2]
c.Next() // zBlank
l, _ = c.Next() // zString
c.Next()
l, _ = c.Next() // String
if l.Token != `"` {
return &ParseError{err: "bad NSID Nsid", lex: l}
}
c.Next()
l, _ = c.Next() // Zstring, quote
l, _ = c.Next() // String, quote
if l.Token != `"` {
return &ParseError{err: "bad NSID Nsid", lex: l}
}
+5 -3
View File
@@ -1,6 +1,8 @@
package dns
import (
"strings"
"codeberg.org/miekg/dns/internal/ddd"
"codeberg.org/miekg/dns/internal/dnslex"
)
@@ -140,15 +142,15 @@ func escapedStringOffset(s string, desiredByteOffset int) (int, bool) {
// remainder returns a remainder of the rdata with embedded spaces, return the parsed string (sans the spaces)
// or an error
func remainder(c *dnslex.Lexer, errstr string) (string, error) {
s := "" // usually one or two strings, just work without strings.Builder
sb := &strings.Builder{} // allocate on stack, no pooling
for {
l, _ := c.Next()
switch l.Value {
case dnslex.String:
s += l.Token
sb.WriteString(l.Token)
case dnslex.Blank:
case dnslex.Newline, dnslex.EOF:
return s, nil
return sb.String(), nil
default:
return "", &ParseError{err: errstr, lex: l}
}
+10 -18
View File
@@ -4,7 +4,6 @@ import (
"crypto"
"fmt"
"codeberg.org/miekg/dns/internal/jump"
"codeberg.org/miekg/dns/internal/pack"
"codeberg.org/miekg/dns/internal/unpack"
)
@@ -24,16 +23,12 @@ func SIG0Sign(m *Msg, k SIG0Signer, options *SIG0Option) error {
return fmt.Errorf("%w: %s", ErrNoSIG0, "sign")
}
last := len(m.Ns) + len(m.Answer) + len(m.Extra) // skip question as 0th, is the first after question
off := jump.To(last, m.Data)
if off == 0 {
isPseudo := m.isPseudo() - 1 // should be 1 (only the tsig) or 2 (opt + tsig)
arcount := setArcount(m, isPseudo)
if arcount == -1 {
return fmt.Errorf("%w: %s", ErrNoSIG0, "sign")
}
m.Data = m.Data[:off]
arcount := uint16(len(m.Extra))
pack.Uint16(arcount, m.Data, msgArcount) // decrease additional section count, because we removed the TSIG
signature, err := k.Sign(s, m.Data, *options)
if err != nil {
return err
@@ -42,13 +37,14 @@ func SIG0Sign(m *Msg, k SIG0Signer, options *SIG0Option) error {
s.Signature = unpack.Base64(signature)
sbuf := make([]byte, s.Len())
if _, off, err = packRR(s, sbuf, 0, nil); err != nil {
_, off, err := packRR(s, sbuf, 0, nil)
if err != nil {
return err
}
sbuf = sbuf[:off]
m.Data = append(m.Data, sbuf...)
pack.Uint16(arcount+1, m.Data, msgArcount) // and +1 after we done for the new and improved TSIG that is added
pack.Uint16(uint16(arcount+1), m.Data, msgArcount) // and +1 after we done for the new and improved TSIG that is added
return nil
}
@@ -65,19 +61,15 @@ func SIG0Verify(m *Msg, y *KEY, k SIG0Signer, options *SIG0Option) error {
return fmt.Errorf("%w: %s", ErrNoSIG0, "verify")
}
last := len(m.Answer) + len(m.Ns) + len(m.Extra)
off := jump.To(last, m.Data)
if off == 0 {
isPseudo := m.isPseudo() - 1
arcount := setArcount(m, isPseudo)
if arcount == -1 {
return fmt.Errorf("%w: %s", ErrNoSIG0, "verify")
}
m.Data = m.Data[:off]
arcount := uint16(len(m.Extra))
pack.Uint16(arcount, m.Data, msgArcount) // decrease additional section count, because we removed the TSIG
err := k.Verify(s, m.Data, *options)
pack.Uint16(arcount+1, m.Data, msgArcount) // restore arcount
pack.Uint16(uint16(arcount+1), m.Data, msgArcount) // restore arcount
return err
}
+27 -17
View File
@@ -37,16 +37,12 @@ func TSIGSign(m *Msg, k TSIGSigner, options *TSIGOption) error {
return fmt.Errorf("%w: %s", ErrNoTSIG, "sign")
}
last := len(m.Ns) + len(m.Answer) + len(m.Extra) // skip question as 0th, is the first after question
off := jump.To(last, m.Data)
if off == 0 {
isPseudo := m.isPseudo() - 1 // should be 1 (only the tsig) or 2 (opt + tsig)
arcount := setArcount(m, isPseudo)
if arcount == -1 {
return fmt.Errorf("%w: %s", ErrNoTSIG, "sign")
}
m.Data = m.Data[:off]
arcount := uint16(len(m.Extra))
pack.Uint16(arcount, m.Data, msgArcount) // decrease additional section count, because we removed the TSIG
macbuf, err := t.mac(m, *options)
if err != nil {
return err
@@ -65,7 +61,8 @@ func TSIGSign(m *Msg, k TSIGSigner, options *TSIGOption) error {
}
tbuf := make([]byte, t.Len())
if _, off, err = packRR(t, tbuf, 0, nil); err != nil {
_, off, err := packRR(t, tbuf, 0, nil)
if err != nil {
return err
}
tbuf = tbuf[:off]
@@ -73,7 +70,7 @@ func TSIGSign(m *Msg, k TSIGSigner, options *TSIGOption) error {
m.Data = append(m.Data, tbuf...)
options.RequestMAC = t.MAC
pack.Uint16(arcount+1, m.Data, msgArcount) // and +1 after we done for the new and improved TSIG that is added
pack.Uint16(uint16(arcount+1), m.Data, msgArcount) // and +1 after we done for the new and improved TSIG that is added
return nil
}
@@ -100,16 +97,12 @@ func TSIGVerify(m *Msg, k TSIGSigner, options *TSIGOption) error {
return ErrSig
}
last := len(m.Answer) + len(m.Ns) + len(m.Extra)
off := jump.To(last, m.Data)
if off == 0 {
isPseudo := m.isPseudo() - 1
arcount := setArcount(m, isPseudo)
if arcount == -1 {
return fmt.Errorf("%w: %s", ErrNoTSIG, "verify")
}
m.Data = m.Data[:off]
arcount := uint16(len(m.Extra))
pack.Uint16(arcount, m.Data, msgArcount) // decrease additional section count, because we removed the TSIG
// restore msg ID, as the origID is used to calculate hash, and set in m.Data.
pack.Uint16(t.OrigID, m.Data, 0)
defer func() {
@@ -135,7 +128,7 @@ func TSIGVerify(m *Msg, k TSIGSigner, options *TSIGOption) error {
if uint64(t.Fudge) < fudge {
return ErrTime
}
pack.Uint16(arcount+1, m.Data, msgArcount) // restore arcount
pack.Uint16(uint16(arcount+1), m.Data, msgArcount) // restore arcount
options.RequestMAC = t.MAC
return nil
}
@@ -164,3 +157,20 @@ func hasTSIG(m *Msg) *TSIG {
t, _ := m.Pseudo[lp-1].(*TSIG)
return t
}
func setArcount(m *Msg, isPseudo int) int {
last := len(m.Ns) + len(m.Answer) + len(m.Extra) + isPseudo // skip question as 0th, is the first after question
off := jump.To(last, m.Data)
if off == 0 {
return -1
}
m.Data = m.Data[:off]
arcount := len(m.Extra)
if isPseudo == 1 {
arcount++
}
pack.Uint16(uint16(arcount), m.Data, msgArcount) // decrease additional section count, because we removed the TSIG/SIG
return arcount
}
+1 -1
View File
@@ -3,7 +3,7 @@ package dns
import "fmt"
// Version is current version of this library.
var Version = v{0, 6, 57}
var Version = v{0, 6, 64}
type v struct {
Major, Minor, Patch int
+4 -4
View File
@@ -9,8 +9,12 @@ import (
func compare(a, b RR) int {
switch x := a.(type) {
case *TSIG:
return x.compare(b)
case *DELEG:
return x.compare(b)
case *OPT:
return x.compare(b)
case *NSEC3:
return x.compare(b)
case *DNSKEY:
@@ -161,8 +165,6 @@ func compare(a, b RR) int {
return x.compare(b)
case *ZONEMD:
return x.compare(b)
case *OPT:
return x.compare(b)
case *RESINFO:
return x.compare(b)
case *SVCB:
@@ -179,8 +181,6 @@ func compare(a, b RR) int {
return x.compare(b)
case *IXFR:
return x.compare(b)
case *TSIG:
return x.compare(b)
}
if x, ok := a.(Comparer); ok {
return x.Compare(b)
+8 -8
View File
@@ -10,8 +10,12 @@ import (
func zpack(rr RR, msg []byte, off int, compression map[string]uint16) (int, error) {
switch x := rr.(type) {
case *TSIG:
return x.pack(msg, off, compression)
case *DELEG:
return x.pack(msg, off, compression)
case *OPT:
return x.pack(msg, off, compression)
case *NSEC3:
return x.pack(msg, off, compression)
case *DNSKEY:
@@ -162,8 +166,6 @@ func zpack(rr RR, msg []byte, off int, compression map[string]uint16) (int, erro
return x.pack(msg, off, compression)
case *ZONEMD:
return x.pack(msg, off, compression)
case *OPT:
return x.pack(msg, off, compression)
case *RESINFO:
return x.pack(msg, off, compression)
case *SVCB:
@@ -180,8 +182,6 @@ func zpack(rr RR, msg []byte, off int, compression map[string]uint16) (int, erro
return x.pack(msg, off, compression)
case *IXFR:
return x.pack(msg, off, compression)
case *TSIG:
return x.pack(msg, off, compression)
}
// if here, we don't have the RR in our pkg, check if it does Packer.
if x, ok := rr.(Packer); ok {
@@ -192,8 +192,12 @@ func zpack(rr RR, msg []byte, off int, compression map[string]uint16) (int, erro
func zunpack(rr RR, data cryptobyte.String, msgBuf []byte) error {
switch x := rr.(type) {
case *TSIG:
return x.unpack(data, msgBuf)
case *DELEG:
return x.unpack(data, msgBuf)
case *OPT:
return x.unpack(data, msgBuf)
case *NSEC3:
return x.unpack(data, msgBuf)
case *DNSKEY:
@@ -344,8 +348,6 @@ func zunpack(rr RR, data cryptobyte.String, msgBuf []byte) error {
return x.unpack(data, msgBuf)
case *ZONEMD:
return x.unpack(data, msgBuf)
case *OPT:
return x.unpack(data, msgBuf)
case *RESINFO:
return x.unpack(data, msgBuf)
case *SVCB:
@@ -362,8 +364,6 @@ func zunpack(rr RR, data cryptobyte.String, msgBuf []byte) error {
return x.unpack(data, msgBuf)
case *IXFR:
return x.unpack(data, msgBuf)
case *TSIG:
return x.unpack(data, msgBuf)
}
// if here, we don't have the RR in our pkg, check if it does Packer.
if x, ok := rr.(Packer); ok {
+4 -4
View File
@@ -7,8 +7,12 @@ import "codeberg.org/miekg/dns/internal/dnslex"
func parse(rr RR, c *dnslex.Lexer, o string) error {
switch x := rr.(type) {
case *TSIG:
return x.parse(c, o)
case *DELEG:
return x.parse(c, o)
case *OPT:
return x.parse(c, o)
case *NSEC3:
return x.parse(c, o)
case *DNSKEY:
@@ -159,8 +163,6 @@ func parse(rr RR, c *dnslex.Lexer, o string) error {
return x.parse(c, o)
case *ZONEMD:
return x.parse(c, o)
case *OPT:
return x.parse(c, o)
case *RESINFO:
return x.parse(c, o)
case *SVCB:
@@ -177,8 +179,6 @@ func parse(rr RR, c *dnslex.Lexer, o string) error {
return x.parse(c, o)
case *IXFR:
return x.parse(c, o)
case *TSIG:
return x.parse(c, o)
case *ZONEVERSION:
return x.parse(c, o)
case *EDE:
+10 -10
View File
@@ -2,7 +2,9 @@
package dns
func (rr *TSIG) Header() *Header { return &rr.Hdr }
func (rr *DELEG) Header() *Header { return &rr.Hdr }
func (rr *OPT) Header() *Header { return &rr.Hdr }
func (rr *NSEC3) Header() *Header { return &rr.Hdr }
func (rr *DNSKEY) Header() *Header { return &rr.Hdr }
func (rr *DS) Header() *Header { return &rr.Hdr }
@@ -78,7 +80,6 @@ func (rr *NIMLOC) Header() *Header { return &rr.Hdr }
func (rr *OPENPGPKEY) Header() *Header { return &rr.Hdr }
func (rr *CSYNC) Header() *Header { return &rr.Hdr }
func (rr *ZONEMD) Header() *Header { return &rr.Hdr }
func (rr *OPT) Header() *Header { return &rr.Hdr }
func (rr *RESINFO) Header() *Header { return &rr.Hdr }
func (rr *SVCB) Header() *Header { return &rr.Hdr }
func (rr *HTTPS) Header() *Header { return &rr.Hdr }
@@ -87,7 +88,6 @@ func (rr *DSYNC) Header() *Header { return &rr.Hdr }
func (rr *ANY) Header() *Header { return &rr.Hdr }
func (rr *AXFR) Header() *Header { return &rr.Hdr }
func (rr *IXFR) Header() *Header { return &rr.Hdr }
func (rr *TSIG) Header() *Header { return &rr.Hdr }
// TypeToRR is a map of constructors for each RR type.
// Basic usage if you have a type code and want to create a [RR]:
@@ -95,7 +95,9 @@ func (rr *TSIG) Header() *Header { return &rr.Hdr }
// rr := dns.TypeToRR[dns.TypeMX]()
// fmt.Println(rr) // "0 CLASS0 MX 0"
var TypeToRR = map[uint16]func() RR{
TypeTSIG: func() RR { return new(TSIG) },
TypeDELEG: func() RR { return new(DELEG) },
TypeOPT: func() RR { return new(OPT) },
TypeNSEC3: func() RR { return new(NSEC3) },
TypeDNSKEY: func() RR { return new(DNSKEY) },
TypeDS: func() RR { return new(DS) },
@@ -170,7 +172,6 @@ var TypeToRR = map[uint16]func() RR{
TypeOPENPGPKEY: func() RR { return new(OPENPGPKEY) },
TypeCSYNC: func() RR { return new(CSYNC) },
TypeZONEMD: func() RR { return new(ZONEMD) },
TypeOPT: func() RR { return new(OPT) },
TypeRESINFO: func() RR { return new(RESINFO) },
TypeSVCB: func() RR { return new(SVCB) },
TypeHTTPS: func() RR { return new(HTTPS) },
@@ -179,14 +180,17 @@ var TypeToRR = map[uint16]func() RR{
TypeANY: func() RR { return new(ANY) },
TypeAXFR: func() RR { return new(AXFR) },
TypeIXFR: func() RR { return new(IXFR) },
TypeTSIG: func() RR { return new(TSIG) },
}
// RRToType is the reverse of TypeToRR.
func RRToType(rr RR) uint16 {
switch rr.(type) {
case *TSIG:
return TypeTSIG
case *DELEG:
return TypeDELEG
case *OPT:
return TypeOPT
case *NSEC3:
return TypeNSEC3
case *DNSKEY:
@@ -335,8 +339,6 @@ func RRToType(rr RR) uint16 {
return TypeCSYNC
case *ZONEMD:
return TypeZONEMD
case *OPT:
return TypeOPT
case *RESINFO:
return TypeRESINFO
case *SVCB:
@@ -353,8 +355,6 @@ func RRToType(rr RR) uint16 {
return TypeAXFR
case *IXFR:
return TypeIXFR
case *TSIG:
return TypeTSIG
}
if x, ok := rr.(Typer); ok {
return x.Type()
@@ -365,7 +365,9 @@ func RRToType(rr RR) uint16 {
// TypeToString is a map of strings for each RR type.
// See [codeberg.org/miekg/dns/dnsutil.TypeToString] for a function that works better when the type is unknown.
var TypeToString = map[uint16]string{
TypeTSIG: "TSIG",
TypeDELEG: "DELEG",
TypeOPT: "OPT",
TypeNSEC3: "NSEC3",
TypeDNSKEY: "DNSKEY",
TypeDS: "DS",
@@ -439,7 +441,6 @@ var TypeToString = map[uint16]string{
TypeOPENPGPKEY: "OPENPGPKEY",
TypeCSYNC: "CSYNC",
TypeZONEMD: "ZONEMD",
TypeOPT: "OPT",
TypeRESINFO: "RESINFO",
TypeSVCB: "SVCB",
TypeHTTPS: "HTTPS",
@@ -448,6 +449,5 @@ var TypeToString = map[uint16]string{
TypeANY: "ANY",
TypeAXFR: "AXFR",
TypeIXFR: "IXFR",
TypeTSIG: "TSIG",
TypeNSAPPTR: "NSAP-PTR",
}
+3 -1
View File
@@ -145,7 +145,9 @@ var frameParsers = [...]frameParser{
func typeFrameParser(t FrameType) frameParser {
if int(t) < len(frameParsers) {
return frameParsers[t]
if f := frameParsers[t]; f != nil {
return f
}
}
return parseUnknownFrame
}
+1 -1
View File
@@ -2,6 +2,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build darwin && go1.12
//go:build darwin
// This exists solely so we can linkname in symbols from syscall.
+3 -3
View File
@@ -1,4 +1,4 @@
# codeberg.org/miekg/dns v0.6.57
# codeberg.org/miekg/dns v0.6.64
## explicit; go 1.25.0
codeberg.org/miekg/dns
codeberg.org/miekg/dns/deleg
@@ -143,8 +143,8 @@ golang.org/x/crypto/salsa20/salsa
# golang.org/x/mod v0.33.0
## explicit; go 1.24.0
golang.org/x/mod/semver
# golang.org/x/net v0.50.0
## explicit; go 1.24.0
# golang.org/x/net v0.51.0
## explicit; go 1.25.0
golang.org/x/net/bpf
golang.org/x/net/http/httpguts
golang.org/x/net/http2