@@ -8,27 +8,31 @@ use super::{
88 message:: * ,
99 ws:: { self as ws_task, AuxNetwork } ,
1010 } ,
11- Config ,
12- CryptoMode ,
11+ Config , CryptoMode ,
1312} ;
1413use crate :: {
1514 constants:: * ,
1615 model:: {
1716 payload:: { Identify , Resume , SelectProtocol } ,
18- Event as GatewayEvent ,
19- ProtocolData ,
17+ Event as GatewayEvent , ProtocolData ,
2018 } ,
2119 ws:: WsStream ,
2220 ConnectionInfo ,
2321} ;
2422use discortp:: discord:: { IpDiscoveryPacket , IpDiscoveryType , MutableIpDiscoveryPacket } ;
2523use error:: { Error , Result } ;
2624use flume:: Sender ;
25+ use serenity_voice_model:: payload:: DaveMlsKeyPackage ;
2726use socket2:: Socket ;
2827#[ cfg( feature = "receive" ) ]
2928use std:: sync:: Arc ;
30- use std:: { net:: IpAddr , str:: FromStr } ;
31- use tokio:: { net:: UdpSocket , spawn, time:: timeout} ;
29+ use std:: {
30+ net:: IpAddr ,
31+ num:: NonZeroU16 ,
32+ str:: FromStr ,
33+ sync:: { atomic:: AtomicU16 , Arc } ,
34+ } ;
35+ use tokio:: { net:: UdpSocket , spawn, sync:: RwLock , time:: timeout} ;
3236use tracing:: { debug, info, instrument} ;
3337use url:: Url ;
3438
@@ -72,11 +76,12 @@ impl Connection {
7276 session_id : info. session_id . clone ( ) ,
7377 token : info. token . clone ( ) ,
7478 user_id : info. user_id . into ( ) ,
79+ max_dave_protocol_version : Some ( davey:: DAVE_PROTOCOL_VERSION ) ,
7580 } ) )
7681 . await ?;
7782
7883 loop {
79- let Some ( value) = client. recv_json ( ) . await ? else {
84+ let Some ( value) = client. recv_event ( ) . await ? else {
8085 continue ;
8186 } ;
8287
@@ -181,7 +186,10 @@ impl Connection {
181186 . await ?;
182187 }
183188
184- let cipher = init_cipher ( & mut client, chosen_crypto, & ws_msg_tx) . await ?;
189+ let ( cipher, dave_session, dave_protocol_version) =
190+ init_cipher ( & mut client, & info, chosen_crypto, & ws_msg_tx) . await ?;
191+ let dave_session = Arc :: new ( RwLock :: new ( dave_session) ) ;
192+ let dave_protocol_version = Arc :: new ( dave_protocol_version) ;
185193
186194 info ! ( "Connected to: {}" , info. endpoint) ;
187195
@@ -213,6 +221,8 @@ impl Connection {
213221 cipher : cipher. clone ( ) ,
214222 #[ cfg( not( feature = "receive" ) ) ]
215223 cipher,
224+ dave_session : dave_session. clone ( ) ,
225+ dave_protocol_version : dave_protocol_version. clone ( ) ,
216226 crypto_state : chosen_crypto. into ( ) ,
217227 #[ cfg( feature = "receive" ) ]
218228 udp_rx : udp_receiver_msg_tx,
@@ -237,6 +247,14 @@ impl Connection {
237247 hello. heartbeat_interval ,
238248 idx,
239249 info. clone ( ) ,
250+ #[ cfg( not( feature = "receive" ) ) ]
251+ dave_session,
252+ #[ cfg( not( feature = "receive" ) ) ]
253+ dave_protocol_version,
254+ #[ cfg( feature = "receive" ) ]
255+ dave_session. clone ( ) ,
256+ #[ cfg( feature = "receive" ) ]
257+ dave_protocol_version. clone ( ) ,
240258 #[ cfg( feature = "receive" ) ]
241259 ssrc_tracker. clone ( ) ,
242260 ) ;
@@ -252,6 +270,8 @@ impl Connection {
252270 config. clone ( ) ,
253271 udp_rx,
254272 ssrc_tracker,
273+ dave_session,
274+ dave_protocol_version,
255275 ) ) ;
256276
257277 Ok ( Connection {
@@ -290,7 +310,7 @@ impl Connection {
290310 let mut resumed = None ;
291311
292312 loop {
293- let Some ( value) = client. recv_json ( ) . await ? else {
313+ let Some ( value) = client. recv_event ( ) . await ? else {
294314 continue ;
295315 } ;
296316
@@ -344,11 +364,12 @@ fn generate_url(endpoint: &mut String) -> Result<Url> {
344364#[ inline]
345365async fn init_cipher (
346366 client : & mut WsStream ,
367+ info : & ConnectionInfo ,
347368 mode : CryptoMode ,
348369 tx : & Sender < WsMessage > ,
349- ) -> Result < Cipher > {
370+ ) -> Result < ( Cipher , Option < davey :: DaveSession > , AtomicU16 ) > {
350371 loop {
351- let Some ( value) = client. recv_json ( ) . await ? else {
372+ let Some ( value) = client. recv_event ( ) . await ? else {
352373 continue ;
353374 } ;
354375
@@ -358,9 +379,37 @@ async fn init_cipher(
358379 return Err ( Error :: CryptoModeInvalid ) ;
359380 }
360381
361- return mode
362- . cipher_from_key ( & desc. secret_key )
363- . map_err ( |_| Error :: CryptoInvalidLength ) ;
382+ let dave_session =
383+ if let Some ( version) = NonZeroU16 :: new ( desc. dave_protocol_version ) {
384+ let mut session = davey:: DaveSession :: new (
385+ version,
386+ info. user_id . get ( ) ,
387+ info. channel_id
388+ . expect ( "channel ID must be set in connection info" )
389+ . get ( ) ,
390+ None ,
391+ )
392+ . map_err ( Error :: DaveInitializationError ) ?;
393+
394+ client
395+ . send_binary ( & GatewayEvent :: DaveMlsKeyPackage ( DaveMlsKeyPackage {
396+ key_package : session
397+ . create_key_package ( )
398+ . map_err ( Error :: DaveCreateKeyPackageError ) ?,
399+ } ) )
400+ . await ?;
401+
402+ Some ( session)
403+ } else {
404+ None
405+ } ;
406+
407+ return Ok ( (
408+ mode. cipher_from_key ( & desc. secret_key )
409+ . map_err ( |_| Error :: CryptoInvalidLength ) ?,
410+ dave_session,
411+ AtomicU16 :: new ( desc. dave_protocol_version ) ,
412+ ) ) ;
364413 } ,
365414 other => {
366415 // Discord can and will send user-specific payload packets during this time
0 commit comments