Compare commits
	
		
			4 Commits
		
	
	
		
			1a25e882f3
			...
			81649bf2fd
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 81649bf2fd | |||
| 72703aa46b | |||
| 63d485b8b5 | |||
| 7f3aa3076d | 
| @ -1,13 +1,11 @@ | |||||||
| mod net; | mod net; | ||||||
|  | mod types; | ||||||
| use pea_2_pea::*; | use pea_2_pea::*; | ||||||
| use rand::RngCore; | use rand::RngCore; | ||||||
| 
 | 
 | ||||||
| use std::{ | use std::{net::UdpSocket, process::exit, time::Duration}; | ||||||
|     io::{Error, ErrorKind, Read, Write}, | 
 | ||||||
|     net::UdpSocket, | use crate::types::Network; | ||||||
|     process::exit, |  | ||||||
|     time::Duration, |  | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| #[derive(clap::Parser)] | #[derive(clap::Parser)] | ||||||
| #[command(name = "pea_2_pea")] | #[command(name = "pea_2_pea")] | ||||||
| @ -70,13 +68,82 @@ fn main() -> std::io::Result<()> { | |||||||
| 
 | 
 | ||||||
|         let mut buf: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE]; |         let mut buf: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE]; | ||||||
|         // query here
 |         // query here
 | ||||||
|         let mut data_lenght: usize = net::query_request(&mut buf, &server_SocketAddr, socket)?; |         let public_sock_addr_raw: String = | ||||||
|  |             match net::query_request(&mut buf, &server_SocketAddr, &socket) { | ||||||
|  |                 Ok(s) => s, | ||||||
|  |                 Err(e) => return Err(ServerErrorResponses::into_io_error(e)), | ||||||
|  |             }; | ||||||
| 
 | 
 | ||||||
|         let mut public_sock_addr: Vec<u8> = buf[1..data_lenght].to_vec(); |         let mut salt: [u8; SALT_AND_IV_SIZE] = [0u8; SALT_AND_IV_SIZE]; | ||||||
|  |         let mut iv: [u8; SALT_AND_IV_SIZE] = [0u8; SALT_AND_IV_SIZE]; | ||||||
|  |         let (public_sock_addr, encryption_key) = match cli.password { | ||||||
|  |             Some(ref p) => { | ||||||
|  |                 let mut rng = rand::rng(); | ||||||
|  |                 rng.fill_bytes(&mut salt); | ||||||
|  |                 rng.fill_bytes(&mut iv); | ||||||
|  |                 let enc_key_tmp = shared::crypto::derive_key_from_password(p.as_bytes(), &salt); | ||||||
|  |                 ( | ||||||
|  |                     shared::crypto::encrypt(&enc_key_tmp, &iv, public_sock_addr_raw.as_bytes()) | ||||||
|  |                         .unwrap() | ||||||
|  |                         .into_boxed_slice(), | ||||||
|  |                     enc_key_tmp, | ||||||
|  |                 ) | ||||||
|  |             } | ||||||
|  |             None => ( | ||||||
|  |                 public_sock_addr_raw.as_bytes().to_vec().into_boxed_slice(), | ||||||
|  |                 [0u8; 32], | ||||||
|  |             ), | ||||||
|  |         }; | ||||||
| 
 | 
 | ||||||
|         // register network
 |         let virtual_network: Network = { | ||||||
| 
 |             match net::get_request( | ||||||
|         let mut salt: Option<[u8; SALT_AND_IV_SIZE as usize]>; |                 &mut buf, | ||||||
|  |                 &server_SocketAddr, | ||||||
|  |                 &socket, | ||||||
|  |                 &cli.network_id, | ||||||
|  |                 &cli.password, | ||||||
|  |             ) { | ||||||
|  |                 Ok(n) => { | ||||||
|  |                     eprintln!("Network exists joining it"); | ||||||
|  |                     let _ = net::send_heartbeat( | ||||||
|  |                         &mut buf, | ||||||
|  |                         &server_SocketAddr, | ||||||
|  |                         &socket, | ||||||
|  |                         &n, | ||||||
|  |                         &public_sock_addr, | ||||||
|  |                         &iv, | ||||||
|  |                     ); | ||||||
|  |                     n | ||||||
|  |                 } | ||||||
|  |                 Err(e) if e.kind() == ServerResponse::ID_DOESNT_EXIST => { | ||||||
|  |                     eprintln!("Network does not exist creating it!"); | ||||||
|  |                     let tmp_v_net: Network = Network::new( | ||||||
|  |                         match cli.password { | ||||||
|  |                             Some(_) => true, | ||||||
|  |                             None => false, | ||||||
|  |                         }, | ||||||
|  |                         encryption_key, | ||||||
|  |                         cli.network_id, | ||||||
|  |                         salt, | ||||||
|  |                         Vec::with_capacity(1), | ||||||
|  |                     ); | ||||||
|  |                     net::register_request( | ||||||
|  |                         &mut buf, | ||||||
|  |                         &server_SocketAddr, | ||||||
|  |                         &socket, | ||||||
|  |                         &tmp_v_net, | ||||||
|  |                         &public_sock_addr, | ||||||
|  |                         &iv, | ||||||
|  |                     ) | ||||||
|  |                     .unwrap(); | ||||||
|  |                     tmp_v_net | ||||||
|  |                 } | ||||||
|  |                 Err(e) => { | ||||||
|  |                     eprintln!("Failed to get data from server. Reason: {}", e); | ||||||
|  |                     exit(5); //EIO
 | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|     } |     } | ||||||
|     Ok(()) |     Ok(()) | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,22 +1,24 @@ | |||||||
| use std::{ | use std::{ | ||||||
|     io::ErrorKind, |     io::ErrorKind, | ||||||
|     net::{SocketAddr, UdpSocket}, |     net::{SocketAddr, UdpSocket}, | ||||||
|  |     str::FromStr, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| use pea_2_pea::*; | use pea_2_pea::*; | ||||||
| use rand::RngCore; | 
 | ||||||
|  | use super::types; | ||||||
| 
 | 
 | ||||||
| // return data_lenght and number of retryes
 | // return data_lenght and number of retryes
 | ||||||
| pub fn send_and_recv_with_retry( | pub fn send_and_recv_with_retry( | ||||||
|     buf: &mut [u8; BUFFER_SIZE], |     buf: &mut [u8; BUFFER_SIZE], | ||||||
|  |     send_buf: &[u8], | ||||||
|     dst: &SocketAddr, |     dst: &SocketAddr, | ||||||
|     socket: UdpSocket, |     socket: &UdpSocket, | ||||||
|     retry_max: usize, |     retry_max: usize, | ||||||
| ) -> Result<(usize, usize), ServerErrorResponses> { | ) -> Result<(usize, usize), ServerErrorResponses> { | ||||||
|     let mut send_buf = *buf; |  | ||||||
|     let mut retry_count: usize = 0; |     let mut retry_count: usize = 0; | ||||||
|     loop { |     loop { | ||||||
|         match socket.send_to(&mut send_buf, dst) { |         match socket.send_to(send_buf, dst) { | ||||||
|             Ok(s) => { |             Ok(s) => { | ||||||
|                 #[cfg(debug_assertions)] |                 #[cfg(debug_assertions)] | ||||||
|                 eprintln!("send {} bytes", s); |                 eprintln!("send {} bytes", s); | ||||||
| @ -77,10 +79,24 @@ pub fn send_and_recv_with_retry( | |||||||
| pub fn query_request( | pub fn query_request( | ||||||
|     buf: &mut [u8; BUFFER_SIZE], |     buf: &mut [u8; BUFFER_SIZE], | ||||||
|     dst: &SocketAddr, |     dst: &SocketAddr, | ||||||
|     socket: UdpSocket, |     socket: &UdpSocket, | ||||||
| ) -> Result<usize, ServerErrorResponses> { | ) -> Result<String, ServerErrorResponses> { | ||||||
|     match send_and_recv_with_retry(buf, dst, socket, STANDARD_RETRY_MAX) { |     match send_and_recv_with_retry( | ||||||
|         Ok((data_lenght, _)) => return Ok(data_lenght), |         buf, | ||||||
|  |         &[ServerMethods::QUERY as u8], | ||||||
|  |         dst, | ||||||
|  |         socket, | ||||||
|  |         STANDARD_RETRY_MAX, | ||||||
|  |     ) { | ||||||
|  |         Ok((data_lenght, _)) => { | ||||||
|  |             return Ok(match std::str::from_utf8(&buf[1..data_lenght]) { | ||||||
|  |                 Ok(s) => s.to_string(), | ||||||
|  |                 Err(e) => { | ||||||
|  |                     eprint!("id to utf-8 failed: {}", e); | ||||||
|  |                     return Err(ServerErrorResponses::GENERAL_ERROR(format!("{}", e))); | ||||||
|  |                 } | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|         Err(e) => return Err(e), |         Err(e) => return Err(e), | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -88,59 +104,217 @@ pub fn query_request( | |||||||
| pub fn register_request( | pub fn register_request( | ||||||
|     buf: &mut [u8; BUFFER_SIZE], |     buf: &mut [u8; BUFFER_SIZE], | ||||||
|     dst: &SocketAddr, |     dst: &SocketAddr, | ||||||
|     socket: UdpSocket, |     socket: &UdpSocket, | ||||||
|     encryption_key: Option<[u8; 32]>, |     network: &types::Network, | ||||||
|     salt_opt: Option<[u8; SALT_AND_IV_SIZE as usize]>, |     public_sock_addr: &Box<[u8]>, | ||||||
|     mut public_sock_addr: Vec<u8>, |     iv: &[u8; SALT_AND_IV_SIZE as usize], | ||||||
|     network_id: String, |  | ||||||
| ) -> Result<usize, ServerErrorResponses> { | ) -> Result<usize, ServerErrorResponses> { | ||||||
|     buf[0] = ServerMethods::REGISTER as u8; // set metod identification byte
 |     let mut send_buf: Box<[u8]> = vec![ | ||||||
|     buf[RegisterRequestDataPositions::ENCRYPTED as usize] = match encryption_key { |         0u8; | ||||||
|         // stor encryption flag byte
 |         RegisterRequestDataPositions::DATA as usize | ||||||
|         Some(_) => true as u8, |             + network.net_id.len() | ||||||
|         None => false as u8, |             + public_sock_addr.len() | ||||||
|     }; |     ] | ||||||
|     buf[RegisterRequestDataPositions::ID_LEN as usize] = network_id.len() as u8; |     .into_boxed_slice(); | ||||||
|  |     send_buf[0] = ServerMethods::REGISTER as u8; // set metod identification byte
 | ||||||
|  |     send_buf[RegisterRequestDataPositions::ENCRYPTED as usize] = network.encrypted as u8; | ||||||
| 
 | 
 | ||||||
|     buf[RegisterRequestDataPositions::DATA as usize |     send_buf[RegisterRequestDataPositions::ID_LEN as usize] = network.net_id.len() as u8; | ||||||
|         ..RegisterRequestDataPositions::DATA as usize + network_id.len()] |  | ||||||
|         .copy_from_slice(network_id.as_bytes()); // store network id
 |  | ||||||
| 
 | 
 | ||||||
|     let mut iv: [u8; SALT_AND_IV_SIZE as usize] = [0; SALT_AND_IV_SIZE as usize]; |     send_buf[RegisterRequestDataPositions::DATA as usize | ||||||
|     let salt: [u8; SALT_AND_IV_SIZE as usize]; |         ..RegisterRequestDataPositions::DATA as usize + network.net_id.len()] | ||||||
|     match salt_opt { |         .copy_from_slice(network.net_id.as_bytes()); // store network id
 | ||||||
|         Some(s) => salt = s, |  | ||||||
|         None => salt = [0; SALT_AND_IV_SIZE as usize], |  | ||||||
|     } |  | ||||||
|     match encryption_key { |  | ||||||
|         Some(encryption_key) => { |  | ||||||
|             let mut rng = rand::rng(); |  | ||||||
|             rng.fill_bytes(&mut iv); |  | ||||||
|             public_sock_addr = |  | ||||||
|                 shared::crypto::encrypt(&encryption_key, &iv, public_sock_addr.as_slice()).unwrap(); |  | ||||||
|         } |  | ||||||
|         None => { |  | ||||||
|             iv = [0; SALT_AND_IV_SIZE as usize]; |  | ||||||
|         } |  | ||||||
|     }; |  | ||||||
| 
 | 
 | ||||||
|     buf[RegisterRequestDataPositions::IV as usize |     send_buf[RegisterRequestDataPositions::IV as usize | ||||||
|         ..RegisterRequestDataPositions::IV as usize + SALT_AND_IV_SIZE as usize] |         ..RegisterRequestDataPositions::IV as usize + SALT_AND_IV_SIZE as usize] | ||||||
|         .copy_from_slice(&iv); // copy iv ad salt do the request
 |         .copy_from_slice(iv); // copy iv ad salt do the request
 | ||||||
|     buf[RegisterRequestDataPositions::SALT as usize |     send_buf[RegisterRequestDataPositions::SALT as usize | ||||||
|         ..RegisterRequestDataPositions::SALT as usize + SALT_AND_IV_SIZE as usize] |         ..RegisterRequestDataPositions::SALT as usize + SALT_AND_IV_SIZE as usize] | ||||||
|         .copy_from_slice(&salt); |         .copy_from_slice(&network.salt); | ||||||
| 
 | 
 | ||||||
|     buf[RegisterRequestDataPositions::SOCKADDR_LEN as usize] = public_sock_addr.len() as u8; |     send_buf[RegisterRequestDataPositions::SOCKADDR_LEN as usize] = public_sock_addr.len() as u8; | ||||||
| 
 | 
 | ||||||
|     buf[RegisterRequestDataPositions::DATA as usize + network_id.len() |     send_buf[RegisterRequestDataPositions::DATA as usize + network.net_id.len() | ||||||
|         ..RegisterRequestDataPositions::DATA as usize + network_id.len() + public_sock_addr.len()] |         ..RegisterRequestDataPositions::DATA as usize | ||||||
|  |             + network.net_id.len() | ||||||
|  |             + public_sock_addr.len()] | ||||||
|         .copy_from_slice(&public_sock_addr); |         .copy_from_slice(&public_sock_addr); | ||||||
| 
 | 
 | ||||||
|     match send_and_recv_with_retry(buf, dst, socket, STANDARD_RETRY_MAX) { |     match send_and_recv_with_retry(buf, &send_buf, dst, socket, STANDARD_RETRY_MAX) { | ||||||
|         Ok((data_lenght, _)) => return Ok(data_lenght), |         Ok((data_lenght, _)) => return Ok(data_lenght), | ||||||
|         Err(e) => return Err(e), |         Err(e) => return Err(e), | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn get_request() -> Result<usize, ServerErrorResponses> {} | pub fn get_request( | ||||||
|  |     buf: &mut [u8; BUFFER_SIZE], | ||||||
|  |     dst: &SocketAddr, | ||||||
|  |     socket: &UdpSocket, | ||||||
|  |     network_id: &String, | ||||||
|  |     password: &Option<String>, | ||||||
|  | ) -> Result<types::Network, ServerErrorResponses> { | ||||||
|  |     let mut send_buf: Box<[u8]> = | ||||||
|  |         vec![0u8; GetRequestDataPositions::ID as usize + network_id.len()].into_boxed_slice(); | ||||||
|  |     send_buf[0] = ServerMethods::GET as u8; | ||||||
|  |     send_buf[GetRequestDataPositions::ID as usize | ||||||
|  |         ..GetRequestDataPositions::ID as usize + network_id.len()] | ||||||
|  |         .copy_from_slice(network_id.as_bytes()); | ||||||
|  | 
 | ||||||
|  |     // this is unused now it will be used to bounds check in the future
 | ||||||
|  |     let data_lenght: usize = | ||||||
|  |         match send_and_recv_with_retry(buf, &send_buf, dst, socket, STANDARD_RETRY_MAX) { | ||||||
|  |             Ok((data_lenght, _)) => data_lenght, | ||||||
|  |             Err(e) => return Err(e), | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |     let encrypted: bool = if buf[GetResponseDataPositions::ENCRYPTED as usize] != 0 { | ||||||
|  |         match password { | ||||||
|  |             Some(_) => true, | ||||||
|  |             None => panic!("Network is encrypted but no password was provided"), | ||||||
|  |         } | ||||||
|  |     } else { | ||||||
|  |         match password { | ||||||
|  |             Some(_) => { | ||||||
|  |                 eprintln!( | ||||||
|  |                     "Warning! Network is not encrypted but password was provided, ignoring password!" | ||||||
|  |                 ) | ||||||
|  |             } | ||||||
|  |             None => {} | ||||||
|  |         } | ||||||
|  |         false | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     let num_of_clients: u8 = buf[GetResponseDataPositions::NUM_OF_CLIENTS as usize]; | ||||||
|  | 
 | ||||||
|  |     let salt: [u8; SALT_AND_IV_SIZE as usize] = buf[GetResponseDataPositions::SALT as usize | ||||||
|  |         ..GetResponseDataPositions::SALT as usize + SALT_AND_IV_SIZE as usize] | ||||||
|  |         .try_into() | ||||||
|  |         .unwrap(); | ||||||
|  | 
 | ||||||
|  |     let mut offset: usize = 0; | ||||||
|  |     let mut peers: Vec<SocketAddr> = Vec::with_capacity(1); // at least one client
 | ||||||
|  | 
 | ||||||
|  |     let key: [u8; 32] = match password { | ||||||
|  |         Some(p) => shared::crypto::derive_key_from_password(p.as_bytes(), &salt), | ||||||
|  |         None => [0; 32], | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     while num_of_clients != 0 { | ||||||
|  |         let sock_addr_len: u8 = buf[GetResponseDataPositions::CLIENTS as usize + offset]; | ||||||
|  |         let mut iv: [u8; SALT_AND_IV_SIZE as usize] = [0; SALT_AND_IV_SIZE as usize]; | ||||||
|  |         let sock_addr_raw: Box<[u8]> = | ||||||
|  |             buf[GetResponseDataPositions::CLIENTS as usize + 1 + offset + SALT_AND_IV_SIZE as usize | ||||||
|  |                 ..GetResponseDataPositions::CLIENTS as usize | ||||||
|  |                     + 1 | ||||||
|  |                     + offset | ||||||
|  |                     + SALT_AND_IV_SIZE as usize | ||||||
|  |                     + sock_addr_len as usize] | ||||||
|  |                 .to_vec() | ||||||
|  |                 .into_boxed_slice(); | ||||||
|  |         loop { | ||||||
|  |             // loop used to easily skip peer
 | ||||||
|  |             let peer: SocketAddr = if encrypted { | ||||||
|  |                 iv.copy_from_slice( | ||||||
|  |                     &buf[GetResponseDataPositions::CLIENTS as usize + 1 + offset | ||||||
|  |                         ..GetResponseDataPositions::CLIENTS as usize | ||||||
|  |                             + 1 | ||||||
|  |                             + offset | ||||||
|  |                             + SALT_AND_IV_SIZE as usize], | ||||||
|  |                 ); | ||||||
|  |                 match SocketAddr::from_str(&{ | ||||||
|  |                     // sacrificed a goat to borrow checker to make this work
 | ||||||
|  |                     let decrypted = match shared::crypto::decrypt(&key, &iv, &sock_addr_raw) { | ||||||
|  |                         Ok(v) => v, | ||||||
|  |                         Err(_) => { | ||||||
|  |                             eprintln!("Warning peer ignored due to invalid data"); | ||||||
|  |                             break; | ||||||
|  |                         } | ||||||
|  |                     }; | ||||||
|  | 
 | ||||||
|  |                     match std::str::from_utf8(decrypted.as_slice()) { | ||||||
|  |                         Ok(s) => s.to_string(), | ||||||
|  |                         Err(e) => { | ||||||
|  |                             eprint!("id to utf-8 failed: {}", e); | ||||||
|  |                             eprintln!("Warning peer ignored due to invalid data"); | ||||||
|  |                             break; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 }) { | ||||||
|  |                     Ok(s) => s, | ||||||
|  |                     Err(_) => { | ||||||
|  |                         eprintln!("Warning peer ignored due to invalid data"); | ||||||
|  |                         break; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } else { | ||||||
|  |                 match SocketAddr::from_str(&match std::str::from_utf8(&sock_addr_raw) { | ||||||
|  |                     Ok(s) => s.to_string(), | ||||||
|  |                     Err(e) => { | ||||||
|  |                         eprint!("id to utf-8 failed: {}", e); | ||||||
|  |                         eprintln!("Warning peer ignored due to invalid data"); | ||||||
|  |                         break; | ||||||
|  |                     } | ||||||
|  |                 }) { | ||||||
|  |                     Ok(s) => s, | ||||||
|  |                     Err(_) => { | ||||||
|  |                         eprintln!("Warning peer ignored due to invalid data"); | ||||||
|  |                         break; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             peers.push(peer); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         offset += SALT_AND_IV_SIZE as usize + sock_addr_len as usize; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return Ok(types::Network::new( | ||||||
|  |         encrypted, | ||||||
|  |         key, | ||||||
|  |         network_id.to_string(), | ||||||
|  |         salt, | ||||||
|  |         peers, | ||||||
|  |     )); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub fn send_heartbeat( | ||||||
|  |     buf: &mut [u8; BUFFER_SIZE], | ||||||
|  |     dst: &SocketAddr, | ||||||
|  |     socket: &UdpSocket, | ||||||
|  |     network: &types::Network, | ||||||
|  |     my_public_sock_addr: &Box<[u8]>, | ||||||
|  |     iv: &[u8; SALT_AND_IV_SIZE as usize], | ||||||
|  | ) -> Result<usize, ServerErrorResponses> { | ||||||
|  |     let mut send_buf: Box<[u8]> = vec![ | ||||||
|  |         0u8; | ||||||
|  |         HeartBeatRequestDataPositions::IV as usize | ||||||
|  |             + SALT_AND_IV_SIZE as usize | ||||||
|  |             + my_public_sock_addr.len() | ||||||
|  |     ] | ||||||
|  |     .into_boxed_slice(); | ||||||
|  | 
 | ||||||
|  |     send_buf[0] = ServerMethods::HEARTBEAT as u8; | ||||||
|  |     send_buf[HeartBeatRequestDataPositions::ID_LEN as usize] = network.net_id.len() as u8; | ||||||
|  |     send_buf[HeartBeatRequestDataPositions::SOCKADDR_LEN as usize] = | ||||||
|  |         my_public_sock_addr.len() as u8; | ||||||
|  | 
 | ||||||
|  |     send_buf[HeartBeatRequestDataPositions::IV as usize | ||||||
|  |         ..HeartBeatRequestDataPositions::IV as usize + SALT_AND_IV_SIZE as usize] | ||||||
|  |         .copy_from_slice(iv); | ||||||
|  | 
 | ||||||
|  |     send_buf[HeartBeatRequestDataPositions::DATA as usize | ||||||
|  |         ..HeartBeatRequestDataPositions::DATA as usize + network.net_id.len()] | ||||||
|  |         .copy_from_slice(network.net_id.as_bytes()); | ||||||
|  | 
 | ||||||
|  |     send_buf[HeartBeatRequestDataPositions::DATA as usize + network.net_id.len() | ||||||
|  |         ..HeartBeatRequestDataPositions::DATA as usize | ||||||
|  |             + network.net_id.len() | ||||||
|  |             + my_public_sock_addr.len()] | ||||||
|  |         .copy_from_slice(&my_public_sock_addr); | ||||||
|  | 
 | ||||||
|  |     match send_and_recv_with_retry(buf, &send_buf, dst, socket, STANDARD_RETRY_MAX) { | ||||||
|  |         Ok((data_lenght, _)) => return Ok(data_lenght), | ||||||
|  |         Err(e) => return Err(e), | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | |||||||
							
								
								
									
										32
									
								
								src/client/types.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/client/types.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | use pea_2_pea::*; | ||||||
|  | #[readonly::make] | ||||||
|  | pub struct Network { | ||||||
|  |     #[readonly] | ||||||
|  |     pub encrypted: bool, | ||||||
|  |     #[readonly] | ||||||
|  |     pub key: [u8; 32], | ||||||
|  |     #[readonly] | ||||||
|  |     pub net_id: String, | ||||||
|  |     #[readonly] | ||||||
|  |     pub salt: [u8; SALT_AND_IV_SIZE as usize], | ||||||
|  |     #[readonly] | ||||||
|  |     pub peers: Vec<std::net::SocketAddr>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Network { | ||||||
|  |     pub fn new( | ||||||
|  |         encrypted: bool, | ||||||
|  |         key: [u8; 32], | ||||||
|  |         net_id: String, | ||||||
|  |         salt: [u8; SALT_AND_IV_SIZE as usize], | ||||||
|  |         peers: Vec<std::net::SocketAddr>, | ||||||
|  |     ) -> Self { | ||||||
|  |         Network { | ||||||
|  |             encrypted, | ||||||
|  |             key, | ||||||
|  |             net_id, | ||||||
|  |             salt, | ||||||
|  |             peers, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										37
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								src/lib.rs
									
									
									
									
									
								
							| @ -4,7 +4,7 @@ pub const SERVER_PORT: u16 = 3543; | |||||||
| pub const BUFFER_SIZE: usize = 65535; | pub const BUFFER_SIZE: usize = 65535; | ||||||
| pub const DEFAULT_TIMEOUT: u64 = 30; | pub const DEFAULT_TIMEOUT: u64 = 30; | ||||||
| pub const VERSION: &str = "v0.1"; | pub const VERSION: &str = "v0.1"; | ||||||
| pub const SALT_AND_IV_SIZE: u8 = 16; | pub const SALT_AND_IV_SIZE: usize = 16; | ||||||
| pub const STANDARD_RETRY_MAX: usize = 10; | pub const STANDARD_RETRY_MAX: usize = 10; | ||||||
| 
 | 
 | ||||||
| #[repr(u8)] | #[repr(u8)] | ||||||
| @ -14,11 +14,14 @@ pub enum ServerMethods { | |||||||
|     GET = 2, |     GET = 2, | ||||||
|     HEARTBEAT = 3, // this also registers addtional clients
 |     HEARTBEAT = 3, // this also registers addtional clients
 | ||||||
| } | } | ||||||
|  | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | ||||||
| #[allow(non_camel_case_types)] | #[allow(non_camel_case_types)] | ||||||
|  | #[repr(u8)] | ||||||
| pub enum ServerResponse { | pub enum ServerResponse { | ||||||
|     GENERAL_ERROR = 255, |     GENERAL_ERROR = 255, | ||||||
|     ID_EXISTS = 254, |     ID_EXISTS = 254, | ||||||
|     ID_DOESNT_EXIST = 253, // both error since sometimes it is the problem that the id exist and somethimes problem is that is doesn't
 |     ID_DOESNT_EXIST = 253, // both error since sometimes it is the problem that the id exist and somethimes problem is that is doesn't
 | ||||||
|  |     IO = 252,              // had to place it here to avoid creating anther enum
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[allow(non_camel_case_types)] | #[allow(non_camel_case_types)] | ||||||
| @ -55,33 +58,51 @@ impl ServerErrorResponses { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | impl ServerErrorResponses { | ||||||
|  |     pub fn kind(&self) -> ServerResponse { | ||||||
|  |         match self { | ||||||
|  |             ServerErrorResponses::GENERAL_ERROR(_) => ServerResponse::GENERAL_ERROR, | ||||||
|  |             ServerErrorResponses::ID_EXISTS => ServerResponse::ID_EXISTS, | ||||||
|  |             ServerErrorResponses::ID_DOESNT_EXIST => ServerResponse::ID_DOESNT_EXIST, | ||||||
|  |             ServerErrorResponses::IO(_) => ServerResponse::IO, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| #[allow(non_camel_case_types)] | #[allow(non_camel_case_types)] | ||||||
|  | #[repr(usize)] | ||||||
| pub enum RegisterRequestDataPositions { | pub enum RegisterRequestDataPositions { | ||||||
|     ENCRYPTED = 1, // this feeld should be 0 if not encrypted
 |     ENCRYPTED = 1, // this feeld should be 0 if not encrypted
 | ||||||
|     ID_LEN = 2, |     ID_LEN = 2, | ||||||
|     SOCKADDR_LEN = 3, |     SOCKADDR_LEN = 3, | ||||||
|     SALT = 4, |     SALT = 4, | ||||||
|     IV = (SALT_AND_IV_SIZE + RegisterRequestDataPositions::SALT as u8) as isize, |     IV = (SALT_AND_IV_SIZE as usize + RegisterRequestDataPositions::SALT as usize) as usize, | ||||||
|     DATA = (SALT_AND_IV_SIZE + RegisterRequestDataPositions::IV as u8) as isize, // after this there will be id and sockaddr in string or encrypted form after
 |     DATA = (SALT_AND_IV_SIZE as usize + RegisterRequestDataPositions::IV as usize) as usize, // after this there will be id and sockaddr in string or encrypted form after
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[allow(non_camel_case_types)] | #[allow(non_camel_case_types)] | ||||||
|  | #[repr(usize)] | ||||||
|  | pub enum GetRequestDataPositions { | ||||||
|  |     ID = 1, // no need for len since id is the whoule rest of the packet
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[allow(non_camel_case_types)] | ||||||
|  | #[repr(usize)] | ||||||
| pub enum GetResponseDataPositions { | pub enum GetResponseDataPositions { | ||||||
|     ENCRYPTED = 1, // this feeld should be 0 if not encrypted
 |     ENCRYPTED = 1, // this feeld should be 0 if not encrypted
 | ||||||
|     ID_LEN = 2, |     NUM_OF_CLIENTS = 2, | ||||||
|     NUM_OF_CLIENTS = 3, |     SALT = 3, | ||||||
|     SALT = 4, |     CLIENTS = (SALT_AND_IV_SIZE as usize + RegisterRequestDataPositions::SALT as usize) as usize, | ||||||
|     CLIENTS = (SALT_AND_IV_SIZE + RegisterRequestDataPositions::SALT as u8) as isize, |  | ||||||
|     // after this there will be blocks of this sturcture: one byte size of sockaddr than there will be IV that is SALT_AND_IV_SIZE long and after that there will be sockaddr this repeats until the end of packet
 |     // after this there will be blocks of this sturcture: one byte size of sockaddr than there will be IV that is SALT_AND_IV_SIZE long and after that there will be sockaddr this repeats until the end of packet
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[allow(non_camel_case_types)] | #[allow(non_camel_case_types)] | ||||||
|  | #[repr(usize)] | ||||||
| pub enum HeartBeatRequestDataPositions { | pub enum HeartBeatRequestDataPositions { | ||||||
|     ID_LEN = 1, |     ID_LEN = 1, | ||||||
|     SOCKADDR_LEN = 2, |     SOCKADDR_LEN = 2, | ||||||
|     IV = 3, |     IV = 3, | ||||||
|     DATA = (HeartBeatRequestDataPositions::IV as u8 + SALT_AND_IV_SIZE) as isize, // first ID than sockaddr
 |     DATA = (HeartBeatRequestDataPositions::IV as usize + SALT_AND_IV_SIZE as usize) as usize, // first ID than sockaddr
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub mod shared; | pub mod shared; | ||||||
|  | |||||||
| @ -62,7 +62,15 @@ pub async fn handle_request( | |||||||
|                 .find(|elem| elem.map(|s| &s.net_id == &net_id)) // find if id exists
 |                 .find(|elem| elem.map(|s| &s.net_id == &net_id)) // find if id exists
 | ||||||
|             { |             { | ||||||
|                 Some(registration) => registration, |                 Some(registration) => registration, | ||||||
|                 None => {let _ = socket.send_to(&[ServerResponse::ID_DOESNT_EXIST as u8], src); |                 None => {match socket.send_to(&[ServerResponse::ID_DOESNT_EXIST as u8], src){ | ||||||
|  |                 Ok(s) => { | ||||||
|  |                     #[cfg(debug_assertions)] | ||||||
|  |                     eprintln!("send {} bytes", s); | ||||||
|  |                 } | ||||||
|  |                 Err(e) => { | ||||||
|  |                     eprintln!("Error snding data: {}", e); | ||||||
|  |                 } | ||||||
|  |             }; | ||||||
|                     return; |                     return; | ||||||
|                 }, |                 }, | ||||||
|             } |             } | ||||||
|  | |||||||
| @ -1,5 +1,4 @@ | |||||||
| use pea_2_pea::*; | use pea_2_pea::*; | ||||||
| use std::ops::{Deref, DerefMut}; |  | ||||||
| use std::sync::{Arc, atomic::Ordering}; | use std::sync::{Arc, atomic::Ordering}; | ||||||
| 
 | 
 | ||||||
| #[derive(Clone)] | #[derive(Clone)] | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user