]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
pcap/file: improve time handling 4779/head
authorVictor Julien <victor@inliniac.net>
Fri, 28 Feb 2020 12:17:03 +0000 (13:17 +0100)
committerJeff Lucovsky <jeff@lucovsky.org>
Sun, 5 Apr 2020 19:11:36 +0000 (15:11 -0400)
This patch addresses two problems.

First, various parts of the engine, but most notably the flow manager (FM),
use a minimum of the time notion of the packet threads. This did not
however, take into account the scenario where one or more of these
threads would be inactive for prolonged times. This could lead to the
time used by the FM could get stale.

This is addressed by keeping track of the last time the per thread packet
timestamp was updated, and only considering it for the 'minimum' when it
is reasonably current.

Second, there was a minor race condition at start up, where the FM would
already inspect the hash table(s) while the packet threads weren't active
yet. Since FM gets the time from the packet threads, it would use a bogus
time of 0.

This is addressed by adding a wait loop to the start of the FM that waits
for 'time' to get ready.

(cherry picked from commit 1e9333288f06ddc2f469053205a5d6662bf32ed7)

src/flow-manager.c
src/tm-threads.c
src/tm-threads.h
src/util-time.c
src/util-time.h

index e7f683ed986bf3d7e5d80b64b9331ebd94d2f1f6..e3e73879142c7a38b15968433940e3cb010a97d2 100644 (file)
@@ -752,6 +752,12 @@ static TmEcode FlowManager(ThreadVars *th_v, void *thread_data)
 */
     memset(&ts, 0, sizeof(ts));
 
+    /* don't start our activities until time is setup */
+    while (!TimeModeIsReady()) {
+        if (suricata_ctl_flags != 0)
+            return TM_ECODE_OK;
+    }
+
     while (1)
     {
         if (TmThreadsCheckFlag(th_v, THV_PAUSE)) {
index a36de222a5ab480cfb84554677c91f27cc793604..27186287eadd0ee3468ab789426ee881ad42c814 100644 (file)
@@ -2273,6 +2273,8 @@ typedef struct Thread_ {
 
     struct timeval pktts;   /**< current packet time of this thread
                              *   (offline mode) */
+    uint32_t sys_sec_stamp; /**< timestamp in seconds of the real system
+                             *   time when the pktts was last updated. */
 } Thread;
 
 typedef struct Threads_ {
@@ -2401,17 +2403,40 @@ void TmThreadsSetThreadTimestamp(const int id, const struct timeval *ts)
     int idx = id - 1;
     Thread *t = &thread_store.threads[idx];
     COPY_TIMESTAMP(ts, &t->pktts);
+    struct timeval systs;
+    gettimeofday(&systs, NULL);
+    t->sys_sec_stamp = (uint32_t)systs.tv_sec;
     SCMutexUnlock(&thread_store_lock);
 }
 
+bool TmThreadsTimeSubsysIsReady(void)
+{
+    bool ready = true;
+    SCMutexLock(&thread_store_lock);
+    for (size_t s = 0; s < thread_store.threads_size; s++) {
+        Thread *t = &thread_store.threads[s];
+        if (!t->in_use)
+            break;
+        if (t->sys_sec_stamp == 0) {
+            ready = false;
+            break;
+        }
+    }
+    SCMutexUnlock(&thread_store_lock);
+    return ready;
+}
+
 void TmThreadsInitThreadsTimestamp(const struct timeval *ts)
 {
+    struct timeval systs;
+    gettimeofday(&systs, NULL);
     SCMutexLock(&thread_store_lock);
     for (size_t s = 0; s < thread_store.threads_size; s++) {
         Thread *t = &thread_store.threads[s];
         if (!t->in_use)
             break;
         COPY_TIMESTAMP(ts, &t->pktts);
+        t->sys_sec_stamp = (uint32_t)systs.tv_sec;
     }
     SCMutexUnlock(&thread_store_lock);
 }
@@ -2423,13 +2448,19 @@ void TmThreadsGetMinimalTimestamp(struct timeval *ts)
     memset(&nullts, 0, sizeof(nullts));
     int set = 0;
     size_t s;
+    struct timeval systs;
+    gettimeofday(&systs, NULL);
 
     SCMutexLock(&thread_store_lock);
     for (s = 0; s < thread_store.threads_size; s++) {
         Thread *t = &thread_store.threads[s];
-        if (t == NULL || t->in_use == 0)
-            continue;
+        if (t->in_use == 0)
+            break;
         if (!(timercmp(&t->pktts, &nullts, ==))) {
+            /* ignore sleeping threads */
+            if (t->sys_sec_stamp + 1 < (uint32_t)systs.tv_sec)
+                continue;
+
             if (!set) {
                 local.tv_sec = t->pktts.tv_sec;
                 local.tv_usec = t->pktts.tv_usec;
index 165967bf3d2a6ef33494fc8b4fa70261f08e6ccb..fb8dc7b9545d3534b1bf9c39d4a87b5688431572 100644 (file)
@@ -288,5 +288,6 @@ int TmThreadsInjectPacketsById(Packet **, int id);
 void TmThreadsInitThreadsTimestamp(const struct timeval *ts);
 void TmThreadsSetThreadTimestamp(const int id, const struct timeval *ts);
 void TmThreadsGetMinimalTimestamp(struct timeval *ts);
+bool TmThreadsTimeSubsysIsReady(void);
 
 #endif /* __TM_THREADS_H__ */
index 5aec73e3b0fe6dfa44923bbe07c1c47e41809134..2d63196e774a839e9e3774e68a16cffab2db4ea3 100644 (file)
@@ -87,6 +87,13 @@ void TimeDeinit(void)
     SCSpinDestroy(&current_time_spinlock);
 }
 
+bool TimeModeIsReady(void)
+{
+    if (live_time_tracking)
+        return true;
+    return TmThreadsTimeSubsysIsReady();
+}
+
 void TimeModeSetLive(void)
 {
     live_time_tracking = true;
index 48319c805ba970f2afb7fe0cf56ff659a82364d1..a8fb6db67282e6466990a8d9e44c359e9163d27c 100644 (file)
@@ -39,6 +39,7 @@ void TimeSetToCurrentTime(void);
 void TimeSetIncrementTime(uint32_t);
 #endif
 
+bool TimeModeIsReady(void);
 void TimeModeSetLive(void);
 void TimeModeSetOffline (void);
 bool TimeModeIsLive(void);