Add more messages
This commit is contained in:
parent
61ee6fe05b
commit
9865c10f40
4 changed files with 216 additions and 44 deletions
93
Cargo.lock
generated
93
Cargo.lock
generated
|
@ -206,18 +206,95 @@ version = "1.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
|
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures"
|
||||||
|
version = "0.3.30"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
|
||||||
|
dependencies = [
|
||||||
|
"futures-channel",
|
||||||
|
"futures-core",
|
||||||
|
"futures-executor",
|
||||||
|
"futures-io",
|
||||||
|
"futures-sink",
|
||||||
|
"futures-task",
|
||||||
|
"futures-util",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-channel"
|
||||||
|
version = "0.3.30"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-core"
|
name = "futures-core"
|
||||||
version = "0.3.30"
|
version = "0.3.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-executor"
|
||||||
|
version = "0.3.30"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-task",
|
||||||
|
"futures-util",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-io"
|
||||||
|
version = "0.3.30"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-macro"
|
||||||
|
version = "0.3.30"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-sink"
|
name = "futures-sink"
|
||||||
version = "0.3.30"
|
version = "0.3.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
|
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-task"
|
||||||
|
version = "0.3.30"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-util"
|
||||||
|
version = "0.3.30"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
|
||||||
|
dependencies = [
|
||||||
|
"futures-channel",
|
||||||
|
"futures-core",
|
||||||
|
"futures-io",
|
||||||
|
"futures-macro",
|
||||||
|
"futures-sink",
|
||||||
|
"futures-task",
|
||||||
|
"memchr",
|
||||||
|
"pin-project-lite",
|
||||||
|
"pin-utils",
|
||||||
|
"slab",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.15"
|
version = "0.2.15"
|
||||||
|
@ -405,6 +482,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
"futures",
|
||||||
"prost",
|
"prost",
|
||||||
"prost-build",
|
"prost-build",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
|
@ -495,6 +573,12 @@ version = "0.2.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
|
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-utils"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prettyplease"
|
name = "prettyplease"
|
||||||
version = "0.2.20"
|
version = "0.2.20"
|
||||||
|
@ -708,6 +792,15 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "slab"
|
||||||
|
version = "0.4.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.13.2"
|
version = "1.13.2"
|
||||||
|
|
|
@ -13,6 +13,7 @@ tokio-util = { version = "0.7", features = ["codec"] }
|
||||||
tokio-rustls = { version = "0.26" }
|
tokio-rustls = { version = "0.26" }
|
||||||
webpki-roots = "0.26"
|
webpki-roots = "0.26"
|
||||||
rustls-pki-types = { version = "1.7.0" , features = ["alloc", "std"]}
|
rustls-pki-types = { version = "1.7.0" , features = ["alloc", "std"]}
|
||||||
|
futures = "0.3.30"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
prost-build = "0.13"
|
prost-build = "0.13"
|
||||||
|
|
81
src/codec.rs
81
src/codec.rs
|
@ -1,25 +1,20 @@
|
||||||
use anyhow::bail;
|
use anyhow::bail;
|
||||||
use bytes::{Buf, BytesMut};
|
use bytes::{BufMut, BytesMut};
|
||||||
use prost::Message;
|
use prost::Message;
|
||||||
use tokio_util::codec::Decoder;
|
use tokio_util::codec::{Decoder, Encoder};
|
||||||
use crate::proto::Version;
|
use crate::MumbleMessage;
|
||||||
|
use crate::proto::{Authenticate, Version, Ping};
|
||||||
|
|
||||||
pub enum MumbleMessages {
|
pub struct MumbleTcpCodec {}
|
||||||
|
|
||||||
}
|
impl MumbleTcpCodec {
|
||||||
|
|
||||||
pub struct MumbleCodec {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MumbleCodec {
|
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {}
|
Self {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decoder for MumbleCodec {
|
impl Decoder for MumbleTcpCodec {
|
||||||
type Item = ();
|
type Item = MumbleMessage;
|
||||||
type Error = anyhow::Error;
|
type Error = anyhow::Error;
|
||||||
|
|
||||||
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
|
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
|
||||||
|
@ -27,21 +22,67 @@ impl Decoder for MumbleCodec {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let message_type = u16::from_be_bytes(src[0..2].try_into()?) as usize;
|
let (message_type, rest) = src.split_at(2);
|
||||||
let message_length = u32::from_be_bytes(src[2..6].try_into()?) as usize;
|
let (message_length, rest) = rest.split_at(4);
|
||||||
let message_data = &src[6..message_length];
|
let message_type = u16::from_be_bytes(message_type.try_into()?) as usize;
|
||||||
|
let message_length = u32::from_be_bytes(message_length.try_into()?) as usize;
|
||||||
|
let mut mumble_message: Option<MumbleMessage> = None;
|
||||||
|
|
||||||
|
if message_length > src.len() {
|
||||||
|
src.reserve(message_length+6);
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
|
||||||
match message_type {
|
match message_type {
|
||||||
0 => {
|
0 => {
|
||||||
//TODO: Version
|
//TODO: Version
|
||||||
let version = Version::decode(message_data);
|
let version = Version::decode(rest)?;
|
||||||
println!("{version:?}");
|
mumble_message = Some(MumbleMessage::Version {data: version});
|
||||||
Ok(Some(()))
|
}
|
||||||
|
3 => {
|
||||||
|
let ping = Ping::decode(rest)?;
|
||||||
|
mumble_message = Some(MumbleMessage::Ping { data: ping });
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
eprintln!("Unknown message type {:?}", message_type);
|
eprintln!("Unknown message type {:?}", message_type);
|
||||||
Ok(None)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let _ = src.split_to(message_length+6);
|
||||||
|
src.reserve(6);
|
||||||
|
Ok(mumble_message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encoder<MumbleMessage> for MumbleTcpCodec {
|
||||||
|
type Error = anyhow::Error;
|
||||||
|
|
||||||
|
fn encode(&mut self, item: MumbleMessage, dst: &mut BytesMut) -> Result<(), Self::Error> {
|
||||||
|
let mut message = BytesMut::new();
|
||||||
|
match item {
|
||||||
|
MumbleMessage::Version { data } => {
|
||||||
|
println!("Send Version");
|
||||||
|
Version::encode(&data, &mut message)?;
|
||||||
|
dst.put_u16(0);
|
||||||
|
}
|
||||||
|
MumbleMessage::Authenticate { data } => {
|
||||||
|
println!("Send Authenticate");
|
||||||
|
Authenticate::encode(&data, &mut message)?;
|
||||||
|
dst.put_u16(2);
|
||||||
|
},
|
||||||
|
MumbleMessage::Ping { data } => {
|
||||||
|
println!("Send Ping");
|
||||||
|
Ping::encode(&data, &mut message)?;
|
||||||
|
dst.put_u16(3);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
bail!("Could not encode unknown message")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dst.put_u32((message.len() as u32) + 6);
|
||||||
|
dst.extend_from_slice(&message);
|
||||||
|
println!("{dst:?}");
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
85
src/lib.rs
85
src/lib.rs
|
@ -1,4 +1,5 @@
|
||||||
pub mod codec;
|
pub mod codec;
|
||||||
|
use futures::sink::SinkExt;
|
||||||
|
|
||||||
pub mod proto {
|
pub mod proto {
|
||||||
include!(concat!(env!("OUT_DIR"), "/mumble_proto.rs"));
|
include!(concat!(env!("OUT_DIR"), "/mumble_proto.rs"));
|
||||||
|
@ -9,8 +10,8 @@ pub mod udp {
|
||||||
}
|
}
|
||||||
|
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
use std::net::SocketAddr;
|
use std::net::{Ipv4Addr, SocketAddr};
|
||||||
use tokio::net::TcpStream;
|
use tokio::net::{TcpStream, UdpSocket};
|
||||||
use tokio::io::AsyncWriteExt;
|
use tokio::io::AsyncWriteExt;
|
||||||
use tokio_stream::StreamExt;
|
use tokio_stream::StreamExt;
|
||||||
use prost::Message;
|
use prost::Message;
|
||||||
|
@ -19,10 +20,18 @@ use tokio_rustls::client::TlsStream;
|
||||||
use tokio_rustls::{TlsConnector};
|
use tokio_rustls::{TlsConnector};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use rustls_pki_types::{CertificateDer, ServerName, UnixTime};
|
use rustls_pki_types::{CertificateDer, ServerName, UnixTime};
|
||||||
use tokio_util::codec::FramedRead;
|
use tokio_util::codec::Framed;
|
||||||
use crate::codec::MumbleCodec;
|
use crate::codec::MumbleTcpCodec;
|
||||||
use bytes::BytesMut;
|
use tokio_rustls::rustls::client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier};
|
||||||
use tokio_rustls::rustls::client::danger::{DangerousClientConfig, HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier};
|
use crate::proto::{Authenticate, Version, Ping};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum MumbleMessage {
|
||||||
|
Version {data: Version},
|
||||||
|
Authenticate {data: Authenticate},
|
||||||
|
Ping { data: Ping },
|
||||||
|
UnknownMessage
|
||||||
|
}
|
||||||
|
|
||||||
pub struct MumbleClient {
|
pub struct MumbleClient {
|
||||||
host: SocketAddr,
|
host: SocketAddr,
|
||||||
|
@ -94,29 +103,57 @@ impl MumbleClient {
|
||||||
Ok(connector.connect(dnsname, stream).await?)
|
Ok(connector.connect(dnsname, stream).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn create_udp_connection(&mut self) -> anyhow::Result<UdpSocket> {
|
||||||
|
let sock = UdpSocket::bind((Ipv4Addr::UNSPECIFIED, 0)).await?;
|
||||||
|
println!("UDP Connect");
|
||||||
|
sock.connect(&self.host).await?;
|
||||||
|
Ok(sock)
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn connect(&mut self) -> anyhow::Result<()> {
|
pub async fn connect(&mut self) -> anyhow::Result<()> {
|
||||||
let tcp_stream = self.create_tcp_connection().await?;
|
let mut framed = Framed::new(self.create_tcp_connection().await?, MumbleTcpCodec::new());
|
||||||
let mut framed_reader = FramedRead::new(tcp_stream, MumbleCodec::new());
|
framed.send(MumbleMessage::Version { data: Version {
|
||||||
let mut message_buffer: BytesMut = BytesMut::new();
|
|
||||||
let version = (proto::Version {
|
|
||||||
os: Some(String::from("Linux")),
|
os: Some(String::from("Linux")),
|
||||||
os_version: None,
|
os_version: Some(String::from("os version")),
|
||||||
release: None,
|
release: Some(String::from("release")),
|
||||||
version_v1: None,
|
version_v1: None,
|
||||||
version_v2: None
|
version_v2: Some(0)
|
||||||
}).encode(&mut message_buffer)?;
|
}}).await?;
|
||||||
|
|
||||||
// let mut complete_buffer = BytesMut::new();
|
let udp_sock = self.create_udp_connection().await?;
|
||||||
// complete_buffer.extend((0u16).to_be_bytes());
|
let mut buf = [0; 1024];
|
||||||
// complete_buffer.extend(((2+4+message_buffer.len()) as u32).to_be_bytes());
|
|
||||||
// complete_buffer.extend(&message_buffer);
|
|
||||||
|
|
||||||
// println!("{complete_buffer:?}");
|
while let Some(frame_result) = framed.next().await {
|
||||||
// tcp_stream.write_all(&complete_buffer).await?;
|
if let Ok(message) = frame_result {
|
||||||
|
println!("Receive: {message:?}");
|
||||||
while let Some(frame_result) = framed_reader.next().await {
|
match message {
|
||||||
if let Ok(data) = frame_result {
|
MumbleMessage::Version { data } => {
|
||||||
println!("{data:?}");
|
framed.send(MumbleMessage::Authenticate { data: Authenticate {
|
||||||
|
username:Some(String::from("Bot")),
|
||||||
|
password: None,
|
||||||
|
tokens: vec![],
|
||||||
|
celt_versions: vec![],
|
||||||
|
opus: Some(true),
|
||||||
|
client_type: Some(1),
|
||||||
|
}}).await?;
|
||||||
|
/*framed.send(MumbleMessage::Ping {data: Ping {
|
||||||
|
good: None,
|
||||||
|
late: None,
|
||||||
|
lost: None,
|
||||||
|
resync: None,
|
||||||
|
tcp_packets: None,
|
||||||
|
tcp_ping_avg: None,
|
||||||
|
tcp_ping_var: None,
|
||||||
|
timestamp: None,
|
||||||
|
udp_packets: None,
|
||||||
|
udp_ping_avg: None,
|
||||||
|
udp_ping_var: None
|
||||||
|
}}).await?;*/
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
println!("{message:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue