feat(secure): add maintenance mode and fix using local ip

This commit is contained in:
DJMrTV 2025-02-05 16:02:32 +01:00
commit e582984bc9
3 changed files with 72 additions and 8 deletions

View file

@ -9,7 +9,7 @@ use tonic::codegen::InterceptedService;
use tonic::transport::Channel;
use crate::grpc::InterceptorFunc;
use crate::grpc::protobufs::account::account_client::AccountClient;
use crate::grpc::protobufs::account::GetNexPasswordRequest;
use crate::grpc::protobufs::account::{GetNexPasswordRequest, GetUserDataRequest, GetUserDataResponse};
static API_KEY: Lazy<MetadataValue<Ascii>> = Lazy::new(||{
let key = env::var("ACCOUNT_GRPC_API_KEY")
@ -74,6 +74,16 @@ impl Client{
Ok(response.password.as_bytes().try_into()?)
}
pub async fn get_user_data(&mut self , pid: u32) -> Result<GetUserDataResponse>{
let req = Request::new(GetUserDataRequest{
pid
});
let response = self.0.get_user_data(req).await?.into_inner();
Ok(response)
}
}
#[cfg(test)]

View file

@ -14,7 +14,7 @@ use simplelog::{ColorChoice, CombinedLogger, Config, LevelFilter, TerminalMode,
use tokio::sync::Mutex;
use tokio::task::JoinHandle;
use crate::nex::account::Account;
use crate::protocols::auth;
use crate::protocols::{auth, block_if_maintenance};
use crate::protocols::auth::AuthProtocolConfig;
use crate::protocols::matchmake_common::MatchmakeData;
use crate::protocols::server::RMCProtocolServer;
@ -58,15 +58,22 @@ static SECURE_SERVER_PORT: Lazy<u16> = Lazy::new(||{
.unwrap_or(10001)
});
static OWN_IP: Lazy<Ipv4Addr> = Lazy::new(||{
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<Ipv4Addr> = Lazy::new(||{
env::var("SERVER_IP_PUBLIC")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or(*OWN_IP_PRIVATE)
});
static SECURE_STATION_URL: Lazy<String> = Lazy::new(||
format!("prudps:/PID=2;sid=1;stream=10;type=2;address={};port={};CID=1", *OWN_IP, *SECURE_SERVER_PORT)
format!("prudps:/PID=2;sid=1;stream=10;type=2;address={};port={};CID=1", *OWN_IP_PUBLIC, *SECURE_SERVER_PORT)
);
#[tokio::main]
@ -93,10 +100,10 @@ struct AuthServer{
}
async fn start_auth_server() -> AuthServer{
info!("starting auth server on {}:{}", *OWN_IP, *AUTH_SERVER_PORT);
info!("starting auth server on {}:{}", *OWN_IP_PRIVATE, *AUTH_SERVER_PORT);
let (router, join_handle) =
Router::new(SocketAddrV4::new(*OWN_IP, *AUTH_SERVER_PORT)).await
Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *AUTH_SERVER_PORT)).await
.expect("unable to startauth server");
info!("setting up endpoints");
@ -162,10 +169,10 @@ struct SecureServer{
}
async fn start_secure_server() -> SecureServer{
info!("starting secure server on {}:{}", *OWN_IP, *SECURE_SERVER_PORT);
info!("starting secure server on {}:{}", *OWN_IP_PRIVATE, *SECURE_SERVER_PORT);
let (router, join_handle) =
Router::new(SocketAddrV4::new(*OWN_IP, *SECURE_SERVER_PORT)).await
Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *SECURE_SERVER_PORT)).await
.expect("unable to startauth server");
info!("setting up endpoints");
@ -175,6 +182,7 @@ async fn start_secure_server() -> SecureServer{
));
let rmcserver = RMCProtocolServer::new(Box::new([
Box::new(block_if_maintenance),
Box::new(protocols::secure::bound_protocol()),
Box::new(protocols::matchmake_extension::bound_protocol(matchmake_data))
]));

View file

@ -1,4 +1,13 @@
use std::env;
use std::future::Future;
use std::pin::Pin;
use log::warn;
use once_cell::sync::Lazy;
use crate::grpc;
use crate::prudp::socket::ConnectionData;
use crate::rmc::message::RMCMessage;
use crate::rmc::response::{ErrorCode, RMCResponse};
pub mod auth;
pub mod server;
@ -6,6 +15,43 @@ pub mod secure;
pub mod matchmake_extension;
pub mod matchmake_common;
static IS_MAINTENANCE: Lazy<bool> = Lazy::new(|| {
env::var("IS_MAINTENANCE")
.ok()
.map(|v| v.parse().expect("IS_MAINTENANCE should be a boolean value"))
.unwrap_or(false)
});
pub fn block_if_maintenance<'a>(rmcmessage: &'a RMCMessage, conn: &'a mut ConnectionData) -> Pin<Box<(dyn Future<Output=Option<RMCResponse>> + Send + 'a)>> {
Box::pin(async move {
if let Some(active_conn) = conn.active_connection_data.as_ref() {
if let Some(secure_conn) = active_conn.active_secure_connection_data.as_ref() {
if let Ok(mut client) = grpc::account::Client::new().await {
if let Ok(client_data) = client.get_user_data(secure_conn.pid).await{
if client_data.access_level >= 2{
return None;
}
}
}
}
}
warn!("login attempted whilest servers are in maintenance");
if *IS_MAINTENANCE {
Some(RMCResponse {
protocol_id: rmcmessage.protocol_id as u8,
response_result: rmcmessage.error_result_with_code(ErrorCode::RendezVous_GameServerMaintenance),
})
} else {
None
}
})
}
#[macro_export]
macro_rules! define_protocol {
($id:literal ($($varname:ident : $ty:ty),*) => {$($func_id:literal => $func:path),*} ) => {