feat: split rmc off from prudp, make macros crate location independent and add tls connection setup
This commit is contained in:
parent
0a1e49d9bc
commit
9da91bb835
24 changed files with 1218 additions and 420 deletions
850
Cargo.lock
generated
850
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
24
Cargo.toml
24
Cargo.toml
|
|
@ -25,8 +25,8 @@ simplelog = "0.12.2"
|
||||||
chrono = "0.4.39"
|
chrono = "0.4.39"
|
||||||
log = "0.4.25"
|
log = "0.4.25"
|
||||||
anyhow = "1.0.95"
|
anyhow = "1.0.95"
|
||||||
rand = "0.9.0-beta.3"
|
rand = "0.8.5"
|
||||||
rustls = "^0.23.21"
|
|
||||||
hmac = "0.12.1"
|
hmac = "0.12.1"
|
||||||
md-5 = "^0.10.6"
|
md-5 = "^0.10.6"
|
||||||
tokio = { version = "1.43.0", features = ["macros", "rt-multi-thread", "net", "sync", "fs"] }
|
tokio = { version = "1.43.0", features = ["macros", "rt-multi-thread", "net", "sync", "fs"] }
|
||||||
|
|
@ -45,6 +45,15 @@ futures = "0.3.31"
|
||||||
reqwest = "0.12.18"
|
reqwest = "0.12.18"
|
||||||
json = "0.12.4"
|
json = "0.12.4"
|
||||||
ctrlc = "3.4.7"
|
ctrlc = "3.4.7"
|
||||||
|
rsa = "0.9.8"
|
||||||
|
sha2 = "0.10.9"
|
||||||
|
chacha20 = "0.9.1"
|
||||||
|
|
||||||
|
rustls = "0.23.27"
|
||||||
|
|
||||||
|
rustls-pki-types = "1.12.0"
|
||||||
|
rustls-webpki = "0.103.3"
|
||||||
|
tokio-rustls = "0.26.2"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -57,3 +66,14 @@ default = ["secure", "auth"]
|
||||||
secure = []
|
secure = []
|
||||||
auth = []
|
auth = []
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "proxy_insecure"
|
||||||
|
path = "src/executables/proxy_insecure.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "proxy_secure"
|
||||||
|
path = "src/executables/proxy_secure.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "backend_server"
|
||||||
|
path = "src/executables/backend_server.rs"
|
||||||
|
|
@ -189,7 +189,7 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream {
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
#pre_inner
|
#pre_inner
|
||||||
crate::rmc::structures::rmc_struct::write_struct(writer, #version, |mut writer|{
|
splatoon_server_rust::rmc::structures::rmc_struct::write_struct(writer, #version, |mut writer|{
|
||||||
#serialize_base_content
|
#serialize_base_content
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
|
@ -218,7 +218,7 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream {
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
#pre_inner
|
#pre_inner
|
||||||
Ok(crate::rmc::structures::rmc_struct::read_struct(reader, #version, move |mut reader|{
|
Ok(splatoon_server_rust::rmc::structures::rmc_struct::read_struct(reader, #version, move |mut reader|{
|
||||||
#deserialize_base_content
|
#deserialize_base_content
|
||||||
})?)
|
})?)
|
||||||
}
|
}
|
||||||
|
|
@ -229,14 +229,14 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream {
|
||||||
let ident = derive_input.ident;
|
let ident = derive_input.ident;
|
||||||
|
|
||||||
let tokens = quote! {
|
let tokens = quote! {
|
||||||
impl crate::rmc::structures::RmcSerialize for #ident{
|
impl splatoon_server_rust::rmc::structures::RmcSerialize for #ident{
|
||||||
fn serialize(&self, writer: &mut dyn ::std::io::Write) -> crate::rmc::structures::Result<()>{
|
fn serialize(&self, writer: &mut dyn ::std::io::Write) -> splatoon_server_rust::rmc::structures::Result<()>{
|
||||||
#serialize_base_content
|
#serialize_base_content
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(reader: &mut dyn ::std::io::Read) -> crate::rmc::structures::Result<Self>{
|
fn deserialize(reader: &mut dyn ::std::io::Read) -> splatoon_server_rust::rmc::structures::Result<Self>{
|
||||||
#deserialize_base_content
|
#deserialize_base_content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -367,8 +367,8 @@ pub fn rmc_struct(attr: TokenStream, input: TokenStream) -> TokenStream{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl crate::rmc::protocols::RmcCallable for #struct_name{
|
impl splatoon_server_rust::rmc::protocols::RmcCallable for #struct_name{
|
||||||
async fn rmc_call(&self, remote_response_connection: &crate::prudp::socket::SendingConnection, protocol_id: u16, method_id: u32, call_id: u32, rest: Vec<u8>){
|
async fn rmc_call(&self, remote_response_connection: &splatoon_server_rust::util::SendingBufferConnection, protocol_id: u16, method_id: u32, call_id: u32, rest: Vec<u8>){
|
||||||
<Self as #ident>::rmc_call(self, remote_response_connection, protocol_id, method_id, call_id, rest).await;
|
<Self as #ident>::rmc_call(self, remote_response_connection, protocol_id, method_id, call_id, rest).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ impl RmcProtocolData{
|
||||||
for (param_name, param_type) in parameters{
|
for (param_name, param_type) in parameters{
|
||||||
quote!{
|
quote!{
|
||||||
let Ok(#param_name) =
|
let Ok(#param_name) =
|
||||||
<#param_type as crate::rmc::structures::RmcSerialize>::deserialize(
|
<#param_type as splatoon_server_rust::rmc::structures::RmcSerialize>::deserialize(
|
||||||
&mut cursor
|
&mut cursor
|
||||||
) else
|
) else
|
||||||
}.to_tokens(tokens);
|
}.to_tokens(tokens);
|
||||||
|
|
@ -84,7 +84,7 @@ impl RmcProtocolData{
|
||||||
quote! {
|
quote! {
|
||||||
{
|
{
|
||||||
log::error!(#error_msg);
|
log::error!(#error_msg);
|
||||||
return Err(crate::rmc::response::ErrorCode::Core_InvalidArgument);
|
return Err(splatoon_server_rust::rmc::response::ErrorCode::Core_InvalidArgument);
|
||||||
};
|
};
|
||||||
}.to_tokens(tokens)
|
}.to_tokens(tokens)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -116,7 +116,7 @@ impl RmcProtocolData{
|
||||||
quote!{
|
quote!{
|
||||||
let retval = retval?;
|
let retval = retval?;
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
crate::rmc::structures::RmcSerialize::serialize(&retval, &mut vec).ok();
|
splatoon_server_rust::rmc::structures::RmcSerialize::serialize(&retval, &mut vec).ok();
|
||||||
Ok(vec)
|
Ok(vec)
|
||||||
}.to_tokens(tokens);
|
}.to_tokens(tokens);
|
||||||
}
|
}
|
||||||
|
|
@ -126,7 +126,7 @@ impl RmcProtocolData{
|
||||||
quote!{
|
quote!{
|
||||||
async fn rmc_call_proto(
|
async fn rmc_call_proto(
|
||||||
&self,
|
&self,
|
||||||
remote_response_connection: &crate::prudp::socket::SendingConnection,
|
remote_response_connection: &splatoon_server_rust::util::SendingBufferConnection,
|
||||||
method_id: u32,
|
method_id: u32,
|
||||||
call_id: u32,
|
call_id: u32,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
|
|
@ -165,7 +165,7 @@ impl RmcProtocolData{
|
||||||
}.to_tokens(tokens);
|
}.to_tokens(tokens);
|
||||||
if self.has_returns {
|
if self.has_returns {
|
||||||
quote! {
|
quote! {
|
||||||
Err(crate::rmc::response::ErrorCode::Core_NotImplemented)
|
Err(splatoon_server_rust::rmc::response::ErrorCode::Core_NotImplemented)
|
||||||
}.to_tokens(tokens);
|
}.to_tokens(tokens);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -176,7 +176,7 @@ impl RmcProtocolData{
|
||||||
|
|
||||||
if *has_returns{
|
if *has_returns{
|
||||||
quote!{
|
quote!{
|
||||||
crate::rmc::response::send_result(
|
splatoon_server_rust::rmc::response::send_result(
|
||||||
remote_response_connection,
|
remote_response_connection,
|
||||||
ret,
|
ret,
|
||||||
#id,
|
#id,
|
||||||
|
|
@ -209,7 +209,7 @@ impl RmcProtocolData{
|
||||||
// boilerplate tokens which all raw traits need
|
// boilerplate tokens which all raw traits need
|
||||||
quote!{
|
quote!{
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub trait #remote_name: crate::rmc::protocols::HasRmcConnection
|
pub trait #remote_name: splatoon_server_rust::rmc::protocols::HasRmcConnection
|
||||||
}.to_tokens(tokens);
|
}.to_tokens(tokens);
|
||||||
|
|
||||||
// generate the body of the raw protocol trait
|
// generate the body of the raw protocol trait
|
||||||
|
|
@ -247,12 +247,12 @@ impl RmcProtocolData{
|
||||||
|
|
||||||
for (param_name, param_type) in parameters{
|
for (param_name, param_type) in parameters{
|
||||||
quote!{
|
quote!{
|
||||||
crate::result::ResultExtension::display_err_or_some(
|
splatoon_server_rust::result::ResultExtension::display_err_or_some(
|
||||||
<#param_type as crate::rmc::structures::RmcSerialize>::serialize(
|
<#param_type as splatoon_server_rust::rmc::structures::RmcSerialize>::serialize(
|
||||||
&#param_name,
|
&#param_name,
|
||||||
&mut cursor
|
&mut cursor
|
||||||
)
|
)
|
||||||
).ok_or(crate::rmc::response::ErrorCode::Core_InvalidArgument)
|
).ok_or(splatoon_server_rust::rmc::response::ErrorCode::Core_InvalidArgument)
|
||||||
}.to_tokens(tokens);
|
}.to_tokens(tokens);
|
||||||
if self.has_returns {
|
if self.has_returns {
|
||||||
quote! {
|
quote! {
|
||||||
|
|
@ -268,25 +268,25 @@ impl RmcProtocolData{
|
||||||
quote!{
|
quote!{
|
||||||
let call_id = rand::random();
|
let call_id = rand::random();
|
||||||
|
|
||||||
let message = crate::rmc::message::RMCMessage{
|
let message = splatoon_server_rust::rmc::message::RMCMessage{
|
||||||
call_id,
|
call_id,
|
||||||
method_id: #method_id,
|
method_id: #method_id,
|
||||||
protocol_id: #proto_id,
|
protocol_id: #proto_id,
|
||||||
rest_of_data: send_data
|
rest_of_data: send_data
|
||||||
};
|
};
|
||||||
|
|
||||||
let rmc_conn = <Self as crate::rmc::protocols::HasRmcConnection>::get_connection(self);
|
let rmc_conn = <Self as splatoon_server_rust::rmc::protocols::HasRmcConnection>::get_connection(self);
|
||||||
}.to_tokens(tokens);
|
}.to_tokens(tokens);
|
||||||
|
|
||||||
if *has_returns{
|
if *has_returns{
|
||||||
quote!{
|
quote!{
|
||||||
crate::result::ResultExtension::display_err_or_some(
|
splatoon_server_rust::result::ResultExtension::display_err_or_some(
|
||||||
rmc_conn.make_raw_call(&message).await
|
rmc_conn.make_raw_call(&message).await
|
||||||
).ok_or(crate::rmc::response::ErrorCode::Core_Exception)
|
).ok_or(splatoon_server_rust::rmc::response::ErrorCode::Core_Exception)
|
||||||
}.to_tokens(tokens);
|
}.to_tokens(tokens);
|
||||||
} else {
|
} else {
|
||||||
quote!{
|
quote!{
|
||||||
crate::result::ResultExtension::display_err_or_some(
|
splatoon_server_rust::result::ResultExtension::display_err_or_some(
|
||||||
rmc_conn.make_raw_call_no_response(&message).await
|
rmc_conn.make_raw_call_no_response(&message).await
|
||||||
);
|
);
|
||||||
}.to_tokens(tokens);
|
}.to_tokens(tokens);
|
||||||
|
|
|
||||||
37
src/common.rs
Normal file
37
src/common.rs
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
use std::fs;
|
||||||
|
use std::fs::File;
|
||||||
|
use chrono::{Local, SecondsFormat};
|
||||||
|
use log::LevelFilter;
|
||||||
|
use simplelog::{ColorChoice, CombinedLogger, Config, TermLogger, TerminalMode, WriteLogger};
|
||||||
|
|
||||||
|
pub fn setup(){
|
||||||
|
CombinedLogger::init(vec![
|
||||||
|
TermLogger::new(
|
||||||
|
LevelFilter::Info,
|
||||||
|
Config::default(),
|
||||||
|
TerminalMode::Mixed,
|
||||||
|
ColorChoice::Auto,
|
||||||
|
),
|
||||||
|
WriteLogger::new(LevelFilter::max(), Config::default(), {
|
||||||
|
fs::create_dir_all("log").unwrap();
|
||||||
|
let date = Local::now().to_rfc3339_opts(SecondsFormat::Secs, false);
|
||||||
|
// this fixes windows being windows
|
||||||
|
let date = date.replace(":", "-");
|
||||||
|
let filename = format!("{}.log", date);
|
||||||
|
if cfg!(windows) {
|
||||||
|
File::create(format!("log\\{}", filename)).unwrap()
|
||||||
|
} else {
|
||||||
|
File::create(format!("log/{}", filename)).unwrap()
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
/*ctrlc::set_handler(||{
|
||||||
|
FORCE_EXIT.call_once_force(|_|{
|
||||||
|
println!("attempting exit");
|
||||||
|
});
|
||||||
|
}).unwrap();*/
|
||||||
|
|
||||||
|
dotenv::dotenv().ok();
|
||||||
|
}
|
||||||
58
src/executables/backend_server.rs
Normal file
58
src/executables/backend_server.rs
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
use log::error;
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use rustls::client::danger::HandshakeSignatureValid;
|
||||||
|
use rustls::pki_types::{CertificateDer, TrustAnchor, UnixTime};
|
||||||
|
use rustls::server::danger::{ClientCertVerified, ClientCertVerifier};
|
||||||
|
use rustls::server::{ClientCertVerifierBuilder, WebPkiClientVerifier};
|
||||||
|
use rustls::{
|
||||||
|
DigitallySignedStruct, DistinguishedName, Error, RootCertStore, ServerConfig, ServerConnection,
|
||||||
|
SignatureScheme,
|
||||||
|
};
|
||||||
|
use rustls_pki_types::PrivateKeyDer;
|
||||||
|
use splatoon_server_rust::common::setup;
|
||||||
|
use splatoon_server_rust::reggie::{get_configured_tls_acceptor, TestStruct, ROOT_TRUST_ANCHOR, SELF_CERT, SELF_KEY};
|
||||||
|
use std::borrow::ToOwned;
|
||||||
|
use std::fs;
|
||||||
|
use std::io::Cursor;
|
||||||
|
use std::net::{IpAddr, SocketAddr, SocketAddrV4};
|
||||||
|
use std::sync::Arc;
|
||||||
|
use macros::{method_id, rmc_proto, rmc_struct};
|
||||||
|
use tokio::io::AsyncReadExt;
|
||||||
|
use tokio::net::{TcpListener, TcpSocket};
|
||||||
|
use tokio::task;
|
||||||
|
use tokio_rustls::TlsAcceptor;
|
||||||
|
use splatoon_server_rust::define_rmc_proto;
|
||||||
|
use splatoon_server_rust::rmc::protocols::new_rmc_gateway_connection;
|
||||||
|
use splatoon_server_rust::rmc::response::ErrorCode;
|
||||||
|
use splatoon_server_rust::rmc::structures::RmcSerialize;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
setup();
|
||||||
|
|
||||||
|
let acceptor = get_configured_tls_acceptor().await;
|
||||||
|
|
||||||
|
let listen = TcpListener::bind("192.168.178.120:2376").await.unwrap();
|
||||||
|
|
||||||
|
while let Ok((stream, addr)) = listen.accept().await {
|
||||||
|
let mut stream = match acceptor.accept(stream).await {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(e) => {
|
||||||
|
error!("an error ocurred whilest accepting tls connection: {:?}", e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
task::spawn(async move {
|
||||||
|
new_rmc_gateway_connection(stream.into(), |_| {
|
||||||
|
Arc::new(TestStruct)
|
||||||
|
});
|
||||||
|
|
||||||
|
println!("lost connection lol");
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
131
src/executables/proxy_insecure.rs
Normal file
131
src/executables/proxy_insecure.rs
Normal file
|
|
@ -0,0 +1,131 @@
|
||||||
|
mod proxy_secure;
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
use std::ffi::CStr;
|
||||||
|
use std::io::{Read, Write};
|
||||||
|
use std::net::{Ipv4Addr, SocketAddrV4, TcpListener, TcpStream};
|
||||||
|
use bytemuck::{Pod, Zeroable};
|
||||||
|
use chacha20::{ChaCha20, Key};
|
||||||
|
use chacha20::cipher::{Iv, KeyIvInit, StreamCipher};
|
||||||
|
use log::error;
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use rsa::pkcs8::{DecodePrivateKey, DecodePublicKey, Document};
|
||||||
|
use rsa::{BigUint, Pkcs1v15Encrypt, RsaPrivateKey, RsaPublicKey};
|
||||||
|
use rsa::pkcs1::EncodeRsaPublicKey;
|
||||||
|
use rsa::pss::BlindedSigningKey;
|
||||||
|
use rsa::signature::{RandomizedSigner, SignatureEncoding};
|
||||||
|
use sha2::Sha256;
|
||||||
|
use tokio::net::TcpSocket;
|
||||||
|
use tokio::task;
|
||||||
|
use splatoon_server_rust::common::setup;
|
||||||
|
use splatoon_server_rust::prudp::packet::VirtualPort;
|
||||||
|
use splatoon_server_rust::prudp::router::Router;
|
||||||
|
use splatoon_server_rust::prudp::unsecure::Unsecure;
|
||||||
|
use splatoon_server_rust::reggie::{establish_tls_connection_to, UnitPacketRead, UnitPacketWrite};
|
||||||
|
use splatoon_server_rust::rmc::structures::RmcSerialize;
|
||||||
|
use splatoon_server_rust::rnex_proxy_common::ConnectionInitData;
|
||||||
|
|
||||||
|
static OWN_IP_PRIVATE: Lazy<Ipv4Addr> = Lazy::new(|| {
|
||||||
|
env::var("SERVER_IP")
|
||||||
|
.ok()
|
||||||
|
.and_then(|s| s.parse().ok())
|
||||||
|
.expect("no public ip specified")
|
||||||
|
});
|
||||||
|
|
||||||
|
static OWN_IP_PUBLIC: Lazy<String> =
|
||||||
|
Lazy::new(|| env::var("SERVER_IP_PUBLIC").unwrap_or(OWN_IP_PRIVATE.to_string()));
|
||||||
|
|
||||||
|
static SERVER_PORT: Lazy<u16> = Lazy::new(|| {
|
||||||
|
env::var("AUTH_SERVER_PORT")
|
||||||
|
.ok()
|
||||||
|
.and_then(|s| s.parse().ok())
|
||||||
|
.unwrap_or(10000)
|
||||||
|
});
|
||||||
|
|
||||||
|
static FORWARD_DESTINATION: Lazy<String> =
|
||||||
|
Lazy::new(|| env::var("FORWARD_DESTINATION").unwrap_or(OWN_IP_PRIVATE.to_string()));
|
||||||
|
|
||||||
|
static RSA_PRIVKEY: Lazy<RsaPrivateKey> = Lazy::new(|| {
|
||||||
|
let path = env::var("RSA_PRIVKEY")
|
||||||
|
.expect("RSA_PRIVKEY not set");
|
||||||
|
|
||||||
|
RsaPrivateKey::read_pkcs8_pem_file(&path)
|
||||||
|
.expect("unable to read private key")
|
||||||
|
});
|
||||||
|
|
||||||
|
static RSA_PUBKEY: Lazy<RsaPublicKey> = Lazy::new(|| {
|
||||||
|
RSA_PRIVKEY.to_public_key()
|
||||||
|
});
|
||||||
|
|
||||||
|
static PUBKEY_ENCODED: Lazy<Document> = Lazy::new(|| {
|
||||||
|
RSA_PUBKEY.to_pkcs1_der().expect("unable to convert pubkey to der")
|
||||||
|
});
|
||||||
|
|
||||||
|
static RSA_SIGNKEY: Lazy<BlindedSigningKey<Sha256>> = Lazy::new(||
|
||||||
|
BlindedSigningKey::<Sha256>::new(RSA_PRIVKEY.clone())
|
||||||
|
);
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
setup();
|
||||||
|
|
||||||
|
let (router_secure, _) = Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *SERVER_PORT))
|
||||||
|
.await
|
||||||
|
.expect("unable to start router");
|
||||||
|
|
||||||
|
let mut socket_secure = router_secure
|
||||||
|
.add_socket(VirtualPort::new(1, 10), Unsecure(
|
||||||
|
"6f599f81"
|
||||||
|
))
|
||||||
|
.await
|
||||||
|
.expect("unable to add socket");
|
||||||
|
|
||||||
|
// let conn = socket_secure.connect(auth_sockaddr).await.unwrap();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let Some(mut conn) = socket_secure.accept().await else {
|
||||||
|
error!("server crashed");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
task::spawn(async move {
|
||||||
|
let mut stream
|
||||||
|
= establish_tls_connection_to("192.168.178.120:2376", "account.spfn.net").await;
|
||||||
|
|
||||||
|
if let Err(e) = stream.send_buffer(&ConnectionInitData{
|
||||||
|
prudpsock_addr: conn.socket_addr
|
||||||
|
}.to_data()).await{
|
||||||
|
error!("error connecting to backend: {}", e);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
loop {
|
||||||
|
tokio::select! {
|
||||||
|
data = conn.recv() => {
|
||||||
|
let Some(data) = data else {
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Err(e) = stream.send_buffer(&data[..]).await{
|
||||||
|
error!("error sending data to backend: {}", e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data = stream.read_buffer() => {
|
||||||
|
let data = match data{
|
||||||
|
Ok(d) => d,
|
||||||
|
Err(e) => {
|
||||||
|
error!("error reveiving data from backend: {}", e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if conn.send(data).await == None{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
26
src/executables/proxy_secure.rs
Normal file
26
src/executables/proxy_secure.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
use splatoon_server_rust::reggie::RemoteRmcTestProto;
|
||||||
|
use std::fs;
|
||||||
|
use std::net::IpAddr;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use rustls::ClientConfig;
|
||||||
|
use rustls_pki_types::ServerName;
|
||||||
|
use tokio::io::AsyncWriteExt;
|
||||||
|
use tokio::net::TcpStream;
|
||||||
|
use tokio_rustls::{TlsConnector, TlsStream};
|
||||||
|
use splatoon_server_rust::common::setup;
|
||||||
|
use splatoon_server_rust::reggie::{establish_tls_connection_to, get_configured_tls_connector, RemoteTestProto, UnitPacketWrite};
|
||||||
|
use splatoon_server_rust::rmc::protocols::{new_rmc_gateway_connection, OnlyRemote};
|
||||||
|
use splatoon_server_rust::rmc::structures::RmcSerialize;
|
||||||
|
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main(){
|
||||||
|
setup();
|
||||||
|
|
||||||
|
let mut stream
|
||||||
|
= establish_tls_connection_to("192.168.178.120:2376", "account.spfn.net").await;
|
||||||
|
|
||||||
|
let remo = new_rmc_gateway_connection(stream.into(), |r| Arc::new(OnlyRemote::<RemoteTestProto>::new(r)) );
|
||||||
|
|
||||||
|
println!("{:?}", remo.test().await);
|
||||||
|
}
|
||||||
22
src/lib.rs
22
src/lib.rs
|
|
@ -1,11 +1,17 @@
|
||||||
mod endianness;
|
extern crate self as splatoon_server_rust;
|
||||||
mod prudp;
|
|
||||||
|
pub mod endianness;
|
||||||
|
pub mod prudp;
|
||||||
pub mod rmc;
|
pub mod rmc;
|
||||||
//mod protocols;
|
//mod protocols;
|
||||||
|
|
||||||
mod grpc;
|
pub mod grpc;
|
||||||
mod kerberos;
|
pub mod kerberos;
|
||||||
mod nex;
|
pub mod nex;
|
||||||
mod result;
|
pub mod result;
|
||||||
mod versions;
|
pub mod versions;
|
||||||
mod web;
|
pub mod web;
|
||||||
|
pub mod common;
|
||||||
|
pub mod reggie;
|
||||||
|
pub mod rnex_proxy_common;
|
||||||
|
pub mod util;
|
||||||
|
|
|
||||||
11
src/main.rs
11
src/main.rs
|
|
@ -7,6 +7,8 @@
|
||||||
//! also the first and only current usage of rnex, expect this and rnex to be split into seperate
|
//! also the first and only current usage of rnex, expect this and rnex to be split into seperate
|
||||||
//! repos soon.
|
//! repos soon.
|
||||||
|
|
||||||
|
extern crate self as splatoon_server_rust;
|
||||||
|
|
||||||
use crate::nex::account::Account;
|
use crate::nex::account::Account;
|
||||||
use crate::nex::auth_handler::{AuthHandler, RemoteAuthClientProtocol};
|
use crate::nex::auth_handler::{AuthHandler, RemoteAuthClientProtocol};
|
||||||
use crate::nex::remote_console::RemoteConsole;
|
use crate::nex::remote_console::RemoteConsole;
|
||||||
|
|
@ -59,6 +61,10 @@ mod nex;
|
||||||
mod result;
|
mod result;
|
||||||
mod versions;
|
mod versions;
|
||||||
mod web;
|
mod web;
|
||||||
|
pub mod reggie;
|
||||||
|
pub mod util;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static KERBEROS_SERVER_PASSWORD: Lazy<String> = Lazy::new(|| {
|
static KERBEROS_SERVER_PASSWORD: Lazy<String> = Lazy::new(|| {
|
||||||
env::var("AUTH_SERVER_PASSWORD")
|
env::var("AUTH_SERVER_PASSWORD")
|
||||||
|
|
@ -135,7 +141,7 @@ async fn main() {
|
||||||
|
|
||||||
dotenv::dotenv().ok();
|
dotenv::dotenv().ok();
|
||||||
|
|
||||||
start_servers().await;
|
//start_servers().await;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
|
@ -278,7 +284,7 @@ async fn start_secure_server() -> SecureServer{
|
||||||
socket,
|
socket,
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
/*
|
||||||
async fn start_auth() -> JoinHandle<()> {
|
async fn start_auth() -> JoinHandle<()> {
|
||||||
tokio::spawn(async {
|
tokio::spawn(async {
|
||||||
let (router_secure, _) = Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *AUTH_SERVER_PORT))
|
let (router_secure, _) = Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *AUTH_SERVER_PORT))
|
||||||
|
|
@ -414,3 +420,4 @@ async fn start_servers() {
|
||||||
#[cfg(feature = "secure")]
|
#[cfg(feature = "secure")]
|
||||||
secure_server.await.expect("auth server crashed");
|
secure_server.await.expect("auth server crashed");
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
@ -144,7 +144,7 @@ impl Debug for VirtualPort {
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone, Pod, Zeroable, SwapEndian, Eq, PartialEq)]
|
#[derive(Debug, Copy, Clone, Pod, Zeroable, SwapEndian, Eq, PartialEq)]
|
||||||
pub struct PRUDPHeader {
|
pub struct PRUDPV1Header {
|
||||||
pub magic: [u8; 2],
|
pub magic: [u8; 2],
|
||||||
pub version: u8,
|
pub version: u8,
|
||||||
pub packet_specific_size: u8,
|
pub packet_specific_size: u8,
|
||||||
|
|
@ -157,7 +157,7 @@ pub struct PRUDPHeader {
|
||||||
pub sequence_id: u16,
|
pub sequence_id: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for PRUDPHeader{
|
impl Default for PRUDPV1Header {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self{
|
Self{
|
||||||
magic: [0xEA, 0xD0],
|
magic: [0xEA, 0xD0],
|
||||||
|
|
@ -239,8 +239,8 @@ impl PacketOption{
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Eq, PartialEq)]
|
#[derive(Debug, Default, Clone, Eq, PartialEq)]
|
||||||
pub struct PRUDPPacket {
|
pub struct PRUDPV1Packet {
|
||||||
pub header: PRUDPHeader,
|
pub header: PRUDPV1Header,
|
||||||
pub packet_signature: [u8; 16],
|
pub packet_signature: [u8; 16],
|
||||||
pub payload: Vec<u8>,
|
pub payload: Vec<u8>,
|
||||||
pub options: Vec<PacketOption>,
|
pub options: Vec<PacketOption>,
|
||||||
|
|
@ -277,9 +277,9 @@ impl Into<u8> for OptionId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PRUDPPacket {
|
impl PRUDPV1Packet {
|
||||||
pub fn new(reader: &mut (impl Read + Seek)) -> Result<Self> {
|
pub fn new(reader: &mut (impl Read + Seek)) -> Result<Self> {
|
||||||
let header: PRUDPHeader = reader.read_struct(IS_BIG_ENDIAN)?;
|
let header: PRUDPV1Header = reader.read_struct(IS_BIG_ENDIAN)?;
|
||||||
|
|
||||||
if header.magic[0] != 0xEA ||
|
if header.magic[0] != 0xEA ||
|
||||||
header.magic[1] != 0xD0 {
|
header.magic[1] != 0xD0 {
|
||||||
|
|
@ -372,7 +372,7 @@ impl PRUDPPacket {
|
||||||
|
|
||||||
|
|
||||||
Self{
|
Self{
|
||||||
header: PRUDPHeader{
|
header: PRUDPV1Header {
|
||||||
types_and_flags: flags,
|
types_and_flags: flags,
|
||||||
sequence_id: self.header.sequence_id,
|
sequence_id: self.header.sequence_id,
|
||||||
substream_id: self.header.substream_id,
|
substream_id: self.header.substream_id,
|
||||||
|
|
@ -444,7 +444,7 @@ impl PRUDPPacket {
|
||||||
|
|
||||||
pub fn base_response_packet(&self) -> Self {
|
pub fn base_response_packet(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
header: PRUDPHeader {
|
header: PRUDPV1Header {
|
||||||
magic: [0xEA, 0xD0],
|
magic: [0xEA, 0xD0],
|
||||||
types_and_flags: TypesFlags(0),
|
types_and_flags: TypesFlags(0),
|
||||||
destination_port: self.header.source_port,
|
destination_port: self.header.source_port,
|
||||||
|
|
@ -481,10 +481,10 @@ impl PRUDPPacket {
|
||||||
mod test {
|
mod test {
|
||||||
use crate::prudp::packet::flags::{NEED_ACK, RELIABLE};
|
use crate::prudp::packet::flags::{NEED_ACK, RELIABLE};
|
||||||
use crate::prudp::packet::types::DATA;
|
use crate::prudp::packet::types::DATA;
|
||||||
use super::{OptionId, PacketOption, PRUDPHeader, TypesFlags, VirtualPort};
|
use super::{OptionId, PacketOption, PRUDPV1Header, TypesFlags, VirtualPort};
|
||||||
#[test]
|
#[test]
|
||||||
fn size_test() {
|
fn size_test() {
|
||||||
assert_eq!(size_of::<PRUDPHeader>(), 14);
|
assert_eq!(size_of::<PRUDPV1Header>(), 14);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -511,7 +511,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn header_read(){
|
fn header_read(){
|
||||||
let header = PRUDPHeader{
|
let header = PRUDPV1Header {
|
||||||
version: 0,
|
version: 0,
|
||||||
destination_port: VirtualPort(0),
|
destination_port: VirtualPort(0),
|
||||||
substream_id: 0,
|
substream_id: 0,
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ use tokio::select;
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
use crate::prudp::socket::{new_socket_pair, AnyInternalSocket, CryptoHandler, ExternalSocket};
|
use crate::prudp::socket::{new_socket_pair, AnyInternalSocket, CryptoHandler, ExternalSocket};
|
||||||
use crate::prudp::packet::{PRUDPPacket, VirtualPort};
|
use crate::prudp::packet::{PRUDPV1Packet, VirtualPort};
|
||||||
use crate::prudp::router::Error::VirtualPortTaken;
|
use crate::prudp::router::Error::VirtualPortTaken;
|
||||||
|
|
||||||
static SERVER_DATAGRAMS: Lazy<u8> = Lazy::new(||{
|
static SERVER_DATAGRAMS: Lazy<u8> = Lazy::new(||{
|
||||||
|
|
@ -31,6 +31,7 @@ pub struct Router {
|
||||||
socket: Arc<UdpSocket>,
|
socket: Arc<UdpSocket>,
|
||||||
_no_outside_construction: PhantomData<()>
|
_no_outside_construction: PhantomData<()>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum Error{
|
pub enum Error{
|
||||||
#[error("tried to register socket to a port which is already taken (port: {0})")]
|
#[error("tried to register socket to a port which is already taken (port: {0})")]
|
||||||
|
|
@ -43,7 +44,7 @@ impl Router {
|
||||||
let mut stream = Cursor::new(&udp_message);
|
let mut stream = Cursor::new(&udp_message);
|
||||||
|
|
||||||
while stream.position() as usize != udp_message.len() {
|
while stream.position() as usize != udp_message.len() {
|
||||||
let packet = match PRUDPPacket::new(&mut stream){
|
let packet = match PRUDPV1Packet::new(&mut stream){
|
||||||
Ok(p) => p,
|
Ok(p) => p,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Somebody({}) is fucking with the servers or their connection is bad (reason: {})", addr, e);
|
error!("Somebody({}) is fucking with the servers or their connection is bad (reason: {})", addr, e);
|
||||||
|
|
@ -155,7 +156,7 @@ impl Router {
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns Some(()) i
|
// returns Some(()) i
|
||||||
pub(crate) async fn add_socket<E: CryptoHandler>(&self, virtual_port: VirtualPort, encryption: E)
|
pub async fn add_socket<E: CryptoHandler>(&self, virtual_port: VirtualPort, encryption: E)
|
||||||
-> Result<ExternalSocket, Error>{
|
-> Result<ExternalSocket, Error>{
|
||||||
let mut endpoints = self.endpoints.write().await;
|
let mut endpoints = self.endpoints.write().await;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use typenum::U5;
|
||||||
use crate::endianness::{IS_BIG_ENDIAN, ReadExtensions};
|
use crate::endianness::{IS_BIG_ENDIAN, ReadExtensions};
|
||||||
use crate::kerberos::{derive_key, TicketInternalData};
|
use crate::kerberos::{derive_key, TicketInternalData};
|
||||||
use crate::nex::account::Account;
|
use crate::nex::account::Account;
|
||||||
use crate::prudp::packet::PRUDPPacket;
|
use crate::prudp::packet::PRUDPV1Packet;
|
||||||
use crate::prudp::socket::{CryptoHandler, CryptoHandlerConnectionInstance, EncryptionPair};
|
use crate::prudp::socket::{CryptoHandler, CryptoHandlerConnectionInstance, EncryptionPair};
|
||||||
use crate::prudp::unsecure::UnsecureInstance;
|
use crate::prudp::unsecure::UnsecureInstance;
|
||||||
use crate::rmc::structures::RmcSerialize;
|
use crate::rmc::structures::RmcSerialize;
|
||||||
|
|
@ -150,7 +150,7 @@ impl CryptoHandler for Secure {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign_pre_handshake(&self, packet: &mut PRUDPPacket) {
|
fn sign_pre_handshake(&self, packet: &mut PRUDPV1Packet) {
|
||||||
packet.set_sizes();
|
packet.set_sizes();
|
||||||
packet.calculate_and_assign_signature(self.0, None, None);
|
packet.calculate_and_assign_signature(self.0, None, None);
|
||||||
}
|
}
|
||||||
|
|
@ -176,17 +176,17 @@ impl CryptoHandlerConnectionInstance for SecureInstance {
|
||||||
self.pid
|
self.pid
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign_connect(&self, packet: &mut PRUDPPacket) {
|
fn sign_connect(&self, packet: &mut PRUDPV1Packet) {
|
||||||
packet.set_sizes();
|
packet.set_sizes();
|
||||||
packet.calculate_and_assign_signature(self.access_key, None, Some(self.self_signature));
|
packet.calculate_and_assign_signature(self.access_key, None, Some(self.self_signature));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign_packet(&self, packet: &mut PRUDPPacket) {
|
fn sign_packet(&self, packet: &mut PRUDPV1Packet) {
|
||||||
packet.set_sizes();
|
packet.set_sizes();
|
||||||
packet.calculate_and_assign_signature(self.access_key, Some(self.session_key), Some(self.self_signature));
|
packet.calculate_and_assign_signature(self.access_key, Some(self.session_key), Some(self.self_signature));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_packet(&self, packet: &PRUDPPacket) -> bool {
|
fn verify_packet(&self, packet: &PRUDPV1Packet) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::net::SocketAddrV4;
|
use std::net::SocketAddrV4;
|
||||||
use hmac::{Hmac, Mac};
|
use hmac::{Hmac, Mac};
|
||||||
|
use macros::RmcSerialize;
|
||||||
use crate::prudp::packet::VirtualPort;
|
use crate::prudp::packet::VirtualPort;
|
||||||
|
|
||||||
type Md5Hmac = Hmac<md5::Md5>;
|
type Md5Hmac = Hmac<md5::Md5>;
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Hash, Debug, Copy, Clone, Ord, PartialOrd)]
|
#[derive(Eq, PartialEq, Hash, Debug, Copy, Clone, Ord, PartialOrd, RmcSerialize)]
|
||||||
|
#[rmc_struct(0)]
|
||||||
pub struct PRUDPSockAddr{
|
pub struct PRUDPSockAddr{
|
||||||
pub regular_socket_addr: SocketAddrV4,
|
pub regular_socket_addr: SocketAddrV4,
|
||||||
pub virtual_port: VirtualPort
|
pub virtual_port: VirtualPort
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use crate::prudp::packet::types::{CONNECT, DATA, DISCONNECT, PING, SYN};
|
||||||
use crate::prudp::packet::PacketOption::{
|
use crate::prudp::packet::PacketOption::{
|
||||||
ConnectionSignature, FragmentId, InitialSequenceId, MaximumSubstreamId, SupportedFunctions,
|
ConnectionSignature, FragmentId, InitialSequenceId, MaximumSubstreamId, SupportedFunctions,
|
||||||
};
|
};
|
||||||
use crate::prudp::packet::{PRUDPHeader, PRUDPPacket, PacketOption, TypesFlags, VirtualPort};
|
use crate::prudp::packet::{PRUDPV1Header, PRUDPV1Packet, PacketOption, TypesFlags, VirtualPort};
|
||||||
use crate::prudp::router::{Error, Router};
|
use crate::prudp::router::{Error, Router};
|
||||||
use crate::prudp::sockaddr::PRUDPSockAddr;
|
use crate::prudp::sockaddr::PRUDPSockAddr;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|
@ -67,7 +67,7 @@ struct InternalConnection<E: CryptoHandlerConnectionInstance> {
|
||||||
crypto_handler_instance: E,
|
crypto_handler_instance: E,
|
||||||
data_sender: Sender<Vec<u8>>,
|
data_sender: Sender<Vec<u8>>,
|
||||||
socket: Arc<UdpSocket>,
|
socket: Arc<UdpSocket>,
|
||||||
packet_queue: HashMap<u16, PRUDPPacket>,
|
packet_queue: HashMap<u16, PRUDPV1Packet>,
|
||||||
last_packet_time: Instant,
|
last_packet_time: Instant,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,7 +88,7 @@ impl<E: CryptoHandlerConnectionInstance> InternalConnection<E> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
async fn send_raw_packet(&self, mut prudp_packet: PRUDPPacket) {
|
async fn send_raw_packet(&self, mut prudp_packet: PRUDPV1Packet) {
|
||||||
prudp_packet.set_sizes();
|
prudp_packet.set_sizes();
|
||||||
|
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
|
|
@ -128,7 +128,7 @@ pub(super) struct InternalSocket<T: CryptoHandler> {
|
||||||
internal_connections: Arc<
|
internal_connections: Arc<
|
||||||
Mutex<BTreeMap<PRUDPSockAddr, Arc<Mutex<InternalConnection<T::CryptoConnectionInstance>>>>>,
|
Mutex<BTreeMap<PRUDPSockAddr, Arc<Mutex<InternalConnection<T::CryptoConnectionInstance>>>>>,
|
||||||
>,
|
>,
|
||||||
connection_establishment_data_sender: Mutex<Option<Sender<PRUDPPacket>>>,
|
connection_establishment_data_sender: Mutex<Option<Sender<PRUDPV1Packet>>>,
|
||||||
connection_sender: Sender<ExternalConnection>,
|
connection_sender: Sender<ExternalConnection>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,7 +170,7 @@ impl<T: CryptoHandler> Deref for InternalSocket<T> {
|
||||||
pub(super) trait AnyInternalSocket:
|
pub(super) trait AnyInternalSocket:
|
||||||
Send + Sync + Deref<Target = CommonSocket> + 'static
|
Send + Sync + Deref<Target = CommonSocket> + 'static
|
||||||
{
|
{
|
||||||
async fn receive_packet(&self, address: PRUDPSockAddr, packet: PRUDPPacket);
|
async fn receive_packet(&self, address: PRUDPSockAddr, packet: PRUDPV1Packet);
|
||||||
async fn connect(&self, address: PRUDPSockAddr) -> Option<()>;
|
async fn connect(&self, address: PRUDPSockAddr) -> Option<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -186,8 +186,8 @@ pub(super) trait AnyInternalConnection:
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<T: CryptoHandlerConnectionInstance> AnyInternalConnection for InternalConnection<T> {
|
impl<T: CryptoHandlerConnectionInstance> AnyInternalConnection for InternalConnection<T> {
|
||||||
async fn send_data_packet(&mut self, data: Vec<u8>) {
|
async fn send_data_packet(&mut self, data: Vec<u8>) {
|
||||||
let mut packet = PRUDPPacket {
|
let mut packet = PRUDPV1Packet {
|
||||||
header: PRUDPHeader {
|
header: PRUDPV1Header {
|
||||||
sequence_id: self.next_server_count(),
|
sequence_id: self.next_server_count(),
|
||||||
substream_id: 0,
|
substream_id: 0,
|
||||||
session_id: self.session_id,
|
session_id: self.session_id,
|
||||||
|
|
@ -214,8 +214,8 @@ impl<T: CryptoHandlerConnectionInstance> AnyInternalConnection for InternalConne
|
||||||
async fn close_connection(&mut self) {
|
async fn close_connection(&mut self) {
|
||||||
// jon confirmed that this should be a safe way to dc a client
|
// jon confirmed that this should be a safe way to dc a client
|
||||||
|
|
||||||
let mut packet = PRUDPPacket {
|
let mut packet = PRUDPV1Packet {
|
||||||
header: PRUDPHeader {
|
header: PRUDPV1Header {
|
||||||
sequence_id: self.next_server_count(),
|
sequence_id: self.next_server_count(),
|
||||||
substream_id: 0,
|
substream_id: 0,
|
||||||
session_id: self.session_id,
|
session_id: self.session_id,
|
||||||
|
|
@ -269,7 +269,7 @@ impl<T: CryptoHandler> InternalSocket<T> {
|
||||||
Some(conn)
|
Some(conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_packet_unbuffered(&self, dest: PRUDPSockAddr, mut packet: PRUDPPacket) {
|
async fn send_packet_unbuffered(&self, dest: PRUDPSockAddr, mut packet: PRUDPV1Packet) {
|
||||||
packet.set_sizes();
|
packet.set_sizes();
|
||||||
|
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
|
|
@ -284,7 +284,7 @@ impl<T: CryptoHandler> InternalSocket<T> {
|
||||||
.expect("failed to send data back");
|
.expect("failed to send data back");
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_syn(&self, address: PRUDPSockAddr, packet: PRUDPPacket) {
|
async fn handle_syn(&self, address: PRUDPSockAddr, packet: PRUDPV1Packet) {
|
||||||
info!("got syn");
|
info!("got syn");
|
||||||
|
|
||||||
let mut response = packet.base_response_packet();
|
let mut response = packet.base_response_packet();
|
||||||
|
|
@ -328,8 +328,8 @@ impl<T: CryptoHandler> InternalSocket<T> {
|
||||||
let mut conn = conn.lock().await;
|
let mut conn = conn.lock().await;
|
||||||
|
|
||||||
if conn.last_packet_time < (Instant::now() - Duration::from_secs(5)) {
|
if conn.last_packet_time < (Instant::now() - Duration::from_secs(5)) {
|
||||||
conn.send_raw_packet(PRUDPPacket {
|
conn.send_raw_packet(PRUDPV1Packet {
|
||||||
header: PRUDPHeader {
|
header: PRUDPV1Header {
|
||||||
sequence_id: 0,
|
sequence_id: 0,
|
||||||
substream_id: 0,
|
substream_id: 0,
|
||||||
session_id: 0,
|
session_id: 0,
|
||||||
|
|
@ -408,7 +408,7 @@ impl<T: CryptoHandler> InternalSocket<T> {
|
||||||
.expect("connection to external socket lost");
|
.expect("connection to external socket lost");
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_connect(&self, address: PRUDPSockAddr, packet: PRUDPPacket) {
|
async fn handle_connect(&self, address: PRUDPSockAddr, packet: PRUDPV1Packet) {
|
||||||
info!("got connect");
|
info!("got connect");
|
||||||
let Some(MaximumSubstreamId(max_substream)) = packet
|
let Some(MaximumSubstreamId(max_substream)) = packet
|
||||||
.options
|
.options
|
||||||
|
|
@ -479,7 +479,7 @@ impl<T: CryptoHandler> InternalSocket<T> {
|
||||||
self.send_packet_unbuffered(address, response).await;
|
self.send_packet_unbuffered(address, response).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_data(&self, address: PRUDPSockAddr, mut packet: PRUDPPacket) {
|
async fn handle_data(&self, address: PRUDPSockAddr, mut packet: PRUDPV1Packet) {
|
||||||
info!("got data");
|
info!("got data");
|
||||||
|
|
||||||
if packet.header.types_and_flags.get_flags() & (NEED_ACK | RELIABLE)
|
if packet.header.types_and_flags.get_flags() & (NEED_ACK | RELIABLE)
|
||||||
|
|
@ -524,7 +524,7 @@ impl<T: CryptoHandler> InternalSocket<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_ping(&self, address: PRUDPSockAddr, packet: PRUDPPacket) {
|
async fn handle_ping(&self, address: PRUDPSockAddr, packet: PRUDPV1Packet) {
|
||||||
let connections = self.internal_connections.lock().await;
|
let connections = self.internal_connections.lock().await;
|
||||||
let Some(conn) = connections.get(&address) else {
|
let Some(conn) = connections.get(&address) else {
|
||||||
error!("tried to send data on inactive connection!");
|
error!("tried to send data on inactive connection!");
|
||||||
|
|
@ -544,7 +544,7 @@ impl<T: CryptoHandler> InternalSocket<T> {
|
||||||
self.send_packet_unbuffered(address, response).await;
|
self.send_packet_unbuffered(address, response).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_disconnect(&self, address: PRUDPSockAddr, packet: PRUDPPacket) {
|
async fn handle_disconnect(&self, address: PRUDPSockAddr, packet: PRUDPV1Packet) {
|
||||||
let connections = self.internal_connections.lock().await;
|
let connections = self.internal_connections.lock().await;
|
||||||
let Some(conn) = connections.get(&address) else {
|
let Some(conn) = connections.get(&address) else {
|
||||||
error!("tried to send data on inactive connection!");
|
error!("tried to send data on inactive connection!");
|
||||||
|
|
@ -571,7 +571,7 @@ impl<T: CryptoHandler> InternalSocket<T> {
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<T: CryptoHandler> AnyInternalSocket for InternalSocket<T> {
|
impl<T: CryptoHandler> AnyInternalSocket for InternalSocket<T> {
|
||||||
async fn receive_packet(&self, address: PRUDPSockAddr, packet: PRUDPPacket) {
|
async fn receive_packet(&self, address: PRUDPSockAddr, packet: PRUDPV1Packet) {
|
||||||
// todo: handle acks and resending
|
// todo: handle acks and resending
|
||||||
|
|
||||||
if let Some(conn) = self.get_connection(address).await {
|
if let Some(conn) = self.get_connection(address).await {
|
||||||
|
|
@ -643,8 +643,8 @@ impl<T: CryptoHandler> AnyInternalSocket for InternalSocket<T> {
|
||||||
|
|
||||||
let remote_signature = address.calculate_connection_signature();
|
let remote_signature = address.calculate_connection_signature();
|
||||||
|
|
||||||
let packet = PRUDPPacket {
|
let packet = PRUDPV1Packet {
|
||||||
header: PRUDPHeader {
|
header: PRUDPV1Header {
|
||||||
source_port: self.virtual_port,
|
source_port: self.virtual_port,
|
||||||
destination_port: address.virtual_port,
|
destination_port: address.virtual_port,
|
||||||
types_and_flags: TypesFlags::default().types(SYN).flags(NEED_ACK),
|
types_and_flags: TypesFlags::default().types(SYN).flags(NEED_ACK),
|
||||||
|
|
@ -674,8 +674,8 @@ impl<T: CryptoHandler> AnyInternalSocket for InternalSocket<T> {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
let packet = PRUDPPacket {
|
let packet = PRUDPV1Packet {
|
||||||
header: PRUDPHeader {
|
header: PRUDPV1Header {
|
||||||
source_port: self.virtual_port,
|
source_port: self.virtual_port,
|
||||||
destination_port: address.virtual_port,
|
destination_port: address.virtual_port,
|
||||||
types_and_flags: TypesFlags::default().types(CONNECT).flags(NEED_ACK),
|
types_and_flags: TypesFlags::default().types(CONNECT).flags(NEED_ACK),
|
||||||
|
|
@ -746,9 +746,9 @@ pub trait CryptoHandlerConnectionInstance: Send + Sync + 'static {
|
||||||
fn encrypt_outgoing(&mut self, substream: u8, data: &mut [u8]);
|
fn encrypt_outgoing(&mut self, substream: u8, data: &mut [u8]);
|
||||||
|
|
||||||
fn get_user_id(&self) -> u32;
|
fn get_user_id(&self) -> u32;
|
||||||
fn sign_connect(&self, packet: &mut PRUDPPacket);
|
fn sign_connect(&self, packet: &mut PRUDPV1Packet);
|
||||||
fn sign_packet(&self, packet: &mut PRUDPPacket);
|
fn sign_packet(&self, packet: &mut PRUDPV1Packet);
|
||||||
fn verify_packet(&self, packet: &PRUDPPacket) -> bool;
|
fn verify_packet(&self, packet: &PRUDPV1Packet) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait CryptoHandler: Send + Sync + 'static {
|
pub trait CryptoHandler: Send + Sync + 'static {
|
||||||
|
|
@ -762,7 +762,7 @@ pub trait CryptoHandler: Send + Sync + 'static {
|
||||||
substream_count: u8,
|
substream_count: u8,
|
||||||
) -> Option<(Vec<u8>, Self::CryptoConnectionInstance)>;
|
) -> Option<(Vec<u8>, Self::CryptoConnectionInstance)>;
|
||||||
|
|
||||||
fn sign_pre_handshake(&self, packet: &mut PRUDPPacket);
|
fn sign_pre_handshake(&self, packet: &mut PRUDPV1Packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for ExternalConnection {
|
impl Deref for ExternalConnection {
|
||||||
|
|
@ -813,6 +813,12 @@ impl SendingConnection {
|
||||||
|
|
||||||
impl<E: CryptoHandlerConnectionInstance> Drop for InternalConnection<E> {
|
impl<E: CryptoHandlerConnectionInstance> Drop for InternalConnection<E> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
println!("yatta");
|
println!("yatta(internal conn)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for CommonConnection {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
println!("yatta(common conn)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use rc4::{Key, KeyInit, Rc4, StreamCipher};
|
use rc4::{Key, KeyInit, Rc4, StreamCipher};
|
||||||
use typenum::U5;
|
use typenum::U5;
|
||||||
use crate::prudp::packet::PRUDPPacket;
|
use crate::prudp::packet::PRUDPV1Packet;
|
||||||
use crate::prudp::socket::{CryptoHandler, CryptoHandlerConnectionInstance, EncryptionPair};
|
use crate::prudp::socket::{CryptoHandler, CryptoHandlerConnectionInstance, EncryptionPair};
|
||||||
|
|
||||||
pub struct Unsecure(pub &'static str);
|
pub struct Unsecure(pub &'static str);
|
||||||
|
|
@ -43,7 +43,7 @@ impl CryptoHandler for Unsecure {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign_pre_handshake(&self, packet: &mut PRUDPPacket) {
|
fn sign_pre_handshake(&self, packet: &mut PRUDPV1Packet) {
|
||||||
packet.set_sizes();
|
packet.set_sizes();
|
||||||
packet.calculate_and_assign_signature(self.0, None, None);
|
packet.calculate_and_assign_signature(self.0, None, None);
|
||||||
}
|
}
|
||||||
|
|
@ -68,17 +68,17 @@ impl CryptoHandlerConnectionInstance for UnsecureInstance {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign_connect(&self, packet: &mut PRUDPPacket) {
|
fn sign_connect(&self, packet: &mut PRUDPV1Packet) {
|
||||||
packet.set_sizes();
|
packet.set_sizes();
|
||||||
packet.calculate_and_assign_signature(self.key, None, Some(self.self_signature));
|
packet.calculate_and_assign_signature(self.key, None, Some(self.self_signature));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign_packet(&self, packet: &mut PRUDPPacket) {
|
fn sign_packet(&self, packet: &mut PRUDPV1Packet) {
|
||||||
packet.set_sizes();
|
packet.set_sizes();
|
||||||
packet.calculate_and_assign_signature(self.key, None, Some(self.self_signature));
|
packet.calculate_and_assign_signature(self.key, None, Some(self.self_signature));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_packet(&self, packet: &PRUDPPacket) -> bool {
|
fn verify_packet(&self, packet: &PRUDPV1Packet) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
144
src/reggie.rs
Normal file
144
src/reggie.rs
Normal file
|
|
@ -0,0 +1,144 @@
|
||||||
|
use std::{fs, io};
|
||||||
|
use std::sync::Arc;
|
||||||
|
use macros::{method_id, rmc_proto, rmc_struct};
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use rustls::{ClientConfig, RootCertStore, ServerConfig};
|
||||||
|
use rustls::client::WebPkiServerVerifier;
|
||||||
|
use rustls::server::WebPkiClientVerifier;
|
||||||
|
use rustls_pki_types::{CertificateDer, PrivateKeyDer, ServerName, TrustAnchor};
|
||||||
|
use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
|
||||||
|
use tokio::net::TcpStream;
|
||||||
|
use tokio_rustls::{TlsAcceptor, TlsConnector};
|
||||||
|
use tokio_rustls::client::TlsStream;
|
||||||
|
use webpki::anchor_from_trusted_cert;
|
||||||
|
use crate::define_rmc_proto;
|
||||||
|
use crate::endianness::IS_BIG_ENDIAN;
|
||||||
|
use crate::rmc::response::ErrorCode;
|
||||||
|
use crate::rmc::structures::RmcSerialize;
|
||||||
|
|
||||||
|
pub static SELF_CERT: Lazy<CertificateDer<'static>> = Lazy::new(|| CertificateDer::from(fs::read("/opt/reggie/certs/SELF.crt").expect("failed to read self cpub ertificate")));
|
||||||
|
pub static ROOT_CA: Lazy<CertificateDer<'static>> = Lazy::new(|| CertificateDer::from(fs::read("/opt/reggie/certs/CA.crt").expect("failed to read root certipub ficate")));
|
||||||
|
pub static SELF_KEY: Lazy<PrivateKeyDer<'static>> = Lazy::new(|| PrivateKeyDer::try_from(fs::read("/opt/reggie/certs/SELF.key").expect("failed to read self pub key")).expect("failed to read self key"));
|
||||||
|
pub static ROOT_TRUST_ANCHOR: Lazy<TrustAnchor<'static>> = Lazy::new(|| anchor_from_trusted_cert(&*ROOT_CA).expect("unable to create root ca trust anchor"));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pub fn get_root_store() -> RootCertStore {
|
||||||
|
RootCertStore {
|
||||||
|
roots: vec![
|
||||||
|
ROOT_TRUST_ANCHOR.clone()
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_root_cert_verifier() -> RootCertStore {
|
||||||
|
RootCertStore {
|
||||||
|
roots: vec![
|
||||||
|
ROOT_TRUST_ANCHOR.clone()
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub async fn get_configured_tls_acceptor() -> TlsAcceptor{
|
||||||
|
let store = get_root_store();
|
||||||
|
|
||||||
|
let cert_verifier = WebPkiClientVerifier::builder(store.into())
|
||||||
|
.build()
|
||||||
|
.expect("unable to build cert verifier");
|
||||||
|
|
||||||
|
let config = ServerConfig::builder()
|
||||||
|
//.with_no_client_auth()
|
||||||
|
.with_client_cert_verifier(cert_verifier)
|
||||||
|
.with_single_cert(vec![
|
||||||
|
SELF_CERT.clone(),
|
||||||
|
ROOT_CA.clone()
|
||||||
|
], SELF_KEY.clone_key())
|
||||||
|
.expect("unable to create server config");
|
||||||
|
|
||||||
|
TlsAcceptor::from(Arc::new(config))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_configured_tls_connector() -> TlsConnector{
|
||||||
|
let store = get_root_store();
|
||||||
|
|
||||||
|
let cert_verifier = WebPkiServerVerifier::builder(store.into())
|
||||||
|
.build()
|
||||||
|
.expect("unable to build cert verifier");
|
||||||
|
|
||||||
|
let config = ClientConfig::builder()
|
||||||
|
//.with_root_certificates(get_root_store())
|
||||||
|
.with_webpki_verifier(cert_verifier)
|
||||||
|
.with_client_auth_cert(vec![
|
||||||
|
SELF_CERT.clone(),
|
||||||
|
ROOT_CA.clone()
|
||||||
|
], SELF_KEY.clone_key())
|
||||||
|
.expect("unable to create client config");
|
||||||
|
|
||||||
|
|
||||||
|
TlsConnector::from(Arc::new(config))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait UnitPacketRead: AsyncRead + Unpin{
|
||||||
|
async fn read_buffer(&mut self) -> Result<Vec<u8>, io::Error>{
|
||||||
|
let mut len_raw: [u8; 4] = [0; 4];
|
||||||
|
|
||||||
|
self.read_exact(&mut len_raw).await?;
|
||||||
|
|
||||||
|
let len = u32::from_le_bytes(len_raw);
|
||||||
|
|
||||||
|
let mut vec = vec![0u8; len as _];
|
||||||
|
|
||||||
|
self.read_exact(&mut vec).await?;
|
||||||
|
|
||||||
|
Ok(vec)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: AsyncRead + Unpin> UnitPacketRead for T{}
|
||||||
|
pub trait UnitPacketWrite: AsyncWrite + Unpin{
|
||||||
|
async fn send_buffer(&mut self, data: &[u8]) -> Result<(), io::Error> {
|
||||||
|
let mut dest_data = Vec::new();
|
||||||
|
|
||||||
|
data.serialize(&mut dest_data).expect("ran out of memory or something");
|
||||||
|
|
||||||
|
self.write_all(&dest_data[..]).await?;
|
||||||
|
|
||||||
|
self.flush().await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: AsyncWrite + Unpin> UnitPacketWrite for T{}
|
||||||
|
|
||||||
|
pub async fn establish_tls_connection_to(address: &str, server_name: &'static str) -> TlsStream<TcpStream>{
|
||||||
|
let connector = get_configured_tls_connector().await;
|
||||||
|
|
||||||
|
let stream = TcpStream::connect(address).await.unwrap();
|
||||||
|
|
||||||
|
let stream = connector.connect(ServerName::try_from(server_name).unwrap(), stream).await
|
||||||
|
.expect("unable to connect via tls");
|
||||||
|
|
||||||
|
stream
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rmc_proto(1)]
|
||||||
|
pub trait RmcTestProto{
|
||||||
|
#[method_id(1)]
|
||||||
|
async fn test(&self) -> Result<String, ErrorCode>;
|
||||||
|
}
|
||||||
|
|
||||||
|
define_rmc_proto!(
|
||||||
|
proto TestProto{
|
||||||
|
RmcTestProto
|
||||||
|
}
|
||||||
|
);
|
||||||
|
#[rmc_struct(TestProto)]
|
||||||
|
pub struct TestStruct;
|
||||||
|
|
||||||
|
impl RmcTestProto for TestStruct{
|
||||||
|
async fn test(&self) -> Result<String, ErrorCode> {
|
||||||
|
Ok("heya".into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,6 +9,7 @@ pub mod nat_traversal;
|
||||||
pub mod matchmake_ext;
|
pub mod matchmake_ext;
|
||||||
pub mod ranking;
|
pub mod ranking;
|
||||||
|
|
||||||
|
use crate::util::{SendingBufferConnection, SplittableBufferConnection};
|
||||||
use crate::prudp::socket::{ExternalConnection, SendingConnection};
|
use crate::prudp::socket::{ExternalConnection, SendingConnection};
|
||||||
use crate::rmc::message::RMCMessage;
|
use crate::rmc::message::RMCMessage;
|
||||||
use crate::rmc::protocols::RemoteCallError::ConnectionBroke;
|
use crate::rmc::protocols::RemoteCallError::ConnectionBroke;
|
||||||
|
|
@ -45,7 +46,7 @@ pub enum RemoteCallError {
|
||||||
InvalidResponse(#[from] structures::Error),
|
InvalidResponse(#[from] structures::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RmcConnection(pub SendingConnection, pub RmcResponseReceiver);
|
pub struct RmcConnection(pub SendingBufferConnection, pub RmcResponseReceiver);
|
||||||
|
|
||||||
pub struct RmcResponseReceiver(Arc<Notify>, Arc<Mutex<HashMap<u32, RMCResponse>>>);
|
pub struct RmcResponseReceiver(Arc<Notify>, Arc<Mutex<HashMap<u32, RMCResponse>>>);
|
||||||
|
|
||||||
|
|
@ -141,7 +142,7 @@ pub trait RmcCallable {
|
||||||
//type Remote: RemoteObject;
|
//type Remote: RemoteObject;
|
||||||
fn rmc_call(
|
fn rmc_call(
|
||||||
&self,
|
&self,
|
||||||
responder: &SendingConnection,
|
responder: &SendingBufferConnection,
|
||||||
protocol_id: u16,
|
protocol_id: u16,
|
||||||
method_id: u32,
|
method_id: u32,
|
||||||
call_id: u32,
|
call_id: u32,
|
||||||
|
|
@ -156,7 +157,7 @@ macro_rules! define_rmc_proto {
|
||||||
}) => {
|
}) => {
|
||||||
paste::paste!{
|
paste::paste!{
|
||||||
pub trait [<Local $name>]: std::any::Any $( + [<Raw $protocol>] + $protocol)* {
|
pub trait [<Local $name>]: std::any::Any $( + [<Raw $protocol>] + $protocol)* {
|
||||||
async fn rmc_call(&self, remote_response_connection: &crate::prudp::socket::SendingConnection, protocol_id: u16, method_id: u32, call_id: u32, rest: Vec<u8>){
|
async fn rmc_call(&self, remote_response_connection: &splatoon_server_rust::util::SendingBufferConnection, protocol_id: u16, method_id: u32, call_id: u32, rest: Vec<u8>){
|
||||||
match protocol_id{
|
match protocol_id{
|
||||||
$(
|
$(
|
||||||
[<Raw $protocol Info>]::PROTOCOL_ID => <Self as [<Raw $protocol>]>::rmc_call_proto(self, remote_response_connection, method_id, call_id, rest).await,
|
[<Raw $protocol Info>]::PROTOCOL_ID => <Self as [<Raw $protocol>]>::rmc_call_proto(self, remote_response_connection, method_id, call_id, rest).await,
|
||||||
|
|
@ -166,16 +167,16 @@ macro_rules! define_rmc_proto {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct [<Remote $name>](crate::rmc::protocols::RmcConnection);
|
pub struct [<Remote $name>](splatoon_server_rust::rmc::protocols::RmcConnection);
|
||||||
|
|
||||||
impl crate::rmc::protocols::RemoteInstantiatable for [<Remote $name>]{
|
impl splatoon_server_rust::rmc::protocols::RemoteInstantiatable for [<Remote $name>]{
|
||||||
fn new(conn: crate::rmc::protocols::RmcConnection) -> Self{
|
fn new(conn: splatoon_server_rust::rmc::protocols::RmcConnection) -> Self{
|
||||||
Self(conn)
|
Self(conn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl crate::rmc::protocols::HasRmcConnection for [<Remote $name>]{
|
impl splatoon_server_rust::rmc::protocols::HasRmcConnection for [<Remote $name>]{
|
||||||
fn get_connection(&self) -> &crate::rmc::protocols::RmcConnection{
|
fn get_connection(&self) -> &splatoon_server_rust::rmc::protocols::RmcConnection{
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -191,7 +192,7 @@ macro_rules! define_rmc_proto {
|
||||||
impl RmcCallable for () {
|
impl RmcCallable for () {
|
||||||
async fn rmc_call(
|
async fn rmc_call(
|
||||||
&self,
|
&self,
|
||||||
remote_response_connection: &crate::prudp::socket::SendingConnection,
|
remote_response_connection: &SendingBufferConnection,
|
||||||
protocol_id: u16,
|
protocol_id: u16,
|
||||||
method_id: u32,
|
method_id: u32,
|
||||||
call_id: u32,
|
call_id: u32,
|
||||||
|
|
@ -222,13 +223,13 @@ impl<T: RemoteInstantiatable> OnlyRemote<T>{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: RemoteInstantiatable> RmcCallable for OnlyRemote<T>{
|
impl<T: RemoteInstantiatable> RmcCallable for OnlyRemote<T>{
|
||||||
fn rmc_call(&self, responder: &SendingConnection, protocol_id: u16, method_id: u32, call_id: u32, rest: Vec<u8>) -> impl std::future::Future<Output = ()> + Send {
|
fn rmc_call(&self, responder: &SendingBufferConnection, protocol_id: u16, method_id: u32, call_id: u32, rest: Vec<u8>) -> impl std::future::Future<Output = ()> + Send {
|
||||||
async{}
|
async{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_incoming<T: RmcCallable + Send + Sync + 'static>(
|
async fn handle_incoming<T: RmcCallable + Send + Sync + 'static>(
|
||||||
mut connection: ExternalConnection,
|
mut connection: SplittableBufferConnection,
|
||||||
remote: Arc<T>,
|
remote: Arc<T>,
|
||||||
notify: Arc<Notify>,
|
notify: Arc<Notify>,
|
||||||
incoming: Arc<Mutex<HashMap<u32, RMCResponse>>>,
|
incoming: Arc<Mutex<HashMap<u32, RMCResponse>>>,
|
||||||
|
|
@ -278,7 +279,7 @@ async fn handle_incoming<T: RmcCallable + Send + Sync + 'static>(
|
||||||
info!("rmc disconnected")
|
info!("rmc disconnected")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_rmc_gateway_connection<T: RmcCallable + Sync + Send + 'static,F>(conn: ExternalConnection, create_internal: F) -> Arc<T>
|
pub fn new_rmc_gateway_connection<T: RmcCallable + Sync + Send + 'static,F>(conn: SplittableBufferConnection, create_internal: F) -> Arc<T>
|
||||||
where
|
where
|
||||||
F: FnOnce(RmcConnection) -> Arc<T>,
|
F: FnOnce(RmcConnection) -> Arc<T>,
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use bytemuck::bytes_of;
|
||||||
use log::error;
|
use log::error;
|
||||||
use v_byte_macros::EnumTryInto;
|
use v_byte_macros::EnumTryInto;
|
||||||
use crate::endianness::{ReadExtensions, IS_BIG_ENDIAN};
|
use crate::endianness::{ReadExtensions, IS_BIG_ENDIAN};
|
||||||
use crate::prudp::packet::{PRUDPPacket};
|
use crate::prudp::packet::{PRUDPV1Packet};
|
||||||
use crate::prudp::packet::flags::{NEED_ACK, RELIABLE};
|
use crate::prudp::packet::flags::{NEED_ACK, RELIABLE};
|
||||||
use crate::prudp::packet::PacketOption::FragmentId;
|
use crate::prudp::packet::PacketOption::FragmentId;
|
||||||
use crate::prudp::packet::types::DATA;
|
use crate::prudp::packet::types::DATA;
|
||||||
|
|
@ -13,6 +13,8 @@ use crate::prudp::socket::{ExternalConnection, SendingConnection};
|
||||||
use crate::rmc::response::ErrorCode::Core_Exception;
|
use crate::rmc::response::ErrorCode::Core_Exception;
|
||||||
use crate::rmc::structures::qresult::ERROR_MASK;
|
use crate::rmc::structures::qresult::ERROR_MASK;
|
||||||
use crate::rmc::structures::RmcSerialize;
|
use crate::rmc::structures::RmcSerialize;
|
||||||
|
use crate::util::SendingBufferConnection;
|
||||||
|
|
||||||
pub enum RMCResponseResult {
|
pub enum RMCResponseResult {
|
||||||
Success {
|
Success {
|
||||||
call_id: u32,
|
call_id: u32,
|
||||||
|
|
@ -145,7 +147,7 @@ pub fn generate_response(protocol_id: u8, response: RMCResponseResult) -> io::Re
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_result(
|
pub async fn send_result(
|
||||||
connection: &SendingConnection,
|
connection: &SendingBufferConnection,
|
||||||
result: Result<Vec<u8>, ErrorCode>,
|
result: Result<Vec<u8>, ErrorCode>,
|
||||||
protocol_id: u8,
|
protocol_id: u8,
|
||||||
method_id: u32,
|
method_id: u32,
|
||||||
|
|
@ -173,7 +175,7 @@ pub async fn send_result(
|
||||||
send_response(connection, response).await
|
send_response(connection, response).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_response(connection: &SendingConnection, rmcresponse: RMCResponse) {
|
pub async fn send_response(connection: &SendingBufferConnection, rmcresponse: RMCResponse) {
|
||||||
connection.send(rmcresponse.to_data()).await;
|
connection.send(rmcresponse.to_data()).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,10 +33,19 @@ pub mod primitives;
|
||||||
pub mod matchmake;
|
pub mod matchmake;
|
||||||
pub mod variant;
|
pub mod variant;
|
||||||
pub mod ranking;
|
pub mod ranking;
|
||||||
|
mod networking;
|
||||||
|
|
||||||
pub trait RmcSerialize: Sized{
|
pub trait RmcSerialize: Sized{
|
||||||
fn serialize(&self, writer: &mut dyn Write) -> Result<()>;
|
fn serialize(&self, writer: &mut dyn Write) -> Result<()>;
|
||||||
fn deserialize(reader: &mut dyn Read) -> Result<Self>;
|
fn deserialize(reader: &mut dyn Read) -> Result<Self>;
|
||||||
|
|
||||||
|
fn to_data(&self) -> Vec<u8>{
|
||||||
|
let mut data = Vec::new();
|
||||||
|
|
||||||
|
self.serialize(&mut data).expect("out of memory or something");
|
||||||
|
|
||||||
|
data
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RmcSerialize for (){
|
impl RmcSerialize for (){
|
||||||
|
|
@ -46,4 +55,6 @@ impl RmcSerialize for (){
|
||||||
fn deserialize(reader: &mut dyn Read) -> Result<Self> {
|
fn deserialize(reader: &mut dyn Read) -> Result<Self> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
32
src/rmc/structures/networking.rs
Normal file
32
src/rmc/structures/networking.rs
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
use std::io::{Read, Write};
|
||||||
|
use std::net::{Ipv4Addr, SocketAddrV4};
|
||||||
|
use crate::prudp::packet::VirtualPort;
|
||||||
|
use crate::rmc::structures::RmcSerialize;
|
||||||
|
|
||||||
|
impl RmcSerialize for SocketAddrV4{
|
||||||
|
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||||
|
self.ip().to_bits().serialize(writer)?;
|
||||||
|
self.port().serialize(writer)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||||
|
let ip = u32::deserialize(reader)?;
|
||||||
|
let port = u16::deserialize(reader)?;
|
||||||
|
|
||||||
|
Ok(SocketAddrV4::new(Ipv4Addr::from_bits(ip), port))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RmcSerialize for VirtualPort{
|
||||||
|
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||||
|
self.0.serialize(writer)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||||
|
Ok(Self(u8::deserialize(reader)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/rnex_proxy_common.rs
Normal file
10
src/rnex_proxy_common.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
use macros::RmcSerialize;
|
||||||
|
use crate::kerberos::KerberosDateTime;
|
||||||
|
use crate::prudp::sockaddr::PRUDPSockAddr;
|
||||||
|
|
||||||
|
#[derive(Debug, RmcSerialize)]
|
||||||
|
#[rmc_struct(0)]
|
||||||
|
pub struct ConnectionInitData{
|
||||||
|
pub prudpsock_addr: PRUDPSockAddr,
|
||||||
|
}
|
||||||
|
|
||||||
94
src/util.rs
Normal file
94
src/util.rs
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
use std::cell::UnsafeCell;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
use std::ops::Deref;
|
||||||
|
use log::error;
|
||||||
|
use tokio::io::{AsyncRead, AsyncWrite};
|
||||||
|
use tokio::sync::mpsc::{channel, Receiver, Sender};
|
||||||
|
use tokio::task;
|
||||||
|
use splatoon_server_rust::reggie::{UnitPacketRead, UnitPacketWrite};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct SendingBufferConnection(Sender<Vec<u8>>);
|
||||||
|
|
||||||
|
pub struct SplittableBufferConnection(SendingBufferConnection, Receiver<Vec<u8>>);
|
||||||
|
|
||||||
|
impl AsRef<SendingBufferConnection> for SplittableBufferConnection{
|
||||||
|
fn as_ref(&self) -> &SendingBufferConnection {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for SplittableBufferConnection{
|
||||||
|
type Target = SendingBufferConnection;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
self.as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
impl<T: Send + Unpin + AsyncWrite + AsyncRead + 'static> From<T> for SplittableBufferConnection{
|
||||||
|
fn from(value: T) -> Self {
|
||||||
|
Self::new(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SplittableBufferConnection {
|
||||||
|
fn new<T: Send + Unpin + AsyncWrite + AsyncRead + 'static>(stream: T) -> Self {
|
||||||
|
let (outside_send, inside_recv) = channel::<Vec<u8>>(10);
|
||||||
|
let (inside_send, outside_recv) = channel::<Vec<u8>>(10);
|
||||||
|
|
||||||
|
task::spawn(async move {
|
||||||
|
let sender = inside_send;
|
||||||
|
let mut recver = inside_recv;
|
||||||
|
let mut stream = stream;
|
||||||
|
loop {
|
||||||
|
tokio::select! {
|
||||||
|
data = recver.recv() => {
|
||||||
|
let Some(data) = data else {
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Err(e) = stream.send_buffer(&data[..]).await{
|
||||||
|
error!("error sending data to backend: {}", e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data = stream.read_buffer() => {
|
||||||
|
let data = match data{
|
||||||
|
Ok(d) => d,
|
||||||
|
Err(e) => {
|
||||||
|
error!("error reveiving data from backend: {}", e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Err(e) = sender.send(data).await{
|
||||||
|
error!("a send error occurred {}", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self(SendingBufferConnection(outside_send), outside_recv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SendingBufferConnection{
|
||||||
|
pub async fn send(&self, buffer: Vec<u8>) -> Option<()>{
|
||||||
|
self.0.send(buffer).await.ok()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SplittableBufferConnection{
|
||||||
|
pub async fn recv(&mut self) -> Option<Vec<u8>>{
|
||||||
|
self.1.recv().await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn duplicate_sender(&self) -> SendingBufferConnection{
|
||||||
|
self.0.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -45,7 +45,7 @@ async fn players_in_match(mmm: &State<Arc<MatchmakeManager>>, gid: u32) -> Optio
|
||||||
|
|
||||||
Some(Json(gathering.connected_players.iter().filter_map(|p| p.upgrade()).map(|p| p.pid).collect()))
|
Some(Json(gathering.connected_players.iter().filter_map(|p| p.upgrade()).map(|p| p.pid).collect()))
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
#[get("/player/<pid>/disconnect")]
|
#[get("/player/<pid>/disconnect")]
|
||||||
async fn disconnect_player(_auth: RnexApiAuth, mmm: &State<Arc<MatchmakeManager>>, pid: u32) -> Option<()>{
|
async fn disconnect_player(_auth: RnexApiAuth, mmm: &State<Arc<MatchmakeManager>>, pid: u32) -> Option<()>{
|
||||||
// this doesnt work and is broken, there might be some other way to remotely close gatherings...
|
// this doesnt work and is broken, there might be some other way to remotely close gatherings...
|
||||||
|
|
@ -59,7 +59,7 @@ async fn disconnect_player(_auth: RnexApiAuth, mmm: &State<Arc<MatchmakeManager>
|
||||||
|
|
||||||
|
|
||||||
Some(())
|
Some(())
|
||||||
}
|
}*/
|
||||||
|
|
||||||
#[get("/gathering/<gid>/close")]
|
#[get("/gathering/<gid>/close")]
|
||||||
async fn close_gathering(_auth: RnexApiAuth, mmm: &State<Arc<MatchmakeManager>>, gid: u32) -> Option<()>{
|
async fn close_gathering(_auth: RnexApiAuth, mmm: &State<Arc<MatchmakeManager>>, gid: u32) -> Option<()>{
|
||||||
|
|
@ -89,7 +89,7 @@ async fn close_gathering(_auth: RnexApiAuth, mmm: &State<Arc<MatchmakeManager>>,
|
||||||
pub async fn start_web(mgr: Arc<MatchmakeManager>) -> JoinHandle<()> {
|
pub async fn start_web(mgr: Arc<MatchmakeManager>) -> JoinHandle<()> {
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
rocket::build()
|
rocket::build()
|
||||||
.mount("/", routes![gatherings, players_in_match, close_gathering, disconnect_player])
|
.mount("/", routes![gatherings, players_in_match, close_gathering])
|
||||||
.manage(mgr)
|
.manage(mgr)
|
||||||
.launch().await
|
.launch().await
|
||||||
.expect("unable to start webserver");
|
.expect("unable to start webserver");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue