feat: refactor prudp code and start working on refactoring rmc
This commit is contained in:
parent
7d24a71f09
commit
3ea7c7e671
37 changed files with 2029 additions and 456 deletions
848
Cargo.lock
generated
848
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -25,6 +25,9 @@ prost = "0.13.4"
|
|||
hex = "0.4.3"
|
||||
|
||||
macros = { path = "macros" }
|
||||
rocket = { version = "0.5.1", features = ["json", "serde_json"] }
|
||||
serde = { version = "1.0.217", features = ["derive"] }
|
||||
async-trait = "0.1.86"
|
||||
|
||||
[build-dependencies]
|
||||
tonic-build = "0.12.3"
|
||||
|
|
@ -32,4 +35,4 @@ tonic-build = "0.12.3"
|
|||
[features]
|
||||
default = ["secure", "auth"]
|
||||
secure = []
|
||||
auth = []
|
||||
auth = []
|
||||
|
|
|
|||
121
src/main.rs
121
src/main.rs
|
|
@ -14,25 +14,21 @@ use simplelog::{ColorChoice, CombinedLogger, Config, LevelFilter, TerminalMode,
|
|||
use tokio::sync::RwLock;
|
||||
use tokio::task::JoinHandle;
|
||||
use crate::nex::account::Account;
|
||||
use crate::protocols::{auth, block_if_maintenance};
|
||||
use crate::protocols::auth::AuthProtocolConfig;
|
||||
use crate::protocols::matchmake_common::MatchmakeData;
|
||||
use crate::protocols::server::RMCProtocolServer;
|
||||
use crate::prudp::socket::{ActiveSecureConnectionData, EncryptionPair, Socket};
|
||||
use crate::prudp::socket::{EncryptionPair, Unsecure};
|
||||
use crate::prudp::packet::{VirtualPort};
|
||||
use crate::prudp::router::Router;
|
||||
use crate::prudp::secure::{generate_secure_encryption_pairs, read_secure_connection_data};
|
||||
use crate::rmc::message::RMCMessage;
|
||||
use crate::rmc::structures::RmcSerialize;
|
||||
use crate::prudp::sockaddr::PRUDPSockAddr;
|
||||
use crate::prudp::station_url::Type::PRUDP;
|
||||
|
||||
mod endianness;
|
||||
mod prudp;
|
||||
pub mod rmc;
|
||||
mod protocols;
|
||||
//mod protocols;
|
||||
|
||||
mod nex;
|
||||
mod grpc;
|
||||
mod kerberos;
|
||||
mod web;
|
||||
|
||||
static KERBEROS_SERVER_PASSWORD: Lazy<String> = Lazy::new(||{
|
||||
env::var("AUTH_SERVER_PASSWORD")
|
||||
|
|
@ -97,6 +93,7 @@ async fn main() {
|
|||
|
||||
start_servers().await;
|
||||
}
|
||||
/*
|
||||
|
||||
struct AuthServer{
|
||||
router: Arc<Router>,
|
||||
|
|
@ -236,74 +233,66 @@ async fn start_secure_server() -> SecureServer{
|
|||
router,
|
||||
socket,
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
async fn start_servers(){
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
let a = tokio::spawn(async{
|
||||
let (router_auth, _) =
|
||||
Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *AUTH_SERVER_PORT)).await.expect("unable to start router");
|
||||
|
||||
let mut socket_auth = router_auth.add_socket(VirtualPort::new(1,10), Unsecure("CD&ML")).await
|
||||
.expect("unable to add socket");
|
||||
|
||||
let mut conn = socket_auth.accept().await.unwrap();
|
||||
info!("got conn");
|
||||
|
||||
if let Some(data) = conn.recv().await{
|
||||
let str = String::from_utf8(data).unwrap();
|
||||
|
||||
println!("{}", str)
|
||||
}
|
||||
});
|
||||
|
||||
let b = tokio::spawn(async{
|
||||
let auth_ip = SocketAddrV4::new(*OWN_IP_PRIVATE, *AUTH_SERVER_PORT);
|
||||
let auth_port = VirtualPort::new(1,10);
|
||||
|
||||
let auth_sockaddr = PRUDPSockAddr::new(auth_ip,auth_port);
|
||||
|
||||
|
||||
let (router_secure, _) =
|
||||
Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *SECURE_SERVER_PORT)).await.expect("unable to start router");
|
||||
|
||||
let mut socket_secure = router_secure.add_socket(VirtualPort::new(1,10), Unsecure("CD&ML")).await
|
||||
.expect("unable to add socket");
|
||||
|
||||
let conn = socket_secure.connect(auth_sockaddr).await.unwrap();
|
||||
|
||||
let conn = conn.duplicate_sender();
|
||||
|
||||
conn.send("Yippie".as_bytes().to_owned()).await;
|
||||
|
||||
info!("got conn");
|
||||
});
|
||||
|
||||
a.await;
|
||||
b.await;
|
||||
|
||||
/*
|
||||
#[cfg(feature = "auth")]
|
||||
let auth_server = start_auth_server().await;
|
||||
#[cfg(feature = "secure")]
|
||||
let secure_server = start_secure_server().await;
|
||||
let web_server = web::start_web().await;
|
||||
|
||||
#[cfg(feature = "auth")]
|
||||
auth_server.join_handle.await.expect("auth server crashed");
|
||||
#[cfg(feature = "secure")]
|
||||
secure_server.join_handle.await.expect("auth server crashed");
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test{
|
||||
use std::io::Cursor;
|
||||
use std::num::ParseIntError;
|
||||
use std::str::from_utf8;
|
||||
use hmac::digest::consts::U5;
|
||||
use rc4::{KeyInit, Rc4, StreamCipher};
|
||||
use crate::prudp::packet::PRUDPPacket;
|
||||
use crate::rmc;
|
||||
|
||||
fn from_hex_stream(val: &str) -> Result<Vec<u8>, ParseIntError> {
|
||||
let res: Result<Vec<u8>, _> = val.as_bytes()
|
||||
.chunks_exact(2)
|
||||
.map(|c| from_utf8(c).expect("unable to convert back to string"))
|
||||
.map(|s| u8::from_str_radix(s, 16))
|
||||
.collect();
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn simulate_packets(){
|
||||
let val = from_hex_stream("ead001037d00afa1e200a5000200d9e4a4050368c18c6de4e2fb1cc40f0c020100768744db99f92c5005a061fd2a1df280cd64d5c1a565952c6befa607cbaf34661312b16db0fa6fccfb81e28b5a3a9bed02b49152bbc99cc112b7e29b9e45ec3d4b89df0fe71390883d9a927c264d07ada0de9cd28499e3ccdf3fd079e4a9848d4d783778c42da2af06106a7326634dc5bec5c3438ef18e30109839ffcc").expect("uuuuh");
|
||||
|
||||
let mut packet = PRUDPPacket::new(&mut Cursor::new(&val)).expect("invalid packet");
|
||||
|
||||
let mut rc4: Rc4<U5> =
|
||||
Rc4::new_from_slice("CD&ML".as_bytes().into()).expect("invalid key");
|
||||
|
||||
rc4.apply_keystream(&mut packet.payload);
|
||||
|
||||
println!("packet: {:?}", packet);
|
||||
|
||||
let rmc_packet = rmc::message::RMCMessage::new(&mut Cursor::new(&packet.payload)).expect("unable to read message");
|
||||
|
||||
let mut a = Cursor::new(&rmc_packet.rest_of_data);
|
||||
|
||||
//let pid = rmc::structures::string::read(&mut a).expect("unable to read pid");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn simulate_packets_response(){
|
||||
let val = from_hex_stream("ead001032501a1af6200a500010013ffcdbc3a2ebc44efc6e38ea32a72b40201002e8644db19fe2a5005a2637d2a16f3b1fe5633037c1ed61c5aefad8afebdf2ff8600e9350fba1298b570c70f6dd647eac2d3faf0ab74ef761e2ee43dc10e249e5f91aed6813dcc04b3c707d9442b6e353b9b0b654e98f860fe5379c41d3c2a1874b7dd37ebf499e03bd2fd3e9a9203c0959feb760c38f504dcd0c9e99b17fd410657da4efa3e01c8a68ab3042d6d489788d5580778d32249cdf1fba8bf68cf4019d116ea7c580622ea1e3635139d91b44635d5e95b6c35b33898fdc0117fa6fc7162840d07a49f1e7089aa0ea65409a8ddeb2334449ba73a0ff7de462cf4a706a696de0f0521b84ae5a3f8587f3585d202d3cc0fb0451519c1b830b5e3cdd6de52e9add7325cbbf08a7c2f8b875934942b226703a22b4bc8931932dab055049051e4144b02").expect("uuuuh");
|
||||
|
||||
let mut packet = PRUDPPacket::new(&mut Cursor::new(&val)).expect("invalid packet");
|
||||
|
||||
let mut rc4: Rc4<U5> =
|
||||
Rc4::new_from_slice("CD&ML".as_bytes().into()).expect("invalid key");
|
||||
|
||||
rc4.apply_keystream(&mut packet.payload);
|
||||
|
||||
println!("packet: {:?}", packet);
|
||||
}
|
||||
web_server.await.expect("webserver crashed");*/
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ use std::sync::Arc;
|
|||
use log::error;
|
||||
use tokio::sync::Mutex;
|
||||
use crate::protocols::auth::AuthProtocolConfig;
|
||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
||||
use crate::rmc::message::RMCMessage;
|
||||
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
||||
use crate::rmc::structures::RmcSerialize;
|
||||
|
|
@ -7,7 +7,6 @@ use crate::grpc::account;
|
|||
use crate::kerberos::KerberosDateTime;
|
||||
use crate::protocols::auth::AuthProtocolConfig;
|
||||
use crate::protocols::auth::ticket_generation::generate_ticket;
|
||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
||||
use crate::rmc;
|
||||
use crate::rmc::message::RMCMessage;
|
||||
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
||||
|
|
@ -4,7 +4,6 @@ use tokio::sync::Mutex;
|
|||
use crate::endianness::{IS_BIG_ENDIAN, ReadExtensions};
|
||||
use crate::protocols::auth::{AuthProtocolConfig, get_login_data_by_pid};
|
||||
use crate::protocols::auth::ticket_generation::generate_ticket;
|
||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
||||
use crate::rmc::message::RMCMessage;
|
||||
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
||||
use crate::rmc::response::ErrorCode::Core_Unknown;
|
||||
|
|
@ -2,7 +2,6 @@ use std::io::Cursor;
|
|||
use std::sync::Arc;
|
||||
use tokio::sync::{Mutex, RwLock};
|
||||
use crate::protocols::matchmake_common::MatchmakeData;
|
||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
||||
use crate::rmc::message::RMCMessage;
|
||||
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
||||
use crate::rmc::structures::qresult::QResult;
|
||||
|
|
@ -5,7 +5,6 @@ use rand::random;
|
|||
use tokio::sync::{Mutex, RwLock};
|
||||
use crate::kerberos::KerberosDateTime;
|
||||
use crate::protocols::notification::Notification;
|
||||
use crate::prudp::socket::{ActiveConnectionData, ConnectionData, SocketData};
|
||||
use crate::rmc::structures::matchmake::{Gathering, MatchmakeParam, MatchmakeSession};
|
||||
use crate::rmc::structures::variant::Variant;
|
||||
|
||||
|
|
@ -44,7 +43,7 @@ impl ExtendedMatchmakeSession{
|
|||
|
||||
let mm_session = MatchmakeSession{
|
||||
gathering: Gathering{
|
||||
self_gid: random(),
|
||||
self_gid: 1,
|
||||
owner_pid: active_secure_connection_data.pid,
|
||||
host_pid: active_secure_connection_data.pid,
|
||||
..session.gathering.clone()
|
||||
|
|
@ -7,7 +7,6 @@ use rand::random;
|
|||
use tokio::sync::{Mutex, RwLock};
|
||||
use tokio::time::sleep;
|
||||
use crate::protocols::matchmake_common::{ExtendedMatchmakeSession, MatchmakeData};
|
||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
||||
use crate::rmc::message::RMCMessage;
|
||||
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
||||
use crate::rmc::structures::matchmake::{AutoMatchmakeParam, MatchmakeSession};
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
use std::io::Cursor;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use log::info;
|
||||
use tokio::sync::{Mutex, RwLock};
|
||||
use tokio::time::sleep;
|
||||
use crate::protocols::matchmake_common::{add_matchmake_session, ExtendedMatchmakeSession, MatchmakeData};
|
||||
use crate::protocols::matchmake_extension::method_auto_matchmake_with_param_postpone::auto_matchmake_with_param_postpone;
|
||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
||||
use crate::rmc::message::RMCMessage;
|
||||
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
||||
use crate::rmc::structures::matchmake::{AutoMatchmakeParam, CreateMatchmakeSessionParam};
|
||||
|
|
@ -29,13 +30,17 @@ pub async fn create_matchmake_session_with_param(
|
|||
|
||||
session.add_player(&socket, conn.clone(), create_matchmake_session.join_message).await;
|
||||
|
||||
println!("{:?}", session);
|
||||
|
||||
|
||||
let mut response = Vec::new();
|
||||
|
||||
|
||||
session.session.serialize(&mut response).expect("unable to serialize session");
|
||||
|
||||
println!("{}", hex::encode(&response));
|
||||
|
||||
|
||||
|
||||
rmcmessage.success_with_data(response)
|
||||
}
|
||||
|
||||
|
|
@ -51,7 +56,32 @@ pub async fn create_matchmake_session_with_param_raw_params(
|
|||
return rmcmessage.error_result_with_code(ErrorCode::Core_InvalidArgument);
|
||||
};
|
||||
|
||||
|
||||
|
||||
create_matchmake_session_with_param(rmcmessage, connection_data, socket, data, matchmake_param).await
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test{
|
||||
use std::io::Cursor;
|
||||
use crate::prudp::packet::PRUDPPacket;
|
||||
use crate::rmc::message::RMCMessage;
|
||||
use crate::rmc::structures::matchmake::MatchmakeSession;
|
||||
use crate::rmc::structures::RmcSerialize;
|
||||
|
||||
#[test]
|
||||
fn test(){
|
||||
let data = hex::decode("ead001030000a1af12001800050002010000000000000000000000000000000000").unwrap();
|
||||
|
||||
let packet = PRUDPPacket::new(&mut Cursor::new(data)).unwrap();
|
||||
|
||||
println!("{:?}", packet);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_2(){
|
||||
let data = hex::decode("250000008e0100000001000000001700000051b39957b90b00000100000051b3995701000001000000").unwrap();
|
||||
|
||||
let msg = RMCMessage::new(&mut Cursor::new(data)).unwrap();
|
||||
|
||||
println!("{:?}", msg)
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@ use std::sync::Arc;
|
|||
use log::info;
|
||||
use tokio::sync::{Mutex, RwLock};
|
||||
use crate::protocols::matchmake_common::MatchmakeData;
|
||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
||||
use crate::rmc::message::RMCMessage;
|
||||
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
||||
use crate::rmc::structures::RmcSerialize;
|
||||
|
|
@ -6,7 +6,6 @@ use log::warn;
|
|||
use once_cell::sync::Lazy;
|
||||
use tokio::sync::Mutex;
|
||||
use crate::grpc;
|
||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
||||
use crate::rmc::message::RMCMessage;
|
||||
use crate::rmc::response::{ErrorCode, RMCResponse};
|
||||
|
||||
|
|
@ -17,7 +16,7 @@ pub mod secure;
|
|||
pub mod matchmake_extension;
|
||||
pub mod matchmake_common;
|
||||
pub mod matchmake;
|
||||
mod notification;
|
||||
pub mod notification;
|
||||
pub mod nat_traversal;
|
||||
|
||||
static IS_MAINTENANCE: Lazy<bool> = Lazy::new(|| {
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
use std::io::Cursor;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use tokio::sync::{Mutex, RwLock};
|
||||
use tokio::time::sleep;
|
||||
use crate::protocols::matchmake_common::MatchmakeData;
|
||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
||||
use crate::rmc::message::RMCMessage;
|
||||
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
||||
use crate::rmc::structures::matchmake::CreateMatchmakeSessionParam;
|
||||
|
|
@ -12,6 +13,7 @@ pub async fn report_nat_properties(
|
|||
socket: &Arc<SocketData>,
|
||||
connection_data: &Arc<Mutex<ConnectionData>>,
|
||||
) -> RMCResponseResult{
|
||||
sleep(Duration::from_millis(50)).await;
|
||||
rmcmessage.success_with_data(Vec::new())
|
||||
}
|
||||
|
||||
|
|
@ -3,7 +3,6 @@ use rand::random;
|
|||
use crate::prudp::packet::{PRUDPHeader, PRUDPPacket, PacketOption, TypesFlags};
|
||||
use crate::prudp::packet::flags::{NEED_ACK, RELIABLE};
|
||||
use crate::prudp::packet::types::DATA;
|
||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
||||
use crate::rmc::message::RMCMessage;
|
||||
use crate::rmc::structures::RmcSerialize;
|
||||
|
||||
|
|
@ -30,10 +29,11 @@ impl ConnectionData{
|
|||
let message = RMCMessage{
|
||||
protocol_id: 14,
|
||||
method_id: 1,
|
||||
call_id: random(),
|
||||
call_id: 1,
|
||||
rest_of_data: data
|
||||
};
|
||||
|
||||
println!("notif: {}", hex::encode(message.to_data()));
|
||||
|
||||
|
||||
let mut prudp_packet = PRUDPPacket{
|
||||
|
|
@ -99,23 +99,6 @@ mod test{
|
|||
println!("{:?}", notif);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test3(){
|
||||
|
||||
let data = hex::decode("ead001032900a1af620084000300020100250000008e0100000001000000001700000051b39957b90b00000100000051b399570100000100000000000000000000000000000000000000").unwrap();
|
||||
let packet = PRUDPPacket::new(&mut Cursor::new(data)).expect("invalid packet");
|
||||
|
||||
println!("{:?}", packet);
|
||||
|
||||
let rmc = RMCMessage::new(&mut Cursor::new(packet.payload)).expect("invalid rmc message");
|
||||
|
||||
println!("{:?}", rmc);
|
||||
|
||||
let notif = Notification::deserialize(&mut Cursor::new(rmc.rest_of_data)).expect("invalid notification");
|
||||
|
||||
println!("{:?}", notif);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rmc_serialization(){
|
||||
let notif = Notification{
|
||||
|
|
@ -2,7 +2,6 @@ use std::io::{Cursor, Write};
|
|||
use std::sync::Arc;
|
||||
use bytemuck::bytes_of;
|
||||
use tokio::sync::Mutex;
|
||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
||||
use crate::prudp::station_url::{nat_types, StationUrl};
|
||||
use crate::prudp::station_url::Type::PRUDPS;
|
||||
use crate::prudp::station_url::UrlOptions::{Address, NatFiltering, NatMapping, NatType, Port, PrincipalID, RVConnectionID};
|
||||
|
|
@ -3,11 +3,11 @@ use std::sync::Arc;
|
|||
use log::error;
|
||||
use tokio::sync::Mutex;
|
||||
use crate::endianness::{IS_BIG_ENDIAN, ReadExtensions};
|
||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
||||
use crate::rmc::message::RMCMessage;
|
||||
use crate::rmc::response::{RMCResponseResult};
|
||||
use crate::rmc::response::ErrorCode::Core_InvalidArgument;
|
||||
use crate::rmc::structures::qbuffer;
|
||||
use crate::rmc::structures::{qbuffer, RmcSerialize};
|
||||
use crate::rmc::structures::qbuffer::QBuffer;
|
||||
|
||||
pub async fn send_report(rmcmessage: &RMCMessage, report_id: u32, data: Vec<u8>) -> RMCResponseResult{
|
||||
let result = tokio::fs::write(format!("./reports/{}", report_id), data).await;
|
||||
|
|
@ -17,7 +17,7 @@ pub async fn send_report(rmcmessage: &RMCMessage, report_id: u32, data: Vec<u8>)
|
|||
Err(e) => error!("{}", e)
|
||||
}
|
||||
|
||||
return rmcmessage.success_with_data(Vec::new());
|
||||
rmcmessage.success_with_data(Vec::new())
|
||||
}
|
||||
|
||||
pub async fn send_report_raw_params(rmcmessage: &RMCMessage, _: &Arc<SocketData>, _conn_data: &Arc<Mutex<ConnectionData>>, _: ()) -> RMCResponseResult{
|
||||
|
|
@ -27,7 +27,7 @@ pub async fn send_report_raw_params(rmcmessage: &RMCMessage, _: &Arc<SocketData>
|
|||
return rmcmessage.error_result_with_code(Core_InvalidArgument);
|
||||
};
|
||||
|
||||
let Ok(data) = qbuffer::read(&mut reader) else {
|
||||
let Ok(QBuffer(data)) = QBuffer::deserialize(&mut reader) else {
|
||||
return rmcmessage.error_result_with_code(Core_InvalidArgument);
|
||||
};
|
||||
|
||||
|
|
@ -5,10 +5,11 @@ use std::sync::Arc;
|
|||
use log::error;
|
||||
use tokio::sync::Mutex;
|
||||
use crate::prudp::packet::PRUDPPacket;
|
||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
||||
use crate::rmc::message::RMCMessage;
|
||||
use crate::rmc::response::{RMCResponse, RMCResponseResult, send_response};
|
||||
use crate::rmc::response::ErrorCode::Core_NotImplemented;
|
||||
use crate::web::DirectionalData::Incoming;
|
||||
use crate::web::WEB_DATA;
|
||||
|
||||
type ContainedProtocolList = Box<[Box<dyn for<'a> Fn(&'a RMCMessage, &'a Arc<SocketData>, &'a Arc<Mutex<ConnectionData>>) -> Pin<Box<dyn Future<Output = Option<RMCResponse>> + Send + 'a>> + Send + Sync>]>;
|
||||
|
||||
|
|
@ -20,6 +21,13 @@ impl RMCProtocolServer{
|
|||
}
|
||||
|
||||
pub async fn process_message(&self, packet: PRUDPPacket, socket: Arc<SocketData>, connection: Arc<Mutex<ConnectionData>>){
|
||||
let locked = connection.lock().await;
|
||||
let addr = locked.sock_addr.regular_socket_addr;
|
||||
drop(locked);
|
||||
let mut web = WEB_DATA.lock().await;
|
||||
web.data.push((addr, Incoming(hex::encode(&packet.payload))));
|
||||
drop(web);
|
||||
|
||||
let Ok(rmc) = RMCMessage::new(&mut Cursor::new(&packet.payload)) else {
|
||||
error!("error reading rmc message");
|
||||
return;
|
||||
|
|
@ -2,6 +2,6 @@ pub mod packet;
|
|||
pub mod router;
|
||||
pub mod socket;
|
||||
mod auth_module;
|
||||
mod sockaddr;
|
||||
pub mod secure;
|
||||
pub mod sockaddr;
|
||||
//pub mod secure;
|
||||
pub mod station_url;
|
||||
|
|
@ -96,10 +96,11 @@ impl Debug for TypesFlags {
|
|||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(PartialEq, Eq, Copy, Clone, Pod, Zeroable, SwapEndian, Hash)]
|
||||
#[derive(PartialEq, Eq, Ord, PartialOrd, Copy, Clone, Pod, Zeroable, SwapEndian, Hash)]
|
||||
pub struct VirtualPort(pub(crate) u8);
|
||||
|
||||
impl VirtualPort {
|
||||
|
||||
#[inline]
|
||||
pub const fn get_stream_type(self) -> u8 {
|
||||
(self.0 & 0xF0) >> 4
|
||||
|
|
@ -236,7 +237,7 @@ impl PacketOption{
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
#[derive(Debug, Default, Clone, Eq, PartialEq)]
|
||||
pub struct PRUDPPacket {
|
||||
pub header: PRUDPHeader,
|
||||
pub packet_signature: [u8; 16],
|
||||
|
|
@ -375,6 +376,7 @@ impl PRUDPPacket {
|
|||
types_and_flags: flags,
|
||||
sequence_id: self.header.sequence_id,
|
||||
substream_id: self.header.substream_id,
|
||||
session_id: self.header.session_id,
|
||||
..base.header
|
||||
},
|
||||
options,
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use once_cell::sync::Lazy;
|
|||
use log::{error, info, trace};
|
||||
use thiserror::Error;
|
||||
use tokio::sync::RwLock;
|
||||
use crate::prudp::socket::SocketData;
|
||||
use crate::prudp::socket::{new_socket_pair, AnyInternalSocket, CryptoHandler, ExternalSocket};
|
||||
use crate::prudp::packet::{PRUDPPacket, VirtualPort};
|
||||
use crate::prudp::router::Error::VirtualPortTaken;
|
||||
|
||||
|
|
@ -22,10 +22,9 @@ static SERVER_DATAGRAMS: Lazy<u8> = Lazy::new(||{
|
|||
});
|
||||
|
||||
pub struct Router {
|
||||
endpoints: RwLock<[Option<Arc<SocketData>>; 16]>,
|
||||
endpoints: RwLock<[Option<Arc<dyn AnyInternalSocket>>; 16]>,
|
||||
running: AtomicBool,
|
||||
socket: Arc<UdpSocket>,
|
||||
//pub auth_module: Arc<dyn AuthModule>
|
||||
_no_outside_construction: PhantomData<()>
|
||||
}
|
||||
#[derive(Debug, Error)]
|
||||
|
|
@ -36,9 +35,6 @@ pub enum Error{
|
|||
|
||||
|
||||
impl Router {
|
||||
fn process_prudp_packet(&self, _packet: &PRUDPPacket){
|
||||
|
||||
}
|
||||
async fn process_prudp_packets<'a>(self: Arc<Self>, _socket: Arc<UdpSocket>, addr: SocketAddrV4, udp_message: Vec<u8>){
|
||||
let mut stream = Cursor::new(&udp_message);
|
||||
|
||||
|
|
@ -69,7 +65,9 @@ impl Router {
|
|||
|
||||
trace!("sending packet to endpoint");
|
||||
|
||||
endpoint.process_packet(connection, &packet).await;
|
||||
tokio::spawn(async move {
|
||||
endpoint.recieve_packet(connection, packet).await
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -88,6 +86,7 @@ impl Router {
|
|||
continue;
|
||||
};
|
||||
|
||||
|
||||
let current_msg = &msg_buffer[0..len];
|
||||
|
||||
tokio::spawn(self.clone().process_prudp_packets(socket.clone(), addr, current_msg.to_vec()));
|
||||
|
|
@ -144,18 +143,22 @@ impl Router {
|
|||
}
|
||||
|
||||
// returns Some(()) i
|
||||
pub(crate) async fn add_socket(&self, socket: Arc<SocketData>) -> Result<(), Error>{
|
||||
pub(crate) async fn add_socket<E: CryptoHandler>(&self, virtual_port: VirtualPort, encryption: E)
|
||||
-> Result<ExternalSocket, Error>{
|
||||
let mut endpoints = self.endpoints.write().await;
|
||||
|
||||
let idx = socket.get_virual_port().get_port_number() as usize;
|
||||
let idx = virtual_port.get_port_number() as usize;
|
||||
|
||||
if endpoints[idx].is_none() {
|
||||
endpoints[idx] = Some(socket);
|
||||
} else {
|
||||
// dont create the socket if we dont need to
|
||||
if !endpoints[idx].is_none(){
|
||||
return Err(VirtualPortTaken(idx as u8));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
let (internal, external) = new_socket_pair(virtual_port, encryption, self.socket.clone());
|
||||
|
||||
endpoints[idx] = Some(internal);
|
||||
|
||||
Ok(external)
|
||||
}
|
||||
|
||||
pub fn get_own_address(&self) -> SocketAddrV4{
|
||||
|
|
|
|||
|
|
@ -73,12 +73,12 @@ pub fn read_secure_connection_data(data: &[u8], act: &Account) -> Option<([u8; 3
|
|||
|
||||
type Rc4U32 = StreamCipherCoreWrapper<Rc4Core<U32>>;
|
||||
|
||||
pub fn generate_secure_encryption_pairs(mut session_key: [u8; 32], count: u8) -> Vec<EncryptionPair>{
|
||||
pub fn generate_secure_encryption_pairs(mut session_key: [u8; 32], count: u8) -> Vec<EncryptionPair<Rc4<U32>>>{
|
||||
let mut vec = Vec::with_capacity(count as usize);
|
||||
|
||||
vec.push(EncryptionPair{
|
||||
send: Box::new(Rc4U32::new_from_slice(&session_key).expect("unable to create rc4")),
|
||||
recv: Box::new(Rc4U32::new_from_slice(&session_key).expect("unable to create rc4"))
|
||||
send: Rc4U32::new_from_slice(&session_key).expect("unable to create rc4"),
|
||||
recv: Rc4U32::new_from_slice(&session_key).expect("unable to create rc4")
|
||||
});
|
||||
|
||||
for _ in 1..=count{
|
||||
|
|
@ -91,8 +91,8 @@ pub fn generate_secure_encryption_pairs(mut session_key: [u8; 32], count: u8) ->
|
|||
}
|
||||
|
||||
vec.push(EncryptionPair{
|
||||
send: Box::new(Rc4U32::new_from_slice(&session_key).expect("unable to create rc4")),
|
||||
recv: Box::new(Rc4U32::new_from_slice(&session_key).expect("unable to create rc4"))
|
||||
send: Rc4U32::new_from_slice(&session_key).expect("unable to create rc4"),
|
||||
recv: Rc4U32::new_from_slice(&session_key).expect("unable to create rc4")
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,14 +5,24 @@ use crate::prudp::packet::VirtualPort;
|
|||
|
||||
type Md5Hmac = Hmac<md5::Md5>;
|
||||
|
||||
#[derive(Eq, PartialEq, Hash, Debug, Copy, Clone)]
|
||||
#[derive(Eq, PartialEq, Hash, Debug, Copy, Clone, Ord, PartialOrd)]
|
||||
pub struct PRUDPSockAddr{
|
||||
pub regular_socket_addr: SocketAddrV4,
|
||||
pub virtual_port: VirtualPort
|
||||
}
|
||||
|
||||
|
||||
|
||||
impl PRUDPSockAddr{
|
||||
pub fn calculate_connection_signature(&self) -> [u8; 16] {
|
||||
|
||||
pub fn new(regular_socket_addr: SocketAddrV4, virtual_port: VirtualPort) -> Self{
|
||||
Self{
|
||||
regular_socket_addr,
|
||||
virtual_port
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn calculate_connection_signature(&self) -> [u8; 16] {
|
||||
let mut hmac = Md5Hmac::new_from_slice(&[0; 16]).expect("fuck");
|
||||
|
||||
let mut data = self.regular_socket_addr.ip().octets().to_vec();
|
||||
|
|
|
|||
1169
src/prudp/socket.rs
1169
src/prudp/socket.rs
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,7 @@
|
|||
pub mod message;
|
||||
pub mod structures;
|
||||
pub mod response;
|
||||
pub mod protocols;
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
17
src/rmc/protocols/mod.rs
Normal file
17
src/rmc/protocols/mod.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
use std::sync::Arc;
|
||||
use async_trait::async_trait;
|
||||
use tokio::sync::Mutex;
|
||||
use crate::prudp::socket::ExternalConnection;
|
||||
use crate::rmc::structures::connection_data::ConnectionData;
|
||||
|
||||
pub trait RmcCallable{
|
||||
fn rmc_call(protocol_id: u8, method_id: u8, rest: Vec<u8>);
|
||||
}
|
||||
|
||||
struct LocalRmcObjectWrapper<T: RmcCallable>(T);
|
||||
impl<T: RmcCallable> LocalRmcObjectWrapper<T>{
|
||||
pub fn new(object: T, conn: ExternalConnection) -> Self{
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6,8 +6,10 @@ use crate::prudp::packet::{PRUDPPacket};
|
|||
use crate::prudp::packet::flags::{NEED_ACK, RELIABLE};
|
||||
use crate::prudp::packet::PacketOption::FragmentId;
|
||||
use crate::prudp::packet::types::DATA;
|
||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
||||
use crate::prudp::socket::ExternalConnection;
|
||||
use crate::rmc::structures::qresult::ERROR_MASK;
|
||||
use crate::web::DirectionalData::{Incoming, Outgoing};
|
||||
use crate::web::WEB_DATA;
|
||||
|
||||
pub enum RMCResponseResult {
|
||||
Success{
|
||||
|
|
@ -76,33 +78,8 @@ pub fn generate_response(protocol_id: u8, response: RMCResponseResult) -> io::Re
|
|||
|
||||
Ok(data_out)
|
||||
}
|
||||
pub async fn send_response(original_packet: &PRUDPPacket, socket: &SocketData, connection: &mut ConnectionData, rmcresponse: RMCResponse){
|
||||
|
||||
let ConnectionData{
|
||||
active_connection_data,
|
||||
..
|
||||
} = connection;
|
||||
|
||||
let Some(active_connection) = active_connection_data else {
|
||||
return;
|
||||
};
|
||||
|
||||
let mut packet = original_packet.base_response_packet();
|
||||
|
||||
|
||||
packet.header.types_and_flags.set_types(DATA);
|
||||
packet.header.types_and_flags.set_flag((original_packet.header.types_and_flags.get_flags() & RELIABLE) | NEED_ACK);
|
||||
|
||||
//packet.header.session_id = active_connection.server_session_id;
|
||||
packet.header.substream_id = 0;
|
||||
|
||||
packet.options.push(FragmentId(0));
|
||||
|
||||
packet.payload = rmcresponse.to_data();
|
||||
|
||||
//tokio::time::sleep(Duration::from_millis(500)).await;
|
||||
|
||||
connection.finish_and_send_packet_to(socket, packet).await;
|
||||
pub async fn send_response(original_packet: &PRUDPPacket, connection: &mut ExternalConnection, rmcresponse: RMCResponse){
|
||||
connection.send(rmcresponse.to_data()).await;
|
||||
}
|
||||
|
||||
//taken from kinnays error list directly
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ pub mod qbuffer;
|
|||
pub mod primitives;
|
||||
pub mod matchmake;
|
||||
pub mod variant;
|
||||
mod ranking;
|
||||
|
||||
pub trait RmcSerialize: Sized{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> Result<()>;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,30 @@
|
|||
use std::io::Read;
|
||||
use std::io::{Read, Write};
|
||||
use bytemuck::bytes_of;
|
||||
use crate::endianness::{IS_BIG_ENDIAN, ReadExtensions};
|
||||
use crate::rmc::structures::Result;
|
||||
pub fn read(reader: &mut impl Read) -> Result<Vec<u8>>{
|
||||
let size: u16 = reader.read_struct(IS_BIG_ENDIAN)?;
|
||||
use crate::rmc::structures::{Result, RmcSerialize};
|
||||
use crate::rmc::structures::qresult::QResult;
|
||||
|
||||
let mut vec = vec![0; size as usize];
|
||||
|
||||
reader.read_exact(&mut vec)?;
|
||||
#[derive(Debug)]
|
||||
pub struct QBuffer(pub Vec<u8>);
|
||||
|
||||
Ok(vec)
|
||||
impl RmcSerialize for QBuffer{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> Result<()> {
|
||||
let len_u16 = self.0.len() as u16;
|
||||
|
||||
writer.write(bytes_of(&len_u16))?;
|
||||
writer.write(&self.0)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn deserialize(mut reader: &mut dyn Read) -> Result<Self> {
|
||||
let size: u16 = reader.read_struct(IS_BIG_ENDIAN)?;
|
||||
|
||||
let mut vec = vec![0; size as usize];
|
||||
|
||||
reader.read_exact(&mut vec)?;
|
||||
|
||||
Ok(Self(vec))
|
||||
}
|
||||
}
|
||||
69
src/rmc/structures/ranking.rs
Normal file
69
src/rmc/structures/ranking.rs
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
use bytemuck::{Pod, Zeroable};
|
||||
use macros::RmcSerialize;
|
||||
use crate::rmc::structures::qbuffer::QBuffer;
|
||||
|
||||
#[derive(RmcSerialize, Debug)]
|
||||
#[rmc_struct(0)]
|
||||
struct UploadCompetitionData{
|
||||
winning_team/*?*/: u32,
|
||||
splatfest_id/*?*/: u32,
|
||||
unk_2/*?*/: u32,
|
||||
unk_3: u32,
|
||||
team_id_1: u8,
|
||||
team_id_2: u8,
|
||||
unk_5: u32,
|
||||
player_data/*?*/: QBuffer,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Pod, Zeroable)]
|
||||
#[repr(C)]
|
||||
struct UserData{
|
||||
name: [u16; 0x10],
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test{
|
||||
use std::io::Cursor;
|
||||
use bytemuck::from_bytes;
|
||||
use tokio::io::AsyncReadExt;
|
||||
use crate::rmc::structures::ranking::{UploadCompetitionData, UserData};
|
||||
use crate::rmc::structures::RmcSerialize;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
let data: [u8; 0xBD] = [
|
||||
0x00, 0xB8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFC, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00,
|
||||
0x00, 0x1F, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x49, 0x00,
|
||||
0x7A, 0x00, 0x7A, 0x00, 0x79, 0x00, 0x53, 0x00, 0x50, 0x00, 0x46, 0x00, 0x4E, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0xF2, 0x00, 0x00, 0x00,
|
||||
0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x1F, 0x5E, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x90, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0A, 0x00, 0x00, 0x14, 0x87, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x00, 0x00, 0x00,
|
||||
];
|
||||
|
||||
let mut cursor = Cursor::new(data);
|
||||
|
||||
let data = UploadCompetitionData::deserialize(&mut cursor).expect("unable to deserialize data");
|
||||
|
||||
let user_data: &UserData = from_bytes(&data.player_data.0[..size_of::<UserData>()]);
|
||||
|
||||
let pos = user_data.name.iter()
|
||||
.position(|v| *v == 0x0000)
|
||||
.unwrap_or(0x10);
|
||||
|
||||
let mut name = user_data.name[0..pos].to_vec();
|
||||
|
||||
name.iter_mut().for_each(|v| *v = v.swap_bytes());
|
||||
|
||||
let name = String::from_utf16(&name).expect("unable to get name");
|
||||
|
||||
println!("{:?}", name);
|
||||
|
||||
assert!(u8::deserialize(&mut cursor).is_err())
|
||||
}
|
||||
}
|
||||
|
|
@ -35,4 +35,5 @@ impl RmcSerialize for &str{
|
|||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
37
src/web/mod.rs
Normal file
37
src/web/mod.rs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
use std::net::SocketAddrV4;
|
||||
use once_cell::sync::Lazy;
|
||||
use rocket::{get, routes, Rocket};
|
||||
use rocket::serde::json::Json;
|
||||
use tokio::task::JoinHandle;
|
||||
use serde::Serialize;
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
#[get("/")]
|
||||
async fn server_data() -> Json<WebData> {
|
||||
Json(WEB_DATA.lock().await.clone())
|
||||
}
|
||||
|
||||
pub async fn start_web() -> JoinHandle<()>{
|
||||
tokio::spawn(async{
|
||||
rocket::build()
|
||||
.mount("/",routes![server_data])
|
||||
.launch().await
|
||||
.expect("unable to start webserver");
|
||||
})
|
||||
}
|
||||
#[derive(Serialize, Clone)]
|
||||
pub enum DirectionalData{
|
||||
Incoming(String),
|
||||
Outgoing(String)
|
||||
}
|
||||
|
||||
#[derive(Serialize, Default, Clone)]
|
||||
pub struct WebData{
|
||||
pub data: Vec<(SocketAddrV4, DirectionalData)>
|
||||
}
|
||||
|
||||
pub static WEB_DATA: Lazy<Mutex<WebData>> = Lazy::new(|| Mutex::new(
|
||||
WebData{
|
||||
data: Vec::new(),
|
||||
}
|
||||
));
|
||||
Loading…
Add table
Add a link
Reference in a new issue