PATH="/sbin:/bin:/usr/sbin:/usr/bin:@IPSEC_SBINDIR@"
export PATH
+# set daemon name
+[ -z "$DAEMON_NAME" ] && DAEMON_NAME="charon"
+
# name and version of the ipsec implementation
OS_NAME=`uname -s`
IPSEC_NAME="@IPSEC_NAME@"
IPSEC_PIDDIR="@IPSEC_PIDDIR@"
IPSEC_SCRIPT="@IPSEC_SCRIPT@"
-IPSEC_STARTER_PID="${IPSEC_PIDDIR}/starter.pid"
-IPSEC_CHARON_PID="${IPSEC_PIDDIR}/charon.pid"
+IPSEC_STARTER_PID="${IPSEC_PIDDIR}/starter.${DAEMON_NAME}.pid"
+IPSEC_CHARON_PID="${IPSEC_PIDDIR}/${DAEMON_NAME}.pid"
IPSEC_STROKE="${IPSEC_DIR}/stroke"
IPSEC_STARTER="${IPSEC_DIR}/starter"
if [ -d /var/lock/subsys ]; then
touch /var/lock/subsys/ipsec
fi
- exec $IPSEC_STARTER "$@"
+ exec $IPSEC_STARTER --daemon $DAEMON_NAME "$@"
;;
status|statusall)
op="$1"
/* verify the executables are actually available */
#ifdef START_CHARON
cfg->setup.charonstart = cfg->setup.charonstart &&
- daemon_exists("charon", CHARON_CMD);
+ daemon_exists(daemon_name, cmd);
#else
cfg->setup.charonstart = FALSE;
#endif
#ifndef _STARTER_FILES_H_
#define _STARTER_FILES_H_
-#define STARTER_PID_FILE IPSEC_PIDDIR "/starter.pid"
-
#define PROC_NETKEY "/proc/net/pfkey"
#define PROC_KLIPS "/proc/net/pf_key"
#define PROC_MODULES "/proc/modules"
#define CONFIG_FILE IPSEC_CONFDIR "/ipsec.conf"
#define SECRETS_FILE IPSEC_CONFDIR "/ipsec.secrets"
-#define CHARON_CMD IPSEC_DIR "/charon"
#define CHARON_CTL_FILE IPSEC_PIDDIR "/charon.ctl"
-#define CHARON_PID_FILE IPSEC_PIDDIR "/charon.pid"
+
+extern char *daemon_name;
+extern char *cmd;
+extern char *pid_file;
#define DYNIP_DIR IPSEC_PIDDIR "/dynip"
if (status == SS_RC_LIBSTRONGSWAN_INTEGRITY ||
status == SS_RC_DAEMON_INTEGRITY)
{
- DBG1(DBG_APP, "charon has quit: integrity test of %s failed",
- (status == 64) ? "libstrongswan" : "charon");
+ DBG1(DBG_APP, "%s has quit: integrity test of %s failed",
+ daemon_name, (status == 64) ? "libstrongswan" : daemon_name);
_stop_requested = 1;
}
else if (status == SS_RC_INITIALIZATION_FAILED)
{
- DBG1(DBG_APP, "charon has quit: initialization failed");
+ DBG1(DBG_APP, "%s has quit: initialization failed", daemon_name);
_stop_requested = 1;
}
if (!_stop_requested)
{
- DBG1(DBG_APP, "charon has died -- restart scheduled (%dsec)",
- CHARON_RESTART_DELAY);
+ DBG1(DBG_APP, "%s has died -- restart scheduled (%dsec)",
+ daemon_name, CHARON_RESTART_DELAY);
alarm(CHARON_RESTART_DELAY); // restart in 5 sec
}
- unlink(CHARON_PID_FILE);
+ unlink(pid_file);
}
}
else if (i == 40)
{
kill(pid, SIGKILL);
- DBG1(DBG_APP, "starter_stop_charon(): charon does not respond, sending KILL");
+ DBG1(DBG_APP, "starter_stop_charon(): %s does not respond, sending KILL",
+ daemon_name);
}
else
{
}
if (_charon_pid == 0)
{
- DBG1(DBG_APP, "charon stopped after %d ms", 200*i);
+ DBG1(DBG_APP, "%s stopped after %d ms", daemon_name, 200*i);
return 0;
}
- DBG1(DBG_APP, "starter_stop_charon(): can't stop charon !!!");
+ DBG1(DBG_APP, "starter_stop_charon(): can't stop %s !!!", daemon_name);
return -1;
}
else
{
- DBG1(DBG_APP, "stater_stop_charon(): charon was not started...");
+ DBG1(DBG_APP, "stater_stop_charon(): %s was not started...", daemon_name);
}
return -1;
}
char buffer[BUF_LEN];
int argc = 1;
char *arg[] = {
- CHARON_CMD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ cmd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
argc = 0;
arg[argc++] = "/usr/bin/gdb";
arg[argc++] = "--args";
- arg[argc++] = CHARON_CMD;
+ arg[argc++] = cmd;
}
if (!no_fork)
{
if (_charon_pid)
{
- DBG1(DBG_APP, "starter_start_charon(): charon already started...");
+ DBG1(DBG_APP, "starter_start_charon(): %s already started...",
+ daemon_name);
return -1;
}
else
{
/* wait for charon for a maximum of 500 x 20 ms = 10 s */
usleep(20000);
- if (stat(CHARON_PID_FILE, &stb) == 0)
+ if (stat(pid_file, &stb) == 0)
{
- DBG1(DBG_APP, "charon (%d) started after %d ms",
+ DBG1(DBG_APP, "%s (%d) started after %d ms", daemon_name,
_charon_pid, 20*(i+1));
return 0;
}
if (_charon_pid)
{
/* If charon is started but with no ctl file, stop it */
- DBG1(DBG_APP, "charon too long to start... - kill kill");
+ DBG1(DBG_APP, "%s too long to start... - kill kill",
+ daemon_name);
for (i = 0; i < 20 && (pid = _charon_pid) != 0; i++)
{
if (i == 0)
}
else
{
- DBG1(DBG_APP, "charon refused to be started");
+ DBG1(DBG_APP, "%s refused to be started", daemon_name);
}
return -1;
}
* for more details.
*/
+#define _GNU_SOURCE
+
#include <sys/select.h>
#include <sys/types.h>
#include <sys/wait.h>
#define CHARON_RESTART_DELAY 5
+static const char* cmd_default = IPSEC_DIR "/charon";
+static const char* pid_file_default = IPSEC_PIDDIR "/charon.pid";
+static const char* starter_pid_file_default = IPSEC_PIDDIR "/starter.pid";
+
+char *daemon_name = NULL;
+char *cmd = NULL;
+char *pid_file = NULL;
+char *starter_pid_file = NULL;
+
/* logging */
static bool log_to_stderr = TRUE;
static bool log_to_syslog = TRUE;
{
if (pid == starter_charon_pid())
{
- name = " (Charon)";
+ if (asprintf(&name, " (%s)", daemon_name) < 0)
+ {
+ name = NULL;
+ }
}
if (WIFSIGNALED(status))
{
starter_charon_sigchild(pid, exit_status);
}
}
+
+ if (name)
+ {
+ free(name);
+ }
}
break;
return FALSE;
}
+/* Set daemon name and adjust command and pid filenames accordingly */
+static bool set_daemon_name()
+{
+ if (!daemon_name)
+ {
+ daemon_name = "charon";
+ }
+
+ if (asprintf(&cmd, IPSEC_DIR"/%s", daemon_name) < 0)
+ {
+ cmd = (char*)cmd_default;
+ }
+
+ if (asprintf(&pid_file, IPSEC_PIDDIR"/%s.pid", daemon_name) < 0)
+ {
+ pid_file = (char*)pid_file_default;
+ }
+
+ if (asprintf(&starter_pid_file, IPSEC_PIDDIR"/starter.%s.pid",
+ daemon_name) < 0)
+ {
+ starter_pid_file = (char*)starter_pid_file_default;
+ }
+
+ return TRUE;
+}
+
+static void cleanup()
+{
+ if (cmd != cmd_default)
+ {
+ free(cmd);
+ }
+
+ if (pid_file != pid_file_default)
+ {
+ free(pid_file);
+ }
+
+ if (starter_pid_file != starter_pid_file_default)
+ {
+ free(starter_pid_file);
+ }
+}
+
static void usage(char *name)
{
fprintf(stderr, "Usage: starter [--nofork] [--auto-update <sec>]\n"
" [--debug|--debug-more|--debug-all|--nolog]\n"
- " [--attach-gdb]\n");
+ " [--attach-gdb] [--daemon <name>]\n");
exit(LSB_RC_INVALID_ARGUMENT);
}
if (!auto_update)
usage(argv[0]);
}
+ else if (streq(argv[i], "--daemon") && i+1 < argc)
+ {
+ daemon_name = argv[++i];
+ }
else
{
usage(argv[0]);
}
}
+ if (!set_daemon_name())
+ {
+ DBG1(DBG_APP, "unable to set daemon name");
+ exit(LSB_RC_FAILURE);
+ }
+
init_log("ipsec_starter");
DBG1(DBG_APP, "Starting %sSwan "VERSION" IPsec [starter]...",
if (getuid() != 0)
{
DBG1(DBG_APP, "permission denied (must be superuser)");
+ cleanup();
exit(LSB_RC_NOT_ALLOWED);
}
- if (check_pid(CHARON_PID_FILE))
+ if (check_pid(pid_file))
{
- DBG1(DBG_APP, "charon is already running (%s exists) -- skipping charon start",
- CHARON_PID_FILE);
+ DBG1(DBG_APP, "%s is already running (%s exists) -- skipping daemon start",
+ daemon_name, pid_file);
}
else
{
if (stat(DEV_RANDOM, &stb) != 0)
{
DBG1(DBG_APP, "unable to start strongSwan IPsec -- no %s!", DEV_RANDOM);
+ cleanup();
exit(LSB_RC_FAILURE);
}
if (stat(DEV_URANDOM, &stb)!= 0)
{
DBG1(DBG_APP, "unable to start strongSwan IPsec -- no %s!", DEV_URANDOM);
+ cleanup();
exit(LSB_RC_FAILURE);
}
{
confread_free(cfg);
}
+ cleanup();
exit(LSB_RC_INVALID_ARGUMENT);
}
last_reload = time_monotonic(NULL);
- if (check_pid(STARTER_PID_FILE))
+ if (check_pid(starter_pid_file))
{
DBG1(DBG_APP, "starter is already running (%s exists) -- no fork done",
- STARTER_PID_FILE);
+ starter_pid_file);
confread_free(cfg);
+ cleanup();
exit(LSB_RC_SUCCESS);
}
break;
default:
confread_free(cfg);
+ cleanup();
exit(LSB_RC_SUCCESS);
}
}
- /* save pid file in /var/run/starter.pid */
+ /* save pid file in /var/run/starter[.daemon_name].pid */
{
- FILE *fd = fopen(STARTER_PID_FILE, "w");
+ FILE *fd = fopen(starter_pid_file, "w");
if (fd)
{
}
starter_netkey_cleanup();
confread_free(cfg);
- unlink(STARTER_PID_FILE);
+ unlink(starter_pid_file);
+ cleanup();
DBG1(DBG_APP, "ipsec starter stopped");
close_log();
exit(LSB_RC_SUCCESS);
}
/*
- * Start charon
+ * Start daemon
*/
if (_action_ & FLAG_ACTION_START_CHARON)
{
if (cfg->setup.charonstart && !starter_charon_pid())
{
- DBG2(DBG_APP, "Attempting to start charon...");
+ DBG2(DBG_APP, "Attempting to start %s...", daemon_name);
if (starter_start_charon(cfg, no_fork, attach_gdb))
{
/* schedule next try */
/*
* Wait for something to happen
*/
- if (pselect(0, NULL, NULL, NULL, auto_update ? &ts : NULL,
+ if (!_action_ &&
+ pselect(0, NULL, NULL, NULL, auto_update ? &ts : NULL,
&action.sa_mask) == 0)
{
/* timeout -> auto_update */