|
|
|
@ -36,6 +36,7 @@ use std::fmt;
|
|
|
|
|
use std::io;
|
|
|
|
|
|
|
|
|
|
static mut ALPROTO_HTTP2: AppProto = ALPROTO_UNKNOWN;
|
|
|
|
|
static mut ALPROTO_DOH2: AppProto = ALPROTO_UNKNOWN;
|
|
|
|
|
|
|
|
|
|
const HTTP2_DEFAULT_MAX_FRAME_SIZE: u32 = 16384;
|
|
|
|
|
const HTTP2_MAX_HANDLED_FRAME_SIZE: usize = 65536;
|
|
|
|
@ -259,7 +260,7 @@ impl HTTP2Transaction {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if doh {
|
|
|
|
|
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);
|
|
|
|
@ -344,10 +345,12 @@ impl HTTP2Transaction {
|
|
|
|
|
&xid,
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
// we store DNS response, and process it when complete
|
|
|
|
|
if self.is_doh_response && self.doh_response_buf.len() < 0xFFFF {
|
|
|
|
|
// a DNS message is U16_MAX
|
|
|
|
|
self.doh_response_buf.extend_from_slice(decompressed);
|
|
|
|
|
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 {
|
|
|
|
|
// a DNS message is U16_MAX
|
|
|
|
|
self.doh_response_buf.extend_from_slice(decompressed);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return Ok(());
|
|
|
|
|
}
|
|
|
|
@ -1105,6 +1108,15 @@ impl HTTP2State {
|
|
|
|
|
return AppLayerResult::err();
|
|
|
|
|
}
|
|
|
|
|
let tx = tx.unwrap();
|
|
|
|
|
if let Some(doh_req_buf) = tx.handle_frame(&head, &txdata, dir) {
|
|
|
|
|
if let Ok(mut dtx) = dns_parse_request(&doh_req_buf) {
|
|
|
|
|
dtx.id = 1;
|
|
|
|
|
tx.dns_request_tx = Some(dtx);
|
|
|
|
|
unsafe {
|
|
|
|
|
AppLayerForceProtocolChange(flow, ALPROTO_DOH2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if reass_limit_reached {
|
|
|
|
|
tx.tx_data
|
|
|
|
|
.set_event(HTTP2Event::ReassemblyLimitReached as u8);
|
|
|
|
@ -1153,12 +1165,17 @@ impl HTTP2State {
|
|
|
|
|
flow,
|
|
|
|
|
) {
|
|
|
|
|
Ok(_) => {
|
|
|
|
|
if !tx_same.doh_response_buf.is_empty() {
|
|
|
|
|
if over {
|
|
|
|
|
if let Ok(dtx) = dns_parse_response(
|
|
|
|
|
&tx_same.doh_response_buf,
|
|
|
|
|
) {
|
|
|
|
|
tx_same.dns_response_tx = Some(dtx);
|
|
|
|
|
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,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -1413,7 +1430,7 @@ const PARSER_NAME: &[u8] = b"http2\0";
|
|
|
|
|
#[no_mangle]
|
|
|
|
|
pub unsafe extern "C" fn rs_http2_register_parser() {
|
|
|
|
|
let default_port = CString::new("[80]").unwrap();
|
|
|
|
|
let parser = RustParser {
|
|
|
|
|
let mut parser = RustParser {
|
|
|
|
|
name: PARSER_NAME.as_ptr() as *const std::os::raw::c_char,
|
|
|
|
|
default_port: default_port.as_ptr(),
|
|
|
|
|
ipproto: IPPROTO_TCP,
|
|
|
|
@ -1479,4 +1496,22 @@ pub unsafe extern "C" fn rs_http2_register_parser() {
|
|
|
|
|
} else {
|
|
|
|
|
SCLogNotice!("Protocol detector and parser disabled for HTTP2.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// doh2 is just http2 wrapped in another name
|
|
|
|
|
parser.name = b"doh2\0".as_ptr() as *const std::os::raw::c_char;
|
|
|
|
|
parser.probe_tc = None;
|
|
|
|
|
parser.default_port = std::ptr::null();
|
|
|
|
|
if AppLayerProtoDetectConfProtoDetectionEnabled(ip_proto_str.as_ptr(), parser.name) != 0 {
|
|
|
|
|
let alproto = AppLayerRegisterProtocolDetection(&parser, 1);
|
|
|
|
|
ALPROTO_DOH2 = alproto;
|
|
|
|
|
if AppLayerParserConfParserEnabled(ip_proto_str.as_ptr(), parser.name) != 0 {
|
|
|
|
|
let _ = AppLayerRegisterParser(&parser, alproto);
|
|
|
|
|
} else {
|
|
|
|
|
SCLogWarning!("DOH2 is not meant to be detection-only.");
|
|
|
|
|
}
|
|
|
|
|
AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_DOH2);
|
|
|
|
|
SCLogDebug!("Rust doh2 parser registered.");
|
|
|
|
|
} else {
|
|
|
|
|
SCLogNotice!("Protocol detector and parser disabled for DOH2.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|