mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2025-09-12 16:14:42 +08:00
AXFRDDNS: Chunk large changes in multiple packets (#3732)
Co-authored-by: Mynacol <Mynacol@users.noreply.github.com> Co-authored-by: Tom Limoncelli <6293917+tlimoncelli@users.noreply.github.com>
This commit is contained in:
parent
89ac03faca
commit
c858e8fa57
1 changed files with 49 additions and 23 deletions
|
@ -366,8 +366,8 @@ func (c *axfrddnsProvider) GetZoneRecords(domain string, meta map[string]string)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildCorrection return a Correction for a given set of DDNS update and the corresponding message.
|
// BuildCorrection return a Correction for a given set of DDNS update and the corresponding message.
|
||||||
func (c *axfrddnsProvider) BuildCorrection(dc *models.DomainConfig, msgs []string, update *dns.Msg) *models.Correction {
|
func (c *axfrddnsProvider) BuildCorrection(dc *models.DomainConfig, msgs []string, updates []*dns.Msg) *models.Correction {
|
||||||
if update == nil {
|
if updates == nil {
|
||||||
return &models.Correction{
|
return &models.Correction{
|
||||||
Msg: fmt.Sprintf("DDNS UPDATES to '%s' (primary master: '%s'). Changes:\n%s", dc.Name, c.master, strings.Join(msgs, "\n")),
|
Msg: fmt.Sprintf("DDNS UPDATES to '%s' (primary master: '%s'). Changes:\n%s", dc.Name, c.master, strings.Join(msgs, "\n")),
|
||||||
}
|
}
|
||||||
|
@ -375,6 +375,7 @@ func (c *axfrddnsProvider) BuildCorrection(dc *models.DomainConfig, msgs []strin
|
||||||
return &models.Correction{
|
return &models.Correction{
|
||||||
Msg: fmt.Sprintf("DDNS UPDATES to '%s' (primary master: '%s'). Changes:\n%s", dc.Name, c.master, strings.Join(msgs, "\n")),
|
Msg: fmt.Sprintf("DDNS UPDATES to '%s' (primary master: '%s'). Changes:\n%s", dc.Name, c.master, strings.Join(msgs, "\n")),
|
||||||
F: func() error {
|
F: func() error {
|
||||||
|
for _, update := range updates {
|
||||||
update.Compress = true
|
update.Compress = true
|
||||||
client := new(dns.Client)
|
client := new(dns.Client)
|
||||||
client.Net = c.updateMode
|
client.Net = c.updateMode
|
||||||
|
@ -396,6 +397,7 @@ func (c *axfrddnsProvider) BuildCorrection(dc *models.DomainConfig, msgs []strin
|
||||||
dns.RcodeToString[msg.MsgHdr.Rcode],
|
dns.RcodeToString[msg.MsgHdr.Rcode],
|
||||||
msg.MsgHdr.Rcode)
|
msg.MsgHdr.Rcode)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
@ -453,8 +455,7 @@ func (c *axfrddnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, fo
|
||||||
|
|
||||||
var msgs []string
|
var msgs []string
|
||||||
var reports []string
|
var reports []string
|
||||||
update := new(dns.Msg)
|
updates := []*dns.Msg{}
|
||||||
update.SetUpdate(dc.Name + ".")
|
|
||||||
|
|
||||||
dummyNs1, err := dns.NewRR(dc.Name + ". IN NS dnscontrol.invalid.")
|
dummyNs1, err := dns.NewRR(dc.Name + ". IN NS dnscontrol.invalid.")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -473,6 +474,9 @@ func (c *axfrddnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, fo
|
||||||
return nil, 0, nil
|
return nil, 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update := new(dns.Msg)
|
||||||
|
update.SetUpdate(dc.Name + ".")
|
||||||
|
|
||||||
// A DNS server should silently ignore a DDNS update that removes
|
// A DNS server should silently ignore a DDNS update that removes
|
||||||
// the last NS record of a zone. Since modifying a record is
|
// the last NS record of a zone. Since modifying a record is
|
||||||
// implemented by successively a deletion of the old record and an
|
// implemented by successively a deletion of the old record and an
|
||||||
|
@ -491,6 +495,9 @@ func (c *axfrddnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, fo
|
||||||
update.Insert([]dns.RR{dummyNs1})
|
update.Insert([]dns.RR{dummyNs1})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i := 1
|
||||||
|
appendFinalUpdate := true
|
||||||
|
|
||||||
for _, change := range changes {
|
for _, change := range changes {
|
||||||
switch change.Type {
|
switch change.Type {
|
||||||
case diff2.DELETE:
|
case diff2.DELETE:
|
||||||
|
@ -523,16 +530,35 @@ func (c *axfrddnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, fo
|
||||||
case diff2.REPORT:
|
case diff2.REPORT:
|
||||||
reports = append(reports, change.Msgs...)
|
reports = append(reports, change.Msgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Chunk packets that exceed 2^14 = 16 KiB.
|
||||||
|
// A single DNS RR can theoretically reach 64 KiB, the total packet limit.
|
||||||
|
// This is a compromise, succeeding whenever RRs are not bigger than about 64 KiB - 16 KiB = 48 KiB.
|
||||||
|
if update.Len() >= 2<<13 {
|
||||||
|
updates = append(updates, update)
|
||||||
|
update = new(dns.Msg)
|
||||||
|
update.SetUpdate(dc.Name + ".")
|
||||||
|
appendFinalUpdate = false
|
||||||
|
i = 1
|
||||||
|
} else {
|
||||||
|
appendFinalUpdate = true
|
||||||
|
i++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if hasNSDeletion {
|
if hasNSDeletion {
|
||||||
update.Remove([]dns.RR{dummyNs2})
|
update.Remove([]dns.RR{dummyNs2})
|
||||||
|
appendFinalUpdate = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if appendFinalUpdate {
|
||||||
|
updates = append(updates, update)
|
||||||
}
|
}
|
||||||
|
|
||||||
returnValue := []*models.Correction{}
|
returnValue := []*models.Correction{}
|
||||||
|
|
||||||
if len(msgs) > 0 {
|
if len(msgs) > 0 {
|
||||||
returnValue = append(returnValue, c.BuildCorrection(dc, msgs, update))
|
returnValue = append(returnValue, c.BuildCorrection(dc, msgs, updates))
|
||||||
}
|
}
|
||||||
if len(reports) > 0 {
|
if len(reports) > 0 {
|
||||||
returnValue = append(returnValue, c.BuildCorrection(dc, reports, nil))
|
returnValue = append(returnValue, c.BuildCorrection(dc, reports, nil))
|
||||||
|
|
Loading…
Add table
Reference in a new issue