Beginings of the RR parser, not compiling
This commit is contained in:
parent
f8f7a96b36
commit
1c86e24806
@ -1,4 +1,5 @@
|
||||
pub mod rr;
|
||||
pub mod op;
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
|
2
src/op/mod.rs
Normal file
2
src/op/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
pub mod op_code;
|
||||
pub mod result_code;
|
60
src/op/op_code.rs
Normal file
60
src/op/op_code.rs
Normal file
@ -0,0 +1,60 @@
|
||||
use std::convert::From;
|
||||
|
||||
#[derive(Debug, PartialEq, PartialOrd)]
|
||||
#[allow(dead_code)]
|
||||
pub enum OpCode {
|
||||
Query, // 0 Query [RFC1035]
|
||||
// 1 IQuery (Inverse Query, OBSOLETE) [RFC3425]
|
||||
Status, // 2 Status [RFC1035]
|
||||
// 3 Unassigned
|
||||
Notify, // 4 Notify [RFC1996]
|
||||
Update, // 5 Update [RFC2136]
|
||||
// 6-15 Unassigned
|
||||
}
|
||||
|
||||
/// Convert from OpCode to u8
|
||||
///
|
||||
/// ```
|
||||
/// use std::convert::From;
|
||||
/// use trust_dns::op::op_code::OpCode;
|
||||
///
|
||||
/// let var: OpCode = From::from(0);
|
||||
/// assert_eq!(OpCode::Query, var);
|
||||
///
|
||||
/// let var: OpCode = 0.into();
|
||||
/// assert_eq!(OpCode::Query, var);
|
||||
/// ```
|
||||
impl From<OpCode> for u8 {
|
||||
fn from(rt: OpCode) -> Self {
|
||||
match rt {
|
||||
OpCode::Query => 0,
|
||||
OpCode::Status => 2,
|
||||
OpCode::Notify => 4,
|
||||
OpCode::Update => 5,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert from u8 to OpCode
|
||||
///
|
||||
/// ```
|
||||
/// use std::convert::From;
|
||||
/// use trust_dns::op::op_code::OpCode;
|
||||
///
|
||||
/// let var: u8 = From::from(OpCode::Query);
|
||||
/// assert_eq!(0, var);
|
||||
///
|
||||
/// let var: u8 = OpCode::Query.into();
|
||||
/// assert_eq!(0, var);
|
||||
/// ```
|
||||
impl From<u8> for OpCode {
|
||||
fn from(value: u8) -> Self {
|
||||
match value {
|
||||
0 => OpCode::Query,
|
||||
2 => OpCode::Status,
|
||||
4 => OpCode::Notify,
|
||||
5 => OpCode::Update,
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
110
src/op/result_code.rs
Normal file
110
src/op/result_code.rs
Normal file
@ -0,0 +1,110 @@
|
||||
#[derive(Debug, PartialEq, PartialOrd)]
|
||||
#[allow(dead_code)]
|
||||
pub enum ResultCode {
|
||||
NoError, // 0 NoError No Error [RFC1035]
|
||||
FormErr, // 1 FormErr Format Error [RFC1035]
|
||||
ServFail, // 2 ServFail Server Failure [RFC1035]
|
||||
NXDomain, // 3 NXDomain Non-Existent Domain [RFC1035]
|
||||
NotImp, // 4 NotImp Not Implemented [RFC1035]
|
||||
Refused, // 5 Refused Query Refused [RFC1035]
|
||||
YXDomain, // 6 YXDomain Name Exists when it should not [RFC2136][RFC6672]
|
||||
YXRRSet, // 7 YXRRSet RR Set Exists when it should not [RFC2136]
|
||||
NXRRSet, // 8 NXRRSet RR Set that should exist does not [RFC2136]
|
||||
NotAuth, // 9 NotAuth Server Not Authoritative for zone [RFC2136]
|
||||
// 9 NotAuth Not Authorized [RFC2845]
|
||||
NotZone, // 10 NotZone Name not contained in zone [RFC2136]
|
||||
// 11-15 Unassigned
|
||||
BADVERS, // 16 BADVERS Bad OPT Version [RFC6891]
|
||||
BADSIG, // 16 BADSIG TSIG Signature Failure [RFC2845]
|
||||
BADKEY, // 17 BADKEY Key not recognized [RFC2845]
|
||||
BADTIME, // 18 BADTIME Signature out of time window [RFC2845]
|
||||
BADMODE, // 19 BADMODE Bad TKEY Mode [RFC2930]
|
||||
BADNAME, // 20 BADNAME Duplicate key name [RFC2930]
|
||||
BADALG, // 21 BADALG Algorithm not supported [RFC2930]
|
||||
BADTRUNC, // 22 BADTRUNC Bad Truncation [RFC4635]
|
||||
BADCOOKIE, // 23 BADCOOKIE (TEMPORARY - registered 2015-07-26, expires 2016-07-26) Bad/missing server cookie [draft-ietf-dnsop-cookies]
|
||||
// 24-3840 Unassigned
|
||||
// 3841-4095 Reserved for Private Use [RFC6895]
|
||||
// 4096-65534 Unassigned
|
||||
// 65535 Reserved, can be allocated by Standards Action [RFC6895]
|
||||
}
|
||||
|
||||
/// Convert from ResultCode to u8
|
||||
///
|
||||
/// ```
|
||||
/// use std::convert::From;
|
||||
/// use trust_dns::op::result_code::ResultCode;
|
||||
///
|
||||
/// let var: ResultCode = From::from(0);
|
||||
/// assert_eq!(ResultCode::NoError, var);
|
||||
///
|
||||
/// let var: ResultCode = 0.into();
|
||||
/// assert_eq!(ResultCode::NoError, var);
|
||||
/// ```
|
||||
impl From<ResultCode> for u8 {
|
||||
fn from(rt: ResultCode) -> Self {
|
||||
match rt {
|
||||
ResultCode::NoError => 0, // 0 NoError No Error [RFC1035]
|
||||
ResultCode::FormErr => 1, // 1 FormErr Format Error [RFC1035]
|
||||
ResultCode::ServFail => 2, // 2 ServFail Server Failure [RFC1035]
|
||||
ResultCode::NXDomain => 3, // 3 NXDomain Non-Existent Domain [RFC1035]
|
||||
ResultCode::NotImp => 4, // 4 NotImp Not Implemented [RFC1035]
|
||||
ResultCode::Refused => 5, // 5 Refused Query Refused [RFC1035]
|
||||
ResultCode::YXDomain => 6, // 6 YXDomain Name Exists when it should not [RFC2136][RFC6672]
|
||||
ResultCode::YXRRSet => 7, // 7 YXRRSet RR Set Exists when it should not [RFC2136]
|
||||
ResultCode::NXRRSet => 8, // 8 NXRRSet RR Set that should exist does not [RFC2136]
|
||||
ResultCode::NotAuth => 9, // 9 NotAuth Server Not Authoritative for zone [RFC2136]
|
||||
ResultCode::NotZone => 10, // 10 NotZone Name not contained in zone [RFC2136]
|
||||
ResultCode::BADVERS => 16, // 16 BADVERS Bad OPT Version [RFC6891]
|
||||
ResultCode::BADSIG => 16, // 16 BADSIG TSIG Signature Failure [RFC2845]
|
||||
ResultCode::BADKEY => 17, // 17 BADKEY Key not recognized [RFC2845]
|
||||
ResultCode::BADTIME => 18, // 18 BADTIME Signature out of time window [RFC2845]
|
||||
ResultCode::BADMODE => 19, // 19 BADMODE Bad TKEY Mode [RFC2930]
|
||||
ResultCode::BADNAME => 20, // 20 BADNAME Duplicate key name [RFC2930]
|
||||
ResultCode::BADALG => 21, // 21 BADALG Algorithm not supported [RFC2930]
|
||||
ResultCode::BADTRUNC => 22, // 22 BADTRUNC Bad Truncation [RFC4635]
|
||||
ResultCode::BADCOOKIE => 23, // 23 BADCOOKIE (TEMPORARY - registered 2015-07-26, expires 2016-07-26) Bad/missing server cookie [draft-ietf-dnsop-cookies]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert from u8 to ResultCode
|
||||
///
|
||||
/// ```
|
||||
/// use std::convert::From;
|
||||
/// use trust_dns::op::result_code::ResultCode;
|
||||
///
|
||||
/// let var: u8 = From::from(ResultCode::NoError);
|
||||
/// assert_eq!(0, var);
|
||||
///
|
||||
/// let var: u8 = ResultCode::NoError.into();
|
||||
/// assert_eq!(0, var);
|
||||
/// ```
|
||||
impl From<u8> for ResultCode {
|
||||
fn from(value: u8) -> Self {
|
||||
match value {
|
||||
0 => ResultCode::NoError, // 0 NoError No Error [RFC1035]
|
||||
1 => ResultCode::FormErr, // 1 FormErr Format Error [RFC1035]
|
||||
2 => ResultCode::ServFail, // 2 ServFail Server Failure [RFC1035]
|
||||
3 => ResultCode::NXDomain, // 3 NXDomain Non-Existent Domain [RFC1035]
|
||||
4 => ResultCode::NotImp, // 4 NotImp Not Implemented [RFC1035]
|
||||
5 => ResultCode::Refused, // 5 Refused Query Refused [RFC1035]
|
||||
6 => ResultCode::YXDomain, // 6 YXDomain Name Exists when it should not [RFC2136][RFC6672]
|
||||
7 => ResultCode::YXRRSet, // 7 YXRRSet RR Set Exists when it should not [RFC2136]
|
||||
8 => ResultCode::NXRRSet, // 8 NXRRSet RR Set that should exist does not [RFC2136]
|
||||
9 => ResultCode::NotAuth, // 9 NotAuth Server Not Authoritative for zone [RFC2136]
|
||||
10 => ResultCode::NotZone, // 10 NotZone Name not contained in zone [RFC2136]
|
||||
// this looks to be backwards compat for 4 bit ResultCodes.
|
||||
//16 => ResultCode::BADVERS, // 16 BADVERS Bad OPT Version [RFC6891]
|
||||
16 => ResultCode::BADSIG, // 16 BADSIG TSIG Signature Failure [RFC2845]
|
||||
17 => ResultCode::BADKEY, // 17 BADKEY Key not recognized [RFC2845]
|
||||
18 => ResultCode::BADTIME, // 18 BADTIME Signature out of time window [RFC2845]
|
||||
19 => ResultCode::BADMODE, // 19 BADMODE Bad TKEY Mode [RFC2930]
|
||||
20 => ResultCode::BADNAME, // 20 BADNAME Duplicate key name [RFC2930]
|
||||
21 => ResultCode::BADALG, // 21 BADALG Algorithm not supported [RFC2930]
|
||||
22 => ResultCode::BADTRUNC, // 22 BADTRUNC Bad Truncation [RFC4635]
|
||||
23 => ResultCode::BADCOOKIE, // 23 BADCOOKIE (TEMPORARY - registered 2015-07-26, expires 2016-07-26) Bad/missing server cookie [draft-ietf-dnsop-cookies]
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
114
src/rr/class.rs
114
src/rr/class.rs
@ -1,114 +0,0 @@
|
||||
use std::convert::From;
|
||||
|
||||
#[derive(Debug, PartialEq, PartialOrd)]
|
||||
#[allow(dead_code)]
|
||||
pub enum RecordClass {
|
||||
IN, // 1 RFC 1035 Internet (IN)
|
||||
CH, // 3 Chaos (CH)
|
||||
HS, // 4 Hesiod (HS)
|
||||
NONE, // 254 QCLASS NONE
|
||||
ANY, // 255 QCLASS * (ANY)
|
||||
}
|
||||
|
||||
// TODO make these a macro...
|
||||
|
||||
/// Convert from RecordClass to &str
|
||||
///
|
||||
/// ```
|
||||
/// use std::convert::From;
|
||||
/// use trust_dns::rr::record_types::RecordClass;
|
||||
///
|
||||
/// let var: &'static str = From::from(RecordClass::IN);
|
||||
/// assert_eq!("IN", var);
|
||||
///
|
||||
/// let var: &'static str = RecordClass::IN.into();
|
||||
/// assert_eq!("IN", var);
|
||||
/// ```
|
||||
impl From<RecordClass> for &'static str {
|
||||
fn from(rt: RecordClass) -> &'static str {
|
||||
match rt {
|
||||
RecordClass::IN => "IN",
|
||||
RecordClass::CH => "CH",
|
||||
RecordClass::HS => "HS",
|
||||
RecordClass::NONE => "NONE",
|
||||
RecordClass::ANY => "ANY",
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert from RecordClass to &str
|
||||
///
|
||||
/// ```
|
||||
/// use std::convert::From;
|
||||
/// use trust_dns::rr::record_types::RecordClass;
|
||||
///
|
||||
/// let var: RecordClass = From::from("A");
|
||||
/// assert_eq!(RecordClass::A, var);
|
||||
///
|
||||
/// let var: RecordClass = "A".into();
|
||||
/// assert_eq!(RecordClass::A, var);
|
||||
/// ```
|
||||
impl<'a> From<&'a str> for RecordClass {
|
||||
fn from(str: &'a str) -> Self {
|
||||
match str {
|
||||
"IN" => RecordClass::IN,
|
||||
"CH" => RecordClass::CH,
|
||||
"HS" => RecordClass::HS,
|
||||
"NONE" => RecordClass::NONE,
|
||||
"ANY" => RecordClass::ANY,
|
||||
"*" => RecordClass::ANY,
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert from RecordClass to &str
|
||||
///
|
||||
/// ```
|
||||
/// use std::convert::From;
|
||||
/// use trust_dns::rr::record_types::RecordClass;
|
||||
///
|
||||
/// let var: RecordClass = From::from(1);
|
||||
/// assert_eq!(RecordClass::A, var);
|
||||
///
|
||||
/// let var: RecordClass = 1.into();
|
||||
/// assert_eq!(RecordClass::A, var);
|
||||
/// ```
|
||||
impl From<RecordClass> for u16 {
|
||||
fn from(rt: RecordClass) -> Self {
|
||||
match rt {
|
||||
RecordClass::IN => 1,
|
||||
RecordClass::CH => 3,
|
||||
RecordClass::HS => 4,
|
||||
RecordClass::NONE => 254,
|
||||
RecordClass::ANY => 255,
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert from RecordClass to &str
|
||||
///
|
||||
/// ```
|
||||
/// use std::convert::From;
|
||||
/// use trust_dns::rr::record_types::RecordClass;
|
||||
///
|
||||
/// let var: u16 = From::from(RecordClass::A);
|
||||
/// assert_eq!(1, var);
|
||||
///
|
||||
/// let var: u16 = RecordClass::A.into();
|
||||
/// assert_eq!(1, var);
|
||||
/// ```
|
||||
impl From<u16> for RecordClass {
|
||||
fn from(value: u16) -> Self {
|
||||
match value {
|
||||
1 => RecordClass::IN,
|
||||
3 => RecordClass::CH,
|
||||
4 => RecordClass::HS,
|
||||
254 => RecordClass::NONE,
|
||||
255 => RecordClass::ANY,
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
112
src/rr/dns_class.rs
Normal file
112
src/rr/dns_class.rs
Normal file
@ -0,0 +1,112 @@
|
||||
use std::convert::From;
|
||||
|
||||
#[derive(Debug, PartialEq, PartialOrd)]
|
||||
#[allow(dead_code)]
|
||||
pub enum DNSClass {
|
||||
IN, // 1 RFC 1035 Internet (IN)
|
||||
CH, // 3 Chaos (CH)
|
||||
HS, // 4 Hesiod (HS)
|
||||
NONE, // 254 QCLASS NONE
|
||||
ANY, // 255 QCLASS * (ANY)
|
||||
}
|
||||
|
||||
// TODO make these a macro or annotation
|
||||
|
||||
/// Convert from DNSClass to &str
|
||||
///
|
||||
/// ```
|
||||
/// use std::convert::From;
|
||||
/// use trust_dns::rr::dns_class::DNSClass;
|
||||
///
|
||||
/// let var: &'static str = From::from(DNSClass::IN);
|
||||
/// assert_eq!("IN", var);
|
||||
///
|
||||
/// let var: &'static str = DNSClass::IN.into();
|
||||
/// assert_eq!("IN", var);
|
||||
/// ```
|
||||
impl From<DNSClass> for &'static str {
|
||||
fn from(rt: DNSClass) -> &'static str {
|
||||
match rt {
|
||||
DNSClass::IN => "IN",
|
||||
DNSClass::CH => "CH",
|
||||
DNSClass::HS => "HS",
|
||||
DNSClass::NONE => "NONE",
|
||||
DNSClass::ANY => "ANY",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert from &str to DNSClass
|
||||
///
|
||||
/// ```
|
||||
/// use std::convert::From;
|
||||
/// use trust_dns::rr::dns_class::DNSClass;
|
||||
///
|
||||
/// let var: DNSClass = From::from("IN");
|
||||
/// assert_eq!(DNSClass::IN, var);
|
||||
///
|
||||
/// let var: DNSClass = "IN".into();
|
||||
/// assert_eq!(DNSClass::IN, var);
|
||||
/// ```
|
||||
impl<'a> From<&'a str> for DNSClass {
|
||||
fn from(str: &'a str) -> Self {
|
||||
match str {
|
||||
"IN" => DNSClass::IN,
|
||||
"CH" => DNSClass::CH,
|
||||
"HS" => DNSClass::HS,
|
||||
"NONE" => DNSClass::NONE,
|
||||
"ANY" => DNSClass::ANY,
|
||||
"*" => DNSClass::ANY,
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert from DNSClass to u16
|
||||
///
|
||||
/// ```
|
||||
/// use std::convert::From;
|
||||
/// use trust_dns::rr::dns_class::DNSClass;
|
||||
///
|
||||
/// let var: DNSClass = From::from(1);
|
||||
/// assert_eq!(DNSClass::IN, var);
|
||||
///
|
||||
/// let var: DNSClass = 1.into();
|
||||
/// assert_eq!(DNSClass::IN, var);
|
||||
/// ```
|
||||
impl From<DNSClass> for u16 {
|
||||
fn from(rt: DNSClass) -> Self {
|
||||
match rt {
|
||||
DNSClass::IN => 1,
|
||||
DNSClass::CH => 3,
|
||||
DNSClass::HS => 4,
|
||||
DNSClass::NONE => 254,
|
||||
DNSClass::ANY => 255,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert from u16 to DNSClass
|
||||
///
|
||||
/// ```
|
||||
/// use std::convert::From;
|
||||
/// use trust_dns::rr::dns_class::DNSClass;
|
||||
///
|
||||
/// let var: u16 = From::from(DNSClass::IN);
|
||||
/// assert_eq!(1, var);
|
||||
///
|
||||
/// let var: u16 = DNSClass::IN.into();
|
||||
/// assert_eq!(1, var);
|
||||
/// ```
|
||||
impl From<u16> for DNSClass {
|
||||
fn from(value: u16) -> Self {
|
||||
match value {
|
||||
1 => DNSClass::IN,
|
||||
3 => DNSClass::CH,
|
||||
4 => DNSClass::HS,
|
||||
254 => DNSClass::NONE,
|
||||
255 => DNSClass::ANY,
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
@ -1 +1,3 @@
|
||||
pub mod type;
|
||||
pub mod record_type;
|
||||
pub mod dns_class;
|
||||
pub mod resource;
|
||||
|
@ -54,7 +54,7 @@ pub enum RecordType {
|
||||
///
|
||||
/// ```
|
||||
/// use std::convert::From;
|
||||
/// use trust_dns::rr::type::RecordType;
|
||||
/// use trust_dns::rr::record_type::RecordType;
|
||||
///
|
||||
/// let var: &'static str = From::from(RecordType::A);
|
||||
/// assert_eq!("A", var);
|
||||
@ -80,7 +80,7 @@ impl From<RecordType> for &'static str {
|
||||
///
|
||||
/// ```
|
||||
/// use std::convert::From;
|
||||
/// use trust_dns::rr::type::RecordType;
|
||||
/// use trust_dns::rr::record_type::RecordType;
|
||||
///
|
||||
/// let var: RecordType = From::from("A");
|
||||
/// assert_eq!(RecordType::A, var);
|
||||
@ -106,7 +106,7 @@ impl<'a> From<&'a str> for RecordType {
|
||||
///
|
||||
/// ```
|
||||
/// use std::convert::From;
|
||||
/// use trust_dns::rr::type::RecordType;
|
||||
/// use trust_dns::rr::record_type::RecordType;
|
||||
///
|
||||
/// let var: RecordType = From::from(1);
|
||||
/// assert_eq!(RecordType::A, var);
|
||||
@ -132,7 +132,7 @@ impl From<RecordType> for u16 {
|
||||
///
|
||||
/// ```
|
||||
/// use std::convert::From;
|
||||
/// use trust_dns::rr::type::RecordType;
|
||||
/// use trust_dns::rr::record_type::RecordType;
|
||||
///
|
||||
/// let var: u16 = From::from(RecordType::A);
|
||||
/// assert_eq!(1, var);
|
@ -1,8 +1,19 @@
|
||||
use super::type::RecordType;
|
||||
use std::collections::{VecDeque,HashMap};
|
||||
use std::iter::Take;
|
||||
use std::slice::Iter;
|
||||
|
||||
use super::record_type::RecordType;
|
||||
use super::dns_class::DNSClass;
|
||||
|
||||
|
||||
// labels 63 octets or less
|
||||
// names 255 octets or less
|
||||
// TTL positive values of a signed 32 bit number.
|
||||
// UDP messages 512 octets or less
|
||||
pub struct Record {
|
||||
type: RecordType;
|
||||
class: ;
|
||||
rr_type: RecordType,
|
||||
dns_class: DNSClass,
|
||||
name_labels: VecDeque<String>,
|
||||
}
|
||||
|
||||
impl Record {
|
||||
@ -10,10 +21,83 @@ impl Record {
|
||||
/// parse a resource record line example:
|
||||
///
|
||||
///
|
||||
fn parse(String line) -> Record {
|
||||
//fn parse(line: &str) -> Record {
|
||||
|
||||
|
||||
// tokenize the string
|
||||
//let mut tokens = line.words();
|
||||
//}
|
||||
|
||||
/// parses the chain of labels
|
||||
/// this has a max of 255 octets, with each label being less than 63.
|
||||
/// all names will be stored lowercase internally.
|
||||
fn parse_labels(slice: &[u8]) -> VecDeque<String> {
|
||||
let mut state: LabelParseState = LabelParseState::LabelLengthOrPointer;
|
||||
let mut labels: VecDeque<String>;
|
||||
// let mut label_map: HashMap<u8, usize>; // temporary map for pointers, offset in slice, start location in labels
|
||||
|
||||
// get the iterator for the slice, we'll use this for getting all the data
|
||||
let iter: Iter<_> = slice.iter();
|
||||
|
||||
// assume all chars are utf-8. We're doing byte-by-byte operations, no endianess issues...
|
||||
// reserved: (1000 0000 aka 0800) && (0100 0000 aka 0400)
|
||||
// pointer: (slice == 1100 0000 aka C0) & C0 == true, then 03FF & slice = offset
|
||||
// label: 03FF & slice = length; slice.next(length) = label
|
||||
// root: 0000
|
||||
loop {
|
||||
state = match state {
|
||||
LabelParseState::LabelLengthOrPointer => {
|
||||
let byte: u8 = *iter.take(1).next().unwrap(); // could default to zero, but it's an error if this doesn't exist, perhaps try! instead
|
||||
|
||||
//
|
||||
match byte {
|
||||
0 => LabelParseState::Root,
|
||||
byte if byte & 0xC0 == 0xC0 => LabelParseState::Pointer(byte & 0x3F),
|
||||
byte if byte <= 0x3F => LabelParseState::Label(byte),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
},
|
||||
LabelParseState::Label(count) => {
|
||||
let label_iter: Take<Iter<u8>> = iter.take(count as usize);
|
||||
let arr: Vec<u8> = label_iter.collect();
|
||||
|
||||
// using lossy, this is safe, but can end up with junk in the name...
|
||||
// TODO other option
|
||||
let label = try!(String::from_utf8(arr));
|
||||
labels.push_back(label);
|
||||
|
||||
// reset to collect more data
|
||||
LabelParseState::LabelLengthOrPointer()
|
||||
},
|
||||
LabelParseState::Pointer(offset) => {
|
||||
// lookup in the hashmap the label to use
|
||||
unimplemented!()
|
||||
},
|
||||
LabelParseState::Root => {
|
||||
// technically could return here...
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return labels;
|
||||
}
|
||||
}
|
||||
|
||||
/// This is the list of states for the state machine
|
||||
enum LabelParseState {
|
||||
LabelLengthOrPointer, // basically the start of the FSM
|
||||
Label(u8), // storing length of the label, must be < 63
|
||||
Pointer(u8), // location of pointer in slice,
|
||||
Root, // root is the end of the labels list, aka null
|
||||
}
|
||||
|
||||
impl LabelParseState {
|
||||
fn take_count(&self) -> u8 {
|
||||
match *self {
|
||||
LabelParseState::LabelLengthOrPointer => 1,
|
||||
LabelParseState::Label => *self, // unwrap the enum, this is the length of the label
|
||||
LabelParseState::Pointer => *self,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user