1/*
2 * Copyright (C) 2017 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25#include "config.h"
26#include "RTCController.h"
27
28#if ENABLE(WEB_RTC)
29
30#include "Document.h"
31#include "LibWebRTCProvider.h"
32#include "RTCPeerConnection.h"
33
34namespace WebCore {
35
36RTCController::~RTCController()
37{
38 for (RTCPeerConnection& connection : m_peerConnections)
39 connection.clearController();
40}
41
42void RTCController::reset(bool shouldFilterICECandidates)
43{
44 m_shouldFilterICECandidates = shouldFilterICECandidates;
45 for (RTCPeerConnection& connection : m_peerConnections)
46 connection.clearController();
47 m_peerConnections.clear();
48 m_filteringDisabledOrigins.clear();
49}
50
51void RTCController::remove(RTCPeerConnection& connection)
52{
53 m_peerConnections.removeFirstMatching([&connection](auto item) {
54 return &connection == &item.get();
55 });
56}
57
58static inline bool matchDocumentOrigin(Document& document, SecurityOrigin& topOrigin, SecurityOrigin& clientOrigin)
59{
60 if (topOrigin.isSameOriginAs(document.securityOrigin()))
61 return true;
62 return topOrigin.isSameOriginAs(document.topOrigin()) && clientOrigin.isSameOriginAs(document.securityOrigin());
63}
64
65bool RTCController::shouldDisableICECandidateFiltering(Document& document)
66{
67 if (!m_shouldFilterICECandidates)
68 return true;
69 return notFound != m_filteringDisabledOrigins.findMatching([&] (const auto& origin) {
70 return matchDocumentOrigin(document, origin.topOrigin, origin.clientOrigin);
71 });
72}
73
74void RTCController::add(RTCPeerConnection& connection)
75{
76 m_peerConnections.append(connection);
77 if (shouldDisableICECandidateFiltering(downcast<Document>(*connection.scriptExecutionContext())))
78 connection.disableICECandidateFiltering();
79}
80
81void RTCController::disableICECandidateFilteringForAllOrigins()
82{
83 if (!LibWebRTCProvider::webRTCAvailable())
84 return;
85
86 m_shouldFilterICECandidates = false;
87 for (RTCPeerConnection& connection : m_peerConnections)
88 connection.disableICECandidateFiltering();
89}
90
91void RTCController::disableICECandidateFilteringForDocument(Document& document)
92{
93 if (!LibWebRTCProvider::webRTCAvailable())
94 return;
95
96 m_filteringDisabledOrigins.append(PeerConnectionOrigin { document.topOrigin(), document.securityOrigin() });
97 for (RTCPeerConnection& connection : m_peerConnections) {
98 if (auto* peerConnectionDocument = downcast<Document>(connection.scriptExecutionContext())) {
99 if (matchDocumentOrigin(*peerConnectionDocument, document.topOrigin(), document.securityOrigin()))
100 connection.disableICECandidateFiltering();
101 }
102 }
103}
104
105void RTCController::enableICECandidateFiltering()
106{
107 if (!LibWebRTCProvider::webRTCAvailable())
108 return;
109
110 m_filteringDisabledOrigins.clear();
111 m_shouldFilterICECandidates = true;
112 for (RTCPeerConnection& connection : m_peerConnections)
113 connection.enableICECandidateFiltering();
114}
115
116} // namespace WebCore
117
118#endif
119