aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libcharon/plugins/ha/ha_cache.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/src/libcharon/plugins/ha/ha_cache.c b/src/libcharon/plugins/ha/ha_cache.c
index a7ddc28cc..970a8a2b9 100644
--- a/src/libcharon/plugins/ha/ha_cache.c
+++ b/src/libcharon/plugins/ha/ha_cache.c
@@ -203,9 +203,24 @@ static status_t rekey_children(ike_sa_t *ike_sa)
enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
while (enumerator->enumerate(enumerator, (void**)&child_sa))
{
- DBG1(DBG_CFG, "resyncing CHILD_SA");
- status = ike_sa->rekey_child_sa(ike_sa, child_sa->get_protocol(child_sa),
- child_sa->get_spi(child_sa, TRUE));
+ if (ike_sa->supports_extension(ike_sa, EXT_MS_WINDOWS) &&
+ ike_sa->has_condition(ike_sa, COND_NAT_THERE))
+ {
+ /* NATed Windows clients don't accept CHILD_SA rekeying, but fail
+ * with an "invalid situation" error. We just close the CHILD_SA,
+ * Windows will reestablish it immediately if required. */
+ DBG1(DBG_CFG, "resyncing CHILD_SA using a delete");
+ status = ike_sa->delete_child_sa(ike_sa,
+ child_sa->get_protocol(child_sa),
+ child_sa->get_spi(child_sa, TRUE));
+ }
+ else
+ {
+ DBG1(DBG_CFG, "resyncing CHILD_SA using a rekey");
+ status = ike_sa->rekey_child_sa(ike_sa,
+ child_sa->get_protocol(child_sa),
+ child_sa->get_spi(child_sa, TRUE));
+ }
if (status == DESTROY_ME)
{
break;