clean up RData a little

This commit is contained in:
Benjamin Fry 2016-05-10 22:11:45 -07:00
parent a3832ebfdd
commit 0a0b0d45d1
4 changed files with 58 additions and 121 deletions

View File

@ -18,6 +18,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Cleaned up authority upsert and lookup interfaces
- All authorities default to IN DNSCLASS now (none others currently supported)
- Cleaned up the Signer interface to support zone signing
- Simplified RData variant implementations
## 0.5.3 2016-04-07
### Fixed

View File

@ -16,7 +16,6 @@
use ::serialize::txt::*;
use ::serialize::binary::*;
use ::error::*;
use ::rr::record_data::RData;
// 3.3.10. NULL RDATA format (EXPERIMENTAL)
//
@ -80,7 +79,7 @@ pub fn emit(encoder: &mut BinEncoder, nil: &NULL) -> EncodeResult {
}
#[allow(unused)]
pub fn parse(tokens: &Vec<Token>) -> ParseResult<RData> {
pub fn parse(tokens: &Vec<Token>) -> ParseResult<NULL> {
unimplemented!()
}

View File

@ -178,56 +178,25 @@ pub fn read(decoder: &mut BinDecoder, rdata_length: u16) -> DecodeResult<OPT> {
let start_idx = decoder.index();
while rdata_length as usize > decoder.index() - start_idx {
//for _ in 0..rdata_length {
// if let Ok(byte) = decoder.pop() {
match state {
// TODO: can condense Code1/2 and Length1/2 into read_u16() calls.
OptReadState::ReadCode => {
state = OptReadState::Code{ code: (try!(decoder.read_u16())).into() };
},
OptReadState::Code{code} => {
let length: usize = try!(decoder.read_u16()) as usize;
state = OptReadState::Data{code:code, length: length, collected: Vec::<u8>::with_capacity(length) };
},
OptReadState::Data{code, length, mut collected } => {
collected.push(try!(decoder.pop()));
if length == collected.len() {
options.insert(code, (code, &collected as &[u8]).into());
state = OptReadState::ReadCode;
} else {
state = OptReadState::Data{code: code, length: length, collected: collected};
}
},
}
// match state {
// // TODO: can condense Code1/2 and Length1/2 into read_u16() calls.
// OptReadState::Code1 => {
// state = OptReadState::Code2{ high: byte };
// },
// OptReadState::Code2{high} => {
// state = OptReadState::Length1{ code: ((((high as u16) << 8) & 0xFF00u16) + (byte as u16 & 0x00FFu16)).into() };
// },
// OptReadState::Length1{code} => {
// state = OptReadState::Length2{ code: code, high: byte };
// },
// OptReadState::Length2{code, high } => {
// let length = (((high as usize) << 8) & 0xFF00usize) + (byte as usize & 0x00FFusize);
// state = OptReadState::Data{code:code, length: length, collected: Vec::<u8>::with_capacity(length) };
// },
// OptReadState::Data{code, length, mut collected } => {
// collected.push(byte);
// if length == collected.len() {
// options.insert(code, (code, &collected as &[u8]).into());
// state = OptReadState::Code1;
// } else {
// state = OptReadState::Data{code: code, length: length, collected: collected};
// }
// },
// }
// } else {
// return Err(DecodeError::EOF);
// }
match state {
// TODO: can condense Code1/2 and Length1/2 into read_u16() calls.
OptReadState::ReadCode => {
state = OptReadState::Code{ code: (try!(decoder.read_u16())).into() };
},
OptReadState::Code{code} => {
let length: usize = try!(decoder.read_u16()) as usize;
state = OptReadState::Data{code:code, length: length, collected: Vec::<u8>::with_capacity(length) };
},
OptReadState::Data{code, length, mut collected } => {
collected.push(try!(decoder.pop()));
if length == collected.len() {
options.insert(code, (code, &collected as &[u8]).into());
state = OptReadState::ReadCode;
} else {
state = OptReadState::Data{code: code, length: length, collected: collected};
}
},
}
}
if state != OptReadState::ReadCode {
@ -258,13 +227,6 @@ enum OptReadState {
Code{ code: EdnsCode }, // expect LSB for the opt code, store the high byte
Data { code: EdnsCode, length: usize, collected: Vec<u8> }, // expect the data for the option
}
// enum OptReadState {
// Code1, // expect MSB for the code
// Code2{ high: u8 }, // expect LSB for the opt code, store the high byte
// Length1{ code: EdnsCode }, // expect MSB for the length, store the option code
// Length2{ code: EdnsCode, high: u8 }, // expect the LSB for the length, store the LSB and code
// Data { code: EdnsCode, length: usize, collected: Vec<u8> }, // expect the data for the option
// }
#[derive(Hash, Debug, Copy, Clone, PartialEq, Eq)]
pub enum EdnsCode {

View File

@ -589,29 +589,31 @@ pub enum RData {
impl RData {
pub fn parse(record_type: RecordType, tokens: &Vec<Token>, origin: Option<&Name>) -> ParseResult<Self> {
match record_type {
RecordType::A => Ok(RData::A(try!(rdata::a::parse(tokens)))),
RecordType::AAAA => Ok(RData::AAAA(try!(rdata::aaaa::parse(tokens)))),
let rdata = match record_type {
RecordType::A => RData::A(try!(rdata::a::parse(tokens))),
RecordType::AAAA => RData::AAAA(try!(rdata::aaaa::parse(tokens))),
RecordType::ANY => panic!("parsing ANY doesn't make sense"),
RecordType::AXFR => panic!("parsing AXFR doesn't make sense"),
RecordType::CNAME => Ok(RData::CNAME(try!(rdata::name::parse(tokens, origin)))),
RecordType::CNAME => RData::CNAME(try!(rdata::name::parse(tokens, origin))),
RecordType::DNSKEY => panic!("DNSKEY should be dynamically generated"),
RecordType::DS => panic!("DS should be dynamically generated"),
RecordType::IXFR => panic!("parsing IXFR doesn't make sense"),
RecordType::MX => Ok(RData::MX(try!(rdata::mx::parse(tokens, origin)))),
RecordType::NULL => rdata::null::parse(tokens),
RecordType::NS => Ok(RData::NS(try!(rdata::name::parse(tokens, origin)))),
RecordType::MX => RData::MX(try!(rdata::mx::parse(tokens, origin))),
RecordType::NULL => RData::NULL(try!(rdata::null::parse(tokens))),
RecordType::NS => RData::NS(try!(rdata::name::parse(tokens, origin))),
RecordType::NSEC => panic!("NSEC should be dynamically generated"),
RecordType::NSEC3 => panic!("NSEC3 should be dynamically generated"),
RecordType::NSEC3PARAM => panic!("NSEC3PARAM should be dynamically generated"),
RecordType::OPT => panic!("parsing OPT doesn't make sense"),
RecordType::PTR => Ok(RData::PTR(try!(rdata::name::parse(tokens, origin)))),
RecordType::PTR => RData::PTR(try!(rdata::name::parse(tokens, origin))),
RecordType::RRSIG => panic!("RRSIG should be dynamically generated"),
RecordType::SIG => panic!("parsing SIG doesn't make sense"),
RecordType::SOA => Ok(RData::SOA(try!(rdata::soa::parse(tokens, origin)))),
RecordType::SRV => Ok(RData::SRV(try!(rdata::srv::parse(tokens, origin)))),
RecordType::TXT => Ok(RData::TXT(try!(rdata::txt::parse(tokens)))),
}
RecordType::SOA => RData::SOA(try!(rdata::soa::parse(tokens, origin))),
RecordType::SRV => RData::SRV(try!(rdata::srv::parse(tokens, origin))),
RecordType::TXT => RData::TXT(try!(rdata::txt::parse(tokens))),
};
Ok(rdata)
}
fn to_bytes(&self) -> Vec<u8> {
@ -623,59 +625,32 @@ impl RData {
buf
}
// pub fn len(&self) -> usize {
// match *self {
// RData::A{..} => 4 /* IPv4 u32 */,
// RData::AAAA{..} => 16 /* IPv6 u128 */,
// RData::CNAME{ref cname} => cname.len(),
// RData::DNSKEY{ref public_key, ..} => 2 /* flags u16 */ +
// 1 /* protocol u8 */ + 1 /* algorithm u8*/ +
// public_key.len(),
// RData::MX{ref exchange, .. } => 2 /* preference u16 */ + exchange.len(),
// RData::NS{ref nsdname} => nsdname.len(),
// RData::NULL{ref anything} => anything.len(),
// RData::OPT{ref option_rdata} => option_rdata.len(),
// RData::PTR{ref ptrdname} => ptrdname.len(),
// RData::SIG{ref signer_name, ref sig, ..} =>
// 2 /* type_covered: u16 */ + 1 /* algorithm u8 */ + 1 /* num_labels: u8 */ +
// 4 /* original_ttl: u32 */ + 4 /* sig_expiration: u32 */ + 4 /* sig_inception: u32 */ +
// 2 /* key_tag: u16 */ + signer_name.len() + sig.len(),
// RData::SOA{ref mname, ref rname, ..} =>
// mname.len() + rname.len() + 4 /* serial: u32 */ + 4 /* refresh: i32 */ +
// 4 /* retry: i32 */ + 4 /* expire: i32 */ + 4 /* minimum: u32 */,
// RData::SRV{ref target, ..} => 2 /* priority: u16 */ + 2 /* weight: u16 */ +
// 2 /* port: u16 */ + target.len(),
// RData::TXT{ref txt_data} => txt_data.iter().fold(0, |acc, item| acc + item.len()),
// }
// }
pub fn read(decoder: &mut BinDecoder, record_type: RecordType, rdata_length: u16) -> DecodeResult<Self> {
let start_idx = decoder.index();
let result = try!(match record_type {
RecordType::A => {debug!("reading A"); Ok(RData::A(try!(rdata::a::read(decoder)))) },
RecordType::AAAA => {debug!("reading AAAA"); Ok(RData::AAAA(try!(rdata::aaaa::read(decoder)))) },
rt @ RecordType::ANY => Err(DecodeError::UnknownRecordTypeValue(rt.into())),
rt @ RecordType::AXFR => Err(DecodeError::UnknownRecordTypeValue(rt.into())),
RecordType::CNAME => {debug!("reading CNAME"); Ok(RData::CNAME(try!(rdata::name::read(decoder)))) },
RecordType::DNSKEY => {debug!("reading DNSKEY"); Ok(RData::DNSKEY(try!(rdata::dnskey::read(decoder, rdata_length)))) },
RecordType::DS => {debug!("reading DS"); Ok(RData::DS(try!(rdata::ds::read(decoder, rdata_length)))) },
rt @ RecordType::IXFR => Err(DecodeError::UnknownRecordTypeValue(rt.into())),
RecordType::MX => {debug!("reading MX"); Ok(RData::MX(try!(rdata::mx::read(decoder)))) },
RecordType::NULL => {debug!("reading NULL"); Ok(RData::NULL(try!(rdata::null::read(decoder, rdata_length)))) },
RecordType::NS => {debug!("reading NS"); Ok(RData::NS(try!(rdata::name::read(decoder)))) },
RecordType::NSEC => {debug!("reading NSEC"); Ok(RData::NSEC(try!(rdata::nsec::read(decoder, rdata_length)))) },
RecordType::NSEC3 => {debug!("reading NSEC3"); Ok(RData::NSEC3(try!(rdata::nsec3::read(decoder, rdata_length)))) },
RecordType::NSEC3PARAM => {debug!("reading NSEC3PARAM"); Ok(RData::NSEC3PARAM(try!(rdata::nsec3param::read(decoder)))) },
RecordType::OPT => {debug!("reading OPT"); Ok(RData::OPT(try!(rdata::opt::read(decoder, rdata_length)))) },
RecordType::PTR => {debug!("reading PTR"); Ok(RData::PTR(try!(rdata::name::read(decoder)))) },
RecordType::RRSIG => {debug!("reading RRSIG"); Ok(RData::SIG(try!(rdata::sig::read(decoder, rdata_length)))) },
RecordType::SIG => {debug!("reading SIG"); Ok(RData::SIG(try!(rdata::sig::read(decoder, rdata_length)))) },
// TODO: this wrap in Ok() should go away when all RData types are converted to strong types
RecordType::SOA => {debug!("reading SOA"); Ok(RData::SOA(try!(rdata::soa::read(decoder)))) },
RecordType::SRV => {debug!("reading SRV"); Ok(RData::SRV(try!(rdata::srv::read(decoder)))) },
RecordType::TXT => {debug!("reading TXT"); Ok(RData::TXT(try!(rdata::txt::read(decoder, rdata_length)))) },
});
let result = match record_type {
RecordType::A => {debug!("reading A"); RData::A(try!(rdata::a::read(decoder))) },
RecordType::AAAA => {debug!("reading AAAA"); RData::AAAA(try!(rdata::aaaa::read(decoder))) },
rt @ RecordType::ANY => return Err(DecodeError::UnknownRecordTypeValue(rt.into())),
rt @ RecordType::AXFR => return Err(DecodeError::UnknownRecordTypeValue(rt.into())),
RecordType::CNAME => {debug!("reading CNAME"); RData::CNAME(try!(rdata::name::read(decoder))) },
RecordType::DNSKEY => {debug!("reading DNSKEY"); RData::DNSKEY(try!(rdata::dnskey::read(decoder, rdata_length))) },
RecordType::DS => {debug!("reading DS"); RData::DS(try!(rdata::ds::read(decoder, rdata_length))) },
rt @ RecordType::IXFR => return Err(DecodeError::UnknownRecordTypeValue(rt.into())),
RecordType::MX => {debug!("reading MX"); RData::MX(try!(rdata::mx::read(decoder))) },
RecordType::NULL => {debug!("reading NULL"); RData::NULL(try!(rdata::null::read(decoder, rdata_length))) },
RecordType::NS => {debug!("reading NS"); RData::NS(try!(rdata::name::read(decoder))) },
RecordType::NSEC => {debug!("reading NSEC"); RData::NSEC(try!(rdata::nsec::read(decoder, rdata_length))) },
RecordType::NSEC3 => {debug!("reading NSEC3"); RData::NSEC3(try!(rdata::nsec3::read(decoder, rdata_length))) },
RecordType::NSEC3PARAM => {debug!("reading NSEC3PARAM"); RData::NSEC3PARAM(try!(rdata::nsec3param::read(decoder))) },
RecordType::OPT => {debug!("reading OPT"); RData::OPT(try!(rdata::opt::read(decoder, rdata_length))) },
RecordType::PTR => {debug!("reading PTR"); RData::PTR(try!(rdata::name::read(decoder))) },
RecordType::RRSIG => {debug!("reading RRSIG"); RData::SIG(try!(rdata::sig::read(decoder, rdata_length))) },
RecordType::SIG => {debug!("reading SIG"); RData::SIG(try!(rdata::sig::read(decoder, rdata_length))) },
RecordType::SOA => {debug!("reading SOA"); RData::SOA(try!(rdata::soa::read(decoder))) },
RecordType::SRV => {debug!("reading SRV"); RData::SRV(try!(rdata::srv::read(decoder))) },
RecordType::TXT => {debug!("reading TXT"); RData::TXT(try!(rdata::txt::read(decoder, rdata_length))) },
};
// we should have read rdata_length, but we did not
let read = decoder.index() - start_idx;