[WebRTC] ICE candidates should be filtered according a policy
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 21 Feb 2017 21:29:01 +0000 (21:29 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 21 Feb 2017 21:29:01 +0000 (21:29 +0000)
https://bugs.webkit.org/show_bug.cgi?id=168348

Patch by Youenn Fablet <youenn@apple.com> on 2017-02-21
Reviewed by Alex Christensen.

Source/WebCore:

Covered by manual tests. Should be covered in the future by layout tests with dedicated internals API.

Adding support for ICE candidate filtering at RTCPeerConnection level.
If ICE candidate filtering is on (by default), host candidates are stored and not sent immediately.
Reflexive candidates are purged from raddr information to not leak the host IP address.

Stored candidates may be advertised to the JS layer if RTCController is notified of a change of filtering policy.
To implement that, PeerConnectionBackend stores all filtered out candidates and RTCPeerConnection register
themselves to RTCController to get notifications of filtering policy changes.

Making RTCPeerConnection use setPendingActivity throughout its lifetime.
This ensures it does not get collected until the page is off or close() is called on the object.

Adding support for enumerating or not all interfaces at libwebrtc level.
This choice is done at creation of the peer connection.

* Modules/mediastream/PeerConnectionBackend.cpp:
(WebCore::PeerConnectionBackend::enableICECandidateFiltering):
(WebCore::PeerConnectionBackend::disableICECandidateFiltering):
(WebCore::filterICECandidate):
(WebCore::PeerConnectionBackend::newICECandidate):
* Modules/mediastream/PeerConnectionBackend.h:
* Modules/mediastream/RTCController.cpp: Added.
(WebCore::RTCController::remove):
(WebCore::RTCController::add):
(WebCore::RTCController::disableICECandidateFiltering):
(WebCore::RTCController::enableICECandidateFiltering):
* Modules/mediastream/RTCController.h: Added.
* Modules/mediastream/RTCPeerConnection.cpp:
(WebCore::RTCPeerConnection::create):
(WebCore::RTCPeerConnection::close):
(WebCore::RTCPeerConnection::rtcController):
(WebCore::RTCPeerConnection::registerToController):
(WebCore::RTCPeerConnection::unregisterFromController):
* Modules/mediastream/RTCPeerConnection.h:
* Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp:
(WebCore::LibWebRTCMediaEndpoint::OnIceCandidate):
* WebCore.xcodeproj/project.pbxproj:
* page/Page.h:
(WebCore::Page::rtcController):
* platform/mediastream/libwebrtc/LibWebRTCProvider.cpp:
(WebCore::LibWebRTCProvider::createPeerConnection):
* platform/mediastream/libwebrtc/LibWebRTCProvider.h:

Source/WebKit2:

Adding the possibility for the UI process to control the ICE candidate filtering and whether libwebrtc can
enumerate all interfaces or not.

Disabling ICE candidate filtering for the moment.
Enabling to enumerate all interfaces for the moment.

In the future, ICE candidate filtering should be tied to getUserMedia.
Interface enumeration should be disabled with the default configuration.
We should do that once we have sufficient testing in various network infrastructures.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::initializeWebPage):
* WebKit2.xcodeproj/project.pbxproj:
* WebProcess/WebPage/WebPage.h:
(WebKit::WebPage::disableICECandidateFiltering):
(WebKit::WebPage::enableICECandidateFiltering):
(WebKit::WebPage::disableEnumeratingAllNetworkInterfaces):
(WebKit::WebPage::enableEnumeratingAllNetworkInterfaces):
* WebProcess/WebPage/WebPage.messages.in:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@212745 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp
Source/WebCore/Modules/mediastream/PeerConnectionBackend.h
Source/WebCore/Modules/mediastream/RTCController.cpp [new file with mode: 0644]
Source/WebCore/Modules/mediastream/RTCController.h [new file with mode: 0644]
Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp
Source/WebCore/Modules/mediastream/RTCPeerConnection.h
Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/inspector/InspectorOverlay.cpp
Source/WebCore/page/Page.h
Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCProvider.cpp
Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCProvider.h
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/WebPageCreationParameters.cpp
Source/WebKit2/Shared/WebPageCreationParameters.h
Source/WebKit2/UIProcess/WebPageProxy.cpp
Source/WebKit2/WebProcess/WebPage/WebPage.cpp
Source/WebKit2/WebProcess/WebPage/WebPage.h
Source/WebKit2/WebProcess/WebPage/WebPage.messages.in

index 6d6223f..d969c2c 100644 (file)
@@ -911,6 +911,7 @@ set(WebCore_SOURCES
     Modules/mediastream/MediaTrackConstraints.cpp
     Modules/mediastream/NavigatorMediaDevices.cpp
     Modules/mediastream/PeerConnectionBackend.cpp
+    Modules/mediastream/RTCController.cpp
     Modules/mediastream/RTCDTMFSender.cpp
     Modules/mediastream/RTCDTMFToneChangeEvent.cpp
     Modules/mediastream/RTCDataChannel.cpp
index 8604046..cf774f9 100644 (file)
@@ -1,3 +1,54 @@
+2017-02-21  Youenn Fablet  <youenn@apple.com>
+
+        [WebRTC] ICE candidates should be filtered according a policy
+        https://bugs.webkit.org/show_bug.cgi?id=168348
+
+        Reviewed by Alex Christensen.
+
+        Covered by manual tests. Should be covered in the future by layout tests with dedicated internals API.
+
+        Adding support for ICE candidate filtering at RTCPeerConnection level.
+        If ICE candidate filtering is on (by default), host candidates are stored and not sent immediately.
+        Reflexive candidates are purged from raddr information to not leak the host IP address.
+
+        Stored candidates may be advertised to the JS layer if RTCController is notified of a change of filtering policy.
+        To implement that, PeerConnectionBackend stores all filtered out candidates and RTCPeerConnection register
+        themselves to RTCController to get notifications of filtering policy changes.
+
+        Making RTCPeerConnection use setPendingActivity throughout its lifetime.
+        This ensures it does not get collected until the page is off or close() is called on the object.
+
+        Adding support for enumerating or not all interfaces at libwebrtc level.
+        This choice is done at creation of the peer connection.
+
+        * Modules/mediastream/PeerConnectionBackend.cpp:
+        (WebCore::PeerConnectionBackend::enableICECandidateFiltering):
+        (WebCore::PeerConnectionBackend::disableICECandidateFiltering):
+        (WebCore::filterICECandidate):
+        (WebCore::PeerConnectionBackend::newICECandidate):
+        * Modules/mediastream/PeerConnectionBackend.h:
+        * Modules/mediastream/RTCController.cpp: Added.
+        (WebCore::RTCController::remove):
+        (WebCore::RTCController::add):
+        (WebCore::RTCController::disableICECandidateFiltering):
+        (WebCore::RTCController::enableICECandidateFiltering):
+        * Modules/mediastream/RTCController.h: Added.
+        * Modules/mediastream/RTCPeerConnection.cpp:
+        (WebCore::RTCPeerConnection::create):
+        (WebCore::RTCPeerConnection::close):
+        (WebCore::RTCPeerConnection::rtcController):
+        (WebCore::RTCPeerConnection::registerToController):
+        (WebCore::RTCPeerConnection::unregisterFromController):
+        * Modules/mediastream/RTCPeerConnection.h:
+        * Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp:
+        (WebCore::LibWebRTCMediaEndpoint::OnIceCandidate):
+        * WebCore.xcodeproj/project.pbxproj:
+        * page/Page.h:
+        (WebCore::Page::rtcController):
+        * platform/mediastream/libwebrtc/LibWebRTCProvider.cpp:
+        (WebCore::LibWebRTCProvider::createPeerConnection):
+        * platform/mediastream/libwebrtc/LibWebRTCProvider.h:
+
 2017-02-21  Jiewen Tan  <jiewen_tan@apple.com>
 
         Unreviewed, update WebCrypto API feature status.
index ba2d43f..d775fe8 100644 (file)
@@ -39,6 +39,7 @@
 #include "RTCIceCandidate.h"
 #include "RTCIceCandidateEvent.h"
 #include "RTCPeerConnection.h"
+#include <wtf/text/StringBuilder.h>
 
 namespace WebCore {
 
@@ -269,6 +270,63 @@ void PeerConnectionBackend::fireICECandidateEvent(RefPtr<RTCIceCandidate>&& cand
     m_peerConnection.fireEvent(RTCIceCandidateEvent::create(false, false, WTFMove(candidate)));
 }
 
+void PeerConnectionBackend::enableICECandidateFiltering()
+{
+    m_shouldFilterICECandidates = true;
+}
+
+void PeerConnectionBackend::disableICECandidateFiltering()
+{
+    m_shouldFilterICECandidates = false;
+    for (auto& pendingICECandidate : m_pendingICECandidates)
+        fireICECandidateEvent(RTCIceCandidate::create(WTFMove(pendingICECandidate.sdp), WTFMove(pendingICECandidate.mid), 0));
+    m_pendingICECandidates.clear();
+}
+
+static inline String filterICECandidate(String&& sdp)
+{
+    ASSERT(!sdp.contains(" host "));
+
+    if (!sdp.contains(" raddr "))
+        return WTFMove(sdp);
+
+    Vector<String> items;
+    sdp.split(' ', items);
+
+    bool skipNextItem = false;
+    bool isFirst = true;
+    StringBuilder filteredSDP;
+    for (auto& item : items) {
+        if (skipNextItem) {
+            skipNextItem = false;
+            continue;
+        }
+        if (item == "raddr" || item == "rport") {
+            skipNextItem = true;
+            continue;
+        }
+        if (isFirst)
+            isFirst = false;
+        else
+            filteredSDP.append(" ");
+        filteredSDP.append(item);
+    }
+    return filteredSDP.toString();
+}
+
+void PeerConnectionBackend::newICECandidate(String&& sdp, String&& mid)
+{
+    if (!m_shouldFilterICECandidates) {
+        fireICECandidateEvent(RTCIceCandidate::create(WTFMove(sdp), WTFMove(mid), 0));
+        return;
+    }
+    if (sdp.contains(" host ")) {
+        m_pendingICECandidates.append(PendingICECandidate { WTFMove(sdp), WTFMove(mid)});
+        return;
+    }
+    fireICECandidateEvent(RTCIceCandidate::create(filterICECandidate(WTFMove(sdp)), WTFMove(mid), 0));
+}
+
 void PeerConnectionBackend::doneGatheringCandidates()
 {
     ASSERT(isMainThread());
index 5df7db4..619518b 100644 (file)
@@ -101,6 +101,10 @@ public:
 
     virtual void emulatePlatformEvent(const String& action) = 0;
 
+    void newICECandidate(String&& sdp, String&& mid);
+    void disableICECandidateFiltering();
+    void enableICECandidateFiltering();
+
 protected:
     void fireICECandidateEvent(RefPtr<RTCIceCandidate>&&);
     void doneGatheringCandidates();
@@ -137,7 +141,15 @@ private:
     std::optional<PeerConnection::SessionDescriptionPromise> m_offerAnswerPromise;
     std::optional<DOMPromise<void>> m_setDescriptionPromise;
     std::optional<DOMPromise<void>> m_addIceCandidatePromise;
-    
+
+    bool m_shouldFilterICECandidates { true };
+    struct PendingICECandidate {
+        // Fields described in https://www.w3.org/TR/webrtc/#idl-def-rtcicecandidateinit.
+        String sdp;
+        String mid;
+    };
+    Vector<PendingICECandidate> m_pendingICECandidates;
+
     bool m_negotiationNeeded { false };
 };
 
diff --git a/Source/WebCore/Modules/mediastream/RTCController.cpp b/Source/WebCore/Modules/mediastream/RTCController.cpp
new file mode 100644 (file)
index 0000000..a1555c2
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "RTCController.h"
+
+#if ENABLE(WEB_RTC)
+
+#include "RTCPeerConnection.h"
+
+namespace WebCore {
+
+void RTCController::remove(RTCPeerConnection& connection)
+{
+    m_peerConnections.removeFirstMatching([&connection](auto item) {
+        return &connection == &item.get();
+    });
+}
+
+void RTCController::add(RTCPeerConnection& connection)
+{
+    m_peerConnections.append(connection);
+    if (!m_shouldFilterICECandidates)
+        connection.disableICECandidateFiltering();
+}
+
+void RTCController::disableICECandidateFiltering()
+{
+    m_shouldFilterICECandidates = false;
+    for (RTCPeerConnection& connection : m_peerConnections)
+        connection.disableICECandidateFiltering();
+}
+
+void RTCController::enableICECandidateFiltering()
+{
+    m_shouldFilterICECandidates = true;
+    for (RTCPeerConnection& connection : m_peerConnections)
+        connection.enableICECandidateFiltering();
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/Modules/mediastream/RTCController.h b/Source/WebCore/Modules/mediastream/RTCController.h
new file mode 100644 (file)
index 0000000..0739a78
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class RTCPeerConnection;
+
+class RTCController {
+public:
+    RTCController() = default;
+
+#if ENABLE(WEB_RTC)
+    void add(RTCPeerConnection&);
+    void remove(RTCPeerConnection&);
+
+    WEBCORE_EXPORT void disableICECandidateFiltering();
+    WEBCORE_EXPORT void enableICECandidateFiltering();
+
+private:
+    Vector<std::reference_wrapper<RTCPeerConnection>> m_peerConnections;
+    bool m_shouldFilterICECandidates { true };
+#endif
+};
+
+} // namespace WebCore
index 8e4dcb1..1f8ddd0 100644 (file)
@@ -42,7 +42,9 @@
 #include "MediaEndpointConfiguration.h"
 #include "MediaStream.h"
 #include "MediaStreamTrack.h"
+#include "Page.h"
 #include "RTCConfiguration.h"
+#include "RTCController.h"
 #include "RTCDataChannel.h"
 #include "RTCIceCandidate.h"
 #include "RTCIceCandidateEvent.h"
@@ -62,7 +64,12 @@ Ref<RTCPeerConnection> RTCPeerConnection::create(ScriptExecutionContext& context
 {
     Ref<RTCPeerConnection> peerConnection = adoptRef(*new RTCPeerConnection(context));
     peerConnection->suspendIfNeeded();
-
+    // RTCPeerConnection may send events at about any time during its lifetime.
+    // Let's make it uncollectable until the pc is closed by JS or the page stops it.
+    if (peerConnection->m_signalingState != SignalingState::Closed) {
+        peerConnection->setPendingActivity(peerConnection.ptr());
+        peerConnection->registerToController();
+    }
     return peerConnection;
 }
 
@@ -412,6 +419,9 @@ void RTCPeerConnection::close()
 
     for (RTCRtpSender& sender : m_transceiverSet->senders())
         sender.stop();
+
+    unregisterFromController();
+    unsetPendingActivity(this);
 }
 
 void RTCPeerConnection::emulatePlatformEvent(const String& action)
@@ -424,6 +434,24 @@ void RTCPeerConnection::stop()
     close();
 }
 
+RTCController& RTCPeerConnection::rtcController()
+{
+    ASSERT(scriptExecutionContext());
+    ASSERT(scriptExecutionContext()->isDocument());
+    auto* page = static_cast<Document*>(scriptExecutionContext())->page();
+    return page->rtcController();
+}
+
+void RTCPeerConnection::registerToController()
+{
+    rtcController().add(*this);
+}
+
+void RTCPeerConnection::unregisterFromController()
+{
+    rtcController().remove(*this);
+}
+
 const char* RTCPeerConnection::activeDOMObjectName() const
 {
     return "RTCPeerConnection";
index a10aaeb..2c0562e 100644 (file)
@@ -46,6 +46,7 @@ namespace WebCore {
 
 class MediaStreamTrack;
 class PeerConnectionBackend;
+class RTCController;
 class RTCIceCandidate;
 class RTCPeerConnectionErrorCallback;
 class RTCSessionDescription;
@@ -136,11 +137,18 @@ public:
     PeerConnectionStates::IceGatheringState internalIceGatheringState() const { return m_iceGatheringState; }
     PeerConnectionStates::IceConnectionState internalIceConnectionState() const { return m_iceConnectionState; }
 
+    void disableICECandidateFiltering() { m_backend->disableICECandidateFiltering(); }
+    void enableICECandidateFiltering() { m_backend->enableICECandidateFiltering(); }
+
 private:
     RTCPeerConnection(ScriptExecutionContext&);
 
     void completeAddTransceiver(RTCRtpTransceiver&, const RtpTransceiverInit&);
 
+    RTCController& rtcController();
+    void registerToController();
+    void unregisterFromController();
+
     // EventTarget implementation.
     void refEventTarget() final { ref(); }
     void derefEventTarget() final { deref(); }
index 983c3d9..fbf7df8 100644 (file)
@@ -36,7 +36,6 @@
 #include "PlatformStrategies.h"
 #include "RTCDataChannel.h"
 #include "RTCDataChannelEvent.h"
-#include "RTCIceCandidate.h"
 #include "RTCPeerConnection.h"
 #include "RTCSessionDescription.h"
 #include "RTCTrackEvent.h"
@@ -446,7 +445,7 @@ void LibWebRTCMediaEndpoint::OnIceCandidate(const webrtc::IceCandidateInterface
     callOnMainThread([protectedThis = makeRef(*this), mid = WTFMove(candidateMid), sdp = WTFMove(candidateSDP)] {
         if (protectedThis->isStopped())
             return;
-        protectedThis->m_peerConnectionBackend.fireICECandidateEvent(RTCIceCandidate::create(String(sdp), String(mid), 0));
+        protectedThis->m_peerConnectionBackend.newICECandidate(String(sdp), String(mid));
     });
 }
 
index 1026d37..cf99d90 100644 (file)
                417DA71E13735DFA007C57FB /* JSInternals.h in Headers */ = {isa = PBXBuildFile; fileRef = 417DA71C13735DFA007C57FB /* JSInternals.h */; };
                41815C1E138319830057AAA4 /* WebCoreTestSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41815C1C138319830057AAA4 /* WebCoreTestSupport.cpp */; };
                41815C1F138319830057AAA4 /* WebCoreTestSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 41815C1D138319830057AAA4 /* WebCoreTestSupport.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               418205471E53E98C00D62207 /* RTCController.h in Headers */ = {isa = PBXBuildFile; fileRef = 418205451E53C8CD00D62207 /* RTCController.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               418205491E53EAB000D62207 /* RTCController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 418205481E53EAAD00D62207 /* RTCController.cpp */; };
                41885B9311B6FDA6003383BB /* FormSubmission.h in Headers */ = {isa = PBXBuildFile; fileRef = 41885B9111B6FDA6003383BB /* FormSubmission.h */; settings = {ATTRIBUTES = (Private, ); }; };
                41885B9411B6FDA6003383BB /* FormSubmission.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41885B9211B6FDA6003383BB /* FormSubmission.cpp */; };
                418A06D0133C04D500CD379C /* EventDispatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 418A06CE133C04D500CD379C /* EventDispatcher.h */; };
                41815C1C138319830057AAA4 /* WebCoreTestSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebCoreTestSupport.cpp; sourceTree = "<group>"; };
                41815C1D138319830057AAA4 /* WebCoreTestSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebCoreTestSupport.h; sourceTree = "<group>"; };
                4181707D1386EDF20057AAA4 /* WebCoreTestSupport.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = WebCoreTestSupport.xcconfig; sourceTree = "<group>"; };
+               418205451E53C8CD00D62207 /* RTCController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCController.h; sourceTree = "<group>"; };
+               418205481E53EAAD00D62207 /* RTCController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RTCController.cpp; sourceTree = "<group>"; };
                41885B9111B6FDA6003383BB /* FormSubmission.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormSubmission.h; sourceTree = "<group>"; };
                41885B9211B6FDA6003383BB /* FormSubmission.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FormSubmission.cpp; sourceTree = "<group>"; };
                418A06CE133C04D500CD379C /* EventDispatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventDispatcher.h; sourceTree = "<group>"; };
                                07221B6617CEC32700848E51 /* RTCDataChannelEvent.cpp */,
                                07221B6717CEC32700848E51 /* RTCDataChannelEvent.h */,
                                07221B6817CEC32700848E51 /* RTCDataChannelEvent.idl */,
+                               418205451E53C8CD00D62207 /* RTCController.h */,
+                               418205481E53EAAD00D62207 /* RTCController.cpp */,
                                07221B6917CEC32700848E51 /* RTCDTMFSender.cpp */,
                                07221B6A17CEC32700848E51 /* RTCDTMFSender.h */,
                                07221B6B17CEC32700848E51 /* RTCDTMFSender.idl */,
                                AD726FEF16DA11F5003A4E6D /* JSCSSRuleCustom.h in Headers */,
                                A8D05FA80A23B301005E7203 /* JSCSSRuleList.h in Headers */,
                                142011B70A003133008303F9 /* JSCSSStyleDeclaration.h in Headers */,
+                               418205471E53E98C00D62207 /* RTCController.h in Headers */,
                                AD726FED16DA1171003A4E6D /* JSCSSStyleDeclarationCustom.h in Headers */,
                                BC46C2070C0DDCA10020CFC3 /* JSCSSStyleRule.h in Headers */,
                                BCC5BE010C0E93110011C2DB /* JSCSSStyleSheet.h in Headers */,
                                BC4EDEF40C08F3FB007EDD49 /* JSHTMLAppletElementCustom.cpp in Sources */,
                                1AE2AA1E0A1CDAB400B42B25 /* JSHTMLAreaElement.cpp in Sources */,
                                7C9DBFED1A9C49B1000D6B25 /* JSHTMLAttachmentElement.cpp in Sources */,
+                               418205491E53EAB000D62207 /* RTCController.cpp in Sources */,
                                E44614370CD689C400FADA75 /* JSHTMLAudioElement.cpp in Sources */,
                                A80E7B120A19D606007FB8C5 /* JSHTMLBaseElement.cpp in Sources */,
                                1AE2AA220A1CDAB400B42B25 /* JSHTMLBodyElement.cpp in Sources */,
index a873c17..6eb3f81 100644 (file)
@@ -44,6 +44,7 @@
 #include "PageConfiguration.h"
 #include "PolygonShape.h"
 #include "PseudoElement.h"
+#include "RTCController.h"
 #include "RectangleShape.h"
 #include "RenderBoxModelObject.h"
 #include "RenderElement.h"
index b95a58e..73ee269 100644 (file)
@@ -29,6 +29,7 @@
 #include "PageVisibilityState.h"
 #include "Pagination.h"
 #include "PlatformScreen.h"
+#include "RTCController.h"
 #include "Region.h"
 #include "ScrollTypes.h"
 #include "SessionID.h"
@@ -223,6 +224,7 @@ public:
     PointerLockController& pointerLockController() const { return *m_pointerLockController; }
 #endif
     LibWebRTCProvider& libWebRTCProvider() { return m_libWebRTCProvider.get(); }
+    RTCController& rtcController() { return m_rtcController; }
 
     ValidationMessageClient* validationMessageClient() const { return m_validationMessageClient.get(); }
     void updateValidationBubbleStateIfNeeded();
@@ -640,6 +642,7 @@ private:
     std::unique_ptr<WebGLStateTracker> m_webGLStateTracker;
 
     UniqueRef<LibWebRTCProvider> m_libWebRTCProvider;
+    RTCController m_rtcController;
 
     int m_nestedRunLoopCount { 0 };
     std::function<void()> m_unnestCallback;
index 62bd704..552ab0e 100644 (file)
@@ -151,7 +151,10 @@ rtc::scoped_refptr<webrtc::PeerConnectionInterface> LibWebRTCProvider::createPee
 
     std::unique_ptr<cricket::BasicPortAllocator> portAllocator;
     staticFactoryAndThreads().signalingThread->Invoke<void>(RTC_FROM_HERE, [&]() {
-        portAllocator.reset(new cricket::BasicPortAllocator(&networkManager, &packetSocketFactory));
+        auto basicPortAllocator = std::make_unique<cricket::BasicPortAllocator>(&networkManager, &packetSocketFactory);
+        if (!m_enableEnumeratingAllNetworkInterfaces)
+            basicPortAllocator->set_flags(basicPortAllocator->flags() | cricket::PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION);
+        portAllocator = WTFMove(basicPortAllocator);
     });
 
     return createActualPeerConnection(observer, WTFMove(portAllocator));
index dca1c22..1f54809 100644 (file)
@@ -60,8 +60,13 @@ public:
     // Used for mock testing
     static void setPeerConnectionFactory(rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>&&);
 
+    void disableEnumeratingAllNetworkInterfaces() { m_enableEnumeratingAllNetworkInterfaces = false; }
+    void enableEnumeratingAllNetworkInterfaces() { m_enableEnumeratingAllNetworkInterfaces = true; }
+
 protected:
     WEBCORE_EXPORT rtc::scoped_refptr<webrtc::PeerConnectionInterface> createPeerConnection(webrtc::PeerConnectionObserver&, rtc::NetworkManager&, rtc::PacketSocketFactory&);
+
+    bool m_enableEnumeratingAllNetworkInterfaces { false };
 #endif
 };
 
index 53beb22..d0f264e 100644 (file)
@@ -1,5 +1,32 @@
 2017-02-21  Youenn Fablet  <youenn@apple.com>
 
+        [WebRTC] ICE candidates should be filtered according a policy
+        https://bugs.webkit.org/show_bug.cgi?id=168348
+
+        Reviewed by Alex Christensen.
+
+        Adding the possibility for the UI process to control the ICE candidate filtering and whether libwebrtc can
+        enumerate all interfaces or not.
+
+        Disabling ICE candidate filtering for the moment.
+        Enabling to enumerate all interfaces for the moment.
+
+        In the future, ICE candidate filtering should be tied to getUserMedia.
+        Interface enumeration should be disabled with the default configuration.
+        We should do that once we have sufficient testing in various network infrastructures.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::initializeWebPage):
+        * WebKit2.xcodeproj/project.pbxproj:
+        * WebProcess/WebPage/WebPage.h:
+        (WebKit::WebPage::disableICECandidateFiltering):
+        (WebKit::WebPage::enableICECandidateFiltering):
+        (WebKit::WebPage::disableEnumeratingAllNetworkInterfaces):
+        (WebKit::WebPage::enableEnumeratingAllNetworkInterfaces):
+        * WebProcess/WebPage/WebPage.messages.in:
+
+2017-02-21  Youenn Fablet  <youenn@apple.com>
+
         [WebRTC] NetworkRTCMonitor should ensure clearing its manager only once
         https://bugs.webkit.org/show_bug.cgi?id=168661
 
index d98d0eb..73ecb66 100644 (file)
@@ -90,6 +90,12 @@ void WebPageCreationParameters::encode(IPC::Encoder& encoder) const
     encoder.encodeEnum(userInterfaceLayoutDirection);
     encoder.encodeEnum(observedLayoutMilestones);
     encoder << overrideContentSecurityPolicy;
+#if ENABLE(WEB_RTC)
+    encoder << disableICECandidateFiltering;
+#if USE(LIBWEBRTC)
+    encoder << enableEnumeratingAllNetworkInterfaces;
+#endif
+#endif
 }
 
 bool WebPageCreationParameters::decode(IPC::Decoder& decoder, WebPageCreationParameters& parameters)
@@ -208,6 +214,14 @@ bool WebPageCreationParameters::decode(IPC::Decoder& decoder, WebPageCreationPar
     if (!decoder.decode(parameters.overrideContentSecurityPolicy))
         return false;
 
+#if ENABLE(WEB_RTC)
+    if (!decoder.decode(parameters.disableICECandidateFiltering))
+        return false;
+#if USE(LIBWEBRTC)
+    if (!decoder.decode(parameters.enableEnumeratingAllNetworkInterfaces))
+        return false;
+#endif
+#endif
     return true;
 }
 
index a6244b8..5bed3fb 100644 (file)
@@ -145,6 +145,13 @@ struct WebPageCreationParameters {
     WebCore::LayoutMilestones observedLayoutMilestones;
 
     String overrideContentSecurityPolicy;
+
+#if ENABLE(WEB_RTC)
+    bool disableICECandidateFiltering { false };
+#if USE(LIBWEBRTC)
+    bool enableEnumeratingAllNetworkInterfaces { false };
+#endif
+#endif
 };
 
 } // namespace WebKit
index dd67ad6..e63ecbd 100644 (file)
@@ -5587,6 +5587,15 @@ WebPageCreationParameters WebPageProxy::creationParameters()
     parameters.observedLayoutMilestones = m_observedLayoutMilestones;
     parameters.overrideContentSecurityPolicy = m_overrideContentSecurityPolicy;
 
+#if ENABLE(WEB_RTC)
+    // FIXME: We should tie ICE filtering with getUserMedia permission.
+    parameters.disableICECandidateFiltering = true;
+#if USE(LIBWEBRTC)
+    // FIXME: Turn down network interface enumeration by default.
+    parameters.enableEnumeratingAllNetworkInterfaces = true;
+#endif
+#endif
+
     return parameters;
 }
 
index 87feb40..18f62e7 100644 (file)
@@ -551,6 +551,15 @@ WebPage::WebPage(uint64_t pageID, WebPageCreationParameters&& parameters)
     m_page->settings().setContentDispositionAttachmentSandboxEnabled(true);
     setSmartInsertDeleteEnabled(parameters.smartInsertDeleteEnabled);
 #endif
+
+#if ENABLE(WEB_RTC)
+    if (parameters.disableICECandidateFiltering)
+        disableICECandidateFiltering();
+#if USE(LIBWEBRTC)
+    if (parameters.enableEnumeratingAllNetworkInterfaces)
+        enableEnumeratingAllNetworkInterfaces();
+#endif
+#endif
 }
 
 void WebPage::reinitializeWebPage(WebPageCreationParameters&& parameters)
index 719bfd8..4714fc7 100644 (file)
@@ -57,6 +57,7 @@
 #include <WebCore/HysteresisActivity.h>
 #include <WebCore/IntRect.h>
 #include <WebCore/IntSizeHash.h>
+#include <WebCore/LibWebRTCProvider.h>
 #include <WebCore/Page.h>
 #include <WebCore/PageOverlay.h>
 #include <WebCore/PageVisibilityState.h>
@@ -1176,6 +1177,15 @@ private:
 #endif
 #endif
 
+#if ENABLE(WEB_RTC)
+    void disableICECandidateFiltering() { m_page->rtcController().disableICECandidateFiltering(); }
+    void enableICECandidateFiltering() { m_page->rtcController().enableICECandidateFiltering(); }
+#if USE(LIBWEBRTC)
+    void disableEnumeratingAllNetworkInterfaces() { m_page->libWebRTCProvider().disableEnumeratingAllNetworkInterfaces(); }
+    void enableEnumeratingAllNetworkInterfaces() { m_page->libWebRTCProvider().enableEnumeratingAllNetworkInterfaces(); }
+#endif
+#endif
+
     void advanceToNextMisspelling(bool startBeforeSelection);
     void changeSpellingToWord(const String& word);
 #if USE(APPKIT)
index 0123aff..5291649 100644 (file)
@@ -306,6 +306,15 @@ messages -> WebPage LegacyReceiver {
 #endif
 #endif
 
+#if ENABLE(WEB_RTC)
+    DisableICECandidateFiltering()
+    EnableICECandidateFiltering()
+#endif
+#if ENABLE(WEB_RTC) && USE(LIBWEBRTC)
+    EnableEnumeratingAllNetworkInterfaces()
+    DisableEnumeratingAllNetworkInterfaces()
+#endif
+
     # Notification
     DidReceiveNotificationPermissionDecision(uint64_t notificationID, bool allowed)