Skip to content

Commit

Permalink
Merge branch 'main' into service-layering
Browse files Browse the repository at this point in the history
  • Loading branch information
ximon18 committed Jul 24, 2024
2 parents 21a7f0b + e7816fc commit c6ec451
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 8 deletions.
6 changes: 6 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ New
* Added `FromStr` impls for `Rcode` and `OptRcode`. ([#357])
* Added `OptRcode::is_ext` to check if the code is an extended code.
([#358])
* Added `Rtype::is_glue` to check if the Rtype may be used as glue. ([#363])

Bug fixes

Expand All @@ -34,6 +35,11 @@ Unstable features
* The `CookiesMiddlewareProcessor` now allows requests with invalid
cookies to proceed if they are authenticated or not required to
authenticate. ([#336])
* Improved zonefile parsing error messages. ([#362]).
* `TryFrom<inplace::Zonefile> for Zonefile` now returns the set of
errors instead of logging and ignoring them. ([#362])
* Allow both glue (A/AAAA) and zone cuts at the same owner when zone
parsing. ([#363])

Other changes

Expand Down
10 changes: 10 additions & 0 deletions src/base/iana/rtype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,3 +425,13 @@ int_enum! {
}

int_enum_str_with_prefix!(Rtype, "TYPE", b"TYPE", u16, "unknown record type");

impl Rtype {
/// Returns true if this record type is a type used for Glue records.
///
/// See the definition of "glue" in [RFC
/// 9499](https://datatracker.ietf.org/doc/rfc9499/) Section 7 "Zones".
pub fn is_glue(&self) -> bool {
matches!(*self, Rtype::A | Rtype::AAAA)
}
}
30 changes: 22 additions & 8 deletions src/zonetree/parsed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,15 @@ impl Zonefile {
// parent zone and refer to a child zone, a DS record cannot
// therefore appear at the apex.
Rtype::NS | Rtype::DS if record.owner() != zone_apex => {
if let Some(normal_records) =
self.normal.get(record.owner())
{
let rtype = normal_records.sample_rtype().unwrap();
// Zone cuts can only be made when records already exist
// at the owner if all such records are glue (records that
// ease resolution of a zone cut name to an address).
let incompatible_normal_record = self
.normal
.get(record.owner())
.and_then(|normal| normal.first_non_glue());

if let Some((&rtype, _)) = incompatible_normal_record {
Err(RecordError::IllegalZoneCut(record, rtype))
} else if self.cnames.contains(record.owner()) {
Err(RecordError::IllegalZoneCut(record, Rtype::CNAME))
Expand Down Expand Up @@ -156,8 +161,15 @@ impl Zonefile {
}
}
_ => {
if let Some(zone_cut) = self.zone_cuts.get(record.owner())
// Only glue records can only be added at the same owner as
// a zone cut.
let incompatible_zone_cut = match record.rtype().is_glue()
{
true => None,
false => self.zone_cuts.get(record.owner()),
};

if let Some(zone_cut) = incompatible_zone_cut {
let rtype = zone_cut.sample_rtype().unwrap();
Err(RecordError::IllegalRecord(record, rtype))
} else if self.cnames.contains(record.owner()) {
Expand Down Expand Up @@ -380,9 +392,7 @@ impl Owners<Normal> {
// Now see if A/AAAA records exists for the name in
// this zone.
for (_rtype, rrset) in
normal.records.iter().filter(|(&rtype, _)| {
rtype == Rtype::A || rtype == Rtype::AAAA
})
normal.records.iter().filter(|(&rtype, _)| rtype.is_glue())
{
for rdata in rrset.data() {
let glue_record = StoredRecord::new(
Expand Down Expand Up @@ -439,6 +449,10 @@ impl Normal {
fn sample_rtype(&self) -> Option<Rtype> {
self.records.iter().next().map(|(&rtype, _)| rtype)
}

fn first_non_glue(&self) -> Option<(&Rtype, &Rrset)> {
self.records.iter().find(|(rtype, _)| !rtype.is_glue())
}
}

//------------ ZoneCut -------------------------------------------------------
Expand Down

0 comments on commit c6ec451

Please sign in to comment.