From 6586f07162a7458902718f5c9a75518f8144ee29 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 28 Oct 2020 15:50:59 +0100 Subject: [PATCH] ikev2: Clear fragments of a retransmitted message if we receive the next one The message_t object used for defragmentation was only cleared after all fragments have been received and the message was delivered. So if we received only some fragments of a retransmitted message, the fragments of the next message were not processed (message_t returns INVALID_ARG if the message ID does not match causing the message to get ignored). This rendered the IKE_SA unusable as the client obviously never retransmitted the fragments of that previous message after it received our response. --- src/libcharon/sa/ikev2/task_manager_v2.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c index 781d6b22b..64d95f581 100644 --- a/src/libcharon/sa/ikev2/task_manager_v2.c +++ b/src/libcharon/sa/ikev2/task_manager_v2.c @@ -1281,7 +1281,7 @@ METHOD(task_manager_t, get_mid, uint32_t, * Handle the given IKE fragment, if it is one. * * Returns SUCCESS if the message is not a fragment, and NEED_MORE if it was - * handled properly. Error states are returned if the fragment was invalid or + * handled properly. Error states are returned if the fragment was invalid or * the reassembled message could not have been processed properly. */ static status_t handle_fragment(private_task_manager_t *this, @@ -1290,6 +1290,12 @@ static status_t handle_fragment(private_task_manager_t *this, message_t *reassembled; status_t status; + if (*defrag && (*defrag)->get_message_id(*defrag) < msg->get_message_id(msg)) + { + /* clear fragments of an incompletely received retransmitted message */ + (*defrag)->destroy(*defrag); + *defrag = NULL; + } if (!msg->get_payload(msg, PLV2_FRAGMENT)) { return SUCCESS;