Changeset 261277 in webkit
- Timestamp:
- May 7, 2020 2:23:43 AM (4 years ago)
- Location:
- trunk/Source
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r261273 r261277 1 2020-05-07 Youenn Fablet <youenn@apple.com> 2 3 Sending WebRTC network packets should not go through the main thread 4 https://bugs.webkit.org/show_bug.cgi?id=211291 5 6 Reviewed by Eric Carlson. 7 8 Covered by existing tests. 9 10 * Modules/mediastream/PeerConnectionBackend.cpp: 11 (WebCore::PeerConnectionBackend::filterSDP const): 12 Fix a case where the SDP would be badly formatted if we do not have yet a MDNS name for the corresponding IP address. 13 Small refactoring to use early returns. 14 * platform/mediastream/libwebrtc/LibWebRTCProvider.cpp: 15 (WebCore::LibWebRTCProvider::getStaticFactoryAndThreads): 16 * platform/mediastream/libwebrtc/LibWebRTCProvider.h: 17 Add the ability for WebKit LibWebRTCProvider to do some processing on creation of the RTC threads. 18 1 19 2020-05-06 Sergio Villar Senin <svillar@igalia.com> 2 20 -
trunk/Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp
r259290 r261277 440 440 StringBuilder filteredSDP; 441 441 sdp.split('\n', [this, &filteredSDP](StringView line) { 442 if (line.startsWith("c=IN IP4")) 443 filteredSDP.append("c=IN IP4 0.0.0.0\r"); 444 else if (line.startsWith("c=IN IP6")) 445 filteredSDP.append("c=IN IP6 ::\r"); 446 else if (!line.startsWith("a=candidate")) 442 if (line.startsWith("c=IN IP4")) { 443 filteredSDP.append("c=IN IP4 0.0.0.0\r\n"); 444 return; 445 } 446 if (line.startsWith("c=IN IP6")) { 447 filteredSDP.append("c=IN IP6 ::\r\n"); 448 return; 449 } 450 if (!line.startsWith("a=candidate")) { 447 451 filteredSDP.append(line); 448 else if (line.find(" host ", 11) == notFound) 452 filteredSDP.append('\n'); 453 return; 454 } 455 if (line.find(" host ", 11) == notFound) { 449 456 filteredSDP.append(filterICECandidate(line.toString())); 450 else { 451 auto ipAddress = extractIPAddress(line); 452 auto mdnsName = m_ipAddressToMDNSNameMap.get(ipAddress); 453 if (!mdnsName.isEmpty()) { 454 auto sdp = line.toString(); 455 sdp.replace(ipAddress, mdnsName); 456 filteredSDP.append(sdp); 457 } 458 } 457 filteredSDP.append('\n'); 458 return; 459 } 460 461 auto ipAddress = extractIPAddress(line); 462 auto mdnsName = m_ipAddressToMDNSNameMap.get(ipAddress); 463 if (mdnsName.isEmpty()) 464 return; 465 auto sdp = line.toString(); 466 sdp.replace(ipAddress, mdnsName); 467 filteredSDP.append(sdp); 459 468 filteredSDP.append('\n'); 460 469 }); -
trunk/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCProvider.cpp
r258547 r261277 192 192 } 193 193 194 static inline PeerConnectionFactoryAndThreads&getStaticFactoryAndThreads(bool useNetworkThreadWithSocketServer)194 PeerConnectionFactoryAndThreads& LibWebRTCProvider::getStaticFactoryAndThreads(bool useNetworkThreadWithSocketServer) 195 195 { 196 196 auto& factoryAndThreads = staticFactoryAndThreads(); … … 201 201 factoryAndThreads.networkThreadWithSocketServer = useNetworkThreadWithSocketServer; 202 202 initializePeerConnectionFactoryAndThreads(factoryAndThreads); 203 startedNetworkThread(); 203 204 } 204 205 return factoryAndThreads; -
trunk/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCProvider.h
r259452 r261277 60 60 61 61 class LibWebRTCAudioModule; 62 struct PeerConnectionFactoryAndThreads; 62 63 struct RTCRtpCapabilities; 63 64 … … 135 136 virtual std::unique_ptr<webrtc::VideoEncoderFactory> createEncoderFactory(); 136 137 138 virtual void startedNetworkThread() { }; 139 140 PeerConnectionFactoryAndThreads& getStaticFactoryAndThreads(bool useNetworkThreadWithSocketServer); 141 137 142 bool m_enableEnumeratingAllNetworkInterfaces { false }; 138 143 // FIXME: Remove m_useNetworkThreadWithSocketServer member variable and make it a global. -
trunk/Source/WebKit/ChangeLog
r261276 r261277 1 2020-05-07 Youenn Fablet <youenn@apple.com> 2 3 Sending WebRTC network packets should not go through the main thread 4 https://bugs.webkit.org/show_bug.cgi?id=211291 5 6 Reviewed by Eric Carlson. 7 8 Following on receiving RTC packets from a background thread, we also send RTC packets from a background thread. 9 Creation of the sockets also happens in a background thread. 10 LibWebRTCNetwork is getting the connection whenever a new connection to network process is created. 11 It will then hop to the RTC network thread to set the IPC connection to the libwebrtc socket factory. 12 13 At creation of the socket, we get the IPC connection to the network process and keep a ref in the RTC socket. 14 In case network process crashed and the IPC connection of the RTC network is null, we hop to the main thread to create a new IPC connection. 15 This will fail the creation of the socket (as well as new ones as well) as long as the IPC connection to network process is not valid again. 16 17 Covered by existing tests. 18 19 * WebProcess/Network/webrtc/LibWebRTCNetwork.cpp: 20 (WebKit::LibWebRTCNetwork::setAsActive): 21 (WebKit::LibWebRTCNetwork::setConnection): 22 (WebKit::LibWebRTCNetwork::dispatchToThread): 23 * WebProcess/Network/webrtc/LibWebRTCNetwork.h: 24 (WebKit::LibWebRTCNetwork::connection): 25 (WebKit::LibWebRTCNetwork::isActive const): 26 * WebProcess/Network/webrtc/LibWebRTCProvider.cpp: 27 (WebKit::LibWebRTCProvider::startedNetworkThread): 28 * WebProcess/Network/webrtc/LibWebRTCProvider.h: 29 * WebProcess/Network/webrtc/LibWebRTCSocket.cpp: 30 (WebKit::LibWebRTCSocket::SendTo): 31 (WebKit::LibWebRTCSocket::Close): 32 (WebKit::LibWebRTCSocket::SetOption): 33 (WebKit::LibWebRTCSocket::suspend): 34 * WebProcess/Network/webrtc/LibWebRTCSocket.h: 35 * WebProcess/Network/webrtc/LibWebRTCSocketFactory.cpp: 36 (WebKit::LibWebRTCSocketFactory::setConnection): 37 (WebKit::LibWebRTCSocketFactory::connection): 38 (WebKit::LibWebRTCSocketFactory::createServerTcpSocket): 39 (WebKit::LibWebRTCSocketFactory::createUdpSocket): 40 (WebKit::LibWebRTCSocketFactory::createClientTcpSocket): 41 (WebKit::LibWebRTCSocketFactory::createNewConnectionSocket): 42 (WebKit::LibWebRTCSocketFactory::addSocket): 43 (WebKit::LibWebRTCSocketFactory::removeSocket): 44 (WebKit::LibWebRTCSocketFactory::forSocketInGroup): 45 * WebProcess/Network/webrtc/LibWebRTCSocketFactory.h: 46 1 47 2020-05-07 Adrian Perez de Castro <aperez@igalia.com> 2 48 -
trunk/Source/WebKit/WebProcess/Network/webrtc/LibWebRTCNetwork.cpp
r261163 r261277 40 40 } 41 41 42 void LibWebRTCNetwork::setAsActive() 43 { 44 ASSERT(!m_isActive); 45 m_isActive = true; 46 #if USE(LIBWEBRTC) 47 if (m_connection) { 48 WebCore::LibWebRTCProvider::callOnWebRTCNetworkThread([this, connection = m_connection]() mutable { 49 m_socketFactory.setConnection(WTFMove(connection)); 50 }); 51 } 52 #endif 53 } 54 42 55 void LibWebRTCNetwork::networkProcessCrashed() 43 56 { … … 54 67 if (m_connection) 55 68 m_connection->removeThreadMessageReceiver(Messages::LibWebRTCNetwork::messageReceiverName()); 69 if (m_isActive) { 70 WebCore::LibWebRTCProvider::callOnWebRTCNetworkThread([this, connection]() mutable { 71 m_socketFactory.setConnection(WTFMove(connection)); 72 }); 73 } 56 74 #endif 57 75 m_connection = WTFMove(connection); … … 62 80 } 63 81 64 bool LibWebRTCNetwork::isActive() const65 {66 #if USE(LIBWEBRTC)67 return WebCore::LibWebRTCProvider::hasWebRTCThreads();68 #else69 return false;70 #endif71 }72 73 82 void LibWebRTCNetwork::dispatchToThread(Function<void()>&& callback) 74 83 { 75 if (! isActive()) {84 if (!m_isActive) { 76 85 RELEASE_LOG_ERROR(WebRTC, "Received WebRTCSocket message while libWebRTCNetwork is not active"); 77 86 return; -
trunk/Source/WebKit/WebProcess/Network/webrtc/LibWebRTCNetwork.h
r261163 r261277 42 42 ~LibWebRTCNetwork(); 43 43 44 IPC::Connection* connection() { return m_connection.get(); } 44 45 void setConnection(RefPtr<IPC::Connection>&&); 46 45 47 void networkProcessCrashed(); 46 48 47 bool isActive() const ;49 bool isActive() const { return m_isActive; } 48 50 49 51 #if USE(LIBWEBRTC) … … 61 63 WebMDNSRegister& mdnsRegister() { return m_mdnsRegister; } 62 64 #endif 65 66 void setAsActive(); 63 67 64 68 private: … … 82 86 WebMDNSRegister m_mdnsRegister; 83 87 #endif 88 bool m_isActive { false }; 84 89 RefPtr<IPC::Connection> m_connection; 85 90 }; -
trunk/Source/WebKit/WebProcess/Network/webrtc/LibWebRTCProvider.cpp
r261133 r261277 132 132 } 133 133 134 void LibWebRTCProvider::startedNetworkThread() 135 { 136 WebProcess::singleton().libWebRTCNetwork().setAsActive(); 137 } 138 134 139 std::unique_ptr<LibWebRTCProvider::SuspendableSocketFactory> LibWebRTCProvider::createSocketFactory(String&& userAgent) 135 140 { -
trunk/Source/WebKit/WebProcess/Network/webrtc/LibWebRTCProvider.h
r256838 r261277 58 58 void registerMDNSName(WebCore::DocumentIdentifier, const String& ipAddress, CompletionHandler<void(MDNSNameOrError&&)>&&) final; 59 59 void disableNonLocalhostConnections() final; 60 void startedNetworkThread() final; 60 61 61 62 #if PLATFORM(COCOA) -
trunk/Source/WebKit/WebProcess/Network/webrtc/LibWebRTCSocket.cpp
r261163 r261277 58 58 } 59 59 60 void LibWebRTCSocket::sendOnMainThread(Function<void(IPC::Connection&)>&& callback)61 {62 callOnMainThread([callback = WTFMove(callback)]() {63 callback(WebProcess::singleton().ensureNetworkProcessConnection().connection());64 });65 }66 67 60 rtc::SocketAddress LibWebRTCSocket::GetLocalAddress() const 68 61 { … … 136 129 int LibWebRTCSocket::SendTo(const void *value, size_t size, const rtc::SocketAddress& address, const rtc::PacketOptions& options) 137 130 { 138 if (!willSend(size)) 131 auto* connection = m_factory.connection(); 132 if (!connection || !willSend(size)) 139 133 return -1; 140 134 … … 142 136 return size; 143 137 144 auto buffer = WebCore::SharedBuffer::create(static_cast<const uint8_t*>(value), size); 145 auto identifier = this->identifier(); 146 147 sendOnMainThread([identifier, buffer = WTFMove(buffer), address, options](auto& connection) { 148 IPC::DataReference data(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size()); 149 connection.send(Messages::NetworkRTCSocket::SendTo { data, RTCNetwork::SocketAddress { address }, RTCPacketOptions { options } }, identifier); 150 }); 138 IPC::DataReference data(static_cast<const uint8_t*>(value), size); 139 connection->send(Messages::NetworkRTCSocket::SendTo { data, RTCNetwork::SocketAddress { address }, RTCPacketOptions { options } }, m_identifier); 140 151 141 return size; 152 142 } … … 154 144 int LibWebRTCSocket::Close() 155 145 { 156 if (m_state == STATE_CLOSED) 146 auto* connection = m_factory.connection(); 147 if (!connection || m_state == STATE_CLOSED) 157 148 return 0; 158 149 159 150 m_state = STATE_CLOSED; 160 151 161 sendOnMainThread([identifier = identifier()](auto& connection) { 162 connection.send(Messages::NetworkRTCSocket::Close(), identifier); 163 }); 152 connection->send(Messages::NetworkRTCSocket::Close(), m_identifier); 153 164 154 return 0; 165 155 } … … 181 171 m_options[option] = value; 182 172 183 sendOnMainThread([identifier = identifier(), option, value](auto& connection) {184 connection .send(Messages::NetworkRTCSocket::SetOption(option, value),identifier);185 }); 173 if (auto* connection = m_factory.connection()) 174 connection->send(Messages::NetworkRTCSocket::SetOption(option, value), m_identifier); 175 186 176 return 0; 187 177 } … … 208 198 209 199 // On suspend, we close TCP sockets as we cannot make sure packets are delivered reliably. 210 if (m_type != Type::UDP) {211 sendOnMainThread([identifier = identifier()](auto& connection) {212 connection.send(Messages::NetworkRTCSocket::Close { }, identifier); 213 });214 }200 if (m_type == Type::UDP) 201 return; 202 203 if (auto* connection = m_factory.connection()) 204 connection->send(Messages::NetworkRTCSocket::Close { }, m_identifier); 215 205 } 216 206 -
trunk/Source/WebKit/WebProcess/Network/webrtc/LibWebRTCSocket.h
r261163 r261277 86 86 int SetOption(rtc::Socket::Option, int) final; 87 87 88 static void sendOnMainThread(Function<void(IPC::Connection&)>&&);89 90 88 LibWebRTCSocketFactory& m_factory; 91 89 WebCore::LibWebRTCSocketIdentifier m_identifier; -
trunk/Source/WebKit/WebProcess/Network/webrtc/LibWebRTCSocketFactory.cpp
r261163 r261277 29 29 #if USE(LIBWEBRTC) 30 30 31 #include "LibWebRTCNetwork.h" 32 #include "Logging.h" 31 33 #include "NetworkProcessConnection.h" 32 34 #include "NetworkRTCMonitorMessages.h" … … 46 48 } 47 49 50 void LibWebRTCSocketFactory::setConnection(RefPtr<IPC::Connection>&& connection) 51 { 52 ASSERT(!WTF::isMainRunLoop()); 53 m_connection = WTFMove(connection); 54 } 55 56 IPC::Connection* LibWebRTCSocketFactory::connection() 57 { 58 ASSERT(!WTF::isMainRunLoop()); 59 return m_connection.get(); 60 } 61 48 62 rtc::AsyncPacketSocket* LibWebRTCSocketFactory::createServerTcpSocket(const void* socketGroup, const rtc::SocketAddress& address, uint16_t minPort, uint16_t maxPort, int options) 49 63 { 64 ASSERT(!WTF::isMainRunLoop()); 65 if (!m_connection) { 66 RELEASE_LOG(WebRTC, "No connection to create server TCP socket"); 67 callOnMainThread([] { 68 WebProcess::singleton().ensureNetworkProcessConnection(); 69 }); 70 return nullptr; 71 } 72 50 73 auto socket = makeUnique<LibWebRTCSocket>(*this, socketGroup, LibWebRTCSocket::Type::ServerTCP, address, rtc::SocketAddress()); 51 74 52 callOnMainThread([identifier = socket->identifier(), address = prepareSocketAddress(address, m_disableNonLocalhostConnections), minPort, maxPort, options]() { 53 if (!WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkRTCProvider::CreateServerTCPSocket(identifier, RTCNetwork::SocketAddress(address), minPort, maxPort, options), 0)) { 54 // FIXME: Set error back to socket 55 return; 56 } 75 m_connection->send(Messages::NetworkRTCProvider::CreateServerTCPSocket(socket->identifier(), RTCNetwork::SocketAddress(address), minPort, maxPort, options), 0); 57 76 58 });59 77 return socket.release(); 60 78 } … … 62 80 rtc::AsyncPacketSocket* LibWebRTCSocketFactory::createUdpSocket(const void* socketGroup, const rtc::SocketAddress& address, uint16_t minPort, uint16_t maxPort) 63 81 { 82 ASSERT(!WTF::isMainRunLoop()); 83 if (!m_connection) { 84 RELEASE_LOG(WebRTC, "No connection to create UDP socket"); 85 callOnMainThread([] { 86 WebProcess::singleton().ensureNetworkProcessConnection(); 87 }); 88 return nullptr; 89 } 90 64 91 auto socket = makeUnique<LibWebRTCSocket>(*this, socketGroup, LibWebRTCSocket::Type::UDP, address, rtc::SocketAddress()); 65 92 66 callOnMainThread([identifier = socket->identifier(), address = prepareSocketAddress(address, m_disableNonLocalhostConnections), minPort, maxPort]() { 67 if (!WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkRTCProvider::CreateUDPSocket(identifier, RTCNetwork::SocketAddress(address), minPort, maxPort), 0)) { 68 // FIXME: Set error back to socket 69 return; 70 } 71 }); 93 m_connection->send(Messages::NetworkRTCProvider::CreateUDPSocket(socket->identifier(), RTCNetwork::SocketAddress(address), minPort, maxPort), 0); 94 72 95 return socket.release(); 73 96 } … … 75 98 rtc::AsyncPacketSocket* LibWebRTCSocketFactory::createClientTcpSocket(const void* socketGroup, const rtc::SocketAddress& localAddress, const rtc::SocketAddress& remoteAddress, String&& userAgent, const rtc::PacketSocketTcpOptions& options) 76 99 { 100 ASSERT(!WTF::isMainRunLoop()); 101 if (!m_connection) { 102 RELEASE_LOG(WebRTC, "No connection to create client TCP socket"); 103 callOnMainThread([] { 104 WebProcess::singleton().ensureNetworkProcessConnection(); 105 }); 106 return nullptr; 107 } 108 77 109 auto socket = makeUnique<LibWebRTCSocket>(*this, socketGroup, LibWebRTCSocket::Type::ClientTCP, localAddress, remoteAddress); 78 110 socket->setState(LibWebRTCSocket::STATE_CONNECTING); 79 111 80 112 // FIXME: We only transfer options.opts but should also handle other members. 81 callOnMainThread([identifier = socket->identifier(), localAddress = prepareSocketAddress(localAddress, m_disableNonLocalhostConnections), remoteAddress = prepareSocketAddress(remoteAddress, m_disableNonLocalhostConnections), userAgent = WTFMove(userAgent).isolatedCopy(), options = options.opts]() { 82 if (!WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkRTCProvider::CreateClientTCPSocket(identifier, RTCNetwork::SocketAddress(localAddress), RTCNetwork::SocketAddress(remoteAddress), userAgent, options), 0)) { 83 // FIXME: Set error back to socket 84 return; 85 } 86 }); 113 m_connection->send(Messages::NetworkRTCProvider::CreateClientTCPSocket(socket->identifier(), RTCNetwork::SocketAddress(prepareSocketAddress(localAddress, m_disableNonLocalhostConnections)), RTCNetwork::SocketAddress(prepareSocketAddress(remoteAddress, m_disableNonLocalhostConnections)), userAgent, options.opts), 0); 114 87 115 return socket.release(); 88 116 } … … 90 118 rtc::AsyncPacketSocket* LibWebRTCSocketFactory::createNewConnectionSocket(LibWebRTCSocket& serverSocket, LibWebRTCSocketIdentifier newConnectionSocketIdentifier, const rtc::SocketAddress& remoteAddress) 91 119 { 120 ASSERT(!WTF::isMainRunLoop()); 121 if (!m_connection) { 122 RELEASE_LOG(WebRTC, "No connection to create incoming TCP socket"); 123 callOnMainThread([] { 124 WebProcess::singleton().ensureNetworkProcessConnection(); 125 }); 126 return nullptr; 127 } 128 92 129 auto socket = makeUnique<LibWebRTCSocket>(*this, serverSocket.socketGroup(), LibWebRTCSocket::Type::ServerConnectionTCP, serverSocket.localAddress(), remoteAddress); 93 130 socket->setState(LibWebRTCSocket::STATE_CONNECTED); 94 131 95 callOnMainThread([identifier = socket->identifier(), newConnectionSocketIdentifier]() { 96 if (!WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkRTCProvider::WrapNewTCPConnection(identifier, newConnectionSocketIdentifier), 0)) { 97 // FIXME: Set error back to socket 98 return; 99 } 100 }); 132 m_connection->send(Messages::NetworkRTCProvider::WrapNewTCPConnection(socket->identifier(), newConnectionSocketIdentifier), 0); 133 101 134 return socket.release(); 102 135 } … … 104 137 void LibWebRTCSocketFactory::addSocket(LibWebRTCSocket& socket) 105 138 { 139 ASSERT(!WTF::isMainRunLoop()); 106 140 ASSERT(!m_sockets.contains(socket.identifier())); 107 141 m_sockets.add(socket.identifier(), &socket); … … 110 144 void LibWebRTCSocketFactory::removeSocket(LibWebRTCSocket& socket) 111 145 { 146 ASSERT(!WTF::isMainRunLoop()); 112 147 ASSERT(m_sockets.contains(socket.identifier())); 113 148 m_sockets.remove(socket.identifier()); … … 116 151 void LibWebRTCSocketFactory::forSocketInGroup(const void* socketGroup, const Function<void(LibWebRTCSocket&)>& callback) 117 152 { 153 ASSERT(!WTF::isMainRunLoop()); 118 154 for (auto* socket : m_sockets.values()) { 119 155 if (socket->socketGroup() == socketGroup) -
trunk/Source/WebKit/WebProcess/Network/webrtc/LibWebRTCSocketFactory.h
r259345 r261277 38 38 namespace WebKit { 39 39 40 class LibWebRTCNetwork; 40 41 class LibWebRTCSocket; 41 42 42 43 class LibWebRTCSocketFactory { 43 44 public: 44 LibWebRTCSocketFactory() { }45 LibWebRTCSocketFactory() = default; 45 46 46 47 void addSocket(LibWebRTCSocket&); … … 60 61 void disableNonLocalhostConnections() { m_disableNonLocalhostConnections = true; } 61 62 63 void setConnection(RefPtr<IPC::Connection>&&); 64 IPC::Connection* connection(); 65 62 66 private: 63 67 // We cannot own sockets, clients of the factory are responsible to free them. … … 67 71 HashMap<LibWebRTCResolverIdentifier, std::unique_ptr<LibWebRTCResolver>> m_resolvers; 68 72 bool m_disableNonLocalhostConnections { false }; 73 74 RefPtr<IPC::Connection> m_connection; 69 75 }; 70 76
Note: See TracChangeset
for help on using the changeset viewer.