Skip to content

Commit

Permalink
Avoid Rust large memcpys
Browse files Browse the repository at this point in the history
  • Loading branch information
ivmarkov committed Jan 5, 2024
1 parent b13e0a5 commit af81c7a
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 11 deletions.
2 changes: 1 addition & 1 deletion edge-captive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ std = ["domain/std"]
[dependencies]
log = { workspace = true }
domain = { workspace = true }
heapless07 = { package = "heapless", version = "0.7" }
octseq = { workspace = true }
10 changes: 6 additions & 4 deletions edge-captive/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,15 @@ pub mod server {

let request = &request_arr[..request_len];

debug!("Received {} bytes from {}", request.len(), source_addr);
let response = crate::process_dns_request(request, &ip.octets(), ttl)
debug!("Received {} bytes from {source_addr}", request.len());

let mut reply_arr = [0_u8; 1280];
let len = crate::reply(request, &ip.octets(), ttl, &mut reply_arr)
.map_err(|_| io::ErrorKind::Other)?;

socket.send_to(response.as_ref(), source_addr)?;
socket.send_to(&reply_arr[..len], source_addr)?;

debug!("Sent {} bytes to {}", response.as_ref().len(), source_addr);
debug!("Sent {len} bytes to {source_addr}");
}

Ok(())
Expand Down
54 changes: 48 additions & 6 deletions edge-captive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
use core::fmt::{self, Display};
use core::time::Duration;

use domain::base::wire::Composer;
use domain::dep::octseq::OctetsBuilder;
use log::debug;

use domain::{
Expand All @@ -17,6 +19,7 @@ use domain::{
dep::octseq::ShortBuf,
rdata::A,
};
use octseq::Truncate;

pub mod io;

Expand Down Expand Up @@ -62,19 +65,20 @@ impl From<ParseError> for DnsError {
}
}

pub fn process_dns_request(
pub fn reply(
request: &[u8],
ip: &[u8; 4],
ttl: Duration,
) -> Result<impl AsRef<[u8]>, DnsError> {
let response = heapless07::Vec::<u8, 512>::new();
buf: &mut [u8],
) -> Result<usize, DnsError> {
let buf = Buf(buf, 0);

let message = domain::base::Message::from_octets(request)?;
debug!("Processing message with header: {:?}", message.header());

let mut responseb = domain::base::MessageBuilder::from_target(response)?;
let mut responseb = domain::base::MessageBuilder::from_target(buf)?;

let response = if matches!(message.header().opcode(), Opcode::Query) {
let buf = if matches!(message.header().opcode(), Opcode::Query) {
debug!("Message is of type Query, processing all questions");

let mut answerb = responseb.start_answer(&message, Rcode::NoError)?;
Expand Down Expand Up @@ -117,5 +121,43 @@ pub fn process_dns_request(
responseb.finish()
};

Ok(response)
Ok(buf.1)
}

struct Buf<'a>(pub &'a mut [u8], pub usize);

impl<'a> Composer for Buf<'a> {}

impl<'a> OctetsBuilder for Buf<'a> {
type AppendError = ShortBuf;

fn append_slice(&mut self, slice: &[u8]) -> Result<(), Self::AppendError> {
if self.1 + slice.len() <= self.0.len() {
let end = self.1 + slice.len();
self.0[self.1..end].copy_from_slice(slice);
self.1 = end;

Ok(())
} else {
Err(ShortBuf)
}
}
}

impl<'a> Truncate for Buf<'a> {
fn truncate(&mut self, len: usize) {
self.1 = len;
}
}

impl<'a> AsMut<[u8]> for Buf<'a> {
fn as_mut(&mut self) -> &mut [u8] {
&mut self.0[..self.1]
}
}

impl<'a> AsRef<[u8]> for Buf<'a> {
fn as_ref(&self) -> &[u8] {
&self.0[..self.1]
}
}

0 comments on commit af81c7a

Please sign in to comment.