]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
suricatasc: reconnect on loss of connection
authorJason Ish <jason.ish@oisf.net>
Mon, 9 Jun 2025 01:43:24 +0000 (19:43 -0600)
committerVictor Julien <victor@inliniac.net>
Tue, 10 Jun 2025 06:36:34 +0000 (08:36 +0200)
If the connection is lost (for example, Suricata is restarted), try to
re-open the connect and re-execute the command.

This was the behavior of the Python implementation.

Ticket: #7746

rust/suricatasc/src/unix/client.rs
rust/suricatasc/src/unix/main.rs

index 0c2d381d2fddb9bbfa534fadf9cebbfdd4362aea..9ba55e3096365d9b032c46363edd8e6b4af81253 100644 (file)
@@ -19,6 +19,7 @@ pub enum ClientError {
 }
 
 pub struct Client {
+    filename: String,
     socket: UnixStream,
 
     // If set, the client will print to stdout the messages sent and
@@ -30,12 +31,25 @@ pub struct Client {
 impl Client {
     pub fn connect<T: AsRef<str>>(filename: T, verbose: bool) -> Result<Self, ClientError> {
         let filename = filename.as_ref().to_string();
-        let socket = UnixStream::connect(filename)?;
-        let mut client = Self { socket, verbose };
+        let socket = UnixStream::connect(&filename)?;
+        let mut client = Self {
+            filename,
+            socket,
+            verbose,
+        };
         client.handshake()?;
         Ok(client)
     }
 
+    pub fn reconnect(&mut self) -> Result<(), ClientError> {
+        if self.verbose {
+            println!("Reconnecting to socket: {}", self.filename);
+        }
+        self.socket = UnixStream::connect(&self.filename)?;
+        self.handshake()?;
+        Ok(())
+    }
+
     fn handshake(&mut self) -> Result<(), ClientError> {
         self.send(&json!({"version": "0.2"}))?;
         self.read().map(serde_json::from_value::<Response>)??;
index e1b7aa45aa25189e0c7321db1e79d2e7167d9c2d..535ae8d116d22daa3e3eb2fa2ec126a902cd9284 100644 (file)
@@ -71,27 +71,42 @@ fn run_interactive(mut client: Client) -> Result<(), Box<dyn std::error::Error>>
         if line.starts_with("quit") {
             break;
         }
-        match command_parser.parse(&line) {
-            Ok(command) => match interactive_request_response(&mut client, &command) {
-                Ok(response) => {
-                    let response: Response = serde_json::from_value(response).unwrap();
-                    if response.status == "OK" {
-                        println!("Success:");
-                        println!(
-                            "{}",
-                            serde_json::to_string_pretty(&response.message).unwrap()
-                        );
-                    } else {
-                        println!("Error:");
-                        println!("{}", serde_json::to_string(&response.message).unwrap());
+        let mut retry = false;
+        loop {
+            match command_parser.parse(&line) {
+                Ok(command) => match interactive_request_response(&mut client, &command) {
+                    Ok(response) => {
+                        let response: Response = serde_json::from_value(response).unwrap();
+                        if response.status == "OK" {
+                            println!("Success:");
+                            println!(
+                                "{}",
+                                serde_json::to_string_pretty(&response.message).unwrap()
+                            );
+                        } else {
+                            println!("Error:");
+                            println!("{}", serde_json::to_string(&response.message).unwrap());
+                        }
+                        break;
                     }
-                }
+                    Err(err) => {
+                        println!("Error: {}", err);
+                        if retry {
+                            break;
+                        }
+                        if let Err(err) = client.reconnect() {
+                            println!("Error: {}", &err);
+                            break;
+                        } else {
+                            retry = true;
+                            continue;
+                        }
+                    }
+                },
                 Err(err) => {
                     println!("{}", err);
+                    break;
                 }
-            },
-            Err(err) => {
-                println!("{}", err);
             }
         }
     }