Changed some stuff
This commit is contained in:
parent
6172628247
commit
7926a26091
2
music
2
music
@ -1 +1 @@
|
||||
Subproject commit ae7f8c7f3d4121704d229cd8995ec33e4824841b
|
||||
Subproject commit ad24c38923afe23d94452973337a416540e3c7aa
|
@ -4,6 +4,7 @@ project(TeaSpeak-Server)
|
||||
set(CMAKE_VERBOSE_MAKEFILE ON)
|
||||
#--allow-multiple-definition
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive -Wall -Wno-reorder -Wno-sign-compare -static-libgcc -static-libstdc++ -g -Wl,--no-whole-archive -pthread ${MEMORY_DEBUG_FLAGS} -Werror=return-type")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--unresolved-symbols=ignore-all")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3")
|
||||
|
||||
@ -43,7 +44,7 @@ set(SERVER_SOURCE_FILES
|
||||
# MySQLLibSSLFix.c
|
||||
|
||||
src/client/ConnectedClient.cpp
|
||||
src/client/voice/PrecomputedPuzzles.cpp
|
||||
src/server/udp-server/PrecomputedPuzzles.cpp
|
||||
src/client/voice/VoiceClient.cpp
|
||||
src/client/voice/VoiceClientHandschake.cpp
|
||||
src/client/voice/VoiceClientCommandHandler.cpp
|
||||
@ -160,7 +161,7 @@ if (COMPILE_WEB_CLIENT)
|
||||
src/client/web/WSWebClient.cpp
|
||||
src/client/web/SampleHandler.cpp
|
||||
src/client/web/VoiceBridge.cpp
|
||||
src/client/command_handler/helpers.h src/music/PlaylistPermissions.cpp src/music/PlaylistPermissions.h src/lincense/LicenseService.cpp src/lincense/LicenseService.h src/groups/GroupManager.cpp src/groups/GroupManager.h src/groups/GroupAssignmentManager.cpp src/groups/GroupAssignmentManager.h src/groups/Group.cpp src/groups/Group.h src/services/VirtualServerInformation.cpp src/services/VirtualServerInformation.h src/vserver/VirtualServerManager.cpp src/vserver/VirtualServerManager.h)
|
||||
src/client/command_handler/helpers.h src/music/PlaylistPermissions.cpp src/music/PlaylistPermissions.h src/lincense/LicenseService.cpp src/lincense/LicenseService.h src/groups/GroupManager.cpp src/groups/GroupManager.h src/groups/GroupAssignmentManager.cpp src/groups/GroupAssignmentManager.h src/groups/Group.cpp src/groups/Group.h src/services/VirtualServerInformation.cpp src/services/VirtualServerInformation.h src/vserver/VirtualServerManager.cpp src/vserver/VirtualServerManager.h src/services/VirtualServerBroadcastService.cpp src/services/VirtualServerBroadcastService.h src/server/udp-server/UDPServer.cpp src/server/udp-server/UDPServer.h)
|
||||
endif ()
|
||||
|
||||
add_executable(PermHelper helpers/permgen.cpp)
|
||||
|
@ -231,13 +231,12 @@ inline sql::result load_permissions_v2(VirtualServerId server_id, v2::Permission
|
||||
#define INSERT_COMMAND "INSERT INTO `permissions` (`serverId`, `type`, `id`, `channelId`, `permId`, `value`, `grant`, `flag_skip`, `flag_negate`) VALUES (:serverId, :type, :id, :chId, :permId, :value, :grant, :flag_skip, :flag_negate)"
|
||||
#define DELETE_COMMAND "DELETE FROM `permissions` WHERE `serverId` = :serverId AND `type` = :type AND `id` = :id AND `permId` = :permId AND `channelId` = :chId"
|
||||
|
||||
std::shared_ptr<v2::PermissionRegister> DatabaseHelper::loadClientPermissionManager(const std::shared_ptr<VirtualServer>& server, ClientDbId cldbid) {
|
||||
auto server_id = server ? server->getServerId() : 0;
|
||||
std::shared_ptr<v2::PermissionRegister> DatabaseHelper::loadClientPermissionManager(VirtualServerId server_id, ClientDbId cldbid) {
|
||||
#ifndef DISABLE_CACHING
|
||||
{
|
||||
lock_guard<threads::Mutex> lock(permManagerLock);
|
||||
for(auto permMgr : this->cachedPermissionManagers)
|
||||
if(permMgr->cldbid == cldbid && permMgr->sid == (server ? server->getServerId() : 0)) {
|
||||
if(permMgr->cldbid == cldbid && permMgr->sid == server_id) {
|
||||
auto ptr = permMgr->manager.lock();
|
||||
if(!ptr){
|
||||
this->cachedPermissionManagers.erase(std::find(this->cachedPermissionManagers.begin(), this->cachedPermissionManagers.end(), permMgr));
|
||||
@ -253,12 +252,12 @@ std::shared_ptr<v2::PermissionRegister> DatabaseHelper::loadClientPermissionMana
|
||||
logTrace(server_id, "[Permission] Loading client permission manager for client {}", cldbid);
|
||||
auto permission_manager = std::make_shared<v2::PermissionRegister>();
|
||||
bool loaded = false;
|
||||
if(this->use_startup_cache && server) {
|
||||
if(this->use_startup_cache) {
|
||||
shared_ptr<StartupCacheEntry> entry;
|
||||
{
|
||||
threads::MutexLock lock(this->startup_lock);
|
||||
for(const auto& entries : this->startup_entries) {
|
||||
if(entries->sid == server->getServerId()) {
|
||||
if(entries->sid == server_id) {
|
||||
entry = entries;
|
||||
break;
|
||||
}
|
||||
@ -267,10 +266,8 @@ std::shared_ptr<v2::PermissionRegister> DatabaseHelper::loadClientPermissionMana
|
||||
if(entry) {
|
||||
for(const auto& perm : entry->permissions) {
|
||||
if(perm->type == permission::SQL_PERM_USER && perm->id == cldbid) {
|
||||
auto channel = perm->channelId > 0 ? server->getChannelTree()->findChannel(perm->channelId) : nullptr;
|
||||
|
||||
if(channel)
|
||||
permission_manager->load_permission(perm->permission->type, {perm->value, perm->grant}, channel->channelId(), perm->flag_skip, perm->flag_negate, perm->value != permNotGranted, perm->grant != permNotGranted);
|
||||
if(perm->channelId > 0)
|
||||
permission_manager->load_permission(perm->permission->type, {perm->value, perm->grant}, perm->channelId, perm->flag_skip, perm->flag_negate, perm->value != permNotGranted, perm->grant != permNotGranted);
|
||||
else
|
||||
permission_manager->load_permission(perm->permission->type, {perm->value, perm->grant}, perm->flag_skip, perm->flag_negate, perm->value != permNotGranted, perm->grant != permNotGranted);
|
||||
}
|
||||
@ -281,10 +278,10 @@ std::shared_ptr<v2::PermissionRegister> DatabaseHelper::loadClientPermissionMana
|
||||
|
||||
if(!loaded) {
|
||||
auto command = sql::command(this->sql, "SELECT `permId`, `value`, `channelId`, `grant`, `flag_skip`, `flag_negate` FROM `permissions` WHERE `serverId` = :serverId AND `type` = :type AND `id` = :id",
|
||||
variable{":serverId", server ? server->getServerId() : 0},
|
||||
variable{":serverId", server_id},
|
||||
variable{":type", permission::SQL_PERM_USER},
|
||||
variable{":id", cldbid});
|
||||
LOG_SQL_CMD(load_permissions_v2(server ? server->getServerId() : 0, permission_manager.get(), command, true));
|
||||
LOG_SQL_CMD(load_permissions_v2(server_id, permission_manager.get(), command, true));
|
||||
}
|
||||
|
||||
|
||||
@ -303,12 +300,11 @@ std::shared_ptr<v2::PermissionRegister> DatabaseHelper::loadClientPermissionMana
|
||||
}
|
||||
|
||||
|
||||
void DatabaseHelper::saveClientPermissions(const std::shared_ptr<ts::server::VirtualServer> &server, ts::ClientDbId client_dbid, const std::shared_ptr<ts::permission::v2::PermissionRegister> &permissions) {
|
||||
void DatabaseHelper::saveClientPermissions(VirtualServerId server_id, ts::ClientDbId client_dbid, const std::shared_ptr<ts::permission::v2::PermissionRegister> &permissions) {
|
||||
const auto updates = permissions->flush_db_updates();
|
||||
if(updates.empty())
|
||||
return;
|
||||
|
||||
auto server_id = server ? server->getServerId() : 0;
|
||||
for(auto& update : updates) {
|
||||
std::string query = update.flag_delete ? DELETE_COMMAND : (update.flag_db ? UPDATE_COMMAND : INSERT_COMMAND);
|
||||
|
||||
@ -323,7 +319,7 @@ void DatabaseHelper::saveClientPermissions(const std::shared_ptr<ts::server::Vir
|
||||
query
|
||||
);
|
||||
sql::command(this->sql, query,
|
||||
variable{":serverId", server ? server->getServerId() : 0},
|
||||
variable{":serverId", server_id},
|
||||
variable{":id", client_dbid},
|
||||
variable{":chId", update.channel_id},
|
||||
variable{":type", permission::SQL_PERM_USER},
|
||||
|
@ -91,8 +91,8 @@ namespace ts {
|
||||
std::deque<std::shared_ptr<ClientDatabaseInfo>> queryDatabaseInfo(const std::shared_ptr<VirtualServer>&, const std::deque<ClientDbId>&);
|
||||
std::deque<std::shared_ptr<ClientDatabaseInfo>> queryDatabaseInfoByUid(const std::shared_ptr<VirtualServer> &, std::deque<std::string>);
|
||||
|
||||
std::shared_ptr<permission::v2::PermissionRegister> loadClientPermissionManager(const std::shared_ptr<VirtualServer>&, ClientDbId);
|
||||
void saveClientPermissions(const std::shared_ptr<VirtualServer>&, ClientDbId , const std::shared_ptr<permission::v2::PermissionRegister>& /* permission manager */);
|
||||
std::shared_ptr<permission::v2::PermissionRegister> loadClientPermissionManager(VirtualServerId, ClientDbId);
|
||||
void saveClientPermissions(VirtualServerId, ClientDbId , const std::shared_ptr<permission::v2::PermissionRegister>& /* permission manager */);
|
||||
|
||||
std::shared_ptr<permission::v2::PermissionRegister> loadChannelPermissions(const std::shared_ptr<VirtualServer>&, ChannelId);
|
||||
void saveChannelPermissions(const std::shared_ptr<VirtualServer>&, ChannelId, const std::shared_ptr<permission::v2::PermissionRegister>& /* permission manager */);
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "src/client/ConnectedClient.h"
|
||||
#include "InstanceHandler.h"
|
||||
#include "src/server/file/FileServer.h"
|
||||
#include "src/groups/Group.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace std::chrono;
|
||||
@ -212,7 +213,7 @@ int GroupManager::insertGroupFromDb(int count, char **values, char **column) {
|
||||
|
||||
group->properties()[property::GROUP_NAME] = targetName;
|
||||
|
||||
group->setPermissionManager(serverInstance->databaseHelper()->loadGroupPermissions(this->server.lock(), group->groupId()));
|
||||
group->setPermissionManager(serverInstance->databaseHelper()->loadGroupPermissions(this->server.lock() ? this->server.lock()->getServerId() : 0, group->groupId(), (uint8_t) -1));
|
||||
|
||||
debugMessage(this->getServerId(), "Push back group -> " + to_string(group->groupId()) + " - " + group->name());
|
||||
this->groups.push_back(group);
|
||||
@ -304,7 +305,7 @@ std::shared_ptr<Group> GroupManager::createGroup(GroupTarget target, GroupType t
|
||||
|
||||
std::shared_ptr<Group> group = std::make_shared<Group>(this, target, type, groupId);
|
||||
group->properties()[property::GROUP_NAME] = name;
|
||||
group->setPermissionManager(serverInstance->databaseHelper()->loadGroupPermissions(this->server.lock(), group->groupId()));
|
||||
group->setPermissionManager(serverInstance->databaseHelper()->loadGroupPermissions(this->server.lock() ? this->server.lock()->getServerId() : 0, group->groupId(), (uint8_t) -1));
|
||||
this->groups.push_back(group);
|
||||
return group;
|
||||
}
|
||||
@ -344,7 +345,7 @@ bool GroupManager::copyGroupPermissions(const shared_ptr<Group> &source, const s
|
||||
res = sql::command(this->sql, "INSERT INTO `permissions` (`serverId`, `type`, `id`, `channelId`, `permId`, `value`, `grant`) SELECT :tsid AS `serverId`, `type`, :target AS `id`, 0 AS `channelId`, `permId`, `value`,`grant` FROM `permissions` WHERE `serverId` = :ssid AND `type` = :type AND `id` = :source",
|
||||
variable{":ssid", sourceServer}, variable{":tsid", targetServer}, variable{":type", SQL_PERM_GROUP}, variable{":source", source->groupId()}, variable{":target", target->groupId()}).execute();
|
||||
|
||||
target->setPermissionManager(serverInstance->databaseHelper()->loadGroupPermissions(target->handle->server.lock(), target->groupId()));
|
||||
target->setPermissionManager(serverInstance->databaseHelper()->loadGroupPermissions(target->handle->server.lock() ? target->handle->server.lock()->getServerId() : 0, target->groupId(), (uint8_t) -1));
|
||||
LOG_SQL_CMD(res);
|
||||
return true;
|
||||
}
|
||||
@ -355,7 +356,7 @@ bool GroupManager::reloadGroupPermissions(std::shared_ptr<Group> group) {
|
||||
return false;
|
||||
}
|
||||
|
||||
group->setPermissionManager(serverInstance->databaseHelper()->loadGroupPermissions(this->server.lock(), group->groupId()));
|
||||
group->setPermissionManager(serverInstance->databaseHelper()->loadGroupPermissions(this->server.lock() ? this->server.lock()->getServerId() : 0, group->groupId(), (uint8_t) -1));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -457,11 +458,6 @@ std::deque<property::ClientProperties> GroupManager::update_server_group_propert
|
||||
unique_lock chan_lock(client->channel_lock, defer_lock);
|
||||
if(channel_lock)
|
||||
chan_lock.lock();
|
||||
|
||||
client->cached_server_groups.clear();
|
||||
client->cached_server_groups.reserve(groups.size());
|
||||
for(const auto& group : groups)
|
||||
client->cached_server_groups.push_back(group->group->groupId());
|
||||
}
|
||||
|
||||
}
|
||||
@ -480,8 +476,6 @@ std::deque<property::ClientProperties> GroupManager::update_server_group_propert
|
||||
unique_lock chan_lock(client->channel_lock, defer_lock);
|
||||
if(channel_lock)
|
||||
chan_lock.lock();
|
||||
|
||||
client->cached_channel_group = group->group->groupId();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -188,7 +188,7 @@ InstanceHandler::InstanceHandler(SqlDataManager *sql) : sql(sql) {
|
||||
this->properties()[property::SERVERINSTANCE_MONTHLY_TIMESTAMP] = duration_cast<seconds>(system_clock::now().time_since_epoch()).count();
|
||||
}
|
||||
|
||||
this->banMgr = new BanManager(this->getSql());
|
||||
this->banMgr = new bans::BanManager(this->getSql());
|
||||
this->banMgr->loadBans();
|
||||
|
||||
this->web_list = make_shared<weblist::WebListManager>();
|
||||
@ -569,7 +569,7 @@ void InstanceHandler::save_group_permissions() {
|
||||
auto permissions = group->permissions();
|
||||
if(permissions->require_db_updates()) {
|
||||
auto begin = system_clock::now();
|
||||
serverInstance->databaseHelper()->saveGroupPermissions(nullptr, group->groupId(), permissions);
|
||||
serverInstance->databaseHelper()->saveGroupPermissions(0, group->groupId(), permissions);
|
||||
auto end = system_clock::now();
|
||||
debugMessage(0, "Saved instance group permissions for group {} ({}) in {}ms", group->groupId(), group->name(), duration_cast<milliseconds>(end - begin).count());
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ namespace ts {
|
||||
FileServer* getFileServer(){ return fileServer; }
|
||||
QueryServer* getQueryServer(){ return queryServer; }
|
||||
DatabaseHelper* databaseHelper(){ return this->dbHelper; }
|
||||
BanManager* banManager(){ return this->banMgr; }
|
||||
bans::BanManager* banManager(){ return this->banMgr; }
|
||||
ssl::SSLManager* sslManager(){ return this->sslMgr; }
|
||||
sql::SqlManager* getSql(){ return sql->sql(); }
|
||||
|
||||
@ -114,7 +114,7 @@ namespace ts {
|
||||
QueryServer* queryServer = nullptr;
|
||||
VirtualServerManager* voiceServerManager = nullptr;
|
||||
DatabaseHelper* dbHelper = nullptr;
|
||||
BanManager* banMgr = nullptr;
|
||||
bans::BanManager* banMgr = nullptr;
|
||||
ssl::SSLManager* sslMgr = nullptr;
|
||||
|
||||
ts::Properties* _properties = nullptr;
|
||||
|
@ -122,7 +122,7 @@ bool VirtualServer::unregisterClient(shared_ptr<ConnectedClient> cl, std::string
|
||||
this->client_move(cl, nullptr, nullptr, reason, ViewReasonId::VREASON_SERVER_LEFT, false, chan_tree_lock);
|
||||
}
|
||||
|
||||
serverInstance->databaseHelper()->saveClientPermissions(this->ref(), cl->getClientDatabaseId(), cl->clientPermissions);
|
||||
serverInstance->databaseHelper()->saveClientPermissions(this->serverId, cl->getClientDatabaseId(), cl->clientPermissions);
|
||||
cl->setClientId(0);
|
||||
return true;
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ void VirtualServer::executeServerTick() {
|
||||
|
||||
if(cl->clientPermissions->require_db_updates()) {
|
||||
auto begin = system_clock::now();
|
||||
serverInstance->databaseHelper()->saveClientPermissions(this->ref(), cl->getClientDatabaseId(), cl->clientPermissions);
|
||||
serverInstance->databaseHelper()->saveClientPermissions(this->serverId, cl->getClientDatabaseId(), cl->clientPermissions);
|
||||
auto end = system_clock::now();
|
||||
debugMessage(this->serverId, "Saved client permissions for client {} ({}) in {}ms", cl->getClientDatabaseId(), cl->getDisplayName(), duration_cast<milliseconds>(end - begin).count());
|
||||
}
|
||||
@ -250,7 +250,7 @@ void VirtualServer::executeServerTick() {
|
||||
auto permissions = group->permissions();
|
||||
if(permissions->require_db_updates()) {
|
||||
auto begin = system_clock::now();
|
||||
serverInstance->databaseHelper()->saveGroupPermissions(this->ref(), group->groupId(), permissions);
|
||||
serverInstance->databaseHelper()->saveGroupPermissions(this->serverId, group->groupId(), permissions);
|
||||
auto end = system_clock::now();
|
||||
debugMessage(this->serverId, "Saved group permissions for group {} ({}) in {}ms", group->groupId(), group->name(), duration_cast<milliseconds>(end - begin).count());
|
||||
}
|
||||
|
@ -792,7 +792,7 @@ vector<pair<ts::permission::PermissionType, ts::permission::v2::PermissionFlagge
|
||||
}
|
||||
|
||||
if(!cache->client_permissions) {
|
||||
cache->client_permissions = serverInstance->databaseHelper()->loadClientPermissionManager(self.lock(), client_dbid);
|
||||
cache->client_permissions = serverInstance->databaseHelper()->loadClientPermissionManager(this->serverId, client_dbid);
|
||||
}
|
||||
|
||||
bool have_skip_permission = false;
|
||||
|
@ -13,7 +13,7 @@ using namespace std::chrono;
|
||||
using namespace ts::server;
|
||||
|
||||
VirtualServerManager::VirtualServerManager(InstanceHandler* handle) : handle(handle) {
|
||||
this->puzzles = new protocol::PuzzleManager();
|
||||
this->puzzles = new server::udp::PuzzleManager();
|
||||
this->handshakeTickers = new threads::Scheduler(1, "handshake ticker");
|
||||
this->execute_loop = new event::EventExecutor("executor #");
|
||||
//this->join_loop = new event::EventExecutor("joiner #");
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
#include <deque>
|
||||
#include <EventLoop.h>
|
||||
#include "client/voice/PrecomputedPuzzles.h"
|
||||
#include "src/server/udp-server/PrecomputedPuzzles.h"
|
||||
#include "server/VoiceIOManager.h"
|
||||
#include "VirtualServer.h"
|
||||
|
||||
@ -57,7 +57,7 @@ namespace ts {
|
||||
bool createServerSnapshot(Command &cmd, std::shared_ptr<VirtualServer> server, int version, std::string &error);
|
||||
std::shared_ptr<VirtualServer> createServerFromSnapshot(std::shared_ptr<VirtualServer> old, std::string, uint16_t, const ts::Command &, std::string &);
|
||||
|
||||
protocol::PuzzleManager* rsaPuzzles() { return this->puzzles; }
|
||||
server::udp::PuzzleManager* rsaPuzzles() { return this->puzzles; }
|
||||
|
||||
event::EventExecutor* get_join_loop() { return this->join_loop; }
|
||||
event::EventExecutor* get_executor_loop() { return this->execute_loop; }
|
||||
@ -80,7 +80,7 @@ namespace ts {
|
||||
InstanceHandler* handle;
|
||||
threads::Mutex instanceLock;
|
||||
std::deque<std::shared_ptr<VirtualServer>> instances;
|
||||
protocol::PuzzleManager* puzzles = nullptr;
|
||||
server::udp::PuzzleManager* puzzles = nullptr;
|
||||
|
||||
event::EventExecutor* execute_loop = nullptr;
|
||||
event::EventExecutor* join_loop = nullptr;
|
||||
|
@ -846,13 +846,13 @@ bool ConnectedClient::handleCommandFull(Command& cmd, bool disconnectOnFail) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<BanRecord> ConnectedClient::resolveActiveBan(const std::string& ip_address) {
|
||||
std::shared_ptr<bans::BanRecord> ConnectedClient::resolveActiveBan(const std::string& ip_address) {
|
||||
if(permission::v2::permission_granted(1, this->calculate_permission(permission::b_client_ignore_bans, 0))) return nullptr;
|
||||
|
||||
//Check if manager banned
|
||||
auto banManager = serverInstance->banManager();
|
||||
shared_ptr<BanRecord> banEntry = nullptr;
|
||||
deque<shared_ptr<BanRecord>> entries;
|
||||
shared_ptr<bans::BanRecord> banEntry = nullptr;
|
||||
deque<shared_ptr<bans::BanRecord>> entries;
|
||||
|
||||
if (!banEntry) {
|
||||
banEntry = banManager->findBanByName(this->server->getServerId(), this->getDisplayName());
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "../channel/ClientChannelView.h"
|
||||
#include "DataClient.h"
|
||||
#include "query/command3.h"
|
||||
#include "src/manager/BanManager.h"
|
||||
|
||||
#define CLIENT_STR_LOG_PREFIX_(this) (std::string("[") + this->getLoggingPeerIp() + ":" + std::to_string(this->getPeerPort()) + "/" + this->getDisplayName() + " | " + std::to_string(this->getClientId()) + "]")
|
||||
#define CLIENT_STR_LOG_PREFIX CLIENT_STR_LOG_PREFIX_(this)
|
||||
@ -244,7 +245,7 @@ namespace ts {
|
||||
virtual void updateChannelClientProperties(bool /* lock channel tree */, bool /* notify our self */);
|
||||
void updateTalkRights(permission::PermissionValue talk_power);
|
||||
|
||||
virtual std::shared_ptr<BanRecord> resolveActiveBan(const std::string& ip_address);
|
||||
virtual std::shared_ptr<bans::BanRecord> resolveActiveBan(const std::string& ip_address);
|
||||
|
||||
inline std::shared_ptr<stats::ConnectionStatistics> getConnectionStatistics() {
|
||||
return this->connectionStatistics;
|
||||
@ -295,7 +296,8 @@ namespace ts {
|
||||
return this->_subscribed_playlist.lock() == playlist;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline auto lock_command_handling() { return std::lock_guard{this->command_lock}; }
|
||||
template <typename T = std::lock_guard<threads::Mutex>>
|
||||
[[nodiscard]] inline auto lock_command_handling() { return T{this->command_lock}; }
|
||||
void increase_join_state() { this->join_state_id++; }
|
||||
protected:
|
||||
std::weak_ptr<ConnectedClient> _this;
|
||||
|
@ -112,7 +112,7 @@ bool DataClient::loadDataForCurrentServer() { //TODO for query
|
||||
}
|
||||
this->_properties->toggleSave(true);
|
||||
|
||||
this->clientPermissions = serverInstance->databaseHelper()->loadClientPermissionManager(ref_server, this->getClientDatabaseId());
|
||||
this->clientPermissions = serverInstance->databaseHelper()->loadClientPermissionManager(ref_server ? ref_server->serverId : 0, this->getClientDatabaseId());
|
||||
|
||||
//Setup / fix stuff
|
||||
if(!this->properties()[property::CLIENT_FLAG_AVATAR].as<string>().empty()){
|
||||
|
@ -98,6 +98,8 @@ namespace ts {
|
||||
|
||||
|
||||
virtual bool loadDataForCurrentServer();
|
||||
|
||||
[[nodiscard]] inline std::shared_ptr<permission::v2::PermissionRegister> permissions() { return this->clientPermissions; }
|
||||
protected:
|
||||
sql::SqlManager* sql;
|
||||
std::shared_ptr<VirtualServer> server;
|
||||
|
@ -174,6 +174,7 @@ void SpeakingClient::handlePacketVoiceWhisper(const pipes::buffer_view& data, bo
|
||||
#endif
|
||||
|
||||
deque<shared_ptr<SpeakingClient>> available_clients;
|
||||
auto type_id_string = std::to_string(type_id);
|
||||
for(const auto& client : this->server->getClients()) {
|
||||
auto speakingClient = dynamic_pointer_cast<SpeakingClient>(client);
|
||||
if(!speakingClient || client == this) continue;
|
||||
@ -185,16 +186,15 @@ void SpeakingClient::handlePacketVoiceWhisper(const pipes::buffer_view& data, bo
|
||||
if(type_id == 0)
|
||||
available_clients.push_back(speakingClient);
|
||||
else {
|
||||
shared_lock client_lock(this->channel_lock);
|
||||
for(const auto& id : client->cached_server_groups) {
|
||||
if(id == type_id) {
|
||||
available_clients.push_back(speakingClient);
|
||||
break;
|
||||
}
|
||||
}
|
||||
auto client_groups = client->properties()[property::CLIENT_SERVERGROUPS].as<std::string>();
|
||||
auto index = client_groups.find(client_groups);
|
||||
if(index == std::string::npos) continue;
|
||||
if(index != client_groups.length() && client_groups[index] != ',') continue;
|
||||
|
||||
available_clients.push_back(speakingClient);
|
||||
}
|
||||
} else if(type == WhisperType::CHANNEL_GROUP) {
|
||||
if(client->cached_channel_group == type_id)
|
||||
if(client->properties()[property::CLIENT_CHANNEL_GROUP_ID].as_save<GroupId>() == type_id)
|
||||
available_clients.push_back(speakingClient);
|
||||
} else if(type == WhisperType::CHANNEL_COMMANDER) {
|
||||
if(client->properties()[property::CLIENT_IS_CHANNEL_COMMANDER].as<bool>())
|
||||
|
@ -1654,7 +1654,7 @@ command_result ConnectedClient::handleCommandChannelClientPermList(Command &cmd)
|
||||
ACTION_REQUIRES_PERMISSION(permission::b_virtualserver_channelclient_permission_list, 1, channel_id);
|
||||
|
||||
if(!serverInstance->databaseHelper()->validClientDatabaseId(this->server, cmd["cldbid"])) return command_result{error::client_invalid_id};
|
||||
auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server, cmd["cldbid"].as<ClientDbId>());
|
||||
auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server ? this->server->serverId : 0, cmd["cldbid"].as<ClientDbId>());
|
||||
|
||||
Command res(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifychannelclientpermlist" : "");
|
||||
|
||||
@ -1714,7 +1714,7 @@ command_result ConnectedClient::handleCommandChannelClientDelPerm(Command &cmd)
|
||||
auto channel = dynamic_pointer_cast<ServerChannel>(l_channel->entry);
|
||||
if(!channel) return command_result{error::vs_critical};
|
||||
|
||||
auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server, cldbid);
|
||||
auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server ? this->server->serverId : 0, cldbid);
|
||||
{
|
||||
auto required_permissions = this->server->calculate_permission(permission::i_client_needed_permission_modify_power, cmd["cldbid"], ClientType::CLIENT_TEAMSPEAK, channel_id);
|
||||
ACTION_REQUIRES_PERMISSION(permission::i_client_permission_modify_power, required_permissions, channel_id);
|
||||
@ -1740,7 +1740,7 @@ command_result ConnectedClient::handleCommandChannelClientDelPerm(Command &cmd)
|
||||
}
|
||||
}
|
||||
|
||||
serverInstance->databaseHelper()->saveClientPermissions(this->server, cldbid, mgr);
|
||||
serverInstance->databaseHelper()->saveClientPermissions(this->server ? this->server->serverId : 0, cldbid, mgr);
|
||||
if (!cll.empty()) {
|
||||
for (const auto &elm : cll) {
|
||||
if(elm->update_cached_permissions()) /* update cached calculated permissions */
|
||||
@ -1784,7 +1784,7 @@ command_result ConnectedClient::handleCommandChannelClientAddPerm(Command &cmd)
|
||||
auto channel = dynamic_pointer_cast<ServerChannel>(l_channel->entry);
|
||||
if(!channel) return command_result{error::vs_critical};
|
||||
|
||||
auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server, cldbid);
|
||||
auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server ? this->server->serverId : 0, cldbid);
|
||||
{
|
||||
auto required_permissions = this->server->calculate_permission(permission::i_client_needed_permission_modify_power, cmd["cldbid"], ClientType::CLIENT_TEAMSPEAK, channel_id);
|
||||
ACTION_REQUIRES_PERMISSION(permission::i_client_permission_modify_power, required_permissions, channel_id);
|
||||
@ -1821,7 +1821,7 @@ command_result ConnectedClient::handleCommandChannelClientAddPerm(Command &cmd)
|
||||
}
|
||||
}
|
||||
|
||||
serverInstance->databaseHelper()->saveClientPermissions(this->server, cldbid, mgr);
|
||||
serverInstance->databaseHelper()->saveClientPermissions(this->server ? this->server->serverId : 0, cldbid, mgr);
|
||||
if (!onlineClientInstances.empty())
|
||||
for (const auto &elm : onlineClientInstances) {
|
||||
if (elm->update_cached_permissions()) /* update cached calculated permissions */
|
||||
|
@ -867,7 +867,7 @@ command_result ConnectedClient::handleCommandClientAddPerm(Command &cmd) {
|
||||
auto cldbid = cmd["cldbid"].as<ClientDbId>();
|
||||
if(!serverInstance->databaseHelper()->validClientDatabaseId(this->server, cldbid))
|
||||
return command_result{error::client_invalid_id};
|
||||
auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server, cldbid);
|
||||
auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server ? this->server->getServerId() : 0, cldbid);
|
||||
|
||||
ACTION_REQUIRES_GLOBAL_PERMISSION(permission::i_client_permission_modify_power, this->server->calculate_permission(permission::i_client_needed_permission_modify_power, cldbid, ClientType::CLIENT_TEAMSPEAK, 0));
|
||||
auto max_value = this->calculate_permission(permission::i_permission_modify_power, 0, true);
|
||||
@ -897,7 +897,7 @@ command_result ConnectedClient::handleCommandClientAddPerm(Command &cmd) {
|
||||
update_channels |= permission_is_client_property(permType);
|
||||
}
|
||||
}
|
||||
serverInstance->databaseHelper()->saveClientPermissions(this->server, cldbid, mgr);
|
||||
serverInstance->databaseHelper()->saveClientPermissions(this->server ? this->server->getServerId() : 0, cldbid, mgr);
|
||||
auto onlineClients = this->server->findClientsByCldbId(cldbid);
|
||||
if (!onlineClients.empty())
|
||||
for (const auto &elm : onlineClients) {
|
||||
@ -919,7 +919,7 @@ command_result ConnectedClient::handleCommandClientDelPerm(Command &cmd) {
|
||||
auto cldbid = cmd["cldbid"].as<ClientDbId>();
|
||||
if(!serverInstance->databaseHelper()->validClientDatabaseId(this->server, cldbid))
|
||||
return command_result{error::client_invalid_id};
|
||||
auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server, cldbid);
|
||||
auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server ? this->server->serverId : 0, cldbid);
|
||||
ACTION_REQUIRES_GLOBAL_PERMISSION(permission::i_client_permission_modify_power, this->server->calculate_permission(permission::i_client_needed_permission_modify_power, cldbid, ClientType::CLIENT_TEAMSPEAK, 0));
|
||||
|
||||
auto ignore_granted_values = permission::v2::permission_granted(1, this->calculate_permission(permission::b_permission_modify_power_ignore, 0));
|
||||
@ -943,7 +943,7 @@ command_result ConnectedClient::handleCommandClientDelPerm(Command &cmd) {
|
||||
}
|
||||
}
|
||||
|
||||
serverInstance->databaseHelper()->saveClientPermissions(this->server, cldbid, mgr);
|
||||
serverInstance->databaseHelper()->saveClientPermissions(this->server ? this->server->serverId : 0, cldbid, mgr);
|
||||
if (!onlineClients.empty())
|
||||
for (const auto &elm : onlineClients) {
|
||||
if(elm->update_cached_permissions()) /* update cached calculated permissions */
|
||||
@ -962,7 +962,7 @@ command_result ConnectedClient::handleCommandClientPermList(Command &cmd) {
|
||||
ACTION_REQUIRES_GLOBAL_PERMISSION(permission::b_virtualserver_client_permission_list, 1);
|
||||
|
||||
if(!serverInstance->databaseHelper()->validClientDatabaseId(this->server, cmd["cldbid"])) return command_result{error::client_invalid_id};
|
||||
auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server, cmd["cldbid"]);
|
||||
auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server ? this->server->getServerId() : 0, cmd["cldbid"]);
|
||||
if (!this->notifyClientPermList(cmd["cldbid"], mgr, cmd.hasParm("permsid"))) return command_result{error::database_empty_result};
|
||||
return command_result{error::ok};
|
||||
}
|
||||
|
@ -1561,7 +1561,7 @@ command_result ConnectedClient::handleCommandPermOverview(Command &cmd) {
|
||||
|
||||
auto server_groups = this->server->getGroupManager()->getServerGroups(client_dbid, ClientType::CLIENT_TEAMSPEAK);
|
||||
auto channel_group = this->server->getGroupManager()->getChannelGroup(client_dbid, channel, true);
|
||||
auto permission_manager = serverInstance->databaseHelper()->loadClientPermissionManager(this->getServer(), client_dbid);
|
||||
auto permission_manager = serverInstance->databaseHelper()->loadClientPermissionManager(this->getServerId(), client_dbid);
|
||||
|
||||
Command result(this->getExternalType() == ClientType::CLIENT_TEAMSPEAK ? "notifypermoverview" : "");
|
||||
size_t index = 0;
|
||||
|
@ -1,44 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <ThreadPool/Mutex.h>
|
||||
#include <tommath.h>
|
||||
#include <memory>
|
||||
#include <deque>
|
||||
|
||||
namespace ts {
|
||||
namespace server {
|
||||
class ConnectedClient;
|
||||
}
|
||||
|
||||
namespace protocol {
|
||||
struct Puzzle {
|
||||
mp_int x;
|
||||
mp_int n;
|
||||
int level;
|
||||
|
||||
mp_int result;
|
||||
|
||||
uint8_t data_x[64];
|
||||
uint8_t data_n[64];
|
||||
uint8_t data_result[64];
|
||||
};
|
||||
class PuzzleManager {
|
||||
public:
|
||||
PuzzleManager();
|
||||
~PuzzleManager();
|
||||
|
||||
bool precomputePuzzles(size_t limit);
|
||||
|
||||
size_t precomputedPuzzleCount();
|
||||
|
||||
std::shared_ptr<Puzzle> nextPuzzle();
|
||||
private:
|
||||
void generatePuzzle();
|
||||
|
||||
threads::Mutex indexLock;
|
||||
size_t cacheIndex = 0;
|
||||
|
||||
std::deque<std::shared_ptr<Puzzle>> cached;
|
||||
};
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@
|
||||
#include "../ConnectedClient.h"
|
||||
#include "protocol/CryptHandler.h"
|
||||
#include "VoiceClientConnection.h"
|
||||
#include "PrecomputedPuzzles.h"
|
||||
#include "src/server/udp-server/PrecomputedPuzzles.h"
|
||||
#include "../../lincense/TeamSpeakLicense.h"
|
||||
|
||||
//#define LOG_INCOMPING_PACKET_FRAGMENTS
|
||||
@ -42,7 +42,7 @@ namespace ts {
|
||||
class VoiceClient : public SpeakingClient {
|
||||
friend class VirtualServer;
|
||||
friend class VoiceServer;
|
||||
friend class POWHandler;
|
||||
friend class ts::server::server::udp::POWHandler;
|
||||
friend class ts::connection::VoiceClientConnection;
|
||||
friend class ConnectedClient;
|
||||
friend class io::IOServerHandler;
|
||||
|
@ -81,3 +81,5 @@ namespace ts::server::groups {
|
||||
ChannelGroup(VirtualServerId /* server id */, GroupId /* id */, GroupType /* type */, std::string /* name */, std::shared_ptr<permission::v2::PermissionRegister> /* permissions */);
|
||||
};
|
||||
}
|
||||
DEFINE_TRANSFORMS(ts::server::groups::GroupType, uint8_t);
|
||||
DEFINE_TRANSFORMS(ts::server::groups::GroupNameMode, uint8_t);
|
@ -332,7 +332,7 @@ GroupAssignmentResult GroupAssignmentManager::add_server_group(ClientDbId client
|
||||
auto cache = std::make_unique<ClientCache>();
|
||||
cache->client_database_id = client;
|
||||
cache->server_group_assignments.emplace_back(group);
|
||||
this->client_cache.push_back(cache);
|
||||
this->client_cache.push_back(std::move(cache));
|
||||
}
|
||||
}
|
||||
|
||||
@ -424,7 +424,7 @@ GroupAssignmentResult GroupAssignmentManager::set_channel_group(ClientDbId clien
|
||||
auto cache = std::make_unique<ClientCache>();
|
||||
cache->client_database_id = client;
|
||||
cache->channel_group_assignments.emplace_back(channel_id, group, temporary);
|
||||
this->client_cache.push_back(cache);
|
||||
this->client_cache.push_back(std::move(cache));
|
||||
} else {
|
||||
return GroupAssignmentResult::SUCCESS;
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ namespace ts::server {
|
||||
ChannelGroupAssignment(ChannelId channel_id, GroupId group_id, bool t) : channel_id{channel_id}, group_id{group_id}, temporary_assignment{t} { }
|
||||
ChannelGroupAssignment(const ChannelGroupAssignment& other) = default;
|
||||
ChannelGroupAssignment(ChannelGroupAssignment&&) = default;
|
||||
ChannelGroupAssignment&operator=(const ChannelGroupAssignment&) = default;
|
||||
|
||||
ChannelId channel_id;
|
||||
GroupId group_id;
|
||||
@ -42,6 +43,7 @@ namespace ts::server {
|
||||
explicit ServerGroupAssignment(GroupId group_id) : group_id{group_id} { }
|
||||
ServerGroupAssignment(const ServerGroupAssignment& other) = default;
|
||||
ServerGroupAssignment(ServerGroupAssignment&&) = default;
|
||||
ServerGroupAssignment&operator=(const ServerGroupAssignment&) = default;
|
||||
|
||||
GroupId group_id;
|
||||
};
|
||||
|
@ -275,7 +275,7 @@ void BanManager::trigger_ban(const std::shared_ptr<BanRecord>& record,
|
||||
).executeLater().waitAndGetLater(LOG_SQL_CMD, {1, "future failed"});
|
||||
}
|
||||
|
||||
std::deque<std::shared_ptr<BanTrigger>> BanManager::trigger_list(const std::shared_ptr<ts::server::BanRecord> &record, ServerId server_id, ssize_t offset, ssize_t length) {
|
||||
std::deque<std::shared_ptr<BanTrigger>> BanManager::trigger_list(const std::shared_ptr<ts::server::bans::BanRecord> &record, ServerId server_id, ssize_t offset, ssize_t length) {
|
||||
std::deque<std::shared_ptr<BanTrigger>> result;
|
||||
|
||||
if(offset < 0) offset = 0;
|
||||
|
@ -9,7 +9,7 @@
|
||||
using namespace std;
|
||||
using namespace std::chrono;
|
||||
using namespace ts;
|
||||
using namespace ts::server;
|
||||
using namespace ts::server::server::udp;
|
||||
|
||||
//#define POW_DEBUG
|
||||
//#define POW_ERROR
|
||||
@ -33,7 +33,7 @@ void POWHandler::execute_tick() {
|
||||
}), this->pending_clients.end());
|
||||
}
|
||||
|
||||
void POWHandler::delete_client(const std::shared_ptr<ts::server::POWHandler::Client> &client) {
|
||||
void POWHandler::delete_client(const std::shared_ptr<POWHandler::Client> &client) {
|
||||
lock_guard lock(this->pending_clients_lock);
|
||||
auto it = find(this->pending_clients.begin(), this->pending_clients.end(), client);
|
||||
if(it != this->pending_clients.end())
|
||||
@ -127,7 +127,7 @@ void POWHandler::handle_datagram(int socket, const sockaddr_storage &address,msg
|
||||
}
|
||||
}
|
||||
|
||||
void POWHandler::send_data(const std::shared_ptr<ts::server::POWHandler::Client> &client, const pipes::buffer_view &buffer) {
|
||||
void POWHandler::send_data(const std::shared_ptr<POWHandler::Client> &client, const pipes::buffer_view &buffer) {
|
||||
auto datagram = io::DatagramPacket::create(client->address, client->address_info, buffer.length() + MAC_SIZE + SERVER_HEADER_SIZE, nullptr);
|
||||
if(!datagram) return; //Should never happen
|
||||
|
||||
@ -144,7 +144,7 @@ void POWHandler::send_data(const std::shared_ptr<ts::server::POWHandler::Client>
|
||||
this->server->send_datagram(client->socket, datagram);
|
||||
}
|
||||
|
||||
void POWHandler::reset_client(const std::shared_ptr<ts::server::POWHandler::Client> &client) {
|
||||
void POWHandler::reset_client(const std::shared_ptr<POWHandler::Client> &client) {
|
||||
uint8_t buffer[2] = {COMMAND_RESET, 0};
|
||||
this->send_data(client, pipes::buffer_view{buffer, 2});
|
||||
client->state = LowHandshakeState::COOKIE_GET;
|
||||
@ -161,7 +161,7 @@ inline void write_reversed(uint8_t* destination, uint8_t* source, size_t length)
|
||||
*(--destination) = *(source++);
|
||||
}
|
||||
|
||||
void POWHandler::handle_cookie_get(const std::shared_ptr<ts::server::POWHandler::Client> &client, const pipes::buffer_view &buffer) {
|
||||
void POWHandler::handle_cookie_get(const std::shared_ptr<POWHandler::Client> &client, const pipes::buffer_view &buffer) {
|
||||
if(buffer.length() != 21) {
|
||||
#ifdef POW_ERROR
|
||||
debugMessage(this->get_server_id(), "[POW][{}][Cookie] Received an invalid packet with an invalid length. Expected {} bytes, but got {} bytes", net::to_string(client->address), 21, buffer.length());
|
||||
@ -191,7 +191,7 @@ void POWHandler::handle_cookie_get(const std::shared_ptr<ts::server::POWHandler:
|
||||
client->state = LowHandshakeState::PUZZLE_GET;
|
||||
}
|
||||
|
||||
void POWHandler::handle_puzzle_get(const std::shared_ptr<ts::server::POWHandler::Client> &client, const pipes::buffer_view &buffer) {
|
||||
void POWHandler::handle_puzzle_get(const std::shared_ptr<POWHandler::Client> &client, const pipes::buffer_view &buffer) {
|
||||
if(buffer.length() != 25) {
|
||||
#ifdef POW_ERROR
|
||||
debugMessage(this->get_server_id(), "[POW][{}][Puzzle] Received an invalid puzzle request with an invalid length. Expected {} bytes, but got {} bytes", net::to_string(client->address), 25, buffer.length());
|
||||
@ -211,7 +211,7 @@ void POWHandler::handle_puzzle_get(const std::shared_ptr<ts::server::POWHandler:
|
||||
}
|
||||
|
||||
if(!client->rsa_challenge)
|
||||
client->rsa_challenge = serverInstance->getVoiceServerManager()->rsaPuzzles()->nextPuzzle();
|
||||
client->rsa_challenge = serverInstance->getVoiceServerManager()->rsaPuzzles()->next_puzzle();
|
||||
|
||||
/* send response */
|
||||
{
|
||||
@ -239,7 +239,7 @@ void POWHandler::handle_puzzle_get(const std::shared_ptr<ts::server::POWHandler:
|
||||
client->state = LowHandshakeState::PUZZLE_SOLVE;
|
||||
}
|
||||
|
||||
void POWHandler::handle_puzzle_solve(const std::shared_ptr<ts::server::POWHandler::Client> &client, const pipes::buffer_view &buffer) {
|
||||
void POWHandler::handle_puzzle_solve(const std::shared_ptr<POWHandler::Client> &client, const pipes::buffer_view &buffer) {
|
||||
if(buffer.length() < 301) {
|
||||
#ifdef POW_ERROR
|
||||
debugMessage(this->get_server_id(), "[POW][{}][Puzzle] Received an invalid puzzle solution with an invalid length. Expected at least {} bytes, but got {} bytes", net::to_string(client->address), 301, buffer.length());
|
||||
@ -283,7 +283,7 @@ void POWHandler::handle_puzzle_solve(const std::shared_ptr<ts::server::POWHandle
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr<VoiceClient> POWHandler::register_verified_client(const std::shared_ptr <ts::server::POWHandler::Client> &client) {
|
||||
shared_ptr<ts::server::VoiceClient> POWHandler::register_verified_client(const std::shared_ptr <POWHandler::Client> &client) {
|
||||
shared_ptr<VoiceClient> voice_client;
|
||||
{
|
||||
lock_guard lock(this->server->connectionLock);
|
||||
|
@ -3,12 +3,12 @@
|
||||
#include <mutex>
|
||||
#include <netinet/in.h>
|
||||
#include <pipes/buffer.h>
|
||||
#include <src/client/voice/PrecomputedPuzzles.h>
|
||||
#include <Definitions.h>
|
||||
#include "VoiceServer.h"
|
||||
#include "src/VirtualServer.h"
|
||||
#include "./udp-server/PrecomputedPuzzles.h"
|
||||
|
||||
namespace ts::server {
|
||||
namespace ts::server::server::udp {
|
||||
class POWHandler {
|
||||
public:
|
||||
enum LowHandshakeState : uint8_t {
|
||||
@ -38,7 +38,7 @@ namespace ts::server {
|
||||
|
||||
uint32_t client_version;
|
||||
|
||||
std::shared_ptr<protocol::Puzzle> rsa_challenge;
|
||||
std::shared_ptr<Puzzle> rsa_challenge;
|
||||
};
|
||||
|
||||
explicit POWHandler(VoiceServer* /* server */);
|
||||
|
@ -11,11 +11,11 @@
|
||||
#include "VoiceIOManager.h"
|
||||
|
||||
namespace ts {
|
||||
namespace protocol {
|
||||
class PuzzleManager;
|
||||
}
|
||||
|
||||
namespace server {
|
||||
namespace server::udp {
|
||||
class POWHandler;
|
||||
}
|
||||
|
||||
class VirtualServer;
|
||||
class ConnectedClient;
|
||||
class VoiceClient;
|
||||
@ -33,7 +33,7 @@ namespace ts {
|
||||
friend class VoiceClient;
|
||||
friend class io::VoiceIOManager;
|
||||
friend struct io::IOEventLoopEvents;
|
||||
friend class POWHandler;
|
||||
friend class server::udp::POWHandler;
|
||||
public:
|
||||
explicit VoiceServer(const std::shared_ptr<VirtualServer>& server);
|
||||
~VoiceServer();
|
||||
|
@ -1,50 +1,50 @@
|
||||
#include "PrecomputedPuzzles.h"
|
||||
#include "../../Configuration.h"
|
||||
#include "../ConnectedClient.h"
|
||||
#include "./PrecomputedPuzzles.h"
|
||||
#include "src/Configuration.h"
|
||||
#include <tomcrypt.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace ts;
|
||||
using namespace ts::protocol;
|
||||
using namespace ts::server::server::udp;
|
||||
|
||||
PuzzleManager::PuzzleManager() {}
|
||||
PuzzleManager::~PuzzleManager() {}
|
||||
PuzzleManager::PuzzleManager() = default;
|
||||
PuzzleManager::~PuzzleManager() = default;
|
||||
|
||||
size_t PuzzleManager::precomputedPuzzleCount() { return this->cached.size(); }
|
||||
|
||||
bool PuzzleManager::precomputePuzzles(size_t limit) {
|
||||
while(precomputedPuzzleCount() < limit) generatePuzzle();
|
||||
return true;
|
||||
size_t PuzzleManager::precomputed_puzzle_count() {
|
||||
std::lock_guard lock{this->cache_lock};
|
||||
return this->cached_puzzles.size();
|
||||
}
|
||||
|
||||
std::shared_ptr<Puzzle> PuzzleManager::nextPuzzle() {
|
||||
this->indexLock.lock();
|
||||
size_t index = this->cacheIndex++ % this->cached.size();
|
||||
this->indexLock.unlock();
|
||||
return this->cached[index];
|
||||
bool PuzzleManager::precompute_puzzles(size_t amount) {
|
||||
std::random_device rd{};
|
||||
std::mt19937 mt{rd()};
|
||||
|
||||
while(this->precomputed_puzzle_count() < amount)
|
||||
this->generate_puzzle();
|
||||
return this->precomputed_puzzle_count() > 0;
|
||||
}
|
||||
|
||||
inline void rndNum(mp_int *result, int byteLength){
|
||||
uint8_t buffer[byteLength];
|
||||
std::shared_ptr<Puzzle> PuzzleManager::next_puzzle() {
|
||||
std::lock_guard lock{this->cache_lock};
|
||||
return this->cached_puzzles[this->cache_index++ % this->cached_puzzles.size()];
|
||||
}
|
||||
|
||||
for(int index = 0; index < byteLength; index++) {
|
||||
int rnd = rand();
|
||||
uint8_t urnd = static_cast<uint8_t>(rnd & 0xFF);
|
||||
buffer[index] = urnd; //TODO more secure!
|
||||
inline void random_number(std::mt19937& generator, mp_int *result, int length){
|
||||
std::uniform_int_distribution<uint8_t> dist{};
|
||||
|
||||
}
|
||||
uint8_t buffer[length];
|
||||
for(auto& byte : buffer)
|
||||
byte = dist(generator);
|
||||
|
||||
mp_zero(result);
|
||||
mp_read_unsigned_bin(result, buffer, byteLength);
|
||||
mp_read_unsigned_bin(result, buffer, length);
|
||||
}
|
||||
|
||||
inline bool solvePuzzle(Puzzle *puzzle){
|
||||
inline bool solve_puzzle(Puzzle *puzzle) {
|
||||
mp_int exp{};
|
||||
mp_init(&exp);
|
||||
mp_2expt(&exp, puzzle->level);
|
||||
|
||||
|
||||
if (mp_exptmod(&puzzle->x, &exp, &puzzle->n, &puzzle->result) != CRYPT_OK) { //Sometimes it fails (unknow why :D)
|
||||
if (mp_exptmod(&puzzle->x, &exp, &puzzle->n, &puzzle->result) != CRYPT_OK) { //Sometimes it fails (unknown why :D)
|
||||
mp_clear(&exp);
|
||||
return false;
|
||||
}
|
||||
@ -66,17 +66,17 @@ inline bool write_bin_data(mp_int& data, uint8_t* result, size_t length) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void PuzzleManager::generatePuzzle() {
|
||||
void PuzzleManager::generate_puzzle(std::mt19937& random_generator) {
|
||||
auto puzzle = new Puzzle{};
|
||||
|
||||
puzzle->level = ts::config::voice::RsaPuzzleLevel;
|
||||
mp_init_multi(&puzzle->x, &puzzle->n, &puzzle->result, nullptr);
|
||||
|
||||
generate_new:
|
||||
rndNum(&puzzle->x, 64);
|
||||
rndNum(&puzzle->n, 64);
|
||||
puzzle->level = ts::config::voice::RsaPuzzleLevel;
|
||||
random_number(random_generator, &puzzle->x, 64);
|
||||
random_number(random_generator, &puzzle->n, 64);
|
||||
|
||||
if(!solvePuzzle(puzzle))
|
||||
if(!solve_puzzle(puzzle))
|
||||
goto generate_new;
|
||||
|
||||
auto valid_x = mp_unsigned_bin_size(&puzzle->x) <= 64;
|
||||
@ -94,7 +94,7 @@ void PuzzleManager::generatePuzzle() {
|
||||
if(!write_bin_data(puzzle->result, puzzle->data_result, 64))
|
||||
goto generate_new;
|
||||
|
||||
this->cached.push_back(shared_ptr<Puzzle>(puzzle, [](Puzzle* elm){
|
||||
this->cached_puzzles.push_back(shared_ptr<Puzzle>(puzzle, [](Puzzle* elm){
|
||||
mp_clear_multi(&elm->n, &elm->x, &elm->result, nullptr);
|
||||
delete elm;
|
||||
}));
|
39
server/src/server/udp-server/PrecomputedPuzzles.h
Normal file
39
server/src/server/udp-server/PrecomputedPuzzles.h
Normal file
@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include <tommath.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <misc/spin_lock.h>
|
||||
#include <random>
|
||||
|
||||
namespace ts::server::server::udp {
|
||||
struct Puzzle {
|
||||
mp_int x;
|
||||
mp_int n;
|
||||
int level;
|
||||
|
||||
mp_int result;
|
||||
|
||||
uint8_t data_x[64];
|
||||
uint8_t data_n[64];
|
||||
uint8_t data_result[64];
|
||||
};
|
||||
|
||||
class PuzzleManager {
|
||||
public:
|
||||
PuzzleManager();
|
||||
~PuzzleManager();
|
||||
|
||||
[[nodiscard]] bool precompute_puzzles(size_t amount);
|
||||
|
||||
[[nodiscard]] size_t precomputed_puzzle_count();
|
||||
|
||||
[[nodiscard]] std::shared_ptr<Puzzle> next_puzzle();
|
||||
private:
|
||||
void generate_puzzle(std::mt19937&);
|
||||
|
||||
size_t cache_index{0};
|
||||
spin_lock cache_lock{};
|
||||
std::vector<std::shared_ptr<Puzzle>> cached_puzzles{};
|
||||
};
|
||||
}
|
5
server/src/server/udp-server/UDPServer.cpp
Normal file
5
server/src/server/udp-server/UDPServer.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by WolverinDEV on 07/03/2020.
|
||||
//
|
||||
|
||||
#include "UDPServer.h"
|
107
server/src/server/udp-server/UDPServer.h
Normal file
107
server/src/server/udp-server/UDPServer.h
Normal file
@ -0,0 +1,107 @@
|
||||
#pragma once
|
||||
|
||||
#include <thread>
|
||||
#include <event.h>
|
||||
#include <vector>
|
||||
#include <misc/spin_lock.h>
|
||||
#include <Definitions.h>
|
||||
#include <mutex>
|
||||
|
||||
namespace ts::server {
|
||||
class VoiceClient;
|
||||
}
|
||||
|
||||
namespace ts::server::server::udp {
|
||||
struct datagram_packet {
|
||||
union pktinfo_storage {
|
||||
in_pktinfo v4;
|
||||
in6_pktinfo v6;
|
||||
};
|
||||
|
||||
datagram_packet* next_packet;
|
||||
|
||||
sockaddr_storage address;
|
||||
pktinfo_storage address_info;
|
||||
|
||||
size_t data_length;
|
||||
uint8_t data[0];
|
||||
};
|
||||
static_assert(std::is_trivially_destructible<datagram_packet>::value);
|
||||
static_assert(std::is_trivially_constructible<datagram_packet>::value);
|
||||
|
||||
template <typename T, size_t N>
|
||||
struct write_ring_queue {
|
||||
std::array<T, N> memory{};
|
||||
size_t current_index{0};
|
||||
size_t filled_index{0};
|
||||
|
||||
[[nodiscard]] constexpr inline auto max_size() const { return N; }
|
||||
[[nodiscard]] inline size_t current_size() const { return this->filled_index - this->current_index; }
|
||||
|
||||
[[nodiscard]] inline bool pop_entry(T& result) {
|
||||
if(this->current_index >= this->filled_index) return false;
|
||||
return this->memory[this->current_index++ % N];
|
||||
}
|
||||
|
||||
[[nodiscard]] inline bool push_entry(T&& entry) {
|
||||
if(this->filled_index - this->current_index >= N) return false;
|
||||
this->memory[this->filled_index++ % N] = std::forward(entry);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct io_loop;
|
||||
struct io_loop_entry {
|
||||
io_loop* io_loop{nullptr};
|
||||
|
||||
int file_descriptor{0};
|
||||
|
||||
event* event_read{};
|
||||
event* event_write{};
|
||||
|
||||
spin_lock write_queue_lock{};
|
||||
datagram_packet* dg_write_queue_head{nullptr};
|
||||
datagram_packet* dg_write_queue_tail{nullptr};
|
||||
|
||||
write_ring_queue<std::weak_ptr<VoiceClient>, 1024 * 8> voice_write_queue{};
|
||||
};
|
||||
|
||||
struct io_loop {
|
||||
std::thread base_dispatcher{};
|
||||
struct event_base* event_base{nullptr};
|
||||
|
||||
std::mutex entries_mutex{};
|
||||
std::vector<io_loop_entry*> registered_entries{};
|
||||
};
|
||||
|
||||
struct io_binding {
|
||||
VirtualServerId server_id{0};
|
||||
sockaddr_storage address{};
|
||||
|
||||
size_t loop_entry_index{0};
|
||||
std::vector<io_loop_entry*> loop_entries{};
|
||||
|
||||
struct server_client {
|
||||
std::shared_ptr<VoiceClient> client{};
|
||||
ClientId client_id{0};
|
||||
};
|
||||
|
||||
std::mutex client_lock{};
|
||||
std::deque<server_client> known_clients{};
|
||||
};
|
||||
|
||||
class Server {
|
||||
public:
|
||||
|
||||
|
||||
void schedule_client_write(const std::shared_ptr<VoiceClient>& /* client */);
|
||||
|
||||
void unregister_client(const std::shared_ptr<VoiceClient>& /* client */);
|
||||
private:
|
||||
std::mutex io_lock{};
|
||||
std::vector<io_loop*> io_loops{};
|
||||
|
||||
std::mutex bindings_lock{};
|
||||
std::vector<io_binding*> io_bindings{};
|
||||
};
|
||||
}
|
@ -317,13 +317,14 @@ ClientMoveResult ClientChannelService::client_move(const std::shared_ptr<Connect
|
||||
}
|
||||
client_channel_lock.unlock();
|
||||
/* both methods lock if they require stuff */
|
||||
this->notifyClientPropertyUpdates(target, client_updates, s_source_channel ? true : false);
|
||||
this->virtual_server_->broadcast_service().client_updated(target, client_updates, s_source_channel ? true : false);
|
||||
TIMING_STEP(timings, "notify cpro");
|
||||
if(s_target_channel) {
|
||||
target->updateChannelClientProperties(false, s_source_channel ? true : false);
|
||||
TIMING_STEP(timings, "notify_t_pr");
|
||||
}
|
||||
debugMessage(this->get_server_id(), "{} Client move timings: {}", CLIENT_STR_LOG_PREFIX_(target), TIMING_FINISH(timings));
|
||||
return ClientMoveResult ::SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -361,7 +362,7 @@ ChannelDeleteResult ClientChannelService::delete_channel(std::shared_ptr<ServerC
|
||||
|
||||
std::deque<std::unique_lock<threads::Mutex>> command_locks;
|
||||
for(const auto& client : clients)
|
||||
command_locks.push_back(std::move(std::unique_lock(client->get_channel_lock())));
|
||||
command_locks.push_back(std::move(client->lock_command_handling<std::unique_lock<threads::Mutex>>()));
|
||||
|
||||
for(const auto& client : clients) {
|
||||
auto result = this->client_move(client, default_channel, invoker, kick_message, ViewReasonId::VREASON_CHANNEL_KICK, true, tree_lock);
|
||||
|
@ -62,7 +62,7 @@ std::vector<std::pair<ts::permission::PermissionType, ts::permission::v2::Permis
|
||||
cache->client_database_id = client_dbid;
|
||||
|
||||
if(!cache->client_permissions)
|
||||
cache->client_permissions = serverInstance->databaseHelper()->loadClientPermissionManager(this->virtual_server_->server_ref(), client_dbid);
|
||||
cache->client_permissions = serverInstance->databaseHelper()->loadClientPermissionManager(this->get_server_id(), client_dbid);
|
||||
|
||||
bool have_skip_permission = false;
|
||||
int skip_permission_type = -1; /* -1 := unset | 0 := skip, not explicit | 1 := skip, explicit */
|
||||
@ -361,7 +361,7 @@ PermissionResetResult PermissionService::reset_server_permissions() {
|
||||
client->notifyChannelGroupList();
|
||||
}
|
||||
|
||||
if(this->notifyClientPropertyUpdates(client, group_manager->assignments().update_client_group_properties(client, client->getChannelId()))) {
|
||||
if(this->virtual_server_->broadcast_service().client_updated(client, group_manager->assignments().update_client_group_properties(client, client->getChannelId()))) {
|
||||
if(client->update_cached_permissions()) /* update cached calculated permissions */
|
||||
client->sendNeededPermissions(false); /* cached permissions had changed, notify the client */
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ namespace ts::server::permissions {
|
||||
ClientType type,
|
||||
ChannelId channel,
|
||||
bool granted,
|
||||
std::shared_ptr<CalculateCache> cache{nullptr}
|
||||
std::shared_ptr<CalculateCache> cache = nullptr
|
||||
);
|
||||
|
||||
std::vector<std::pair<permission::PermissionType, permission::v2::PermissionFlaggedValue>> calculate_client_permissions(
|
||||
@ -60,7 +60,7 @@ namespace ts::server::permissions {
|
||||
ClientType type,
|
||||
ChannelId channel,
|
||||
bool granted,
|
||||
std::shared_ptr<CalculateCache> cache{nullptr}
|
||||
std::shared_ptr<CalculateCache> cache = nullptr
|
||||
);
|
||||
private:
|
||||
vserver::VirtualServerBase* virtual_server_{nullptr};
|
||||
|
5
server/src/services/VirtualServerBroadcastService.cpp
Normal file
5
server/src/services/VirtualServerBroadcastService.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by WolverinDEV on 07/03/2020.
|
||||
//
|
||||
|
||||
#include "VirtualServerBroadcastService.h"
|
31
server/src/services/VirtualServerBroadcastService.h
Normal file
31
server/src/services/VirtualServerBroadcastService.h
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <deque>
|
||||
#include <Properties.h>
|
||||
|
||||
namespace ts::server {
|
||||
class ConnectedClient;
|
||||
}
|
||||
|
||||
namespace ts::server::vserver {
|
||||
class VirtualServerBase;
|
||||
|
||||
class BroadcastService {
|
||||
public:
|
||||
explicit BroadcastService(VirtualServerBase*);
|
||||
|
||||
bool client_updated(const std::shared_ptr<ConnectedClient>& /* client */,
|
||||
const std::deque<std::shared_ptr<property::PropertyDescription>>& /* keys */, bool /* notify_client */ = true);
|
||||
|
||||
inline bool client_updated(const std::shared_ptr<ConnectedClient>& client, const std::deque<property::ClientProperties>& keys, bool notify_client = true) {
|
||||
if(keys.empty()) return false;
|
||||
|
||||
std::deque<std::shared_ptr<property::PropertyDescription>> _keys{};
|
||||
for(const auto& key : keys) _keys.push_back(property::impl::info<property::ClientProperties>(key));
|
||||
return this->client_updated(client, _keys, notify_client);
|
||||
};
|
||||
private:
|
||||
VirtualServerBase* virtual_server_;
|
||||
};
|
||||
}
|
@ -11,5 +11,5 @@ InformationService::InformationService(ts::server::vserver::VirtualServerBase *h
|
||||
InformationService::~InformationService() {}
|
||||
|
||||
float InformationService::averagePing() {
|
||||
|
||||
return -2;
|
||||
}
|
@ -7,6 +7,7 @@
|
||||
#include "../client/ConnectedClient.h"
|
||||
#include "VirtualServerBase.h"
|
||||
#include <log/LogUtils.h>
|
||||
#include <src/InstanceHandler.h>
|
||||
|
||||
using namespace ts::server::vserver;
|
||||
|
||||
@ -78,6 +79,9 @@ VirtualServerStopResult VirtualServerBase::stop_server() {
|
||||
|
||||
VirtualServerStartResult VirtualServerBase::start_server_(ts::rwshared_lock<ts::rw_mutex> &slock, std::string &error) {
|
||||
//TODO: Load server permissions, etc
|
||||
|
||||
error = "Not implemented";
|
||||
return VirtualServerStartResult::CUSTOM;
|
||||
}
|
||||
|
||||
VirtualServerClientRegisterResult VirtualServerBase::register_client(const std::shared_ptr<ConnectedClient> &client) {
|
||||
@ -201,14 +205,14 @@ void VirtualServerBase::unregister_client(const std::shared_ptr<ConnectedClient>
|
||||
}
|
||||
|
||||
{
|
||||
if(!chan_tree_lock.owns_lock())
|
||||
chan_tree_lock.lock();
|
||||
|
||||
if(cl->currentChannel) //We dont have to make him invisible if he hasnt even a channel
|
||||
this->client_move(cl, nullptr, nullptr, reason, ViewReasonId::VREASON_SERVER_LEFT, false, chan_tree_lock);
|
||||
auto channel_clients_lock = this->lock_channel_clients();
|
||||
if(client->getChannel()) {//We dont have to make him invisible if he hasn't even a channel
|
||||
auto result = this->channel_service().client_move(client, nullptr, nullptr, "", ViewReasonId::VREASON_SERVER_LEFT, false, channel_clients_lock);;
|
||||
if(result != channels::ClientMoveResult::SUCCESS)
|
||||
logCritical(this->server_id(), "Failed to unregister client {} from the server channel tree ({}).", client->getDisplayName(), (int) result);
|
||||
}
|
||||
}
|
||||
|
||||
serverInstance->databaseHelper()->saveClientPermissions(this->ref(), cl->getClientDatabaseId(), cl->clientPermissions);
|
||||
cl->setClientId(0);
|
||||
return true;
|
||||
serverInstance->databaseHelper()->saveClientPermissions(this->server_id(), client->getClientDatabaseId(), client->permissions());
|
||||
client->setClientId(0);
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
#include <lock/rw_mutex.h>
|
||||
#include <PermissionRegister.h>
|
||||
#include <sql/SqlQuery.h>
|
||||
#include <src/services/VirtualServerBroadcastService.h>
|
||||
#include "../services/PermissionsService.h"
|
||||
#include "../services/ClientChannelService.h"
|
||||
|
||||
@ -93,6 +94,7 @@ do { \
|
||||
[[nodiscard]] inline const std::shared_ptr<stats::ConnectionStatistics>& server_connection_statistics() { return this->server_connection_statistics_; }
|
||||
|
||||
[[nodiscard]] inline permissions::PermissionService& permission_service() { return this->permission_service_; }
|
||||
[[nodiscard]] inline BroadcastService& broadcast_service() { return this->broadcast_service_; }
|
||||
|
||||
[[nodiscard]] inline channels::ClientChannelService& channel_service() { return this->channel_service_; }
|
||||
[[nodiscard]] inline ts::rwshared_lock<ts::rw_mutex> lock_channel_clients() { return ts::rwshared_lock{this->channel_clients_lock_, ts::rw_lock_shared}; }
|
||||
@ -135,6 +137,7 @@ do { \
|
||||
/* some services */
|
||||
permissions::PermissionService permission_service_;
|
||||
channels::ClientChannelService channel_service_;
|
||||
BroadcastService broadcast_service_;
|
||||
|
||||
struct {
|
||||
size_t count{0};
|
||||
|
2
shared
2
shared
@ -1 +1 @@
|
||||
Subproject commit 0d0d7dd1924ee93bcbe4875c3cf007117d05e4d7
|
||||
Subproject commit 9533fe8920ea82313dcd49a4e003f39e50c7d81e
|
Loading…
x
Reference in New Issue
Block a user