summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2008-03-13 14:24:32 +0000
committerRainer Gerhards <rgerhards@adiscon.com>2008-03-13 14:24:32 +0000
commit5287b695e6961ff4941aa0e0e5ba743334415234 (patch)
treecc8d303bab6ea11aff8baea94167e70d2611524a
parent8ca90eb55502cc7a6f9e6163bf7e46cb5142b2e2 (diff)
downloadrsyslog-5287b695e6961ff4941aa0e0e5ba743334415234.tar.gz
rsyslog-5287b695e6961ff4941aa0e0e5ba743334415234.tar.xz
rsyslog-5287b695e6961ff4941aa0e0e5ba743334415234.zip
cleaned up new relp code files to make them suitable for implementation
-rw-r--r--ChangeLog1
-rw-r--r--Makefile.am10
-rw-r--r--configure.ac8
-rw-r--r--doc/rsyslog_conf.html4
-rw-r--r--plugins/imrelp/imrelp.c16
-rw-r--r--plugins/omrelp/omrelp.c503
-rw-r--r--relputil.c113
7 files changed, 330 insertions, 325 deletions
diff --git a/ChangeLog b/ChangeLog
index ac3a045a..8d8f2cc8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,6 @@
---------------------------------------------------------------------------
Version 3.12.3 (rgerhards), 2008-03-??
+- some more internal cleanup ;)
---------------------------------------------------------------------------
Version 3.12.2 (rgerhards), 2008-03-13
- added RSYSLOGD_MODDIR environment variable
diff --git a/Makefile.am b/Makefile.am
index d8dbff6c..104b962a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -156,11 +156,11 @@ endif
# relp support
#
if ENABLE_RELP
-#pkglib_LTLIBRARIES += lmrelp.la
-#lmrelp_la_SOURCES = gss-misc.c gss-misc.h
-#lmrelp_la_CPPFLAGS = $(pthreads_cflags) $(relp_cflags)
-#lmrelp_la_LDFLAGS = -module -avoid-version
-#lmrelp_la_LIBADD = $(relp_libs)
+pkglib_LTLIBRARIES += lmrelputil.la
+lmrelputil_la_SOURCES = relputil.c relputil.h
+lmrelputil_la_CPPFLAGS = $(pthreads_cflags) $(relp_cflags)
+lmrelputil_la_LDFLAGS = -module -avoid-version
+lmrelputil_la_LIBADD = $(relp_libs)
endif
man_MANS = rfc3195d.8 rsyslogd.8 rsyslog.conf.5
diff --git a/configure.ac b/configure.ac
index bb8c065c..4712e86e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -455,10 +455,10 @@ AC_ARG_ENABLE(relp,
[enable_relp=no]
)
if test "x$enable_relp" = "xyes"; then
-# AC_CHECK_HEADERS(
-# [net-relp/net-relp-config.h],,
-# [AC_MSG_FAILURE([Net-RELP is missing])]
-# )
+ AC_CHECK_HEADERS(
+ [relp.h],,
+ [AC_MSG_FAILURE([RELP library is missing (no headers)])]
+ )
AC_CHECK_LIB(
[relp],
[relpInit],
diff --git a/doc/rsyslog_conf.html b/doc/rsyslog_conf.html
index 03b15c17..1dc53944 100644
--- a/doc/rsyslog_conf.html
+++ b/doc/rsyslog_conf.html
@@ -26,7 +26,7 @@ number of modules. Here is the entry point to their documentation and
what they do (list is currently not complete)</p>
<ul>
<li><a href="omsnmp.html">omsnmp</a> - SNMP
-trap output module</li>
+trap output module</li><li>omrelp - RELP output module</li>
<li>omgss - output module for GSS-enabled syslog</li>
<li>ommysql - output module for MySQL</li>
<li>ompgsql - output module for PostgreSQL</li>
@@ -34,7 +34,7 @@ trap output module</li>
generic database output module (Firebird/Interbase, MS SQL, Sybase,
SQLLite, Ingres, Oracle, mSQL)</li>
<li><a href="imfile.html">imfile</a>
--&nbsp; input module for text files</li>
+-&nbsp; input module for text files</li><li>imrelp - RELP input module</li>
<li>imudp - udp syslog message input</li>
<li><a href="imtcp.html">imtcp</a> - input
plugin for plain tcp syslog</li>
diff --git a/plugins/imrelp/imrelp.c b/plugins/imrelp/imrelp.c
index 7baa95f2..cabc368f 100644
--- a/plugins/imrelp/imrelp.c
+++ b/plugins/imrelp/imrelp.c
@@ -1,9 +1,10 @@
-/* imtcp.c
- * This is the implementation of the TCP input module.
+/* imrelp.c
*
- * File begun on 2007-12-21 by RGerhards (extracted from syslogd.c)
+ * This is the implementation of the RELP input module.
*
- * Copyright 2007 Rainer Gerhards and Adiscon GmbH.
+ * File begun on 2008-03-13 by RGerhards
+ *
+ * Copyright 2008 Rainer Gerhards and Adiscon GmbH.
*
* This file is part of rsyslog.
*
@@ -35,9 +36,6 @@
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
-#if HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
#include "rsyslog.h"
#include "syslogd.h"
#include "cfsysline.h"
@@ -203,9 +201,9 @@ CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(tcpsrv, LM_TCPSRV_FILENAME));
/* register config file handlers */
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverrun", 0, eCmdHdlrGetWord,
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputrelpserverrun", 0, eCmdHdlrGetWord,
addTCPListener, NULL, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpmaxsessions", 0, eCmdHdlrInt,
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputrelpmaxsessions", 0, eCmdHdlrInt,
NULL, &iTCPSessMax, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler,
resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
diff --git a/plugins/omrelp/omrelp.c b/plugins/omrelp/omrelp.c
index 00a3c8ed..8f464e30 100644
--- a/plugins/omrelp/omrelp.c
+++ b/plugins/omrelp/omrelp.c
@@ -1,16 +1,13 @@
-/* omfwd.c
- * This is the implementation of the build-in forwarding output module.
+/* omrelp.c
+ *
+ * This is the implementation of the RELP output module.
*
* NOTE: read comments in module-template.h to understand how this file
* works!
*
- * File begun on 2007-07-20 by RGerhards (extracted from syslogd.c)
- * This file is under development and has not yet arrived at being fully
- * self-contained and a real object. So far, it is mostly an excerpt
- * of the "old" message code without any modifications. However, it
- * helps to have things at the right place one we go to the meat of it.
+ * File begun on 2008-03-13 by RGerhards
*
- * Copyright 2007 Rainer Gerhards and Adiscon GmbH.
+ * Copyright 2008 Rainer Gerhards and Adiscon GmbH.
*
* This file is part of rsyslog.
*
@@ -30,7 +27,6 @@
* A copy of the GPL can be found in the file "COPYING" in this distribution.
*/
#include "config.h"
-#ifdef SYSLOG_INET
#include "rsyslog.h"
#include <stdio.h>
#include <stdarg.h>
@@ -63,20 +59,6 @@
MODULE_TYPE_OUTPUT
-#ifdef SYSLOG_INET
-#define INET_SUSPEND_TIME 60
-/* equal to 1 minute - TODO: see if we can get rid of this now that we have
- * the retry intervals in the engine -- rgerhards, 2008-03-12
- */
-
-#define INET_RETRY_MAX 30 /* maximum of retries for gethostbyname() */
- /* was 10, changed to 30 because we reduced INET_SUSPEND_TIME by one third. So
- * this "fixes" some of implications of it (see comment on INET_SUSPEND_TIME).
- * rgerhards, 2005-07-26
- * TODO: this needs to be reviewed in spite of the new engine, too -- rgerhards, 2008-03-12
- */
-#endif
-
/* internal structures
*/
DEF_OMOD_STATIC_DATA
@@ -93,15 +75,12 @@ typedef struct _instanceData {
eDestFORW_SUSP,
eDestFORW_UNKN
} eDestState;
- int iRtryCnt;
struct addrinfo *f_addr;
int compressionLevel; /* 0 - no compression, else level for zlib */
char *port;
- int protocol;
# define FORW_UDP 0
# define FORW_TCP 1
/* following fields for TCP-based delivery */
- time_t ttSuspend; /* time selector was suspended */
tcpclt_t *pTCPClt; /* our tcpclt object */
} instanceData;
@@ -152,9 +131,7 @@ CODESTARTfreeInstance
if(pData->pSockArray != NULL)
net.closeUDPListenSockets(pData->pSockArray);
- if(pData->protocol == FORW_TCP) {
- tcpclt.Destruct(&pData->pTCPClt);
- }
+ tcpclt.Destruct(&pData->pTCPClt);
ENDfreeInstance
@@ -165,58 +142,7 @@ CODESTARTdbgPrintInstInfo
ENDdbgPrintInstInfo
-/* Send a message via UDP
- * rgehards, 2007-12-20
- */
-static rsRetVal UDPSend(instanceData *pData, char *msg, size_t len)
-{
- DEFiRet;
- struct addrinfo *r;
- int i;
- unsigned lsent = 0;
- int bSendSuccess;
-
- if(pData->pSockArray != NULL) {
- /* we need to track if we have success sending to the remote
- * peer. Success is indicated by at least one sendto() call
- * succeeding. We track this be bSendSuccess. We can not simply
- * rely on lsent, as a call might initially work, but a later
- * call fails. Then, lsent has the error status, even though
- * the sendto() succeeded.
- * rgerhards, 2007-06-22
- */
- bSendSuccess = FALSE;
- for (r = pData->f_addr; r; r = r->ai_next) {
- for (i = 0; i < *pData->pSockArray; i++) {
- lsent = sendto(pData->pSockArray[i+1], msg, len, 0, r->ai_addr, r->ai_addrlen);
- if (lsent == len) {
- bSendSuccess = TRUE;
- break;
- } else {
- int eno = errno;
- char errStr[1024];
- dbgprintf("sendto() error: %d = %s.\n",
- eno, rs_strerror_r(eno, errStr, sizeof(errStr)));
- }
- }
- if (lsent == len && !send_to_all)
- break;
- }
- /* finished looping */
- if (bSendSuccess == FALSE) {
- dbgprintf("error forwarding via udp, suspending\n");
- iRet = RS_RET_SUSPENDED;
- }
- }
-
- RETiRet;
-}
-
-/* CODE FOR SENDING TCP MESSAGES */
-
-
-/* Send a frame via plain TCP protocol
- * rgerhards, 2007-12-28
+/* Send a frame
*/
static rsRetVal TCPSendFrame(void *pvData, char *msg, size_t len)
{
@@ -313,12 +239,11 @@ static rsRetVal doTryResume(instanceData *pData)
*/
hints.ai_flags = AI_NUMERICSERV;
hints.ai_family = family;
- hints.ai_socktype = pData->protocol == FORW_UDP ? SOCK_DGRAM : SOCK_STREAM;
+ hints.ai_socktype = SOCK_STREAM;
if((e = getaddrinfo(pData->f_hname,
getFwdSyslogPt(pData), &hints, &res)) == 0) {
dbgprintf("%s found, resuming.\n", pData->f_hname);
pData->f_addr = res;
- pData->iRtryCnt = 0;
pData->eDestState = eDestFORW;
} else {
iRet = RS_RET_SUSPENDED;
@@ -346,7 +271,7 @@ BEGINdoAction
CODESTARTdoAction
switch (pData->eDestState) {
case eDestFORW_SUSP:
- dbgprintf("internal error in omfwd.c, eDestFORW_SUSP in doAction()!\n");
+ dbgprintf("internal error in omrelp.c, eDestFORW_SUSP in doAction()!\n");
iRet = RS_RET_SUSPENDED;
break;
@@ -356,85 +281,60 @@ CODESTARTdoAction
break;
case eDestFORW:
- dbgprintf(" %s:%s/%s\n", pData->f_hname, getFwdSyslogPt(pData),
- pData->protocol == FORW_UDP ? "udp" : "tcp");
- /* with UDP, check if the socket is there and, if not, alloc
- * it. TODO: there should be a better place for that code.
- * rgerhards, 2007-12-26
- */
- if(pData->protocol == FORW_UDP) {
- if(pData->pSockArray == NULL) {
- pData->pSockArray = net.create_udp_socket((uchar*)pData->f_hname, NULL, 0);
- }
- }
- if ( 0) // TODO: think about this strcmp(getHOSTNAME(f->f_pMsg), LocalHostName) && NoHops )
- /* what we need to do is get the hostname as an additonal string (during parseSe..). Then,
- * we can compare that string to LocalHostName. That way, we do not need to access the
- * msgobject, and everything is clean. The question remains, though, if that functionality
- * here actually makes sense or not. If we really need it, it might make more sense to compare
- * the target IP address to the IP addresses of the local machene - that is a far better way of
- * handling things than to relay on the error-prone hostname property.
- * rgerhards, 2007-07-27
+ dbgprintf(" %s:%s/%s\n", pData->f_hname, getFwdSyslogPt(pData), "tcp");
+ psz = (char*) ppString[0];
+ l = strlen((char*) psz);
+ if(l > MAXLINE)
+ l = MAXLINE;
+
+# ifdef USE_NETZIP
+
+ /* TODO: move all this ZLIB code into a library module! */
+
+ /* Check if we should compress and, if so, do it. We also
+ * check if the message is large enough to justify compression.
+ * The smaller the message, the less likely is a gain in compression.
+ * To save CPU cycles, we do not try to compress very small messages.
+ * What "very small" means needs to be configured. Currently, it is
+ * hard-coded but this may be changed to a config parameter.
+ * rgerhards, 2006-11-30
*/
- dbgprintf("Not sending message to remote.\n");
- else {
- pData->ttSuspend = time(NULL);
- psz = (char*) ppString[0];
- l = strlen((char*) psz);
- if (l > MAXLINE)
- l = MAXLINE;
-
-# ifdef USE_NETZIP
- /* Check if we should compress and, if so, do it. We also
- * check if the message is large enough to justify compression.
- * The smaller the message, the less likely is a gain in compression.
- * To save CPU cycles, we do not try to compress very small messages.
- * What "very small" means needs to be configured. Currently, it is
- * hard-coded but this may be changed to a config parameter.
- * rgerhards, 2006-11-30
- */
- if(pData->compressionLevel && (l > MIN_SIZE_FOR_COMPRESS)) {
- Bytef out[MAXLINE+MAXLINE/100+12] = "z";
- uLongf destLen = sizeof(out) / sizeof(Bytef);
- uLong srcLen = l;
- int ret;
- ret = compress2((Bytef*) out+1, &destLen, (Bytef*) psz,
- srcLen, pData->compressionLevel);
- dbgprintf("Compressing message, length was %d now %d, return state %d.\n",
- l, (int) destLen, ret);
- if(ret != Z_OK) {
- /* if we fail, we complain, but only in debug mode
- * Otherwise, we are silent. In any case, we ignore the
- * failed compression and just sent the uncompressed
- * data, which is still valid. So this is probably the
- * best course of action.
- * rgerhards, 2006-11-30
- */
- dbgprintf("Compression failed, sending uncompressed message\n");
- } else if(destLen+1 < l) {
- /* only use compression if there is a gain in using it! */
- dbgprintf("there is gain in compression, so we do it\n");
- psz = (char*) out;
- l = destLen + 1; /* take care for the "z" at message start! */
- }
- ++destLen;
+ if(pData->compressionLevel && (l > MIN_SIZE_FOR_COMPRESS)) {
+ Bytef out[MAXLINE+MAXLINE/100+12] = "z";
+ uLongf destLen = sizeof(out) / sizeof(Bytef);
+ uLong srcLen = l;
+ int ret;
+ ret = compress2((Bytef*) out+1, &destLen, (Bytef*) psz,
+ srcLen, pData->compressionLevel);
+ dbgprintf("Compressing message, length was %d now %d, return state %d.\n",
+ l, (int) destLen, ret);
+ if(ret != Z_OK) {
+ /* if we fail, we complain, but only in debug mode
+ * Otherwise, we are silent. In any case, we ignore the
+ * failed compression and just sent the uncompressed
+ * data, which is still valid. So this is probably the
+ * best course of action.
+ * rgerhards, 2006-11-30
+ */
+ dbgprintf("Compression failed, sending uncompressed message\n");
+ } else if(destLen+1 < l) {
+ /* only use compression if there is a gain in using it! */
+ dbgprintf("there is gain in compression, so we do it\n");
+ psz = (char*) out;
+ l = destLen + 1; /* take care for the "z" at message start! */
}
+ ++destLen;
+ }
# endif
- if(pData->protocol == FORW_UDP) {
- /* forward via UDP */
- CHKiRet(UDPSend(pData, psz, l));
- } else {
- /* forward via TCP */
- rsRetVal ret;
- ret = tcpclt.Send(pData->pTCPClt, pData, psz, l);
- if(ret != RS_RET_OK) {
- /* error! */
- dbgprintf("error forwarding via tcp, suspending\n");
- pData->eDestState = eDestFORW_SUSP;
- iRet = RS_RET_SUSPENDED;
- }
- }
+ /* forward */
+ rsRetVal ret;
+ ret = tcpclt.Send(pData->pTCPClt, pData, psz, l);
+ if(ret != RS_RET_OK) {
+ /* error! */
+ dbgprintf("error forwarding via tcp, suspending\n");
+ pData->eDestState = eDestFORW_SUSP;
+ iRet = RS_RET_SUSPENDED;
}
break;
}
@@ -451,162 +351,156 @@ BEGINparseSelectorAct
TCPFRAMINGMODE tcp_framing;
CODESTARTparseSelectorAct
CODE_STD_STRING_REQUESTparseSelectorAct(1)
- if(*p == '@') {
- if((iRet = createInstance(&pData)) != RS_RET_OK)
- goto finalize_it;
- ++p; /* eat '@' */
- if(*p == '@') { /* indicator for TCP! */
- pData->protocol = FORW_TCP;
- ++p; /* eat this '@', too */
- } else {
- pData->protocol = FORW_UDP;
- }
- /* we are now after the protocol indicator. Now check if we should
- * use compression. We begin to use a new option format for this:
- * @(option,option)host:port
- * The first option defined is "z[0..9]" where the digit indicates
- * the compression level. If it is not given, 9 (best compression) is
- * assumed. An example action statement might be:
- * @@(z5,o)127.0.0.1:1400
- * Which means send via TCP with medium (5) compresion (z) to the local
- * host on port 1400. The '0' option means that octet-couting (as in
- * IETF I-D syslog-transport-tls) is to be used for framing (this option
- * applies to TCP-based syslog only and is ignored when specified with UDP).
- * That is not yet implemented.
- * rgerhards, 2006-12-07
- */
- if(*p == '(') {
- /* at this position, it *must* be an option indicator */
- do {
- ++p; /* eat '(' or ',' (depending on when called) */
- /* check options */
- if(*p == 'z') { /* compression */
+ if(!strncmp((char*) p, ":omrelp:", sizeof(":omrelp:") - 1)) {
+ p += sizeof(":omrelp:") - 1; /* eat indicator sequence (-1 because of '\0'!) */
+ } else {
+ ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED);
+ }
+
+ /* ok, if we reach this point, we have something for us */
+ if((iRet = createInstance(&pData)) != RS_RET_OK)
+ FINALIZE;
+
+ /* we are now after the protocol indicator. Now check if we should
+ * use compression. We begin to use a new option format for this:
+ * @(option,option)host:port
+ * The first option defined is "z[0..9]" where the digit indicates
+ * the compression level. If it is not given, 9 (best compression) is
+ * assumed. An example action statement might be:
+ * :omrelp:(z5,o)127.0.0.1:1400
+ * Which means send via TCP with medium (5) compresion (z) to the local
+ * host on port 1400. The '0' option means that octet-couting (as in
+ * IETF I-D syslog-transport-tls) is to be used for framing (this option
+ * applies to TCP-based syslog only and is ignored when specified with UDP).
+ * That is not yet implemented.
+ * rgerhards, 2006-12-07
+ * TODO: think of all this in spite of RELP -- rgerhards, 2008-03-13
+ */
+ if(*p == '(') {
+ /* at this position, it *must* be an option indicator */
+ do {
+ ++p; /* eat '(' or ',' (depending on when called) */
+ /* check options */
+ if(*p == 'z') { /* compression */
# ifdef USE_NETZIP
+ ++p; /* eat */
+ if(isdigit((int) *p)) {
+ int iLevel;
+ iLevel = *p - '0';
++p; /* eat */
- if(isdigit((int) *p)) {
- int iLevel;
- iLevel = *p - '0';
- ++p; /* eat */
- pData->compressionLevel = iLevel;
- } else {
- errmsg.LogError(NO_ERRCODE, "Invalid compression level '%c' specified in "
- "forwardig action - NOT turning on compression.",
- *p);
- }
+ pData->compressionLevel = iLevel;
+ } else {
+ errmsg.LogError(NO_ERRCODE, "Invalid compression level '%c' specified in "
+ "forwardig action - NOT turning on compression.",
+ *p);
+ }
# else
- errmsg.LogError(NO_ERRCODE, "Compression requested, but rsyslogd is not compiled "
- "with compression support - request ignored.");
+ errmsg.LogError(NO_ERRCODE, "Compression requested, but rsyslogd is not compiled "
+ "with compression support - request ignored.");
# endif /* #ifdef USE_NETZIP */
- } else if(*p == 'o') { /* octet-couting based TCP framing? */
- ++p; /* eat */
- /* no further options settable */
- tcp_framing = TCP_FRAMING_OCTET_COUNTING;
- } else { /* invalid option! Just skip it... */
- errmsg.LogError(NO_ERRCODE, "Invalid option %c in forwarding action - ignoring.", *p);
- ++p; /* eat invalid option */
- }
- /* the option processing is done. We now do a generic skip
- * to either the next option or the end of the option
- * block.
- */
- while(*p && *p != ')' && *p != ',')
- ++p; /* just skip it */
- } while(*p && *p == ','); /* Attention: do.. while() */
- if(*p == ')')
- ++p; /* eat terminator, on to next */
- else
- /* we probably have end of string - leave it for the rest
- * of the code to handle it (but warn the user)
- */
- errmsg.LogError(NO_ERRCODE, "Option block not terminated in forwarding action.");
- }
- /* extract the host first (we do a trick - we replace the ';' or ':' with a '\0')
- * now skip to port and then template name. rgerhards 2005-07-06
- */
- for(q = p ; *p && *p != ';' && *p != ':' ; ++p)
- /* JUST SKIP */;
-
- pData->port = NULL;
- if(*p == ':') { /* process port */
- uchar * tmp;
-
- *p = '\0'; /* trick to obtain hostname (later)! */
- tmp = ++p;
- for(i=0 ; *p && isdigit((int) *p) ; ++p, ++i)
- /* SKIP AND COUNT */;
- pData->port = malloc(i + 1);
- if(pData->port == NULL) {
- errmsg.LogError(NO_ERRCODE, "Could not get memory to store syslog forwarding port, "
- "using default port, results may not be what you intend\n");
- /* we leave f_forw.port set to NULL, this is then handled by
- * getFwdSyslogPt().
- */
- } else {
- memcpy(pData->port, tmp, i);
- *(pData->port + i) = '\0';
+ } else if(*p == 'o') { /* octet-couting based TCP framing? */
+ ++p; /* eat */
+ /* no further options settable */
+ tcp_framing = TCP_FRAMING_OCTET_COUNTING;
+ } else { /* invalid option! Just skip it... */
+ errmsg.LogError(NO_ERRCODE, "Invalid option %c in forwarding action - ignoring.", *p);
+ ++p; /* eat invalid option */
}
- }
-
- /* now skip to template */
- bErr = 0;
- while(*p && *p != ';') {
- if(*p && *p != ';' && !isspace((int) *p)) {
- if(bErr == 0) { /* only 1 error msg! */
- bErr = 1;
- errno = 0;
- errmsg.LogError(NO_ERRCODE, "invalid selector line (port), probably not doing "
- "what was intended");
- }
- }
- ++p;
- }
-
- /* TODO: make this if go away! */
- if(*p == ';') {
- *p = '\0'; /* trick to obtain hostname (later)! */
- strcpy(pData->f_hname, (char*) q);
- *p = ';';
- } else
- strcpy(pData->f_hname, (char*) q);
-
- /* process template */
- if((iRet = cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS, (uchar*) " StdFwdFmt"))
- != RS_RET_OK)
- goto finalize_it;
-
- /* first set the pData->eDestState */
- memset(&hints, 0, sizeof(hints));
- /* port must be numeric, because config file syntax requests this */
- hints.ai_flags = AI_NUMERICSERV;
- hints.ai_family = family;
- hints.ai_socktype = pData->protocol == FORW_UDP ? SOCK_DGRAM : SOCK_STREAM;
- if( (error = getaddrinfo(pData->f_hname, getFwdSyslogPt(pData), &hints, &res)) != 0) {
- pData->eDestState = eDestFORW_UNKN;
- pData->iRtryCnt = INET_RETRY_MAX;
- pData->ttSuspend = time(NULL);
+ /* the option processing is done. We now do a generic skip
+ * to either the next option or the end of the option
+ * block.
+ */
+ while(*p && *p != ')' && *p != ',')
+ ++p; /* just skip it */
+ } while(*p && *p == ','); /* Attention: do.. while() */
+ if(*p == ')')
+ ++p; /* eat terminator, on to next */
+ else
+ /* we probably have end of string - leave it for the rest
+ * of the code to handle it (but warn the user)
+ */
+ errmsg.LogError(NO_ERRCODE, "Option block not terminated in forwarding action.");
+ }
+ /* extract the host first (we do a trick - we replace the ';' or ':' with a '\0')
+ * now skip to port and then template name. rgerhards 2005-07-06
+ */
+ for(q = p ; *p && *p != ';' && *p != ':' ; ++p)
+ /* JUST SKIP */;
+
+ pData->port = NULL;
+ if(*p == ':') { /* process port */
+ uchar * tmp;
+
+ *p = '\0'; /* trick to obtain hostname (later)! */
+ tmp = ++p;
+ for(i=0 ; *p && isdigit((int) *p) ; ++p, ++i)
+ /* SKIP AND COUNT */;
+ pData->port = malloc(i + 1);
+ if(pData->port == NULL) {
+ errmsg.LogError(NO_ERRCODE, "Could not get memory to store syslog forwarding port, "
+ "using default port, results may not be what you intend\n");
+ /* we leave f_forw.port set to NULL, this is then handled by
+ * getFwdSyslogPt().
+ */
} else {
- pData->eDestState = eDestFORW;
- pData->f_addr = res;
+ memcpy(pData->port, tmp, i);
+ *(pData->port + i) = '\0';
}
- /*
- * Otherwise the host might be unknown due to an
- * inaccessible nameserver (perhaps on the same
- * host). We try to get the ip number later, like
- * FORW_SUSP.
- */
- if(pData->protocol == FORW_TCP) {
- /* create our tcpclt */
- CHKiRet(tcpclt.Construct(&pData->pTCPClt));
- /* and set callbacks */
- CHKiRet(tcpclt.SetSendInit(pData->pTCPClt, TCPSendInit));
- CHKiRet(tcpclt.SetSendFrame(pData->pTCPClt, TCPSendFrame));
- CHKiRet(tcpclt.SetSendPrepRetry(pData->pTCPClt, TCPSendPrepRetry));
- CHKiRet(tcpclt.SetFraming(pData->pTCPClt, tcp_framing));
+ }
+
+ /* now skip to template */
+ bErr = 0;
+ while(*p && *p != ';') {
+ if(*p && *p != ';' && !isspace((int) *p)) {
+ if(bErr == 0) { /* only 1 error msg! */
+ bErr = 1;
+ errno = 0;
+ errmsg.LogError(NO_ERRCODE, "invalid selector line (port), probably not doing "
+ "what was intended");
+ }
}
+ ++p;
+ }
+ /* TODO: make this if go away! */
+ if(*p == ';') {
+ *p = '\0'; /* trick to obtain hostname (later)! */
+ strcpy(pData->f_hname, (char*) q);
+ *p = ';';
+ } else
+ strcpy(pData->f_hname, (char*) q);
+
+ /* process template */
+ if((iRet = cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS, (uchar*) " StdFwdFmt"))
+ != RS_RET_OK)
+ goto finalize_it;
+
+ /* first set the pData->eDestState */
+ memset(&hints, 0, sizeof(hints));
+ /* port must be numeric, because config file syntax requests this */
+ hints.ai_flags = AI_NUMERICSERV;
+ hints.ai_family = family;
+ hints.ai_socktype = SOCK_STREAM;
+ if( (error = getaddrinfo(pData->f_hname, getFwdSyslogPt(pData), &hints, &res)) != 0) {
+ pData->eDestState = eDestFORW_UNKN;
} else {
- iRet = RS_RET_CONFLINE_UNPROCESSED;
+ pData->eDestState = eDestFORW;
+ pData->f_addr = res;
}
+ /*
+ * Otherwise the host might be unknown due to an
+ * inaccessible nameserver (perhaps on the same
+ * host). We try to get the ip number later, like
+ * FORW_SUSP.
+ */
+
+ /* create our tcpclt */
+ CHKiRet(tcpclt.Construct(&pData->pTCPClt));
+ /* and set callbacks */
+ CHKiRet(tcpclt.SetSendInit(pData->pTCPClt, TCPSendInit));
+ CHKiRet(tcpclt.SetSendFrame(pData->pTCPClt, TCPSendFrame));
+ CHKiRet(tcpclt.SetSendPrepRetry(pData->pTCPClt, TCPSendPrepRetry));
+ CHKiRet(tcpclt.SetFraming(pData->pTCPClt, tcp_framing));
/* TODO: do we need to call freeInstance if we failed - this is a general question for
* all output modules. I'll address it lates as the interface evolves. rgerhards, 2007-07-25
@@ -645,6 +539,5 @@ CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(tcpclt, LM_TCPCLT_FILENAME));
ENDmodInit
-#endif /* #ifdef SYSLOG_INET */
/* vim:set ai:
*/
diff --git a/relputil.c b/relputil.c
new file mode 100644
index 00000000..2e0f1f57
--- /dev/null
+++ b/relputil.c
@@ -0,0 +1,113 @@
+/* relputil.c
+ *
+ * This is a miscellaneous helper class for RELP features.
+ *
+ * Copyright 2008 Rainer Gerhards and Adiscon GmbH.
+ *
+ * This file is part of rsyslog.
+ *
+ * Rsyslog is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Rsyslog is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
+ */
+#include "config.h"
+#include "rsyslog.h"
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <relp.h>
+#include "syslogd.h"
+#include "syslogd-types.h"
+#include "srUtils.h"
+#include "net.h"
+#include "omfwd.h"
+#include "template.h"
+#include "msg.h"
+#include "tcpsyslog.h"
+#include "module-template.h"
+#include "obj.h"
+#include "errmsg.h"
+#include "relputil.h"
+
+MODULE_TYPE_LIB
+
+/* static data */
+DEFobjStaticHelpers
+DEFobjCurrIf(errmsg)
+
+
+/* queryInterface function
+ * rgerhards, 2008-02-29
+ */
+BEGINobjQueryInterface(relputil)
+CODESTARTobjQueryInterface(relputil)
+ if(pIf->ifVersion != relputilCURR_IF_VERSION) { /* check for current version, increment on each change */
+ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED);
+ }
+
+ /* ok, we have the right interface, so let's fill it
+ * Please note that we may also do some backwards-compatibility
+ * work here (if we can support an older interface version - that,
+ * of course, also affects the "if" above).
+ */
+
+finalize_it:
+ENDobjQueryInterface(relputil)
+
+
+/* exit our class
+ * rgerhards, 2008-03-10
+ */
+BEGINObjClassExit(relputil, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */
+CODESTARTObjClassExit(relputil)
+ /* release objects we no longer need */
+ objRelease(errmsg, CORE_COMPONENT);
+ENDObjClassExit(relputil)
+
+
+/* Initialize our class. Must be called as the very first method
+ * before anything else is called inside this class.
+ * rgerhards, 2008-02-29
+ */
+BEGINAbstractObjClassInit(relputil, 1, OBJ_IS_LOADABLE_MODULE) /* class, version - CHANGE class also in END MACRO! */
+ /* request objects we use */
+ CHKiRet(objUse(errmsg, CORE_COMPONENT));
+ENDObjClassInit(relputil)
+
+
+/* --------------- here now comes the plumbing that makes as a library module --------------- */
+
+
+BEGINmodExit
+CODESTARTmodExit
+ relputilClassExit();
+ENDmodExit
+
+
+BEGINqueryEtryPt
+CODESTARTqueryEtryPt
+CODEqueryEtryPt_STD_LIB_QUERIES
+ENDqueryEtryPt
+
+
+BEGINmodInit()
+CODESTARTmodInit
+ *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
+
+ /* Initialize all classes that are in our module - this includes ourselfs */
+ CHKiRet(relputilClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */
+ENDmodInit