Avoid overriding $RUSTFLAGS when needed for rustc 1.63
[dnssec-prover] / src / rr.rs
index 253c412481cd6db8b8059413c340f05b0ba84e3a..0733dd2fa2897d79836a5632e4d5c9d33d7df93b 100644 (file)
--- a/src/rr.rs
+++ b/src/rr.rs
@@ -41,7 +41,7 @@ impl Name {
                } else if n == 0 {
                        Some(".")
                } else {
-                       self.as_str().splitn(labels as usize - n as usize + 1, ".").last()
+                       self.as_str().splitn(labels as usize - n as usize + 1, '.').last()
                }
        }
 }
@@ -61,7 +61,7 @@ impl TryFrom<String> for Name {
                if *s.as_bytes().last().unwrap_or(&0) != b"."[0] { return Err(()); }
                if s.len() > 255 { return Err(()); }
                if s.chars().any(|c| !c.is_ascii_graphic() || c == '"') { return Err(()); }
-               for label in s.split(".") {
+               for label in s.split('.') {
                        if label.len() > 63 { return Err(()); }
                }
 
@@ -157,7 +157,7 @@ impl RR {
                        RR::NSec3(_) => NSec3::TYPE,
                }
        }
-       fn write_u16_len_prefixed_data(&self, out: &mut Vec<u8>) {
+       fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
                match self {
                        RR::A(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
                        RR::AAAA(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
@@ -209,9 +209,25 @@ pub(crate) trait StaticRecord : Ord + Sized {
        const TYPE: u16;
        fn name(&self) -> &Name;
        fn json(&self) -> String;
-       fn write_u16_len_prefixed_data(&self, out: &mut Vec<u8>);
+       fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W);
        fn read_from_data(name: Name, data: &[u8], wire_packet: &[u8]) -> Result<Self, ()>;
 }
+
+/// A record that can be written to a generic [`Writer`]
+pub(crate) trait WriteableRecord : Record {
+       fn serialize_u16_len_prefixed<W: Writer>(&self, out: &mut W);
+}
+impl<RR: StaticRecord> WriteableRecord for RR {
+       fn serialize_u16_len_prefixed<W: Writer>(&self, out: &mut W) {
+               RR::write_u16_len_prefixed_data(self, out)
+       }
+}
+impl WriteableRecord for RR {
+       fn serialize_u16_len_prefixed<W: Writer>(&self, out: &mut W) {
+               RR::write_u16_len_prefixed_data(self, out)
+       }
+}
+
 /// A trait describing a resource record (including the [`RR`] enum).
 pub trait Record : Ord {
        /// The resource record type, as maintained by IANA.
@@ -243,7 +259,7 @@ impl Record for RR {
        }
 }
 
-#[derive(Debug, Clone, PartialEq, Eq, Ord)]
+#[derive(Debug, Clone, PartialEq, Eq)]
 /// A text resource record, containing arbitrary text data
 pub struct Txt {
        /// The name this record is at.
@@ -256,9 +272,9 @@ pub struct Txt {
 }
 /// The wire type for TXT records
 pub const TXT_TYPE: u16 = 16;
-impl PartialOrd for Txt {
-       fn partial_cmp(&self, o: &Txt) -> Option<Ordering> {
-               Some(self.name.cmp(&o.name)
+impl Ord for Txt {
+       fn cmp(&self, o: &Txt) -> Ordering {
+               self.name.cmp(&o.name)
                        .then_with(|| {
                                // Compare in wire encoding form, i.e. compare in 255-byte chunks
                                for i in 1..(self.data.len() / 255) + 2 {
@@ -270,9 +286,12 @@ impl PartialOrd for Txt {
                                        if !slice_cmp.is_eq() { return slice_cmp; }
                                }
                                Ordering::Equal
-                       }))
+                       })
        }
 }
+impl PartialOrd for Txt {
+       fn partial_cmp(&self, o: &Txt) -> Option<Ordering> { Some(self.cmp(o)) }
+}
 impl StaticRecord for Txt {
        const TYPE: u16 = TXT_TYPE;
        fn name(&self) -> &Name { &self.name }
@@ -295,18 +314,18 @@ impl StaticRecord for Txt {
                debug_assert!(data.is_empty());
                Ok(Txt { name, data: parsed_data })
        }
-       fn write_u16_len_prefixed_data(&self, out: &mut Vec<u8>) {
+       fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
                let len = (self.data.len() + (self.data.len() + 254) / 255) as u16;
-               out.extend_from_slice(&len.to_be_bytes());
+               out.write(&len.to_be_bytes());
 
                let mut data_write = &self.data[..];
-               out.extend_from_slice(&[data_write.len().try_into().unwrap_or(255)]);
+               out.write(&[data_write.len().try_into().unwrap_or(255)]);
                while !data_write.is_empty() {
                        let split_pos = core::cmp::min(255, data_write.len());
-                       out.extend_from_slice(&data_write[..split_pos]);
+                       out.write(&data_write[..split_pos]);
                        data_write = &data_write[split_pos..];
                        if !data_write.is_empty() {
-                               out.extend_from_slice(&[data_write.len().try_into().unwrap_or(255)]);
+                               out.write(&[data_write.len().try_into().unwrap_or(255)]);
                        }
                }
        }
@@ -355,11 +374,11 @@ impl StaticRecord for TLSA {
                        data_ty: read_u8(&mut data)?, data: data.to_vec(),
                })
        }
-       fn write_u16_len_prefixed_data(&self, out: &mut Vec<u8>) {
+       fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
                let len = 3 + self.data.len();
-               out.extend_from_slice(&(len as u16).to_be_bytes());
-               out.extend_from_slice(&[self.cert_usage, self.selector, self.data_ty]);
-               out.extend_from_slice(&self.data);
+               out.write(&(len as u16).to_be_bytes());
+               out.write(&[self.cert_usage, self.selector, self.data_ty]);
+               out.write(&self.data);
        }
 }
 
@@ -385,9 +404,9 @@ impl StaticRecord for CName {
                debug_assert!(data.is_empty());
                Ok(res)
        }
-       fn write_u16_len_prefixed_data(&self, out: &mut Vec<u8>) {
+       fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
                let len: u16 = name_len(&self.canonical_name);
-               out.extend_from_slice(&len.to_be_bytes());
+               out.write(&len.to_be_bytes());
                write_name(out, &self.canonical_name);
        }
 }
@@ -416,9 +435,9 @@ impl StaticRecord for DName {
                debug_assert!(data.is_empty());
                Ok(res)
        }
-       fn write_u16_len_prefixed_data(&self, out: &mut Vec<u8>) {
+       fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
                let len: u16 = name_len(&self.delegation_name);
-               out.extend_from_slice(&len.to_be_bytes());
+               out.write(&len.to_be_bytes());
                write_name(out, &self.delegation_name);
        }
 }
@@ -460,13 +479,13 @@ impl StaticRecord for DnsKey {
                        alg: read_u8(&mut data)?, pubkey: data.to_vec(),
                })
        }
-       fn write_u16_len_prefixed_data(&self, out: &mut Vec<u8>) {
+       fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
                let len = 2 + 1 + 1 + self.pubkey.len();
-               out.extend_from_slice(&(len as u16).to_be_bytes());
-               out.extend_from_slice(&self.flags.to_be_bytes());
-               out.extend_from_slice(&self.protocol.to_be_bytes());
-               out.extend_from_slice(&self.alg.to_be_bytes());
-               out.extend_from_slice(&self.pubkey);
+               out.write(&(len as u16).to_be_bytes());
+               out.write(&self.flags.to_be_bytes());
+               out.write(&self.protocol.to_be_bytes());
+               out.write(&self.alg.to_be_bytes());
+               out.write(&self.pubkey);
        }
 }
 impl DnsKey {
@@ -531,13 +550,13 @@ impl StaticRecord for DS {
                        digest_type: read_u8(&mut data)?, digest: data.to_vec(),
                })
        }
-       fn write_u16_len_prefixed_data(&self, out: &mut Vec<u8>) {
+       fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
                let len = 2 + 1 + 1 + self.digest.len();
-               out.extend_from_slice(&(len as u16).to_be_bytes());
-               out.extend_from_slice(&self.key_tag.to_be_bytes());
-               out.extend_from_slice(&self.alg.to_be_bytes());
-               out.extend_from_slice(&self.digest_type.to_be_bytes());
-               out.extend_from_slice(&self.digest);
+               out.write(&(len as u16).to_be_bytes());
+               out.write(&self.key_tag.to_be_bytes());
+               out.write(&self.alg.to_be_bytes());
+               out.write(&self.digest_type.to_be_bytes());
+               out.write(&self.digest);
        }
 }
 
@@ -610,18 +629,18 @@ impl StaticRecord for RRSig {
                        signature: data.to_vec(),
                })
        }
-       fn write_u16_len_prefixed_data(&self, out: &mut Vec<u8>) {
+       fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
                let len = 2 + 1 + 1 + 4*3 + 2 + name_len(&self.key_name) + self.signature.len() as u16;
-               out.extend_from_slice(&len.to_be_bytes());
-               out.extend_from_slice(&self.ty.to_be_bytes());
-               out.extend_from_slice(&self.alg.to_be_bytes());
-               out.extend_from_slice(&self.labels.to_be_bytes());
-               out.extend_from_slice(&self.orig_ttl.to_be_bytes());
-               out.extend_from_slice(&self.expiration.to_be_bytes());
-               out.extend_from_slice(&self.inception.to_be_bytes());
-               out.extend_from_slice(&self.key_tag.to_be_bytes());
+               out.write(&len.to_be_bytes());
+               out.write(&self.ty.to_be_bytes());
+               out.write(&self.alg.to_be_bytes());
+               out.write(&self.labels.to_be_bytes());
+               out.write(&self.orig_ttl.to_be_bytes());
+               out.write(&self.expiration.to_be_bytes());
+               out.write(&self.inception.to_be_bytes());
+               out.write(&self.key_tag.to_be_bytes());
                write_name(out, &self.key_name);
-               out.extend_from_slice(&self.signature);
+               out.write(&self.signature);
        }
 }
 
@@ -632,12 +651,24 @@ pub struct NSecTypeMask([u8; 8192]);
 impl NSecTypeMask {
        /// Constructs a new, empty, type mask.
        pub fn new() -> Self { Self([0; 8192]) }
+       /// Builds a new type mask with the given types set
+       pub fn from_types(types: &[u16]) -> Self {
+               let mut flags = [0; 8192];
+               for t in types {
+                       flags[*t as usize >> 3] |= 1 << (7 - (*t as usize % 8));
+               }
+               let res = Self(flags);
+               for t in types {
+                       debug_assert!(res.contains_type(*t));
+               }
+               res
+       }
        /// Checks if the given type (from [`Record::ty`]) is set, indicating a record of this type
        /// exists.
        pub fn contains_type(&self, ty: u16) -> bool {
                let f = self.0[(ty >> 3) as usize];
                // DNSSEC's bit fields are in wire order, so the high bit is type 0, etc.
-               f & (1 << (7 - (ty & 3))) != 0
+               f & (1 << (7 - (ty % 8))) != 0
        }
        fn write_json(&self, s: &mut String) {
                *s += "[";
@@ -696,9 +727,9 @@ impl StaticRecord for NSec {
                debug_assert!(data.is_empty());
                Ok(res)
        }
-       fn write_u16_len_prefixed_data(&self, out: &mut Vec<u8>) {
+       fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
                let len = name_len(&self.next_name) + nsec_types_bitmap_len(&self.types.0);
-               out.extend_from_slice(&len.to_be_bytes());
+               out.write(&len.to_be_bytes());
                write_name(out, &self.next_name);
                write_nsec_types_bitmap(out, &self.types.0);
        }
@@ -754,17 +785,17 @@ impl StaticRecord for NSec3 {
                debug_assert!(data.is_empty());
                Ok(res)
        }
-       fn write_u16_len_prefixed_data(&self, out: &mut Vec<u8>) {
+       fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
                let len = 4 + 2 + self.salt.len() as u16 + self.next_name_hash.len() as u16 +
                        nsec_types_bitmap_len(&self.types.0);
-               out.extend_from_slice(&len.to_be_bytes());
-               out.extend_from_slice(&self.hash_algo.to_be_bytes());
-               out.extend_from_slice(&self.flags.to_be_bytes());
-               out.extend_from_slice(&self.hash_iterations.to_be_bytes());
-               out.extend_from_slice(&(self.salt.len() as u8).to_be_bytes());
-               out.extend_from_slice(&self.salt);
-               out.extend_from_slice(&(self.next_name_hash.len() as u8).to_be_bytes());
-               out.extend_from_slice(&self.next_name_hash);
+               out.write(&len.to_be_bytes());
+               out.write(&self.hash_algo.to_be_bytes());
+               out.write(&self.flags.to_be_bytes());
+               out.write(&self.hash_iterations.to_be_bytes());
+               out.write(&(self.salt.len() as u8).to_be_bytes());
+               out.write(&self.salt);
+               out.write(&(self.next_name_hash.len() as u8).to_be_bytes());
+               out.write(&self.next_name_hash);
                write_nsec_types_bitmap(out, &self.types.0);
        }
 }
@@ -788,12 +819,12 @@ impl StaticRecord for A {
        fn read_from_data(name: Name, data: &[u8], _wire_packet: &[u8]) -> Result<Self, ()> {
                if data.len() != 4 { return Err(()); }
                let mut address = [0; 4];
-               address.copy_from_slice(&data);
+               address.copy_from_slice(data);
                Ok(A { name, address })
        }
-       fn write_u16_len_prefixed_data(&self, out: &mut Vec<u8>) {
-               out.extend_from_slice(&4u16.to_be_bytes());
-               out.extend_from_slice(&self.address);
+       fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
+               out.write(&4u16.to_be_bytes());
+               out.write(&self.address);
        }
 }
 
@@ -816,12 +847,12 @@ impl StaticRecord for AAAA {
        fn read_from_data(name: Name, data: &[u8], _wire_packet: &[u8]) -> Result<Self, ()> {
                if data.len() != 16 { return Err(()); }
                let mut address = [0; 16];
-               address.copy_from_slice(&data);
+               address.copy_from_slice(data);
                Ok(AAAA { name, address })
        }
-       fn write_u16_len_prefixed_data(&self, out: &mut Vec<u8>) {
-               out.extend_from_slice(&16u16.to_be_bytes());
-               out.extend_from_slice(&self.address);
+       fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
+               out.write(&16u16.to_be_bytes());
+               out.write(&self.address);
        }
 }
 
@@ -849,8 +880,8 @@ impl StaticRecord for NS {
                debug_assert!(data.is_empty());
                Ok(res)
        }
-       fn write_u16_len_prefixed_data(&self, out: &mut Vec<u8>) {
-               out.extend_from_slice(&name_len(&self.name_server).to_be_bytes());
+       fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
+               out.write(&name_len(&self.name_server).to_be_bytes());
                write_name(out, &self.name_server);
        }
 }