From 94c7eb2f392494abc3eb1dae771b1ba944499f32 Mon Sep 17 00:00:00 2001 From: WolverinDEV Date: Thu, 14 Jan 2021 22:16:56 +0100 Subject: [PATCH] Improved abort signal printing and some reformats --- file/local_server/LocalFileTransferDisk.cpp | 3 +- .../local_server/LocalFileTransferNetwork.cpp | 25 +++-- file/local_server/NetTools.h | 7 +- rtclib | 2 +- server/src/SignalHandler.cpp | 34 +++++-- server/src/SignalHandler.h | 2 + server/src/client/command_handler/file.cpp | 10 +- server/src/client/command_handler/misc.cpp | 6 +- server/src/client/shared/WhisperHandler.cpp | 25 ++--- server/src/client/voice/PacketDecoder.cpp | 17 ++-- server/src/client/voice/PacketEncoder.cpp | 98 ++++++++++--------- server/src/client/voice/PacketEncoder.h | 2 +- .../client/voice/ServerCommandExecutor.cpp | 3 +- server/src/client/web/WSWebClient.cpp | 4 +- 14 files changed, 143 insertions(+), 95 deletions(-) diff --git a/file/local_server/LocalFileTransferDisk.cpp b/file/local_server/LocalFileTransferDisk.cpp index 3f187a5..18aff29 100644 --- a/file/local_server/LocalFileTransferDisk.cpp +++ b/file/local_server/LocalFileTransferDisk.cpp @@ -116,8 +116,9 @@ bool FileClient::enqueue_disk_buffer_bytes(const void *snd_buffer, size_t size) size_t buffer_size; { std::lock_guard block{this->disk_buffer.mutex}; - if(this->disk_buffer.write_disconnected) + if(this->disk_buffer.write_disconnected) { goto write_disconnected; + } *this->disk_buffer.buffer_tail = tbuffer; this->disk_buffer.buffer_tail = &tbuffer->next; diff --git a/file/local_server/LocalFileTransferNetwork.cpp b/file/local_server/LocalFileTransferNetwork.cpp index 61ac1b5..fe576cd 100644 --- a/file/local_server/LocalFileTransferNetwork.cpp +++ b/file/local_server/LocalFileTransferNetwork.cpp @@ -133,8 +133,10 @@ bool FileClient::enqueue_network_buffer_bytes(const void *snd_buffer, size_t siz size_t buffer_size; { std::lock_guard block{this->network_buffer.mutex}; - if(this->network_buffer.write_disconnected) + if(this->network_buffer.write_disconnected) { goto write_disconnected; + } + *this->network_buffer.buffer_tail = tbuffer; this->network_buffer.buffer_tail = &tbuffer->next; @@ -898,8 +900,9 @@ size_t LocalFileTransfer::handle_transfer_read_raw(const std::shared_ptrtransfer_key.provided_bytes += bytes_write; } - if(client->transfer_key.provided_bytes < TRANSFER_KEY_LENGTH) + if(client->transfer_key.provided_bytes < TRANSFER_KEY_LENGTH) { return 0; /* we need more data */ + } if(pipes::SSL::is_ssl((uint8_t*) client->transfer_key.key, client->transfer_key.provided_bytes)) { client->networking.protocol = FileClient::PROTOCOL_HTTPS; @@ -911,12 +914,14 @@ size_t LocalFileTransfer::handle_transfer_read_raw(const std::shared_ptrtransfer_key.key, TRANSFER_KEY_LENGTH); client->transfer_key.provided_bytes = 0; - if(!this->initialize_client_ssl(client)) + if(!this->initialize_client_ssl(client)) { return (size_t) -1; + } client->networking.pipe_ssl.process_incoming_data(pipes::buffer_view{first_bytes, TRANSFER_KEY_LENGTH}); - if(length > 0) + if(length > 0) { client->networking.pipe_ssl.process_incoming_data(pipes::buffer_view{buffer, length}); + } return client->network_buffer.bytes; } else { client->networking.protocol = FileClient::PROTOCOL_TS_V1; @@ -1226,8 +1231,9 @@ TransferKeyApplyResult LocalFileTransfer::handle_transfer_key_provided(const std } } - if(!client->transfer) + if(!client->transfer) { return TransferKeyApplyResult::UNKNOWN_KEY; + } if(client->transfer->direction == Transfer::DIRECTION_UPLOAD) { auto server = dynamic_pointer_cast(client->transfer->server); @@ -1255,14 +1261,16 @@ TransferKeyApplyResult LocalFileTransfer::handle_transfer_key_provided(const std { std::unique_lock slock{client->state_mutex}; - if(client->state != FileClient::STATE_AWAITING_KEY) + if(client->state != FileClient::STATE_AWAITING_KEY) { return TransferKeyApplyResult::SUCCESS; /* something disconnected the client */ + } client->state = FileClient::STATE_TRANSFERRING; } - if(auto callback{this->callback_transfer_started}; callback) + if(auto callback{this->callback_transfer_started}; callback) { callback(client->transfer); + } client->timings.key_received = std::chrono::system_clock::now(); return TransferKeyApplyResult::SUCCESS; @@ -1283,8 +1291,9 @@ TransferUploadRawResult LocalFileTransfer::handle_transfer_upload_raw(const std: client->statistics.file_transferred.increase_bytes(write_length); client->enqueue_disk_buffer_bytes(buffer, write_length); this->enqueue_disk_io(client); - if(bytesWritten) + if(bytesWritten) { *bytesWritten = write_length; + } return result; } diff --git a/file/local_server/NetTools.h b/file/local_server/NetTools.h index 3d2e044..71d77c5 100644 --- a/file/local_server/NetTools.h +++ b/file/local_server/NetTools.h @@ -107,8 +107,9 @@ namespace ts::server::file::networking { throttle |= this->right->should_throttle(right_timestamp); if(!throttle) return false; - if(right_timestamp.tv_sec > next_timestamp.tv_sec || (right_timestamp.tv_sec == next_timestamp.tv_sec && right_timestamp.tv_usec > next_timestamp.tv_usec)) + if(right_timestamp.tv_sec > next_timestamp.tv_sec || (right_timestamp.tv_sec == next_timestamp.tv_sec && right_timestamp.tv_usec > next_timestamp.tv_usec)) { next_timestamp = right_timestamp; + } return true; } @@ -141,8 +142,10 @@ namespace ts::server::file::networking { std::lock_guard slock{this->mutex}; this->total_bytes += bytes; - if(this->span_index != current_span) + if(this->span_index != current_span) { this->history[this->span_index % kAverageTimeCount] = std::exchange(this->span_bytes, 0); + } + this->span_index = current_span; this->span_bytes += bytes; } diff --git a/rtclib b/rtclib index 2c08b87..449f4f3 160000 --- a/rtclib +++ b/rtclib @@ -1 +1 @@ -Subproject commit 2c08b8759268095b96f3904757300905db1ea61d +Subproject commit 449f4f3baab91ba488f83def70193d08f350f193 diff --git a/server/src/SignalHandler.cpp b/server/src/SignalHandler.cpp index 87c3c79..83b1ad3 100644 --- a/server/src/SignalHandler.cpp +++ b/server/src/SignalHandler.cpp @@ -26,6 +26,18 @@ google_breakpad::ExceptionHandler* globalExceptionHandler = nullptr; if(signal(s, c) != nullptr) logError(LOG_GENERAL, "Cant setup signal handler for " #s); +void print_current_exception() { + if(std::current_exception()) { + logCritical(LOG_GENERAL, "Exception reached stack root and cause the server to crash!"); + logCritical(LOG_GENERAL, " Type: {}", std::current_exception().__cxa_exception_type()->name()); + try { + std::rethrow_exception(std::current_exception()); + } catch(std::exception& ex) { + logCritical(LOG_GENERAL, " Message: {}", ex.what()); + } catch(...) {} + } +} + extern bool mainThreadDone; #ifdef BREAKPAD_EXCEPTION_HANDLER static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, void* context, bool succeeded) { @@ -41,15 +53,7 @@ static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, } catch (...) { logCritical(LOG_GENERAL, "Failed to write/move crash dump!"); } - if(std::current_exception()) { - logCritical(LOG_GENERAL, "Exception reached stack root and cause the server to crash!"); - logCritical(LOG_GENERAL, " Type: {}", std::current_exception().__cxa_exception_type()->name()); - try { - std::rethrow_exception(std::current_exception()); - } catch(std::exception& ex) { - logCritical(LOG_GENERAL, " Message: {}", ex.what()); - } catch(...) {} - } + print_current_exception(); logCritical(LOG_GENERAL, "Please report this crash to the TeaSpeak maintainer WolverinDEV"); logCritical(LOG_GENERAL, "Official issue and bug tracker url: https://github.com/TeaSpeak/TeaSpeak/issues"); @@ -58,7 +62,9 @@ static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, terminal::finalize_pipe(); ts::server::shutdownInstance(ts::config::messages::applicationCrashed); - while(!mainThreadDone) threads::self::sleep_for(chrono::seconds(1)); + while(!mainThreadDone) { + threads::self::sleep_for(chrono::seconds(1)); + } return succeeded; } #endif @@ -75,6 +81,8 @@ bool ts::syssignal::setup() { //We cant listen for this signal if stdin ist a atty SIG(SIGINT, &ts::syssignal::handleStopSignal); } + SIG(SIGABRT, &ts::syssignal::handleAbortSignal); + std::set_terminate(ts::syssignal::handleTerminate); return true; } @@ -116,4 +124,10 @@ void ts::syssignal::handleStopSignal(int signal) { raise(SIGKILL); } ts::server::shutdownInstance(); +} + + +void ts::syssignal::handleTerminate() { + logCritical(0, "The server crashed (Received a terminate signal)!"); + print_current_exception(); } \ No newline at end of file diff --git a/server/src/SignalHandler.h b/server/src/SignalHandler.h index 6ff5215..13bcf9e 100644 --- a/server/src/SignalHandler.h +++ b/server/src/SignalHandler.h @@ -8,5 +8,7 @@ namespace ts { extern bool setup(); extern bool setup_threads(); extern void handleStopSignal(int); + extern void handleAbortSignal(int); + extern void handleTerminate(); } } \ No newline at end of file diff --git a/server/src/client/command_handler/file.cpp b/server/src/client/command_handler/file.cpp index 23aefd9..a1a81c3 100644 --- a/server/src/client/command_handler/file.cpp +++ b/server/src/client/command_handler/file.cpp @@ -40,7 +40,6 @@ using namespace ts::token; constexpr static auto kFileAPITimeout = std::chrono::milliseconds{500}; constexpr static auto kMaxClientTransfers = 10; -#define QUERY_PASSWORD_LENGTH 12 //ftgetfilelist cid=1 cpw path=\/ return_code=1:x //Answer: @@ -90,8 +89,9 @@ command_result ConnectedClient::handleCommandFTGetFileList(Command &cmd) { } } - if(!query_result->wait_for(kFileAPITimeout)) + if(!query_result->wait_for(kFileAPITimeout)) { return command_result{error::file_api_timeout}; + } if(!query_result->succeeded()) { debugMessage(this->getServerId(), "{} Failed to query directory: {} / {}", CLIENT_STR_LOG_PREFIX, file::filesystem::directory_query_error_messages[(int) query_result->error().error_type], query_result->error().error_message); @@ -118,8 +118,9 @@ command_result ConnectedClient::handleCommandFTGetFileList(Command &cmd) { } const auto& files = query_result->response(); - if(files.empty()) + if(files.empty()) { return command_result{error::database_empty_result}; + } auto return_code = cmd["return_code"].size() > 0 ? cmd["return_code"].string() : ""; @@ -131,8 +132,9 @@ command_result ConnectedClient::handleCommandFTGetFileList(Command &cmd) { notify_file_list.reset(); notify_file_list.put_unchecked(0, "path", cmd["path"].string()); notify_file_list.put_unchecked(0, "cid", cmd["cid"].string()); - if(!return_code.empty()) + if(!return_code.empty()){ notify_file_list.put_unchecked(0, "return_code", return_code); + } } auto bulk = notify_file_list.bulk(bulk_index++); diff --git a/server/src/client/command_handler/misc.cpp b/server/src/client/command_handler/misc.cpp index a55d9da..8953ad4 100644 --- a/server/src/client/command_handler/misc.cpp +++ b/server/src/client/command_handler/misc.cpp @@ -663,8 +663,9 @@ command_result ConnectedClient::handleCommandBanList(Command &cmd) { CMD_CHK_AND_INC_FLOOD_POINTS(25); ServerId sid = this->getServerId(); - if (cmd[0].has("sid")) + if (cmd[0].has("sid")) { sid = cmd["sid"]; + } if (sid == 0) { ACTION_REQUIRES_GLOBAL_PERMISSION(permission::b_client_ban_list_global, 1); @@ -672,8 +673,9 @@ command_result ConnectedClient::handleCommandBanList(Command &cmd) { auto server = serverInstance->getVoiceServerManager()->findServerById(sid); if (!server) return command_result{error::parameter_invalid}; - if (!permission::v2::permission_granted(1, server->calculate_permission(permission::b_client_ban_list, this->getClientDatabaseId(), this->getType(), 0))) + if (!permission::v2::permission_granted(1, server->calculate_permission(permission::b_client_ban_list, this->getClientDatabaseId(), this->getType(), 0))) { return command_result{permission::b_client_ban_list}; + } } //When empty: return command_result{error::database_empty_result}; diff --git a/server/src/client/shared/WhisperHandler.cpp b/server/src/client/shared/WhisperHandler.cpp index 9868141..b33820f 100644 --- a/server/src/client/shared/WhisperHandler.cpp +++ b/server/src/client/shared/WhisperHandler.cpp @@ -18,8 +18,6 @@ WhisperHandler::~WhisperHandler() { } bool WhisperHandler::validate_whisper_packet(const protocol::ClientPacketParser &packet, bool& match_last_header, void *&payload_ptr, size_t &payload_length) { - std::lock_guard process_lock{this->whisper_head_mutex}; - size_t head_length; if(packet.flags() & protocol::PacketFlag::NewProtocol) { if(packet.payload_length() < 3 + 10) { @@ -45,19 +43,22 @@ bool WhisperHandler::validate_whisper_packet(const protocol::ClientPacketParser } auto head_ptr = packet.payload().data_ptr() + 3; - match_last_header = this->whisper_head_length == head_length && memcmp(this->whisper_head_ptr, head_ptr, head_length) == 0; - if(!match_last_header) { - if(this->whisper_head_capacity < head_length) { - if(this->whisper_head_ptr) { - ::free(this->whisper_head_ptr); + { + std::lock_guard process_lock{this->whisper_head_mutex}; + match_last_header = this->whisper_head_length == head_length && memcmp(this->whisper_head_ptr, head_ptr, head_length) == 0; + if(!match_last_header) { + if(this->whisper_head_capacity < head_length) { + if(this->whisper_head_ptr) { + ::free(this->whisper_head_ptr); + } + + this->whisper_head_ptr = malloc(head_length); + this->whisper_head_capacity = head_length; } - this->whisper_head_ptr = malloc(head_length); - this->whisper_head_capacity = head_length; + this->whisper_head_length = head_length; + memcpy(this->whisper_head_ptr, head_ptr, head_length); } - - this->whisper_head_length = head_length; - memcpy(this->whisper_head_ptr, head_ptr, head_length); } assert(packet.payload_length() >= head_length + 3); diff --git a/server/src/client/voice/PacketDecoder.cpp b/server/src/client/voice/PacketDecoder.cpp index ec6d698..ae7c32a 100644 --- a/server/src/client/voice/PacketDecoder.cpp +++ b/server/src/client/voice/PacketDecoder.cpp @@ -221,10 +221,11 @@ CommandReassembleResult PacketDecoder::try_reassemble_ordered_packet( ReassembledCommand *&assembled_command) { assert(buffer_lock.owns_lock()); - if(!buffer.front_set()) + if(!buffer.front_set()) { return CommandReassembleResult::NO_COMMANDS_PENDING; + } - uint8_t packet_flags{0}; + uint8_t packet_flags; std::unique_ptr rcommand{nullptr, ReassembledCommand::free}; @@ -234,11 +235,13 @@ CommandReassembleResult PacketDecoder::try_reassemble_ordered_packet( uint16_t sequence_length{1}; size_t total_payload_length{first_buffer.payload_length}; do { - if(sequence_length >= buffer.capacity()) + if(sequence_length >= buffer.capacity()) { return CommandReassembleResult::SEQUENCE_LENGTH_TOO_LONG; + } - if(!buffer.slot_set(sequence_length)) + if(!buffer.slot_set(sequence_length)) { return CommandReassembleResult::NO_COMMANDS_PENDING; /* we need more packets */ + } auto& packet = buffer.slot_value(sequence_length++); total_payload_length += packet.payload_length; @@ -293,12 +296,14 @@ CommandReassembleResult PacketDecoder::try_reassemble_ordered_packet( auto compressed_command = std::move(rcommand); auto decompressed_size = compression::qlz_decompressed_size(compressed_command->command(), compressed_command->length()); - if(decompressed_size > 64 * 1024 * 1024) + if(decompressed_size > 64 * 1024 * 1024) { return CommandReassembleResult::COMMAND_TOO_LARGE; + } rcommand.reset(ReassembledCommand::allocate(decompressed_size)); - if(!compression::qlz_decompress_payload(compressed_command->command(), rcommand->command(), &decompressed_size)) + if(!compression::qlz_decompress_payload(compressed_command->command(), rcommand->command(), &decompressed_size)) { return CommandReassembleResult::COMMAND_DECOMPRESS_FAILED; + } rcommand->set_length(decompressed_size); } diff --git a/server/src/client/voice/PacketEncoder.cpp b/server/src/client/voice/PacketEncoder.cpp index 25737e1..210cc2d 100644 --- a/server/src/client/voice/PacketEncoder.cpp +++ b/server/src/client/voice/PacketEncoder.cpp @@ -5,7 +5,8 @@ #include #include -#include +#include +#include using namespace ts; using namespace ts::server::server::udp; @@ -15,7 +16,7 @@ PacketEncoder::PacketEncoder(ts::connection::CryptHandler *crypt_handler, client this->acknowledge_manager_.callback_data = this; this->acknowledge_manager_.destroy_packet = [](void* packet) { - reinterpret_cast(packet)->unref(); + reinterpret_cast(packet)->unref(); }; this->acknowledge_manager_.callback_resend_failed = [](void* this_ptr, const auto& entry) { auto encoder = reinterpret_cast(this_ptr); @@ -37,7 +38,7 @@ void PacketEncoder::reset() { rhead = std::exchange(this->resend_queue_head, nullptr); this->encrypt_queue_tail = &this->encrypt_queue_head; - this->resend_queue_tail = &this->resend_queue_head; + this->send_queue_tail = &this->resend_queue_head; } while(whead) { @@ -87,8 +88,8 @@ void PacketEncoder::send_packet_acknowledge(uint16_t pid, bool low) { char buffer[2]; le2be16(pid, buffer); - auto pflags = PacketFlag::Unencrypted | PacketFlag::NewProtocol; - this->send_packet(low ? protocol::PacketType::ACK_LOW : protocol::PacketType::ACK, (PacketFlag::PacketFlag) pflags, buffer, 2); + auto pflags = protocol::PacketFlag::Unencrypted | protocol::PacketFlag::NewProtocol; + this->send_packet(low ? protocol::PacketType::ACK_LOW : protocol::PacketType::ACK, (protocol::PacketFlag::PacketFlag) pflags, buffer, 2); } @@ -101,7 +102,7 @@ void PacketEncoder::send_command(const std::string_view &command, bool low, std: size_t data_length{command.length()}; uint8_t head_pflags{0}; - PacketType ptype{low ? PacketType::COMMAND_LOW : PacketType::COMMAND}; + protocol::PacketType ptype{low ? protocol::PacketType::COMMAND_LOW : protocol::PacketType::COMMAND}; protocol::OutgoingServerPacket *packets_head{nullptr}; protocol::OutgoingServerPacket **packets_tail{&packets_head}; @@ -123,19 +124,19 @@ void PacketEncoder::send_command(const std::string_view &command, bool low, std: data_buffer = (char*) compressed_buffer; own_data_buffer_ptr = compressed_buffer; data_length = compressed_size; - head_pflags |= PacketFlag::Compressed; + head_pflags |= protocol::PacketFlag::Compressed; } else { ::free(compressed_buffer); } } - uint8_t ptype_and_flags{(uint8_t) ((uint8_t) ptype | (uint8_t) PacketFlag::NewProtocol)}; + uint8_t ptype_and_flags{(uint8_t) ((uint8_t) ptype | (uint8_t) protocol::PacketFlag::NewProtocol)}; if(data_length > MAX_COMMAND_PACKET_PAYLOAD_LENGTH) { auto chunk_count = (size_t) ceil((float) data_length / (float) MAX_COMMAND_PACKET_PAYLOAD_LENGTH); auto chunk_size = (size_t) ceil((float) data_length / (float) chunk_count); while(true) { - auto bytes = min(chunk_size, data_length); + auto bytes = std::min(chunk_size, data_length); auto packet = protocol::allocate_outgoing_packet(bytes); packet->type_and_flags = ptype_and_flags; memcpy(packet->payload, data_buffer, bytes); @@ -145,12 +146,12 @@ void PacketEncoder::send_command(const std::string_view &command, bool low, std: data_length -= bytes; if(data_length == 0) { - packet->type_and_flags |= PacketFlag::Fragmented; + packet->type_and_flags |= protocol::PacketFlag::Fragmented; break; } data_buffer += bytes; } - packets_head->type_and_flags |= PacketFlag::Fragmented; + packets_head->type_and_flags |= protocol::PacketFlag::Fragmented; } else { auto packet = protocol::allocate_outgoing_packet(data_length); packet->type_and_flags = ptype_and_flags; @@ -163,20 +164,19 @@ void PacketEncoder::send_command(const std::string_view &command, bool low, std: { std::lock_guard id_lock{this->packet_id_mutex}; - { - uint32_t full_id; - auto head = packets_head; - while(head) { - full_id = this->packet_id_manager.generate_full_id(ptype); - head->set_packet_id(full_id & 0xFFFFU); - head->generation = full_id >> 16U; + uint32_t full_id; + auto head = packets_head; + while(head) { + full_id = this->packet_id_manager.generate_full_id(ptype); - /* loss stats (In order required so we're using the this->packet_id_mutex) */ - this->packet_statistics_->send_command(head->packet_type(), full_id); + head->set_packet_id(full_id & 0xFFFFU); + head->generation = full_id >> 16U; - head = head->next; - } + /* loss stats (In order required so we're using the this->packet_id_mutex) */ + this->packet_statistics_->send_command(head->packet_type(), full_id); + + head = head->next; } } packets_head->type_and_flags |= head_pflags; @@ -200,10 +200,11 @@ void PacketEncoder::send_command(const std::string_view &command, bool low, std: head->ref(); /* Even thou the packet is yet unencrypted, it will be encrypted with the next write. The next write will be before the next resend because the next ptr must be null in order to resend a packet */ - if(&head->next == packets_tail) + if(&head->next == packets_tail) { this->acknowledge_manager_.process_packet(ptype, full_packet_id, head, std::move(ack_listener)); - else + } else { this->acknowledge_manager_.process_packet(ptype, full_packet_id, head, nullptr); + } head = head->next; } @@ -222,7 +223,7 @@ void PacketEncoder::send_command(const std::string_view &command, bool low, std: } void PacketEncoder::encrypt_pending_packets() { - OutgoingServerPacket* packets_head; + protocol::OutgoingServerPacket* packets_head; { std::lock_guard wlock{this->write_queue_mutex}; packets_head = this->encrypt_queue_head; @@ -230,36 +231,39 @@ void PacketEncoder::encrypt_pending_packets() { this->encrypt_queue_tail = &this->encrypt_queue_head; } - if(!packets_head) + if(!packets_head) { return; + } auto packet = packets_head; auto packet_tail = packet; while(packet) { this->prepare_outgoing_packet(packet); packet = packet->next; - if(packet) + + if(packet) { packet_tail = packet; + } } { std::lock_guard wlock{this->write_queue_mutex}; - *this->resend_queue_tail = packets_head; - this->resend_queue_tail = &packet_tail->next; + *this->send_queue_tail = packets_head; + this->send_queue_tail = &packet_tail->next; } } bool PacketEncoder::prepare_outgoing_packet(ts::protocol::OutgoingServerPacket *packet) { - if(packet->type_and_flags & PacketFlag::Unencrypted) { + if(packet->type_and_flags & protocol::PacketFlag::Unencrypted) { this->crypt_handler_->write_default_mac(packet->mac); } else { - CryptHandler::key_t crypt_key{}; - CryptHandler::nonce_t crypt_nonce{}; + connection::CryptHandler::key_t crypt_key{}; + connection::CryptHandler::nonce_t crypt_nonce{}; std::string error{}; if(!this->crypt_handler_->encryption_initialized()) { - crypt_key = CryptHandler::kDefaultKey; - crypt_nonce = CryptHandler::kDefaultNonce; + crypt_key = connection::CryptHandler::kDefaultKey; + crypt_nonce = connection::CryptHandler::kDefaultNonce; } else { if(!this->crypt_handler_->generate_key_nonce(false, (uint8_t) packet->packet_type(), packet->packet_id(), packet->generation, crypt_key, crypt_nonce)) { this->callback_crypt_error(this->callback_data, CryptError::KEY_GENERATION_FAILED, ""); @@ -267,7 +271,7 @@ bool PacketEncoder::prepare_outgoing_packet(ts::protocol::OutgoingServerPacket * } } - auto crypt_result = this->crypt_handler_->encrypt((char*) packet->packet_data() + ServerPacketP::kHeaderOffset, ServerPacketP::kHeaderLength, + auto crypt_result = this->crypt_handler_->encrypt((char*) packet->packet_data() + protocol::ServerPacketP::kHeaderOffset, protocol::ServerPacketP::kHeaderLength, packet->payload, packet->payload_size, packet->mac, crypt_key, crypt_nonce, error); @@ -286,12 +290,12 @@ PacketEncoder::BufferPopResult PacketEncoder::pop_write_buffer(protocol::Outgoin if(this->resend_queue_head) { result = this->resend_queue_head; if(result->next) { - assert(this->resend_queue_tail != &result->next); + assert(this->send_queue_tail != &result->next); this->resend_queue_head = result->next; } else { - assert(this->resend_queue_tail == &result->next); + assert(this->send_queue_tail == &result->next); this->resend_queue_head = nullptr; - this->resend_queue_tail = &this->resend_queue_head; + this->send_queue_tail = &this->resend_queue_head; } } else if(this->encrypt_queue_head) { result = this->encrypt_queue_head; @@ -311,8 +315,10 @@ PacketEncoder::BufferPopResult PacketEncoder::pop_write_buffer(protocol::Outgoin more_packets = this->resend_queue_head != nullptr || this->encrypt_queue_head != nullptr; } - if(need_prepare_packet) + if(need_prepare_packet) { this->prepare_outgoing_packet(result); + } + return more_packets ? BufferPopResult::MORE_AVAILABLE : BufferPopResult::DRAINED; } @@ -325,20 +331,22 @@ void PacketEncoder::execute_resend(const std::chrono::system_clock::time_point & if(!buffers.empty()) { size_t send_count{0}; { - lock_guard wlock{this->write_queue_mutex}; + std::lock_guard wlock{this->write_queue_mutex}; for(auto& buffer : buffers) { auto packet = (protocol::OutgoingServerPacket*) buffer->packet_ptr; /* Test if the packet is still in the write/enqueue queue */ - if(packet->next) + if(packet->next) { continue; + } - if(&packet->next == this->encrypt_queue_tail || &packet->next == this->resend_queue_tail) + if(&packet->next == this->encrypt_queue_tail || &packet->next == this->send_queue_tail) { continue; + } packet->ref(); /* for the write queue again */ - *this->resend_queue_tail = packet; - this->resend_queue_tail = &packet->next; + *this->send_queue_tail = packet; + this->send_queue_tail = &packet->next; send_count++; buffer->resend_count++; @@ -352,7 +360,7 @@ void PacketEncoder::execute_resend(const std::chrono::system_clock::time_point & } } -bool PacketEncoder::wait_empty_write_and_prepare_queue(chrono::time_point until) { +bool PacketEncoder::wait_empty_write_and_prepare_queue(std::chrono::time_point until) { while(true) { { std::lock_guard wlock{this->write_queue_mutex}; diff --git a/server/src/client/voice/PacketEncoder.h b/server/src/client/voice/PacketEncoder.h index 4ab6491..112be38 100644 --- a/server/src/client/voice/PacketEncoder.h +++ b/server/src/client/voice/PacketEncoder.h @@ -75,7 +75,7 @@ namespace ts::server::server::udp { spin_mutex write_queue_mutex{}; protocol::OutgoingServerPacket* resend_queue_head{nullptr}; - protocol::OutgoingServerPacket** resend_queue_tail{&resend_queue_head}; + protocol::OutgoingServerPacket** send_queue_tail{&resend_queue_head}; protocol::OutgoingServerPacket* encrypt_queue_head{nullptr}; protocol::OutgoingServerPacket** encrypt_queue_tail{&encrypt_queue_head}; diff --git a/server/src/client/voice/ServerCommandExecutor.cpp b/server/src/client/voice/ServerCommandExecutor.cpp index 51aaabf..1d4ac72 100644 --- a/server/src/client/voice/ServerCommandExecutor.cpp +++ b/server/src/client/voice/ServerCommandExecutor.cpp @@ -47,8 +47,9 @@ void ServerCommandExecutor::enqueue_command_execution(ReassembledCommand *comman if(!command_handling_scheduled) { auto voice_server = this->client->getVoiceServer(); - if(voice_server) + if(voice_server) { voice_server->schedule_command_handling(&*client); + } } } diff --git a/server/src/client/web/WSWebClient.cpp b/server/src/client/web/WSWebClient.cpp index e5aac87..a83cecf 100644 --- a/server/src/client/web/WSWebClient.cpp +++ b/server/src/client/web/WSWebClient.cpp @@ -18,7 +18,7 @@ void WebClient::handleMessageWrite(int fd, short, void *) { auto buffer = this->queue_write[0]; this->queue_write.pop_front(); - auto written = send(fd, buffer.data_ptr(), buffer.length(), MSG_NOSIGNAL); + auto written = send(fd, buffer.data_ptr(), buffer.length(), MSG_NOSIGNAL | MSG_DONTWAIT); if(written == -1) { buffer_lock.unlock(); @@ -66,7 +66,7 @@ void WebClient::handleMessageRead(int fd, short, void *) { size_t buffer_length = 1024 * 4; uint8_t buffer[buffer_length]; - auto length = read(fd, buffer, buffer_length); + auto length = recv(fd, buffer, buffer_length, MSG_NOSIGNAL | MSG_DONTWAIT); if(length <= 0){ if(errno == EINTR || errno == EAGAIN) ;