diff --git a/git-teaspeak b/git-teaspeak index 4c4c216..93ac500 160000 --- a/git-teaspeak +++ b/git-teaspeak @@ -1 +1 @@ -Subproject commit 4c4c2161722469fffebc5dbb0411af884d3b709e +Subproject commit 93ac5008175a2925d8031ab04555913fe97e9baf diff --git a/rtclib b/rtclib index c65d26c..f6b0368 160000 --- a/rtclib +++ b/rtclib @@ -1 +1 @@ -Subproject commit c65d26c58c82dbdd2091a9ba53eb83a249fd189f +Subproject commit f6b03688f0f80803f182fdaab7d645f4f7633bdf diff --git a/server/lock_concept b/server/lock_concept index f258142..13d33d0 100644 --- a/server/lock_concept +++ b/server/lock_concept @@ -1,3 +1,9 @@ +Locking Order: +Channel Tree: +1. Server Channel Tree +2. Client Channel Tree + + CommandResult handleCommandClientUpdate(Command&); CommandResult handleCommandClientEdit(Command&); CommandResult handleCommandClientEdit(Command&, const std::shared_ptr& /* target */); @@ -55,4 +61,4 @@ Move client acts like access server channel tree: write lock channel_tree_lock = TODO: Some kind of perm channel lock TODO: Fix handleCommandChannelEdit -Test: Channel hide & show with clients! Multible clients as well! \ No newline at end of file +Test: Channel hide & show with clients! Multiple clients as well! \ No newline at end of file diff --git a/server/src/client/SpeakingClient.cpp b/server/src/client/SpeakingClient.cpp index 55d4094..68c8671 100644 --- a/server/src/client/SpeakingClient.cpp +++ b/server/src/client/SpeakingClient.cpp @@ -100,18 +100,26 @@ command_result SpeakingClient::handleCommandClientInit(Command& cmd) { { lock_guard lock(this->server->join_attempts_lock); - auto inetAddr = this->getPeerIp(); - if(config::voice::clientConnectLimit > 0 && this->server->join_attempts[inetAddr] + 1 > config::voice::clientConnectLimit) + auto client_address = this->getPeerIp(); + auto& client_join_attempts = this->server->join_attempts[client_address]; + auto& general_join_attempts = this->server->join_attempts["_"]; + + if(config::voice::clientConnectLimit > 0 && client_join_attempts + 1 > config::voice::clientConnectLimit) { return command_result{error::client_join_rate_limit_reached}; - if(config::voice::connectLimit > 0 && this->server->join_attempts["_"] + 1 > config::voice::connectLimit) + } + + if(config::voice::connectLimit > 0 && general_join_attempts + 1 > config::voice::connectLimit) { return command_result{error::server_join_rate_limit_reached}; - this->server->join_attempts[inetAddr]++; - this->server->join_attempts["_"]++; + } + + client_join_attempts++; + general_join_attempts++; } TIMING_STEP(timings, "join atmp c"); - if(!DatabaseHelper::assignDatabaseId(this->server->getSql(), this->server->getServerId(), _this.lock())) + if(!DatabaseHelper::assignDatabaseId(this->server->getSql(), this->server->getServerId(), _this.lock())) { return command_result{error::vs_critical, "Could not assign database id!"}; + } TIMING_STEP(timings, "db assign "); this->server->getGroupManager()->enableCache(this->getClientDatabaseId()); diff --git a/server/src/client/voice/PacketEncoder.cpp b/server/src/client/voice/PacketEncoder.cpp index 958af42..f0b1acd 100644 --- a/server/src/client/voice/PacketEncoder.cpp +++ b/server/src/client/voice/PacketEncoder.cpp @@ -94,9 +94,9 @@ void PacketEncoder::send_packet_acknowledge(uint16_t pid, bool low) { #define MAX_COMMAND_PACKET_PAYLOAD_LENGTH (487) -void PacketEncoder::send_command(const std::string_view &command, bool low, std::unique_ptr> ack_listener) { +void PacketEncoder::send_command(const std::string_view &command, bool low, std::unique_ptr> ack_listener) { bool own_data_buffer{false}; - void* own_data_buffer_ptr; /* imutable! */ + void* own_data_buffer_ptr; /* immutable! */ const char* data_buffer{command.data()}; size_t data_length{command.length()}; diff --git a/server/src/client/voice/PacketEncoder.h b/server/src/client/voice/PacketEncoder.h index 23674f7..8517430 100644 --- a/server/src/client/voice/PacketEncoder.h +++ b/server/src/client/voice/PacketEncoder.h @@ -44,7 +44,7 @@ namespace ts::server::server::udp { void send_packet(protocol::OutgoingServerPacket* /* packet */); /* will claim ownership */ void send_packet(protocol::PacketType /* type */, protocol::PacketFlag::PacketFlags /* flags */, const void* /* payload */, size_t /* payload length */); - void send_command(const std::string_view& /* build command command */, bool /* command low */, std::unique_ptr> /* acknowledge listener */); + void send_command(const std::string_view& /* build command command */, bool /* command low */, std::unique_ptr> /* acknowledge listener */); void send_packet_acknowledge(uint16_t /* packet id */, bool /* acknowledge low */); diff --git a/server/src/client/voice/VoiceClient.cpp b/server/src/client/voice/VoiceClient.cpp index 0f2da0a..3b09e21 100644 --- a/server/src/client/voice/VoiceClient.cpp +++ b/server/src/client/voice/VoiceClient.cpp @@ -59,7 +59,7 @@ VoiceClient::~VoiceClient() { memtrack::freed(this); } -void VoiceClient::sendCommand0(const std::string_view& cmd, bool low, std::unique_ptr> listener) { +void VoiceClient::sendCommand0(const std::string_view& cmd, bool low, std::unique_ptr> listener) { this->connection->send_command(cmd, low, std::move(listener)); #ifdef PKT_LOG_CMD @@ -146,21 +146,22 @@ bool VoiceClient::disconnect(ts::ViewReasonId reason_id, const std::string &reas this->currentChannel = nullptr; } - auto listener = make_unique>(); auto weak_self = this->_this; - listener->waitAndGetLater([weak_self](bool* success) { - if(weak_self.expired()) return; + this->sendCommand0(cmd.build(), false, std::make_unique>([weak_self](bool success) { auto self = weak_self.lock(); - if(!self) return; + if(!self) { + return; + } - if(!success || !*success) { + if(!success) { + /* In theory we have no need to disconnect the client any more since a failed acknowledge would do the trick for us */ debugMessage(self->getServerId(), "{} Failed to receive disconnect acknowledge!", CLIENT_STR_LOG_PREFIX_(self)); - } else + } else { debugMessage(self->getServerId(), "{} Received disconnect acknowledge!", CLIENT_STR_LOG_PREFIX_(self)); + } self->close_connection(chrono::system_clock::time_point{}); /* we received the ack, we do not need to flush anything */ - }, system_clock::now() + seconds(5)); - this->sendCommand0(cmd.build(), false, std::move(listener)); + })); } else { //TODO: Extra case for INIT_HIGH? this->close_connection(chrono::system_clock::now() + chrono::seconds{5}); diff --git a/server/src/client/voice/VoiceClient.h b/server/src/client/voice/VoiceClient.h index 561d212..4753928 100644 --- a/server/src/client/voice/VoiceClient.h +++ b/server/src/client/voice/VoiceClient.h @@ -65,11 +65,11 @@ namespace ts { bool disconnect(const std::string&) override; bool disconnect(ViewReasonId /* reason type */, const std::string& /* reason */, const std::shared_ptr& /* invoker */, bool /* notify viewer */); - void sendCommand(const ts::Command &command, bool low = false) override { return this->sendCommand0(command.build(), low); } - void sendCommand(const ts::command_builder &command, bool low) override { return this->sendCommand0(command.build(), low); } + void sendCommand(const ts::Command &command, bool low = false) override { return this->sendCommand0(command.build(), low, nullptr); } + void sendCommand(const ts::command_builder &command, bool low) override { return this->sendCommand0(command.build(), low, nullptr); } /* Note: Order is only guaranteed if progressDirectly is on! */ - virtual void sendCommand0(const std::string_view& /* data */, bool low = false, std::unique_ptr> listener = nullptr); + virtual void sendCommand0(const std::string_view& /* data */, bool low, std::unique_ptr> listener); connection::VoiceClientConnection* getConnection(){ return connection; } std::shared_ptr getVoiceServer(){ return voice_server; } diff --git a/server/src/client/voice/VoiceClientConnection.cpp b/server/src/client/voice/VoiceClientConnection.cpp index fbaa957..8a754f7 100644 --- a/server/src/client/voice/VoiceClientConnection.cpp +++ b/server/src/client/voice/VoiceClientConnection.cpp @@ -230,7 +230,7 @@ void VoiceClientConnection::send_packet(protocol::OutgoingServerPacket* packet) this->packet_encoder_.send_packet(packet); } -void VoiceClientConnection::send_command(const std::string_view &cmd, bool b, std::unique_ptr> cb) { +void VoiceClientConnection::send_command(const std::string_view &cmd, bool b, std::unique_ptr> cb) { this->packet_encoder_.send_command(cmd, b, std::move(cb)); } diff --git a/server/src/client/voice/VoiceClientConnection.h b/server/src/client/voice/VoiceClientConnection.h index f17e001..1712d60 100644 --- a/server/src/client/voice/VoiceClientConnection.h +++ b/server/src/client/voice/VoiceClientConnection.h @@ -58,7 +58,7 @@ namespace ts { void send_packet(protocol::PacketType /* type */, protocol::PacketFlag::PacketFlags /* flags */, const void* /* payload */, size_t /* payload length */); void send_packet(protocol::OutgoingServerPacket* /* packet */); /* method takes ownership of the packet */ - void send_command(const std::string_view& /* build command command */, bool /* command low */, std::unique_ptr> /* acknowledge listener */); + void send_command(const std::string_view& /* build command command */, bool /* command low */, std::unique_ptr> /* acknowledge listener */); CryptHandler* getCryptHandler(){ return &crypt_handler; } diff --git a/shared b/shared index c1085c8..c079098 160000 --- a/shared +++ b/shared @@ -1 +1 @@ -Subproject commit c1085c84cfa24921587c19cb3a2d5e1864473025 +Subproject commit c0790984eeea45c2692680fd133e6048cbafe57c