From 7ba6bd9f7a197418e958b998148da0b8dd7211f6 Mon Sep 17 00:00:00 2001 From: basisbit <hp.stefan@gmail.com> Date: Wed, 9 Dec 2020 13:58:26 +0100 Subject: [PATCH] Fix voiceBridge collision Cherry-picked the commits from https://github.com/bigbluebutton/bigbluebutton/pull/9251 The added code checks if a meetingID is unique and makes sure no two meetings use the same VoiceBridge. Also see Issue # 9024 --- .../org/bigbluebutton/api/MeetingService.java | 32 +++++++++++++++++-- .../web/controllers/ApiController.groovy | 22 +++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java index d2a3ee7ad7..d73e1783bf 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java @@ -290,8 +290,10 @@ public class MeetingService implements MessageListener { public synchronized boolean createMeeting(Meeting m) { String internalMeetingId = paramsProcessorUtil.convertToInternalMeetingId(m.getExternalId()); - Meeting existing = getNotEndedMeetingWithId(internalMeetingId); - if (existing == null) { + Meeting existingId = getNotEndedMeetingWithId(internalMeetingId); + Meeting existingTelVoice = getNotEndedMeetingWithTelVoice(m.getTelVoice()); + Meeting existingWebVoice = getNotEndedMeetingWithWebVoice(m.getWebVoice()); + if (existingId == null && existingTelVoice == null && existingWebVoice == null) { meetings.put(m.getInternalId(), m); handle(new CreateMeeting(m)); return true; @@ -450,6 +452,32 @@ public class MeetingService implements MessageListener { return null; } + public Meeting getNotEndedMeetingWithTelVoice(String telVoice) { + if (telVoice == null) + return null; + for (Map.Entry<String, Meeting> entry : meetings.entrySet()) { + Meeting m = entry.getValue(); + if (m.getTelVoice() == telVoice) { + if (!m.isForciblyEnded()) + return m; + } + } + return null; + } + + public Meeting getNotEndedMeetingWithWebVoice(String webVoice) { + if (webVoice == null) + return null; + for (Map.Entry<String, Meeting> entry : meetings.entrySet()) { + Meeting m = entry.getValue(); + if (m.getWebVoice() == webVoice) { + if (!m.isForciblyEnded()) + return m; + } + } + return null; + } + public Boolean validateTextTrackSingleUseToken(String recordId, String caption, String token) { return recordingService.validateTextTrackSingleUseToken(recordId, caption, token); } diff --git a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy index 227ba2b3fc..221dd716b9 100755 --- a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy +++ b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy @@ -136,6 +136,20 @@ class ApiController { return } + // Ensure unique TelVoice. Uniqueness is not guaranteed by paramsProcessorUtil. + if (!params.voiceBridge) { + // Try up to 10 times. We should find a valid telVoice quickly unless + // the server hosts ~100k meetings (default 5-digit telVoice) + for (int i in 1..10) { + String telVoice = paramsProcessorUtil.processTelVoice(""); + if (!meetingService.getNotEndedMeetingWithTelVoice(telVoice)) { + params.voiceBridge = telVoice; + break; + } + } + // Still no unique voiceBridge found? Let createMeeting handle it. + } + Meeting newMeeting = paramsProcessorUtil.processCreateParams(params) if (meetingService.createMeeting(newMeeting)) { @@ -167,6 +181,14 @@ class ApiController { } return + } else { + Meeting existingTelVoice = meetingService.getNotEndedMeetingWithTelVoice(newMeeting.getTelVoice()); + Meeting existingWebVoice = meetingService.getNotEndedMeetingWithWebVoice(newMeeting.getWebVoice()); + if (existingTelVoice != null || existingWebVoice != null) { + log.error "VoiceBridge already in use by another meeting (different meetingId)" + errors.nonUniqueMeetingIdError() + respondWithErrors(errors) + } } } } -- GitLab