2025-01-19 14:14:48 +01:00
use std ::{ env , io , thread } ;
use std ::io ::Cursor ;
2025-01-19 13:02:15 +01:00
use std ::marker ::PhantomData ;
2025-01-19 15:56:36 +01:00
use std ::net ::{ Ipv4Addr , SocketAddr , SocketAddrV4 , TcpStream , UdpSocket } ;
use std ::net ::SocketAddr ::V4 ;
2025-01-19 13:02:15 +01:00
use std ::ops ::{ Deref , DerefMut } ;
2025-01-19 15:56:36 +01:00
use std ::sync ::{ Arc , Mutex , RwLock } ;
2025-01-19 14:14:48 +01:00
use std ::sync ::atomic ::{ AtomicBool , Ordering } ;
use std ::thread ::JoinHandle ;
use once_cell ::sync ::Lazy ;
2025-01-19 14:34:02 +01:00
use log ::{ error , info } ;
2025-01-19 14:14:48 +01:00
use crate ::prudp ::auth_module ::AuthModule ;
2025-01-19 13:02:15 +01:00
use crate ::prudp ::endpoint ::Endpoint ;
2025-01-19 15:56:36 +01:00
use crate ::prudp ::packet ::{ PRUDPPacket , VirtualPort } ;
use crate ::prudp ::sockaddr ::PRUDPSockAddr ;
2025-01-19 14:14:48 +01:00
static SERVER_DATAGRAMS : Lazy < u8 > = Lazy ::new ( | | {
env ::var ( " SERVER_DATAGRAM_COUNT " ) . ok ( )
. and_then ( | s | s . parse ( ) . ok ( ) )
. unwrap_or ( 1 )
} ) ;
2025-01-19 13:02:15 +01:00
pub struct NexServer {
2025-01-19 15:56:36 +01:00
pub endpoints : RwLock < Vec < Endpoint > > ,
2025-01-19 14:14:48 +01:00
pub running : AtomicBool ,
//pub auth_module: Arc<dyn AuthModule>
2025-01-19 13:02:15 +01:00
_no_outside_construction : PhantomData < ( ) >
}
2025-01-19 15:56:36 +01:00
pub struct Connection < ' a > {
socket : & ' a UdpSocket ,
prudp_addr : PRUDPSockAddr
}
2025-01-19 13:02:15 +01:00
impl NexServer {
2025-01-19 14:14:48 +01:00
fn process_prudp_packet ( & self , packet : & PRUDPPacket ) {
}
2025-01-19 15:56:36 +01:00
fn process_prudp_packets < ' a > ( & self , socket : & ' a UdpSocket , addr : SocketAddrV4 , udp_message : & [ u8 ] ) {
2025-01-19 14:14:48 +01:00
let mut stream = Cursor ::new ( udp_message ) ;
while stream . position ( ) as usize ! = udp_message . len ( ) {
let packet = match PRUDPPacket ::new ( & mut stream ) {
Ok ( p ) = > p ,
Err ( e ) = > {
2025-01-19 15:56:36 +01:00
error! ( " Somebody({}) is fucking with the servers or their connection is bad " , addr ) ;
2025-01-19 14:14:48 +01:00
break ;
} ,
} ;
2025-01-19 14:34:02 +01:00
info! ( " got valid prudp packet from someone({}): \n {:?} " , addr , packet ) ;
2025-01-19 15:56:36 +01:00
let connection = Connection {
socket ,
prudp_addr : packet . source_sockaddr ( addr )
} ;
let endpoints = self . endpoints . read ( ) . expect ( " poison " ) ;
let Some ( endpoint ) = endpoints . iter ( ) . find ( | e | {
e . get_virual_port ( ) . get_port_number ( ) = = connection . prudp_addr . virtual_port . get_port_number ( )
} ) else {
error! ( " connection to invalid endpoint({}) attempted by {} " , connection . prudp_addr . virtual_port . get_port_number ( ) , connection . prudp_addr . regular_socket_addr ) ;
continue ;
} ;
2025-01-19 14:14:48 +01:00
}
}
fn server_thread_entry ( self : Arc < Self > , socket : Arc < UdpSocket > ) {
2025-01-19 14:37:29 +01:00
info! ( " starting datagram thread " ) ;
2025-01-19 14:14:48 +01:00
while self . running . load ( Ordering ::Relaxed ) {
// yes we actually allow the max udp to be read lol
let mut msg_buffer = vec! [ 0 u8 ; 65507 ] ;
let ( len , addr ) = socket . recv_from ( & mut msg_buffer )
. expect ( " Datagram thread crashed due to unexpected error from recv_from " ) ;
2025-01-19 15:56:36 +01:00
let V4 ( addr ) = addr else {
error! ( " somehow got ipv6 packet...? ignoring " ) ;
continue ;
} ;
2025-01-19 14:14:48 +01:00
let current_msg = & msg_buffer [ 0 .. len ] ;
2025-01-19 14:37:29 +01:00
info! ( " attempting to process message " ) ;
2025-01-19 15:56:36 +01:00
self . process_prudp_packets ( & socket , addr , current_msg ) ;
2025-01-19 14:14:48 +01:00
}
2025-01-19 13:02:15 +01:00
}
2025-01-19 14:14:48 +01:00
pub fn new ( addr : SocketAddrV4 ) -> io ::Result < ( Arc < Self > , JoinHandle < ( ) > ) > {
2025-01-19 13:02:15 +01:00
let own_impl = NexServer {
endpoints : Default ::default ( ) ,
2025-01-19 14:14:48 +01:00
running : AtomicBool ::new ( true ) ,
2025-01-19 13:02:15 +01:00
_no_outside_construction : Default ::default ( )
} ;
let arc = Arc ::new ( own_impl ) ;
2025-01-19 14:14:48 +01:00
let socket = Arc ::new ( UdpSocket ::bind ( addr ) ? ) ;
2025-01-19 13:02:15 +01:00
2025-01-19 14:14:48 +01:00
let mut thread = None ;
2025-01-19 13:02:15 +01:00
2025-01-19 14:14:48 +01:00
for _ in 0 .. * SERVER_DATAGRAMS {
let socket = socket . clone ( ) ;
let server = arc . clone ( ) ;
2025-01-19 14:37:29 +01:00
2025-01-19 14:14:48 +01:00
thread = Some ( thread ::spawn ( move | | {
server . server_thread_entry ( socket ) ;
} ) ) ;
}
2025-01-19 13:02:15 +01:00
2025-01-19 14:14:48 +01:00
let thread = thread . expect ( " cannot have less than 1 thread for a server " ) ;
2025-01-19 13:02:15 +01:00
2025-01-19 14:14:48 +01:00
Ok ( ( arc , thread ) )
}
}
2025-01-19 13:02:15 +01:00