diff options
-rw-r--r-- | net.c | 66 | ||||
-rw-r--r-- | net.h | 3 | ||||
-rw-r--r-- | omfwd.c | 44 | ||||
-rw-r--r-- | syslogd.c | 6 |
4 files changed, 84 insertions, 35 deletions
@@ -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++; @@ -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) */ @@ -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 @@ -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 |