Anonymous avatar Anonymous committed f2aca66

DionaeaHarvester better connection checking and segfault bugfix

Comments (0)

Files changed (3)

 typedef pqxx::broken_connection connection_ex;
 typedef pqxx::undefined_column undefined_column_ex;
 typedef pqxx::in_doubt_error commit_ex;
+typedef pqxx::undefined_table undef_table_ex;
+typedef pqxx::sql_error sql_ex;
 
 using std::nothrow;
 using std::exception;

modules/channel/dionaeaHarvester/dionaeaHarvester.cc

         r = w.exec(q);
         if(commit)
             w.commit();
+    } catch(connection_ex& ex) {
+        LOG(ERROR) << "DionaeaHarvester, check your database and/or connection";
+        return false;
     } catch (undefined_column_ex& ex) {
         LOG(ERROR) << "Missing column? Check your SQL query and/or database, something is wrong\n"
                    << "Query executed: " << q;
         return false;
         
-    }  catch (commit_ex& ex) {
+    } catch (commit_ex& ex) {
         LOG(WARN) << "Not sure whether transaction was commited.";
         return false;
 
-    } catch(std::exception& ex) {
-        LOG(ERROR) << "Unhandled and unexpected exception was caught, this should not happen"
-                   << ex.what() << "\n"
-                   << "Query executed: " << q;
+    } catch(undef_table_ex& ex) {
+        LOG(ERROR) << "Trying to read from non existed table while executing SQL: " 
+                   << q;
         return false;
+    } catch(sql_ex& ex) {
+        LOG(ERROR) << "For SQL: " << q
+                   << " an SQL exception was caught, discarding the data";
+        return false;
+    }
+    catch(std::exception& ex) {
+        LOG(CRITIC) << "While executing SQL: " << q << " unhandled exception was catched, rethrowing";
+        throw ex;
     }
 
     return true;
         LOG(ERROR) << "DionaeaHarvester: Cannot allocate memory for connection object";
         return false;
     } catch(connection_ex& ex) {
-        LOG(WARN) << "DionaeaHarvester: Database connection problem";
+        LOG(ERROR) << "DionaeaHarvester, check your database and/or connection";
         delete connection;
         connection = NULL;
         return false;
 };
 
 bool DionaeaHarvester::notify() {
-    if(connection) {
+    if(check_and_complain_connection(connection)) {
         fetch_data();
         return true;
     }
 }
 
 bool DionaeaHarvester::stop() {
-    if(connection) {
+    if(check_connection(connection)) {
         connection->disconnect();
         LOG(INFO) << "Disconnected from "<< credentials.user << "@"
                   << credentials.hostname << ":" << credentials.database;
     snprintf(buf,1023,ChannelSelects::fetch_connections,range.from.c_str(),range.to.c_str());
 #endif
     buf[1023] = '\0';
+    DionaeaConnections *connections = NULL;
+    try {
+        dbwork_t work(*connection);
+        dbresult_t result;
 
-    dbwork_t work(*connection);
-    dbresult_t result;
+        if(!exec_query(work,result,buf,true)) {
+            LOG(WARN) << "DionaeaHarvester query execution failed, discarding data";
+            return;
+        }
 
-    exec_query(work,result,buf,true);
+        connections = new DionaeaConnections();
 
-    DionaeaConnections *connections = new DionaeaConnections();
+        DionaeaConnections::unindexedTransaction* txn;
+        for(int i=0;i<result.size();++i) {
+            txn = new DionaeaConnections::unindexedTransaction();
+            txn->protocol = result[i][2].as<const char*>();
+            txn->dst_host = result[i][3].as<const char*>();
+            txn->dst_port = result[i][4].as<u_int16_t>();
+            txn->src_host = result[i][5].as<const char*>();
+            txn->src_port = result[i][6].as<u_int16_t>();
+            connections->rows.push_back(txn);
+        }
+        
+        connections->set_dbresult(result);
+        connections->set_date_range(range.from,range.to);
 
-    DionaeaConnections::unindexedTransaction* txn;
-    for(int i=0;i<result.size();++i) {
-        txn = new DionaeaConnections::unindexedTransaction();
-        txn->protocol = result[i][2].as<const char*>();
-        txn->dst_host = result[i][3].as<const char*>();
-        txn->dst_port = result[i][4].as<u_int16_t>();
-        txn->src_host = result[i][5].as<const char*>();
-        txn->src_port = result[i][6].as<u_int16_t>();
-        connections->rows.push_back(txn);
+        notify_workflows(connections);
+        connections = NULL; //forget about it
+
+    } catch(alloc_ex& ex) {
+        LOG(CRITIC) << "Cannot allocate memory, discarding data";
+        if(connections) delete connections;
+    } catch(connection_ex& ex) {
+        LOG(ERROR) << "DionaeaHarvester, check your database and/or connection";
+    } catch(std::exception& ex) {
+        LOG(CRITIC) << "Unhandled exception was caught, discarding data";
+        if(connections) delete connections;
     }
-    
-    connections->set_dbresult(result);
-    connections->set_date_range(range.from,range.to);
+};
 
-    notify_workflows(connections);
-    connections = NULL; //forget about it
+inline bool DionaeaHarvester::check_connection(const dbconnection_t* c) {
+    return c && c->is_open();
+};
+
+inline bool DionaeaHarvester::check_and_complain_connection(const dbconnection_t* c) {
+    if(check_connection(c))
+        return true;
+    LOG(ERROR) << "DionaeaHarvester, check your database and/or connection";
+    return false;
 };
 
 /* A SIMPLE FACTORY FOR CREATING OBJECTS */
 extern "C" Channel* create_channel() {
-    return new DionaeaHarvester();
+    return new(nothrow) DionaeaHarvester();
 };
 

modules/channel/dionaeaHarvester/dionaeaHarvester.h

 #include "../../data/dionaeaconnections.h"
 #include "selects.h"
 
+bool exec_query(dbwork_t& w,dbresult_t& r, const char* q,bool commit = false);
 
-bool exec_query(dbwork_t& w,dbresult_t& r, const char* q,bool commit = false);
 
 class DionaeaHarvester : public Channel {
     
 
         bool notify();
         bool load_misc_conf(const setting_t& misc);
+ protected:
+        inline bool check_connection(const dbconnection_t* c);
+        inline bool check_and_complain_connection(const dbconnection_t* c);
 
  private:
         int interval;
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.