intel_cache_lib/
ic_server.rs

1use libloading::Library;
2
3use std::io::{Error};
4use std::thread;
5use std::net::{TcpListener,SocketAddrV4,Ipv4Addr};
6
7use crate::lib_backend::{establish_connection,establish_testing_connection,parse_ic_packet};
8use crate::ic_types::{IcPacket,IcConnection,IcExecute};
9use crate::IcModule;
10
11/// The Server interface struct for IntelCache. It will listen on port 64209 for new clients.
12/// Then for each client, it will create a new thread for the client,
13/// process and return
14/// [`IcPacket`]s to the handled client.
15/// 
16/// Note: to initialize the server the struct must be defined as a global.
17pub struct IcServer { }
18impl IcServer {
19	fn handle_client(mut c: IcConnection) -> Result<(),Error> {
20		println!("CONNECTION FROM {:?}", c.addr());
21		let mut modules = IcServer::load_basic_modules();
22		loop {
23			match c.get_packet() {
24				Ok(p) => {
25					if c.login != None {
26						println!("{}->SERVER: {}",c.login.as_ref().unwrap().username,&p.header.as_ref().unwrap_or(&"NONE".to_string()))
27					} else {
28						println!("ANONYMOUS->SERVER: {}",&p.header.as_ref().unwrap_or(&"NONE".to_string()))
29					}
30					let mut icc: Box<dyn IcExecute<Connection = IcConnection>>;
31					let cmd: Vec::<String>;
32					match parse_ic_packet(p.clone(),&modules){
33						Ok(v) => { 
34							cmd = v.0;
35							icc = v.1;
36							let mut op = icc.exec(&mut c,Some(cmd),p.body,p.cached);
37							if c.login != None {
38								println!("SERVER->{}: {}",c.login.as_ref().unwrap().username,&op.header.as_ref().unwrap_or(&"NONE".to_string()))
39							} else {
40								println!("SERVER->ANONYMOUS: {}",&op.header.as_ref().unwrap_or(&"NONE".to_string()))
41							}
42							c.send_packet(&mut op).unwrap();
43						},
44						Err(_e) => {
45							if c.login != None {
46								println!("SERVER->{}: {}",c.login.as_ref().unwrap().username,&p.header.as_ref().unwrap_or(&"NONE".to_string()))
47							} else {
48								println!("SERVER->ANONYMOUS: {}",&p.header.as_ref().unwrap_or(&"NONE".to_string()))
49							}
50							c.send_packet(&mut IcPacket::new(Some("Err: Not Found".to_string()),None)).unwrap();
51						},
52					}
53				},
54				Err(_e) =>{println!("Client disconnected.");IcServer::unload_modules(&mut modules);return Ok(())},
55			}
56		}
57	}
58	
59	fn load_basic_modules() -> (Vec<Library>,Vec<Box<dyn IcModule>>){
60		let mut ret = Vec::<Box<dyn IcModule>>::new();
61		let mut libs = Vec::<Library>::new();
62		let basic_module_paths = vec!["libic_core_module.so","libic_storage_module.so"];
63		for path in basic_module_paths {
64			unsafe {
65				let icml = Library::new(path).unwrap_or_else(|error| panic!("{}", error));
66				libs.push(icml);
67				let icmc = libs.last().unwrap().get::<unsafe fn() -> *mut dyn IcModule>(b"icm_new\0").unwrap_or_else(|error| panic!("{}", error));
68				ret.push(Box::from_raw(icmc()));
69			}
70		}
71		(libs,ret)
72	}
73	
74	fn unload_modules(modules: &mut(Vec<Library>,Vec<Box<dyn IcModule>>)) {
75		modules.1.clear();
76		modules.0.clear();
77	}
78	
79	/// `listen` will start the server. 
80	pub fn listen(&'static mut self,testing: bool) {
81		if ! testing {
82			match establish_connection() {
83			Ok(_v) =>{
84					let loopback:Ipv4Addr = Ipv4Addr::new(0, 0, 0, 0);
85					let socket:SocketAddrV4 = SocketAddrV4::new(loopback, 64209);
86					let listener = TcpListener::bind(socket).unwrap();
87					for stream in listener.incoming() { 
88						match stream {
89							Err(e) => { eprintln!("ERR <ic_server.rs:73>: {}",e) },
90							Ok(stream) => { thread::spawn( move || {
91									IcServer::handle_client(IcConnection::new(stream,testing)).unwrap_or_else(|error| eprintln!("ERR <ic_server.rs:75>: {:?}",error));
92								});
93							},
94						}
95					}
96				},
97			Err(e) => println!("Error connecting to internal database: {}",e),
98			}
99		} else {
100			println!("TESTING ON");
101			match establish_testing_connection() {
102			Ok(_v) =>{
103					let loopback:Ipv4Addr = Ipv4Addr::new(0, 0, 0, 0);
104					let socket:SocketAddrV4 = SocketAddrV4::new(loopback, 46290);
105					let listener = TcpListener::bind(socket).unwrap();
106					for stream in listener.incoming() { 
107						match stream {
108							Err(e) => { eprintln!("ERR <ic_server.rs:92>: {}",e) },
109							Ok(stream) => { thread::spawn(  move || {
110									IcServer::handle_client(IcConnection::new(stream,testing)).unwrap_or_else(|error| eprintln!("ERR <ic_server.rs:94>: {:?}",error));
111								});
112							},
113						}
114					}
115				},
116			Err(e) => println!("Error connecting to internal database: {}",e),
117			}
118		}
119	}
120}