summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net.c66
-rw-r--r--net.h3
-rw-r--r--omfwd.c44
-rw-r--r--syslogd.c6
4 files changed, 84 insertions, 35 deletions
diff --git a/net.c b/net.c
index 7b52bb98..fdeb71da 100644
--- a/net.c
+++ b/net.c
@@ -840,34 +840,42 @@ finalize_it:
/* closes the UDP listen sockets (if they exist) and frees
* all dynamically assigned memory.
*/
-void closeUDPListenSockets()
+void closeUDPListenSockets(int *pSockArr)
{
register int i;
dbgprintf("in closeUDPListenSockets()\n");
- if(finet != NULL) {
- for (i = 0; i < *finet; i++)
- close(finet[i+1]);
- free(finet);
- finet = NULL;
+ assert(pSockArr != NULL);
+ if(pSockArr != NULL) {
+ for (i = 0; i < *pSockArr; i++)
+ close(pSockArr[i+1]);
+ free(pSockArr);
+ pSockArr = NULL;
}
}
/* creates the UDP listen sockets
+ * hostname and/or LogPort may be NULL, but not both!
+ * bIsServer indicates if a server socket should be created
+ * 1 - server, 0 - client
*/
-int *create_udp_socket(uchar *LogPort)
+int *create_udp_socket(uchar *hostname, uchar *LogPort, int bIsServer)
{
struct addrinfo hints, *res, *r;
int error, maxs, *s, *socks, on = 1;
int sockflags;
- assert(LogPort != NULL);
+dbgprintf("create_udp_socket('%s', '%s', %d);\n", hostname, LogPort, bIsServer);
+ assert(!((LogPort == NULL) && (hostname == NULL)));
memset(&hints, 0, sizeof(hints));
- hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
+ if(bIsServer)
+ hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
+ else
+ hints.ai_flags = AI_NUMERICSERV;
hints.ai_family = family;
hints.ai_socktype = SOCK_DGRAM;
- error = getaddrinfo(NULL, (char*) LogPort, &hints, &res);
+ error = getaddrinfo((char*) hostname, (char*) LogPort, &hints, &res);
if(error) {
logerror((char*) gai_strerror(error));
logerror("UDP message reception disabled due to error logged in last message.\n");
@@ -891,7 +899,7 @@ int *create_udp_socket(uchar *LogPort)
if (*s < 0) {
if(!(r->ai_family == PF_INET6 && errno == EAFNOSUPPORT))
logerror("create_udp_socket(), socket");
- /* it is debatable if PF_INET with EAFNOSUPPORT should
+ /* it is debateble if PF_INET with EAFNOSUPPORT should
* also be ignored...
*/
continue;
@@ -960,23 +968,25 @@ int *create_udp_socket(uchar *LogPort)
continue;
}
- /* 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
- * socket can not listen on the same port as an IPv6 socket. The only
- * workaround is to ignore the "socket in use" error. This is what we
- * do if we have to.
- */
- if( (bind(*s, r->ai_addr, r->ai_addrlen) < 0)
-# ifndef IPV6_V6ONLY
- && (errno != EADDRINUSE)
-# endif
- ) {
- logerror("bind");
- close(*s);
- *s = -1;
- continue;
- }
+ 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
+ * systems the IPv6 socket does also accept IPv4 sockets. So an IPv4
+ * socket can not listen on the same port as an IPv6 socket. The only
+ * workaround is to ignore the "socket in use" error. This is what we
+ * do if we have to.
+ */
+ if( (bind(*s, r->ai_addr, r->ai_addrlen) < 0)
+ # ifndef IPV6_V6ONLY
+ && (errno != EADDRINUSE)
+ # endif
+ ) {
+ logerror("bind");
+ close(*s);
+ *s = -1;
+ continue;
+ }
+ }
(*socks)++;
s++;
diff --git a/net.h b/net.h
index 6c50f5e9..2b7a3a73 100644
--- a/net.h
+++ b/net.h
@@ -76,7 +76,8 @@ rsRetVal addAllowedSenderLine(char* pName, uchar** ppRestOfConfLine);
void PrintAllowedSenders(int iListToPrint);
void clearAllowedSenders ();
void debugListenInfo(int fd, char *type);
-int *create_udp_socket(uchar *LogPort);
+int *create_udp_socket(uchar *hostname, uchar *LogPort, int bIsServer);
+void closeUDPListenSockets(int *finet);
extern int ACLAddHostnameOnFail; /* add hostname to acl when DNS resolving has failed */
extern int ACLDontResolve; /* add hostname to acl instead of resolving it to IP(s) */
diff --git a/omfwd.c b/omfwd.c
index ba0a118a..e24bc969 100644
--- a/omfwd.c
+++ b/omfwd.c
@@ -91,6 +91,7 @@ DEF_OMOD_STATIC_DATA
typedef struct _instanceData {
char f_hname[MAXHOSTNAMELEN+1];
short sock; /* file descriptor */
+ int *pSockArray; /* sockets to use for UDP */
enum { /* TODO: we shoud revisit these definitions */
eDestFORW,
eDestFORW_SUSP,
@@ -184,7 +185,7 @@ static rsRetVal UDPSend(instanceData *pData, char *msg, size_t len)
unsigned lsent = 0;
int bSendSuccess;
- if(finet != NULL) {
+ if(pData->pSockArray != NULL) {
/* we need to track if we have success sending to the remote
* peer. Success is indicated by at least one sendto() call
* succeeding. We track this be bSendSuccess. We can not simply
@@ -195,8 +196,8 @@ static rsRetVal UDPSend(instanceData *pData, char *msg, size_t len)
*/
bSendSuccess = FALSE;
for (r = pData->f_addr; r; r = r->ai_next) {
- for (i = 0; i < *finet; i++) {
- lsent = sendto(finet[i+1], msg, len, 0, r->ai_addr, r->ai_addrlen);
+ for (i = 0; i < *pData->pSockArray; i++) {
+ lsent = sendto(pData->pSockArray[i+1], msg, len, 0, r->ai_addr, r->ai_addrlen);
if (lsent == len) {
bSendSuccess = TRUE;
break;
@@ -220,6 +221,31 @@ static rsRetVal UDPSend(instanceData *pData, char *msg, size_t len)
return iRet;
}
+/* Initialize UDP sockets (for sender)
+ * This is done once per selector line, if not yet initialized.
+ * TODO: Ipv4/v6 settings!
+ */
+static rsRetVal UDPSendCreateSocket(int **ppSockArray)
+{
+ DEFiRet;
+
+ assert(ppSockArray != NULL);
+#if 0
+dbgprintf("ppSockArray %lx, %lx\n", ppSockArray, *ppSockArray);
+ ppSockArray = (int *) malloc(sizeof(int) * 2);
+dbgprintf("ppSockArray %lx, %lx, %lx\n", ppSockArray, *ppSockArray, *ppSockArray[0]);
+ *ppSockArray[0] = 1;
+dbgprintf("ppSockArray %lx, %lx, %lx\n", ppSockArray, *ppSockArray, *ppSockArray[0]);
+ (*ppSockArray)[1] = socket(PF_INET, SOCK_DGRAM, 0);
+dbgprintf("UDPSendCreateSocket returns %d\n", *ppSockArray[1]);
+#endif
+
+// *ppSockArray = create_udp_socket(pData->f_hname, NULL, 0));
+
+ return iRet;
+}
+
+
/* CODE FOR SENDING TCP MESSAGES */
/* Initialize TCP sockets (for sender)
@@ -753,6 +779,18 @@ CODESTARTdoAction
case eDestFORW:
dbgprintf(" %s:%s/%s\n", pData->f_hname, getFwdSyslogPt(pData),
pData->protocol == FORW_UDP ? "udp" : "tcp");
+ /* with UDP, check if the socket is there and, if not, alloc
+ * it. TODO: there should be a better place for that code.
+ * rgerhards, 2007-12-26
+ */
+ if(pData->protocol == FORW_UDP) {
+dbgprintf("We have a udp selector, send socket 0x%lx\n", (unsigned long) pData->pSockArray);
+ if(pData->pSockArray == NULL) {
+dbgprintf("UDP send socket not yet initialized, doing it now\n");
+ pData->pSockArray = create_udp_socket((uchar*)pData->f_hname, NULL, 0);
+ // CHKiRet(UDPSendCreateSocket(&pData->pSockArray));
+ }
+ }
if ( 0) // TODO: think about this strcmp(getHOSTNAME(f->f_pMsg), LocalHostName) && NoHops )
/* what we need to do is get the hostname as an additonal string (during parseSe..). Then,
* we can compare that string to LocalHostName. That way, we do not need to access the
diff --git a/syslogd.c b/syslogd.c
index cc8afbc5..e51841ae 100644
--- a/syslogd.c
+++ b/syslogd.c
@@ -2775,7 +2775,7 @@ die(int sig)
/* now clean up the listener part */
#ifdef SYSLOG_INET
/* Close the UDP inet socket. */
- closeUDPListenSockets();
+ closeUDPListenSockets(finet);
#endif
/* rger 2005-02-22
@@ -3580,12 +3580,12 @@ init(void)
*/
if(Forwarding || AcceptRemote) {
if (finet == NULL) {
- if((finet = create_udp_socket((uchar*)LogPort)) != NULL)
+ if((finet = create_udp_socket(NULL, (uchar*)LogPort, 1)) != NULL)
dbgprintf("Opened %d syslog UDP port(s).\n", *finet);
}
} else {
/* this case can happen during HUP processing. */
- closeUDPListenSockets();
+ closeUDPListenSockets(finet);
}
#endif