alert http2 any any -> any any (msg:"SURICATA HTTP2 failed decompression"; flow:established; app-layer-event:http2.failed_decompression; classtype:protocol-command-decode; sid:2290009; rev:1;)
alert http2 any any -> any any (msg:"SURICATA HTTP2 invalid range header"; flow:established; app-layer-event:http2.invalid_range; classtype:protocol-command-decode; sid:2290010; rev:1;)
alert http2 any any -> any any (msg:"SURICATA HTTP2 variable-length integer overflow"; flow:established; app-layer-event:http2.header_integer_overflow; classtype:protocol-command-decode; sid:2290011; rev:1;)
+alert http2 any any -> any any (msg:"SURICATA HTTP2 too many streams"; flow:established; app-layer-event:http2.too_many_streams; classtype:protocol-command-decode; sid:2290012; rev:1;)
const HTTP2_FRAME_RSTSTREAM_LEN: usize = 4;
const HTTP2_FRAME_PRIORITY_LEN: usize = 5;
const HTTP2_FRAME_WINDOWUPDATE_LEN: usize = 4;
-//TODO make this configurable
+//TODO make these configurable
pub const HTTP2_MAX_TABLESIZE: u32 = 0x10000; // 65536
+pub const HTTP2_MAX_STREAMS: usize = 0x1000; // 4096
#[repr(u8)]
#[derive(Copy, Clone, PartialOrd, PartialEq, Debug)]
HTTP2StateClosed = 7,
//not a RFC-defined state, used for stream 0 frames appyling to the global connection
HTTP2StateGlobal = 8,
+ //not a RFC-defined state, dropping this old tx because we have too many
+ HTTP2StateTodrop = 9,
}
#[derive(Debug)]
FailedDecompression,
InvalidRange,
HeaderIntegerOverflow,
+ TooManyStreams,
}
pub struct HTTP2DynTable {
tx.tx_id = self.tx_id;
tx.stream_id = sid;
tx.state = HTTP2TransactionState::HTTP2StateOpen;
+ // do not use SETTINGS_MAX_CONCURRENT_STREAMS as it can grow too much
+ if self.transactions.len() > HTTP2_MAX_STREAMS {
+ // set at least one another transaction to the drop state
+ for tx_old in &mut self.transactions {
+ if tx_old.state != HTTP2TransactionState::HTTP2StateTodrop {
+ // use a distinct state, even if we do not log it
+ tx_old.set_event(HTTP2Event::TooManyStreams);
+ tx_old.state = HTTP2TransactionState::HTTP2StateTodrop;
+ break;
+ }
+ }
+ }
self.transactions.push(tx);
return self.transactions.last_mut().unwrap();
}