From 537cbe12f09c25b40efbb2f7e76a760f0e04a4ec Mon Sep 17 00:00:00 2001 From: momo5502 Date: Tue, 9 Oct 2018 10:53:04 +0200 Subject: [PATCH] Revert "[DHT] Integrate the protocol into the game's network infrastructure" --- src/Components/Modules/DHT.cpp | 81 ++++++++++++++++++++----- src/Components/Modules/DHT.hpp | 10 +-- src/Components/Modules/Localization.cpp | 2 - src/Components/Modules/Network.cpp | 50 --------------- src/Components/Modules/Network.hpp | 3 - src/Components/Modules/QuickPatch.cpp | 12 +--- 6 files changed, 74 insertions(+), 84 deletions(-) diff --git a/src/Components/Modules/DHT.cpp b/src/Components/Modules/DHT.cpp index 96d07948..3fa5784a 100644 --- a/src/Components/Modules/DHT.cpp +++ b/src/Components/Modules/DHT.cpp @@ -43,6 +43,7 @@ extern "C" int dht_gettimeofday(struct timeval *tp, struct timezone* /*tzp*/) namespace Components { + SOCKET DHT::Socket; std::mutex DHT::Mutex; std::vector DHT::Nodes; std::map, Utils::Slot)>> DHT::Handlers; @@ -65,12 +66,6 @@ namespace Components DHT::Handlers[hashStr] = callback; } - void DHT::BootstrapDone() - { - // Tell the game we got our external ip - Utils::Hook::Set(0x649D6F0, 1); - } - void DHT::Hash(std::string data, void* out, size_t size) { ZeroMemory(out, size); @@ -120,10 +115,11 @@ namespace Components } } - void DHT::OnData(char* buf, int len, sockaddr* from, int fromlen) + void DHT::OnData(std::string data, Network::Address address) { time_t tosleep = 0; - dht_periodic(buf, len, from, fromlen, &tosleep, DHT::Callback, NULL); + sockaddr addr = address.getSockAddr(); + dht_periodic(data.data(), data.size(), &addr, sizeof(addr), &tosleep, DHT::Callback, NULL); } void DHT::StoreNodes(bool force) @@ -217,8 +213,29 @@ namespace Components } } + void DHT::SocketFrame() + { + static char buffer[0x2001]; + + sockaddr_in addr; + int addrLen = sizeof(addr); + + while (true) + { + int len = recvfrom(DHT::Socket, buffer, sizeof buffer, 0, reinterpret_cast(&addr), &addrLen); + if (len <= 0) break; + + Network::Address address(&addr); + + std::string data(buffer, len); + DHT::OnData(data, address); + } + } + void DHT::RunFrame() { + DHT::SocketFrame(); + time_t tosleep = 0; dht_periodic(NULL, 0, NULL, 0, &tosleep, DHT::Callback, NULL); DHT::StoreNodes(false); @@ -239,6 +256,36 @@ namespace Components dht_ping_node(&addr, sizeof(addr)); } + void DHT::InitSocket() + { + WSAData data; + WSAStartup(MAKEWORD(2, 2), &data); + + DHT::Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + + int broadcastOn = 1; + setsockopt(DHT::Socket, SOL_SOCKET, SO_BROADCAST, LPSTR(&broadcastOn), sizeof(broadcastOn)); + + unsigned long nonBlocking = 1; + ioctlsocket(DHT::Socket, FIONBIO, &nonBlocking); + + sockaddr_in addr; + ZeroMemory(&addr, sizeof(addr)); + + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + + unsigned short port = DHT_PORT; + while (port < DHT_PORT + DHT_RANGE) + { + addr.sin_port = htons(port++); + if (bind(DHT::Socket, reinterpret_cast(&addr), sizeof(addr)) != SOCKET_ERROR) + { + break; + } + } + } + DHT::DHT() { // #ifdef DEBUG @@ -267,22 +314,23 @@ namespace Components Utils::IO::WriteFile(file, idData); } - dht_init(INT(*Game::ip_socket), -1, reinterpret_cast(idData.data()), reinterpret_cast("JC\0\0")); + DHT::InitSocket(); + dht_init(INT(DHT::Socket), -1, reinterpret_cast(idData.data()), reinterpret_cast("JC\0\0")); DHT::LoadNodes(); Scheduler::OnFrame(DHT::RunFrame); DHT::Bootstrap("router.bittorrent.com:6881"); + DHT::Bootstrap("router.utorrent.com:6881"); DHT::Bootstrap("dht.transmissionbt.com:6881"); + //DHT::Bootstrap("router.bitcomet.com:6881"); // Blacklisted DHT::Bootstrap("dht.aelitis.com:6881"); }); - auto callback = [](std::vector addresses) + DHT::Insert("IW4x", [](std::vector addresses) { std::lock_guard _(DHT::Mutex); - DHT::BootstrapDone(); - for (auto& address : addresses) { if (std::find(DHT::Nodes.begin(), DHT::Nodes.end(), address) == DHT::Nodes.end()) @@ -300,9 +348,7 @@ namespace Components Logger::Print("Received %s\n", address.getCString()); } - }; - - DHT::Insert("xPROTO_IW4x", callback); + }); Command::Add("addnode", [](Command::Params* params) { @@ -313,11 +359,14 @@ namespace Components }); } - void DHT::preDestroy() + DHT::~DHT() { DHT::Handlers.clear(); DHT::StoreNodes(true); dht_uninit(); + + closesocket(DHT::Socket); + WSACleanup(); } } diff --git a/src/Components/Modules/DHT.hpp b/src/Components/Modules/DHT.hpp index cc772770..315e8a66 100644 --- a/src/Components/Modules/DHT.hpp +++ b/src/Components/Modules/DHT.hpp @@ -11,9 +11,9 @@ namespace Components typedef unsigned char Id[20]; DHT(); - void preDestroy() override; + ~DHT(); - static void OnData(char* buf, int len, sockaddr* from, int fromlen); + static void OnData(std::string data, Network::Address address); static void Insert(std::string data, Utils::Slot)> callback); @@ -28,9 +28,8 @@ namespace Components static void Hash(std::string data, void* out, size_t size); - static void BootstrapDone(); - private: + static SOCKET Socket; static std::mutex Mutex; static std::vector Nodes; static std::map, Utils::Slot)>> Handlers; @@ -40,6 +39,9 @@ namespace Components static void StoreNodes(bool force); static void LoadNodes(); + static void InitSocket(); + static void SocketFrame(); + static void Bootstrap(Network::Address node); }; } diff --git a/src/Components/Modules/Localization.cpp b/src/Components/Modules/Localization.cpp index 09daf5a4..8a8232f7 100644 --- a/src/Components/Modules/Localization.cpp +++ b/src/Components/Modules/Localization.cpp @@ -287,8 +287,6 @@ namespace Components } }); - Localization::Set("PLATFORM_POPUP_CONNECTION", "Connecting to the DHT network"); - // #ifndef DISABLE_ANTICHEAT // if (!Dedicated::IsEnabled() && !ZoneBuilder::IsEnabled() && !Utils::IsWineEnvironment() && !Loader::IsPerformingUnitTests()) // { diff --git a/src/Components/Modules/Network.cpp b/src/Components/Modules/Network.cpp index dc2ef50c..1e84a8b0 100644 --- a/src/Components/Modules/Network.cpp +++ b/src/Components/Modules/Network.cpp @@ -336,52 +336,6 @@ namespace Components } } - int __stdcall Network::SendTo(SOCKET s, const char * buf, int len, int flags, const sockaddr* to, int tolen) - { - static char buffer[0x20000]; - - if (len <= 4 || *reinterpret_cast(buf) != -1) - { - if (len + 4 > sizeof(buffer)) - { - Logger::Error("Network layer 1: Packet exceeds buffer length!\n"); - } - - std::memmove(buffer + 4, buf, len); - *reinterpret_cast(buffer) = -2; - - len += 4; - buf = buffer; - } - - return sendto(s, buf, len, flags, to, tolen); - } - - int __stdcall Network::RecvFrom(SOCKET s, char* buf, int len, int flags, sockaddr* from, int * fromlen) - { - int size = recvfrom(s, buf, len, flags, from, fromlen); - if (size >= 4) - { - int magic = *reinterpret_cast(buf); - - if (magic == -2) - { - size -= 4; - std::memmove(buf, buf + 4, size); - } - else if (magic != -1) - { - if (len > size) buf[size] = 0; - DHT::OnData(buf, size, from, *fromlen); - - size = -1; - WSASetLastError(WSAEWOULDBLOCK); - } - } - - return size; - } - Network::Network() { AssertSize(Game::netadr_t, 20); @@ -418,10 +372,6 @@ namespace Components // Install packet deploy hook Utils::Hook::RedirectJump(0x5AA713, Network::DeployPacketStub); - // Intercept the games native network IO interaction - Utils::Hook::Set(0x6D740C, Network::SendTo); - Utils::Hook::Set(0x6D7464, Network::RecvFrom); - Network::Handle("resolveAddress", [](Address address, std::string data) { Network::SendRaw(address, address.getString()); diff --git a/src/Components/Modules/Network.hpp b/src/Components/Modules/Network.hpp index e4e57d8a..b6beda23 100644 --- a/src/Components/Modules/Network.hpp +++ b/src/Components/Modules/Network.hpp @@ -89,9 +89,6 @@ namespace Components static void NetworkStartStub(); static void PacketErrorCheck(); - - static int __stdcall SendTo(SOCKET s, const char * buf, int len, int flags, const sockaddr* to, int tolen); - static int __stdcall RecvFrom(SOCKET s, char* buf, int len, int flags, sockaddr* from, int * fromlen); }; } diff --git a/src/Components/Modules/QuickPatch.cpp b/src/Components/Modules/QuickPatch.cpp index ce11e613..02b4d621 100644 --- a/src/Components/Modules/QuickPatch.cpp +++ b/src/Components/Modules/QuickPatch.cpp @@ -284,7 +284,7 @@ namespace Components Utils::Hook::Nop(0x684080, 5); // Don't spam the console // spawn upnp thread when UPNP_init returns - /*Utils::Hook::Hook(0x47982B, []() + Utils::Hook::Hook(0x47982B, []() { std::thread([]() { @@ -296,16 +296,10 @@ namespace Components std::this_thread::sleep_for(500ms); } }).detach(); - }, HOOK_JUMP).install()->quick();*/ - - // Completely disable UPNP, as it conflicts with our new network protocol - Utils::Hook::Set(0x4797F2, 0xC3); + }, HOOK_JUMP).install()->quick(); // disable the IWNet IP detection (default 'got ipdetect' flag to 1) - //Utils::Hook::Set(0x649D6F0, 1); - - // Tell the game we're already trying to receive our IP - Utils::Hook(0x48C5C0, 0x4513B4, HOOK_JUMP).install()->quick(); + Utils::Hook::Set(0x649D6F0, 1); // Fix stats sleeping Utils::Hook::Set(0x6832BA, 0xEB);