diff options
Diffstat (limited to 'client-native-rift/src')
-rw-r--r-- | client-native-rift/src/crypto.rs | 6 | ||||
-rw-r--r-- | client-native-rift/src/main.rs | 87 | ||||
-rw-r--r-- | client-native-rift/src/protocol.rs | 30 | ||||
-rw-r--r-- | client-native-rift/src/signaling.rs | 40 |
4 files changed, 162 insertions, 1 deletions
diff --git a/client-native-rift/src/crypto.rs b/client-native-rift/src/crypto.rs index 1144de0..3f00c67 100644 --- a/client-native-rift/src/crypto.rs +++ b/client-native-rift/src/crypto.rs @@ -7,7 +7,7 @@ pub struct Key(Aes256Gcm); impl Key { pub fn derive(secret: String) -> Self { - let salt = base64::decode("").unwrap(); + let salt = base64::decode("thisisagoodsaltAAAAAAA==").unwrap(); let mut key = [0u8; 256]; fastpbkdf2::pbkdf2_hmac_sha256(secret.as_bytes(), salt.as_slice(), 250000, &mut key); @@ -30,3 +30,7 @@ impl Key { String::from_utf8(plaintext).unwrap() } } + +pub fn hash(secret: &str) -> String { + sha256::digest(format!("also-a-very-good-salt{}", secret)) +} diff --git a/client-native-rift/src/main.rs b/client-native-rift/src/main.rs index 028188e..d9935e8 100644 --- a/client-native-rift/src/main.rs +++ b/client-native-rift/src/main.rs @@ -1,6 +1,93 @@ +#![feature(async_closure)] + +use std::{sync::Arc, time::Duration}; + +use signaling::signaling_connect; +use webrtc::{ + api::{ + interceptor_registry::register_default_interceptors, media_engine::MediaEngine, APIBuilder, + }, + data_channel::data_channel_message::DataChannelMessage, + ice_transport::ice_server::RTCIceServer, + interceptor::registry::Registry, + peer_connection::{ + configuration::RTCConfiguration, math_rand_alpha, + peer_connection_state::RTCPeerConnectionState, + }, +}; + pub mod crypto; pub mod protocol; +pub mod signaling; fn main() { + tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap() + .block_on(run()) +} + +async fn run() { + let (send, recv) = signaling_connect("meet.metamuffin.org", "hunter2").await; + + let mut media_engine = MediaEngine::default(); + media_engine.register_default_codecs().unwrap(); + let mut registry = Registry::new(); + registry = register_default_interceptors(registry, &mut media_engine).unwrap(); + let api = APIBuilder::new() + .with_media_engine(media_engine) + .with_interceptor_registry(registry) + .build(); + + let config = RTCConfiguration { + ice_servers: vec![RTCIceServer { + urls: vec!["stun:metamuffin.org:16900".to_owned()], + ..Default::default() + }], + ..Default::default() + }; + + let peer_connection = Arc::new(api.new_peer_connection(config).await.unwrap()); + + let data_channel = peer_connection + .create_data_channel("data", None) + .await + .unwrap(); + + let (done_tx, mut done_rx) = tokio::sync::mpsc::channel::<()>(1); + + peer_connection + .on_peer_connection_state_change(Box::new(move |s: RTCPeerConnectionState| { + println!("conn state: {s}"); + Box::pin(async {}) + })) + .await; + + let d_label = data_channel.label().to_owned(); + data_channel + .on_message(Box::new(move |msg: DataChannelMessage| { + let msg_str = String::from_utf8(msg.data.to_vec()).unwrap(); + println!("Message from DataChannel '{}': '{}'", d_label, msg_str); + Box::pin(async {}) + })) + .await; + + let offer = peer_connection.create_offer(None).await.unwrap(); + peer_connection + .set_local_description(offer.clone()) + .await + .unwrap(); + + println!("{offer:?}"); + + tokio::time::sleep(Duration::from_secs(5)).await; + + // // Wait for the answer to be pasted + // let line = signal::must_read_stdin().unwrap(); + // let desc_data = signal::decode(line.as_str()).unwrap(); + // let answer = serde_json::from_str::<RTCSessionDescription>(&desc_data)?; + // // Apply the answer as the remote description + // peer_connection.set_remote_description(answer).await?; } diff --git a/client-native-rift/src/protocol.rs b/client-native-rift/src/protocol.rs index 5fb1ecb..b3719d0 100644 --- a/client-native-rift/src/protocol.rs +++ b/client-native-rift/src/protocol.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use webrtc::peer_connection::sdp::sdp_type::RTCSdpType; #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] @@ -18,3 +19,32 @@ pub enum ServerboundPacket { message: String, }, } + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct RelayMessageWrapper { + sender: usize, // redundant, but ensures the server didnt cheat + inner: RelayMessage, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum RelayMessage { + Offer(RTCSessionDescriptionInit), + Answer(RTCSessionDescriptionInit), + IceCandidate(RTCIceCandidateInit), +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct RTCSessionDescriptionInit { + #[serde(rename = "type")] + pub ty: RTCSdpType, + pub sdp: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct RTCIceCandidateInit { + pub candidate: String, + pub sdp_m_line_index: Option<usize>, + pub sdp_mid: Option<String>, + pub username_fragment: Option<String>, +} diff --git a/client-native-rift/src/signaling.rs b/client-native-rift/src/signaling.rs new file mode 100644 index 0000000..c61b982 --- /dev/null +++ b/client-native-rift/src/signaling.rs @@ -0,0 +1,40 @@ +use crate::protocol::ClientboundPacket; +use crate::{crypto::hash, protocol::ServerboundPacket}; +use futures_util::{SinkExt, StreamExt}; +use tokio_tungstenite::tungstenite::{self, Message}; + +pub async fn signaling_connect( + host: &str, + secret: &str, +) -> ( + impl SinkExt<ServerboundPacket>, + impl StreamExt<Item = Option<ClientboundPacket>>, +) { + let (conn, _) = tokio_tungstenite::connect_async( + url::Url::parse(&format!("wss://{host}/signaling/{}", hash(secret))).unwrap(), + ) + .await + .unwrap(); + + let (tx, rx) = conn.split(); + let prx = rx.map(|mesg| { + let mesg = mesg.unwrap(); + match mesg { + tungstenite::Message::Text(t) => { + let p: ClientboundPacket = serde_json::from_str(t.as_str()).unwrap(); + Some(p) + } + tungstenite::Message::Close(_) => { + eprintln!("ws closed :("); + None + } + _ => None, + } + }); + let ptx = tx.with(async move |p| { + Ok::<_, tokio_tungstenite::tungstenite::error::Error>(Message::Text( + serde_json::to_string::<ServerboundPacket>(&p).unwrap(), + )) + }); + (ptx, prx) +} |