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
*
}
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");
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 {
#include "util-affinity.h"
#include "util-device.h"
#include "util-runmodes.h"
+#include "util-atomic.h"
static const char *default_mode = NULL;
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)
{
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) {
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
*
#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) {
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 {
#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");
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);
}
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;
if (r < 0) {
SCLogError(SC_ERR_AFP_CREATE, "Couldn't init AF_PACKET socket");
SCFree(ptv);
+ afpconfig->DerefFunc(afpconfig);
SCReturnInt(TM_ECODE_FAILED);
}
#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;
*data = (void *)ptv;
- /* we've received a single use structure, we can free it */
- SCFree(initdata);
+ afpconfig->DerefFunc(afpconfig);
SCReturnInt(TM_ECODE_OK);
}
int cluster_type;
/* promisc mode */
int promisc;
+ SC_ATOMIC_DECLARE(unsigned int, ref);
+ void (*DerefFunc)(void *);
} AFPIfaceConfig;
void TmModuleReceiveAFPRegister (void);
}
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;
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);
}
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);
}
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);
}
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
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);
}
}
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 {
/* 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) {
}
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;
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);
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);
}
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 */
int buffer_size;
/* BPF filter */
char *bpf_filter;
+ SC_ATOMIC_DECLARE(unsigned int, ref);
+ void (*DerefFunc)(void *);
} PcapIfaceConfig;
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;
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);
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",
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;
}
char iface[PFRING_IFACE_NAME_LENGTH];
/* number of threads */
int threads;
+ SC_ATOMIC_DECLARE(unsigned int, ref);
+ void (*DerefFunc)(void *);
} PfringIfaceConfig;