From 1e391695c1c17e066cf6bda5664ef60ed1586fd1 Mon Sep 17 00:00:00 2001 From: Chad Pilkey <capilkey@gmail.com> Date: Mon, 3 Jun 2019 18:54:30 +0000 Subject: [PATCH] strip mDNS candidates from sip.js SDPs --- .../imports/api/audio/client/bridge/sip.js | 7 +++- bigbluebutton-html5/imports/utils/sdpUtils.js | 42 +++++++++++++------ .../public/compatibility/sip.js | 3 ++ 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/bigbluebutton-html5/imports/api/audio/client/bridge/sip.js b/bigbluebutton-html5/imports/api/audio/client/bridge/sip.js index 3aa3bd611f..92d6542bd3 100755 --- a/bigbluebutton-html5/imports/api/audio/client/bridge/sip.js +++ b/bigbluebutton-html5/imports/api/audio/client/bridge/sip.js @@ -2,7 +2,9 @@ import browser from 'browser-detect'; import BaseAudioBridge from './base'; import logger from '/imports/startup/client/logger'; import { fetchStunTurnServers } from '/imports/utils/fetchStunTurnServers'; -import { isUnifiedPlan, toUnifiedPlan, toPlanB} from '/imports/utils/sdpUtils'; +import { + isUnifiedPlan, toUnifiedPlan, toPlanB, stripMDnsCandidates, +} from '/imports/utils/sdpUtils'; const MEDIA = Meteor.settings.public.media; const MEDIA_TAG = MEDIA.mediaTag; @@ -40,6 +42,7 @@ export default class SIPBridge extends BaseAudioBridge { window.isUnifiedPlan = isUnifiedPlan; window.toUnifiedPlan = toUnifiedPlan; window.toPlanB = toPlanB; + window.stripMDnsCandidates = stripMDnsCandidates; } static parseDTMF(message) { @@ -182,7 +185,7 @@ export default class SIPBridge extends BaseAudioBridge { // transceivers - prlanzarin 2019/05/21 const browserUA = window.navigator.userAgent.toLocaleLowerCase(); const isSafariWebview = ((browserUA.indexOf('iphone') > -1 - || browserUA.indexOf('ipad') > -1) && browserUA.indexOf('safari') == -1); + || browserUA.indexOf('ipad') > -1) && browserUA.indexOf('safari') === -1); // Second UA check to get all Safari browsers to enable Unified Plan <-> PlanB // translation diff --git a/bigbluebutton-html5/imports/utils/sdpUtils.js b/bigbluebutton-html5/imports/utils/sdpUtils.js index 454c905ca1..a079f0e8cb 100644 --- a/bigbluebutton-html5/imports/utils/sdpUtils.js +++ b/bigbluebutton-html5/imports/utils/sdpUtils.js @@ -1,5 +1,5 @@ -import Interop from '@jitsi/sdp-interop' -import transform from 'sdp-transform' +import Interop from '@jitsi/sdp-interop'; +import transform from 'sdp-transform'; import logger from '/imports/startup/client/logger'; // sdp-interop library for unified-plan <-> plan-b translation @@ -8,9 +8,7 @@ const interop = new Interop.Interop(); // Some heuristics to determine if the input SDP is Unified Plan const isUnifiedPlan = (sdp) => { const parsedSDP = transform.parse(sdp); - if (parsedSDP.media.length <= 3 && parsedSDP.media.every((m) => { - return ['video', 'audio', 'data'].indexOf(m.mid) !== -1; - })) { + if (parsedSDP.media.length <= 3 && parsedSDP.media.every(m => ['video', 'audio', 'data'].indexOf(m.mid) !== -1)) { logger.info({ logCode: 'sdp_utils_not_unified_plan' }, 'SDP does not look like Unified Plan'); return false; } @@ -18,14 +16,12 @@ const isUnifiedPlan = (sdp) => { logger.info({ logCode: 'sdp_utils_is_unified_plan' }, 'SDP looks like Unified Plan'); return true; -} +}; // Some heuristics to determine if the input SDP is Plan B const isPlanB = (sdp) => { const parsedSDP = transform.parse(sdp); - if (parsedSDP.media.length > 3 || !parsedSDP.media.every((m) => { - return ['video', 'audio', 'data'].indexOf(m.mid) !== -1; - })) { + if (parsedSDP.media.length > 3 || !parsedSDP.media.every(m => ['video', 'audio', 'data'].indexOf(m.mid) !== -1)) { logger.info({ logCode: 'sdp_utils_not_plan_b' }, 'SDP does not look like Plan B'); return false; } @@ -33,7 +29,7 @@ const isPlanB = (sdp) => { logger.info({ logCode: 'sdp_utils_is_plan_b' }, 'SDP looks like Plan B'); return true; -} +}; // Specific method for translating FS SDPs from Plan B to Unified Plan (vice-versa) @@ -41,12 +37,32 @@ const toPlanB = (unifiedPlanSDP) => { const planBSDP = interop.toPlanB(unifiedPlanSDP); logger.info({ logCode: 'sdp_utils_unified_plan_to_plan_b' }, `Converted Unified Plan to Plan B ${JSON.stringify(planBSDP)}`); return planBSDP; -} +}; const toUnifiedPlan = (planBSDP) => { const unifiedPlanSDP = interop.toUnifiedPlan(planBSDP); logger.info({ logCode: 'sdp_utils_plan_b_to_unified_plan' }, `Converted Plan B to Unified Plan ${JSON.stringify(unifiedPlanSDP)}`); return unifiedPlanSDP; -} +}; -export { interop, isUnifiedPlan, toPlanB, toUnifiedPlan }; +const stripMDnsCandidates = (sdp) => { + const parsedSDP = transform.parse(sdp); + let strippedCandidates = 0; + parsedSDP.media.forEach((media) => { + media.candidates = media.candidates.filter((candidate) => { + if (candidate.ip && candidate.ip.indexOf('.local') === -1) { + return true; + } + strippedCandidates += 1; + return false; + }); + }); + if (strippedCandidates > 0) { + logger.info({ logCode: 'sdp_utils_mdns_candidate_strip' }, `Stripped ${strippedCandidates} mDNS candidates`); + } + return transform.write(parsedSDP); +}; + +export { + interop, isUnifiedPlan, toPlanB, toUnifiedPlan, stripMDnsCandidates, +}; diff --git a/bigbluebutton-html5/public/compatibility/sip.js b/bigbluebutton-html5/public/compatibility/sip.js index 63ea6b37ab..ddea0ad180 100755 --- a/bigbluebutton-html5/public/compatibility/sip.js +++ b/bigbluebutton-html5/public/compatibility/sip.js @@ -11618,6 +11618,9 @@ MediaHandler.prototype = Object.create(SIP.MediaHandler.prototype, { sdp = SIP.Hacks.Chrome.needsExplicitlyInactiveSDP(sdp); sdp = SIP.Hacks.AllBrowsers.unmaskDtls(sdp); + if (window.stripMDnsCandidates) { + sdp = window.stripMDnsCandidates(sdp); + } var sdpWrapper = { type: methodName === 'createOffer' ? 'offer' : 'answer', -- GitLab