Removed the whole TS3 WebList feature

This commit is contained in:
WolverinDEV 2021-02-25 11:54:47 +01:00
parent 2c7e7e43d4
commit 1ea630b326
18 changed files with 5 additions and 626 deletions

View File

@ -88,7 +88,6 @@ namespace ts::server::file::transfer {
} transfer_key{};
struct {
/* TODO: Could be a spin lock (never gets locked while writing so no long blocking activity) */
std::mutex mutex{};
size_t bytes{0};

View File

@ -125,9 +125,6 @@ set(SERVER_SOURCE_FILES
src/ShutdownHelper.cpp
src/lincense/TeamSpeakLicense.cpp
src/weblist/WebListManager.cpp
src/weblist/TeamSpeakWebClient.cpp
src/snapshots/permission.cpp
src/snapshots/client.cpp
src/snapshots/channel.cpp

View File

@ -42,7 +42,6 @@ uint16_t ts::config::binding::DefaultFilePort;
std::string config::server::DefaultServerVersion;
std::string config::server::DefaultServerPlatform;
LicenseType config::server::DefaultServerLicense;
bool config::server::enable_teamspeak_weblist;
bool config::server::strict_ut8_mode;
bool config::server::show_invisible_clients_as_online;
bool config::server::disable_ip_saving;
@ -1283,11 +1282,6 @@ std::deque<std::shared_ptr<EntryBinding>> config::create_bindings() {
ADD_DESCRIPTION("Enable/disable the deletion of invalid icon id permissions");
}
#endif
{
CREATE_BINDING("allow_weblist", 0);
BIND_BOOL(config::server::enable_teamspeak_weblist, true);
ADD_DESCRIPTION("Enable/disable weblist reports globally! (Server setting wount be disabled, they will be just not send)");
}
{
CREATE_BINDING("strict_ut8_mode", FLAG_RELOADABLE);
BIND_BOOL(config::server::strict_ut8_mode, false);

View File

@ -73,7 +73,6 @@ namespace ts::config {
extern bool strict_ut8_mode;
extern bool enable_teamspeak_weblist;
extern bool show_invisible_clients_as_online;
extern bool disable_ip_saving;
extern bool default_music_bot;

View File

@ -3,7 +3,6 @@
#define XFREE undefined_free
#define XREALLOC undefined_realloc
#include "src/weblist/WebListManager.h"
#include <log/LogUtils.h>
#include "InstanceHandler.h"
#include "src/client/InternalClient.h"
@ -208,8 +207,6 @@ InstanceHandler::InstanceHandler(SqlDataManager *sql) : sql(sql) {
this->banMgr = new BanManager(this->getSql());
this->banMgr->loadBans();
this->web_list = make_shared<weblist::WebListManager>();
}
InstanceHandler::~InstanceHandler() {
@ -256,8 +253,6 @@ bool InstanceHandler::startInstance() {
this->server_command_executor_ = std::make_shared<ServerCommandExecutor>(ts::config::threads::command_execute);
this->web_list->enabled = ts::config::server::enable_teamspeak_weblist;
this->permission_mapper = make_shared<permission::PermissionNameMapper>();
if(!this->permission_mapper->initialize(config::permission_mapping_file, errorMessage)) {
logCritical(LOG_INSTANCE, "Failed to initialize permission name mapping from file {}: {}", config::permission_mapping_file, errorMessage);
@ -418,7 +413,6 @@ void InstanceHandler::stopInstance() {
this->active = false;
this->activeCon.notify_all();
}
this->web_list->enabled = false;
this->server_command_executor_->shutdown();
/* TODO: Block on canceling. */
@ -557,8 +551,6 @@ void InstanceHandler::tickInstance() {
this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_DELETED].as<uint64_t>() +
this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_VARIANZ].as<uint64_t>();
}
this->web_list->tick();
}
void InstanceHandler::save_group_permissions() {

View File

@ -12,7 +12,6 @@
#include <files/FileServer.h>
#include "weblist/WebListManager.h"
#include "./client/web/WebClient.h"
#include "./client/voice/VoiceClient.h"
#include "./client/InternalClient.h"
@ -516,9 +515,6 @@ bool VirtualServer::start(std::string& error) {
}
);
if(this->properties()[property::VIRTUALSERVER_WEBLIST_ENABLED].as<bool>())
serverInstance->getWebList()->enable_report(this->self.lock());
properties()[property::VIRTUALSERVER_CLIENTS_ONLINE] = 0;
properties()[property::VIRTUALSERVER_QUERYCLIENTS_ONLINE] = 0;
properties()[property::VIRTUALSERVER_CHANNELS_ONLINE] = 0;
@ -613,12 +609,6 @@ void VirtualServer::stop(const std::string& reason, bool disconnect_query) {
this->webControlServer = nullptr;
#endif
{
auto list = serverInstance->getWebList();
if(list)
list->disable_report(self_lock);
}
if(this->groups) {
this->groups->clearCache();
}

View File

@ -7,7 +7,6 @@
#include "../../manager/PermissionNameMapper.h"
#include "../../server/QueryServer.h"
#include "../../server/VoiceServer.h"
#include "../../weblist/WebListManager.h"
#include "../ConnectedClient.h"
#include "../InternalClient.h"
#include "../music/MusicClient.h"

View File

@ -12,7 +12,6 @@
#include "../../server/QueryServer.h"
#include "../music/MusicClient.h"
#include "../query/QueryClient.h"
#include "../../weblist/WebListManager.h"
#include "../../manager/ConversationManager.h"
#include "../../manager/PermissionNameMapper.h"
#include "../../manager/ActionLogger.h"

View File

@ -15,7 +15,6 @@
#include "../../server/QueryServer.h"
#include "../music/MusicClient.h"
#include "../query/QueryClient.h"
#include "../../weblist/WebListManager.h"
#include "../../manager/ConversationManager.h"
#include "../../manager/PermissionNameMapper.h"
#include "../../manager/ActionLogger.h"

View File

@ -17,7 +17,6 @@
#include "../../server/QueryServer.h"
#include "../music/MusicClient.h"
#include "../query/QueryClient.h"
#include "../../weblist/WebListManager.h"
#include "../../manager/ConversationManager.h"
#include "../../manager/PermissionNameMapper.h"
#include "../../manager/ActionLogger.h"

View File

@ -20,7 +20,6 @@
#include "../../server/QueryServer.h"
#include "../music/MusicClient.h"
#include "../query/QueryClient.h"
#include "../../weblist/WebListManager.h"
#include "../../manager/ConversationManager.h"
#include "../../manager/PermissionNameMapper.h"
#include <experimental/filesystem>

View File

@ -16,7 +16,6 @@
#include "../../server/QueryServer.h"
#include "../music/MusicClient.h"
#include "../query/QueryClient.h"
#include "../../weblist/WebListManager.h"
#include "../../manager/ConversationManager.h"
#include "../../manager/PermissionNameMapper.h"
#include "../../manager/ActionLogger.h"
@ -127,16 +126,7 @@ command_result ConnectedClient::handleCommandServerEdit(Command &cmd) {
SERVEREDIT_CHK_PROP_CACHED("virtualserver_hostmessage_mode", permission::b_virtualserver_modify_hostmessage, int) }
SERVEREDIT_CHK_PROP_CACHED("virtualserver_welcomemessage", permission::b_virtualserver_modify_welcomemessage, string) }
SERVEREDIT_CHK_PROP_CACHED("virtualserver_weblist_enabled", permission::b_virtualserver_modify_weblist, bool)
if (target_server && target_server->running()) {
if (cmd["virtualserver_weblist_enabled"].as<bool>())
serverInstance->getWebList()->enable_report(target_server);
else
serverInstance->getWebList()->disable_report(target_server);
debugMessage(target_server->getServerId(), "Changed weblist state to -> {}",
cmd["virtualserver_weblist_enabled"].as<bool>() ? "activated" : "disabled");
}
} SERVEREDIT_CHK_PROP_CACHED("virtualserver_needed_identity_security_level", permission::b_virtualserver_modify_needed_identity_security_level, int) }
SERVEREDIT_CHK_PROP_CACHED("virtualserver_needed_identity_security_level", permission::b_virtualserver_modify_needed_identity_security_level, int) }
SERVEREDIT_CHK_PROP_CACHED("virtualserver_antiflood_points_tick_reduce", permission::b_virtualserver_modify_antiflood, uint64_t) }
SERVEREDIT_CHK_PROP_CACHED("virtualserver_antiflood_points_needed_command_block", permission::b_virtualserver_modify_antiflood, uint64_t) }

View File

@ -150,8 +150,10 @@ std::shared_ptr<IOEventLoop> VoiceIOManager::spawnEventLoop() {
memset(thread_usage, 0, num_threads);
for(auto& ev_loop : this->event_loops) {
if(ev_loop->bound_thread < 0 || ev_loop->bound_thread >= num_threads)
if(ev_loop->bound_thread < 0 || ev_loop->bound_thread >= num_threads) {
continue;
}
thread_usage[ev_loop->bound_thread]++;
}

View File

@ -1,316 +0,0 @@
#include "src/VirtualServer.h"
#include "TeamSpeakWebClient.h"
#include "log/LogUtils.h"
#include "src/server/VoiceServer.h"
using namespace ts;
using namespace ts::weblist;
using namespace ts::server;
TSWebClient::TSWebClient(const std::shared_ptr<VirtualServer> &server, struct event_base *event_base, uint16_t session_index, bool resend_name) : server(server), event_base(event_base), session_index(session_index), send_name(resend_name) { }
TSWebClient::~TSWebClient() {
this->unregister_events(true);
try {
if(this->close_thread.get_id() == std::this_thread::get_id())
this->close_thread.detach();
else if(this->close_thread.joinable())
this->close_thread.join();
} catch(std::exception& ex) {
logCritical(this->server ? this->server->getServerId() : 0, "[WebList] Failed to join or detach close thread! message: {}", ex.what());
}
}
void TSWebClient::_handle_message_read(int file_descriptor, short, void *ptr_client) {
const auto client = (TSWebClient*) ptr_client;
pipes::buffer buffer{512};
const auto read = recv(file_descriptor, buffer.data_ptr(), buffer.length(), MSG_NOSIGNAL | MSG_DONTWAIT);
if(read <= 0) {
logError(client->server->getServerId(), "[WebList] Failed to read weblist response. ({} | {} => {})", read, errno, strerror(errno));
{
std::lock_guard elock{client->event_mutex};
if(client->event_read)
event_del_noblock(client->event_read);
}
client->trigger_fail_later("failed to read!", true);
return;
}
client->handle_message_read(buffer.view(0, read));
}
void TSWebClient::_handle_message_write(int file_descriptor, short, void *ptr_client) {
const auto client = (TSWebClient*) ptr_client;
pipes::buffer buffer;
{
std::lock_guard lock(client->write_lock);
if(client->write_buffer.empty()) return;
buffer = std::move(client->write_buffer[0]);
client->write_buffer.pop_front();
if(!client->write_buffer.empty()) {
std::lock_guard elock{client->event_mutex};
if(client->event_write)
event_add(client->event_write, nullptr);
}
}
const auto write = sendto(file_descriptor, buffer.data_ptr(), buffer.length(), 0, (const sockaddr *) &client->remote_address, sizeof(sockaddr_in));
if(write != buffer.length()){
logError(client->server->getServerId(), "[WebList] Failed to send weblist response. ({} | {} => {})", write, errno, strerror(errno));
client->trigger_fail_later("failed to write!", true);
return;
}
}
void TSWebClient::_handle_timeout(int, short, void *ptr_client) {
const auto client = (TSWebClient*) ptr_client;
{
std::lock_guard elock{client->event_mutex};
if(client->event_timeout)
event_del_noblock(client->event_timeout);
}
client->trigger_fail_later("timeout", true);
}
void TSWebClient::unregister_events(bool blocking) {
const auto unregister = [blocking](event*& event) {
if(blocking) {
event_del_block(event);
event_free(event);
event = nullptr;
} else {
event_del_noblock(event);
}
};
std::unique_lock elock{this->event_mutex};
auto tevent = std::exchange(this->event_timeout, nullptr);
auto revent = std::exchange(this->event_read, nullptr);
auto wevent = std::exchange(this->event_write, nullptr);
elock.unlock();
if(tevent) unregister(tevent);
if(revent) unregister(revent);
if(wevent) unregister(wevent);
if(this->file_descriptor > 0) {
close(this->file_descriptor);
this->file_descriptor = 0;
}
}
void TSWebClient::reset_timeout(bool reschedule) {
std::lock_guard elock{this->event_mutex};
if(this->event_timeout) {
event_del(this->event_timeout);
if(reschedule) {
timeval timeout{0};
timeout.tv_sec = 5;
event_add(this->event_timeout, &timeout);
}
}
}
void TSWebClient::trigger_fail_later(const std::string &error, bool retry) {
if(this->state >= S_FINALIZING || this->close_thread.joinable()) return;
this->state = S_FINALIZING;
this->close_thread = std::thread([&, error, retry](){
this->unregister_events(true);
if(this->callback_error)
this->callback_error(error,retry);
});
}
void TSWebClient::trigger_success_later() {
if(this->state >= S_FINALIZING || this->close_thread.joinable()) return;
this->state = S_FINALIZING;
this->close_thread = std::thread([&](){
this->unregister_events(true);
if(this->callback_success)
this->callback_success();
});
}
void TSWebClient::write_message(const pipes::buffer_view &buffer) {
if(this->state >= S_FINALIZING) return;
{
std::lock_guard lock(this->write_lock);
this->write_buffer.push_back(buffer.own_buffer());
}
if(this->event_write)
event_add(this->event_write, nullptr);
}
#define BASE_PORT 30566
void TSWebClient::report() {
this->state = S_INITIALIZING;
memset(&this->remote_address, 0, sizeof(sockaddr_in));
this->remote_address.sin_family = AF_INET;
this->remote_address.sin_port = htons(2010);
{
auto record = gethostbyname("weblist.teamspeak.com");
if(!record) {
this->trigger_fail_later("Failed to resolve weblist.teamspeak.com", true);
return;
}
this->remote_address.sin_addr.s_addr = ((in_addr*) record->h_addr)->s_addr;
}
this->file_descriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(this->file_descriptor <= 0) {
this->trigger_fail_later("Failed to create file descriptor", true);
return;
}
if(fcntl(this->file_descriptor, F_SETFD, FD_CLOEXEC) < 0) {
this->trigger_fail_later("Failed to enable FD_CLOEXEC for {} (WebReport)", true);
return;
}
int allow = 1;
setsockopt(this->file_descriptor, SOL_SOCKET, SO_REUSEADDR, &allow, sizeof(int));
{
sockaddr_in address{};
address.sin_family = AF_INET;
address.sin_port = htons(BASE_PORT + this->server->getServerId());
address.sin_addr.s_addr = INADDR_ANY;
if(this->server->getVoiceServer()) {
for(const auto& binding : this->server->getVoiceServer()->activeBindings()) {
if(binding->address.ss_family != AF_INET) continue;
address.sin_addr.s_addr = ((sockaddr_in*) &binding->address)->sin_addr.s_addr;
debugMessage(this->server->getServerId(), "[WebList] Requesting from local address {}:{}", binding->address_string(), ntohs(address.sin_port));
break;
}
}
if(bind(this->file_descriptor, (const sockaddr *) &address, sizeof(address)) < 0) {
this->trigger_fail_later("Failed to bind socket", true);
return;
}
}
this->event_read = event_new(this->event_base, this->file_descriptor, EV_READ | EV_PERSIST, TSWebClient::_handle_message_read, this);
this->event_write = event_new(this->event_base, this->file_descriptor, EV_WRITE, TSWebClient::_handle_message_write, this);
this->event_timeout = event_new(this->event_base, -1, 0, TSWebClient::_handle_timeout, this);
event_add(this->event_read, nullptr);
this->reset_timeout(true);
this->request_session();
}
void TSWebClient::abort() {
this->trigger_fail_later("aborted", false);
}
void TSWebClient::abort_sync() {
this->unregister_events(true);
if(this->callback_error)
this->callback_error("aborted", false);
}
inline char nibble(int c) {
assert(c < 16);
if(c >= 0 && c <= 9)
return (char) ('0' + c);
else
return (char) ('A' + (c - 10));
}
inline std::string hex(const pipes::buffer_view &buffer) {
std::string result;
for(size_t index = 0; index < buffer.length(); index++)
result += std::string() + "0x" + nibble(buffer[index] >> 4) + nibble(buffer[index] & 0x0F) + " ";
if(result.empty()) return result;
return result.substr(0, result.length() - 1);
}
void TSWebClient::handle_message_read(const pipes::buffer_view &buffer) {
this->reset_timeout(true);
if(this->state == S_INITIALIZING) {
if(buffer.length() != 8) {
this->trigger_fail_later("Failed to receive key. (Invalid packet length of " + std::to_string(buffer.length()) + ". Expected 8. Buffer: " + hex(buffer) + ")", true);
return;
}
this->session_id = *(uint32_t*) &buffer[4];
this->send_status(this->send_name);
} else if(this->state == S_DATA_EXCHANGE) {
if(buffer.length() != 5) {
this->trigger_fail_later("Failed to receive exchange stats. (Invalid packet length of " + std::to_string(buffer.length()) + ". Expected 5. Buffer: " + hex(buffer) + ")", true);
return;
}
int status = buffer[4];
if(status == 7) {
this->send_name = true;
debugMessage(this->server->getServerId(), "[WebList] Received exchange status 7. Resending with server name.");
this->send_status(true);
return;
} else if(status == 0) {
this->trigger_success_later();
return;
} else {
debugMessage(this->server->getServerId(), "[WebList] Weblist request failed. Status code {}. Buffer: {}", status, hex(buffer));
this->trigger_fail_later("Invalid exchange status. Status: " + std::to_string(status), status != 5);
return;
}
}
}
void TSWebClient::request_session() {
this->state = S_INITIALIZING;
pipes::buffer buffer{4};
buffer[0] = 1; //Version
buffer[1] = (uint8_t) (session_index >> 8); //Packet number
buffer[2] = (uint8_t) (session_index & 0xFF);
buffer[3] = 1; //Request session
this->write_message(buffer);
}
void TSWebClient::send_status(bool flag_name) {
this->state = S_DATA_EXCHANGE;
auto name = this->server->getDisplayName();
pipes::buffer buffer{4 + 4 + 3 * 2 + 1 + 1 + (flag_name ? name.length() : 0)};
buffer[0] = 1; //Version
buffer[1] = (uint8_t) (session_index >> 8); //Packet number
buffer[2] = (uint8_t) (session_index & 0xFF);
buffer[3] = 2; //Status update
*(uint32_t*) &buffer[4] = this->session_id;
*(uint16_t*) &buffer[8] = this->server->properties()[property::VIRTUALSERVER_PORT].as<uint16_t>();
*(uint16_t*) &buffer[10] = this->server->properties()[property::VIRTUALSERVER_MAXCLIENTS].as<uint16_t>();
*(uint16_t*) &buffer[12] = this->server->properties()[property::VIRTUALSERVER_CLIENTS_ONLINE].as<uint16_t>();
bool flag_channel = this->server->could_default_create_channel();
bool flag_password = this->server->properties()[property::VIRTUALSERVER_FLAG_PASSWORD].as<bool>();
debugMessage(this->server->getServerId(), "[WebList] Sending properties: flag_channel: {}, flag_password: {}", flag_channel, flag_password);
buffer[14] = (flag_password ? 0x01 : 0) | (flag_channel ? 0x02 : 0); //Create channels (0x01 = password)
if(flag_name) {
buffer[15] = (uint8_t) name.length();
if(name.length() > 0) {
memcpy(&buffer[16], name.c_str(), name.length());
}
} else {
buffer[15] = 0; //We dont want to send a server name
}
this->write_message(buffer);
}

View File

@ -1,73 +0,0 @@
#pragma once
#include <pipes/buffer.h>
#include <functional>
#include <memory>
#include <event.h>
namespace ts {
namespace server {
class VirtualServer;
}
namespace weblist {
class TSWebClient {
public:
enum State {
S_UNINITIALIZED,
S_INITIALIZING,
S_DATA_EXCHANGE,
S_FINALIZING,
S_FINALIZED
};
TSWebClient(const std::shared_ptr <server::VirtualServer> &server, struct event_base *event_base, uint16_t session_index, bool /* resend name */);
virtual ~TSWebClient();
void report();
void abort();
void abort_sync();
inline bool running() { return this->state != S_FINALIZED && this->state != S_UNINITIALIZED; }
std::function<void(const std::string&, bool)> callback_error;
std::function<void()> callback_success;
private:
std::shared_ptr<server::VirtualServer> server;
struct event_base* event_base = nullptr;
std::thread close_thread;
State state;
sockaddr_in remote_address{};
std::mutex write_lock;
std::deque<pipes::buffer> write_buffer{};
int file_descriptor{0};
std::mutex event_mutex{};
struct event* event_read{nullptr};
struct event* event_write{nullptr};
struct event* event_timeout{nullptr};
void unregister_events(bool /* blocking */);
void reset_timeout(bool /* reschedule */);
static void _handle_message_read(int, short, void*);
static void _handle_message_write(int, short, void*);
static void _handle_timeout(int, short,void*);
void trigger_fail_later(const std::string& /* message */, bool /* retry */);
void trigger_success_later();
void write_message(const pipes::buffer_view& /* buffer */);
private:
void handle_message_read(const pipes::buffer_view& /* buffer */);
uint16_t session_index = 1;
uint32_t session_id = 0;
bool send_name = false;
void request_session();
void send_status(bool /* name */);
};
}
}

View File

@ -1,141 +0,0 @@
#include <algorithm>
#include <thread>
#include <ThreadPool/ThreadHelper.h>
#include "src/VirtualServer.h"
#include "log/LogUtils.h"
#include "TeamSpeakWebClient.h"
#include "WebListManager.h"
using namespace std;
using namespace std::chrono;
using namespace ts;
using namespace ts::server;
using namespace ts::weblist;
WebListManager::WebListManager() {
this->event_base = event_base_new();
this->event_base_dispatch = std::thread([&]{
while(this->event_base) {
::event_base_loop(this->event_base, EVLOOP_NO_EXIT_ON_EMPTY);
if(this->event_base) {
logWarning(LOG_GENERAL, "WebList report event loop exited without terminating. Rescheduling....");
std::this_thread::sleep_for(std::chrono::seconds{1});
} else {
break;
}
}
});
}
WebListManager::~WebListManager() {
auto event_base_ = std::exchange(this->event_base, nullptr);
if(event_base_) {
event_base_loopbreak(event_base_);
}
threads::save_join(this->event_base_dispatch, true);
if(event_base_) {
event_base_free(event_base_);
}
}
void WebListManager::enable_report(const std::shared_ptr<ts::server::VirtualServer> &server) {
{
unique_lock lock(this->entry_lock);
for(const auto& entry : this->entries) {
if(entry->server == server)
return;
}
auto entry = make_shared<Entry>();
entry->server = server;
entry->scheduled_request = system_clock::now();
entry->fail_count = 0;
this->entries.push_back(entry);
}
}
bool WebListManager::reports_enabled(const std::shared_ptr<ts::server::VirtualServer> &server) {
{
lock_guard lock(this->entry_lock);
for(const auto& entry : this->entries) {
if(entry->server == server) return true;
}
}
return false;
}
void WebListManager::disable_report(const std::shared_ptr<ts::server::VirtualServer> &server) {
if(!server) return;
unique_lock lock(this->entry_lock);
for(const auto& entry : this->entries) {
if(entry->server == server) {
shared_ptr copied_entry{entry}; //Copy it before erasing
auto it = find(this->entries.begin(), this->entries.end(), copied_entry);
if(it != this->entries.end())
this->entries.erase(it);
if(copied_entry->current_request) {
lock.unlock();
copied_entry->current_request->abort_sync();
}
return;
}
}
}
void WebListManager::tick() {
if(!this->enabled) return;
unique_lock lock(this->entry_lock);
auto entries = this->entries;
lock.unlock();
auto now = system_clock::now();
for(const auto& entry : entries) {
if(entry->scheduled_request < now && (!entry->current_request || entry->scheduled_request + minutes(5) < now)) {
entry->current_request = make_shared<TSWebClient>(entry->server, this->event_base, entry->session_count, entry->last_name != entry->server->getDisplayName());
weak_ptr weak_entry = entry;
entry->current_request->callback_success = [weak_entry, now](){
auto _entry = weak_entry.lock();
if(!_entry) return;
_entry->fail_count = 0;
_entry->scheduled_request = now + minutes(10);
_entry->session_count++;
_entry->last_name = _entry->server->getDisplayName();
logMessage(_entry->server->getServerId(), "[WebList] Status update succeeded! Scheduling next update in ten minutes.");
_entry->current_request.reset();
};
entry->current_request->callback_error = [weak_entry, now](auto error, bool retry) {
auto _entry = weak_entry.lock();
if(!_entry) return;
_entry->fail_count++;
logError(_entry->server->getServerId(), "[WebList] Status update failed. Error: " + error);
if(_entry->fail_count == 1 && retry) {
logMessage(_entry->server->getServerId(), "[WebList] Scheduling next update attempt in 1 minute.");
_entry->scheduled_request = now + seconds(60);
} else if(_entry->fail_count == 2 && retry) {
logMessage(_entry->server->getServerId(), "[WebList] Scheduling next update attempt in 5 minutes.");
_entry->scheduled_request = now + seconds(5 * 60);
} else if(_entry->fail_count >= 3) {
logMessage(_entry->server->getServerId(), "[WebList] Scheduling next update attempt in 10 minutes.");
_entry->scheduled_request = now + minutes(10);
}
_entry->current_request.reset();
};
{
/* could be blocking due to gethostbyname. We dont want to have the request deallocated */
auto ref_request = entry->current_request;
ref_request->report();
}
}
}
}

View File

@ -1,49 +0,0 @@
#pragma once
#include <thread>
#include <memory>
#include <chrono>
#include <mutex>
#include <deque>
#include <condition_variable>
struct event_base;
namespace ts {
namespace server {
class VirtualServer;
}
namespace weblist {
class TSWebClient;
class WebListManager {
private:
struct Entry {
std::shared_ptr<server::VirtualServer> server;
std::shared_ptr<TSWebClient> current_request;
std::chrono::system_clock::time_point last_success;
std::chrono::system_clock::time_point scheduled_request;
int fail_count = 0;
uint16_t session_count = 1;
std::string last_name;
};
public:
WebListManager();
~WebListManager();
void enable_report(const std::shared_ptr<server::VirtualServer>& /* server */);
bool reports_enabled(const std::shared_ptr<server::VirtualServer>& /* server */);
void disable_report(const std::shared_ptr<server::VirtualServer>& /* server */);
void tick();
bool enabled = false;
private:
struct event_base* event_base{nullptr};
std::thread event_base_dispatch{};
std::mutex entry_lock{};
std::deque<std::shared_ptr<Entry>> entries{};
};
}
}

2
shared

@ -1 +1 @@
Subproject commit 7ff7d01cd39795050cd8d6e4257e3e0d6dd4bc61
Subproject commit 799bf8d26b5742e3e5df3c9ecbca233113d8f73d