Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
added daemon and pidfile support
  • Loading branch information
remcovanmook committed Jun 23, 2018
commit 9b0dc236074448af30aa150aea441bab59435619
120 changes: 99 additions & 21 deletions bird-rtrlib-cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
#include <string.h>
#include <syslog.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "bird.h"
#include "cli.h"
Expand All @@ -47,6 +50,10 @@ static size_t bird_command_length = -1;
static char *bird_add_roa_table_arg = "";
// Main configuration.
static struct config config;
// for daemon loop
static int time_to_die = 0;
// fopr pidfile
static int pid_fd = -1;

/**
* Handle SIGPIPE on bird_socket, write error log entry
Expand All @@ -57,6 +64,33 @@ void sigpipe_handler(int signum)
syslog(LOG_ERR, "Caught SIGPIPE %d.", signum);
}

void sigkill_handler(int signum)
{
syslog(LOG_INFO, "Got kill signal, cleaning up and exiting.");
/* Unlock and close lockfile */
if (pid_fd != -1) {
lockf(pid_fd, F_ULOCK, 0);
close(pid_fd);
}
/* Try to delete lockfile */
if (config.pidfile != NULL) {
unlink(config.pidfile);
}
time_to_die++;
}

void create_pidfile()
{
char str[256];
pid_fd = open(config.pidfile, O_RDWR|O_CREAT, 0640);
if (pid_fd < 0)
exit(EXIT_FAILURE);
if (lockf(pid_fd, F_TLOCK, 0) < 0)
exit(EXIT_FAILURE);
sprintf(str,"%d\n", getpid());
write(pid_fd, str, strlen(str));
}

/**
* Performs cleanup on resources allocated by `init()`.
*/
Expand Down Expand Up @@ -155,16 +189,11 @@ static void pfx_update_callback(struct pfx_table *table,
if (config.ip_version)
{
int prefix_allowed = 0;
if (strchr(ip_addr_str,'.') != NULL)
{
if ( strchr(config.ip_version, '4') != NULL )
prefix_allowed++;
}
if (strchr(ip_addr_str,':') != NULL)
{
if ( strchr(config.ip_version, '6') != NULL )
prefix_allowed++;
}
// Is this an IPv4 prefix?
if ((strchr(ip_addr_str,'.') != NULL) && (strchr(config.ip_version, '4') != NULL) )
prefix_allowed++;
if ((strchr(ip_addr_str,':') != NULL) && (strchr(config.ip_version, '6') != NULL) )
prefix_allowed++;
if (prefix_allowed == 0)
return;
}
Expand Down Expand Up @@ -208,6 +237,11 @@ static void pfx_update_callback(struct pfx_table *table,
// log answer, if any valid response
if (size > 0) {
bird_response[size] = 0;
// Any bird response that doesn't start with 0000 is bad
if ((strstr(bird_response, "0000") == NULL) && (strstr(bird_response, "0001") == NULL))
syslog(LOG_ERR,"Bird command %s resulted in: %s\n", bird_command, bird_response);
// else
// fprintf (stdout,"%s %s/%d \t", added ? "add" : "del", ip_addr_str, record.min_len);
if (config.quiet != true)
syslog(LOG_INFO, "From BIRD: %s", bird_response);
}
Expand All @@ -221,6 +255,7 @@ static void pfx_update_callback(struct pfx_table *table,
*/
int main(int argc, char *argv[])
{

// Buffer for commands and its length.
char *command = 0;
size_t command_len = 0;
Expand All @@ -240,6 +275,33 @@ int main(int argc, char *argv[])
fprintf(stderr, "Invalid configuration parameters!\n");
return EXIT_FAILURE;
}
pid_t process_id = 0;
pid_t sid = 0;

// Launch daemon if configured
if (config.daemon == true)
{
process_id = fork ();
// fork failed
if (process_id < 0)
{
fprintf(stderr,"fork failed!\n");
exit(1);
}
// Parent process, end it
if (process_id > 0)
exit(0);

// We're now in the child process
if (config.pidfile != NULL)
create_pidfile();
syslog(LOG_INFO, "initiated and running.");
sid = setsid();
if (sid < 0)
exit(1);
chdir ("/");
}

// Setup BIRD ROA table command argument.
if (config.bird_roa_table) {
init_bird_add_roa_table_arg(config.bird_roa_table);
Expand All @@ -250,7 +312,7 @@ int main(int argc, char *argv[])
bird_socket = bird_connect(config.bird_socket_path);
if (bird_socket == -1) {
cleanup();
fprintf(stderr, "Failed to connect to BIRD socket!\n");
syslog(LOG_ERR, "Failed to connect to BIRD socket!\n");
return EXIT_FAILURE;
}

Expand All @@ -273,7 +335,7 @@ int main(int argc, char *argv[])
break;
default:
cleanup();
fprintf(stderr, "Invalid connection type, use tcp or ssh!\n");
syslog(LOG_ERR, "Invalid connection type, use tcp or ssh!\n");
return EXIT_FAILURE;
}

Expand All @@ -291,31 +353,47 @@ int main(int argc, char *argv[])
pfx_update_callback, NULL, NULL, NULL);
// check for init errors
if (ret == RTR_ERROR) {
fprintf(stderr, "Error in rtr_mgr_init!\n");
syslog(LOG_ERR, "Error in rtr_mgr_init!\n");
return EXIT_FAILURE;
}
else if (ret == RTR_INVALID_PARAM) {
fprintf(stderr, "Invalid params passed to rtr_mgr_init\n");
syslog(LOG_ERR, "Invalid params passed to rtr_mgr_init\n");
return EXIT_FAILURE;
}
// check if rtr_mgr config valid
if (!conf) {
fprintf(stderr, "No config for rtr manager!\n");
syslog(LOG_ERR, "No config for rtr manager!\n");
return EXIT_FAILURE;
}
// set handler for SIGPIPE
signal(SIGPIPE, sigpipe_handler);
// set handler for SIGKILL and SIGTERM
signal(SIGKILL, sigkill_handler);
signal(SIGTERM, sigkill_handler);
// start rtr_mgr
rtr_mgr_start(conf);
// Server loop. Read commands from stdin.
fprintf(stdout, "bird-rtrlib-cli connected to %s:%s ready for IP versions %s.\nType 'exit' to clean up and quit.\n",

if (config.daemon == true)
{
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
// Child loop
while(time_to_die == 0)
sleep(1);
}
else
{
fprintf(stdout, "bird-rtrlib-cli connected to %s:%s ready for IP versions %s.\nType 'exit' to clean up and quit.\n",
config.rtr_host,
config.rtr_port,
config.ip_version ? config.ip_version : "all"
);
while (getline(&command, &command_len, stdin) != -1) {
if (strncmp(command, CMD_EXIT, strlen(CMD_EXIT)) == 0)
break;
);
// CLI loop. Read commands from stdin.
while (getline(&command, &command_len, stdin) != -1) {
if (strncmp(command, CMD_EXIT, strlen(CMD_EXIT)) == 0)
break;
}
}
// Clean up RTRLIB memory.
rtr_mgr_stop(conf);
Expand Down
24 changes: 24 additions & 0 deletions cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
#define ARGKEY_RTRSSH_USERNAME 0x103
#define ARGKEY_IP_VERSION 'v'
#define ARGKEY_QUIET 'q'
#define ARGKEY_DAEMON 'd'
#define ARGKEY_PIDFILE 'p'

// Parser function for argp_parse().
static error_t argp_parser(int key, char *arg, struct argp_state *state)
Expand Down Expand Up @@ -75,6 +77,12 @@ static error_t argp_parser(int key, char *arg, struct argp_state *state)
case ARGKEY_QUIET:
config->quiet = true;
break;
case ARGKEY_DAEMON:
config->daemon = true;
break;
case ARGKEY_PIDFILE:
config->pidfile = arg;
break;
default:
// Process unknown argument.
return ARGP_ERR_UNKNOWN;
Expand Down Expand Up @@ -172,6 +180,22 @@ int parse_cli(int argc, char **argv, struct config *config)
"(Optional) Report only errors.",
1
},
{
"daemon",
ARGKEY_DAEMON,
0,
0,
"(Optional) run as daemon, detach from terminal.",
1
},
{
"pidfile",
ARGKEY_PIDFILE,
"<PIDFILE>",
0,
"(Optional) Name of the pidfile",
2
},
{0}
};
// argp structure to be passed to argp_parse().
Expand Down
2 changes: 2 additions & 0 deletions config.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ struct config {
char *rtr_ssh_privkey_file;
char *ip_version;
bool quiet;
bool daemon;
char *pidfile;
};

/**
Expand Down