aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2014-07-11 11:59:01 +0200
committerMartin Willi <martin@revosec.ch>2014-08-25 09:53:02 +0200
commitcd9bba508bbacc9e0197f54c4cf20116f59e7974 (patch)
treef4c78620ac3d09d3d206cc2698a715767464f153 /src
parent11bf11c1f55402cc08deeb53ee94387afc4a4525 (diff)
downloadstrongswan-cd9bba508bbacc9e0197f54c4cf20116f59e7974.tar.bz2
strongswan-cd9bba508bbacc9e0197f54c4cf20116f59e7974.tar.xz
ikev1: Accept Quick Mode DELETES while Quick Mode rekeying is active
If a peer immediately sends DELETE messages when completing Quick Mode rekeying, the third Quick Mode message and the DELETE are sent simultaneously. This implies that DELETE messages may arrive before the completing third Quick Mode message. Handle this case by ignoring the DELETE INFORMATIONAL in Quick Mode and let the delete task handle it.
Diffstat (limited to 'src')
-rw-r--r--src/libcharon/sa/ikev1/tasks/quick_mode.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.c b/src/libcharon/sa/ikev1/tasks/quick_mode.c
index e6273682d..0d6be3881 100644
--- a/src/libcharon/sa/ikev1/tasks/quick_mode.c
+++ b/src/libcharon/sa/ikev1/tasks/quick_mode.c
@@ -1117,11 +1117,22 @@ METHOD(task_t, process_r, status_t,
}
case QM_NEGOTIATED:
{
- if (message->get_exchange_type(message) == INFORMATIONAL_V1 ||
- has_notify_errors(this, message))
+ if (has_notify_errors(this, message))
{
return SUCCESS;
}
+ if (message->get_exchange_type(message) == INFORMATIONAL_V1)
+ {
+ if (message->get_payload(message, PLV1_DELETE))
+ {
+ /* If the DELETE for a Quick Mode follows immediately
+ * after rekeying, we might receive it before the
+ * third completing Quick Mode message. Ignore it, as
+ * it gets handled by a separately queued delete task. */
+ return NEED_MORE;
+ }
+ return SUCCESS;
+ }
if (!install(this))
{
ike_sa_t *ike_sa = this->ike_sa;
@@ -1198,6 +1209,14 @@ METHOD(task_t, build_r, status_t,
this->state = QM_NEGOTIATED;
return NEED_MORE;
}
+ case QM_NEGOTIATED:
+ if (message->get_exchange_type(message) == INFORMATIONAL_V1)
+ {
+ /* skip INFORMATIONAL response if we received a INFORMATIONAL
+ * delete, see process_r() */
+ return ALREADY_DONE;
+ }
+ /* fall */
default:
return FAILED;
}