/** * \brief Removes this TV from tv_root based on its type * * \param tv The tv instance to remove from the global tv list. * \param type Holds the type this TV belongs to. */ void TmThreadRemove(ThreadVars *tv, int type) { SCMutexLock(&tv_root_lock); if (tv_root[type] == NULL) { SCMutexUnlock(&tv_root_lock); return; } ThreadVars *t = tv_root[type]; while (t != tv) { t = t->next; } if (t != NULL) { if (t->prev != NULL) t->prev->next = t->next; if (t->next != NULL) t->next->prev = t->prev; if (t == tv_root[type]) tv_root[type] = t->next;; } SCMutexUnlock(&tv_root_lock); return; }
TmEcode ReceiveNFQThreadInit(ThreadVars *tv, void *initdata, void **data) { SCMutexLock(&nfq_init_lock); #ifndef OS_WIN32 sigset_t sigs; sigfillset(&sigs); pthread_sigmask(SIG_BLOCK, &sigs, NULL); #endif /* OS_WIN32 */ NFQThreadVars *ntv = (NFQThreadVars *) initdata; /* store the ThreadVars pointer in our NFQ thread context * as we will need it in our callback function */ ntv->tv = tv; int r = NFQInitThread(ntv, (max_pending_packets * NFQ_BURST_FACTOR)); if (r < 0) { SCLogError(SC_ERR_NFQ_THREAD_INIT, "nfq thread failed to initialize"); SCMutexUnlock(&nfq_init_lock); exit(EXIT_FAILURE); } #define T_DATA_SIZE 70000 ntv->data = SCMalloc(T_DATA_SIZE); if (ntv->data == NULL) { SCMutexUnlock(&nfq_init_lock); return TM_ECODE_FAILED; } ntv->datalen = T_DATA_SIZE; #undef T_DATA_SIZE *data = (void *)ntv; SCMutexUnlock(&nfq_init_lock); return TM_ECODE_OK; }
/** \brief Return packet to Packet pool * */ void PacketPoolReturnPacket(Packet *p) { PktPool *my_pool = GetThreadPacketPool(); PACKET_RELEASE_REFS(p); PktPool *pool = p->pool; if (pool == NULL) { PacketFree(p); return; } #ifdef DEBUG_VALIDATION BUG_ON(pool->initialized == 0); BUG_ON(pool->destroyed == 1); BUG_ON(my_pool->initialized == 0); BUG_ON(my_pool->destroyed == 1); #endif /* DEBUG_VALIDATION */ if (pool == my_pool) { /* Push back onto this thread's own stack, so no locking. */ p->next = my_pool->head; my_pool->head = p; } else { PktPool *pending_pool = my_pool->pending_pool; if (pending_pool == NULL) { /* No pending packet, so store the current packet. */ my_pool->pending_pool = pool; my_pool->pending_head = p; my_pool->pending_tail = p; my_pool->pending_count = 1; } else if (pending_pool == pool) { /* Another packet for the pending pool list. */ p->next = my_pool->pending_head; my_pool->pending_head = p; my_pool->pending_count++; if (SC_ATOMIC_GET(pool->return_stack.sync_now) || my_pool->pending_count > MAX_PENDING_RETURN_PACKETS) { /* Return the entire list of pending packets. */ SCMutexLock(&pool->return_stack.mutex); my_pool->pending_tail->next = pool->return_stack.head; pool->return_stack.head = my_pool->pending_head; SC_ATOMIC_RESET(pool->return_stack.sync_now); SCMutexUnlock(&pool->return_stack.mutex); SCCondSignal(&pool->return_stack.cond); /* Clear the list of pending packets to return. */ my_pool->pending_pool = NULL; my_pool->pending_head = NULL; my_pool->pending_tail = NULL; my_pool->pending_count = 0; } } else { /* Push onto return stack for this pool */ SCMutexLock(&pool->return_stack.mutex); p->next = pool->return_stack.head; pool->return_stack.head = p; SC_ATOMIC_RESET(pool->return_stack.sync_now); SCMutexUnlock(&pool->return_stack.mutex); SCCondSignal(&pool->return_stack.cond); } } }
/** * \brief Appends this TV to tv_root based on its type * * \param type holds the type this TV belongs to. */ void TmThreadAppend(ThreadVars *tv, int type) { SCMutexLock(&tv_root_lock); if (tv_root[type] == NULL) { tv_root[type] = tv; tv->next = NULL; tv->prev = NULL; //printf("TmThreadAppend: thread \'%s\' is the first thread in the list.\n", tv->name); SCMutexUnlock(&tv_root_lock); return; } ThreadVars *t = tv_root[type]; while (t) { if (t->next == NULL) { t->next = tv; tv->prev = t; tv->next = NULL; break; } t = t->next; } SCMutexUnlock(&tv_root_lock); //printf("TmThreadAppend: thread \'%s\' is added to the list.\n", tv->name); }
int LogFileWrite(LogFileCtx *file_ctx, MemBuffer *buffer) { if (file_ctx->type == LOGFILE_TYPE_SYSLOG) { syslog(file_ctx->syslog_setup.alert_syslog_level, "%s", (const char *)MEMBUFFER_BUFFER(buffer)); } else if (file_ctx->type == LOGFILE_TYPE_FILE || file_ctx->type == LOGFILE_TYPE_UNIX_DGRAM || file_ctx->type == LOGFILE_TYPE_UNIX_STREAM) { /* append \n for files only */ MemBufferWriteString(buffer, "\n"); SCMutexLock(&file_ctx->fp_mutex); file_ctx->Write((const char *)MEMBUFFER_BUFFER(buffer), MEMBUFFER_OFFSET(buffer), file_ctx); SCMutexUnlock(&file_ctx->fp_mutex); } #ifdef HAVE_LIBHIREDIS else if (file_ctx->type == LOGFILE_TYPE_REDIS) { SCMutexLock(&file_ctx->fp_mutex); LogFileWriteRedis(file_ctx, (const char *)MEMBUFFER_BUFFER(buffer), MEMBUFFER_OFFSET(buffer)); SCMutexUnlock(&file_ctx->fp_mutex); } #endif return 0; }
/* same as 'simple' */ Packet *TmqhInputFlow(ThreadVars *tv) { PacketQueue *q = &trans_q[tv->inq->id]; SCPerfSyncCountersIfSignalled(tv, 0); SCMutexLock(&q->mutex_q); if (q->len == 0) { /* if we have no packets in queue, wait... */ #ifdef __tile__ for (;;) { if (q->len > 0 || q->cond_q) break; SCMutexUnlock(&q->mutex_q); SCMutexLock(&q->mutex_q); } #else SCCondWait(&q->cond_q, &q->mutex_q); #endif } if (q->len > 0) { Packet *p = PacketDequeue(q); SCMutexUnlock(&q->mutex_q); return p; } else { /* return NULL if we have no pkt. Should only happen on signals. */ SCMutexUnlock(&q->mutex_q); return NULL; } }
void *CudaHandlerModuleGetData(const char *module_name, const char *data_name) { SCMutexLock(&mutex); CudaHandlerModule *module = cudahl_modules; while (module != NULL && strcasecmp(module->name, module_name) != 0) module = module->next; if (module == NULL) { SCLogError(SC_ERR_CUDA_HANDLER_ERROR, "Trying to retrieve data " "\"%s\" from module \"%s\" that hasn't been registered " "yet.", module_name, data_name); SCMutexUnlock(&mutex); return NULL; } CudaHandlerModuleData *data = module->module_data; while (data != NULL && (strcasecmp(data_name, data->name) != 0)) { data = data->next; } if (data == NULL) { SCLogInfo("Data \"%s\" already registered for this module \"%s\". " "Returning it.", data_name, module_name); SCMutexUnlock(&mutex); return NULL; } SCMutexUnlock(&mutex); return data->data; }
/** * \brief Initialize the "magic" context. */ int MagicInit(void) { BUG_ON(g_magic_ctx != NULL); SCEnter(); char *filename = NULL; FILE *fd = NULL; SCMutexInit(&g_magic_lock, NULL); SCMutexLock(&g_magic_lock); g_magic_ctx = magic_open(0); if (g_magic_ctx == NULL) { SCLogError(SC_ERR_MAGIC_OPEN, "magic_open failed: %s", magic_error(g_magic_ctx)); goto error; } (void)ConfGet("magic-file", &filename); if (filename != NULL) { if (strlen(filename) == 0) { /* set filename to NULL on *nix systems so magic_load uses system * default path (see man libmagic) */ SCLogConfig("using system default magic-file"); filename = NULL; } else { SCLogConfig("using magic-file %s", filename); if ( (fd = fopen(filename, "r")) == NULL) { SCLogWarning(SC_ERR_FOPEN, "Error opening file: \"%s\": %s", filename, strerror(errno)); goto error; } fclose(fd); } } if (magic_load(g_magic_ctx, filename) != 0) { SCLogError(SC_ERR_MAGIC_LOAD, "magic_load failed: %s", magic_error(g_magic_ctx)); goto error; } SCMutexUnlock(&g_magic_lock); SCReturnInt(0); error: if (g_magic_ctx != NULL) { magic_close(g_magic_ctx); g_magic_ctx = NULL; } SCMutexUnlock(&g_magic_lock); SCReturnInt(-1); }
/** \internal * \brief Get a host from the hash directly. * * Called in conditions where the spare queue is empty and memcap is reached. * * Walks the hash until a host can be freed. "host_prune_idx" atomic int makes * sure we don't start at the top each time since that would clear the top of * the hash leading to longer and longer search times under high pressure (observed). * * \retval h host or NULL */ static Host *HostGetUsedHost(void) { uint32_t idx = SC_ATOMIC_GET(host_prune_idx) % host_config.hash_size; uint32_t cnt = host_config.hash_size; while (cnt--) { if (++idx >= host_config.hash_size) idx = 0; HostHashRow *hb = &host_hash[idx]; if (hb == NULL) continue; if (HRLOCK_TRYLOCK(hb) != 0) continue; Host *h = hb->tail; if (h == NULL) { HRLOCK_UNLOCK(hb); continue; } if (SCMutexTrylock(&h->m) != 0) { HRLOCK_UNLOCK(hb); continue; } /** never prune a host that is used by a packets * we are currently processing in one of the threads */ if (SC_ATOMIC_GET(h->use_cnt) > 0) { HRLOCK_UNLOCK(hb); SCMutexUnlock(&h->m); continue; } /* remove from the hash */ if (h->hprev != NULL) h->hprev->hnext = h->hnext; if (h->hnext != NULL) h->hnext->hprev = h->hprev; if (hb->head == h) hb->head = h->hnext; if (hb->tail == h) hb->tail = h->hprev; h->hnext = NULL; h->hprev = NULL; HRLOCK_UNLOCK(hb); HostClearMemory (h); SCMutexUnlock(&h->m); (void) SC_ATOMIC_ADD(host_prune_idx, (host_config.hash_size - cnt)); return h; } return NULL; }
/** \internal * \brief Get a tracker from the hash directly. * * Called in conditions where the spare queue is empty and memcap is reached. * * Walks the hash until a tracker can be freed. "defragtracker_prune_idx" atomic int makes * sure we don't start at the top each time since that would clear the top of * the hash leading to longer and longer search times under high pressure (observed). * * \retval dt tracker or NULL */ static DefragTracker *DefragTrackerGetUsedDefragTracker(void) { uint32_t idx = SC_ATOMIC_GET(defragtracker_prune_idx) % defrag_config.hash_size; uint32_t cnt = defrag_config.hash_size; while (cnt--) { if (++idx >= defrag_config.hash_size) idx = 0; DefragTrackerHashRow *hb = &defragtracker_hash[idx]; if (DRLOCK_TRYLOCK(hb) != 0) continue; DefragTracker *dt = hb->tail; if (dt == NULL) { DRLOCK_UNLOCK(hb); continue; } if (SCMutexTrylock(&dt->lock) != 0) { DRLOCK_UNLOCK(hb); continue; } /** never prune a tracker that is used by a packets * we are currently processing in one of the threads */ if (SC_ATOMIC_GET(dt->use_cnt) > 0) { DRLOCK_UNLOCK(hb); SCMutexUnlock(&dt->lock); continue; } /* remove from the hash */ if (dt->hprev != NULL) dt->hprev->hnext = dt->hnext; if (dt->hnext != NULL) dt->hnext->hprev = dt->hprev; if (hb->head == dt) hb->head = dt->hnext; if (hb->tail == dt) hb->tail = dt->hprev; dt->hnext = NULL; dt->hprev = NULL; DRLOCK_UNLOCK(hb); DefragTrackerClearMemory(dt); SCMutexUnlock(&dt->lock); (void) SC_ATOMIC_ADD(defragtracker_prune_idx, (defrag_config.hash_size - cnt)); return dt; } return NULL; }
/** * \brief Adds a Function-Dependent(FD) filter * * \param Name of the function for which a FD filter has to be registered * * \retval 0 on success * \retval -1 on failure */ int SCLogAddFDFilter(const char *function) { SCLogFDFilter *curr = NULL; SCLogFDFilter *prev = NULL; SCLogFDFilter *temp = NULL; if (sc_log_module_initialized != 1) { printf("Logging module not initialized. Call SCLogInitLogModule() " "first before using the debug API\n"); return -1; } if (function == NULL) { printf("Invalid argument supplied to SCLogAddFDFilter\n"); return -1; } SCMutexLock(&sc_log_fd_filters_m); curr = sc_log_fd_filters; while (curr != NULL) { prev = curr; if (strcmp(function, curr->func) == 0) { SCMutexUnlock(&sc_log_fd_filters_m); return 0; } curr = curr->next; } if ( (temp = SCMalloc(sizeof(SCLogFDFilter))) == NULL) { printf("Error Allocating memory (SCMalloc)\n"); exit(EXIT_FAILURE); } memset(temp, 0, sizeof(SCLogFDFilter)); if ( (temp->func = SCStrdup(function)) == NULL) { printf("Error Allocating memory (SCStrdup)\n"); exit(EXIT_FAILURE); } if (sc_log_fd_filters == NULL) sc_log_fd_filters = temp; /* clang thinks prev can be NULL, but it can't be unless * sc_log_fd_filters is also NULL which is handled here. * Doing this "fix" to shut clang up. */ else if (prev != NULL) prev->next = temp; SCMutexUnlock(&sc_log_fd_filters_m); sc_log_fd_filters_present = 1; return 0; }
CUcontext CudaHandlerModuleGetContext(const char *name, int device_id) { SCMutexLock(&mutex); CudaHandlerModule *module = cudahl_modules; while (module != NULL && strcasecmp(module->name, name) != 0) module = module->next; if (module != NULL) { if (module->device_id != device_id) { SCLogError(SC_ERR_CUDA_HANDLER_ERROR, "Module already " "registered, but the new device_id is different " "from the already registered device_id."); exit(EXIT_FAILURE); } SCMutexUnlock(&mutex); return module->context; } CudaHandlerModule *new_module = SCMalloc(sizeof(CudaHandlerModule)); if (new_module == NULL) exit(EXIT_FAILURE); memset(new_module, 0, sizeof(CudaHandlerModule)); new_module->device_id = device_id; new_module->name = SCStrdup(name); if (new_module->name == NULL) exit(EXIT_FAILURE); if (cudahl_modules == NULL) { cudahl_modules = new_module; } else { new_module->next = cudahl_modules; cudahl_modules = new_module; } if (no_of_cuda_contexts <= device_id) { cuda_contexts = SCRealloc(cuda_contexts, sizeof(CUcontext) * (device_id + 1)); if (cuda_contexts == NULL) exit(EXIT_FAILURE); memset(cuda_contexts + no_of_cuda_contexts, 0, sizeof(CUcontext) * ((device_id + 1) - no_of_cuda_contexts)); no_of_cuda_contexts = device_id + 1; } if (cuda_contexts[device_id] == 0) { SCCudaDevices *devices = SCCudaGetDeviceList(); if (SCCudaCtxCreate(&cuda_contexts[device_id], CU_CTX_SCHED_BLOCKING_SYNC, devices->devices[device_id]->device) == -1) { SCLogDebug("ctxcreate failure."); exit(EXIT_FAILURE); } } new_module->context = cuda_contexts[device_id]; SCMutexUnlock(&mutex); return cuda_contexts[device_id]; }
/** * \brief Removes a Function-Dependent(FD) filter * * \param Name of the function for which a FD filter has to be unregistered * * \retval 0 on success(the filter was removed or the filter was not present) * \retval -1 on failure/error */ int SCLogRemoveFDFilter(const char *function) { SCLogFDFilter *curr = NULL; SCLogFDFilter *prev = NULL; if (sc_log_module_initialized != 1) { printf("Logging module not initialized. Call SCLogInitLogModule() " "first before using the debug API\n"); return -1 ; } if (function == NULL) { printf("Invalid argument(s) supplied to SCLogRemoveFDFilter\n"); return -1; } SCMutexLock(&sc_log_fd_filters_m); if (sc_log_fd_filters == NULL) { SCMutexUnlock(&sc_log_fd_filters_m); return 0; } curr = sc_log_fd_filters; prev = curr; while (curr != NULL) { if (strcmp(function, curr->func) == 0) break; prev = curr; curr = curr->next; } if (curr == NULL) { SCMutexUnlock(&sc_log_fd_filters_m); return 0; } if (sc_log_fd_filters == curr) sc_log_fd_filters = curr->next; else prev->next = curr->next; SCLogReleaseFDFilter(curr); SCMutexUnlock(&sc_log_fd_filters_m); if (sc_log_fd_filters == NULL) sc_log_fd_filters_present = 0; return 0; }
void CudaHandlerAddCudaProfileFromConf(const char *name, void *(*Callback)(ConfNode *node), void (*Free)(void *)) { /* we don't do data validation */ SCMutexLock(&mutex); CudaHandlerConfProfile *tmp_cp = conf_profiles; while (tmp_cp != NULL && strcasecmp(name, tmp_cp->name) != 0) tmp_cp = tmp_cp->next; if (tmp_cp != NULL) { SCLogError(SC_ERR_INVALID_ARGUMENT, "We already have a cuda conf " "profile by the name \"%s\" registered.", name); exit(EXIT_FAILURE); } char tmp[200]; int r = snprintf(tmp, sizeof(tmp), "%s%s", "cuda.", name); if (r < 0) { SCLogError(SC_ERR_FATAL, "snprintf failure."); exit(EXIT_FAILURE); } else if (r > (int)sizeof(tmp)) { SCLogError(SC_ERR_FATAL, "buffer not big enough to write param."); exit(EXIT_FAILURE); } void *ctx = Callback(ConfGetNode(tmp)); if (ctx == NULL) { SCMutexUnlock(&mutex); return; } CudaHandlerConfProfile *new_cp = SCMalloc(sizeof(CudaHandlerConfProfile)); if (new_cp == NULL) exit(EXIT_FAILURE); memset(new_cp, 0, sizeof(CudaHandlerConfProfile)); new_cp->name = SCStrdup(name); if (new_cp->name == NULL) exit(EXIT_FAILURE); new_cp->ctx = ctx; new_cp->Free = Free; if (conf_profiles == NULL) { conf_profiles = new_cp; } else { new_cp->next = conf_profiles; conf_profiles = new_cp; } SCMutexUnlock(&mutex); return; }
/** * \test Test the deallocation of app layer parser memory on occurance of * error in the parsing process. */ static int AppLayerParserTest01(void) { AppLayerParserBackupParserTable(); int result = 0; Flow *f = NULL; uint8_t testbuf[] = { 0x11 }; uint32_t testlen = sizeof(testbuf); TcpSession ssn; AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); memset(&ssn, 0, sizeof(ssn)); /* Register the Test protocol state and parser functions */ AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_TEST, STREAM_TOSERVER, TestProtocolParser); AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_TEST, TestProtocolStateAlloc, TestProtocolStateFree); f = UTHBuildFlow(AF_INET, "1.2.3.4", "4.3.2.1", 20, 40); if (f == NULL) goto end; f->protoctx = &ssn; f->alproto = ALPROTO_TEST; f->proto = IPPROTO_TCP; StreamTcpInitConfig(TRUE); SCMutexLock(&f->m); int r = AppLayerParserParse(alp_tctx, f, ALPROTO_TEST, STREAM_TOSERVER|STREAM_EOF, testbuf, testlen); if (r != -1) { printf("returned %" PRId32 ", expected -1: ", r); SCMutexUnlock(&f->m); goto end; } SCMutexUnlock(&f->m); if (!(f->flags & FLOW_NO_APPLAYER_INSPECTION)) { printf("flag should have been set, but is not: "); goto end; } result = 1; end: AppLayerParserRestoreParserTable(); StreamTcpFreeConfig(TRUE); UTHFreeFlow(f); return result; }
/** * \brief Updates a FD filter, based on whether the function that calls this * function, is registered as a FD filter or not. This is called by * a function only before its exit. * * \param function Function_name from where the log_message originated * */ void SCLogCheckFDFilterExit(const char *function) { SCLogFDFilter *curr = NULL; SCLogFDFilterThreadList *thread_list = NULL; //pid_t self = syscall(SYS_gettid); pthread_t self = pthread_self(); if (sc_log_module_initialized != 1) { printf("Logging module not initialized. Call SCLogInitLogModule() " "first before using the debug API\n"); return; } SCMutexLock(&sc_log_fd_filters_m); curr = sc_log_fd_filters; while (curr != NULL) { if (strcmp(function, curr->func) == 0) break; curr = curr->next; } if (curr == NULL) { SCMutexUnlock(&sc_log_fd_filters_m); return; } SCMutexUnlock(&sc_log_fd_filters_m); SCMutexLock(&sc_log_fd_filters_tl_m); thread_list = sc_log_fd_filters_tl; while (thread_list != NULL) { if (pthread_equal(self, thread_list->t)) break; thread_list = thread_list->next; } SCMutexUnlock(&sc_log_fd_filters_tl_m); if (thread_list != NULL) thread_list->entered--; return; }
/** * \brief Add a single Netfilter queue * * \param string with the queue number * * \retval 0 on success. * \retval -1 on failure. */ int NFQRegisterQueue(const uint16_t number) { NFQThreadVars *ntv = NULL; NFQQueueVars *nq = NULL; char queue[10] = { 0 }; static bool many_queues_warned = false; uint16_t num_cpus = UtilCpuGetNumProcessorsOnline(); if (g_nfq_t == NULL || g_nfq_q == NULL) { SCLogError(SC_ERR_INVALID_ARGUMENT, "NFQ context is not initialized"); return -1; } SCMutexLock(&nfq_init_lock); if (!many_queues_warned && (receive_queue_num >= num_cpus)) { SCLogWarning(SC_WARN_UNCOMMON, "using more Netfilter queues than %hu available CPU core(s) " "may degrade performance", num_cpus); many_queues_warned = true; } if (receive_queue_num >= NFQ_MAX_QUEUE) { SCLogError(SC_ERR_INVALID_ARGUMENT, "can not register more than %d Netfilter queues", NFQ_MAX_QUEUE); SCMutexUnlock(&nfq_init_lock); return -1; } ntv = &g_nfq_t[receive_queue_num]; ntv->nfq_index = receive_queue_num; nq = &g_nfq_q[receive_queue_num]; nq->queue_num = number; receive_queue_num++; SCMutexUnlock(&nfq_init_lock); snprintf(queue, sizeof(queue) - 1, "NFQ#%hu", number); LiveRegisterDevice(queue); ntv->livedev = LiveGetDevice(queue); if (ntv->livedev == NULL) { SCLogError(SC_ERR_INVALID_VALUE, "Unable to find Live device"); return -1; } SCLogDebug("Queue %d registered.", number); return 0; }
void CudaHandlerModuleStoreData(const char *module_name, const char *data_name, void *data_ptr) { SCMutexLock(&mutex); CudaHandlerModule *module = cudahl_modules; while (module != NULL && strcasecmp(module->name, module_name) != 0) module = module->next; if (module == NULL) { SCLogError(SC_ERR_CUDA_HANDLER_ERROR, "Trying to retrieve data " "\"%s\" from module \"%s\" that hasn't been registered " "yet.", module_name, data_name); exit(EXIT_FAILURE); } CudaHandlerModuleData *data = module->module_data; while (data != NULL && (strcasecmp(data_name, data->name) != 0)) { data = data->next; } if (data != NULL) { SCLogWarning(SC_ERR_CUDA_HANDLER_ERROR, "Data \"%s\" already " "registered for this module \"%s\".", data_name, module_name); SCMutexUnlock(&mutex); goto end; } CudaHandlerModuleData *new_data = SCMalloc(sizeof(CudaHandlerModuleData)); if (new_data == NULL) exit(EXIT_FAILURE); memset(new_data, 0, sizeof(CudaHandlerModuleData)); new_data->name = SCStrdup(data_name); if (new_data->name == NULL) exit(EXIT_FAILURE); new_data->data = data_ptr; if (module->module_data == NULL) { module->module_data = new_data; } else { new_data->next = module->module_data; module->module_data = new_data; } SCMutexUnlock(&mutex); end: return; }
/** \brief LogFileFreeCtx() Destroy a LogFileCtx (Close the file and free memory) * \param motcx pointer to the OutputCtx * \retval int 1 if succesful, 0 if error * */ int LogFileFreeCtx(LogFileCtx *lf_ctx) { if (lf_ctx == NULL) { SCReturnInt(0); } if (lf_ctx->fp != NULL) { SCMutexLock(&lf_ctx->fp_mutex); lf_ctx->Close(lf_ctx); SCMutexUnlock(&lf_ctx->fp_mutex); } SCMutexDestroy(&lf_ctx->fp_mutex); if (lf_ctx->prefix != NULL) { SCFree(lf_ctx->prefix); lf_ctx->prefix_len = 0; } if(lf_ctx->filename != NULL) SCFree(lf_ctx->filename); if (lf_ctx->sensor_name) SCFree(lf_ctx->sensor_name); OutputUnregisterFileRotationFlag(&lf_ctx->rotation_flag); SCFree(lf_ctx); SCReturnInt(1); }
/** * \brief select the queue to output in a round robin fashion. * * \param tv thread vars * \param p packet */ void TmqhOutputFlowRoundRobin(ThreadVars *tv, Packet *p) { int32_t qid = 0; TmqhFlowCtx *ctx = (TmqhFlowCtx *)tv->outctx; /* if no flow we use the first queue, * should be rare */ if (p->flow != NULL) { qid = SC_ATOMIC_GET(p->flow->autofp_tmqh_flow_qid); if (qid == -1) { qid = SC_ATOMIC_ADD(ctx->round_robin_idx, 1); if (qid >= ctx->size) { SC_ATOMIC_RESET(ctx->round_robin_idx); qid = 0; } (void) SC_ATOMIC_ADD(ctx->queues[qid].total_flows, 1); (void) SC_ATOMIC_SET(p->flow->autofp_tmqh_flow_qid, qid); } } else { qid = ctx->last++; if (ctx->last == ctx->size) ctx->last = 0; } (void) SC_ATOMIC_ADD(ctx->queues[qid].total_packets, 1); PacketQueue *q = ctx->queues[qid].q; SCMutexLock(&q->mutex_q); PacketEnqueue(q, p); SCCondSignal(&q->cond_q); SCMutexUnlock(&q->mutex_q); return; }
TmEcode AlertPcapInfo (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) { AlertPcapInfoThread *aft = (AlertPcapInfoThread *)data; int i; /* logging is useless if we don't have pcap number */ if ((p->pcap_cnt != 0) && (p->alerts.cnt > 0)) { SCMutexLock(&aft->file_ctx->fp_mutex); /* only count logged alert */ aft->file_ctx->alerts += p->alerts.cnt; for (i = 0; i < p->alerts.cnt; i++) { PacketAlert *pa = &p->alerts.alerts[i]; fprintf(aft->file_ctx->fp, "%" PRIu64 ":%" PRIu32 ":%" PRIu32 ":%d:%d:%d:%d:0:0:%s\n", p->pcap_cnt, pa->s->gid, pa->s->id, pa->s->rev, pa->flags & (PACKET_ALERT_FLAG_STATE_MATCH|PACKET_ALERT_FLAG_STREAM_MATCH) ? 1 : 0, p->flowflags & FLOW_PKT_TOSERVER ? 1 : 0, p->flowflags & FLOW_PKT_TOCLIENT ? 1 : 0, pa->s->msg); } SCMutexUnlock(&aft->file_ctx->fp_mutex); } return TM_ECODE_OK; }
int OutputJSONBuffer(json_t *js, LogFileCtx *file_ctx, MemBuffer *buffer) { char *js_s = json_dumps(js, JSON_PRESERVE_ORDER|JSON_COMPACT|JSON_ENSURE_ASCII| #ifdef JSON_ESCAPE_SLASH JSON_ESCAPE_SLASH #else 0 #endif ); if (unlikely(js_s == NULL)) return TM_ECODE_OK; SCMutexLock(&file_ctx->fp_mutex); if (json_out == ALERT_REMOTE) { MemBufferWriteString(buffer, "%s\n", js_s); SendToRemote((char *)MEMBUFFER_BUFFER(buffer), MEMBUFFER_OFFSET(buffer)); } else if (json_out == ALERT_SYSLOG) { syslog(alert_syslog_level, "%s", js_s); } else if (json_out == ALERT_FILE || json_out == ALERT_UNIX_DGRAM || json_out == ALERT_UNIX_STREAM) { MemBufferWriteString(buffer, "%s\n", js_s); file_ctx->Write((const char *)MEMBUFFER_BUFFER(buffer), MEMBUFFER_OFFSET(buffer), file_ctx); } SCMutexUnlock(&file_ctx->fp_mutex); free(js_s); return 0; }
/* add a flowbit to the flow */ static void FlowAlertSidAdd(Flow *f, uint32_t sid) { FlowAlertSid *fb = FlowAlertSidGet(f, sid); if (fb == NULL) { fb = SCMalloc(sizeof(FlowAlertSid)); if (unlikely(fb == NULL)) return; fb->type = DETECT_FLOWALERTSID; fb->sid = sid; fb->next = NULL; SCLogDebug("fb->type %u, sid %"PRIu32"", fb->type, fb->sid); GenericVarAppend(&f->flowvar, (GenericVar *)fb); SCLogDebug("fb->type %u, sid %"PRIu32"", fb->type, fb->sid); SCLogDebug("adding flowalertsid with sid %" PRIu32 " (%"PRIu32")", sid, fb->sid); #ifdef FLOWALERTSID_STATS SCMutexLock(&flowbits_mutex); flowbits_added++; flowbits_memuse += sizeof(FlowAlertSid); if (flowbits_memuse > flowbits_memuse_max) flowbits_memuse_max = flowbits_memuse; SCMutexUnlock(&flowbits_mutex); #endif /* FLOWALERTSID_STATS */ } }
/** * \brief Make the threshold logic for signatures * * \param de_ctx Dectection Context * \param tsh_ptr Threshold element * \param p Packet structure * \param s Signature structure * * \retval 2 silent match (no alert but apply actions) * \retval 1 alert on this event * \retval 0 do not alert on this event */ int PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const DetectThresholdData *td, Packet *p, const Signature *s, PacketAlert *pa) { SCEnter(); int ret = 0; if (td == NULL) { SCReturnInt(0); } if (td->type == TYPE_SUPPRESS) { ret = ThresholdHandlePacketSuppress(p,td,s->id,s->gid); } else if (td->track == TRACK_SRC) { Host *src = HostGetHostFromHash(&p->src); if (src) { ret = ThresholdHandlePacketHost(src,p,td,s->id,s->gid,pa); HostRelease(src); } } else if (td->track == TRACK_DST) { Host *dst = HostGetHostFromHash(&p->dst); if (dst) { ret = ThresholdHandlePacketHost(dst,p,td,s->id,s->gid,pa); HostRelease(dst); } } else if (td->track == TRACK_RULE) { SCMutexLock(&de_ctx->ths_ctx.threshold_table_lock); ret = ThresholdHandlePacketRule(de_ctx,p,td,s,pa); SCMutexUnlock(&de_ctx->ths_ctx.threshold_table_lock); } SCReturnInt(ret); }
void *CudaHandlerGetCudaProfile(const char *name) { SCMutexLock(&mutex); CudaHandlerConfProfile *tmp_cp = conf_profiles; while (tmp_cp != NULL && strcasecmp(name, tmp_cp->name) != 0) tmp_cp = tmp_cp->next; if (tmp_cp == NULL) { SCMutexUnlock(&mutex); return NULL; } SCMutexUnlock(&mutex); return tmp_cp->ctx; }
/* Used by l7inspection to return msgs to pool */ void StreamMsgReturnToPool(StreamMsg *s) { SCLogDebug("s %p", s); SCMutexLock(&stream_msg_pool_mutex); PoolReturn(stream_msg_pool, (void *)s); SCMutexUnlock(&stream_msg_pool_mutex); }
/* Used by stream reassembler to get msgs */ StreamMsg *StreamMsgGetFromPool(void) { SCMutexLock(&stream_msg_pool_mutex); StreamMsg *s = (StreamMsg *)PoolGet(stream_msg_pool); SCMutexUnlock(&stream_msg_pool_mutex); return s; }
/** * \brief Prints the FG filters(both WL and BL). Used for debugging purposes. * * \retval count The no of FG filters */ int SCLogPrintFDFilters(void) { SCLogFDFilter *fdf = NULL; int count = 0; if (sc_log_module_initialized != 1) { printf("Logging module not initialized. Call SCLogInitLogModule() " "first before using the debug API\n"); return 0; } #ifdef DEBUG printf("FD filters:\n"); #endif SCMutexLock(&sc_log_fd_filters_m); fdf = sc_log_fd_filters; while (fdf != NULL) { #ifdef DEBUG printf("%s \n", fdf->func); #endif fdf = fdf->next; count++; } SCMutexUnlock(&sc_log_fd_filters_m); return count; }
/** * \internal * * \brief check all hosts in a hash row for timing out * * \param hb host hash row *LOCKED* * \param h last host in the hash row * \param ts timestamp * * \retval cnt timed out hosts */ static uint32_t HostHashRowTimeout(HostHashRow *hb, Host *h, struct timeval *ts) { uint32_t cnt = 0; do { if (SCMutexTrylock(&h->m) != 0) { h = h->hprev; continue; } Host *next_host = h->hprev; /* check if the host is fully timed out and * ready to be discarded. */ if (HostHostTimedOut(h, ts) == 1) { /* remove from the hash */ if (h->hprev != NULL) h->hprev->hnext = h->hnext; if (h->hnext != NULL) h->hnext->hprev = h->hprev; if (hb->head == h) hb->head = h->hnext; if (hb->tail == h) hb->tail = h->hprev; h->hnext = NULL; h->hprev = NULL; HostClearMemory (h); /* no one is referring to this host, use_cnt 0, removed from hash * so we can unlock it and move it back to the spare queue. */ SCMutexUnlock(&h->m); /* move to spare list */ HostMoveToSpare(h); cnt++; } else { SCMutexUnlock(&h->m); } h = next_host; } while (h != NULL); return cnt; }
TmEcode AlertDebugLogDecoderEvent(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) { AlertDebugLogThread *aft = (AlertDebugLogThread *)data; int i; char timebuf[64]; if (p->alerts.cnt == 0) return TM_ECODE_OK; MemBufferReset(aft->buffer); CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); MemBufferWriteString(aft->buffer, "+================\n" "TIME: %s\n", timebuf); if (p->pcap_cnt > 0) { MemBufferWriteString(aft->buffer, "PCAP PKT NUM: %"PRIu64"\n", p->pcap_cnt); } MemBufferWriteString(aft->buffer, "ALERT CNT: %" PRIu32 "\n", p->alerts.cnt); for (i = 0; i < p->alerts.cnt; i++) { PacketAlert *pa = &p->alerts.alerts[i]; if (unlikely(pa->s == NULL)) { continue; } MemBufferWriteString(aft->buffer, "ALERT MSG [%02d]: %s\n" "ALERT GID [%02d]: %" PRIu32 "\n" "ALERT SID [%02d]: %" PRIu32 "\n" "ALERT REV [%02d]: %" PRIu32 "\n" "ALERT CLASS [%02d]: %s\n" "ALERT PRIO [%02d]: %" PRIu32 "\n", i, pa->s->msg, i, pa->s->gid, i, pa->s->id, i, pa->s->rev, i, pa->s->class_msg, i, pa->s->prio); } MemBufferWriteString(aft->buffer, "PACKET LEN: %" PRIu32 "\n" "PACKET:\n", GET_PKT_LEN(p)); PrintRawDataToBuffer(aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, GET_PKT_DATA(p), GET_PKT_LEN(p)); SCMutexLock(&aft->file_ctx->fp_mutex); (void)MemBufferPrintToFPAsString(aft->buffer, aft->file_ctx->fp); fflush(aft->file_ctx->fp); aft->file_ctx->alerts += p->alerts.cnt; SCMutexUnlock(&aft->file_ctx->fp_mutex); return TM_ECODE_OK; }