From 458437edef19bc4ddcb0a5a9b41d337a33471398 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Mon, 28 Jun 2021 14:31:15 +0200 Subject: [PATCH] [Net] Add WebSocketServer handshake_timeout property. Allows customization of the maximum time a client is allowed to stay in the the "pending" state (i.e. awaiting HTTP handshake). This used to be 1 second by before, the new default is 3 seconds. --- modules/websocket/doc_classes/WebSocketServer.xml | 3 +++ modules/websocket/websocket_server.cpp | 13 +++++++++++++ modules/websocket/websocket_server.h | 4 ++++ modules/websocket/wsl_server.cpp | 6 +++--- modules/websocket/wsl_server.h | 4 +--- 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/modules/websocket/doc_classes/WebSocketServer.xml b/modules/websocket/doc_classes/WebSocketServer.xml index 78f28327704..7bc0d64718f 100644 --- a/modules/websocket/doc_classes/WebSocketServer.xml +++ b/modules/websocket/doc_classes/WebSocketServer.xml @@ -89,6 +89,9 @@ When using SSL (see [member private_key] and [member ssl_certificate]), you can set this to a valid [X509Certificate] to be provided as additional CA chain information during the SSL handshake. + + The time in seconds before a pending client (i.e. a client that has not yet finished the HTTP handshake) is considered stale and forcefully disconnected. + When set to a valid [CryptoKey] (along with [member ssl_certificate]) will cause the server to require SSL instead of regular TCP (i.e. the [code]wss://[/code] protocol). diff --git a/modules/websocket/websocket_server.cpp b/modules/websocket/websocket_server.cpp index dfe44716593..9b2d04f14f0 100644 --- a/modules/websocket/websocket_server.cpp +++ b/modules/websocket/websocket_server.cpp @@ -65,6 +65,10 @@ void WebSocketServer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_ca_chain"), &WebSocketServer::set_ca_chain); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "ca_chain", PROPERTY_HINT_RESOURCE_TYPE, "X509Certificate", PROPERTY_USAGE_NONE), "set_ca_chain", "get_ca_chain"); + ClassDB::bind_method(D_METHOD("get_handshake_timeout"), &WebSocketServer::get_handshake_timeout); + ClassDB::bind_method(D_METHOD("set_handshake_timeout", "timeout"), &WebSocketServer::set_handshake_timeout); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "handshake_timeout"), "set_handshake_timeout", "get_handshake_timeout"); + ADD_SIGNAL(MethodInfo("client_close_request", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::INT, "code"), PropertyInfo(Variant::STRING, "reason"))); ADD_SIGNAL(MethodInfo("client_disconnected", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::BOOL, "was_clean_close"))); ADD_SIGNAL(MethodInfo("client_connected", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::STRING, "protocol"))); @@ -108,6 +112,15 @@ void WebSocketServer::set_ca_chain(Ref p_ca_chain) { ca_chain = p_ca_chain; } +float WebSocketServer::get_handshake_timeout() const { + return handshake_timeout / 1000.0; +} + +void WebSocketServer::set_handshake_timeout(float p_timeout) { + ERR_FAIL_COND(p_timeout <= 0.0); + handshake_timeout = p_timeout * 1000; +} + NetworkedMultiplayerPeer::ConnectionStatus WebSocketServer::get_connection_status() const { if (is_listening()) { return CONNECTION_CONNECTED; diff --git a/modules/websocket/websocket_server.h b/modules/websocket/websocket_server.h index bc5e591e7b1..26864f3085a 100644 --- a/modules/websocket/websocket_server.h +++ b/modules/websocket/websocket_server.h @@ -48,6 +48,7 @@ protected: Ref private_key; Ref ssl_cert; Ref ca_chain; + uint32_t handshake_timeout = 3000; public: virtual Error listen(int p_port, const Vector p_protocols = Vector(), bool gd_mp_api = false) = 0; @@ -78,6 +79,9 @@ public: Ref get_ca_chain() const; void set_ca_chain(Ref p_ca_chain); + float get_handshake_timeout() const; + void set_handshake_timeout(float p_timeout); + WebSocketServer(); ~WebSocketServer(); }; diff --git a/modules/websocket/wsl_server.cpp b/modules/websocket/wsl_server.cpp index 22bb1b6d1a0..ccdb6e92924 100644 --- a/modules/websocket/wsl_server.cpp +++ b/modules/websocket/wsl_server.cpp @@ -95,8 +95,8 @@ bool WSLServer::PendingPeer::_parse_request(const Vector p_protocols) { return true; } -Error WSLServer::PendingPeer::do_handshake(const Vector p_protocols) { - if (OS::get_singleton()->get_ticks_msec() - time > WSL_SERVER_TIMEOUT) { +Error WSLServer::PendingPeer::do_handshake(const Vector p_protocols, uint64_t p_timeout) { + if (OS::get_singleton()->get_ticks_msec() - time > p_timeout) { return ERR_TIMEOUT; } if (use_ssl) { @@ -188,7 +188,7 @@ void WSLServer::poll() { List> remove_peers; for (List>::Element *E = _pending.front(); E; E = E->next()) { Ref ppeer = E->get(); - Error err = ppeer->do_handshake(_protocols); + Error err = ppeer->do_handshake(_protocols, handshake_timeout); if (err == ERR_BUSY) { continue; } else if (err != OK) { diff --git a/modules/websocket/wsl_server.h b/modules/websocket/wsl_server.h index 39177a16a8f..a428c89f4f5 100644 --- a/modules/websocket/wsl_server.h +++ b/modules/websocket/wsl_server.h @@ -40,8 +40,6 @@ #include "core/io/stream_peer_tcp.h" #include "core/io/tcp_server.h" -#define WSL_SERVER_TIMEOUT 1000 - class WSLServer : public WebSocketServer { GDCIIMPL(WSLServer, WebSocketServer); @@ -64,7 +62,7 @@ private: CharString response; int response_sent = 0; - Error do_handshake(const Vector p_protocols); + Error do_handshake(const Vector p_protocols, uint64_t p_timeout); }; int _in_buf_size = DEF_BUF_SHIFT;