summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AUTHORS31
-rw-r--r--ChangeLog33
-rw-r--r--Makefile.am4
-rw-r--r--action.c3
-rw-r--r--configure.ac40
-rw-r--r--doc/Makefile.am5
-rw-r--r--doc/index.html7
-rw-r--r--doc/man_rsyslogd.html438
-rw-r--r--doc/manual.html23
-rw-r--r--doc/omudpspoof.html77
-rw-r--r--doc/rsconf1_dirgroup.html2
-rw-r--r--doc/rsconf1_dirowner.html2
-rw-r--r--doc/rsconf1_filegroup.html2
-rw-r--r--doc/rsconf1_fileowner.html2
-rw-r--r--doc/rsyslog_conf_global.html19
-rw-r--r--doc/rsyslog_conf_modules.html1
-rw-r--r--doc/rsyslog_php_syslog_ng.html4
-rw-r--r--doc/rsyslog_recording_pri.html2
-rw-r--r--doc/rsyslog_tls.html2
-rw-r--r--doc/status.html8
-rw-r--r--doc/v4compatibility.html77
-rw-r--r--doc/v5compatibility.html19
-rw-r--r--plugins/omstdout/omstdout.c13
-rw-r--r--plugins/omudpspoof/Makefile.am8
-rw-r--r--plugins/omudpspoof/omudpspoof.c500
-rw-r--r--runtime/conf.c18
-rw-r--r--runtime/conf.h6
-rw-r--r--runtime/glbl.c5
-rw-r--r--runtime/glbl.h3
-rw-r--r--runtime/msg.c347
-rw-r--r--runtime/msg.h6
-rw-r--r--runtime/parser.c1
-rw-r--r--runtime/rsyslog.h3
-rw-r--r--runtime/rule.c7
-rw-r--r--runtime/wti.c1
-rw-r--r--tcpclt.c14
-rw-r--r--tcpclt.h6
-rw-r--r--template.c6
-rw-r--r--tests/Makefile.am6
-rwxr-xr-xtests/diag.sh1
-rw-r--r--tests/nettester.c17
-rwxr-xr-xtests/parsertest.sh18
-rwxr-xr-xtests/proprepltest.sh7
-rw-r--r--tests/testsuites/master.nolimittag11
-rw-r--r--tests/testsuites/master.rfctag11
-rw-r--r--tests/testsuites/nolimittag.conf8
-rw-r--r--tests/testsuites/rfctag.conf9
-rw-r--r--tools/omfwd.c14
-rw-r--r--tools/rsyslogd.815
-rw-r--r--tools/syslogd.c328
50 files changed, 1157 insertions, 1033 deletions
diff --git a/AUTHORS b/AUTHORS
index b19f528a..8a3b5560 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,19 +1,14 @@
-Rainer Gerhards <rgerhards@adiscon.com>, Adiscon GmbH
-Michael Meckelein <mmeckelein@hq.adiscon.com>, Adiscon GmbH
+Thankfully, we have had so many contributions that maintaining the
+AUTHORS file would be a big task in itself. On the other hand, we
+now use git and I make sure that each author receives proper credit
+for patches I receive.
-Contributors
-Michael Biebl
- - helped continously with autotools
- - provided numerous advise on how to do things under Linux
- - provided excellent advise in many, many cases
-Andres Riancho (andres-dot-riancho-at-gmail-dot-com)
- (alias APR in code files)
- - supplied regexp functionality for the property replacer - a great feature.
- thanks!
-Bjoern Kalkbrenner
- - provided code for the "execute shell script" action
-Peter Vrabec
- - provided IPv6-enabling code
-varmojfekoj
- - helped with a variety of things and, most importantly, contributed
- the gssapi functionality
+So rather than trying to reproduce the git author log here (and
+often making mistakes in that), I invite you to check the git logs.
+You can also do this online at
+
+http://git.adiscon.com/?p=rsyslog.git;a=summary
+
+Rainer Gerhards
+<rgerhards@adiscon.com>
+lead rsyslog developer
diff --git a/ChangeLog b/ChangeLog
index db3e69f7..8ddfa647 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,11 @@
---------------------------------------------------------------------------
+Version 5.1.3 [DEVEL] (rgerhards), 2009-07-??
+- enhance: UDP spoofing supported via new output module omudpspoof
+ See the omudpspoof documentation for details and samples
+- bugfix: message could be truncated after TAG, often when forwarding
+ This was a result of an internal processing error if maximum field
+ sizes had been specified in the property replacer.
+---------------------------------------------------------------------------
Version 5.1.2 [DEVEL] (rgerhards), 2009-07-08
- bugfix: properties inputname, fromhost, fromhost-ip, msg were lost when
working with disk queues
@@ -53,7 +60,18 @@ increase.
- increased ompgsql performance by adapting to new transactional
output module interface
---------------------------------------------------------------------------
-Version 4.5.1 [DEVEL] (rgerhards), 2009-07-??
+Version 4.5.2 [DEVEL] (rgerhards), 2009-07-??
+- bugfix: memory leak with some input modules. Those inputs that
+ use parseAndSubmitMsg() leak two small memory blocks with every message.
+ Typically, those process only relatively few messages, so the issue
+ does most probably not have any effect in practice.
+---------------------------------------------------------------------------
+Version 4.5.1 [DEVEL] (rgerhards), 2009-07-15
+- CONFIG CHANGE: $HUPisRestart default is now "off". We are doing this
+ to support removal of restart-type HUP in v5.
+- bugfix: fromhost-ip was sometimes truncated
+- bugfix: potential segfault when zip-compressed syslog records were
+ received (double free)
- bugfix: properties inputname, fromhost, fromhost-ip, msg were lost when
working with disk queues
- performance enhancement: much faster, up to twice as fast (depending
@@ -62,6 +80,16 @@ Version 4.5.1 [DEVEL] (rgerhards), 2009-07-??
was on. Happend e.g. with imuxsock.
- added $klogConsoleLogLevel directive which permits to set a new
console log level while rsyslog is active
+- bugfix: message could be truncated after TAG, often when forwarding
+ This was a result of an internal processing error if maximum field
+ sizes had been specified in the property replacer.
+- added ability for the TCP output action to "rebind" its send socket after
+ sending n messages (actually, it re-opens the connection, the name is
+ used because this is a concept very similiar to $ActionUDPRebindInterval).
+ New config directive $ActionSendTCPRebindInterval added for the purpose.
+ By default, rebinding is disabled. This is considered useful for load
+ balancers.
+- testbench improvements
---------------------------------------------------------------------------
Version 4.5.0 [DEVEL] (rgerhards), 2009-07-02
- activation order of inputs changed, they are now activated only after
@@ -324,6 +352,9 @@ version before switching to this one.
- bugfix: memory leak in ompgsql
Thanks to Ken for providing the patch
---------------------------------------------------------------------------
+Version 3.22.2 [v3-stable] (rgerhards), 2009-07-??
+- bugfix: sending syslog messages with zip compression did not work
+---------------------------------------------------------------------------
Version 3.22.1 [v3-stable] (rgerhards), 2009-07-02
- bugfix: invalid error message issued if $inlcudeConfig was on an empty
set of files (e.g. *.conf, where none such files existed)
diff --git a/Makefile.am b/Makefile.am
index 8a130655..34bb8f0d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -96,6 +96,10 @@ if ENABLE_OMSTDOUT
SUBDIRS += plugins/omstdout
endif
+if ENABLE_OMUDPSPOOF
+SUBDIRS += plugins/omudpspoof
+endif
+
if ENABLE_OMTEMPLATE
SUBDIRS += plugins/omtemplate
endif
diff --git a/action.c b/action.c
index 352f7f9c..ab89ffd3 100644
--- a/action.c
+++ b/action.c
@@ -45,6 +45,7 @@
#include "batch.h"
#include "wti.h"
#include "datetime.h"
+#include "unicode-helper.h"
#define NO_TIME_PROVIDED 0 /* indicate we do not provide any cached time */
@@ -1180,7 +1181,7 @@ doActionCallAction(action_t *pAction, msg_t *pMsg)
/* suppress duplicate messages */
if ((pAction->f_ReduceRepeated == 1) && pAction->f_pMsg != NULL &&
(pMsg->msgFlags & MARK) == 0 && getMSGLen(pMsg) == getMSGLen(pAction->f_pMsg) &&
- !strcmp(getMSG(pMsg), getMSG(pAction->f_pMsg)) &&
+ !ustrcmp(getMSG(pMsg), getMSG(pAction->f_pMsg)) &&
!strcmp(getHOSTNAME(pMsg), getHOSTNAME(pAction->f_pMsg)) &&
!strcmp(getPROCID(pMsg, LOCK_MUTEX), getPROCID(pAction->f_pMsg, LOCK_MUTEX)) &&
!strcmp(getAPPNAME(pMsg, LOCK_MUTEX), getAPPNAME(pAction->f_pMsg, LOCK_MUTEX))) {
diff --git a/configure.ac b/configure.ac
index e9cfe073..4f964c56 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.61)
-AC_INIT([rsyslog],[5.1.2],[rsyslog@lists.adiscon.com])
+AC_INIT([rsyslog],[5.1.3],[rsyslog@lists.adiscon.com])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([ChangeLog])
AC_CONFIG_MACRO_DIR([m4])
@@ -176,6 +176,7 @@ if test "$enable_regexp" = "yes"; then
fi
+
# zlib compression
AC_ARG_ENABLE(zlib,
[AS_HELP_STRING([--enable-zlib],[Enable zlib compression support @<:@default=yes@:>@])],
@@ -233,7 +234,7 @@ AC_ARG_ENABLE(pthreads,
)
if test "x$enable_pthreads" = "xno"; then
- AC_MSG_ERROR(rsyslog v3 does no longer support single threading mode -- use a previous version for that);
+ AC_MSG_ERROR(rsyslog v3+ does no longer support single threading mode -- use a previous version for that);
fi
if test "x$enable_pthreads" != "xno"; then
@@ -415,7 +416,7 @@ if test "x$enable_mysql" = "xyes"; then
[yes],,,
)
if test "x${HAVE_MYSQL_CONFIG}" != "xyes"; then
- AC_MSG_FAILURE([mysql_config not found in PATH])
+ AC_MSG_FAILURE([mysql_config not found in PATH - usually a package named mysql-dev, libmysql-dev or similar, is missing - install it to fix this issue])
fi
AC_CHECK_LIB(
[mysqlclient],
@@ -719,6 +720,36 @@ AC_ARG_ENABLE(omprog,
AM_CONDITIONAL(ENABLE_OMPROG, test x$enable_omprog = xyes)
+# settings for omudpspoof
+AC_ARG_ENABLE(omudpspoof,
+ [AS_HELP_STRING([--enable-omudpspoof],[Compiles omudpspoof module @<:@default=no@:>@])],
+ [case "${enableval}" in
+ yes) enable_omudpspoof="yes" ;;
+ no) enable_omudpspoof="no" ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-omudpspoof) ;;
+ esac],
+ [enable_omudpspoof=no]
+)
+
+if test "x$enable_omudpspoof" = "xyes"; then
+ AC_CHECK_HEADERS(
+ [libnet.h],,
+ [AC_MSG_FAILURE([libnet is missing])]
+ )
+ AC_CHECK_LIB(
+ [net],
+ [libnet_init],
+ [UDPSPOOF_CFLAGS=""
+ UDPSPOOF_LIBS="-lnet"
+ ],
+ [AC_MSG_FAILURE([libnet is missing])]
+ )
+fi
+AM_CONDITIONAL(ENABLE_OMUDPSPOOF, test x$enable_omudpspoof = xyes)
+AC_SUBST(UDPSPOOF_CFLAGS)
+AC_SUBST(UDPSPOOF_LIBS)
+
+
# settings for omstdout
AC_ARG_ENABLE(omstdout,
[AS_HELP_STRING([--enable-omstdout],[Compiles stdout module @<:@default=no@:>@])],
@@ -818,6 +849,7 @@ AC_CONFIG_FILES([Makefile \
plugins/ommail/Makefile \
plugins/omsnmp/Makefile \
plugins/omoracle/Makefile \
+ plugins/omudpspoof/Makefile \
plugins/cust1/Makefile \
tests/Makefile])
AC_OUTPUT
@@ -825,7 +857,6 @@ AC_OUTPUT
echo "****************************************************"
echo "rsyslog will be compiled with the following settings:"
echo
-echo " Multithreading support enabled: $enable_pthreads"
echo " Large file support enabled: $enable_largefile"
echo " Networking support enabled: $enable_inet"
echo " Regular expressions support enabled: $enable_regexp"
@@ -844,6 +875,7 @@ echo "---{ output plugins }---"
echo " Mail support enabled: $enable_mail"
echo " omprog module will be compiled: $enable_omprog"
echo " omstdout module will be compiled: $enable_omstdout"
+echo " omudpspoof module will be compiled: $enable_omudpspoof"
echo " output template module will be compiled: $enable_omtemplate"
echo
echo "---{ database support }---"
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 62ec7500..a447cddf 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -13,7 +13,6 @@ html_files = \
ipv6.html \
log_rotation_fix_size.html \
manual.html \
- man_rsyslogd.html \
modules.html \
property_replacer.html \
rsyslog_ng_comparison.html \
@@ -31,6 +30,8 @@ html_files = \
version_naming.html \
contributors.html \
dev_queue.html \
+ omstdout.html \
+ omudpspoof.html \
omsnmp.html \
ommysql.html \
omoracle.html \
@@ -91,6 +92,8 @@ html_files = \
rsconf1_resetconfigvariables.html \
rsconf1_umask.html \
v3compatibility.html \
+ v4compatibility.html \
+ v5compatibility.html \
im3195.html \
netstream.html \
ns_gtls.html \
diff --git a/doc/index.html b/doc/index.html
index 349c8e57..b3b336a7 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -25,8 +25,7 @@ To do the really cool things, though,
you need to learn a bit about its new features.
The man pages offer a bare minimum of information (and are still quite long). Read the
<a href="manual.html">html documentation</a> instead.
-When you change the configuration,
-remember to restart (or HUP) rsyslogd, because otherwise it won't use your
-new settings (and you'll end up totally puzzled why this great config of yours
-does not even work a bit...;))
+When you change the configuration, remember to restart rsyslogd, because otherwise
+it will not use your new settings (and you'll end up totally puzzled why this great
+config of yours does not even work a bit...;))
</body></html>
diff --git a/doc/man_rsyslogd.html b/doc/man_rsyslogd.html
deleted file mode 100644
index d18fd88a..00000000
--- a/doc/man_rsyslogd.html
+++ /dev/null
@@ -1,438 +0,0 @@
-<BODY><PRE>
-RSYSLOGD(8) Linux System Administration RSYSLOGD(8)
-
-
-
-<B>NAME</B>
- rsyslogd - reliable and extended syslogd
-
-<B>SYNOPSIS</B>
- <B>rsyslogd </B>[ <B>-4 </B>] [ <B>-6 </B>] [ <B>-A </B>] [ <B>-a </B><I>socket </I>] [ <B>-d </B>] [ <B>-e </B>]
- [ <B>-f </B><I>config file </I>] [ <B>-h </B>] [ <B>-i </B><I>pid file </I>] [ <B>-l </B><I>hostlist </I>]
- [ <B>-m </B><I>interval </I>] [ <B>-n </B>] [ <B>-o </B>] [ <B>-p </B><I>socket </I>]
- [ <B>-r </B><I>[port] </I>] [ <B>-s </B><I>domainlist </I>] [ <B>-t </B><I>port,max-nbr-of-sessions </I>]
- [ <B>-v </B>] [ <B>-w </B>] [ <B>-x </B>]
-
-
-<B>DESCRIPTION</B>
- <B>Rsyslogd </B>is a system utility providing support for message logging.
- Support of both internet and unix domain sockets enables this utility
- to support both local and remote logging (via UDP and TCP).
-
- <B>Rsyslogd</B>(8) is derived from the sysklogd package which in turn is
- derived from the stock BSD sources.
-
- <B>Rsyslogd </B>provides a kind of logging that many modern programs use.
- Every logged message contains at least a time and a hostname field,
- normally a program name field, too, but that depends on how trusty the
- logging program is. The rsyslog package supports free definition of
- output formats via templates. It also supports precise timestamps and
- writing directly to MySQL databases. If the database option is used,
- tools like phpLogCon can be used to view the log data.
-
- While the <B>rsyslogd </B>sources have been heavily modified a couple of notes
- are in order. First of all there has been a systematic attempt to
- insure that rsyslogd follows its default, standard BSD behavior. Of
- course, some configuration file changes are necessary in order to sup-
- port the template system. However, rsyslogd should be able to use a
- standard syslog.conf and act like the original syslogd. However, an
- original syslogd will not work correctly with a rsyslog-enhanced con-
- figuration file. At best, it will generate funny looking file names.
- The second important concept to note is that this version of rsyslogd
- interacts transparently with the version of syslog found in the stan-
- dard libraries. If a binary linked to the standard shared libraries
- fails to function correctly we would like an example of the anomalous
- behavior.
-
- The main configuration file <I>/etc/rsyslog.conf </I>or an alternative file,
- given with the <B>-f </B>option, is read at startup. Any lines that begin
- with the hash mark (‘‘#’’) and empty lines are ignored. If an error
- occurs during parsing the error element is ignored. It is tried to
- parse the rest of the line.
-
- For details and configuration examples, see the <B>rsyslog.conf (5) </B>man
- page.
-
-
-
-<B>OPTIONS</B>
- <B>-A </B>When sending UDP messages, there are potentially multiple paths
- to the target destination. By default, <B>rsyslogd </B>only sends to
- the first target it can successfully send to. If -A is given,
- messages are sent to all targets. This may improve reliability,
- but may also cause message duplication. This option should
- enabled only if it is fully understood.
-
- <B>-4 </B>Causes <B>rsyslogd </B>to listen to IPv4 addresses only. If neither -4
- nor -6 is given, <B>rsyslogd </B>listens to all configured addresses of
- the system.
-
- <B>-6 </B>Causes <B>rsyslogd </B>to listen to IPv6 addresses only. If neither -4
- nor -6 is given, <B>rsyslogd </B>listens to all configured addresses of
- the system.
-
- <B>-a </B><I>socket</I>
- Using this argument you can specify additional sockets from that
- <B>rsyslogd </B>has to listen to. This is needed if you’re going to
- let some daemon run within a chroot() environment. You can use
- up to 19 additional sockets. If your environment needs even
- more, you have to increase the symbol <B>MAXFUNIX </B>within the sys-
- logd.c source file. An example for a chroot() daemon is
- described by the people from OpenBSD at
- http://www.psionic.com/papers/dns.html.
-
- <B>-d </B>Turns on debug mode. Using this the daemon will not proceed a
- <B>fork</B>(2) to set itself in the background, but opposite to that
- stay in the foreground and write much debug information on the
- current tty. See the DEBUGGING section for more information.
-
- <B>-e </B>Set the default of $RepeatedMsgReduction config option to "off".
- Hine: "e" like "every message". For further information, see
- there.
-
- <B>-f </B><I>config file</I>
- Specify an alternative configuration file instead of <I>/etc/rsys-</I>
- <I>log.conf</I>, which is the default.
-
- <B>-h </B>By default rsyslogd will not forward messages it receives from
- remote hosts. Specifying this switch on the command line will
- cause the log daemon to forward any remote messages it receives
- to forwarding hosts which have been defined.
-
- <B>-i </B><I>pid file</I>
- Specify an alternative pid file instead of the default one.
- This option must be used if multiple instances of rsyslogd
- should run on a single machine.
-
- <B>-l </B><I>hostlist</I>
- Specify a hostname that should be logged only with its simple
- hostname and not the fqdn. Multiple hosts may be specified
- using the colon (‘‘:’’) separator.
-
- <B>-m </B><I>interval</I>
- The <B>rsyslogd </B>logs a mark timestamp regularly. The default
- <I>interval </I>between two <I>-- MARK -- </I>lines is 20 minutes. This can
- be changed with this option. Setting the <I>interval </I>to zero turns
- it off entirely.
-
- <B>-n </B>Avoid auto-backgrounding. This is needed especially if the
- <B>rsyslogd </B>is started and controlled by <B>init</B>(8).
-
- <B>-o </B>Omit reading the standard local log socket. This option is most
- useful for running multiple instances of rsyslogd on a single
- machine. When specified, no local log socket is opened at all.
-
- <B>-p </B><I>socket</I>
- You can specify an alternative unix domain socket instead of
- <I>/dev/log</I>.
-
- <B>-r </B><I>["port"]</I>
- Activates the syslog/udp listener service. The listener will
- listen to the specified port. If no port is specified, 0 is
- used as port number, which in turn will lead to a lookup of the
- system default syslog port. If there is no system default, 514
- is used. Please note that the port must immediately follow the
- -r option. Thus "-r514" is valid while "-r 514" is invalid (note
- the space).
-
- <B>-s </B><I>domainlist</I>
- Specify a domainname that should be stripped off before logging.
- Multiple domains may be specified using the colon (‘‘:’’) sepa-
- rator. Please be advised that no sub-domains may be specified
- but only entire domains. For example if <B>-s north.de </B>is speci-
- fied and the host logging resolves to satu.infodrom.north.de no
- domain would be cut, you will have to specify two domains like:
- <B>-s north.de:infodrom.north.de</B>.
-
- <B>-t </B><I>port,max-nbr-of-sessions</I>
- Activates the syslog/tcp listener service. The listener will
- listen to the specified port. If max-nbr-of-sessions is speci-
- fied, that becomes the maximum number of concurrent tcp ses-
- sions. If not specified, the default is 200. Please note that
- syslog/tcp is not standardized, but the implementation in rsys-
- logd follows common practice and is compatible with e.g. Cisco
- PIX, syslog-ng and MonitorWare (Windows). Please note that the
- port must immediately follow the -t option. Thus "-t514" is
- valid while "-t 514" is invalid (note the space).
-
- <B>-v </B>Print version and exit.
-
- <B>-w </B>Supress warnings issued when messages are received from non-
- authorized machines (those, that are in no AllowedSender list).
-
- <B>-x </B>Disable DNS for remote messages.
-
-
-<B>SIGNALS</B>
- <B>Rsyslogd </B>reacts to a set of signals. You may easily send a signal to
- <B>rsyslogd </B>using the following:
-
- kill -SIGNAL ‘cat /var/run/rsyslogd.pid‘
-
-
- <B>SIGHUP </B>This lets <B>rsyslogd </B>perform a re-initialization. All open files
- are closed, the configuration file (default is <I>/etc/rsys-</I>
- <I>log.conf</I>) will be reread and the <B>rsyslog</B>(3) facility is started
- again.
-
- <B>SIGTERM</B>
- <B>Rsyslogd </B>will die.
-
- <B>SIGINT</B>, <B>SIGQUIT</B>
- If debugging is enabled these are ignored, otherwise <B>rsyslogd</B>
- will die.
-
- <B>SIGUSR1</B>
- Switch debugging on/off. This option can only be used if <B>rsys-</B>
- <B>logd </B>is started with the <B>-d </B>debug option.
-
- <B>SIGCHLD</B>
- Wait for childs if some were born, because of wall’ing messages.
-
-
-<B>SUPPORT FOR REMOTE LOGGING</B>
- <B>Rsyslogd </B>provides network support to the syslogd facility. Network
- support means that messages can be forwarded from one node running
- rsyslogd to another node running rsyslogd (or a compatible syslog
- implementation) where they will be actually logged to a disk file.
-
- To enable this you have to specify either the <B>-r </B>or <B>-t </B>option on the
- command line. The default behavior is that <B>rsyslogd </B>won’t listen to
- the network. You can also combine these two options if you want rsys-
- logd to listen to both TCP and UDP messages.
-
- The strategy is to have rsyslogd listen on a unix domain socket for
- locally generated log messages. This behavior will allow rsyslogd to
- inter-operate with the syslog found in the standard C library. At the
- same time rsyslogd listens on the standard syslog port for messages
- forwarded from other hosts. To have this work correctly the <B>ser-</B>
- <B>vices</B>(5) files (typically found in <I>/etc</I>) must have the following entry:
-
- syslog 514/udp
-
- If this entry is missing <B>rsyslogd </B>will use the well known port of 514
- (so in most cases, it’s not really needed).
-
- To cause messages to be forwarded to another host replace the normal
- file line in the <I>rsyslog.conf </I>file with the name of the host to which
- the messages is to be sent prepended with an @ (for UDP delivery) or
- the sequence @@ (for TCP delivery). The host name can also be followed
- by a colon and a port number, in which case the message is sent to the
- specified port on the remote host.
-
- For example, to forward <B>ALL </B>messages to a remote host use the
- following <I>rsyslog.conf </I>entry:
-
- # Sample rsyslogd configuration file to
- # messages to a remote host forward all.
- *.* @hostname
- More samples can be found in sample.conf.
-
- If the remote hostname cannot be resolved at startup, because
- the name-server might not be accessible (it may be started after
- rsyslogd) you don’t have to worry. <B>Rsyslogd </B>will retry to
- resolve the name ten times and then complain. Another possibil-
- ity to avoid this is to place the hostname in <I>/etc/hosts</I>.
-
- With normal <B>syslogd</B>s you would get syslog-loops if you send out
- messages that were received from a remote host to the same host
- (or more complicated to a third host that sends it back to the
- first one, and so on).
-
- To avoid this no messages that were received from a remote host
- are sent out to another (or the same) remote host. You can dis-
- able this feature by the <B>-h </B>option.
-
- If the remote host is located in the same domain as the host,
- <B>rsyslogd </B>is running on, only the simple hostname will be logged
- instead of the whole fqdn.
-
- In a local network you may provide a central log server to have
- all the important information kept on one machine. If the net-
- work consists of different domains you don’t have to complain
- about logging fully qualified names instead of simple hostnames.
- You may want to use the strip-domain feature <B>-s </B>of this server.
- You can tell <B>rsyslogd </B>to strip off several domains other than
- the one the server is located in and only log simple hostnames.
-
- Using the <B>-l </B>option there’s also a possibility to define single
- hosts as local machines. This, too, results in logging only
- their simple hostnames and not the fqdns.
-
-
-<B>OUTPUT TO DATABASES</B>
- <B>Rsyslogd </B>has support for writing data to MySQL database tables. The
- exact specifics are described in the <B>rsyslog.conf (5) </B>man page. Be sure
- to read it if you plan to use database logging.
-
- While it is often handy to have the data in a database, you must be
- aware of the implications. Most importantly, database logging takes far
- longer than logging to a text file. A system that can handle a large
- log volume when writing to text files can most likely not handle a sim-
- ilar large volume when writing to a database table.
-
-
-<B>OUTPUT TO NAMED PIPES (FIFOs)</B>
- <B>Rsyslogd </B>has support for logging output to named pipes (fifos). A fifo
- or named pipe can be used as a destination for log messages by prepend-
- ing a pipy symbol (‘‘|’’) to the name of the file. This is handy for
- debugging. Note that the fifo must be created with the mkfifo command
- before <B>rsyslogd </B>is started.
-
- The following configuration file routes debug messages from the
- kernel to a fifo:
-
- # Sample configuration to route kernel debugging
- # messages ONLY to /usr/adm/debug which is a
- # named pipe.
- kern.=debug |/usr/adm/debug
-
-
-<B>INSTALLATION CONCERNS</B>
- There is probably one important consideration when installing rsyslogd.
- It is dependent on proper formatting of messages by the syslog func-
- tion. The functioning of the syslog function in the shared libraries
- changed somewhere in the region of libc.so.4.[2-4].n. The specific
- change was to null-terminate the message before transmitting it to the
- <I>/dev/log </I>socket. Proper functioning of this version of rsyslogd is
- dependent on null-termination of the message.
-
- This problem will typically manifest itself if old statically linked
- binaries are being used on the system. Binaries using old versions of
- the syslog function will cause empty lines to be logged followed by the
- message with the first character in the message removed. Relinking
- these binaries to newer versions of the shared libraries will correct
- this problem.
-
- The <B>rsyslogd</B>(8) can be run from <B>init</B>(8) or started as part of the rc.*
- sequence. If it is started from init the option <I>-n </I>must be set, other-
- wise you’ll get tons of syslog daemons started. This is because
- <B>init</B>(8) depends on the process ID.
-
-
-<B>SECURITY THREATS</B>
- There is the potential for the rsyslogd daemon to be used as a conduit
- for a denial of service attack. A rogue program(mer) could very easily
- flood the rsyslogd daemon with syslog messages resulting in the log
- files consuming all the remaining space on the filesystem. Activating
- logging over the inet domain sockets will of course expose a system to
- risks outside of programs or individuals on the local machine.
-
- There are a number of methods of protecting a machine:
-
- 1. Implement kernel firewalling to limit which hosts or networks
- have access to the 514/UDP socket.
-
- 2. Logging can be directed to an isolated or non-root filesystem
- which, if filled, will not impair the machine.
-
- 3. The ext2 filesystem can be used which can be configured to limit
- a certain percentage of a filesystem to usage by root only.
- <B>NOTE </B>that this will require rsyslogd to be run as a non-root
- process. <B>ALSO NOTE </B>that this will prevent usage of remote log-
- ging since rsyslogd will be unable to bind to the 514/UDP
- socket.
-
- 4. Disabling inet domain sockets will limit risk to the local
- machine.
-
- 5. Use step 4 and if the problem persists and is not secondary to a
- rogue program/daemon get a 3.5 ft (approx. 1 meter) length of
- sucker rod* and have a chat with the user in question.
-
- Sucker rod def. — 3/4, 7/8 or 1in. hardened steel rod, male
- threaded on each end. Primary use in the oil industry in West-
- ern North Dakota and other locations to pump ’suck’ oil from oil
- wells. Secondary uses are for the construction of cattle feed
- lots and for dealing with the occasional recalcitrant or bel-
- ligerent individual.
-
- <B>Message replay and spoofing</B>
- If remote logging is enabled, messages can easily be spoofed and
- replayed. As the messages are transmitted in clear-text, an attacker
- might use the information obtained from the packets for malicious
- things. Also, an attacker might reply recorded messages or spoof a
- sender’s IP address, which could lead to a wrong perception of system
- activity. Be sure to think about syslog network security before
- enabling it.
-
-
-<B>DEBUGGING</B>
- When debugging is turned on using <B>-d </B>option then <B>rsyslogd </B>will be very
- verbose by writing much of what it does on stdout. Whenever the con-
- figuration file is reread and re-parsed you’ll see a tabular, corre-
- sponding to the internal data structure. This tabular consists of four
- fields:
-
- <I>number </I>This field contains a serial number starting by zero. This num-
- ber represents the position in the internal data structure (i.e.
- the array). If one number is left out then there might be an
- error in the corresponding line in <I>/etc/rsyslog.conf</I>.
-
- <I>pattern</I>
- This field is tricky and represents the internal structure
- exactly. Every column stands for a facility (refer to <B>sys-</B>
- <B>log</B>(3)). As you can see, there are still some facilities left
- free for former use, only the left most are used. Every field
- in a column represents the priorities (refer to <B>syslog</B>(3)).
-
- <I>action </I>This field describes the particular action that takes place
- whenever a message is received that matches the pattern. Refer
- to the <B>syslog.conf</B>(5) manpage for all possible actions.
-
- <I>arguments</I>
- This field shows additional arguments to the actions in the last
- field. For file-logging this is the filename for the logfile;
- for user-logging this is a list of users; for remote logging
- this is the hostname of the machine to log to; for console-log-
- ging this is the used console; for tty-logging this is the spec-
- ified tty; wall has no additional arguments.
-
-
- <B>templates</B>
- There will also be a second internal structure which lists all
- defined templates and there contents. This also enables you to
- see the internally-defined, hardcoded templates.
-
-<B>FILES</B>
- <I>/etc/rsyslog.conf</I>
- Configuration file for <B>rsyslogd</B>. See <B>rsyslog.conf</B>(5) for exact
- information.
- <I>/dev/log</I>
- The Unix domain socket to from where local syslog messages are
- read.
- <I>/var/run/rsyslogd.pid</I>
- The file containing the process id of <B>rsyslogd</B>.
-
-<B>BUGS</B>
- Please review the file BUGS for up-to-date information on known bugs
- and annoyances.
-
-<B>Further Information</B>
- Please visit <B>http://www.rsyslog.com/doc </B>for additional information,
- tutorials and a support forum.
-
-<B>SEE ALSO</B>
- <B>rsyslog.conf</B>(5), <B>logger</B>(1), <B>syslog</B>(2), <B>syslog</B>(3), <B>services</B>(5),
- <B>savelog</B>(8)
-
-
-<B>COLLABORATORS</B>
- <B>rsyslogd </B>is derived from sysklogd sources, which in turn was taken from
- the BSD sources. Special thanks to Greg Wettstein (greg@wind.enjel-
- lic.com) and Martin Schulze (joey@linux.de) for the fine sysklogd pack-
- age.
-
- Rainer Gerhards
- Adiscon GmbH
- Grossrinderfeld, Germany
- rgerhards@adiscon.com
-
- Michael Meckelein
- Adiscon GmbH
- mmeckelein@adiscon.com
-
-
-
-Version 1.16.1 (devel) 17 July 2007 RSYSLOGD(8)
-</PRE></BODY>
diff --git a/doc/manual.html b/doc/manual.html
index 96497300..f45a4952 100644
--- a/doc/manual.html
+++ b/doc/manual.html
@@ -19,21 +19,24 @@ rsyslog support</a> available directly from the source!</p>
<p><b>Please visit the <a href="http://www.rsyslog.com/sponsors">rsyslog sponsor's page</a>
to honor the project sponsors or become one yourself!</b> We are very grateful for any help towards the
project goals.</p>
-<p><b>This documentation is for version 5.1.2 (devel branch) of rsyslog.</b>
-Visit the <i> <a href="http://www.rsyslog.com/doc-status.html">rsyslog status page</a></i></b> to obtain current
-version information and project status.
+<p><b>This documentation is for version 5.1.3 (devel branch) of rsyslog.</b>
+Visit the <i><a href="http://www.rsyslog.com/doc-status.html">rsyslog status page</a></i></b>
+to obtain current version information and project status.
</p><p><b>If you like rsyslog, you might
want to lend us a helping hand. </b>It doesn't require a lot of
time - even a single mouse click helps. Learn <a href="how2help.html">how to help the rsyslog project</a>.
Due to popular demand, there is now a <a href="rsyslog_ng_comparison.html">side-by-side comparison
between rsyslog and syslog-ng</a>.</p>
<p>If you are upgrading from rsyslog v2 or stock sysklogd,
-<a href="v3compatibility.html">be
-sure to read the rsyslog v3 compatibility document!</a> It will work even
+<a href="v3compatibility.html">be sure to read the rsyslog v3 compatibility notes</a>,
+and if you are upgrading from v3, read the
+<a href="v4compatibility.html">rsyslog v4 compatibility notes</a> and
+if you upgrade from v4, read the
+<a href="v5compatibility.html">rsyslog v5 compatibility notes</a>.
+<p>Rsyslog will work even
if you do not read the doc, but doing so will definitely improve your experience.</p>
-<p><span style="font-weight: bold;"></span><b>Follow
-the links below for the</b><br></p><ul>
-
+<p><b>Follow the links below for the</b></p>
+<ul>
<li><a href="troubleshoot.html">troubleshooting rsyslog problems</a></li>
<li><a href="rsyslog_conf.html">configuration file syntax (rsyslog.conf)</a></li>
<li><a href="http://www.rsyslog.com/tool-regex">a regular expression checker/generator tool for rsyslog</a></li>
@@ -41,10 +44,8 @@ the links below for the</b><br></p><ul>
<li>a commented <a href="sample.conf.html">sample rsyslog.conf</a> </li>
<li><a href="bugs.html">rsyslog bug list</a></li>
<li><a href="rsyslog_packages.html"> rsyslog packages</a></li>
-<li><a href="generic_design.html">backgrounder on
-generic syslog application design</a></li>
+<li><a href="generic_design.html">backgrounder on generic syslog application design</a></li>
<li><a href="modules.html">description of rsyslog modules</a></li>
-<li><a href="man_rsyslogd.html">rsyslogd man page</a> (heavily outdated)</li>
</ul>
<p><b>We have some in-depth papers on</b></p>
<ul>
diff --git a/doc/omudpspoof.html b/doc/omudpspoof.html
new file mode 100644
index 00000000..e5f963c7
--- /dev/null
+++ b/doc/omudpspoof.html
@@ -0,0 +1,77 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+<title>UDP spoofing output module (omudpspoof)</title>
+</head>
+<body>
+<a href="rsyslog_conf_modules.html">rsyslog module reference</a>
+
+<h1>UDP spoofing output module (omudpspoof)</h1>
+<p><b>Module Name:&nbsp;&nbsp;&nbsp; omstdout</b></p>
+<p><b>Author: </b>David Lang &lt;david@lang.hm&gt; and Rainer Gerhards
+&lt;rgerhards@adiscon.com&gt;</p>
+<p><b>Available Since</b>: 5.1.3</p>
+<p><b>Description</b>:</p>
+<p>This module is similar to the regular UDP forwarder, but permits to
+spoof the sender address. Also, it enables to circle through a number of
+source ports.
+<p><b>Configuration Directives</b>:</p>
+<ul>
+<li><b>$ActionUDPSpoofSourceNameTemplate</b> &lt;templatename&gt;<br>
+This MUST be specified. It is the name of the template that contains a
+numerical IP address that is to be used as the source system IP address.
+While it may often be a constant value, it can be generated as usual via the
+property replacer, as long as it is a valid IPv4 address.
+<li><b>$ActionUDPSpoofTargetHost</b> &lt;hostname&gt;<br>
+Host that the messages shall be sent to.
+<li><b>$ActionUDPSpoofTargetPort</b> &lt;port&gt;<br>
+Remote port that the messages shall be sent to.
+<li><b>$ActionUDPSpoofDefaultTemplate</b> &lt;templatename&gt;<br>
+This setting instructs omudpspoof to use a template different from the
+default template for all of its actions that do not have a template specified
+explicitely.
+<li><b>$ActionUDPSpoofSourcePortStart</b> &lt;number&gt;<br>
+Specifies the start value for circeling the source ports. Must be less than or
+equal to the end value. Default is 32000.
+<li><b>$ActionUDPSpoofSourcePortEnd</b> &lt;number&gt;<br>
+Specifies the ending value for circeling the source ports. Must be less than or
+equal to the start value. Default is 42000.
+</ul>
+<b>Caveats/Known Bugs:</b>
+<ul>
+<li><b>IPv6</b> is currently not supported. If you need this capability, please let us
+know via the rsyslog mailing list.
+</ul>
+<p><b>Sample:</b></p>
+<p>The following sample forwards all syslog messages in unmodified form to the
+remote server server.example.com. The sender address 192.0.2.1 with the fixed
+source port 514 is used.
+</p>
+<textarea rows="8" cols="80">$ModLoad omudpspoof
+$template spoofaddr,"192.0.2.1"
+$template spooftemplate,"%rawmsg%"
+$ActionUDPSpoofSourceNameTemplate spoofaddr
+$ActionUDPSpoofTargetHost server.example.com
+$ActionUDPSpoofSourcePortStart 514
+$ActionUDPSpoofSourcePortEnd 514
+*.*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :omudpspoof:;spooftemplate
+</textarea>
+<p>The following sample is similar to the first, but uses as many defaults as possible.
+In that sample, a source port in the range 32000..42000 is used. The message is formatted
+according to rsyslog's canned default forwarding format. Note that if any parameters
+have been changed, the previously set defaults will be used!
+</p>
+<textarea rows="5" cols="80">$ModLoad omudpspoof
+$template spoofaddr,"192.0.2.1"
+$ActionUDPSpoofSourceNameTemplate spoofaddr
+$ActionUDPSpoofTargetHost server.example.com
+*.*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :omudpspoof:
+</textarea>
+<p>[<a href="rsyslog_conf.html">rsyslog.conf overview</a>]
+[<a href="manual.html">manual index</a>] [<a href="http://www.rsyslog.com/">rsyslog site</a>]</p>
+<p><font size="2">This documentation is part of the
+<a href="http://www.rsyslog.com/">rsyslog</a>
+project.<br>
+Copyright &copy; 2009 by <a href="http://www.gerhards.net/rainer">Rainer Gerhards</a> and
+<a href="http://www.adiscon.com/">Adiscon</a>.
+Released under the GNU GPL version 3 or higher.</font></p>
+</body></html>
diff --git a/doc/rsconf1_dirgroup.html b/doc/rsconf1_dirgroup.html
index de070126..4bc8692f 100644
--- a/doc/rsconf1_dirgroup.html
+++ b/doc/rsconf1_dirgroup.html
@@ -9,7 +9,7 @@
<p><b>Type:</b> global configuration directive</p>
<p><b>Default:</b> </p>
<p><b>Description:</b></p>
-<p>Set the group for directories newly created. Please note that this setting does not affect the group of directories already existing. The parameter is a group name, for which the groupid is obtained by rsyslogd on startup and on HUPing. Interim changes to the user mapping are not detected.</p>
+<p>Set the group for directories newly created. Please note that this setting does not affect the group of directories already existing. The parameter is a group name, for which the groupid is obtained by rsyslogd on during startup processing. Interim changes to the user mapping are not detected.</p>
<p><b>Sample:</b></p>
<p><code><b>$DirGroup loggroup</b></code></p>
diff --git a/doc/rsconf1_dirowner.html b/doc/rsconf1_dirowner.html
index da8e252d..f779c008 100644
--- a/doc/rsconf1_dirowner.html
+++ b/doc/rsconf1_dirowner.html
@@ -9,7 +9,7 @@
<p><b>Type:</b> global configuration directive</p>
<p><b>Default:</b> </p>
<p><b>Description:</b></p>
-<p>Set the file owner for directories newly created. Please note that this setting does not affect the owner of directories already existing. The parameter is a user name, for which the userid is obtained by rsyslogd on startup and on HUPing. Interim changes to the user mapping are not detected.</p>
+<p>Set the file owner for directories newly created. Please note that this setting does not affect the owner of directories already existing. The parameter is a user name, for which the userid is obtained by rsyslogd during startup processing. Interim changes to the user mapping are not detected.</p>
<p><b>Sample:</b></p>
<p><code><b>$DirOwner loguser</b></code></p>
diff --git a/doc/rsconf1_filegroup.html b/doc/rsconf1_filegroup.html
index dd5b8ad5..935f074a 100644
--- a/doc/rsconf1_filegroup.html
+++ b/doc/rsconf1_filegroup.html
@@ -9,7 +9,7 @@
<p><b>Type:</b> global configuration directive</p>
<p><b>Default:</b> </p>
<p><b>Description:</b></p>
-<p>Set the group for dynaFiles newly created. Please note that this setting does not affect the group of files already existing. The parameter is a group name, for which the groupid is obtained by rsyslogd on startup and on HUPing. Interim changes to the user mapping are not detected.</p>
+<p>Set the group for dynaFiles newly created. Please note that this setting does not affect the group of files already existing. The parameter is a group name, for which the groupid is obtained by rsyslogd during startup processing. Interim changes to the user mapping are not detected.</p>
<p><b>Sample:</b></p>
<p><code><b>$FileGroup loggroup</b></code></p>
diff --git a/doc/rsconf1_fileowner.html b/doc/rsconf1_fileowner.html
index 935cfffd..62125c8d 100644
--- a/doc/rsconf1_fileowner.html
+++ b/doc/rsconf1_fileowner.html
@@ -9,7 +9,7 @@
<p><b>Type:</b> global configuration directive</p>
<p><b>Default:</b> </p>
<p><b>Description:</b></p>
-<p>Set the file owner for dynaFiles newly created. Please note that this setting does not affect the owner of files already existing. The parameter is a user name, for which the userid is obtained by rsyslogd on startup and on HUPing. Interim changes to the user mapping are not detected.</p>
+<p>Set the file owner for dynaFiles newly created. Please note that this setting does not affect the owner of files already existing. The parameter is a user name, for which the userid is obtained by rsyslogd during startup processing. Interim changes to the user mapping are not detected.</p>
<p><b>Sample:</b></p>
<p><code><b>$FileOwner loguser</b></code></p>
diff --git a/doc/rsyslog_conf_global.html b/doc/rsyslog_conf_global.html
index 2371c4ae..f37dcc5a 100644
--- a/doc/rsyslog_conf_global.html
+++ b/doc/rsyslog_conf_global.html
@@ -97,6 +97,13 @@ default 60000 (1 minute)]</li>
(driver-specific)</li><li>$ActionSendStreamDriverAuthMode &lt;mode&gt;,&nbsp; authentication mode to use with the stream driver
(driver-specific)</li><li>$ActionSendStreamDriverPermittedPeer &lt;ID&gt;,&nbsp; accepted fingerprint (SHA1) or name of remote peer
(driver-specific) -<span style="font-weight: bold;"> directive may go away</span>!</li>
+<li><b>$ActionSendTCPRebindInterval</b> nbr</a>- [available since 4.5.1] - instructs the TCP send
+action to close and re-open the connection to the remote host every nbr of messages sent.
+Zero, the default, means that no such processing is done. This directive is useful for
+use with load-balancers. Note that there is some performance overhead associated with it,
+so it is advisable to not too often &quot;rebind&quot; the connection (what
+&quot;too often&quot; actually means depends on your configuration, a rule of thumb is
+that it should be not be much more often than once per second).</li>
<li><b>$ActionSendUDPRebindInterval</b> nbr</a>- [available since 4.3.2] - instructs the UDP send
action to rebind the send socket every nbr of messages sent. Zero, the default, means
that no rebind is done. This directive is useful for use with load-balancers.</li>
@@ -130,11 +137,15 @@ our paper on <a href="multi_ruleset.html">using multiple rule sets in rsyslog</a
<li><a href="rsconf1_gssforwardservicename.html">$GssForwardServiceName</a></li>
<li><a href="rsconf1_gsslistenservicename.html">$GssListenServiceName</a></li>
<li><a href="rsconf1_gssmode.html">$GssMode</a></li>
-<li>$HUPisRestart [<b>on</b>/off] - if set to on, a HUP is a full daemon restart. This means any queued messages are discarded (depending
+<li>$HUPisRestart [on/<b>off</b>] - if set to on, a HUP is a full daemon restart. This means any queued messages are discarded (depending
on queue configuration, of course) all modules are unloaded and reloaded. This mode keeps compatible with sysklogd, but is
-not recommended for use with rsyslog. To do a full restart, simply stop and start the daemon. The default is "on" for
-compatibility reasons. If it is set to "off", a HUP will only close open files. This is a much quicker action and usually
-the only one that is needed e.g. for log rotation. <b>It is recommended to set the setting to "off".</b></li>
+not recommended for use with rsyslog. To do a full restart, simply stop and start the daemon. The default (since 4.5.1) is "off".
+If it is set to "off", a HUP will only close open files. This is a much quicker action and usually
+the only one that is needed e.g. for log rotation. <b>Restart-type HUPs (value "on") are depricated</b>
+and will go away in rsyslog v5. So it is a good idea to change anything that needs it, now.
+Usually that should not be a big issue, as the restart-type HUP can easily be replaced by
+something along the lines of &quot;/etc/init.d/rsyslog restart&quot;.
+</li>
<li><a href="rsconf1_includeconfig.html">$IncludeConfig</a></li><li>MainMsgQueueCheckpointInterval &lt;number&gt;</li>
<li>$MainMsgQueueDequeueBatchSize &lt;number&gt; [default 32]</li>
<li>$MainMsgQueueDequeueSlowdown &lt;number&gt; [number
diff --git a/doc/rsyslog_conf_modules.html b/doc/rsyslog_conf_modules.html
index df9abeea..f9bdad4a 100644
--- a/doc/rsyslog_conf_modules.html
+++ b/doc/rsyslog_conf_modules.html
@@ -20,6 +20,7 @@ SQLLite, Ingres, Oracle, mSQL)</li>
<li><a href="ommail.html">ommail</a> -
permits rsyslog to alert folks by mail if something important happens</li>
<li><a href="omoracle.html">omoracle</a> - output module for Oracle (native OCI interface)</li>
+<li><a href="omudpspoof.html">omudpspoof</a> - output module sending UDP syslog messages with a spoofed address</li>
<li><a href="imfile.html">imfile</a>
-&nbsp; input module for text files</li>
<li><a href="imrelp.html">imrelp</a> - RELP
diff --git a/doc/rsyslog_php_syslog_ng.html b/doc/rsyslog_php_syslog_ng.html
index 9e722755..bf48a1eb 100644
--- a/doc/rsyslog_php_syslog_ng.html
+++ b/doc/rsyslog_php_syslog_ng.html
@@ -107,7 +107,7 @@ server machine, &quot;syslog&quot; is the database name (default from the schema
and &quot;pass&quot; are the logon credentials. Use a user with low privileges, insert into the
logs table is sufficient. &quot;syslog-ng&quot; is the template name and tells rsyslogd to
use the SQL statement shown above.</p>
-<p>Once you have made the changes, all you need to do is reload (or HUP)
+<p>Once you have made the changes, all you need to do is restart
rsyslogd. Then, you should see syslog messages flow into your database - and
show up in php-syslog-ng.</p>
<h2>Conclusion</h2>
@@ -148,4 +148,4 @@ no Front-Cover Texts, and no Back-Cover Texts. A copy of the license can be
viewed at <a href="http://www.gnu.org/copyleft/fdl.html">
http://www.gnu.org/copyleft/fdl.html</a>.</p>
</body>
-</html> \ No newline at end of file
+</html>
diff --git a/doc/rsyslog_recording_pri.html b/doc/rsyslog_recording_pri.html
index 1dcf00c7..cf11e3e5 100644
--- a/doc/rsyslog_recording_pri.html
+++ b/doc/rsyslog_recording_pri.html
@@ -62,7 +62,7 @@ semicolon:</p>
<p>That's all you need to do. There is one common pitfall: you need to define
the template before you use it in a selector line. Otherwise, you will receive
an error.</p>
-<p>Once you have applied the changes, you need to restart or HUP rsyslogd. It
+<p>Once you have applied the changes, you need to restart rsyslogd. It
will then pick the new configuration.</p>
<h2>What if I do not want rsyslogd to be the standard syslogd?</h2>
<p>If you do not want to switch to rsyslog, you can still use it as a setup aid.
diff --git a/doc/rsyslog_tls.html b/doc/rsyslog_tls.html
index e37d26a7..bb312c77 100644
--- a/doc/rsyslog_tls.html
+++ b/doc/rsyslog_tls.html
@@ -128,7 +128,7 @@ This is all you need to do. You can use the rest of your rsyslog.conf
together with this configuration. The way messages are received does
not interfer with any other option, so you are able to do anything else
you like without any restrictions.
-<p>Restart (or HUP) rsyslogd. The server should now be fully
+<p>Restart rsyslogd. The server should now be fully
operational.</p>
<h3>Client Setup</h3>
<p>The client setup is equally&nbsp;simple. You need less
diff --git a/doc/status.html b/doc/status.html
index 56ad78d9..c5de1ad3 100644
--- a/doc/status.html
+++ b/doc/status.html
@@ -2,16 +2,16 @@
<html><head><title>rsyslog status page</title></head>
<body>
<h2>rsyslog status page</h2>
-<p>This page reflects the status as of 2009-07-08.</p>
+<p>This page reflects the status as of 2009-07-15.</p>
<h2>Current Releases</h2>
<p><b>v5 development:</b> 5.1.2 [2009-07-08] -
<a href="http://www.rsyslog.com/Article386.phtml">change log</a> -
<a href="http://www.rsyslog.com/Downloads-req-viewdownloaddetails-lid-166.phtml">download</a>
-<br><b>v4 development:</b> 4.5.0 [2009-07-03] -
-<a href="http://www.rsyslog.com/Article380.phtml">change log</a> -
-<a href="http://www.rsyslog.com/Downloads-req-viewdownloaddetails-lid-164.phtml">download</a></p>
+<br><b>v4 development:</b> 4.5.1 [2009-07-15] -
+<a href="http://www.rsyslog.com/Article388.phtml">change log</a> -
+<a href="http://www.rsyslog.com/Downloads-req-viewdownloaddetails-lid-167.phtml">download</a></p>
<br><b>beta:</b> 4.3.2 [2009-06-24] -
<a href="http://www.rsyslog.com/Article378.phtml">change log</a> -
diff --git a/doc/v4compatibility.html b/doc/v4compatibility.html
new file mode 100644
index 00000000..5d877af1
--- /dev/null
+++ b/doc/v4compatibility.html
@@ -0,0 +1,77 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><title>Compatibility notes for rsyslog v4</title>
+</head>
+<body>
+<h1>Compatibility Notes for rsyslog v4</h1>
+<p><small><i>Written by <a href="http://www.gerhards.net/rainer">Rainer Gerhards</a>
+(2009-07-15)</i></small></p>
+<p>The changes introduced in rsyslog v4 are numerous, but not very intrusive.
+This document describes things to keep in mind when moving from v3 to v4. It
+does not list enhancements nor does it talk about compatibility concerns introduced
+by v3 (for this, see the <a href="v3compatibility.html">rsyslog v3 compatibility notes</a>).
+<h2>HUP processing</h2>
+<p>With v3 and below, rsyslog used the traditional HUP behaviour. That meant that
+all output files are closed and the configuration file is re-read and the new configuration
+applied.
+<p>With a program as simple and static as sysklogd, this was not much of an issue. The
+most important config settings (like udp reception) of a traditional syslogd can not be
+modified via the configuration file. So a config file reload only meant setting up a new set of filters. It also didn't account as problem that while doing so messages may be lost - without
+any threading and queuing model, a traditional syslogd will potentially always loose
+messages, so it is irrelevant if this happens, too, during the short config re-read
+phase.
+<p>In rsyslog, things are quite different: the program is more or less a framework into
+which loadable modules are loaded as needed for a particular configuration. The software
+that will acutally be running is taylored via the config file. Thus, a re-read of
+the config file requires a full, very heavy restart, because the software acutally
+running with the new config can be totally different from what ran with the old config.
+<p>Consequently, the traditional HUP is a very heavy operation and may even cause some
+data loss because queues must be shut down, listeners stopped and so on. Some of these
+operations (depending on their configuration) involve intentional message loss. The operation
+also takes up a lot of system resources and needs quite some time (maybe seconds) to be
+completed. During this restart period, the syslog subsytem is not fully available.
+<p>From the software developer's point of view, the full restart done by a HUP is rather complex,
+especially if user-timeout limits set on action completion are taken into consideration (for
+those in the know: at the extreme ends this means we need to cancel threads as a last resort,
+but than we need to make sure that such cancellation does not happen at points where it
+would be fatal for a restart). A regular restart, where the process is actually terminated, is
+much less complex, because the operating system does a full cleanup after process termination,
+so rsyslogd does not need to take care for exotic cleanup cases and leave that to the OS.
+In the end result, restart-type HUPs clutter the code, increase complexity (read: add bugs)
+and cost performance.
+<p>On the contrary, a HUP is typically needed for log rotation, and the real desire is
+to close files. This is a non-disruptive and very lightweigth operation.
+<p>Many people have said that they are used to HUP the syslogd to apply configuration
+changes. This is true, but it is questionable if that really justifies all the cost that
+comes with it. After all, it is the difference between typing
+<pre>
+$ kill -HUP `cat /var/run/rsyslogd.pid`
+</pre>
+versus
+<pre>
+$ /etc/init.d/rsyslog restart
+</pre>
+Semantically, both is mostly the same thing. The only difference is that with the restart
+command rsyslogd can spit config error message to stderr, so that the user is able to see
+any problems and fix them. With a HUP, we do not have access to stderr and thus can log
+error messages only to their configured destinations; exprience tells that most users
+will never find them there. What, by the way, is another strong argument against
+restarting rsyslogd by HUPing it.
+<p>So a restart via HUP is not strictly necessary
+and most other deamons require that a restart command is typed in if a restart is required.
+<p>Rsyslog will follow this paradigm in the next versions, resulting in many benefits. In v4,
+we provide some support for the old-style semantics. We introduced a setting $HUPisRestart
+which may be set to &quot;on&quot; (tradional, heavy operationg)
+or &quot;off&quot; (new, lightweight &quot;file close only&quot; operation).
+The initial versions had the default set to traditional behavior, but starting with 4.5.1
+we are now using the new behavior as the default.
+<p>Most importantly, <b>this may break some scripts</b>, but my sincere belief is that
+there are very few scripts that automatically <b>change</b> rsyslog's config and then do a
+HUP to reload it. Anyhow, if you have some of these, it may be a good idea to change
+them now instead of turning restart-type HUPs on. Other than that, one mainly needs
+to change the habit of how to restart rsyslog after a configuration change.
+<p><b>Please note that restart-type HUP is depricated and will go away in rsyslog v5.</b>
+So it is a good idea to become ready for the new version now and also enjoy some of the
+benefits of the &quot;real restart&quot;, like the better error-reporting capability.
+<p>Note that code complexity reduction (and thus performance improvement) needs the restart-type
+HUP code to be removed, so these changes can (and will) only happen in version 5.
+</body></html>
diff --git a/doc/v5compatibility.html b/doc/v5compatibility.html
new file mode 100644
index 00000000..24fcbd25
--- /dev/null
+++ b/doc/v5compatibility.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><title>Compatibility notes for rsyslog v5</title>
+</head>
+<body>
+<h1>Compatibility Notes for rsyslog v5</h1>
+<p><small><i>Written by <a href="http://www.gerhards.net/rainer">Rainer Gerhards</a>
+(2009-07-15)</i></small></p>
+<p>The changes introduced in rsyslog v5 are numerous, but not very intrusive.
+This document describes things to keep in mind when moving from v4 to v5. It
+does not list enhancements nor does it talk about compatibility concerns introduced
+by earlier versions (for this, see their respective compatibility documents).
+<h2>HUP processing</h2>
+<p>The $HUPisRestart directive is supported by some early v5 versions, but has been removed
+in 5.1.3 and above. That means that restart-type HUP processing is no longer
+available. This processing was redundant and had a lot a drawbacks.
+For details, please see the
+<a href="v4compatibility.html">rsyslog v4 compatibility notes</a> which elaborate
+on the reasons and the (few) things you may need to change.
+</body></html>
diff --git a/plugins/omstdout/omstdout.c b/plugins/omstdout/omstdout.c
index b9125f19..584ae458 100644
--- a/plugins/omstdout/omstdout.c
+++ b/plugins/omstdout/omstdout.c
@@ -50,11 +50,13 @@ MODULE_TYPE_OUTPUT
DEF_OMOD_STATIC_DATA
/* config variables */
-static int bUseArrayInterface; /* shall action use array instead of string template interface? */
+static int bUseArrayInterface = 0; /* shall action use array instead of string template interface? */
+static int bEnsureLFEnding = 1; /* shall action use array instead of string template interface? */
typedef struct _instanceData {
int bUseArrayInterface; /* uses action use array instead of string template interface? */
+ int bEnsureLFEnding; /* ensure that a linefeed is written at the end of EACH record (test aid for nettester) */
} instanceData;
BEGINcreateInstance
@@ -90,6 +92,7 @@ BEGINdoAction
int iParam;
int iBuf;
char szBuf[65564];
+ size_t len;
CODESTARTdoAction
if(pData->bUseArrayInterface) {
/* if we use array passing, we need to put together a string
@@ -120,7 +123,11 @@ CODESTARTdoAction
} else {
toWrite = (char*) ppString[0];
}
+ len = strlen(toWrite);
write(1, toWrite, strlen(toWrite)); /* 1 is stdout! */
+ if(pData->bEnsureLFEnding && toWrite[len-1] != '\n') {
+ write(1, "\n", 1); /* write missing LF */
+ }
ENDdoAction
@@ -143,6 +150,7 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1)
iTplOpts = (bUseArrayInterface == 0) ? 0 : OMSR_TPL_AS_ARRAY;
CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, iTplOpts, (uchar*) "RSYSLOG_FileFormat"));
pData->bUseArrayInterface = bUseArrayInterface;
+ pData->bEnsureLFEnding = bEnsureLFEnding;
CODE_STD_FINALIZERparseSelectorAct
ENDparseSelectorAct
@@ -165,6 +173,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a
{
DEFiRet;
bUseArrayInterface = 0;
+ bEnsureLFEnding = 1;
RETiRet;
}
@@ -195,6 +204,8 @@ CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionomstdoutarrayinterface", 0, eCmdHdlrBinary, NULL,
&bUseArrayInterface, STD_LOADABLE_MODULE_ID));
}
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionomstdoutensurelfending", 0, eCmdHdlrBinary, NULL,
+ &bEnsureLFEnding, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler,
resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
ENDmodInit
diff --git a/plugins/omudpspoof/Makefile.am b/plugins/omudpspoof/Makefile.am
new file mode 100644
index 00000000..79c495a0
--- /dev/null
+++ b/plugins/omudpspoof/Makefile.am
@@ -0,0 +1,8 @@
+pkglib_LTLIBRARIES = omudpspoof.la
+
+omudpspoof_la_SOURCES = omudpspoof.c
+omudpspoof_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(UDPSPOOF_CFLAGS)
+omudpspoof_la_LDFLAGS = -module -avoid-version
+omudpspoof_la_LIBADD = $(UDPSPOOF_LIBS)
+
+EXTRA_DIST =
diff --git a/plugins/omudpspoof/omudpspoof.c b/plugins/omudpspoof/omudpspoof.c
new file mode 100644
index 00000000..8eb63c73
--- /dev/null
+++ b/plugins/omudpspoof/omudpspoof.c
@@ -0,0 +1,500 @@
+/* omudpspoof.c
+ *
+ * This is a udp-based output module that support spoofing.
+ *
+ * This file builds on UDP spoofing code contributed by
+ * David Lang <david@lang.hm>. I then created a "real" rsyslog module
+ * out of that code and omfwd. I decided to make it a separate module because
+ * omfwd already mixes up too many things (TCP & UDP & a differnt modes,
+ * this has historic reasons), it would not be a good idea to also add
+ * spoofing to it. And, looking at the requirements, there is little in
+ * common between omfwd and this module.
+ *
+ * Note: I have briefly checked libnet source code and I somewhat have the feeling
+ * that under some circumstances we may get into trouble with the lib. For
+ * example, it registers an atexit() handler, which should not play nicely
+ * with our dynamically loaded modules. Anyhow, I refrain from looking deeper
+ * at libnet code, especially as testing does not show any real issues. If some
+ * occur, it may be easier to modify libnet for dynamic load environments than
+ * using a work-around (as a side not, libnet looks somewhat unmaintained, the CVS
+ * I can see on sourceforge dates has no updates done less than 7 years ago).
+ * On the other hand, it looks like libnet is thread safe (at least is appropriately
+ * compiled, which I hope the standard packages are). So I do not guard calls to
+ * it with my own mutex calls.
+ * rgerhards, 2009-07-10
+ *
+ * Copyright 2009 David Lang (spoofing code)
+ * Copyright 2009 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 <time.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <fnmatch.h>
+#include <assert.h>
+#include <errno.h>
+#include <ctype.h>
+#include <unistd.h>
+#ifdef USE_NETZIP
+#include <zlib.h>
+#endif
+#include "conf.h"
+#include "syslogd-types.h"
+#include "srUtils.h"
+#include "net.h"
+#include "template.h"
+#include "msg.h"
+#include "cfsysline.h"
+#include "module-template.h"
+#include "glbl.h"
+#include "errmsg.h"
+#include "dirty.h"
+#include "unicode-helper.h"
+
+
+#include <libnet.h>
+#define _BSD_SOURCE 1
+#define __BSD_SOURCE 1
+#define __FAVOR_BSD 1
+
+
+MODULE_TYPE_OUTPUT
+
+/* internal structures
+ */
+DEF_OMOD_STATIC_DATA
+DEFobjCurrIf(errmsg)
+DEFobjCurrIf(glbl)
+DEFobjCurrIf(net)
+
+typedef struct _instanceData {
+ uchar *host;
+ uchar *port;
+ int *pSockArray; /* sockets to use for UDP */
+ int compressionLevel; /* 0 - no compression, else level for zlib */
+ struct addrinfo *f_addr;
+ u_short sourcePort;
+ u_short sourcePortStart; /* for sorce port iteration */
+ u_short sourcePortEnd;
+} instanceData;
+
+#define DFLT_SOURCE_PORT_START 32000
+#define DFLT_SOURCE_PORT_END 42000
+
+/* config data */
+static uchar *pszTplName = NULL; /* name of the default template to use */
+static uchar *pszSourceNameTemplate = NULL; /* name of the template containing the spoofing address */
+static uchar *pszTargetHost = NULL;
+static uchar *pszTargetPort = NULL;
+static int iCompressionLevel = 0; /* zlib compressionlevel, the usual values */
+static int iSourcePortStart = DFLT_SOURCE_PORT_START;
+static int iSourcePortEnd = DFLT_SOURCE_PORT_END;
+
+
+/* add some variables needed for libnet */
+libnet_t *libnet_handle;
+char errbuf[LIBNET_ERRBUF_SIZE];
+
+/* forward definitions */
+static rsRetVal doTryResume(instanceData *pData);
+
+
+/* Close the UDP sockets.
+ * rgerhards, 2009-05-29
+ */
+static rsRetVal
+closeUDPSockets(instanceData *pData)
+{
+ DEFiRet;
+ assert(pData != NULL);
+ if(pData->pSockArray != NULL) {
+ net.closeUDPListenSockets(pData->pSockArray);
+ pData->pSockArray = NULL;
+ freeaddrinfo(pData->f_addr);
+ pData->f_addr = NULL;
+ }
+ RETiRet;
+}
+
+
+/* get the syslog forward port
+ * We may change the implementation to try to lookup the port
+ * if it is unspecified. So far, we use the IANA default auf 514.
+ * rgerhards, 2007-06-28
+ */
+static inline uchar *getFwdPt(instanceData *pData)
+{
+ return (pData->port == NULL) ? UCHAR_CONSTANT("514") : pData->port;
+}
+
+
+BEGINcreateInstance
+CODESTARTcreateInstance
+ENDcreateInstance
+
+
+BEGINisCompatibleWithFeature
+CODESTARTisCompatibleWithFeature
+ if(eFeat == sFEATURERepeatedMsgReduction)
+ iRet = RS_RET_OK;
+ENDisCompatibleWithFeature
+
+
+BEGINfreeInstance
+CODESTARTfreeInstance
+ /* final cleanup */
+ closeUDPSockets(pData);
+ free(pData->port);
+ free(pData->host);
+ENDfreeInstance
+
+
+BEGINdbgPrintInstInfo
+CODESTARTdbgPrintInstInfo
+ DBGPRINTF("%s", pData->host);
+ENDdbgPrintInstInfo
+
+
+/* Send a message via UDP
+ * rgehards, 2007-12-20
+ */
+static rsRetVal UDPSend(instanceData *pData, uchar *pszSourcename, char *msg, size_t len)
+{
+ struct addrinfo *r;
+ int lsent = 0;
+ int bSendSuccess;
+ int j, build_ip;
+ u_char opt[20];
+ struct sockaddr_in *tempaddr,source_ip;
+ libnet_ptag_t ip, ipo;
+ libnet_ptag_t udp;
+ DEFiRet;
+
+ if(pData->pSockArray == NULL) {
+ CHKiRet(doTryResume(pData));
+ }
+
+ ip = ipo = udp = 0;
+ if(pData->sourcePort++ >= pData->sourcePortEnd){
+ pData->sourcePort = pData->sourcePortStart;
+ }
+
+ inet_pton(AF_INET, (char*)pszSourcename, &(source_ip.sin_addr));
+
+ bSendSuccess = FALSE;
+ for (r = pData->f_addr; r; r = r->ai_next) {
+ tempaddr = (struct sockaddr_in *)r->ai_addr;
+ libnet_clear_packet(libnet_handle);
+ udp = libnet_build_udp(
+ pData->sourcePort, /* source port */
+ tempaddr->sin_port, /* destination port */
+ LIBNET_UDP_H + len, /* packet length */
+ 0, /* checksum */
+ (u_char*)msg, /* payload */
+ len, /* payload size */
+ libnet_handle, /* libnet handle */
+ udp); /* libnet id */
+ if (udp == -1) {
+ DBGPRINTF("Can't build UDP header: %s\n", libnet_geterror(libnet_handle));
+ }
+
+ build_ip = 0;
+ /* this is not a legal options string */
+ for (j = 0; j < 20; j++) {
+ opt[j] = libnet_get_prand(LIBNET_PR2);
+ }
+ ipo = libnet_build_ipv4_options(opt, 20, libnet_handle, ipo);
+ if (ipo == -1) {
+ DBGPRINTF("Can't build IP options: %s\n", libnet_geterror(libnet_handle));
+ }
+ ip = libnet_build_ipv4(
+ LIBNET_IPV4_H + 20 + len + LIBNET_UDP_H, /* length */
+ 0, /* TOS */
+ 242, /* IP ID */
+ 0, /* IP Frag */
+ 64, /* TTL */
+ IPPROTO_UDP, /* protocol */
+ 0, /* checksum */
+ source_ip.sin_addr.s_addr,
+ tempaddr->sin_addr.s_addr,
+ NULL, /* payload */
+ 0, /* payload size */
+ libnet_handle, /* libnet handle */
+ ip); /* libnet id */
+ if (ip == -1) {
+ DBGPRINTF("Can't build IP header: %s\n", libnet_geterror(libnet_handle));
+ }
+
+ /* Write it to the wire. */
+ lsent = libnet_write(libnet_handle);
+ if (lsent == -1) {
+ DBGPRINTF("Write error: %s\n", libnet_geterror(libnet_handle));
+ } else {
+ bSendSuccess = TRUE;
+ break;
+ }
+ }
+ /* finished looping */
+ if (bSendSuccess == FALSE) {
+ DBGPRINTF("error forwarding via udp, suspending\n");
+ iRet = RS_RET_SUSPENDED;
+ }
+
+finalize_it:
+ RETiRet;
+}
+
+
+/* try to resume connection if it is not ready
+ * rgerhards, 2007-08-02
+ */
+static rsRetVal doTryResume(instanceData *pData)
+{
+ int iErr;
+ struct addrinfo *res;
+ struct addrinfo hints;
+ DEFiRet;
+
+ if(pData->pSockArray != NULL)
+ FINALIZE;
+
+ /* The remote address is not yet known and needs to be obtained */
+ DBGPRINTF(" %s\n", pData->host);
+ memset(&hints, 0, sizeof(hints));
+ /* port must be numeric, because config file syntax requires this */
+ hints.ai_flags = AI_NUMERICSERV;
+ hints.ai_family = glbl.GetDefPFFamily();
+ hints.ai_socktype = SOCK_DGRAM;
+ if((iErr = (getaddrinfo((char*)pData->host, (char*)getFwdPt(pData), &hints, &res))) != 0) {
+ DBGPRINTF("could not get addrinfo for hostname '%s':'%s': %d%s\n",
+ pData->host, getFwdPt(pData), iErr, gai_strerror(iErr));
+ ABORT_FINALIZE(RS_RET_SUSPENDED);
+ }
+ DBGPRINTF("%s found, resuming.\n", pData->host);
+ pData->f_addr = res;
+ pData->pSockArray = net.create_udp_socket((uchar*)pData->host, NULL, 0);
+
+finalize_it:
+ if(iRet != RS_RET_OK) {
+ if(pData->f_addr != NULL) {
+ freeaddrinfo(pData->f_addr);
+ pData->f_addr = NULL;
+ }
+ iRet = RS_RET_SUSPENDED;
+ }
+
+ RETiRet;
+}
+
+
+BEGINtryResume
+CODESTARTtryResume
+ iRet = doTryResume(pData);
+ENDtryResume
+
+BEGINdoAction
+ char *psz; /* temporary buffering */
+ register unsigned l;
+ int iMaxLine;
+CODESTARTdoAction
+ CHKiRet(doTryResume(pData));
+
+ iMaxLine = glbl.GetMaxLine();
+
+ DBGPRINTF(" %s:%s/udpspoofs\n", pData->host, getFwdPt(pData));
+
+ psz = (char*) ppString[0];
+ l = strlen((char*) psz);
+ if((int) l > iMaxLine)
+ l = iMaxLine;
+
+# 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;
+ 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';
+ 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
+
+ CHKiRet(UDPSend(pData, ppString[1], psz, l));
+
+finalize_it:
+ENDdoAction
+
+
+BEGINparseSelectorAct
+CODESTARTparseSelectorAct
+CODE_STD_STRING_REQUESTparseSelectorAct(2)
+ /* first check if this config line is actually for us */
+ if(strncmp((char*) p, ":omudpspoof:", sizeof(":omudpspoof:") - 1)) {
+ ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED);
+ }
+
+ /* ok, if we reach this point, we have something for us */
+ p += sizeof(":omudpspoof:") - 1; /* eat indicator sequence (-1 because of '\0'!) */
+ CHKiRet(createInstance(&pData));
+
+ if(pszSourceNameTemplate == NULL) {
+ errmsg.LogError(0, NO_ERRCODE, "No $ActionOMUDPSpoofSourceNameTemplate given, can not continue with this action.");
+ ABORT_FINALIZE(RS_RET_NO_SRCNAME_TPL);
+ }
+
+ if(pszTargetHost == NULL) {
+ errmsg.LogError(0, NO_ERRCODE, "No $ActionOMUDPSpoofTargetHost given, can not continue with this action.");
+ ABORT_FINALIZE(RS_RET_HOST_NOT_SPECIFIED);
+ }
+
+ /* fill instance properties */
+ CHKmalloc(pData->host = ustrdup(pszTargetHost));
+ if(pszTargetPort == NULL)
+ pData->port = NULL;
+ else
+ CHKmalloc(pData->port = ustrdup(pszTargetPort));
+ CHKiRet(OMSRsetEntry(*ppOMSR, 1, ustrdup(pszSourceNameTemplate), OMSR_NO_RQD_TPL_OPTS));
+ pData->compressionLevel = iCompressionLevel;
+ pData->sourcePort = pData->sourcePortStart = iSourcePortStart;
+ pData->sourcePortEnd = iSourcePortEnd;
+
+ /* process template */
+ CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS,
+ (pszTplName == NULL) ? (uchar*)"RSYSLOG_TraditionalForwardFormat" : pszTplName));
+
+CODE_STD_FINALIZERparseSelectorAct
+ENDparseSelectorAct
+
+
+/* a common function to free our configuration variables - used both on exit
+ * and on $ResetConfig processing. -- rgerhards, 2008-05-16
+ */
+static void
+freeConfigVars(void)
+{
+ free(pszTplName);
+ pszTplName = NULL;
+ free(pszTargetHost);
+ pszTargetHost = NULL;
+ free(pszTargetPort);
+ pszTargetPort = NULL;
+}
+
+
+BEGINmodExit
+CODESTARTmodExit
+ /* destroy the libnet state needed for forged UDP sources */
+ libnet_destroy(libnet_handle);
+ /* release what we no longer need */
+ objRelease(errmsg, CORE_COMPONENT);
+ objRelease(glbl, CORE_COMPONENT);
+ objRelease(net, LM_NET_FILENAME);
+ freeConfigVars();
+ENDmodExit
+
+
+BEGINqueryEtryPt
+CODESTARTqueryEtryPt
+CODEqueryEtryPt_STD_OMOD_QUERIES
+ENDqueryEtryPt
+
+
+/* Reset config variables for this module to default values.
+ * rgerhards, 2008-03-28
+ */
+static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
+{
+ freeConfigVars();
+ /* we now must reset all non-string values */
+ iCompressionLevel = 0;
+ iSourcePortStart = DFLT_SOURCE_PORT_START;
+ iSourcePortEnd = DFLT_SOURCE_PORT_END;
+ return RS_RET_OK;
+}
+
+
+BEGINmodInit()
+CODESTARTmodInit
+ *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
+CODEmodInit_QueryRegCFSLineHdlr
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
+ CHKiRet(objUse(errmsg, CORE_COMPONENT));
+ CHKiRet(objUse(net,LM_NET_FILENAME));
+
+ /* Initialize the libnet library. Root priviledges are required.
+ * this initializes a IPv4 socket to use for forging UDP packets.
+ */
+ libnet_handle = libnet_init(
+ LIBNET_RAW4, /* injection type */
+ NULL, /* network interface */
+ errbuf); /* errbuf */
+
+ if(libnet_handle == NULL) {
+ errmsg.LogError(0, NO_ERRCODE, "Error initializing libnet, can not continue ");
+ ABORT_FINALIZE(RS_RET_ERR_LIBNET_INIT);
+ }
+
+ CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspoofdefaulttemplate", 0, eCmdHdlrGetWord, NULL, &pszTplName, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspoofsourcenametemplate", 0, eCmdHdlrGetWord, NULL, &pszSourceNameTemplate, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspooftargethost", 0, eCmdHdlrGetWord, NULL, &pszTargetHost, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspooftargetport", 0, eCmdHdlrGetWord, NULL, &pszTargetPort, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspoofsourceportstart", 0, eCmdHdlrInt, NULL, &iSourcePortStart, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspoofsourceportend", 0, eCmdHdlrInt, NULL, &iSourcePortEnd, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpcompressionlevel", 0, eCmdHdlrInt, NULL, &iCompressionLevel, NULL));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
+ENDmodInit
+
+/* vim:set ai:
+ */
diff --git a/runtime/conf.c b/runtime/conf.c
index 84178fd5..2e37edf2 100644
--- a/runtime/conf.c
+++ b/runtime/conf.c
@@ -93,7 +93,7 @@ DEFobjCurrIf(net)
DEFobjCurrIf(rule)
DEFobjCurrIf(ruleset)
-static int iNbrActions; /* number of actions the running config has. Needs to be init on ReInitConf() */
+static int iNbrActions = 0; /* number of currently defined actions */
/* The following global variables are used for building
* tag and host selector lines during startup and config reload.
@@ -1204,21 +1204,6 @@ cfline(uchar *line, rule_t **pfCurr)
}
-/* Reinitialize the configuration subsystem. This is a "work-around" to the fact
- * that we do not yet have actual config objects. This method is to be called
- * whenever a totally new config is started (which means on startup and HUP).
- * Note that it MUST NOT be called for an included config file.
- * rgerhards, 2008-07-28
- */
-static rsRetVal
-ReInitConf(void)
-{
- DEFiRet;
- iNbrActions = 0; /* this is what we created the function for ;) - action count is reset */
- RETiRet;
-}
-
-
/* return the current number of active actions
* rgerhards, 2008-07-28
*/
@@ -1252,7 +1237,6 @@ CODESTARTobjQueryInterface(conf)
pIf->doIncludeLine = doIncludeLine;
pIf->cfline = cfline;
pIf->processConfFile = processConfFile;
- pIf->ReInitConf = ReInitConf;
pIf->GetNbrActActions = GetNbrActActions;
finalize_it:
diff --git a/runtime/conf.h b/runtime/conf.h
index 25b887be..6db1623e 100644
--- a/runtime/conf.h
+++ b/runtime/conf.h
@@ -37,10 +37,12 @@ BEGINinterface(conf) /* name must also be changed in ENDinterface macro! */
rsRetVal (*doIncludeLine)(uchar **pp, __attribute__((unused)) void* pVal);
rsRetVal (*cfline)(uchar *line, rule_t **pfCurr);
rsRetVal (*processConfFile)(uchar *pConfFile);
- rsRetVal (*ReInitConf)(void);
rsRetVal (*GetNbrActActions)(int *);
ENDinterface(conf)
-#define confCURR_IF_VERSION 2 /* increment whenever you change the interface structure! */
+#define confCURR_IF_VERSION 3 /* increment whenever you change the interface structure! */
+/* in Version 3, entry point "ReInitConf()" was removed, as we do not longer need
+ * to support restart-type HUP -- rgerhards, 2009-07-15
+ */
/* prototypes */
diff --git a/runtime/glbl.c b/runtime/glbl.c
index 32b85622..534dc262 100644
--- a/runtime/glbl.c
+++ b/runtime/glbl.c
@@ -55,7 +55,6 @@ DEFobjCurrIf(prop)
*/
static uchar *pszWorkDir = NULL;
static int bOptimizeUniProc = 1; /* enable uniprocessor optimizations */
-static int bHUPisRestart = 1; /* should SIGHUP cause a full system restart? */
static int bPreserveFQDN = 0; /* should FQDNs always be preserved? */
static int iMaxLine = 2048; /* maximum length of a syslog message */
static int iDefPFFamily = PF_UNSPEC; /* protocol family (IPv4, IPv6 or both) */
@@ -95,7 +94,6 @@ static dataType Get##nameFunc(void) \
SIMP_PROP(OptimizeUniProc, bOptimizeUniProc, int)
SIMP_PROP(PreserveFQDN, bPreserveFQDN, int)
-SIMP_PROP(HUPisRestart, bHUPisRestart, int)
SIMP_PROP(MaxLine, iMaxLine, int)
SIMP_PROP(DefPFFamily, iDefPFFamily, int) /* note that in the future we may check the family argument */
SIMP_PROP(DropMalPTRMsgs, bDropMalPTRMsgs, int)
@@ -247,7 +245,6 @@ CODESTARTobjQueryInterface(glbl)
SIMP_PROP(MaxLine);
SIMP_PROP(OptimizeUniProc);
SIMP_PROP(PreserveFQDN);
- SIMP_PROP(HUPisRestart);
SIMP_PROP(DefPFFamily);
SIMP_PROP(DropMalPTRMsgs);
SIMP_PROP(Option_DisallowWarning);
@@ -293,7 +290,6 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a
}
bDropMalPTRMsgs = 0;
bOptimizeUniProc = 1;
- bHUPisRestart = 1;
bPreserveFQDN = 0;
return RS_RET_OK;
}
@@ -316,7 +312,6 @@ BEGINAbstractObjClassInit(glbl, 1, OBJ_IS_CORE_MODULE) /* class, version */
CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdriverkeyfile", 0, eCmdHdlrGetWord, NULL, &pszDfltNetstrmDrvrKeyFile, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdrivercertfile", 0, eCmdHdlrGetWord, NULL, &pszDfltNetstrmDrvrCertFile, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"optimizeforuniprocessor", 0, eCmdHdlrBinary, NULL, &bOptimizeUniProc, NULL));
- CHKiRet(regCfSysLineHdlr((uchar *)"hupisrestart", 0, eCmdHdlrBinary, NULL, &bHUPisRestart, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"preservefqdn", 0, eCmdHdlrBinary, NULL, &bPreserveFQDN, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, NULL));
ENDObjClassInit(glbl)
diff --git a/runtime/glbl.h b/runtime/glbl.h
index dcfb6d5f..8ecd8466 100644
--- a/runtime/glbl.h
+++ b/runtime/glbl.h
@@ -8,7 +8,7 @@
* Please note that there currently is no glbl.c file as we do not yet
* have any implementations.
*
- * Copyright 2008 Rainer Gerhards and Adiscon GmbH.
+ * Copyright 2008, 2009 Rainer Gerhards and Adiscon GmbH.
*
* This file is part of the rsyslog runtime library.
*
@@ -44,7 +44,6 @@ BEGINinterface(glbl) /* name must also be changed in ENDinterface macro! */
rsRetVal (*Set##name)(dataType);
SIMP_PROP(MaxLine, int)
SIMP_PROP(OptimizeUniProc, int)
- SIMP_PROP(HUPisRestart, int)
SIMP_PROP(PreserveFQDN, int)
SIMP_PROP(DefPFFamily, int)
SIMP_PROP(DropMalPTRMsgs, int)
diff --git a/runtime/msg.c b/runtime/msg.c
index 63ed0083..8a72a6d6 100644
--- a/runtime/msg.c
+++ b/runtime/msg.c
@@ -1130,15 +1130,21 @@ char *getProtocolVersionString(msg_t *pM)
}
-static char *getRawMsg(msg_t *pM)
+static inline void
+getRawMsg(msg_t *pM, uchar **pBuf, int *piLen)
{
- if(pM == NULL)
- return "";
- else
- if(pM->pszRawMsg == NULL)
- return "";
- else
- return (char*)pM->pszRawMsg;
+ if(pM == NULL) {
+ *pBuf= UCHAR_CONSTANT("");
+ *piLen = 0;
+ } else {
+ if(pM->pszRawMsg == NULL) {
+ *pBuf= UCHAR_CONSTANT("");
+ *piLen = 0;
+ } else {
+ *pBuf = pM->pszRawMsg;
+ *piLen = pM->iLenRawMsg;
+ }
+ }
}
@@ -1159,16 +1165,16 @@ int getMSGLen(msg_t *pM)
return((pM == NULL) ? 0 : pM->iLenMSG);
}
-char *getMSG(msg_t *pM)
+uchar *getMSG(msg_t *pM)
{
- char *ret;
+ uchar *ret;
if(pM == NULL)
- ret = "";
+ ret = UCHAR_CONSTANT("");
else {
if(pM->offMSG == -1)
- ret = "";
+ ret = UCHAR_CONSTANT("");
else
- ret = (char*)(pM->pszRawMsg + pM->offMSG);
+ ret = pM->pszRawMsg + pM->offMSG;
}
return ret;
}
@@ -1613,21 +1619,23 @@ static inline void tryEmulateTAG(msg_t *pM, bool bLockMutex)
}
-static inline char *getTAG(msg_t *pM)
+static inline void
+getTAG(msg_t *pM, uchar **ppBuf, int *piLen)
{
- char *ret;
-
- if(pM == NULL)
- ret = "";
- else {
+ if(pM == NULL) {
+ *ppBuf = UCHAR_CONSTANT("");
+ *piLen = 0;
+ } else {
if(pM->iLenTAG == 0)
tryEmulateTAG(pM, LOCK_MUTEX);
- if(pM->iLenTAG == 0)
- ret = "";
- else
- ret = (char*) ((pM->iLenTAG < CONF_TAG_BUFSIZE) ? pM->TAG.szBuf : pM->TAG.pszTAG);
+ if(pM->iLenTAG == 0) {
+ *ppBuf = UCHAR_CONSTANT("");
+ *piLen = 0;
+ } else {
+ *ppBuf = (pM->iLenTAG < CONF_TAG_BUFSIZE) ? pM->TAG.szBuf : pM->TAG.pszTAG;
+ *piLen = pM->iLenTAG;
+ }
}
- return(ret);
}
@@ -1754,10 +1762,10 @@ int getProgramNameLen(msg_t *pM, bool bLockMutex)
/* get the "programname" as sz string
* rgerhards, 2005-10-19
*/
-char *getProgramName(msg_t *pM, bool bLockMutex)
+uchar *getProgramName(msg_t *pM, bool bLockMutex)
{
prepareProgramName(pM, bLockMutex);
- return (pM->pCSProgName == NULL) ? "" : (char*) rsCStrGetSzStrNoNULL(pM->pCSProgName);
+ return (pM->pCSProgName == NULL) ? UCHAR_CONSTANT("") : rsCStrGetSzStrNoNULL(pM->pCSProgName);
}
@@ -1774,7 +1782,7 @@ static void tryEmulateAPPNAME(msg_t *pM)
if(getProtocolVersion(pM) == 0) {
/* only then it makes sense to emulate */
- MsgSetAPPNAME(pM, getProgramName(pM, MUTEX_ALREADY_LOCKED));
+ MsgSetAPPNAME(pM, (char*)getProgramName(pM, MUTEX_ALREADY_LOCKED));
}
}
@@ -2130,14 +2138,14 @@ static uchar *getNOW(eNOWType eNow)
* be used in selector line processing.
* rgerhards 2005-09-15
*/
-char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
+uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
propid_t propID, size_t *pPropLen,
unsigned short *pbMustBeFreed)
{
- char *pRes; /* result pointer */
+ uchar *pRes; /* result pointer */
int bufLen = -1; /* length of string or -1, if not known */
- char *pBufStart;
- char *pBuf;
+ uchar *pBufStart;
+ uchar *pBuf;
int iLen;
short iOffs;
@@ -2159,16 +2167,17 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
bufLen = getMSGLen(pMsg);
break;
case PROP_TIMESTAMP:
- pRes = getTimeReported(pMsg, pTpe->data.field.eDateFormat);
+ pRes = (uchar*)getTimeReported(pMsg, pTpe->data.field.eDateFormat);
break;
case PROP_HOSTNAME:
- pRes = getHOSTNAME(pMsg);
+ pRes = (uchar*)getHOSTNAME(pMsg);
+ bufLen = getHOSTNAMELen(pMsg);
break;
case PROP_SYSLOGTAG:
- pRes = getTAG(pMsg);
+ getTAG(pMsg, &pRes, &bufLen);
break;
case PROP_RAWMSG:
- pRes = getRawMsg(pMsg);
+ getRawMsg(pMsg, &pRes, &bufLen);
break;
/* enable this, if someone actually uses UxTradMsg, delete after some time has
* passed and nobody complained -- rgerhards, 2009-06-16
@@ -2177,120 +2186,121 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
break;
*/
case PROP_INPUTNAME:
- getInputName(pMsg, ((uchar**) &pRes), &bufLen);
+ getInputName(pMsg, &pRes, &bufLen);
break;
case PROP_FROMHOST:
- pRes = (char*) getRcvFrom(pMsg);
+ pRes = getRcvFrom(pMsg);
break;
case PROP_FROMHOST_IP:
- pRes = (char*) getRcvFromIP(pMsg);
+ pRes = getRcvFromIP(pMsg);
break;
case PROP_PRI:
- pRes = getPRI(pMsg);
+ pRes = (uchar*)getPRI(pMsg);
break;
case PROP_PRI_TEXT:
- pBuf = malloc(20 * sizeof(char));
+ pBuf = malloc(20 * sizeof(uchar));
if(pBuf == NULL) {
*pbMustBeFreed = 0;
- return "**OUT OF MEMORY**";
+ return UCHAR_CONSTANT("**OUT OF MEMORY**");
} else {
*pbMustBeFreed = 1;
- pRes = textpri(pBuf, 20, getPRIi(pMsg));
+ pRes = (uchar*)textpri((char*)pBuf, 20, getPRIi(pMsg));
}
break;
case PROP_IUT:
- pRes = "1"; /* always 1 for syslog messages (a MonitorWare thing;)) */
+ pRes = UCHAR_CONSTANT("1"); /* always 1 for syslog messages (a MonitorWare thing;)) */
+ bufLen = 1;
break;
case PROP_SYSLOGFACILITY:
- pRes = getFacility(pMsg);
+ pRes = (uchar*)getFacility(pMsg);
break;
case PROP_SYSLOGFACILITY_TEXT:
- pRes = getFacilityStr(pMsg);
+ pRes = (uchar*)getFacilityStr(pMsg);
break;
case PROP_SYSLOGSEVERITY:
- pRes = getSeverity(pMsg);
+ pRes = (uchar*)getSeverity(pMsg);
break;
case PROP_SYSLOGSEVERITY_TEXT:
- pRes = getSeverityStr(pMsg);
+ pRes = (uchar*)getSeverityStr(pMsg);
break;
case PROP_TIMEGENERATED:
- pRes = getTimeGenerated(pMsg, pTpe->data.field.eDateFormat);
+ pRes = (uchar*)getTimeGenerated(pMsg, pTpe->data.field.eDateFormat);
break;
case PROP_PROGRAMNAME:
pRes = getProgramName(pMsg, LOCK_MUTEX);
break;
case PROP_PROTOCOL_VERSION:
- pRes = getProtocolVersionString(pMsg);
+ pRes = (uchar*)getProtocolVersionString(pMsg);
break;
case PROP_STRUCTURED_DATA:
- pRes = getStructuredData(pMsg);
+ pRes = (uchar*)getStructuredData(pMsg);
break;
case PROP_APP_NAME:
- pRes = getAPPNAME(pMsg, LOCK_MUTEX);
+ pRes = (uchar*)getAPPNAME(pMsg, LOCK_MUTEX);
break;
case PROP_PROCID:
- pRes = getPROCID(pMsg, LOCK_MUTEX);
+ pRes = (uchar*)getPROCID(pMsg, LOCK_MUTEX);
break;
case PROP_MSGID:
- pRes = getMSGID(pMsg);
+ pRes = (uchar*)getMSGID(pMsg);
break;
case PROP_SYS_NOW:
- if((pRes = (char*) getNOW(NOW_NOW)) == NULL) {
- return "***OUT OF MEMORY***";
+ if((pRes = getNOW(NOW_NOW)) == NULL) {
+ return UCHAR_CONSTANT("**OUT OF MEMORY**");
} else
*pbMustBeFreed = 1; /* all of these functions allocate dyn. memory */
break;
case PROP_SYS_YEAR:
- if((pRes = (char*) getNOW(NOW_YEAR)) == NULL) {
- return "***OUT OF MEMORY***";
+ if((pRes = getNOW(NOW_YEAR)) == NULL) {
+ return UCHAR_CONSTANT("**OUT OF MEMORY**");
} else
*pbMustBeFreed = 1; /* all of these functions allocate dyn. memory */
break;
case PROP_SYS_MONTH:
- if((pRes = (char*) getNOW(NOW_MONTH)) == NULL) {
- return "***OUT OF MEMORY***";
+ if((pRes = getNOW(NOW_MONTH)) == NULL) {
+ return UCHAR_CONSTANT("**OUT OF MEMORY**");
} else
*pbMustBeFreed = 1; /* all of these functions allocate dyn. memory */
break;
case PROP_SYS_DAY:
- if((pRes = (char*) getNOW(NOW_DAY)) == NULL) {
- return "***OUT OF MEMORY***";
+ if((pRes = getNOW(NOW_DAY)) == NULL) {
+ return UCHAR_CONSTANT("**OUT OF MEMORY**");
} else
*pbMustBeFreed = 1; /* all of these functions allocate dyn. memory */
break;
case PROP_SYS_HOUR:
- if((pRes = (char*) getNOW(NOW_HOUR)) == NULL) {
- return "***OUT OF MEMORY***";
+ if((pRes = getNOW(NOW_HOUR)) == NULL) {
+ return UCHAR_CONSTANT("**OUT OF MEMORY**");
} else
*pbMustBeFreed = 1; /* all of these functions allocate dyn. memory */
break;
case PROP_SYS_HHOUR:
- if((pRes = (char*) getNOW(NOW_HHOUR)) == NULL) {
- return "***OUT OF MEMORY***";
+ if((pRes = getNOW(NOW_HHOUR)) == NULL) {
+ return UCHAR_CONSTANT("**OUT OF MEMORY**");
} else
*pbMustBeFreed = 1; /* all of these functions allocate dyn. memory */
break;
case PROP_SYS_QHOUR:
- if((pRes = (char*) getNOW(NOW_QHOUR)) == NULL) {
- return "***OUT OF MEMORY***";
+ if((pRes = getNOW(NOW_QHOUR)) == NULL) {
+ return UCHAR_CONSTANT("**OUT OF MEMORY**");
} else
*pbMustBeFreed = 1; /* all of these functions allocate dyn. memory */
break;
case PROP_SYS_MINUTE:
- if((pRes = (char*) getNOW(NOW_MINUTE)) == NULL) {
- return "***OUT OF MEMORY***";
+ if((pRes = getNOW(NOW_MINUTE)) == NULL) {
+ return UCHAR_CONSTANT("**OUT OF MEMORY**");
} else
*pbMustBeFreed = 1; /* all of these functions allocate dyn. memory */
break;
case PROP_SYS_MYHOSTNAME:
- pRes = (char*) glbl.GetLocalHostName();
+ pRes = glbl.GetLocalHostName();
break;
default:
/* there is no point in continuing, we may even otherwise render the
* error message unreadable. rgerhards, 2007-07-10
*/
dbgprintf("invalid property id: '%d'\n", propID);
- return "**INVALID PROPERTY NAME**";
+ return UCHAR_CONSTANT("**INVALID PROPERTY NAME**");
}
@@ -2310,8 +2320,8 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
*/
if(pTpe->data.field.has_fields == 1) {
size_t iCurrFld;
- char *pFld;
- char *pFldEnd;
+ uchar *pFld;
+ uchar *pFldEnd;
/* first, skip to the field in question. The field separator
* is always one character and is stored in the template entry.
*/
@@ -2349,7 +2359,7 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
if(*pbMustBeFreed == 1)
free(pRes);
*pbMustBeFreed = 0;
- return "**OUT OF MEMORY**";
+ return UCHAR_CONSTANT("**OUT OF MEMORY**");
}
/* now copy */
memcpy(pBuf, pFld, iLen);
@@ -2366,12 +2376,12 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
if(*pbMustBeFreed == 1)
free(pRes);
*pbMustBeFreed = 0;
- return "**FIELD NOT FOUND**";
+ return UCHAR_CONSTANT("**FIELD NOT FOUND**");
}
} else if(pTpe->data.field.iFromPos != 0 || pTpe->data.field.iToPos != 0) {
/* we need to obtain a private copy */
int iFrom, iTo;
- char *pSb;
+ uchar *pSb;
iFrom = pTpe->data.field.iFromPos;
iTo = pTpe->data.field.iToPos;
/* need to zero-base to and from (they are 1-based!) */
@@ -2379,43 +2389,55 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
--iFrom;
if(iTo > 0)
--iTo;
- iLen = iTo - iFrom + 1; /* the +1 is for an actual char, NOT \0! */
- pBufStart = pBuf = malloc((iLen + 1) * sizeof(char));
- if(pBuf == NULL) {
- if(*pbMustBeFreed == 1)
- free(pRes);
- *pbMustBeFreed = 0;
- return "**OUT OF MEMORY**";
- }
- pSb = pRes;
- if(iFrom) {
- /* skip to the start of the substring (can't do pointer arithmetic
- * because the whole string might be smaller!!)
- */
- while(*pSb && iFrom) {
- --iFrom;
+ if(bufLen == -1)
+ bufLen = ustrlen(pRes);
+ if(iFrom == 0 && iTo >= bufLen) {
+ /* in this case, the requested string is a superset of what we already have,
+ * so there is no need to do any processing. This is a frequent case for size-limited
+ * fields like TAG in the default forwarding template (so it is a useful optimization
+ * to check for this condition ;)). -- rgerhards, 2009-07-09
+ */
+ ; /*DO NOTHING*/
+ } else {
+ iLen = iTo - iFrom + 1; /* the +1 is for an actual char, NOT \0! */
+ pBufStart = pBuf = malloc((iLen + 1) * sizeof(char));
+ if(pBuf == NULL) {
+ if(*pbMustBeFreed == 1)
+ free(pRes);
+ *pbMustBeFreed = 0;
+ return UCHAR_CONSTANT("**OUT OF MEMORY**");
+ }
+ pSb = pRes;
+ if(iFrom) {
+ /* skip to the start of the substring (can't do pointer arithmetic
+ * because the whole string might be smaller!!)
+ */
+ while(*pSb && iFrom) {
+ --iFrom;
+ ++pSb;
+ }
+ }
+ /* OK, we are at the begin - now let's copy... */
+ bufLen = iLen;
+ while(*pSb && iLen) {
+ *pBuf++ = *pSb;
++pSb;
+ --iLen;
}
+ *pBuf = '\0';
+ bufLen -= iLen; /* subtract remaining length if the string was smaller! */
+ if(*pbMustBeFreed == 1)
+ free(pRes);
+ pRes = pBufStart;
+ *pbMustBeFreed = 1;
}
- /* OK, we are at the begin - now let's copy... */
- bufLen = iLen;
- while(*pSb && iLen) {
- *pBuf++ = *pSb;
- ++pSb;
- --iLen;
- }
- *pBuf = '\0';
- if(*pbMustBeFreed == 1)
- free(pRes);
- pRes = pBufStart;
- *pbMustBeFreed = 1;
#ifdef FEATURE_REGEXP
} else {
/* Check for regular expressions */
if (pTpe->data.field.has_regex != 0) {
if (pTpe->data.field.has_regex == 2)
/* Could not compile regex before! */
- return "**NO MATCH** **BAD REGULAR EXPRESSION**";
+ return UCHAR_CONSTANT("**NO MATCH** **BAD REGULAR EXPRESSION**");
dbgprintf("string to match for regex is: %s\n", pRes);
@@ -2428,7 +2450,7 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
*/
while(!bFound) {
int iREstat;
- iREstat = regexp.regexec(&pTpe->data.field.re, pRes + iOffs, nmatch, pmatch, 0);
+ iREstat = regexp.regexec(&pTpe->data.field.re, (char*)(pRes + iOffs), nmatch, pmatch, 0);
dbgprintf("regexec return is %d\n", iREstat);
if(iREstat == 0) {
if(pmatch[0].rm_so == -1) {
@@ -2456,11 +2478,11 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
*pbMustBeFreed = 0;
}
if(pTpe->data.field.nomatchAction == TPL_REGEX_NOMATCH_USE_DFLTSTR)
- return "**NO MATCH**";
+ return UCHAR_CONSTANT("**NO MATCH**");
else if(pTpe->data.field.nomatchAction == TPL_REGEX_NOMATCH_USE_ZERO)
- return "0";
+ return UCHAR_CONSTANT("0");
else
- return "";
+ return UCHAR_CONSTANT("");
}
} else {
/* Match- but did it match the one we wanted? */
@@ -2472,24 +2494,24 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
*pbMustBeFreed = 0;
}
if(pTpe->data.field.nomatchAction == TPL_REGEX_NOMATCH_USE_DFLTSTR)
- return "**NO MATCH**";
+ return UCHAR_CONSTANT("**NO MATCH**");
else
- return "";
+ return UCHAR_CONSTANT("");
}
}
/* OK, we have a usable match - we now need to malloc pB */
int iLenBuf;
- char *pB;
+ uchar *pB;
iLenBuf = pmatch[pTpe->data.field.iSubMatchToUse].rm_eo
- pmatch[pTpe->data.field.iSubMatchToUse].rm_so;
- pB = (char *) malloc((iLenBuf + 1) * sizeof(char));
+ pB = malloc((iLenBuf + 1) * sizeof(uchar));
if (pB == NULL) {
if (*pbMustBeFreed == 1)
free(pRes);
*pbMustBeFreed = 0;
- return "**OUT OF MEMORY ALLOCATING pBuf**";
+ return UCHAR_CONSTANT("**OUT OF MEMORY**");
}
/* Lets copy the matched substring to the buffer */
@@ -2512,7 +2534,7 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
free(pRes);
*pbMustBeFreed = 0;
}
- return "***REGEXP NOT AVAILABLE***";
+ return UCHAR_CONSTANT("***REGEXP NOT AVAILABLE***");
}
}
#endif /* #ifdef FEATURE_REGEXP */
@@ -2524,7 +2546,7 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
uchar cFirst = *pRes; /* save first char */
if(*pbMustBeFreed == 1)
free(pRes);
- pRes = (cFirst == ' ') ? "" : " ";
+ pRes = (cFirst == ' ') ? UCHAR_CONSTANT("") : UCHAR_CONSTANT(" ");
bufLen = (cFirst == ' ') ? 0 : 1;
*pbMustBeFreed = 0;
}
@@ -2536,21 +2558,21 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
if(pTpe->data.field.eCaseConv != tplCaseConvNo) {
/* we need to obtain a private copy */
if(bufLen == -1)
- bufLen = strlen(pRes);
- char *pBStart;
- char *pB;
- char *pSrc;
+ bufLen = ustrlen(pRes);
+ uchar *pBStart;
+ uchar *pB;
+ uchar *pSrc;
pBStart = pB = malloc((bufLen + 1) * sizeof(char));
if(pB == NULL) {
if(*pbMustBeFreed == 1)
free(pRes);
*pbMustBeFreed = 0;
- return "**OUT OF MEMORY**";
+ return UCHAR_CONSTANT("**OUT OF MEMORY**");
}
pSrc = pRes;
while(*pSrc) {
*pB++ = (pTpe->data.field.eCaseConv == tplCaseConvUpper) ?
- (char)toupper((int)*pSrc) : (char)tolower((int)*pSrc);
+ (uchar)toupper((int)*pSrc) : (uchar)tolower((int)*pSrc);
/* currently only these two exist */
++pSrc;
}
@@ -2574,10 +2596,10 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
*/
if(pTpe->data.field.options.bDropCC) {
int iLenBuf = 0;
- char *pSrc = pRes;
- char *pDstStart;
- char *pDst;
- char bDropped = 0;
+ uchar *pSrc = pRes;
+ uchar *pDstStart;
+ uchar *pDst;
+ uchar bDropped = 0;
while(*pSrc) {
if(!iscntrl((int) *pSrc++))
@@ -2592,7 +2614,7 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
if(*pbMustBeFreed == 1)
free(pRes);
*pbMustBeFreed = 0;
- return "**OUT OF MEMORY**";
+ return UCHAR_CONSTANT("**OUT OF MEMORY**");
}
for(pSrc = pRes; *pSrc; pSrc++) {
if(!iscntrl((int) *pSrc))
@@ -2606,9 +2628,9 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
*pbMustBeFreed = 1;
}
} else if(pTpe->data.field.options.bSpaceCC) {
- char *pSrc;
- char *pDstStart;
- char *pDst;
+ uchar *pSrc;
+ uchar *pDstStart;
+ uchar *pDst;
if(*pbMustBeFreed == 1) {
/* in this case, we already work on dynamic
@@ -2622,13 +2644,13 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
}
} else {
if(bufLen == -1)
- bufLen = strlen(pRes);
+ bufLen = ustrlen(pRes);
pDst = pDstStart = malloc(bufLen + 1);
if(pDst == NULL) {
if(*pbMustBeFreed == 1)
free(pRes);
*pbMustBeFreed = 0;
- return "**OUT OF MEMORY**";
+ return UCHAR_CONSTANT("**OUT OF MEMORY**");
}
for(pSrc = pRes; *pSrc; pSrc++) {
if(iscntrl((int) *pSrc))
@@ -2648,7 +2670,7 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
*/
int iNumCC = 0;
int iLenBuf = 0;
- char *pB;
+ uchar *pB;
for(pB = pRes ; *pB ; ++pB) {
++iLenBuf;
@@ -2658,21 +2680,21 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
if(iNumCC > 0) { /* if 0, there is nothing to escape, so we are done */
/* OK, let's do the escaping... */
- char *pBStart;
- char szCCEsc[8]; /* buffer for escape sequence */
+ uchar *pBStart;
+ uchar szCCEsc[8]; /* buffer for escape sequence */
int i;
iLenBuf += iNumCC * 4;
- pBStart = pB = malloc((iLenBuf + 1) * sizeof(char));
+ pBStart = pB = malloc((iLenBuf + 1) * sizeof(uchar));
if(pB == NULL) {
if(*pbMustBeFreed == 1)
free(pRes);
*pbMustBeFreed = 0;
- return "**OUT OF MEMORY**";
+ return UCHAR_CONSTANT("**OUT OF MEMORY**");
}
while(*pRes) {
if(iscntrl((int) *pRes)) {
- snprintf(szCCEsc, sizeof(szCCEsc), "#%3.3d", *pRes);
+ snprintf((char*)szCCEsc, sizeof(szCCEsc), "#%3.3d", *pRes);
for(i = 0 ; i < 4 ; ++i)
*pB++ = szCCEsc[i];
} else {
@@ -2696,10 +2718,10 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
if(pTpe->data.field.options.bSecPathDrop || pTpe->data.field.options.bSecPathReplace) {
if(pTpe->data.field.options.bSecPathDrop) {
int iLenBuf = 0;
- char *pSrc = pRes;
- char *pDstStart;
- char *pDst;
- char bDropped = 0;
+ uchar *pSrc = pRes;
+ uchar *pDstStart;
+ uchar *pDst;
+ uchar bDropped = 0;
while(*pSrc) {
if(*pSrc++ != '/')
@@ -2714,7 +2736,7 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
if(*pbMustBeFreed == 1)
free(pRes);
*pbMustBeFreed = 0;
- return "**OUT OF MEMORY**";
+ return UCHAR_CONSTANT("**OUT OF MEMORY**");
}
for(pSrc = pRes; *pSrc; pSrc++) {
if(*pSrc != '/')
@@ -2728,9 +2750,9 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
*pbMustBeFreed = 1;
}
} else {
- char *pSrc;
- char *pDstStart;
- char *pDst;
+ uchar *pSrc;
+ uchar *pDstStart;
+ uchar *pDst;
if(*pbMustBeFreed == 1) {
/* here, again, we can modify the string as we already obtained
@@ -2744,13 +2766,13 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
}
} else {
if(bufLen == -1)
- bufLen = strlen(pRes);
+ bufLen = ustrlen(pRes);
pDst = pDstStart = malloc(bufLen + 1);
if(pDst == NULL) {
if(*pbMustBeFreed == 1)
free(pRes);
*pbMustBeFreed = 0;
- return "**OUT OF MEMORY**";
+ return UCHAR_CONSTANT("**OUT OF MEMORY**");
}
for(pSrc = pRes; *pSrc; pSrc++) {
if(*pSrc == '/')
@@ -2770,19 +2792,19 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
/* check for "." and ".." (note the parenthesis in the if condition!) */
if((*pRes == '.') && (*(pRes + 1) == '\0' || (*(pRes + 1) == '.' && *(pRes + 2) == '\0'))) {
- char *pTmp = pRes;
+ uchar *pTmp = pRes;
if(*(pRes + 1) == '\0')
- pRes = "_";
+ pRes = UCHAR_CONSTANT("_");
else
- pRes = "_.";;
+ pRes = UCHAR_CONSTANT("_.");;
if(*pbMustBeFreed == 1)
free(pTmp);
*pbMustBeFreed = 0;
} else if(*pRes == '\0') {
if(*pbMustBeFreed == 1)
free(pRes);
- pRes = "_";
+ pRes = UCHAR_CONSTANT("_");
bufLen = 1;
*pbMustBeFreed = 0;
}
@@ -2793,19 +2815,19 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
*/
if(pTpe->data.field.options.bDropLastLF && !pTpe->data.field.options.bEscapeCC) {
int iLn;
- char *pB;
+ uchar *pB;
if(bufLen == -1)
- bufLen = strlen(pRes);
+ bufLen = ustrlen(pRes);
iLn = bufLen;
if(iLn > 0 && *(pRes + iLn - 1) == '\n') {
/* we have a LF! */
/* check if we need to obtain a private copy */
if(*pbMustBeFreed == 0) {
/* ok, original copy, need a private one */
- pB = malloc((iLn + 1) * sizeof(char));
+ pB = malloc((iLn + 1) * sizeof(uchar));
if(pB == NULL) {
*pbMustBeFreed = 0;
- return "**OUT OF MEMORY**";
+ return UCHAR_CONSTANT("**OUT OF MEMORY**");
}
memcpy(pB, pRes, iLn - 1);
pRes = pB;
@@ -2824,19 +2846,19 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
if(pTpe->data.field.options.bCSV) {
/* we need to obtain a private copy, as we need to at least add the double quotes */
int iBufLen;
- char *pBStart;
- char *pDst;
- char *pSrc;
+ uchar *pBStart;
+ uchar *pDst;
+ uchar *pSrc;
if(bufLen == -1)
- bufLen = strlen(pRes);
+ bufLen = ustrlen(pRes);
iBufLen = bufLen;
/* the malloc may be optimized, we currently use the worst case... */
- pBStart = pDst = malloc((2 * iBufLen + 3) * sizeof(char));
+ pBStart = pDst = malloc((2 * iBufLen + 3) * sizeof(uchar));
if(pDst == NULL) {
if(*pbMustBeFreed == 1)
free(pRes);
*pbMustBeFreed = 0;
- return "**OUT OF MEMORY**";
+ return UCHAR_CONSTANT("**OUT OF MEMORY**");
}
pSrc = pRes;
*pDst++ = '"'; /* starting quote */
@@ -2855,10 +2877,9 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
}
if(bufLen == -1)
- bufLen = strlen(pRes);
+ bufLen = ustrlen(pRes);
*pPropLen = bufLen;
- /*dbgprintf("MsgGetProp(\"%s\"): \"%s\"\n", pName, pRes); only for verbose debug logging */
ENDfunc
return(pRes);
}
diff --git a/runtime/msg.h b/runtime/msg.h
index c20fb005..98b3599a 100644
--- a/runtime/msg.h
+++ b/runtime/msg.h
@@ -159,7 +159,7 @@ void MsgSetMSGoffs(msg_t *pMsg, short offs);
void MsgSetRawMsgWOSize(msg_t *pMsg, char* pszRawMsg);
void MsgSetRawMsg(msg_t *pMsg, char* pszRawMsg, size_t lenMsg);
rsRetVal MsgReplaceMSG(msg_t *pThis, uchar* pszMSG, int lenMSG);
-char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
+uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
propid_t propID, size_t *pPropLen, unsigned short *pbMustBeFreed);
char *textpri(char *pRes, size_t pResLen, int pri);
rsRetVal msgGetMsgVar(msg_t *pThis, cstr_t *pstrPropName, var_t **ppVar);
@@ -168,7 +168,7 @@ uchar *getRcvFrom(msg_t *pM);
/* TODO: remove these five (so far used in action.c) */
-char *getMSG(msg_t *pM);
+uchar *getMSG(msg_t *pM);
char *getHOSTNAME(msg_t *pM);
char *getPROCID(msg_t *pM, bool bLockMutex);
char *getAPPNAME(msg_t *pM, bool bLockMutex);
@@ -176,7 +176,7 @@ int getMSGLen(msg_t *pM);
char *getHOSTNAME(msg_t *pM);
int getHOSTNAMELen(msg_t *pM);
-char *getProgramName(msg_t *pM, bool bLockMutex);
+uchar *getProgramName(msg_t *pM, bool bLockMutex);
int getProgramNameLen(msg_t *pM, bool bLockMutex);
uchar *getRcvFrom(msg_t *pM);
rsRetVal propNameToID(cstr_t *pCSPropName, propid_t *pPropID);
diff --git a/runtime/parser.c b/runtime/parser.c
index a5183105..a2538fa3 100644
--- a/runtime/parser.c
+++ b/runtime/parser.c
@@ -115,7 +115,6 @@ static inline rsRetVal uncompressMessage(msg_t *pMsg)
FINALIZE; /* unconditional exit, nothing left to do... */
}
MsgSetRawMsg(pMsg, (char*)deflateBuf, iLenDefBuf);
- free(deflateBuf);
}
finalize_it:
if(deflateBuf != NULL)
diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h
index c51b1272..71cb9cf2 100644
--- a/runtime/rsyslog.h
+++ b/runtime/rsyslog.h
@@ -381,6 +381,9 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth
RS_RET_FILENAME_INVALID = -2140, /**< filename invalid, not found, no access, ... */
RS_RET_ZLIB_ERR = -2141, /**< error during zlib call */
RS_RET_VAR_NOT_FOUND = -2142, /**< variable not found */
+ RS_RET_NO_SRCNAME_TPL = -2143, /**< sourcename template was not specified where one was needed (omudpspoof spoof addr) */
+ RS_RET_HOST_NOT_SPECIFIED = -2144, /**< (target) host was not specified where it was needed */
+ RS_RET_ERR_LIBNET_INIT = -2145, /**< error initializing libnet */
/* RainerScript error messages (range 1000.. 1999) */
RS_RET_SYSVAR_NOT_FOUND = 1001, /**< system variable could not be found (maybe misspelled) */
diff --git a/runtime/rule.c b/runtime/rule.c
index 3a257a90..182d616a 100644
--- a/runtime/rule.c
+++ b/runtime/rule.c
@@ -39,6 +39,7 @@
#include "vm.h"
#include "var.h"
#include "srUtils.h"
+#include "unicode-helper.h"
#include "dirty.h" /* for getFIOPName */
/* static data */
@@ -104,7 +105,7 @@ shouldProcessThisMessage(rule_t *pRule, msg_t *pMsg, int *bProcessMsg)
{
DEFiRet;
unsigned short pbMustBeFreed;
- char *pszPropVal;
+ uchar *pszPropVal;
int bRet = 0;
size_t propLen;
vm_t *pVM = NULL;
@@ -189,12 +190,12 @@ shouldProcessThisMessage(rule_t *pRule, msg_t *pMsg, int *bProcessMsg)
break;
case FIOP_ISEQUAL:
if(rsCStrSzStrCmp(pRule->f_filterData.prop.pCSCompValue,
- (uchar*) pszPropVal, strlen(pszPropVal)) == 0)
+ pszPropVal, ustrlen(pszPropVal)) == 0)
bRet = 1; /* process message! */
break;
case FIOP_STARTSWITH:
if(rsCStrSzStrStartsWithCStr(pRule->f_filterData.prop.pCSCompValue,
- (uchar*) pszPropVal, strlen(pszPropVal)) == 0)
+ pszPropVal, ustrlen(pszPropVal)) == 0)
bRet = 1; /* process message! */
break;
case FIOP_REGEX:
diff --git a/runtime/wti.c b/runtime/wti.c
index 769575e1..9233cb4c 100644
--- a/runtime/wti.c
+++ b/runtime/wti.c
@@ -356,7 +356,6 @@ wtiWorker(wti_t *pThis)
d_pthread_mutex_lock(&pThis->mut);
pthread_cleanup_pop(0); /* remove cleanup handler */
-RUNLOG_STR("XXX: Worker shutdown");
pWtp->pfOnWorkerShutdown(pWtp->pUsr);
wtiSetState(pThis, eWRKTHRD_STOPPED, 0, MUTEX_ALREADY_LOCKED);
diff --git a/tcpclt.c b/tcpclt.c
index c53f00f7..617aaef6 100644
--- a/tcpclt.c
+++ b/tcpclt.c
@@ -297,6 +297,12 @@ Send(tcpclt_t *pThis, void *pData, char *msg, size_t len)
CHKiRet(TCPSendBldFrame(pThis, &msg, &len, &bMsgMustBeFreed));
+ if(pThis->iRebindInterval > 0 && ++pThis->iNumMsgs == pThis->iRebindInterval) {
+ /* we need to rebind, and use the retry logic for this*/
+ CHKiRet(pThis->prepRetryFunc(pData)); /* try to recover */
+ pThis->iNumMsgs = 0;
+ }
+
while(!bDone) { /* loop is broken when send succeeds or error occurs */
CHKiRet(pThis->initFunc(pData));
iRet = pThis->sendFunc(pData, msg, len);
@@ -388,6 +394,13 @@ SetFraming(tcpclt_t *pThis, TCPFRAMINGMODE framing)
pThis->tcp_framing = framing;
RETiRet;
}
+static rsRetVal
+SetRebindInterval(tcpclt_t *pThis, int iRebindInterval)
+{
+ DEFiRet;
+ pThis->iRebindInterval = iRebindInterval;
+ RETiRet;
+}
/* Standard-Constructor
@@ -445,6 +458,7 @@ CODESTARTobjQueryInterface(tcpclt)
pIf->SetSendFrame = SetSendFrame;
pIf->SetSendPrepRetry = SetSendPrepRetry;
pIf->SetFraming = SetFraming;
+ pIf->SetRebindInterval = SetRebindInterval;
finalize_it:
ENDobjQueryInterface(tcpclt)
diff --git a/tcpclt.h b/tcpclt.h
index 1d704044..5a8eba75 100644
--- a/tcpclt.h
+++ b/tcpclt.h
@@ -36,6 +36,8 @@ typedef struct tcpclt_s {
short bResendLastOnRecon; /* should the last message be resent on a successful reconnect? */
size_t lenPrevMsg;
/* session specific callbacks */
+ int iRebindInterval; /* how often should the send socket be rebound? */
+ int iNumMsgs; /* number of messages during current "rebind session" */
rsRetVal (*initFunc)(void*);
rsRetVal (*sendFunc)(void*, char*, size_t);
rsRetVal (*prepRetryFunc)(void*);
@@ -55,8 +57,10 @@ BEGINinterface(tcpclt) /* name must also be changed in ENDinterface macro! */
rsRetVal (*SetSendFrame)(tcpclt_t*, rsRetVal (*)(void*, char*, size_t));
rsRetVal (*SetSendPrepRetry)(tcpclt_t*, rsRetVal (*)(void*));
rsRetVal (*SetFraming)(tcpclt_t*, TCPFRAMINGMODE framing);
+ /* v3, 2009-07-14*/
+ rsRetVal (*SetRebindInterval)(tcpclt_t*, int iRebindInterval);
ENDinterface(tcpclt)
-#define tcpcltCURR_IF_VERSION 2 /* increment whenever you change the interface structure! */
+#define tcpcltCURR_IF_VERSION 3 /* increment whenever you change the interface structure! */
/* prototypes */
diff --git a/template.c b/template.c
index 832183b0..0116e782 100644
--- a/template.c
+++ b/template.c
@@ -121,8 +121,10 @@ rsRetVal tplToString(struct template *pTpl, msg_t *pMsg, uchar **ppBuf, size_t *
if(iBuf + iLenVal + 1 >= *pLenBuf) /* we reserve one char for the final \0! */
CHKiRet(ExtendBuf(ppBuf, pLenBuf, iBuf + iLenVal + 1));
- memcpy(*ppBuf + iBuf, pVal, iLenVal);
- iBuf += iLenVal;
+ if(iLenVal > 0) { /* may be zero depending on property */
+ memcpy(*ppBuf + iBuf, pVal, iLenVal);
+ iBuf += iLenVal;
+ }
if(bMustBeFreed)
free(pVal);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index e5b1f819..6ca0c069 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -15,6 +15,7 @@ TESTS = $(TESTRUNS) cfg.sh \
if ENABLE_OMSTDOUT
TESTS += omod-if-array.sh \
+ proprepltest.sh \
parsertest.sh \
timestamp.sh \
inputname.sh \
@@ -124,6 +125,11 @@ EXTRA_DIST= 1.rstest 2.rstest 3.rstest err1.rstest \
testsuites/threadingmq.conf \
threadingmqaq.sh \
testsuites/threadingmqaq.conf \
+ proprepltest.sh \
+ testsuites/rfctag.conf \
+ testsuites/master.rfctag \
+ testsuites/nolimittag.conf \
+ testsuites/master.nolimittag \
DiagTalker.java \
cfg.sh
diff --git a/tests/diag.sh b/tests/diag.sh
index 299c5d71..13bb877d 100755
--- a/tests/diag.sh
+++ b/tests/diag.sh
@@ -83,6 +83,7 @@ case $1 in
fi
;;
'nettester') # perform nettester-based tests
+ # use -v for verbose output!
./nettester -t$2 -i$3
if [ "$?" -ne "0" ]; then
exit 1
diff --git a/tests/nettester.c b/tests/nettester.c
index 41b093c5..71641745 100644
--- a/tests/nettester.c
+++ b/tests/nettester.c
@@ -38,6 +38,7 @@
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/stat.h>
+#include <sys/time.h>
#include <arpa/inet.h>
#include <assert.h>
#include <unistd.h>
@@ -82,14 +83,27 @@ static char *inputMode2Str(inputMode_t mode)
void readLine(int fd, char *ln)
{
+ char *orig = ln;
char c;
int lenRead;
+
+ if(verbose)
+ fprintf(stderr, "begin readLine\n");
lenRead = read(fd, &c, 1);
while(lenRead == 1 && c != '\n') {
+ if(c == '\0') {
+ *ln = c;
+ fprintf(stderr, "Warning: there was a '\\0'-Byte in the read response "
+ "right after this string: '%s'\n", orig);
+ c = '?';
+ }
*ln++ = c;
- lenRead = read(fd, &c, 1);
+ lenRead = read(fd, &c, 1);
}
*ln = '\0';
+
+ if(verbose)
+ fprintf(stderr, "end readLine, val read '%s'\n", orig);
}
@@ -208,7 +222,6 @@ int openPipe(char *configFile, pid_t *pid, int *pfd)
"RSYSLOG_DEBUGLOG=log", NULL };
*/
-
sprintf(confFile, "-f%s/testsuites/%s.conf", srcdir,
(pszCustomConf == NULL) ? configFile : pszCustomConf);
newargv[1] = confFile;
diff --git a/tests/parsertest.sh b/tests/parsertest.sh
index 8e04b95e..ef33256e 100755
--- a/tests/parsertest.sh
+++ b/tests/parsertest.sh
@@ -1,13 +1,5 @@
-echo test parsertest via udp
-$srcdir/killrsyslog.sh # kill rsyslogd if it runs for some reason
-
-echo test parsertest via tcp
-./nettester -tparse1 -itcp
-if [ "$?" -ne "0" ]; then
- exit 1
-fi
-
-./nettester -tparse1 -iudp
-if [ "$?" -ne "0" ]; then
- exit 1
-fi
+echo TEST: parsertest.sh - various parser tests
+source $srcdir/diag.sh init
+source $srcdir/diag.sh nettester parse1 udp
+source $srcdir/diag.sh nettester parse1 tcp
+source $srcdir/diag.sh init
diff --git a/tests/proprepltest.sh b/tests/proprepltest.sh
new file mode 100755
index 00000000..3c252e52
--- /dev/null
+++ b/tests/proprepltest.sh
@@ -0,0 +1,7 @@
+echo TEST: proprepltest.sh - various tests for the property replacer
+source $srcdir/diag.sh init
+source $srcdir/diag.sh nettester rfctag udp
+source $srcdir/diag.sh nettester rfctag tcp
+source $srcdir/diag.sh nettester nolimittag udp
+source $srcdir/diag.sh nettester nolimittag tcp
+source $srcdir/diag.sh init
diff --git a/tests/testsuites/master.nolimittag b/tests/testsuites/master.nolimittag
new file mode 100644
index 00000000..502d9d5d
--- /dev/null
+++ b/tests/testsuites/master.nolimittag
@@ -0,0 +1,11 @@
+<167>Mar 6 16:57:54 172.20.245.8 TAG: Rest of message...
++TAG:+
+# now one char, no colon
+<167>Mar 6 16:57:54 172.20.245.8 0 Rest of message...
++0+
+# Now exactly with 32 characters
+<167>Mar 6 16:57:54 172.20.245.8 01234567890123456789012345678901 Rest of message...
++01234567890123456789012345678901+
+# Now oversize, should be completely output with this config
+<167>Mar 6 16:57:54 172.20.245.8 01234567890123456789012345678901-toolong Rest of message...
++01234567890123456789012345678901-toolong+
diff --git a/tests/testsuites/master.rfctag b/tests/testsuites/master.rfctag
new file mode 100644
index 00000000..3f1e0c66
--- /dev/null
+++ b/tests/testsuites/master.rfctag
@@ -0,0 +1,11 @@
+<167>Mar 6 16:57:54 172.20.245.8 TAG: Rest of message...
++TAG:+
+# now one char, no colon
+<167>Mar 6 16:57:54 172.20.245.8 0 Rest of message...
++0+
+# Now exactly with 32 characters
+<167>Mar 6 16:57:54 172.20.245.8 01234567890123456789012345678901 Rest of message...
++01234567890123456789012345678901+
+# Now oversize, should be truncated with this config
+<167>Mar 6 16:57:54 172.20.245.8 01234567890123456789012345678901-toolong Rest of message...
++01234567890123456789012345678901+
diff --git a/tests/testsuites/nolimittag.conf b/tests/testsuites/nolimittag.conf
new file mode 100644
index 00000000..0b6ec387
--- /dev/null
+++ b/tests/testsuites/nolimittag.conf
@@ -0,0 +1,8 @@
+$ModLoad ../plugins/omstdout/.libs/omstdout
+$IncludeConfig nettest.input.conf # This picks the to be tested input from the test driver!
+
+$ErrorMessagesToStderr off
+
+# use a special format
+$template fmt,"+%syslogtag%+\n"
+*.* :omstdout:;fmt
diff --git a/tests/testsuites/rfctag.conf b/tests/testsuites/rfctag.conf
new file mode 100644
index 00000000..8619e89e
--- /dev/null
+++ b/tests/testsuites/rfctag.conf
@@ -0,0 +1,9 @@
+$ModLoad ../plugins/omstdout/.libs/omstdout
+$IncludeConfig nettest.input.conf # This picks the to be tested input from the test driver!
+
+$ErrorMessagesToStderr off
+
+# use a special format
+# Note: the plus signs are necessary to detect truncated logs!
+$template fmt,"+%syslogtag:1:32%+\n"
+*.* :omstdout:;fmt
diff --git a/tools/omfwd.c b/tools/omfwd.c
index 2966a5e4..38d9cfa6 100644
--- a/tools/omfwd.c
+++ b/tools/omfwd.c
@@ -10,7 +10,7 @@
* 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.
*
- * Copyright 2007 Rainer Gerhards and Adiscon GmbH.
+ * Copyright 2007, 2009 Rainer Gerhards and Adiscon GmbH.
*
* This file is part of rsyslog.
*
@@ -90,6 +90,7 @@ typedef struct _instanceData {
char *port;
int protocol;
int iUDPRebindInterval; /* rebind interval */
+ int iTCPRebindInterval; /* rebind interval */
int nXmit; /* number of transmissions since last (re-)bind */
# define FORW_UDP 0
# define FORW_TCP 1
@@ -104,6 +105,7 @@ static short iStrmDrvrMode = 0; /* mode for stream driver, driver-dependent (0 m
static short bResendLastOnRecon = 0; /* should the last message be re-sent on a successful reconnect? */
static uchar *pszStrmDrvrAuthMode = NULL; /* authentication mode to use */
static int iUDPRebindInterval = 0; /* support for automatic re-binding (load balancers!). 0 - no rebind */
+static int iTCPRebindInterval = 0; /* support for automatic re-binding (load balancers!). 0 - no rebind */
static permittedPeers_t *pPermPeers = NULL;
@@ -206,8 +208,6 @@ static rsRetVal UDPSend(instanceData *pData, char *msg, size_t len)
unsigned lsent = 0;
int bSendSuccess;
-dbgprintf("rebind logic: interval %d, curr %d, mod %d, if %d\n", pData->iUDPRebindInterval, pData->nXmit,
- (pData->nXmit % pData->iUDPRebindInterval), ((pData->nXmit % pData->iUDPRebindInterval) == 0));
if(pData->iUDPRebindInterval && (pData->nXmit++ % pData->iUDPRebindInterval == 0)) {
dbgprintf("omfwd dropping UDP 'connection' (as configured)\n");
pData->nXmit = 1; /* else we have an addtl wrap at 2^31-1 */
@@ -438,11 +438,11 @@ CODESTARTdoAction
*/
if(pData->compressionLevel && (l > MIN_SIZE_FOR_COMPRESS)) {
Bytef *out;
- uLongf destLen = sizeof(out) / sizeof(Bytef);
+ 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(iMaxLine + iMaxLine/100 + 12));
+ CHKmalloc(out = (Bytef*) malloc(destLen));
out[0] = 'z';
out[1] = '\0';
ret = compress2((Bytef*) out+1, &destLen, (Bytef*) psz,
@@ -645,6 +645,7 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1)
/* copy over config data as needed */
pData->iUDPRebindInterval = iUDPRebindInterval;
+ pData->iTCPRebindInterval = iTCPRebindInterval;
/* process template */
CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS,
@@ -659,6 +660,7 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1)
CHKiRet(tcpclt.SetSendFrame(pData->pTCPClt, TCPSendFrame));
CHKiRet(tcpclt.SetSendPrepRetry(pData->pTCPClt, TCPSendPrepRetry));
CHKiRet(tcpclt.SetFraming(pData->pTCPClt, tcp_framing));
+ CHKiRet(tcpclt.SetRebindInterval(pData->pTCPClt, pData->iTCPRebindInterval));
pData->iStrmDrvrMode = iStrmDrvrMode;
if(pszStrmDrvr != NULL)
CHKmalloc(pData->pszStrmDrvr = (uchar*)strdup((char*)pszStrmDrvr));
@@ -730,6 +732,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a
iStrmDrvrMode = 0;
bResendLastOnRecon = 0;
iUDPRebindInterval = 0;
+ iTCPRebindInterval = 0;
return RS_RET_OK;
}
@@ -744,6 +747,7 @@ CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(net,LM_NET_FILENAME));
CHKiRet(regCfSysLineHdlr((uchar *)"actionforwarddefaulttemplate", 0, eCmdHdlrGetWord, NULL, &pszTplName, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"actionsendtcprebindinterval", 0, eCmdHdlrInt, NULL, &iTCPRebindInterval, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"actionsendudprebindinterval", 0, eCmdHdlrInt, NULL, &iUDPRebindInterval, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"actionsendstreamdriver", 0, eCmdHdlrGetWord, NULL, &pszStrmDrvr, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"actionsendstreamdrivermode", 0, eCmdHdlrInt, NULL, &iStrmDrvrMode, NULL));
diff --git a/tools/rsyslogd.8 b/tools/rsyslogd.8
index 7d4b5e03..6ac30e46 100644
--- a/tools/rsyslogd.8
+++ b/tools/rsyslogd.8
@@ -248,20 +248,17 @@ kill -HUP $(cat /var/run/rsyslogd.pid)
.B HUP
This lets
.B rsyslogd
-perform a re-initialization. All open files are closed, the
-configuration file (default is
-.IR /etc/rsyslog.conf ")"
-will be reread and the
-.BR rsyslog (3)
-facility is started again.
+perform close all open files.
+Also, in v3 a full restart will be done in order to read changed configuration files.
Note that this means a full rsyslogd restart is done. This has, among others,
the consequence that TCP and other connections are torn down. Also, if any
queues are not running in disk assisted mode or are not set to persist data
on shutdown, queue data is lost. HUPing rsyslogd is an extremely expensive
operation and should only be done when actually necessary. Actually, it is
-a rsyslgod stop immediately followed by a restart. Future versions will probably
-include a special handling which only closes files, but will not cause any
-of the other effects.
+a rsyslgod stop immediately followed by a restart. Future versions will remove
+this restart functionality of HUP (it will go away in v5). So it is advised to use
+HUP only for closing files, and a "real restart" (e.g. /etc/rc.d/rsyslogd restart)
+to activate configuration changes.
.TP
.B TERM ", " INT ", " QUIT
.B Rsyslogd
diff --git a/tools/syslogd.c b/tools/syslogd.c
index e4daff54..ada3288e 100644
--- a/tools/syslogd.c
+++ b/tools/syslogd.c
@@ -16,12 +16,9 @@
* parts of the code have been rewritten.
*
* This Project was intiated and is maintained by
- * Rainer Gerhards <rgerhards@hq.adiscon.com>. See
- * AUTHORS to learn who helped make it become a reality.
+ * Rainer Gerhards <rgerhards@hq.adiscon.com>.
*
- * If you have questions about rsyslogd in general, please email
- * info@adiscon.com. To learn more about rsyslogd, please visit
- * http://www.rsyslog.com.
+ * For further information, please see http://www.rsyslog.com
*
* \author Rainer Gerhards <rgerhards@adiscon.com>
* \date 2003-10-17
@@ -425,7 +422,7 @@ diagGetMainMsgQSize(int *piSize)
/* rgerhards, 2005-10-24: crunch_list is called only during option processing. So
- * it is never called once rsyslogd is running (not even when HUPed). This code
+ * it is never called once rsyslogd is running. This code
* contains some exits, but they are considered safe because they only happen
* during startup. Anyhow, when we review the code here, we might want to
* reconsider the exit()s.
@@ -605,8 +602,10 @@ static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int f
if((pMsg->msgFlags & PARSE_HOSTNAME) == 0)
MsgSetHOSTNAME(pMsg, hname, ustrlen(hname));
MsgSetRcvFromStr(pMsg, hname, ustrlen(hname), &propFromHost);
- CHKiRet(MsgSetRcvFromIPStr(pMsg, hnameIP, ustrlen(hname), &propFromHostIP));
+ CHKiRet(MsgSetRcvFromIPStr(pMsg, hnameIP, ustrlen(hnameIP), &propFromHostIP));
MsgSetAfterPRIOffs(pMsg, p - msg);
+ prop.Destruct(&propFromHost);
+ prop.Destruct(&propFromHostIP);
logmsg(pMsg, flags);
@@ -920,239 +919,6 @@ finalize_it:
RETiRet;
}
-#if 0 // Code obsoleted by merge imfile, but check for changes if there are problems
-//thus I leave it in for the time being TODO: remove
-/* This functions looks at the given message and checks if it matches the
- * provided filter condition. If so, it returns true, else it returns
- * false. This is a helper to logmsg() and meant to drive the decision
- * process if a message is to be processed or not. As I expect this
- * decision code to grow more complex over time AND logmsg() is already
- * a very lengthy function, I thought a separate function is more appropriate.
- * 2005-09-19 rgerhards
- * 2008-02-25 rgerhards: changed interface, now utilizes iRet, bProcessMsg
- * returns is message should be procesed.
- */
-static rsRetVal shouldProcessThisMessage(selector_t *f, msg_t *pMsg, int *bProcessMsg)
-{
- DEFiRet;
- unsigned short pbMustBeFreed;
- char *pszPropVal;
- int bRet = 0;
- vm_t *pVM = NULL;
- var_t *pResult = NULL;
-
- assert(f != NULL);
- assert(pMsg != NULL);
-
- /* we first have a look at the global, BSD-style block filters (for tag
- * and host). Only if they match, we evaluate the actual filter.
- * rgerhards, 2005-10-18
- */
- if(f->eHostnameCmpMode == HN_NO_COMP) {
- /* EMPTY BY INTENSION - we check this value first, because
- * it is the one most often used, so this saves us time!
- */
- } else if(f->eHostnameCmpMode == HN_COMP_MATCH) {
- if(rsCStrSzStrCmp(f->pCSHostnameComp, (uchar*) getHOSTNAME(pMsg), getHOSTNAMELen(pMsg))) {
- /* not equal, so we are already done... */
- dbgprintf("hostname filter '+%s' does not match '%s'\n",
- rsCStrGetSzStrNoNULL(f->pCSHostnameComp), getHOSTNAME(pMsg));
- FINALIZE;
- }
- } else { /* must be -hostname */
- if(!rsCStrSzStrCmp(f->pCSHostnameComp, (uchar*) getHOSTNAME(pMsg), getHOSTNAMELen(pMsg))) {
- /* not equal, so we are already done... */
- dbgprintf("hostname filter '-%s' does not match '%s'\n",
- rsCStrGetSzStrNoNULL(f->pCSHostnameComp), getHOSTNAME(pMsg));
- FINALIZE;
- }
- }
-
- if(f->pCSProgNameComp != NULL) {
- int bInv = 0, bEqv = 0, offset = 0;
- if(*(rsCStrGetSzStrNoNULL(f->pCSProgNameComp)) == '-') {
- if(*(rsCStrGetSzStrNoNULL(f->pCSProgNameComp) + 1) == '-')
- offset = 1;
- else {
- bInv = 1;
- offset = 1;
- }
- }
- if(!rsCStrOffsetSzStrCmp(f->pCSProgNameComp, offset, (uchar*) getProgramName(pMsg), getProgramNameLen(pMsg)))
- bEqv = 1;
-
- if((!bEqv && !bInv) || (bEqv && bInv)) {
- /* not equal or inverted selection, so we are already done... */
- dbgprintf("programname filter '%s' does not match '%s'\n",
- rsCStrGetSzStrNoNULL(f->pCSProgNameComp), getProgramName(pMsg));
- FINALIZE;
- }
- }
-
- /* done with the BSD-style block filters */
-
- if(f->f_filter_type == FILTER_PRI) {
- /* skip messages that are incorrect priority */
- if ( (f->f_filterData.f_pmask[pMsg->iFacility] == TABLE_NOPRI) || \
- ((f->f_filterData.f_pmask[pMsg->iFacility] & (1<<pMsg->iSeverity)) == 0) )
- bRet = 0;
- else
- bRet = 1;
- } else if(f->f_filter_type == FILTER_EXPR) {
- CHKiRet(vm.Construct(&pVM));
- CHKiRet(vm.ConstructFinalize(pVM));
- CHKiRet(vm.SetMsg(pVM, pMsg));
- CHKiRet(vm.ExecProg(pVM, f->f_filterData.f_expr->pVmprg));
- CHKiRet(vm.PopBoolFromStack(pVM, &pResult));
- dbgprintf("result of expression evaluation: %lld\n", pResult->val.num);
- /* VM is destructed on function exit */
- bRet = (pResult->val.num) ? 1 : 0;
- } else {
- assert(f->f_filter_type == FILTER_PROP); /* assert() just in case... */
- pszPropVal = MsgGetProp(pMsg, NULL, f->f_filterData.prop.pCSPropName, &pbMustBeFreed);
-
- /* Now do the compares (short list currently ;)) */
- switch(f->f_filterData.prop.operation ) {
- case FIOP_CONTAINS:
- if(rsCStrLocateInSzStr(f->f_filterData.prop.pCSCompValue, (uchar*) pszPropVal) != -1)
- bRet = 1;
- break;
- case FIOP_ISEQUAL:
- if(rsCStrSzStrCmp(f->f_filterData.prop.pCSCompValue,
- (uchar*) pszPropVal, strlen(pszPropVal)) == 0)
- bRet = 1; /* process message! */
- break;
- case FIOP_STARTSWITH:
- if(rsCStrSzStrStartsWithCStr(f->f_filterData.prop.pCSCompValue,
- (uchar*) pszPropVal, strlen(pszPropVal)) == 0)
- bRet = 1; /* process message! */
- break;
- case FIOP_REGEX:
- if(rsCStrSzStrMatchRegex(f->f_filterData.prop.pCSCompValue,
- (unsigned char*) pszPropVal, 0, &f->f_filterData.prop.regex_cache) == RS_RET_OK)
- bRet = 1;
- break;
- case FIOP_EREREGEX:
- if(rsCStrSzStrMatchRegex(f->f_filterData.prop.pCSCompValue,
- (unsigned char*) pszPropVal, 1, &f->f_filterData.prop.regex_cache) == RS_RET_OK)
- bRet = 1;
- break;
- default:
- /* here, it handles NOP (for performance reasons) */
- assert(f->f_filterData.prop.operation == FIOP_NOP);
- bRet = 1; /* as good as any other default ;) */
- break;
- }
-
- /* now check if the value must be negated */
- if(f->f_filterData.prop.isNegated)
- bRet = (bRet == 1) ? 0 : 1;
-
- if(Debug) {
- dbgprintf("Filter: check for property '%s' (value '%s') ",
- rsCStrGetSzStrNoNULL(f->f_filterData.prop.pCSPropName),
- pszPropVal);
- if(f->f_filterData.prop.isNegated)
- dbgprintf("NOT ");
- dbgprintf("%s '%s': %s\n",
- getFIOPName(f->f_filterData.prop.operation),
- rsCStrGetSzStrNoNULL(f->f_filterData.prop.pCSCompValue),
- bRet ? "TRUE" : "FALSE");
- }
-
- /* cleanup */
- if(pbMustBeFreed)
- free(pszPropVal);
- }
-
-finalize_it:
- /* destruct in any case, not just on error, but it makes error handling much easier */
- if(pVM != NULL)
- vm.Destruct(&pVM);
-
- if(pResult != NULL)
- var.Destruct(&pResult);
-
- *bProcessMsg = bRet;
- RETiRet;
-}
-
-
-/* helper to processMsg(), used to call the configured actions. It is
- * executed from within llExecFunc() of the action list.
- * rgerhards, 2007-08-02
- */
-typedef struct processMsgDoActions_s {
- int bPrevWasSuspended; /* was the previous action suspended? */
- msg_t *pMsg;
-} processMsgDoActions_t;
-DEFFUNC_llExecFunc(processMsgDoActions)
-{
- DEFiRet;
- rsRetVal iRetMod; /* return value of module - we do not always pass that back */
- action_t *pAction = (action_t*) pData;
- processMsgDoActions_t *pDoActData = (processMsgDoActions_t*) pParam;
-
- assert(pAction != NULL);
-
- if((pAction->bExecWhenPrevSusp == 1) && (pDoActData->bPrevWasSuspended == 0)) {
- dbgprintf("not calling action because the previous one is not suspended\n");
- ABORT_FINALIZE(RS_RET_OK);
- }
-
- /* MULTIQUEUE: look at this below! (I say: batch states!) */
- iRetMod = actionCallAction(pAction, pDoActData->pMsg);
- if(iRetMod == RS_RET_DISCARDMSG) {
- ABORT_FINALIZE(RS_RET_DISCARDMSG);
- } else if(iRetMod == RS_RET_SUSPENDED) {
- /* indicate suspension for next module to be called */
- pDoActData->bPrevWasSuspended = 1;
- } else {
- pDoActData->bPrevWasSuspended = 0;
- }
-
-finalize_it:
- RETiRet;
-}
-
-
-/* Process (consume) a received message from the main queue. Here, messages are
- * filtered and those where the filter evaluates to true are passed to the action
- * queue for further processing.
- * rgerhards, 2005-10-13
- */
-static void
-processMsg(msg_t *pMsg)
-{
- selector_t *f;
- int bContinue;
- int bProcessMsg;
- processMsgDoActions_t DoActData;
- rsRetVal iRet;
-
- BEGINfunc
- assert(pMsg != NULL);
-
- /* log the message to the particular outputs */
-
- bContinue = 1;
- for (f = Files; f != NULL && bContinue ; f = f->f_next) {
- /* first check the filters... */
- iRet = shouldProcessThisMessage(f, pMsg, &bProcessMsg);
- if(!bProcessMsg) {
- continue;
- }
-
- /* ok -- from here, we have action-specific code, nothing really selector-specific -- rger 2007-08-01 */
- DoActData.pMsg = pMsg;
- DoActData.bPrevWasSuspended = 0;
- if(llExecFunc(&f->llActList, processMsgDoActions, (void*)&DoActData) == RS_RET_DISCARDMSG)
- bContinue = 0;
- }
- ENDfunc
-}
-
-#endif // if 0 from merge omfile
/* The consumer of dequeued messages. This function is called by the
* queue engine on dequeueing of a message. It runs on a SEPARATE
@@ -1953,16 +1719,6 @@ die(int sig)
/* terminate the remaining classes */
GlobalClassExit();
- /* TODO: this would also be the right place to de-init the builtin output modules. We
- * do not currently do that, because the module interface does not allow for
- * it. This will come some time later (it's essential with loadable modules).
- * For the time being, this is a memory leak on exit, but as the process is
- * terminated, we do not really bother about it.
- * rgerhards, 2007-08-03
- * I have added some code now, but all that mod init/de-init should be moved to
- * init, so that modules are unloaded and reloaded on HUP to. Eventually it should go
- * into destructAllActions() - but that needs to be seen. -- rgerhards, 2007-08-09
- */
module.UnloadAndDestructAll(eMOD_LINK_ALL);
DBGPRINTF("Clean shutdown completed, bye\n");
@@ -2372,13 +2128,12 @@ startInputModules(void)
}
-/* INIT -- Initialize syslogd from configuration table
- * init() is called at initial startup AND each time syslogd is HUPed
+/* INIT -- Initialize syslogd
* Note that if iConfigVerify is set, only the config file is verified but nothing
* else happens. -- rgerhards, 2008-07-28
*/
static rsRetVal
-init()
+init(void)
{
rsRetVal localRet;
int iNbrActions;
@@ -2389,8 +2144,6 @@ init()
struct sigaction sigAct;
DEFiRet;
- thrdTerminateAll(); /* stop all running input threads - TODO: reconsider location! */
-
/* initialize some static variables */
pDfltHostnameCmp = NULL;
pDfltProgNameCmp = NULL;
@@ -2398,37 +2151,6 @@ init()
DBGPRINTF("rsyslog %s - called init()\n", VERSION);
- /* delete the message queue, which also flushes all messages left over */
- if(pMsgQueue != NULL) {
- DBGPRINTF("deleting main message queue\n");
- qqueueDestruct(&pMsgQueue); /* delete pThis here! */
- pMsgQueue = NULL;
- }
-
- /* Close all open log files and free log descriptor array. This also frees
- * all output-modules instance data.
- */
- destructAllActions();
-
- /* Unload all non-static modules */
- DBGPRINTF("Unloading non-static modules.\n");
- module.UnloadAndDestructAll(eMOD_LINK_DYNAMIC_LOADED);
-
- DBGPRINTF("Clearing templates.\n");
- tplDeleteNew();
-
- /* re-setting values to defaults (where applicable) */
- /* once we have loadable modules, we must re-visit this code. The reason is
- * that config variables are not re-set, because the module is not yet loaded. On
- * the other hand, that doesn't matter, because the module got unloaded and is then
- * re-loaded, so the variables should be re-set via that way. And this is exactly how
- * it works. Loadable module's variables are initialized on load, the rest here.
- * rgerhards, 2008-04-28
- */
- conf.cfsysline((uchar*)"ResetConfigVariables");
-
- conf.ReInitConf();
-
/* construct the default ruleset */
ruleset.Construct(&pRuleset);
ruleset.SetName(pRuleset, UCHAR_CONSTANT("RSYSLOG_DefaultRuleset"));
@@ -2593,22 +2315,22 @@ init()
dbgPrintInitInfo();
}
+ memset(&sigAct, 0, sizeof (sigAct));
+ sigemptyset(&sigAct.sa_mask);
+ sigAct.sa_handler = sighup_handler;
+ sigaction(SIGHUP, &sigAct, NULL);
+
+ DBGPRINTF(" started.\n");
+
/* we now generate the startup message. It now includes everything to
* identify this instance. -- rgerhards, 2005-08-17
*/
snprintf(bufStartUpMsg, sizeof(bufStartUpMsg)/sizeof(char),
" [origin software=\"rsyslogd\" " "swVersion=\"" VERSION \
- "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] (re)start",
+ "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] start",
(int) myPid);
logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)bufStartUpMsg, 0);
- memset(&sigAct, 0, sizeof (sigAct));
- sigemptyset(&sigAct.sa_mask);
- sigAct.sa_handler = sighup_handler;
- sigaction(SIGHUP, &sigAct, NULL);
-
- DBGPRINTF(" (re)started.\n");
-
finalize_it:
RETiRet;
}
@@ -2751,19 +2473,11 @@ doHUP(void)
snprintf(buf, sizeof(buf) / sizeof(char),
" [origin software=\"rsyslogd\" " "swVersion=\"" VERSION
- "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] rsyslogd was HUPed, type '%s'.",
- (int) myPid, glbl.GetHUPisRestart() ? "restart" : "lightweight");
+ "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] rsyslogd was HUPed",
+ (int) myPid);
errno = 0;
- logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)buf, 0);
- if(glbl.GetHUPisRestart()) {
- DBGPRINTF("Received SIGHUP, configured to be restart, reloading rsyslogd.\n");
- init(); /* main queue is stopped as part of init() */
- runInputModules();
- } else {
- DBGPRINTF("Received SIGHUP, configured to be a non-restart type of HUP - notifying actions.\n");
- ruleset.IterateAllActions(doHUPActions, NULL);
- }
+ ruleset.IterateAllActions(doHUPActions, NULL);
}
@@ -3039,20 +2753,16 @@ static rsRetVal mainThread()
*/
if(gidDropPriv != 0) {
doDropPrivGid(gidDropPriv);
- glbl.SetHUPisRestart(0); /* we can not do restart-type HUPs with dropped privs */
}
if(uidDropPriv != 0) {
doDropPrivUid(uidDropPriv);
- glbl.SetHUPisRestart(0); /* we can not do restart-type HUPs with dropped privs */
}
/* finally let the inputs run... */
runInputModules();
/* END OF INTIALIZATION
- * ... but keep in mind that we might do a restart and thus init() might
- * be called again. -- rgerhards, 2005-10-24
*/
DBGPRINTF("initialization completed, transitioning to regular run mode\n");