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",
|
||||
"colored",
|
||||
"hmac",
|
||||
"libc",
|
||||
"orx-concurrent-vec",
|
||||
"pbkdf2",
|
||||
"rand",
|
||||
@ -757,6 +758,7 @@ dependencies = [
|
||||
"sha2",
|
||||
"smol",
|
||||
"tappers",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1076,6 +1078,28 @@ dependencies = [
|
||||
"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]]
|
||||
name = "windows-core"
|
||||
version = "0.61.2"
|
||||
|
@ -29,5 +29,12 @@ sha2 = "0.10.9"
|
||||
smol = "2.0.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]
|
||||
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 tun;
|
||||
mod types;
|
||||
@ -52,14 +53,15 @@ fn main() -> std::io::Result<()> {
|
||||
}
|
||||
let mut buf: [u8; UDP_BUFFER_SIZE] = [0; UDP_BUFFER_SIZE];
|
||||
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") {
|
||||
// bind to OS assigned random port
|
||||
Ok(socket) => return Ok(socket),
|
||||
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"))]
|
||||
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];
|
||||
ips_used[0] = true; // ignore net addr
|
||||
ips_used[u8::MAX as usize] = true; // ignore broadcast
|
||||
eprintln!(
|
||||
println!(
|
||||
"{} reaching to other peers to obtain ip address",
|
||||
"[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) {
|
||||
Ok(t) => t,
|
||||
Err(e) => {
|
||||
eprintln!(
|
||||
"{} failed to create Tun interface, Error: {}, are you running as root?",
|
||||
"[CRITICAL]".red().bold(),
|
||||
e
|
||||
);
|
||||
return Err(e);
|
||||
let tun_iface = Arc::new(
|
||||
match tun::create_tun_interface(virtual_network.read().unwrap().private_ip) {
|
||||
Ok(t) => t,
|
||||
Err(e) => {
|
||||
eprintln!(
|
||||
"{} failed to create Tun interface, Error: {}, are you running as root?",
|
||||
"[CRITICAL]".red().bold(),
|
||||
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(())
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ use std::{
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
|
||||
use colored::Colorize;
|
||||
use pea_2_pea::*;
|
||||
use rand::{RngCore, rng};
|
||||
use tappers::Netmask;
|
||||
@ -479,3 +480,131 @@ pub fn P2P_hello(
|
||||
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(
|
||||
tun_iface: &tappers::Tun,
|
||||
socket: std::net::UdpSocket,
|
||||
tun_iface: Arc<tappers::Tun>,
|
||||
socket: Arc<std::net::UdpSocket>,
|
||||
network: Arc<RwLock<Network>>,
|
||||
) {
|
||||
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(
|
||||
buf[..data_lenght - 1].to_vec().into(),
|
||||
network.clone(),
|
||||
socket.try_clone().expect("couldn't clone the socket"),
|
||||
socket.clone(),
|
||||
))
|
||||
.detach();
|
||||
}
|
||||
@ -43,7 +43,7 @@ pub async fn read_tun_iface(
|
||||
pub async fn handle_ip_packet(
|
||||
packet_data: Box<[u8]>,
|
||||
network: Arc<RwLock<Network>>,
|
||||
socket: std::net::UdpSocket,
|
||||
socket: Arc<std::net::UdpSocket>,
|
||||
) {
|
||||
let dst_ip = std::net::Ipv4Addr::from(
|
||||
match <[u8; 4]>::try_from(
|
||||
|
Loading…
x
Reference in New Issue
Block a user