]> git.ipfire.org Git - people/ms/suricata.git/commitdiff
dns: conditional logging
authorJason Ish <jason.ish@oisf.net>
Sun, 7 Jun 2020 12:07:26 +0000 (14:07 +0200)
committerVictor Julien <victor@inliniac.net>
Sat, 11 Jul 2020 06:37:41 +0000 (08:37 +0200)
Apply config to newly created response TX.

rust/src/dns/dns.rs

index eed58640485e3cead6f946cbbf64c8c7b14edece..e78810679739345a474b290f788a003d45681a5e 100644 (file)
@@ -20,6 +20,8 @@ extern crate nom;
 use std;
 use std::ffi::CString;
 use std::mem::transmute;
+use std::collections::HashMap;
+use std::collections::VecDeque;
 
 use crate::log::*;
 use crate::applayer::*;
@@ -318,6 +320,36 @@ impl Drop for DNSTransaction {
     }
 }
 
+struct ConfigTracker {
+    map: HashMap<u16, AppLayerTxConfig>,
+    queue: VecDeque<u16>,
+}
+
+impl ConfigTracker {
+    fn new() -> ConfigTracker {
+        ConfigTracker {
+            map: HashMap::new(),
+            queue: VecDeque::new(),
+        }
+    }
+
+    fn add(&mut self, id: u16, config: AppLayerTxConfig) {
+        // If at size limit, remove the oldest entry.
+        if self.queue.len() > 499 {
+            if let Some(id) = self.queue.pop_front() {
+                self.map.remove(&id);
+            }
+        }
+
+        self.map.insert(id, config);
+        self.queue.push_back(id);
+    }
+
+    fn remove(&mut self, id: &u16) -> Option<AppLayerTxConfig> {
+        self.map.remove(id)
+    }
+}
+
 pub struct DNSState {
     // Internal transaction ID.
     pub tx_id: u64,
@@ -330,6 +362,8 @@ pub struct DNSState {
     pub request_buffer: Vec<u8>,
     pub response_buffer: Vec<u8>,
 
+    config: Option<ConfigTracker>,
+
     gap: bool,
 }
 
@@ -342,6 +376,7 @@ impl DNSState {
             events: 0,
             request_buffer: Vec::new(),
             response_buffer: Vec::new(),
+            config: None,
             gap: false,
         };
     }
@@ -355,6 +390,7 @@ impl DNSState {
             events: 0,
             request_buffer: Vec::with_capacity(0xffff),
             response_buffer: Vec::with_capacity(0xffff),
+            config: None,
             gap: false,
         };
     }
@@ -479,6 +515,11 @@ impl DNSState {
                 }
 
                 let mut tx = self.new_tx();
+                if let Some(ref mut config) = &mut self.config {
+                    if let Some(config) = config.remove(&response.header.tx_id) {
+                        tx.tx_data.config = config;
+                    }
+                }
                 tx.response = Some(response);
                 self.transactions.push(tx);
                 return true;
@@ -944,6 +985,23 @@ pub extern "C" fn rs_dns_probe_tcp(
     return 0;
 }
 
+#[no_mangle]
+pub extern "C" fn rs_dns_apply_tx_config(
+    _state: *mut std::os::raw::c_void, _tx: *mut std::os::raw::c_void,
+    _mode: std::os::raw::c_int, config: AppLayerTxConfig
+) {
+    let tx = cast_pointer!(_tx, DNSTransaction);
+    let state = cast_pointer!(_state, DNSState);
+    if let Some(request) = &tx.request {
+        if state.config.is_none() {
+            state.config = Some(ConfigTracker::new());
+        }
+        if let Some(ref mut tracker) = &mut state.config {
+            tracker.add(request.header.tx_id, config);
+        }
+    }
+}
+
 #[no_mangle]
 pub unsafe extern "C" fn rs_dns_init(proto: AppProto) {
     ALPROTO_DNS = proto;
@@ -979,7 +1037,7 @@ pub unsafe extern "C" fn rs_dns_udp_register_parser() {
         get_de_state: rs_dns_state_get_tx_detect_state,
         set_de_state: rs_dns_state_set_tx_detect_state,
         get_tx_data: rs_dns_state_get_tx_data,
-        apply_tx_config: None,
+        apply_tx_config: Some(rs_dns_apply_tx_config),
     };
 
     let ip_proto_str = CString::new("udp").unwrap();
@@ -1024,7 +1082,7 @@ pub unsafe extern "C" fn rs_dns_tcp_register_parser() {
         get_de_state: rs_dns_state_get_tx_detect_state,
         set_de_state: rs_dns_state_set_tx_detect_state,
         get_tx_data: rs_dns_state_get_tx_data,
-        apply_tx_config: None,
+        apply_tx_config: Some(rs_dns_apply_tx_config),
     };
 
     let ip_proto_str = CString::new("tcp").unwrap();