summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2013-07-11 10:01:57 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2013-07-11 10:01:57 +0200
commit38aa077ccb3bac7493c401dbd91b97037d208d54 (patch)
treee5319635d2f50c3b7aa5dca12b53144571d80027
parent330120d1efb9c4a4a2aa3f5af529b87e57315d47 (diff)
downloadrsyslog-38aa077ccb3bac7493c401dbd91b97037d208d54.tar.gz
rsyslog-38aa077ccb3bac7493c401dbd91b97037d208d54.tar.bz2
rsyslog-38aa077ccb3bac7493c401dbd91b97037d208d54.zip
imudp: add ability to specify SO_RCVBUF size (rcvbufSize parameter)
-rw-r--r--ChangeLog1
-rw-r--r--doc/imudp.html37
-rw-r--r--plugins/imudp/imudp.c7
-rw-r--r--plugins/omudpspoof/omudpspoof.c2
-rw-r--r--runtime/net.c35
-rw-r--r--runtime/net.h2
-rw-r--r--tools/omfwd.c2
7 files changed, 70 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index a0e50d02..10ee1019 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,4 @@
+- imudp: add ability to specify SO_RCVBUF size (rcvbufSize parameter)
- impstats: add process resource usage counters [via getrusage()]
----------------------------------------------------------------------------
Version 7.2.7 [v7-stable] 2013-04-17
diff --git a/doc/imudp.html b/doc/imudp.html
index 105e0b2a..961bbeba 100644
--- a/doc/imudp.html
+++ b/doc/imudp.html
@@ -18,8 +18,8 @@
multiple input actions.
</p>
-<p><b>Configuration Directives</b>:</p>
-<p><b>Global Directives</b>:</p>
+<p><b>Configuration Parameters</b>:</p>
+<p><b>Module Parameters</b>:</p>
<ul>
<li><b>TimeRequery</b> &lt;nbr-of-times&gt;<br>
this is a performance
@@ -37,7 +37,7 @@ processing under Linux (and thus reduce chance of packet loss).
<li><b>SchedulingPriority</b> &lt;number&gt;<br>
Scheduling priority to use.
</ul>
-<p><b>Action Directives</b>:</p>
+<p><b>Action Parameters</b>:</p>
<ul>
<li><b>Address</b> &lt;IP&gt;<br>
local IP address (or name) the UDP listens should bind to</li>
@@ -47,6 +47,18 @@ default 514, start UDP server on this port. Either a single port can be specifie
<br>Array of ports: Port=["514","515","10514","..."]</li>
<li><b>Ruleset</b> &lt;ruleset&gt;<br>
Binds the listener to a specific <a href="multi_ruleset.html">ruleset</a>.</li>
+<li><b>rcvbufSize</b> &lt;size&gt;<br>
+Available since 7.5.3+<br>
+This request a socket receive buffer of specific size from the operating system.
+It is an expert parameter, which should only be changed for a good reason. Note that
+setting this parameter disables Linux auto-tuning, which usually works pretty well.
+The default value is 0, which means "keep the OS buffer size unchanged". This is a size
+value. So in addition to pure integer values, sizes like "256k", "1m" and the like can
+be specified. Note that setting very large sizes may require root or other special
+privileges. Also note that the OS may slightly adjust the value or shrink it to a
+system-set max value if the user is not sufficiently privileged. Technically, this
+parameter will result in a setsockopt() call with SO_RCVBUF (and SO_RCVBUFFORCE if it
+is available).
</ul>
<b>Caveats/Known Bugs:</b>
<ul>
@@ -59,10 +71,17 @@ user account.
<p><b>Sample:</b></p>
<p>This sets up an UPD server on port 514:<br>
</p>
-<textarea rows="15" cols="60">module(load="imudp") # needs to be done just once
+<textarea rows="4" cols="60">module(load="imudp") # needs to be done just once
input(type="imudp" port="514")
</textarea>
+<p>The following sample is mostly equivalent to the first one, but request a
+larger rcvuf size. Note that 1m most probably will not be honored by the OS
+until the user is sufficiently privileged.</p>
+<textarea rows="4" cols="60">module(load="imudp") # needs to be done just once
+input(type="imudp" port="514" rcvbufSize="1m")
+</textarea>
+
<p><b>Legacy Configuration Directives</b>:</p>
<p>Multiple receivers may be configured by specifying
$UDPServerRun multiple times.
@@ -81,14 +100,10 @@ equivalent to: SchedulingPolicy
<li>$IMUDPSchedulingPriority &lt;number&gt; Available since 4.7.4+, 5.7.3+, 6.1.3+.<br>
equivalent to: SchedulingPriority
</ul>
-<b>Caveats/Known Bugs:</b>
-<ul>
-<li>currently none known</li>
-</ul>
-<p><b>Sample:</b></p>
+<p><b>Legacy Sample:</b></p>
<p>This sets up an UPD server on port 514:<br>
</p>
-<textarea rows="15" cols="60">$ModLoad imudp # needs to be done just once
+<textarea rows="4" cols="60">$ModLoad imudp # needs to be done just once
$UDPServerRun 514
</textarea>
<p>[<a href="rsyslog_conf.html">rsyslog.conf overview</a>]
@@ -96,7 +111,7 @@ $UDPServerRun 514
<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
+Copyright &copy; 2009-2013 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>
diff --git a/plugins/imudp/imudp.c b/plugins/imudp/imudp.c
index 06e1471d..ec128d14 100644
--- a/plugins/imudp/imudp.c
+++ b/plugins/imudp/imudp.c
@@ -109,6 +109,7 @@ struct instanceConf_s {
uchar *pszBindPort; /* Port to bind socket to */
uchar *pszBindRuleset; /* name of ruleset to bind to */
ruleset_t *pBindRuleset; /* ruleset to bind listener to (use system default if unspecified) */
+ int rcvbuf; /* 0 means: do not set, keep OS default */
struct instanceConf_s *next;
};
@@ -140,6 +141,7 @@ static struct cnfparamblk modpblk =
static struct cnfparamdescr inppdescr[] = {
{ "port", eCmdHdlrArray, CNFPARAM_REQUIRED }, /* legacy: InputTCPServerRun */
{ "address", eCmdHdlrString, 0 },
+ { "rcvbufsize", eCmdHdlrSize, 0 },
{ "ruleset", eCmdHdlrString, 0 }
};
static struct cnfparamblk inppblk =
@@ -165,6 +167,7 @@ createInstance(instanceConf_t **pinst)
inst->pszBindPort = NULL;
inst->pszBindAddr = NULL;
inst->pszBindRuleset = NULL;
+ inst->rcvbuf = 0;
/* node created, let's add to config */
if(loadModConf->tail == NULL) {
@@ -239,7 +242,7 @@ addListner(instanceConf_t *inst)
DBGPRINTF("Trying to open syslog UDP ports at %s:%s.\n", bindName, inst->pszBindPort);
- newSocks = net.create_udp_socket(bindAddr, port, 1);
+ newSocks = net.create_udp_socket(bindAddr, port, 1, inst->rcvbuf);
if(newSocks != NULL) {
/* we now need to add the new sockets to the existing set */
/* ready to copy */
@@ -682,6 +685,8 @@ createListner(es_str_t *port, struct cnfparamvals *pvals)
inst->pszBindAddr = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
} else if(!strcmp(inppblk.descr[i].name, "ruleset")) {
inst->pszBindRuleset = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
+ } else if(!strcmp(inppblk.descr[i].name, "rcvbufsize")) {
+ inst->rcvbuf = (int) pvals[i].val.d.n;
} else {
dbgprintf("imudp: program error, non-handled "
"param '%s'\n", inppblk.descr[i].name);
diff --git a/plugins/omudpspoof/omudpspoof.c b/plugins/omudpspoof/omudpspoof.c
index a45d49fa..69144426 100644
--- a/plugins/omudpspoof/omudpspoof.c
+++ b/plugins/omudpspoof/omudpspoof.c
@@ -441,7 +441,7 @@ static rsRetVal doTryResume(instanceData *pData)
}
DBGPRINTF("%s found, resuming.\n", pData->host);
pData->f_addr = res;
- pData->pSockArray = net.create_udp_socket((uchar*)pData->host, NULL, 0);
+ pData->pSockArray = net.create_udp_socket((uchar*)pData->host, NULL, 0, 0);
finalize_it:
if(iRet != RS_RET_OK) {
diff --git a/runtime/net.c b/runtime/net.c
index 1a8f2438..8f5ad3d2 100644
--- a/runtime/net.c
+++ b/runtime/net.c
@@ -1269,12 +1269,16 @@ void closeUDPListenSockets(int *pSockArr)
* hostname and/or pszPort may be NULL, but not both!
* bIsServer indicates if a server socket should be created
* 1 - server, 0 - client
+ * param rcvbuf indicates desired rcvbuf size; 0 means OS default
*/
-int *create_udp_socket(uchar *hostname, uchar *pszPort, int bIsServer)
+int *create_udp_socket(uchar *hostname, uchar *pszPort, int bIsServer, int rcvbuf)
{
struct addrinfo hints, *res, *r;
int error, maxs, *s, *socks, on = 1;
int sockflags;
+ int actrcvbuf;
+ socklen_t optlen;
+ char errStr[1024];
assert(!((pszPort == NULL) && (hostname == NULL)));
memset(&hints, 0, sizeof(hints));
@@ -1377,6 +1381,35 @@ int *create_udp_socket(uchar *hostname, uchar *pszPort, int bIsServer)
continue;
}
+ if(rcvbuf != 0) {
+# if defined(SO_RCVBUFFORCE)
+ if(setsockopt(*s, SOL_SOCKET, SO_RCVBUFFORCE, &rcvbuf, sizeof(rcvbuf)) < 0)
+# endif
+ {
+ /* if we fail, try to do it the regular way. Experiments show that at
+ * least some platforms do not return an error here, but silently set
+ * it to the max permitted value. So we do our error check a bit
+ * differently by querying the size below.
+ */
+ setsockopt(*s, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
+ }
+ }
+
+ if(Debug || rcvbuf != 0) {
+ optlen = sizeof(actrcvbuf);
+ if(getsockopt(*s, SOL_SOCKET, SO_RCVBUF, &actrcvbuf, &optlen) == 0) {
+ dbgprintf("socket %d, actual rcvbuf size %d\n", *s, actrcvbuf);
+ if(rcvbuf != 0 && actrcvbuf/2 != rcvbuf) {
+ errmsg.LogError(errno, NO_ERRCODE,
+ "cannot set rcvbuf size %d for socket %d, value now is %d",
+ rcvbuf, *s, actrcvbuf/2);
+ }
+ } else {
+ dbgprintf("could not obtain rcvbuf size for socket %d: %s\n",
+ *s, rs_strerror_r(errno, errStr, sizeof(errStr)));
+ }
+ }
+
if(bIsServer) {
/* rgerhards, 2007-06-22: if we run on a kernel that does not support
* the IPV6_V6ONLY socket option, we need to use a work-around. On such
diff --git a/runtime/net.h b/runtime/net.h
index 1b41c81c..36f9eb41 100644
--- a/runtime/net.h
+++ b/runtime/net.h
@@ -137,7 +137,7 @@ BEGINinterface(net) /* name must also be changed in ENDinterface macro! */
void (*PrintAllowedSenders)(int iListToPrint);
void (*clearAllowedSenders)(uchar*);
void (*debugListenInfo)(int fd, char *type);
- int *(*create_udp_socket)(uchar *hostname, uchar *LogPort, int bIsServer);
+ int *(*create_udp_socket)(uchar *hostname, uchar *LogPort, int bIsServer, int rcvbuf);
void (*closeUDPListenSockets)(int *finet);
int (*isAllowedSender)(uchar *pszType, struct sockaddr *pFrom, const char *pszFromHost); /* deprecated! */
rsRetVal (*getLocalHostname)(uchar**);
diff --git a/tools/omfwd.c b/tools/omfwd.c
index 129392d2..a7f8bf7b 100644
--- a/tools/omfwd.c
+++ b/tools/omfwd.c
@@ -576,7 +576,7 @@ static rsRetVal doTryResume(instanceData *pData)
pData->f_addr = res;
pData->bIsConnected = 1;
if(pData->pSockArray == NULL) {
- pData->pSockArray = net.create_udp_socket((uchar*)pData->target, NULL, 0);
+ pData->pSockArray = net.create_udp_socket((uchar*)pData->target, NULL, 0, 0);
}
} else {
CHKiRet(TCPSendInit((void*)pData));