Exemple #1
0
static inline rsRetVal
addEntry(struct sockaddr_storage *addr, dnscache_entry_t **pEtry)
{
    int r;
    struct sockaddr_storage *keybuf;
    dnscache_entry_t *etry = NULL;
    DEFiRet;

    CHKmalloc(etry = MALLOC(sizeof(dnscache_entry_t)));
    CHKiRet(resolveAddr(addr, etry));
    memcpy(&etry->addr, addr, SALEN((struct sockaddr*) addr));
    etry->nUsed = 0;
    *pEtry = etry;

    CHKmalloc(keybuf = malloc(sizeof(struct sockaddr_storage)));
    memcpy(keybuf, addr, sizeof(struct sockaddr_storage));

    pthread_rwlock_unlock(&dnsCache.rwlock); /* release read lock */
    pthread_rwlock_wrlock(&dnsCache.rwlock); /* and re-aquire for writing */
    r = hashtable_insert(dnsCache.ht, keybuf, *pEtry);
    if(r == 0) {
        DBGPRINTF("dnscache: inserting element failed\n");
    }
    pthread_rwlock_unlock(&dnsCache.rwlock);
    pthread_rwlock_rdlock(&dnsCache.rwlock); /* we need this again */

finalize_it:
    if(iRet != RS_RET_OK && etry != NULL) {
        /* Note: sub-fields cannot be populated in this case */
        free(etry);
    }
    RETiRet;
}
Exemple #2
0
addEntry(struct sockaddr_storage *const addr, dnscache_entry_t **const pEtry)
{
	int r;
	dnscache_entry_t *etry = NULL;
	DEFiRet;

	/* entry still does not exist, so add it */
	struct sockaddr_storage *const keybuf =  malloc(sizeof(struct sockaddr_storage));
	CHKmalloc(keybuf);
	CHKmalloc(etry = malloc(sizeof(dnscache_entry_t)));
	resolveAddr(addr, etry);
	assert(etry != NULL);
	memcpy(&etry->addr, addr, SALEN((struct sockaddr*) addr));
	etry->nUsed = 0;
	if(dnscacheEnableTTL) {
		etry->validUntil = time(NULL) + dnscacheDefaultTTL;
	}

	memcpy(keybuf, addr, sizeof(struct sockaddr_storage));

	r = hashtable_insert(dnsCache.ht, keybuf, etry);
	if(r == 0) {
		DBGPRINTF("dnscache: inserting element failed\n");
	}
	*pEtry = etry;

finalize_it:
	if(iRet != RS_RET_OK) {
		free(keybuf);
	}
	RETiRet;
}
Exemple #3
0
/* add a counter to an object
 * ctrName is duplicated, caller must free it if requried
 * NOTE: The counter is READ-ONLY and MUST NOT be modified (most
 * importantly, it must not be initialized, so the caller must
 * ensure the counter is properly initialized before AddCounter()
 * is called.
 */
static rsRetVal
addCounter(statsobj_t *pThis, uchar *ctrName, statsCtrType_t ctrType, int8_t flags, void *pCtr)
{
	ctr_t *ctr;
	DEFiRet;

	CHKmalloc(ctr = malloc(sizeof(ctr_t)));
	ctr->next = NULL;
	ctr->prev = NULL;
	CHKmalloc(ctr->name = ustrdup(ctrName));
	ctr->flags = flags;
	ctr->ctrType = ctrType;
	switch(ctrType) {
	case ctrType_IntCtr:
		ctr->val.pIntCtr = (intctr_t*) pCtr;
		break;
	case ctrType_Int:
		ctr->val.pInt = (int*) pCtr;
		break;
	}
	addCtrToList(pThis, ctr);

finalize_it:
	RETiRet;
}
Exemple #4
0
/* create a new lookup table object AND include it in our list of
 * lookup tables.
 */
rsRetVal
lookupNew(lookup_ref_t **ppThis)
{
	lookup_ref_t *pThis = NULL;
	lookup_t *t = NULL;
	DEFiRet;

	CHKmalloc(pThis = calloc(1, sizeof(lookup_ref_t)));
	CHKmalloc(t = calloc(1, sizeof(lookup_t)));
	pthread_rwlock_init(&pThis->rwlock, NULL);
	pthread_mutex_init(&pThis->reloader_mut, NULL);
	pthread_cond_init(&pThis->run_reloader, NULL);
	pthread_attr_init(&pThis->reloader_thd_attr);
	pThis->do_reload = pThis->do_stop = 0;
	pThis->reload_on_hup = 1; /*DO reload on HUP (default)*/
	pthread_create(&pThis->reloader, &pThis->reloader_thd_attr, lookupTableReloader, pThis);

	pThis->next = NULL;
	if(loadConf->lu_tabs.root == NULL) {
		loadConf->lu_tabs.root = pThis;
	} else {
		loadConf->lu_tabs.last->next = pThis;
	}
	loadConf->lu_tabs.last = pThis;

	pThis->self = t;

	*ppThis = pThis;
finalize_it:
	if(iRet != RS_RET_OK) {
		free(t);
		free(pThis);
	}
	RETiRet;
}
Exemple #5
0
/* this reloads a lookup table. This is done while the engine is running,
 * as such the function must ensure proper locking and proper order of
 * operations (so that nothing can interfere). If the table cannot be loaded,
 * the old table is continued to be used.
 */
static rsRetVal
lookupReload(lookup_t *pThis)
{
	uint32_t i;
	lookup_t newlu; /* dummy to be able to use support functions without 
	                   affecting current settings. */
	DEFiRet;
	
	DBGPRINTF("reload requested for lookup table '%s'\n", pThis->name);
	memset(&newlu, 0, sizeof(newlu));
	CHKmalloc(newlu.name = ustrdup(pThis->name));
	CHKmalloc(newlu.filename = ustrdup(pThis->filename));
	CHKiRet(lookupReadFile(&newlu));
	/* all went well, copy over data members */
	pthread_rwlock_wrlock(&pThis->rwlock);
	for(i = 0 ; i < pThis->nmemb ; ++i) {
		free(pThis->d.strtab[i].key), /* we don't care about exec order of frees */
		free(pThis->d.strtab[i].val);
	}
	free(pThis->d.strtab);
	pThis->d.strtab = newlu.d.strtab; /* hand table AND ALL STRINGS over! */
	pthread_rwlock_unlock(&pThis->rwlock);
	errmsg.LogError(0, RS_RET_OK, "lookup table '%s' reloaded from file '%s'",
			pThis->name, pThis->filename);
finalize_it:
	free(newlu.name);
	free(newlu.filename);
	RETiRet;
}
Exemple #6
0
/* ConstructionFinalizer */
static rsRetVal
tcpsrvConstructFinalize(tcpsrv_t *pThis)
{
	DEFiRet;
	ISOBJ_TYPE_assert(pThis, tcpsrv);

	/* prepare network stream subsystem */
	CHKiRet(netstrms.Construct(&pThis->pNS));
	if(pThis->pszDrvrName != NULL)
		CHKiRet(netstrms.SetDrvrName(pThis->pNS, pThis->pszDrvrName));
	CHKiRet(netstrms.SetDrvrMode(pThis->pNS, pThis->iDrvrMode));
	if(pThis->pszDrvrAuthMode != NULL)
		CHKiRet(netstrms.SetDrvrAuthMode(pThis->pNS, pThis->pszDrvrAuthMode));
	if(pThis->pPermPeers != NULL)
		CHKiRet(netstrms.SetDrvrPermPeers(pThis->pNS, pThis->pPermPeers));
	CHKiRet(netstrms.ConstructFinalize(pThis->pNS));

	/* set up listeners */
	CHKmalloc(pThis->ppLstn = calloc(pThis->iLstnMax, sizeof(netstrm_t*)));
	CHKmalloc(pThis->ppLstnPort = calloc(pThis->iLstnMax, sizeof(tcpLstnPortList_t*)));
	iRet = pThis->OpenLstnSocks(pThis);

finalize_it:
	if(iRet != RS_RET_OK) {
		if(pThis->pNS != NULL)
			netstrms.Destruct(&pThis->pNS);
		errmsg.LogError(0, iRet, "tcpsrv could not create listener (inputname: '%s')",
				(pThis->pszInputName == NULL) ? (uchar*)"*UNSET*" : pThis->pszInputName);
	}
	RETiRet;
}
Exemple #7
0
/* get the name of the local host. A pointer to a character pointer is passed
 * in, which on exit points to the local hostname. This buffer is dynamically
 * allocated and must be free()ed by the caller. If the functions returns an
 * error, the pointer is NULL. This function is based on GNU/Hurd's localhostname
 * function.
 * rgerhards, 20080-04-10
 */
static rsRetVal
getLocalHostname(uchar **ppName)
{
	DEFiRet;
	uchar *buf = NULL;
	size_t buf_len = 0;

	assert(ppName != NULL);

	do {
		if(buf == NULL) {
			buf_len = 128;        /* Initial guess */
			CHKmalloc(buf = MALLOC(buf_len));
		} else {
			uchar *p;

			buf_len += buf_len;
			CHKmalloc(p = realloc (buf, buf_len));
			buf = p;
		}
	} while((gethostname((char*)buf, buf_len) == 0 && !memchr (buf, '\0', buf_len)) || errno == ENAMETOOLONG);

	*ppName = buf;
	buf = NULL;

finalize_it:
	if(iRet != RS_RET_OK) {
		if(buf != NULL)
			free(buf);
	}
	RETiRet;
}
Exemple #8
0
/* get the name of the local host. A pointer to a character pointer is passed
 * in, which on exit points to the local hostname. This buffer is dynamically
 * allocated and must be free()ed by the caller. If the functions returns an
 * error, the pointer is NULL.
 * This function always tries to return a FQDN, even so be quering DNS. So it
 * is safe to assume for the caller that when the function does not return
 * a FQDN, it simply is not available. The domain part of that string is
 * normalized to lower case. The hostname is kept in mixed case for historic
 * reasons.
 */
static rsRetVal
getLocalHostname(uchar **ppName)
{
	DEFiRet;
	char hnbuf[8192];
	uchar *fqdn = NULL;

	if(gethostname(hnbuf, sizeof(hnbuf)) != 0) {
		strcpy(hnbuf, "localhost");
	} else {
		hnbuf[sizeof(hnbuf)-1] = '\0'; /* be on the safe side... */
	}
	char *dot = strstr(hnbuf, ".");
	if(dot == NULL) {
		/* we need to (try) to find the real name via resolver */
		struct hostent *hent = gethostbyname((char*)hnbuf);
		if(hent) {
			int i = 0;
			if(hent->h_aliases) {
				const size_t hnlen = strlen(hnbuf);
				for(i = 0; hent->h_aliases[i]; i++) {
					if(!strncmp(hent->h_aliases[i], hnbuf, hnlen)
					   && hent->h_aliases[i][hnlen] == '.') {
						break; /* match! */
					}
				}
			}
			if(hent->h_aliases && hent->h_aliases[i]) {
				CHKmalloc(fqdn = (uchar*)strdup(hent->h_aliases[i]));
			} else {
				CHKmalloc(fqdn = (uchar*)strdup(hent->h_name));
			}
			dot = strstr((char*)fqdn, ".");
		}
	}

	if(fqdn == NULL) {
		/* already was FQDN or we could not obtain a better one */
		CHKmalloc(fqdn = (uchar*) strdup(hnbuf));
	}

	if(dot != NULL)
		for(char *p = dot+1 ; *p ; ++p)
			*p = tolower(*p);

	*ppName = fqdn;
finalize_it:
	RETiRet;
}
Exemple #9
0
/* add new listener port to listener port list
 * rgerhards, 2009-05-21
 */
static inline rsRetVal
addNewLstnPort(tcpsrv_t *pThis, uchar *pszPort, int bSuppOctetFram, uchar *pszAddr)
{
	tcpLstnPortList_t *pEntry;
	uchar statname[64];
	DEFiRet;

	ISOBJ_TYPE_assert(pThis, tcpsrv);

	/* create entry */
	CHKmalloc(pEntry = MALLOC(sizeof(tcpLstnPortList_t)));
	CHKmalloc(pEntry->pszPort = ustrdup(pszPort));

        pEntry->pszAddr = NULL; // Initalize address to null
        /* only if a bind adress is defined copy it in struct */
        if (pszAddr != NULL) CHKmalloc(pEntry->pszAddr = ustrdup(pszAddr));

	strcpy((char*)pEntry->dfltTZ, (char*)pThis->dfltTZ);
	pEntry->bSPFramingFix = pThis->bSPFramingFix;
	pEntry->pSrv = pThis;
	pEntry->pRuleset = pThis->pRuleset;
	pEntry->bSuppOctetFram = bSuppOctetFram;

	/* we need to create a property */ 
	CHKiRet(prop.Construct(&pEntry->pInputName));
	CHKiRet(prop.SetString(pEntry->pInputName, pThis->pszInputName, ustrlen(pThis->pszInputName)));
	CHKiRet(prop.ConstructFinalize(pEntry->pInputName));

	/* and add to list */
	pEntry->pNext = pThis->pLstnPorts;
	pThis->pLstnPorts = pEntry;

	/* support statistics gathering */
	CHKiRet(statsobj.Construct(&(pEntry->stats)));
	snprintf((char*)statname, sizeof(statname), "%s(%s)", pThis->pszInputName, pszPort);
	statname[sizeof(statname)-1] = '\0'; /* just to be on the save side... */
	CHKiRet(statsobj.SetName(pEntry->stats, statname));
	CHKiRet(statsobj.SetOrigin(pEntry->stats, pThis->pszOrigin));
	CHKiRet(ratelimitNew(&pEntry->ratelimiter, "tcperver", NULL));
	ratelimitSetLinuxLike(pEntry->ratelimiter, pThis->ratelimitInterval, pThis->ratelimitBurst);
	ratelimitSetThreadSafe(pEntry->ratelimiter);
	STATSCOUNTER_INIT(pEntry->ctrSubmit, pEntry->mutCtrSubmit);
	CHKiRet(statsobj.AddCounter(pEntry->stats, UCHAR_CONSTANT("submitted"),
		ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pEntry->ctrSubmit)));
	CHKiRet(statsobj.ConstructFinalize(pEntry->stats));

finalize_it:
	RETiRet;
}
Exemple #10
0
/* extract a groupname and return its gid.
 * rgerhards, 2007-07-17
 */
static rsRetVal doGetGID(uchar **pp, rsRetVal (*pSetHdlr)(void*, uid_t), void *pVal)
{
	struct group *pgBuf = NULL;
	struct group gBuf;
	DEFiRet;
	uchar szName[256];
	int bufSize = 2048;
	char * stringBuf = NULL;

	assert(pp != NULL);
	assert(*pp != NULL);

	if(getSubString(pp, (char*) szName, sizeof(szName) / sizeof(uchar), ' ')  != 0) {
		errmsg.LogError(0, RS_RET_NOT_FOUND, "could not extract group name");
		ABORT_FINALIZE(RS_RET_NOT_FOUND);
	}


	CHKmalloc(stringBuf = malloc(bufSize));
	while(pgBuf == NULL) {
		errno = 0;
		getgrnam_r((char*)szName, &gBuf, stringBuf, bufSize, &pgBuf);
		if((pgBuf == NULL) && (errno == ERANGE)) {
			/* Increase bufsize and try again.*/
			bufSize *= 2;
			CHKmalloc(stringBuf = realloc(stringBuf, bufSize));
		}
	}

	if(pgBuf == NULL) {
		errmsg.LogError(0, RS_RET_NOT_FOUND, "ID for group '%s' could not be found or error", (char*)szName);
		iRet = RS_RET_NOT_FOUND;
	} else {
		if(pSetHdlr == NULL) {
			/* we should set value directly to var */
			*((gid_t*)pVal) = pgBuf->gr_gid;
		} else {
			/* we set value via a set function */
			CHKiRet(pSetHdlr(pVal, pgBuf->gr_gid));
		}
		dbgprintf("gid %d obtained for group '%s'\n", (int) pgBuf->gr_gid, szName);
	}

	skipWhiteSpace(pp); /* skip over any whitespace */

finalize_it:
	free(stringBuf);
	RETiRet;
}
Exemple #11
0
/* create a new lookup table object AND include it in our list of
 * lookup tables.
 */
static rsRetVal
lookupNew(lookup_ref_t **ppThis)
{
	lookup_ref_t *pThis = NULL;
	lookup_t *t = NULL;
	int initialized = 0;
	DEFiRet;

	CHKmalloc(pThis = calloc(1, sizeof(lookup_ref_t)));
	CHKmalloc(t = calloc(1, sizeof(lookup_t)));
	CHKiConcCtrl(pthread_rwlock_init(&pThis->rwlock, NULL));
	initialized++; /*1*/
	CHKiConcCtrl(pthread_mutex_init(&pThis->reloader_mut, NULL));
	initialized++; /*2*/
	CHKiConcCtrl(pthread_cond_init(&pThis->run_reloader, NULL));
	initialized++; /*3*/
	CHKiConcCtrl(pthread_attr_init(&pThis->reloader_thd_attr));
	initialized++; /*4*/
	pThis->do_reload = pThis->do_stop = 0;
	pThis->reload_on_hup = 1; /*DO reload on HUP (default)*/
	CHKiConcCtrl(pthread_create(&pThis->reloader, &pThis->reloader_thd_attr, lookupTableReloader, pThis));
	initialized++; /*5*/

	pThis->next = NULL;
	if(loadConf->lu_tabs.root == NULL) {
		loadConf->lu_tabs.root = pThis;
	} else {
		loadConf->lu_tabs.last->next = pThis;
	}
	loadConf->lu_tabs.last = pThis;

	pThis->self = t;

	*ppThis = pThis;
finalize_it:
	if(iRet != RS_RET_OK) {
		errmsg.LogError(errno, iRet, "a lookup table could not be initialized: failed at init-step %d "
		"(please enable debug logs for details)", initialized);
		if (initialized > 4) lookupStopReloader(pThis);
		if (initialized > 3) pthread_attr_destroy(&pThis->reloader_thd_attr);
		if (initialized > 2) pthread_cond_destroy(&pThis->run_reloader);
		if (initialized > 1) pthread_mutex_destroy(&pThis->reloader_mut);
		if (initialized > 0) pthread_rwlock_destroy(&pThis->rwlock);
		free(t);
		free(pThis);
	}
	RETiRet;
}
Exemple #12
0
/* add new entry to list. We assume that the fd is not already present and DO NOT check this!
 * Returns newly created entry in pEvtLst.
 * Note that we currently need to use level-triggered mode, because the upper layers do not work
 * in parallel. As such, in edge-triggered mode we may not get notified, because new data comes
 * in after we have read everything that was present. To use ET mode, we need to change the upper
 * peers so that they immediately start a new wait before processing the data read. That obviously
 * requires more elaborate redesign and we postpone this until the current more simplictic mode has
 * been proven OK in practice.
 * rgerhards, 2009-11-18
 */
static inline rsRetVal
addEvent(nsdpoll_ptcp_t *pThis, int id, void *pUsr, int mode, nsd_ptcp_t *pSock, nsdpoll_epollevt_lst_t **pEvtLst) {
	nsdpoll_epollevt_lst_t *pNew;
	DEFiRet;

	CHKmalloc(pNew = (nsdpoll_epollevt_lst_t*) calloc(1, sizeof(nsdpoll_epollevt_lst_t)));
	pNew->id = id;
	pNew->pUsr = pUsr;
	pNew->pSock = pSock;
	pNew->event.events = 0; /* TODO: at some time we should be able to use EPOLLET */
	//pNew->event.events = EPOLLET;
	if(mode & NSDPOLL_IN)
		pNew->event.events |= EPOLLIN;
	if(mode & NSDPOLL_OUT)
		pNew->event.events |= EPOLLOUT;
	pNew->event.data.ptr = pNew;
	pthread_mutex_lock(&pThis->mutEvtLst);
	pNew->pNext = pThis->pRoot;
	pThis->pRoot = pNew;
	pthread_mutex_unlock(&pThis->mutEvtLst);
	*pEvtLst = pNew;

finalize_it:
	RETiRet;
}
Exemple #13
0
/* Add a parser to the list. We use a VERY simple and ineffcient algorithm,
 * but it is employed only for a few milliseconds during config processing. So
 * I prefer to keep it very simple and with simple data structures. Unfortunately,
 * we need to preserve the order, but I don't like to add a tail pointer as that
 * would require a container object. So I do the extra work to skip to the tail
 * when adding elements...
 * rgerhards, 2009-11-03
 */
static rsRetVal
AddParserToList(parserList_t **ppListRoot, parser_t *pParser)
{
	parserList_t *pThis;
	parserList_t *pTail;
	DEFiRet;

	CHKmalloc(pThis = MALLOC(sizeof(parserList_t)));
	pThis->pParser = pParser;
	pThis->pNext = NULL;

	if(*ppListRoot == NULL) {
		pThis->pNext = *ppListRoot;
		*ppListRoot = pThis;
	} else {
		/* find tail first */
		for(pTail = *ppListRoot ; pTail->pNext != NULL ; pTail = pTail->pNext)
			/* just search, do nothing else */;
		/* add at tail */
		pTail->pNext = pThis;
	}
DBGPRINTF("DDDDD: added parser '%s' to list %p\n", pParser->pName, ppListRoot);
finalize_it:
	RETiRet;
}
Exemple #14
0
/* add a function to the function registry.
 * The handed-over cstr_t* object must no longer be used by the caller.
 * A duplicate function name is an error.
 * rgerhards, 2009-04-06
 */
static rsRetVal
rsfrAddFunction(uchar *szName, prsf_t rsf)
{
	rsf_entry_t *pEntry;
	size_t lenName;
	DEFiRet;

	assert(szName != NULL);
	assert(rsf != NULL);

	/* first check if we have a duplicate name, with the current approach this means
	 * we need to go through the whole list.
	 */
	lenName = strlen((char*)szName);
	for(pEntry = funcRegRoot ; pEntry != NULL ; pEntry = pEntry->pNext)
		if(!rsCStrSzStrCmp(pEntry->pName, szName, lenName))
			ABORT_FINALIZE(RS_RET_DUP_FUNC_NAME);

	/* unique name, so add to head of list */
	CHKmalloc(pEntry = calloc(1, sizeof(rsf_entry_t)));
	CHKiRet(rsCStrConstructFromszStr(&pEntry->pName, szName));
	CHKiRet(cstrFinalize(pEntry->pName));
	pEntry->rsf = rsf;
	pEntry->pNext = funcRegRoot;
	funcRegRoot = pEntry;

finalize_it:
	if(iRet != RS_RET_OK && iRet != RS_RET_DUP_FUNC_NAME)
		free(pEntry);

	RETiRet;
}
Exemple #15
0
/* Add a strgen to the list. We use a VERY simple and ineffcient algorithm,
 * but it is employed only for a few milliseconds during config processing. So
 * I prefer to keep it very simple and with simple data structures. Unfortunately,
 * we need to preserve the order, but I don't like to add a tail pointer as that
 * would require a container object. So I do the extra work to skip to the tail
 * when adding elements...
 */
static rsRetVal
AddStrgenToList(strgenList_t **ppListRoot, strgen_t *pStrgen)
{
	strgenList_t *pThis;
	strgenList_t *pTail;
	DEFiRet;

	CHKmalloc(pThis = MALLOC(sizeof(strgenList_t)));
	pThis->pStrgen = pStrgen;
	pThis->pNext = NULL;

	if(*ppListRoot == NULL) {
		pThis->pNext = *ppListRoot;
		*ppListRoot = pThis;
	} else {
		/* find tail first */
		for(pTail = *ppListRoot ; pTail->pNext != NULL ; pTail = pTail->pNext)
			/* just search, do nothing else */;
		/* add at tail */
		pTail->pNext = pThis;
	}

finalize_it:
	RETiRet;
}
Exemple #16
0
/* Construction finalizer
 * rgerhards, 2008-01-17
 */
rsRetVal
wtiConstructFinalize(wti_t *pThis)
{
	DEFiRet;
	int iDeqBatchSize;

	ISOBJ_TYPE_assert(pThis, wti);

	DBGPRINTF("%s: finalizing construction of worker instance data (for %d actions)\n",
		  wtiGetDbgHdr(pThis), iActionNbr);

	/* initialize our thread instance descriptor (no concurrency here) */
	pThis->bIsRunning = WRKTHRD_STOPPED;

	/* must use calloc as we need zero-init */
	CHKmalloc(pThis->actWrkrInfo = calloc(iActionNbr, sizeof(actWrkrInfo_t)));

	if(pThis->pWtp == NULL) {
		dbgprintf("wtiConstructFinalize: pWtp not set, this may be intentional\n");
		FINALIZE;
	}

	/* we now alloc the array for user pointers. We obtain the max from the queue itself. */
	CHKiRet(pThis->pWtp->pfGetDeqBatchSize(pThis->pWtp->pUsr, &iDeqBatchSize));
	CHKiRet(batchInit(&pThis->batch, iDeqBatchSize));

finalize_it:
	RETiRet;
}
Exemple #17
0
/* note: this function is only called once in action.c */
rsRetVal
wtiNewIParam(wti_t *const pWti, action_t *const pAction, actWrkrIParams_t **piparams)
{
	actWrkrInfo_t *const wrkrInfo = &(pWti->actWrkrInfo[pAction->iActionNbr]);
	actWrkrIParams_t *iparams;
	int newMax;
	DEFiRet;

	if(wrkrInfo->p.tx.currIParam == wrkrInfo->p.tx.maxIParams) {
		/* we need to extend */
		newMax = (wrkrInfo->p.tx.maxIParams == 0) ? CONF_IPARAMS_BUFSIZE
							  : 2 * wrkrInfo->p.tx.maxIParams;
		CHKmalloc(iparams = realloc(wrkrInfo->p.tx.iparams,
					    sizeof(actWrkrIParams_t) * pAction->iNumTpls * newMax));
		memset(iparams + (wrkrInfo->p.tx.currIParam * pAction->iNumTpls), 0,
		       sizeof(actWrkrIParams_t) * pAction->iNumTpls * (newMax - wrkrInfo->p.tx.maxIParams));
		wrkrInfo->p.tx.iparams = iparams;
		wrkrInfo->p.tx.maxIParams = newMax;
	}
	*piparams = wrkrInfo->p.tx.iparams + wrkrInfo->p.tx.currIParam * pAction->iNumTpls;
	++wrkrInfo->p.tx.currIParam;

finalize_it:
	RETiRet;
}
Exemple #18
0
/* create a new lookup table object AND include it in our list of
 * lookup tables.
 */
rsRetVal
lookupNew(lookup_t **ppThis)
{
	lookup_t *pThis = NULL;
	DEFiRet;

	CHKmalloc(pThis = malloc(sizeof(lookup_t)));
	pthread_rwlock_init(&pThis->rwlock, NULL);
	pThis->name = NULL;

	if(loadConf->lu_tabs.root == NULL) {
		loadConf->lu_tabs.root = pThis;
		pThis->next = NULL;
	} else {
		pThis->next = loadConf->lu_tabs.last;
	}
	loadConf->lu_tabs.last = pThis;

	*ppThis = pThis;
finalize_it:
	if(iRet != RS_RET_OK) {
		free(pThis);
	}
	RETiRet;
}
Exemple #19
0
/* extend the string buffer if its size is insufficient.
 * Param iMinNeeded is the minumum free space needed. If it is larger
 * than the default alloc increment, space for at least this amount is
 * allocated. In practice, a bit more is allocated because we envision that
 * some more characters may be added after these.
 * rgerhards, 2008-01-07
 * changed to utilized realloc() -- rgerhards, 2009-06-16
 */
rsRetVal
rsCStrExtendBuf(cstr_t *pThis, size_t iMinNeeded)
{
	uchar *pNewBuf;
	size_t iNewSize;
	DEFiRet;

	/* first compute the new size needed */
	if(iMinNeeded > RS_STRINGBUF_ALLOC_INCREMENT) {
		/* we allocate "n" ALLOC_INCREMENTs. Usually, that should
		 * leave some room after the absolutely needed one. It also
		 * reduces memory fragmentation. Note that all of this are
		 * integer operations (very important to understand what is
		 * going on)! Parenthesis are for better readibility.
		 */
		iNewSize = (iMinNeeded / RS_STRINGBUF_ALLOC_INCREMENT + 1) * RS_STRINGBUF_ALLOC_INCREMENT;
	} else {
		iNewSize = pThis->iBufSize + RS_STRINGBUF_ALLOC_INCREMENT;
	}
	iNewSize += pThis->iBufSize; /* add current size */

	/* DEV debugging only: dbgprintf("extending string buffer, old %d, new %d\n", pThis->iBufSize, iNewSize); */
	CHKmalloc(pNewBuf = (uchar*) realloc(pThis->pBuf, iNewSize * sizeof(uchar)));
	pThis->iBufSize = iNewSize;
	pThis->pBuf = pNewBuf;

finalize_it:
	RETiRet;
}
Exemple #20
0
/* Converts the CStr object to a classical zero-terminated C string,
 * returns that string and destroys the CStr object. The returned string
 * MUST be freed by the caller. The function might return NULL if
 * no memory can be allocated.
 *
 * This is the NEW replacement for rsCStrConvSzStrAndDestruct which does
 * no longer utilize a special buffer but soley works on pBuf (and also
 * assumes that cstrFinalize had been called).
 *
 * Parameters are as follows:
 * pointer to the object, pointer to string-pointer to receive string and
 * bRetNULL: 0 - must not return NULL on empty string, return "" in that
 * case, 1 - return NULL instead of an empty string.
 * PLEASE NOTE: the caller must free the memory returned in ppSz in any case
 * (except, of course, if it is NULL).
 */
rsRetVal cstrConvSzStrAndDestruct(cstr_t *pThis, uchar **ppSz, int bRetNULL)
{
	DEFiRet;
	uchar* pRetBuf;

	rsCHECKVALIDOBJECT(pThis, OIDrsCStr);
	assert(ppSz != NULL);
	assert(bRetNULL == 0 || bRetNULL == 1);

	if(pThis->pBuf == NULL) {
		if(bRetNULL == 0) {
			CHKmalloc(pRetBuf = MALLOC(sizeof(uchar)));
			*pRetBuf = '\0';
		} else {
			pRetBuf = NULL;
		}
	} else
		pRetBuf = pThis->pBuf;
	
	*ppSz = pRetBuf;

finalize_it:
	/* We got it, now free the object ourselfs. Please note
	 * that we can NOT use the rsCStrDestruct function as it would
	 * also free the sz String buffer, which we pass on to the user.
	 */
	RSFREEOBJ(pThis);
	RETiRet;
}
Exemple #21
0
/* load our low-level driver. This must be done before any
 * driver-specific functions (allmost all...) can be carried
 * out. Note that the driver's .ifIsLoaded is correctly
 * initialized by calloc() and we depend on that.
 * WARNING: this code is mostly identical to similar code in 
 * nssel.c - TODO: abstract it and move it to some common place.
 * rgerhards, 2008-04-18
 */
static rsRetVal
loadDrvr(netstrms_t *pThis)
{
	DEFiRet;
	uchar *pBaseDrvrName;
	uchar szDrvrName[48]; /* 48 shall be large enough */

	pBaseDrvrName = pThis->pBaseDrvrName;
	if(pBaseDrvrName == NULL) /* if no drvr name is set, use system default */
		pBaseDrvrName = glbl.GetDfltNetstrmDrvr();
	if(snprintf((char*)szDrvrName, sizeof(szDrvrName), "lmnsd_%s", pBaseDrvrName) == sizeof(szDrvrName))
		ABORT_FINALIZE(RS_RET_DRVRNAME_TOO_LONG);
	CHKmalloc(pThis->pDrvrName = (uchar*) strdup((char*)szDrvrName));

	pThis->Drvr.ifVersion = nsdCURR_IF_VERSION;
	/* The pDrvrName+2 below is a hack to obtain the object name. It 
	 * safes us to have yet another variable with the name without "lm" in
	 * front of it. If we change the module load interface, we may re-think
	 * about this hack, but for the time being it is efficient and clean
	 * enough. -- rgerhards, 2008-04-18
	 */
	CHKiRet(obj.UseObj(__FILE__, szDrvrName+2, szDrvrName, (void*) &pThis->Drvr));

finalize_it:
	if(iRet != RS_RET_OK) {
		if(pThis->pDrvrName != NULL)
			free(pThis->pDrvrName);
			pThis->pDrvrName = NULL;
	}
	RETiRet;
}
Exemple #22
0
static rsRetVal
setReportingNamespace(statsobj_t *pThis, uchar *ns)
{
	DEFiRet;
	CHKmalloc(pThis->reporting_ns = ustrdup(ns));
finalize_it:
	RETiRet;
}
Exemple #23
0
/* set name. Note that we make our own copy of the memory, caller is
 * responsible to free up name it passes in (if required).
 */
static rsRetVal
setName(statsobj_t *pThis, uchar *name)
{
	DEFiRet;
	CHKmalloc(pThis->name = ustrdup(name));
finalize_it:
	RETiRet;
}
Exemple #24
0
/* set origin (module name, etc).
 * Note that we make our own copy of the memory, caller is
 * responsible to free up name it passes in (if required).
 */
static rsRetVal
setOrigin(statsobj_t *pThis, uchar *origin)
{
	DEFiRet;
	CHKmalloc(pThis->origin = ustrdup(origin));
finalize_it:
	RETiRet;
}
Exemple #25
0
static rsRetVal  /* assumes exclusive access to bucket */
dynstats_rebuildSurvivorTable(dynstats_bucket_t *b) {
	htable *survivor_table = NULL;
	htable *new_table = NULL;
	size_t htab_sz;
	DEFiRet;
	
	htab_sz = (size_t) (DYNSTATS_HASHTABLE_SIZE_OVERPROVISIONING * b->maxCardinality + 1);
	if (b->table == NULL) {
		CHKmalloc(survivor_table = create_hashtable(htab_sz, hash_from_string, key_equals_string,
			no_op_free));
	}
	CHKmalloc(new_table = create_hashtable(htab_sz, hash_from_string, key_equals_string, no_op_free));
	statsobj.UnlinkAllCounters(b->stats);
	if (b->survivor_table != NULL) {
		dynstats_destroyCountersIn(b, b->survivor_table, b->survivor_ctrs);
	}
	b->survivor_table = (b->table == NULL) ? survivor_table : b->table;
	b->survivor_ctrs = b->ctrs;
	b->table = new_table;
	b->ctrs = NULL;
finalize_it:
	if (iRet != RS_RET_OK) {
		LogError(errno, RS_RET_INTERNAL_ERROR, "error trying to evict "
			"TTL-expired metrics of dyn-stats bucket named: %s", b->name);
		if (new_table == NULL) {
			LogError(errno, RS_RET_INTERNAL_ERROR, "error trying to "
				"initialize hash-table for dyn-stats bucket named: %s", b->name);
		} else {
			assert(0); /* "can" not happen -- triggers Coverity CID 184307:
			hashtable_destroy(new_table, 0);
			We keep this as guard should code above change in the future */
		}
		if (b->table == NULL) {
			if (survivor_table == NULL) {
				LogError(errno, RS_RET_INTERNAL_ERROR, "error trying to initialize "
				"ttl-survivor hash-table for dyn-stats bucket named: %s", b->name);
			} else {
				hashtable_destroy(survivor_table, 0);
			}
		}
	}
	RETiRet;
}
Exemple #26
0
// in case existing buffer too small
static rsRetVal _grow_buffer(protocolState_t *pState)
{
	DEFiRet;
	pState->buffer_size *= 2;
	free(pState->encode_buffer);
	pState->encode_buffer = (char *)malloc(pState->buffer_size);
	CHKmalloc(pState->encode_buffer);

finalize_it:
	RETiRet;
}
Exemple #27
0
static rsRetVal
addContextForReporting(json_object *to, const uchar* field_name, const uchar* value) {
	json_object *v;
	DEFiRet;

	CHKmalloc(v = json_object_new_string((const char*) value));

	json_object_object_add(to, (const char*) field_name, v);
finalize_it:
	RETiRet;
}
Exemple #28
0
addEntry(struct sockaddr_storage *const addr, dnscache_entry_t **const pEtry)
{
	int r;
	struct sockaddr_storage *keybuf = NULL;
	dnscache_entry_t *etry = NULL;
	DEFiRet;

	pthread_rwlock_wrlock(&dnsCache.rwlock);
	/* first check, if the entry was added in the mean time */
	etry = findEntry(addr);
	if(etry != NULL) {
		FINALIZE;
	}

	/* entry still does not exist, so add it */
	CHKmalloc(etry = malloc(sizeof(dnscache_entry_t)));
	CHKmalloc(keybuf = malloc(sizeof(struct sockaddr_storage)));
	CHKiRet(resolveAddr(addr, etry));
	memcpy(&etry->addr, addr, SALEN((struct sockaddr*) addr));
	etry->nUsed = 0;

	memcpy(keybuf, addr, sizeof(struct sockaddr_storage));

	r = hashtable_insert(dnsCache.ht, keybuf, etry);
	keybuf = NULL;
	if(r == 0) {
		DBGPRINTF("dnscache: inserting element failed\n");
	}

finalize_it:
	pthread_rwlock_unlock(&dnsCache.rwlock);
	if(iRet == RS_RET_OK) {
		*pEtry = etry;
	} else {
		free(keybuf);
		free(etry); /* Note: sub-fields cannot be populated in this case */
	}
	RETiRet;
}
Exemple #29
0
/* Called by strmsrv on acceptance of a new session. This allocates our
 * own session data.
 * rgerhards, 2009-06-02
 */
static rsRetVal
OnSessConstructFinalize(void *pUsr)
{
    diis_sess_t *pData;
    DEFiRet;

    assert(pUsr != NULL);
    CHKmalloc(pData = calloc(1, sizeof(diis_sess_t)));
    pData->state = DIIS_IN_HDR;
    *((diis_sess_t**) pUsr) = pData;

finalize_it:
    RETiRet;
}
Exemple #30
0
rsRetVal
lookupBuildTable(lookup_t *pThis, struct json_object *jroot)
{
	//struct json_object *jversion, *jnomatch, *jtype, *jtab;
	struct json_object *jtab;
	struct json_object *jrow, *jindex, *jvalue;
	uint32_t i;
	uint32_t maxStrSize;
	DEFiRet;

#if 0 // enable when we continue to work on this module
	jversion = json_object_object_get(jroot, "version");
	jnomatch = json_object_object_get(jroot, "nomatch");
	jtype = json_object_object_get(jroot, "type");
#endif
	jtab = json_object_object_get(jroot, "table");
	pThis->nmemb = json_object_array_length(jtab);
	CHKmalloc(pThis->d.strtab = malloc(pThis->nmemb * sizeof(lookup_string_tab_etry_t)));

	maxStrSize = 0;
	for(i = 0 ; i < pThis->nmemb ; ++i) {
		jrow = json_object_array_get_idx(jtab, i);
		jindex = json_object_object_get(jrow, "index");
		jvalue = json_object_object_get(jrow, "value");
		CHKmalloc(pThis->d.strtab[i].key = (uchar*) strdup(json_object_get_string(jindex)));
		CHKmalloc(pThis->d.strtab[i].val = (uchar*) strdup(json_object_get_string(jvalue)));
		maxStrSize += ustrlen(pThis->d.strtab[i].val);
	}

	qsort(pThis->d.strtab, pThis->nmemb, sizeof(lookup_string_tab_etry_t), qs_arrcmp_strtab);
dbgprintf("DDDD: table loaded (max size %u):\n", maxStrSize);
for(i = 0 ; i < pThis->nmemb ; ++i)
  dbgprintf("key: '%s', val: '%s'\n", pThis->d.strtab[i].key, pThis->d.strtab[i].val);

finalize_it:
	RETiRet;
}