/* runs in a dedicated thread */ static LogThreadedFetchResult _fetch(LogThreadedFetcherDriver *s) { ThreadedDiskqSourceDriver *self = (ThreadedDiskqSourceDriver *) s; LogPathOptions local_options = LOG_PATH_OPTIONS_INIT; gint64 remaining_messages = log_queue_get_length(self->queue); LogMessage *msg = log_queue_pop_head(self->queue, &local_options); if (!msg) { if (remaining_messages != 0) msg_error("Closing corrupt diskq file, waiting for new", evt_tag_long("lost_messages", remaining_messages), evt_tag_str("file", self->filename)); else msg_info("Diskq file has been read, waiting for new file", evt_tag_str("file", self->filename)); _close_diskq(s); self->waiting_for_file_change = TRUE; LogThreadedFetchResult result = { THREADED_FETCH_NOT_CONNECTED, NULL }; return result; } LogThreadedFetchResult result = { THREADED_FETCH_SUCCESS, msg }; return result; }
/* NOTE: lock should be acquired for writing before calling this function. */ static void _advance_time_based_on_message(PatternDB *self, PDBProcessParams *process_params, const LogStamp *ls) { GTimeVal now; /* clamp the current time between the timestamp of the current message * (low limit) and the current system time (high limit). This ensures * that incorrect clocks do not skew the current time know by the * correllation engine too much. */ cached_g_current_time(&now); self->last_tick = now; if (ls->tv_sec < now.tv_sec) now.tv_sec = ls->tv_sec; /* the expire callback uses this pointer to find the process_params it * needs to emit messages. ProcessParams itself is a per-thread value, * however the timer callback is executing with the writer lock held. * There's no other mechanism to pass this pointer to the timer callback, * so we add it to PatternDB, but make sure it is properly protected by * locks. * */ self->timer_process_params = process_params; timer_wheel_set_time(self->timer_wheel, now.tv_sec); self->timer_process_params = NULL; msg_debug("Advancing patterndb current time because of an incoming message", evt_tag_long("utc", timer_wheel_get_time(self->timer_wheel))); }
/* * This function can be called any time when pattern-db is not processing * messages, but we expect the correllation timer to move forward. It * doesn't need to be called absolutely regularly as it'll use the current * system time to determine how much time has passed since the last * invocation. See the timing comment at pattern_db_process() for more * information. */ void pattern_db_timer_tick(PatternDB *self) { GTimeVal now; glong diff; PDBProcessParams process_params_p = {0}; PDBProcessParams *process_params = &process_params_p; g_static_rw_lock_writer_lock(&self->lock); self->timer_process_params = process_params; cached_g_current_time(&now); diff = g_time_val_diff(&now, &self->last_tick); if (diff > 1e6) { glong diff_sec = (glong) (diff / 1e6); timer_wheel_set_time(self->timer_wheel, timer_wheel_get_time(self->timer_wheel) + diff_sec); msg_debug("Advancing patterndb current time because of timer tick", evt_tag_long("utc", timer_wheel_get_time(self->timer_wheel))); /* update last_tick, take the fraction of the seconds not calculated into this update into account */ self->last_tick = now; g_time_val_add(&self->last_tick, - (glong)(diff - diff_sec * 1e6)); } else if (diff < 0) { /* time moving backwards, this can only happen if the computer's time * is changed. We don't update patterndb's idea of the time now, wait * another tick instead to update that instead. */ self->last_tick = now; } self->timer_process_params = NULL; g_static_rw_lock_writer_unlock(&self->lock); _flush_emitted_messages(self, process_params); }
static void pattern_db_expire_entry(TimerWheel *wheel, guint64 now, gpointer user_data) { PDBContext *context = user_data; PatternDB *pdb = (PatternDB *) timer_wheel_get_associated_data(wheel); GString *buffer = g_string_sized_new(256); LogMessage *msg = correllation_context_get_last_message(&context->super); PDBProcessParams *process_params = pdb->timer_process_params; msg_debug("Expiring patterndb correllation context", evt_tag_str("last_rule", context->rule->rule_id), evt_tag_long("utc", timer_wheel_get_time(pdb->timer_wheel))); process_params->context = context; process_params->rule = context->rule; process_params->msg = msg; process_params->buffer = buffer; _execute_rule_actions(pdb, process_params, RAT_TIMEOUT); g_hash_table_remove(pdb->correllation.state, &context->super.key); g_string_free(buffer, TRUE); /* pdb_context_free is automatically called when returning from this function by the timerwheel code as a destroy notify callback. */ }