#[cfg(feature = "debug")]
pub fn _debug_state_stats(&self) {
- SCLogDebug!("ssn2vec_map {} guid2name_cache {} read_offset_cache {} ssn2tree_cache {} dcerpc_rec_frag_cache {} file_ts_guid {} file_tc_guid {} transactions {}",
- self.ssn2vec_map.len(),
+ SCLogDebug!("ssn2vec_cache {} guid2name_cache {} read_offset_cache {} ssn2tree_cache {} dcerpc_rec_frag_cache {} file_ts_guid {} file_tc_guid {} transactions {}",
+ self.ssn2vec_cache.len(),
self.guid2name_cache.len(),
self.read_offset_cache.len(),
self.ssn2tree_cache.len(),
use std;
use std::str;
use std::ffi::{self, CString};
-use std::collections::HashMap;
use std::collections::VecDeque;
use nom7::{Err, Needed};
pub static mut SMB_CFG_MAX_TREE_CACHE_SIZE: usize = 512;
/// For SMBState::dcerpc_rec_frag_cache
pub static mut SMB_CFG_MAX_FRAG_CACHE_SIZE: usize = 128;
+/// For SMBState::ssn2vec_cache
+pub static mut SMB_CFG_MAX_SSN2VEC_CACHE_SIZE: usize = 512;
static mut ALPROTO_SMB: AppProto = ALPROTO_UNKNOWN;
pub state_data: AppLayerStateData,
/// map ssn/tree/msgid to vec (guid/name/share)
- pub ssn2vec_map: HashMap<SMBCommonHdr, Vec<u8>>,
+ pub ssn2vec_cache: LruCache<SMBCommonHdr, Vec<u8>>,
/// map guid to filename
///
pub fn new() -> Self {
Self {
state_data:AppLayerStateData::new(),
- ssn2vec_map:HashMap::new(),
+ ssn2vec_cache:LruCache::new(NonZeroUsize::new(unsafe { SMB_CFG_MAX_SSN2VEC_CACHE_SIZE }).unwrap()),
guid2name_cache:LruCache::new(NonZeroUsize::new(unsafe { SMB_CFG_MAX_GUID_CACHE_SIZE }).unwrap()),
read_offset_cache:LruCache::new(NonZeroUsize::new(unsafe { SMB_CFG_MAX_READ_OFFSET_CACHE_SIZE }).unwrap()),
ssn2tree_cache:LruCache::new(NonZeroUsize::new(unsafe { SMB_CFG_MAX_TREE_CACHE_SIZE }).unwrap()),
SCLogError!("Invalid max-dcerpc-frag-cache-size value");
}
}
+ let retval = conf_get("app-layer.protocols.smb.max-session-cache-size");
+ if let Some(val) = retval {
+ if let Ok(v) = val.parse::<usize>() {
+ if v > 0 {
+ SMB_CFG_MAX_SSN2VEC_CACHE_SIZE = v;
+ } else {
+ SCLogError!("Invalid max-session-cache-size value");
+ }
+ } else {
+ SCLogError!("Invalid max-session-cache-size value");
+ }
+ }
SCLogConfig!("read: max record size: {}, max queued chunks {}, max queued size {}",
SMB_CFG_MAX_READ_SIZE, SMB_CFG_MAX_READ_QUEUE_CNT, SMB_CFG_MAX_READ_QUEUE_SIZE);
SCLogConfig!("write: max record size: {}, max queued chunks {}, max queued size {}",
let name_key = SMBCommonHdr::from1(r, SMBHDR_TYPE_FILENAME);
let name_val = cr.file_name.to_vec();
- state.ssn2vec_map.insert(name_key, name_val);
+ state.ssn2vec_cache.put(name_key, name_val);
let tx_hdr = SMBCommonHdr::from1(r, SMBHDR_TYPE_GENERICTX);
let tx = state.new_create_tx(&cr.file_name,
fid.extend_from_slice(&u32_as_bytes(r.ssn_id));
let _name = state.guid2name_cache.pop(&fid);
- state.ssn2vec_map.insert(SMBCommonHdr::from1(r, SMBHDR_TYPE_GUID), fid.to_vec());
+ state.ssn2vec_cache.put(SMBCommonHdr::from1(r, SMBHDR_TYPE_GUID), fid.to_vec());
SCLogDebug!("closing FID {:?}/{:?}", cd.fid, fid);
smb1_close_file(state, &fid, Direction::ToServer);
SCLogDebug!("Create AndX {:?}", cr);
let guid_key = SMBCommonHdr::from1(r, SMBHDR_TYPE_FILENAME);
- if let Some(mut p) = state.ssn2vec_map.remove(&guid_key) {
+ if let Some(mut p) = state.ssn2vec_cache.pop(&guid_key) {
p.retain(|&i|i != 0x00);
let mut fid = cr.fid.to_vec();
}
},
SMB1_COMMAND_CLOSE => {
- let fid = state.ssn2vec_map.remove(&SMBCommonHdr::from1(r, SMBHDR_TYPE_GUID));
+ let fid = state.ssn2vec_cache.pop(&SMBCommonHdr::from1(r, SMBHDR_TYPE_GUID));
if let Some(fid) = fid {
SCLogDebug!("closing FID {:?}", fid);
smb1_close_file(state, &fid, Direction::ToClient);
let mut pipe_dcerpc = false;
if rd.pipe.is_some() {
let pipe = rd.pipe.unwrap();
- state.ssn2vec_map.insert(SMBCommonHdr::from1(r, SMBHDR_TYPE_GUID),
+ state.ssn2vec_cache.put(SMBCommonHdr::from1(r, SMBHDR_TYPE_GUID),
pipe.fid.to_vec());
let mut frankenfid = pipe.fid.to_vec();
SCLogDebug!("TRANS response {:?}", rd);
// see if we have a stored fid
- let fid = state.ssn2vec_map.remove(
+ let fid = state.ssn2vec_cache.pop(
&SMBCommonHdr::from1(r, SMBHDR_TYPE_GUID)).unwrap_or_default();
SCLogDebug!("FID {:?}", fid);
/* update key-guid map */
let guid_key = SMBCommonHdr::from2(r, SMBHDR_TYPE_GUID);
- state.ssn2vec_map.insert(guid_key, wr.guid.to_vec());
+ state.ssn2vec_cache.put(guid_key, wr.guid.to_vec());
let file_guid = wr.guid.to_vec();
let file_name = match state.guid2name_cache.get(&file_guid) {
b"<unknown>".to_vec()
} else {
guid_key.msg_id -= 1;
- match state.ssn2vec_map.get(&guid_key) {
+ match state.ssn2vec_cache.get(&guid_key) {
Some(n) => { n.to_vec() },
None => { b"<unknown>".to_vec()},
}
SCLogDebug!("create_options {:08x}", cr.create_options);
let name_key = SMBCommonHdr::from2_notree(r, SMBHDR_TYPE_FILENAME);
- state.ssn2vec_map.insert(name_key, cr.data.to_vec());
+ state.ssn2vec_cache.put(name_key, cr.data.to_vec());
let tx_hdr = SMBCommonHdr::from2(r, SMBHDR_TYPE_GENERICTX);
let tx = state.new_create_tx(cr.data, cr.disposition, del, dir, tx_hdr);
/* search key-guid map */
let guid_key = SMBCommonHdr::new(SMBHDR_TYPE_GUID,
r.session_id, r.tree_id, r.message_id);
- let _guid_vec = state.ssn2vec_map.remove(&guid_key).unwrap_or_default();
+ let _guid_vec = state.ssn2vec_cache.pop(&guid_key).unwrap_or_default();
SCLogDebug!("SMBv2 write response for GUID {:?}", _guid_vec);
} else {
events.push(SMBEvent::MalformedData);
SCLogDebug!("SMBv2: Create response => {:?}", cr);
let guid_key = SMBCommonHdr::from2_notree(r, SMBHDR_TYPE_FILENAME);
- if let Some(mut p) = state.ssn2vec_map.remove(&guid_key) {
+ if let Some(mut p) = state.ssn2vec_cache.pop(&guid_key) {
p.retain(|&i|i != 0x00);
_ = state.guid2name_cache.put(cr.guid.to_vec(), p);
} else {