From 32da4d781929d9e5334348b3d01a6103a34009cd Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Mon, 8 Jul 2019 08:52:25 +0200 Subject: [PATCH] Add TCP connect timeout. Default timeout is 30 seconds (i.e. after 30 seconds of calling connect_to_host if the TCP peer is not connected the connection will error out). This value can be configured in project settings: `network/limits/tcp/connect_timeout_seconds` --- core/io/stream_peer_tcp.cpp | 12 ++++++++++++ core/io/stream_peer_tcp.h | 1 + core/register_core_types.cpp | 2 ++ 3 files changed, 15 insertions(+) diff --git a/core/io/stream_peer_tcp.cpp b/core/io/stream_peer_tcp.cpp index a8dd263484f..310bb12bc0d 100644 --- a/core/io/stream_peer_tcp.cpp +++ b/core/io/stream_peer_tcp.cpp @@ -30,6 +30,8 @@ #include "stream_peer_tcp.h" +#include "core/project_settings.h" + Error StreamPeerTCP::_poll_connection() { ERR_FAIL_COND_V(status != STATUS_CONNECTING || !_sock.is_valid() || !_sock->is_open(), FAILED); @@ -40,6 +42,12 @@ Error StreamPeerTCP::_poll_connection() { status = STATUS_CONNECTED; return OK; } else if (err == ERR_BUSY) { + // Check for connect timeout + if (OS::get_singleton()->get_ticks_msec() > timeout) { + disconnect_from_host(); + status = STATUS_ERROR; + return ERR_CONNECTION_ERROR; + } // Still trying to connect return OK; } @@ -54,6 +62,7 @@ void StreamPeerTCP::accept_socket(Ref p_sock, IP_Address p_host, uint _sock = p_sock; _sock->set_blocking_enabled(false); + timeout = OS::get_singleton()->get_ticks_msec() + (((uint64_t)GLOBAL_GET("network/limits/tcp/connect_timeout_seconds")) * 1000); status = STATUS_CONNECTING; peer_host = p_host; @@ -74,6 +83,7 @@ Error StreamPeerTCP::connect_to_host(const IP_Address &p_host, uint16_t p_port) _sock->set_blocking_enabled(false); + timeout = OS::get_singleton()->get_ticks_msec() + (((uint64_t)GLOBAL_GET("network/limits/tcp/connect_timeout_seconds")) * 1000); err = _sock->connect_to_host(p_host, p_port); if (err == OK) { @@ -281,6 +291,7 @@ void StreamPeerTCP::disconnect_from_host() { if (_sock.is_valid() && _sock->is_open()) _sock->close(); + timeout = 0; status = STATUS_NONE; peer_host = IP_Address(); peer_port = 0; @@ -356,6 +367,7 @@ void StreamPeerTCP::_bind_methods() { StreamPeerTCP::StreamPeerTCP() : _sock(Ref(NetSocket::create())), + timeout(0), status(STATUS_NONE), peer_port(0) { } diff --git a/core/io/stream_peer_tcp.h b/core/io/stream_peer_tcp.h index 1ca39375aab..321fb3a6c8a 100644 --- a/core/io/stream_peer_tcp.h +++ b/core/io/stream_peer_tcp.h @@ -52,6 +52,7 @@ public: protected: Ref _sock; + uint64_t timeout; Status status; IP_Address peer_host; uint16_t peer_port; diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index 11cd07042f6..e4425461240 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -207,6 +207,8 @@ void register_core_types() { void register_core_settings() { //since in register core types, globals may not e present + GLOBAL_DEF("network/limits/tcp/connect_timeout_seconds", (30)); + ProjectSettings::get_singleton()->set_custom_property_info("network/limits/tcp/connect_timeout_seconds", PropertyInfo(Variant::INT, "network/limits/tcp/connect_timeout_seconds", PROPERTY_HINT_RANGE, "1,1800,1")); GLOBAL_DEF_RST("network/limits/packet_peer_stream/max_buffer_po2", (16)); ProjectSettings::get_singleton()->set_custom_property_info("network/limits/packet_peer_stream/max_buffer_po2", PropertyInfo(Variant::INT, "network/limits/packet_peer_stream/max_buffer_po2", PROPERTY_HINT_RANGE, "0,64,1,or_greater")); }