// // Created by WolverinDEV on 28/04/2020. // #include #include #include "LocalFileProvider.h" using namespace ts::server; using LocalFileServer = file::LocalFileProvider; using LocalVirtualFileServer = file::LocalVirtualFileServer; std::shared_ptr server_instance{}; 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; } void file::finalize() { auto server = std::exchange(server_instance, nullptr); if(!server) return; server->finalize(); } std::shared_ptr file::server() { return server_instance; } LocalFileServer::LocalFileProvider() : file_system_{}, file_transfer_{this->file_system_} {} LocalFileServer::~LocalFileProvider() = default; bool LocalFileServer::initialize(std::string &error) { if(!this->file_system_.initialize(error, "files/")) return false; if(!this->file_transfer_.start()) { error = "transfer server startup failed"; this->file_system_.finalize(); return false; } return true; } void LocalFileServer::finalize() { this->file_transfer_.stop(); this->file_system_.finalize(); } file::filesystem::AbstractProvider &LocalFileServer::file_system() { return this->file_system_; } file::transfer::AbstractProvider &LocalFileServer::file_transfer() { return this->file_transfer_; } std::string file::LocalFileProvider::file_base_path() const { return this->file_system_.root_path(); } std::shared_ptr LocalFileServer::register_server(ServerId server_id) { auto server = this->find_virtual_server(server_id); if(server) return server; server = std::make_shared(server_id, std::to_string(server_id)); { std::lock_guard slock{this->servers_mutex}; this->servers_.push_back(server); } return server; } void LocalFileServer::unregister_server(ServerId server_id) { auto server_unique_id = std::to_string(server_id); std::lock_guard slock{this->servers_mutex}; auto it = std::find_if(this->servers_.begin(), this->servers_.end(), [&](const std::shared_ptr& server) { return server->unique_id() == server_unique_id; }); if(it == this->servers_.end()) return; this->servers_.erase(it); } void LocalVirtualFileServer::max_networking_upload_bandwidth(int64_t value) { VirtualFileServer::max_networking_upload_bandwidth(value); this->upload_throttle.set_max_bandwidth(value); } void LocalVirtualFileServer::max_networking_download_bandwidth(int64_t value) { VirtualFileServer::max_networking_download_bandwidth(value); this->download_throttle.set_max_bandwidth(value); }