diff options
-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; } |