tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit cd54cbb82ab834524334813fdc275aae46142d11
parent 99392821594702a12cb6381b5dbb438de49593f1
Author: Dan Baker <dbaker@mozilla.com>
Date:   Mon,  1 Dec 2025 18:52:03 -0700

Bug 2000941 - Vendor libwebrtc from fd381db407

Upstream commit: https://webrtc.googlesource.com/src/+/fd381db407aeb2a72e00083fabddcdb02389ea97
    Clarify Socket ownership in TurnServer using type system

    Change socket maps that owns keys to use unique_ptr for keys.
    This automates deallocation of the sockets and requires to be more careful when accessing the map.

    Bug: None
    Change-Id: I9f7f810a5b9bcaf3974a80f01b140cd029878a2b
    Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/408821
    Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
    Reviewed-by: Harald Alvestrand <hta@webrtc.org>
    Cr-Commit-Position: refs/heads/main@{#45612}

Diffstat:
Mthird_party/libwebrtc/README.mozilla.last-vendor | 4++--
Mthird_party/libwebrtc/p2p/test/turn_server.cc | 70++++++++++++++++++++++++++++++++++------------------------------------
Mthird_party/libwebrtc/p2p/test/turn_server.h | 17+++++++----------
3 files changed, 43 insertions(+), 48 deletions(-)

diff --git a/third_party/libwebrtc/README.mozilla.last-vendor b/third_party/libwebrtc/README.mozilla.last-vendor @@ -1,4 +1,4 @@ # ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc -libwebrtc updated from /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-12-02T01:48:55.251832+00:00. +libwebrtc updated from /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-12-02T01:51:44.556439+00:00. # base of lastest vendoring -ef084b6cc6 +fd381db407 diff --git a/third_party/libwebrtc/p2p/test/turn_server.cc b/third_party/libwebrtc/p2p/test/turn_server.cc @@ -68,6 +68,17 @@ bool IsTurnChannelData(uint16_t msg_type) { return ((msg_type & 0xC000) == 0x4000); } +// Helper to search a map keyed by unique_ptr using raw pointer. +template <typename Map, typename Key> +Map::iterator FindByRawPtr(Map& map, Key* ptr) { + // Wrap raw pointer to unique_ptr to be able to compare it with map keys. + std::unique_ptr<Key> uptr = absl::WrapUnique(ptr); + typename Map::iterator iter = map.find(uptr); + // Do not forget to release ownership as `ptr` is passed without ownership. + uptr.release(); + return iter; +} + } // namespace int GetStunSuccessResponseTypeOrZero(const StunMessage& req) { @@ -97,19 +108,12 @@ TurnServer::TurnServer(const Environment& env, TaskQueueBase* thread) TurnServer::~TurnServer() { RTC_DCHECK_RUN_ON(thread_); - for (auto& [socket, unused] : server_sockets_) { - delete socket; - } - - for (auto& [socket, unused] : server_listen_sockets_) { - delete socket; - } } void TurnServer::AddInternalSocket(std::unique_ptr<AsyncPacketSocket> socket, ProtocolType protocol) { RTC_DCHECK_RUN_ON(thread_); - auto [it, inserted] = server_sockets_.emplace(socket.release(), protocol); + auto [it, inserted] = server_sockets_.emplace(std::move(socket), protocol); RTC_DCHECK(inserted); it->first->RegisterReceivedPacketCallback( [&](AsyncPacketSocket* socket, const ReceivedIpPacket& packet) { @@ -124,7 +128,7 @@ void TurnServer::AddInternalServerSocket( std::unique_ptr<SSLAdapterFactory> ssl_adapter_factory) { RTC_DCHECK_RUN_ON(thread_); auto [iter, inserted] = server_listen_sockets_.emplace( - socket.release(), + std::move(socket), ServerSocketInfo{.proto = protocol, .ssl_adapter_factory = std::move(ssl_adapter_factory)}); RTC_DCHECK(inserted); @@ -141,20 +145,15 @@ void TurnServer::SetExternalSocketFactory(PacketSocketFactory* factory, void TurnServer::OnNewInternalConnection(Socket* socket) { RTC_DCHECK_RUN_ON(thread_); - RTC_DCHECK(server_listen_sockets_.find(socket) != - server_listen_sockets_.end()); - AcceptConnection(socket); -} - -void TurnServer::AcceptConnection(Socket* server_socket) { - RTC_DCHECK_RUN_ON(thread_); + auto iter = FindByRawPtr(server_listen_sockets_, socket); + RTC_DCHECK(iter != server_listen_sockets_.end()); // Check if someone is trying to connect to us. SocketAddress accept_addr; std::unique_ptr<Socket> accepted_socket = - absl::WrapUnique(server_socket->Accept(&accept_addr)); + absl::WrapUnique(socket->Accept(&accept_addr)); if (accepted_socket != nullptr) { - const ServerSocketInfo& info = server_listen_sockets_[server_socket]; + const ServerSocketInfo& info = iter->second; if (info.ssl_adapter_factory) { std::unique_ptr<SSLAdapter> ssl_adapter = absl::WrapUnique( info.ssl_adapter_factory->CreateAdapter(accepted_socket.release())); @@ -175,7 +174,10 @@ void TurnServer::AcceptConnection(Socket* server_socket) { void TurnServer::OnInternalSocketClose(AsyncPacketSocket* socket, int err) { RTC_DCHECK_RUN_ON(thread_); - DestroyInternalSocket(socket); + if (auto iter = FindByRawPtr(server_sockets_, socket); + iter != server_sockets_.end()) { + DestroyInternalSocket(iter); + } } void TurnServer::OnInternalPacket(AsyncPacketSocket* socket, @@ -185,7 +187,7 @@ void TurnServer::OnInternalPacket(AsyncPacketSocket* socket, if (packet.payload().size() < TURN_CHANNEL_HEADER_SIZE) { return; } - auto iter = server_sockets_.find(socket); + auto iter = FindByRawPtr(server_sockets_, socket); RTC_DCHECK(iter != server_sockets_.end()); TurnServerConnection conn(packet.source_address(), iter->second, socket); uint16_t msg_type = GetBE16(packet.payload().data()); @@ -508,32 +510,28 @@ void TurnServer::Send(TurnServerConnection* conn, const ByteBufferWriter& buf) { void TurnServer::DestroyAllocation(TurnServerAllocation* allocation) { // Removing the internal socket if the connection is not udp. AsyncPacketSocket* socket = allocation->conn()->socket(); - auto iter = server_sockets_.find(socket); + auto iter = FindByRawPtr(server_sockets_, socket); // Skip if the socket serving this allocation is UDP, as this will be shared // by all allocations. // Note: We may not find a socket if it's a TCP socket that was closed, and // the allocation is only now timing out. if (iter != server_sockets_.end() && iter->second != PROTO_UDP) { - DestroyInternalSocket(socket); + DestroyInternalSocket(iter); } allocations_.erase(*(allocation->conn())); } -void TurnServer::DestroyInternalSocket(AsyncPacketSocket* socket) { - auto iter = server_sockets_.find(socket); - if (iter != server_sockets_.end()) { - AsyncPacketSocket* server_socket = iter->first; - server_socket->UnsubscribeCloseEvent(this); - server_socket->DeregisterReceivedPacketCallback(); - server_sockets_.erase(iter); - std::unique_ptr<AsyncPacketSocket> socket_to_delete = - absl::WrapUnique(server_socket); - // We must destroy the socket async to avoid invalidating the sigslot - // callback list iterator inside a sigslot callback. (In other words, - // deleting an object from within a callback from that object). - thread_->PostTask([socket_to_delete = std::move(socket_to_delete)] {}); - } +void TurnServer::DestroyInternalSocket(ServerSocketMap::iterator iter) { + RTC_DCHECK(iter != server_sockets_.end()); + auto node = server_sockets_.extract(iter); + AsyncPacketSocket* server_socket = node.key().get(); + server_socket->UnsubscribeCloseEvent(this); + server_socket->DeregisterReceivedPacketCallback(); + // We must destroy the socket async to avoid invalidating the callback list + // iterator. (In other words, deleting an object from within a callback from + // that object). + thread_->PostTask([node = std::move(node)] {}); } TurnServerConnection::TurnServerConnection(const SocketAddress& src, diff --git a/third_party/libwebrtc/p2p/test/turn_server.h b/third_party/libwebrtc/p2p/test/turn_server.h @@ -270,6 +270,9 @@ class TurnServer : public sigslot::has_slots<> { } private: + using ServerSocketMap = + std::map<std::unique_ptr<AsyncPacketSocket>, ProtocolType>; + // All private member functions and variables should have access restricted to // thread_. But compile-time annotations are missing for members access from // TurnServerAllocation (via friend declaration). @@ -279,9 +282,6 @@ class TurnServer : public sigslot::has_slots<> { const ReceivedIpPacket& packet) RTC_RUN_ON(thread_); void OnNewInternalConnection(Socket* socket); - - // Accept connections on this server socket. - void AcceptConnection(Socket* server_socket) RTC_RUN_ON(thread_); void OnInternalSocketClose(AsyncPacketSocket* socket, int err); void HandleStunMessage(TurnServerConnection* conn, @@ -325,7 +325,8 @@ class TurnServer : public sigslot::has_slots<> { void Send(TurnServerConnection* conn, const ByteBufferWriter& buf); void DestroyAllocation(TurnServerAllocation* allocation) RTC_RUN_ON(thread_); - void DestroyInternalSocket(AsyncPacketSocket* socket) RTC_RUN_ON(thread_); + void DestroyInternalSocket(ServerSocketMap::iterator iter) + RTC_RUN_ON(thread_); struct ServerSocketInfo { ProtocolType proto; @@ -348,12 +349,8 @@ class TurnServer : public sigslot::has_slots<> { // Check for permission when receiving an external packet. bool enable_permission_checks_ = true; - // `server_sockets_` and `server_listen_sockets_` use raw pointers as keys, - // but de-facto they should be unique_ptr. It is responsibility of the - // TurnServer to de-allocate keys when map entries are erased. - std::map<AsyncPacketSocket*, ProtocolType> server_sockets_ - RTC_GUARDED_BY(thread_); - std::map<Socket*, ServerSocketInfo> server_listen_sockets_ + ServerSocketMap server_sockets_ RTC_GUARDED_BY(thread_); + std::map<std::unique_ptr<Socket>, ServerSocketInfo> server_listen_sockets_ RTC_GUARDED_BY(thread_); std::unique_ptr<PacketSocketFactory> external_socket_factory_ RTC_GUARDED_BY(thread_);