Loading .vscode/tasks.json +389 −62 Original line number Diff line number Diff line Loading @@ -58,6 +58,333 @@ "group": "build", "problemMatcher": [], "detail": "CMake template clean rebuild task" }, { "label": "CMake: build", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$msCompile" ], "group": "build" }, { "label": "CMake: build", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" } ], "version": "2.0.0" Loading src/event/epoll.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -50,6 +50,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace netplus { std::atomic<bool> event::Running(true); std::atomic<bool> event::Restart(false); static std::vector<socket*> SSOCKETS; static std::map<int, std::shared_ptr<con>> CONNECTIONS; Loading src/event/iocp.cpp +24 −82 Original line number Diff line number Diff line Loading @@ -518,39 +518,10 @@ namespace netplus { continue; } // If there's pending data to send (handshake response) // CRITICAL: flush_out() posts WSASend ASYNCHRONOUSLY in IOCP mode if (owner->csock->hasPendingWrite()) { std::cerr << "[IOCP] Flushing handshake response, posting async WSASend..." << std::endl; try { owner->csock->flush_out(); } catch (NetException& flushEx) { if (flushEx.getErrorType() == NetException::Note) { std::cerr << "[IOCP] flush_out Note - buffer full, will retry" << std::endl; } else { std::cerr << "[IOCP] flush_out error: " << flushEx.what() << std::endl; throw; } } std::cerr << "[IOCP] flush_out posted - now continuing in READ handler" << std::endl; // After posting async write, DON'T try to recv more data yet. // The write completion handler will decide what's next. // Just post recv and let IOCP sequence things properly. if (!owner->csock->getHandshakeDone()) { std::cerr << "[IOCP] Still in handshake, posting recv for next message" << std::endl; try { post_recv(st, *owner); } catch (...) {} } else { std::cerr << "[IOCP] Handshake complete, posting recv for application data" << std::endl; try { post_recv(st, *owner); } catch (...) {} } continue; } // CRITICAL: handshake_after_accept() has ALREADY called flush_out() internally! // Do NOT call flush_out again - the WRITE completion handler will manage async writes. // Just check if handshake is done, otherwise repost recv for more data. // If handshake still not done, wait for more data if (!owner->csock->getHandshakeDone()) { std::cerr << "[IOCP] Handshake not done yet, reposting recv" << std::endl; try { Loading Loading @@ -608,7 +579,7 @@ namespace netplus { // CRITICAL: Clear the pending IOCP write flag owner->csock->setPendingWrite(false); std::cerr << "[IOCP] Write completed, cleared _pendingIocpWrite" << std::endl; std::cerr << "[IOCP] Write completed, cleared _pendingIocpWrite, isSSL=" << isSSL << std::endl; if (isSSL) { // SSL: all data was encrypted and sent Loading @@ -625,66 +596,37 @@ namespace netplus { } } // If handshake not done, continue handshake after send completes // If handshake not done, need to continue it if (!owner->csock->getHandshakeDone()) { std::cerr << "[IOCP] Write completed during handshake, continuing handshake..." << std::endl; std::cerr << "[IOCP] Write completed during handshake, checking for more queued data..." << std::endl; try { owner->csock->handshake_after_accept(); std::cerr << "[IOCP] handshake_after_accept returned, handshakeDone=" << owner->csock->getHandshakeDone() << std::endl; // If there's more data to send, flush it // Check if there's more queued handshake data to send if (owner->csock->hasPendingWrite()) { std::cerr << "[IOCP] More data to send, flushing..." << std::endl; std::cerr << "[IOCP] More handshake data queued, flushing..." << std::endl; try { owner->csock->flush_out(); } catch (NetException& flushEx) { if (flushEx.getErrorType() != NetException::Note) { std::cerr << "[IOCP] flush_out error: " << flushEx.what() << std::endl; throw; } std::cerr << "[IOCP] flush_out returned Note during handshake continuation" << std::endl; } std::cerr << "[IOCP] flush_out returned Note" << std::endl; } } catch (NetException& e) { if (e.getErrorType() == NetException::Note) { std::cerr << "[IOCP] Handshake needs more data, posting recv" << std::endl; // Need more data - but first check if we have data to send if (owner->csock->hasPendingWrite()) { try { owner->csock->flush_out(); } catch (...) {} } // Post recv for more handshake data try { post_recv(st, *owner); } catch (...) {} continue; } // Real error std::cerr << "[IOCP] Handshake error after write: " << e.what() << std::endl; ev->DisconnectEvent(*owner, tid, 0); remove_con(st, cs); try { owner->csock->close(); } catch (...) {} // Continue with next WRITE completion owner->WritePending.store(false); continue; } // Handshake complete or needs more data if (!owner->csock->getHandshakeDone()) { // Post recv for more handshake data try { post_recv(st, *owner); } catch (...) {} } else { std::cerr << "[IOCP] Handshake complete after write!" << std::endl; // Post recv for application data // No more queued data. Post recv to wait for client's next message. // Do NOT call handshake_after_accept() - it will be called from READ handler // when client data arrives. std::cerr << "[IOCP] No more queued data, posting recv for client message" << std::endl; try { post_recv(st, *owner); } catch (...) {} } owner->WritePending.store(false); continue; } } owner->WritePending.store(false); Loading src/ssl.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -2654,11 +2654,13 @@ void netplus::ssl::queueRaw(const std::vector<uint8_t>& v) { void netplus::ssl::queueRaw(std::vector<uint8_t>&& v) { if (v.empty()) return; std::cerr << "[SSL] queueRaw: queued " << v.size() << " bytes, queue size now=" << (_send_queue.size() + 1) << std::endl; _send_queue.emplace_back(std::move(v)); } void netplus::ssl::queueRaw(const uint8_t* p, size_t n) { if (!p || n == 0) return; std::cerr << "[SSL] queueRaw: queued " << n << " bytes, queue size now=" << (_send_queue.size() + 1) << std::endl; _send_queue.emplace_back(p, p + n); } Loading Loading
.vscode/tasks.json +389 −62 Original line number Diff line number Diff line Loading @@ -58,6 +58,333 @@ "group": "build", "problemMatcher": [], "detail": "CMake template clean rebuild task" }, { "label": "CMake: build", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$msCompile" ], "group": "build" }, { "label": "CMake: build", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" }, { "label": "Build libnetplus (Release)", "type": "shell", "command": "cmake", "args": [ "--build", "build", "--config", "Release" ], "problemMatcher": [ "$gcc", "$msCompile" ], "group": "build" } ], "version": "2.0.0" Loading
src/event/epoll.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -50,6 +50,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace netplus { std::atomic<bool> event::Running(true); std::atomic<bool> event::Restart(false); static std::vector<socket*> SSOCKETS; static std::map<int, std::shared_ptr<con>> CONNECTIONS; Loading
src/event/iocp.cpp +24 −82 Original line number Diff line number Diff line Loading @@ -518,39 +518,10 @@ namespace netplus { continue; } // If there's pending data to send (handshake response) // CRITICAL: flush_out() posts WSASend ASYNCHRONOUSLY in IOCP mode if (owner->csock->hasPendingWrite()) { std::cerr << "[IOCP] Flushing handshake response, posting async WSASend..." << std::endl; try { owner->csock->flush_out(); } catch (NetException& flushEx) { if (flushEx.getErrorType() == NetException::Note) { std::cerr << "[IOCP] flush_out Note - buffer full, will retry" << std::endl; } else { std::cerr << "[IOCP] flush_out error: " << flushEx.what() << std::endl; throw; } } std::cerr << "[IOCP] flush_out posted - now continuing in READ handler" << std::endl; // After posting async write, DON'T try to recv more data yet. // The write completion handler will decide what's next. // Just post recv and let IOCP sequence things properly. if (!owner->csock->getHandshakeDone()) { std::cerr << "[IOCP] Still in handshake, posting recv for next message" << std::endl; try { post_recv(st, *owner); } catch (...) {} } else { std::cerr << "[IOCP] Handshake complete, posting recv for application data" << std::endl; try { post_recv(st, *owner); } catch (...) {} } continue; } // CRITICAL: handshake_after_accept() has ALREADY called flush_out() internally! // Do NOT call flush_out again - the WRITE completion handler will manage async writes. // Just check if handshake is done, otherwise repost recv for more data. // If handshake still not done, wait for more data if (!owner->csock->getHandshakeDone()) { std::cerr << "[IOCP] Handshake not done yet, reposting recv" << std::endl; try { Loading Loading @@ -608,7 +579,7 @@ namespace netplus { // CRITICAL: Clear the pending IOCP write flag owner->csock->setPendingWrite(false); std::cerr << "[IOCP] Write completed, cleared _pendingIocpWrite" << std::endl; std::cerr << "[IOCP] Write completed, cleared _pendingIocpWrite, isSSL=" << isSSL << std::endl; if (isSSL) { // SSL: all data was encrypted and sent Loading @@ -625,66 +596,37 @@ namespace netplus { } } // If handshake not done, continue handshake after send completes // If handshake not done, need to continue it if (!owner->csock->getHandshakeDone()) { std::cerr << "[IOCP] Write completed during handshake, continuing handshake..." << std::endl; std::cerr << "[IOCP] Write completed during handshake, checking for more queued data..." << std::endl; try { owner->csock->handshake_after_accept(); std::cerr << "[IOCP] handshake_after_accept returned, handshakeDone=" << owner->csock->getHandshakeDone() << std::endl; // If there's more data to send, flush it // Check if there's more queued handshake data to send if (owner->csock->hasPendingWrite()) { std::cerr << "[IOCP] More data to send, flushing..." << std::endl; std::cerr << "[IOCP] More handshake data queued, flushing..." << std::endl; try { owner->csock->flush_out(); } catch (NetException& flushEx) { if (flushEx.getErrorType() != NetException::Note) { std::cerr << "[IOCP] flush_out error: " << flushEx.what() << std::endl; throw; } std::cerr << "[IOCP] flush_out returned Note during handshake continuation" << std::endl; } std::cerr << "[IOCP] flush_out returned Note" << std::endl; } } catch (NetException& e) { if (e.getErrorType() == NetException::Note) { std::cerr << "[IOCP] Handshake needs more data, posting recv" << std::endl; // Need more data - but first check if we have data to send if (owner->csock->hasPendingWrite()) { try { owner->csock->flush_out(); } catch (...) {} } // Post recv for more handshake data try { post_recv(st, *owner); } catch (...) {} continue; } // Real error std::cerr << "[IOCP] Handshake error after write: " << e.what() << std::endl; ev->DisconnectEvent(*owner, tid, 0); remove_con(st, cs); try { owner->csock->close(); } catch (...) {} // Continue with next WRITE completion owner->WritePending.store(false); continue; } // Handshake complete or needs more data if (!owner->csock->getHandshakeDone()) { // Post recv for more handshake data try { post_recv(st, *owner); } catch (...) {} } else { std::cerr << "[IOCP] Handshake complete after write!" << std::endl; // Post recv for application data // No more queued data. Post recv to wait for client's next message. // Do NOT call handshake_after_accept() - it will be called from READ handler // when client data arrives. std::cerr << "[IOCP] No more queued data, posting recv for client message" << std::endl; try { post_recv(st, *owner); } catch (...) {} } owner->WritePending.store(false); continue; } } owner->WritePending.store(false); Loading
src/ssl.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -2654,11 +2654,13 @@ void netplus::ssl::queueRaw(const std::vector<uint8_t>& v) { void netplus::ssl::queueRaw(std::vector<uint8_t>&& v) { if (v.empty()) return; std::cerr << "[SSL] queueRaw: queued " << v.size() << " bytes, queue size now=" << (_send_queue.size() + 1) << std::endl; _send_queue.emplace_back(std::move(v)); } void netplus::ssl::queueRaw(const uint8_t* p, size_t n) { if (!p || n == 0) return; std::cerr << "[SSL] queueRaw: queued " << n << " bytes, queue size now=" << (_send_queue.size() + 1) << std::endl; _send_queue.emplace_back(p, p + n); } Loading