diff --git a/git-teaspeak b/git-teaspeak index c3a2818..71efb00 160000 --- a/git-teaspeak +++ b/git-teaspeak @@ -1 +1 @@ -Subproject commit c3a2818a7f698f3a0efbf32426924299214106da +Subproject commit 71efb006ebdce2740e652306df36e34465a21dfc diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index f3931c9..8e9da8c 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -235,7 +235,7 @@ target_link_libraries(PermMapHelper SET(CPACK_PACKAGE_VERSION_MAJOR "1") SET(CPACK_PACKAGE_VERSION_MINOR "4") -SET(CPACK_PACKAGE_VERSION_PATCH "10") +SET(CPACK_PACKAGE_VERSION_PATCH "11") if (BUILD_TYPE_NAME EQUAL OFF) SET(CPACK_PACKAGE_VERSION_DATA "beta") elseif (BUILD_TYPE_NAME STREQUAL "") diff --git a/server/main.cpp b/server/main.cpp index df3fef7..887c8f0 100644 --- a/server/main.cpp +++ b/server/main.cpp @@ -309,6 +309,32 @@ int main(int argc, char** argv) { logMessageFmt(true, LOG_GENERAL, strobf("[]---------------------------------------------------------[]").string()); } + { + rlimit rlimit{0, 0}; + //forum.teaspeak.de/index.php?threads/2570/ + constexpr auto seek_help_message = "Fore more help visit the forum and read this thread (https://forum.teaspeak.de/index.php?threads/2570/)."; + if(getrlimit(RLIMIT_NOFILE, &rlimit) != 0) { + //prlimit -n4096 -p pid_of_process + logWarningFmt(true, LOG_INSTANCE, "Failed to get open file rlimit ({}). Please ensure its over 16384.", strerror(errno)); + logWarningFmt(true, LOG_INSTANCE, seek_help_message); + } else { + const auto original = rlimit.rlim_cur; + rlimit.rlim_cur = std::max(rlimit.rlim_cur, std::min(rlimit.rlim_max, (rlim_t) 16384)); + if(original != rlimit.rlim_cur) { + if(setrlimit(RLIMIT_NOFILE, &rlimit) != 0) { + logErrorFmt(true, LOG_INSTANCE, "Failed to set open file rlimit to {} ({}). Please ensure its over 16384.", rlimit.rlim_cur, strerror(errno)); + logWarningFmt(true, LOG_INSTANCE, seek_help_message); + goto rlimit_updates; + } + } + if(rlimit.rlim_cur < 16384) { + logWarningFmt(true, LOG_INSTANCE, "Open file rlimit is bellow 16384 ({}). Please increase the system file descriptor limits.", rlimit.rlim_cur); + logWarningFmt(true, LOG_INSTANCE, seek_help_message); + } + } + rlimit_updates:; + } + logMessage(LOG_GENERAL, "Starting TeaSpeak-Server v{}", build::version()->string(true)); logMessage(LOG_GENERAL, "Starting music providers"); diff --git a/server/src/client/command_handler/channel.cpp b/server/src/client/command_handler/channel.cpp index 3c430ee..8f8431c 100644 --- a/server/src/client/command_handler/channel.cpp +++ b/server/src/client/command_handler/channel.cpp @@ -529,51 +529,66 @@ command_result ConnectedClient::handleCommandChannelCreate(Command &cmd) { CMD_CHK_AND_INC_FLOOD_POINTS(25); CMD_CHK_PARM_COUNT(1); - //TODO: Use for this here the cache as well! - auto permission_cache = make_shared(); - if (cmd[0].has("cpid") && cmd["cpid"].as() != 0) ACTION_REQUIRES_GLOBAL_PERMISSION_CACHED(permission::b_channel_create_child, 1, permission_cache); - if (cmd[0].has("channel_order")) ACTION_REQUIRES_GLOBAL_PERMISSION_CACHED(permission::b_channel_create_with_sortorder, 1, permission_cache); - - if(!cmd[0].has("channel_flag_permanent")) cmd[0]["channel_flag_permanent"] = false; - if(!cmd[0].has("channel_flag_semi_permanent")) cmd[0]["channel_flag_semi_permanent"] = false; - if(!cmd[0].has("channel_flag_default")) cmd[0]["channel_flag_default"] = false; - if(!cmd[0].has("channel_flag_password")) cmd[0]["channel_flag_password"] = false; - - if (cmd[0]["channel_flag_permanent"].as()) ACTION_REQUIRES_GLOBAL_PERMISSION_CACHED(permission::b_channel_create_permanent, 1, permission_cache); - else if (cmd[0]["channel_flag_semi_permanent"].as()) ACTION_REQUIRES_GLOBAL_PERMISSION_CACHED(permission::b_channel_create_semi_permanent, 1, permission_cache); - else ACTION_REQUIRES_GLOBAL_PERMISSION_CACHED(permission::b_channel_create_temporary, 1, permission_cache); - - if (!cmd[0]["channel_flag_permanent"].as() && !this->server) return command_result{error::parameter_invalid, "You can only create a permanent channel"}; - - if (cmd[0]["channel_flag_default"].as()) ACTION_REQUIRES_GLOBAL_PERMISSION_CACHED(permission::b_channel_create_with_default, 1, permission_cache); - if (cmd[0]["channel_flag_password"].as()) ACTION_REQUIRES_GLOBAL_PERMISSION_CACHED(permission::b_channel_create_with_password, 1, permission_cache); - else if(permission::v2::permission_granted(1, this->calculate_permission(permission::b_channel_create_modify_with_force_password, 0, false, permission_cache))) - return command_result{permission::b_channel_create_modify_with_force_password}; - - if(cmd[0].has("channel_password") && this->getType() == ClientType::CLIENT_QUERY) - cmd["channel_password"] = base64::decode(digest::sha1(cmd["channel_password"].string())); - if (cmd[0].has("channel_description")) ACTION_REQUIRES_GLOBAL_PERMISSION_CACHED(permission::b_channel_create_with_description, 1, permission_cache); - if (cmd[0].has("channel_maxclients") || (cmd[0].has("channel_flag_maxclients_unlimited") && !cmd["channel_flag_maxclients_unlimited"].as())) { - ACTION_REQUIRES_GLOBAL_PERMISSION_CACHED(permission::b_channel_create_with_maxclients, 1, permission_cache); - if(!cmd[0]["channel_flag_permanent"].as() && !cmd[0]["channel_flag_semi_permanent"].as()) { - cmd["channel_maxclients"] = -1; - cmd["channel_flag_maxclients_unlimited"] = 1; - } - } - if (cmd[0].has("channel_maxfamilyclients")) ACTION_REQUIRES_GLOBAL_PERMISSION_CACHED(permission::b_channel_create_with_maxfamilyclients, 1, permission_cache); - if (cmd[0].has("channel_needed_talk_power")) ACTION_REQUIRES_GLOBAL_PERMISSION_CACHED(permission::b_channel_create_with_needed_talk_power, 1, permission_cache); - if (cmd[0].has("channel_topic")) ACTION_REQUIRES_GLOBAL_PERMISSION_CACHED(permission::b_channel_create_with_topic, 1, permission_cache); + std::shared_ptr parent = nullptr; + std::shared_ptr created_channel = nullptr, old_default_channel; auto target_tree = this->server ? this->server->channelTree : serverInstance->getChannelTree().get(); auto& tree_lock = this->server ? this->server->channel_tree_lock : serverInstance->getChannelTreeLock(); unique_lock tree_channel_lock(tree_lock); + if (cmd[0].has("cpid") && cmd["cpid"].as() != 0 && cmd["cpid"].as() != -1) { + parent = target_tree->findLinkedChannel(cmd["cpid"].as()); + if (!parent) return command_result{error::channel_invalid_id, "Cant resolve parent channel"}; + } + ChannelId parent_channel_id = parent ? parent->entry->channelId() : 0; + +#define test_permission(required, permission_type) \ + do {\ + if(!permission::v2::permission_granted(required, this->calculate_permission(permission_type, parent_channel_id, false, permission_cache))) \ + return command_result{permission_type};\ + } while(0) + + + //TODO: Use for this here the cache as well! + auto permission_cache = make_shared(); + if(parent) test_permission(1, permission::b_channel_create_child); + if (cmd[0].has("channel_order")) test_permission(1, permission::b_channel_create_with_sortorder); + if(!cmd[0].has("channel_flag_permanent")) cmd[0]["channel_flag_permanent"] = false; + if(!cmd[0].has("channel_flag_semi_permanent")) cmd[0]["channel_flag_semi_permanent"] = false; + if(!cmd[0].has("channel_flag_default")) cmd[0]["channel_flag_default"] = false; + if(!cmd[0].has("channel_flag_password")) cmd[0]["channel_flag_password"] = false; + + if (cmd[0]["channel_flag_permanent"].as()) test_permission(1, permission::b_channel_create_permanent); + else if (cmd[0]["channel_flag_semi_permanent"].as()) test_permission(1, permission::b_channel_create_semi_permanent); + else test_permission(1, permission::b_channel_create_temporary); + + if (!cmd[0]["channel_flag_permanent"].as() && !this->server) return command_result{error::parameter_invalid, "You can only create a permanent channel"}; + + if (cmd[0]["channel_flag_default"].as()) test_permission(1, permission::b_channel_create_with_default); + if (cmd[0]["channel_flag_password"].as()) test_permission(1, permission::b_channel_create_with_password); + else if(permission::v2::permission_granted(1, this->calculate_permission(permission::b_channel_create_modify_with_force_password, parent_channel_id, false, permission_cache))) + return command_result{permission::b_channel_create_modify_with_force_password}; + + if(cmd[0].has("channel_password") && this->getType() == ClientType::CLIENT_QUERY) + cmd["channel_password"] = base64::decode(digest::sha1(cmd["channel_password"].string())); + if (cmd[0].has("channel_description")) test_permission(1, permission::b_channel_create_with_description); + if (cmd[0].has("channel_maxclients") || (cmd[0].has("channel_flag_maxclients_unlimited") && !cmd["channel_flag_maxclients_unlimited"].as())) { + test_permission(1, permission::b_channel_create_with_maxclients); + if(!cmd[0]["channel_flag_permanent"].as() && !cmd[0]["channel_flag_semi_permanent"].as()) { + cmd["channel_maxclients"] = -1; + cmd["channel_flag_maxclients_unlimited"] = 1; + } + } + if (cmd[0].has("channel_maxfamilyclients")) test_permission(1, permission::b_channel_create_with_maxfamilyclients); + if (cmd[0].has("channel_needed_talk_power")) test_permission(1,permission::b_channel_create_with_needed_talk_power); + if (cmd[0].has("channel_topic")) test_permission(1,permission::b_channel_create_with_topic); + if(cmd[0].has("channel_conversation_history_length")) { auto value = cmd["channel_conversation_history_length"].as(); if(value == 0) { - ACTION_REQUIRES_GLOBAL_PERMISSION_CACHED(permission::b_channel_create_modify_conversation_history_unlimited, 1, permission_cache); + test_permission(1, permission::b_channel_create_modify_conversation_history_unlimited); } else { - ACTION_REQUIRES_GLOBAL_PERMISSION_CACHED(permission::i_channel_create_modify_conversation_history_length, 1, permission_cache); + test_permission(1, permission::i_channel_create_modify_conversation_history_length); } } @@ -585,9 +600,10 @@ command_result ConnectedClient::handleCommandChannelCreate(Command &cmd) { else cmd["channel_delete_delay"] = 0; } else { - ACTION_REQUIRES_GLOBAL_PERMISSION_CACHED(permission::i_channel_create_modify_with_temp_delete_delay, cmd["channel_delete_delay"].as(), permission_cache); + test_permission(cmd["channel_delete_delay"].as(), permission::i_channel_create_modify_with_temp_delete_delay); } } +#undef test_permission { size_t created_total = 0, created_tmp = 0, created_semi = 0, created_perm = 0; @@ -607,14 +623,14 @@ command_result ConnectedClient::handleCommandChannelCreate(Command &cmd) { if(this->server && created_total >= this->server->properties()[property::VIRTUALSERVER_MAX_CHANNELS].as()) return command_result{error::channel_limit_reached}; - auto max_channels = this->calculate_permission(permission::i_client_max_channels, 0, false, permission_cache); + auto max_channels = this->calculate_permission(permission::i_client_max_channels, parent_channel_id, false, permission_cache); if(max_channels.has_value) { if(!permission::v2::permission_granted(created_perm + created_semi + created_tmp + 1, max_channels)) return command_result{permission::i_client_max_channels}; } if (cmd[0]["channel_flag_permanent"].as()) { - max_channels = this->calculate_permission(permission::i_client_max_permanent_channels, 0, false, permission_cache); + max_channels = this->calculate_permission(permission::i_client_max_permanent_channels, parent_channel_id, false, permission_cache); if(max_channels.has_value) { if(!permission::v2::permission_granted(created_perm + 1, max_channels)) @@ -622,7 +638,7 @@ command_result ConnectedClient::handleCommandChannelCreate(Command &cmd) { } } else if (cmd[0]["channel_flag_semi_permanent"].as()) { - max_channels = this->calculate_permission(permission::i_client_max_semi_channels, 0, false, permission_cache); + max_channels = this->calculate_permission(permission::i_client_max_semi_channels, parent_channel_id, false, permission_cache); if(max_channels.has_value) { if(!permission::v2::permission_granted(created_semi + 1, max_channels)) @@ -630,7 +646,7 @@ command_result ConnectedClient::handleCommandChannelCreate(Command &cmd) { } } else { - max_channels = this->calculate_permission(permission::i_client_max_temporary_channels, 0, false, permission_cache); + max_channels = this->calculate_permission(permission::i_client_max_temporary_channels, parent_channel_id, false, permission_cache); if(max_channels.has_value) { if(!permission::v2::permission_granted(created_tmp + 1, max_channels)) @@ -640,20 +656,12 @@ command_result ConnectedClient::handleCommandChannelCreate(Command &cmd) { } //TODO check voice (opus etc) - std::shared_ptr parent = nullptr; - std::shared_ptr created_channel = nullptr, old_default_channel; - //bool enforce_permanent_parent = cmd[0]["channel_flag_default"].as(); //TODO check parents here { //Checkout the parent(s) - if (cmd[0].has("cpid") && cmd["cpid"].as() != 0 && cmd["cpid"].as() != -1) { - parent = target_tree->findLinkedChannel(cmd["cpid"].as()); - if (!parent) return command_result{error::channel_invalid_id, "Cant resolve parent channel"}; - } - { - auto min_channel_deep = this->calculate_permission(permission::i_channel_min_depth, 0, false, permission_cache); - auto max_channel_deep = this->calculate_permission(permission::i_channel_max_depth, 0, false, permission_cache); + auto min_channel_deep = this->calculate_permission(permission::i_channel_min_depth, parent_channel_id, false, permission_cache); + auto max_channel_deep = this->calculate_permission(permission::i_channel_max_depth, parent_channel_id, false, permission_cache); if(min_channel_deep.has_value || max_channel_deep.has_value) { auto channel_deep = 0; @@ -704,8 +712,8 @@ command_result ConnectedClient::handleCommandChannelCreate(Command &cmd) { created_channel->properties()[property::CHANNEL_CREATED_BY] = this->getClientDatabaseId(); { - auto default_modify_power = this->calculate_permission(permission::i_channel_modify_power, 0, false, permission_cache); - auto default_delete_power = this->calculate_permission(permission::i_channel_delete_power, 0, false, permission_cache); + auto default_modify_power = this->calculate_permission(permission::i_channel_modify_power, parent_channel_id, false, permission_cache); + auto default_delete_power = this->calculate_permission(permission::i_channel_delete_power, parent_channel_id, false, permission_cache); auto permission_manager = created_channel->permissions(); permission_manager->set_permission( diff --git a/server/src/client/web/VoiceBridge.cpp b/server/src/client/web/VoiceBridge.cpp index e791ae5..74c3fe5 100644 --- a/server/src/client/web/VoiceBridge.cpp +++ b/server/src/client/web/VoiceBridge.cpp @@ -1,8 +1,7 @@ #include #include -#include -#include #include +#include #include "WebClient.h" #include "VoiceBridge.h" @@ -11,7 +10,7 @@ using namespace ts; using namespace ts::server; using namespace ts::web; -void log(pipes::Logger::LogLevel level, const std::string& name, const std::string& message, ...) { +void VoiceBridge::callback_log(void* ptr, pipes::Logger::LogLevel level, const std::string& name, const std::string& message, ...) { auto max_length = 1024 * 8; char buffer[max_length]; @@ -20,7 +19,49 @@ void log(pipes::Logger::LogLevel level, const std::string& name, const std::stri max_length = vsnprintf(buffer, max_length, message.c_str(), args); va_end(args); - debugMessage(LOG_GENERAL, "[WebRTC][{}][{}] {}", level, name, string(buffer)); + auto bridge = (VoiceBridge*) ptr; + debugMessage(LOG_GENERAL, "{}[WebRTC][{}][{}] {}", CLIENT_STR_LOG_PREFIX_(bridge->owner()), level, name, string(buffer)); +} + +namespace gioloop { + void* main_loop_; + + void*(*g_main_loop_new)(void* /* context */, bool /* is true */); + void(*g_main_loop_run)(void* /* loop */); + void(*g_main_loop_unref)(void* /* loop */); + void*(*g_main_loop_ref)(void* /* loop */); + + bool initialized{false}; + void initialize() { + if(initialized) return; + initialized = true; + + g_main_loop_new = (decltype(g_main_loop_new)) dlsym(nullptr, "g_main_loop_new"); + g_main_loop_run = (decltype(g_main_loop_run)) dlsym(nullptr, "g_main_loop_run"); + g_main_loop_ref = (decltype(g_main_loop_ref)) dlsym(nullptr, "g_main_loop_ref"); + g_main_loop_unref = (decltype(g_main_loop_unref)) dlsym(nullptr, "g_main_loop_unref"); + + if(!g_main_loop_run || !g_main_loop_new || !g_main_loop_ref || !g_main_loop_unref) { + logWarning(LOG_INSTANCE, "Missing g_main_loop_new, g_main_loop_run, g_main_loop_ref or g_main_loop_unref functions. Could not spawn main loop."); + g_main_loop_run = nullptr; + g_main_loop_new = nullptr; + return; + } + + main_loop_ = g_main_loop_new(nullptr, false); + if(!main_loop_) { + logError(LOG_INSTANCE, "Failed to spawn new event loop for the web client."); + return; + } + + std::thread([]{ + g_main_loop_run(main_loop_); + }).detach(); + } + + std::shared_ptr loop() { + return std::shared_ptr{(GMainLoop*) g_main_loop_ref(main_loop_), g_main_loop_unref}; + } } VoiceBridge::VoiceBridge(const shared_ptr& owner) : _owner(owner) { @@ -48,14 +89,16 @@ VoiceBridge::VoiceBridge(const shared_ptr& owner) : _owner(owner) { config->nice_config->allow_ice_tcp = false; config->nice_config->use_upnp = config::web::enable_upnp; - //FIXME Use the internal thread or a shared worker - /* Not creating the thread here because DataPipes has a better impl with a join + gioloop::initialize(); + config->nice_config->main_loop = gioloop::loop(); + /* config->nice_config->main_loop = std::shared_ptr(g_main_loop_new(nullptr, false), g_main_loop_unref); std::thread(g_main_loop_run, config->nice_config->main_loop.get()).detach(); */ config->logger = make_shared(); - config->logger->callback_log = log; + config->logger->callback_log = VoiceBridge::callback_log; + config->logger->callback_argument = this; //config->sctp.local_port = 5202; //Fire Fox don't support a different port :D this->connection = make_unique(config); @@ -87,7 +130,7 @@ bool VoiceBridge::initialize(std::string &error) { } }; - this->connection->callback_new_stream = [&](const std::shared_ptr &channel) { this->handle_media_stream(channel); }; //bind(&VoiceBridge::handle_media_stream, this, placeholders::_1); => crash + this->connection->callback_new_stream = [&](const std::shared_ptr &channel) { this->handle_media_stream(channel); }; //bind(&VoiceBridge::handle_media_stream, this, placeholders::_1); => crash this->connection->callback_setup_fail = [&](rtc::PeerConnection::ConnectionComponent comp, const std::string& reason) { debugMessage(this->server_id(), "{} WebRTC setup failed! Component {} ({})", CLIENT_STR_LOG_PREFIX_(this->owner()), comp, reason); if(this->callback_failed) @@ -123,20 +166,25 @@ void VoiceBridge::execute_tick() { } } -void VoiceBridge::handle_media_stream(const std::shared_ptr &undefined_stream) { +void VoiceBridge::handle_media_stream(const std::shared_ptr &undefined_stream) { if(undefined_stream->type() == rtc::CHANTYPE_APPLICATION) { - auto stream = dynamic_pointer_cast(undefined_stream); + auto stream = dynamic_pointer_cast(undefined_stream); if(!stream) return; stream->callback_datachannel_new = [&](const std::shared_ptr &channel) { this->handle_data_channel(channel); }; //bind(&VoiceBridge::handle_data_channel, this, placeholders::_1); => may crash? } else if(undefined_stream->type() == rtc::CHANTYPE_AUDIO) { - auto stream = dynamic_pointer_cast(undefined_stream); + auto stream = dynamic_pointer_cast(undefined_stream); if(!stream) return; this->_audio_channel = stream; stream->register_local_extension("urn:ietf:params:rtp-hdrext:ssrc-audio-level"); - //bind(&VoiceBridge::handle_audio_data, this, placeholders::_1, placeholders::_2, placeholders::_3); => may crash? - stream->incoming_data_handler = [&](const std::shared_ptr &channel, const pipes::buffer_view &data, size_t payload_offset) { this->handle_audio_data(channel, data, payload_offset); }; + for(const auto& codec : stream->list_codecs()) { + if(codec->type == rtc::codec::Codec::OPUS) { + codec->accepted = true; + break; + } + } + stream->incoming_data_handler = [&](const std::shared_ptr &channel, const pipes::buffer_view &data, size_t payload_offset) { this->handle_audio_data(channel, data, payload_offset); }; } else { logError(this->server_id(), "Got offer for unknown channel of type {}", undefined_stream->type()); } @@ -163,8 +211,8 @@ void VoiceBridge::handle_data_channel(const std::shared_ptr &c }; } -void VoiceBridge::handle_audio_data(const std::shared_ptr &channel, const pipes::buffer_view &data, size_t payload_offset) { - if(channel->codec->type != rtc::codec::TypedAudio::OPUS) { +void VoiceBridge::handle_audio_data(const std::shared_ptr &channel, const pipes::buffer_view &data, size_t payload_offset) { + if(channel->codec->type != rtc::codec::Codec::OPUS) { debugMessage(this->server_id(), "{} Got unknown codec ({})!", CLIENT_STR_LOG_PREFIX_(this->owner()), channel->codec->type); return; } @@ -172,7 +220,7 @@ void VoiceBridge::handle_audio_data(const std::shared_ptr &ch auto ac = _audio_channel.lock(); if(!ac) return; - for(const auto& ext : ac->list_extensions(0x02)) { + for(const auto& ext : ac->list_extensions(rtc::direction::incoming)) { if(ext->name == "urn:ietf:params:rtp-hdrext:ssrc-audio-level") { int level; if(rtc::protocol::rtp_header_extension_parse_audio_level(data, ext->id, &level) == 0) { diff --git a/server/src/client/web/VoiceBridge.h b/server/src/client/web/VoiceBridge.h index d0a8632..41ae577 100644 --- a/server/src/client/web/VoiceBridge.h +++ b/server/src/client/web/VoiceBridge.h @@ -1,8 +1,8 @@ #pragma once #include -#include -#include +#include +#include namespace ts { namespace server { @@ -36,19 +36,20 @@ namespace ts { void execute_tick(); private: + static void callback_log(void* ptr, pipes::Logger::LogLevel level, const std::string& name, const std::string& message, ...); inline int server_id(); inline std::shared_ptr owner(); - void handle_media_stream(const std::shared_ptr& /* stream */); + void handle_media_stream(const std::shared_ptr& /* stream */); void handle_data_channel(const std::shared_ptr & /* channel */); - void handle_audio_data(const std::shared_ptr& /* channel */, const pipes::buffer_view& /* buffer */, size_t /* payload offset */); + void handle_audio_data(const std::shared_ptr& /* channel */, const pipes::buffer_view& /* buffer */, size_t /* payload offset */); std::weak_ptr _owner; std::chrono::system_clock::time_point offer_timestamp; std::unique_ptr connection; std::shared_ptr _voice_channel; - std::weak_ptr _audio_channel; + std::weak_ptr _audio_channel; struct { uint16_t packet_id = 0; bool muted = true; diff --git a/server/src/client/web/WebClient.cpp b/server/src/client/web/WebClient.cpp index 6d04ae9..eafe1be 100644 --- a/server/src/client/web/WebClient.cpp +++ b/server/src/client/web/WebClient.cpp @@ -476,8 +476,11 @@ void WebClient::handleMessage(const std::string &message) { auto vb_ptr = &*this->voice_bridge; /* read only no lock needed */ std::thread([&, vb_ptr, lock = this->ref()]{ unique_lock vbl{this->voice_bridge_lock}; - if(&*this->voice_bridge == vb_ptr) - this->voice_bridge.release(); + if(&*this->voice_bridge == vb_ptr) { + auto bridge = std::exchange(this->voice_bridge, nullptr); + vbl.unlock(); + bridge.reset(); + } }).detach(); Json::Value response; @@ -551,7 +554,7 @@ void WebClient::handleMessage(const std::string &message) { this->sendJson(response); } } else if(subType == "ice") { - shared_lock read_voice_bridge_lock(this->voice_bridge_lock); + std::shared_lock read_voice_bridge_lock{this->voice_bridge_lock}; if(!this->voice_bridge) { debugMessage(this->getServerId(), "[{}] Received remote ICE candidate without having a voice bridge! Dropping candidate.", CLIENT_STR_LOG_PREFIX); return; @@ -578,7 +581,7 @@ void WebClient::handleMessage(const std::string &message) { } } } else if(subType == "ice_finish") { - shared_lock read_voice_bridge_lock(this->voice_bridge_lock); + std::shared_lock read_voice_bridge_lock{this->voice_bridge_lock}; if(!this->voice_bridge) { debugMessage(this->getServerId(), "[{}] Received remote ICE candidate without having a voice bridge! Dropping candidate.", CLIENT_STR_LOG_PREFIX); return; diff --git a/server/src/manager/ConversationManager.h b/server/src/manager/ConversationManager.h index 9d8ed75..4f6415d 100644 --- a/server/src/manager/ConversationManager.h +++ b/server/src/manager/ConversationManager.h @@ -222,7 +222,7 @@ namespace ts { class ConversationManager { public: - ConversationManager(const std::shared_ptr& /* server */); + explicit ConversationManager(const std::shared_ptr& /* server */); virtual ~ConversationManager(); void initialize(const std::shared_ptr& _this); diff --git a/server/src/terminal/CommandHandler.cpp b/server/src/terminal/CommandHandler.cpp index 3f2708c..1a2b151 100644 --- a/server/src/terminal/CommandHandler.cpp +++ b/server/src/terminal/CommandHandler.cpp @@ -473,8 +473,10 @@ namespace terminal { if(cmd.arguments.size() < 1) { value = 1024; - rlimit limit{1024, 10000}; - setrlimit(7, &limit); + rlimit rlimit{0, 0}; + getrlimit(RLIMIT_NOFILE, &rlimit); + logMessage("RLimit: {}/{}", rlimit.rlim_cur, rlimit.rlim_max); + //setrlimit(7, &limit); } else if(cmd.larguments[0] == "clear") { logMessage("Clearup leaks"); for(auto& fd : fd_leaks)