More tweaks. Added SIGCHLD handler and code to try to restart the TCP server if it dies for whatever reason.

git-svn-id: file:///home/mbr/svn/fwknop/trunk@221 510a4753-2344-4c79-9c09-4d669213fbeb
This commit is contained in:
Damien Stuart 2010-06-21 03:24:27 +00:00
parent 315f3e6778
commit 68b171ddd4
6 changed files with 83 additions and 15 deletions

View File

@ -14,7 +14,6 @@
#include <sys/wait.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/types.h>
#include <signal.h>
#include "extcmd.h"
@ -49,8 +48,6 @@ set_nonblock(int fd)
int
run_extcmd(char *cmd, char *so_buf, char *se_buf, size_t so_buf_sz, size_t se_buf_sz, int *status)
{
//--DSS temp
//return(0);
pid_t pid;
struct timeval tv;

View File

@ -258,10 +258,10 @@ main(int argc, char **argv)
else
{
res = run_tcp_server(&opts);
if(res < 0)
log_msg(LOG_WARNING, "Fork error from run_tcp_serv.");
else
opts.tcp_server_pid = res;
//if(res < 0)
// log_msg(LOG_WARNING, "Fork error from run_tcp_serv.");
//else
// opts.tcp_server_pid = res;
}
}
@ -273,25 +273,25 @@ main(int argc, char **argv)
got_signal = 0;
if(got_sighup)
{
log_msg(LOG_WARNING|LOG_STDERR, "Got SIGHUP. Re-reading configs.");
log_msg(LOG_WARNING, "Got SIGHUP. Re-reading configs.");
free_configs(&opts);
got_sighup = 0;
}
else if(got_sigint)
{
log_msg(LOG_WARNING|LOG_STDERR, "Got SIGINT. Exiting...");
log_msg(LOG_WARNING, "Got SIGINT. Exiting...");
got_sigint = 0;
break;
}
else if(got_sigterm)
{
log_msg(LOG_WARNING|LOG_STDERR, "Got SIGTERM. Exiting...");
log_msg(LOG_WARNING, "Got SIGTERM. Exiting...");
got_sigterm = 0;
break;
}
else
{
log_msg(LOG_WARNING|LOG_STDERR,
log_msg(LOG_WARNING,
"Got signal %i. No defined action but to exit.", last_sig);
break;
}
@ -312,6 +312,25 @@ main(int argc, char **argv)
}
}
log_msg(LOG_INFO, "Shutting Down fwknopd.");
/* Kill the TCP server (if we have one running).
*/
if(opts.tcp_server_pid > 0)
{
log_msg(LOG_INFO, "Killing the TCP server (pid=%i)",
opts.tcp_server_pid);
kill(opts.tcp_server_pid, SIGTERM);
/* --DSS XXX: This seems to be necessary if the tcp server
* was restarted byt this program. We need to
* investigate an fix this. For now, this works
* (it is kludgy, but does no harm afaik).
*/
kill(opts.tcp_server_pid, SIGKILL);
}
/* Other cleanup.
*/
fw_cleanup();

View File

@ -24,6 +24,8 @@
*****************************************************************************
*/
#include <pcap.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "fwknopd_common.h"
#include "pcap_capture.h"
@ -33,6 +35,7 @@
#include "sig_handler.h"
#include "fw_util.h"
#include "log_msg.h"
#include "sig_handler.h"
/* The pcap capture routine.
*/
@ -47,6 +50,8 @@ pcap_capture(fko_srv_options_t *opts)
int pcap_errcnt = 0;
int pending_break = 0;
int promisc = 1;
int status;
pid_t child_pid;
/* Set non-promiscuous mode only of the ENABLE_PCAP_PROMISC is
* explicitly set to 'N'.
@ -143,12 +148,13 @@ pcap_capture(fko_srv_options_t *opts)
*/
while(1)
{
/* Any signal except USR1 and USR2 mean break the loop.
/* Any signal except USR1, USR2, and SIGCHLD mean break the loop.
*/
if((got_signal != 0) && ((got_sigusr1 + got_sigusr2) == 0))
if((got_signal != 0) && ((got_sigusr1 + got_sigusr2 + got_sigchld) == 0))
{
pcap_breakloop(pcap);
pending_break = 1;
signal(SIGCHLD, SIG_IGN);
}
res = pcap_dispatch(pcap, 1, (pcap_handler)&process_packet, (unsigned char *)opts);
@ -223,6 +229,38 @@ pcap_capture(fko_srv_options_t *opts)
*/
check_firewall_rules(opts);
/* If we got a SIGCHLD and it was the tcp server, then handle it here.
*/
if(got_sigchld && pending_break != 1)
{
if(opts->tcp_server_pid > 0)
{
child_pid = waitpid(0, &status, WNOHANG);
if(child_pid == opts->tcp_server_pid)
{
if(WIFSIGNALED(status))
log_msg(LOG_WARNING, "TCP server got signal: %i", WTERMSIG(status));
log_msg(LOG_WARNING, "TCP server exited with status of %i. Attempting restart.",
WEXITSTATUS(status));
opts->tcp_server_pid = 0;
/* Attempt to restart tcp server ? */
usleep(1000000);
res = run_tcp_server(opts);
//if(res < 0)
// log_msg(LOG_WARNING, "Fork error from run_tcp_serv.");
//else
// opts->tcp_server_pid = res;
}
}
got_sigchld = 0;
got_signal = 0;
}
usleep(10000);
}
#endif /* HAVE_LIBPCAP */

View File

@ -34,6 +34,7 @@ sig_atomic_t got_sigint = 0; /* SIGINT flag */
sig_atomic_t got_sigterm = 0; /* SIGTERM flag */
sig_atomic_t got_sigusr1 = 0; /* SIGUSR1 flag */
sig_atomic_t got_sigusr2 = 0; /* SIGUSR2 flag */
sig_atomic_t got_sigchld = 0; /* SIGCHLD flag */
/* SIGHUP Handler
*/
@ -58,6 +59,9 @@ sig_handler(int sig)
case SIGUSR2:
got_sigusr2 = 1;
return;
case SIGCHLD:
got_sigchld = 1;
return;
}
}
@ -109,6 +113,12 @@ set_sig_handlers(void)
err++;
}
if(signal(SIGCHLD, sig_handler) == SIG_ERR)
{
log_msg(LOG_ERR|LOG_STDERR, "* Error setting SIGUSR2 handler");
err++;
}
return(err);
}

View File

@ -35,6 +35,7 @@ extern sig_atomic_t got_sigint;
extern sig_atomic_t got_sigterm;
extern sig_atomic_t got_sigusr1;
extern sig_atomic_t got_sigusr2;
extern sig_atomic_t got_sigchld;
void sig_handler(int sig);

View File

@ -50,7 +50,7 @@ run_tcp_server(fko_srv_options_t *opts)
unsigned short port = atoi(opts->config[CONF_TCPSERV_PORT]);
log_msg(LOG_INFO, "Kicking off TCP server for port %i", port);
log_msg(LOG_INFO, "Kicking off TCP server for port %i)", port);
/* Fork off a child process to run the command and provide its outputs.
*/
@ -60,7 +60,10 @@ run_tcp_server(fko_srv_options_t *opts)
* in either case we simply return that value to the caller.
*/
if (pid != 0)
{
opts->tcp_server_pid = pid;
return(pid);
}
/* We are the child, so let's make a TCP server */
@ -111,7 +114,7 @@ run_tcp_server(fko_srv_options_t *opts)
exit(EXIT_FAILURE); /* Should this be fatal? */
}
if(opts->verbose > 1)
if(opts->verbose)
{
memset(sipbuf, 0x0, MAX_IP_STR_LEN);
inet_ntop(AF_INET, &(caddr.sin_addr.s_addr), sipbuf, MAX_IP_STR_LEN);