diff --git a/doc/09-object-types.md b/doc/09-object-types.md index f24a35b8d..841e1cf58 100644 --- a/doc/09-object-types.md +++ b/doc/09-object-types.md @@ -1102,7 +1102,8 @@ Configuration Attributes: max\_anonymous\_clients | Number | **Optional.** Limit the number of anonymous client connections (not configured endpoints and signing requests). cipher\_list | String | **Optional.** Cipher list that is allowed. For a list of available ciphers run `openssl ciphers`. Defaults to `ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:AES256-GCM-SHA384:AES128-GCM-SHA256`. tls\_protocolmin | String | **Optional.** Minimum TLS protocol version. Since v2.11, only `TLSv1.2` is supported. Defaults to `TLSv1.2`. - tls\_handshake\_timeout | Number | **Optional.** TLS Handshake timeout. Defaults to `10s`. + tls\_handshake\_timeout | Number | **Deprecated.** TLS Handshake timeout. Defaults to `10s`. + connect\_timeout | Number | **Optional.** Timeout for establishing new connections. Affects both incoming and outgoing connections. Within this time, the TCP and TLS handshakes must complete and either a HTTP request or an Icinga cluster connection must be initiated. Defaults to `15s`. access\_control\_allow\_origin | Array | **Optional.** Specifies an array of origin URLs that may access the API. [(MDN docs)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Access-Control-Allow-Origin) access\_control\_allow\_credentials | Boolean | **Deprecated.** Indicates whether or not the actual request can be made using credentials. Defaults to `true`. [(MDN docs)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Access-Control-Allow-Credentials) access\_control\_allow\_headers | String | **Deprecated.** Used in response to a preflight request to indicate which HTTP headers can be used when making the actual request. Defaults to `Authorization`. [(MDN docs)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Access-Control-Allow-Headers) diff --git a/lib/remote/apilistener.cpp b/lib/remote/apilistener.cpp index 166a60824..d9c5d6781 100644 --- a/lib/remote/apilistener.cpp +++ b/lib/remote/apilistener.cpp @@ -460,7 +460,21 @@ void ApiListener::ListenerCoroutineProc(boost::asio::yield_context yc, const Sha auto strand (Shared::Make(io)); - IoEngine::SpawnCoroutine(*strand, [this, strand, sslConn](asio::yield_context yc) { NewClientHandler(yc, strand, sslConn, String(), RoleServer); }); + IoEngine::SpawnCoroutine(*strand, [this, strand, sslConn](asio::yield_context yc) { + Timeout::Ptr timeout(new Timeout(strand->context(), *strand, boost::posix_time::microseconds(int64_t(GetConnectTimeout() * 1e6)), + [sslConn](asio::yield_context yc) { + Log(LogWarning, "ApiListener") + << "Timeout while processing incoming connection from " + << sslConn->lowest_layer().remote_endpoint(); + + boost::system::error_code ec; + sslConn->lowest_layer().cancel(ec); + } + )); + Defer cancelTimeout([timeout]() { timeout->Cancel(); }); + + NewClientHandler(yc, strand, sslConn, String(), RoleServer); + }); } catch (const std::exception& ex) { Log(LogCritical, "ApiListener") << "Cannot accept new connection: " << ex.what(); @@ -496,6 +510,18 @@ void ApiListener::AddConnection(const Endpoint::Ptr& endpoint) try { auto sslConn (Shared::Make(io, *m_SSLContext, endpoint->GetName())); + Timeout::Ptr timeout(new Timeout(strand->context(), *strand, boost::posix_time::microseconds(int64_t(GetConnectTimeout() * 1e6)), + [sslConn, endpoint, host, port](asio::yield_context yc) { + Log(LogCritical, "ApiListener") + << "Timeout while reconnecting to endpoint '" << endpoint->GetName() << "' via host '" << host + << "' and port '" << port << "', cancelling attempt"; + + boost::system::error_code ec; + sslConn->lowest_layer().cancel(ec); + } + )); + Defer cancelTimeout([&timeout]() { timeout->Cancel(); }); + Connect(sslConn->lowest_layer(), host, port, yc); NewClientHandler(yc, strand, sslConn, endpoint->GetName(), RoleClient); diff --git a/lib/remote/apilistener.ti b/lib/remote/apilistener.ti index ede50b606..c3bdd9371 100644 --- a/lib/remote/apilistener.ti +++ b/lib/remote/apilistener.ti @@ -37,12 +37,16 @@ class ApiListener : ConfigObject default {{{ return -1; }}} }; - [config] double tls_handshake_timeout { + [config, deprecated] double tls_handshake_timeout { get; set; default {{{ return Configuration::TlsHandshakeTimeout; }}} }; + [config] double connect_timeout { + default {{{ return 15.0; }}} + }; + [config] String ticket_salt; [config] Array::Ptr access_control_allow_origin;