aboutsummaryrefslogtreecommitdiff
path: root/client-native-rift/src
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2022-09-13 19:09:12 +0200
committermetamuffin <metamuffin@disroot.org>2022-09-13 19:09:12 +0200
commit473c7624c1419c6636addebb183dede5be88b061 (patch)
treea5e27396bda5a5a2281337a0049b004218e98200 /client-native-rift/src
parent7e88c11cbf817cb6cdbaf9b9f55564c4f9081e26 (diff)
downloadkeks-meet-473c7624c1419c6636addebb183dede5be88b061.tar
keks-meet-473c7624c1419c6636addebb183dede5be88b061.tar.bz2
keks-meet-473c7624c1419c6636addebb183dede5be88b061.tar.zst
getting closer to webrtc in rust
Diffstat (limited to 'client-native-rift/src')
-rw-r--r--client-native-rift/src/crypto.rs6
-rw-r--r--client-native-rift/src/main.rs87
-rw-r--r--client-native-rift/src/protocol.rs30
-rw-r--r--client-native-rift/src/signaling.rs40
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)
+}