Some fixes

This commit is contained in:
WolverinDEV 2019-09-14 12:06:48 +02:00
parent 709d2c0f5d
commit 2ae00f07cd
18 changed files with 198 additions and 156 deletions

View File

@ -22,7 +22,7 @@ namespace license {
std::shared_ptr<License> readLocalLicence(const std::string& buffer, std::string& error){
string bbuffer = base64::decode(buffer);
if(bbuffer.length() < sizeof(License)) {
error = "Invalid license size";
error = "invalid size";
return nullptr;
}
@ -30,7 +30,7 @@ namespace license {
memcpy(license, bbuffer.data(), sizeof(License));
if(license->header.version != LICENSE_VERSION){
error = "Invalid license version (" + to_string(license->header.version) + ")";
error = "invalid version (" + to_string(license->header.version) + ")";
return nullptr;
}
xorBuffer(&((char*) license)[sizeof(License::header)], sizeof(License::data), license->header.cryptKey, sizeof(license->header.cryptKey));

View File

@ -1,6 +1,7 @@
#include <client/linux/handler/exception_handler.h>
#include <iostream>
#include <misc/endianness.h>
#include <misc/strobf.h>
#include <CXXTerminal/QuickTerminal.h>
#include <event2/thread.h>
#include <log/LogUtils.h>
@ -119,13 +120,6 @@ int main(int argc, char** argv) {
OpenSSL_add_ssl_algorithms();
ts::permission::setup_permission_resolve();
{
u_char buffer[SHA512_DIGEST_LENGTH];
SHA512_CTX md{};
SHA512_Init(&md);
SHA512_Update(&md, "Hello World", 11);
SHA512_Final(buffer,&md);
}
{
auto evthread_use_pthreads_result = evthread_use_pthreads();
assert(evthread_use_pthreads_result == 0);
@ -241,18 +235,18 @@ int main(int argc, char** argv) {
std::string descriptors = "LTGE";
bool crypt_init = false;
for(const auto& c : descriptors)
if(crypt_init |= crypt_mp_init(&c))
if((crypt_init |= crypt_mp_init(&c)))
break;
if(!crypt_init) {
logCritical(LOG_GENERAL, "Could not initialise libtomcrypt mp descriptors!");
return 1;
}
if(register_prng(&sprng_desc) == -1) {
cerr << "could not setup prng" << endl;
logCritical(LOG_GENERAL, "could not setup prng");
return EXIT_FAILURE;
}
if (register_cipher(&rijndael_desc) == -1) {
cerr << "could not setup rijndael" << endl;
logCritical(LOG_GENERAL, "could not setup rijndael");
return EXIT_FAILURE;
}
testTomMath();
@ -263,18 +257,17 @@ int main(int argc, char** argv) {
shared_ptr<logger::LoggerConfig> logConfig = nullptr;
std::string line;
logMessage("Loading configuration");
terminal::instance()->writeMessage("Loading configuration");
logMessageFmt(true, LOG_GENERAL, "Loading configuration");
auto cfgErrors = ts::config::parseConfig(CONFIG_NAME);
if(!cfgErrors.empty()){
logError("Could not load configuration. Errors: (" + to_string(cfgErrors.size()) + ")");
logErrorFmt(true, LOG_GENERAL, "Could not load configuration. Errors: (" + to_string(cfgErrors.size()) + ")");
for(const auto& entry : cfgErrors)
logError(" - " + entry);
logError("Stopping server...");
logError(true, LOG_GENERAL, " - {}", entry);
logErrorFmt(true, LOG_GENERAL, "Stopping server...");
goto stopApp;
}
logMessage("Setting up log");
logMessage(LOG_GENERAL, "Setting up logging");
logConfig = make_shared<logger::LoggerConfig>();
logConfig->logfileLevel = (spdlog::level::level_enum) ts::config::log::logfileLevel;
logConfig->terminalLevel = (spdlog::level::level_enum) ts::config::log::terminalLevel;
@ -291,23 +284,23 @@ int main(int argc, char** argv) {
logger::updateLogLevels();
if(ts::config::license_original && ts::config::license_original->data.type != license::LicenseType::DEMO){
logMessageFmt(true, LOG_GENERAL, "[]---------------------------------------------------------[]");
logMessageFmt(true, LOG_GENERAL, " §aThank you for buying the TeaSpeak-§lPremium-§aSoftware! ");
logMessageFmt(true, LOG_GENERAL, " §aLicense information:");
logMessageFmt(true, LOG_GENERAL, " §aLicense owner : §e" + ts::config::license_original->owner());
logMessageFmt(true, LOG_GENERAL, " §aLicense type : §e" + license::LicenseTypeNames[ts::config::license_original->data.type]);
logMessageFmt(true, LOG_GENERAL, strobf("[]---------------------------------------------------------[]").string());
logMessageFmt(true, LOG_GENERAL, strobf(" §aThank you for buying the TeaSpeak-§lPremium-§aSoftware! ").string());
logMessageFmt(true, LOG_GENERAL, strobf(" §aLicense information:").string());
logMessageFmt(true, LOG_GENERAL, strobf(" §aLicense owner : §e").string() + ts::config::license_original->owner());
logMessageFmt(true, LOG_GENERAL, strobf(" §aLicense type : §e").string() + license::LicenseTypeNames[ts::config::license_original->data.type]);
if(ts::config::license_original->end().time_since_epoch().count() == 0){
logMessageFmt(true, LOG_GENERAL, " §aLicense expires: §enever");
logMessageFmt(true, LOG_GENERAL, strobf(" §aLicense expires: §enever").string());
} else {
char timeBuffer[32];
time_t t = duration_cast<seconds>(ts::config::license_original->end().time_since_epoch()).count();
tm* stime = localtime(&t);
strftime(timeBuffer, 32, "%c", stime);
logMessageFmt(true, LOG_GENERAL, " §aLicense expires: §e" + string(timeBuffer));
logMessageFmt(true, LOG_GENERAL, strobf(" §aLicense expires: §e").string() + string(timeBuffer));
}
logMessage(string() + " §aLicense valid : " + (ts::config::license_original->isValid() ? "§ayes" : "§cno"));
logMessageFmt(true, LOG_GENERAL, "[]---------------------------------------------------------[]");
logMessage(string() + strobf(" §aLicense valid : ").string() + (ts::config::license_original->isValid() ? strobf("§ayes").string() : strobf("§cno").string()));
logMessageFmt(true, LOG_GENERAL, strobf("[]---------------------------------------------------------[]").string());
}
logMessage(LOG_GENERAL, "Starting TeaSpeak-Server v{}", build::version()->string(true));
@ -400,7 +393,7 @@ int main(int argc, char** argv) {
stopApp:
logMessage("Stopping application");
logMessageFmt(true, LOG_GENERAL, "Stopping application");
if(serverInstance)
serverInstance->stopInstance();
delete serverInstance;
@ -410,7 +403,7 @@ int main(int argc, char** argv) {
if(sql)
sql->finalize();
delete sql;
logMessage("Application suspend successful!");
logMessageFmt(true, LOG_GENERAL, "Application suspend successful!");
logger::uninstall();
terminal::uninstall();

View File

@ -9,27 +9,13 @@
#include <log/LogUtils.h>
#include <regex>
#include <src/geo/GeoLocation.h>
#include <misc/strobf.h>
using namespace std;
using namespace std::chrono;
using namespace ts;
using namespace ts::config;
inline std::string decode_string(const std::string& input)
{
const size_t passwordLength = 16;
static const char password[passwordLength] = "invalid pointer";
// out = in XOR NOT(password)
std::string result = input;
for (size_t i = 0; i < input.length(); i++)
result[i] ^= ~password[i % passwordLength];
return result;
}
//"Password" is "invalid pointe"
#define CRYPTED_VERSION_PLATFORM decode_string("\xda\xf8\xe7\xeb\xeb") //Its "Linux"
#define CRYPTED_VERSION_PREFIX decode_string("\xc2\xf4\xe8\xcd\xe3\xf3\xfa\xb4\xaf") //Its "TeaSpeak "
//Variable define
std::string config::database::url;
std::string config::database::sqlite::locking_mode;
@ -432,7 +418,7 @@ vector<string> config::parseConfig(const std::string& path) {
//Due to an implementation mistake every default license looks like this:
//AQA7CN26AAAAAMoLy9BIR2S9HyMeqBx7ZMUUc1rFXkt5YztwZCQRngncqtSs8hsQrzszzeNQSEcVXLtvIhm6m331OgjdugAAAADKbA25Oxab9/MK0xK3iZ8mUg+YkaZQkYS2Bj4Kcq2WFTCynv+sIfeYaei+VV8f/AJvxJDUfADJoSoGX85BIT3cTV+usRs3Adx0Ix/Wi5G4roL8Ypl0p8lYwELLGEVyEQf21rYMWOtVkQk2yoGuQikgLxr6p9sShKmAoES1lbHr8Xk=
//teaspeak_license = license::createLocalLicence(license::LicenseType::DEMO, system_clock::time_point(), "TeaSpeak");
teaspeak_license = "AQA7CN26AAAAAMoLy9BIR2S9HyMeqBx7ZMUUc1rFXkt5YztwZCQRngncqtSs8hsQrzszzeNQSEcVXLtvIhm6m331OgjdugAAAADKbA25Oxab9/MK0xK3iZ8mUg+YkaZQkYS2Bj4Kcq2WFTCynv+sIfeYaei+VV8f/AJvxJDUfADJoSoGX85BIT3cTV+usRs3Adx0Ix/Wi5G4roL8Ypl0p8lYwELLGEVyEQf21rYMWOtVkQk2yoGuQikgLxr6p9sShKmAoES1lbHr8Xk=";
teaspeak_license = strobf("AQA7CN26AAAAAMoLy9BIR2S9HyMeqBx7ZMUUc1rFXkt5YztwZCQRngncqtSs8hsQrzszzeNQSEcVXLtvIhm6m331OgjdugAAAADKbA25Oxab9/MK0xK3iZ8mUg+YkaZQkYS2Bj4Kcq2WFTCynv+sIfeYaei+VV8f/AJvxJDUfADJoSoGX85BIT3cTV+usRs3Adx0Ix/Wi5G4roL8Ypl0p8lYwELLGEVyEQf21rYMWOtVkQk2yoGuQikgLxr6p9sShKmAoES1lbHr8Xk=").string();
config::license = license::readLocalLicence(teaspeak_license, err);
} else {
config::license_original = license::readLocalLicence(teaspeak_license, err);
@ -441,8 +427,8 @@ vector<string> config::parseConfig(const std::string& path) {
if(!config::license){
#if true
logErrorFmt(true, LOG_GENERAL, "The given license isnt valid!");
logErrorFmt(true, LOG_GENERAL, "Falling back to the default license.");
logErrorFmt(true, LOG_GENERAL, strobf("The given license isnt valid!").string());
logErrorFmt(true, LOG_GENERAL, strobf("Falling back to the default license.").string());
teaspeak_license = "none";
goto license_parsing;
#else
@ -451,17 +437,17 @@ vector<string> config::parseConfig(const std::string& path) {
#endif
}
if(!config::license){
errors.emplace_back("Invalid license code!");
errors.emplace_back(strobf("Invalid license code!").string());
return errors;
}
if(!config::license->isValid()) {
if(config::license->data.type == license::LicenseType::INVALID) {
errors.emplace_back("Give license isn't valid!");
errors.emplace_back(strobf("Give license isn't valid!").string());
return errors;
}
logErrorFmt(true, LOG_GENERAL, "The given license isnt valid!");
logErrorFmt(true, LOG_GENERAL, "Falling back to the default license.");
logErrorFmt(true, LOG_GENERAL, strobf("The given license isnt valid!").string());
logErrorFmt(true, LOG_GENERAL, strobf("Falling back to the default license.").string());
teaspeak_license = "none";
goto license_parsing;
}
@ -475,7 +461,7 @@ vector<string> config::parseConfig(const std::string& path) {
for(const auto& entry : config::web::ice_servers) {
auto dp = entry.find(':');
if(dp == string::npos) {
errors.push_back("Invalid ice server entry! Missing port");
errors.emplace_back("Invalid ice server entry! Missing port");
continue;
}
auto host = entry.substr(0, dp);
@ -493,21 +479,21 @@ vector<string> config::parseConfig(const std::string& path) {
}
}
auto currentVersion = CRYPTED_VERSION_PREFIX + build::version()->string(true);
auto currentVersion = strobf("TeaSpeak ").string() + build::version()->string(true);
if(currentVersion != config::server::DefaultServerVersion) {
auto ref = config::server::DefaultServerVersion;
try {
auto pattern = "TeaSpeak " + build::pattern();
auto pattern = strobf("TeaSpeak\\s+").string() + build::pattern();
static std::regex const matcher(pattern);
if (std::regex_match(ref, matcher)) {
logMessage("Updating displayed version in config to " + currentVersion);
logMessage(LOG_GENERAL, "Updating displayed TeaSpeak server version in config from {} to {}", ref, currentVersion);
config["server"]["version"] = currentVersion;
config::server::DefaultServerVersion = currentVersion;
} else {
debugMessage("Pattern not match (" + pattern + ")");
debugMessage(LOG_GENERAL, "Config version string does not matches default pattern. Do no updating it (Pattern: {}, Value: {})", pattern, ref);
}
} catch(std::exception& e){
logError("Could not update displayed version (" + string(e.what()) + ")");
logError(LOG_GENERAL, "Could not update displayed version ({})", e.what());
}
}
@ -1114,13 +1100,13 @@ std::deque<std::shared_ptr<EntryBinding>> config::create_bindings() {
BIND_GROUP(server)
{
CREATE_BINDING("platform", PREMIUM_ONLY);
BIND_STRING(config::server::DefaultServerPlatform, CRYPTED_VERSION_PLATFORM);
BIND_STRING(config::server::DefaultServerPlatform, strobf("Linux").string());
ADD_DESCRIPTION("The displayed platform to the client");
ADD_NOTE("This option is only for the premium version.");
}
{
CREATE_BINDING("version", PREMIUM_ONLY);
BIND_STRING(config::server::DefaultServerVersion, CRYPTED_VERSION_PREFIX + build::version()->string(true));
BIND_STRING(config::server::DefaultServerVersion, strobf("TeaSpeak ").string() + build::version()->string(true));
ADD_DESCRIPTION("The displayed version to the client");
ADD_NOTE("This option is only for the premium version.");
}

View File

@ -89,24 +89,12 @@ std::shared_ptr<Properties> ConnectionStatistics::statistics() {
return this->properties;
}
/* general statistics */
inline int8_t typeIndex(const PacketTypeInfo& type){
if(type == PacketTypeInfo::Command || type == PacketTypeInfo::CommandLow)
return 1;
else if(type == PacketTypeInfo::Ack || type == PacketTypeInfo::AckLow)
return 2;
else if(type == PacketTypeInfo::Voice || type == PacketTypeInfo::VoiceWhisper)
return 3;
return -1;
}
void ConnectionStatistics::logIncomingPacket(const ClientPacket& pkt) {
void ConnectionStatistics::logIncomingPacket(const category::value &category, size_t size) {
auto info_entry = new StatisticEntry{};
info_entry->timestamp = system_clock::now();
info_entry->size = uint16_t(pkt.data().length() + pkt.header().length() + pkt.mac().length());
info_entry->size = uint16_t(size);
auto index = typeIndex(pkt.type());
this->_log_incoming_packet(info_entry, index);
this->_log_incoming_packet(info_entry, category);
}
void ConnectionStatistics::_log_incoming_packet(ts::stats::StatisticEntry *info_entry, int8_t index) {
@ -128,15 +116,15 @@ void ConnectionStatistics::_log_incoming_packet(ts::stats::StatisticEntry *info_
this->handle->_log_incoming_packet(info_entry, index);
}
void ConnectionStatistics::logOutgoingPacket(const ServerPacket& pkt) {
void ConnectionStatistics::logOutgoingPacket(const category::value &category, size_t size) {
auto info_entry = new StatisticEntry{};
info_entry->timestamp = system_clock::now();
info_entry->size = uint16_t(pkt.data().length() + pkt.header().length() + pkt.mac().length());
info_entry->size = uint16_t(size);
auto index = typeIndex(pkt.type());
this->_log_outgoing_packet(info_entry, index);
this->_log_outgoing_packet(info_entry, category);
}
void ConnectionStatistics::_log_outgoing_packet(ts::stats::StatisticEntry *info_entry, int8_t index) {
if(index >= 0 && index <= 3) {
this->connection_packets_sent[index] ++;
@ -157,7 +145,7 @@ void ConnectionStatistics::_log_outgoing_packet(ts::stats::StatisticEntry *info_
}
/* file transfer */
void ConnectionStatistics::logFileTransfareIn(uint64_t bytes) {
void ConnectionStatistics::logFileTransferIn(uint64_t bytes) {
auto info_entry = new StatisticEntry{};
info_entry->timestamp = system_clock::now();
info_entry->size = bytes;
@ -180,7 +168,7 @@ void ConnectionStatistics::_log_incoming_file_packet(ts::stats::StatisticEntry *
this->handle->_log_incoming_file_packet(info_entry);
}
void ConnectionStatistics::logFileTransfareOut(uint64_t bytes) {
void ConnectionStatistics::logFileTransferOut(uint64_t bytes) {
auto info_entry = new StatisticEntry{};
info_entry->timestamp = system_clock::now();
info_entry->size = bytes;
@ -306,6 +294,22 @@ DataSummery ConnectionStatistics::dataReport() {
return report;
}
FullReport ConnectionStatistics::full_report() {
FullReport report{};
for(size_t index = 0 ; index < 4; index++) {
report.connection_bytes_sent[index] = (uint64_t) this->connection_bytes_sent[index];
report.connection_packets_sent[index] = (uint64_t) this->connection_packets_sent[index];
report.connection_bytes_received[index] = (uint64_t) this->connection_bytes_received[index];
report.connection_packets_received[index] = (uint64_t) this->connection_packets_received[index];
}
report.file_bytes_sent = this->file_bytes_sent;
report.file_bytes_received = this->file_bytes_received;
return report;
}
std::pair<uint64_t, uint64_t> ConnectionStatistics::mark_file_bytes() {
std::pair<uint64_t, uint64_t> result;

View File

@ -28,21 +28,52 @@ namespace ts {
uint32_t file_send;
};
struct FullReport {
uint64_t connection_packets_sent[4]{0, 0, 0, 0};
uint64_t connection_bytes_sent[4]{0, 0, 0, 0};
uint64_t connection_packets_received[4]{0, 0, 0, 0};
uint64_t connection_bytes_received[4]{0, 0, 0, 0};
uint64_t file_bytes_sent = 0;
uint64_t file_bytes_received = 0;
};
class ConnectionStatistics {
public:
struct category {
enum value {
COMMAND,
ACK,
VOICE,
UNKNOWN
};
inline static category::value from_type(const protocol::PacketTypeInfo& type){
if(type == protocol::PacketTypeInfo::Command || type == protocol::PacketTypeInfo::CommandLow)
return value::COMMAND;
else if(type == protocol::PacketTypeInfo::Ack || type == protocol::PacketTypeInfo::AckLow)
return value::ACK;
else if(type == protocol::PacketTypeInfo::Voice || type == protocol::PacketTypeInfo::VoiceWhisper)
return value::VOICE;
return value::UNKNOWN;
}
};
explicit ConnectionStatistics(const std::shared_ptr<ConnectionStatistics>& /* root */, bool /* spawn properties */);
~ConnectionStatistics();
std::shared_ptr<Properties> statistics();
void logIncomingPacket(const protocol::ClientPacket&);
void logOutgoingPacket(const protocol::ServerPacket&);
void logFileTransfareIn(uint64_t);
void logFileTransfareOut(uint64_t);
inline void logIncomingPacket(const protocol::ClientPacket& packet) { this->logIncomingPacket(category::from_type(packet.type()), packet.length()); }
void logIncomingPacket(const category::value& /* category */, size_t /* length */);
inline void logOutgoingPacket(const protocol::ServerPacket& packet) { this->logOutgoingPacket(category::from_type(packet.type()), packet.length()); }
void logOutgoingPacket(const category::value& /* category */, size_t /* length */);
void logFileTransferIn(uint64_t);
void logFileTransferOut(uint64_t);
void tick();
DataSummery dataReport();
FullReport full_report();
std::pair<uint64_t, uint64_t> mark_file_bytes();
@ -51,28 +82,6 @@ namespace ts {
inline bool has_properties() { return !!this->properties; }
private:
class spin_lock {
std::atomic_flag locked = ATOMIC_FLAG_INIT;
public:
void lock() {
uint8_t round = 0;
while (locked.test_and_set(std::memory_order_acquire)) {
//Yield when we're using this lock for a longer time, which we usually not doing
if(round++ % 8 == 0)
std::this_thread::yield();
}
}
inline bool try_lock() {
return !locked.test_and_set(std::memory_order_acquire);
}
void unlock() {
locked.clear(std::memory_order_release);
}
};
typedef spin_lock fast_lock_t;
bool _measure_bandwidths = true;
std::shared_ptr<ConnectionStatistics> handle;
std::shared_ptr<Properties> properties;
@ -89,8 +98,8 @@ namespace ts {
std::atomic<uint64_t> mark_file_bytes_sent = 0;
std::atomic<uint64_t> mark_file_bytes_received = 0;
fast_lock_t history_lock_outgoing;
fast_lock_t history_lock_incoming;
spin_lock history_lock_outgoing;
spin_lock history_lock_incoming;
std::deque<StatisticEntry*> history_file_incoming{};
std::deque<StatisticEntry*> history_file_outgoing{};
std::deque<StatisticEntry*> history_incoming{};

View File

@ -20,6 +20,7 @@
#include <misc/digest.h>
#include <misc/base64.h>
#include <misc/rnd.h>
#include <misc/strobf.h>
#include <jemalloc/jemalloc.h>
#ifndef _POSIX_SOURCE
@ -479,7 +480,7 @@ void InstanceHandler::tickInstance() {
this->dbHelper->tick();
}
{
ALARM_TIMER(t, "InstanceHandler::tickInstance -> license tick", milliseconds(5));
ALARM_TIMER(t, strobf("InstanceHandler::tickInstance -> license tick").string(), milliseconds(5));
this->licenseHelper->tick();
}
}

View File

@ -67,6 +67,7 @@ namespace build {
int buildCount(){ return BUILD_COUNT; }
std::string pattern(){
return R"([0-9]{1,5}\.[0-9]{1,5}\.[0-9]{1,5}(\-.*)?)";
//return R"([0-9]{1,5}\.[0-9]{1,5}\.[0-9]{1,5}(\-.*)?)";
return R"([0-9]{1,5}\.[0-9]{1,5}\.[0-9]{1,5}(-\S+( \[[Bb]uild: \d+\])?)?)";
}
}

View File

@ -31,6 +31,7 @@
#include <misc/digest.h>
#include <misc/rnd.h>
#include <misc/timer.h>
#include <misc/strobf.h>
#include <bbcode/bbcodes.h>
namespace fs = std::experimental::filesystem;
@ -4130,6 +4131,7 @@ CommandResult ConnectedClient::handleCommandBanTriggerList(ts::Command &cmd) {
CMD_RESET_IDLE;
CMD_CHK_AND_INC_FLOOD_POINTS(25);
CACHED_PERM_CHECK(permission::b_client_ban_trigger_list, 1, true);
CMD_REQ_PARM("banid");
auto record = serverInstance->banManager()->findBanById(this->getServerId(), cmd["banid"]);
@ -6199,7 +6201,7 @@ CommandResult ConnectedClient::handleCommandMusicBotCreate(Command& cmd) {
if(config::license->isPremium())
return {findError("music_limit_reached"), ""};
else
return {findError("music_limit_reached"), "You reached the server music bot limit. You could increase this limit by extend your server with a premium license."};
return {findError("music_limit_reached"), strobf("You reached the server music bot limit. You could increase this limit by extend your server with a premium license.").string()};
}

View File

@ -255,7 +255,10 @@ bool ConnectedClient::notifyConnectionInfo(const shared_ptr<ConnectedClient> &ta
Command notify("notifyconnectioninfo");
notify["clid"] = target->getClientId();
/* we deliver data to the web client as well, because its a bit dump :D */
if(target->getClientId() != this->getClientId()) {
auto report = target->connectionStatistics->full_report();
/* default values which normally sets the client */
notify["connection_bandwidth_received_last_minute_control"] = -1;
notify["connection_bandwidth_received_last_minute_keepalive"] = -1;
@ -271,6 +274,7 @@ bool ConnectedClient::notifyConnectionInfo(const shared_ptr<ConnectedClient> &ta
notify["connection_bandwidth_sent_last_second_keepalive"] = -1;
notify["connection_bandwidth_sent_last_second_speech"] = -1;
/* its flipped here because the report is out of the clients view */
notify["connection_bytes_received_control"] = -1;
notify["connection_bytes_received_keepalive"] = -1;
notify["connection_bytes_received_speech"] = -1;
@ -278,6 +282,7 @@ bool ConnectedClient::notifyConnectionInfo(const shared_ptr<ConnectedClient> &ta
notify["connection_bytes_sent_keepalive"] = -1;
notify["connection_bytes_sent_speech"] = -1;
/* its flipped here because the report is out of the clients view */
notify["connection_packets_received_control"] = -1;
notify["connection_packets_received_keepalive"] = -1;
notify["connection_packets_received_speech"] = -1;
@ -296,22 +301,43 @@ bool ConnectedClient::notifyConnectionInfo(const shared_ptr<ConnectedClient> &ta
notify["connection_connected_time"] = 0;
notify["connection_idle_time"] = 0;
notify["connection_filetransfer_bandwidth_sent"] = 0;
notify["connection_filetransfer_bandwidth_received"] = 0;
if(info) {
for(const auto& elm : info->properties) {
notify[elm.first] = elm.second;
}
} else {
//Fill in some server stuff
if(dynamic_pointer_cast<VoiceClient>(target))
notify["connection_ping"] = floor<milliseconds>(dynamic_pointer_cast<VoiceClient>(target)->calculatePing()).count();
else if(dynamic_pointer_cast<WebClient>(target))
notify["connection_ping"] = floor<milliseconds>(dynamic_pointer_cast<WebClient>(target)->client_ping()).count();
}
/* its flipped here because the report is out of the clients view */
notify["connection_filetransfer_bandwidth_sent"] = report.file_bytes_received;
notify["connection_filetransfer_bandwidth_received"] = report.file_bytes_sent;
}
if(info) {
for(const auto& elm : info->properties) {
notify[elm.first] = elm.second;
}
} else {
//Fill in some server stuff
if(dynamic_pointer_cast<VoiceClient>(target))
notify["connection_ping"] = floor<milliseconds>(dynamic_pointer_cast<VoiceClient>(target)->calculatePing()).count();
else if(dynamic_pointer_cast<WebClient>(target))
notify["connection_ping"] = floor<milliseconds>(dynamic_pointer_cast<WebClient>(target)->client_ping()).count();
if(target->getType() == ClientType::CLIENT_TEASPEAK || target->getType() == ClientType::CLIENT_TEAMSPEAK || target->getType() == ClientType::CLIENT_WEB) {
auto report = target->connectionStatistics->full_report();
/* its flipped here because the report is out of the clients view */
notify["connection_bytes_received_control"] = report.connection_bytes_sent[stats::ConnectionStatistics::category::COMMAND];
notify["connection_bytes_received_keepalive"] = report.connection_bytes_sent[stats::ConnectionStatistics::category::ACK];
notify["connection_bytes_received_speech"] = report.connection_bytes_sent[stats::ConnectionStatistics::category::VOICE];
notify["connection_bytes_sent_control"] = report.connection_bytes_sent[stats::ConnectionStatistics::category::COMMAND];
notify["connection_bytes_sent_keepalive"] = report.connection_bytes_sent[stats::ConnectionStatistics::category::ACK];
notify["connection_bytes_sent_speech"] = report.connection_bytes_sent[stats::ConnectionStatistics::category::VOICE];
/* its flipped here because the report is out of the clients view */
notify["connection_packets_received_control"] = report.connection_packets_sent[stats::ConnectionStatistics::category::COMMAND];
notify["connection_packets_received_keepalive"] = report.connection_packets_sent[stats::ConnectionStatistics::category::ACK];
notify["connection_packets_received_speech"] = report.connection_packets_sent[stats::ConnectionStatistics::category::VOICE];
notify["connection_packets_sent_control"] = report.connection_packets_sent[stats::ConnectionStatistics::category::COMMAND];
notify["connection_packets_sent_keepalive"] = report.connection_packets_sent[stats::ConnectionStatistics::category::ACK];
notify["connection_packets_sent_speech"] = report.connection_packets_sent[stats::ConnectionStatistics::category::VOICE];
}
}
if(target->getClientId() == this->getClientId() || this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_client_remoteaddress_view, 1, target->currentChannel, true)) {
notify["connection_client_ip"] = target->getLoggingPeerIp();
notify["connection_client_port"] = target->getPeerPort();

View File

@ -2,6 +2,7 @@
#include <iomanip>
#include <netinet/in.h>
#include <log/LogUtils.h>
#include <misc/strobf.h>
#include "../InstanceHandler.h"
#include "../manager/ConversationManager.h"
@ -46,7 +47,7 @@ if(!var) { \
return true; \
} \
if(!ignore_disabled && var->properties()[property::CLIENT_DISABLED].as<bool>()) { \
send_message(serverInstance->musicRoot(), "This bot has been disabled. Upgrade your TeaSpeak license to use more bots."); \
send_message(serverInstance->musicRoot(), strobf("This bot has been disabled. Upgrade your TeaSpeak license to use more bots.").string()); \
return true; \
}

View File

@ -353,7 +353,7 @@ bool FileClient::tick() {
}
this->bytesHandled += read;
this->client->getConnectionStatistics()->logFileTransfareOut(read);
this->client->getConnectionStatistics()->logFileTransferOut(read);
if(read > 0){
writeBuffer.resize(read);
this->sendMessage(writeBuffer);
@ -449,7 +449,7 @@ bool FileClient::applyKey(const string &key) {
bool FileClient::uploadWriteBytes(const pipes::buffer_view& message) {
this->client->getConnectionStatistics()->logFileTransfareIn(message.length());
this->client->getConnectionStatistics()->logFileTransferIn(message.length());
if(!fstream->good()){
logError(LOG_FT, "{} uploadWriteBytes(...) called with invalid fstream!", this->client_prefix());
return false;

View File

@ -103,6 +103,7 @@ void WebClient::enqueue_raw_packet(const pipes::buffer_view &msg) {
if(this->writeEvent)
event_add(this->writeEvent, nullptr);
}
this->connectionStatistics->logOutgoingPacket(stats::ConnectionStatistics::category::COMMAND, buffer.length());
}
void WebClient::registerMessageProcess() {
@ -136,6 +137,7 @@ void WebClient::processNextMessage(const std::chrono::system_clock::time_point&
bool has_next = !this->queue_read.empty();
buffer_lock.unlock();
this->connectionStatistics->logIncomingPacket(stats::ConnectionStatistics::category::COMMAND, buffer.length());
if(!this->ssl_detected) {
this->ssl_detected = true;
this->ssl_encrypted = is_ssl_handshake_header(buffer);

View File

@ -451,6 +451,8 @@ void WebClient::handleMessage(const std::string &message) {
this->voice_bridge = make_unique<web::VoiceBridge>(dynamic_pointer_cast<WebClient>(_this.lock())); //FIXME Add config
this->voice_bridge->callback_voice_data = [&](const pipes::buffer_view& buffer, bool a, bool b) {
/* may somehow get the "real" packet size? */
this->connectionStatistics->logIncomingPacket(stats::ConnectionStatistics::category::VOICE, buffer.length());
this->handlePacketVoice(buffer, a, b);
};
this->voice_bridge->callback_initialized = [&](){
@ -637,10 +639,15 @@ void WebClient::send_voice_packet(const pipes::buffer_view &view, const Speaking
shared_lock read_voice_bridge_lock(this->voice_bridge_lock);
if(this->voice_bridge) {
auto channel = this->voice_bridge->voice_channel();
if(channel) channel->send(view);
if(channel) {
channel->send(view);
/* may somehow get the "real" packet size? */
this->connectionStatistics->logOutgoingPacket(stats::ConnectionStatistics::category::VOICE, view.length());
}
}
}
void WebClient::send_voice_whisper_packet(const pipes::buffer_view &view, const SpeakingClient::VoicePacketFlags &flags) {
logError(this->server->getServerId(), "Web client got whisper packet");
//As well log the data!
}

View File

@ -1,4 +1,5 @@
#include <log/LogUtils.h>
#include <misc/strobf.h>
#include <src/Configuration.h>
#include <arpa/inet.h>
#include <src/SignalHandler.h>
@ -50,7 +51,7 @@ void LicenseHelper::tick() {
if(promise.state() != threads::FutureState::WORKING){
auto exception = this->request.current->exception();
if(promise.state() == threads::FutureState::FAILED) {
this->handle_request_failed(verbose, exception ? exception->what() : "unknown");
this->handle_request_failed(verbose, exception ? exception->what() : strobf("unknown").c_str());
this->request.current = nullptr; /* connection should be already closed */
return;
} else {
@ -58,23 +59,23 @@ void LicenseHelper::tick() {
this->request.current = nullptr; /* connection should be already closed */
if(!response){
this->handle_request_failed(verbose, exception ? exception->what() : "invalid result (null)");
this->handle_request_failed(verbose, exception ? exception->what() : strobf("invalid result (null)").c_str());
return;
}
if(!response->license_valid || !response->properties_valid){
if(!response->license_valid) {
if(config::license->isPremium()) logCritical("Could not validate license.");
else logCritical("Your server has been shutdown remotely!");
if(config::license->isPremium()) logCritical(strobf("Could not validate license.").c_str());
else logCritical(strobf("Your server has been shutdown remotely!").c_str());
} else if(!response->properties_valid) {
logCritical("Property adjustment failed!");
logCritical(strobf("Property adjustment failed!").c_str());
} else
logCritical("Your license expired!");
logCritical("Stopping application!");
logCritical(strobf("Your license expired!").c_str());
logCritical(strobf("Stopping application!").c_str());
ts::server::shutdownInstance();
return;
} else {
this->scheduled_request = this->last_request + hours(2);
logMessage(LOG_INSTANCE, "License successfully validated! Scheduling next check at {}", format_time(this->scheduled_request));
logMessage(LOG_INSTANCE, strobf("License successfully validated! Scheduling next check at {}").c_str(), format_time(this->scheduled_request));
if(response->speach_reset)
serverInstance->resetSpeechTime();
serverInstance->properties()[property::SERVERINSTANCE_SPOKEN_TIME_VARIANZ] = response->speach_varianz_adjustment;
@ -99,9 +100,9 @@ void LicenseHelper::tick() {
void LicenseHelper::do_request(bool verbose) {
if(verbose) {
if(config::license && config::license->isPremium())
logMessage(LOG_INSTANCE, "Validating license");
logMessage(LOG_INSTANCE, strobf("Validating license").c_str());
else
logMessage(LOG_INSTANCE, "Validating instance integrity");
logMessage(LOG_INSTANCE, strobf("Validating instance integrity").c_str());
}
this->last_request = system_clock::now();
@ -116,7 +117,7 @@ void LicenseHelper::do_request(bool verbose) {
if(verbose) {
auto promise = request->requestInfo();
if(promise.state() == threads::FutureState::WORKING) {
logMessage(LOG_INSTANCE, "Old check timed out (10 min). Running new one!");
logMessage(LOG_INSTANCE, strobf("Old check timed out (10 min). Running new one!").c_str());
}
}
request->abortRequest();
@ -131,26 +132,26 @@ void LicenseHelper::do_request(bool verbose) {
server_addr.sin_family = AF_INET;
#ifdef DO_LOCAL_REQUEST
auto license_host = gethostbyname("localhost");
auto license_host = gethostbyname(strobf("localhost").c_str());
server_addr.sin_addr.s_addr = ((in_addr*) license_host->h_addr)->s_addr;
#else
auto license_host = gethostbyname("license.teaspeak.de");
auto license_host = gethostbyname(strobf("license.teaspeak.de").c_str());
if(!license_host){
if(verbose) logError("Could not valid license! (1)");
if(verbose) logError(strobf("Could not valid license! (1)").c_str());
return;
}
if(!license_host->h_addr){
if(verbose) logError("Could not valid license! (2)");
if(verbose) logError(strobf("Could not valid license! (2)").c_str());
return;
}
server_addr.sin_addr.s_addr = ((in_addr*) license_host->h_addr)->s_addr;
logger::logger(0)->debug("Requesting server {}", inet_ntoa(server_addr.sin_addr));
logger::logger(0)->debug(strobf("Requesting server {}").c_str(), inet_ntoa(server_addr.sin_addr));
int first = server_addr.sin_addr.s_addr >> 24;
if(first == 0 || first == 127 || first == 255) {
if(config::license->isPremium()) {
logError("You tried to nullroot 'license.teaspeak.de'!");
logCritical("Could not validate license!");
logCritical("Stopping server!");
logError(strobf("You tried to nullroot 'license.teaspeak.de'!").c_str());
logCritical(strobf("Could not validate license!").c_str());
logCritical(strobf("Stopping server!").c_str());
ts::server::shutdownInstance();
return;
}
@ -175,9 +176,9 @@ void LicenseHelper::do_request(bool verbose) {
void LicenseHelper::handle_request_failed(bool verbose, const std::string& error) {
if(verbose) {
if(config::license && config::license->isPremium())
logError(LOG_INSTANCE, "License validation failed: {}", error);
logError(LOG_INSTANCE, strobf("License validation failed: {}").c_str(), error);
else
logError(LOG_INSTANCE, "Instance integrity check failed: {}", error);
logError(LOG_INSTANCE, strobf("Instance integrity check failed: {}").c_str(), error);
}
this->request_fail_count++;
milliseconds next_request;
@ -193,5 +194,5 @@ void LicenseHelper::handle_request_failed(bool verbose, const std::string& error
this->scheduled_request = this->last_request + next_request;
if(verbose)
logMessage(LOG_INSTANCE, "Scheduling next check at {}", format_time(this->scheduled_request));
logMessage(LOG_INSTANCE, strobf("Scheduling next check at {}").c_str(), format_time(this->scheduled_request));
}

View File

@ -91,7 +91,7 @@ inline deque<std::shared_ptr<BanRecord>> resolveBansByQuery(sql::command& comman
if(!res) cerr << res << endl;
debugMessage("Query: " + command.sqlCommand() + " -> " + to_string(result.size()));
debugMessage(LOG_GENERAL, "Query: {} -> {}", command.sqlCommand(), result.size());
return result;
}
@ -263,11 +263,11 @@ void BanManager::trigger_ban(const std::shared_ptr<BanRecord>& record,
variable{":hid", hardware_id},
variable{":name", nickname},
variable{":ip", ip},
variable{":timestamp", duration_cast<milliseconds>(record->until.time_since_epoch()).count()}
variable{":timestamp", duration_cast<milliseconds>(chrono::system_clock::now().time_since_epoch()).count()}
).executeLater().waitAndGetLater(LOG_SQL_CMD, {1, "future failed"});
record->triggered++;
sql::command(this->sql, "UPDATE `bannedClients` SET `triggered` = :triggered WHERE `banId` = :bid AND `serverId` = :sid",
sql::command(this->sql, "UPDATE `bannedClients` SET `triggered` = :triggered WHERE `banId` = :banId AND `serverId` = :sid",
variable{":sid", record->serverId},
variable{":banId", record->banId},
variable{":triggered", record->triggered}

View File

@ -46,6 +46,15 @@ namespace interaction {
*(DefaultMemoryInfo*) SHARED_MEMORY_PTR = DefaultMemoryInfo{};
info = (DefaultMemoryInfo*) SHARED_MEMORY_PTR;
/* initialize the mutex */
{
pthread_mutexattr_t attr{};
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
pthread_mutexattr_setpshared(&attr, true);
pthread_mutex_init(&info->memoryLock, &attr);
}
pthread_mutex_lock(&info->memoryLock);
memset(info->infoUsed, 0, sizeof(info->infoUsed) / sizeof(info->infoUsed[0]));
} else {

View File

@ -14,7 +14,7 @@ namespace interaction {
template <size_t N>
struct MemoryInfo {
pthread_mutex_t memoryLock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t memoryLock;
size_t instanceCount = 0;
size_t maxInstances = N;

2
shared

@ -1 +1 @@
Subproject commit c117799cc9b391ec8072db35bbd0558aba7dff53
Subproject commit 316afd9f5649448798f1e15fbd2cac171623aaac