Skip to content
Snippets Groups Projects
Commit b34cd486 authored by Adrien Béraud's avatar Adrien Béraud
Browse files

conference: properly protect confInfo_

Change-Id: Ifb897e5918163fe9d6ee7eefb9e65a76c441d8dc
parent 9d5f9e32
Branches
No related tags found
No related merge requests found
...@@ -648,17 +648,13 @@ Call::setConferenceInfo(const std::string& msg) ...@@ -648,17 +648,13 @@ Call::setConferenceInfo(const std::string& msg)
if (confID_.empty()) { if (confID_.empty()) {
// confID_ empty -> participant set confInfo with the received one // confID_ empty -> participant set confInfo with the received one
confInfo_ = std::move(newInfo); confInfo_ = std::move(newInfo);
std::vector<std::map<std::string, std::string>> toSend =
confInfo_.toVectorMapStringString();
// Inform client that layout has changed // Inform client that layout has changed
jami::emitSignal<DRing::CallSignal::OnConferenceInfosUpdated>(id_, std::move(toSend)); jami::emitSignal<DRing::CallSignal::OnConferenceInfosUpdated>(id_, confInfo_.toVectorMapStringString());
} else { } else {
// confID_ not empty -> host merge confInfo with the received confInfo // confID_ not empty -> host merge confInfo with the received confInfo
auto oldInfo = confInfo_;
for (auto& newI : newInfo) { for (auto& newI : newInfo) {
bool isNewParticipant = true; bool isNewParticipant = true;
for (auto& oldI : oldInfo) { for (auto& oldI : confInfo_) {
if (newI.uri == oldI.uri) { if (newI.uri == oldI.uri) {
oldI = newI; oldI = newI;
isNewParticipant = false; isNewParticipant = false;
...@@ -669,11 +665,9 @@ Call::setConferenceInfo(const std::string& msg) ...@@ -669,11 +665,9 @@ Call::setConferenceInfo(const std::string& msg)
// ParticipantInfo not present in confInfo -> the sender of newInfo ... // ParticipantInfo not present in confInfo -> the sender of newInfo ...
// is currently hosting another conference. Add the unknown participant ... // is currently hosting another conference. Add the unknown participant ...
// to the confInfo // to the confInfo
oldInfo.emplace_back(newI); confInfo_.emplace_back(newI);
} }
} }
confInfo_ = std::move(oldInfo);
if (auto conf = Manager::instance().getConferenceFromID(confID_)) if (auto conf = Manager::instance().getConferenceFromID(confID_))
conf->updateConferenceInfo(confInfo_); conf->updateConferenceInfo(confInfo_);
} }
......
...@@ -92,11 +92,10 @@ Conference::Conference() ...@@ -92,11 +92,10 @@ Conference::Conference()
if (auto videoMixer = shared->getVideoMixer()) if (auto videoMixer = shared->getVideoMixer())
active = info.source == videoMixer->getActiveParticipant(); active = info.source == videoMixer->getActiveParticipant();
subCalls.erase(it->second); subCalls.erase(it->second);
std::string_view partURI = uri; std::string_view partURI = string_remove_suffix(uri, '@');
partURI = string_remove_suffix(partURI, '@');
auto isModerator = shared->isModerator(partURI); auto isModerator = shared->isModerator(partURI);
if (uri.empty()) if (uri.empty())
partURI = "host"; partURI = "host"sv;
auto isMuted = shared->isMuted(partURI); auto isMuted = shared->isMuted(partURI);
newInfo.emplace_back(ParticipantInfo {std::move(uri), newInfo.emplace_back(ParticipantInfo {std::move(uri),
"", "",
...@@ -120,12 +119,7 @@ Conference::Conference() ...@@ -120,12 +119,7 @@ Conference::Conference()
ParticipantInfo {std::move(uri), "", false, 0, 0, 0, 0, true, false, isModerator}); ParticipantInfo {std::move(uri), "", false, 0, 0, 0, 0, true, false, isModerator});
} }
{ shared->updateConferenceInfo(std::move(newInfo));
std::lock_guard<std::mutex> lk2(shared->confInfoMutex_);
shared->confInfo_ = std::move(newInfo);
}
shared->sendConferenceInfos();
}); });
}); });
#endif #endif
...@@ -184,9 +178,7 @@ Conference::add(const std::string& participant_id) ...@@ -184,9 +178,7 @@ Conference::add(const std::string& participant_id)
// Check if participant was muted before conference // Check if participant was muted before conference
if (auto call = Manager::instance().callFactory.getCall<SIPCall>(participant_id)) { if (auto call = Manager::instance().callFactory.getCall<SIPCall>(participant_id)) {
if (call->isPeerMuted()) { if (call->isPeerMuted()) {
auto uri = call->getPeerNumber(); participantsMuted_.emplace(string_remove_suffix(call->getPeerNumber(), '@'));
uri = string_remove_suffix(uri, '@');
participantsMuted_.emplace(uri);
} }
} }
#ifdef ENABLE_VIDEO #ifdef ENABLE_VIDEO
...@@ -256,11 +248,8 @@ ConfInfo::toVectorMapStringString() const ...@@ -256,11 +248,8 @@ ConfInfo::toVectorMapStringString() const
{ {
std::vector<std::map<std::string, std::string>> infos; std::vector<std::map<std::string, std::string>> infos;
infos.reserve(size()); infos.reserve(size());
auto it = cbegin(); for (const auto& info : *this)
while (it != cend()) { infos.emplace_back(info.toMap());
infos.emplace_back(it->toMap());
++it;
}
return infos; return infos;
} }
...@@ -277,20 +266,19 @@ Conference::sendConferenceInfos() ...@@ -277,20 +266,19 @@ Conference::sendConferenceInfos()
if (!account) if (!account)
continue; continue;
ConfInfo confInfo = std::move(getConfInfoHostUri(account->getUsername()+ "@ring.dht")); ConfInfo confInfo = getConfInfoHostUri(account->getUsername()+ "@ring.dht");
Json::Value jsonArray = {}; Json::Value jsonArray = {};
{
std::lock_guard<std::mutex> lk2(confInfoMutex_);
for (const auto& info : confInfo) { for (const auto& info : confInfo) {
jsonArray.append(info.toJson()); jsonArray.append(info.toJson());
} }
}
Json::StreamWriterBuilder builder = {}; runOnMainThread([
const auto confInfoStr = Json::writeString(builder, jsonArray); call,
call->sendTextMessage(std::map<std::string, std::string> {{"application/confInfo+json", confInfoStr = Json::writeString(Json::StreamWriterBuilder{}, jsonArray),
confInfoStr}}, from = account->getFromUri()
account->getFromUri()); ] {
call->sendTextMessage({{"application/confInfo+json", confInfoStr}}, from);
});
} }
} }
...@@ -417,8 +405,7 @@ Conference::bindHost() ...@@ -417,8 +405,7 @@ Conference::bindHost()
for (const auto& item : participants_) { for (const auto& item : participants_) {
if (auto call = Manager::instance().getCallFromCallID(item)) { if (auto call = Manager::instance().getCallFromCallID(item)) {
std::string_view uri = call->getPeerNumber(); auto uri = string_remove_suffix(call->getPeerNumber(), '@');
uri = string_remove_suffix(uri, '@');
if (isMuted(uri)) if (isMuted(uri))
continue; continue;
rbPool.bindCallID(item, RingBufferPool::DEFAULT_ID); rbPool.bindCallID(item, RingBufferPool::DEFAULT_ID);
...@@ -547,8 +534,7 @@ Conference::onConfOrder(const std::string& callId, const std::string& confOrder) ...@@ -547,8 +534,7 @@ Conference::onConfOrder(const std::string& callId, const std::string& confOrder)
{ {
// Check if the peer is a master // Check if the peer is a master
if (auto call = Manager::instance().getCallFromCallID(callId)) { if (auto call = Manager::instance().getCallFromCallID(callId)) {
std::string_view uri = call->getPeerNumber(); auto uri = string_remove_suffix(call->getPeerNumber(), '@');
uri = string_remove_suffix(uri, '@');
if (!isModerator(uri)) { if (!isModerator(uri)) {
JAMI_WARN("Received conference order from a non master (%s)", uri.data()); JAMI_WARN("Received conference order from a non master (%s)", uri.data());
return; return;
...@@ -593,8 +579,7 @@ Conference::setModerator(const std::string& uri, const bool& state) ...@@ -593,8 +579,7 @@ Conference::setModerator(const std::string& uri, const bool& state)
{ {
for (const auto& p : participants_) { for (const auto& p : participants_) {
if (auto call = Manager::instance().callFactory.getCall<SIPCall>(p)) { if (auto call = Manager::instance().callFactory.getCall<SIPCall>(p)) {
std::string_view partURI = call->getPeerNumber(); auto partURI = string_remove_suffix(call->getPeerNumber(), '@');
partURI = string_remove_suffix(partURI, '@');
if (partURI == uri) { if (partURI == uri) {
if (state and not isModerator(uri)) { if (state and not isModerator(uri)) {
JAMI_DBG("Add %s as moderator", partURI.data()); JAMI_DBG("Add %s as moderator", partURI.data());
...@@ -615,13 +600,9 @@ Conference::setModerator(const std::string& uri, const bool& state) ...@@ -615,13 +600,9 @@ Conference::setModerator(const std::string& uri, const bool& state)
void void
Conference::updateModerators() Conference::updateModerators()
{ {
{ std::lock_guard<std::mutex> lk(confInfoMutex_);
std::lock_guard<std::mutex> lk2(confInfoMutex_);
for (auto& info : confInfo_) { for (auto& info : confInfo_) {
auto uri = info.uri; info.isModerator = isModerator(string_remove_suffix(info.uri, '@'));
uri = string_remove_suffix(uri, '@');
info.isModerator = isModerator(uri);
}
} }
sendConferenceInfos(); sendConferenceInfos();
} }
...@@ -673,19 +654,18 @@ Conference::muteParticipant(const std::string& uri, const bool& state, const std ...@@ -673,19 +654,18 @@ Conference::muteParticipant(const std::string& uri, const bool& state, const std
} }
// Mute participant // Mute participant
auto peerURI = string_remove_suffix(uri, '@');
for (const auto& p : participants_) { for (const auto& p : participants_) {
std::string_view peerURI = string_remove_suffix(uri, '@');
if (auto call = Manager::instance().callFactory.getCall<SIPCall>(p)) { if (auto call = Manager::instance().callFactory.getCall<SIPCall>(p)) {
std::string_view partURI = call->getPeerNumber(); auto partURI = string_remove_suffix(call->getPeerNumber(), '@');
partURI = string_remove_suffix(partURI, '@');
if (partURI == peerURI) { if (partURI == peerURI) {
if (state and not isMuted(partURI)) { if (state and not isMuted(partURI)) {
JAMI_DBG("Mute participant %s", partURI.data()); JAMI_DBG("Mute participant %.*s", (int)partURI.size(), partURI.data());
participantsMuted_.emplace(std::string(partURI)); participantsMuted_.emplace(std::string(partURI));
unbindParticipant(p); unbindParticipant(p);
updateMuted(); updateMuted();
} else if (not state and isMuted(partURI)) { } else if (not state and isMuted(partURI)) {
JAMI_DBG("Unmute participant %s", partURI.data()); JAMI_DBG("Unmute participant %.*s", (int)partURI.size(), partURI.data());
participantsMuted_.erase(std::string(partURI)); participantsMuted_.erase(std::string(partURI));
bindParticipant(p); bindParticipant(p);
updateMuted(); updateMuted();
...@@ -699,15 +679,13 @@ Conference::muteParticipant(const std::string& uri, const bool& state, const std ...@@ -699,15 +679,13 @@ Conference::muteParticipant(const std::string& uri, const bool& state, const std
void void
Conference::updateMuted() Conference::updateMuted()
{ {
{ std::lock_guard<std::mutex> lk(confInfoMutex_);
std::lock_guard<std::mutex> lk2(confInfoMutex_);
for (auto& info : confInfo_) { for (auto& info : confInfo_) {
auto uri = string_remove_suffix(info.uri, '@'); auto uri = string_remove_suffix(info.uri, '@');
if (uri.empty()) if (uri.empty())
uri = "host"; uri = "host"sv;
info.audioMuted = isMuted(uri); info.audioMuted = isMuted(uri);
} }
}
sendConferenceInfos(); sendConferenceInfos();
} }
...@@ -735,11 +713,8 @@ Conference::isHost(std::string_view uri) const ...@@ -735,11 +713,8 @@ Conference::isHost(std::string_view uri) const
// (a local URI can be in the call with another device) // (a local URI can be in the call with another device)
for (const auto& p : participants_) { for (const auto& p : participants_) {
if (auto call = Manager::instance().callFactory.getCall<SIPCall>(p)) { if (auto call = Manager::instance().callFactory.getCall<SIPCall>(p)) {
auto w = call->getAccount(); if (auto account = call->getAccount().lock()) {
auto account = w.lock(); if (account->getUsername() == uri)
if (!account)
continue;
if (account->getUsername() == uri) {
return true; return true;
} }
} }
...@@ -750,6 +725,7 @@ Conference::isHost(std::string_view uri) const ...@@ -750,6 +725,7 @@ Conference::isHost(std::string_view uri) const
void void
Conference::updateConferenceInfo(ConfInfo confInfo) Conference::updateConferenceInfo(ConfInfo confInfo)
{ {
std::lock_guard<std::mutex> lk(confInfoMutex_);
confInfo_ = std::move(confInfo); confInfo_ = std::move(confInfo);
sendConferenceInfos(); sendConferenceInfos();
} }
...@@ -764,8 +740,7 @@ Conference::hangupParticipant(const std::string& participant_id) ...@@ -764,8 +740,7 @@ Conference::hangupParticipant(const std::string& participant_id)
for (const auto& p : participants_) { for (const auto& p : participants_) {
if (auto call = Manager::instance().callFactory.getCall<SIPCall>(p)) { if (auto call = Manager::instance().callFactory.getCall<SIPCall>(p)) {
std::string_view partURI = call->getPeerNumber(); std::string_view partURI = string_remove_suffix(call->getPeerNumber(), '@');
partURI = string_remove_suffix(partURI, '@');
if (partURI == participant_id) { if (partURI == participant_id) {
Manager::instance().hangupCall(call->getCallId()); Manager::instance().hangupCall(call->getCallId());
return; return;
......
...@@ -254,7 +254,8 @@ private: ...@@ -254,7 +254,8 @@ private:
ParticipantSet participants_; ParticipantSet participants_;
mutable std::mutex confInfoMutex_ {}; mutable std::mutex confInfoMutex_ {};
mutable ConfInfo confInfo_ {}; ConfInfo confInfo_ {};
void sendConferenceInfos(); void sendConferenceInfos();
// We need to convert call to frame // We need to convert call to frame
std::mutex videoToCallMtx_; std::mutex videoToCallMtx_;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment