Skip to content

Commit

Permalink
DAVE user join/part (#1276)
Browse files Browse the repository at this point in the history
  • Loading branch information
Neko-Life authored Oct 14, 2024
1 parent 78c75e3 commit 5fa9101
Show file tree
Hide file tree
Showing 5 changed files with 277 additions and 106 deletions.
46 changes: 40 additions & 6 deletions include/dpp/discordvoiceclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ enum voice_websocket_opcode_t : uint8_t {
voice_client_dave_mls_key_package = 26,
voice_client_dave_mls_proposals = 27,
voice_client_dave_mls_commit_message = 28,
voice_client_dave_announce_commit_transaction = 29,
voice_client_dave_announce_commit_transition = 29,
voice_client_dave_mls_welcome = 30,
voice_client_dave_mls_invalid_commit_welcome = 31,
};
Expand Down Expand Up @@ -206,7 +206,7 @@ struct dave_binary_header_t {
[[nodiscard]] std::vector<uint8_t> get_data() const;

/**
* Get transition ID for process_welcome
* Get transition ID for process_commit and process_welcome
*
* @return Transition ID
*/
Expand All @@ -215,7 +215,7 @@ struct dave_binary_header_t {
private:
/**
* @brief Transition id, only valid when the opcode is
* welcome state. Use get_transition_id() to obtain value.
* commit and welcome state. Use get_transition_id() to obtain value.
*/
uint16_t transition_id;
};
Expand Down Expand Up @@ -478,11 +478,12 @@ class DPP_EXPORT discord_voice_client : public websocket_client
std::set<std::string> dave_mls_user_list;

/**
* @brief The list of users that just joined for DAVE
* @brief The list of users that have left the voice channel but
* not yet removed from MLS group.
*/
std::set<std::string> dave_mls_new_user_list;
std::set<std::string> dave_mls_pending_remove_list;

/**
/**
* @brief File descriptor for UDP connection
*/
dpp::socket fd;
Expand Down Expand Up @@ -1200,6 +1201,39 @@ class DPP_EXPORT discord_voice_client : public websocket_client
* which internally uses scrypt.
*/
void get_user_privacy_code(const dpp::snowflake user, privacy_code_callback_t callback) const;

/**
* @brief Notify gateway ready for a DAVE transition.
*
* Fires Voice Ready event when appropriate.
*
* https://daveprotocol.com/#commit-handling
*/
void ready_for_transition(const std::string &data);

/**
* @brief Reset dave session, send voice_client_dave_mls_invalid_commit_welcome
* payload with current transition Id and our new key package to gateway.
*
* https://daveprotocol.com/#recovery-from-invalid-commit-or-welcome
*/
void recover_from_invalid_commit_welcome();

/**
* @brief Execute pending protocol upgrade/downgrade to/from dave.
* @return true if did an upgrade/downgrade
*/
bool execute_pending_upgrade_downgrade();

/**
* @brief Reset dave session and prepare initial session group.
*/
void reinit_dave_mls_group();

/**
* @brief Process roster map from commit/welcome.
*/
void process_mls_group_rosters(const std::map<unsigned long, std::vector<unsigned char>> &rmap);
};

} // namespace dpp
Expand Down
17 changes: 12 additions & 5 deletions src/dpp/discordvoiceclient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,9 @@ bool discord_voice_client::is_playing() {
}

uint16_t dave_binary_header_t::get_transition_id() const {
if (opcode != voice_client_dave_mls_welcome) {
throw dpp::logic_exception("Can't get transition ID from buffer that is not of type voice_client_dave_mls_welcome(30)");
bool has_transition_id = opcode == voice_client_dave_mls_welcome || opcode == voice_client_dave_announce_commit_transition;
if (!has_transition_id) {
throw dpp::logic_exception("Can't get transition ID from buffer that is not of type voice_client_dave_announce_commit_transition(29) or voice_client_dave_mls_welcome(30)");
}
return transition_id;
}
Expand All @@ -98,7 +99,9 @@ dave_binary_header_t::dave_binary_header_t(const std::string& buffer) {
seq = (buffer[0] << 8) | buffer[1];
opcode = buffer[2];
transition_id = (buffer[3] << 8) | buffer[4];
package.assign(buffer.begin() + (opcode == voice_client_dave_mls_welcome ? 5 : 3), buffer.end());

bool has_transition_id = opcode == voice_client_dave_mls_welcome || opcode == voice_client_dave_announce_commit_transition;
package.assign(buffer.begin() + (has_transition_id ? 5 : 3), buffer.end());
}

std::vector<uint8_t> dave_binary_header_t::get_data() const {
Expand Down Expand Up @@ -129,13 +132,17 @@ void discord_voice_client::get_user_privacy_code(const dpp::snowflake user, priv

bool discord_voice_client::is_end_to_end_encrypted() const {
#ifdef HAVE_VOICE
if (mls_state == nullptr) {
if (mls_state == nullptr || mls_state->encryptor == nullptr) {
return false;
}

bool has_pending_downgrade = mls_state->pending_transition.is_pending && mls_state->pending_transition.protocol_version != dave_version_1;

return !has_pending_downgrade && !mls_state->privacy_code.empty();
/*
* A dave_version 0 should be enough to know we're in non-e2ee session, we should also check for pending downgrade and
* whether session encryptor actually has key rachet set to encrypt opus packets.
*/
return !has_pending_downgrade && dave_version != dave_version_none && mls_state->encryptor->has_key_ratchet();
#else
return false;
#endif
Expand Down
13 changes: 5 additions & 8 deletions src/dpp/voice/enabled/enabled.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,18 +87,10 @@ struct dave_state {
* @brief Our key package
*/
std::shared_ptr<::mlspp::SignaturePrivateKey> mls_key;
/**
* @brief Cached commit package for use in welcome
*/
std::vector<uint8_t> cached_commit;
/**
* @brief Current transition ID
*/
uint64_t transition_id{0};
/**
* @brief True when we have a sending ratchet
*/
bool have_sending_ratchet{false};
/**
* @brief Have sent ready event to listeners
*/
Expand Down Expand Up @@ -133,6 +125,11 @@ struct dave_state {
* MLS group is not established.
*/
std::string privacy_code;

/**
* @brief Cached roster map to track rosters changes.
*/
dave::roster_map cached_roster_map;
};

/**
Expand Down
Loading

0 comments on commit 5fa9101

Please sign in to comment.