WebRTC data channel only applications require capture permissions for direct connections
authoryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 5 Apr 2018 02:05:01 +0000 (02:05 +0000)
committeryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 5 Apr 2018 02:05:01 +0000 (02:05 +0000)
https://bugs.webkit.org/show_bug.cgi?id=174500
<rdar://problem/34134281>

Reviewed by Eric Carlson.

Source/WebCore:

Test: webrtc/datachannel/mdns-ice-candidates.html

Add support at PeerConnectionBackend to obfuscate any gathered host candidate
by replacing the IP address with an opaque name that can be resolved by MDNS.
An opaque name is generated for each IP address and is scoped by the document owning the peer connection object.

Add support to resolve any such MDNS ICE candidate.
A limit of 250 ms is fixed for the resolution to happen.
After 250 ms, the candidate is discarded.

Add an experimental flag around this feature, off by default.

* Modules/mediastream/PeerConnectionBackend.cpp:
(WebCore::extractIPAddres):
(WebCore::PeerConnectionBackend::addIceCandidate):
(WebCore::PeerConnectionBackend::addIceCandidateSucceeded):
(WebCore::PeerConnectionBackend::addIceCandidateFailed):
(WebCore::PeerConnectionBackend::newICECandidate):
(WebCore::PeerConnectionBackend::doneGatheringCandidates):
(WebCore::PeerConnectionBackend::registerMDNSName):
(WebCore::PeerConnectionBackend::finishedRegisteringMDNSName):
* Modules/mediastream/PeerConnectionBackend.h:
* Modules/mediastream/RTCIceCandidate.h:
(WebCore::RTCIceCandidate::setCandidate):
* Modules/mediastream/RTCPeerConnection.h:
* dom/Document.cpp:
(WebCore::Document::prepareForDestruction):
(WebCore::Document::suspend):
* page/RuntimeEnabledFeatures.h:
(WebCore::RuntimeEnabledFeatures::mdnsICECandidatesEnabled const):
(WebCore::RuntimeEnabledFeatures::setMDNSICECandidatesEnabled):
* platform/mediastream/libwebrtc/LibWebRTCProvider.h:

Source/WebKit:

Add support for MDNS registration and resolution by NetworkProcess.
WebProcess gives instruction to do the actual registrations/resolutions.

* CMakeLists.txt:
* DerivedSources.make:
* NetworkProcess/NetworkConnectionToWebProcess.cpp:
(WebKit::NetworkConnectionToWebProcess::NetworkConnectionToWebProcess):
(WebKit::NetworkConnectionToWebProcess::didReceiveMessage):
* NetworkProcess/NetworkConnectionToWebProcess.h:
(WebKit::NetworkConnectionToWebProcess::mdnsRegister):
* NetworkProcess/webrtc/NetworkMDNSRegister.cpp: Added.
(WebKit::NetworkMDNSRegister::NetworkMDNSRegister):
(WebKit::NetworkMDNSRegister::~NetworkMDNSRegister):
(WebKit::NetworkMDNSRegister::unregisterMDNSNames):
(WebKit::PendingRegistrationRequest::PendingRegistrationRequest):
(WebKit::registerMDNSNameCallback):
(WebKit::NetworkMDNSRegister::registerMDNSName):
(WebKit::PendingResolutionRequest::PendingResolutionRequest):
(WebKit::PendingResolutionRequest::~PendingResolutionRequest):
(WebKit::PendingResolutionRequest::timeout):
(WebKit::resolveMDNSNameCallback):
(WebKit::NetworkMDNSRegister::resolveMDNSName):
* NetworkProcess/webrtc/NetworkMDNSRegister.h: Added.
* NetworkProcess/webrtc/NetworkMDNSRegister.messages.in: Added.
* Shared/WebPreferences.yaml:
* UIProcess/API/C/WKPreferences.cpp:
(WKPreferencesSetWebRTCMDNSICECandidatesEnabled):
(WKPreferencesGetWebRTCMDNSICECandidatesEnabled):
* UIProcess/API/C/WKPreferencesRef.h:
* WebKit.xcodeproj/project.pbxproj:
* WebProcess/InjectedBundle/InjectedBundle.cpp:
(WebKit::InjectedBundle::overrideBoolPreferenceForTestRunner):
* WebProcess/Network/NetworkProcessConnection.cpp:
(WebKit::NetworkProcessConnection::didReceiveMessage):
* WebProcess/Network/webrtc/LibWebRTCNetwork.h:
(WebKit::LibWebRTCNetwork::mdnsRegister):
* WebProcess/Network/webrtc/LibWebRTCProvider.cpp:
(WebKit::LibWebRTCProvider::unregisterMDNSNames):
(WebKit::LibWebRTCProvider::registerMDNSName):
(WebKit::LibWebRTCProvider::resolveMDNSName):
* WebProcess/Network/webrtc/LibWebRTCProvider.h:
* WebProcess/Network/webrtc/WebMDNSRegister.cpp: Added.
(WebKit::WebMDNSRegister::finishedRegisteringMDNSName):
(WebKit::WebMDNSRegister::finishedResolvingMDNSName):
(WebKit::WebMDNSRegister::unregisterMDNSNames):
(WebKit::WebMDNSRegister::registerMDNSName):
(WebKit::WebMDNSRegister::resolveMDNSName):
* WebProcess/Network/webrtc/WebMDNSRegister.h: Added.
* WebProcess/Network/webrtc/WebMDNSRegister.messages.in: Added.

Tools:

Adding options to enable MDNS ICE candidates.

* WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
* WebKitTestRunner/InjectedBundle/TestRunner.cpp:
(WTR::TestRunner::setMediaDevicesEnabled):
(WTR::TestRunner::setMDNSICECandidatesEnabled):
* WebKitTestRunner/InjectedBundle/TestRunner.h:
* WebKitTestRunner/TestController.cpp:
(WTR::TestController::resetPreferencesToConsistentValues):

LayoutTests:

* webrtc/datachannel/mdns-ice-candidates-expected.txt: Added.
* webrtc/datachannel/mdns-ice-candidates.html: Added.

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

39 files changed:
LayoutTests/ChangeLog
LayoutTests/platform/mac-wk1/TestExpectations
LayoutTests/webrtc/datachannel/mdns-ice-candidates-expected.txt [new file with mode: 0644]
LayoutTests/webrtc/datachannel/mdns-ice-candidates.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp
Source/WebCore/Modules/mediastream/PeerConnectionBackend.h
Source/WebCore/Modules/mediastream/RTCIceCandidate.h
Source/WebCore/Modules/mediastream/RTCPeerConnection.h
Source/WebCore/dom/Document.cpp
Source/WebCore/page/RuntimeEnabledFeatures.h
Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCProvider.h
Source/WebKit/CMakeLists.txt
Source/WebKit/ChangeLog
Source/WebKit/DerivedSources.make
Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp
Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h
Source/WebKit/NetworkProcess/webrtc/NetworkMDNSRegister.cpp [new file with mode: 0644]
Source/WebKit/NetworkProcess/webrtc/NetworkMDNSRegister.h [new file with mode: 0644]
Source/WebKit/NetworkProcess/webrtc/NetworkMDNSRegister.messages.in [new file with mode: 0644]
Source/WebKit/Shared/WebPreferences.yaml
Source/WebKit/UIProcess/API/C/WKPreferences.cpp
Source/WebKit/UIProcess/API/C/WKPreferencesRef.h
Source/WebKit/WebKit.xcodeproj/project.pbxproj
Source/WebKit/WebProcess/InjectedBundle/InjectedBundle.cpp
Source/WebKit/WebProcess/Network/NetworkProcessConnection.cpp
Source/WebKit/WebProcess/Network/webrtc/LibWebRTCNetwork.h
Source/WebKit/WebProcess/Network/webrtc/LibWebRTCProvider.cpp
Source/WebKit/WebProcess/Network/webrtc/LibWebRTCProvider.h
Source/WebKit/WebProcess/Network/webrtc/WebMDNSRegister.cpp [new file with mode: 0644]
Source/WebKit/WebProcess/Network/webrtc/WebMDNSRegister.h [new file with mode: 0644]
Source/WebKit/WebProcess/Network/webrtc/WebMDNSRegister.messages.in [new file with mode: 0644]
Source/WebKit/WebProcess/WebProcess.cpp
Source/WebKit/WebProcess/WebProcess.h
Tools/ChangeLog
Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl
Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp
Tools/WebKitTestRunner/InjectedBundle/TestRunner.h
Tools/WebKitTestRunner/TestController.cpp

index 0e0d042..15d6f32 100644 (file)
@@ -1,3 +1,14 @@
+2018-04-04  Youenn Fablet  <youenn@apple.com>
+
+        WebRTC data channel only applications require capture permissions for direct connections
+        https://bugs.webkit.org/show_bug.cgi?id=174500
+        <rdar://problem/34134281>
+
+        Reviewed by Eric Carlson.
+
+        * webrtc/datachannel/mdns-ice-candidates-expected.txt: Added.
+        * webrtc/datachannel/mdns-ice-candidates.html: Added.
+
 2018-04-04  Ryan Haddad  <ryanhaddad@apple.com>
 
         Mark storage/websql/database-lock-after-reload.html as flaky.
index 88dc8c7..cb742cc 100644 (file)
@@ -150,6 +150,7 @@ webrtc [ Skip ]
 http/tests/webrtc [ Skip ]
 http/wpt/webrtc [ Skip ]
 webrtc/datachannel [ Pass ]
+webrtc/datachannel/mdns-ice-candidates.html [ Skip ]
 webrtc/datachannel/bufferedAmountLowThreshold.html [ Pass Failure ]
 webrtc/datachannel/bufferedAmountLowThreshold-default.html [ Pass Failure ]
 
diff --git a/LayoutTests/webrtc/datachannel/mdns-ice-candidates-expected.txt b/LayoutTests/webrtc/datachannel/mdns-ice-candidates-expected.txt
new file mode 100644 (file)
index 0000000..f74e86c
--- /dev/null
@@ -0,0 +1,7 @@
+
+PASS Getting some MDNS candidates 
+PASS Basic data channel exchange from offerer to receiver 
+PASS Basic data channel exchange from receiver to offerer 
+PASS Basic data channel exchange from offerer to receiver using UDP only 
+PASS Basic data channel exchange from offerer to receiver 
+
diff --git a/LayoutTests/webrtc/datachannel/mdns-ice-candidates.html b/LayoutTests/webrtc/datachannel/mdns-ice-candidates.html
new file mode 100644 (file)
index 0000000..c6576d9
--- /dev/null
@@ -0,0 +1,154 @@
+<!doctype html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Testing basic data channel from offerer to receiver with MDNS ICE Candidates</title>
+    <script src="../../resources/testharness.js"></script>
+    <script src="../../resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <script src ="../routines.js"></script>
+    <script>
+if (window.testRunner)
+    testRunner.setMDNSICECandidatesEnabled(true);
+if (window.internals)
+    internals.setICECandidateFiltering(true);
+
+var localChannel;
+var remoteChannel;
+
+function closeDataChannels() {
+    localChannel.close();
+    remoteChannel.close();
+    closeConnections();
+}
+
+function receiveMessages(event) {
+try {
+    if (++counter === 1)
+        assert_equals(event.data, "one");
+    else if (counter === 2)
+        assert_equals(event.data, "two");
+    else if (counter === 3)
+        assert_equals(event.data, "three");
+    else if (counter === 4) {
+        assert_equals(event.data, "four");
+        closeDataChannels();
+        finishTest();
+    } else
+        assert_unreached();
+} catch(e) {
+    console.log(e);
+}
+}
+
+function sendMessages(channel)
+{
+    channel.send("one");
+    channel.send("two");
+    channel.send("three");
+    channel.send("four");
+}
+
+promise_test((test) => {
+    return new Promise((resolve, reject) => {
+        createConnections((localConnection) => {
+            localConnection.createDataChannel('sendDataChannel');
+        }, () => {
+        }, {
+            filterOutICECandidate: (candidate) => {
+                if (candidate && candidate.candidate.toLowerCase().indexOf("host") !== -1)
+                    assert_true(candidate.candidate.indexOf(".local") !== -1);
+                if (!candidate)
+                    resolve();
+                return false;
+            }
+        });
+        setTimeout(() => { reject("Test timed out"); }, 5000);
+    });
+}, "Getting some MDNS candidates");
+
+var finishTest;
+promise_test((test) => {
+    counter = 0;
+    return new Promise((resolve, reject) => {
+        finishTest = resolve;
+        createConnections((localConnection) => {
+            localChannel = localConnection.createDataChannel('sendDataChannel');
+            localChannel.onopen = () => { sendMessages(localChannel) };
+        }, (remoteConnection) => {
+            remoteConnection.ondatachannel = (event) => {
+                remoteChannel = event.channel;
+                remoteChannel.onmessage = receiveMessages;
+            };
+        });
+        setTimeout(() => { reject("Test timed out"); }, 5000);
+    });
+}, "Basic data channel exchange from offerer to receiver");
+
+promise_test((test) => {
+    counter = 0;
+    return new Promise((resolve, reject) => {
+        finishTest = resolve;
+        createConnections((localConnection) => {
+            localChannel = localConnection.createDataChannel('sendDataChannel');
+            localChannel.onmessage = receiveMessages;
+        }, (remoteConnection) => {
+            remoteConnection.ondatachannel = (event) => {
+                remoteChannel = event.channel;
+                remoteChannel.onopen = () => { sendMessages(remoteChannel) };
+            };
+        });
+        setTimeout(() => { reject("Test timed out"); }, 5000);
+    });
+}, "Basic data channel exchange from receiver to offerer");
+
+
+promise_test((test) => {
+    counter = 0;
+    return new Promise((resolve, reject) => {
+        finishTest = resolve;
+        createConnections((localConnection) => {
+            localChannel = localConnection.createDataChannel('sendDataChannel');
+            localChannel.onopen = () => { sendMessages(localChannel) };
+        }, (remoteConnection) => {
+            remoteConnection.ondatachannel = (event) => {
+                remoteChannel = event.channel;
+                remoteChannel.onmessage = receiveMessages;
+            };
+        }, { filterOutICECandidate: (candidate) => { return candidate && candidate.candidate.toLowerCase().indexOf("udp") == -1; } });
+        setTimeout(() => { reject("Test timed out"); }, 5000);
+    });
+}, "Basic data channel exchange from offerer to receiver using UDP only");
+
+promise_test((test) => {
+    counter = 0;
+    return new Promise((resolve, reject) => {
+        var checkDataChannelOptions = (channel, init) => {
+            assert_equals(channel.ordered, init.ordered, "ordered");
+            assert_equals(channel.maxPacketLifeTime, init.maxPacketLifeTime, "maxPacketLifeTime");
+            assert_equals(channel.maxRetransmitTime, init.maxRetransmitTime, "maxRetransmitTime");
+            assert_equals(channel.maxRetransmits, init.maxRetransmits, "maxRetransmits");
+            assert_equals(channel.protocol, init.protocol, "protocol");
+            assert_equals(channel.negotiated, init.negotiated, "negotiated");
+            assert_equals(channel.id, init.id, "id");
+        };
+
+        finishTest = resolve;
+        createConnections((localConnection) => {
+            var init = { ordered: true, maxPacketLifeTime: 10, maxRetransmitTime: 11, protocol: "whatever", negotiated: false, id: 1 };
+            localChannel = localConnection.createDataChannel('sendDataChannel', init);
+            localChannel.onopen = () => { sendMessages(localChannel) };
+        }, (remoteConnection) => {
+            remoteConnection.ondatachannel = (event) => {
+                remoteChannel = event.channel;
+                remoteChannel.onmessage = receiveMessages;
+            };
+        });
+        setTimeout(() => { reject("Test timed out"); }, 5000);
+    });
+}, "Basic data channel exchange from offerer to receiver");
+
+    </script>
+  </body>
+</html>
index f9dd073..34853aa 100644 (file)
@@ -1,3 +1,44 @@
+2018-04-04  Youenn Fablet  <youenn@apple.com>
+
+        WebRTC data channel only applications require capture permissions for direct connections
+        https://bugs.webkit.org/show_bug.cgi?id=174500
+        <rdar://problem/34134281>
+
+        Reviewed by Eric Carlson.
+
+        Test: webrtc/datachannel/mdns-ice-candidates.html
+
+        Add support at PeerConnectionBackend to obfuscate any gathered host candidate
+        by replacing the IP address with an opaque name that can be resolved by MDNS.
+        An opaque name is generated for each IP address and is scoped by the document owning the peer connection object.
+
+        Add support to resolve any such MDNS ICE candidate.
+        A limit of 250 ms is fixed for the resolution to happen.
+        After 250 ms, the candidate is discarded.
+
+        Add an experimental flag around this feature, off by default.
+
+        * Modules/mediastream/PeerConnectionBackend.cpp:
+        (WebCore::extractIPAddres):
+        (WebCore::PeerConnectionBackend::addIceCandidate):
+        (WebCore::PeerConnectionBackend::addIceCandidateSucceeded):
+        (WebCore::PeerConnectionBackend::addIceCandidateFailed):
+        (WebCore::PeerConnectionBackend::newICECandidate):
+        (WebCore::PeerConnectionBackend::doneGatheringCandidates):
+        (WebCore::PeerConnectionBackend::registerMDNSName):
+        (WebCore::PeerConnectionBackend::finishedRegisteringMDNSName):
+        * Modules/mediastream/PeerConnectionBackend.h:
+        * Modules/mediastream/RTCIceCandidate.h:
+        (WebCore::RTCIceCandidate::setCandidate):
+        * Modules/mediastream/RTCPeerConnection.h:
+        * dom/Document.cpp:
+        (WebCore::Document::prepareForDestruction):
+        (WebCore::Document::suspend):
+        * page/RuntimeEnabledFeatures.h:
+        (WebCore::RuntimeEnabledFeatures::mdnsICECandidatesEnabled const):
+        (WebCore::RuntimeEnabledFeatures::setMDNSICECandidatesEnabled):
+        * platform/mediastream/libwebrtc/LibWebRTCProvider.h:
+
 2018-04-04  Brian Burg  <bburg@apple.com>
 
         [Cocoa] WebDriver: test imported/w3c/webdriver/tests/cookies/add_cookie.py::test_add_non_session_cookie fails
index 4687e23..dc51bb5 100644 (file)
@@ -40,7 +40,9 @@
 #include "RTCIceCandidate.h"
 #include "RTCPeerConnection.h"
 #include "RTCPeerConnectionIceEvent.h"
+#include "RuntimeEnabledFeatures.h"
 #include <wtf/text/StringBuilder.h>
+#include <wtf/text/StringConcatenateNumbers.h>
 
 namespace WebCore {
 
@@ -254,15 +256,58 @@ void PeerConnectionBackend::setRemoteDescriptionFailed(Exception&& exception)
     m_setDescriptionPromise = std::nullopt;
 }
 
+static String extractIPAddres(const String& sdp)
+{
+    ASSERT(sdp.contains(" host "));
+    unsigned counter = 0;
+    for (auto item : StringView { sdp }.split(' ')) {
+        if (++counter == 5)
+            return item.toString();
+    }
+    return { };
+}
+
 void PeerConnectionBackend::addIceCandidate(RTCIceCandidate* iceCandidate, DOMPromiseDeferred<void>&& promise)
 {
     ASSERT(!m_peerConnection.isClosed());
 
     if (!iceCandidate) {
+        if (m_waitingForMDNSResolution) {
+            m_finishedReceivingCandidates = true;
+            m_endOfIceCandidatePromise = WTFMove(promise);
+            return;
+        }
         endOfIceCandidates(WTFMove(promise));
         return;
     }
 
+    if (RuntimeEnabledFeatures::sharedFeatures().mdnsICECandidatesEnabled()) {
+        auto name = extractIPAddres(iceCandidate->candidate());
+        if (name.endsWith(".local")) {
+            ++m_waitingForMDNSResolution;
+            auto& document = downcast<Document>(*m_peerConnection.scriptExecutionContext());
+            auto& provider = document.page()->libWebRTCProvider();
+            provider.resolveMDNSName(document.sessionID(), name, [peerConnection = makeRef(m_peerConnection), this, name, iceCandidate = makeRef(*iceCandidate), promise = WTFMove(promise)] (LibWebRTCProvider::IPAddressOrError&& result) mutable {
+                if (peerConnection->isStopped())
+                    return;
+
+                --m_waitingForMDNSResolution;
+                if (!result.has_value()) {
+                    if (result.error() != MDNSRegisterError::Timeout)
+                        peerConnection->scriptExecutionContext()->addConsoleMessage(MessageSource::JS, MessageLevel::Warning, makeString("MDNS resolution of a host candidate failed with error", (unsigned)result.error()));
+                    return;
+                }
+
+                auto candidate = iceCandidate->candidate();
+                candidate.replace(name, result.value());
+                iceCandidate->setCandidate(WTFMove(candidate));
+                m_addIceCandidatePromise = WTFMove(promise);
+                this->doAddIceCandidate(iceCandidate);
+            });
+            return;
+        }
+    }
+
     // FIXME: As per https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addicecandidate(), this check should be done before enqueuing the task.
     if (iceCandidate->sdpMid().isNull() && !iceCandidate->sdpMLineIndex()) {
         promise.reject(Exception { TypeError, ASCIILiteral("Trying to add a candidate that is missing both sdpMid and sdpMLineIndex") });
@@ -285,6 +330,9 @@ void PeerConnectionBackend::addIceCandidateSucceeded()
 
     m_addIceCandidatePromise->resolve();
     m_addIceCandidatePromise = std::nullopt;
+
+    if (!m_waitingForMDNSResolution && m_finishedReceivingCandidates)
+        endOfIceCandidates(WTFMove(*m_endOfIceCandidatePromise));
 }
 
 void PeerConnectionBackend::addIceCandidateFailed(Exception&& exception)
@@ -299,6 +347,9 @@ void PeerConnectionBackend::addIceCandidateFailed(Exception&& exception)
 
     m_addIceCandidatePromise->reject(WTFMove(exception));
     m_addIceCandidatePromise = std::nullopt;
+
+    if (!m_waitingForMDNSResolution && m_finishedReceivingCandidates)
+        endOfIceCandidates(WTFMove(*m_endOfIceCandidatePromise));
 }
 
 void PeerConnectionBackend::fireICECandidateEvent(RefPtr<RTCIceCandidate>&& candidate)
@@ -376,13 +427,21 @@ String PeerConnectionBackend::filterSDP(String&& sdp) const
 void PeerConnectionBackend::newICECandidate(String&& sdp, String&& mid, unsigned short sdpMLineIndex)
 {
     ALWAYS_LOG(LOGIDENTIFIER, "Gathered ice candidate:", sdp);
+    m_finishedGatheringCandidates = false;
 
     if (!m_shouldFilterICECandidates) {
         fireICECandidateEvent(RTCIceCandidate::create(WTFMove(sdp), WTFMove(mid), sdpMLineIndex));
         return;
     }
     if (sdp.find(" host ", 0) != notFound) {
-        m_pendingICECandidates.append(PendingICECandidate { WTFMove(sdp), WTFMove(mid), sdpMLineIndex});
+        // FIXME: We might need to clear all pending candidates when setting again local description.
+        m_pendingICECandidates.append(PendingICECandidate { String { sdp }, WTFMove(mid), sdpMLineIndex});
+        if (RuntimeEnabledFeatures::sharedFeatures().mdnsICECandidatesEnabled()) {
+            auto ipAddress = extractIPAddres(sdp);
+            // We restrict to IPv4 candidates for now.
+            if (ipAddress.contains('.'))
+                registerMDNSName(ipAddress);
+        }
         return;
     }
     fireICECandidateEvent(RTCIceCandidate::create(filterICECandidate(WTFMove(sdp)), WTFMove(mid), sdpMLineIndex));
@@ -392,9 +451,52 @@ void PeerConnectionBackend::doneGatheringCandidates()
 {
     ASSERT(isMainThread());
     ALWAYS_LOG(LOGIDENTIFIER, "Finished ice candidate gathering");
+    m_finishedGatheringCandidates = true;
+
+    if (m_waitingForMDNSRegistration)
+        return;
 
     m_peerConnection.fireEvent(RTCPeerConnectionIceEvent::create(false, false, nullptr));
     m_peerConnection.updateIceGatheringState(RTCIceGatheringState::Complete);
+    m_pendingICECandidates.clear();
+}
+
+void PeerConnectionBackend::registerMDNSName(const String& ipAddress)
+{
+    ++m_waitingForMDNSRegistration;
+    auto& document = downcast<Document>(*m_peerConnection.scriptExecutionContext());
+    auto& provider = document.page()->libWebRTCProvider();
+    provider.registerMDNSName(document.sessionID(), document.identifier().toUInt64(), ipAddress, [peerConnection = makeRef(m_peerConnection), this, ipAddress] (LibWebRTCProvider::MDNSNameOrError&& result) {
+        if (peerConnection->isStopped())
+            return;
+
+        --m_waitingForMDNSRegistration;
+        if (!result.has_value()) {
+            m_peerConnection.scriptExecutionContext()->addConsoleMessage(MessageSource::JS, MessageLevel::Warning, makeString("MDNS registration of a host candidate failed with error", (unsigned)result.error()));
+            return;
+        }
+
+        this->finishedRegisteringMDNSName(ipAddress, result.value());
+    });
+}
+
+void PeerConnectionBackend::finishedRegisteringMDNSName(const String& ipAddress, const String& name)
+{
+    Vector<PendingICECandidate*> candidates;
+    for (auto& candidate : m_pendingICECandidates) {
+        if (candidate.sdp.find(ipAddress) != notFound) {
+            auto sdp = candidate.sdp;
+            sdp.replace(ipAddress, name);
+            fireICECandidateEvent(RTCIceCandidate::create(String(sdp), String(candidate.mid), candidate.sdpMLineIndex));
+            candidates.append(&candidate);
+        }
+    }
+    m_pendingICECandidates.removeAllMatching([&] (const auto& candidate) {
+        return candidates.contains(&candidate);
+    });
+
+    if (!m_waitingForMDNSRegistration && m_finishedGatheringCandidates)
+        doneGatheringCandidates();
 }
 
 void PeerConnectionBackend::updateSignalingState(RTCSignalingState newSignalingState)
index 61c1dc6..0fa48cd 100644 (file)
@@ -34,6 +34,7 @@
 #if ENABLE(WEB_RTC)
 
 #include "JSDOMPromiseDeferred.h"
+#include "LibWebRTCProvider.h"
 #include "RTCRtpParameters.h"
 #include "RTCSessionDescription.h"
 #include "RTCSignalingState.h"
@@ -127,6 +128,8 @@ public:
 
     virtual bool isLocalDescriptionSet() const = 0;
 
+    void finishedRegisteringMDNSName(const String& ipAddress, const String& name);
+
 protected:
     void fireICECandidateEvent(RefPtr<RTCIceCandidate>&&);
     void doneGatheringCandidates();
@@ -159,6 +162,8 @@ private:
     virtual void endOfIceCandidates(DOMPromiseDeferred<void>&& promise) { promise.resolve(); }
     virtual void doStop() = 0;
 
+    void registerMDNSName(const String& ipAddress);
+
 protected:
     RTCPeerConnection& m_peerConnection;
 
@@ -166,6 +171,7 @@ private:
     std::optional<PeerConnection::SessionDescriptionPromise> m_offerAnswerPromise;
     std::optional<DOMPromiseDeferred<void>> m_setDescriptionPromise;
     std::optional<DOMPromiseDeferred<void>> m_addIceCandidatePromise;
+    std::optional<DOMPromiseDeferred<void>> m_endOfIceCandidatePromise;
 
     bool m_shouldFilterICECandidates { true };
     struct PendingICECandidate {
@@ -181,6 +187,13 @@ private:
     const void* m_logIdentifier;
 #endif
     bool m_negotiationNeeded { false };
+    bool m_finishedGatheringCandidates { false };
+    uint64_t m_waitingForMDNSRegistration { 0 };
+
+    bool m_finishedReceivingCandidates { false };
+    uint64_t m_waitingForMDNSResolution { 0 };
+
+    HashMap<String, String> m_mdnsMapping;
 };
 
 } // namespace WebCore
index 2c66549..b35c20d 100644 (file)
@@ -52,6 +52,8 @@ public:
     const String& sdpMid() const { return m_sdpMid; }
     std::optional<unsigned short> sdpMLineIndex() const { return m_sdpMLineIndex; }
 
+    void setCandidate(String&& candidate) { m_candidate = WTFMove(candidate); }
+
 private:
     RTCIceCandidate(const String& candidate, const String& sdpMid, std::optional<unsigned short> sdpMLineIndex);
 
index bee8121..e99751d 100644 (file)
@@ -107,6 +107,7 @@ public:
     void close();
 
     bool isClosed() const { return m_connectionState == RTCPeerConnectionState::Closed; }
+    bool isStopped() const { return m_isStopped; }
 
     // 5.1 RTCPeerConnection extensions
     const Vector<std::reference_wrapper<RTCRtpSender>>& getSenders() const { return m_transceiverSet->senders(); }
index ce1beaf..c7a182b 100644 (file)
 #include "KeyboardEvent.h"
 #include "KeyframeEffectReadOnly.h"
 #include "LayoutDisallowedScope.h"
+#include "LibWebRTCProvider.h"
 #include "LoaderStrategy.h"
 #include "Logging.h"
 #include "MediaCanStartListener.h"
@@ -2349,6 +2350,11 @@ void Document::prepareForDestruction()
     if (m_frame)
         m_frame->animation().detachFromDocument(this);
 
+#if USE(LIBWEBRTC)
+    if (auto* page = this->page())
+        page->libWebRTCProvider().unregisterMDNSNames(identifier().toUInt64());
+#endif
+
 #if ENABLE(SERVICE_WORKER)
     setActiveServiceWorker(nullptr);
     setServiceWorkerConnection(nullptr);
@@ -4877,6 +4883,11 @@ void Document::suspend(ActiveDOMObject::ReasonForSuspension reason)
             view->compositor().cancelCompositingLayerUpdate();
     }
 
+#if USE(LIBWEBRTC)
+    if (auto* page = this->page())
+        page->libWebRTCProvider().unregisterMDNSNames(identifier().toUInt64());
+#endif
+
 #if ENABLE(SERVICE_WORKER)
     if (RuntimeEnabledFeatures::sharedFeatures().serviceWorkerEnabled() && reason == ActiveDOMObject::ReasonForSuspension::PageCache) {
         ASSERT_WITH_MESSAGE(!activeServiceWorker(), "Documents with an active service worker should not go into PageCache in the first place");
index fd7d2b3..888117f 100644 (file)
@@ -120,6 +120,8 @@ public:
     void setPeerConnectionEnabled(bool isEnabled) { m_isPeerConnectionEnabled = isEnabled; }
     bool webRTCLegacyAPIEnabled() const { return m_webRTCLegacyAPIEnabled; }
     void setWebRTCLegacyAPIEnabled(bool isEnabled) { m_webRTCLegacyAPIEnabled = isEnabled; }
+    bool mdnsICECandidatesEnabled() const { return m_mdnsICECandidatesEnabled; }
+    void setMDNSICECandidatesEnabled(bool isEnabled) { m_mdnsICECandidatesEnabled = isEnabled; }
 #endif
 
 #if ENABLE(LEGACY_CSS_VENDOR_PREFIXES)
@@ -290,6 +292,7 @@ private:
 #if ENABLE(WEB_RTC)
     bool m_isPeerConnectionEnabled { true };
     bool m_webRTCLegacyAPIEnabled { false };
+    bool m_mdnsICECandidatesEnabled { false };
 #endif
 
 #if ENABLE(LEGACY_CSS_VENDOR_PREFIXES)
index 9dac5d4..2864f8d 100644 (file)
 #pragma once
 
 #include "LibWebRTCMacros.h"
-#include <wtf/Forward.h>
+#include <pal/SessionID.h>
+#include <wtf/CompletionHandler.h>
+#include <wtf/EnumTraits.h>
+#include <wtf/Expected.h>
 #include <wtf/UniqueRef.h>
+#include <wtf/text/WTFString.h>
 
 #if USE(LIBWEBRTC)
 
@@ -53,6 +57,8 @@ namespace WebCore {
 
 class LibWebRTCAudioModule;
 
+enum class MDNSRegisterError { NotImplemented, BadParameter, DNSSD, Internal, Timeout };
+
 class WEBCORE_EXPORT LibWebRTCProvider {
 public:
     static UniqueRef<LibWebRTCProvider> create();
@@ -65,6 +71,27 @@ public:
 
     virtual void setH264HardwareEncoderAllowed(bool) { }
 
+    using IPAddressOrError = Expected<String, MDNSRegisterError>;
+    using MDNSNameOrError = Expected<String, MDNSRegisterError>;
+
+    virtual void unregisterMDNSNames(uint64_t documentIdentifier)
+    {
+        UNUSED_PARAM(documentIdentifier);
+    }
+
+    virtual void registerMDNSName(PAL::SessionID, uint64_t documentIdentifier, const String& ipAddress, CompletionHandler<void(MDNSNameOrError&&)>&& callback)
+    {
+        UNUSED_PARAM(documentIdentifier);
+        UNUSED_PARAM(ipAddress);
+        callback(makeUnexpected(MDNSRegisterError::NotImplemented));
+    }
+
+    virtual void resolveMDNSName(PAL::SessionID, const String& name, CompletionHandler<void(IPAddressOrError&&)>&& callback)
+    {
+        UNUSED_PARAM(name);
+        callback(makeUnexpected(MDNSRegisterError::NotImplemented));
+    }
+
 #if USE(LIBWEBRTC)
     virtual rtc::scoped_refptr<webrtc::PeerConnectionInterface> createPeerConnection(webrtc::PeerConnectionObserver&, webrtc::PeerConnectionInterface::RTCConfiguration&&);
 
@@ -98,3 +125,16 @@ protected:
 };
 
 } // namespace WebCore
+
+namespace WTF {
+template<> struct EnumTraits<WebCore::MDNSRegisterError> {
+    using values = EnumValues<
+        WebCore::MDNSRegisterError,
+        WebCore::MDNSRegisterError::NotImplemented,
+        WebCore::MDNSRegisterError::BadParameter,
+        WebCore::MDNSRegisterError::DNSSD,
+        WebCore::MDNSRegisterError::Internal,
+        WebCore::MDNSRegisterError::Timeout
+    >;
+};
+}
index a5b9f1d..705a6f4 100644 (file)
@@ -146,6 +146,8 @@ set(WebKit_SOURCES
     NetworkProcess/capture/NetworkCaptureResource.cpp
     NetworkProcess/capture/NetworkDataTaskReplay.cpp
 
+    NetworkProcess/webrtc/NetworkMDNSRegister.cpp
+
     Platform/Logging.cpp
     Platform/Module.cpp
 
@@ -533,6 +535,7 @@ set(WebKit_SOURCES
     WebProcess/Network/webrtc/LibWebRTCResolver.cpp
     WebProcess/Network/webrtc/LibWebRTCSocket.cpp
     WebProcess/Network/webrtc/LibWebRTCSocketFactory.cpp
+    WebProcess/Network/webrtc/WebMDNSRegister.cpp
     WebProcess/Network/webrtc/WebRTCMonitor.cpp
     WebProcess/Network/webrtc/WebRTCResolver.cpp
     WebProcess/Network/webrtc/WebRTCSocket.cpp
@@ -627,6 +630,7 @@ set(WebKit_MESSAGES_IN_FILES
 
     NetworkProcess/cache/CacheStorageEngineConnection.messages.in
 
+    NetworkProcess/webrtc/NetworkMDNSRegister.messages.in
     NetworkProcess/webrtc/NetworkRTCMonitor.messages.in
     NetworkProcess/webrtc/NetworkRTCProvider.messages.in
     NetworkProcess/webrtc/NetworkRTCSocket.messages.in
@@ -689,6 +693,7 @@ set(WebKit_MESSAGES_IN_FILES
 
     WebProcess/Geolocation/WebGeolocationManager.messages.in
 
+    WebProcess/Network/webrtc/WebMDNSRegister.messages.in
     WebProcess/Network/webrtc/WebRTCMonitor.messages.in
     WebProcess/Network/webrtc/WebRTCResolver.messages.in
     WebProcess/Network/webrtc/WebRTCSocket.messages.in
index 0aa871c..5485be5 100644 (file)
@@ -1,3 +1,61 @@
+2018-04-04  Youenn Fablet  <youenn@apple.com>
+
+        WebRTC data channel only applications require capture permissions for direct connections
+        https://bugs.webkit.org/show_bug.cgi?id=174500
+        <rdar://problem/34134281>
+
+        Reviewed by Eric Carlson.
+
+        Add support for MDNS registration and resolution by NetworkProcess.
+        WebProcess gives instruction to do the actual registrations/resolutions.
+
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * NetworkProcess/NetworkConnectionToWebProcess.cpp:
+        (WebKit::NetworkConnectionToWebProcess::NetworkConnectionToWebProcess):
+        (WebKit::NetworkConnectionToWebProcess::didReceiveMessage):
+        * NetworkProcess/NetworkConnectionToWebProcess.h:
+        (WebKit::NetworkConnectionToWebProcess::mdnsRegister):
+        * NetworkProcess/webrtc/NetworkMDNSRegister.cpp: Added.
+        (WebKit::NetworkMDNSRegister::NetworkMDNSRegister):
+        (WebKit::NetworkMDNSRegister::~NetworkMDNSRegister):
+        (WebKit::NetworkMDNSRegister::unregisterMDNSNames):
+        (WebKit::PendingRegistrationRequest::PendingRegistrationRequest):
+        (WebKit::registerMDNSNameCallback):
+        (WebKit::NetworkMDNSRegister::registerMDNSName):
+        (WebKit::PendingResolutionRequest::PendingResolutionRequest):
+        (WebKit::PendingResolutionRequest::~PendingResolutionRequest):
+        (WebKit::PendingResolutionRequest::timeout):
+        (WebKit::resolveMDNSNameCallback):
+        (WebKit::NetworkMDNSRegister::resolveMDNSName):
+        * NetworkProcess/webrtc/NetworkMDNSRegister.h: Added.
+        * NetworkProcess/webrtc/NetworkMDNSRegister.messages.in: Added.
+        * Shared/WebPreferences.yaml:
+        * UIProcess/API/C/WKPreferences.cpp:
+        (WKPreferencesSetWebRTCMDNSICECandidatesEnabled):
+        (WKPreferencesGetWebRTCMDNSICECandidatesEnabled):
+        * UIProcess/API/C/WKPreferencesRef.h:
+        * WebKit.xcodeproj/project.pbxproj:
+        * WebProcess/InjectedBundle/InjectedBundle.cpp:
+        (WebKit::InjectedBundle::overrideBoolPreferenceForTestRunner):
+        * WebProcess/Network/NetworkProcessConnection.cpp:
+        (WebKit::NetworkProcessConnection::didReceiveMessage):
+        * WebProcess/Network/webrtc/LibWebRTCNetwork.h:
+        (WebKit::LibWebRTCNetwork::mdnsRegister):
+        * WebProcess/Network/webrtc/LibWebRTCProvider.cpp:
+        (WebKit::LibWebRTCProvider::unregisterMDNSNames):
+        (WebKit::LibWebRTCProvider::registerMDNSName):
+        (WebKit::LibWebRTCProvider::resolveMDNSName):
+        * WebProcess/Network/webrtc/LibWebRTCProvider.h:
+        * WebProcess/Network/webrtc/WebMDNSRegister.cpp: Added.
+        (WebKit::WebMDNSRegister::finishedRegisteringMDNSName):
+        (WebKit::WebMDNSRegister::finishedResolvingMDNSName):
+        (WebKit::WebMDNSRegister::unregisterMDNSNames):
+        (WebKit::WebMDNSRegister::registerMDNSName):
+        (WebKit::WebMDNSRegister::resolveMDNSName):
+        * WebProcess/Network/webrtc/WebMDNSRegister.h: Added.
+        * WebProcess/Network/webrtc/WebMDNSRegister.messages.in: Added.
+
 2018-04-04  Alex Christensen  <achristensen@webkit.org>
 
         Use CompletionHandlers for DelayedReplies
index 4f564d5..f96e11b 100644 (file)
@@ -107,6 +107,7 @@ MESSAGE_RECEIVERS = \
     LegacyCustomProtocolManagerProxy \
     NPObjectMessageReceiver \
     NetworkConnectionToWebProcess \
+    NetworkMDNSRegister\
     NetworkProcess \
     NetworkProcessConnection \
     NetworkProcessProxy \
@@ -160,6 +161,7 @@ MESSAGE_RECEIVERS = \
     WebInspectorInterruptDispatcher \
     WebInspectorProxy \
     WebInspectorUI \
+    WebMDNSRegister\
     WebNotificationManager \
     WebPage \
     WebPageProxy \
index 05bee73..e3e823f 100644 (file)
@@ -33,6 +33,7 @@
 #include "NetworkCache.h"
 #include "NetworkConnectionToWebProcessMessages.h"
 #include "NetworkLoad.h"
+#include "NetworkMDNSRegisterMessages.h"
 #include "NetworkProcess.h"
 #include "NetworkProcessConnectionMessages.h"
 #include "NetworkRTCMonitorMessages.h"
@@ -67,6 +68,9 @@ Ref<NetworkConnectionToWebProcess> NetworkConnectionToWebProcess::create(IPC::Co
 
 NetworkConnectionToWebProcess::NetworkConnectionToWebProcess(IPC::Connection::Identifier connectionIdentifier)
     : m_connection(IPC::Connection::createServerConnection(connectionIdentifier, *this))
+#if ENABLE(WEB_RTC)
+    , m_mdnsRegister(*this)
+#endif
 {
     m_connection->open();
 }
@@ -125,6 +129,12 @@ void NetworkConnectionToWebProcess::didReceiveMessage(IPC::Connection& connectio
         return;
     }
 #endif
+#if ENABLE(WEB_RTC)
+    if (decoder.messageReceiverName() == Messages::NetworkMDNSRegister::messageReceiverName()) {
+        mdnsRegister().didReceiveMessage(connection, decoder);
+        return;
+    }
+#endif
 
     if (decoder.messageReceiverName() == Messages::CacheStorageEngineConnection::messageReceiverName()) {
         cacheStorageConnection().didReceiveMessage(connection, decoder);
index 35fa956..a6241dd 100644 (file)
@@ -30,8 +30,8 @@
 #include "Connection.h"
 #include "DownloadID.h"
 #include "NetworkConnectionToWebProcessMessages.h"
+#include "NetworkMDNSRegister.h"
 #include "NetworkRTCProvider.h"
-
 #include <WebCore/ResourceLoadPriority.h>
 #include <wtf/RefCounted.h>
 
@@ -131,6 +131,9 @@ private:
 #if USE(LIBWEBRTC)
     NetworkRTCProvider& rtcProvider();
 #endif
+#if ENABLE(WEB_RTC)
+    NetworkMDNSRegister& mdnsRegister() { return m_mdnsRegister; }
+#endif
 
     CacheStorageEngineConnection& cacheStorageConnection();
 
@@ -146,6 +149,9 @@ private:
 #if USE(LIBWEBRTC)
     RefPtr<NetworkRTCProvider> m_rtcProvider;
 #endif
+#if ENABLE(WEB_RTC)
+    NetworkMDNSRegister m_mdnsRegister;
+#endif
 
     bool m_captureExtraNetworkLoadMetricsEnabled { false };
 
diff --git a/Source/WebKit/NetworkProcess/webrtc/NetworkMDNSRegister.cpp b/Source/WebKit/NetworkProcess/webrtc/NetworkMDNSRegister.cpp
new file mode 100644 (file)
index 0000000..eed2c61
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2018 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 "NetworkMDNSRegister.h"
+
+#if ENABLE(WEB_RTC)
+
+#include "Logging.h"
+#include "NetworkConnectionToWebProcess.h"
+#include "WebMDNSRegisterMessages.h"
+#include <pal/SessionID.h>
+#include <wtf/UUID.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+#define RELEASE_LOG_IF_ALLOWED(sessionID, fmt, ...) RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), Network, "%p - NetworkMDNSRegister::" fmt, this, ##__VA_ARGS__)
+#define RELEASE_LOG_IF_ALLOWED_IN_CALLBACK(sessionID, fmt, ...) RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), Network, "NetworkMDNSRegister callback - " fmt, ##__VA_ARGS__)
+
+NetworkMDNSRegister::NetworkMDNSRegister(NetworkConnectionToWebProcess& connection)
+    : m_connection(connection)
+{
+}
+
+NetworkMDNSRegister::~NetworkMDNSRegister()
+{
+#if ENABLE_MDNS
+    for (auto& value : m_services.values())
+        DNSServiceRefDeallocate(value);
+#endif
+}
+
+#if ENABLE_MDNS
+void NetworkMDNSRegister::unregisterMDNSNames(WebCore::DocumentIdentifier documentIdentifier)
+{
+    auto iterator = m_services.find(documentIdentifier);
+    if (iterator == m_services.end())
+        return;
+    DNSServiceRefDeallocate(iterator->value);
+}
+
+struct PendingRegistrationRequest {
+    PendingRegistrationRequest(Ref<IPC::Connection> connection, uint64_t requestIdentifier, String&& name, PAL::SessionID sessionID)
+        : connection(WTFMove(connection))
+        , requestIdentifier(requestIdentifier)
+        , name(WTFMove(name))
+        , sessionID(sessionID)
+    {
+    }
+
+    Ref<IPC::Connection> connection;
+    uint64_t requestIdentifier { 0 };
+    String name;
+    PAL::SessionID sessionID;
+    DNSRecordRef record;
+};
+
+static void registerMDNSNameCallback(DNSServiceRef, DNSRecordRef record, DNSServiceFlags, DNSServiceErrorType errorCode, void *context)
+{
+    std::unique_ptr<PendingRegistrationRequest> request { static_cast<PendingRegistrationRequest*>(context) };
+
+    RELEASE_LOG_IF_ALLOWED_IN_CALLBACK(request->sessionID, "registerMDNSNameCallback with error %d", errorCode);
+
+    if (errorCode) {
+        request->connection->send(Messages::WebMDNSRegister::FinishedRegisteringMDNSName { request->requestIdentifier, makeUnexpected(MDNSRegisterError::DNSSD) }, 0);
+        return;
+    }
+    request->connection->send(Messages::WebMDNSRegister::FinishedRegisteringMDNSName { request->requestIdentifier, request->name }, 0);
+}
+
+void NetworkMDNSRegister::registerMDNSName(uint64_t requestIdentifier, PAL::SessionID sessionID, DocumentIdentifier documentIdentifier, const String& ipAddress)
+{
+    DNSServiceRef service;
+    auto iterator = m_services.find(documentIdentifier);
+    if (iterator == m_services.end()) {
+        if (auto error = DNSServiceCreateConnection(&service)) {
+            m_connection.connection().send(Messages::WebMDNSRegister::FinishedRegisteringMDNSName { requestIdentifier, makeUnexpected(MDNSRegisterError::DNSSD) }, 0);
+            return;
+        }
+        if (auto error = DNSServiceSetDispatchQueue(service, dispatch_get_main_queue())) {
+            m_connection.connection().send(Messages::WebMDNSRegister::FinishedRegisteringMDNSName { requestIdentifier, makeUnexpected(MDNSRegisterError::DNSSD) }, 0);
+            return;
+        }
+        ASSERT(service);
+        m_services.add(documentIdentifier, service);
+    } else
+        service = iterator->value;
+
+    String baseName = createCanonicalUUIDString();
+    String name = makeString(baseName, String::number(++m_registrationCount), ".local");
+
+    auto ip = inet_addr(ipAddress.utf8().data());
+
+    if (ip == ( in_addr_t)(-1)) {
+        RELEASE_LOG_IF_ALLOWED(sessionID, "registerMDNSName inet_addr error");
+        m_connection.connection().send(Messages::WebMDNSRegister::FinishedRegisteringMDNSName { requestIdentifier, makeUnexpected(MDNSRegisterError::BadParameter) }, 0);
+        return;
+    }
+
+    auto pendingRequest = std::make_unique<PendingRegistrationRequest>(makeRef(m_connection.connection()), requestIdentifier, WTFMove(name), sessionID);
+    auto* record = &pendingRequest->record;
+    auto error = DNSServiceRegisterRecord(service,
+        record,
+        kDNSServiceFlagsUnique,
+        0,
+        pendingRequest->name.utf8().data(),
+        kDNSServiceType_A,
+        kDNSServiceClass_IN,
+        4,
+        &ip,
+        0,
+        registerMDNSNameCallback,
+        pendingRequest.get());
+    if (error) {
+        RELEASE_LOG_IF_ALLOWED(sessionID, "registerMDNSName DNSServiceRegisterRecord error %d", error);
+        m_connection.connection().send(Messages::WebMDNSRegister::FinishedRegisteringMDNSName { requestIdentifier, makeUnexpected(MDNSRegisterError::DNSSD) }, 0);
+        return;
+    }
+    pendingRequest.release();
+}
+
+struct PendingResolutionRequest {
+    PendingResolutionRequest(Ref<IPC::Connection> connection, uint64_t requestIdentifier, PAL::SessionID sessionID)
+        : connection(WTFMove(connection))
+        , requestIdentifier(requestIdentifier)
+        , timeoutTimer(*this, &PendingResolutionRequest::timeout)
+        , sessionID(sessionID)
+    {
+        timeoutTimer.startOneShot(500_ms);
+    }
+
+    ~PendingResolutionRequest()
+    {
+        if (service)
+            DNSServiceRefDeallocate(service);
+        if (operationService)
+            DNSServiceRefDeallocate(operationService);
+    }
+
+    void timeout()
+    {
+        connection->send(Messages::WebMDNSRegister::FinishedResolvingMDNSName { requestIdentifier, makeUnexpected(MDNSRegisterError::Timeout) }, 0);
+        requestIdentifier = 0;
+    }
+
+    Ref<IPC::Connection> connection;
+    uint64_t requestIdentifier { 0 };
+    DNSServiceRef service { nullptr };
+    DNSServiceRef operationService { nullptr };
+    Timer timeoutTimer;
+    PAL::SessionID sessionID;
+};
+
+static void resolveMDNSNameCallback(DNSServiceRef, DNSServiceFlags, uint32_t, DNSServiceErrorType errorCode, const char *hostname, const struct sockaddr *socketAddress, uint32_t ttl, void *context)
+{
+    std::unique_ptr<PendingResolutionRequest> request { static_cast<PendingResolutionRequest*>(context) };
+
+    if (!request->requestIdentifier)
+        return;
+
+    if (errorCode) {
+        RELEASE_LOG_IF_ALLOWED_IN_CALLBACK(request->sessionID, "resolveMDNSNameCallback MDNS error %d", errorCode);
+        request->connection->send(Messages::WebMDNSRegister::FinishedResolvingMDNSName { request->requestIdentifier, makeUnexpected(MDNSRegisterError::DNSSD) }, 0);
+        return;
+    }
+
+    const void* address = socketAddress->sa_family == AF_INET6 ? (const void*) &((const struct sockaddr_in6*)socketAddress)->sin6_addr : (const void*)&((const struct sockaddr_in*)socketAddress)->sin_addr;
+
+    char buffer[INET6_ADDRSTRLEN] = { 0 };
+    if (!inet_ntop(socketAddress->sa_family, address, buffer, sizeof(buffer))) {
+        RELEASE_LOG_IF_ALLOWED_IN_CALLBACK(request->sessionID, "resolveMDNSNameCallback inet_ntop error");
+        request->connection->send(Messages::WebMDNSRegister::FinishedResolvingMDNSName { request->requestIdentifier, makeUnexpected(MDNSRegisterError::DNSSD) }, 0);
+        return;
+    }
+
+    request->connection->send(Messages::WebMDNSRegister::FinishedResolvingMDNSName { request->requestIdentifier, String { buffer } }, 0);
+}
+
+void NetworkMDNSRegister::resolveMDNSName(uint64_t requestIdentifier, PAL::SessionID sessionID, const String& name)
+{
+    UNUSED_PARAM(sessionID);
+    auto pendingRequest = std::make_unique<PendingResolutionRequest>(makeRef(m_connection.connection()), requestIdentifier, sessionID);
+
+    if (auto error = DNSServiceCreateConnection(&pendingRequest->service)) {
+        RELEASE_LOG_IF_ALLOWED(sessionID, "resolveMDNSName DNSServiceCreateConnection error %d", error);
+        m_connection.connection().send(Messages::WebMDNSRegister::FinishedResolvingMDNSName { requestIdentifier, makeUnexpected(MDNSRegisterError::DNSSD) }, 0);
+        return;
+    }
+
+    DNSServiceRef service;
+    auto error = DNSServiceGetAddrInfo(&service,
+        kDNSServiceFlagsUnique,
+        0,
+        kDNSServiceProtocol_IPv4,
+        name.utf8().data(),
+        resolveMDNSNameCallback,
+        pendingRequest.get());
+    pendingRequest->operationService = service;
+    if (error) {
+        RELEASE_LOG_IF_ALLOWED(sessionID, "resolveMDNSName DNSServiceGetAddrInfo error %d", error);
+        m_connection.connection().send(Messages::WebMDNSRegister::FinishedResolvingMDNSName { requestIdentifier, makeUnexpected(MDNSRegisterError::DNSSD) }, 0);
+        return;
+    }
+    pendingRequest.release();
+
+    error = DNSServiceSetDispatchQueue(service, dispatch_get_main_queue());
+    if (error) {
+        RELEASE_LOG_IF_ALLOWED(sessionID, "resolveMDNSName DNSServiceSetDispatchQueue error %d", error);
+        m_connection.connection().send(Messages::WebMDNSRegister::FinishedResolvingMDNSName { requestIdentifier, makeUnexpected(MDNSRegisterError::DNSSD) }, 0);
+    }
+}
+#else
+void NetworkMDNSRegister::unregisterMDNSNames(WebCore::DocumentIdentifier)
+{
+}
+
+void NetworkMDNSRegister::registerMDNSName(uint64_t requestIdentifier, PAL::SessionID sessionID, DocumentIdentifier documentIdentifier, const String& ipAddress)
+{
+    RELEASE_LOG_IF_ALLOWED(sessionID, "registerMDNSName not implemented");
+    m_connection.connection().send(Messages::WebMDNSRegister::FinishedRegisteringMDNSName { requestIdentifier, makeUnexpected(MDNSRegisterError::NotImplemented) }, 0);
+}
+
+void NetworkMDNSRegister::resolveMDNSName(uint64_t requestIdentifier, PAL::SessionID sessionID, const String& name)
+{
+    RELEASE_LOG_IF_ALLOWED(sessionID, "resolveMDNSName not implemented");
+    m_connection.connection().send(Messages::WebMDNSRegister::FinishedResolvingMDNSName { requestIdentifier, makeUnexpected(MDNSRegisterError::NotImplemented) }, 0);
+}
+
+#endif
+
+} // namespace WebKit
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebKit/NetworkProcess/webrtc/NetworkMDNSRegister.h b/Source/WebKit/NetworkProcess/webrtc/NetworkMDNSRegister.h
new file mode 100644 (file)
index 0000000..8fe397f
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2018 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
+
+#if ENABLE(WEB_RTC)
+
+#include "RTCNetwork.h"
+#include <WebCore/DocumentIdentifier.h>
+#include <wtf/Expected.h>
+#include <wtf/Forward.h>
+#include <wtf/HashMap.h>
+
+#if defined __has_include && __has_include(<dns_sd.h>)
+#define ENABLE_MDNS 1
+#else
+#define ENABLE_MDNS 0
+#endif
+
+#if ENABLE_MDNS
+#include <dns_sd.h>
+#endif
+
+namespace IPC {
+class Connection;
+class Decoder;
+}
+
+namespace PAL {
+class SessionID;
+}
+
+namespace WebKit {
+
+class NetworkConnectionToWebProcess;
+
+class NetworkMDNSRegister {
+public:
+    NetworkMDNSRegister(NetworkConnectionToWebProcess&);
+    ~NetworkMDNSRegister();
+
+    void didReceiveMessage(IPC::Connection&, IPC::Decoder&);
+
+private:
+    void unregisterMDNSNames(WebCore::DocumentIdentifier);
+    void registerMDNSName(uint64_t requestIdentifier, PAL::SessionID, WebCore::DocumentIdentifier, const String& ipAddress);
+    void resolveMDNSName(uint64_t requestIdentifier, PAL::SessionID, const String& name);
+
+    NetworkConnectionToWebProcess& m_connection;
+#if ENABLE_MDNS
+    HashMap<WebCore::DocumentIdentifier, DNSServiceRef> m_services;
+
+    uint64_t m_registrationCount { 0 };
+#endif
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebKit/NetworkProcess/webrtc/NetworkMDNSRegister.messages.in b/Source/WebKit/NetworkProcess/webrtc/NetworkMDNSRegister.messages.in
new file mode 100644 (file)
index 0000000..a88f770
--- /dev/null
@@ -0,0 +1,31 @@
+# Copyright (C) 2018 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.
+
+#if ENABLE(WEB_RTC)
+
+messages -> NetworkMDNSRegister {
+    UnregisterMDNSNames(WebCore::DocumentIdentifier documentIdentifier)
+    RegisterMDNSName(uint64_t requestIdentifier, PAL::SessionID sessionID, WebCore::DocumentIdentifier documentIdentifier, String ipAddress)
+    ResolveMDNSName(uint64_t requestIdentifier, PAL::SessionID sessionID, String name)
+}
+
+#endif // ENABLE(WEB_RTC)
index f86033e..e7d0a31 100644 (file)
@@ -1114,6 +1114,15 @@ WebRTCLegacyAPIEnabled:
   webcoreBinding: RuntimeEnabledFeatures
   condition: ENABLE(WEB_RTC)
 
+MDNSICECandidatesEnabled:
+  type: bool
+  defaultValue: false
+  humanReadableName: "Enable MDNS ICE candidates"
+  humanReadableDescription: "Enable MDNS ICE candidates"
+  webcoreBinding: RuntimeEnabledFeatures
+  category: experimental
+  condition: ENABLE(WEB_RTC)
+
 IsSecureContextAttributeEnabled:
   type: bool
   defaultValue: DEFAULT_EXPERIMENTAL_FEATURES_ENABLED
index a4fcd2e..6474d1c 100644 (file)
@@ -1414,6 +1414,16 @@ bool WKPreferencesGetWebRTCLegacyAPIEnabled(WKPreferencesRef preferencesRef)
     return toImpl(preferencesRef)->webRTCLegacyAPIEnabled();
 }
 
+void WKPreferencesSetWebRTCMDNSICECandidatesEnabled(WKPreferencesRef preferencesRef, bool enabled)
+{
+    toImpl(preferencesRef)->setMDNSICECandidatesEnabled(enabled);
+}
+
+bool WKPreferencesGetWebRTCMDNSICECandidatesEnabled(WKPreferencesRef preferencesRef)
+{
+    return toImpl(preferencesRef)->mDNSICECandidatesEnabled();
+}
+
 void WKPreferencesSetSpatialNavigationEnabled(WKPreferencesRef preferencesRef, bool enabled)
 {
     toImpl(preferencesRef)->setSpatialNavigationEnabled(enabled);
index 73c7c0b..35b92c3 100644 (file)
@@ -268,6 +268,10 @@ WK_EXPORT bool WKPreferencesGetPeerConnectionEnabled(WKPreferencesRef preference
 WK_EXPORT void WKPreferencesSetWebRTCLegacyAPIEnabled(WKPreferencesRef preferencesRef, bool enabled);
 WK_EXPORT bool WKPreferencesGetWebRTCLegacyAPIEnabled(WKPreferencesRef preferencesRef);
 
+// Defaults to false
+WK_EXPORT void WKPreferencesSetWebRTCMDNSICECandidatesEnabled(WKPreferencesRef preferencesRef, bool enabled);
+WK_EXPORT bool WKPreferencesGetWebRTCMDNSICECandidatesEnabled(WKPreferencesRef preferencesRef);
+
 // Defaults to false.
 WK_EXPORT void WKPreferencesSetSpatialNavigationEnabled(WKPreferencesRef preferencesRef, bool enabled);
 WK_EXPORT bool WKPreferencesGetSpatialNavigationEnabled(WKPreferencesRef preferencesRef);
index 100b2fd..8408cbe 100644 (file)
                41DC459E1E3DBDA100B11F51 /* WebRTCSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41DC459D1E3DBCF000B11F51 /* WebRTCSocket.cpp */; };
                41DC459F1E3DBDA500B11F51 /* WebRTCSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 41FAF5F31E3BFE7F001AE678 /* WebRTCSocket.h */; };
                41DC45A11E3DC53F00B11F51 /* WebRTCResolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41DC45A01E3DC53C00B11F51 /* WebRTCResolver.cpp */; };
+               41F12A9E2069BB4400FF26E8 /* WebMDNSRegister.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41B7ED6E20681DCF0087D853 /* WebMDNSRegister.cpp */; };
+               41F12A9F2069BB4C00FF26E8 /* NetworkMDNSRegister.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41B7ED6F206965900087D853 /* NetworkMDNSRegister.cpp */; };
                41FABD2A1F4DE001006A6C97 /* CacheStorageEngineCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 41FABD281F4DDFDC006A6C97 /* CacheStorageEngineCache.h */; };
                41FAF5F51E3C0649001AE678 /* WebRTCResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = 41FAF5F41E3C0641001AE678 /* WebRTCResolver.h */; };
                41FAF5F81E3C1021001AE678 /* LibWebRTCResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = 41FAF5F61E3C0B47001AE678 /* LibWebRTCResolver.h */; };
                51F060E11654318500F3281F /* WebRTCMonitorMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51F060DD1654317500F3281F /* WebRTCMonitorMessageReceiver.cpp */; };
                51F060E11654318500F3282C /* WebRTCResolverMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51F060DD1654317500F3282C /* WebRTCResolverMessageReceiver.cpp */; };
                51F060E11654318500F3282E /* NetworkRTCProviderMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51F060DD1654317500F3282E /* NetworkRTCProviderMessageReceiver.cpp */; };
+               51F060E11654318500F3282F /* WebMDNSRegisterMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51F060DD1654317500F3282F /* WebMDNSRegisterMessageReceiver.cpp */; };
+               51F060E11654318500F3283F /* NetworkMDNSRegisterMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51F060DD1654317500F3283F /* NetworkMDNSRegisterMessageReceiver.cpp */; };
                51F7DC41180CC93600212CA3 /* XPCServiceMain.mm in Sources */ = {isa = PBXBuildFile; fileRef = BC82839616B47EC400A278FE /* XPCServiceMain.mm */; };
                51F7DC43180CC93600212CA3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC3DE46815A91763008D26FC /* Foundation.framework */; };
                51F7DC44180CC93600212CA3 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC2EF5B0486A6940098B216 /* WebKit.framework */; };
                41AC86811E042E5300303074 /* WebRTCResolver.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; lineEnding = 0; name = WebRTCResolver.messages.in; path = Network/webrtc/WebRTCResolver.messages.in; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = "<none>"; };
                41B28B081F83AD3E00FB52AC /* RTCPacketOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCPacketOptions.h; sourceTree = "<group>"; };
                41B28B091F83AD3E00FB52AC /* RTCPacketOptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RTCPacketOptions.cpp; sourceTree = "<group>"; };
+               41B7ED6C20681DCE0087D853 /* WebMDNSRegister.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebMDNSRegister.h; path = Network/webrtc/WebMDNSRegister.h; sourceTree = "<group>"; };
+               41B7ED6D20681DCF0087D853 /* WebMDNSRegister.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = WebMDNSRegister.messages.in; path = Network/webrtc/WebMDNSRegister.messages.in; sourceTree = "<group>"; };
+               41B7ED6E20681DCF0087D853 /* WebMDNSRegister.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebMDNSRegister.cpp; path = Network/webrtc/WebMDNSRegister.cpp; sourceTree = "<group>"; };
+               41B7ED6F206965900087D853 /* NetworkMDNSRegister.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NetworkMDNSRegister.cpp; path = NetworkProcess/webrtc/NetworkMDNSRegister.cpp; sourceTree = "<group>"; };
+               41B7ED70206965900087D853 /* NetworkMDNSRegister.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetworkMDNSRegister.h; path = NetworkProcess/webrtc/NetworkMDNSRegister.h; sourceTree = "<group>"; };
+               41B7ED71206965900087D853 /* NetworkMDNSRegister.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = NetworkMDNSRegister.messages.in; path = NetworkProcess/webrtc/NetworkMDNSRegister.messages.in; sourceTree = "<group>"; };
                41C858191F510DEE0065E085 /* CacheStorageEngineCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CacheStorageEngineCache.cpp; sourceTree = "<group>"; };
                41D129D91F3D101400D15E47 /* WebCacheStorageProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebCacheStorageProvider.h; sourceTree = "<group>"; };
                41DC45941E3D6E1E00B11F51 /* NetworkRTCProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetworkRTCProvider.h; path = NetworkProcess/webrtc/NetworkRTCProvider.h; sourceTree = "<group>"; };
                51F060DD1654317500F3281F /* WebRTCMonitorMessageReceiver.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WebRTCMonitorMessageReceiver.cpp; sourceTree = "<group>"; };
                51F060DD1654317500F3282C /* WebRTCResolverMessageReceiver.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WebRTCResolverMessageReceiver.cpp; sourceTree = "<group>"; };
                51F060DD1654317500F3282E /* NetworkRTCProviderMessageReceiver.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkRTCProviderMessageReceiver.cpp; sourceTree = "<group>"; };
+               51F060DD1654317500F3282F /* WebMDNSRegisterMessageReceiver.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WebMDNSRegisterMessageReceiver.cpp; sourceTree = "<group>"; };
+               51F060DD1654317500F3283F /* NetworkMDNSRegisterMessageReceiver.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkMDNSRegisterMessageReceiver.cpp; sourceTree = "<group>"; };
                51F060DE1654317500F3281B /* WebResourceLoaderMessages.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebResourceLoaderMessages.h; sourceTree = "<group>"; };
                51F7DC4A180CC93600212CA3 /* com.apple.WebKit.Storage.xpc */ = {isa = PBXFileReference; explicitFileType = "wrapper.xpc-service"; includeInIndex = 0; path = com.apple.WebKit.Storage.xpc; sourceTree = BUILT_PRODUCTS_DIR; };
                51F886A31F2C214A00C193EF /* WKTestingSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKTestingSupport.cpp; sourceTree = "<group>"; };
                        children = (
                                41DC45991E3DBB2400B11F51 /* LibWebRTCSocketClient.cpp */,
                                41DC459A1E3DBB2400B11F51 /* LibWebRTCSocketClient.h */,
+                               41B7ED6F206965900087D853 /* NetworkMDNSRegister.cpp */,
+                               41B7ED70206965900087D853 /* NetworkMDNSRegister.h */,
+                               41B7ED71206965900087D853 /* NetworkMDNSRegister.messages.in */,
                                4130759A1DE84FB00039EC69 /* NetworkRTCMonitor.cpp */,
                                4130759B1DE84FB00039EC69 /* NetworkRTCMonitor.h */,
                                4130759C1DE84FB00039EC69 /* NetworkRTCMonitor.messages.in */,
                                413075A01DE85EE70039EC69 /* LibWebRTCSocket.h */,
                                413075A51DE85EE70039EC69 /* LibWebRTCSocketFactory.cpp */,
                                413075A61DE85EE70039EC69 /* LibWebRTCSocketFactory.h */,
+                               41B7ED6E20681DCF0087D853 /* WebMDNSRegister.cpp */,
+                               41B7ED6C20681DCE0087D853 /* WebMDNSRegister.h */,
+                               41B7ED6D20681DCF0087D853 /* WebMDNSRegister.messages.in */,
                                413075A21DE85EE70039EC69 /* WebRTCMonitor.cpp */,
                                413075A31DE85EE70039EC69 /* WebRTCMonitor.h */,
                                413075A41DE85EE70039EC69 /* WebRTCMonitor.messages.in */,
                                51DD9F2616367DA2001578E9 /* NetworkConnectionToWebProcessMessageReceiver.cpp */,
                                51DD9F2716367DA2001578E9 /* NetworkConnectionToWebProcessMessages.h */,
                                52F060DD1654317500F3281B /* NetworkContentRuleListManagerMessageReceiver.cpp */,
+                               51F060DD1654317500F3283F /* NetworkMDNSRegisterMessageReceiver.cpp */,
                                517CF0E1163A486C00C2950E /* NetworkProcessConnectionMessageReceiver.cpp */,
                                517CF0E2163A486C00C2950E /* NetworkProcessConnectionMessages.h */,
                                51ACC9341628064800342550 /* NetworkProcessMessageReceiver.cpp */,
                                1CA8B944127C882A00576C2B /* WebInspectorProxyMessages.h */,
                                1CBBE49E19B66C53006B7D81 /* WebInspectorUIMessageReceiver.cpp */,
                                1CBBE49F19B66C53006B7D81 /* WebInspectorUIMessages.h */,
+                               51F060DD1654317500F3282F /* WebMDNSRegisterMessageReceiver.cpp */,
                                31BA9248148830810062EDB5 /* WebNotificationManagerMessageReceiver.cpp */,
                                31BA9249148830810062EDB5 /* WebNotificationManagerMessages.h */,
                                C0CE729E1247E71D00BC0EC4 /* WebPageMessageReceiver.cpp */,
                                530258461DCBBD2200DA89C2 /* NetworkDataTaskReplay.cpp in Sources */,
                                839902021BE9A02B000F3653 /* NetworkLoad.cpp in Sources */,
                                4103FBA52061C8FE00C2EAF8 /* NetworkLoadChecker.cpp in Sources */,
+                               41F12A9F2069BB4C00FF26E8 /* NetworkMDNSRegister.cpp in Sources */,
+                               51F060E11654318500F3283F /* NetworkMDNSRegisterMessageReceiver.cpp in Sources */,
                                51795568162876CF00FA43B6 /* NetworkProcess.cpp in Sources */,
                                7EC4F0FB18E4ACBB008056AF /* NetworkProcessCocoa.mm in Sources */,
                                5183DDEC1630BDFC008BE5C7 /* NetworkProcessConnection.cpp in Sources */,
                                BC9BA5041697C45300E44616 /* WebKit2Initialize.cpp in Sources */,
                                465250E61ECF52DC002025CB /* WebKit2InitializeCocoa.mm in Sources */,
                                51FB08FF1639DE1A00EC324A /* WebLoaderStrategy.cpp in Sources */,
+                               41F12A9E2069BB4400FF26E8 /* WebMDNSRegister.cpp in Sources */,
+                               51F060E11654318500F3282F /* WebMDNSRegisterMessageReceiver.cpp in Sources */,
                                CD003A5219D49B5D005ABCE0 /* WebMediaKeyStorageManager.cpp in Sources */,
                                C98C48A51B6FD4C300145103 /* WebMediaSessionFocusManager.cpp in Sources */,
                                C9C1833B1B74026A007036A7 /* WebMediaSessionFocusManagerClient.cpp in Sources */,
index 490e342..a7c4c1a 100644 (file)
@@ -238,6 +238,8 @@ void InjectedBundle::overrideBoolPreferenceForTestRunner(WebPageGroupProxy* page
 #if ENABLE(WEB_RTC)
     if (preference == "WebKitWebRTCLegacyAPIEnabled")
         RuntimeEnabledFeatures::sharedFeatures().setWebRTCLegacyAPIEnabled(enabled);
+    if (preference == "WebKitMDNSICECandidatesEnabled")
+        RuntimeEnabledFeatures::sharedFeatures().setMDNSICECandidatesEnabled(enabled);
 #endif
 
     if (preference == "WebKitIsSecureContextAttributeEnabled") {
index 792fd04..4b5e104 100644 (file)
@@ -34,6 +34,7 @@
 #include "WebCacheStorageProvider.h"
 #include "WebCoreArgumentCoders.h"
 #include "WebLoaderStrategy.h"
+#include "WebMDNSRegisterMessages.h"
 #include "WebProcess.h"
 #include "WebRTCMonitor.h"
 #include "WebRTCMonitorMessages.h"
@@ -89,6 +90,12 @@ void NetworkProcessConnection::didReceiveMessage(IPC::Connection& connection, IP
         return;
     }
 #endif
+#if ENABLE(WEB_RTC)
+    if (decoder.messageReceiverName() == Messages::WebMDNSRegister::messageReceiverName()) {
+        WebProcess::singleton().libWebRTCNetwork().mdnsRegister().didReceiveMessage(connection, decoder);
+        return;
+    }
+#endif
     if (decoder.messageReceiverName() == Messages::WebCacheStorageConnection::messageReceiverName()) {
         WebProcess::singleton().cacheStorageProvider().process(connection, decoder);
         return;
index 2a9c5ba..72d42ea 100644 (file)
 #pragma once
 
 #if USE(LIBWEBRTC)
-
 #include "LibWebRTCSocketFactory.h"
 #include "WebRTCMonitor.h"
 #include "WebRTCResolver.h"
 #include "WebRTCSocket.h"
+#endif
+
+#include "WebMDNSRegister.h"
 
 namespace WebKit {
 
@@ -38,17 +40,26 @@ class LibWebRTCNetwork {
 public:
     LibWebRTCNetwork() = default;
 
+#if USE(LIBWEBRTC)
     WebRTCMonitor& monitor() { return m_webNetworkMonitor; }
     LibWebRTCSocketFactory& socketFactory() { return m_socketFactory; }
 
     WebRTCSocket socket(uint64_t identifier) { return WebRTCSocket(socketFactory(), identifier); }
     WebRTCResolver resolver(uint64_t identifier) { return WebRTCResolver(socketFactory(), identifier); }
+#endif
+
+#if ENABLE(WEB_RTC)
+    WebMDNSRegister& mdnsRegister() { return m_mdnsRegister; }
+#endif
 
 private:
+#if USE(LIBWEBRTC)
     LibWebRTCSocketFactory m_socketFactory;
     WebRTCMonitor m_webNetworkMonitor;
+#endif
+#if ENABLE(WEB_RTC)
+    WebMDNSRegister m_mdnsRegister;
+#endif
 };
 
 } // namespace WebKit
-
-#endif // USE(LIBWEBRTC)
index 1c259d2..8910bcb 100644 (file)
@@ -32,6 +32,8 @@
 #include "WebProcess.h"
 #include <webrtc/pc/peerconnectionfactory.h>
 
+using namespace WebCore;
+
 namespace WebKit {
 
 rtc::scoped_refptr<webrtc::PeerConnectionInterface> LibWebRTCProvider::createPeerConnection(webrtc::PeerConnectionObserver& observer, webrtc::PeerConnectionInterface::RTCConfiguration&& configuration)
@@ -39,6 +41,21 @@ rtc::scoped_refptr<webrtc::PeerConnectionInterface> LibWebRTCProvider::createPee
     return WebCore::LibWebRTCProvider::createPeerConnection(observer, WebProcess::singleton().libWebRTCNetwork().monitor(), WebProcess::singleton().libWebRTCNetwork().socketFactory(), WTFMove(configuration));
 }
 
+void LibWebRTCProvider::unregisterMDNSNames(uint64_t documentIdentifier)
+{
+    WebProcess::singleton().libWebRTCNetwork().mdnsRegister().unregisterMDNSNames(documentIdentifier);
+}
+
+    void LibWebRTCProvider::registerMDNSName(PAL::SessionID sessionID, uint64_t documentIdentifier, const String& ipAddress, CompletionHandler<void(MDNSNameOrError&&)>&& callback)
+{
+    WebProcess::singleton().libWebRTCNetwork().mdnsRegister().registerMDNSName(sessionID, documentIdentifier, ipAddress, WTFMove(callback));
+}
+
+void LibWebRTCProvider::resolveMDNSName(PAL::SessionID sessionID, const String& name, CompletionHandler<void(IPAddressOrError&&)>&& callback)
+{
+    WebProcess::singleton().libWebRTCNetwork().mdnsRegister().resolveMDNSName(sessionID, name, WTFMove(callback));
+}
+
 } // namespace WebKit
 
 #endif // USE(LIBWEBRTC)
index 12e66fa..580362f 100644 (file)
@@ -47,6 +47,10 @@ public:
 
 private:
     rtc::scoped_refptr<webrtc::PeerConnectionInterface> createPeerConnection(webrtc::PeerConnectionObserver&, webrtc::PeerConnectionInterface::RTCConfiguration&&) final;
+
+    void unregisterMDNSNames(uint64_t documentIdentifier) final;
+    void registerMDNSName(PAL::SessionID, uint64_t documentIdentifier, const String& ipAddress, CompletionHandler<void(MDNSNameOrError&&)>&&) final;
+    void resolveMDNSName(PAL::SessionID, const String& name, CompletionHandler<void(IPAddressOrError&&)>&&) final;
 };
 #else
 using LibWebRTCProvider = WebCore::LibWebRTCProvider;
diff --git a/Source/WebKit/WebProcess/Network/webrtc/WebMDNSRegister.cpp b/Source/WebKit/WebProcess/Network/webrtc/WebMDNSRegister.cpp
new file mode 100644 (file)
index 0000000..e37126b
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2018 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 "WebMDNSRegister.h"
+
+#if ENABLE(WEB_RTC)
+
+#include "NetworkMDNSRegisterMessages.h"
+#include "NetworkProcessConnection.h"
+#include "WebProcess.h"
+#include <WebCore/Document.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+void WebMDNSRegister::finishedRegisteringMDNSName(uint64_t identifier, LibWebRTCProvider::MDNSNameOrError&& result)
+{
+    auto pendingRegistration = m_pendingRegistrations.take(identifier);
+    if (!pendingRegistration.callback)
+        return;
+
+    if (result.has_value()) {
+        auto iterator = m_registeringDocuments.find(pendingRegistration.documentIdentifier);
+        if (iterator == m_registeringDocuments.end())
+            return;
+        iterator->value.add(pendingRegistration.ipAddress, result.value());
+    }
+
+    pendingRegistration.callback(WTFMove(result));
+}
+
+void WebMDNSRegister::finishedResolvingMDNSName(uint64_t identifier, LibWebRTCProvider::IPAddressOrError&& result)
+{
+    auto callback = m_pendingResolutions.take(identifier);
+    if (callback)
+        callback(WTFMove(result));
+}
+
+void WebMDNSRegister::unregisterMDNSNames(uint64_t documentIdentifier)
+{
+    auto identifier = makeObjectIdentifier<DocumentIdentifierType>(documentIdentifier);
+    if (m_registeringDocuments.take(identifier).isEmpty())
+        return;
+
+    auto& connection = WebProcess::singleton().ensureNetworkProcessConnection().connection();
+    connection.send(Messages::NetworkMDNSRegister::UnregisterMDNSNames { identifier }, 0);
+}
+
+void WebMDNSRegister::registerMDNSName(PAL::SessionID sessionID, uint64_t documentIdentifier, const String& ipAddress, CompletionHandler<void(LibWebRTCProvider::MDNSNameOrError&&)>&& callback)
+{
+    auto identifier = makeObjectIdentifier<DocumentIdentifierType>(documentIdentifier);
+    auto& map = m_registeringDocuments.ensure(identifier, [] {
+        return HashMap<String, String> { };
+    }).iterator->value;
+
+    auto iterator = map.find(ipAddress);
+    if (iterator != map.end()) {
+        callback(iterator->value);
+        return;
+    }
+
+    m_pendingRegistrations.add(++m_pendingRequestsIdentifier, PendingRegistration { WTFMove(callback), identifier, ipAddress });
+
+    auto& connection = WebProcess::singleton().ensureNetworkProcessConnection().connection();
+    if (!connection.send(Messages::NetworkMDNSRegister::RegisterMDNSName { m_pendingRequestsIdentifier, sessionID, identifier, ipAddress }, 0))
+        finishedRegisteringMDNSName(m_pendingRequestsIdentifier, makeUnexpected(MDNSRegisterError::Internal));
+}
+
+void WebMDNSRegister::resolveMDNSName(PAL::SessionID sessionID, const String& name, CompletionHandler<void(LibWebRTCProvider::IPAddressOrError&&)>&& callback)
+{
+    m_pendingResolutions.add(++m_pendingRequestsIdentifier, WTFMove(callback));
+
+    auto& connection = WebProcess::singleton().ensureNetworkProcessConnection().connection();
+    if (!connection.send(Messages::NetworkMDNSRegister::ResolveMDNSName { m_pendingRequestsIdentifier, sessionID, name }, 0))
+        finishedResolvingMDNSName(m_pendingRequestsIdentifier, makeUnexpected(MDNSRegisterError::Internal));
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebKit/WebProcess/Network/webrtc/WebMDNSRegister.h b/Source/WebKit/WebProcess/Network/webrtc/WebMDNSRegister.h
new file mode 100644 (file)
index 0000000..bd6e9d1
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2018 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
+
+#if ENABLE(WEB_RTC)
+
+#include <WebCore/DocumentIdentifier.h>
+#include <WebCore/LibWebRTCProvider.h>
+#include <wtf/Expected.h>
+#include <wtf/Forward.h>
+#include <wtf/HashMap.h>
+
+namespace IPC {
+class Connection;
+class Decoder;
+}
+
+namespace WebKit {
+
+class WebMDNSRegister {
+public:
+    WebMDNSRegister() = default;
+
+    void unregisterMDNSNames(uint64_t documentIdentifier);
+    void registerMDNSName(PAL::SessionID, uint64_t documentIdentifier, const String& ipAddress, CompletionHandler<void(WebCore::LibWebRTCProvider::MDNSNameOrError&&)>&&);
+    void resolveMDNSName(PAL::SessionID, const String& name, CompletionHandler<void(WebCore::LibWebRTCProvider::IPAddressOrError&&)>&&);
+
+    void didReceiveMessage(IPC::Connection&, IPC::Decoder&);
+
+private:
+    void finishedRegisteringMDNSName(uint64_t, WebCore::LibWebRTCProvider::MDNSNameOrError&&);
+    void finishedResolvingMDNSName(uint64_t, WebCore::LibWebRTCProvider::IPAddressOrError&&);
+
+    struct PendingRegistration {
+        CompletionHandler<void(WebCore::LibWebRTCProvider::MDNSNameOrError&&)> callback;
+        WebCore::DocumentIdentifier documentIdentifier;
+        String ipAddress;
+    };
+    HashMap<uint64_t, PendingRegistration> m_pendingRegistrations;
+
+    HashMap<uint64_t, CompletionHandler<void(WebCore::LibWebRTCProvider::IPAddressOrError&&)>> m_pendingResolutions;
+    uint64_t m_pendingRequestsIdentifier { 0 };
+
+    HashMap<WebCore::DocumentIdentifier, HashMap<String, String>> m_registeringDocuments;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebKit/WebProcess/Network/webrtc/WebMDNSRegister.messages.in b/Source/WebKit/WebProcess/Network/webrtc/WebMDNSRegister.messages.in
new file mode 100644 (file)
index 0000000..e943e99
--- /dev/null
@@ -0,0 +1,30 @@
+# Copyright (C) 2018 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.
+
+#if ENABLE(WEB_RTC)
+
+messages -> WebMDNSRegister {
+    void FinishedRegisteringMDNSName(uint64_t identifier, WebCore::LibWebRTCProvider::MDNSNameOrError result)
+    void FinishedResolvingMDNSName(uint64_t identifier, WebCore::LibWebRTCProvider::IPAddressOrError result)
+}
+
+#endif // ENABLE(WEB_RTC)
index 746f722..e007764 100644 (file)
@@ -1672,14 +1672,12 @@ bool WebProcess::hasVisibleWebPage() const
     return false;
 }
 
-#if USE(LIBWEBRTC)
 LibWebRTCNetwork& WebProcess::libWebRTCNetwork()
 {
     if (!m_libWebRTCNetwork)
         m_libWebRTCNetwork = std::make_unique<LibWebRTCNetwork>();
     return *m_libWebRTCNetwork;
 }
-#endif
 
 #if ENABLE(SERVICE_WORKER)
 void WebProcess::establishWorkerContextConnectionToStorageProcess(uint64_t pageGroupID, uint64_t pageID, const WebPreferencesStore& store, PAL::SessionID initialSessionID)
index 8d4ec6d..02353e1 100644 (file)
@@ -174,9 +174,7 @@ public:
     void networkProcessConnectionClosed(NetworkProcessConnection*);
     WebLoaderStrategy& webLoaderStrategy();
 
-#if USE(LIBWEBRTC)
     LibWebRTCNetwork& libWebRTCNetwork();
-#endif
 
     void webToStorageProcessConnectionClosed(WebToStorageProcessConnection*);
     WebToStorageProcessConnection* existingWebToStorageProcessConnection() { return m_webToStorageProcessConnection.get(); }
@@ -414,9 +412,7 @@ private:
 
     Ref<WebCacheStorageProvider> m_cacheStorageProvider;
 
-#if USE(LIBWEBRTC)
     std::unique_ptr<LibWebRTCNetwork> m_libWebRTCNetwork;
-#endif
 
     HashSet<String> m_dnsPrefetchedHosts;
     PAL::HysteresisActivity m_dnsPrefetchHystereris;
index a6b7ddb..12b1620 100644 (file)
@@ -1,3 +1,21 @@
+2018-04-04  Youenn Fablet  <youenn@apple.com>
+
+        WebRTC data channel only applications require capture permissions for direct connections
+        https://bugs.webkit.org/show_bug.cgi?id=174500
+        <rdar://problem/34134281>
+
+        Reviewed by Eric Carlson.
+
+        Adding options to enable MDNS ICE candidates.
+
+        * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+        * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+        (WTR::TestRunner::setMediaDevicesEnabled):
+        (WTR::TestRunner::setMDNSICECandidatesEnabled):
+        * WebKitTestRunner/InjectedBundle/TestRunner.h:
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::TestController::resetPreferencesToConsistentValues):
+
 2018-04-04  Ryan Haddad  <ryanhaddad@apple.com>
 
         Disable failing WKWebViewAutofillTests
index 8935dae..7b1e6b9 100644 (file)
@@ -317,6 +317,7 @@ interface TestRunner {
     void setOpenPanelFiles(object filesArray);
 
     void setWebRTCLegacyAPIEnabled(boolean value);
+    void setMDNSICECandidatesEnabled(boolean value);
 
     void terminateNetworkProcess();
     void terminateServiceWorkerProcess();
index 167bc3e..9e7d88b 100644 (file)
@@ -370,6 +370,13 @@ void TestRunner::setMediaDevicesEnabled(bool enabled)
     WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled);
 }
 
+void TestRunner::setMDNSICECandidatesEnabled(bool enabled)
+{
+    WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitMDNSICECandidatesEnabled"));
+    auto& injectedBundle = InjectedBundle::singleton();
+    WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled);
+}
+
 void TestRunner::setWebRTCLegacyAPIEnabled(bool enabled)
 {
     WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitWebRTCLegacyAPIEnabled"));
index 7af8e65..784f7a3 100644 (file)
@@ -129,6 +129,7 @@ public:
     void setEncryptedMediaAPIEnabled(bool);
     void setMediaDevicesEnabled(bool);
     void setWebRTCLegacyAPIEnabled(bool);
+    void setMDNSICECandidatesEnabled(bool);
 
     // Special DOM functions.
     void clearBackForwardList();
index 948881c..8495865 100644 (file)
@@ -668,6 +668,7 @@ void TestController::resetPreferencesToConsistentValues(const TestOptions& optio
     WKPreferencesSetWebAudioEnabled(preferences, true);
     WKPreferencesSetMediaDevicesEnabled(preferences, true);
     WKPreferencesSetWebRTCLegacyAPIEnabled(preferences, true);
+    WKPreferencesSetWebRTCMDNSICECandidatesEnabled(preferences, false);
     WKPreferencesSetDeveloperExtrasEnabled(preferences, true);
     WKPreferencesSetJavaScriptRuntimeFlags(preferences, kWKJavaScriptRuntimeFlagsAllEnabled);
     WKPreferencesSetJavaScriptCanOpenWindowsAutomatically(preferences, true);