diff --git a/src/flow-manager.c b/src/flow-manager.c index 328e973519f6..0535dbd19f40 100644 --- a/src/flow-manager.c +++ b/src/flow-manager.c @@ -740,6 +740,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)) { diff --git a/src/tm-threads.c b/src/tm-threads.c index 74ba6e0eb2d0..15d9999db249 100644 --- a/src/tm-threads.c +++ b/src/tm-threads.c @@ -2103,6 +2103,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_ { @@ -2226,17 +2228,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); } @@ -2248,13 +2273,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; diff --git a/src/tm-threads.h b/src/tm-threads.h index 1c838a781353..6d901e8f18d2 100644 --- a/src/tm-threads.h +++ b/src/tm-threads.h @@ -243,5 +243,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__ */ diff --git a/src/util-time.c b/src/util-time.c index 5aec73e3b0fe..2d63196e774a 100644 --- a/src/util-time.c +++ b/src/util-time.c @@ -87,6 +87,13 @@ void TimeDeinit(void) SCSpinDestroy(¤t_time_spinlock); } +bool TimeModeIsReady(void) +{ + if (live_time_tracking) + return true; + return TmThreadsTimeSubsysIsReady(); +} + void TimeModeSetLive(void) { live_time_tracking = true; diff --git a/src/util-time.h b/src/util-time.h index 48319c805ba9..a8fb6db67282 100644 --- a/src/util-time.h +++ b/src/util-time.h @@ -39,6 +39,7 @@ void TimeSetToCurrentTime(void); void TimeSetIncrementTime(uint32_t); #endif +bool TimeModeIsReady(void); void TimeModeSetLive(void); void TimeModeSetOffline (void); bool TimeModeIsLive(void);