diff --git a/src/libdoh/Cargo.toml b/src/libdoh/Cargo.toml index 88b151f..929b480 100644 --- a/src/libdoh/Cargo.toml +++ b/src/libdoh/Cargo.toml @@ -21,7 +21,6 @@ base64 = "0.11" futures = "0.3" hyper = { version = "0.13", default-features = false, features = ["stream"] } native-tls = { version = "0.2.3", optional = true } -padme-padding = "0.1" tokio = { version = "0.2", features = ["rt-threaded", "time", "tcp", "udp", "stream"] } tokio-tls = { version = "0.3", optional = true } diff --git a/src/libdoh/src/constants.rs b/src/libdoh/src/constants.rs index f1a676b..e2e30b2 100644 --- a/src/libdoh/src/constants.rs +++ b/src/libdoh/src/constants.rs @@ -1,4 +1,3 @@ -pub const BLOCK_SIZE: usize = 128; pub const DNS_QUERY_PARAM: &str = "dns"; pub const MAX_DNS_QUESTION_LEN: usize = 512; pub const MAX_DNS_RESPONSE_LEN: usize = 4096; diff --git a/src/libdoh/src/dns.rs b/src/libdoh/src/dns.rs index 98b79e1..321f57a 100644 --- a/src/libdoh/src/dns.rs +++ b/src/libdoh/src/dns.rs @@ -1,7 +1,5 @@ use anyhow::{ensure, Error}; use byteorder::{BigEndian, ByteOrder}; -use padme_padding::Padme; -use std::cmp; const DNS_HEADER_SIZE: usize = 12; const DNS_MAX_HOSTNAME_SIZE: usize = 256; @@ -210,7 +208,18 @@ pub fn set_edns_max_payload_size(packet: &mut Vec, max_payload_size: u16) -> Ok(()) } -pub fn add_edns_padding(packet: &mut Vec, min_size: usize) -> Result<(), Error> { +fn padded_len(unpadded_len: usize) -> usize { + const BOUNDARIES: [usize; 16] = [ + 64, 128, 192, 256, 320, 384, 512, 704, 768, 896, 960, 1024, 1088, 1152, 2688, 4080, + ]; + BOUNDARIES + .iter() + .find(|&&boundary| boundary >= unpadded_len) + .copied() + .unwrap_or(DNS_MAX_PACKET_SIZE) +} + +pub fn add_edns_padding(packet: &mut Vec) -> Result<(), Error> { let mut packet_len = packet.len(); ensure!(packet_len > DNS_OFFSET_QUESTION, "Short packet"); ensure!(packet_len <= DNS_MAX_PACKET_SIZE, "Large packet"); @@ -244,8 +253,7 @@ pub fn add_edns_padding(packet: &mut Vec, min_size: usize) -> Result<(), Err edns_offset } }; - ensure!(packet_len < DNS_MAX_PACKET_SIZE, "Large packet"); - let padding_len = cmp::max(min_size, Padme::padding_len(packet_len)); + let padding_len = padded_len(packet_len) - packet_len; let mut edns_padding_prr = vec![b'X'; 4 + padding_len]; BigEndian::write_u16(&mut edns_padding_prr[0..], DNS_PTYPE_PADDING); BigEndian::write_u16(&mut edns_padding_prr[2..], padding_len as u16); @@ -261,14 +269,14 @@ pub fn add_edns_padding(packet: &mut Vec, min_size: usize) -> Result<(), Err 0xffff - edns_rdlen as usize >= edns_padding_prr_len, "EDNS section too large for padding" ); - BigEndian::write_u16( - &mut packet[edns_rdlen_offset..], - edns_rdlen + edns_padding_prr_len as u16, - ); ensure!( DNS_MAX_PACKET_SIZE - packet_len >= edns_padding_prr_len, "Large packet" ); + BigEndian::write_u16( + &mut packet[edns_rdlen_offset..], + edns_rdlen + edns_padding_prr_len as u16, + ); packet.extend(&edns_padding_prr); Ok(()) } diff --git a/src/libdoh/src/lib.rs b/src/libdoh/src/lib.rs index 2410331..bd862b6 100644 --- a/src/libdoh/src/lib.rs +++ b/src/libdoh/src/lib.rs @@ -203,7 +203,9 @@ impl DoH { Ok(ttl) => ttl, } }; - dns::add_edns_padding(&mut packet, BLOCK_SIZE).map_err(|_| DoHError::TooLarge)?; + dns::add_edns_padding(&mut packet) + .map_err(|_| DoHError::TooLarge) + .ok(); let packet_len = packet.len(); let response = Response::builder() .header(hyper::header::CONTENT_LENGTH, packet_len)