Blob Blame History Raw
diff -Naur libreswan-3.23-orig/programs/pluto/ikev2.c libreswan-3.23/programs/pluto/ikev2.c
--- libreswan-3.23-orig/programs/pluto/ikev2.c	2018-01-25 15:19:46.000000000 -0500
+++ libreswan-3.23/programs/pluto/ikev2.c	2018-04-26 21:55:22.841931926 -0400
@@ -917,7 +917,12 @@
 
 	if (is_msg_request(md)) {
 		/* this a new IKE request and not a response */
-		if (md->from_state == STATE_V2_CREATE_R) {
+		if (resp_state_with_msgid(pst->st_serialno,
+					  htonl(md->msgid_received)) != NULL) {
+			what = "CREATE_CHILD_SA Request retransmission ignored";
+			st = NULL;
+
+		} else if (md->from_state == STATE_V2_CREATE_R) {
 			what = "Child SA Request";
 			st = duplicate_state(pst, IPSEC_SA);
 			change_state(st, STATE_V2_CREATE_R);
diff -Naur libreswan-3.23-orig/programs/pluto/ikev2_parent.c libreswan-3.23/programs/pluto/ikev2_parent.c
--- libreswan-3.23-orig/programs/pluto/ikev2_parent.c	2018-04-26 21:54:36.863176992 -0400
+++ libreswan-3.23/programs/pluto/ikev2_parent.c	2018-04-26 21:55:22.843931915 -0400
@@ -5009,6 +5009,8 @@
 				ikev2_print_ts(&rst->st_ts_this);
 				ikev2_print_ts(&rst->st_ts_that);
 
+				st->st_connection = rst->st_connection;
+
 				ret = STF_OK;
 			}
 
diff -Naur libreswan-3.23-orig/programs/pluto/state.c libreswan-3.23/programs/pluto/state.c
--- libreswan-3.23-orig/programs/pluto/state.c	2018-01-25 15:19:46.000000000 -0500
+++ libreswan-3.23/programs/pluto/state.c	2018-04-26 21:55:22.842931921 -0400
@@ -592,6 +592,39 @@
 	}
 	return FALSE;
 }
+
+static bool ikev2_child_resp_eq_pst_msgid(const struct state *st,
+		so_serial_t psn, msgid_t st_msgid)
+{
+	if (st->st_clonedfrom == psn &&
+			st->st_msgid == st_msgid &&
+			IS_CHILD_SA_RESPONDER(st)) {
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/*
+ * Find the state object that match the following:
+ *      st_msgid (IKEv2 Child responder state)
+ *      parent duplicated from
+ *      expected state
+ */
+
+struct state *resp_state_with_msgid(so_serial_t psn, msgid_t st_msgid)
+{
+	passert(psn >= SOS_FIRST);
+
+	FOR_EACH_COOKIED_STATE(st, {
+			if (ikev2_child_resp_eq_pst_msgid(st, psn, st_msgid))
+			return st;
+			});
+	DBG(DBG_CONTROL,
+			DBG_log("no waiting child state matching pst #%lu msg id %u",
+				psn, ntohs(st_msgid)));
+	return NULL;
+}
+
 /*
  * Find the state object that match the following:
  *	st_msgid (IKE/IPsec initiator state)
diff -Naur libreswan-3.23-orig/programs/pluto/state.h libreswan-3.23/programs/pluto/state.h
--- libreswan-3.23-orig/programs/pluto/state.h	2018-01-25 15:19:46.000000000 -0500
+++ libreswan-3.23/programs/pluto/state.h	2018-04-26 21:55:22.842931921 -0400
@@ -684,7 +684,9 @@
 					const struct connection *c,
 					lset_t ok_states);
 
-struct state *state_with_parent_msgid_expect(so_serial_t psn, msgid_t st_msgid,
+extern struct state *resp_state_with_msgid(so_serial_t psn, msgid_t st_msgid);
+
+extern struct state *state_with_parent_msgid_expect(so_serial_t psn, msgid_t st_msgid,
 		                enum state_kind expected_state);
 
 extern struct state *find_state_ikev2_parent(const u_char *icookie,