diff options
author | Martin Willi <martin@revosec.ch> | 2014-07-11 11:59:01 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2014-08-25 09:53:02 +0200 |
commit | cd9bba508bbacc9e0197f54c4cf20116f59e7974 (patch) | |
tree | f4c78620ac3d09d3d206cc2698a715767464f153 /src | |
parent | 11bf11c1f55402cc08deeb53ee94387afc4a4525 (diff) | |
download | strongswan-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.c | 23 |
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; } |