From 2311ed2bdf22be10b07d56223ba4c4f4734f44da Mon Sep 17 00:00:00 2001 From: Collecting Date: Sun, 11 Jan 2026 08:11:38 +0000 Subject: [PATCH 1/2] fix(sockets): SIGSEGV & Socket Handling Signed-off-by: Collecting --- src/core/hle/service/sockets/bsd.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp index 6eda3e010..971b7b0a5 100644 --- a/src/core/hle/service/sockets/bsd.cpp +++ b/src/core/hle/service/sockets/bsd.cpp @@ -562,6 +562,10 @@ std::pair BSD::SocketImpl(Domain domain, Type type, Protocol protoco if (it != socket_pool.end() && !it->second.empty()) { descriptor.socket = it->second.back(); it->second.pop_back(); + + // call Initialize here so socket_proxy.cpp functions work + descriptor.socket->Initialize(descriptor.domain, descriptor.type, descriptor.protocol); + LOG_DEBUG(Service, "Reused socket from pool for fd={}", fd); } else { descriptor.socket = std::make_shared(room_network); @@ -1089,12 +1093,19 @@ void BSD::BuildErrnoResponse(HLERequestContext& ctx, Errno bsd_errno) const noex } void BSD::OnProxyPacketReceived(const Network::ProxyPacket& packet) { - for (auto& optional_descriptor : file_descriptors) { - if (!optional_descriptor.has_value()) { - continue; + // We must ensure we only deliver the packet ONCE + std::vector processed_sockets; + + for (auto& optional_desc : file_descriptors) { + if (optional_desc.has_value() && optional_desc->socket) { + Network::SocketBase* socket_ptr = optional_desc->socket.get(); + + // If we haven't given this specific socket the packet yet... + if (std::find(processed_sockets.begin(), processed_sockets.end(), socket_ptr) == processed_sockets.end()) { + socket_ptr->HandleProxyPacket(packet); + processed_sockets.push_back(socket_ptr); + } } - FileDescriptor& descriptor = *optional_descriptor; - descriptor.socket.get()->HandleProxyPacket(packet); } } From 0bec953153c73f195e9c04c8978a06c448a05f85 Mon Sep 17 00:00:00 2001 From: Collecting Date: Sun, 11 Jan 2026 08:12:40 +0000 Subject: [PATCH 2/2] fix(sockets): Clear Socket Data Properly for Initialization Signed-off-by: Collecting --- src/core/internal_network/socket_proxy.cpp | 56 +++++++++++++++------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/src/core/internal_network/socket_proxy.cpp b/src/core/internal_network/socket_proxy.cpp index 4d2f4bb8f..6f8288c9b 100644 --- a/src/core/internal_network/socket_proxy.cpp +++ b/src/core/internal_network/socket_proxy.cpp @@ -29,28 +29,39 @@ ProxySocket::~ProxySocket() { } void ProxySocket::HandleProxyPacket(const ProxyPacket& packet) { - if (protocol != packet.protocol || local_endpoint.portno != packet.remote_endpoint.portno || - closed) { - stats.packets_dropped++; - LOG_DEBUG(Network, "Dropped packet: protocol mismatch or closed socket. Stats: sent={}, recv={}, dropped={}", - stats.packets_sent, stats.packets_received, stats.packets_dropped); + auto room_member = room_network.GetRoomMember().lock(); + if (!room_member) return; + + const auto my_ip = room_member->GetFakeIpAddress(); + + // If the sender (local_endpoint) is OUR IP, ignore it. + // We don't want to process our own sent packets. + if (packet.local_endpoint.ip == my_ip) { return; } + // Only accept packets meant for us or actual broadcasts. + if (packet.remote_endpoint.ip != my_ip && !packet.broadcast) { + return; + } + + // PROTOCOL & PORT CHECK + if (protocol != packet.protocol || local_endpoint.portno != packet.remote_endpoint.portno || closed) { + stats.packets_dropped++; + return; + } + + // BROADCAST CHECK if (!broadcast && packet.broadcast) { stats.packets_dropped++; - LOG_DEBUG(Network, "Dropped broadcast packet on non-broadcast socket"); return; } + // DECOMPRESSION & QUEUEING auto decompressed = packet; decompressed.data = Common::Compression::DecompressDataZSTD(packet.data); - - // Check if decompression failed (returns empty vector on error) if (decompressed.data.empty() && !packet.data.empty()) { stats.packets_dropped++; - LOG_WARNING(Network, "Dropped packet: ZSTD decompression failed. Stats: sent={}, recv={}, dropped={}", - stats.packets_sent, stats.packets_received, stats.packets_dropped); return; } @@ -58,13 +69,6 @@ void ProxySocket::HandleProxyPacket(const ProxyPacket& packet) { received_packets.push(decompressed); stats.packets_received++; stats.bytes_received += decompressed.data.size(); - - // Log statistics periodically (every 100 packets) - if (stats.packets_received % 100 == 0) { - LOG_DEBUG(Network, "ProxySocket stats: sent={} ({} bytes), recv={} ({} bytes), dropped={}", - stats.packets_sent, stats.bytes_sent, - stats.packets_received, stats.bytes_received, stats.packets_dropped); - } } template @@ -77,6 +81,24 @@ Errno ProxySocket::Initialize(Domain domain, Type type, Protocol socket_protocol protocol = socket_protocol; SetSockOpt(fd, SO_TYPE, type); + // Reset all state flags + is_bound = false; + closed = false; + broadcast = false; + + // Wipe the endpoint. + // This forces the RoomMember to assign a new/fresh identity if possible + local_endpoint = {}; + + // Reset stats so the new session starts at 0 bytes + stats = {}; + + // Clear the queue. + std::lock_guard guard(packets_mutex); + while(!received_packets.empty()) { + received_packets.pop(); + } + return Errno::SUCCESS; }