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.
* 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,
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;