mirror of
https://github.com/speyejack/smo-multi-rs.git
synced 2025-10-05 15:42:45 +02:00
Allow for non-udp users to connect
This commit is contained in:
105
Cargo.lock
generated
105
Cargo.lock
generated
@@ -137,6 +137,95 @@ dependencies = [
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab30e97ab6aacfe635fad58f22c2bb06c8b685f7421eb1e064a729e2a5f481fa"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2bfc52cbddcfd745bf1740338492bb0bd83d76c67b445f91c5fb29fae29ecaa1"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2acedae88d38235936c3922476b10fced7b2b68136f5e3c03c2d5be348a1115"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d11aa21b5b587a64682c0094c2bdd4df0076c5324961a40cc3abd7f37930528"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93a66fc6d035a26a3ae255a6d2bca35eda63ae4c5512bef54449113f7a1228e5"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0db9cce532b0eae2ccf2766ab246f114b56b9cf6d445e00c2549fbc100ca045d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca0bae1fe9752cf7fd9b0064c674ae63f97b37bc714d745cbde0afb7ec4e6765"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "842fc63b931f4056a24d59de13fb1272134ce261816e063e634ad0c15cdc5306"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0828a5471e340229c11c77ca80017937ce3c58cb788a17e5f1c2d5c485a9577"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.7"
|
||||
@@ -381,6 +470,12 @@ version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
@@ -587,6 +682,15 @@ dependencies = [
|
||||
"wide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.9.0"
|
||||
@@ -601,6 +705,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"clap",
|
||||
"dashmap",
|
||||
"futures",
|
||||
"hex",
|
||||
"nalgebra",
|
||||
"quickcheck",
|
||||
|
@@ -29,6 +29,7 @@ tracing = {version="0.1.36"}
|
||||
tracing-subscriber = {version="0.3.15", features=["std", "env-filter", "fmt"]}
|
||||
quickcheck = "1.0.3"
|
||||
serde_json = "1.0.83"
|
||||
futures = "0.3.23"
|
||||
|
||||
[workspace]
|
||||
members = [
|
||||
|
@@ -144,7 +144,7 @@ async fn proxy_client(
|
||||
|
||||
let mut cli = Connection::new(cli_sock);
|
||||
let mut serv = Connection::new(serv_sock);
|
||||
let mut udp = UdpConnection::new(udp, serv_udp_addr);
|
||||
let mut udp = UdpConnection::from_connection(udp, serv_udp_addr);
|
||||
let mut use_udp = true;
|
||||
let mut last_tag_packet = Instant::now();
|
||||
|
||||
@@ -160,11 +160,6 @@ async fn proxy_client(
|
||||
let mut packet = packet_result?;
|
||||
packet.resize();
|
||||
|
||||
let (origin_conn, dest_conn) = match origin {
|
||||
Origin::Client => (&mut cli, &mut serv),
|
||||
Origin::Server => (&mut serv, &mut cli),
|
||||
};
|
||||
|
||||
tracing::debug!("got packet: {}", packet.data.get_type_name());
|
||||
match &packet.data {
|
||||
PacketData::Tag { .. } => {
|
||||
@@ -177,7 +172,8 @@ async fn proxy_client(
|
||||
PacketData::UdpInit { port } => {
|
||||
let addr = SocketAddr::new(serv_udp_addr.ip(), *port);
|
||||
tracing::debug!("New udp peer: {:?}", addr);
|
||||
udp = UdpConnection::new(udp.socket, addr);
|
||||
|
||||
udp.set_client_port(*port);
|
||||
|
||||
serv.write_packet(&Packet::new(
|
||||
Guid::default(),
|
||||
@@ -190,15 +186,19 @@ async fn proxy_client(
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let (origin_conn, dest_conn) = match origin {
|
||||
Origin::Client => (&mut cli, &mut serv),
|
||||
Origin::Server => (&mut serv, &mut cli),
|
||||
};
|
||||
|
||||
if use_udp && origin != plex {
|
||||
if let &Packet {
|
||||
data: PacketData::Player { .. },
|
||||
..
|
||||
} = &packet
|
||||
{
|
||||
tracing::trace!("Sending over udp!");
|
||||
udp.write_packet(&packet).await.unwrap();
|
||||
continue;
|
||||
match packet.data {
|
||||
PacketData::Player { .. } => {
|
||||
tracing::trace!("Sending over udp!");
|
||||
udp.write_packet(&packet).await.unwrap();
|
||||
continue;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
dest_conn.write_packet(&packet).await?
|
||||
|
@@ -172,10 +172,7 @@ impl Client {
|
||||
true
|
||||
}
|
||||
PacketData::UdpInit { port } => {
|
||||
let ip = self.udp_conn.send_addr.ip();
|
||||
let new_addr = SocketAddr::new(ip, *port);
|
||||
tracing::debug!("Setting new udp peer addr: {}", new_addr);
|
||||
self.udp_conn.send_addr = new_addr;
|
||||
self.udp_conn.set_client_port(*port);
|
||||
false
|
||||
}
|
||||
_ => true,
|
||||
@@ -225,9 +222,15 @@ impl Client {
|
||||
packet.data.get_type_name()
|
||||
);
|
||||
|
||||
match packet.data {
|
||||
PacketData::Player { .. } => self.udp_conn.write_packet(packet).await,
|
||||
_ => self.conn.write_packet(packet).await,
|
||||
if self.udp_conn.is_client_udp() {
|
||||
// Use UDP traffic
|
||||
match packet.data {
|
||||
PacketData::Player { .. } => self.udp_conn.write_packet(packet).await,
|
||||
_ => self.conn.write_packet(packet).await,
|
||||
}
|
||||
} else {
|
||||
// Fall back to TCP traffic
|
||||
self.conn.write_packet(packet).await
|
||||
}
|
||||
} else {
|
||||
Ok(())
|
||||
@@ -261,8 +264,7 @@ impl Client {
|
||||
tracing::debug!("Binding udp to: {:?}", local_udp_addr);
|
||||
|
||||
tracing::debug!("setting new udp connection");
|
||||
let udp_addr = SocketAddr::new(tcp_sock_addr.ip(), 55446);
|
||||
let mut udp_conn = UdpConnection::new(udp, udp_addr);
|
||||
let udp_conn = UdpConnection::new(udp, tcp_sock_addr.ip());
|
||||
|
||||
tracing::debug!("Waiting for reply");
|
||||
let connect = conn.read_packet().await?;
|
||||
|
@@ -1,4 +1,7 @@
|
||||
use std::{io::Cursor, net::SocketAddr};
|
||||
use std::{
|
||||
io::Cursor,
|
||||
net::{IpAddr, Ipv4Addr, SocketAddr},
|
||||
};
|
||||
|
||||
use bytes::{Buf, BufMut, BytesMut};
|
||||
use tokio::{
|
||||
@@ -8,22 +11,35 @@ use tokio::{
|
||||
|
||||
use crate::{
|
||||
net::{encoding::Decodable, encoding::Encodable, Packet, MAX_PACKET_SIZE},
|
||||
types::{EncodingError, Result},
|
||||
types::{EncodingError, Result, SMOError},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum UdpSenderStatus {
|
||||
Pending(IpAddr),
|
||||
Connected(SocketAddr),
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct UdpConnection {
|
||||
pub socket: UdpSocket,
|
||||
pub buff: BytesMut,
|
||||
pub send_addr: SocketAddr,
|
||||
pub send_addr: UdpSenderStatus,
|
||||
}
|
||||
|
||||
impl UdpConnection {
|
||||
pub fn new(stream: UdpSocket, addr: SocketAddr) -> Self {
|
||||
pub fn new(stream: UdpSocket, addr: IpAddr) -> Self {
|
||||
UdpConnection {
|
||||
socket: stream,
|
||||
buff: BytesMut::with_capacity(1024),
|
||||
send_addr: addr,
|
||||
send_addr: UdpSenderStatus::Pending(addr),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_connection(stream: UdpSocket, addr: SocketAddr) -> Self {
|
||||
UdpConnection {
|
||||
socket: stream,
|
||||
buff: BytesMut::with_capacity(1024),
|
||||
send_addr: UdpSenderStatus::Connected(addr),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +61,24 @@ impl UdpConnection {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_client_udp(&self) -> bool {
|
||||
match self.send_addr {
|
||||
UdpSenderStatus::Connected(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_client_port(&mut self, port: u16) {
|
||||
let new_addr = match self.send_addr {
|
||||
UdpSenderStatus::Pending(ip) => SocketAddr::new(ip, port),
|
||||
UdpSenderStatus::Connected(addr) => {
|
||||
let ip = addr.ip();
|
||||
SocketAddr::new(ip, port)
|
||||
}
|
||||
};
|
||||
self.send_addr = UdpSenderStatus::Connected(new_addr)
|
||||
}
|
||||
|
||||
pub async fn read_packet(&mut self) -> Result<Packet> {
|
||||
loop {
|
||||
if let Some(packet) = self.parse_packet()? {
|
||||
@@ -56,20 +90,33 @@ impl UdpConnection {
|
||||
|
||||
pub async fn read_socket(&mut self) -> Result<()> {
|
||||
let mut buff = vec![0u8; 100];
|
||||
let read_amount = self.socket.recv_from(&mut buff).await?;
|
||||
self.buff.put_slice(&buff[..read_amount.0]);
|
||||
|
||||
if let UdpSenderStatus::Connected(expected_addr) = self.send_addr {
|
||||
let (read_amount, addr) = self.socket.recv_from(&mut buff).await?;
|
||||
if addr == expected_addr {
|
||||
self.buff.put_slice(&buff[..read_amount]);
|
||||
}
|
||||
} else {
|
||||
// Never resolve as connection isnt ready
|
||||
futures::future::pending().await
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn write_packet(&mut self, packet: &Packet) -> Result<()> {
|
||||
let mut buff = BytesMut::with_capacity(MAX_PACKET_SIZE);
|
||||
packet.encode(&mut buff)?;
|
||||
if let UdpSenderStatus::Connected(send_addr) = self.send_addr {
|
||||
let mut buff = BytesMut::with_capacity(MAX_PACKET_SIZE);
|
||||
packet.encode(&mut buff)?;
|
||||
|
||||
let mut amount = 0;
|
||||
while amount < buff.len() {
|
||||
let last_write = self.socket.send_to(&buff[..], self.send_addr).await;
|
||||
amount += last_write.unwrap();
|
||||
let mut amount = 0;
|
||||
while amount < buff.len() {
|
||||
let last_write = self.socket.send_to(&buff[..], send_addr).await;
|
||||
amount += last_write.unwrap();
|
||||
}
|
||||
Ok(())
|
||||
} else {
|
||||
Err(SMOError::UdpNotInit)
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@@ -28,6 +28,8 @@ pub enum SMOError {
|
||||
ClientInit(#[from] ClientInitError),
|
||||
#[error("Invalid error")]
|
||||
JsonError(#[from] serde_json::Error),
|
||||
#[error("Udp not initialized")]
|
||||
UdpNotInit,
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
|
Reference in New Issue
Block a user