summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--omfwd.c198
-rw-r--r--omfwd.h1
-rw-r--r--syslogd.c171
3 files changed, 200 insertions, 170 deletions
diff --git a/omfwd.c b/omfwd.c
index e38756c6..67aeb792 100644
--- a/omfwd.c
+++ b/omfwd.c
@@ -37,6 +37,10 @@
#include <fnmatch.h>
#include <assert.h>
#include <errno.h>
+#include <ctype.h>
+#ifdef USE_PTHREADS
+#include <pthread.h>
+#endif
#include "rsyslog.h"
#include "syslogd.h"
#include "syslogd-types.h"
@@ -273,6 +277,200 @@ rsRetVal modInitFwd(int iIFVersRequested __attribute__((unused)), int *ipIFVersP
*pQueryEtryPt = queryEtryPt;
return RS_RET_OK;
}
+
+
+/* try to process a selector action line. Checks if the action
+ * applies to this module and, if so, processed it. If not, it
+ * is left untouched. The driver will then call another module
+ */
+rsRetVal parseSelectorActFwd(uchar **pp, selector_t *f)
+{
+ uchar *p, *q;
+ int i;
+ int error;
+ int bErr;
+ rsRetVal iRet = RS_RET_CONFLINE_PROCESSED;
+ struct addrinfo hints, *res;
+ char szTemplateName[128];
+
+ assert(pp != NULL);
+ assert(f != NULL);
+
+ p = *pp;
+
+ switch (*p)
+ {
+ case '@':
+ ++p; /* eat '@' */
+ if(*p == '@') { /* indicator for TCP! */
+ f->f_un.f_forw.protocol = FORW_TCP;
+ ++p; /* eat this '@', too */
+ /* in this case, we also need a mutex... */
+# ifdef USE_PTHREADS
+ pthread_mutex_init(&f->f_un.f_forw.mtxTCPSend, 0);
+# endif
+ } else {
+ f->f_un.f_forw.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 */
+# ifdef USE_NETZIP
+ ++p; /* eat */
+ if(isdigit((int) *p)) {
+ int iLevel;
+ iLevel = *p - '0';
+ ++p; /* eat */
+ f->f_un.f_forw.compressionLevel = iLevel;
+ } else {
+ logerrorInt("Invalid compression level '%c' specified in "
+ "forwardig action - NOT turning on compression.",
+ *p);
+ }
+# else
+ logerror("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 */
+ f->f_un.f_forw.tcp_framing = TCP_FRAMING_OCTET_COUNTING;
+ } else { /* invalid option! Just skip it... */
+ logerrorInt("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)
+ */
+ logerror("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 */;
+
+ f->f_un.f_forw.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 */;
+ f->f_un.f_forw.port = malloc(i + 1);
+ if(f->f_un.f_forw.port == NULL) {
+ logerror("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(f->f_un.f_forw.port, tmp, i);
+ *(f->f_un.f_forw.port + i) = '\0';
+ }
+ }
+
+ /* 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;
+ logerror("invalid selector line (port), probably not doing "
+ "what was intended");
+ }
+ }
+ ++p;
+ }
+
+ if(*p == ';') {
+ *p = '\0'; /* trick to obtain hostname (later)! */
+ ++p;
+ /* Now look for the template! */
+ cflineParseTemplateName(&p, szTemplateName,
+ sizeof(szTemplateName) / sizeof(char));
+ } else
+ szTemplateName[0] = '\0';
+ if(szTemplateName[0] == '\0') {
+ /* we do not have a template, so let's use the default */
+ strcpy(szTemplateName, " StdFwdFmt");
+ }
+
+ /* first set the f->f_type */
+ strcpy(f->f_un.f_forw.f_hname, (char*) q);
+ 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 = f->f_un.f_forw.protocol == FORW_UDP ? SOCK_DGRAM : SOCK_STREAM;
+ f->doAction = doActionFwd;
+ if( (error = getaddrinfo(f->f_un.f_forw.f_hname, getFwdSyslogPt(f), &hints, &res)) != 0) {
+ f->f_type = F_FORW_UNKN;
+ f->f_prevcount = INET_RETRY_MAX;
+ f->f_un.f_forw.ttSuspend = time(NULL);
+ } else {
+ f->f_type = F_FORW;
+ f->f_un.f_forw.f_addr = res;
+ }
+
+ /* then try to find the template and re-set f_type to UNUSED
+ * if it can not be found. */
+ cflineSetTemplateAndIOV(f, szTemplateName);
+ if(f->f_type == F_UNUSED)
+ /* safety measure to make sure we have a valid
+ * selector line before we continue down below.
+ * rgerhards 2005-07-29
+ */
+ break;
+
+ dprintf("forwarding host: '%s:%s/%s' template '%s'\n", q, getFwdSyslogPt(f),
+ f->f_un.f_forw.protocol == FORW_UDP ? "udp" : "tcp",
+ szTemplateName);
+ /*
+ * 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.
+ */
+ default:
+ iRet = RS_RET_CONFLINE_UNPROCESSED;
+ break;
+ }
+
+ if(iRet == RS_RET_CONFLINE_PROCESSED)
+ *pp = p;
+ return iRet;
+}
+
#endif /* #ifdef SYSLOG_INET */
/*
* vi:set ai:
diff --git a/omfwd.h b/omfwd.h
index 391c73c2..b65c7637 100644
--- a/omfwd.h
+++ b/omfwd.h
@@ -27,6 +27,7 @@
/* prototypes */
int doActionFwd(selector_t *f);
rsRetVal modInitFwd(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)());
+rsRetVal parseSelectorActFwd(uchar **pp, selector_t *f);
#endif /* #ifndef OMFWD_H_INCLUDED */
/*
diff --git a/syslogd.c b/syslogd.c
index c745b7ab..b59b584d 100644
--- a/syslogd.c
+++ b/syslogd.c
@@ -5037,16 +5037,8 @@ static rsRetVal cflineProcessTagSelector(uchar **pline)
static rsRetVal cfline(char *line, register selector_t *f)
{
uchar *p;
- register uchar *q;
- register int i;
int syncfile;
rsRetVal iRet;
-#ifdef SYSLOG_INET
- struct addrinfo hints, *res;
- int error;
- int bErr;
-#endif
- char szTemplateName[128];
#ifdef WITH_DB
int iMySQLPropErr = 0;
#endif
@@ -5105,168 +5097,7 @@ static rsRetVal cfline(char *line, register selector_t *f)
switch (*p)
{
case '@':
-#ifdef SYSLOG_INET
- ++p; /* eat '@' */
- if(*p == '@') { /* indicator for TCP! */
- f->f_un.f_forw.protocol = FORW_TCP;
- ++p; /* eat this '@', too */
- /* in this case, we also need a mutex... */
-# ifdef USE_PTHREADS
- pthread_mutex_init(&f->f_un.f_forw.mtxTCPSend, 0);
-# endif
- } else {
- f->f_un.f_forw.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 */
-# ifdef USE_NETZIP
- ++p; /* eat */
- if(isdigit((int) *p)) {
- int iLevel;
- iLevel = *p - '0';
- ++p; /* eat */
- f->f_un.f_forw.compressionLevel = iLevel;
- } else {
- logerrorInt("Invalid compression level '%c' specified in "
- "forwardig action - NOT turning on compression.",
- *p);
- }
-# else
- logerror("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 */
- f->f_un.f_forw.tcp_framing = TCP_FRAMING_OCTET_COUNTING;
- } else { /* invalid option! Just skip it... */
- logerrorInt("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)
- */
- logerror("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 */;
-
- f->f_un.f_forw.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 */;
- f->f_un.f_forw.port = malloc(i + 1);
- if(f->f_un.f_forw.port == NULL) {
- logerror("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(f->f_un.f_forw.port, tmp, i);
- *(f->f_un.f_forw.port + i) = '\0';
- }
- }
-
- /* 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;
- logerror("invalid selector line (port), probably not doing "
- "what was intended");
- }
- }
- ++p;
- }
-
- if(*p == ';') {
- *p = '\0'; /* trick to obtain hostname (later)! */
- ++p;
- /* Now look for the template! */
- cflineParseTemplateName(&p, szTemplateName,
- sizeof(szTemplateName) / sizeof(char));
- } else
- szTemplateName[0] = '\0';
- if(szTemplateName[0] == '\0') {
- /* we do not have a template, so let's use the default */
- strcpy(szTemplateName, " StdFwdFmt");
- }
-
- /* first set the f->f_type */
- strcpy(f->f_un.f_forw.f_hname, (char*) q);
- 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 = f->f_un.f_forw.protocol == FORW_UDP ? SOCK_DGRAM : SOCK_STREAM;
- f->doAction = doActionFwd;
- if( (error = getaddrinfo(f->f_un.f_forw.f_hname, getFwdSyslogPt(f), &hints, &res)) != 0) {
- f->f_type = F_FORW_UNKN;
- f->f_prevcount = INET_RETRY_MAX;
- f->f_un.f_forw.ttSuspend = time(NULL);
- } else {
- f->f_type = F_FORW;
- f->f_un.f_forw.f_addr = res;
- }
-
- /* then try to find the template and re-set f_type to UNUSED
- * if it can not be found. */
- cflineSetTemplateAndIOV(f, szTemplateName);
- if(f->f_type == F_UNUSED)
- /* safety measure to make sure we have a valid
- * selector line before we continue down below.
- * rgerhards 2005-07-29
- */
- break;
-
- dprintf("forwarding host: '%s:%s/%s' template '%s'\n", q, getFwdSyslogPt(f),
- f->f_un.f_forw.protocol == FORW_UDP ? "udp" : "tcp",
- szTemplateName);
- /*
- * 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.
- */
-#endif /* #ifdef SYSLOG_INET */
+ parseSelectorActFwd(&p, f);
break;
case '$':