AXFRDDNS: Adopt diff2 in compatibility mode (#1905)

This commit is contained in:
Tom Limoncelli 2023-01-03 13:06:21 -05:00 committed by GitHub
parent a498679c72
commit 8f8c0abaf3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -351,109 +351,109 @@ func (c *axfrddnsProvider) GetDomainCorrections(dc *models.DomainConfig) ([]*mod
txtutil.SplitSingleLongTxt(dc.Records) // Autosplit long TXT records
var corrections []*models.Correction
if !diff2.EnableDiff2 || true { // Remove "|| true" when diff2 version arrives
var create, del, mod diff.Changeset
if !diff2.EnableDiff2 {
differ := diff.New(dc)
_, create, del, mod, err := differ.IncrementalDiff(foundRecords)
if err != nil {
return nil, err
}
buf := &bytes.Buffer{}
// Print a list of changes. Generate an actual change that is the zone
changes := false
for _, i := range create {
changes = true
fmt.Fprintln(buf, i)
}
for _, i := range del {
changes = true
fmt.Fprintln(buf, i)
}
for _, i := range mod {
changes = true
fmt.Fprintln(buf, i)
}
msg := fmt.Sprintf("DDNS UPDATES to '%s' (primary master: '%s'). Changes:\n%s", dc.Name, c.master, buf)
if changes {
corrections = append(corrections,
&models.Correction{
Msg: msg,
F: func() error {
// An RFC2136-compliant server must silently ignore an
// update that inserts a non-CNAME RRset when a CNAME RR
// with the same name is present in the zone (and
// vice-versa). Therefore we prefer to first remove records
// and then insert new ones.
//
// Compliant servers must also silently ignore an update
// that removes the last NS record of a zone. Therefore we
// don't want to remove all NS records before inserting a
// new one. For the particular case of NS record, we prefer
// to insert new records before ot remove old ones.
//
// This remarks does not apply for "modified" NS records, as
// updates are processed one-by-one.
//
// This provider does not allow modifying the TTL of an NS
// record in a zone that defines only one NS. That would
// would require removing the single NS record, before
// adding the new one. But who does that anyway?
update := new(dns.Msg)
update.SetUpdate(dc.Name + ".")
update.Id = uint16(c.rand.Intn(math.MaxUint16))
for _, c := range create {
if c.Desired.Type == "NS" {
update.Insert([]dns.RR{c.Desired.ToRR()})
}
}
for _, c := range del {
update.Remove([]dns.RR{c.Existing.ToRR()})
}
for _, c := range mod {
update.Remove([]dns.RR{c.Existing.ToRR()})
update.Insert([]dns.RR{c.Desired.ToRR()})
}
for _, c := range create {
if c.Desired.Type != "NS" {
update.Insert([]dns.RR{c.Desired.ToRR()})
}
}
client := new(dns.Client)
client.Net = c.updateMode
client.Timeout = dnsTimeout
if c.updateKey != nil {
client.TsigSecret =
map[string]string{c.updateKey.id: c.updateKey.secret}
update.SetTsig(c.updateKey.id, c.updateKey.algo, 300, time.Now().Unix())
if c.updateKey.algo == dns.HmacMD5 {
client.TsigProvider = md5Provider(c.updateKey.secret)
}
}
msg, _, err := client.Exchange(update, c.master)
if err != nil {
return err
}
if msg.MsgHdr.Rcode != 0 {
return fmt.Errorf("[Error] AXFRDDNS: nameserver refused to update the zone: %s (%d)",
dns.RcodeToString[msg.MsgHdr.Rcode],
msg.MsgHdr.Rcode)
}
return nil
},
})
}
return corrections, nil
_, create, del, mod, err = differ.IncrementalDiff(foundRecords)
} else {
differ := diff.NewCompat(dc)
_, create, del, mod, err = differ.IncrementalDiff(foundRecords)
}
if err != nil {
return nil, err
}
// Insert Future diff2 version here.
buf := &bytes.Buffer{}
// Print a list of changes. Generate an actual change that is the zone
changes := false
for _, i := range create {
changes = true
fmt.Fprintln(buf, i)
}
for _, i := range del {
changes = true
fmt.Fprintln(buf, i)
}
for _, i := range mod {
changes = true
fmt.Fprintln(buf, i)
}
msg := fmt.Sprintf("DDNS UPDATES to '%s' (primary master: '%s'). Changes:\n%s", dc.Name, c.master, buf)
if changes {
corrections = append(corrections,
&models.Correction{
Msg: msg,
F: func() error {
// An RFC2136-compliant server must silently ignore an
// update that inserts a non-CNAME RRset when a CNAME RR
// with the same name is present in the zone (and
// vice-versa). Therefore we prefer to first remove records
// and then insert new ones.
//
// Compliant servers must also silently ignore an update
// that removes the last NS record of a zone. Therefore we
// don't want to remove all NS records before inserting a
// new one. For the particular case of NS record, we prefer
// to insert new records before ot remove old ones.
//
// This remarks does not apply for "modified" NS records, as
// updates are processed one-by-one.
//
// This provider does not allow modifying the TTL of an NS
// record in a zone that defines only one NS. That would
// would require removing the single NS record, before
// adding the new one. But who does that anyway?
update := new(dns.Msg)
update.SetUpdate(dc.Name + ".")
update.Id = uint16(c.rand.Intn(math.MaxUint16))
for _, c := range create {
if c.Desired.Type == "NS" {
update.Insert([]dns.RR{c.Desired.ToRR()})
}
}
for _, c := range del {
update.Remove([]dns.RR{c.Existing.ToRR()})
}
for _, c := range mod {
update.Remove([]dns.RR{c.Existing.ToRR()})
update.Insert([]dns.RR{c.Desired.ToRR()})
}
for _, c := range create {
if c.Desired.Type != "NS" {
update.Insert([]dns.RR{c.Desired.ToRR()})
}
}
client := new(dns.Client)
client.Net = c.updateMode
client.Timeout = dnsTimeout
if c.updateKey != nil {
client.TsigSecret =
map[string]string{c.updateKey.id: c.updateKey.secret}
update.SetTsig(c.updateKey.id, c.updateKey.algo, 300, time.Now().Unix())
if c.updateKey.algo == dns.HmacMD5 {
client.TsigProvider = md5Provider(c.updateKey.secret)
}
}
msg, _, err := client.Exchange(update, c.master)
if err != nil {
return err
}
if msg.MsgHdr.Rcode != 0 {
return fmt.Errorf("[Error] AXFRDDNS: nameserver refused to update the zone: %s (%d)",
dns.RcodeToString[msg.MsgHdr.Rcode],
msg.MsgHdr.Rcode)
}
return nil
},
})
}
return corrections, nil