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, &not_before, &not_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),
 					 &not_before, TRUE, &not_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

Reply via email to