pgsql: config limit maximum number of live transactions

As is done for other protocols

Ticket: #5527
pull/7884/head
Philippe Antoine 4 years ago committed by Victor Julien
parent e160917bcf
commit af40873127

@ -1721,7 +1721,7 @@ incompatible with ``decode-mime``. If both are enabled,
Maximum transactions
~~~~~~~~~~~~~~~~~~~~
MQTT, FTP, and NFS have each a `max-tx` parameter that can be customized.
MQTT, FTP, PostgreSQL and NFS have each a `max-tx` parameter that can be customized.
`max-tx` refers to the maximum number of live transactions for each flow.
An app-layer event `protocol.too_many_transactions` is triggered when this value is reached.
The point of this parameter is to find a balance between the completeness of analysis

@ -32,12 +32,15 @@ pub const PGSQL_CONFIG_DEFAULT_STREAM_DEPTH: u32 = 0;
static mut ALPROTO_PGSQL: AppProto = ALPROTO_UNKNOWN;
static mut PGSQL_MAX_TX: usize = 1024;
#[repr(u8)]
#[derive(Copy, Clone, PartialOrd, PartialEq, Debug)]
pub enum PgsqlTransactionState {
Init = 0,
RequestReceived,
ResponseDone,
FlushedOut,
}
#[derive(Debug)]
@ -123,6 +126,7 @@ pub struct PgsqlState {
backend_secret_key: u32,
backend_pid: u32,
state_progress: PgsqlStateProgress,
tx_index_completed: usize,
}
impl State<PgsqlTransaction> for PgsqlState {
@ -145,6 +149,7 @@ impl PgsqlState {
backend_secret_key: 0,
backend_pid: 0,
state_progress: PgsqlStateProgress::IdleState,
tx_index_completed: 0,
}
}
@ -162,6 +167,7 @@ impl PgsqlState {
}
}
if found {
self.tx_index_completed = 0;
self.transactions.remove(index);
}
}
@ -180,6 +186,21 @@ impl PgsqlState {
self.tx_id += 1;
tx.tx_id = self.tx_id;
SCLogDebug!("Creating new transaction. tx_id: {}", tx.tx_id);
if self.transactions.len() > unsafe { PGSQL_MAX_TX } + self.tx_index_completed {
// If there are too many open transactions,
// mark the earliest ones as completed, and take care
// to avoid quadratic complexity
let mut index = self.tx_index_completed;
for tx_old in &mut self.transactions.range_mut(self.tx_index_completed..) {
index = index + 1;
if tx_old.tx_state < PgsqlTransactionState::ResponseDone {
tx_old.tx_state = PgsqlTransactionState::FlushedOut;
//TODO set event
break;
}
}
self.tx_index_completed = index;
}
return tx;
}
@ -738,6 +759,13 @@ pub unsafe extern "C" fn rs_pgsql_register_parser() {
}
AppLayerParserSetStreamDepth(IPPROTO_TCP as u8, ALPROTO_PGSQL, stream_depth)
}
if let Some(val) = conf_get("app-layer.protocols.pgsql.max-tx") {
if let Ok(v) = val.parse::<usize>() {
PGSQL_MAX_TX = v;
} else {
SCLogError!("Invalid value for pgsql.max-tx");
}
}
} else {
SCLogDebug!("Protocol detector and parser disabled for PGSQL.");
}

@ -835,6 +835,8 @@ app-layer:
enabled: no
# Stream reassembly size for PostgreSQL. By default, track it completely.
stream-depth: 0
# Maximum number of live PostgreSQL transactions per flow
# max-tx: 1024
dcerpc:
enabled: yes
ftp:

Loading…
Cancel
Save