runmode: introduce configuration dereferencing.

A devide configuration can be used by multiple threads. It is thus
necessary to wait that all threads stop using the configuration before
freeing it. This patch introduces an atomic counter and a free function
which has to be called by each thread when it will not use anymore
the structure. If the configuration is not used anymore, it is freed
by the free function.
remotes/origin/master-1.1.x
Eric Leblond 15 years ago
parent 3261b814db
commit 45d5c3ca59

@ -78,6 +78,15 @@ void RunModeIdsAFPRegister(void)
return;
}
void AFPDerefConfig(void *conf)
{
AFPIfaceConfig *pfp = (AFPIfaceConfig *)conf;
/* Pcap config is used only once but cost of this low. */
if (SC_ATOMIC_SUB(pfp->ref, 1) == 0) {
SCFree(pfp);
}
}
/**
* \brief extract information from config file
*
@ -108,10 +117,13 @@ void *ParseAFPConfig(const char *iface)
}
strlcpy(aconf->iface, iface, sizeof(aconf->iface));
aconf->threads = 1;
SC_ATOMIC_INIT(aconf->ref);
SC_ATOMIC_ADD(aconf->ref, 1);
aconf->buffer_size = 0;
aconf->cluster_id = 1;
aconf->cluster_type = PACKET_FANOUT_HASH;
aconf->promisc = 1;
aconf->DerefFunc = AFPDerefConfig;
/* Find initial node */
af_packet_node = ConfGetNode("af-packet");
@ -138,6 +150,10 @@ void *ParseAFPConfig(const char *iface)
if (aconf->threads == 0) {
aconf->threads = 1;
}
SC_ATOMIC_RESET(aconf->ref);
SC_ATOMIC_ADD(aconf->ref, aconf->threads);
if (ConfGetChildValue(if_root, "cluster-id", &tmpclusterid) != 1) {
SCLogError(SC_ERR_INVALID_ARGUMENT,"Could not get cluster-id from config");
} else {

@ -39,6 +39,7 @@
#include "util-affinity.h"
#include "util-device.h"
#include "util-runmodes.h"
#include "util-atomic.h"
static const char *default_mode = NULL;
@ -67,6 +68,18 @@ void RunModeIdsPcapRegister(void)
return;
}
void PcapDerefConfig(void *conf)
{
PcapIfaceConfig *pfp = (PcapIfaceConfig *)conf;
/* Pcap config is used only once but cost of this low. */
if (SC_ATOMIC_SUB(pfp->ref, 1) == 0) {
if (pfp->bpf_filter) {
SCFree(pfp->bpf_filter);
}
SCFree(pfp);
}
}
void *ParsePcapConfig(const char *iface)
{
@ -96,6 +109,10 @@ void *ParsePcapConfig(const char *iface)
aconf->bpf_filter = tmpbpf;
}
SC_ATOMIC_INIT(aconf->ref);
SC_ATOMIC_ADD(aconf->ref, 1);
aconf->DerefFunc = PcapDerefConfig;
/* Find initial node */
pcap_node = ConfGetNode("pcap");
if (pcap_node == NULL) {

@ -75,6 +75,14 @@ void RunModeIdsPfringRegister(void)
return;
}
void PfringDerefConfig(void *conf)
{
PfringIfaceConfig *pfp = (PfringIfaceConfig *)conf;
if (SC_ATOMIC_SUB(pfp->ref, 1) == 0) {
SCFree(pfp);
}
}
/**
* \brief extract information from config file
*
@ -111,6 +119,9 @@ void *OldParsePfringConfig(const char *iface)
#ifdef HAVE_PFRING_CLUSTER_TYPE
pfconf->ctype = (cluster_type)default_ctype;
#endif
pfconf->DerefFunc = PfringDerefConfig;
SC_ATOMIC_INIT(pfconf->ref);
SC_ATOMIC_ADD(pfconf->ref, 1);
/* Find initial node */
if (ConfGet("pfring.threads", &threadsstr) != 1) {
@ -123,6 +134,10 @@ void *OldParsePfringConfig(const char *iface)
if (pfconf->threads == 0) {
pfconf->threads = 1;
}
SC_ATOMIC_RESET(pfconf->ref);
SC_ATOMIC_ADD(pfconf->ref, pfconf->threads);
if (ConfGet("pfring.cluster-id", &tmpclusterid) != 1) {
SCLogError(SC_ERR_INVALID_ARGUMENT,"Could not get cluster-id from config");
} else {
@ -190,6 +205,9 @@ void *ParsePfringConfig(const char *iface)
#ifdef HAVE_PFRING_CLUSTER_TYPE
pfconf->ctype = (cluster_type)default_ctype;
#endif
pfconf->DerefFunc = PfringDerefConfig;
SC_ATOMIC_INIT(pfconf->ref);
SC_ATOMIC_ADD(pfconf->ref, 1);
/* Find initial node */
pf_ring_node = ConfGetNode("pfring");
@ -220,6 +238,9 @@ void *ParsePfringConfig(const char *iface)
pfconf->threads = 1;
}
SC_ATOMIC_RESET(pfconf->ref);
SC_ATOMIC_ADD(pfconf->ref, pfconf->threads);
/* command line value has precedence */
if (ConfGet("pfring.cluster-id", &tmpclusterid) == 1) {
pfconf->cluster_id = (uint16_t)atoi(tmpclusterid);

@ -556,8 +556,10 @@ TmEcode ReceiveAFPThreadInit(ThreadVars *tv, void *initdata, void **data) {
}
AFPThreadVars *ptv = SCMalloc(sizeof(AFPThreadVars));
if (ptv == NULL)
if (ptv == NULL) {
afpconfig->DerefFunc(afpconfig);
SCReturnInt(TM_ECODE_FAILED);
}
memset(ptv, 0, sizeof(AFPThreadVars));
ptv->tv = tv;
@ -586,6 +588,7 @@ TmEcode ReceiveAFPThreadInit(ThreadVars *tv, void *initdata, void **data) {
if (r < 0) {
SCLogError(SC_ERR_AFP_CREATE, "Couldn't init AF_PACKET socket");
SCFree(ptv);
afpconfig->DerefFunc(afpconfig);
SCReturnInt(TM_ECODE_FAILED);
}
@ -599,6 +602,7 @@ TmEcode ReceiveAFPThreadInit(ThreadVars *tv, void *initdata, void **data) {
#define T_DATA_SIZE 70000
ptv->data = SCMalloc(T_DATA_SIZE);
if (ptv->data == NULL) {
afpconfig->DerefFunc(afpconfig);
SCReturnInt(TM_ECODE_FAILED);
}
ptv->datalen = T_DATA_SIZE;
@ -607,8 +611,7 @@ TmEcode ReceiveAFPThreadInit(ThreadVars *tv, void *initdata, void **data) {
*data = (void *)ptv;
/* we've received a single use structure, we can free it */
SCFree(initdata);
afpconfig->DerefFunc(afpconfig);
SCReturnInt(TM_ECODE_OK);
}

@ -51,6 +51,8 @@ typedef struct AFPIfaceConfig_
int cluster_type;
/* promisc mode */
int promisc;
SC_ATOMIC_DECLARE(unsigned int, ref);
void (*DerefFunc)(void *);
} AFPIfaceConfig;
void TmModuleReceiveAFPRegister (void);

@ -295,8 +295,10 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
}
PcapThreadVars *ptv = SCMalloc(sizeof(PcapThreadVars));
if (ptv == NULL)
if (ptv == NULL) {
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED);
}
memset(ptv, 0, sizeof(PcapThreadVars));
ptv->tv = tv;
@ -308,6 +310,7 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
if (ptv->pcap_handle == NULL) {
SCLogError(SC_ERR_PCAP_CREATE, "Coudn't create a new pcap handler, error %s", pcap_geterr(ptv->pcap_handle));
SCFree(ptv);
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED);
}
@ -317,6 +320,7 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
if (pcap_set_snaplen_r != 0) {
SCLogError(SC_ERR_PCAP_SET_SNAPLEN, "Couldn't set snaplen, error: %s", pcap_geterr(ptv->pcap_handle));
SCFree(ptv);
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED);
}
@ -325,6 +329,7 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
if (pcap_set_promisc_r != 0) {
SCLogError(SC_ERR_PCAP_SET_PROMISC, "Couldn't set promisc mode, error %s", pcap_geterr(ptv->pcap_handle));
SCFree(ptv);
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED);
}
@ -333,6 +338,7 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
if (pcap_set_timeout_r != 0) {
SCLogError(SC_ERR_PCAP_SET_TIMEOUT, "Problems setting timeout, error %s", pcap_geterr(ptv->pcap_handle));
SCFree(ptv);
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED);
}
#ifdef HAVE_PCAP_SET_BUFF
@ -345,6 +351,7 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
if (pcap_set_buffer_size_r != 0) {
SCLogError(SC_ERR_PCAP_SET_BUFF_SIZE, "Problems setting pcap buffer size, error %s", pcap_geterr(ptv->pcap_handle));
SCFree(ptv);
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED);
}
}
@ -356,6 +363,7 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
if (pcap_activate_r != 0) {
SCLogError(SC_ERR_PCAP_ACTIVATE_HANDLE, "Couldn't activate the pcap handler, error %s", pcap_geterr(ptv->pcap_handle));
SCFree(ptv);
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED);
ptv->pcap_state = PCAP_STATE_DOWN;
} else {
@ -365,28 +373,34 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
/* set bpf filter if we have one */
if (pcapconfig->bpf_filter) {
ptv->bpf_filter = SCStrdup(pcapconfig->bpf_filter);
/* free bpf as we are using a copy */
SCFree(pcapconfig->bpf_filter);
if(pcap_compile(ptv->pcap_handle,&ptv->filter,ptv->bpf_filter,1,0) < 0) {
SCLogError(SC_ERR_BPF,"bpf compilation error %s",pcap_geterr(ptv->pcap_handle));
SCFree(ptv);
pcapconfig->DerefFunc(pcapconfig);
return TM_ECODE_FAILED;
}
if(pcap_setfilter(ptv->pcap_handle,&ptv->filter) < 0) {
SCLogError(SC_ERR_BPF,"could not set bpf filter %s",pcap_geterr(ptv->pcap_handle));
SCFree(ptv);
pcapconfig->DerefFunc(pcapconfig);
return TM_ECODE_FAILED;
}
}
ptv->datalink = pcap_datalink(ptv->pcap_handle);
pcapconfig->DerefFunc(pcapconfig);
*data = (void *)ptv;
SCReturnInt(TM_ECODE_OK);
}
#else /* implied LIBPCAP_VERSION_MAJOR == 0 */
TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
SCEnter();
PcapIfaceConfig *pcapconfig = initdata;
char *tmpbpfstring;
if (initdata == NULL) {
@ -395,8 +409,11 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
}
PcapThreadVars *ptv = SCMalloc(sizeof(PcapThreadVars));
if (ptv == NULL)
if (ptv == NULL) {
/* Dereference config */
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED);
}
memset(ptv, 0, sizeof(PcapThreadVars));
ptv->tv = tv;
@ -404,6 +421,8 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
SCLogInfo("using interface %s", (char *)initdata);
if(strlen(initdata)>PCAP_IFACE_NAME_LENGTH) {
SCFree(ptv);
/* Dereference config */
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED);
}
strlcpy(ptv->iface, (char *)initdata, PCAP_IFACE_NAME_LENGTH);
@ -414,6 +433,8 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
if (ptv->pcap_handle == NULL) {
SCLogError(SC_ERR_PCAP_OPEN_LIVE, "Problem creating pcap handler for live mode, error %s", errbuf);
SCFree(ptv);
/* Dereference config */
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED);
}
@ -425,20 +446,25 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
if(pcap_compile(ptv->pcap_handle,&ptv->filter, ptv->bpf_filter,1,0) < 0) {
SCLogError(SC_ERR_BPF,"bpf compilation error %s",pcap_geterr(ptv->pcap_handle));
SCFree(ptv);
/* Dereference config */
pcapconfig->DerefFunc(pcapconfig);
return TM_ECODE_FAILED;
}
if(pcap_setfilter(ptv->pcap_handle,&ptv->filter) < 0) {
SCLogError(SC_ERR_BPF,"could not set bpf filter %s",pcap_geterr(ptv->pcap_handle));
SCFree(ptv);
/* Dereference config */
pcapconfig->DerefFunc(pcapconfig);
return TM_ECODE_FAILED;
}
}
ptv->datalink = pcap_datalink(ptv->pcap_handle);
*data = (void *)ptv;
/* Dereference config */
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_OK);
}
#endif /* LIBPCAP_VERSION_MAJOR */

@ -51,6 +51,8 @@ typedef struct PcapIfaceConfig_
int buffer_size;
/* BPF filter */
char *bpf_filter;
SC_ATOMIC_DECLARE(unsigned int, ref);
void (*DerefFunc)(void *);
} PcapIfaceConfig;

@ -275,9 +275,15 @@ TmEcode ReceivePfringThreadInit(ThreadVars *tv, void *initdata, void **data) {
char *tmpctype;
PfringIfaceConfig *pfconf = (PfringIfaceConfig *) initdata;
if (pfconf == NULL)
return TM_ECODE_FAILED;
PfringThreadVars *ptv = SCMalloc(sizeof(PfringThreadVars));
if (ptv == NULL)
if (ptv == NULL) {
pfconf->DerefFunc(pfconf);
return TM_ECODE_FAILED;
}
memset(ptv, 0, sizeof(PfringThreadVars));
ptv->tv = tv;
@ -289,6 +295,7 @@ TmEcode ReceivePfringThreadInit(ThreadVars *tv, void *initdata, void **data) {
if (ptv->pd == NULL) {
SCLogError(SC_ERR_PF_RING_OPEN,"opening %s failed: pfring_open error",
ptv->interface);
pfconf->DerefFunc(pfconf);
return TM_ECODE_FAILED;
} else {
pfring_set_application_name(ptv->pd, PROG_NAME);
@ -311,6 +318,7 @@ TmEcode ReceivePfringThreadInit(ThreadVars *tv, void *initdata, void **data) {
if (rc != 0) {
SCLogError(SC_ERR_PF_RING_SET_CLUSTER_FAILED, "pfring_set_cluster "
"returned %d for cluster-id: %d", rc, ptv->cluster_id);
pfconf->DerefFunc(pfconf);
return TM_ECODE_FAILED;
}
SCLogInfo("(%s) Using PF_RING v.%d.%d.%d, interface %s, cluster-id %d",
@ -329,12 +337,14 @@ TmEcode ReceivePfringThreadInit(ThreadVars *tv, void *initdata, void **data) {
if (rc != 0) {
SCLogError(SC_ERR_PF_RING_OPEN, "pfring_enable failed returned %d ", rc);
pfconf->DerefFunc(pfconf);
return TM_ECODE_FAILED;
}
#endif /* HAVE_PFRING_ENABLE */
*data = (void *)ptv;
pfconf->DerefFunc(pfconf);
return TM_ECODE_OK;
}

@ -41,6 +41,8 @@ typedef struct PfringIfaceConfig_
char iface[PFRING_IFACE_NAME_LENGTH];
/* number of threads */
int threads;
SC_ATOMIC_DECLARE(unsigned int, ref);
void (*DerefFunc)(void *);
} PfringIfaceConfig;

Loading…
Cancel
Save