From 16350594eeb546a55fcf206884953d4f5bc49341 Mon Sep 17 00:00:00 2001 From: Peter Rindal Date: Fri, 29 Dec 2023 13:07:06 -0800 Subject: [PATCH] fixed partial reads on Channel initial handshake --- CMakeLists.txt | 7 ----- cryptoTools/Network/Channel.cpp | 5 ++-- cryptoTools/Network/IOService.cpp | 27 +++++++++-------- tests_cryptoTools/BtChannel_Tests.cpp | 42 +++++++++++++++++++++++++++ tests_cryptoTools/BtChannel_Tests.h | 3 ++ tests_cryptoTools/UnitTests.cpp | 2 ++ 6 files changed, 64 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d338496..25fcb72 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,13 +26,6 @@ if("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") endif() if(MSVC) - # optionally add the following to CMAKE_PREFIX_PATH - if(NOT DEFINED CMAKE_PREFIX_PATH AND NOT DEFINED NO_OC_DEFAULT_PREFIX) - set(CMAKE_PREFIX_PATH - "c:/libs" - "${CMAKE_CURRENT_SOURCE_DIR}/.." - ) - endif() else() # Select flags. set(CMAKE_C_FLAGS "-Wall -Wfatal-errors") diff --git a/cryptoTools/Network/Channel.cpp b/cryptoTools/Network/Channel.cpp index 0098bcd..8a51107 100644 --- a/cryptoTools/Network/Channel.cpp +++ b/cryptoTools/Network/Channel.cpp @@ -450,7 +450,7 @@ namespace osuCrypto { auto buffer = boost::asio::buffer((char*)&mRecvChar, 1); auto& sock = mSock->mSock; - sock.async_receive(buffer, [this](const error_code& ec, u64 bytesTransferred) { + boost::asio::async_read(sock, buffer, [this](const error_code& ec, u64 bytesTransferred) { boost::asio::dispatch(mStrand, [this, ec, bytesTransferred] { if (ec || bytesTransferred != 1) @@ -488,14 +488,13 @@ namespace osuCrypto { std::copy(str.begin(), str.end(), mSendBuffer.begin() + sizeof(details::size_header_type)); - IF_LOG(mChl->mLog.push("Success: async connect to server. ConnectionString = " \ + str + " " + std::to_string((u64) & *mChl->mHandle))); auto buffer = boost::asio::buffer((char*)mSendBuffer.data(), mSendBuffer.size()); auto& sock = mSock->mSock;; - sock.async_send(buffer, [this](const error_code& ec, u64 bytesTransferred) { + boost::asio::async_write(sock, buffer, [this](const error_code& ec, u64 bytesTransferred) { boost::asio::dispatch(mStrand, [this, ec, bytesTransferred] { if (ec || bytesTransferred != mSendBuffer.size()) diff --git a/cryptoTools/Network/IOService.cpp b/cryptoTools/Network/IOService.cpp index 8bb1b3b..77438dc 100644 --- a/cryptoTools/Network/IOService.cpp +++ b/cryptoTools/Network/IOService.cpp @@ -140,7 +140,7 @@ namespace osuCrypto //#endif LOG_MSG("listening with socket#" + std::to_string(sockIter->mIdx) + " at " + mAddress.address().to_string() + " : " + std::to_string(mAddress.port())); - + //BoostSocketInterface* newSocket = new BoostSocketInterface(mIOService.mIoService); mHandle.async_accept(sockIter->mSock, [sockIter, this](const boost::system::error_code& ec) { @@ -208,7 +208,7 @@ namespace osuCrypto sockIter->mBuff[0] = 'q'; auto buffer = boost::asio::buffer((char*)sockIter->mBuff.data(), sockIter->mBuff.size()); - sockIter->mSock.async_send(buffer, [this, sockIter](const error_code& ec, u64 bytesTransferred) { + boost::asio::async_write(sockIter->mSock, buffer, [this, sockIter](const error_code& ec, u64 bytesTransferred) { if (ec || bytesTransferred != 1) erasePendingSocket(sockIter); else @@ -225,10 +225,10 @@ namespace osuCrypto sockIter->mBuff.resize(sizeof(u32)); auto buffer = boost::asio::buffer((char*)sockIter->mBuff.data(), sockIter->mBuff.size()); - sockIter->mSock.async_receive(buffer, + boost::asio::async_read(sockIter->mSock, buffer, [sockIter, this](const boost::system::error_code& ec, u64 bytesTransferred) { - if (!ec) + if (!ec && bytesTransferred == sizeof(u32)) { LOG_MSG("Recv header with socket#" + std::to_string(sockIter->mIdx)); @@ -236,10 +236,14 @@ namespace osuCrypto sockIter->mBuff.resize(size); auto buffer = boost::asio::buffer((char*)sockIter->mBuff.data(), sockIter->mBuff.size()); + + boost::asio::async_read(sockIter->mSock, buffer, + [sockIter, this, size](const boost::system::error_code& ec3, u64 bytesTransferred2) + { + boost::asio::dispatch(mStrand, [sockIter, this, size, ec3, bytesTransferred2] + { - sockIter->mSock.async_receive(buffer, - bind_executor(mStrand, [sockIter, this](const boost::system::error_code& ec3, u64 bytesTransferred2) { - if (!ec3) + if (!ec3 && bytesTransferred2 == size) { LOG_MSG("Recv boby with socket#" + std::to_string(sockIter->mIdx) + " ~ " + sockIter->mBuff); @@ -251,16 +255,15 @@ namespace osuCrypto else { std::stringstream ss; - ss << "socket header body failed: " << ec3.message() << std::endl; + ss << "socket header body failed: " << ec3.message() + << ", bt: " << bytesTransferred2 << " / " << size << std::endl; mIOService.printError(ss.str()); LOG_MSG("Recv body failed with socket#" + std::to_string(sockIter->mIdx) + " ~ " + ec3.message()); } erasePendingSocket(sockIter); - } - ) - ); - + }); + }); } else { diff --git a/tests_cryptoTools/BtChannel_Tests.cpp b/tests_cryptoTools/BtChannel_Tests.cpp index f1023c7..8bb9460 100644 --- a/tests_cryptoTools/BtChannel_Tests.cpp +++ b/tests_cryptoTools/BtChannel_Tests.cpp @@ -532,6 +532,48 @@ namespace tests_cryptoTools //chl.waitForConnection(std::chrono::seconds(1)); } + + + void BtNetwork_PartialConnect_Test(const CLP& cmd) + { + IOService ios; + ios.showErrorMessages(true); + auto tls = getIfTLS(cmd); + + Session server(ios, "127.0.0.1", 1212, SessionMode::Server, tls, "name"); + auto chl = server.addChannel(); + + boost::asio::ip::tcp::socket sock(ios.mIoService); + + boost::asio::ip::tcp::resolver resolver(ios.mIoService); + boost::asio::ip::tcp::resolver::query query("127.0.0.1", "1212"); + boost::asio::ip::tcp::endpoint addr = *resolver.resolve(query); + + error_code ec; + sock.connect(addr, ec); + + + std::stringstream ss; + ss << "name`42`_autoName_0`_autoName_0"; + auto str = ss.str(); + u32 size = (u32)str.size(); + auto buff = boost::asio::buffer((u8*)&size, sizeof(u32));; + boost::asio::write(sock, buff); + + auto s = str.size() / 2; + buff = boost::asio::buffer(str.data(), s);; + boost::asio::write(sock, buff); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + + buff = boost::asio::buffer(str.data() + s, str.size() - s);; + boost::asio::write(sock, buff); + + auto c = chl.waitForConnection(std::chrono::seconds(10000)); + if (!c) + throw RTE_LOC; + } + + void BtNetwork_shutdown_test(const osuCrypto::CLP& cmd) { diff --git a/tests_cryptoTools/BtChannel_Tests.h b/tests_cryptoTools/BtChannel_Tests.h index 822a5de..13b5aa2 100644 --- a/tests_cryptoTools/BtChannel_Tests.h +++ b/tests_cryptoTools/BtChannel_Tests.h @@ -12,6 +12,8 @@ namespace tests_cryptoTools void BtNetwork_Connect1_Test(const osuCrypto::CLP& cmd); void BtNetwork_BadConnect_Test(const osuCrypto::CLP& cmd); + void BtNetwork_PartialConnect_Test(const osuCrypto::CLP& cmd); + void BtNetwork_shutdown_test(const osuCrypto::CLP& cmd); @@ -52,6 +54,7 @@ namespace tests_cryptoTools inline void np() { throw oc::UnitTestSkipped("ENABLE_BOOST not defined."); } inline void BtNetwork_Connect1_Test(const osuCrypto::CLP& cmd) { np(); } inline void BtNetwork_BadConnect_Test(const osuCrypto::CLP& cmd) { np(); } + inline void BtNetwork_PartialConnect_Test(const osuCrypto::CLP& cmd) { np(); } inline void BtNetwork_shutdown_test(const osuCrypto::CLP& cmd) { np(); } inline void BtNetwork_RapidConnect_Test(const osuCrypto::CLP& cmd) { np(); } inline void BtNetwork_OneMegabyteSend_Test(const osuCrypto::CLP& cmd) { np(); } diff --git a/tests_cryptoTools/UnitTests.cpp b/tests_cryptoTools/UnitTests.cpp index 84783f0..e93861c 100644 --- a/tests_cryptoTools/UnitTests.cpp +++ b/tests_cryptoTools/UnitTests.cpp @@ -41,6 +41,8 @@ namespace tests_cryptoTools th.add("BtNetwork_ServerMode_Test ", BtNetwork_ServerMode_Test); th.add("BtNetwork_clientClose_Test ", BtNetwork_clientClose_Test); th.add("BtNetwork_BadConnect_Test ", BtNetwork_BadConnect_Test); + th.add("BtNetwork_PartialConnect_Test ", BtNetwork_PartialConnect_Test); + th.add("BtNetwork_oneWorker_Test ", BtNetwork_oneWorker_Test); th.add("BtNetwork_queue_Test ", BtNetwork_queue_Test); th.add("BtNetwork_socketAdapter_test ", BtNetwork_socketAdapter_test);