<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[287096] branches/safari-613.1.12-branch/Source/WebKit</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/287096">287096</a></dd>
<dt>Author</dt> <dd>repstein@apple.com</dd>
<dt>Date</dt> <dd>2021-12-15 12:15:35 -0800 (Wed, 15 Dec 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>Cherry-pick <a href="http://trac.webkit.org/projects/webkit/changeset/286961">r286961</a>. rdar://problem/86343642

    REGRESSION (<a href="http://trac.webkit.org/projects/webkit/changeset/286841">r286841</a>): [ iOS ] Many webrtc tests flaky failing on iOS
    https://bugs.webkit.org/show_bug.cgi?id=234181
    <rdar://problem/86343642>

    Reviewed by Eric Carlson.

    Use network connection state change callback to know when connection fails or is cancelled.
    Introduce ConnectionStateTracker to know when to stop reading new UDP packets.
    ConnectionStateTracker will be stopped when state is changed to failed or cancelled as well as when the whole connection is closed.
    Renaming m_nwConnections to m_connections as m_nwConnections name was already used.
    Reduce error logging to only new error codes or when connectino enters unrecoverable failure (hence changing to failed state).

    Covered by existing tests.

    * NetworkProcess/webrtc/NetworkRTCUDPSocketCocoa.h:
    * NetworkProcess/webrtc/NetworkRTCUDPSocketCocoa.mm:

    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@286961 268f45cc-cd09-0410-ab3c-d52691b4dbfc</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchessafari613112branchSourceWebKitChangeLog">branches/safari-613.1.12-branch/Source/WebKit/ChangeLog</a></li>
<li><a href="#branchessafari613112branchSourceWebKitNetworkProcesswebrtcNetworkRTCUDPSocketCocoah">branches/safari-613.1.12-branch/Source/WebKit/NetworkProcess/webrtc/NetworkRTCUDPSocketCocoa.h</a></li>
<li><a href="#branchessafari613112branchSourceWebKitNetworkProcesswebrtcNetworkRTCUDPSocketCocoamm">branches/safari-613.1.12-branch/Source/WebKit/NetworkProcess/webrtc/NetworkRTCUDPSocketCocoa.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchessafari613112branchSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-613.1.12-branch/Source/WebKit/ChangeLog (287095 => 287096)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-613.1.12-branch/Source/WebKit/ChangeLog  2021-12-15 20:14:08 UTC (rev 287095)
+++ branches/safari-613.1.12-branch/Source/WebKit/ChangeLog     2021-12-15 20:15:35 UTC (rev 287096)
</span><span class="lines">@@ -1,3 +1,46 @@
</span><ins>+2021-12-15  Alan Coon  <alancoon@apple.com>
+
+        Cherry-pick r286961. rdar://problem/86343642
+
+    REGRESSION (r286841): [ iOS ] Many webrtc tests flaky failing on iOS
+    https://bugs.webkit.org/show_bug.cgi?id=234181
+    <rdar://problem/86343642>
+    
+    Reviewed by Eric Carlson.
+    
+    Use network connection state change callback to know when connection fails or is cancelled.
+    Introduce ConnectionStateTracker to know when to stop reading new UDP packets.
+    ConnectionStateTracker will be stopped when state is changed to failed or cancelled as well as when the whole connection is closed.
+    Renaming m_nwConnections to m_connections as m_nwConnections name was already used.
+    Reduce error logging to only new error codes or when connectino enters unrecoverable failure (hence changing to failed state).
+    
+    Covered by existing tests.
+    
+    * NetworkProcess/webrtc/NetworkRTCUDPSocketCocoa.h:
+    * NetworkProcess/webrtc/NetworkRTCUDPSocketCocoa.mm:
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@286961 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2021-12-13  Youenn Fablet  <youenn@apple.com>
+
+            REGRESSION (r286841): [ iOS ] Many webrtc tests flaky failing on iOS
+            https://bugs.webkit.org/show_bug.cgi?id=234181
+            <rdar://problem/86343642>
+
+            Reviewed by Eric Carlson.
+
+            Use network connection state change callback to know when connection fails or is cancelled.
+            Introduce ConnectionStateTracker to know when to stop reading new UDP packets.
+            ConnectionStateTracker will be stopped when state is changed to failed or cancelled as well as when the whole connection is closed.
+            Renaming m_nwConnections to m_connections as m_nwConnections name was already used.
+            Reduce error logging to only new error codes or when connectino enters unrecoverable failure (hence changing to failed state).
+
+            Covered by existing tests.
+
+            * NetworkProcess/webrtc/NetworkRTCUDPSocketCocoa.h:
+            * NetworkProcess/webrtc/NetworkRTCUDPSocketCocoa.mm:
+
</ins><span class="cx"> 2021-12-13  Youenn Fablet  <youenn@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Fix ServiceWorker downloads
</span></span></pre></div>
<a id="branchessafari613112branchSourceWebKitNetworkProcesswebrtcNetworkRTCUDPSocketCocoah"></a>
<div class="modfile"><h4>Modified: branches/safari-613.1.12-branch/Source/WebKit/NetworkProcess/webrtc/NetworkRTCUDPSocketCocoa.h (287095 => 287096)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-613.1.12-branch/Source/WebKit/NetworkProcess/webrtc/NetworkRTCUDPSocketCocoa.h   2021-12-15 20:14:08 UTC (rev 287095)
+++ branches/safari-613.1.12-branch/Source/WebKit/NetworkProcess/webrtc/NetworkRTCUDPSocketCocoa.h      2021-12-15 20:15:35 UTC (rev 287096)
</span><span class="lines">@@ -77,7 +77,7 @@
</span><span class="cx"> 
</span><span class="cx">     NetworkRTCProvider& m_rtcProvider;
</span><span class="cx">     WebCore::LibWebRTCSocketIdentifier m_identifier;
</span><del>-    Ref<NetworkRTCUDPSocketCocoaConnections> m_nwConnections;
</del><ins>+    Ref<NetworkRTCUDPSocketCocoaConnections> m_connections;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebKit
</span></span></pre></div>
<a id="branchessafari613112branchSourceWebKitNetworkProcesswebrtcNetworkRTCUDPSocketCocoamm"></a>
<div class="modfile"><h4>Modified: branches/safari-613.1.12-branch/Source/WebKit/NetworkProcess/webrtc/NetworkRTCUDPSocketCocoa.mm (287095 => 287096)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-613.1.12-branch/Source/WebKit/NetworkProcess/webrtc/NetworkRTCUDPSocketCocoa.mm  2021-12-15 20:14:08 UTC (rev 287095)
+++ branches/safari-613.1.12-branch/Source/WebKit/NetworkProcess/webrtc/NetworkRTCUDPSocketCocoa.mm     2021-12-15 20:15:35 UTC (rev 287096)
</span><span class="lines">@@ -58,11 +58,21 @@
</span><span class="cx">     void sendTo(const uint8_t*, size_t, const rtc::SocketAddress&, const rtc::PacketOptions&);
</span><span class="cx">     void setListeningPort(int);
</span><span class="cx"> 
</span><ins>+    class ConnectionStateTracker : public ThreadSafeRefCounted<ConnectionStateTracker> {
+    public:
+        static Ref<ConnectionStateTracker> create() { return adoptRef(*new ConnectionStateTracker()); }
+        void markAsStopped() { m_isStopped = true; }
+        bool isStopped() const { return m_isStopped; }
+
+    private:
+        bool m_isStopped { false };
+    };
+
</ins><span class="cx"> private:
</span><span class="cx">     NetworkRTCUDPSocketCocoaConnections(WebCore::LibWebRTCSocketIdentifier, NetworkRTCProvider&, const rtc::SocketAddress&, Ref<IPC::Connection>&&, String&& attributedBundleIdentifier, bool isFirstParty, bool isRelayDisabled, const WebCore::RegistrableDomain&);
</span><span class="cx"> 
</span><del>-    RetainPtr<nw_connection_t> createNWConnection(const rtc::SocketAddress&);
-    void setupNWConnection(nw_connection_t, const rtc::SocketAddress&);
</del><ins>+    std::pair<RetainPtr<nw_connection_t>, Ref<ConnectionStateTracker>> createNWConnection(const rtc::SocketAddress&);
+    void setupNWConnection(nw_connection_t, ConnectionStateTracker&, const rtc::SocketAddress&);
</ins><span class="cx">     void configureParameters(nw_parameters_t, nw_ip_version_t);
</span><span class="cx"> 
</span><span class="cx">     WebCore::LibWebRTCSocketIdentifier m_identifier;
</span><span class="lines">@@ -79,7 +89,7 @@
</span><span class="cx">     RetainPtr<nw_listener_t> m_nwListener;
</span><span class="cx">     Lock m_nwConnectionsLock;
</span><span class="cx">     bool m_isClosed WTF_GUARDED_BY_LOCK(m_nwConnectionsLock) { false };
</span><del>-    HashMap<rtc::SocketAddress, RetainPtr<nw_connection_t>> m_nwConnections WTF_GUARDED_BY_LOCK(m_nwConnectionsLock);
</del><ins>+    HashMap<rtc::SocketAddress, std::pair<RetainPtr<nw_connection_t>, RefPtr<ConnectionStateTracker>>> m_nwConnections WTF_GUARDED_BY_LOCK(m_nwConnectionsLock);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> static dispatch_queue_t udpSocketQueue()
</span><span class="lines">@@ -100,7 +110,7 @@
</span><span class="cx"> NetworkRTCUDPSocketCocoa::NetworkRTCUDPSocketCocoa(WebCore::LibWebRTCSocketIdentifier identifier, NetworkRTCProvider& rtcProvider, const rtc::SocketAddress& address, Ref<IPC::Connection>&& connection, String&& attributedBundleIdentifier, bool isFirstParty, bool isRelayDisabled, const WebCore::RegistrableDomain& domain)
</span><span class="cx">     : m_rtcProvider(rtcProvider)
</span><span class="cx">     , m_identifier(identifier)
</span><del>-    , m_nwConnections(NetworkRTCUDPSocketCocoaConnections::create(identifier, rtcProvider, address, WTFMove(connection), WTFMove(attributedBundleIdentifier), isFirstParty, isRelayDisabled, domain))
</del><ins>+    , m_connections(NetworkRTCUDPSocketCocoaConnections::create(identifier, rtcProvider, address, WTFMove(connection), WTFMove(attributedBundleIdentifier), isFirstParty, isRelayDisabled, domain))
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -110,23 +120,23 @@
</span><span class="cx"> 
</span><span class="cx"> void NetworkRTCUDPSocketCocoa::close()
</span><span class="cx"> {
</span><del>-    m_nwConnections->close();
</del><ins>+    m_connections->close();
</ins><span class="cx">     m_rtcProvider.takeSocket(m_identifier);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void NetworkRTCUDPSocketCocoa::setListeningPort(int port)
</span><span class="cx"> {
</span><del>-    m_nwConnections->setListeningPort(port);
</del><ins>+    m_connections->setListeningPort(port);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void NetworkRTCUDPSocketCocoa::setOption(int option, int value)
</span><span class="cx"> {
</span><del>-    m_nwConnections->setOption(option, value);
</del><ins>+    m_connections->setOption(option, value);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void NetworkRTCUDPSocketCocoa::sendTo(const uint8_t* data, size_t size, const rtc::SocketAddress& address, const rtc::PacketOptions& options)
</span><span class="cx"> {
</span><del>-    m_nwConnections->sendTo(data, size, address, options);
</del><ins>+    m_connections->sendTo(data, size, address, options);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static rtc::SocketAddress socketAddressFromIncomingConnection(nw_connection_t connection)
</span><span class="lines">@@ -225,16 +235,18 @@
</span><span class="cx">         }
</span><span class="cx">     }).get());
</span><span class="cx"> 
</span><del>-    nw_listener_set_new_connection_handler(m_nwListener.get(), makeBlockPtr([protectedThis = Ref { *this }](nw_connection_t connection) {
</del><ins>+    nw_listener_set_new_connection_handler(m_nwListener.get(), makeBlockPtr([protectedThis = Ref { *this }](nw_connection_t nwConnection) {
</ins><span class="cx">         Locker locker { protectedThis->m_nwConnectionsLock };
</span><span class="cx">         if (protectedThis->m_isClosed)
</span><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        auto remoteAddress = socketAddressFromIncomingConnection(connection);
</del><ins>+        auto remoteAddress = socketAddressFromIncomingConnection(nwConnection);
</ins><span class="cx">         ASSERT(remoteAddress != HashTraits<rtc::SocketAddress>::emptyValue() && !HashTraits<rtc::SocketAddress>::isDeletedValue(remoteAddress));
</span><span class="cx"> 
</span><del>-        protectedThis->m_nwConnections.set(remoteAddress, connection);
-        protectedThis->setupNWConnection(connection, remoteAddress);
</del><ins>+        auto connectionStateTracker = ConnectionStateTracker::create();
+        protectedThis->setupNWConnection(nwConnection, connectionStateTracker.get(), remoteAddress);
+
+        protectedThis->m_nwConnections.set(remoteAddress, std::make_pair(nwConnection, WTFMove(connectionStateTracker)));
</ins><span class="cx">     }).get());
</span><span class="cx"> 
</span><span class="cx">     nw_listener_start(m_nwListener.get());
</span><span class="lines">@@ -263,12 +275,14 @@
</span><span class="cx">     Locker locker { m_nwConnectionsLock };
</span><span class="cx">     m_isClosed = true;
</span><span class="cx"> 
</span><ins>+    for (auto& nwConnection : m_nwConnections.values()) {
+        nwConnection.second->markAsStopped();
+        nw_connection_cancel(nwConnection.first.get());
+    }
+    m_nwConnections.clear();
+
</ins><span class="cx">     nw_listener_cancel(m_nwListener.get());
</span><span class="cx">     m_nwListener = nullptr;
</span><del>-
-    for (auto& nwConnection : m_nwConnections.values())
-        nw_connection_cancel(nwConnection.get());
-    m_nwConnections.clear();
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void NetworkRTCUDPSocketCocoaConnections::setOption(int, int)
</span><span class="lines">@@ -276,10 +290,10 @@
</span><span class="cx">     // FIXME: Validate this is not needed.
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static inline void processUDPData(RetainPtr<nw_connection_t>&& nwConnection, Function<void(const uint8_t*, size_t)>&& processData)
</del><ins>+static inline void processUDPData(RetainPtr<nw_connection_t>&& nwConnection, Ref<NetworkRTCUDPSocketCocoaConnections::ConnectionStateTracker> connectionStateTracker, int errorCode, Function<void(const uint8_t*, size_t)>&& processData)
</ins><span class="cx"> {
</span><span class="cx">     auto nwConnectionReference = nwConnection.get();
</span><del>-    nw_connection_receive(nwConnectionReference, 1, std::numeric_limits<uint32_t>::max(), makeBlockPtr([nwConnection = WTFMove(nwConnection), processData = WTFMove(processData)](dispatch_data_t content, nw_content_context_t context, bool isComplete, nw_error_t error) mutable {
</del><ins>+    nw_connection_receive(nwConnectionReference, 1, std::numeric_limits<uint32_t>::max(), makeBlockPtr([nwConnection = WTFMove(nwConnection), processData = WTFMove(processData), errorCode, connectionStateTracker = WTFMove(connectionStateTracker)](dispatch_data_t content, nw_content_context_t, bool, nw_error_t error) mutable {
</ins><span class="cx">         if (content) {
</span><span class="cx">             dispatch_data_apply(content, makeBlockPtr([&](dispatch_data_t, size_t, const void* data, size_t size) {
</span><span class="cx">                 processData(static_cast<const uint8_t*>(data), size);
</span><span class="lines">@@ -286,15 +300,18 @@
</span><span class="cx">                 return true;
</span><span class="cx">             }).get());
</span><span class="cx">         }
</span><del>-        if (isComplete && context && nw_content_context_get_is_final(context))
</del><ins>+        if (connectionStateTracker->isStopped())
</ins><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        RELEASE_LOG_ERROR_IF(!!error, WebRTC, "NetworkRTCUDPSocketCocoaConnections failed processing UDP data with error %d", nw_error_get_error_code(error));
-        processUDPData(WTFMove(nwConnection), WTFMove(processData));
</del><ins>+        if (error && errorCode != nw_error_get_error_code(error)) {
+            errorCode = nw_error_get_error_code(error);
+            RELEASE_LOG_ERROR(WebRTC, "NetworkRTCUDPSocketCocoaConnections failed processing UDP data with error %d", errorCode);
+        }
+        processUDPData(WTFMove(nwConnection), WTFMove(connectionStateTracker), errorCode, WTFMove(processData));
</ins><span class="cx">     }).get());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RetainPtr<nw_connection_t> NetworkRTCUDPSocketCocoaConnections::createNWConnection(const rtc::SocketAddress& remoteAddress)
</del><ins>+std::pair<RetainPtr<nw_connection_t>, Ref<NetworkRTCUDPSocketCocoaConnections::ConnectionStateTracker>> NetworkRTCUDPSocketCocoaConnections::createNWConnection(const rtc::SocketAddress& remoteAddress)
</ins><span class="cx"> {
</span><span class="cx">     auto parameters = adoptNS(nw_parameters_create_secure_udp(NW_PARAMETERS_DISABLE_PROTOCOL, NW_PARAMETERS_DEFAULT_CONFIGURATION));
</span><span class="cx">     {
</span><span class="lines">@@ -321,15 +338,23 @@
</span><span class="cx">     auto host = adoptNS(nw_endpoint_create_host(remoteHostAddress.c_str(), String::number(remoteAddress.port()).utf8().data()));
</span><span class="cx">     auto nwConnection = adoptNS(nw_connection_create(host.get(), parameters.get()));
</span><span class="cx"> 
</span><del>-    setupNWConnection(nwConnection.get(), remoteAddress);
-    return nwConnection;
</del><ins>+    auto connectionStateTracker = ConnectionStateTracker::create();
+
+    setupNWConnection(nwConnection.get(), connectionStateTracker.get(), remoteAddress);
+    return std::make_pair(WTFMove(nwConnection), WTFMove(connectionStateTracker));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void NetworkRTCUDPSocketCocoaConnections::setupNWConnection(nw_connection_t nwConnection, const rtc::SocketAddress& remoteAddress)
</del><ins>+void NetworkRTCUDPSocketCocoaConnections::setupNWConnection(nw_connection_t nwConnection, ConnectionStateTracker& connectionStateTracker, const rtc::SocketAddress& remoteAddress)
</ins><span class="cx"> {
</span><span class="cx">     nw_connection_set_queue(nwConnection, udpSocketQueue());
</span><span class="cx"> 
</span><del>-    processUDPData(nwConnection, [identifier = m_identifier, connection = m_connection.copyRef(), ip = remoteAddress.ipaddr(), port = remoteAddress.port()](auto* message, auto size) mutable {
</del><ins>+    nw_connection_set_state_changed_handler(nwConnection, makeBlockPtr([connectionStateTracker = Ref  { connectionStateTracker }](nw_connection_state_t state, _Nullable nw_error_t error) {
+        RELEASE_LOG_ERROR_IF(state == nw_connection_state_failed, WebRTC, "NetworkRTCUDPSocketCocoaConnections connection failed with error %d", error ? nw_error_get_error_code(error) : 0);
+        if (state == nw_connection_state_failed || state == nw_connection_state_cancelled)
+            connectionStateTracker->markAsStopped();
+    }).get());
+
+    processUDPData(nwConnection, Ref  { connectionStateTracker }, 0, [identifier = m_identifier, connection = m_connection.copyRef(), ip = remoteAddress.ipaddr(), port = remoteAddress.port()](auto* message, auto size) mutable {
</ins><span class="cx">         IPC::DataReference data(message, size);
</span><span class="cx">         connection->send(Messages::LibWebRTCNetwork::SignalReadPacket { identifier, data, RTCNetwork::IPAddress(ip), port, rtc::TimeMillis() * 1000 }, 0);
</span><span class="cx">     });
</span><span class="lines">@@ -349,7 +374,7 @@
</span><span class="cx">         Locker locker { m_nwConnectionsLock };
</span><span class="cx">         nwConnection = m_nwConnections.ensure(remoteAddress, [this, &remoteAddress] {
</span><span class="cx">             return createNWConnection(remoteAddress);
</span><del>-        }).iterator->value.get();
</del><ins>+        }).iterator->value.first.get();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     auto value = adoptNS(dispatch_data_create(data, size, nullptr, DISPATCH_DATA_DESTRUCTOR_DEFAULT));
</span></span></pre>
</div>
</div>

</body>
</html>