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