diff --git a/src/conference/session/call-session.cpp b/src/conference/session/call-session.cpp
index 158232011bd393f5bb88f6a281b3ba639ba46088..125438d44f52d6d94a101cf9111d0ef2b1661849 100644
--- a/src/conference/session/call-session.cpp
+++ b/src/conference/session/call-session.cpp
@@ -635,15 +635,22 @@ void CallSessionPrivate::updated(bool isUpdate) {
 			         "Call updated by remote while in transcient state (Pausing/Updating/Resuming)");
 			acceptUpdate(nullptr, localState, Utils::toString(localState));
 			break;
+		case CallSession::State::End:
+		case CallSession::State::Released:
+			lWarning() << "Session [" << q
+			           << "] is going to reject the reINVITE or UPDATE because it is already in state ["
+			           << Utils::toString(state) << "]";
+			sal_error_info_set(&sei, SalReasonNoMatch, "SIP", 0, "Incompatible SDP", nullptr);
+			op->declineWithErrorInfo(&sei, nullptr);
+			sal_error_info_reset(&sei);
+			break;
 		case CallSession::State::Idle:
 		case CallSession::State::OutgoingInit:
-		case CallSession::State::End:
 		case CallSession::State::IncomingReceived:
 		case CallSession::State::PushIncomingReceived:
 		case CallSession::State::OutgoingProgress:
 		case CallSession::State::Referred:
 		case CallSession::State::Error:
-		case CallSession::State::Released:
 		case CallSession::State::EarlyUpdatedByRemote:
 		case CallSession::State::EarlyUpdating:
 			lWarning() << "Receiving reINVITE or UPDATE while in state [" << Utils::toString(state)
diff --git a/src/conference/session/media-session.cpp b/src/conference/session/media-session.cpp
index e71bd7d68763007d8010ba8907d55c78786222da..29ced9f0fb1cd378c07f06701359e436c105d248 100644
--- a/src/conference/session/media-session.cpp
+++ b/src/conference/session/media-session.cpp
@@ -696,6 +696,17 @@ bool MediaSessionPrivate::incompatibleSecurity(const std::shared_ptr<SalMediaDes
 
 void MediaSessionPrivate::updating(bool isUpdate) {
 	L_Q();
+	if ((state == CallSession::State::End) || (state == CallSession::State::Released)) {
+		lWarning() << "Session [" << q << "] is going to reject the reINVITE or UPDATE because it is already in state ["
+		           << Utils::toString(state) << "]";
+		SalErrorInfo sei;
+		memset(&sei, 0, sizeof(sei));
+		sal_error_info_set(&sei, SalReasonNoMatch, "SIP", 0, "Incompatible SDP", nullptr);
+		op->declineWithErrorInfo(&sei, nullptr);
+		sal_error_info_reset(&sei);
+		return;
+	}
+
 	std::shared_ptr<SalMediaDescription> rmd = op->getRemoteMediaDescription();
 	// Fix local parameter before creating new local media description in order to have it consistent with the offer.
 	// Note that in some case such as if we are the offerer or transition from the state UpdateByRemote to
diff --git a/tester/call_race_conditions.c b/tester/call_race_conditions.c
index daa487b5a90b7b55361c3724b5e3d1b52ee416d1..4cc44081d91d1a9a251e2a453fde0f48da22cfd1 100644
--- a/tester/call_race_conditions.c
+++ b/tester/call_race_conditions.c
@@ -65,19 +65,24 @@ static void call_with_video_added_by_both_parties(void) {
 	linphone_call_params_unref(pauline_params);
 	linphone_call_params_unref(marie_params);
 
-	BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallUpdating, 1, 10000));
-	BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallUpdating, 1, 10000));
+	BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallUpdating, 1, liblinphone_tester_sip_timeout));
+	BC_ASSERT_TRUE(
+	    wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallUpdating, 1, liblinphone_tester_sip_timeout));
 
 	/* Marie shall transition to UpdatedByRemote (Pauline has priority per RFC3261 since she is the call-id owner)*/
-	BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallUpdatedByRemote, 1, 10000));
+	BC_ASSERT_TRUE(
+	    wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallUpdatedByRemote, 1, liblinphone_tester_sip_timeout));
 
 	/* Marie will succeed with its re INVITE transaction */
-	BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallStreamsRunning, 2, 10000));
+	BC_ASSERT_TRUE(
+	    wait_for_list(lcs, &marie->stat.number_of_LinphoneCallStreamsRunning, 2, liblinphone_tester_sip_timeout));
 
 	/* Pauline shall return to Updating state*/
-	BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallUpdating, 2, 10000));
+	BC_ASSERT_TRUE(
+	    wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallUpdating, 2, liblinphone_tester_sip_timeout));
 	/* And finally succeed too */
-	BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallStreamsRunning, 2, 10000));
+	BC_ASSERT_TRUE(
+	    wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallStreamsRunning, 2, liblinphone_tester_sip_timeout));
 
 	ei = linphone_call_get_error_info(marie_call);
 	BC_ASSERT_TRUE(linphone_error_info_get_protocol_code(ei) == 0);
@@ -93,6 +98,51 @@ end:
 	linphone_core_manager_destroy(pauline);
 }
 
+static void call_with_info_sent_by_both_parties(void) {
+	LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
+	LinphoneCoreManager *pauline =
+	    linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
+	LinphoneCall *marie_call, *pauline_call;
+	LinphoneInfoMessage *marie_info, *pauline_info;
+	bctbx_list_t *lcs = NULL;
+	bool_t call_ok;
+	int number_of_infos = 4;
+
+	lcs = bctbx_list_append(lcs, marie->lc);
+	lcs = bctbx_list_append(lcs, pauline->lc);
+
+	BC_ASSERT_TRUE(call_ok = call(pauline, marie));
+	if (!call_ok) goto end;
+
+	marie_call = linphone_core_get_current_call(marie->lc);
+	BC_ASSERT_PTR_NOT_NULL(marie_call);
+	pauline_call = linphone_core_get_current_call(pauline->lc);
+	BC_ASSERT_PTR_NOT_NULL(pauline_call);
+
+	// Send multiple INFO messages in order to be sure to have at least one 491 request pending
+	for (int i = 0; i < number_of_infos; i++) {
+		marie_info = linphone_core_create_info_message(marie->lc);
+		pauline_info = linphone_core_create_info_message(pauline->lc);
+
+		linphone_call_send_info_message(pauline_call, pauline_info);
+		linphone_call_send_info_message(marie_call, marie_info);
+
+		linphone_info_message_unref(marie_info);
+		linphone_info_message_unref(pauline_info);
+	}
+
+	BC_ASSERT_TRUE(
+	    wait_for_list(lcs, &pauline->stat.number_of_InfoReceived, number_of_infos, liblinphone_tester_sip_timeout));
+	BC_ASSERT_TRUE(
+	    wait_for_list(lcs, &marie->stat.number_of_InfoReceived, number_of_infos, liblinphone_tester_sip_timeout));
+
+	end_call(pauline, marie);
+end:
+	bctbx_list_free(lcs);
+	linphone_core_manager_destroy(marie);
+	linphone_core_manager_destroy(pauline);
+}
+
 static void call_paused_by_both_parties(void) {
 	LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
 	LinphoneCoreManager *pauline =
@@ -113,11 +163,11 @@ static void call_paused_by_both_parties(void) {
 	linphone_call_pause(marie_call);
 	linphone_call_pause(pauline_call);
 
-	BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallPausing, 1, 10000));
-	BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallPausing, 1, 10000));
+	BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallPausing, 1, liblinphone_tester_sip_timeout));
+	BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallPausing, 1, liblinphone_tester_sip_timeout));
 
-	BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallPaused, 1, 10000));
-	BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallPaused, 1, 10000));
+	BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallPaused, 1, liblinphone_tester_sip_timeout));
+	BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallPaused, 1, liblinphone_tester_sip_timeout));
 
 	BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallUpdatedByRemote, 1, int, "%d");
 	BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallPausing, 2, int, "%d");
@@ -128,8 +178,10 @@ static void call_paused_by_both_parties(void) {
 	/* both resume the call at the same time */
 	linphone_call_resume(marie_call);
 	linphone_call_resume(pauline_call);
-	BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallStreamsRunning, 2, 10000));
-	BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallStreamsRunning, 2, 10000));
+	BC_ASSERT_TRUE(
+	    wait_for_list(lcs, &marie->stat.number_of_LinphoneCallStreamsRunning, 2, liblinphone_tester_sip_timeout));
+	BC_ASSERT_TRUE(
+	    wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallStreamsRunning, 2, liblinphone_tester_sip_timeout));
 	liblinphone_tester_check_rtcp(pauline, marie);
 
 	end_call(pauline, marie);
@@ -168,7 +220,6 @@ static void call_end_and_reinvite(void) {
 	BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallEnd, 1, 10000));
 	BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallReleased, 1, 10000));
 	BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallReleased, 1, 10000));
-
 end:
 	bctbx_list_free(lcs);
 	linphone_core_manager_destroy(marie);
@@ -177,6 +228,7 @@ end:
 
 static test_t call_race_conditions_tests[] = {
     TEST_NO_TAG("Call with video added by both parties", call_with_video_added_by_both_parties),
+    TEST_NO_TAG("Call with INFO sent by both parties", call_with_info_sent_by_both_parties),
     TEST_NO_TAG("Call paused by both parties", call_paused_by_both_parties),
     TEST_NO_TAG("Call ended and re-invited at the same time", call_end_and_reinvite)};
 
diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c
index 44d73626a47cd97b4588aa6609683e0d67f81bd8..308d8f8c067305697e0831c5d0c5b9e62d46c3e8 100644
--- a/tester/call_single_tester.c
+++ b/tester/call_single_tester.c
@@ -4314,8 +4314,8 @@ static void call_established_with_rejected_info(void) {
 
 		im2 = linphone_core_create_info_message(pauline->lc);
 		linphone_call_send_info_message(linphone_core_get_current_call(pauline->lc), im2);
-		BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_inforeceived, 1));
-		BC_ASSERT_EQUAL(marie->stat.number_of_inforeceived, 1, int, "%d");
+		BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_InfoReceived, 1));
+		BC_ASSERT_EQUAL(marie->stat.number_of_InfoReceived, 1, int, "%d");
 		linphone_info_message_unref(im2);
 
 		check_call_state(pauline, LinphoneCallStreamsRunning);
@@ -4354,8 +4354,8 @@ static void call_established_with_complex_rejected_operation(void) {
 		info = linphone_core_create_info_message(marie->lc);
 		linphone_call_send_info_message(linphone_core_get_current_call(marie->lc), info);
 		linphone_info_message_unref(info);
-		BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_inforeceived, 1));
-		BC_ASSERT_EQUAL(pauline->stat.number_of_inforeceived, 1, int, "%d");
+		BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_InfoReceived, 1));
+		BC_ASSERT_EQUAL(pauline->stat.number_of_InfoReceived, 1, int, "%d");
 		/*to give time for 200ok to arrive*/
 		wait_for_until(marie->lc, pauline->lc, NULL, 0, 1000);
 
@@ -4425,8 +4425,8 @@ static void call_established_with_rejected_info_during_reinvite(void) {
 		info = linphone_core_create_info_message(marie->lc);
 		linphone_call_send_info_message(linphone_core_get_current_call(marie->lc), info);
 		linphone_info_message_unref(info);
-		BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_inforeceived, 1));
-		BC_ASSERT_EQUAL(pauline->stat.number_of_inforeceived, 1, int, "%d");
+		BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_InfoReceived, 1));
+		BC_ASSERT_EQUAL(pauline->stat.number_of_InfoReceived, 1, int, "%d");
 		/*to give time for 200ok to arrive*/
 		wait_for_until(marie->lc, pauline->lc, NULL, 0, 1000);
 
diff --git a/tester/call_video_tester.cpp b/tester/call_video_tester.cpp
index c28114e83d208db2279507697e3de2ed18fb4b82..5df9ee23a4821c5cc3355f1a3e3506163f8a476a 100644
--- a/tester/call_video_tester.cpp
+++ b/tester/call_video_tester.cpp
@@ -1789,7 +1789,7 @@ static void multiple_early_media(void) {
 		info = linphone_core_create_info_message(marie1->lc);
 		linphone_call_send_info_message(marie1_call, info);
 		linphone_info_message_unref(info);
-		BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_inforeceived, 1, 3000));
+		BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_InfoReceived, 1, 3000));
 	}
 
 	end_call(pauline, marie1);
diff --git a/tester/liblinphone_tester.h b/tester/liblinphone_tester.h
index 224722283bce06b623de4d6a90f2a93229336bd5..dac5b88d40e1edc4924d97bd853d3c70e2bda190 100644
--- a/tester/liblinphone_tester.h
+++ b/tester/liblinphone_tester.h
@@ -380,7 +380,7 @@ typedef struct _stats {
 	int number_of_LinphoneConsolidatedPresenceDoNotDisturb;
 	int number_of_LinphoneConsolidatedPresenceOffline;
 
-	int number_of_inforeceived;
+	int number_of_InfoReceived;
 	LinphoneInfoMessage *last_received_info_message;
 
 	int number_of_LinphoneSubscriptionIncomingReceived;
diff --git a/tester/message_tester.c b/tester/message_tester.c
index 487b775fd62f7701f01fd3a1d86168b8a3601320..548eb48742b22172c88449e2be3f865c02942cc7 100644
--- a/tester/message_tester.c
+++ b/tester/message_tester.c
@@ -2347,7 +2347,7 @@ void info_message_base(bool_t with_content) {
 		linphone_call_send_info_message(linphone_core_get_current_call(marie->lc), info);
 		linphone_info_message_unref(info);
 
-		BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_inforeceived, 1));
+		BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_InfoReceived, 1));
 
 		BC_ASSERT_PTR_NOT_NULL(pauline->stat.last_received_info_message);
 		hvalue = linphone_info_message_get_header(pauline->stat.last_received_info_message, "Weather");
diff --git a/tester/tester.c b/tester/tester.c
index ca36c07dd6fc033085ef1e52b698283394de539f..97d8bb16830e274194967117027dec4d79be7360 100644
--- a/tester/tester.c
+++ b/tester/tester.c
@@ -3517,7 +3517,7 @@ void info_message_received(LinphoneCore *lc, BCTBX_UNUSED(LinphoneCall *call), c
 		linphone_info_message_unref(counters->last_received_info_message);
 	}
 	counters->last_received_info_message = linphone_info_message_copy(msg);
-	counters->number_of_inforeceived++;
+	counters->number_of_InfoReceived++;
 }
 
 void linphone_subscription_state_change(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state) {
diff --git a/tools/python/unittests/linphonetester.py b/tools/python/unittests/linphonetester.py
index 15eb9ab4e1b7f6fac96ab778f00191e1fa7892dd..2430823311c41c0960df452e7b729d90c5ae4af7 100644
--- a/tools/python/unittests/linphonetester.py
+++ b/tools/python/unittests/linphonetester.py
@@ -281,7 +281,7 @@ class CoreManagerStats:
         self.number_of_LinphonePresenceActivityWorship = 0
         self.last_received_presence = None
 
-        self.number_of_inforeceived = 0
+        self.number_of_InfoReceived = 0
 
         self.number_of_LinphoneSubscriptionIncomingReceived = 0
         self.number_of_LinphoneSubscriptionOutgoingInit = 0