diff --git a/file/include/files/FileServer.h b/file/include/files/FileServer.h index 6c084b3..929b87d 100644 --- a/file/include/files/FileServer.h +++ b/file/include/files/FileServer.h @@ -413,7 +413,7 @@ namespace ts::server::file { std::deque> servers_{}; }; - extern bool initialize(std::string& /* error */); + extern bool initialize(std::string& /* error */, const std::string& /* host names */, uint16_t /* port */); extern void finalize(); extern std::shared_ptr server(); diff --git a/file/local_server/LocalFileProvider.cpp b/file/local_server/LocalFileProvider.cpp index 9250b2f..074a745 100644 --- a/file/local_server/LocalFileProvider.cpp +++ b/file/local_server/LocalFileProvider.cpp @@ -3,6 +3,7 @@ // #include +#include #include "LocalFileProvider.h" using namespace ts::server; @@ -10,13 +11,80 @@ using LocalFileServer = file::LocalFileProvider; using LocalVirtualFileServer = file::LocalVirtualFileServer; std::shared_ptr server_instance{}; -bool file::initialize(std::string &error) { +bool file::initialize(std::string &error, const std::string& hostnames, uint16_t port) { server_instance = std::make_shared(); if(!server_instance->initialize(error)) { server_instance = nullptr; return false; } + + bool any_bind{false}; + for(const auto& binding : net::resolve_bindings(hostnames, port)) { + if(!get<2>(binding).empty()) { + logError(LOG_FT, "Failed to resolve binding for {}: {}", get<0>(binding), get<2>(binding)); + continue; + } + + auto result = dynamic_cast(server_instance->file_transfer()).add_network_binding({ get<0>(binding), get<1>(binding) }); + switch (result) { + case transfer::NetworkingBindResult::SUCCESS: + any_bind = true; + break; + + case transfer::NetworkingBindResult::OUT_OF_MEMORY: + logWarning(LOG_FT, "Failed to listen to address {}: Out of memory", get<0>(binding)); + continue; + + case transfer::NetworkingBindResult::FAILED_TO_LISTEN: + logWarning(LOG_FT, "Failed to listen on {}: {}/{}", get<0>(binding), errno, strerror(errno)); + continue; + + case transfer::NetworkingBindResult::FAILED_TO_BIND: + logWarning(LOG_FT, "Failed to bind on {}: {}/{}", get<0>(binding), errno, strerror(errno)); + continue; + + case transfer::NetworkingBindResult::BINDING_ALREADY_EXISTS: + logWarning(LOG_FT, "Failed to bind on {}: binding already exists", get<0>(binding)); + continue; + + case transfer::NetworkingBindResult::NETWORKING_NOT_INITIALIZED: + logWarning(LOG_FT, "Failed to bind on {}: networking not initialized", get<0>(binding)); + continue; + + case transfer::NetworkingBindResult::FAILED_TO_ALLOCATE_SOCKET: + logWarning(LOG_FT, "Failed to allocate a socket for {}: {}/{}", get<0>(binding), errno, strerror(errno)); + continue; + } + } +#if 0 + { + auto query_bindings_string = this->properties()[property::SERVERINSTANCE_QUERY_HOST].as(); + auto query_port = this->properties()[property::SERVERINSTANCE_QUERY_PORT].as(); + auto query_bindings = net::resolve_bindings(query_bindings_string, query_port); + deque> bindings; + + for(auto& binding : query_bindings) { + if(!get<2>(binding).empty()) { + logError(LOG_QUERY, "Failed to resolve binding for {}: {}", get<0>(binding), get<2>(binding)); + continue; + } + auto entry = make_shared(); + memcpy(&entry->address, &get<1>(binding), sizeof(sockaddr_storage)); + + entry->file_descriptor = -1; + entry->event_accept = nullptr; + bindings.push_back(entry); + } + + logMessage(LOG_QUERY, "Starting server on {}:{}", query_bindings_string, query_port); + if(!queryServer->start(bindings, errorMessage)) { + logCritical(LOG_QUERY, "Failed to start query server: {}", errorMessage); + return false; + } + } +#endif + return true; } @@ -32,28 +100,13 @@ std::shared_ptr file::server() { } LocalFileServer::LocalFileProvider() : file_system_{}, file_transfer_{this->file_system_} {} -LocalFileServer::~LocalFileProvider() {} +LocalFileServer::~LocalFileProvider() = default; bool LocalFileServer::initialize(std::string &error) { if(!this->file_system_.initialize(error, "files/")) return false; - - std::deque> bindings{}; - { - auto binding = std::make_shared(); - - binding->hostname = "0.0.0.0"; - - auto& iaddr = *(sockaddr_in*) &binding->address; - iaddr.sin_family = AF_INET; - iaddr.sin_port = htons(30303); - iaddr.sin_addr.s_addr = INADDR_ANY; - - bindings.push_back(std::move(binding)); - } - - if(!this->file_transfer_.start(bindings)) { + if(!this->file_transfer_.start()) { error = "transfer server startup failed"; this->file_system_.finalize(); return false; diff --git a/file/local_server/LocalFileProvider.h b/file/local_server/LocalFileProvider.h index 22af126..88d8a9e 100644 --- a/file/local_server/LocalFileProvider.h +++ b/file/local_server/LocalFileProvider.h @@ -11,6 +11,7 @@ #include #include #include +#include #include "./NetTools.h" #define TRANSFER_MAX_CACHED_BYTES (1024 * 1024 * 1) // Buffer up to 1mb @@ -243,7 +244,7 @@ namespace ts::server::file { std::chrono::system_clock::time_point disconnecting{}; } timings; - explicit FileClient(LocalFileTransfer* handle) : handle{handle} {} + explicit FileClient(LocalFileTransfer* handle) : handle{handle} { memtrack::allocated(this); } ~FileClient(); void add_network_write_event(bool /* ignore bandwidth limits */); @@ -270,8 +271,24 @@ namespace ts::server::file { enum struct NetworkingStartResult { SUCCESS, + OUT_OF_MEMORY + }; + + enum struct NetworkingBindResult { + SUCCESS, + + BINDING_ALREADY_EXISTS, + NETWORKING_NOT_INITIALIZED, + FAILED_TO_ALLOCATE_SOCKET, /* errno is set */ + FAILED_TO_BIND, + FAILED_TO_LISTEN, + OUT_OF_MEMORY, - NO_BINDINGS + }; + + enum struct NetworkingUnbindResult { + SUCCESS, + UNKNOWN_BINDING }; enum struct ClientWorkerStartResult { @@ -364,7 +381,12 @@ namespace ts::server::file { /* UNKNOWN ERROR */ }; - struct NetworkBinding : std::enable_shared_from_this { + struct NetworkBinding { + std::string hostname{}; + sockaddr_storage address{}; + }; + + struct ActiveNetworkBinding : std::enable_shared_from_this { std::string hostname{}; sockaddr_storage address{}; @@ -379,9 +401,13 @@ namespace ts::server::file { explicit LocalFileTransfer(filesystem::LocalFileSystem&); ~LocalFileTransfer(); - [[nodiscard]] bool start(const std::deque>& /* bindings */); + [[nodiscard]] bool start(); void stop(); + [[nodiscard]] NetworkingBindResult add_network_binding(const NetworkBinding& /* binding */); + [[nodiscard]] std::vector active_network_bindings(); + [[nodiscard]] NetworkingUnbindResult remove_network_binding(const NetworkBinding& /* binding */); + std::shared_ptr>> initialize_channel_transfer(Transfer::Direction direction, const std::shared_ptr& server, ChannelId channelId, const TransferInfo &info) override; @@ -430,11 +456,13 @@ namespace ts::server::file { } disconnect; struct { + std::mutex mutex; + bool active{false}; std::thread dispatch_thread{}; struct event_base* event_base{nullptr}; - std::deque> bindings{}; + std::deque> bindings{}; } network{}; struct { diff --git a/file/local_server/LocalFileTransfer.cpp b/file/local_server/LocalFileTransfer.cpp index 0a19d1e..505a1da 100644 --- a/file/local_server/LocalFileTransfer.cpp +++ b/file/local_server/LocalFileTransfer.cpp @@ -7,7 +7,6 @@ #include #include #include "./LocalFileProvider.h" -#include "LocalFileProvider.h" #include namespace fs = std::experimental::filesystem; @@ -42,12 +41,13 @@ FileClient::~FileClient() { assert(!this->networking.event_write); assert(this->state == STATE_DISCONNECTED); + memtrack::freed(this); } LocalFileTransfer::LocalFileTransfer(filesystem::LocalFileSystem &fs) : file_system_{fs} {} LocalFileTransfer::~LocalFileTransfer() = default; -bool LocalFileTransfer::start(const std::deque>& bindings) { +bool LocalFileTransfer::start() { (void) this->start_client_worker(); { @@ -66,17 +66,15 @@ bool LocalFileTransfer::start(const std::deque>& { - this->network.bindings = bindings; auto start_result = this->start_networking(); switch (start_result) { case NetworkingStartResult::SUCCESS: break; + case NetworkingStartResult::OUT_OF_MEMORY: logError(LOG_FT, "Failed to start networking (Out of memory)"); goto error_exit_network; - case NetworkingStartResult::NO_BINDINGS: - logError(LOG_FT, "Failed to start networking (No address could be bound)"); - goto error_exit_network; + default: logError(LOG_FT, "Failed to start networking ({})", (int) start_result); goto error_exit_network; diff --git a/file/local_server/LocalFileTransferNetwork.cpp b/file/local_server/LocalFileTransferNetwork.cpp index 16d514f..5f5b8e8 100644 --- a/file/local_server/LocalFileTransferNetwork.cpp +++ b/file/local_server/LocalFileTransferNetwork.cpp @@ -168,95 +168,161 @@ void FileClient::flush_network_buffer() { } NetworkingStartResult LocalFileTransfer::start_networking() { + std::lock_guard nlock{this->network.mutex}; assert(!this->network.active); this->network.active = true; this->network.event_base = event_base_new(); if(!this->network.event_base) return NetworkingStartResult::OUT_OF_MEMORY; - bool bound{false}; - for(auto& binding : this->network.bindings) { - binding->file_descriptor = socket(binding->address.ss_family, SOCK_STREAM | SOCK_NONBLOCK, 0); - if(!binding->file_descriptor) { - logWarning(LOG_FT, "Failed to allocate socket for {}: {}/{}", binding->hostname, errno, strerror(errno)); - continue; - } - - - int enable = 1, disabled = 0; - - if (setsockopt(binding->file_descriptor, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) - logWarning(LOG_FT, "Failed to activate SO_REUSEADDR for binding {} ({} | {})", binding->hostname, errno, strerror(errno)); - - if(setsockopt(binding->file_descriptor, IPPROTO_TCP, TCP_NOPUSH, &disabled, sizeof disabled) < 0) - logWarning(LOG_FT, "Failed to deactivate TCP_NOPUSH for binding {} ({} | {})", binding->hostname, errno, strerror(errno)); - - if(binding->address.ss_family == AF_INET6) { - if(setsockopt(binding->file_descriptor, IPPROTO_IPV6, IPV6_V6ONLY, &enable, sizeof(int)) < 0) - logWarning(LOG_FT, "Failed to activate IPV6_V6ONLY for IPv6 binding {} ({} | {})", binding->hostname, errno, strerror(errno)); - } - if(fcntl(binding->file_descriptor, F_SETFD, FD_CLOEXEC) < 0) - logWarning(LOG_FT, "Failed to set flag FD_CLOEXEC for binding {} ({} | {})", binding->hostname, errno, strerror(errno)); - - - if (bind(binding->file_descriptor, (struct sockaddr *) &binding->address, sizeof(binding->address)) < 0) { - logError(LOG_FT, "Failed to bind server to {}. (Failed to bind socket: {} | {})", binding->hostname, errno, strerror(errno)); - goto reset_binding; - } - - if (listen(binding->file_descriptor, 8) < 0) { - logError(LOG_FT, "Failed to bind server to {}. (Failed to listen: {} | {})", binding->hostname, errno, strerror(errno)); - goto reset_binding; - } - - binding->handle = this; - binding->accept_event = event_new(this->network.event_base, binding->file_descriptor, (unsigned) EV_READ | (unsigned) EV_PERSIST, &LocalFileTransfer::callback_transfer_network_accept, &*binding); - if(!binding->accept_event) - goto reset_binding; - - event_add(binding->accept_event, nullptr); - logMessage(LOG_FT, "Started to listen on {}:{}", binding->hostname, net::port(binding->address)); - - bound = true; - continue; - - reset_binding: - if(binding->accept_event) { - event_free(binding->accept_event); - binding->accept_event = nullptr; - } - - if(binding->file_descriptor > 0) - ::close(binding->file_descriptor); - binding->file_descriptor = 0; - - binding->handle = nullptr; - } - if(!bound) { - event_base_free(std::exchange(this->network.event_base, nullptr)); - return NetworkingStartResult::NO_BINDINGS; - } - this->network.dispatch_thread = std::thread(&LocalFileTransfer::dispatch_loop_network, this); return NetworkingStartResult::SUCCESS; } -void LocalFileTransfer::shutdown_networking() { - if(!this->network.active) return; - this->network.active = false; +NetworkingBindResult LocalFileTransfer::add_network_binding(const NetworkBinding &binding) { + std::lock_guard nlock{this->network.mutex}; + if(!this->network.active) + return NetworkingBindResult::NETWORKING_NOT_INITIALIZED; - for(auto& binding : this->network.bindings) { - if(binding->accept_event) { - event_del_block(binding->accept_event); - event_free(binding->accept_event); - binding->accept_event = nullptr; + for(const auto& abinding : this->network.bindings) { + if(net::address_equal(abinding->address, binding.address) && net::port(abinding->address) == net::port(binding.address)) + return NetworkingBindResult::BINDING_ALREADY_EXISTS; + } + + NetworkingBindResult result{NetworkingBindResult::SUCCESS}; + auto abinding = std::make_shared(); + abinding->handle = this; + abinding->hostname = binding.hostname; + memcpy(&abinding->address, &binding.address, sizeof(binding.address)); + + abinding->file_descriptor = socket(abinding->address.ss_family, SOCK_STREAM | SOCK_NONBLOCK, 0); + if(!abinding->file_descriptor) { + //logWarning(LOG_FT, "Failed to allocate socket for {}: {}/{}", abinding->hostname, errno, strerror(errno)); + return NetworkingBindResult::FAILED_TO_ALLOCATE_SOCKET; + } + + + int enable = 1, disabled = 0; + + if (setsockopt(abinding->file_descriptor, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) + logWarning(LOG_FT, "Failed to activate SO_REUSEADDR for binding {} ({}/{})", abinding->hostname, errno, strerror(errno)); + + if(setsockopt(abinding->file_descriptor, IPPROTO_TCP, TCP_NOPUSH, &disabled, sizeof disabled) < 0) + logWarning(LOG_FT, "Failed to deactivate TCP_NOPUSH for binding {} ({}/{})", abinding->hostname, errno, strerror(errno)); + + if(abinding->address.ss_family == AF_INET6) { + if(setsockopt(abinding->file_descriptor, IPPROTO_IPV6, IPV6_V6ONLY, &enable, sizeof(int)) < 0) + logWarning(LOG_FT, "Failed to activate IPV6_V6ONLY for IPv6 binding {} ({}/{})", abinding->hostname, errno, strerror(errno)); + } + if(fcntl(abinding->file_descriptor, F_SETFD, FD_CLOEXEC) < 0) + logWarning(LOG_FT, "Failed to set flag FD_CLOEXEC for binding {} ({}/{})", abinding->hostname, errno, strerror(errno)); + + + if (bind(abinding->file_descriptor, (struct sockaddr *) &abinding->address, sizeof(abinding->address)) < 0) { + //logError(LOG_FT, "Failed to bind server to {}. (Failed to bind socket: {}/{})", binding->hostname, errno, strerror(errno)); + result = NetworkingBindResult::FAILED_TO_BIND; + goto reset_binding; + } + + if (listen(abinding->file_descriptor, 8) < 0) { + //logError(LOG_FT, "Failed to bind server to {}. (Failed to listen: {}/{})", binding->hostname, errno, strerror(errno)); + result = NetworkingBindResult::FAILED_TO_LISTEN; + goto reset_binding; + } + + abinding->accept_event = event_new(this->network.event_base, abinding->file_descriptor, (unsigned) EV_READ | (unsigned) EV_PERSIST, &LocalFileTransfer::callback_transfer_network_accept, &*abinding); + if(!abinding->accept_event) { + result = NetworkingBindResult::OUT_OF_MEMORY; + goto reset_binding; + } + + event_add(abinding->accept_event, nullptr); + logMessage(LOG_FT, "Started to listen on {}:{}", abinding->hostname, net::port(abinding->address)); + this->network.bindings.push_back(std::move(abinding)); + + return NetworkingBindResult::SUCCESS; + + reset_binding: + if(abinding->accept_event) { + event_free(abinding->accept_event); + abinding->accept_event = nullptr; + } + + if(abinding->file_descriptor > 0) + ::close(abinding->file_descriptor); + abinding->file_descriptor = 0; + abinding->handle = nullptr; + return result; +} + +std::vector LocalFileTransfer::active_network_bindings() { + std::lock_guard nlock{this->network.mutex}; + std::vector result{}; + result.reserve(this->network.bindings.size()); + + for(const auto& binding : this->network.bindings) { + auto& rbinding = result.emplace_back(); + rbinding.hostname = binding->hostname; + memcpy(&rbinding.address, &binding->address, sizeof(rbinding.address)); + } + + return result; +} + +NetworkingUnbindResult LocalFileTransfer::remove_network_binding(const NetworkBinding &binding) { + std::lock_guard nlock{this->network.mutex}; + std::shared_ptr abinding{}; + for(auto it = this->network.bindings.begin(); it != this->network.bindings.end(); it++) { + abinding = *it; + + if(net::address_equal(abinding->address, binding.address) && net::port(abinding->address) == net::port(binding.address)) { + this->network.bindings.erase(it); + break; } + abinding = nullptr; + } - if(binding->file_descriptor > 0) - ::close(binding->file_descriptor); - binding->file_descriptor = 0; + if(!abinding) + return NetworkingUnbindResult::UNKNOWN_BINDING; - binding->handle = nullptr; + if(abinding->accept_event) { + event_del_block(abinding->accept_event); + event_free(abinding->accept_event); + abinding->accept_event = nullptr; + } + + if(abinding->file_descriptor > 0) + ::close(abinding->file_descriptor); + abinding->file_descriptor = 0; + abinding->handle = nullptr; + + return NetworkingUnbindResult::SUCCESS; +} + +void LocalFileTransfer::shutdown_networking() { + event_base* ev_base; + std::thread dispatch_thread{}; + { + std::lock_guard nlock{this->network.mutex}; + if(!this->network.active) return; + this->network.active = false; + + for(auto& binding : this->network.bindings) { + if(binding->accept_event) { + event_del_block(binding->accept_event); + event_free(binding->accept_event); + binding->accept_event = nullptr; + } + + if(binding->file_descriptor > 0) + ::close(binding->file_descriptor); + binding->file_descriptor = 0; + binding->handle = nullptr; + } + this->network.bindings.clear(); + + ev_base = std::exchange(this->network.event_base, nullptr); + std::swap(this->network.dispatch_thread, dispatch_thread); } { @@ -269,12 +335,11 @@ void LocalFileTransfer::shutdown_networking() { } } - auto ev_base = std::exchange(this->network.event_base, nullptr); if(ev_base) event_base_loopbreak(ev_base); - if(this->network.dispatch_thread.joinable()) - this->network.dispatch_thread.join(); + if(dispatch_thread.joinable()) + dispatch_thread.join(); if(ev_base) event_base_free(ev_base); @@ -428,7 +493,7 @@ void LocalFileTransfer::finalize_client_ssl(const std::shared_ptr &c } void LocalFileTransfer::callback_transfer_network_accept(int fd, short, void *ptr_binding) { - auto binding = reinterpret_cast(ptr_binding); + auto binding = reinterpret_cast(ptr_binding); auto transfer = binding->handle; sockaddr_storage address{}; diff --git a/server/src/FileServerHandler.cpp b/server/src/FileServerHandler.cpp index 670f098..dfdab34 100644 --- a/server/src/FileServerHandler.cpp +++ b/server/src/FileServerHandler.cpp @@ -3,7 +3,6 @@ // #include -#include #include #include "./client/ConnectedClient.h" @@ -15,15 +14,10 @@ using namespace ts::server::file; FileServerHandler::FileServerHandler(ts::server::InstanceHandler *instance) : instance_{instance} {} bool FileServerHandler::initialize(std::string &error) { - /* - * FIXME: Ports etc! - * - auto bindings_string = this->properties()[property::SERVERINSTANCE_FILETRANSFER_HOST].as(); - auto port = this->properties()[property::SERVERINSTANCE_FILETRANSFER_PORT].as(); - */ - if(!file::initialize(error)) + if(!file::initialize(error, serverInstance->properties()[property::SERVERINSTANCE_FILETRANSFER_HOST].as(), serverInstance->properties()[property::SERVERINSTANCE_FILETRANSFER_PORT].as())) return false; + file::config::ssl_option_supplier = [&]{ return this->instance_->sslManager()->web_ssl_options(); }; diff --git a/server/src/VirtualServer.h b/server/src/VirtualServer.h index eb31e5c..c112185 100644 --- a/server/src/VirtualServer.h +++ b/server/src/VirtualServer.h @@ -58,7 +58,6 @@ namespace ts { class InstanceHandler; class VoiceServer; class QueryServer; - class LocalFileServer; class SpeakingClient; class WebControlServer; diff --git a/server/src/client/command_handler/server.cpp b/server/src/client/command_handler/server.cpp index 8a46735..e26f19c 100644 --- a/server/src/client/command_handler/server.cpp +++ b/server/src/client/command_handler/server.cpp @@ -259,8 +259,8 @@ command_result ConnectedClient::handleCommandServerRequestConnectionInfo(Command first_bulk.put_unchecked(property::CONNECTION_FILETRANSFER_BANDWIDTH_SENT, minute_report.file_bytes_sent); first_bulk.put_unchecked(property::CONNECTION_FILETRANSFER_BANDWIDTH_RECEIVED, minute_report.file_bytes_received); - first_bulk.put_unchecked(property::CONNECTION_FILETRANSFER_BYTES_SENT_TOTAL, minute_report.file_bytes_sent); - first_bulk.put_unchecked(property::CONNECTION_FILETRANSFER_BYTES_RECEIVED_TOTAL, minute_report.file_bytes_received); + first_bulk.put_unchecked(property::CONNECTION_FILETRANSFER_BYTES_SENT_TOTAL, this->server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_DOWNLOADED].as()); + first_bulk.put_unchecked(property::CONNECTION_FILETRANSFER_BYTES_RECEIVED_TOTAL, this->server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_UPLOADED].as()); first_bulk.put_unchecked("connection_filetransfer_bytes_sent_month", this->server->properties()[property::VIRTUALSERVER_MONTH_BYTES_DOWNLOADED].as()); first_bulk.put_unchecked("connection_filetransfer_bytes_received_month", this->server->properties()[property::VIRTUALSERVER_MONTH_BYTES_UPLOADED].as()); diff --git a/server/src/client/web/VoiceBridge.cpp b/server/src/client/web/VoiceBridge.cpp index 4e4b587..cb31be0 100644 --- a/server/src/client/web/VoiceBridge.cpp +++ b/server/src/client/web/VoiceBridge.cpp @@ -190,6 +190,8 @@ void VoiceBridge::handle_data_channel(const std::shared_ptr &c weak_ptr weak_channel = channel; channel->callback_binary = [&, weak_channel](const pipes::buffer_view& buffer) { + if(buffer.length() < 2) + return; this->callback_voice_data(buffer.view(2), buffer[0] == 1, buffer[1] == 1); /* buffer.substr(2), buffer[0] == 1, buffer[1] == 1 */ }; diff --git a/server/src/client/web/WebClient.cpp b/server/src/client/web/WebClient.cpp index 9fa5a63..baf67ca 100644 --- a/server/src/client/web/WebClient.cpp +++ b/server/src/client/web/WebClient.cpp @@ -28,6 +28,8 @@ WebClient::WebClient(WebControlServer* server, int fd) : SpeakingClient(server-> assert(server->getTS()); this->state = ConnectionState::INIT_LOW; this->file_descriptor = fd; + + debugMessage(this->server->getServerId(), " Creating WebClient instance at {}", (void*) this); } void WebClient::initialize() { @@ -120,6 +122,7 @@ void WebClient::initialize() { WebClient::~WebClient() { memtrack::freed(this); + debugMessage(this->server->getServerId(), " Destroying WebClient instance at {}", (void*) this); } static Json::StreamWriterBuilder stream_write_builder = []{ diff --git a/server/src/terminal/CommandHandler.cpp b/server/src/terminal/CommandHandler.cpp index 1a2b151..ac179ff 100644 --- a/server/src/terminal/CommandHandler.cpp +++ b/server/src/terminal/CommandHandler.cpp @@ -11,8 +11,6 @@ #include "../SignalHandler.h" #include "../client/ConnectedClient.h" #include "../InstanceHandler.h" -#include "../VirtualServerManager.h" -#include "../VirtualServer.h" #include "../ShutdownHelper.h" #include "../server/QueryServer.h" @@ -385,6 +383,7 @@ namespace terminal { resident_set = rss * page_size_kb; } + //meminfo track bool handleCommandMemInfo(TerminalCommand& cmd){ bool flag_base = false, flag_malloc = false, flag_track = false, flag_buffer = false;