From 88ca17236acf7fe92900b363621cfee0c3f9fa27 Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Sun, 29 Sep 2024 01:15:48 +0200 Subject: [PATCH] remove two-socket download --- include/Client.h | 4 -- include/TNetwork.h | 3 +- src/Client.cpp | 1 - src/TNetwork.cpp | 142 ++++++--------------------------------- src/TResourceManager.cpp | 2 +- 5 files changed, 22 insertions(+), 130 deletions(-) diff --git a/include/Client.h b/include/Client.h index bf83651..894310f 100644 --- a/include/Client.h +++ b/include/Client.h @@ -66,7 +66,6 @@ public: std::string GetCarData(int Ident); std::string GetCarPositionRaw(int Ident); void SetUDPAddr(const ip::udp::endpoint& Addr) { mUDPAddress = Addr; } - void SetDownSock(ip::tcp::socket&& CSock) { mDownSocket = std::move(CSock); } void SetTCPSock(ip::tcp::socket&& CSock) { mSocket = std::move(CSock); } void Disconnect(std::string_view Reason); bool IsDisconnected() const { return !mSocket.is_open(); } @@ -75,8 +74,6 @@ public: [[nodiscard]] const std::unordered_map& GetIdentifiers() const { return mIdentifiers; } [[nodiscard]] const ip::udp::endpoint& GetUDPAddr() const { return mUDPAddress; } [[nodiscard]] ip::udp::endpoint& GetUDPAddr() { return mUDPAddress; } - [[nodiscard]] ip::tcp::socket& GetDownSock() { return mDownSocket; } - [[nodiscard]] const ip::tcp::socket& GetDownSock() const { return mDownSocket; } [[nodiscard]] ip::tcp::socket& GetTCPSock() { return mSocket; } [[nodiscard]] const ip::tcp::socket& GetTCPSock() const { return mSocket; } [[nodiscard]] std::string GetRoles() const { return mRole; } @@ -122,7 +119,6 @@ private: SparseArray mVehiclePosition; std::string mName = "Unknown Client"; ip::tcp::socket mSocket; - ip::tcp::socket mDownSocket; ip::udp::endpoint mUDPAddress {}; int mUnicycleID = -1; std::string mRole; diff --git a/include/TNetwork.h b/include/TNetwork.h index 1640be6..28029db 100644 --- a/include/TNetwork.h +++ b/include/TNetwork.h @@ -58,7 +58,6 @@ private: std::mutex mOpenIDMutex; std::vector UDPRcvFromClient(ip::udp::endpoint& ClientEndpoint); - void HandleDownload(TConnection&& TCPSock); void OnConnect(const std::weak_ptr& c); void TCPClient(const std::weak_ptr& c); void Looper(const std::weak_ptr& c); @@ -67,7 +66,7 @@ private: void Parse(TClient& c, const std::vector& Packet); void SendFile(TClient& c, const std::string& Name); static bool TCPSendRaw(TClient& C, ip::tcp::socket& socket, const uint8_t* Data, size_t Size); - static void SplitLoad(TClient& c, size_t Sent, size_t Size, bool D, const std::string& Name); + static void SendFileToClient(TClient& c, size_t Size, const std::string& Name); static const uint8_t* SendSplit(TClient& c, ip::tcp::socket& Socket, const uint8_t* DataPtr, size_t Size); }; diff --git a/src/Client.cpp b/src/Client.cpp index af40243..ae30334 100644 --- a/src/Client.cpp +++ b/src/Client.cpp @@ -144,7 +144,6 @@ void TClient::EnqueuePacket(const std::vector& Packet) { TClient::TClient(TServer& Server, ip::tcp::socket&& Socket) : mServer(Server) , mSocket(std::move(Socket)) - , mDownSocket(ip::tcp::socket(Server.IoCtx())) , mLastPingTime(std::chrono::high_resolution_clock::now()) { } diff --git a/src/TNetwork.cpp b/src/TNetwork.cpp index f1d5cda..8f9e015 100644 --- a/src/TNetwork.cpp +++ b/src/TNetwork.cpp @@ -240,7 +240,8 @@ void TNetwork::Identify(TConnection&& RawConnection) { if (Code == 'C') { Client = Authentication(std::move(RawConnection)); } else if (Code == 'D') { - HandleDownload(std::move(RawConnection)); + beammp_errorf("Old download packet detected - the client is wildly out of date, this will be ignored"); + return; } else if (Code == 'P') { boost::system::error_code ec; write(RawConnection.Socket, buffer("P"), ec); @@ -249,7 +250,7 @@ void TNetwork::Identify(TConnection&& RawConnection) { beammp_errorf("Invalid code got in Identify: '{}'", Code); } } catch (const std::exception& e) { - beammp_errorf("Error during handling of code {} - client left in invalid state, closing socket", Code); + beammp_errorf("Error during handling of code {} - client left in invalid state, closing socket: {}", Code, e.what()); boost::system::error_code ec; RawConnection.Socket.shutdown(socket_base::shutdown_both, ec); if (ec) { @@ -262,27 +263,7 @@ void TNetwork::Identify(TConnection&& RawConnection) { } } -void TNetwork::HandleDownload(TConnection&& Conn) { - char D; - boost::system::error_code ec; - read(Conn.Socket, buffer(&D, 1), ec); - if (ec) { - Conn.Socket.shutdown(socket_base::shutdown_both, ec); - // ignore ec - return; - } - auto ID = uint8_t(D); - mServer.ForEachClient([&](const std::weak_ptr& ClientPtr) -> bool { - ReadLock Lock(mServer.GetClientMutex()); - if (!ClientPtr.expired()) { - auto c = ClientPtr.lock(); - if (c->GetID() == ID) { - c->SetDownSock(std::move(Conn.Socket)); - } - } - return true; - }); -} + std::string HashPassword(const std::string& str) { std::stringstream ret; @@ -772,8 +753,6 @@ void TNetwork::Parse(TClient& c, const std::vector& Packet) { } void TNetwork::SendFile(TClient& c, const std::string& UnsafeName) { - beammp_info(c.GetName() + " requesting : " + UnsafeName.substr(UnsafeName.find_last_of('/'))); - if (!fs::path(UnsafeName).has_filename()) { if (!TCPSend(c, StringToVector("CO"))) { // TODO: handle @@ -796,87 +775,9 @@ void TNetwork::SendFile(TClient& c, const std::string& UnsafeName) { // TODO: handle } - /// Wait for connections - int T = 0; - while (!c.GetDownSock().is_open() && T < 50) { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - T++; - } - - if (!c.GetDownSock().is_open()) { - beammp_error("Client doesn't have a download socket!"); - if (!c.IsDisconnected()) - c.Disconnect("Missing download socket"); - return; - } - size_t Size = size_t(std::filesystem::file_size(FileName)); - size_t MSize = Size / 2; - std::thread SplitThreads[2] { - std::thread([&] { - RegisterThread("SplitLoad_0"); - SplitLoad(c, 0, MSize, false, FileName); - }), - std::thread([&] { - RegisterThread("SplitLoad_1"); - SplitLoad(c, MSize, Size, true, FileName); - }) - }; - - for (auto& SplitThread : SplitThreads) { - if (SplitThread.joinable()) { - SplitThread.join(); - } - } -} - -static std::pair SplitIntoChunks(size_t FullSize, size_t ChunkSize) { - if (FullSize < ChunkSize) { - return { 0, FullSize }; - } - size_t Count = FullSize / (FullSize / ChunkSize); - size_t LastChunkSize = FullSize - (Count * ChunkSize); - return { Count, LastChunkSize }; -} - -TEST_CASE("SplitIntoChunks") { - size_t FullSize; - size_t ChunkSize; - SUBCASE("Normal case") { - FullSize = 1234567; - ChunkSize = 1234; - } - SUBCASE("Zero original size") { - FullSize = 0; - ChunkSize = 100; - } - SUBCASE("Equal full size and chunk size") { - FullSize = 125; - ChunkSize = 125; - } - SUBCASE("Even split") { - FullSize = 10000; - ChunkSize = 100; - } - SUBCASE("Odd split") { - FullSize = 13; - ChunkSize = 2; - } - SUBCASE("Large sizes") { - FullSize = 10 * GB; - ChunkSize = 125 * MB; - } - auto [Count, LastSize] = SplitIntoChunks(FullSize, ChunkSize); - CHECK((Count * ChunkSize) + LastSize == FullSize); -} - -const uint8_t* /* end ptr */ TNetwork::SendSplit(TClient& c, ip::tcp::socket& Socket, const uint8_t* DataPtr, size_t Size) { - if (TCPSendRaw(c, Socket, DataPtr, Size)) { - return DataPtr + Size; - } else { - return nullptr; - } + SendFileToClient(c, Size, FileName); } #if defined(BEAMMP_LINUX) @@ -886,8 +787,8 @@ const uint8_t* /* end ptr */ TNetwork::SendSplit(TClient& c, ip::tcp::socket& So #include #include #endif -void TNetwork::SplitLoad(TClient& c, size_t Offset, size_t End, bool D, const std::string& Name) { - TScopedTimer timer(fmt::format("Download of {}-{} for '{}'", Offset, End, Name)); +void TNetwork::SendFileToClient(TClient& c, size_t Size, const std::string& Name) { + TScopedTimer timer(fmt::format("Download of '{}' for client {}", Name, c.GetID())); #if defined(BEAMMP_LINUX) signal(SIGPIPE, SIG_IGN); // on linux, we can use sendfile(2)! @@ -897,11 +798,11 @@ void TNetwork::SplitLoad(TClient& c, size_t Offset, size_t End, bool D, const st return; } // native handle, needed in order to make native syscalls with it - int socket = D ? c.GetDownSock().native_handle() : c.GetTCPSock().native_handle(); + int socket = c.GetTCPSock().native_handle(); ssize_t ret = 0; - auto ToSendTotal = End - Offset; - auto Start = Offset; + auto ToSendTotal = Size; + auto Start = 0; while (ret < ssize_t(ToSendTotal)) { auto SysOffset = off_t(Start + size_t(ret)); ret = sendfile(socket, fd, &SysOffset, ToSendTotal - size_t(ret)); @@ -915,35 +816,32 @@ void TNetwork::SplitLoad(TClient& c, size_t Offset, size_t End, bool D, const st std::ifstream f(Name.c_str(), std::ios::binary); uint32_t Split = 125 * MB; std::vector Data; - if (End > Split) + if (Size > Split) Data.resize(Split); else - Data.resize(End); - ip::tcp::socket* TCPSock { nullptr }; - if (D) - TCPSock = &c.GetDownSock(); - else - TCPSock = &c.GetTCPSock(); - while (!c.IsDisconnected() && Offset < End) { - size_t Diff = End - Offset; + Data.resize(Size); + ip::tcp::socket* TCPSock = &c.GetTCPSock(); + std::streamsize Sent = 0; + while (!c.IsDisconnected() && Sent < Size) { + size_t Diff = Size - Sent; if (Diff > Split) { - f.seekg(Offset, std::ios_base::beg); + f.seekg(Sent, std::ios_base::beg); f.read(reinterpret_cast(Data.data()), Split); if (!TCPSendRaw(c, *TCPSock, Data.data(), Split)) { if (!c.IsDisconnected()) c.Disconnect("TCPSendRaw failed in mod download (1)"); break; } - Offset += Split; + Sent += Split; } else { - f.seekg(Offset, std::ios_base::beg); + f.seekg(Sent, std::ios_base::beg); f.read(reinterpret_cast(Data.data()), Diff); if (!TCPSendRaw(c, *TCPSock, Data.data(), int32_t(Diff))) { if (!c.IsDisconnected()) c.Disconnect("TCPSendRaw failed in mod download (2)"); break; } - Offset += Diff; + Sent += Diff; } } #endif diff --git a/src/TResourceManager.cpp b/src/TResourceManager.cpp index 89d4258..82d1667 100644 --- a/src/TResourceManager.cpp +++ b/src/TResourceManager.cpp @@ -127,7 +127,7 @@ void TResourceManager::RefreshFiles() { } beammp_debugf("sha256('{}'): {}", File, result); mMods.push_back(nlohmann::json { - { "file_name", File }, + { "file_name", std::filesystem::path(File).filename() }, { "file_size", Read }, { "hash_algorithm", "sha256" }, { "hash", result },