finalize P2P comm now just debugging
This commit is contained in:
parent
ddbe156846
commit
c6583ea534
24
Cargo.lock
generated
24
Cargo.lock
generated
@ -749,6 +749,7 @@ dependencies = [
|
|||||||
"clap",
|
"clap",
|
||||||
"colored",
|
"colored",
|
||||||
"hmac",
|
"hmac",
|
||||||
|
"libc",
|
||||||
"orx-concurrent-vec",
|
"orx-concurrent-vec",
|
||||||
"pbkdf2",
|
"pbkdf2",
|
||||||
"rand",
|
"rand",
|
||||||
@ -757,6 +758,7 @@ dependencies = [
|
|||||||
"sha2",
|
"sha2",
|
||||||
"smol",
|
"smol",
|
||||||
"tappers",
|
"tappers",
|
||||||
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1076,6 +1078,28 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu",
|
||||||
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-core"
|
name = "windows-core"
|
||||||
version = "0.61.2"
|
version = "0.61.2"
|
||||||
|
@ -29,5 +29,12 @@ sha2 = "0.10.9"
|
|||||||
smol = "2.0.2"
|
smol = "2.0.2"
|
||||||
tappers = "0.4.2"
|
tappers = "0.4.2"
|
||||||
|
|
||||||
|
[target.'cfg(windows)'.dependencies]
|
||||||
|
winapi = { version = "0.3", features = ["winsock2", "mswsock", "minwindef"] }
|
||||||
|
|
||||||
|
[target.'cfg(unix)'.dependencies]
|
||||||
|
libc = "0.2"
|
||||||
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
no-timeout = []
|
no-timeout = []
|
||||||
|
113
src/client/config.rs
Normal file
113
src/client/config.rs
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
use std::io::ErrorKind;
|
||||||
|
use std::net::{SocketAddr, UdpSocket};
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
use std::os::windows::io::AsRawSocket;
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
use winapi::shared::minwindef::{BOOL, DWORD, FALSE};
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
use winapi::um::mswsock::SIO_UDP_CONNRESET;
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
use winapi::um::winsock2::{SOCKET_ERROR, WSAIoctl};
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
use std::os::unix::io::AsRawFd;
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
fn enable_icmp_errors(socket: &UdpSocket) -> std::io::Result<()> {
|
||||||
|
let socket_handle = socket.as_raw_socket();
|
||||||
|
let mut bytes_returned: DWORD = 0;
|
||||||
|
let enable: BOOL = FALSE;
|
||||||
|
|
||||||
|
let result = unsafe {
|
||||||
|
WSAIoctl(
|
||||||
|
socket_handle as usize,
|
||||||
|
SIO_UDP_CONNRESET,
|
||||||
|
&enable as *const _ as *mut _,
|
||||||
|
std::mem::size_of::<BOOL>() as DWORD,
|
||||||
|
std::ptr::null_mut(),
|
||||||
|
0,
|
||||||
|
&mut bytes_returned,
|
||||||
|
std::ptr::null_mut(),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if result == SOCKET_ERROR {
|
||||||
|
Err(std::io::Error::last_os_error())
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
fn enable_icmp_errors(socket: &UdpSocket) -> std::io::Result<()> {
|
||||||
|
let fd = socket.as_raw_fd();
|
||||||
|
let optval: libc::c_int = 1;
|
||||||
|
|
||||||
|
let ret = unsafe {
|
||||||
|
libc::setsockopt(
|
||||||
|
fd,
|
||||||
|
libc::SOL_IP,
|
||||||
|
libc::IP_RECVERR,
|
||||||
|
&optval as *const _ as *const libc::c_void,
|
||||||
|
std::mem::size_of::<libc::c_int>() as libc::socklen_t,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if ret < 0 {
|
||||||
|
Err(std::io::Error::last_os_error())
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
fn check_icmp_error_queue(socket: &UdpSocket) -> std::io::Result<()> {
|
||||||
|
use libc::{MSG_ERRQUEUE, iovec, msghdr, recvmsg};
|
||||||
|
|
||||||
|
let fd = socket.as_raw_fd();
|
||||||
|
let mut buf = [0u8; 1024];
|
||||||
|
let mut control_buf = [0u8; 1024];
|
||||||
|
|
||||||
|
let mut iov = iovec {
|
||||||
|
iov_base: buf.as_mut_ptr() as *mut libc::c_void,
|
||||||
|
iov_len: buf.len(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut msg: msghdr = unsafe { std::mem::zeroed() };
|
||||||
|
msg.msg_iov = &mut iov;
|
||||||
|
msg.msg_iovlen = 1;
|
||||||
|
msg.msg_control = control_buf.as_mut_ptr() as *mut libc::c_void;
|
||||||
|
msg.msg_controllen = control_buf.len();
|
||||||
|
|
||||||
|
let result = unsafe { recvmsg(fd, &mut msg, MSG_ERRQUEUE) };
|
||||||
|
|
||||||
|
if result < 0 {
|
||||||
|
let error = std::io::Error::last_os_error();
|
||||||
|
if error.kind() == std::io::ErrorKind::WouldBlock {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
return Err(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::NetworkUnreachable,
|
||||||
|
"ICMP destination unreachable received",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
fn check_icmp_error_queue(_socket: &UdpSocket) -> std::io::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(target_os = "linux", target_os = "windows")))]
|
||||||
|
fn enable_icmp_errors(_socket: &UdpSocket) -> std::io::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(target_os = "linux", target_os = "windows")))]
|
||||||
|
fn check_icmp_error_queue(_socket: &UdpSocket) -> std::io::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
mod config;
|
||||||
mod net;
|
mod net;
|
||||||
mod tun;
|
mod tun;
|
||||||
mod types;
|
mod types;
|
||||||
@ -52,14 +53,15 @@ fn main() -> std::io::Result<()> {
|
|||||||
}
|
}
|
||||||
let mut buf: [u8; UDP_BUFFER_SIZE] = [0; UDP_BUFFER_SIZE];
|
let mut buf: [u8; UDP_BUFFER_SIZE] = [0; UDP_BUFFER_SIZE];
|
||||||
let (socket, virtual_network, my_public_sock_addr) = {
|
let (socket, virtual_network, my_public_sock_addr) = {
|
||||||
let socket: UdpSocket = (|| -> std::io::Result<UdpSocket> {
|
let socket: Arc<UdpSocket> = Arc::new(|| -> std::io::Result<UdpSocket> {
|
||||||
match UdpSocket::bind("0.0.0.0:0") {
|
match UdpSocket::bind("0.0.0.0:0") {
|
||||||
// bind to OS assigned random port
|
// bind to OS assigned random port
|
||||||
Ok(socket) => return Ok(socket),
|
Ok(socket) => return Ok(socket),
|
||||||
Err(e) => Err(e), // exit on error
|
Err(e) => Err(e), // exit on error
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
.expect("Failed to bind to any available port");
|
.expect("Failed to bind to any available port")
|
||||||
|
.into();
|
||||||
|
|
||||||
#[cfg(not(feature = "no-timeout"))]
|
#[cfg(not(feature = "no-timeout"))]
|
||||||
socket.set_read_timeout(Some(Duration::new(10, 0)))?; // set timeout to 10 seconds
|
socket.set_read_timeout(Some(Duration::new(10, 0)))?; // set timeout to 10 seconds
|
||||||
@ -178,7 +180,7 @@ fn main() -> std::io::Result<()> {
|
|||||||
let mut ips_used: [bool; u8::MAX as usize + 1] = [false; u8::MAX as usize + 1];
|
let mut ips_used: [bool; u8::MAX as usize + 1] = [false; u8::MAX as usize + 1];
|
||||||
ips_used[0] = true; // ignore net addr
|
ips_used[0] = true; // ignore net addr
|
||||||
ips_used[u8::MAX as usize] = true; // ignore broadcast
|
ips_used[u8::MAX as usize] = true; // ignore broadcast
|
||||||
eprintln!(
|
println!(
|
||||||
"{} reaching to other peers to obtain ip address",
|
"{} reaching to other peers to obtain ip address",
|
||||||
"[LOG]".blue()
|
"[LOG]".blue()
|
||||||
);
|
);
|
||||||
@ -243,17 +245,52 @@ fn main() -> std::io::Result<()> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let tun_iface = match tun::create_tun_interface(virtual_network.read().unwrap().private_ip) {
|
let tun_iface = Arc::new(
|
||||||
Ok(t) => t,
|
match tun::create_tun_interface(virtual_network.read().unwrap().private_ip) {
|
||||||
Err(e) => {
|
Ok(t) => t,
|
||||||
eprintln!(
|
Err(e) => {
|
||||||
"{} failed to create Tun interface, Error: {}, are you running as root?",
|
eprintln!(
|
||||||
"[CRITICAL]".red().bold(),
|
"{} failed to create Tun interface, Error: {}, are you running as root?",
|
||||||
e
|
"[CRITICAL]".red().bold(),
|
||||||
);
|
e
|
||||||
return Err(e);
|
);
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
smol::block_on(async {
|
||||||
|
smol::spawn(tun::read_tun_iface(
|
||||||
|
tun_iface.clone(),
|
||||||
|
socket.clone(),
|
||||||
|
virtual_network.clone(),
|
||||||
|
))
|
||||||
|
.detach();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
buf.fill(0);
|
||||||
|
match socket.recv_from(&mut buf) {
|
||||||
|
Ok((data_lenght, src)) => {
|
||||||
|
smol::spawn(net::handle_incoming_connection(
|
||||||
|
buf,
|
||||||
|
src,
|
||||||
|
virtual_network.clone(),
|
||||||
|
tun_iface.clone(),
|
||||||
|
data_lenght,
|
||||||
|
))
|
||||||
|
.detach();
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprint!(
|
||||||
|
"{} failed to read from socket Error: {}",
|
||||||
|
"[ERROR]".red(),
|
||||||
|
e
|
||||||
|
);
|
||||||
|
exit(5); //EIO
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ use std::{
|
|||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use colored::Colorize;
|
||||||
use pea_2_pea::*;
|
use pea_2_pea::*;
|
||||||
use rand::{RngCore, rng};
|
use rand::{RngCore, rng};
|
||||||
use tappers::Netmask;
|
use tappers::Netmask;
|
||||||
@ -479,3 +480,131 @@ pub fn P2P_hello(
|
|||||||
Err(e) => return Err(e),
|
Err(e) => return Err(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn handle_incoming_connection(
|
||||||
|
buf: [u8; UDP_BUFFER_SIZE],
|
||||||
|
src: SocketAddr,
|
||||||
|
network: Arc<RwLock<types::Network>>,
|
||||||
|
tun_iface: Arc<tappers::Tun>,
|
||||||
|
data_lenght: usize,
|
||||||
|
) {
|
||||||
|
match buf[0] {
|
||||||
|
x if x == P2PMethods::PACKET as u8 => {
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
println!("PACKET from difernt peer receved");
|
||||||
|
|
||||||
|
if network.read().unwrap().encrypted {
|
||||||
|
match shared::crypto::decrypt(
|
||||||
|
&network.read().unwrap().key,
|
||||||
|
&buf[P2PStandardDataPositions::IV as usize
|
||||||
|
..P2PStandardDataPositions::IV as usize + SALT_AND_IV_SIZE],
|
||||||
|
&buf[P2PStandardDataPositions::DATA as usize..data_lenght as usize-1 /*compensate for size and index diference*/],
|
||||||
|
) {
|
||||||
|
Ok(data) => match tun_iface.send(&data) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(e) => eprintln!(
|
||||||
|
"{} failed to write packet to tun interface, Error: {}",
|
||||||
|
"[WARNING]".yellow(),
|
||||||
|
e
|
||||||
|
),
|
||||||
|
},
|
||||||
|
Err(e) => eprintln!(
|
||||||
|
"{} failed to decrypt packet, Error: {}",
|
||||||
|
"[WARNING]".yellow(),
|
||||||
|
e
|
||||||
|
),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
match tun_iface.send(&buf[P2PStandardDataPositions::DATA as usize..data_lenght as usize-1 /*compensate for size and index diference*/]) {
|
||||||
|
Ok(_) => {},
|
||||||
|
Err(e) => eprintln!("{} failed to write packet to tun interface, Error: {}", "[WARNING]".yellow(), e),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x if x == P2PMethods::PEER_HELLO as u8 => {
|
||||||
|
println!("{} peer hello receved from: {}", "[LOG]".blue(), src);
|
||||||
|
|
||||||
|
let tmp_data: Vec<u8>;
|
||||||
|
{
|
||||||
|
let mut network_write_lock = network.write().unwrap();
|
||||||
|
let key: [u8; 32] = network_write_lock.key;
|
||||||
|
let encrypted: bool = network_write_lock.encrypted;
|
||||||
|
network_write_lock.peers.push(Peer::new(
|
||||||
|
src,
|
||||||
|
Some(
|
||||||
|
match std::net::Ipv4Addr::from_str(
|
||||||
|
match std::str::from_utf8(if encrypted {
|
||||||
|
match shared::crypto::decrypt(&key, &buf[P2PStandardDataPositions::IV as usize
|
||||||
|
..P2PStandardDataPositions::IV as usize + SALT_AND_IV_SIZE], &buf[P2PStandardDataPositions::DATA as usize..data_lenght as usize-1 /*compensate for size and index diference*/]) {
|
||||||
|
Ok(data) => {tmp_data = data; &tmp_data},
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!(
|
||||||
|
"{} failed to decrypt ip from peer, ignoring it Error: {}",
|
||||||
|
"[WARNING]".yellow(),
|
||||||
|
e
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
&buf[P2PStandardDataPositions::DATA as usize..data_lenght as usize-1 /*compensate for size and index diference*/]
|
||||||
|
}) {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!(
|
||||||
|
"{} failed to parse ip from peer, ignoring it Error: {}",
|
||||||
|
"[WARNING]".yellow(),
|
||||||
|
e
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
Ok(ip) => ip,
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!(
|
||||||
|
"{} failed to parse ip from peer, ignoring it Error: {}",
|
||||||
|
"[WARNING]".yellow(),
|
||||||
|
e
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x if x == P2PMethods::PEER_GOODBYE as u8 => {
|
||||||
|
println!("{} peer goodbye receved from: {}", "[LOG]".blue(), src);
|
||||||
|
|
||||||
|
let mut network_lock = network.write().unwrap();
|
||||||
|
|
||||||
|
let key = network_lock.key;
|
||||||
|
let encrypted: bool = network_lock.encrypted;
|
||||||
|
|
||||||
|
let mut data_tmp: Vec<u8> = Vec::with_capacity(SALT_AND_IV_SIZE); // block size
|
||||||
|
|
||||||
|
network_lock.peers.retain(|peer| !{peer.private_ip == match std::net::Ipv4Addr::from_str(match std::str::from_utf8( if encrypted {
|
||||||
|
match shared::crypto::decrypt(&key, &buf[P2PStandardDataPositions::IV as usize..P2PStandardDataPositions::IV as usize + SALT_AND_IV_SIZE], &buf[P2PStandardDataPositions::DATA as usize..data_lenght as usize-1 /*compensate for size and index diference*/]) {
|
||||||
|
Ok(data) => {data_tmp = data;
|
||||||
|
&data_tmp},
|
||||||
|
Err(e) => {eprintln!("{} error parsing ip, Error: {}", "[ERROR]".red(), e); return false;},
|
||||||
|
}
|
||||||
|
} else {&buf[P2PStandardDataPositions::DATA as usize..data_lenght as usize-1 /*compensate for size and index diference*/]}) {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(e) => {eprintln!("{} error parsing ip, Error: {}", "[ERROR]".red(), e); return false;},
|
||||||
|
}) {
|
||||||
|
Ok(ip) => ip,
|
||||||
|
Err(e) => {eprintln!("{} error parsing ip, Error: {}", "[ERROR]".red(), e); return false;},
|
||||||
|
} && peer.sock_addr == src});
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {
|
||||||
|
eprintln!(
|
||||||
|
"{} unknown method ID: 0x{:02x}, Droping!",
|
||||||
|
"[WARNING]".bright_yellow(),
|
||||||
|
buf[0]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -21,8 +21,8 @@ pub fn create_tun_interface(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn read_tun_iface(
|
pub async fn read_tun_iface(
|
||||||
tun_iface: &tappers::Tun,
|
tun_iface: Arc<tappers::Tun>,
|
||||||
socket: std::net::UdpSocket,
|
socket: Arc<std::net::UdpSocket>,
|
||||||
network: Arc<RwLock<Network>>,
|
network: Arc<RwLock<Network>>,
|
||||||
) {
|
) {
|
||||||
let mut buf: [u8; IP_BUFFER_SIZE] = [0u8; IP_BUFFER_SIZE];
|
let mut buf: [u8; IP_BUFFER_SIZE] = [0u8; IP_BUFFER_SIZE];
|
||||||
@ -33,7 +33,7 @@ pub async fn read_tun_iface(
|
|||||||
smol::spawn(handle_ip_packet(
|
smol::spawn(handle_ip_packet(
|
||||||
buf[..data_lenght - 1].to_vec().into(),
|
buf[..data_lenght - 1].to_vec().into(),
|
||||||
network.clone(),
|
network.clone(),
|
||||||
socket.try_clone().expect("couldn't clone the socket"),
|
socket.clone(),
|
||||||
))
|
))
|
||||||
.detach();
|
.detach();
|
||||||
}
|
}
|
||||||
@ -43,7 +43,7 @@ pub async fn read_tun_iface(
|
|||||||
pub async fn handle_ip_packet(
|
pub async fn handle_ip_packet(
|
||||||
packet_data: Box<[u8]>,
|
packet_data: Box<[u8]>,
|
||||||
network: Arc<RwLock<Network>>,
|
network: Arc<RwLock<Network>>,
|
||||||
socket: std::net::UdpSocket,
|
socket: Arc<std::net::UdpSocket>,
|
||||||
) {
|
) {
|
||||||
let dst_ip = std::net::Ipv4Addr::from(
|
let dst_ip = std::net::Ipv4Addr::from(
|
||||||
match <[u8; 4]>::try_from(
|
match <[u8; 4]>::try_from(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user