loolwsd/LOOLWSD.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ loolwsd/LOOLWSD.hpp | 2 ++ loolwsd/UserMessages.hpp | 1 + loolwsd/configure.ac | 20 ++++++++++++++++++++ 4 files changed, 64 insertions(+)
New commits: commit f52fa89036de03d955f64db721ac2f1565f48273 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> Date: Wed Jul 13 22:01:23 2016 -0400 Build-time configurable WSD limits The server can now be configured at build time to limit the total number of connections and/or the number of open documents, at a given time. ./configure --with-max-documents=10 --with-max-connections=20 will limit the number of documents to 10 and total number of connections (on one or all documents) to 20. Change-Id: I0c73a7e906c4f567cb3da480e885524815c9cc89 Reviewed-on: https://gerrit.libreoffice.org/27203 Reviewed-by: Ashod Nakashian <ashnak...@gmail.com> Tested-by: Ashod Nakashian <ashnak...@gmail.com> diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp index bcf70a0..20f1756 100644 --- a/loolwsd/LOOLWSD.cpp +++ b/loolwsd/LOOLWSD.cpp @@ -594,6 +594,15 @@ private: throw WebSocketErrorMessageException(SERVICE_UNAVALABLE_INTERNAL_ERROR); } +#if MAX_DOCUMENTS > 0 + if (++LOOLWSD::NumDocBrokers > MAX_DOCUMENTS) + { + --LOOLWSD::NumDocBrokers; + Log::error("Maximum number of open documents reached."); + throw WebSocketErrorMessageException(SERVICE_UNAVALABLE_LIMIT_REACHED); + } +#endif + // Set one we just created. Log::debug("New DocumentBroker for docKey [" + docKey + "]."); docBroker = std::make_shared<DocumentBroker>(uriPublic, docKey, LOOLWSD::ChildRoot, child); @@ -609,6 +618,9 @@ private: // Remove. std::unique_lock<std::mutex> lock(docBrokersMutex); docBrokers.erase(docKey); +#if MAX_DOCUMENTS > 0 + --LOOLWSD::NumDocBrokers; +#endif } throw WebSocketErrorMessageException(SERVICE_UNAVALABLE_INTERNAL_ERROR); @@ -723,6 +735,9 @@ private: std::unique_lock<std::mutex> docBrokersLock(docBrokersMutex); Log::debug("Removing DocumentBroker for docKey [" + docKey + "]."); docBrokers.erase(docKey); +#if MAX_DOCUMENTS > 0 + --LOOLWSD::NumDocBrokers; +#endif Log::info("Removing complete doc [" + docKey + "] from Admin."); Admin::instance().rmDoc(docKey); } @@ -810,7 +825,20 @@ public: request, response)) return; +#if MAX_CONNECTIONS > 0 + if (++LOOLWSD::NumConnections > MAX_CONNECTIONS) + { + --LOOLWSD::NumConnections; + Log::error("Maximum number of connections reached."); + throw WebSocketErrorMessageException(SERVICE_UNAVALABLE_LIMIT_REACHED); + } +#endif + handleClientRequest(request,response); + +#if MAX_CONNECTIONS > 0 + --LOOLWSD::NumConnections; +#endif } static void handleClientRequest(HTTPServerRequest& request, HTTPServerResponse& response) @@ -1197,6 +1225,8 @@ bool LOOLWSD::SSLEnabled = static std::string UnitTestLibrary; unsigned int LOOLWSD::NumPreSpawnedChildren = 0; +std::atomic<unsigned> LOOLWSD::NumDocBrokers; +std::atomic<unsigned> LOOLWSD::NumConnections; class AppConfigMap : public Poco::Util::MapConfiguration { @@ -1293,6 +1323,17 @@ void LOOLWSD::initialize(Application& self) setenv("MAX_CONCURRENCY", std::to_string(maxConcurrency).c_str(), 1); } + // In Trial Versions we might want to set some limits. + LOOLWSD::NumDocBrokers = 0; + LOOLWSD::NumConnections = 0; + Log::info() << "Open Documents Limit: " << (MAX_DOCUMENTS > 0 ? + std::to_string(MAX_DOCUMENTS) : + std::string("unlimited")) << Log::end; + + Log::info() << "Client Connections Limit: " << (MAX_CONNECTIONS > 0 ? + std::to_string(MAX_CONNECTIONS) : + std::string("unlimited")) << Log::end; + StorageBase::initialize(); ServerApplication::initialize(self); diff --git a/loolwsd/LOOLWSD.hpp b/loolwsd/LOOLWSD.hpp index 76e942e..b750bda 100644 --- a/loolwsd/LOOLWSD.hpp +++ b/loolwsd/LOOLWSD.hpp @@ -44,6 +44,8 @@ public: static std::string FileServerRoot; static std::string LOKitVersion; static bool SSLEnabled; + static std::atomic<unsigned> NumDocBrokers; + static std::atomic<unsigned> NumConnections; static std::string GenSessionId() diff --git a/loolwsd/UserMessages.hpp b/loolwsd/UserMessages.hpp index 93e3e57..5208b09 100644 --- a/loolwsd/UserMessages.hpp +++ b/loolwsd/UserMessages.hpp @@ -13,6 +13,7 @@ #define INCLUDED_USERMESSAGES_HPP constexpr auto SERVICE_UNAVALABLE_INTERNAL_ERROR = "Service is unavailable. Please try again later and report to your administrator if the issue persists."; +constexpr auto SERVICE_UNAVALABLE_LIMIT_REACHED = "This server has reached the number of connections or documents it supports at a given time."; #endif diff --git a/loolwsd/configure.ac b/loolwsd/configure.ac index 3b01637..4f2565e 100644 --- a/loolwsd/configure.ac +++ b/loolwsd/configure.ac @@ -80,6 +80,14 @@ AC_ARG_ENABLE([ssl], AS_HELP_STRING([--disable-ssl], [Compile without SSL support])) +AC_ARG_WITH([max-documents], + AS_HELP_STRING([--max-documents], + [Compile with a hard-coded limit on the number of documents])) + +AC_ARG_WITH([max-connections], + AS_HELP_STRING([--max-connections], + [Compile with a hard-coded limit on the total number of client connections])) + # Handle options AS_IF([test "$enable_debug" = yes -a -n "$with_poco_libs"], [POCO_DEBUG_SUFFIX=d], @@ -96,6 +104,18 @@ else fi AC_SUBST(ENABLE_DEBUG) +MAX_DOCUMENTS=0 +AS_IF([test -n "$with_max_documents"], + [MAX_DOCUMENTS="$with_max_documents"]) +AC_DEFINE_UNQUOTED([MAX_DOCUMENTS],[$MAX_DOCUMENTS],[Limit the maximum number of open documents]) +AC_SUBST(MAX_DOCUMENTS) + +MAX_CONNECTIONS=0 +AS_IF([test -n "$with_max_connections"], + [MAX_CONNECTIONS="$with_max_connections"]) +AC_DEFINE_UNQUOTED([MAX_CONNECTIONS],[$MAX_CONNECTIONS],[Limit the maximum number of open documents]) +AC_SUBST(MAX_CONNECTIONS) + # Test for build environment CXXFLAGS="$CXXFLAGS -std=c++11" _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits