51 lines
1.5 KiB
Rust
51 lines
1.5 KiB
Rust
use crate::errors::*;
|
|
use crate::ser::packet::{DnsPacketData, DnsPacketWriteContext};
|
|
use crate::ser::text::{next_field, DnsTextContext, DnsTextData, DnsTextFormatter};
|
|
use bytes::Bytes;
|
|
use failure::Fail;
|
|
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) -> crate::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)
|
|
}
|
|
}
|