fix some network stuff
This commit is contained in:
parent
c6583ea534
commit
dc55e4e1f6
@ -1,5 +1,5 @@
|
|||||||
mod config;
|
|
||||||
mod net;
|
mod net;
|
||||||
|
mod net_utils;
|
||||||
mod tun;
|
mod tun;
|
||||||
mod types;
|
mod types;
|
||||||
use colored::Colorize;
|
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::block_on(async {
|
||||||
smol::spawn(tun::read_tun_iface(
|
smol::spawn(tun::read_tun_iface(
|
||||||
tun_iface.clone(),
|
tun_iface.clone(),
|
||||||
@ -281,12 +285,12 @@ fn main() -> std::io::Result<()> {
|
|||||||
.detach();
|
.detach();
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprint!(
|
eprintln!(
|
||||||
"{} failed to read from socket Error: {}",
|
"{} failed to read from socket Error: {}\n{}",
|
||||||
"[ERROR]".red(),
|
"[WARNING]".red(),
|
||||||
e
|
e,
|
||||||
|
"Retrying".bright_yellow()
|
||||||
);
|
);
|
||||||
exit(5); //EIO
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,14 +5,12 @@ use std::{
|
|||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::types;
|
||||||
|
use crate::net_utils;
|
||||||
|
use crate::types::Peer;
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
use pea_2_pea::*;
|
use pea_2_pea::*;
|
||||||
use rand::{RngCore, rng};
|
use rand::{RngCore, rng};
|
||||||
use tappers::Netmask;
|
|
||||||
|
|
||||||
use crate::types::Peer;
|
|
||||||
|
|
||||||
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(
|
||||||
@ -22,34 +20,51 @@ pub fn send_and_recv_with_retry(
|
|||||||
socket: &UdpSocket,
|
socket: &UdpSocket,
|
||||||
retry_max: usize,
|
retry_max: usize,
|
||||||
) -> Result<(usize, usize), ServerErrorResponses> {
|
) -> Result<(usize, usize), ServerErrorResponses> {
|
||||||
|
#[cfg(any(target_os = "linux", target_os = "windows"))]
|
||||||
|
net_utils::enable_icmp_errors(socket)?;
|
||||||
|
|
||||||
let mut retry_count: usize = 0;
|
let mut retry_count: usize = 0;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match socket.send_to(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);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => match e.kind() {
|
||||||
panic!("Error sending data: {}", e);
|
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) {
|
match socket.recv_from(buf) {
|
||||||
Ok((data_lenght, src)) => {
|
Ok((data_length, src)) => {
|
||||||
if src != *dst {
|
if src != *dst {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
match buf[0] {
|
match buf[0] {
|
||||||
x if x == send_buf[0] as u8 => {
|
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 => {
|
x if x == ServerResponse::GENERAL_ERROR as u8 => {
|
||||||
return Err(ServerErrorResponses::IO(std::io::Error::new(
|
return Err(ServerErrorResponses::IO(std::io::Error::new(
|
||||||
std::io::ErrorKind::InvalidData,
|
std::io::ErrorKind::InvalidData,
|
||||||
match std::str::from_utf8(&buf[1..data_lenght]) {
|
match std::str::from_utf8(&buf[1..data_length]) {
|
||||||
// the firts byte is compensated for sice this is len not index
|
|
||||||
Ok(s) => s.to_string(),
|
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 => {
|
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 {
|
if retry_count >= retry_max {
|
||||||
return Err(ServerErrorResponses::IO(std::io::Error::new(
|
return Err(ServerErrorResponses::IO(std::io::Error::new(
|
||||||
ErrorKind::TimedOut,
|
ErrorKind::TimedOut,
|
||||||
"max retry count reached without responce",
|
"Max retry count reached - destination may be unreachable",
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
retry_count += 1;
|
retry_count += 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => match e.kind() {
|
||||||
return Err(ServerErrorResponses::IO(e));
|
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)),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use std::io::ErrorKind;
|
use std::net::UdpSocket;
|
||||||
use std::net::{SocketAddr, UdpSocket};
|
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
use std::os::windows::io::AsRawSocket;
|
use std::os::windows::io::AsRawSocket;
|
||||||
@ -14,7 +13,7 @@ use winapi::um::winsock2::{SOCKET_ERROR, WSAIoctl};
|
|||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[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 socket_handle = socket.as_raw_socket();
|
||||||
let mut bytes_returned: DWORD = 0;
|
let mut bytes_returned: DWORD = 0;
|
||||||
let enable: BOOL = FALSE;
|
let enable: BOOL = FALSE;
|
||||||
@ -41,7 +40,7 @@ fn enable_icmp_errors(socket: &UdpSocket) -> std::io::Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[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 fd = socket.as_raw_fd();
|
||||||
let optval: libc::c_int = 1;
|
let optval: libc::c_int = 1;
|
||||||
|
|
||||||
@ -63,7 +62,7 @@ fn enable_icmp_errors(socket: &UdpSocket) -> std::io::Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[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};
|
use libc::{MSG_ERRQUEUE, iovec, msghdr, recvmsg};
|
||||||
|
|
||||||
let fd = socket.as_raw_fd();
|
let fd = socket.as_raw_fd();
|
@ -15,11 +15,12 @@ pub fn create_tun_interface(
|
|||||||
let mut broadcast_addr_oct = private_ip.octets();
|
let mut broadcast_addr_oct = private_ip.octets();
|
||||||
broadcast_addr_oct[3] = 255;
|
broadcast_addr_oct[3] = 255;
|
||||||
addr_req.set_broadcast(std::net::Ipv4Addr::from(broadcast_addr_oct));
|
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()?;
|
tun_iface.set_up()?;
|
||||||
return Ok(tun_iface);
|
return Ok(tun_iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub async fn read_tun_iface(
|
pub async fn read_tun_iface(
|
||||||
tun_iface: Arc<tappers::Tun>,
|
tun_iface: Arc<tappers::Tun>,
|
||||||
socket: Arc<std::net::UdpSocket>,
|
socket: Arc<std::net::UdpSocket>,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user