Skip to content

Commit

Permalink
Domain name compression is broken in 0.10.0 (#321)
Browse files Browse the repository at this point in the history
This PR fixes a bug in SliceLabelIter’s next method that causes it to
return short labels. This fixes StaticCompressor which uses this iterator.
  • Loading branch information
hunts authored May 30, 2024
1 parent f84abe0 commit 7ebfcf3
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 2 deletions.
46 changes: 46 additions & 0 deletions src/base/message_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2449,4 +2449,50 @@ mod test {
let msg = create_compressed(TreeCompressor::new(Vec::new()));
assert_eq!(&expect[..], msg.as_ref());
}

#[test]
fn compress_positive_response() {
// An example positive response to `A example.com.` that is compressed
//
// ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 0
// ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
//
// ;; QUESTION SECTION:
// ;example.com. IN A
//
// ;; ANSWER SECTION:
// example.com. 3600 IN A 203.0.113.1
//
// ;; MSG SIZE rcvd: 45
let expect = &[
0x00, 0x00, 0x81, 0xa0, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 0x63,
0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x01,
0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00, 0x04, 0xcb, 0x00, 0x71,
0x01,
];

let name = "example.com.".parse::<Name<Vec<u8>>>().unwrap();
let mut msg =
MessageBuilder::from_target(StaticCompressor::new(Vec::new()))
.unwrap()
.question();
msg.header_mut().set_rcode(Rcode::NOERROR);
msg.header_mut().set_rd(true);
msg.header_mut().set_ra(true);
msg.header_mut().set_qr(true);
msg.header_mut().set_ad(true);

// Question
msg.push((name.clone(), Rtype::A)).unwrap();

// Answer
let mut msg = msg.answer();
msg.push((name.clone(), 3600, A::from_octets(203, 0, 113, 1)))
.unwrap();

let actual = msg.finish().into_target();
assert_eq!(45, actual.len(), "unexpected response size");
assert_eq!(expect[..], actual, "unexpected response data");
}
}
37 changes: 35 additions & 2 deletions src/base/name/label.rs
Original file line number Diff line number Diff line change
Expand Up @@ -741,16 +741,17 @@ impl<'a> Iterator for SliceLabelsIter<'a> {
type Item = &'a Label;

fn next(&mut self) -> Option<Self::Item> {
if self.start == usize::MAX {
if self.start >= self.slice.len() {
return None;
}

loop {
match Label::split_from(&self.slice[self.start..]) {
Ok((label, _)) => {
if label.is_root() {
self.start = usize::MAX;
} else {
self.start += label.len();
self.start += label.len() + 1;
}
return Some(label);
}
Expand Down Expand Up @@ -1034,4 +1035,36 @@ mod test {
],
);
}

#[test]
fn iter_slice() {
assert_eq!(None, Label::iter_slice(&[], 0).next());
assert_eq!(None, Label::iter_slice(&[], 1).next());

// example.com.
let buf = [
0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 0x63, 0x6f,
0x6d, 0x00,
];

let mut it = Label::iter_slice(&buf, 0);
assert_eq!(Label::from_slice(b"example").ok(), it.next());
assert_eq!(Label::from_slice(b"com").ok(), it.next());
assert_eq!(Some(Label::root()), it.next());
assert_eq!(None, it.next());

let mut it = Label::iter_slice(&buf, b"example".len() + 1);
assert_eq!(
Label::from_slice(b"com").ok(),
it.next(),
"should jump to 2nd label"
);

let mut it = Label::iter_slice(&buf, buf.len() - 1);
assert_eq!(
Some(Label::root()),
it.next(),
"should jump to last/root label"
);
}
}

0 comments on commit 7ebfcf3

Please sign in to comment.