doh2: handle dns message in POST requests

Ticket: 5773

Handles both directions the same way for data if content type is
application/dns-message
pull/11536/head
Philippe Antoine 1 year ago committed by Victor Julien
parent bd5ad0d74a
commit 6e12475f48

@ -61,6 +61,13 @@ impl Direction {
pub fn is_to_client(&self) -> bool {
matches!(self, Self::ToClient)
}
pub fn index(&self) -> usize {
match self {
Self::ToClient => 0,
_ => 1,
}
}
}
impl Default for Direction {

@ -151,9 +151,9 @@ pub struct HTTP2Transaction {
pub req_line: Vec<u8>,
pub resp_line: Vec<u8>,
is_doh_response: bool,
is_doh_data: [bool; 2],
// dns response buffer
pub doh_response_buf: Vec<u8>,
pub doh_data_buf: [Vec<u8>; 2],
pub dns_request_tx: Option<DNSTransaction>,
pub dns_response_tx: Option<DNSTransaction>,
}
@ -187,8 +187,8 @@ impl HTTP2Transaction {
escaped: Vec::with_capacity(16),
req_line: Vec::new(),
resp_line: Vec::new(),
is_doh_response: false,
doh_response_buf: Vec::new(),
is_doh_data: [false; 2],
doh_data_buf: Default::default(),
dns_request_tx: None,
dns_response_tx: None,
}
@ -235,7 +235,7 @@ impl HTTP2Transaction {
}
} else if block.name.as_ref() == b"content-type" {
if block.value.as_ref() == b"application/dns-message" {
self.is_doh_response = true;
self.is_doh_data[dir.index()] = true;
}
} else if block.name.as_ref() == b":path" {
path = Some(&block.value);
@ -260,7 +260,7 @@ impl HTTP2Transaction {
}
}
}
if doh && unsafe {ALPROTO_DOH2} != ALPROTO_UNKNOWN {
if doh && unsafe { ALPROTO_DOH2 } != ALPROTO_UNKNOWN {
if let Some(p) = path {
if let Ok((_, dns_req)) = parser::doh_extract_request(p) {
return Some(dns_req);
@ -345,11 +345,11 @@ impl HTTP2Transaction {
&xid,
);
};
if unsafe {ALPROTO_DOH2} != ALPROTO_UNKNOWN {
if unsafe { ALPROTO_DOH2 } != ALPROTO_UNKNOWN {
// we store DNS response, and process it when complete
if self.is_doh_response && self.doh_response_buf.len() < 0xFFFF {
if self.is_doh_data[dir.index()] && self.doh_data_buf[dir.index()].len() < 0xFFFF {
// a DNS message is U16_MAX
self.doh_response_buf.extend_from_slice(decompressed);
self.doh_data_buf[dir.index()].extend_from_slice(decompressed);
}
}
return Ok(());
@ -432,6 +432,26 @@ impl HTTP2Transaction {
}
return r;
}
fn handle_dns_data(&mut self, over: bool, dir: Direction, flow: *const Flow) {
if !self.doh_data_buf[dir.index()].is_empty() && over {
if dir.is_to_client() {
if let Ok(mut dtx) = dns_parse_response(&self.doh_data_buf[dir.index()]) {
dtx.id = 1;
self.dns_response_tx = Some(dtx);
unsafe {
AppLayerForceProtocolChange(flow, ALPROTO_DOH2);
}
}
} else if let Ok(mut dtx) = dns_parse_request(&self.doh_data_buf[dir.index()]) {
dtx.id = 1;
self.dns_request_tx = Some(dtx);
unsafe {
AppLayerForceProtocolChange(flow, ALPROTO_DOH2);
}
}
}
}
}
impl Drop for HTTP2Transaction {
@ -1165,20 +1185,7 @@ impl HTTP2State {
flow,
) {
Ok(_) => {
if !tx_same.doh_response_buf.is_empty() && over {
if let Ok(mut dtx) =
dns_parse_response(&tx_same.doh_response_buf)
{
dtx.id = 1;
tx_same.dns_response_tx = Some(dtx);
unsafe {
AppLayerForceProtocolChange(
flow,
ALPROTO_DOH2,
);
}
}
}
tx_same.handle_dns_data(over, dir, flow);
}
_ => {
self.set_event(HTTP2Event::FailedDecompression);

Loading…
Cancel
Save