Loading CMakeSettings.json +1 −8 Original line number Diff line number Diff line Loading @@ -8,14 +8,7 @@ "installRoot": "C:/Users/jan.koester/build_blogi/${name}", "cmakeCommandArgs": "", "buildCommandArgs": "", "inheritEnvironments": [ "msvc_x64_x64" ], "variables": [ { "name": "CMAKE_INSTALL_PREFIX", "value": "C:/Users/jan.koester/build_blogi/install", "type": "PATH" } ] "inheritEnvironments": [ "msvc_x64_x64" ] } ] } No newline at end of file src/connection.h +1 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ namespace netplus { class eventapi; class pollapi; class socket; // forward declaration added template<typename T> struct condata_traits { Loading src/event/iocp.cpp +101 −50 Original line number Diff line number Diff line Loading @@ -144,10 +144,12 @@ namespace netplus { if (eargs->ssocket->_Type == sockettype::TCP) { pa->sock = std::make_unique<tcp>(); } else if (eargs->ssocket->_Type == sockettype::SSL) { } else if (eargs->ssocket->_Type == sockettype::SSL) { auto* srv = static_cast<ssl*>(eargs->ssocket); pa->sock = std::make_unique<ssl>(srv->_cert); } else { } else { delete pa; return; } Loading @@ -169,10 +171,18 @@ namespace netplus { // Point the Overlapped buffer to our persistent context memory buffer buf(ctx->readCtx.buffer, BLOCKSIZE); // Debug: report read post if (c.csock) { std::cerr << "[IOCP] start_read posting WSARecv for fd=" << c.csock->fd() << std::endl; } else { std::cerr << "[IOCP] start_read: csock == nullptr" << std::endl; } // This triggers the raw WSARecv. For SSL, it fills the internal _rx_netbuf. if (c.csock->_Type == sockettype::SSL) { static_cast<ssl*>(c.csock.get())->recvDataWSA(buf, 0); } else { } else { static_cast<tcp*>(c.csock.get())->recvDataWSA(buf, 0); } } Loading @@ -181,6 +191,11 @@ namespace netplus { con& c = *ctx->CurCon; if (c.SendData.empty()) return; // Debug: report write post if (c.csock) { std::cerr << "[IOCP] start_write posting WSASend for fd=" << c.csock->fd() << " bytes=" << c.SendData.size() << std::endl; } // Take plaintext from SendData and pass it to the WSA method // For SSL, this will perform the encryption before calling WSASend size_t toSend = (std::min)((size_t)BLOCKSIZE, c.SendData.size()); Loading @@ -189,7 +204,8 @@ namespace netplus { size_t consumed = 0; if (c.csock->_Type == sockettype::SSL) { consumed = static_cast<ssl*>(c.csock.get())->sendDataWSA(out, 0); } else { } else { consumed = static_cast<tcp*>(c.csock.get())->sendDataWSA(out, 0); } Loading Loading @@ -223,11 +239,13 @@ namespace netplus { if (!accepted) { // Unknown overlapped - ignore std::cerr << "[IOCP] AcceptEx completion: no pending entry for overlapped=" << pOverlapped << std::endl; continue; } // Update accept context SOCKET accSock = (SOCKET)accepted->fd(); std::cerr << "[IOCP] AcceptEx completion: accepted fd=" << accSock << " overlapped=" << pOverlapped << std::endl; setsockopt(accSock, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char*)&eargs->listenSock, sizeof(eargs->listenSock)); Loading @@ -249,9 +267,12 @@ namespace netplus { HANDLE h = CreateIoCompletionPort((HANDLE)(uintptr_t)pClient->CurCon->csock->fd(), eargs->eviocp, (ULONG_PTR)pClient, 0); if (!h) { std::cerr << "[IOCP] CreateIoCompletionPort associate accepted failed for fd=" << pClient->CurCon->csock->fd() << std::endl; eargs->event->DisconnectEvent(*pClient->CurCon, tid, (ULONG_PTR)eargs->args); delete pClient; } else { } else { std::cerr << "[IOCP] calling ConnectEvent for fd=" << pClient->CurCon->csock->fd() << std::endl; eargs->event->ConnectEvent(*pClient->CurCon, tid, (ULONG_PTR)eargs->args); start_read(pClient); } Loading @@ -263,8 +284,10 @@ namespace netplus { { std::lock_guard<std::mutex> lk(ACCEPT_MTX); ACCEPT_PENDING.emplace(&nextSock->_Overlapped, std::move(nextSock)); std::cerr << "[IOCP] Re-posted AcceptEx; pending_count=" << ACCEPT_PENDING.size() << std::endl; } } catch (NetException& e) { } catch (NetException& e) { std::cerr << "AcceptEx repost error: " << e.what() << std::endl; } continue; Loading @@ -276,6 +299,7 @@ namespace netplus { con& c = *pClientContext->CurCon; if (!bReturn || (bReturn && dwBytesTransfered == 0)) { std::cerr << "[IOCP] connection closed or error on fd=" << c.csock->fd() << " bReturn=" << bReturn << " bytes=" << dwBytesTransfered << std::endl; eargs->event->DisconnectEvent(c, tid, (ULONG_PTR)eargs->args); delete pClientContext; continue; Loading @@ -298,11 +322,14 @@ namespace netplus { size_t decrypted = 0; while ((decrypted = sslSocket->recvDataWSA(plain, 0)) > 0) { c.RecvData.append(plain.data.buf, decrypted); std::cerr << "[IOCP] RequestEvent (SSL) fd=" << c.csock->fd() << " appending " << decrypted << " bytes total_recv=" << c.RecvData.size() << std::endl; eargs->event->RequestEvent(c, tid, (ULONG_PTR)eargs->args); } } else { } else { // Plain TCP c.RecvData.append(pIoCtx->buffer, dwBytesTransfered); std::cerr << "[IOCP] RequestEvent (TCP) fd=" << c.csock->fd() << " appended bytes=" << dwBytesTransfered << " total_recv=" << c.RecvData.size() << std::endl; eargs->event->RequestEvent(c, tid, (ULONG_PTR)eargs->args); } Loading @@ -310,7 +337,8 @@ namespace netplus { if (!c.SendData.empty()) start_write(pClientContext); else start_read(pClientContext); } else if (pIoCtx->operation == OP_WRITE) { } else if (pIoCtx->operation == OP_WRITE) { // For SSL: dwBytesTransfered is the size of the ENCRYPTED record sent. // For TCP: It is the size of the plaintext sent. Loading @@ -327,14 +355,17 @@ namespace netplus { } if (c.SendData.empty()) { std::cerr << "[IOCP] ResponseEvent fd=" << c.csock->fd() << " send_queue_empty" << std::endl; eargs->event->ResponseEvent(c, tid, (ULONG_PTR)eargs->args); } if (!c.SendData.empty()) start_write(pClientContext); else start_read(pClientContext); } } catch (NetException& e) { } catch (NetException& e) { if (e.getErrorType() != NetException::Note) { std::cerr << "[IOCP] NetException during IO processing for fd=" << c.csock->fd() << ": " << e.what() << std::endl; eargs->event->DisconnectEvent(c, tid, (ULONG_PTR)eargs->args); delete pClientContext; } Loading @@ -343,6 +374,10 @@ namespace netplus { } }; void eventapi::CreateConnection(std::shared_ptr<con>& res) { res = std::make_shared<con>(this); } event::event(socket* serversocket, int timeout) : _ServerSocket(serversocket) { if (!serversocket) { NetException e; Loading @@ -353,6 +388,8 @@ namespace netplus { _ServerSocket->bind(); _ServerSocket->listen(); std::cerr << "[IOCP] server bind/listen OK; fd=" << _ServerSocket->fd() << std::endl; SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); threads = sysinfo.dwNumberOfProcessors; Loading @@ -369,6 +406,8 @@ namespace netplus { throw e; } std::cerr << "[IOCP] created IOCP handle=" << iocp << std::endl; EventWorkerArgs eargs; eargs.ssocket = _ServerSocket; eargs.event = this; Loading Loading @@ -397,6 +436,8 @@ namespace netplus { throw e; } std::cerr << "[IOCP] associated listener socket=" << eargs.listenSock << " with IOCP key=" << eargs.listenerKey << std::endl; if (_ServerSocket->_Type == sockettype::SSL) { // Resolve AcceptEx function pointer GUID guidAcceptEx = WSAID_ACCEPTEX; Loading @@ -410,6 +451,8 @@ namespace netplus { throw e; } std::cerr << "[IOCP] AcceptEx function pointer loaded" << std::endl; // Pre-post AcceptEx pool const int ACCEPT_POOL = 64; for (int i = 0; i < ACCEPT_POOL; ++i) { Loading @@ -419,18 +462,22 @@ namespace netplus { ACCEPT_PENDING.emplace(&s->_Overlapped, std::move(s)); } std::cerr << "[IOCP] pre-posted AcceptEx pool size=" << ACCEPT_PENDING.size() << std::endl; // No blocking accept loop here. Worker threads will handle accepts. while (event::Running) { std::this_thread::sleep_for(std::chrono::milliseconds(50)); } } else { } else { // Listener Loop (Standard Accept for IOCP) for non-SSL sockets while (event::Running) { std::unique_ptr<socket> cltSrv; if (_ServerSocket->_Type == sockettype::TCP) { cltSrv = std::make_unique<tcp>(); } else if (_ServerSocket->_Type == sockettype::SSL) { } else if (_ServerSocket->_Type == sockettype::SSL) { netplus::ssl* srv = static_cast<netplus::ssl*>(_ServerSocket); cltSrv = std::make_unique<ssl>(srv->_cert); } Loading @@ -440,15 +487,19 @@ namespace netplus { client* pClient = new client(this); pClient->CurCon->csock = std::move(cltSrv); std::cerr << "[IOCP] accept() returned, client fd=" << pClient->CurCon->csock->fd() << std::endl; HANDLE h = CreateIoCompletionPort((HANDLE)(uintptr_t)pClient->CurCon->csock->fd(), iocp, (ULONG_PTR)pClient, 0); if (!h) { delete pClient; continue; } std::cerr << "[IOCP] calling ConnectEvent for fd=" << pClient->CurCon->csock->fd() << std::endl; this->ConnectEvent(*pClient->CurCon, 0, args); EventWorker::start_read(pClient); } catch (NetException& e) { } catch (NetException& e) { if (event::Running) std::cerr << "Accept error: " << e.what() << std::endl; } } Loading src/ssl.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -282,7 +282,7 @@ namespace netplus { readExactRaw(*s, hdr, 5); if (hdr[1] != 0x03) { if (hdr[1] != 0x0303) { netplus::NetException e; e[netplus::NetException::Error] << "ssl::accept: bad TLS major version"; throw e; Loading test/CMakeLists.txt +5 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,11 @@ add_executable(x509 x509.cpp) target_link_libraries(x509 netplus-static) add_executable(http http.cpp) target_link_libraries(http netplus-static) add_test( NAME dest_test COMMAND des Loading Loading
CMakeSettings.json +1 −8 Original line number Diff line number Diff line Loading @@ -8,14 +8,7 @@ "installRoot": "C:/Users/jan.koester/build_blogi/${name}", "cmakeCommandArgs": "", "buildCommandArgs": "", "inheritEnvironments": [ "msvc_x64_x64" ], "variables": [ { "name": "CMAKE_INSTALL_PREFIX", "value": "C:/Users/jan.koester/build_blogi/install", "type": "PATH" } ] "inheritEnvironments": [ "msvc_x64_x64" ] } ] } No newline at end of file
src/connection.h +1 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ namespace netplus { class eventapi; class pollapi; class socket; // forward declaration added template<typename T> struct condata_traits { Loading
src/event/iocp.cpp +101 −50 Original line number Diff line number Diff line Loading @@ -144,10 +144,12 @@ namespace netplus { if (eargs->ssocket->_Type == sockettype::TCP) { pa->sock = std::make_unique<tcp>(); } else if (eargs->ssocket->_Type == sockettype::SSL) { } else if (eargs->ssocket->_Type == sockettype::SSL) { auto* srv = static_cast<ssl*>(eargs->ssocket); pa->sock = std::make_unique<ssl>(srv->_cert); } else { } else { delete pa; return; } Loading @@ -169,10 +171,18 @@ namespace netplus { // Point the Overlapped buffer to our persistent context memory buffer buf(ctx->readCtx.buffer, BLOCKSIZE); // Debug: report read post if (c.csock) { std::cerr << "[IOCP] start_read posting WSARecv for fd=" << c.csock->fd() << std::endl; } else { std::cerr << "[IOCP] start_read: csock == nullptr" << std::endl; } // This triggers the raw WSARecv. For SSL, it fills the internal _rx_netbuf. if (c.csock->_Type == sockettype::SSL) { static_cast<ssl*>(c.csock.get())->recvDataWSA(buf, 0); } else { } else { static_cast<tcp*>(c.csock.get())->recvDataWSA(buf, 0); } } Loading @@ -181,6 +191,11 @@ namespace netplus { con& c = *ctx->CurCon; if (c.SendData.empty()) return; // Debug: report write post if (c.csock) { std::cerr << "[IOCP] start_write posting WSASend for fd=" << c.csock->fd() << " bytes=" << c.SendData.size() << std::endl; } // Take plaintext from SendData and pass it to the WSA method // For SSL, this will perform the encryption before calling WSASend size_t toSend = (std::min)((size_t)BLOCKSIZE, c.SendData.size()); Loading @@ -189,7 +204,8 @@ namespace netplus { size_t consumed = 0; if (c.csock->_Type == sockettype::SSL) { consumed = static_cast<ssl*>(c.csock.get())->sendDataWSA(out, 0); } else { } else { consumed = static_cast<tcp*>(c.csock.get())->sendDataWSA(out, 0); } Loading Loading @@ -223,11 +239,13 @@ namespace netplus { if (!accepted) { // Unknown overlapped - ignore std::cerr << "[IOCP] AcceptEx completion: no pending entry for overlapped=" << pOverlapped << std::endl; continue; } // Update accept context SOCKET accSock = (SOCKET)accepted->fd(); std::cerr << "[IOCP] AcceptEx completion: accepted fd=" << accSock << " overlapped=" << pOverlapped << std::endl; setsockopt(accSock, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char*)&eargs->listenSock, sizeof(eargs->listenSock)); Loading @@ -249,9 +267,12 @@ namespace netplus { HANDLE h = CreateIoCompletionPort((HANDLE)(uintptr_t)pClient->CurCon->csock->fd(), eargs->eviocp, (ULONG_PTR)pClient, 0); if (!h) { std::cerr << "[IOCP] CreateIoCompletionPort associate accepted failed for fd=" << pClient->CurCon->csock->fd() << std::endl; eargs->event->DisconnectEvent(*pClient->CurCon, tid, (ULONG_PTR)eargs->args); delete pClient; } else { } else { std::cerr << "[IOCP] calling ConnectEvent for fd=" << pClient->CurCon->csock->fd() << std::endl; eargs->event->ConnectEvent(*pClient->CurCon, tid, (ULONG_PTR)eargs->args); start_read(pClient); } Loading @@ -263,8 +284,10 @@ namespace netplus { { std::lock_guard<std::mutex> lk(ACCEPT_MTX); ACCEPT_PENDING.emplace(&nextSock->_Overlapped, std::move(nextSock)); std::cerr << "[IOCP] Re-posted AcceptEx; pending_count=" << ACCEPT_PENDING.size() << std::endl; } } catch (NetException& e) { } catch (NetException& e) { std::cerr << "AcceptEx repost error: " << e.what() << std::endl; } continue; Loading @@ -276,6 +299,7 @@ namespace netplus { con& c = *pClientContext->CurCon; if (!bReturn || (bReturn && dwBytesTransfered == 0)) { std::cerr << "[IOCP] connection closed or error on fd=" << c.csock->fd() << " bReturn=" << bReturn << " bytes=" << dwBytesTransfered << std::endl; eargs->event->DisconnectEvent(c, tid, (ULONG_PTR)eargs->args); delete pClientContext; continue; Loading @@ -298,11 +322,14 @@ namespace netplus { size_t decrypted = 0; while ((decrypted = sslSocket->recvDataWSA(plain, 0)) > 0) { c.RecvData.append(plain.data.buf, decrypted); std::cerr << "[IOCP] RequestEvent (SSL) fd=" << c.csock->fd() << " appending " << decrypted << " bytes total_recv=" << c.RecvData.size() << std::endl; eargs->event->RequestEvent(c, tid, (ULONG_PTR)eargs->args); } } else { } else { // Plain TCP c.RecvData.append(pIoCtx->buffer, dwBytesTransfered); std::cerr << "[IOCP] RequestEvent (TCP) fd=" << c.csock->fd() << " appended bytes=" << dwBytesTransfered << " total_recv=" << c.RecvData.size() << std::endl; eargs->event->RequestEvent(c, tid, (ULONG_PTR)eargs->args); } Loading @@ -310,7 +337,8 @@ namespace netplus { if (!c.SendData.empty()) start_write(pClientContext); else start_read(pClientContext); } else if (pIoCtx->operation == OP_WRITE) { } else if (pIoCtx->operation == OP_WRITE) { // For SSL: dwBytesTransfered is the size of the ENCRYPTED record sent. // For TCP: It is the size of the plaintext sent. Loading @@ -327,14 +355,17 @@ namespace netplus { } if (c.SendData.empty()) { std::cerr << "[IOCP] ResponseEvent fd=" << c.csock->fd() << " send_queue_empty" << std::endl; eargs->event->ResponseEvent(c, tid, (ULONG_PTR)eargs->args); } if (!c.SendData.empty()) start_write(pClientContext); else start_read(pClientContext); } } catch (NetException& e) { } catch (NetException& e) { if (e.getErrorType() != NetException::Note) { std::cerr << "[IOCP] NetException during IO processing for fd=" << c.csock->fd() << ": " << e.what() << std::endl; eargs->event->DisconnectEvent(c, tid, (ULONG_PTR)eargs->args); delete pClientContext; } Loading @@ -343,6 +374,10 @@ namespace netplus { } }; void eventapi::CreateConnection(std::shared_ptr<con>& res) { res = std::make_shared<con>(this); } event::event(socket* serversocket, int timeout) : _ServerSocket(serversocket) { if (!serversocket) { NetException e; Loading @@ -353,6 +388,8 @@ namespace netplus { _ServerSocket->bind(); _ServerSocket->listen(); std::cerr << "[IOCP] server bind/listen OK; fd=" << _ServerSocket->fd() << std::endl; SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); threads = sysinfo.dwNumberOfProcessors; Loading @@ -369,6 +406,8 @@ namespace netplus { throw e; } std::cerr << "[IOCP] created IOCP handle=" << iocp << std::endl; EventWorkerArgs eargs; eargs.ssocket = _ServerSocket; eargs.event = this; Loading Loading @@ -397,6 +436,8 @@ namespace netplus { throw e; } std::cerr << "[IOCP] associated listener socket=" << eargs.listenSock << " with IOCP key=" << eargs.listenerKey << std::endl; if (_ServerSocket->_Type == sockettype::SSL) { // Resolve AcceptEx function pointer GUID guidAcceptEx = WSAID_ACCEPTEX; Loading @@ -410,6 +451,8 @@ namespace netplus { throw e; } std::cerr << "[IOCP] AcceptEx function pointer loaded" << std::endl; // Pre-post AcceptEx pool const int ACCEPT_POOL = 64; for (int i = 0; i < ACCEPT_POOL; ++i) { Loading @@ -419,18 +462,22 @@ namespace netplus { ACCEPT_PENDING.emplace(&s->_Overlapped, std::move(s)); } std::cerr << "[IOCP] pre-posted AcceptEx pool size=" << ACCEPT_PENDING.size() << std::endl; // No blocking accept loop here. Worker threads will handle accepts. while (event::Running) { std::this_thread::sleep_for(std::chrono::milliseconds(50)); } } else { } else { // Listener Loop (Standard Accept for IOCP) for non-SSL sockets while (event::Running) { std::unique_ptr<socket> cltSrv; if (_ServerSocket->_Type == sockettype::TCP) { cltSrv = std::make_unique<tcp>(); } else if (_ServerSocket->_Type == sockettype::SSL) { } else if (_ServerSocket->_Type == sockettype::SSL) { netplus::ssl* srv = static_cast<netplus::ssl*>(_ServerSocket); cltSrv = std::make_unique<ssl>(srv->_cert); } Loading @@ -440,15 +487,19 @@ namespace netplus { client* pClient = new client(this); pClient->CurCon->csock = std::move(cltSrv); std::cerr << "[IOCP] accept() returned, client fd=" << pClient->CurCon->csock->fd() << std::endl; HANDLE h = CreateIoCompletionPort((HANDLE)(uintptr_t)pClient->CurCon->csock->fd(), iocp, (ULONG_PTR)pClient, 0); if (!h) { delete pClient; continue; } std::cerr << "[IOCP] calling ConnectEvent for fd=" << pClient->CurCon->csock->fd() << std::endl; this->ConnectEvent(*pClient->CurCon, 0, args); EventWorker::start_read(pClient); } catch (NetException& e) { } catch (NetException& e) { if (event::Running) std::cerr << "Accept error: " << e.what() << std::endl; } } Loading
src/ssl.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -282,7 +282,7 @@ namespace netplus { readExactRaw(*s, hdr, 5); if (hdr[1] != 0x03) { if (hdr[1] != 0x0303) { netplus::NetException e; e[netplus::NetException::Error] << "ssl::accept: bad TLS major version"; throw e; Loading
test/CMakeLists.txt +5 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,11 @@ add_executable(x509 x509.cpp) target_link_libraries(x509 netplus-static) add_executable(http http.cpp) target_link_libraries(http netplus-static) add_test( NAME dest_test COMMAND des Loading