Skip to content

Commit

Permalink
less allocations in parse_svcb_ip (#41)
Browse files Browse the repository at this point in the history
  • Loading branch information
jrouaix authored Dec 10, 2024
1 parent f9ce1c9 commit ba314c1
Showing 1 changed file with 31 additions and 31 deletions.
62 changes: 31 additions & 31 deletions src/decoders/dns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ use byteorder::{BigEndian, WriteBytesExt};
use log::{error, warn};
use nom::{
bytes::complete::take,
combinator::{fail, map, map_parser, verify},
multi::{fold_many0, many0},
combinator::{fail, iterator, map, map_parser, verify},
multi::fold_many0,
number::complete::{be_u128, be_u16, be_u32, be_u8, le_u32},
sequence::tuple,
IResult,
Expand Down Expand Up @@ -227,46 +227,46 @@ fn parse_svcb_alpn(mut input: &[u8]) -> nom::IResult<&[u8], String> {
}

/// Parse the IPs
fn parse_svcb_ip(data: &[u8]) -> nom::IResult<&[u8], String> {
fn parse_svcb_ip(mut input: &[u8]) -> nom::IResult<&[u8], String> {
const IPV4: u16 = 4;
const IPV6: u16 = 6;

let mut dns_data = data;
let ipv4_parser = || map(be_u32, Ipv4Addr::from);
let ipv6_parser = || map(be_u128, Ipv6Addr::from);

let mut ipv4_addrs = vec![];
let mut ipv6_addrs = vec![];
let mut ipv4s = String::with_capacity(2 * 16); // let's reserve max space for 2 IPV4 addresses
let mut ipv6s = String::with_capacity(2 * 40); // let's reserve max space for 2 IPV6 addresses

// IPs can either be IPv4 or/and IPv6
while !dns_data.is_empty() {
let (remaining_dns_data, (ip_version, ip_size)) =
tuple((verify(be_u16, |val| *val == IPV4 || *val == IPV6), be_u16))(dns_data)?;

let (remaining_dns_data, ip_data) = take(ip_size)(remaining_dns_data)?;

dns_data = remaining_dns_data;
while !input.is_empty() {
let (i, ip_version) = verify(be_u16, |val| *val == IPV4 || *val == IPV6)(input)?;
let (i, ip_size) = be_u16(i)?;
let (i, ip_data) = take(ip_size)(i)?;
input = i;

// There can be multiple IPs
match ip_version {
IPV4 => {
let (_, mut addrs) =
many0(map(be_u32, |raw| Ipv4Addr::from(raw).to_string()))(ip_data)?;
ipv4_addrs.append(&mut addrs);
if ip_version == IPV4 {
let mut iter = iterator(ip_data, ipv4_parser());
for ip in iter.into_iter() {
if !ipv4s.is_empty() {
ipv4s.push(',');
}
write!(ipv4s, "{}", ip).ok(); // ignore errors on write in String
}
IPV6 => {
let (_, mut addrs) =
many0(map(be_u128, |raw| Ipv6Addr::from(raw).to_string()))(ip_data)?;
ipv6_addrs.append(&mut addrs);
iter.finish()?;
} else if ip_version == IPV6 {
let mut iter = iterator(ip_data, ipv6_parser());
for ip in iter.into_iter() {
if !ipv6s.is_empty() {
ipv6s.push(',');
}
write!(ipv6s, "{}", ip).ok(); // ignore errors on write in String
}
_ => {}
};
iter.finish()?;
}
}

let message = format!(
"ipv4 hint:{}, ipv6 hint:{}",
ipv4_addrs.join(","),
ipv6_addrs.join(",")
);
Ok((dns_data, message))
let message = format!("ipv4 hint:{ipv4s}, ipv6 hint:{ipv6s}");
Ok((input, message))
}

/// Get the MAC Address from the log data
Expand Down

0 comments on commit ba314c1

Please sign in to comment.