Created
December 4, 2014 04:49
-
-
Save Roguelazer/59d253a19f0e335a76dc to your computer and use it in GitHub Desktop.
limit_nsca_child_processes.diff
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- nsca~/src/nsca.c 2014-12-03 20:44:00.000000000 -0800 | |
+++ nsca/src/nsca.c 2014-12-03 20:46:29.098392130 -0800 | |
@@ -21,6 +21,9 @@ | |
#include "../include/utils.h" | |
#include "../include/nsca.h" | |
+#include <stdio.h> | |
+#include <errno.h> | |
+ | |
static int server_port=DEFAULT_SERVER_PORT; | |
static char server_address[16]="0.0.0.0"; | |
@@ -66,6 +69,9 @@ | |
int nrhand=0; | |
int nwhand=0; | |
int npfds=0; | |
+ | |
+int live_children=0; | |
+int max_children=100; | |
#ifdef HAVE_LIBWRAP | |
int allow_severity=LOG_INFO; | |
@@ -457,6 +463,9 @@ | |
else if(!strcmp(varname,"pid_file")) | |
pid_file=strdup(varvalue); | |
+ else if(!strcmp(varname,"max_children")) | |
+ max_children = strtoul(varvalue, NULL, 10); | |
+ | |
else{ | |
syslog(LOG_ERR,"Unknown option specified in config file '%s' - Line %d\n",filename,line); | |
@@ -475,7 +484,9 @@ | |
/* get rid of all the children we can... */ | |
static void reap_children(int sig){ | |
- while(waitpid(-1,NULL,WNOHANG)>0); | |
+ while(waitpid(-1,NULL,WNOHANG)>0) { | |
+ live_children--; | |
+ } | |
return; | |
} | |
@@ -770,6 +781,11 @@ | |
/* wait for a connection request */ | |
while(1){ | |
+ if(mode==MULTI_PROCESS_DAEMON) { | |
+ /* Check for children every loop interation */ | |
+ reap_children(0); | |
+ } | |
+ | |
/* we got a live one... */ | |
if((new_sd=accept(sock,0,0))>=0) | |
break; | |
@@ -820,22 +836,6 @@ | |
} | |
#endif | |
- | |
- /* fork() if we have to... */ | |
- if(mode==MULTI_PROCESS_DAEMON){ | |
- | |
- pid=fork(); | |
- if(pid){ | |
- /* parent doesn't need the new connection */ | |
- close(new_sd); | |
- return; | |
- } | |
- else{ | |
- /* child does not need to listen for connections */ | |
- close(sock); | |
- } | |
- } | |
- | |
/* find out who just connected... */ | |
addrlen=sizeof(addr); | |
rc=getpeername(new_sd,&addr,&addrlen); | |
@@ -853,17 +853,44 @@ | |
nptr=(struct sockaddr_in *)&addr; | |
+ | |
+ /* fork() if we have to... */ | |
+ if(mode==MULTI_PROCESS_DAEMON){ | |
+ if (live_children >= max_children) { | |
+ syslog(LOG_ERR, "already have %d children, refusing connect from %s", live_children, inet_ntoa(nptr->sin_addr)); | |
+ close(new_sd); | |
+ return; | |
+ } | |
+ | |
+ pid=fork(); | |
+ if(pid > 0){ | |
+ live_children++; | |
+ /* parent doesn't need the new connection */ | |
+ close(new_sd); | |
+ return; | |
+ } | |
+ else if (pid == 0){ | |
+ /* child does not need to listen for connections */ | |
+ close(sock); | |
+ } | |
+ } else { | |
+ syslog(LOG_ERR, "fork failed! errno %d, %s", errno, strerror(errno)); | |
+ close(new_sd); | |
+ return; | |
+ } | |
+ | |
/* log info to syslog facility */ | |
if(debug==TRUE) | |
syslog(LOG_DEBUG,"Connection from %s port %d",inet_ntoa(nptr->sin_addr),nptr->sin_port); | |
/* handle the connection */ | |
- if(mode==SINGLE_PROCESS_DAEMON) | |
+ if(mode==SINGLE_PROCESS_DAEMON) { | |
/* mark the connection as ready to be handled */ | |
register_write_handler(new_sd, handle_connection, NULL); | |
- else | |
+ } else { | |
/* handle the client connection */ | |
handle_connection(new_sd, NULL); | |
+ } | |
return; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment