Loading debian/changelog +10 −0 Original line number Diff line number Diff line libnetplus (20260505+15) unstable; urgency=high * Windows: fix recvBatchAddr blocking indefinitely — use select() poll with zero timeout before each recvfrom to avoid blocking on sockets where MSG_DONTWAIT is not available * Windows: fix completeHandshake blocking on first recvData call — reorder to waitRead() before recv to ensure data is available -- Jan Koester <jan.koester@tuxist.de> Mon, 05 May 2026 18:45:00 +0200 libnetplus (20260505+14) unstable; urgency=high * Revert -fvisibility=hidden — breaks RTTI symbol export Loading src/quic.cpp +11 −13 Original line number Diff line number Diff line Loading @@ -2589,6 +2589,17 @@ void quic::completeHandshake() { throw e; } if (std::chrono::steady_clock::now() - start > timeout) { NetException e; e[NetException::Error] << "quic::completeHandshake: handshake timed out"; throw e; } // Wait for data availability before attempting recv (avoids blocking // on Windows where MSG_DONTWAIT is not supported) socketwait sw; if (!sw.waitRead(*this, 5)) continue; // no data within 5ms, retry try { buffer recv_buf_wrapper(65535); recv_attempts++; Loading @@ -2603,19 +2614,6 @@ void quic::completeHandshake() { throw; } } if (_handshake_complete) { break; } if (std::chrono::steady_clock::now() - start > timeout) { NetException e; e[NetException::Error] << "quic::completeHandshake: handshake timed out"; throw e; } socketwait sw; sw.waitRead(*this, 5); // wait up to 5ms for incoming handshake data } _conn_state.store(ConnectionState::Connected); Loading src/windows/udp.cpp +8 −8 Original line number Diff line number Diff line Loading @@ -435,11 +435,15 @@ size_t udp::recvBatchAddr(std::vector<std::vector<uint8_t>>& out, out.clear(); addrs.clear(); // Temporarily set socket to non-blocking for batch receive u_long nb = 1; ::ioctlsocket(_Socket, FIONBIO, &nb); for (int i = 0; i < max_count; ++i) { // Non-blocking poll: check if data is available before recvfrom fd_set fds; FD_ZERO(&fds); FD_SET(_Socket, &fds); struct timeval tv = {0, 0}; // zero timeout = immediate poll int ready = ::select(0, &fds, nullptr, nullptr, &tv); if (ready <= 0) break; // no more data available std::vector<uint8_t> buf(65535); sockaddr_storage peer{}; socklen_t peer_len = sizeof(peer); Loading @@ -453,10 +457,6 @@ size_t udp::recvBatchAddr(std::vector<std::vector<uint8_t>>& out, } else break; } // Restore blocking mode nb = 0; ::ioctlsocket(_Socket, FIONBIO, &nb); return out.size(); } Loading Loading
debian/changelog +10 −0 Original line number Diff line number Diff line libnetplus (20260505+15) unstable; urgency=high * Windows: fix recvBatchAddr blocking indefinitely — use select() poll with zero timeout before each recvfrom to avoid blocking on sockets where MSG_DONTWAIT is not available * Windows: fix completeHandshake blocking on first recvData call — reorder to waitRead() before recv to ensure data is available -- Jan Koester <jan.koester@tuxist.de> Mon, 05 May 2026 18:45:00 +0200 libnetplus (20260505+14) unstable; urgency=high * Revert -fvisibility=hidden — breaks RTTI symbol export Loading
src/quic.cpp +11 −13 Original line number Diff line number Diff line Loading @@ -2589,6 +2589,17 @@ void quic::completeHandshake() { throw e; } if (std::chrono::steady_clock::now() - start > timeout) { NetException e; e[NetException::Error] << "quic::completeHandshake: handshake timed out"; throw e; } // Wait for data availability before attempting recv (avoids blocking // on Windows where MSG_DONTWAIT is not supported) socketwait sw; if (!sw.waitRead(*this, 5)) continue; // no data within 5ms, retry try { buffer recv_buf_wrapper(65535); recv_attempts++; Loading @@ -2603,19 +2614,6 @@ void quic::completeHandshake() { throw; } } if (_handshake_complete) { break; } if (std::chrono::steady_clock::now() - start > timeout) { NetException e; e[NetException::Error] << "quic::completeHandshake: handshake timed out"; throw e; } socketwait sw; sw.waitRead(*this, 5); // wait up to 5ms for incoming handshake data } _conn_state.store(ConnectionState::Connected); Loading
src/windows/udp.cpp +8 −8 Original line number Diff line number Diff line Loading @@ -435,11 +435,15 @@ size_t udp::recvBatchAddr(std::vector<std::vector<uint8_t>>& out, out.clear(); addrs.clear(); // Temporarily set socket to non-blocking for batch receive u_long nb = 1; ::ioctlsocket(_Socket, FIONBIO, &nb); for (int i = 0; i < max_count; ++i) { // Non-blocking poll: check if data is available before recvfrom fd_set fds; FD_ZERO(&fds); FD_SET(_Socket, &fds); struct timeval tv = {0, 0}; // zero timeout = immediate poll int ready = ::select(0, &fds, nullptr, nullptr, &tv); if (ready <= 0) break; // no more data available std::vector<uint8_t> buf(65535); sockaddr_storage peer{}; socklen_t peer_len = sizeof(peer); Loading @@ -453,10 +457,6 @@ size_t udp::recvBatchAddr(std::vector<std::vector<uint8_t>>& out, } else break; } // Restore blocking mode nb = 0; ::ioctlsocket(_Socket, FIONBIO, &nb); return out.size(); } Loading