multiplexed_socket: fix race condition on acceptation

Because some callbacks can take a long time (accepting a SIP channel
will starts to sync profiles, ask for new channel, etc), control packets
are handled in their own thread. However, if the peer accepts a request,
it can starts to use it and send data on it. When finished, it will close
the socket and both peer will remove the channel.
In some case, the channel can be removed before
MultiplexedSocket::Impl::onAccept, causing upper layers to handle a
bad channel. In this patch, we removes the channel only when upper layers
know that the channel is accepted and ready to use. Also, onAccept()
doesn't create wrong channels (which was a bug, where isInitiator() was
in the wrong state).

GitLab: #659
Change-Id: I4f45feacc2624ce0135ace09f7e0188b56fcf81f
This commit is contained in:
Sébastien Blin
2021-11-24 10:39:56 -05:00
parent 81d75c92d5
commit 35e4cfce40
3 changed files with 60 additions and 30 deletions

View File

@ -101,6 +101,8 @@ SyncHistoryTest::setUp()
void
SyncHistoryTest::tearDown()
{
auto aliceArchive = std::filesystem::current_path().string() + "/alice.gz";
std::remove(aliceArchive.c_str());
if (alice2Id.empty()) {
wait_for_removal_of({aliceId, bobId});
} else {
@ -117,7 +119,6 @@ SyncHistoryTest::testCreateConversationThenSync()
// Now create alice2
auto aliceArchive = std::filesystem::current_path().string() + "/alice.gz";
std::remove(aliceArchive.c_str());
aliceAccount->exportArchive(aliceArchive);
std::map<std::string, std::string> details = DRing::getAccountTemplate("RING");
details[ConfProperties::TYPE] = "RING";
@ -155,7 +156,6 @@ SyncHistoryTest::testCreateConversationThenSync()
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&] {
return alice2Ready && conversationReady;
}));
std::remove(aliceArchive.c_str());
DRing::unregisterSignalHandlers();
}
@ -166,7 +166,6 @@ SyncHistoryTest::testCreateConversationWithOnlineDevice()
// Now create alice2
auto aliceArchive = std::filesystem::current_path().string() + "/alice.gz";
std::remove(aliceArchive.c_str());
aliceAccount->exportArchive(aliceArchive);
std::map<std::string, std::string> details = DRing::getAccountTemplate("RING");
details[ConfProperties::TYPE] = "RING";
@ -208,7 +207,6 @@ SyncHistoryTest::testCreateConversationWithOnlineDevice()
return alice2Ready && conversationReady;
}));
DRing::unregisterSignalHandlers();
std::remove(aliceArchive.c_str());
}
void
@ -253,7 +251,6 @@ SyncHistoryTest::testCreateConversationWithMessagesThenAddDevice()
// Now create alice2
auto aliceArchive = std::filesystem::current_path().string() + "/alice.gz";
std::remove(aliceArchive.c_str());
aliceAccount->exportArchive(aliceArchive);
std::map<std::string, std::string> details = DRing::getAccountTemplate("RING");
details[ConfProperties::TYPE] = "RING";
@ -289,7 +286,6 @@ SyncHistoryTest::testCreateConversationWithMessagesThenAddDevice()
CPPUNIT_ASSERT(messages[0]["body"] == "Message 3");
CPPUNIT_ASSERT(messages[1]["body"] == "Message 2");
CPPUNIT_ASSERT(messages[2]["body"] == "Message 1");
std::remove(aliceArchive.c_str());
}
void
@ -319,7 +315,6 @@ SyncHistoryTest::testCreateMultipleConversationThenAddDevice()
// Now create alice2
auto aliceArchive = std::filesystem::current_path().string() + "/alice.gz";
std::remove(aliceArchive.c_str());
aliceAccount->exportArchive(aliceArchive);
std::map<std::string, std::string> details = DRing::getAccountTemplate("RING");
details[ConfProperties::TYPE] = "RING";
@ -350,7 +345,6 @@ SyncHistoryTest::testCreateMultipleConversationThenAddDevice()
CPPUNIT_ASSERT(
cv.wait_for(lk, std::chrono::seconds(60), [&]() { return conversationReady == 4; }));
DRing::unregisterSignalHandlers();
std::remove(aliceArchive.c_str());
}
void
@ -360,7 +354,6 @@ SyncHistoryTest::testReceivesInviteThenAddDevice()
// Export alice
auto aliceArchive = std::filesystem::current_path().string() + "/alice.gz";
std::remove(aliceArchive.c_str());
aliceAccount->exportArchive(aliceArchive);
auto bobAccount = Manager::instance().getAccount<JamiAccount>(bobId);
@ -429,7 +422,6 @@ SyncHistoryTest::testReceivesInviteThenAddDevice()
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&] { return requestReceived; }));
DRing::unregisterSignalHandlers();
std::remove(aliceArchive.c_str());
}
void
@ -439,7 +431,6 @@ SyncHistoryTest::testRemoveConversationOnAllDevices()
// Now create alice2
auto aliceArchive = std::filesystem::current_path().string() + "/alice.gz";
std::remove(aliceArchive.c_str());
aliceAccount->exportArchive(aliceArchive);
std::map<std::string, std::string> details = DRing::getAccountTemplate("RING");
details[ConfProperties::TYPE] = "RING";
@ -493,7 +484,6 @@ SyncHistoryTest::testRemoveConversationOnAllDevices()
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&] { return conversationRemoved; }));
DRing::unregisterSignalHandlers();
std::remove(aliceArchive.c_str());
}
void
@ -506,7 +496,6 @@ SyncHistoryTest::testSyncCreateAccountExportDeleteReimportOldBackup()
// Backup alice before start conversation, worst scenario for invites
auto aliceArchive = std::filesystem::current_path().string() + "/alice.gz";
std::remove(aliceArchive.c_str());
aliceAccount->exportArchive(aliceArchive);
// Start conversation
@ -599,7 +588,6 @@ SyncHistoryTest::testSyncCreateAccountExportDeleteReimportOldBackup()
messageBobReceived = 0;
DRing::sendMessage(alice2Id, convId, std::string("hi"), "");
cv.wait_for(lk, std::chrono::seconds(30), [&]() { return messageBobReceived == 1; });
std::remove(aliceArchive.c_str());
DRing::unregisterSignalHandlers();
}
@ -686,7 +674,6 @@ SyncHistoryTest::testSyncCreateAccountExportDeleteReimportWithConvId()
// Backup alice after startConversation with member
auto aliceArchive = std::filesystem::current_path().string() + "/alice.gz";
std::remove(aliceArchive.c_str());
aliceAccount->exportArchive(aliceArchive);
// disable account (same as removed)
@ -711,7 +698,6 @@ SyncHistoryTest::testSyncCreateAccountExportDeleteReimportWithConvId()
messageBobReceived = 0;
DRing::sendMessage(alice2Id, convId, std::string("hi"), "");
cv.wait_for(lk, std::chrono::seconds(30), [&]() { return messageBobReceived == 1; });
std::remove(aliceArchive.c_str());
DRing::unregisterSignalHandlers();
}
@ -782,7 +768,6 @@ SyncHistoryTest::testSyncCreateAccountExportDeleteReimportWithConvReq()
// Backup alice after startConversation with member
auto aliceArchive = std::filesystem::current_path().string() + "/alice.gz";
std::remove(aliceArchive.c_str());
aliceAccount->exportArchive(aliceArchive);
// disable account (same as removed)
@ -806,7 +791,6 @@ SyncHistoryTest::testSyncCreateAccountExportDeleteReimportWithConvReq()
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() {
return conversationReady && messageBobReceived == 1;
}));
std::remove(aliceArchive.c_str());
DRing::unregisterSignalHandlers();
}
@ -848,7 +832,6 @@ SyncHistoryTest::testSyncOneToOne()
// Now create alice2
auto aliceArchive = std::filesystem::current_path().string() + "/alice.gz";
std::remove(aliceArchive.c_str());
aliceAccount->exportArchive(aliceArchive);
std::map<std::string, std::string> details = DRing::getAccountTemplate("RING");
details[ConfProperties::TYPE] = "RING";
@ -863,7 +846,6 @@ SyncHistoryTest::testSyncOneToOne()
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&] {
return alice2Ready && conversationReady;
}));
std::remove(aliceArchive.c_str());
DRing::unregisterSignalHandlers();
}
@ -874,7 +856,6 @@ SyncHistoryTest::testConversationRequestRemoved()
// Export alice
auto aliceArchive = std::filesystem::current_path().string() + "/alice.gz";
std::remove(aliceArchive.c_str());
aliceAccount->exportArchive(aliceArchive);
auto bobAccount = Manager::instance().getAccount<JamiAccount>(bobId);
@ -951,7 +932,6 @@ SyncHistoryTest::testConversationRequestRemoved()
}));
DRing::unregisterSignalHandlers();
std::remove(aliceArchive.c_str());
}
void
@ -964,7 +944,6 @@ SyncHistoryTest::testProfileReceivedMultiDevice()
// Export alice
auto aliceArchive = std::filesystem::current_path().string() + "/alice.gz";
std::remove(aliceArchive.c_str());
aliceAccount->exportArchive(aliceArchive);
// Set VCards
@ -1058,7 +1037,6 @@ END:VCARD";
details[ConfProperties::ARCHIVE_PATH] = aliceArchive;
bobProfileReceived = false, aliceProfileReceived = false;
alice2Id = Manager::instance().addAccount(details);
std::remove(aliceArchive.c_str());
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(60), [&] {
return aliceProfileReceived && bobProfileReceived;