From 7c891eb8410b4f90f71856773a53130a9f62b644 Mon Sep 17 00:00:00 2001 From: proller Date: Fri, 28 Apr 2017 00:51:09 +0300 Subject: [PATCH] Server: Special mode with empty listen_host : try listen v4 and v6 (#730) * Server: Special mode with empty listen_host : try listen v4 and v6 without fatal error if protocol not supported (for docker and freebsd) * fix build on freebsd/macos * Requested change * Update Server.cpp * Update Server.cpp * Fix deadlock when queue_log queue is full * Add log error on query log fail * Fix incudes, move code from daemon/OwnPatternFormatter.h * Update SystemLog.h * Update SystemLog.h * Auto version update to [54230] * Catch only "Protocol not supported" listen error * Update Server.cpp --- dbms/src/Server/Server.cpp | 132 ++++++++++++++++++++----------------- 1 file changed, 73 insertions(+), 59 deletions(-) diff --git a/dbms/src/Server/Server.cpp b/dbms/src/Server/Server.cpp index 1554cbf883..93e1fdfdd2 100644 --- a/dbms/src/Server/Server.cpp +++ b/dbms/src/Server/Server.cpp @@ -443,10 +443,12 @@ int Server::main(const std::vector & args) listen_hosts.emplace_back(config().getString(key)); } + bool try_listen = false; if (listen_hosts.empty()) { listen_hosts.emplace_back("::1"); listen_hosts.emplace_back("127.0.0.1"); + try_listen = true; } auto make_socket_address = [&](const std::string & host, std::uint16_t port) { @@ -479,76 +481,88 @@ int Server::main(const std::vector & args) for (const auto & listen_host : listen_hosts) { /// For testing purposes, user may omit tcp_port or http_port or https_port in configuration file. - - /// HTTP - if (config().has("http_port")) + try { - Poco::Net::SocketAddress http_socket_address = make_socket_address(listen_host, config().getInt("http_port")); - Poco::Net::ServerSocket http_socket(http_socket_address); - http_socket.setReceiveTimeout(settings.receive_timeout); - http_socket.setSendTimeout(settings.send_timeout); + /// HTTP + if (config().has("http_port")) + { + Poco::Net::SocketAddress http_socket_address = make_socket_address(listen_host, config().getInt("http_port")); + Poco::Net::ServerSocket http_socket(http_socket_address); + http_socket.setReceiveTimeout(settings.receive_timeout); + http_socket.setSendTimeout(settings.send_timeout); - servers.emplace_back(new Poco::Net::HTTPServer( - new HTTPRequestHandlerFactory(*this, "HTTPHandler-factory"), server_pool, http_socket, http_params)); + servers.emplace_back(new Poco::Net::HTTPServer( + new HTTPRequestHandlerFactory(*this, "HTTPHandler-factory"), server_pool, http_socket, http_params)); - LOG_INFO(log, "Listening http://" + http_socket_address.toString()); - } - - /// HTTPS - if (config().has("https_port")) - { -#if Poco_NetSSL_FOUND - std::call_once(ssl_init_once, SSLInit); - Poco::Net::SocketAddress http_socket_address = make_socket_address(listen_host, config().getInt("https_port")); - Poco::Net::SecureServerSocket http_socket(http_socket_address); - http_socket.setReceiveTimeout(settings.receive_timeout); - http_socket.setSendTimeout(settings.send_timeout); - - servers.emplace_back(new Poco::Net::HTTPServer( - new HTTPRequestHandlerFactory(*this, "HTTPHandler-factory"), server_pool, http_socket, http_params)); - - LOG_INFO(log, "Listening https://" + http_socket_address.toString()); -#else - throw Exception{"https protocol disabled because poco library built without NetSSL support.", - ErrorCodes::SUPPORT_IS_DISABLED}; -#endif - } + LOG_INFO(log, "Listening http://" + http_socket_address.toString()); + } - /// TCP - if (config().has("tcp_port")) - { - Poco::Net::SocketAddress tcp_address = make_socket_address(listen_host, config().getInt("tcp_port")); - Poco::Net::ServerSocket tcp_socket(tcp_address); - tcp_socket.setReceiveTimeout(settings.receive_timeout); - tcp_socket.setSendTimeout(settings.send_timeout); - servers.emplace_back( - new Poco::Net::TCPServer(new TCPConnectionFactory(*this), server_pool, tcp_socket, new Poco::Net::TCPServerParams)); - - LOG_INFO(log, "Listening tcp: " + tcp_address.toString()); - } + /// HTTPS + if (config().has("https_port")) + { + #if Poco_NetSSL_FOUND + std::call_once(ssl_init_once, SSLInit); + Poco::Net::SocketAddress http_socket_address = make_socket_address(listen_host, config().getInt("https_port")); + Poco::Net::SecureServerSocket http_socket(http_socket_address); + http_socket.setReceiveTimeout(settings.receive_timeout); + http_socket.setSendTimeout(settings.send_timeout); + + servers.emplace_back(new Poco::Net::HTTPServer( + new HTTPRequestHandlerFactory(*this, "HTTPHandler-factory"), server_pool, http_socket, http_params)); + + LOG_INFO(log, "Listening https://" + http_socket_address.toString()); + #else + throw Exception{"https protocol disabled because poco library built without NetSSL support.", + ErrorCodes::SUPPORT_IS_DISABLED}; + #endif + } + /// TCP + if (config().has("tcp_port")) + { + Poco::Net::SocketAddress tcp_address = make_socket_address(listen_host, config().getInt("tcp_port")); + Poco::Net::ServerSocket tcp_socket(tcp_address); + tcp_socket.setReceiveTimeout(settings.receive_timeout); + tcp_socket.setSendTimeout(settings.send_timeout); + servers.emplace_back( + new Poco::Net::TCPServer(new TCPConnectionFactory(*this), server_pool, tcp_socket, new Poco::Net::TCPServerParams)); + + LOG_INFO(log, "Listening tcp: " + tcp_address.toString()); + } - /// At least one of TCP and HTTP servers must be created. - if (servers.empty()) - throw Exception("No 'tcp_port' and 'http_port' is specified in configuration file.", ErrorCodes::NO_ELEMENTS_IN_CONFIG); + /// At least one of TCP and HTTP servers must be created. + if (servers.empty()) + throw Exception("No 'tcp_port' and 'http_port' is specified in configuration file.", ErrorCodes::NO_ELEMENTS_IN_CONFIG); - /// Interserver IO HTTP - if (config().has("interserver_http_port")) + /// Interserver IO HTTP + if (config().has("interserver_http_port")) + { + Poco::Net::SocketAddress interserver_address = make_socket_address(listen_host, config().getInt("interserver_http_port")); + Poco::Net::ServerSocket interserver_io_http_socket(interserver_address); + interserver_io_http_socket.setReceiveTimeout(settings.receive_timeout); + interserver_io_http_socket.setSendTimeout(settings.send_timeout); + servers.emplace_back(new Poco::Net::HTTPServer( + new HTTPRequestHandlerFactory(*this, "InterserverIOHTTPHandler-factory"), + server_pool, + interserver_io_http_socket, + http_params)); + + LOG_INFO(log, "Listening interserver: " + interserver_address.toString()); + } + } + catch (const Poco::Net::NetException & e) { - Poco::Net::SocketAddress interserver_address = make_socket_address(listen_host, config().getInt("interserver_http_port")); - Poco::Net::ServerSocket interserver_io_http_socket(interserver_address); - interserver_io_http_socket.setReceiveTimeout(settings.receive_timeout); - interserver_io_http_socket.setSendTimeout(settings.send_timeout); - servers.emplace_back(new Poco::Net::HTTPServer( - new HTTPRequestHandlerFactory(*this, "InterserverIOHTTPHandler-factory"), - server_pool, - interserver_io_http_socket, - http_params)); - - LOG_INFO(log, "Listening interserver: " + interserver_address.toString()); + if (try_listen && e.code() == POCO_EPROTONOSUPPORT) + LOG_ERROR(log, "Listen [" << listen_host << "]: " << e.what() << ": " << e.message()); + else + throw; } + } + if (servers.empty()) + throw Exception("No servers started (add valid listen_host and 'tcp_port' or 'http_port' to configuration file.)", ErrorCodes::NO_ELEMENTS_IN_CONFIG); + for (auto & server : servers) server->start(); -- GitLab