From b6ca7cf91855241c0b591d52711a9b55738d5f6b Mon Sep 17 00:00:00 2001 From: Xertis <118364459+Xertis@users.noreply.github.com> Date: Tue, 30 Sep 2025 23:45:00 +0300 Subject: [PATCH 1/2] make Nagle's algorithm configurable --- doc/ru/scripting/builtins/libnetwork.md | 6 ++++++ res/scripts/classes.lua | 2 ++ src/logic/scripting/lua/libs/libnetwork.cpp | 24 +++++++++++++++++++++ src/network/Network.cpp | 16 ++++++++++++++ src/network/Network.hpp | 2 ++ 5 files changed, 50 insertions(+) diff --git a/doc/ru/scripting/builtins/libnetwork.md b/doc/ru/scripting/builtins/libnetwork.md index c9cc890c..16f9dd5c 100644 --- a/doc/ru/scripting/builtins/libnetwork.md +++ b/doc/ru/scripting/builtins/libnetwork.md @@ -72,6 +72,12 @@ socket:is_connected() --> bool -- Возвращает адрес и порт соединения. socket:get_address() --> str, int + +-- Возвращает состояние NoDelay +socket:get_nodelay() --> bool + +-- Устанавливает состояние NoDelay +socket:set_nodelay(state: bool) ``` ```lua diff --git a/res/scripts/classes.lua b/res/scripts/classes.lua index e63d5a5a..0d422b04 100644 --- a/res/scripts/classes.lua +++ b/res/scripts/classes.lua @@ -44,6 +44,8 @@ local Socket = {__index={ is_alive=function(self) return network.__is_alive(self.id) end, is_connected=function(self) return network.__is_connected(self.id) end, get_address=function(self) return network.__get_address(self.id) end, + set_nodelay=function(self, nodelay) return network.__set_nodelay(self.id, nodelay or false) end, + get_nodelay=function(self) return network.__get_nodelay(self.id) end, }} local WriteableSocket = {__index={ diff --git a/src/logic/scripting/lua/libs/libnetwork.cpp b/src/logic/scripting/lua/libs/libnetwork.cpp index 94390c93..af7dedef 100644 --- a/src/logic/scripting/lua/libs/libnetwork.cpp +++ b/src/logic/scripting/lua/libs/libnetwork.cpp @@ -382,6 +382,28 @@ static int l_get_total_download(lua::State* L, network::Network& network) { return lua::pushinteger(L, network.getTotalDownload()); } +static int l_set_nodelay(lua::State* L, network::Network& network) { + u64id_t id = lua::tointeger(L, 1); + bool noDelay = lua::toboolean(L, 2); + if (auto connection = network.getConnection(id)) { + if (connection->getTransportType() == network::TransportType::TCP) { + dynamic_cast(connection)->setNoDelay(noDelay); + } + } + return 0; +} + +static int l_get_nodelay(lua::State* L, network::Network& network) { + u64id_t id = lua::tointeger(L, 1); + if (auto connection = network.getConnection(id)) { + if (connection->getTransportType() == network::TransportType::TCP) { + bool noDelay = dynamic_cast(connection)->getNoDelay(); + return lua::pushboolean(L, noDelay); + } + } + return lua::pushboolean(L, false); +} + static int l_pull_events(lua::State* L, network::Network& network) { lua::createtable(L, events_queue.size(), 0); @@ -458,5 +480,7 @@ const luaL_Reg networklib[] = { {"__get_address", wrap}, {"__is_serveropen", wrap}, {"__get_serverport", wrap}, + {"__set_nodelay", wrap}, + {"__get_nodelay", wrap}, {NULL, NULL} }; diff --git a/src/network/Network.cpp b/src/network/Network.cpp index 234197e4..337193ed 100644 --- a/src/network/Network.cpp +++ b/src/network/Network.cpp @@ -329,6 +329,22 @@ public: } } + void setNoDelay(bool noDelay) override { + int opt = noDelay ? 1 : 0; + if (setsockopt(descriptor, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(opt)) < 0) { + throw handle_socket_error("setsockopt(TCP_NODELAY) failed"); + } + } + + bool getNoDelay() const override { + int opt = 0; + socklen_t len = sizeof(opt); + if (getsockopt(descriptor, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, &len) < 0) { + throw handle_socket_error("getsockopt(TCP_NODELAY) failed"); + } + return opt != 0; + } + void startListen() { while (state == ConnectionState::CONNECTED) { int size = recvsocket(descriptor, buffer.data(), buffer.size()); diff --git a/src/network/Network.hpp b/src/network/Network.hpp index ddde70b5..5074bcab 100644 --- a/src/network/Network.hpp +++ b/src/network/Network.hpp @@ -76,6 +76,8 @@ namespace network { virtual void connect(runnable callback) = 0; virtual int recv(char* buffer, size_t length) = 0; virtual int available() = 0; + virtual void setNoDelay(bool noDelay) = 0; + [[nodiscard]] virtual bool getNoDelay() const = 0; [[nodiscard]] TransportType getTransportType() const noexcept override { return TransportType::TCP; From 1f049c2fd04586795a3013a2979064cea5fa002a Mon Sep 17 00:00:00 2001 From: Xertis <118364459+Xertis@users.noreply.github.com> Date: Wed, 1 Oct 2025 01:05:30 +0300 Subject: [PATCH 2/2] change "get" to "is" --- doc/ru/scripting/builtins/libnetwork.md | 2 +- res/scripts/classes.lua | 2 +- src/logic/scripting/lua/libs/libnetwork.cpp | 6 +++--- src/network/Network.cpp | 2 +- src/network/Network.hpp | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/ru/scripting/builtins/libnetwork.md b/doc/ru/scripting/builtins/libnetwork.md index 69fe42d5..bef8967c 100644 --- a/doc/ru/scripting/builtins/libnetwork.md +++ b/doc/ru/scripting/builtins/libnetwork.md @@ -95,7 +95,7 @@ socket:is_connected() --> bool socket:get_address() --> str, int -- Возвращает состояние NoDelay -socket:get_nodelay() --> bool +socket:is_nodelay() --> bool -- Устанавливает состояние NoDelay socket:set_nodelay(state: bool) diff --git a/res/scripts/classes.lua b/res/scripts/classes.lua index d7c93f31..3e102515 100644 --- a/res/scripts/classes.lua +++ b/res/scripts/classes.lua @@ -45,7 +45,7 @@ local Socket = {__index={ is_connected=function(self) return network.__is_connected(self.id) end, get_address=function(self) return network.__get_address(self.id) end, set_nodelay=function(self, nodelay) return network.__set_nodelay(self.id, nodelay or false) end, - get_nodelay=function(self) return network.__get_nodelay(self.id) end, + is_nodelay=function(self) return network.__is_nodelay(self.id) end, }} local WriteableSocket = {__index={ diff --git a/src/logic/scripting/lua/libs/libnetwork.cpp b/src/logic/scripting/lua/libs/libnetwork.cpp index 08542a54..a78f17db 100644 --- a/src/logic/scripting/lua/libs/libnetwork.cpp +++ b/src/logic/scripting/lua/libs/libnetwork.cpp @@ -413,11 +413,11 @@ static int l_set_nodelay(lua::State* L, network::Network& network) { return 0; } -static int l_get_nodelay(lua::State* L, network::Network& network) { +static int l_is_nodelay(lua::State* L, network::Network& network) { u64id_t id = lua::tointeger(L, 1); if (auto connection = network.getConnection(id)) { if (connection->getTransportType() == network::TransportType::TCP) { - bool noDelay = dynamic_cast(connection)->getNoDelay(); + bool noDelay = dynamic_cast(connection)->isNoDelay(); return lua::pushboolean(L, noDelay); } } @@ -540,6 +540,6 @@ const luaL_Reg networklib[] = { {"__is_serveropen", wrap}, {"__get_serverport", wrap}, {"__set_nodelay", wrap}, - {"__get_nodelay", wrap}, + {"__is_nodelay", wrap}, {NULL, NULL} }; diff --git a/src/network/Network.cpp b/src/network/Network.cpp index f999abdf..50534c9b 100644 --- a/src/network/Network.cpp +++ b/src/network/Network.cpp @@ -362,7 +362,7 @@ public: } } - bool getNoDelay() const override { + bool isNoDelay() const override { int opt = 0; socklen_t len = sizeof(opt); if (getsockopt(descriptor, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, &len) < 0) { diff --git a/src/network/Network.hpp b/src/network/Network.hpp index 40c8ed3f..3fec46e0 100644 --- a/src/network/Network.hpp +++ b/src/network/Network.hpp @@ -78,7 +78,7 @@ namespace network { virtual int recv(char* buffer, size_t length) = 0; virtual int available() = 0; virtual void setNoDelay(bool noDelay) = 0; - [[nodiscard]] virtual bool getNoDelay() const = 0; + [[nodiscard]] virtual bool isNoDelay() const = 0; [[nodiscard]] TransportType getTransportType() const noexcept override { return TransportType::TCP;