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