pcap/file: improve time handling

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.
pull/4626/head
Victor Julien 6 years ago
parent 4977daec32
commit 072c421e46

@ -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)) {

@ -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;

@ -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__ */

@ -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;

@ -39,6 +39,7 @@ void TimeSetToCurrentTime(void);
void TimeSetIncrementTime(uint32_t);
#endif
bool TimeModeIsReady(void);
void TimeModeSetLive(void);
void TimeModeSetOffline (void);
bool TimeModeIsLive(void);

Loading…
Cancel
Save