fix some network stuff

This commit is contained in:
PoliEcho 2025-07-30 18:41:32 +02:00
parent c6583ea534
commit dc55e4e1f6
4 changed files with 62 additions and 30 deletions

View File

@ -1,5 +1,5 @@
mod config;
mod net;
mod net_utils;
mod tun;
mod types;
use colored::Colorize;
@ -259,6 +259,10 @@ fn main() -> std::io::Result<()> {
},
);
// timeout is no longer needed
#[cfg(not(feature = "no-timeout"))]
socket.set_read_timeout(None)?;
smol::block_on(async {
smol::spawn(tun::read_tun_iface(
tun_iface.clone(),
@ -281,12 +285,12 @@ fn main() -> std::io::Result<()> {
.detach();
}
Err(e) => {
eprint!(
"{} failed to read from socket Error: {}",
"[ERROR]".red(),
e
eprintln!(
"{} failed to read from socket Error: {}\n{}",
"[WARNING]".red(),
e,
"Retrying".bright_yellow()
);
exit(5); //EIO
}
}
}

View File

@ -5,14 +5,12 @@ use std::{
sync::{Arc, RwLock},
};
use super::types;
use crate::net_utils;
use crate::types::Peer;
use colored::Colorize;
use pea_2_pea::*;
use rand::{RngCore, rng};
use tappers::Netmask;
use crate::types::Peer;
use super::types;
// return data_lenght and number of retryes
pub fn send_and_recv_with_retry(
@ -22,34 +20,51 @@ pub fn send_and_recv_with_retry(
socket: &UdpSocket,
retry_max: usize,
) -> Result<(usize, usize), ServerErrorResponses> {
#[cfg(any(target_os = "linux", target_os = "windows"))]
net_utils::enable_icmp_errors(socket)?;
let mut retry_count: usize = 0;
loop {
match socket.send_to(send_buf, dst) {
Ok(s) => {
#[cfg(debug_assertions)]
eprintln!("send {} bytes", s);
}
Err(e) => {
panic!("Error sending data: {}", e);
}
Err(e) => match e.kind() {
ErrorKind::ConnectionReset
| ErrorKind::ConnectionRefused
| ErrorKind::NetworkUnreachable
| ErrorKind::HostUnreachable => {
return Err(ServerErrorResponses::IO(std::io::Error::new(
e.kind(),
format!("Destination unreachable: {}", e),
)));
}
_ => return Err(ServerErrorResponses::IO(e)),
},
}
#[cfg(target_os = "linux")]
if let Err(icmp_error) = net_utils::check_icmp_error_queue(socket) {
return Err(ServerErrorResponses::IO(icmp_error));
}
match socket.recv_from(buf) {
Ok((data_lenght, src)) => {
Ok((data_length, src)) => {
if src != *dst {
continue;
}
match buf[0] {
x if x == send_buf[0] as u8 => {
return Ok((data_lenght, retry_count));
return Ok((data_length, retry_count));
}
x if x == ServerResponse::GENERAL_ERROR as u8 => {
return Err(ServerErrorResponses::IO(std::io::Error::new(
std::io::ErrorKind::InvalidData,
match std::str::from_utf8(&buf[1..data_lenght]) {
// the firts byte is compensated for sice this is len not index
match std::str::from_utf8(&buf[1..data_length]) {
Ok(s) => s.to_string(),
Err(e) => format!("invalid error string: {}", e).to_string(),
Err(e) => format!("invalid error string: {}", e),
},
)));
}
@ -65,19 +80,32 @@ pub fn send_and_recv_with_retry(
}
}
Err(e) if e.kind() == ErrorKind::WouldBlock || e.kind() == ErrorKind::TimedOut => {
// timedout
#[cfg(target_os = "linux")]
if let Err(icmp_error) = net_utils::check_icmp_error_queue(socket) {
return Err(ServerErrorResponses::IO(icmp_error));
}
if retry_count >= retry_max {
return Err(ServerErrorResponses::IO(std::io::Error::new(
ErrorKind::TimedOut,
"max retry count reached without responce",
"Max retry count reached - destination may be unreachable",
)));
}
retry_count += 1;
continue;
}
Err(e) => {
return Err(ServerErrorResponses::IO(e));
}
Err(e) => match e.kind() {
ErrorKind::ConnectionReset
| ErrorKind::ConnectionRefused
| ErrorKind::NetworkUnreachable
| ErrorKind::HostUnreachable => {
return Err(ServerErrorResponses::IO(std::io::Error::new(
e.kind(),
format!("Destination unreachable during receive: {}", e),
)));
}
_ => return Err(ServerErrorResponses::IO(e)),
},
}
}
}

View File

@ -1,5 +1,4 @@
use std::io::ErrorKind;
use std::net::{SocketAddr, UdpSocket};
use std::net::UdpSocket;
#[cfg(target_os = "windows")]
use std::os::windows::io::AsRawSocket;
@ -14,7 +13,7 @@ use winapi::um::winsock2::{SOCKET_ERROR, WSAIoctl};
use std::os::unix::io::AsRawFd;
#[cfg(target_os = "windows")]
fn enable_icmp_errors(socket: &UdpSocket) -> std::io::Result<()> {
pub 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;
@ -41,7 +40,7 @@ fn enable_icmp_errors(socket: &UdpSocket) -> std::io::Result<()> {
}
#[cfg(target_os = "linux")]
fn enable_icmp_errors(socket: &UdpSocket) -> std::io::Result<()> {
pub fn enable_icmp_errors(socket: &UdpSocket) -> std::io::Result<()> {
let fd = socket.as_raw_fd();
let optval: libc::c_int = 1;
@ -63,7 +62,7 @@ fn enable_icmp_errors(socket: &UdpSocket) -> std::io::Result<()> {
}
#[cfg(target_os = "linux")]
fn check_icmp_error_queue(socket: &UdpSocket) -> std::io::Result<()> {
pub fn check_icmp_error_queue(socket: &UdpSocket) -> std::io::Result<()> {
use libc::{MSG_ERRQUEUE, iovec, msghdr, recvmsg};
let fd = socket.as_raw_fd();

View File

@ -15,11 +15,12 @@ pub fn create_tun_interface(
let mut broadcast_addr_oct = private_ip.octets();
broadcast_addr_oct[3] = 255;
addr_req.set_broadcast(std::net::Ipv4Addr::from(broadcast_addr_oct));
tun_iface.add_addr(private_ip)?;
tun_iface.add_addr(addr_req)?;
tun_iface.set_up()?;
return Ok(tun_iface);
}
pub async fn read_tun_iface(
tun_iface: Arc<tappers::Tun>,
socket: Arc<std::net::UdpSocket>,