File rsyslog-8.17.x-enable-IPFREEBIND_socket_option.patch of Package rsyslog.6132
From a6fa31c2c42a5162a25c90f58cce2247d6f3b464 Mon Sep 17 00:00:00 2001
From: Marius Tomaschewski <mt@suse.de>
Date: Mon, 14 Mar 2016 12:28:54 +0100
Subject: [PATCH 1/4] imudp: Use IP_FREEBIND option for UDP sockets
Rather a proof of concept patch (originally by Marius) that allows
rsyslog to bind UDP ports even w/out specific interface being up at the
moment.
---
runtime/net.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/runtime/net.c b/runtime/net.c
index 01129d6..f65f4d9 100644
--- a/runtime/net.c
+++ b/runtime/net.c
@@ -1348,6 +1348,9 @@ int *create_udp_socket(uchar *hostname, uchar *pszPort, int bIsServer, int rcvbu
}
if(bIsServer) {
+ if (setsockopt(*s, IPPROTO_IP, IP_FREEBIND, &on, sizeof(on)) < 0)
+ dbgprintf("unable to enable free IP bind socket option");
+
/* 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
* systems the IPv6 socket does also accept IPv4 sockets. So an IPv4
--
2.6.2
From 5f12c9b57e208eb1d6271aecf8dee8af310762db Mon Sep 17 00:00:00 2001
From: Nirmoy Das <ndas@suse.de>
Date: Tue, 22 Mar 2016 15:42:53 +0100
Subject: [PATCH 2/4] imudp: add config option for IP_FREEBIND socket option
ipfreebind config option by default enables IP_FREEBIND socket
option with warn message on success.
---
plugins/imudp/imudp.c | 10 +++++++++-
plugins/omudpspoof/omudpspoof.c | 2 +-
runtime/net.c | 17 +++++++++++++----
runtime/net.h | 2 +-
tools/omfwd.c | 2 +-
5 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/plugins/imudp/imudp.c b/plugins/imudp/imudp.c
index 82a4a34..5507787 100644
--- a/plugins/imudp/imudp.c
+++ b/plugins/imudp/imudp.c
@@ -116,6 +116,10 @@ struct instanceConf_s {
int ratelimitInterval;
int ratelimitBurst;
int rcvbuf; /* 0 means: do not set, keep OS default */
+ /* 0 means: IP_FREEBIND is disabled
+ 1 means: IP_FREEBIND enabled + warning disabled
+ 1+ means: IP+FREEBIND enabled + warning enabled */
+ int ipfreebind;
struct instanceConf_s *next;
sbool bAppendPortToInpname;
};
@@ -179,6 +183,7 @@ static struct cnfparamdescr inppdescr[] = {
{ "ratelimit.interval", eCmdHdlrInt, 0 },
{ "ratelimit.burst", eCmdHdlrInt, 0 },
{ "rcvbufsize", eCmdHdlrSize, 0 },
+ { "ipfreebind", eCmdHdlrInt, 0 },
{ "ruleset", eCmdHdlrString, 0 }
};
static struct cnfparamblk inppblk =
@@ -209,6 +214,7 @@ createInstance(instanceConf_t **pinst)
inst->ratelimitBurst = 10000; /* arbitrary high limit */
inst->ratelimitInterval = 0; /* off */
inst->rcvbuf = 0;
+ inst->ipfreebind = 2; /* IP_FREEBIND is enabled with warning message */
inst->dfltTZ = NULL;
/* node created, let's add to config */
@@ -285,7 +291,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, inst->rcvbuf);
+ newSocks = net.create_udp_socket(bindAddr, port, 1, inst->rcvbuf, inst->ipfreebind);
if(newSocks != NULL) {
/* we now need to add the new sockets to the existing set */
/* ready to copy */
@@ -933,6 +939,8 @@ createListner(es_str_t *port, struct cnfparamvals *pvals)
inst->ratelimitInterval = (int) pvals[i].val.d.n;
} else if(!strcmp(inppblk.descr[i].name, "rcvbufsize")) {
inst->rcvbuf = (int) pvals[i].val.d.n;
+ } else if(!strcmp(inppblk.descr[i].name, "ipfreebind")) {
+ inst->ipfreebind = (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 5bcd91c..4176cf0 100644
--- a/plugins/omudpspoof/omudpspoof.c
+++ b/plugins/omudpspoof/omudpspoof.c
@@ -573,7 +573,7 @@ static rsRetVal doTryResume(wrkrInstanceData_t *pWrkrData)
}
DBGPRINTF("%s found, resuming.\n", pData->host);
pWrkrData->f_addr = res;
- pWrkrData->pSockArray = net.create_udp_socket((uchar*)pData->host, NULL, 0, 0);
+ pWrkrData->pSockArray = net.create_udp_socket((uchar*)pData->host, NULL, 0, 0, 0);
finalize_it:
if(iRet != RS_RET_OK) {
diff --git a/runtime/net.c b/runtime/net.c
index f65f4d9..e773a7a 100644
--- a/runtime/net.c
+++ b/runtime/net.c
@@ -1208,7 +1208,7 @@ void closeUDPListenSockets(int *pSockArr)
* 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 rcvbuf)
+int *create_udp_socket(uchar *hostname, uchar *pszPort, int bIsServer, int rcvbuf, int ipfreebind)
{
struct addrinfo hints, *res, *r;
int error, maxs, *s, *socks, on = 1;
@@ -1348,8 +1348,6 @@ int *create_udp_socket(uchar *hostname, uchar *pszPort, int bIsServer, int rcvbu
}
if(bIsServer) {
- if (setsockopt(*s, IPPROTO_IP, IP_FREEBIND, &on, sizeof(on)) < 0)
- dbgprintf("unable to enable free IP bind socket option");
/* 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
@@ -1363,7 +1361,18 @@ int *create_udp_socket(uchar *hostname, uchar *pszPort, int bIsServer, int rcvbu
&& (errno != EADDRINUSE)
# endif
) {
- errmsg.LogError(errno, NO_ERRCODE, "bind");
+ if (errno == EADDRNOTAVAIL && ipfreebind) {
+ if (setsockopt(*s, IPPROTO_IP, IP_FREEBIND, &on, sizeof(on)) < 0) {
+ errmsg.LogError(errno, NO_ERRCODE, "setsockopt(IP_FREEBIND)");
+ }
+ else if (bind(*s, r->ai_addr, r->ai_addrlen) < 0) {
+ errmsg.LogError(errno, NO_ERRCODE, "bind with IP_FREEBIND");
+ } else {
+ if (ipfreebind > 1)
+ errmsg.LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "bound address %s IP free", hostname);
+ continue;
+ }
+ }
close(*s);
*s = -1;
continue;
diff --git a/runtime/net.h b/runtime/net.h
index d7a7b51..b664fb4 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 rcvbuf);
+ int *(*create_udp_socket)(uchar *hostname, uchar *LogPort, int bIsServer, int rcvbuf, int ipfreebind);
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 f2a721c..29d7f14 100644
--- a/tools/omfwd.c
+++ b/tools/omfwd.c
@@ -760,7 +760,7 @@ static rsRetVal doTryResume(wrkrInstanceData_t *pWrkrData)
pWrkrData->f_addr = res;
pWrkrData->bIsConnected = 1;
if(pWrkrData->pSockArray == NULL) {
- pWrkrData->pSockArray = net.create_udp_socket((uchar*)pData->target, NULL, 0, 0);
+ pWrkrData->pSockArray = net.create_udp_socket((uchar*)pData->target, NULL, 0, 0, 0);
}
} else {
CHKiRet(TCPSendInit((void*)pWrkrData));
--
2.6.2
From 3e3bd32f10e17dd66b64c2667ea2e49d65afca6f Mon Sep 17 00:00:00 2001
From: Nirmoy Das <ndas@suse.de>
Date: Wed, 23 Mar 2016 10:46:55 +0100
Subject: [PATCH 3/4] cleanup/beautify, removed numerical with defines
---
plugins/imudp/imudp.c | 2 +-
runtime/net.c | 4 ++--
runtime/net.h | 5 +++++
3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/plugins/imudp/imudp.c b/plugins/imudp/imudp.c
index 5507787..37d8aad 100644
--- a/plugins/imudp/imudp.c
+++ b/plugins/imudp/imudp.c
@@ -214,7 +214,7 @@ createInstance(instanceConf_t **pinst)
inst->ratelimitBurst = 10000; /* arbitrary high limit */
inst->ratelimitInterval = 0; /* off */
inst->rcvbuf = 0;
- inst->ipfreebind = 2; /* IP_FREEBIND is enabled with warning message */
+ inst->ipfreebind = IPFREEBIND_ENABLED_WITH_LOG;
inst->dfltTZ = NULL;
/* node created, let's add to config */
diff --git a/runtime/net.c b/runtime/net.c
index e773a7a..4cbedba 100644
--- a/runtime/net.c
+++ b/runtime/net.c
@@ -1361,14 +1361,14 @@ int *create_udp_socket(uchar *hostname, uchar *pszPort, int bIsServer, int rcvbu
&& (errno != EADDRINUSE)
# endif
) {
- if (errno == EADDRNOTAVAIL && ipfreebind) {
+ if (errno == EADDRNOTAVAIL && ipfreebind != IPFREEBIND_DISABLED) {
if (setsockopt(*s, IPPROTO_IP, IP_FREEBIND, &on, sizeof(on)) < 0) {
errmsg.LogError(errno, NO_ERRCODE, "setsockopt(IP_FREEBIND)");
}
else if (bind(*s, r->ai_addr, r->ai_addrlen) < 0) {
errmsg.LogError(errno, NO_ERRCODE, "bind with IP_FREEBIND");
} else {
- if (ipfreebind > 1)
+ if (ipfreebind >= IPFREEBIND_ENABLED_WITH_LOG)
errmsg.LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "bound address %s IP free", hostname);
continue;
}
diff --git a/runtime/net.h b/runtime/net.h
index b664fb4..b2f49e3 100644
--- a/runtime/net.h
+++ b/runtime/net.h
@@ -39,6 +39,11 @@ typedef enum _TCPFRAMINGMODE {
#define ADDR_NAME 0x01 /* address is hostname wildcard) */
#define ADDR_PRI6 0x02 /* use IPv6 address prior to IPv4 when resolving */
+/* defines for IP_FREEBIND, currently being used in imudp */
+#define IPFREEBIND_DISABLED 0x00 /* don't enable IP_FREEBIND in sock option */
+#define IPFREEBIND_ENABLED_NO_LOG 0x01 /* enable IP_FREEBIND but no warn on success */
+#define IPFREEBIND_ENABLED_WITH_LOG 0x02 /* enable IP_FREEBIND and warn on success */
+
#ifdef OS_BSD
# ifndef _KERNEL
# define s6_addr32 __u6_addr.__u6_addr32
--
2.6.2
From 66ce7eb11351eb9ece917e50b4218e4c55ca15e9 Mon Sep 17 00:00:00 2001
From: Nirmoy Das <ndas@suse.de>
Date: Tue, 29 Mar 2016 17:16:01 +0200
Subject: [PATCH 4/4] portability: define IP_FREEBIND if it is not already
defined.
---
runtime/net.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/runtime/net.h b/runtime/net.h
index b2f49e3..6809570 100644
--- a/runtime/net.h
+++ b/runtime/net.h
@@ -39,6 +39,10 @@ typedef enum _TCPFRAMINGMODE {
#define ADDR_NAME 0x01 /* address is hostname wildcard) */
#define ADDR_PRI6 0x02 /* use IPv6 address prior to IPv4 when resolving */
+/* portability: incase IP_FREEBIND is not defined */
+#ifndef IP_FREEBIND
+#define IP_FREEBIND 0
+#endif
/* defines for IP_FREEBIND, currently being used in imudp */
#define IPFREEBIND_DISABLED 0x00 /* don't enable IP_FREEBIND in sock option */
#define IPFREEBIND_ENABLED_NO_LOG 0x01 /* enable IP_FREEBIND but no warn on success */
--
2.6.2