Hello,
Please find attached some of the patches we have applied.
The goal is mainly to ease integration with our build environment
patch-0000-ha-flush-segment -> Add a command to flush all the SA of a HA segment
patch-0001-alert-initial-contact -> Add an alert to listen to INITIAL CONTACT
events
patch-0002-libhydra-flush-only-managed-sas -> do not flush everything but only
managed SA types (AH, ESP, IPCOMP) -> Leave intact SA inserted by other daemons
like bird.
patch-0003-ha-fifo-sanity-checks -> Add some checks on the HA ctl file
patch-0004-ha-sync-delay -> Already in a branch on github. The goal is to
request a sync only once the configuration has been completely reloaded.
patch-0005-disable-backtrace-use -> Condition "backtrace" since we do not have
backtrace available on our systems
patch-0006-fix-compile-warnings -> Fix some of the warnings we got on our
toolchain
patch-0007-kernel_pfroute-virtual-ip-option -> implement the install_virtual_ip
option for the kernel_pfroute plugin
We have other patches mainly on config reload but they seem to change
strongSwan's current behavior too much to be integrated.
Please feel free to integrate/modify what you may consider useful for others.
Best Regards,
Emeric
diff --git src/libcharon/bus/bus.h src/libcharon/bus/bus.h
index 4e76156..1d1c4fd 100644
--- src/libcharon/bus/bus.h
+++ src/libcharon/bus/bus.h
@@ -157,6 +157,10 @@ enum alert_t {
ALERT_INITIAL_CONTACT_RECEIVED,
/** Initial contact sent, no argument */
ALERT_INITIAL_CONTACT_SENT,
+ /** Configuration reload started, no argument */
+ ALERT_CONF_RELOAD_STARTED,
+ /** Configuration reload finished, no argument */
+ ALERT_CONF_RELOAD_FINISHED,
};
/**
diff --git src/libcharon/plugins/ha/ha_cache.c src/libcharon/plugins/ha/ha_cache.c
index 72edb12..686034f 100644
--- src/libcharon/plugins/ha/ha_cache.c
+++ src/libcharon/plugins/ha/ha_cache.c
@@ -61,6 +61,11 @@ struct private_ha_cache_t {
* Mutex to lock cache
*/
mutex_t *mutex;
+
+ /**
+ * Sync configuration on config reload
+ */
+ bool sync;
};
/**
@@ -408,6 +413,23 @@ static job_requeue_t request_resync(private_ha_cache_t *this)
return JOB_REQUEUE_NONE;
}
+METHOD(listener_t, alert_hook, bool,
+ private_ha_cache_t *this, ike_sa_t *ike_sa, alert_t alert, va_list args)
+{
+ if (alert == ALERT_CONF_RELOAD_FINISHED)
+ {
+ if (this->sync)
+ {
+ lib->processor->queue_job(lib->processor, (job_t*)
+ callback_job_create_with_prio((callback_job_cb_t)request_resync,
+ this, NULL, NULL, JOB_PRIO_CRITICAL));
+ }
+ /* Request sync only after the first configuration load */
+ return FALSE;
+ }
+ return TRUE;
+}
+
METHOD(ha_cache_t, destroy, void,
private_ha_cache_t *this)
{
@@ -426,6 +448,9 @@ ha_cache_t *ha_cache_create(ha_kernel_t *kernel, ha_socket_t *socket,
INIT(this,
.public = {
+ .listener = {
+ .alert = _alert_hook,
+ },
.cache = _cache,
.delete = _delete_,
.resync = _resync,
@@ -438,14 +463,8 @@ ha_cache_t *ha_cache_create(ha_kernel_t *kernel, ha_socket_t *socket,
.tunnel = tunnel,
.cache = hashtable_create(hashtable_hash_ptr, hashtable_equals_ptr, 8),
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ .sync = sync,
);
- if (sync)
- {
- /* request a resync as soon as we are up */
- lib->scheduler->schedule_job(lib->scheduler, (job_t*)
- callback_job_create_with_prio((callback_job_cb_t)request_resync,
- this, NULL, NULL, JOB_PRIO_CRITICAL), 1);
- }
return &this->public;
}
diff --git src/libcharon/plugins/ha/ha_cache.h src/libcharon/plugins/ha/ha_cache.h
index 761c270..64be02b 100644
--- src/libcharon/plugins/ha/ha_cache.h
+++ src/libcharon/plugins/ha/ha_cache.h
@@ -37,6 +37,11 @@ typedef struct ha_cache_t ha_cache_t;
struct ha_cache_t {
/**
+ * Implements listener interface to catch reload events
+ */
+ listener_t listener;
+
+ /**
* Cache an IKE specific message.
*
* @param ike_sa associated IKE_SA
diff --git src/libcharon/plugins/ha/ha_plugin.c src/libcharon/plugins/ha/ha_plugin.c
index 037b69b..48086eb 100644
--- src/libcharon/plugins/ha/ha_plugin.c
+++ src/libcharon/plugins/ha/ha_plugin.c
@@ -167,6 +167,7 @@ static bool plugin_cb(private_ha_plugin_t *this,
charon->bus->add_listener(charon->bus, &this->segments->listener);
charon->bus->add_listener(charon->bus, &this->ike->listener);
charon->bus->add_listener(charon->bus, &this->child->listener);
+ charon->bus->add_listener(charon->bus, &this->cache->listener);
charon->attributes->add_provider(charon->attributes,
&this->attr->provider);
}
@@ -177,6 +178,7 @@ static bool plugin_cb(private_ha_plugin_t *this,
charon->bus->remove_listener(charon->bus, &this->segments->listener);
charon->bus->remove_listener(charon->bus, &this->ike->listener);
charon->bus->remove_listener(charon->bus, &this->child->listener);
+ charon->bus->remove_listener(charon->bus, &this->cache->listener);
}
return TRUE;
}
diff --git src/libcharon/plugins/stroke/stroke_socket.c src/libcharon/plugins/stroke/stroke_socket.c
index db7e66f..e8d6c0b 100644
--- src/libcharon/plugins/stroke/stroke_socket.c
+++ src/libcharon/plugins/stroke/stroke_socket.c
@@ -730,6 +730,14 @@ static bool on_accept(private_stroke_socket_t *this, stream_t *stream)
case STR_COUNTERS:
stroke_counters(this, msg, out);
break;
+ case STR_CONF_RELOAD_START:
+ DBG1(DBG_CFG, "received stroke conf reload start");
+ charon->bus->alert(charon->bus, ALERT_CONF_RELOAD_STARTED);
+ break;
+ case STR_CONF_RELOAD_END:
+ DBG1(DBG_CFG, "received stroke conf reload end");
+ charon->bus->alert(charon->bus, ALERT_CONF_RELOAD_FINISHED);
+ break;
default:
DBG1(DBG_CFG, "received unknown stroke");
break;
diff --git src/starter/starter.c src/starter/starter.c
index a192989..adef7c2 100644
--- src/starter/starter.c
+++ src/starter/starter.c
@@ -712,6 +712,11 @@ int main (int argc, char **argv)
exit(LSB_RC_SUCCESS);
}
+ if (starter_charon_pid())
+ {
+ starter_stroke_config_reload_start();
+ }
+
/*
* Delete all connections. Will be added below
*/
@@ -855,6 +860,7 @@ int main (int argc, char **argv)
}
_action_ &= ~FLAG_ACTION_START_CHARON;
+ starter_stroke_config_reload_start();
for (ca = cfg->ca_first; ca; ca = ca->next)
{
if (ca->state == STATE_ADDED)
@@ -920,6 +926,7 @@ int main (int argc, char **argv)
}
}
}
+ starter_stroke_config_reload_end();
}
/*
diff --git src/starter/starterstroke.c src/starter/starterstroke.c
index 79a92cd..009680d 100644
--- src/starter/starterstroke.c
+++ src/starter/starterstroke.c
@@ -133,6 +133,22 @@ static char* connection_name(starter_conn_t *conn)
return conn->name;
}
+int starter_stroke_config_reload_start()
+{
+ stroke_msg_t *msg;
+
+ msg = create_stroke_msg(STR_CONF_RELOAD_START);
+ return send_stroke_msg(msg);
+}
+
+int starter_stroke_config_reload_end()
+{
+ stroke_msg_t *msg;
+
+ msg = create_stroke_msg(STR_CONF_RELOAD_END);
+ return send_stroke_msg(msg);
+}
+
static void add_end(stroke_msg_t **msg, size_t offset, starter_end_t *conn_end)
{
stroke_end_t *msg_end;
diff --git src/starter/starterstroke.h src/starter/starterstroke.h
index 1264863..ddb335d 100644
--- src/starter/starterstroke.h
+++ src/starter/starterstroke.h
@@ -18,6 +18,8 @@
#include "confread.h"
+int starter_stroke_config_reload_start();
+int starter_stroke_config_reload_end();
int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn);
int starter_stroke_del_conn(starter_conn_t *conn);
int starter_stroke_route_conn(starter_conn_t *conn);
diff --git src/stroke/stroke_msg.h src/stroke/stroke_msg.h
index 17f8a43..7b4d925 100644
--- src/stroke/stroke_msg.h
+++ src/stroke/stroke_msg.h
@@ -227,6 +227,10 @@ struct stroke_msg_t {
STR_USER_CREDS,
/* print/reset counters */
STR_COUNTERS,
+ /*Â notify a config reload start */
+ STR_CONF_RELOAD_START,
+ /* notify a config reload end */
+ STR_CONF_RELOAD_END,
/* more to come */
} type;
diff --git src/libcharon/bus/bus.h src/libcharon/bus/bus.h
index b6757b1..4e76156 100644
--- src/libcharon/bus/bus.h
+++ src/libcharon/bus/bus.h
@@ -153,6 +153,10 @@ enum alert_t {
ALERT_CERT_EXCEEDED_PATH_LEN,
/** Certificate rejected; other policy violation, certificate_t */
ALERT_CERT_POLICY_VIOLATION,
+ /** Initial contact received, no argument */
+ ALERT_INITIAL_CONTACT_RECEIVED,
+ /** Initial contact sent, no argument */
+ ALERT_INITIAL_CONTACT_SENT,
};
/**
diff --git src/libcharon/sa/ikev2/tasks/ike_auth.c src/libcharon/sa/ikev2/tasks/ike_auth.c
index 2554496..199544c 100644
--- src/libcharon/sa/ikev2/tasks/ike_auth.c
+++ src/libcharon/sa/ikev2/tasks/ike_auth.c
@@ -471,6 +471,7 @@ METHOD(task_t, build_i, status_t,
idi, idr, host->get_family(host)))
{
message->add_notify(message, FALSE, INITIAL_CONTACT, chunk_empty);
+ charon->bus->alert(charon->bus, ALERT_INITIAL_CONTACT_SENT);
}
}
@@ -652,6 +653,7 @@ METHOD(task_t, process_r, status_t,
message->get_notify(message, INITIAL_CONTACT))
{
this->initial_contact = TRUE;
+ charon->bus->alert(charon->bus, ALERT_INITIAL_CONTACT_RECEIVED);
}
/* another auth round done, invoke authorize hook */
diff --git src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
index 3b32ba5..c06f2cb 100644
--- src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
+++ src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
@@ -2073,36 +2073,60 @@ METHOD(kernel_ipsec_t, del_sa, status_t,
return SUCCESS;
}
+typedef struct pfkey_satype_t pfkey_satype_t;
+
+struct pfkey_satype_t
+{
+ u_int8_t satype;
+ const char *name;
+};
+
+/* These are the satypes we manage.
+ */
+const pfkey_satype_t pfkey_managed_satypes[] =
+{
+ { SADB_SATYPE_AH, "AH" },
+ { SADB_SATYPE_ESP, "ESP" },
+ { SADB_X_SATYPE_IPCOMP, "IPCOMP" },
+};
+
METHOD(kernel_ipsec_t, flush_sas, status_t,
private_kernel_pfkey_ipsec_t *this)
{
unsigned char request[PFKEY_BUFFER_SIZE];
struct sadb_msg *msg, *out;
size_t len;
+ int i;
memset(&request, 0, sizeof(request));
- DBG2(DBG_KNL, "flushing all SAD entries");
+ for (i = 0; i < countof(pfkey_managed_satypes); i++)
+ {
+ DBG2(DBG_KNL, "flushing all SAD entries for satype: %s",
+ pfkey_managed_satypes[i].name);
msg = (struct sadb_msg*)request;
msg->sadb_msg_version = PF_KEY_V2;
msg->sadb_msg_type = SADB_FLUSH;
- msg->sadb_msg_satype = SADB_SATYPE_UNSPEC;
+ msg->sadb_msg_satype = pfkey_managed_satypes[i].satype;
msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
if (pfkey_send(this, msg, &out, &len) != SUCCESS)
{
- DBG1(DBG_KNL, "unable to flush SAD entries");
+ DBG1(DBG_KNL, "unable to flush SAD entries for satype: %s",
+ pfkey_managed_satypes[i].name);
return FAILED;
}
else if (out->sadb_msg_errno)
{
- DBG1(DBG_KNL, "unable to flush SAD entries: %s (%d)",
- strerror(out->sadb_msg_errno), out->sadb_msg_errno);
+ DBG1(DBG_KNL, "unable to flush SAD entries: %s (%d) for satype: %s",
+ strerror(out->sadb_msg_errno), out->sadb_msg_errno,
+ pfkey_managed_satypes[i].name);
free(out);
return FAILED;
}
free(out);
+ }
return SUCCESS;
}
diff --git src/libcharon/plugins/ha/ha_ctl.c src/libcharon/plugins/ha/ha_ctl.c
index 0b86834..7b62298 100644
--- src/libcharon/plugins/ha/ha_ctl.c
+++ src/libcharon/plugins/ha/ha_ctl.c
@@ -59,6 +59,7 @@ static job_requeue_t dispatch_fifo(private_ha_ctl_t *this)
bool oldstate;
char buf[8];
u_int segment;
+ struct stat sb;
oldstate = thread_cancelability(TRUE);
fifo = open(HA_FIFO, O_RDONLY);
@@ -69,6 +70,13 @@ static job_requeue_t dispatch_fifo(private_ha_ctl_t *this)
sleep(1);
return JOB_REQUEUE_FAIR;
}
+ if (fstat(fifo, &sb) != 0 || !S_ISFIFO(sb.st_mode))
+ {
+ DBG1(DBG_CFG, "error: %s is not a FIFO", HA_FIFO);
+ sleep(1);
+ /* XXX recreate it? */
+ return JOB_REQUEUE_FAIR;
+ }
memset(buf, 0, sizeof(buf));
if (read(fifo, buf, sizeof(buf)-1) > 1)
@@ -103,6 +111,7 @@ static job_requeue_t dispatch_fifo(private_ha_ctl_t *this)
METHOD(ha_ctl_t, destroy, void,
private_ha_ctl_t *this)
{
+ unlink(HA_FIFO);
free(this);
}
@@ -113,6 +122,7 @@ ha_ctl_t *ha_ctl_create(ha_segments_t *segments, ha_cache_t *cache)
{
private_ha_ctl_t *this;
mode_t old;
+ struct stat sb;
INIT(this,
.public = {
@@ -122,8 +132,15 @@ ha_ctl_t *ha_ctl_create(ha_segments_t *segments, ha_cache_t *cache)
.cache = cache,
);
- if (access(HA_FIFO, R_OK|W_OK) != 0)
+ /* Just a little sanity check.
+ * Note: Yes, 'TOCTOU' is possible but it doesn't matter
+ */
+ if (access(HA_FIFO, R_OK|W_OK) != 0
+ || (stat(HA_FIFO, &sb) == 0 && !S_ISFIFO(sb.st_mode)))
{
+ DBG1(DBG_CFG, "Access to %s as HA FIFO is not granted, delete it", HA_FIFO);
+ unlink(HA_FIFO);
+
old = umask(S_IRWXO);
if (mkfifo(HA_FIFO, S_IRUSR | S_IWUSR) != 0)
{
@@ -139,6 +156,9 @@ ha_ctl_t *ha_ctl_create(ha_segments_t *segments, ha_cache_t *cache)
strerror(errno));
}
+ /* XXX On mkfifo/chown error,
+ * should we run queue_job or not (like in the UCI plugin)?
+ */
lib->processor->queue_job(lib->processor,
(job_t*)callback_job_create_with_prio((callback_job_cb_t)dispatch_fifo,
this, NULL, (callback_job_cancel_t)return_false, JOB_PRIO_CRITICAL));
diff --git src/starter/invokecharon.c src/starter/invokecharon.c
index 5d95305..00d573a 100644
--- src/starter/invokecharon.c
+++ src/starter/invokecharon.c
@@ -97,6 +97,7 @@ int starter_stop_charon (void)
}
usleep(200000); /* sleep for 200 ms */
}
+ unlink(CHARON_CTL_FILE);
if (_charon_pid == 0)
{
DBG1(DBG_APP, "%s stopped after %d ms", daemon_name, 200*i);
diff --git src/libcharon/encoding/payloads/fragment_payload.c src/libcharon/encoding/payloads/fragment_payload.c
index b861fcc..7f158f5 100644
--- src/libcharon/encoding/payloads/fragment_payload.c
+++ src/libcharon/encoding/payloads/fragment_payload.c
@@ -222,4 +222,4 @@ fragment_payload_t *fragment_payload_create_from_data(u_int8_t num, bool last,
this->data = chunk_clone(data);
this->payload_length = get_header_length(this) + data.len;
return &this->public;
-}
\ No newline at end of file
+}
diff --git src/libcharon/plugins/error_notify/error_notify_listener.c src/libcharon/plugins/error_notify/error_notify_listener.c
index 13860fe..f7a1f49 100644
--- src/libcharon/plugins/error_notify/error_notify_listener.c
+++ src/libcharon/plugins/error_notify/error_notify_listener.c
@@ -96,13 +96,13 @@ METHOD(listener_t, alert, bool,
case ALERT_PROPOSAL_MISMATCH_IKE:
msg.type = htonl(ERROR_NOTIFY_PROPOSAL_MISMATCH_IKE);
list = va_arg(args, linked_list_t*);
- snprintf(msg.str, sizeof(msg.str), "the received IKE_SA poposals "
+ snprintf(msg.str, sizeof(msg.str), "the received IKE_SA proposals "
"did not match: %#P", list);
break;
case ALERT_PROPOSAL_MISMATCH_CHILD:
msg.type = htonl(ERROR_NOTIFY_PROPOSAL_MISMATCH_CHILD);
list = va_arg(args, linked_list_t*);
- snprintf(msg.str, sizeof(msg.str), "the received CHILD_SA poposals "
+ snprintf(msg.str, sizeof(msg.str), "the received CHILD_SA proposals "
"did not match: %#P", list);
break;
case ALERT_TS_MISMATCH:
@@ -153,14 +153,14 @@ METHOD(listener_t, alert, bool,
msg.type = htonl(ERROR_NOTIFY_CERT_EXPIRED);
cert = va_arg(args, certificate_t*);
cert->get_validity(cert, NULL, ¬_before, ¬_after);
- snprintf(msg.str, sizeof(msg.str), "certificiate expired: '%Y' "
+ snprintf(msg.str, sizeof(msg.str), "certificate expired: '%Y' "
"(valid from %T to %T)", cert->get_subject(cert),
¬_before, TRUE, ¬_after, TRUE);
break;
case ALERT_CERT_REVOKED:
msg.type = htonl(ERROR_NOTIFY_CERT_REVOKED);
cert = va_arg(args, certificate_t*);
- snprintf(msg.str, sizeof(msg.str), "certificiate revoked: '%Y'",
+ snprintf(msg.str, sizeof(msg.str), "certificate revoked: '%Y'",
cert->get_subject(cert));
break;
case ALERT_CERT_NO_ISSUER:
diff --git src/libcharon/plugins/load_tester/load_tester.c src/libcharon/plugins/load_tester/load_tester.c
index b7b971e..f5a998e 100644
--- src/libcharon/plugins/load_tester/load_tester.c
+++ src/libcharon/plugins/load_tester/load_tester.c
@@ -21,6 +21,7 @@
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <errno.h>
/**
diff --git src/libcharon/plugins/vici/vici_control.c src/libcharon/plugins/vici/vici_control.c
index 01d5036..408d299 100644
--- src/libcharon/plugins/vici/vici_control.c
+++ src/libcharon/plugins/vici/vici_control.c
@@ -138,7 +138,7 @@ static child_cfg_t* find_child_cfg(char *name, peer_cfg_t **out)
{
enumerator_t *enumerator;
peer_cfg_t *peer_cfg;
- child_cfg_t *child_cfg;
+ child_cfg_t *child_cfg = NULL;
enumerator = charon->backends->create_peer_cfg_enumerator(
charon->backends, NULL, NULL, NULL, NULL, IKE_ANY);
diff --git src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c
index 151b497..2284a48 100644
--- src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c
+++ src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c
@@ -321,7 +321,7 @@ METHOD(authenticator_t, build, status_t,
chunk_t auth_data;
status_t status;
auth_payload_t *auth_payload;
- auth_method_t auth_method;
+ auth_method_t auth_method = AUTH_NONE;
id = this->ike_sa->get_my_id(this->ike_sa);
auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
diff --git src/libstrongswan/credentials/certificates/ocsp_request.h src/libstrongswan/credentials/certificates/ocsp_request.h
index 0b18713..730d95d 100644
--- src/libstrongswan/credentials/certificates/ocsp_request.h
+++ src/libstrongswan/credentials/certificates/ocsp_request.h
@@ -31,7 +31,7 @@ typedef struct ocsp_request_t ocsp_request_t;
struct ocsp_request_t {
/**
- * Implements certificiate_t interface
+ * Implements certificate_t interface
*/
certificate_t interface;
};
diff --git src/libstrongswan/credentials/certificates/ocsp_response.h src/libstrongswan/credentials/certificates/ocsp_response.h
index 1575774..9c5637b 100644
--- src/libstrongswan/credentials/certificates/ocsp_response.h
+++ src/libstrongswan/credentials/certificates/ocsp_response.h
@@ -50,7 +50,7 @@ extern enum_name_t *ocsp_status_names;
struct ocsp_response_t {
/**
- * Implements certificiate_t interface
+ * Implements certificate_t interface
*/
certificate_t certificate;
diff --git src/libstrongswan/plugins/openssl/openssl_util.c src/libstrongswan/plugins/openssl/openssl_util.c
index 0e61086..ca4e7fb 100644
--- src/libstrongswan/plugins/openssl/openssl_util.c
+++ src/libstrongswan/plugins/openssl/openssl_util.c
@@ -148,7 +148,7 @@ chunk_t openssl_asn1_obj2chunk(ASN1_OBJECT *asn1)
{
if (asn1)
{
- return chunk_create((u_char*)asn1->data, asn1->length);
+ return chunk_create((u_char*)(uintptr_t)(const void*)asn1->data, asn1->length);
}
return chunk_empty;
}
diff --git src/libstrongswan/plugins/plugin_feature.c src/libstrongswan/plugins/plugin_feature.c
index 2d0ce8a..70eafe1 100644
--- src/libstrongswan/plugins/plugin_feature.c
+++ src/libstrongswan/plugins/plugin_feature.c
@@ -59,7 +59,7 @@ ENUM(plugin_feature_names, FEATURE_NONE, FEATURE_CUSTOM,
*/
u_int32_t plugin_feature_hash(plugin_feature_t *feature)
{
- chunk_t data;
+ chunk_t data = {0};
switch (feature->type)
{
diff --git src/libstrongswan/threading/mutex.c src/libstrongswan/threading/mutex.c
index 10cf045..985883a 100644
--- src/libstrongswan/threading/mutex.c
+++ src/libstrongswan/threading/mutex.c
@@ -128,14 +128,14 @@ METHOD(mutex_t, lock_r, void,
{
thread_t *self = thread_current();
- if (cas_ptr(&this->thread, self, self))
+ if (cas_ptr((void **)&this->thread, self, self))
{
this->times++;
}
else
{
lock(&this->generic);
- cas_ptr(&this->thread, NULL, self);
+ cas_ptr((void **)&this->thread, NULL, self);
this->times = 1;
}
}
@@ -145,7 +145,7 @@ METHOD(mutex_t, unlock_r, void,
{
if (--this->times == 0)
{
- cas_ptr(&this->thread, thread_current(), NULL);
+ cas_ptr((void **)&this->thread, thread_current(), NULL);
unlock(&this->generic);
}
}
@@ -227,9 +227,9 @@ METHOD(condvar_t, wait_, void,
/* keep track of the number of times this thread locked the mutex */
times = recursive->times;
/* mutex owner gets cleared during condvar wait */
- cas_ptr(&recursive->thread, self, NULL);
+ cas_ptr((void **)&recursive->thread, self, NULL);
pthread_cond_wait(&this->condvar, &mutex->mutex);
- cas_ptr(&recursive->thread, NULL, self);
+ cas_ptr((void **)&recursive->thread, NULL, self);
recursive->times = times;
}
else
@@ -259,10 +259,10 @@ METHOD(condvar_t, timed_wait_abs, bool,
u_int times;
times = recursive->times;
- cas_ptr(&recursive->thread, self, NULL);
+ cas_ptr((void **)&recursive->thread, self, NULL);
timed_out = pthread_cond_timedwait(&this->condvar, &mutex->mutex,
&ts) == ETIMEDOUT;
- cas_ptr(&recursive->thread, NULL, self);
+ cas_ptr((void **)&recursive->thread, NULL, self);
recursive->times = times;
}
else
diff --git src/libstrongswan/utils/utils/string.c src/libstrongswan/utils/utils/string.c
index 14087e7..56910ed 100644
--- src/libstrongswan/utils/utils/string.c
+++ src/libstrongswan/utils/utils/string.c
@@ -44,7 +44,7 @@ char* translate(char *str, const char *from, const char *to)
char* strreplace(const char *str, const char *search, const char *replace)
{
size_t len, slen, rlen, count = 0;
- char *res, *pos, *found, *dst;
+ char *res, *pos, *found = NULL, *dst;
if (!str || !*str || !search || !*search || !replace)
{
diff --git src/starter/parser/conf_parser.h src/starter/parser/conf_parser.h
index 2093820..49131a0 100644
--- src/starter/parser/conf_parser.h
+++ src/starter/parser/conf_parser.h
@@ -119,4 +119,4 @@ struct conf_parser_t {
*/
conf_parser_t *conf_parser_create(const char *file);
-#endif /** CONF_PARSER_H_ @}*/
\ No newline at end of file
+#endif /** CONF_PARSER_H_ @}*/
diff --git configure.ac configure.ac
index 65098d7..5d2de38 100644
--- configure.ac
+++ configure.ac
@@ -283,6 +283,7 @@ ARG_ENABL_SET([systemd], [enable systemd specific IKE daemon charon-syste
ARG_ENABL_SET([swanctl], [enable swanctl configuration and control tool.])
ARG_ENABL_SET([tkm], [enable Trusted Key Manager support.])
# optional features
+ARG_DISBL_SET([backtraces], [disable backtraces use.])
ARG_ENABL_SET([bfd-backtraces], [use binutils libbfd to resolve backtraces for memory leaks and segfaults.])
ARG_ENABL_SET([dbghelp-backtraces],[use dbghlp.dll on Windows to create and print backtraces for memory leaks and segfaults.])
ARG_DISBL_SET([ikev1], [disable IKEv1 protocol support in charon.])
@@ -461,10 +462,12 @@ AC_SEARCH_LIBS(dlopen, dl, [DLLIB=$LIBS])
AC_SUBST(DLLIB)
# glibc's backtrace() can be replicated on FreeBSD with libexecinfo
-LIBS=""
-AC_SEARCH_LIBS(backtrace, execinfo, [BTLIB=$LIBS])
-AC_CHECK_FUNCS(backtrace)
-AC_SUBST(BTLIB)
+if test x$backtraces = xtrue; then
+ LIBS=""
+ AC_SEARCH_LIBS(backtrace, execinfo, [BTLIB=$LIBS])
+ AC_CHECK_FUNCS(backtrace)
+ AC_SUBST(BTLIB)
+fi
# OpenSolaris needs libsocket and libnsl for socket()
LIBS=""
@@ -1149,20 +1152,22 @@ if test x$integrity_test = xtrue; then
)
fi
-if test x$bfd_backtraces = xtrue; then
+if test x$backtraces = xtrue; then
+ if test x$bfd_backtraces = xtrue; then
AC_CHECK_LIB([bfd],[main],[LIBS="$LIBS"],[AC_MSG_ERROR([binutils libbfd not found!])],[])
AC_CHECK_HEADER([bfd.h],[AC_DEFINE([HAVE_BFD_H],,[have binutils bfd.h])],
[AC_MSG_ERROR([binutils bfd.h header not found!])])
BFDLIB="-lbfd"
AC_SUBST(BFDLIB)
-fi
+ fi
-if test x$unwind_backtraces = xtrue; then
+ if test x$unwind_backtraces = xtrue; then
AC_CHECK_LIB([unwind],[main],[LIBS="$LIBS"],[AC_MSG_ERROR([libunwind not found!])],[])
AC_CHECK_HEADER([libunwind.h],[AC_DEFINE([HAVE_LIBUNWIND_H],,[have libunwind.h])],
[AC_MSG_ERROR([libunwind.h header not found!])])
UNWINDLIB="-lunwind"
AC_SUBST(UNWINDLIB)
+ fi
fi
AM_CONDITIONAL(USE_DEV_HEADERS, [test "x$dev_headers" != xno])
@@ -1548,6 +1553,7 @@ AM_CONDITIONAL(USE_KERNEL_PFROUTE, test x$kernel_pfroute = xtrue)
# other options
# ---------------
+AM_CONDITIONAL(USE_BACKTRACE, test x$backtraces = xtrue)
AM_CONDITIONAL(USE_LEAK_DETECTIVE, test x$leak_detective = xtrue)
AM_CONDITIONAL(USE_LOCK_PROFILER, test x$lock_profiler = xtrue)
AM_CONDITIONAL(USE_DUMM, test x$dumm = xtrue)
@@ -1617,6 +1623,9 @@ fi
if test x$ikev2 = xtrue; then
AC_DEFINE([USE_IKEV2], [], [support for IKEv2 protocol])
fi
+if test x$backtraces = xtrue; then
+ AC_DEFINE([USE_BACKTRACE], [], [support for backtrace])
+fi
# ====================================================
# options for enabled modules (see conf/Makefile.am)
diff --git src/charon-cmd/charon-cmd.c src/charon-cmd/charon-cmd.c
index 6f2b6f1..74ebf30 100644
--- src/charon-cmd/charon-cmd.c
+++ src/charon-cmd/charon-cmd.c
@@ -29,7 +29,9 @@
#include <library.h>
#include <hydra.h>
#include <daemon.h>
+#ifdef USE_BACKTRACE
#include <utils/backtrace.h>
+#endif
#include <threading/thread.h>
#include "cmd/cmd_options.h"
@@ -188,12 +190,14 @@ static bool lookup_uid_gid()
*/
static void segv_handler(int signal)
{
+#ifdef USE_BACKTRACE
backtrace_t *backtrace;
DBG1(DBG_DMN, "thread %u received %d", thread_current_id(), signal);
backtrace = backtrace_create(2);
backtrace->log(backtrace, stderr, TRUE);
backtrace->destroy(backtrace);
+#endif
DBG1(DBG_DMN, "killing ourself, received critical signal");
abort();
diff --git src/charon-nm/charon-nm.c src/charon-nm/charon-nm.c
index 80551f8..76b6909 100644
--- src/charon-nm/charon-nm.c
+++ src/charon-nm/charon-nm.c
@@ -23,7 +23,9 @@
#include <daemon.h>
#include <library.h>
+#ifdef USE_BACKTRACE
#include <utils/backtrace.h>
+#endif
#include <threading/thread.h>
#include <nm/nm_backend.h>
@@ -116,12 +118,14 @@ static void run()
*/
static void segv_handler(int signal)
{
+#ifdef USE_BACKTRACE
backtrace_t *backtrace;
DBG1(DBG_DMN, "thread %u received %d", thread_current_id(), signal);
backtrace = backtrace_create(2);
backtrace->log(backtrace, stderr, TRUE);
backtrace->destroy(backtrace);
+#endif
DBG1(DBG_DMN, "killing ourself, received critical signal");
abort();
diff --git src/charon-svc/charon-svc.c src/charon-svc/charon-svc.c
index 03cbdb8..8b733b5 100644
--- src/charon-svc/charon-svc.c
+++ src/charon-svc/charon-svc.c
@@ -17,7 +17,9 @@
#include <hydra.h>
#include <daemon.h>
+#ifdef USE_BACKTRACE
#include <utils/backtrace.h>
+#endif
#include <threading/thread.h>
/**
diff --git src/charon-tkm/src/charon-tkm.c src/charon-tkm/src/charon-tkm.c
index 7c60f0c..e7a3c2d 100644
--- src/charon-tkm/src/charon-tkm.c
+++ src/charon-tkm/src/charon-tkm.c
@@ -28,7 +28,9 @@
#include <hydra.h>
#include <daemon.h>
#include <library.h>
+#ifdef USE_BACKTRACE
#include <utils/backtrace.h>
+#endif
#include <threading/thread.h>
#include <sa/keymat.h>
#include <credentials/credential_manager.h>
@@ -134,12 +136,14 @@ static void run()
*/
static void segv_handler(int signal)
{
+#ifdef USE_BACKTRACE
backtrace_t *backtrace;
DBG1(DBG_DMN, "thread %u received %d", thread_current_id(), signal);
backtrace = backtrace_create(2);
backtrace->log(backtrace, stderr, TRUE);
backtrace->destroy(backtrace);
+#endif
DBG1(DBG_DMN, "killing ourself, received critical signal");
abort();
diff --git src/charon/charon.c src/charon/charon.c
index 081e494..014595a 100644
--- src/charon/charon.c
+++ src/charon/charon.c
@@ -33,7 +33,9 @@
#include <daemon.h>
#include <library.h>
+#ifdef USE_BACKTRACE
#include <utils/backtrace.h>
+#endif
#include <threading/thread.h>
#ifdef ANDROID
@@ -184,6 +186,7 @@ static bool lookup_uid_gid()
*/
static void segv_handler(int signal)
{
+#ifdef USE_BACKTRACE
backtrace_t *backtrace;
DBG1(DBG_DMN, "thread %u received %d", thread_current_id(), signal);
@@ -191,6 +194,7 @@ static void segv_handler(int signal)
backtrace->log(backtrace, NULL, TRUE);
backtrace->log(backtrace, stderr, TRUE);
backtrace->destroy(backtrace);
+#endif
DBG1(DBG_DMN, "killing ourself, received critical signal");
abort();
diff --git src/libstrongswan/utils/backtrace.c src/libstrongswan/utils/backtrace.c
index 6dd68d6..e64ba88 100644
--- src/libstrongswan/utils/backtrace.c
+++ src/libstrongswan/utils/backtrace.c
@@ -347,6 +347,7 @@ static bfd_entry_t *get_bfd_entry(char *filename)
return NULL;
}
+#if defined(HAVE_BACKTRACE) || defined(HAVE_LIBUNWIND_H) || defined(WIN32)
/**
* Print the source file with line number to file, libbfd variant
*/
@@ -376,12 +377,14 @@ static void print_sourceline(FILE *file, char *filename, void *ptr, void *base)
}
bfd_mutex->unlock(bfd_mutex);
}
+#endif
#else /* !HAVE_BFD_H */
void backtrace_init() {}
void backtrace_deinit() {}
+#if defined(HAVE_BACKTRACE) || defined(HAVE_LIBUNWIND_H) || defined(WIN32)
/**
* Print the source file with line number to file, slow addr2line variant
*/
@@ -417,6 +420,7 @@ static void print_sourceline(FILE *file, char *filename, void *ptr, void* base)
esc(file, TTY_FG_DEF));
}
}
+#endif
#endif /* HAVE_BFD_H */
diff --git src/starter/starter.c src/starter/starter.c
index adef7c2..8d4801c 100644
--- src/starter/starter.c
+++ src/starter/starter.c
@@ -35,7 +35,9 @@
#include <library.h>
#include <hydra.h>
#include <utils/backtrace.h>
+#ifdef USE_BACKTRACE
#include <threading/thread.h>
+#endif
#include <utils/debug.h>
#include "confread.h"
@@ -247,12 +249,14 @@ static void signal_handler(int signal)
*/
static void fatal_signal_handler(int signal)
{
+#ifdef USE_BACKTRACE
backtrace_t *backtrace;
DBG1(DBG_APP, "thread %u received %d", thread_current_id(), signal);
backtrace = backtrace_create(2);
backtrace->log(backtrace, stderr, TRUE);
backtrace->destroy(backtrace);
+#endif
DBG1(DBG_APP, "killing ourself, received critical signal");
abort();
diff --git src/libcharon/plugins/ha/ha_cache.c src/libcharon/plugins/ha/ha_cache.c
index 0650f7f..72edb12 100644
--- src/libcharon/plugins/ha/ha_cache.c
+++ src/libcharon/plugins/ha/ha_cache.c
@@ -342,6 +342,52 @@ METHOD(ha_cache_t, resync, void,
rekey_segment(this, segment);
}
+METHOD(ha_cache_t, flush, void,
+ private_ha_cache_t *this, u_int segment)
+{
+ enumerator_t *enumerator;
+ linked_list_t *delete_list = linked_list_create();
+ ike_sa_id_t *id;
+ ike_sa_t *ike_sa;
+ entry_t *entry;
+
+ DBG1(DBG_CFG, "Flushing HA segment %d", segment);
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->cache->create_enumerator(this->cache);
+ while (enumerator->enumerate(enumerator, &ike_sa, &entry))
+ {
+ if (entry->segment == segment)
+ {
+ id = ike_sa->get_id(ike_sa);
+ delete_list->insert_last(delete_list, id->clone(id));
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ DBG1(DBG_CFG, "%d IKE SA to be deleted", delete_list->get_count(delete_list));
+
+ while (delete_list->remove_last(delete_list, (void**)&id) == SUCCESS)
+ {
+ ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, id);
+
+ if (ike_sa->delete(ike_sa) != DESTROY_ME)
+ {
+ charon->ike_sa_manager->checkin(
+ charon->ike_sa_manager, ike_sa);
+ }
+ else
+ {
+ charon->ike_sa_manager->checkin_and_destroy(
+ charon->ike_sa_manager, ike_sa);
+ }
+ id->destroy(id);
+ }
+ this->mutex->unlock(this->mutex);
+
+ delete_list->destroy(delete_list);
+}
+
/**
* Request a resync of all segments
*/
@@ -383,6 +429,7 @@ ha_cache_t *ha_cache_create(ha_kernel_t *kernel, ha_socket_t *socket,
.cache = _cache,
.delete = _delete_,
.resync = _resync,
+ .flush = _flush,
.destroy = _destroy,
},
.count = count,
diff --git src/libcharon/plugins/ha/ha_cache.h src/libcharon/plugins/ha/ha_cache.h
index 8cfcbb2..761c270 100644
--- src/libcharon/plugins/ha/ha_cache.h
+++ src/libcharon/plugins/ha/ha_cache.h
@@ -59,6 +59,13 @@ struct ha_cache_t {
void (*resync)(ha_cache_t *this, u_int segment);
/**
+ * Flush a segment using
+ *
+ * @param segment segment to flush
+ */
+ void (*flush)(ha_cache_t *this, u_int segment);
+
+ /**
* Destroy a ha_cache_t.
*/
void (*destroy)(ha_cache_t *this);
diff --git src/libcharon/plugins/ha/ha_ctl.c src/libcharon/plugins/ha/ha_ctl.c
index a954997..0b86834 100644
--- src/libcharon/plugins/ha/ha_ctl.c
+++ src/libcharon/plugins/ha/ha_ctl.c
@@ -87,6 +87,9 @@ static job_requeue_t dispatch_fifo(private_ha_ctl_t *this)
case '*':
this->cache->resync(this->cache, segment);
break;
+ case 'F':
+ this->cache->flush(this->cache, segment);
+ break;
default:
break;
}
diff --git src/libcharon/plugins/ha/ha_dispatcher.c src/libcharon/plugins/ha/ha_dispatcher.c
index 31eeb93..4c06d15 100644
--- src/libcharon/plugins/ha/ha_dispatcher.c
+++ src/libcharon/plugins/ha/ha_dispatcher.c
@@ -986,6 +986,29 @@ static void process_resync(private_ha_dispatcher_t *this,
message->destroy(message);
}
+static void process_flush(private_ha_dispatcher_t *this,
+ ha_message_t *message)
+{
+ ha_message_attribute_t attribute;
+ ha_message_value_t value;
+ enumerator_t *enumerator;
+
+ enumerator = message->create_attribute_enumerator(message);
+ while (enumerator->enumerate(enumerator, &attribute, &value))
+ {
+ switch (attribute)
+ {
+ case HA_SEGMENT:
+ this->cache->flush(this->cache, value.u16);
+ break;
+ default:
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ message->destroy(message);
+}
+
/**
* Dispatcher job function
*/
@@ -1039,6 +1062,9 @@ static job_requeue_t dispatch(private_ha_dispatcher_t *this)
case HA_RESYNC:
process_resync(this, message);
break;
+ case HA_FLUSH:
+ process_flush(this, message);
+ break;
default:
DBG1(DBG_CFG, "received unknown HA message type %d", type);
message->destroy(message);
diff --git src/libcharon/plugins/ha/ha_message.c src/libcharon/plugins/ha/ha_message.c
index 6b00ed8..6ccab4b 100644
--- src/libcharon/plugins/ha/ha_message.c
+++ src/libcharon/plugins/ha/ha_message.c
@@ -58,6 +58,7 @@ ENUM(ha_message_type_names, HA_IKE_ADD, HA_IKE_IV,
"SEGMENT_TAKE",
"STATUS",
"RESYNC",
+ "FLUSH",
"IKE_IV",
);
diff --git src/libcharon/plugins/ha/ha_message.h src/libcharon/plugins/ha/ha_message.h
index 2ccb1fc..34eee0d 100644
--- src/libcharon/plugins/ha/ha_message.h
+++ src/libcharon/plugins/ha/ha_message.h
@@ -63,6 +63,8 @@ enum ha_message_type_t {
HA_STATUS,
/** segments the receiving node is requested to resync */
HA_RESYNC,
+ /** segments the receiving node is requested to flush */
+ HA_FLUSH,
/** IV synchronization for IKEv1 Main/Aggressive mode */
HA_IKE_IV,
};
diff --git src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c
index 0f78022..df80c29 100644
--- src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c
+++ src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c
@@ -408,6 +408,11 @@ struct private_kernel_pfroute_net_t
* Time in ms to wait for IP addresses to appear/disappear
*/
int vip_wait;
+
+ /**
+ * whether to actually install virtual IPs
+ */
+ bool install_virtual_ip;
};
@@ -1197,6 +1202,11 @@ METHOD(kernel_net_t, add_ip, status_t,
tun_device_t *tun;
bool timeout = FALSE;
+ if (!this->install_virtual_ip)
+ { /* disabled by config */
+ return SUCCESS;
+ }
+
tun = tun_device_create(NULL);
if (!tun)
{
@@ -1271,6 +1281,11 @@ METHOD(kernel_net_t, del_ip, status_t,
host_t *addr;
bool timeout = FALSE, found = FALSE;
+ if (!this->install_virtual_ip)
+ { /* disabled by config */
+ return SUCCESS;
+ }
+
this->lock->write_lock(this->lock);
enumerator = this->tuns->create_enumerator(this->tuns);
while (enumerator->enumerate(enumerator, &tun))
@@ -1848,6 +1863,8 @@ kernel_pfroute_net_t *kernel_pfroute_net_create()
.roam_lock = spinlock_create(),
.vip_wait = lib->settings->get_int(lib->settings,
"%s.plugins.kernel-pfroute.vip_wait", 1000, lib->ns),
+ .install_virtual_ip = lib->settings->get_bool(lib->settings,
+ "%s.install_virtual_ip", TRUE, lib->ns),
);
timerclear(&this->last_route_reinstall);
timerclear(&this->next_roam);
_______________________________________________
Dev mailing list
[email protected]
https://lists.strongswan.org/mailman/listinfo/dev