summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/omfile.c3
-rw-r--r--tools/omfwd.c180
-rw-r--r--tools/rsyslogd.84
-rw-r--r--tools/syslogd.c16
4 files changed, 179 insertions, 24 deletions
diff --git a/tools/omfile.c b/tools/omfile.c
index ba9f7f70..2ebb7df9 100644
--- a/tools/omfile.c
+++ b/tools/omfile.c
@@ -155,7 +155,6 @@ typedef struct _instanceData {
uchar *cryprovName; /* crypto provider */
uchar *cryprovNameFull;/* full internal crypto provider name */
void *cryprovData; /* opaque data ptr for provider use */
- void *cryprovFileData;/* opaque data ptr for file instance */
cryprov_if_t cryprov; /* ptr to crypto provider interface */
sbool useCryprov; /* quicker than checkig ptr (1 vs 8 bytes!) */
int iCurrElt; /* currently active cache element (-1 = none) */
@@ -1089,7 +1088,7 @@ initCryprov(instanceData *pData, struct nvlst *lst)
szDrvrName);
ABORT_FINALIZE(RS_RET_CRYPROV_ERR);
}
- CHKiRet(pData->cryprov.SetCnfParam(pData->cryprovData, lst));
+ CHKiRet(pData->cryprov.SetCnfParam(pData->cryprovData, lst, CRYPROV_PARAMTYPE_REGULAR));
dbgprintf("loaded crypto provider %s, data instance at %p\n",
szDrvrName, pData->cryprovData);
diff --git a/tools/omfwd.c b/tools/omfwd.c
index 129392d2..42311bcd 100644
--- a/tools/omfwd.c
+++ b/tools/omfwd.c
@@ -4,7 +4,7 @@
* NOTE: read comments in module-template.h to understand how this file
* works!
*
- * Copyright 2007-2012 Adiscon GmbH.
+ * Copyright 2007-2013 Adiscon GmbH.
*
* This file is part of rsyslog.
*
@@ -39,6 +39,7 @@
#include <errno.h>
#include <ctype.h>
#include <unistd.h>
+#include <stdint.h>
#ifdef USE_NETZIP
#include <zlib.h>
#endif
@@ -74,6 +75,10 @@ DEFobjCurrIf(netstrms)
DEFobjCurrIf(netstrm)
DEFobjCurrIf(tcpclt)
+/* some local constants (just) for better readybility */
+#define IS_FLUSH 1
+#define NO_FLUSH 0
+
typedef struct _instanceData {
uchar *tplName; /* name of assigned template */
netstrms_t *pNS; /* netstream subsystem */
@@ -97,6 +102,14 @@ typedef struct _instanceData {
TCPFRAMINGMODE tcp_framing;
int bResendLastOnRecon; /* should the last message be re-sent on a successful reconnect? */
tcpclt_t *pTCPClt; /* our tcpclt object */
+# define COMPRESS_NEVER 0
+# define COMPRESS_SINGLE_MSG 1 /* old, single-message compression */
+ /* all other settings are for stream-compression */
+# define COMPRESS_STREAM_ALWAYS 2
+ uint8_t compressionMode;
+ sbool strmCompFlushOnTxEnd; /* flush stream compression on transaction end? */
+ sbool bzInitDone; /* did we do an init of zstrm already? */
+ z_stream zstrm; /* zip stream to use for tcp compression */
uchar sndBuf[16*1024]; /* this is intensionally fixed -- see no good reason to make configurable */
unsigned offsSndBuf; /* next free spot in send buffer */
} instanceData;
@@ -132,6 +145,8 @@ static struct cnfparamdescr actpdescr[] = {
{ "protocol", eCmdHdlrGetWord, 0 },
{ "tcp_framing", eCmdHdlrGetWord, 0 },
{ "ziplevel", eCmdHdlrInt, 0 },
+ { "compression.mode", eCmdHdlrGetWord, 0 },
+ { "compression.stream.flushontxend", eCmdHdlrBinary, 0 },
{ "rebindinterval", eCmdHdlrInt, 0 },
{ "streamdriver", eCmdHdlrGetWord, 0 },
{ "streamdrivermode", eCmdHdlrInt, 0 },
@@ -169,6 +184,7 @@ ENDinitConfVars
static rsRetVal doTryResume(instanceData *pData);
+static rsRetVal doZipFinish(instanceData *pData);
/* this function gets the default template. It coordinates action between
* old-style and new-style configuration parts.
@@ -240,6 +256,7 @@ static inline void
DestructTCPInstanceData(instanceData *pData)
{
assert(pData != NULL);
+ doZipFinish(pData);
if(pData->pNetstrm != NULL)
netstrm.Destruct(&pData->pNetstrm);
if(pData->pNS != NULL)
@@ -423,14 +440,8 @@ finalize_it:
/* CODE FOR SENDING TCP MESSAGES */
-
-/* Send a buffer via TCP. Usually, this is used to send the current
- * send buffer, but if a message is larger than the buffer, we need to
- * have the capability to send the message buffer directly.
- * rgerhards, 2011-04-04
- */
static rsRetVal
-TCPSendBuf(instanceData *pData, uchar *buf, unsigned len)
+TCPSendBufUncompressed(instanceData *pData, uchar *buf, unsigned len)
{
DEFiRet;
unsigned alreadySent;
@@ -438,6 +449,7 @@ TCPSendBuf(instanceData *pData, uchar *buf, unsigned len)
alreadySent = 0;
CHKiRet(netstrm.CheckConnection(pData->pNetstrm)); /* hack for plain tcp syslog - see ptcp driver for details */
+
while(alreadySent != len) {
lenSend = len - alreadySent;
CHKiRet(netstrm.Send(pData->pNetstrm, buf+alreadySent, &lenSend));
@@ -455,6 +467,104 @@ finalize_it:
RETiRet;
}
+static rsRetVal
+TCPSendBufCompressed(instanceData *pData, uchar *buf, unsigned len, sbool bIsFlush)
+{
+ int zRet; /* zlib return state */
+ unsigned outavail;
+ uchar zipBuf[32*1024];
+ int op;
+ DEFiRet;
+
+ if(!pData->bzInitDone) {
+ /* allocate deflate state */
+ pData->zstrm.zalloc = Z_NULL;
+ pData->zstrm.zfree = Z_NULL;
+ pData->zstrm.opaque = Z_NULL;
+ /* see note in file header for the params we use with deflateInit2() */
+ zRet = deflateInit(&pData->zstrm, 9);
+ if(zRet != Z_OK) {
+ DBGPRINTF("error %d returned from zlib/deflateInit()\n", zRet);
+ ABORT_FINALIZE(RS_RET_ZLIB_ERR);
+ }
+ pData->bzInitDone = RSTRUE;
+ }
+
+ /* now doing the compression */
+ pData->zstrm.next_in = (Bytef*) buf;
+ pData->zstrm.avail_in = len;
+ if(pData->strmCompFlushOnTxEnd && bIsFlush)
+ op = Z_SYNC_FLUSH;
+ else
+ op = Z_NO_FLUSH;
+ /* run deflate() on buffer until everything has been compressed */
+ do {
+ DBGPRINTF("omfwd: in deflate() loop, avail_in %d, total_in %ld, isFlush %d\n", pData->zstrm.avail_in, pData->zstrm.total_in, bIsFlush);
+ pData->zstrm.avail_out = sizeof(zipBuf);
+ pData->zstrm.next_out = zipBuf;
+ zRet = deflate(&pData->zstrm, op); /* no bad return value */
+ DBGPRINTF("after deflate, ret %d, avail_out %d\n", zRet, pData->zstrm.avail_out);
+ outavail = sizeof(zipBuf) - pData->zstrm.avail_out;
+ if(outavail != 0) {
+ CHKiRet(TCPSendBufUncompressed(pData, zipBuf, outavail));
+ }
+ } while (pData->zstrm.avail_out == 0);
+
+finalize_it:
+ RETiRet;
+}
+
+static rsRetVal
+TCPSendBuf(instanceData *pData, uchar *buf, unsigned len, sbool bIsFlush)
+{
+ DEFiRet;
+ if(pData->compressionMode >= COMPRESS_STREAM_ALWAYS)
+ iRet = TCPSendBufCompressed(pData, buf, len, bIsFlush);
+ else
+ iRet = TCPSendBufUncompressed(pData, buf, len);
+ RETiRet;
+}
+
+/* finish zlib buffer, to be called before closing the ZIP file (if
+ * running in stream mode).
+ */
+static rsRetVal
+doZipFinish(instanceData *pData)
+{
+ int zRet; /* zlib return state */
+ DEFiRet;
+ unsigned outavail;
+ uchar zipBuf[32*1024];
+
+ if(!pData->bzInitDone)
+ goto done;
+
+// TODO: can we get this into a single common function?
+dbgprintf("DDDD: in doZipFinish()\n");
+ pData->zstrm.avail_in = 0;
+ /* run deflate() on buffer until everything has been compressed */
+ do {
+ DBGPRINTF("in deflate() loop, avail_in %d, total_in %ld\n", pData->zstrm.avail_in, pData->zstrm.total_in);
+ pData->zstrm.avail_out = sizeof(zipBuf);
+ pData->zstrm.next_out = zipBuf;
+ zRet = deflate(&pData->zstrm, Z_FINISH); /* no bad return value */
+ DBGPRINTF("after deflate, ret %d, avail_out %d\n", zRet, pData->zstrm.avail_out);
+ outavail = sizeof(zipBuf) - pData->zstrm.avail_out;
+ if(outavail != 0) {
+ CHKiRet(TCPSendBufUncompressed(pData, zipBuf, outavail));
+ }
+ } while (pData->zstrm.avail_out == 0);
+
+finalize_it:
+ zRet = deflateEnd(&pData->zstrm);
+ if(zRet != Z_OK) {
+ DBGPRINTF("error %d returned from zlib/deflateEnd()\n", zRet);
+ }
+
+ pData->bzInitDone = 0;
+done: RETiRet;
+}
+
/* Add frame to send buffer (or send, if requried)
*/
@@ -467,14 +577,14 @@ static rsRetVal TCPSendFrame(void *pvData, char *msg, size_t len)
(unsigned) len, pData->offsSndBuf);
if(pData->offsSndBuf != 0 && pData->offsSndBuf + len >= sizeof(pData->sndBuf)) {
/* no buffer space left, need to commit previous records */
- CHKiRet(TCPSendBuf(pData, pData->sndBuf, pData->offsSndBuf));
+ CHKiRet(TCPSendBuf(pData, pData->sndBuf, pData->offsSndBuf, NO_FLUSH));
pData->offsSndBuf = 0;
iRet = RS_RET_PREVIOUS_COMMITTED;
}
/* check if the message is too large to fit into buffer */
if(len > sizeof(pData->sndBuf)) {
- CHKiRet(TCPSendBuf(pData, (uchar*)msg, len));
+ CHKiRet(TCPSendBuf(pData, (uchar*)msg, len, NO_FLUSH));
ABORT_FINALIZE(RS_RET_OK); /* committed everything so far */
}
@@ -496,7 +606,6 @@ static rsRetVal TCPSendPrepRetry(void *pvData)
{
DEFiRet;
instanceData *pData = (instanceData *) pvData;
-dbgprintf("TCPSendPrepRetry performs a DestructTCPInstanceData\n");
assert(pData != NULL);
DestructTCPInstanceData(pData);
@@ -576,7 +685,7 @@ static rsRetVal doTryResume(instanceData *pData)
pData->f_addr = res;
pData->bIsConnected = 1;
if(pData->pSockArray == NULL) {
- pData->pSockArray = net.create_udp_socket((uchar*)pData->target, NULL, 0);
+ pData->pSockArray = net.create_udp_socket((uchar*)pData->target, NULL, 0, 0);
}
} else {
CHKiRet(TCPSendInit((void*)pData));
@@ -636,11 +745,10 @@ CODESTARTdoAction
* hard-coded but this may be changed to a config parameter.
* rgerhards, 2006-11-30
*/
- if(pData->compressionLevel && (l > CONF_MIN_SIZE_FOR_COMPRESS)) {
+ if(pData->compressionMode == COMPRESS_SINGLE_MSG && (l > CONF_MIN_SIZE_FOR_COMPRESS)) {
uLongf destLen = iMaxLine + iMaxLine/100 +12; /* recommended value from zlib doc */
uLong srcLen = l;
int ret;
- /* TODO: optimize malloc sequence? -- rgerhards, 2008-09-02 */
CHKmalloc(out = (Bytef*) MALLOC(destLen));
out[0] = 'z';
out[1] = '\0';
@@ -679,6 +787,9 @@ CODESTARTdoAction
DestructTCPInstanceData(pData);
iRet = RS_RET_SUSPENDED;
}
+ if(pData->compressionMode >= COMPRESS_STREAM_ALWAYS && pData->strmCompFlushOnTxEnd)
+ /* mimic not committed, as we need the EndTx entry point to be called */
+ iRet = RS_RET_DEFER_COMMIT;
}
finalize_it:
# ifdef USE_NETZIP
@@ -691,7 +802,7 @@ BEGINendTransaction
CODESTARTendTransaction
dbgprintf("omfwd: endTransaction, offsSndBuf %u\n", pData->offsSndBuf);
if(pData->offsSndBuf != 0) {
- iRet = TCPSendBuf(pData, pData->sndBuf, pData->offsSndBuf);
+ iRet = TCPSendBuf(pData, pData->sndBuf, pData->offsSndBuf, IS_FLUSH);
pData->offsSndBuf = 0;
}
ENDendTransaction
@@ -756,14 +867,18 @@ setInstParamDefaults(instanceData *pData)
pData->iRebindInterval = 0;
pData->bResendLastOnRecon = 0;
pData->pPermPeers = NULL;
- pData->compressionLevel = 0;
+ pData->compressionLevel = 9;
+ pData->strmCompFlushOnTxEnd = 1;
+ pData->compressionMode = COMPRESS_NEVER;
}
BEGINnewActInst
struct cnfparamvals *pvals;
uchar *tplToUse;
+ char *cstr;
int i;
rsRetVal localRet;
+ int complevel = -1;
CODESTARTnewActInst
DBGPRINTF("newActInst (omfwd)\n");
@@ -860,9 +975,10 @@ CODESTARTnewActInst
free(str);
} else if(!strcmp(actpblk.descr[i].name, "ziplevel")) {
# ifdef USE_NETZIP
- int complevel = pvals[i].val.d.n;
+ complevel = pvals[i].val.d.n;
if(complevel >= 0 && complevel <= 10) {
pData->compressionLevel = complevel;
+ pData->compressionMode = COMPRESS_SINGLE_MSG;
} else {
errmsg.LogError(0, NO_ERRCODE, "Invalid ziplevel %d specified in "
"forwardig action - NOT turning on compression.",
@@ -876,11 +992,39 @@ CODESTARTnewActInst
pData->bResendLastOnRecon = (int) pvals[i].val.d.n;
} else if(!strcmp(actpblk.descr[i].name, "template")) {
pData->tplName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
+ } else if(!strcmp(actpblk.descr[i].name, "compression.stream.flushontxend")) {
+ pData->strmCompFlushOnTxEnd = (sbool) pvals[i].val.d.n;
+ } else if(!strcmp(actpblk.descr[i].name, "compression.mode")) {
+ cstr = es_str2cstr(pvals[i].val.d.estr, NULL);
+ if(!strcasecmp(cstr, "stream:always")) {
+ pData->compressionMode = COMPRESS_STREAM_ALWAYS;
+ } else if(!strcasecmp(cstr, "none")) {
+ pData->compressionMode = COMPRESS_NEVER;
+ } else if(!strcasecmp(cstr, "single")) {
+ pData->compressionMode = COMPRESS_SINGLE_MSG;
+ } else {
+ errmsg.LogError(0, RS_RET_PARAM_ERROR, "omfwd: invalid value for 'compression.mode' "
+ "parameter (given is '%s')", cstr);
+ free(cstr);
+ ABORT_FINALIZE(RS_RET_PARAM_ERROR);
+ }
+ free(cstr);
} else {
DBGPRINTF("omfwd: program error, non-handled "
"param '%s'\n", actpblk.descr[i].name);
}
}
+
+ if(complevel != -1) {
+ pData->compressionLevel = complevel;
+ if(pData->compressionMode == COMPRESS_NEVER) {
+ /* to keep compatible with pre-7.3.11, only setting the
+ * compresion level means old-style single-message mode.
+ */
+ pData->compressionMode = COMPRESS_SINGLE_MSG;
+ }
+ }
+
CODE_STD_STRING_REQUESTnewActInst(1)
tplToUse = ustrdup((pData->tplName == NULL) ? getDfltTpl() : pData->tplName);
@@ -948,6 +1092,7 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1)
iLevel = *p - '0';
++p; /* eat */
pData->compressionLevel = iLevel;
+ pData->compressionMode = COMPRESS_SINGLE_MSG;
} else {
errmsg.LogError(0, NO_ERRCODE, "Invalid compression level '%c' specified in "
"forwardig action - NOT turning on compression.",
@@ -1025,7 +1170,6 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1)
while(*p && *p != ';' && *p != '#' && !isspace((int) *p))
++p; /*JUST SKIP*/
- /* TODO: make this if go away! */
if(*p == ';' || *p == '#' || isspace(*p)) {
uchar cTmp = *p;
*p = '\0'; /* trick to obtain hostname (later)! */
diff --git a/tools/rsyslogd.8 b/tools/rsyslogd.8
index 620006f2..ac732b88 100644
--- a/tools/rsyslogd.8
+++ b/tools/rsyslogd.8
@@ -191,6 +191,10 @@ is specified and the host logging resolves to satu.infodrom.north.de
no domain would be cut, you will have to specify two domains like:
.BR "\-s north.de:infodrom.north.de" .
.TP
+.BI "\-S ip_address" "local client source IP"
+rsyslogd uses ip_address as local client address while connecting
+to remote logserver. Currently used by omrelp only and only with tcp.
+.TP
.BI "\-u " "userlevel"
This is a "catch all" option for some very seldomly-used user settings.
The "userlevel" variable selects multiple things. Add the specific values
diff --git a/tools/syslogd.c b/tools/syslogd.c
index a8a733d6..2f0f64c3 100644
--- a/tools/syslogd.c
+++ b/tools/syslogd.c
@@ -1056,7 +1056,7 @@ finalize_it:
* the time being (remember that we want to restructure config processing at large!).
* rgerhards, 2009-10-27
*/
-rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName, struct cnfparamvals *queueParams)
+rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName, struct nvlst *lst)
{
struct queuefilenames_s *qfn;
uchar *qfname = NULL;
@@ -1072,7 +1072,7 @@ rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName, struct cnfpara
/* name our main queue object (it's not fatal if it fails...) */
obj.SetName((obj_t*) (*ppQueue), pszQueueName);
- if(queueParams == NULL) { /* use legacy parameters? */
+ if(lst == NULL) { /* use legacy parameters? */
/* ... set some properties ... */
# define setQPROP(func, directive, data) \
CHKiRet_Hdlr(func(*ppQueue, data)) { \
@@ -1129,7 +1129,7 @@ rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName, struct cnfpara
# undef setQPROPstr
} else { /* use new style config! */
qqueueSetDefaultsRulesetQueue(*ppQueue);
- qqueueApplyCnfParam(*ppQueue, queueParams);
+ qqueueApplyCnfParam(*ppQueue, lst);
}
/* ... and finally start the queue! */
@@ -1772,7 +1772,7 @@ int realMain(int argc, char **argv)
* of other options, we do this during the inital option processing.
* rgerhards, 2008-04-04
*/
- while((ch = getopt(argc, argv, "46a:Ac:dDef:g:hi:l:m:M:nN:op:qQr::s:t:T:u:vwx")) != EOF) {
+ while((ch = getopt(argc, argv, "46a:Ac:dDef:g:hi:l:m:M:nN:op:qQr::s:S:t:T:u:vwx")) != EOF) {
switch((char)ch) {
case '4':
case '6':
@@ -1790,6 +1790,7 @@ int realMain(int argc, char **argv)
case 'q': /* add hostname if DNS resolving has failed */
case 'Q': /* dont resolve hostnames in ACL to IPs */
case 's':
+ case 'S': /* Source IP for local client to be used on multihomed host */
case 'T': /* chroot on startup (primarily for testing) */
case 'u': /* misc user settings */
case 'w': /* disable disallowed host warnings */
@@ -1881,6 +1882,13 @@ int realMain(int argc, char **argv)
case 'a':
fprintf(stderr, "rsyslogd: error -a is no longer supported, use module imuxsock instead");
break;
+ case 'S': /* Source IP for local client to be used on multihomed host */
+ if(glbl.GetSourceIPofLocalClient() != NULL) {
+ fprintf (stderr, "rsyslogd: Only one -S argument allowed, the first one is taken.\n");
+ } else {
+ glbl.SetSourceIPofLocalClient((uchar*)arg);
+ }
+ break;
case 'f': /* configuration file */
ConfFile = (uchar*) arg;
break;