starter: Remove main parts of pluto support (invoke, whack).
This commit is contained in:
parent
95e41fb80a
commit
041e763b77
|
@ -4,8 +4,8 @@ include $(CLEAR_VARS)
|
|||
# copy-n-paste from Makefile.am (update for LEX/YACC)
|
||||
LOCAL_SRC_FILES := \
|
||||
parser.c lexer.c ipsec-parser.h netkey.c args.h netkey.h \
|
||||
starterwhack.c starterwhack.h starterstroke.c invokepluto.c confread.c \
|
||||
starterstroke.h invokepluto.h confread.h args.c \
|
||||
starterstroke.c confread.c \
|
||||
starterstroke.h confread.h args.c \
|
||||
keywords.c files.h keywords.h cmp.c starter.c cmp.h invokecharon.c \
|
||||
invokecharon.h klips.c klips.h
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
ipsec_PROGRAMS = starter
|
||||
starter_SOURCES = \
|
||||
parser.y lexer.l ipsec-parser.h netkey.c args.h netkey.h \
|
||||
starterwhack.c starterwhack.h starterstroke.c invokepluto.c confread.c \
|
||||
starterstroke.h invokepluto.h confread.h args.c \
|
||||
starterstroke.c confread.c \
|
||||
starterstroke.h confread.h args.c \
|
||||
keywords.c files.h keywords.h cmp.c starter.c cmp.h invokecharon.c \
|
||||
invokecharon.h klips.c klips.h
|
||||
|
||||
|
|
|
@ -1,326 +0,0 @@
|
|||
/* strongSwan Pluto launcher
|
||||
* Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <library.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include "confread.h"
|
||||
#include "invokepluto.h"
|
||||
#include "files.h"
|
||||
#include "starterwhack.h"
|
||||
|
||||
static int _pluto_pid = 0;
|
||||
static int _stop_requested;
|
||||
|
||||
pid_t
|
||||
starter_pluto_pid(void)
|
||||
{
|
||||
return _pluto_pid;
|
||||
}
|
||||
|
||||
void
|
||||
starter_pluto_sigchild(pid_t pid, int status)
|
||||
{
|
||||
if (pid == _pluto_pid)
|
||||
{
|
||||
_pluto_pid = 0;
|
||||
if (status == SS_RC_LIBSTRONGSWAN_INTEGRITY ||
|
||||
status == SS_RC_DAEMON_INTEGRITY)
|
||||
{
|
||||
DBG1(DBG_APP, "pluto has quit: integrity test of %s failed",
|
||||
(status == 64) ? "libstrongswan" : "pluto");
|
||||
_stop_requested = 1;
|
||||
}
|
||||
else if (status == SS_RC_INITIALIZATION_FAILED)
|
||||
{
|
||||
DBG1(DBG_APP, "pluto has quit: initialization failed");
|
||||
_stop_requested = 1;
|
||||
}
|
||||
if (!_stop_requested)
|
||||
{
|
||||
DBG1(DBG_APP, "pluto has died -- restart scheduled (%dsec)",
|
||||
PLUTO_RESTART_DELAY);
|
||||
alarm(PLUTO_RESTART_DELAY); // restart in 5 sec
|
||||
}
|
||||
unlink(PLUTO_PID_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
starter_stop_pluto (void)
|
||||
{
|
||||
int i;
|
||||
pid_t pid = _pluto_pid;
|
||||
|
||||
if (pid)
|
||||
{
|
||||
_stop_requested = 1;
|
||||
|
||||
if (starter_whack_shutdown() == 0)
|
||||
{
|
||||
for (i = 0; i < 400; i++)
|
||||
{
|
||||
usleep(20000); /* sleep for 20 ms */
|
||||
if (_pluto_pid == 0)
|
||||
{
|
||||
DBG1(DBG_APP, "pluto stopped after %d ms", 20*(i+1));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* be more and more aggressive */
|
||||
for (i = 0; i < 20 && (pid = _pluto_pid) != 0; i++)
|
||||
{
|
||||
|
||||
if (i < 10)
|
||||
{
|
||||
kill(pid, SIGTERM);
|
||||
}
|
||||
if (i == 10)
|
||||
{
|
||||
kill(pid, SIGKILL);
|
||||
DBG1(DBG_APP, "starter_stop_pluto(): pluto does not respond, sending KILL");
|
||||
}
|
||||
else
|
||||
{
|
||||
kill(pid, SIGKILL);
|
||||
}
|
||||
usleep(100000); /* sleep for 100 ms */
|
||||
}
|
||||
if (_pluto_pid == 0)
|
||||
{
|
||||
DBG1(DBG_APP, "pluto stopped after %d ms", 8000 + 100*i);
|
||||
return 0;
|
||||
}
|
||||
DBG1(DBG_APP, "starter_stop_pluto(): can't stop pluto !!!");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_APP, "stater_stop_pluto(): pluto is not started...");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define ADD_DEBUG(v) { \
|
||||
for (l = cfg->setup.plutodebug; l && *l; l++) if (streq(*l, v)) \
|
||||
arg[argc++] = "--debug-" v; \
|
||||
}
|
||||
|
||||
int
|
||||
starter_start_pluto (starter_config_t *cfg, bool no_fork, bool attach_gdb)
|
||||
{
|
||||
struct stat stb;
|
||||
int i;
|
||||
pid_t pid;
|
||||
char **l;
|
||||
int argc = 2;
|
||||
char *arg[] = {
|
||||
PLUTO_CMD, "--nofork"
|
||||
, 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, NULL, NULL
|
||||
};
|
||||
|
||||
printf ("starter_start_pluto entered\n");
|
||||
|
||||
if (attach_gdb)
|
||||
{
|
||||
argc = 0;
|
||||
arg[argc++] = "/usr/bin/gdb";
|
||||
arg[argc++] = "--args";
|
||||
arg[argc++] = PLUTO_CMD;
|
||||
arg[argc++] = "--nofork";
|
||||
}
|
||||
if (cfg->setup.plutostderrlog || no_fork)
|
||||
{
|
||||
arg[argc++] = "--stderrlog";
|
||||
}
|
||||
if (cfg->setup.uniqueids)
|
||||
{
|
||||
arg[argc++] = "--uniqueids";
|
||||
}
|
||||
ADD_DEBUG("none")
|
||||
ADD_DEBUG("all")
|
||||
ADD_DEBUG("raw")
|
||||
ADD_DEBUG("crypt")
|
||||
ADD_DEBUG("parsing")
|
||||
ADD_DEBUG("emitting")
|
||||
ADD_DEBUG("control")
|
||||
ADD_DEBUG("lifecycle")
|
||||
ADD_DEBUG("klips")
|
||||
ADD_DEBUG("kernel")
|
||||
ADD_DEBUG("dns")
|
||||
ADD_DEBUG("natt")
|
||||
ADD_DEBUG("oppo")
|
||||
ADD_DEBUG("controlmore")
|
||||
ADD_DEBUG("private")
|
||||
if (cfg->setup.crlcheckinterval > 0)
|
||||
{
|
||||
static char buf1[15];
|
||||
|
||||
arg[argc++] = "--crlcheckinterval";
|
||||
snprintf(buf1, sizeof(buf1), "%d", (int)cfg->setup.crlcheckinterval);
|
||||
arg[argc++] = buf1;
|
||||
}
|
||||
if (cfg->setup.cachecrls)
|
||||
{
|
||||
arg[argc++] = "--cachecrls";
|
||||
}
|
||||
if (cfg->setup.strictcrlpolicy)
|
||||
{
|
||||
arg[argc++] = "--strictcrlpolicy";
|
||||
}
|
||||
if (cfg->setup.nocrsend)
|
||||
{
|
||||
arg[argc++] = "--nocrsend";
|
||||
}
|
||||
if (cfg->setup.nat_traversal)
|
||||
{
|
||||
arg[argc++] = "--nat_traversal";
|
||||
}
|
||||
if (cfg->setup.force_keepalive)
|
||||
{
|
||||
arg[argc++] = "--force_keepalive";
|
||||
}
|
||||
if (cfg->setup.keep_alive)
|
||||
{
|
||||
static char buf2[15];
|
||||
|
||||
arg[argc++] = "--keep_alive";
|
||||
snprintf(buf2, sizeof(buf2), "%d", (int)cfg->setup.keep_alive);
|
||||
arg[argc++] = buf2;
|
||||
}
|
||||
if (cfg->setup.virtual_private)
|
||||
{
|
||||
arg[argc++] = "--virtual_private";
|
||||
arg[argc++] = cfg->setup.virtual_private;
|
||||
}
|
||||
if (cfg->setup.pkcs11module)
|
||||
{
|
||||
arg[argc++] = "--pkcs11module";
|
||||
arg[argc++] = cfg->setup.pkcs11module;
|
||||
}
|
||||
if (cfg->setup.pkcs11initargs)
|
||||
{
|
||||
arg[argc++] = "--pkcs11initargs";
|
||||
arg[argc++] = cfg->setup.pkcs11initargs;
|
||||
}
|
||||
if (cfg->setup.pkcs11keepstate)
|
||||
{
|
||||
arg[argc++] = "--pkcs11keepstate";
|
||||
}
|
||||
if (cfg->setup.pkcs11proxy)
|
||||
{
|
||||
arg[argc++] = "--pkcs11proxy";
|
||||
}
|
||||
|
||||
if (_pluto_pid)
|
||||
{
|
||||
DBG1(DBG_APP, "starter_start_pluto(): pluto already started...");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
unlink(PLUTO_CTL_FILE);
|
||||
_stop_requested = 0;
|
||||
|
||||
if (cfg->setup.prepluto)
|
||||
ignore_result(system(cfg->setup.prepluto));
|
||||
|
||||
pid = fork();
|
||||
switch (pid)
|
||||
{
|
||||
case -1:
|
||||
DBG1(DBG_APP, "can't fork(): %s", strerror(errno));
|
||||
return -1;
|
||||
case 0:
|
||||
/* child */
|
||||
if (cfg->setup.plutostderrlog)
|
||||
{
|
||||
int f = creat(cfg->setup.plutostderrlog, 00644);
|
||||
|
||||
/* redirect stderr to file */
|
||||
if (f < 0)
|
||||
{
|
||||
DBG1(DBG_APP, "couldn't open stderr redirection file '%s'",
|
||||
cfg->setup.plutostderrlog);
|
||||
}
|
||||
else
|
||||
{
|
||||
dup2(f, 2);
|
||||
}
|
||||
}
|
||||
setsid();
|
||||
closefrom(3);
|
||||
sigprocmask(SIG_SETMASK, 0, NULL);
|
||||
/* disable glibc's malloc checker, conflicts with leak detective */
|
||||
setenv("MALLOC_CHECK_", "0", 1);
|
||||
execv(arg[0], arg);
|
||||
DBG1(DBG_APP, "can't execv(%s,...): %s", arg[0], strerror(errno));
|
||||
exit(1);
|
||||
default:
|
||||
/* father */
|
||||
_pluto_pid = pid;
|
||||
for (i = 0; i < 500 && _pluto_pid; i++)
|
||||
{
|
||||
/* wait for pluto for a maximum of 500 x 20 ms = 10 s */
|
||||
usleep(20000);
|
||||
if (stat(PLUTO_CTL_FILE, &stb) == 0)
|
||||
{
|
||||
DBG1(DBG_APP, "pluto (%d) started after %d ms",
|
||||
_pluto_pid, 20*(i+1));
|
||||
if (cfg->setup.postpluto)
|
||||
{
|
||||
ignore_result(system(cfg->setup.postpluto));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (_pluto_pid)
|
||||
{
|
||||
/* If pluto is started but with no ctl file, stop it */
|
||||
DBG1(DBG_APP, "pluto too long to start... - kill kill");
|
||||
for (i = 0; i < 20 && (pid = _pluto_pid) != 0; i++)
|
||||
{
|
||||
if (i < 10)
|
||||
{
|
||||
kill(pid, SIGTERM);
|
||||
}
|
||||
else
|
||||
{
|
||||
kill(pid, SIGKILL);
|
||||
}
|
||||
usleep(20000); /* sleep for 20 ms */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_APP, "pluto refused to be started");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
/* strongSwan pluto launcher
|
||||
* Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef _STARTER_PLUTO_H_
|
||||
#define _STARTER_PLUTO_H_
|
||||
|
||||
#define PLUTO_RESTART_DELAY 5
|
||||
|
||||
extern void starter_pluto_sigchild (pid_t pid, int status);
|
||||
extern pid_t starter_pluto_pid (void);
|
||||
extern int starter_stop_pluto (void);
|
||||
extern int starter_start_pluto (struct starter_config *cfg, bool no_fork, bool attach_gdb);
|
||||
|
||||
#endif /* _STARTER_PLUTO_H_ */
|
||||
|
|
@ -42,9 +42,7 @@
|
|||
|
||||
#include "confread.h"
|
||||
#include "files.h"
|
||||
#include "starterwhack.h"
|
||||
#include "starterstroke.h"
|
||||
#include "invokepluto.h"
|
||||
#include "invokecharon.h"
|
||||
#include "netkey.h"
|
||||
#include "klips.h"
|
||||
|
@ -54,6 +52,8 @@
|
|||
#define LOG_AUTHPRIV LOG_AUTH
|
||||
#endif
|
||||
|
||||
#define CHARON_RESTART_DELAY 5
|
||||
|
||||
/* logging */
|
||||
static bool log_to_stderr = TRUE;
|
||||
static bool log_to_syslog = TRUE;
|
||||
|
@ -164,10 +164,6 @@ static void signal_handler(int signal)
|
|||
|
||||
while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
|
||||
{
|
||||
if (pid == starter_pluto_pid())
|
||||
{
|
||||
name = " (Pluto)";
|
||||
}
|
||||
if (pid == starter_charon_pid())
|
||||
{
|
||||
name = " (Charon)";
|
||||
|
@ -196,10 +192,6 @@ static void signal_handler(int signal)
|
|||
{
|
||||
DBG2(DBG_APP, "child %d%s has quit", pid, name?name:"");
|
||||
}
|
||||
if (pid == starter_pluto_pid())
|
||||
{
|
||||
starter_pluto_sigchild(pid, exit_status);
|
||||
}
|
||||
if (pid == starter_charon_pid())
|
||||
{
|
||||
starter_charon_sigchild(pid, exit_status);
|
||||
|
@ -209,7 +201,6 @@ static void signal_handler(int signal)
|
|||
break;
|
||||
|
||||
case SIGALRM:
|
||||
_action_ |= FLAG_ACTION_START_PLUTO;
|
||||
_action_ |= FLAG_ACTION_START_CHARON;
|
||||
break;
|
||||
|
||||
|
@ -416,11 +407,10 @@ int main (int argc, char **argv)
|
|||
|
||||
if (lib->settings->get_bool(lib->settings, "starter.load_warning", load_warning))
|
||||
{
|
||||
if (lib->settings->get_str(lib->settings, "charon.load", NULL) ||
|
||||
lib->settings->get_str(lib->settings, "pluto.load", NULL))
|
||||
if (lib->settings->get_str(lib->settings, "charon.load", NULL))
|
||||
{
|
||||
DBG1(DBG_APP, "!! Your strongswan.conf contains manual plugin load options for");
|
||||
DBG1(DBG_APP, "!! pluto and/or charon. This is recommended for experts only, see");
|
||||
DBG1(DBG_APP, "!! Your strongswan.conf contains manual plugin load options for charon.");
|
||||
DBG1(DBG_APP, "!! This is recommended for experts only, see");
|
||||
DBG1(DBG_APP, "!! http://wiki.strongswan.org/projects/strongswan/wiki/PluginLoad");
|
||||
}
|
||||
}
|
||||
|
@ -432,15 +422,6 @@ int main (int argc, char **argv)
|
|||
exit(LSB_RC_NOT_ALLOWED);
|
||||
}
|
||||
|
||||
if (check_pid(PLUTO_PID_FILE))
|
||||
{
|
||||
DBG1(DBG_APP, "pluto is already running (%s exists) -- skipping pluto start",
|
||||
PLUTO_PID_FILE);
|
||||
}
|
||||
else
|
||||
{
|
||||
_action_ |= FLAG_ACTION_START_PLUTO;
|
||||
}
|
||||
if (check_pid(CHARON_PID_FILE))
|
||||
{
|
||||
DBG1(DBG_APP, "charon is already running (%s exists) -- skipping charon start",
|
||||
|
@ -588,14 +569,10 @@ int main (int argc, char **argv)
|
|||
for (;;)
|
||||
{
|
||||
/*
|
||||
* Stop pluto/charon (if started) and exit
|
||||
* Stop charon (if started) and exit
|
||||
*/
|
||||
if (_action_ & FLAG_ACTION_QUIT)
|
||||
{
|
||||
if (starter_pluto_pid())
|
||||
{
|
||||
starter_stop_pluto();
|
||||
}
|
||||
if (starter_charon_pid())
|
||||
{
|
||||
starter_stop_charon();
|
||||
|
@ -614,7 +591,7 @@ int main (int argc, char **argv)
|
|||
*/
|
||||
if (_action_ & FLAG_ACTION_RELOAD)
|
||||
{
|
||||
if (starter_pluto_pid() || starter_charon_pid())
|
||||
if (starter_charon_pid())
|
||||
{
|
||||
for (conn = cfg->conn_first; conn; conn = conn->next)
|
||||
{
|
||||
|
@ -624,10 +601,6 @@ int main (int argc, char **argv)
|
|||
{
|
||||
starter_stroke_del_conn(conn);
|
||||
}
|
||||
if (starter_pluto_pid())
|
||||
{
|
||||
starter_whack_del_conn(conn);
|
||||
}
|
||||
conn->state = STATE_TO_ADD;
|
||||
}
|
||||
}
|
||||
|
@ -639,10 +612,6 @@ int main (int argc, char **argv)
|
|||
{
|
||||
starter_stroke_del_ca(ca);
|
||||
}
|
||||
if (starter_pluto_pid())
|
||||
{
|
||||
starter_whack_del_ca(ca);
|
||||
}
|
||||
ca->state = STATE_TO_ADD;
|
||||
}
|
||||
}
|
||||
|
@ -661,82 +630,62 @@ int main (int argc, char **argv)
|
|||
if (new_cfg && (new_cfg->err + new_cfg->non_fatal_err == 0))
|
||||
{
|
||||
/* Switch to new config. New conn will be loaded below */
|
||||
if (!starter_cmp_pluto(cfg, new_cfg))
|
||||
|
||||
/* Look for new connections that are already loaded */
|
||||
for (conn = cfg->conn_first; conn; conn = conn->next)
|
||||
{
|
||||
DBG1(DBG_APP, "Pluto has changed");
|
||||
if (starter_pluto_pid())
|
||||
starter_stop_pluto();
|
||||
_action_ &= ~FLAG_ACTION_LISTEN;
|
||||
_action_ |= FLAG_ACTION_START_PLUTO;
|
||||
if (conn->state == STATE_ADDED)
|
||||
{
|
||||
for (conn2 = new_cfg->conn_first; conn2; conn2 = conn2->next)
|
||||
{
|
||||
if (conn2->state == STATE_TO_ADD && starter_cmp_conn(conn, conn2))
|
||||
{
|
||||
conn->state = STATE_REPLACED;
|
||||
conn2->state = STATE_ADDED;
|
||||
conn2->id = conn->id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
/* Remove conn sections that have become unused */
|
||||
for (conn = cfg->conn_first; conn; conn = conn->next)
|
||||
{
|
||||
/* Only reload conn and ca sections if pluto is not killed */
|
||||
|
||||
/* Look for new connections that are already loaded */
|
||||
for (conn = cfg->conn_first; conn; conn = conn->next)
|
||||
if (conn->state == STATE_ADDED)
|
||||
{
|
||||
if (conn->state == STATE_ADDED)
|
||||
if (starter_charon_pid())
|
||||
{
|
||||
for (conn2 = new_cfg->conn_first; conn2; conn2 = conn2->next)
|
||||
starter_stroke_del_conn(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Look for new ca sections that are already loaded */
|
||||
for (ca = cfg->ca_first; ca; ca = ca->next)
|
||||
{
|
||||
if (ca->state == STATE_ADDED)
|
||||
{
|
||||
for (ca2 = new_cfg->ca_first; ca2; ca2 = ca2->next)
|
||||
{
|
||||
if (ca2->state == STATE_TO_ADD && starter_cmp_ca(ca, ca2))
|
||||
{
|
||||
if (conn2->state == STATE_TO_ADD && starter_cmp_conn(conn, conn2))
|
||||
{
|
||||
conn->state = STATE_REPLACED;
|
||||
conn2->state = STATE_ADDED;
|
||||
conn2->id = conn->id;
|
||||
break;
|
||||
}
|
||||
ca->state = STATE_REPLACED;
|
||||
ca2->state = STATE_ADDED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove conn sections that have become unused */
|
||||
for (conn = cfg->conn_first; conn; conn = conn->next)
|
||||
/* Remove ca sections that have become unused */
|
||||
for (ca = cfg->ca_first; ca; ca = ca->next)
|
||||
{
|
||||
if (ca->state == STATE_ADDED)
|
||||
{
|
||||
if (conn->state == STATE_ADDED)
|
||||
if (starter_charon_pid())
|
||||
{
|
||||
if (starter_charon_pid())
|
||||
{
|
||||
starter_stroke_del_conn(conn);
|
||||
}
|
||||
if (starter_pluto_pid())
|
||||
{
|
||||
starter_whack_del_conn(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Look for new ca sections that are already loaded */
|
||||
for (ca = cfg->ca_first; ca; ca = ca->next)
|
||||
{
|
||||
if (ca->state == STATE_ADDED)
|
||||
{
|
||||
for (ca2 = new_cfg->ca_first; ca2; ca2 = ca2->next)
|
||||
{
|
||||
if (ca2->state == STATE_TO_ADD && starter_cmp_ca(ca, ca2))
|
||||
{
|
||||
ca->state = STATE_REPLACED;
|
||||
ca2->state = STATE_ADDED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove ca sections that have become unused */
|
||||
for (ca = cfg->ca_first; ca; ca = ca->next)
|
||||
{
|
||||
if (ca->state == STATE_ADDED)
|
||||
{
|
||||
if (starter_charon_pid())
|
||||
{
|
||||
starter_stroke_del_ca(ca);
|
||||
}
|
||||
if (starter_pluto_pid())
|
||||
{
|
||||
starter_whack_del_ca(ca);
|
||||
}
|
||||
starter_stroke_del_ca(ca);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -755,40 +704,6 @@ int main (int argc, char **argv)
|
|||
last_reload = time_monotonic(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start pluto
|
||||
*/
|
||||
if (_action_ & FLAG_ACTION_START_PLUTO)
|
||||
{
|
||||
if (cfg->setup.plutostart && !starter_pluto_pid())
|
||||
{
|
||||
DBG2(DBG_APP, "Attempting to start pluto...");
|
||||
|
||||
if (starter_start_pluto(cfg, no_fork, attach_gdb) == 0)
|
||||
{
|
||||
starter_whack_listen();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* schedule next try */
|
||||
alarm(PLUTO_RESTART_DELAY);
|
||||
}
|
||||
}
|
||||
_action_ &= ~FLAG_ACTION_START_PLUTO;
|
||||
|
||||
for (ca = cfg->ca_first; ca; ca = ca->next)
|
||||
{
|
||||
if (ca->state == STATE_ADDED)
|
||||
ca->state = STATE_TO_ADD;
|
||||
}
|
||||
|
||||
for (conn = cfg->conn_first; conn; conn = conn->next)
|
||||
{
|
||||
if (conn->state == STATE_ADDED)
|
||||
conn->state = STATE_TO_ADD;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Start charon
|
||||
*/
|
||||
|
@ -800,29 +715,17 @@ int main (int argc, char **argv)
|
|||
if (starter_start_charon(cfg, no_fork, attach_gdb))
|
||||
{
|
||||
/* schedule next try */
|
||||
alarm(PLUTO_RESTART_DELAY);
|
||||
alarm(CHARON_RESTART_DELAY);
|
||||
}
|
||||
starter_stroke_configure(cfg);
|
||||
}
|
||||
_action_ &= ~FLAG_ACTION_START_CHARON;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tell pluto to reread its interfaces
|
||||
*/
|
||||
if (_action_ & FLAG_ACTION_LISTEN)
|
||||
{
|
||||
if (starter_pluto_pid())
|
||||
{
|
||||
starter_whack_listen();
|
||||
_action_ &= ~FLAG_ACTION_LISTEN;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Add stale conn and ca sections
|
||||
*/
|
||||
if (starter_pluto_pid() || starter_charon_pid())
|
||||
if (starter_charon_pid())
|
||||
{
|
||||
for (ca = cfg->ca_first; ca; ca = ca->next)
|
||||
{
|
||||
|
@ -832,10 +735,6 @@ int main (int argc, char **argv)
|
|||
{
|
||||
starter_stroke_add_ca(ca);
|
||||
}
|
||||
if (starter_pluto_pid())
|
||||
{
|
||||
starter_whack_add_ca(ca);
|
||||
}
|
||||
ca->state = STATE_ADDED;
|
||||
}
|
||||
}
|
||||
|
@ -853,10 +752,6 @@ int main (int argc, char **argv)
|
|||
{
|
||||
starter_stroke_add_conn(cfg, conn);
|
||||
}
|
||||
if (starter_pluto_pid())
|
||||
{
|
||||
starter_whack_add_conn(conn);
|
||||
}
|
||||
conn->state = STATE_ADDED;
|
||||
|
||||
if (conn->startup == STARTUP_START)
|
||||
|
@ -865,13 +760,6 @@ int main (int argc, char **argv)
|
|||
{
|
||||
starter_stroke_initiate_conn(conn);
|
||||
}
|
||||
if (conn->keyexchange == KEY_EXCHANGE_IKEV1)
|
||||
{
|
||||
if (starter_pluto_pid())
|
||||
{
|
||||
starter_whack_initiate_conn(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (conn->startup == STARTUP_ROUTE)
|
||||
{
|
||||
|
@ -879,13 +767,6 @@ int main (int argc, char **argv)
|
|||
{
|
||||
starter_stroke_route_conn(conn);
|
||||
}
|
||||
if (conn->keyexchange == KEY_EXCHANGE_IKEV1)
|
||||
{
|
||||
if (starter_pluto_pid())
|
||||
{
|
||||
starter_whack_route_conn(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,418 +0,0 @@
|
|||
/* strongSwan whack functions to communicate with pluto (whack.c)
|
||||
* Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <library.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <constants.h>
|
||||
#include <defs.h>
|
||||
#include <whack.h>
|
||||
|
||||
#include "starterwhack.h"
|
||||
#include "confread.h"
|
||||
#include "files.h"
|
||||
|
||||
#define ip_version(string) (strchr(string, '.') ? AF_INET : AF_INET6)
|
||||
|
||||
static int pack_str (char **p, char **next, char **roof)
|
||||
{
|
||||
const char *s = (*p==NULL) ? "" : *p; /* note: NULL becomes ""! */
|
||||
size_t len = strlen(s) + 1;
|
||||
|
||||
if ((*roof - *next) < len)
|
||||
{
|
||||
return 0; /* not enough space */
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(*next, s);
|
||||
*next += len;
|
||||
*p = NULL; /* don't send pointers on the wire! */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int send_whack_msg (whack_message_t *msg)
|
||||
{
|
||||
struct sockaddr_un ctl_addr;
|
||||
int sock;
|
||||
ssize_t len;
|
||||
char *str_next, *str_roof;
|
||||
|
||||
ctl_addr.sun_family = AF_UNIX;
|
||||
strcpy(ctl_addr.sun_path, PLUTO_CTL_FILE);
|
||||
|
||||
/* pack strings */
|
||||
str_next = (char *)msg->string;
|
||||
str_roof = (char *)&msg->string[sizeof(msg->string)];
|
||||
|
||||
if (!pack_str(&msg->name, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->left.id, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->left.cert, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->left.ca, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->left.groups, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->left.updown, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->left.sourceip, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->left.virt, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->right.id, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->right.cert, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->right.ca, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->right.groups, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->right.updown, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->right.sourceip, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->right.virt, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->keyid, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->myid, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->cacert, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->ldaphost, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->ldapbase, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->crluri, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->crluri2, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->ocspuri, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->ike, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->esp, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->sc_data, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->whack_lease_ip, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->whack_lease_id, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->xauth_identity, &str_next, &str_roof)
|
||||
|| (str_roof - str_next < msg->keyval.len))
|
||||
{
|
||||
DBG1(DBG_APP, "send_wack_msg(): can't pack strings");
|
||||
return -1;
|
||||
}
|
||||
if (msg->keyval.ptr)
|
||||
{
|
||||
memcpy(str_next, msg->keyval.ptr, msg->keyval.len);
|
||||
}
|
||||
msg->keyval.ptr = NULL;
|
||||
str_next += msg->keyval.len;
|
||||
len = str_next - (char *)msg;
|
||||
|
||||
/* connect to pluto ctl */
|
||||
sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (sock < 0)
|
||||
{
|
||||
DBG1(DBG_APP, "socket() failed: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (connect(sock, (struct sockaddr *)&ctl_addr,
|
||||
offsetof(struct sockaddr_un, sun_path) + strlen(ctl_addr.sun_path)) < 0)
|
||||
{
|
||||
DBG1(DBG_APP, "connect(pluto_ctl) failed: %s", strerror(errno));
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* send message */
|
||||
if (write(sock, msg, len) != len)
|
||||
{
|
||||
DBG1(DBG_APP, "write(pluto_ctl) failed: %s", strerror(errno));
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* TODO: read reply */
|
||||
close(sock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void init_whack_msg(whack_message_t *msg)
|
||||
{
|
||||
memset(msg, 0, sizeof(whack_message_t));
|
||||
msg->magic = WHACK_MAGIC;
|
||||
}
|
||||
|
||||
static char *connection_name(starter_conn_t *conn, char *buf, size_t size)
|
||||
{
|
||||
/* if connection name is '%auto', create a new name like conn_xxxxx */
|
||||
if (streq(conn->name, "%auto"))
|
||||
{
|
||||
snprintf(buf, size, "conn_%ld", conn->id);
|
||||
return buf;
|
||||
}
|
||||
return conn->name;
|
||||
}
|
||||
|
||||
static void set_whack_end(whack_end_t *w, starter_end_t *end, sa_family_t family)
|
||||
{
|
||||
w->id = end->id;
|
||||
w->cert = end->cert;
|
||||
w->ca = end->ca;
|
||||
w->groups = end->groups;
|
||||
w->host_addr = end->addr;
|
||||
w->has_client = end->has_client;
|
||||
w->sourceip = end->sourceip;
|
||||
w->sourceip_mask = end->sourceip_mask;
|
||||
|
||||
if (end->sourceip && end->sourceip_mask > 0)
|
||||
{
|
||||
ttoaddr(end->sourceip, 0, ip_version(end->sourceip), &w->host_srcip);
|
||||
w->has_srcip = !end->has_natip;
|
||||
}
|
||||
else
|
||||
{
|
||||
anyaddr(AF_INET, &w->host_srcip);
|
||||
}
|
||||
|
||||
if (family == AF_INET6 && isanyaddr(&end->nexthop))
|
||||
{
|
||||
anyaddr(AF_INET6, &end->nexthop);
|
||||
}
|
||||
w->host_nexthop = end->nexthop;
|
||||
|
||||
if (w->has_client)
|
||||
{
|
||||
char *pos;
|
||||
int len = 0;
|
||||
|
||||
pos = strchr(end->subnet, ',');
|
||||
if (pos)
|
||||
{
|
||||
len = pos - end->subnet;
|
||||
}
|
||||
ttosubnet(end->subnet, len, ip_version(end->subnet), &w->client);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (end->has_virt)
|
||||
{
|
||||
w->virt = end->subnet;
|
||||
}
|
||||
w->client.addr.u.v4.sin_family = addrtypeof(&w->host_addr);
|
||||
}
|
||||
|
||||
w->has_client_wildcard = end->has_client_wildcard;
|
||||
w->has_port_wildcard = end->has_port_wildcard;
|
||||
w->has_natip = end->has_natip;
|
||||
w->allow_any = end->allow_any && !end->dns_failed;
|
||||
w->modecfg = end->modecfg;
|
||||
w->hostaccess = end->hostaccess;
|
||||
w->sendcert = end->sendcert;
|
||||
w->updown = end->updown;
|
||||
w->host_port = IKE_UDP_PORT;
|
||||
w->port = end->port;
|
||||
w->protocol = end->protocol;
|
||||
|
||||
if (w->port != 0)
|
||||
{
|
||||
int port = htons(w->port);
|
||||
|
||||
setportof(port, &w->host_addr);
|
||||
setportof(port, &w->client.addr);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
starter_whack_add_pubkey (starter_conn_t *conn, starter_end_t *end
|
||||
, const char *lr)
|
||||
{
|
||||
const char *err;
|
||||
static char keyspace[1024 + 4];
|
||||
char buf[ADDRTOT_BUF], name[32];
|
||||
whack_message_t msg;
|
||||
|
||||
init_whack_msg(&msg);
|
||||
connection_name(conn, name, sizeof(name));
|
||||
|
||||
msg.whack_key = TRUE;
|
||||
msg.pubkey_alg = PUBKEY_ALG_RSA;
|
||||
if (end->rsakey)
|
||||
{
|
||||
/* special values to ignore */
|
||||
if (streq(end->rsakey, "")
|
||||
|| streq(end->rsakey, "%none")
|
||||
|| streq(end->rsakey, "%cert")
|
||||
|| streq(end->rsakey, "0x00"))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
err = atobytes(end->rsakey, 0, keyspace, sizeof(keyspace), &msg.keyval.len);
|
||||
if (err)
|
||||
{
|
||||
DBG1(DBG_APP, "conn %s/%s: rsakey malformed [%s]", name, lr, err);
|
||||
return 1;
|
||||
}
|
||||
if (end->id)
|
||||
{
|
||||
msg.keyid = end->id;
|
||||
}
|
||||
else
|
||||
{
|
||||
addrtot(&end->addr, 0, buf, sizeof(buf));
|
||||
msg.keyid = buf;
|
||||
}
|
||||
msg.keyval.ptr = keyspace;
|
||||
return send_whack_msg(&msg);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int starter_whack_add_conn(starter_conn_t *conn)
|
||||
{
|
||||
char esp_buf[256], name[32];
|
||||
whack_message_t msg;
|
||||
int r;
|
||||
|
||||
init_whack_msg(&msg);
|
||||
|
||||
msg.whack_connection = TRUE;
|
||||
msg.name = connection_name(conn, name, sizeof(name));
|
||||
|
||||
msg.ikev1 = conn->keyexchange == KEY_EXCHANGE_IKEV1;
|
||||
msg.addr_family = conn->addr_family;
|
||||
msg.tunnel_addr_family = conn->tunnel_addr_family;
|
||||
msg.sa_ike_life_seconds = conn->sa_ike_life_seconds;
|
||||
msg.sa_ipsec_life_seconds = conn->sa_ipsec_life_seconds;
|
||||
msg.sa_rekey_margin = conn->sa_rekey_margin;
|
||||
msg.sa_rekey_fuzz = conn->sa_rekey_fuzz;
|
||||
msg.sa_keying_tries = conn->sa_keying_tries;
|
||||
msg.policy = conn->policy;
|
||||
msg.xauth_identity = conn->xauth_identity;
|
||||
msg.reqid = conn->reqid;
|
||||
msg.mark_in.value = conn->mark_in.value;
|
||||
msg.mark_in.mask = conn->mark_in.mask;
|
||||
msg.mark_out.value = conn->mark_out.value;
|
||||
msg.mark_out.mask = conn->mark_out.mask;
|
||||
|
||||
/*
|
||||
* Make sure the IKEv2-only policy bits are unset for IKEv1 connections
|
||||
*/
|
||||
msg.policy &= ~POLICY_DONT_REAUTH;
|
||||
msg.policy &= ~POLICY_BEET;
|
||||
msg.policy &= ~POLICY_MOBIKE;
|
||||
msg.policy &= ~POLICY_FORCE_ENCAP;
|
||||
|
||||
set_whack_end(&msg.left, &conn->left, conn->addr_family);
|
||||
set_whack_end(&msg.right, &conn->right, conn->addr_family);
|
||||
|
||||
msg.esp = conn->esp;
|
||||
msg.ike = conn->ike;
|
||||
msg.pfsgroup = conn->pfsgroup;
|
||||
|
||||
/* taken from pluto/whack.c */
|
||||
if (msg.pfsgroup)
|
||||
{
|
||||
snprintf(esp_buf, sizeof (esp_buf), "%s;%s"
|
||||
, msg.esp ? msg.esp : ""
|
||||
, msg.pfsgroup ? msg.pfsgroup : "");
|
||||
msg.esp = esp_buf;
|
||||
|
||||
DBG2(DBG_APP, "Setting --esp=%s", msg.esp);
|
||||
}
|
||||
msg.dpd_delay = conn->dpd_delay;
|
||||
msg.dpd_timeout = conn->dpd_timeout;
|
||||
msg.dpd_action = conn->dpd_action;
|
||||
/* msg.dpd_count = conn->dpd_count; not supported yet by strongSwan */
|
||||
|
||||
r = send_whack_msg(&msg);
|
||||
|
||||
if (r == 0 && (conn->policy & POLICY_PUBKEY))
|
||||
{
|
||||
r += starter_whack_add_pubkey (conn, &conn->left, "left");
|
||||
r += starter_whack_add_pubkey (conn, &conn->right, "right");
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int starter_whack_del_conn(starter_conn_t *conn)
|
||||
{
|
||||
char name[32];
|
||||
whack_message_t msg;
|
||||
|
||||
init_whack_msg(&msg);
|
||||
msg.whack_delete = TRUE;
|
||||
msg.name = connection_name(conn, name, sizeof(name));
|
||||
return send_whack_msg(&msg);
|
||||
}
|
||||
|
||||
int starter_whack_route_conn(starter_conn_t *conn)
|
||||
{
|
||||
char name[32];
|
||||
whack_message_t msg;
|
||||
|
||||
init_whack_msg(&msg);
|
||||
msg.whack_route = TRUE;
|
||||
msg.name = connection_name(conn, name, sizeof(name));
|
||||
return send_whack_msg(&msg);
|
||||
}
|
||||
|
||||
int starter_whack_initiate_conn(starter_conn_t *conn)
|
||||
{
|
||||
char name[32];
|
||||
whack_message_t msg;
|
||||
|
||||
init_whack_msg(&msg);
|
||||
msg.whack_initiate = TRUE;
|
||||
msg.whack_async = TRUE;
|
||||
msg.name = connection_name(conn, name, sizeof(name));
|
||||
return send_whack_msg(&msg);
|
||||
}
|
||||
|
||||
int starter_whack_listen(void)
|
||||
{
|
||||
whack_message_t msg;
|
||||
init_whack_msg(&msg);
|
||||
msg.whack_listen = TRUE;
|
||||
return send_whack_msg(&msg);
|
||||
}
|
||||
|
||||
int starter_whack_shutdown(void)
|
||||
{
|
||||
whack_message_t msg;
|
||||
|
||||
init_whack_msg(&msg);
|
||||
msg.whack_shutdown = TRUE;
|
||||
return send_whack_msg(&msg);
|
||||
}
|
||||
|
||||
int starter_whack_add_ca(starter_ca_t *ca)
|
||||
{
|
||||
whack_message_t msg;
|
||||
|
||||
init_whack_msg(&msg);
|
||||
|
||||
msg.whack_ca = TRUE;
|
||||
msg.name = ca->name;
|
||||
msg.cacert = ca->cacert;
|
||||
msg.ldaphost = ca->ldaphost;
|
||||
msg.ldapbase = ca->ldapbase;
|
||||
msg.crluri = ca->crluri;
|
||||
msg.crluri2 = ca->crluri2;
|
||||
msg.ocspuri = ca->ocspuri;
|
||||
msg.whack_strict = ca->strict;
|
||||
|
||||
return send_whack_msg(&msg);
|
||||
}
|
||||
|
||||
int starter_whack_del_ca(starter_ca_t *ca)
|
||||
{
|
||||
whack_message_t msg;
|
||||
|
||||
init_whack_msg(&msg);
|
||||
|
||||
msg.whack_delete = TRUE;
|
||||
msg.whack_ca = TRUE;
|
||||
msg.name = ca->name;
|
||||
|
||||
return send_whack_msg(&msg);
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
/* FreeS/WAN whack functions to communicate with pluto (whack.h)
|
||||
* Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef _STARTER_WHACK_H_
|
||||
#define _STARTER_WHACK_H_
|
||||
|
||||
#include "confread.h"
|
||||
|
||||
extern int starter_whack_add_conn(starter_conn_t *conn);
|
||||
extern int starter_whack_del_conn(starter_conn_t *conn);
|
||||
extern int starter_whack_route_conn(starter_conn_t *conn);
|
||||
extern int starter_whack_initiate_conn(starter_conn_t *conn);
|
||||
extern int starter_whack_listen(void);
|
||||
extern int starter_whack_shutdown(void);
|
||||
extern int starter_whack_add_ca(starter_ca_t *ca);
|
||||
extern int starter_whack_del_ca(starter_ca_t *ca);
|
||||
|
||||
#endif /* _STARTER_WHACK_H_ */
|
||||
|
Loading…
Reference in New Issue