blob: c7b751ddddb8345c3d009ccf7dc9954567c36922 [file] [log] [blame]
/*
* Copyright (C) 2017-2022 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 "Document.h"
#include "LibWebRTCProvider.h"
#include "RTCNetworkManager.h"
#include "RTCPeerConnection.h"
namespace WebCore {
RTCController::~RTCController()
{
for (RTCPeerConnection& connection : m_peerConnections)
connection.clearController();
}
void RTCController::reset(bool shouldFilterICECandidates)
{
m_shouldFilterICECandidates = shouldFilterICECandidates;
for (RTCPeerConnection& connection : m_peerConnections)
connection.clearController();
m_peerConnections.clear();
m_filteringDisabledOrigins.clear();
}
void RTCController::remove(RTCPeerConnection& connection)
{
m_peerConnections.removeFirstMatching([&connection](auto item) {
return &connection == &item.get();
});
}
static inline bool matchDocumentOrigin(Document& document, SecurityOrigin& topOrigin, SecurityOrigin& clientOrigin)
{
if (topOrigin.isSameOriginAs(document.securityOrigin()))
return true;
return topOrigin.isSameOriginAs(document.topOrigin()) && clientOrigin.isSameOriginAs(document.securityOrigin());
}
bool RTCController::shouldDisableICECandidateFiltering(Document& document)
{
if (!m_shouldFilterICECandidates)
return true;
return notFound != m_filteringDisabledOrigins.findIf([&] (const auto& origin) {
return matchDocumentOrigin(document, origin.topOrigin, origin.clientOrigin);
});
}
void RTCController::add(RTCPeerConnection& connection)
{
auto& document = downcast<Document>(*connection.scriptExecutionContext());
if (auto* networkManager = document.rtcNetworkManager())
networkManager->setICECandidateFiltering(!shouldDisableICECandidateFiltering(document));
m_peerConnections.append(connection);
if (shouldDisableICECandidateFiltering(downcast<Document>(*connection.scriptExecutionContext())))
connection.disableICECandidateFiltering();
}
void RTCController::disableICECandidateFilteringForAllOrigins()
{
if (!LibWebRTCProvider::webRTCAvailable())
return;
m_shouldFilterICECandidates = false;
for (RTCPeerConnection& connection : m_peerConnections) {
if (auto* document = downcast<Document>(connection.scriptExecutionContext())) {
if (auto* networkManager = document->rtcNetworkManager())
networkManager->setICECandidateFiltering(false);
}
connection.disableICECandidateFiltering();
}
}
void RTCController::disableICECandidateFilteringForDocument(Document& document)
{
if (!LibWebRTCProvider::webRTCAvailable())
return;
if (auto* networkManager = document.rtcNetworkManager())
networkManager->setICECandidateFiltering(false);
m_filteringDisabledOrigins.append(PeerConnectionOrigin { document.topOrigin(), document.securityOrigin() });
for (RTCPeerConnection& connection : m_peerConnections) {
if (auto* peerConnectionDocument = downcast<Document>(connection.scriptExecutionContext())) {
if (matchDocumentOrigin(*peerConnectionDocument, document.topOrigin(), document.securityOrigin())) {
if (auto* networkManager = peerConnectionDocument->rtcNetworkManager())
networkManager->setICECandidateFiltering(false);
connection.disableICECandidateFiltering();
}
}
}
}
void RTCController::enableICECandidateFiltering()
{
if (!LibWebRTCProvider::webRTCAvailable())
return;
m_filteringDisabledOrigins.clear();
m_shouldFilterICECandidates = true;
for (RTCPeerConnection& connection : m_peerConnections) {
connection.enableICECandidateFiltering();
if (auto* document = downcast<Document>(connection.scriptExecutionContext())) {
if (auto* networkManager = document->rtcNetworkManager())
networkManager->setICECandidateFiltering(true);
}
}
}
} // namespace WebCore
#endif