rust-dnsbox/lib/dnsbox-base/src/common_types/sig.rs

53 lines
1.4 KiB
Rust

use bytes::Bytes;
use errors::*;
use failure::Fail;
use ser::packet::{DnsPacketData, DnsPacketWriteContext};
use ser::text::{DnsTextData, DnsTextFormatter, DnsTextContext, next_field};
use std::fmt;
use std::io::Cursor;
/// Optional TTL
///
/// Always present in wire format, but optional in zone; defaults to TTL
/// of the RR.
///
/// Must be followed by a field that doesn't accept any unsigned 32-bit
/// integer as text representation (like `TimeStrict` for `SIG`).
///
/// If field is missing in zone representation the context must provide
/// a TTL.
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct OptionalTTL(pub u32);
impl DnsPacketData for OptionalTTL {
fn deserialize(data: &mut Cursor<Bytes>) -> Result<Self> {
Ok(OptionalTTL(DnsPacketData::deserialize(data)?))
}
fn serialize(&self, context: &mut DnsPacketWriteContext, packet: &mut Vec<u8>) -> Result<()> {
self.0.serialize(context, packet)
}
}
impl DnsTextData for OptionalTTL {
fn dns_parse(context: &DnsTextContext, data: &mut &str) -> ::errors::Result<Self> {
let mut data_found = *data;
let field = next_field(&mut data_found)?;
match field.parse::<u32>() {
Ok(ttl) => {
*data = data_found;
Ok(OptionalTTL(ttl))
},
Err(e) => {
Ok(OptionalTTL(context.last_ttl()
.ok_or_else(|| e.context("TTL not available in context, failed parsing optional TTL"))?
))
},
}
}
fn dns_format(&self, f: &mut DnsTextFormatter) -> fmt::Result {
self.0.dns_format(f)
}
}