Compare commits
4 Commits
4a6ac4a8b9
...
f070bc713b
| Author | SHA1 | Date | |
|---|---|---|---|
| f070bc713b | |||
| ee4d4f9cf6 | |||
| e8f4498806 | |||
| d0ec1e29c6 |
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
// "rust-analyzer.cargo.target": "x86_64-pc-windows-gnu",
|
// "rust-analyzer.cargo.target": "x86_64-pc-windows-gnu",
|
||||||
// "rust-analyzer.cargo.target": "x86_64-unknown-linux-gnu",
|
// "rust-analyzer.cargo.target": "x86_64-unknown-linux-gnu",
|
||||||
|
|
||||||
// "rust-analyzer.cargo.features": ["tun"]
|
// "rust-analyzer.cargo.features": ["tun"]
|
||||||
}
|
}
|
||||||
581
Cargo.lock
generated
581
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -50,6 +50,7 @@ default-net = "0.22.0"
|
|||||||
socket2 = "0.6.3"
|
socket2 = "0.6.3"
|
||||||
hostname = "0.4.2"
|
hostname = "0.4.2"
|
||||||
sysinfo = "0.38.4"
|
sysinfo = "0.38.4"
|
||||||
|
tun-rs = { version = "2.8.5", features = ["async"] }
|
||||||
# rolling-file = { path = "../rolling-file" }
|
# rolling-file = { path = "../rolling-file" }
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
|
|||||||
@ -551,17 +551,16 @@ impl ArpWaitList {
|
|||||||
if (now - item.timestamp) > 5 {
|
if (now - item.timestamp) > 5 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let packet = form_ethernet_packet(src_mac, mac, item.origin_data);
|
let mut packet = form_ethernet_packet(src_mac, mac, item.origin_data);
|
||||||
|
|
||||||
let pkt_size = packet.len();
|
let pkt_size = packet.len();
|
||||||
|
|
||||||
let Ok(encrypted) = edge.encryptor.load().encrypt(&packet) else {
|
let encryptor = edge.encryptor.load();
|
||||||
// let Ok(encrypted) = edge.encryptor.read().unwrap().encrypt(&packet) else {
|
if let Err(e) = encryptor.encrypt(&mut packet) {
|
||||||
// let Ok(encrypted) = aes_encrypt(&encrypt_key, &packet) else {
|
error!("failed to encrypt packet request: {:?}", e);
|
||||||
error!("failed to encrypt packet request");
|
|
||||||
return;
|
return;
|
||||||
};
|
}
|
||||||
let data_bytes = Bytes::from(encrypted);
|
let data_bytes = packet.freeze();
|
||||||
let data = SdlData {
|
let data = SdlData {
|
||||||
is_p2p: true,
|
is_p2p: true,
|
||||||
network_id,
|
network_id,
|
||||||
|
|||||||
@ -1,22 +1,20 @@
|
|||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::sync::atomic::{Ordering};
|
use std::sync::atomic::Ordering;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use crate::config::{TCP_PING_TIME};
|
use crate::config::TCP_PING_TIME;
|
||||||
use crate::network::ipv6::run_ipv6;
|
use crate::network::ipv6::run_ipv6;
|
||||||
use crate::network::{
|
use crate::network::{get_edge, ping_to_sn, read_and_parse_packet, TunTapPacketHandler};
|
||||||
get_edge, ping_to_sn, read_and_parse_packet, TunTapPacketHandler,
|
|
||||||
};
|
|
||||||
use crate::tcp::{init_quic_conn, send_stun_request};
|
use crate::tcp::{init_quic_conn, send_stun_request};
|
||||||
use crate::utils::{send_to_sock, CommandLine};
|
use crate::utils::{send_to_sock, CommandLine};
|
||||||
use crate::{ConnectionInfo};
|
use crate::ConnectionInfo;
|
||||||
use bytes::BytesMut;
|
use bytes::BytesMut;
|
||||||
use etherparse::{PacketBuilder};
|
use etherparse::PacketBuilder;
|
||||||
use sdlan_sn_rs::peer::{SdlanSock};
|
use sdlan_sn_rs::peer::SdlanSock;
|
||||||
use sdlan_sn_rs::utils::{get_current_timestamp, ip_to_string, is_multi_broadcast};
|
use sdlan_sn_rs::utils::{get_current_timestamp, ip_to_string, is_multi_broadcast};
|
||||||
use sdlan_sn_rs::utils::{Mac, Result};
|
use sdlan_sn_rs::utils::{Mac, Result};
|
||||||
use tokio::net::{UdpSocket};
|
use tokio::net::UdpSocket;
|
||||||
use tokio::sync::mpsc::{channel, Receiver, Sender};
|
use tokio::sync::mpsc::{channel, Receiver, Sender};
|
||||||
use tokio_util::sync::CancellationToken;
|
use tokio_util::sync::CancellationToken;
|
||||||
|
|
||||||
@ -120,7 +118,11 @@ pub async fn async_main(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run_edge_loop(eee: &'static Node, global_dns_rx: Receiver<(Vec<u8>, SocketAddr)>, cancel: CancellationToken) {
|
async fn run_edge_loop(
|
||||||
|
eee: &'static Node,
|
||||||
|
global_dns_rx: Receiver<(Vec<u8>, SocketAddr)>,
|
||||||
|
cancel: CancellationToken,
|
||||||
|
) {
|
||||||
ping_to_sn().await;
|
ping_to_sn().await;
|
||||||
{
|
{
|
||||||
let cancel2 = cancel.clone();
|
let cancel2 = cancel.clone();
|
||||||
@ -202,7 +204,7 @@ pub async fn loop_socket_v4(
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_dns_reply(sock: &Arc<UdpSocket>) -> Option<Vec<u8>> {
|
async fn receive_dns_reply(sock: &Arc<UdpSocket>) -> Option<Vec<u8>> {
|
||||||
let mut reply = vec![0;1024];
|
let mut reply = vec![0; 1024];
|
||||||
if let Ok((size, _from)) = sock.recv_from(&mut reply).await {
|
if let Ok((size, _from)) = sock.recv_from(&mut reply).await {
|
||||||
if size == 0 {
|
if size == 0 {
|
||||||
// closed
|
// closed
|
||||||
@ -214,7 +216,11 @@ async fn receive_dns_reply(sock: &Arc<UdpSocket>) -> Option<Vec<u8>> {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn loop_tap(eee: &'static Node, mut dns_rx: Receiver<(Vec<u8>, SocketAddr)>, cancel: CancellationToken) {
|
async fn loop_tap(
|
||||||
|
eee: &'static Node,
|
||||||
|
mut dns_rx: Receiver<(Vec<u8>, SocketAddr)>,
|
||||||
|
cancel: CancellationToken,
|
||||||
|
) {
|
||||||
debug!("loop tap");
|
debug!("loop tap");
|
||||||
let (tx, mut rx) = channel(10);
|
let (tx, mut rx) = channel(10);
|
||||||
tokio::spawn(async {
|
tokio::spawn(async {
|
||||||
@ -233,10 +239,10 @@ async fn loop_tap(eee: &'static Node, mut dns_rx: Receiver<(Vec<u8>, SocketAddr)
|
|||||||
if let Ok(mut dns) = simple_dns::Packet::parse(&data.0) {
|
if let Ok(mut dns) = simple_dns::Packet::parse(&data.0) {
|
||||||
let transaction_id = dns.id();
|
let transaction_id = dns.id();
|
||||||
if let Some((ip, port, origin_transaction_id)) = eee.dns_matcher.get_client_info(transaction_id) {
|
if let Some((ip, port, origin_transaction_id)) = eee.dns_matcher.get_client_info(transaction_id) {
|
||||||
warn!("got dns reply from global 223.5.5.5, will send to {}:{}",
|
warn!("got dns reply from global 223.5.5.5, will send to {}:{}",
|
||||||
ip_to_string(&ip), port);
|
ip_to_string(&ip), port);
|
||||||
|
|
||||||
|
|
||||||
let dstmac = eee.device_config.get_mac();
|
let dstmac = eee.device_config.get_mac();
|
||||||
let srcmac = eee.device_config.dns_mac;
|
let srcmac = eee.device_config.dns_mac;
|
||||||
|
|
||||||
@ -293,23 +299,25 @@ async fn loop_tap(eee: &'static Node, mut dns_rx: Receiver<(Vec<u8>, SocketAddr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "tun", target_os = "windows"))]
|
#[cfg(any(feature = "tun", target_os = "windows"))]
|
||||||
fn get_data_from_tun_with_layer2_zeroed(eee: &Node) -> BytesMut {
|
async fn get_data_from_tun_with_layer2_zeroed(eee: &Node) -> BytesMut {
|
||||||
let mut temp = BytesMut::zeroed(1514);
|
let mut temp = BytesMut::zeroed(1514);
|
||||||
// let mut temp = BytesMut::with_capacity(1514);
|
// let mut temp = BytesMut::with_capacity(1514);
|
||||||
let mut data_buf = temp.split_off(14);
|
let mut data_buf = temp.split_off(14);
|
||||||
|
let Ok(size) = eee.device.recv(&mut data_buf).await else {
|
||||||
let Ok(size) = eee.device.recv(&mut data_buf) else {
|
error!("failed to receive");
|
||||||
return BytesMut::new();
|
return BytesMut::new();
|
||||||
};
|
};
|
||||||
|
warn!("got {} bytes from tun with layer 2", size);
|
||||||
|
|
||||||
data_buf.truncate(size);
|
data_buf.truncate(size);
|
||||||
temp.unsplit(data_buf);
|
temp.unsplit(data_buf);
|
||||||
temp
|
temp
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "tun"))]
|
#[cfg(not(feature = "tun"))]
|
||||||
fn get_data_from_tap_with_layer2(eee: &Node) -> BytesMut {
|
async fn get_data_from_tap_with_layer2(eee: &Node) -> BytesMut {
|
||||||
let mut buf = BytesMut::zeroed(1514);
|
let mut buf = BytesMut::zeroed(1514);
|
||||||
let Ok(size) = eee.device.recv(&mut buf) else {
|
let Ok(size) = eee.device.recv(&mut buf).await else {
|
||||||
return BytesMut::new();
|
return BytesMut::new();
|
||||||
};
|
};
|
||||||
buf.truncate(size);
|
buf.truncate(size);
|
||||||
@ -318,18 +326,17 @@ fn get_data_from_tap_with_layer2(eee: &Node) -> BytesMut {
|
|||||||
|
|
||||||
async fn get_tun_flow(eee: &'static Node, tx: Sender<BytesMut>) {
|
async fn get_tun_flow(eee: &'static Node, tx: Sender<BytesMut>) {
|
||||||
loop {
|
loop {
|
||||||
let buf = tokio::task::spawn_blocking(|| {
|
let buf = {
|
||||||
#[cfg(any(feature = "tun", target_os = "windows"))]
|
#[cfg(any(feature = "tun", target_os = "windows"))]
|
||||||
let data = get_data_from_tun_with_layer2_zeroed(eee);
|
let data = get_data_from_tun_with_layer2_zeroed(eee).await;
|
||||||
#[cfg(all(not(feature = "tun"), not(target_os="windows")))]
|
#[cfg(all(not(feature = "tun"), not(target_os = "windows")))]
|
||||||
let data = get_data_from_tap_with_layer2(eee);
|
let data = get_data_from_tap_with_layer2(eee).await;
|
||||||
|
|
||||||
data
|
data
|
||||||
})
|
};
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
if buf.len() == 0 {
|
if buf.len() == 0 {
|
||||||
|
error!("buf length is zero, quitting loop");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if let Err(e) = tx.send(buf).await {
|
if let Err(e) = tx.send(buf).await {
|
||||||
@ -360,18 +367,14 @@ async fn read_and_parse_tun_packet(eee: &'static Node, buf: BytesMut) {
|
|||||||
async fn edge_send_packet_to_net(eee: &Node, data: BytesMut) {
|
async fn edge_send_packet_to_net(eee: &Node, data: BytesMut) {
|
||||||
// debug!("edge send packet to net({} bytes): {:?}", data.len(), data);
|
// debug!("edge send packet to net({} bytes): {:?}", data.len(), data);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
let encrypt_key = eee.get_encrypt_key();
|
let encrypt_key = eee.get_encrypt_key();
|
||||||
if encrypt_key.len() == 0 {
|
if encrypt_key.len() == 0 {
|
||||||
error!("drop tun packet due to encrypt key len is 0");
|
error!("drop tun packet due to encrypt key len is 0");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
if let Err(e) = eee
|
if let Err(e) = eee.device.handle_packet_from_device(data).await {
|
||||||
.device
|
|
||||||
.handle_packet_from_device(data)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
error!("failed to handle packet from device: {}", e.to_string());
|
error!("failed to handle packet from device: {}", e.to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,16 +17,17 @@ use tokio::sync::mpsc::Sender;
|
|||||||
use tracing::{debug, error, warn};
|
use tracing::{debug, error, warn};
|
||||||
|
|
||||||
use crate::network::{ArpTable, RouteTable2};
|
use crate::network::{ArpTable, RouteTable2};
|
||||||
use crate::utils::DynamicDNSClient;
|
|
||||||
use crate::pb::{
|
use crate::pb::{
|
||||||
encode_to_tcp_message, encode_to_udp_message, SdlArpRequest, SdlEmpty, SdlStunProbe,
|
encode_to_tcp_message, encode_to_udp_message, SdlArpRequest, SdlEmpty, SdlStunProbe,
|
||||||
SdlStunProbeReply,
|
SdlStunProbeReply,
|
||||||
};
|
};
|
||||||
use crate::quic::quic_init;
|
use crate::quic::quic_init;
|
||||||
use crate::tcp::{get_quic_write_conn, NatType, PacketType, StunProbeAttr};
|
use crate::tcp::{get_quic_write_conn, NatType, PacketType, StunProbeAttr};
|
||||||
|
use crate::utils::DynamicDNSClient;
|
||||||
use crate::utils::Socket;
|
use crate::utils::Socket;
|
||||||
use crate::{
|
use crate::{
|
||||||
CommandLine, ConnectionInfo, DNSMatcher, ErrorReport, ErrorSeverity, MyEncryptor, RuleCache, get_base_dir, get_default_interface
|
get_base_dir, get_default_interface, CommandLine, ConnectionInfo, DNSMatcher, ErrorReport,
|
||||||
|
ErrorSeverity, MyEncryptor, RuleCache,
|
||||||
};
|
};
|
||||||
|
|
||||||
use sdlan_sn_rs::peer::{IpSubnet, V6Info};
|
use sdlan_sn_rs::peer::{IpSubnet, V6Info};
|
||||||
@ -111,27 +112,23 @@ pub async fn init_edge(
|
|||||||
// let tcpsock = TCPSocket::build("121.4.79.234:1234").await?;
|
// let tcpsock = TCPSocket::build("121.4.79.234:1234").await?;
|
||||||
let tcp_pong = Arc::new(AtomicU64::new(0));
|
let tcp_pong = Arc::new(AtomicU64::new(0));
|
||||||
|
|
||||||
|
let iface = match new_iface("dev") {
|
||||||
let mode = if cfg!(not(feature = "tun")) {
|
|
||||||
Mode::Tap
|
|
||||||
} else {
|
|
||||||
Mode::Tun
|
|
||||||
};
|
|
||||||
|
|
||||||
let iface = match new_iface("dev", mode) {
|
|
||||||
Ok(iface) => iface,
|
Ok(iface) => iface,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
if let Some(ref chan) = error_report_channel {
|
if let Some(ref chan) = error_report_channel {
|
||||||
println!("sending one panic");
|
println!("sending one panic");
|
||||||
chan.send(ErrorReport { severity: ErrorSeverity::Panic, message: e.to_string() }).await;
|
chan.send(ErrorReport {
|
||||||
|
severity: ErrorSeverity::Panic,
|
||||||
|
message: e.to_string(),
|
||||||
|
})
|
||||||
|
.await;
|
||||||
return Err(e.into());
|
return Err(e.into());
|
||||||
} else {
|
} else {
|
||||||
panic!("new iface failed: {}", e.to_string());
|
panic!("new iface failed: {}", e.to_string());
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
let edge = Node::new(
|
let edge = Node::new(
|
||||||
mac,
|
mac,
|
||||||
pubkey,
|
pubkey,
|
||||||
@ -320,7 +317,6 @@ pub struct Node {
|
|||||||
//cookie_match: DashMap<u32, oneshot::Sender<SdlStunProbeReply>>,
|
//cookie_match: DashMap<u32, oneshot::Sender<SdlStunProbeReply>>,
|
||||||
pub cookie_match: Queryer,
|
pub cookie_match: Queryer,
|
||||||
// packet_id_match: DashMap<u32, oneshot::Sender<RegisterSuperFeedback>>,
|
// packet_id_match: DashMap<u32, oneshot::Sender<RegisterSuperFeedback>>,
|
||||||
|
|
||||||
exclusive_tcp: TcpListener,
|
exclusive_tcp: TcpListener,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -478,7 +474,6 @@ impl Node {
|
|||||||
virtual_iface: Iface,
|
virtual_iface: Iface,
|
||||||
tcp_listener: TcpListener,
|
tcp_listener: TcpListener,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
#[cfg(any(feature = "tun", target_os = "windows"))]
|
#[cfg(any(feature = "tun", target_os = "windows"))]
|
||||||
arp_table: ArpTable::new(),
|
arp_table: ArpTable::new(),
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
use std::{net::SocketAddr, sync::atomic::Ordering, time::Duration};
|
use std::{net::SocketAddr, sync::atomic::Ordering, time::Duration};
|
||||||
|
|
||||||
use crate::FiveTuple;
|
|
||||||
use crate::pb::SdlPolicyRequest;
|
use crate::pb::SdlPolicyRequest;
|
||||||
use crate::tcp::{NatType, get_quic_write_conn};
|
use crate::tcp::{get_quic_write_conn, NatType};
|
||||||
|
use crate::FiveTuple;
|
||||||
use crate::{network::TunTapPacketHandler, utils::mac_to_string};
|
use crate::{network::TunTapPacketHandler, utils::mac_to_string};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -11,19 +11,19 @@ use crate::{
|
|||||||
encode_to_tcp_message, encode_to_udp_message, SdlData, SdlEmpty, SdlPeerInfo, SdlQueryInfo,
|
encode_to_tcp_message, encode_to_udp_message, SdlData, SdlEmpty, SdlPeerInfo, SdlQueryInfo,
|
||||||
SdlRegister, SdlRegisterAck, SdlStunProbeReply,
|
SdlRegister, SdlRegisterAck, SdlStunProbeReply,
|
||||||
},
|
},
|
||||||
tcp::{PacketType},
|
tcp::PacketType,
|
||||||
utils::{send_to_sock, Socket},
|
utils::{send_to_sock, Socket},
|
||||||
};
|
};
|
||||||
use bytes::BytesMut;
|
use bytes::BytesMut;
|
||||||
use etherparse::{Ethernet2Header, IpNumber, PacketHeaders, ip_number};
|
use etherparse::{ip_number, Ethernet2Header, IpNumber, PacketHeaders};
|
||||||
use prost::Message;
|
use prost::Message;
|
||||||
use sdlan_sn_rs::utils::{BROADCAST_MAC};
|
use sdlan_sn_rs::utils::BROADCAST_MAC;
|
||||||
use sdlan_sn_rs::{
|
use sdlan_sn_rs::{
|
||||||
config::{AF_INET, AF_INET6},
|
config::{AF_INET, AF_INET6},
|
||||||
peer::{is_sdlan_sock_equal, SdlanSock, V6Info},
|
peer::{is_sdlan_sock_equal, SdlanSock, V6Info},
|
||||||
utils::{
|
utils::{
|
||||||
get_current_timestamp, get_sdlan_sock_from_socketaddr, is_multi_broadcast,
|
get_current_timestamp, get_sdlan_sock_from_socketaddr, is_multi_broadcast, Mac, Result,
|
||||||
Mac, Result, SDLanError,
|
SDLanError,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -569,7 +569,17 @@ pub async fn check_peer_registration_needed(
|
|||||||
}
|
}
|
||||||
let origin_family = k.sock.family;
|
let origin_family = k.sock.family;
|
||||||
if origin_family != peer_sock.family {
|
if origin_family != peer_sock.family {
|
||||||
return;
|
if peer_sock.family == AF_INET6 && origin_family == AF_INET {
|
||||||
|
info!(
|
||||||
|
"Upgrading peer {} from IPv4 to IPv6 P2P",
|
||||||
|
mac_to_string(&src_mac)
|
||||||
|
);
|
||||||
|
|
||||||
|
// k.sock = peer_sock.deepcopy();
|
||||||
|
// k.last_seen.store(now, Ordering::Relaxed);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
if peer_sock.family == AF_INET6 && k.sock.read().unwrap().family == AF_INET {
|
if peer_sock.family == AF_INET6 && k.sock.read().unwrap().family == AF_INET {
|
||||||
@ -833,11 +843,8 @@ async fn renew_identity_request(eee: &Node, identity: u32) {
|
|||||||
// println!("policy request: {:?}", policy_request);
|
// println!("policy request: {:?}", policy_request);
|
||||||
// debug!("send register super: {:?}", register_super);
|
// debug!("send register super: {:?}", register_super);
|
||||||
// let packet_id = edge.get_next_packet_id();
|
// let packet_id = edge.get_next_packet_id();
|
||||||
let data = encode_to_tcp_message(
|
let data =
|
||||||
Some(policy_request),
|
encode_to_tcp_message(Some(policy_request), PacketType::PolicyRequest as u8).unwrap();
|
||||||
PacketType::PolicyRequest as u8,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let stream = get_quic_write_conn();
|
let stream = get_quic_write_conn();
|
||||||
if let Err(e) = stream.send(data).await {
|
if let Err(e) = stream.send(data).await {
|
||||||
@ -855,31 +862,34 @@ async fn handle_tun_packet(
|
|||||||
//let key = eee.get_encrypt_key();
|
//let key = eee.get_encrypt_key();
|
||||||
|
|
||||||
// if key.len() == 0 {
|
// if key.len() == 0 {
|
||||||
// check the encrypt key
|
// check the encrypt key
|
||||||
// error!("packet encrypt key not provided");
|
// error!("packet encrypt key not provided");
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// test_aes(key.as_slice());
|
// test_aes(key.as_slice());
|
||||||
|
|
||||||
let origin = eee.encryptor.load().decrypt(&payload);
|
let mut payload = BytesMut::from(payload);
|
||||||
// let origin = eee.encryptor.read().unwrap().decrypt(&payload);
|
let decrypt_res = eee.encryptor.load().decrypt(&mut payload);
|
||||||
// let origin = aes_decrypt(&payload);
|
if let Err(_e) = decrypt_res {
|
||||||
if let Err(_e) = origin {
|
|
||||||
error!("failed to decrypt original data");
|
error!("failed to decrypt original data");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let data = origin.unwrap();
|
let data = payload;
|
||||||
let Ok(headers) = PacketHeaders::from_ethernet_slice(&data) else {
|
let Ok(headers) = PacketHeaders::from_ethernet_slice(&data) else {
|
||||||
error!("failed to parse packet");
|
error!("failed to parse packet");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
if _from_sn {
|
if _from_sn {
|
||||||
eee.stats.rx_sup.fetch_add(data.len() as u64, Ordering::Relaxed);
|
eee.stats
|
||||||
|
.rx_sup
|
||||||
|
.fetch_add(data.len() as u64, Ordering::Relaxed);
|
||||||
} else {
|
} else {
|
||||||
eee.stats.rx_p2p.fetch_add(data.len() as u64, Ordering::Relaxed);
|
eee.stats
|
||||||
|
.rx_p2p
|
||||||
|
.fetch_add(data.len() as u64, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ip) = headers.net {
|
if let Some(ip) = headers.net {
|
||||||
@ -888,7 +898,6 @@ async fn handle_tun_packet(
|
|||||||
let protocol = ipv4.protocol;
|
let protocol = ipv4.protocol;
|
||||||
match protocol {
|
match protocol {
|
||||||
ip_number::TCP => {
|
ip_number::TCP => {
|
||||||
|
|
||||||
let Some(transport) = headers.transport else {
|
let Some(transport) = headers.transport else {
|
||||||
error!("failed to get transport header");
|
error!("failed to get transport header");
|
||||||
return;
|
return;
|
||||||
@ -904,9 +913,13 @@ async fn handle_tun_packet(
|
|||||||
dst_ip: ipv4.source.into(),
|
dst_ip: ipv4.source.into(),
|
||||||
src_port: tcp_header.destination_port,
|
src_port: tcp_header.destination_port,
|
||||||
dst_port: tcp_header.source_port,
|
dst_port: tcp_header.source_port,
|
||||||
proto:IpNumber::TCP.0,
|
proto: IpNumber::TCP.0,
|
||||||
};
|
};
|
||||||
let (valid, need_refresh) = eee.rule_cache.is_identity_ok(eee.config.allow_routing.load(Ordering::Relaxed), pkt.identity_id, five_tuple);
|
let (valid, need_refresh) = eee.rule_cache.is_identity_ok(
|
||||||
|
eee.config.allow_routing.load(Ordering::Relaxed),
|
||||||
|
pkt.identity_id,
|
||||||
|
five_tuple,
|
||||||
|
);
|
||||||
if need_refresh {
|
if need_refresh {
|
||||||
renew_identity_request(eee, pkt.identity_id).await;
|
renew_identity_request(eee, pkt.identity_id).await;
|
||||||
}
|
}
|
||||||
@ -930,9 +943,13 @@ async fn handle_tun_packet(
|
|||||||
dst_ip: ipv4.source.into(),
|
dst_ip: ipv4.source.into(),
|
||||||
src_port: udp_header.destination_port,
|
src_port: udp_header.destination_port,
|
||||||
dst_port: udp_header.source_port,
|
dst_port: udp_header.source_port,
|
||||||
proto:IpNumber::UDP.0,
|
proto: IpNumber::UDP.0,
|
||||||
};
|
};
|
||||||
let (valid, need_refresh) = eee.rule_cache.is_identity_ok(eee.config.allow_routing.load(Ordering::Relaxed), pkt.identity_id, five_tuple);
|
let (valid, need_refresh) = eee.rule_cache.is_identity_ok(
|
||||||
|
eee.config.allow_routing.load(Ordering::Relaxed),
|
||||||
|
pkt.identity_id,
|
||||||
|
five_tuple,
|
||||||
|
);
|
||||||
if need_refresh {
|
if need_refresh {
|
||||||
renew_identity_request(eee, pkt.identity_id).await;
|
renew_identity_request(eee, pkt.identity_id).await;
|
||||||
}
|
}
|
||||||
@ -949,17 +966,10 @@ async fn handle_tun_packet(
|
|||||||
// just ignore, ok
|
// just ignore, ok
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
debug!("sending packet to tun, {} bytes", data.len());
|
debug!("sending packet to tun, {} bytes", data.len());
|
||||||
if let Err(e) = eee
|
if let Err(e) = eee.device.handle_packet_from_net(&data).await {
|
||||||
.device
|
|
||||||
.handle_packet_from_net(&data)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
error!("failed to handle packet from net: {}", e.to_string());
|
error!("failed to handle packet from net: {}", e.to_string());
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -1312,7 +1322,11 @@ pub async fn update_supernode_reg(eee: &Node) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub fn form_ethernet_packet(src_mac: Mac, dst_mac: Mac, mut data_with_zeroed_layer2: BytesMut) -> BytesMut {
|
pub fn form_ethernet_packet(
|
||||||
|
src_mac: Mac,
|
||||||
|
dst_mac: Mac,
|
||||||
|
mut data_with_zeroed_layer2: BytesMut,
|
||||||
|
) -> BytesMut {
|
||||||
let mut etherheader = Ethernet2Header::default();
|
let mut etherheader = Ethernet2Header::default();
|
||||||
etherheader.destination = dst_mac;
|
etherheader.destination = dst_mac;
|
||||||
etherheader.ether_type = etherparse::EtherType::IPV4;
|
etherheader.ether_type = etherparse::EtherType::IPV4;
|
||||||
|
|||||||
@ -15,6 +15,8 @@ use sdlan_sn_rs::utils::{ip_to_string, is_ipv6_multicast, net_bit_len_to_mask, M
|
|||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::ffi::{c_char, c_int};
|
use std::ffi::{c_char, c_int};
|
||||||
use std::fs::{self, OpenOptions};
|
use std::fs::{self, OpenOptions};
|
||||||
|
#[cfg(feature = "tun")]
|
||||||
|
use std::hint::L3;
|
||||||
#[cfg(not(feature = "tun"))]
|
#[cfg(not(feature = "tun"))]
|
||||||
use std::net::IpAddr;
|
use std::net::IpAddr;
|
||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
@ -25,7 +27,7 @@ use std::sync::atomic::Ordering;
|
|||||||
|
|
||||||
use sdlan_sn_rs::utils::Result;
|
use sdlan_sn_rs::utils::Result;
|
||||||
use std::io::{BufRead, BufReader, ErrorKind, Read, Write};
|
use std::io::{BufRead, BufReader, ErrorKind, Read, Write};
|
||||||
use std::os::fd::AsRawFd;
|
use std::os::fd::{AsFd, AsRawFd};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
use tracing::{debug, error, info, warn};
|
use tracing::{debug, error, info, warn};
|
||||||
@ -33,11 +35,11 @@ use tracing::{debug, error, info, warn};
|
|||||||
#[cfg(feature = "tun")]
|
#[cfg(feature = "tun")]
|
||||||
use crate::caculate_crc;
|
use crate::caculate_crc;
|
||||||
use crate::get_edge;
|
use crate::get_edge;
|
||||||
#[cfg(feature = "tun")]
|
|
||||||
use crate::network::parse_dns_payload;
|
|
||||||
#[cfg(not(feature = "tun"))]
|
#[cfg(not(feature = "tun"))]
|
||||||
use crate::network::{parse_dns_payload, ArpHdr, EthHdr, ARP_REPLY};
|
use crate::network::{parse_dns_payload, ArpHdr, EthHdr, ARP_REPLY};
|
||||||
use crate::network::{send_packet_to_net, Node};
|
#[cfg(feature = "tun")]
|
||||||
|
use crate::network::{parse_dns_payload, LAYER};
|
||||||
|
use crate::network::{send_packet_to_net, Node, LAYER};
|
||||||
#[cfg(not(feature = "tun"))]
|
#[cfg(not(feature = "tun"))]
|
||||||
use crate::pb::SdlArpResponse;
|
use crate::pb::SdlArpResponse;
|
||||||
#[cfg(feature = "tun")]
|
#[cfg(feature = "tun")]
|
||||||
@ -52,97 +54,46 @@ const RESOLV_FILE: &'static str = "/etc/resolv.conf";
|
|||||||
const RESOLV_FILE_BACKUP: &'static str = "/etc/resolv.conf.punchnet.bak";
|
const RESOLV_FILE_BACKUP: &'static str = "/etc/resolv.conf.punchnet.bak";
|
||||||
use crate::network::DNS_IP;
|
use crate::network::DNS_IP;
|
||||||
|
|
||||||
// #[link(name = "tuntap", kind="static")]
|
|
||||||
#[link(name = "tuntap")]
|
|
||||||
extern "C" {
|
|
||||||
fn tuntap_setup(fd: c_int, name: *mut u8, mode: c_int, packet_info: c_int) -> c_int;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub struct Iface {
|
pub struct Iface {
|
||||||
fd: std::fs::File,
|
dev: tun_rs::AsyncDevice,
|
||||||
mode: Mode,
|
|
||||||
name: String,
|
name: String,
|
||||||
has_resolvectl: bool,
|
has_resolvectl: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_iface(tunname: &str, mode: Mode) -> std::io::Result<Iface> {
|
pub fn new_iface(tunname: &str) -> std::io::Result<Iface> {
|
||||||
match Iface::without_packet_info(tunname, mode) {
|
match tun_rs::DeviceBuilder::new()
|
||||||
Err(e) => {
|
// .offload(true)
|
||||||
error!("failed to create tun: {}", e.as_str());
|
.layer(LAYER)
|
||||||
Err(std::io::Error::new(ErrorKind::Other, "failed to create virtial device, is run with root?"))
|
.enable(true)
|
||||||
|
.name(tunname)
|
||||||
|
.mtu(1280)
|
||||||
|
.packet_information(false)
|
||||||
|
.build_async()
|
||||||
|
{
|
||||||
|
Ok(dev) => {
|
||||||
|
let name = dev.name().unwrap().clone();
|
||||||
|
Ok(Iface {
|
||||||
|
dev,
|
||||||
|
name,
|
||||||
|
has_resolvectl: check_has_resolvectl(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("failed to create tun: {}", e);
|
||||||
|
Err(std::io::Error::new(
|
||||||
|
ErrorKind::Other,
|
||||||
|
"failed to create virtial device, is run with root?",
|
||||||
|
))
|
||||||
}
|
}
|
||||||
Ok(iface) => Ok(iface),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Iface {
|
impl Iface {
|
||||||
|
|
||||||
pub fn get_if_idx(&self) -> u32 {
|
pub fn get_if_idx(&self) -> u32 {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub fn with_packet_info(ifname: &str, mode: Mode) -> Result<Self> {
|
|
||||||
Iface::open_tun(ifname, mode, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn without_packet_info(ifname: &str, mode: Mode) -> Result<Self> {
|
|
||||||
Iface::open_tun(ifname, mode, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn open_tun(ifname: &str, mode: Mode, need_packet_info: bool) -> Result<Self> {
|
|
||||||
let fs = match OpenOptions::new()
|
|
||||||
.read(true)
|
|
||||||
.write(true)
|
|
||||||
.open("/dev/net/tun")
|
|
||||||
{
|
|
||||||
Ok(fs) => fs,
|
|
||||||
Err(e) => panic!("failed to open tun: {}", e),
|
|
||||||
};
|
|
||||||
let mut name_ptr: *mut u8 = null_mut();
|
|
||||||
let mut success = false;
|
|
||||||
let mut _name = Vec::new();
|
|
||||||
for i in 0..16 {
|
|
||||||
_name.clear();
|
|
||||||
_name.extend_from_slice(ifname.as_bytes());
|
|
||||||
_name.extend_from_slice(i.to_string().as_bytes());
|
|
||||||
_name.extend_from_slice(&[0; 33]);
|
|
||||||
|
|
||||||
name_ptr = _name.as_mut_ptr();
|
|
||||||
|
|
||||||
let result = unsafe {
|
|
||||||
tuntap_setup(
|
|
||||||
fs.as_raw_fd(),
|
|
||||||
name_ptr,
|
|
||||||
mode as c_int,
|
|
||||||
if need_packet_info { 1 } else { 0 },
|
|
||||||
)
|
|
||||||
};
|
|
||||||
if result >= 0 {
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if success {
|
|
||||||
let name = unsafe {
|
|
||||||
CStr::from_ptr(name_ptr as *const c_char)
|
|
||||||
.to_string_lossy()
|
|
||||||
.into_owned()
|
|
||||||
};
|
|
||||||
let has_resolvectl = check_has_resolvectl();
|
|
||||||
|
|
||||||
Ok(Iface {
|
|
||||||
fd: fs,
|
|
||||||
mode,
|
|
||||||
name,
|
|
||||||
has_resolvectl,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
Err(SDLanError::NormalError("failed to setup tun"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reload_config(&self, node: &Node, device_config: &DeviceConfig, network_domain: &str) {
|
pub fn reload_config(&self, node: &Node, device_config: &DeviceConfig, network_domain: &str) {
|
||||||
let netbit = device_config.get_net_bit();
|
let netbit = device_config.get_net_bit();
|
||||||
let ip = device_config.get_ip();
|
let ip = device_config.get_ip();
|
||||||
@ -197,7 +148,13 @@ impl Iface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: set dns should be opened
|
// TODO: set dns should be opened
|
||||||
if let Err(e) = set_dns(self, node.take_over_dns, &self.name, network_domain, &ip_to_string(&default_gw)) {
|
if let Err(e) = set_dns(
|
||||||
|
self,
|
||||||
|
node.take_over_dns,
|
||||||
|
&self.name,
|
||||||
|
network_domain,
|
||||||
|
&ip_to_string(&default_gw),
|
||||||
|
) {
|
||||||
error!("failed to set dns: {}", e.as_str());
|
error!("failed to set dns: {}", e.as_str());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -224,18 +181,24 @@ impl Iface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(e) = set_dns(self, node.take_over_dns, &self.name, network_domain, &ip_to_string(&default_gw)) {
|
if let Err(e) = set_dns(
|
||||||
|
self,
|
||||||
|
node.take_over_dns,
|
||||||
|
&self.name,
|
||||||
|
network_domain,
|
||||||
|
&ip_to_string(&default_gw),
|
||||||
|
) {
|
||||||
error!("failed to set dns: {}", e.as_str());
|
error!("failed to set dns: {}", e.as_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn recv(&self, buf: &mut [u8]) -> std::io::Result<usize> {
|
pub async fn recv(&self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||||
(&self.fd).read(buf)
|
self.dev.recv(buf).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send(&self, content: &[u8]) -> std::io::Result<usize> {
|
pub async fn send(&self, content: &[u8]) -> std::io::Result<usize> {
|
||||||
(&self.fd).write(content)
|
self.dev.send(content).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,7 +206,7 @@ impl Iface {
|
|||||||
impl TunTapPacketHandler for Iface {
|
impl TunTapPacketHandler for Iface {
|
||||||
async fn handle_packet_from_net(&self, data: &[u8]) -> std::io::Result<()> {
|
async fn handle_packet_from_net(&self, data: &[u8]) -> std::io::Result<()> {
|
||||||
// debug!("in tap mode, got data: {:?}", data);
|
// debug!("in tap mode, got data: {:?}", data);
|
||||||
match self.send(data) {
|
match self.send(data).await {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("failed to write to tap: {}", e.to_string());
|
error!("failed to write to tap: {}", e.to_string());
|
||||||
return Err(e);
|
return Err(e);
|
||||||
@ -252,158 +215,6 @@ impl TunTapPacketHandler for Iface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "abc")]
|
|
||||||
async fn handle_packet_from_device(
|
|
||||||
&self,
|
|
||||||
data: BytesMut,
|
|
||||||
// encrypt_key: &[u8],
|
|
||||||
) -> std::io::Result<()> {
|
|
||||||
use etherparse::PacketHeaders;
|
|
||||||
|
|
||||||
debug!("in tap mode2");
|
|
||||||
let edge = get_edge();
|
|
||||||
|
|
||||||
let Ok(headers) = PacketHeaders::from_ethernet_slice(&data) else {
|
|
||||||
error!("failed to parse packet");
|
|
||||||
return Ok(());
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(eth) = headers.link {
|
|
||||||
use etherparse::EtherType;
|
|
||||||
|
|
||||||
if let Some(hdr) = eth.ethernet2() {
|
|
||||||
use bytes::Bytes;
|
|
||||||
|
|
||||||
if hdr.ether_type == EtherType::ARP {
|
|
||||||
use crate::network::{ArpHdr, ARP_REQUEST};
|
|
||||||
|
|
||||||
let arp = ArpHdr::from_slice(&data);
|
|
||||||
match arp.opcode {
|
|
||||||
ARP_REQUEST => {
|
|
||||||
let dest_ip = ((arp.dipaddr[0] as u32) << 16) + arp.dipaddr[1] as u32;
|
|
||||||
|
|
||||||
if edge.device_config.contains(&Ipv4Addr::from_bits(dest_ip)) {
|
|
||||||
let _ = edge.send_arp_request(dest_ip, dest_ip).await;
|
|
||||||
} else {
|
|
||||||
if let Some((_, real_ip)) = edge.route_table.lookup(dest_ip) {
|
|
||||||
let real_ip = u32::from_be_bytes(real_ip.octets());
|
|
||||||
let _ = edge.send_arp_request(dest_ip, real_ip).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
let request = SdlArpRequest {
|
|
||||||
pkt_id: edge.get_next_packet_id(),
|
|
||||||
target_ip: dest_ip,
|
|
||||||
};
|
|
||||||
|
|
||||||
let req = encode_to_tcp_message(Some(request), PacketType::ArpRequest as u8).unwrap();
|
|
||||||
let conn = get_quic_write_conn();
|
|
||||||
debug!("sending arp request");
|
|
||||||
let _ = conn.send(req).await;
|
|
||||||
*/
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
_other => {
|
|
||||||
// just do the following logic
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(ip) = headers.net {
|
|
||||||
match ip {
|
|
||||||
etherparse::NetHeaders::Ipv4(ipv4, _) => {
|
|
||||||
use crate::FiveTuple;
|
|
||||||
use etherparse::IpNumber;
|
|
||||||
|
|
||||||
if let Some(transport) = headers.transport {
|
|
||||||
match ipv4.protocol {
|
|
||||||
IpNumber::TCP => {
|
|
||||||
if let Some(tcp) = transport.tcp() {
|
|
||||||
let out_five_tuple = FiveTuple {
|
|
||||||
src_ip: ipv4.source.into(),
|
|
||||||
dst_ip: ipv4.destination.into(),
|
|
||||||
src_port: tcp.source_port,
|
|
||||||
dst_port: tcp.destination_port,
|
|
||||||
proto: IpNumber::TCP.0,
|
|
||||||
};
|
|
||||||
|
|
||||||
edge.rule_cache.touch_packet(out_five_tuple);
|
|
||||||
}
|
|
||||||
|
|
||||||
// is tcp
|
|
||||||
}
|
|
||||||
IpNumber::UDP => {
|
|
||||||
if let Some(udp) = transport.udp() {
|
|
||||||
let out_five_tuple = FiveTuple {
|
|
||||||
src_ip: ipv4.source.into(),
|
|
||||||
dst_ip: ipv4.destination.into(),
|
|
||||||
src_port: udp.source_port,
|
|
||||||
dst_port: udp.destination_port,
|
|
||||||
proto: IpNumber::UDP.0,
|
|
||||||
};
|
|
||||||
edge.rule_cache.touch_packet(out_five_tuple);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_other => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if u32::from_be_bytes(ipv4.destination) == DNS_IP {
|
|
||||||
// should send to dns
|
|
||||||
parse_dns_payload(edge, &headers.payload.slice());
|
|
||||||
if let Err(e) = edge
|
|
||||||
.udp_sock_for_dns
|
|
||||||
.send_to(&data[14..], format!("{}:15353", edge.server_ip))
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
error!("failed to send request to 15353: {}", e);
|
|
||||||
}
|
|
||||||
// edge.udp_sock_for_dns.send_to()
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_other => {
|
|
||||||
// just ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let target = hdr.destination;
|
|
||||||
if is_ipv6_multicast(&target) {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
let size = data.len();
|
|
||||||
|
|
||||||
let Ok(encrypted) = edge.encryptor.load().encrypt(&data) else {
|
|
||||||
// let Ok(encrypted) = edge.encryptor.read().unwrap().encrypt(&data) else {
|
|
||||||
// let Ok(encrypted) = aes_encrypt(encrypt_key, &data) else {
|
|
||||||
error!("failed to encrypt packet request");
|
|
||||||
return Ok(());
|
|
||||||
};
|
|
||||||
let data_bytes = Bytes::from(encrypted);
|
|
||||||
let data = SdlData {
|
|
||||||
is_p2p: true,
|
|
||||||
network_id: edge.network_id.load(Ordering::Relaxed),
|
|
||||||
ttl: SDLAN_DEFAULT_TTL as u32,
|
|
||||||
src_mac: Vec::from(edge.device_config.get_mac()),
|
|
||||||
dst_mac: Vec::from(target),
|
|
||||||
data: data_bytes,
|
|
||||||
identity_id: edge.identity_id.load(),
|
|
||||||
session_token: edge.session_token.get(),
|
|
||||||
};
|
|
||||||
let msg = encode_to_udp_message(Some(data), PacketType::Data as u8).unwrap();
|
|
||||||
|
|
||||||
send_packet_to_net(edge, target, &msg, size as u64).await;
|
|
||||||
} else {
|
|
||||||
error!("erro 2");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
error!("erro 1");
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn handle_packet_from_device(
|
async fn handle_packet_from_device(
|
||||||
&self,
|
&self,
|
||||||
data: BytesMut,
|
data: BytesMut,
|
||||||
@ -433,7 +244,7 @@ impl TunTapPacketHandler for Iface {
|
|||||||
if dest_ip == DNS_IP {
|
if dest_ip == DNS_IP {
|
||||||
error!("got dns ip");
|
error!("got dns ip");
|
||||||
edge.device_config.dns_mac;
|
edge.device_config.dns_mac;
|
||||||
write_arp_to_device(edge, edge.device_config.dns_mac, DNS_IP);
|
write_arp_to_device(edge, edge.device_config.dns_mac, DNS_IP).await;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -517,17 +328,16 @@ impl TunTapPacketHandler for Iface {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut data = data;
|
||||||
let size = data.len();
|
let size = data.len();
|
||||||
|
|
||||||
let encrypted = match edge.encryptor.load().encrypt(&data) {
|
let encryptor = edge.encryptor.load();
|
||||||
Ok(data) => data,
|
if let Err(e) = encryptor.encrypt(&mut data) {
|
||||||
Err(e) => {
|
error!("failed to encrypt packet request: {:?}", e);
|
||||||
error!("failed to encrypt packet request: {}", e.as_str());
|
return Ok(());
|
||||||
return Ok(());
|
}
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let data_bytes = Bytes::from(encrypted);
|
let data_bytes = data.freeze();
|
||||||
let data = SdlData {
|
let data = SdlData {
|
||||||
is_p2p: true,
|
is_p2p: true,
|
||||||
network_id: edge.network_id.load(Ordering::Relaxed),
|
network_id: edge.network_id.load(Ordering::Relaxed),
|
||||||
@ -633,14 +443,14 @@ impl TunTapPacketHandler for Iface {
|
|||||||
arp.sipaddr =
|
arp.sipaddr =
|
||||||
[((self_ip >> 16) & 0xffff) as u16, (self_ip & 0xffff) as u16];
|
[((self_ip >> 16) & 0xffff) as u16, (self_ip & 0xffff) as u16];
|
||||||
|
|
||||||
let data = arp.marshal_to_bytes();
|
let mut data_buf = BytesMut::from(arp.marshal_to_bytes().as_slice());
|
||||||
// let Ok(encrypted) = aes_encrypt(key, &data) else {
|
let encryptor = edge.encryptor.load();
|
||||||
let Ok(encrypted) = edge.encryptor.load().encrypt(&data) else {
|
if let Err(e) = encryptor.encrypt(&mut data_buf) {
|
||||||
error!("failed to encrypt arp reply");
|
error!("failed to encrypt arp reply: {:?}", e);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
}
|
||||||
|
|
||||||
let data_bytes = Bytes::from(encrypted);
|
let data_bytes = data_buf.freeze();
|
||||||
|
|
||||||
let data = SdlData {
|
let data = SdlData {
|
||||||
is_p2p: true,
|
is_p2p: true,
|
||||||
@ -796,71 +606,72 @@ impl TunTapPacketHandler for Iface {
|
|||||||
}
|
}
|
||||||
_other => {}
|
_other => {}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match eee.arp_table.get(dstip) {
|
match eee.arp_table.get(dstip) {
|
||||||
Some(mac) => {
|
Some(mac) => {
|
||||||
let pkt_size = data.len() + 14;
|
let pkt_size = data.len() + 14;
|
||||||
let mut etherheader = Ethernet2Header::default();
|
let mut etherheader = Ethernet2Header::default();
|
||||||
etherheader.destination = mac;
|
etherheader.destination = mac;
|
||||||
etherheader.ether_type = etherparse::EtherType::IPV4;
|
etherheader.ether_type = etherparse::EtherType::IPV4;
|
||||||
etherheader.source = src_mac;
|
etherheader.source = src_mac;
|
||||||
// let mut packet = Vec::with_capacity(14 + data.len() + 4);
|
// let mut packet = Vec::with_capacity(14 + data.len() + 4);
|
||||||
|
|
||||||
header.copy_from_slice(ðerheader.to_bytes()[..]);
|
header.copy_from_slice(ðerheader.to_bytes()[..]);
|
||||||
|
|
||||||
let crc = caculate_crc(&data);
|
let crc = caculate_crc(&data);
|
||||||
header.unsplit(data);
|
header.unsplit(data);
|
||||||
|
|
||||||
// packet.extend_from_slice(ðerheader.to_bytes()[..]);
|
// packet.extend_from_slice(ðerheader.to_bytes()[..]);
|
||||||
// packet.extend_from_slice(&data);
|
// packet.extend_from_slice(&data);
|
||||||
header.extend_from_slice(&crc.to_be_bytes());
|
header.extend_from_slice(&crc.to_be_bytes());
|
||||||
// packet.extend_from_slice(&crc.to_be_bytes());
|
// packet.extend_from_slice(&crc.to_be_bytes());
|
||||||
|
|
||||||
// let pkt_size = packet.len();
|
// let pkt_size = packet.len();
|
||||||
// println!("sending data with mac");
|
// println!("sending data with mac");
|
||||||
|
|
||||||
// let Ok(encrypted) = aes_encrypt(&encrypt_key, &packet) else {
|
let encryptor = eee.encryptor.load();
|
||||||
let Ok(encrypted) = eee.encryptor.load().encrypt(&header) else {
|
if let Err(e) = encryptor.encrypt(&mut header) {
|
||||||
error!("failed to encrypt packet request");
|
error!("failed to encrypt packet request: {:?}", e);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
|
||||||
|
|
||||||
let data = SdlData {
|
|
||||||
is_p2p: true,
|
|
||||||
network_id: eee.network_id.load(Ordering::Relaxed),
|
|
||||||
ttl: SDLAN_DEFAULT_TTL as u32,
|
|
||||||
src_mac: Vec::from(src_mac),
|
|
||||||
dst_mac: Vec::from(mac),
|
|
||||||
data: Bytes::from(encrypted),
|
|
||||||
session_token: eee.session_token.get(),
|
|
||||||
identity_id: eee.identity_id.load(),
|
|
||||||
};
|
|
||||||
let msg =
|
|
||||||
encode_to_udp_message(Some(data), PacketType::Data as u8).unwrap();
|
|
||||||
let size = msg.len();
|
|
||||||
send_packet_to_net(eee, mac, &msg, pkt_size as u64).await;
|
|
||||||
}
|
}
|
||||||
None => {
|
let data_bytes = header.freeze();
|
||||||
header.unsplit(data);
|
|
||||||
eee.arp_table.add_to_arp_wait_list(dstip, header);
|
|
||||||
debug!(
|
|
||||||
"find ip: {:?} => {:?}",
|
|
||||||
src.to_be_bytes(),
|
|
||||||
dstip.to_be_bytes()
|
|
||||||
);
|
|
||||||
debug!(
|
|
||||||
"no mac found for ip {:?}, sending arp request",
|
|
||||||
dstip.to_be_bytes()
|
|
||||||
);
|
|
||||||
// let _ = eee.send_arp_request(dstip, dstip).await;
|
|
||||||
|
|
||||||
if eee.device_config.contains(&Ipv4Addr::from_bits(dstip)) {
|
let data = SdlData {
|
||||||
let _ = eee.send_arp_request(dstip, dstip).await;
|
is_p2p: true,
|
||||||
} else {
|
network_id: eee.network_id.load(Ordering::Relaxed),
|
||||||
if let Some((_, real_ip)) = eee.route_table.lookup(dstip) {
|
ttl: SDLAN_DEFAULT_TTL as u32,
|
||||||
let real_ip = u32::from_be_bytes(real_ip.octets());
|
src_mac: Vec::from(src_mac),
|
||||||
let _ = eee.send_arp_request(dstip, real_ip).await;
|
dst_mac: Vec::from(mac),
|
||||||
}
|
data: data_bytes,
|
||||||
|
session_token: eee.session_token.get(),
|
||||||
|
identity_id: eee.identity_id.load(),
|
||||||
|
};
|
||||||
|
let msg =
|
||||||
|
encode_to_udp_message(Some(data), PacketType::Data as u8).unwrap();
|
||||||
|
let size = msg.len();
|
||||||
|
send_packet_to_net(eee, mac, &msg, pkt_size as u64).await;
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
header.unsplit(data);
|
||||||
|
eee.arp_table.add_to_arp_wait_list(dstip, header);
|
||||||
|
debug!(
|
||||||
|
"find ip: {:?} => {:?}",
|
||||||
|
src.to_be_bytes(),
|
||||||
|
dstip.to_be_bytes()
|
||||||
|
);
|
||||||
|
debug!(
|
||||||
|
"no mac found for ip {:?}, sending arp request",
|
||||||
|
dstip.to_be_bytes()
|
||||||
|
);
|
||||||
|
// let _ = eee.send_arp_request(dstip, dstip).await;
|
||||||
|
|
||||||
|
if eee.device_config.contains(&Ipv4Addr::from_bits(dstip)) {
|
||||||
|
let _ = eee.send_arp_request(dstip, dstip).await;
|
||||||
|
} else {
|
||||||
|
if let Some((_, real_ip)) = eee.route_table.lookup(dstip) {
|
||||||
|
let real_ip = u32::from_be_bytes(real_ip.octets());
|
||||||
|
let _ = eee.send_arp_request(dstip, real_ip).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -906,26 +717,39 @@ fn add_resolvectl(name: &str, network_domain: &str) -> Result<()> {
|
|||||||
.arg("dns")
|
.arg("dns")
|
||||||
.arg(name)
|
.arg(name)
|
||||||
.arg("100.100.100.100")
|
.arg("100.100.100.100")
|
||||||
.output()?.status.success() {
|
.output()?
|
||||||
|
.status
|
||||||
|
.success()
|
||||||
|
{
|
||||||
error!("faield to run resolvectl dns");
|
error!("faield to run resolvectl dns");
|
||||||
return Err(SDLanError::IOError("failed to resolvectl dns".to_owned()))
|
return Err(SDLanError::IOError("failed to resolvectl dns".to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if !Command::new("resolvectl")
|
if !Command::new("resolvectl")
|
||||||
.arg("domain")
|
.arg("domain")
|
||||||
.arg(name)
|
.arg(name)
|
||||||
// .arg(format!("~{}", network_domain))
|
// .arg(format!("~{}", network_domain))
|
||||||
.arg("~.")
|
.arg("~.")
|
||||||
.output()?.status.success() {
|
.output()?
|
||||||
|
.status
|
||||||
|
.success()
|
||||||
|
{
|
||||||
error!("failed to run resolvectl domain");
|
error!("failed to run resolvectl domain");
|
||||||
return Err(SDLanError::IOError("failed to resolvectl domain".to_owned()))
|
return Err(SDLanError::IOError(
|
||||||
|
"failed to resolvectl domain".to_owned(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_dns(iface: &Iface, take_over_dns: bool, name: &str, network_domain: &str, gw: &str) -> Result<()> {
|
fn set_dns(
|
||||||
|
iface: &Iface,
|
||||||
|
take_over_dns: bool,
|
||||||
|
name: &str,
|
||||||
|
network_domain: &str,
|
||||||
|
gw: &str,
|
||||||
|
) -> Result<()> {
|
||||||
error!("network_domain = {}", network_domain);
|
error!("network_domain = {}", network_domain);
|
||||||
if iface.has_resolvectl {
|
if iface.has_resolvectl {
|
||||||
add_resolvectl(name, network_domain)?;
|
add_resolvectl(name, network_domain)?;
|
||||||
@ -941,7 +765,7 @@ fn set_dns(iface: &Iface, take_over_dns: bool, name: &str, network_domain: &str,
|
|||||||
|
|
||||||
pub fn restore_dns(take_over_dns: bool) -> Result<()> {
|
pub fn restore_dns(take_over_dns: bool) -> Result<()> {
|
||||||
let eee = get_edge();
|
let eee = get_edge();
|
||||||
if !eee.device.has_resolvectl && take_over_dns{
|
if !eee.device.has_resolvectl && take_over_dns {
|
||||||
// should restore /etc/resolv.conf
|
// should restore /etc/resolv.conf
|
||||||
restore_resolv_conf()?;
|
restore_resolv_conf()?;
|
||||||
}
|
}
|
||||||
@ -1126,9 +950,11 @@ pub fn del_route(net: &Ipv4Net, gw: &Ipv4Addr) -> Result<()> {
|
|||||||
.arg(net.to_string())
|
.arg(net.to_string())
|
||||||
.arg("gw")
|
.arg("gw")
|
||||||
.arg(gw.to_string())
|
.arg(gw.to_string())
|
||||||
.output()?.status.success() {
|
.output()?
|
||||||
|
.status
|
||||||
return Err(SDLanError::IOError("failed to delete route".to_owned()))
|
.success()
|
||||||
|
{
|
||||||
|
return Err(SDLanError::IOError("failed to delete route".to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -1141,8 +967,11 @@ pub fn add_route(net: &Ipv4Net, gw: &Ipv4Addr, _ifidx: u32) -> Result<()> {
|
|||||||
.arg(net.to_string())
|
.arg(net.to_string())
|
||||||
.arg("gw")
|
.arg("gw")
|
||||||
.arg(gw.to_string())
|
.arg(gw.to_string())
|
||||||
.output()?.status.success() {
|
.output()?
|
||||||
return Err(SDLanError::IOError("failed to delete route".to_owned()))
|
.status
|
||||||
|
.success()
|
||||||
|
{
|
||||||
|
return Err(SDLanError::IOError("failed to delete route".to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -1152,9 +981,13 @@ pub fn set_disallow_routing() -> Result<()> {
|
|||||||
if !Command::new("sysctl")
|
if !Command::new("sysctl")
|
||||||
.arg("-w")
|
.arg("-w")
|
||||||
.arg("net.ipv4.ip_forward=0")
|
.arg("net.ipv4.ip_forward=0")
|
||||||
.output()?.status.success() {
|
.output()?
|
||||||
|
.status
|
||||||
return Err(SDLanError::IOError("failed to set ip_forward to 0".to_owned()))
|
.success()
|
||||||
|
{
|
||||||
|
return Err(SDLanError::IOError(
|
||||||
|
"failed to set ip_forward to 0".to_owned(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if !Command::new("iptables")
|
if !Command::new("iptables")
|
||||||
@ -1164,20 +997,29 @@ pub fn set_disallow_routing() -> Result<()> {
|
|||||||
.arg("POSTROUTING")
|
.arg("POSTROUTING")
|
||||||
.arg("-j")
|
.arg("-j")
|
||||||
.arg("MASQUERADE")
|
.arg("MASQUERADE")
|
||||||
.output()?.status.success() {
|
.output()?
|
||||||
|
.status
|
||||||
return Err(SDLanError::IOError("failed to delete masquerade".to_owned()))
|
.success()
|
||||||
|
{
|
||||||
|
return Err(SDLanError::IOError(
|
||||||
|
"failed to delete masquerade".to_owned(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_allow_routing() -> Result<()>{
|
pub fn set_allow_routing() -> Result<()> {
|
||||||
if !Command::new("sysctl")
|
if !Command::new("sysctl")
|
||||||
.arg("-w")
|
.arg("-w")
|
||||||
.arg("net.ipv4.ip_forward=1")
|
.arg("net.ipv4.ip_forward=1")
|
||||||
.output()?.status.success() {
|
.output()?
|
||||||
return Err(SDLanError::IOError("failed to set ip_forward to 1".to_owned()))
|
.status
|
||||||
|
.success()
|
||||||
|
{
|
||||||
|
return Err(SDLanError::IOError(
|
||||||
|
"failed to set ip_forward to 1".to_owned(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if !Command::new("iptables")
|
if !Command::new("iptables")
|
||||||
@ -1187,9 +1029,11 @@ pub fn set_allow_routing() -> Result<()>{
|
|||||||
.arg("POSTROUTING")
|
.arg("POSTROUTING")
|
||||||
.arg("-j")
|
.arg("-j")
|
||||||
.arg("MASQUERADE")
|
.arg("MASQUERADE")
|
||||||
.output()?.status.success() {
|
.output()?
|
||||||
|
.status
|
||||||
return Err(SDLanError::IOError("failed to clear masquerade".to_owned()))
|
.success()
|
||||||
|
{
|
||||||
|
return Err(SDLanError::IOError("failed to clear masquerade".to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if !Command::new("iptables")
|
if !Command::new("iptables")
|
||||||
@ -1199,8 +1043,11 @@ pub fn set_allow_routing() -> Result<()>{
|
|||||||
.arg("POSTROUTING")
|
.arg("POSTROUTING")
|
||||||
.arg("-j")
|
.arg("-j")
|
||||||
.arg("MASQUERADE")
|
.arg("MASQUERADE")
|
||||||
.output()?.status.success() {
|
.output()?
|
||||||
return Err(SDLanError::IOError("failed to add masquerade".to_owned()))
|
.status
|
||||||
|
.success()
|
||||||
|
{
|
||||||
|
return Err(SDLanError::IOError("failed to add masquerade".to_owned()));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -1242,11 +1089,11 @@ pub async fn arp_reply_arrived(edge: &Node, data: SdlArpResponse) {
|
|||||||
|
|
||||||
let src_ip = data.origin_ip;
|
let src_ip = data.origin_ip;
|
||||||
|
|
||||||
write_arp_to_device(edge, src_mac, src_ip);
|
write_arp_to_device(edge, src_mac, src_ip).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "tun"))]
|
#[cfg(not(feature = "tun"))]
|
||||||
pub fn write_arp_to_device(edge: &Node, src_mac: Mac, src_ip: u32) {
|
pub async fn write_arp_to_device(edge: &Node, src_mac: Mac, src_ip: u32) {
|
||||||
let dst_mac = edge.device_config.get_mac();
|
let dst_mac = edge.device_config.get_mac();
|
||||||
let dst_ip = edge.device_config.get_ip();
|
let dst_ip = edge.device_config.get_ip();
|
||||||
|
|
||||||
@ -1271,7 +1118,7 @@ pub fn write_arp_to_device(edge: &Node, src_mac: Mac, src_ip: u32) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let data = hdr.marshal_to_bytes();
|
let data = hdr.marshal_to_bytes();
|
||||||
if let Err(_e) = edge.device.send(&data) {
|
if let Err(_e) = edge.device.send(&data).await {
|
||||||
error!("failed to write arp response to device");
|
error!("failed to write arp response to device");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,20 +4,22 @@ use etherparse::{Ethernet2Header, IpHeaders, NetSlice, SlicedPacket, TransportSl
|
|||||||
use ipnet::Ipv4Net;
|
use ipnet::Ipv4Net;
|
||||||
use sdlan_sn_rs::config::SDLAN_DEFAULT_TTL;
|
use sdlan_sn_rs::config::SDLAN_DEFAULT_TTL;
|
||||||
use sdlan_sn_rs::utils::{
|
use sdlan_sn_rs::utils::{
|
||||||
BROADCAST_MAC, Result, SDLanError, aes_encrypt, ip_to_string, is_multi_broadcast, net_bit_len_to_mask
|
aes_encrypt, ip_to_string, is_multi_broadcast, net_bit_len_to_mask, Result, SDLanError,
|
||||||
|
BROADCAST_MAC,
|
||||||
};
|
};
|
||||||
use std::io::{Error, ErrorKind};
|
use std::io::{Error, ErrorKind};
|
||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
use std::os::windows::process::CommandExt;
|
use std::os::windows::process::CommandExt;
|
||||||
use std::process::Command;
|
use std::process::{Command, Stdio};
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tracing::{debug, error, info};
|
use tracing::{debug, error, info};
|
||||||
|
use tun_rs::{AsyncDevice, SyncDevice};
|
||||||
use wintun;
|
use wintun;
|
||||||
|
|
||||||
use crate::network::{
|
use crate::network::{
|
||||||
form_ethernet_packet, generate_arp_request, parse_dns_payload, send_packet_to_net, ArpHdr,
|
form_ethernet_packet, generate_arp_request, parse_dns_payload, send_packet_to_net, ArpHdr,
|
||||||
Node, ARP_REPLY, ARP_REQUEST, DNS_IP,
|
Node, ARP_REPLY, ARP_REQUEST, DNS_IP, LAYER,
|
||||||
};
|
};
|
||||||
use crate::pb::{encode_to_udp_message, SdlArpResponse, SdlData};
|
use crate::pb::{encode_to_udp_message, SdlArpResponse, SdlData};
|
||||||
use crate::tcp::PacketType;
|
use crate::tcp::PacketType;
|
||||||
@ -28,13 +30,135 @@ use super::device::{DeviceConfig, Mode};
|
|||||||
use super::TunTapPacketHandler;
|
use super::TunTapPacketHandler;
|
||||||
|
|
||||||
pub struct Iface {
|
pub struct Iface {
|
||||||
|
device: AsyncDevice,
|
||||||
|
if_idx: u32,
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iface {
|
||||||
|
fn new(_path: &str, name: &str) -> Self {
|
||||||
|
println!("layer = {:?}", LAYER);
|
||||||
|
let dev = tun_rs::DeviceBuilder::new()
|
||||||
|
// .wintun_file(path.to_string())
|
||||||
|
.name(name)
|
||||||
|
// .ipv4(Ipv4Addr::new(10, 10, 4, 39), Ipv4Addr::new(255, 255, 255, 0), None)
|
||||||
|
.layer(tun_rs::Layer::L3)
|
||||||
|
.mtu(1280)
|
||||||
|
// .enable(true)
|
||||||
|
.build_async()
|
||||||
|
.expect("failed to create tun");
|
||||||
|
|
||||||
|
let idx = dev.if_index().expect("failed to get if index");
|
||||||
|
println!("index = {}", idx);
|
||||||
|
Self {
|
||||||
|
device: dev,
|
||||||
|
if_idx: idx,
|
||||||
|
name: name.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iface {
|
||||||
|
pub fn get_if_idx(&self) -> u32 {
|
||||||
|
self.if_idx
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn recv(&self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||||
|
self.device.recv(buf).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn send(&self, content: &[u8]) -> std::io::Result<usize> {
|
||||||
|
self.device.send(content).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reload_config(&self, node: &Node, device_config: &DeviceConfig, network_domain: &str) {
|
||||||
|
let netbit = device_config.get_net_bit();
|
||||||
|
let ip = device_config.get_ip();
|
||||||
|
if netbit == 0 || ip == 0 {
|
||||||
|
error!("reload config's ip is 0");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mask = net_bit_len_to_mask(netbit);
|
||||||
|
let ip = ip_to_string(&ip);
|
||||||
|
|
||||||
|
let netbit = ip_to_string(&net_bit_len_to_mask(netbit));
|
||||||
|
|
||||||
|
let mut cmd = Command::new("netsh");
|
||||||
|
debug!("name={}, addr={}, mask={}", self.name, ip, netbit);
|
||||||
|
let command = cmd
|
||||||
|
.creation_flags(0x08000000)
|
||||||
|
.arg("interface")
|
||||||
|
.arg("ip")
|
||||||
|
.arg("set")
|
||||||
|
.arg("address")
|
||||||
|
.arg(&format!("name=\"{}\"", self.name))
|
||||||
|
.arg("source=static")
|
||||||
|
.arg(&format!("addr={}", ip))
|
||||||
|
.arg(&format!("mask={}", netbit));
|
||||||
|
|
||||||
|
let res = command.status();
|
||||||
|
// let res = command.output();
|
||||||
|
|
||||||
|
match res {
|
||||||
|
Ok(r) => {
|
||||||
|
if r.success() {
|
||||||
|
debug!("netsh ok");
|
||||||
|
} else {
|
||||||
|
error!("failed to run netsh, returned {:?}", r.code())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("failed to run netsh: {}", e.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut cmd = Command::new("netsh");
|
||||||
|
let command = cmd
|
||||||
|
.creation_flags(0x08000000)
|
||||||
|
.arg("interface")
|
||||||
|
.arg("ipv4")
|
||||||
|
.arg("set")
|
||||||
|
.arg("subinterface")
|
||||||
|
.arg(&format!("\"{}\"", self.name))
|
||||||
|
.arg(format!("mtu={}", device_config.mtu))
|
||||||
|
.arg("store=persistent");
|
||||||
|
|
||||||
|
let res = command.status();
|
||||||
|
|
||||||
|
match res {
|
||||||
|
Ok(r) => {
|
||||||
|
if r.success() {
|
||||||
|
debug!("netsh2 ok");
|
||||||
|
} else {
|
||||||
|
error!("failed to run netsh set mtu, returned {:?}", r.code())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("failed to run netsh2: {}", e.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// let gw = ip_to_string(&default_gw);
|
||||||
|
// debug!("gw = {}", ip);
|
||||||
|
if let Err(e) = set_dns(&self.name, network_domain, &ip, self.if_idx) {
|
||||||
|
error!("failed to set dns: {:?}", e);
|
||||||
|
} else {
|
||||||
|
debug!("set dns ok");
|
||||||
|
}
|
||||||
|
|
||||||
|
node.route_table.apply_system(self.if_idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct IfaceOld {
|
||||||
if_idx: u32,
|
if_idx: u32,
|
||||||
name: String,
|
name: String,
|
||||||
_adapter: Arc<wintun::Adapter>,
|
_adapter: Arc<wintun::Adapter>,
|
||||||
session: Arc<wintun::Session>,
|
session: Arc<wintun::Session>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Iface {
|
impl IfaceOld {
|
||||||
pub fn get_if_idx(&self) -> u32 {
|
pub fn get_if_idx(&self) -> u32 {
|
||||||
self.if_idx
|
self.if_idx
|
||||||
}
|
}
|
||||||
@ -55,11 +179,12 @@ impl Iface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn send(&self, content: &[u8]) -> std::io::Result<usize> {
|
pub fn send(&self, content: &[u8]) -> std::io::Result<usize> {
|
||||||
let Ok(mut pkt) = self
|
let Ok(mut pkt) = self.session.allocate_send_packet(content.len() as u16) else {
|
||||||
.session
|
error!("failed to allocate send packet");
|
||||||
.allocate_send_packet(content.len() as u16) else {
|
return Err(std::io::Error::new(
|
||||||
error!("failed to allocate send packet");
|
std::io::ErrorKind::Other,
|
||||||
return Err(std::io::Error::new(std::io::ErrorKind::Other, "failed to allocate send packet"));
|
"failed to allocate send packet",
|
||||||
|
));
|
||||||
};
|
};
|
||||||
let buf: &mut [u8] = pkt.bytes_mut();
|
let buf: &mut [u8] = pkt.bytes_mut();
|
||||||
buf.copy_from_slice(content);
|
buf.copy_from_slice(content);
|
||||||
@ -230,14 +355,14 @@ impl TunTapPacketHandler for Iface {
|
|||||||
arp.sipaddr =
|
arp.sipaddr =
|
||||||
[((self_ip >> 16) & 0xffff) as u16, (self_ip & 0xffff) as u16];
|
[((self_ip >> 16) & 0xffff) as u16, (self_ip & 0xffff) as u16];
|
||||||
|
|
||||||
let data = arp.marshal_to_bytes();
|
let mut data_buf = BytesMut::from(arp.marshal_to_bytes().as_slice());
|
||||||
// let Ok(encrypted) = aes_encrypt(key, &data) else {
|
let encryptor = edge.encryptor.load();
|
||||||
let Ok(encrypted) = edge.encryptor.load().encrypt(&data) else {
|
if let Err(e) = encryptor.encrypt(&mut data_buf) {
|
||||||
error!("failed to encrypt arp reply");
|
error!("failed to encrypt arp reply: {:?}", e);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
}
|
||||||
|
|
||||||
let data_bytes = Bytes::from(encrypted);
|
let data_bytes = data_buf.freeze();
|
||||||
|
|
||||||
let data = SdlData {
|
let data = SdlData {
|
||||||
is_p2p: true,
|
is_p2p: true,
|
||||||
@ -310,7 +435,7 @@ impl TunTapPacketHandler for Iface {
|
|||||||
|
|
||||||
// println!("got ip packet");
|
// println!("got ip packet");
|
||||||
// println!("got data: {:?}", rest);
|
// println!("got data: {:?}", rest);
|
||||||
match edge.device.send(rest) {
|
match edge.device.send(rest).await {
|
||||||
Ok(size) => {
|
Ok(size) => {
|
||||||
debug!("send to tun {} bytes", size);
|
debug!("send to tun {} bytes", size);
|
||||||
}
|
}
|
||||||
@ -330,140 +455,7 @@ impl TunTapPacketHandler for Iface {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// async fn handle_packet_from_device(
|
|
||||||
// &self,
|
|
||||||
// data: BytesMut,
|
|
||||||
// // encrypt_key: &[u8],
|
|
||||||
// ) -> std::io::Result<()> {
|
|
||||||
// let eee = get_edge();
|
|
||||||
|
|
||||||
// let src_mac = eee.device_config.get_mac();
|
|
||||||
|
|
||||||
// match IpHeaders::from_slice(&data) {
|
|
||||||
// Ok((iphdr, _payload)) => {
|
|
||||||
// let Some(ipv4hdr) = iphdr.ipv4() else {
|
|
||||||
// debug!("ipv6 packet ignored");
|
|
||||||
// return Ok(());
|
|
||||||
// };
|
|
||||||
// let dstip = u32::from_be_bytes(ipv4hdr.0.destination);
|
|
||||||
// debug!("packet dst ip: {:?}", ipv4hdr.0.destination);
|
|
||||||
// let src = u32::from_be_bytes(ipv4hdr.0.source);
|
|
||||||
// debug!("packet src ip: {:?}", ipv4hdr.0.source);
|
|
||||||
// // packet should be sent to dev
|
|
||||||
// debug!("got {} bytes from tun", data.len());
|
|
||||||
// if (!eee.config.allow_routing.load(Ordering::Relaxed)) && (src != eee.device_config.get_ip()) {
|
|
||||||
// info!("dropping routed packet");
|
|
||||||
// return Ok(());
|
|
||||||
// }
|
|
||||||
// if !eee.is_authorized() {
|
|
||||||
// debug!("drop tun packet due to not authed");
|
|
||||||
// return Ok(());
|
|
||||||
// }
|
|
||||||
// if dstip == DNS_IP {
|
|
||||||
// // println!("request for dns");
|
|
||||||
// let addr = format!("{}:15353", eee.server_ip);
|
|
||||||
// // println!("send dns to {}", addr);
|
|
||||||
// if let Err(e) = eee.udp_sock_for_dns.send_to(&data, &addr).await {
|
|
||||||
// error!("failed to send request to 15353: {}", e);
|
|
||||||
// }
|
|
||||||
// return Ok(());
|
|
||||||
// }
|
|
||||||
// match send_arp_request(ArpRequestInfo::Lookup { ip: dstip }).await {
|
|
||||||
// ArpResponse::LookupResp {
|
|
||||||
// mac,
|
|
||||||
// ip,
|
|
||||||
// do_arp_request,
|
|
||||||
// } => {
|
|
||||||
// if do_arp_request {
|
|
||||||
// add_to_arp_wait_list(dstip, data);
|
|
||||||
|
|
||||||
// info!(
|
|
||||||
// "find ip: {:?} => {:?}",
|
|
||||||
// src.to_be_bytes(),
|
|
||||||
// dstip.to_be_bytes()
|
|
||||||
// );
|
|
||||||
// let arp_msg =
|
|
||||||
// generate_arp_request(src_mac, ip, eee.device_config.get_ip());
|
|
||||||
|
|
||||||
// let Ok(encrypted) = eee.encryptor.load().encrypt(&arp_msg) else {
|
|
||||||
// // let Ok(encrypted) = aes_encrypt(&encrypt_key, &arp_msg) else {
|
|
||||||
// error!("failed to encrypt arp request");
|
|
||||||
// return Ok(());
|
|
||||||
// };
|
|
||||||
// // println!("arp_msg: {:?}", arp_msg);
|
|
||||||
// let data = SdlData {
|
|
||||||
// network_id: eee.network_id.load(Ordering::Relaxed),
|
|
||||||
// src_mac: Vec::from(src_mac),
|
|
||||||
// dst_mac: Vec::from([0xff; 6]),
|
|
||||||
// is_p2p: true,
|
|
||||||
// ttl: SDLAN_DEFAULT_TTL as u32,
|
|
||||||
// data: Bytes::from(encrypted),
|
|
||||||
|
|
||||||
// session_token: eee.session_token.get(),
|
|
||||||
// identity_id: eee.identity_id.load(),
|
|
||||||
// };
|
|
||||||
// let data =
|
|
||||||
// encode_to_udp_message(Some(data), PacketType::Data as u8).unwrap();
|
|
||||||
// debug!("sending arp");
|
|
||||||
// // let data = marshal_message(&data);
|
|
||||||
// send_packet_to_net(eee, BROADCAST_MAC, &data, arp_msg.len() as u64)
|
|
||||||
// .await;
|
|
||||||
// // edge.sock.send(data).await;
|
|
||||||
// // println!("should send arp");
|
|
||||||
// return Ok(());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let packet = form_ethernet_packet(src_mac, mac, &data);
|
|
||||||
// // prepend the ether header
|
|
||||||
// /*
|
|
||||||
// let mut etherheader = Ethernet2Header::default();
|
|
||||||
// etherheader.destination = mac;
|
|
||||||
// etherheader.ether_type = etherparse::EtherType::IPV4;
|
|
||||||
// etherheader.source = src_mac;
|
|
||||||
// let mut packet = Vec::with_capacity(14 + data.len() + 4);
|
|
||||||
// packet.extend_from_slice(ðerheader.to_bytes()[..]);
|
|
||||||
// packet.extend_from_slice(&data);
|
|
||||||
// */
|
|
||||||
// // let crc = CRC_HASH.checksum(&packet);
|
|
||||||
// // packet.extend_from_slice(&crc.to_be_bytes());
|
|
||||||
|
|
||||||
// let pkt_size = packet.len();
|
|
||||||
// // println!("sending data with mac");
|
|
||||||
|
|
||||||
// // let Ok(encrypted) = aes_encrypt(&encrypt_key, &packet) else {
|
|
||||||
// let Ok(encrypted) = eee.encryptor.load().encrypt(&packet) else {
|
|
||||||
// error!("failed to encrypt packet request");
|
|
||||||
// return Ok(());
|
|
||||||
// };
|
|
||||||
// let data = SdlData {
|
|
||||||
// is_p2p: true,
|
|
||||||
// network_id: eee.network_id.load(Ordering::Relaxed),
|
|
||||||
// ttl: SDLAN_DEFAULT_TTL as u32,
|
|
||||||
// src_mac: Vec::from(src_mac),
|
|
||||||
// dst_mac: Vec::from(mac),
|
|
||||||
// data: Bytes::from(encrypted),
|
|
||||||
// session_token: eee.session_token.get(),
|
|
||||||
// identity_id: eee.identity_id.load(),
|
|
||||||
// };
|
|
||||||
// let msg =
|
|
||||||
// encode_to_udp_message(Some(data), PacketType::Data as u8).unwrap();
|
|
||||||
// let size = msg.len();
|
|
||||||
// send_packet_to_net(eee, mac, &msg, pkt_size as u64).await;
|
|
||||||
// // let dstip = u32::from_be_bytes(ipv4hdr.0.destination);
|
|
||||||
// }
|
|
||||||
// _ => {}
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// Err(e) => {
|
|
||||||
// error!("failed to parse ip packet: {}", e.to_string());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// Ok(())
|
|
||||||
// }
|
|
||||||
|
|
||||||
async fn handle_packet_from_device(&self, mut header: BytesMut) -> std::io::Result<()> {
|
async fn handle_packet_from_device(&self, mut header: BytesMut) -> std::io::Result<()> {
|
||||||
use etherparse::IpHeaders;
|
|
||||||
|
|
||||||
let eee = get_edge();
|
let eee = get_edge();
|
||||||
|
|
||||||
let src_mac = eee.device_config.get_mac();
|
let src_mac = eee.device_config.get_mac();
|
||||||
@ -524,78 +516,79 @@ impl TunTapPacketHandler for Iface {
|
|||||||
}
|
}
|
||||||
_other => {}
|
_other => {}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match eee.arp_table.get(dstip) {
|
match eee.arp_table.get(dstip) {
|
||||||
Some(mac) => {
|
Some(mac) => {
|
||||||
let pkt_size = data.len() + 14;
|
let pkt_size = data.len() + 14;
|
||||||
let mut etherheader = Ethernet2Header::default();
|
let mut etherheader = Ethernet2Header::default();
|
||||||
etherheader.destination = mac;
|
etherheader.destination = mac;
|
||||||
etherheader.ether_type = etherparse::EtherType::IPV4;
|
etherheader.ether_type = etherparse::EtherType::IPV4;
|
||||||
etherheader.source = src_mac;
|
etherheader.source = src_mac;
|
||||||
// let mut packet = Vec::with_capacity(14 + data.len() + 4);
|
// let mut packet = Vec::with_capacity(14 + data.len() + 4);
|
||||||
|
|
||||||
header.copy_from_slice(ðerheader.to_bytes()[..]);
|
header.copy_from_slice(ðerheader.to_bytes()[..]);
|
||||||
|
|
||||||
let crc = caculate_crc(&data);
|
let crc = caculate_crc(&data);
|
||||||
header.unsplit(data);
|
header.unsplit(data);
|
||||||
|
|
||||||
// packet.extend_from_slice(ðerheader.to_bytes()[..]);
|
// packet.extend_from_slice(ðerheader.to_bytes()[..]);
|
||||||
// packet.extend_from_slice(&data);
|
// packet.extend_from_slice(&data);
|
||||||
header.extend_from_slice(&crc.to_be_bytes());
|
header.extend_from_slice(&crc.to_be_bytes());
|
||||||
// packet.extend_from_slice(&crc.to_be_bytes());
|
// packet.extend_from_slice(&crc.to_be_bytes());
|
||||||
|
|
||||||
// let pkt_size = packet.len();
|
// let pkt_size = packet.len();
|
||||||
// println!("sending data with mac");
|
// println!("sending data with mac");
|
||||||
|
|
||||||
// let Ok(encrypted) = aes_encrypt(&encrypt_key, &packet) else {
|
let encryptor = eee.encryptor.load();
|
||||||
let Ok(encrypted) = eee.encryptor.load().encrypt(&header) else {
|
if let Err(e) = encryptor.encrypt(&mut header) {
|
||||||
error!("failed to encrypt packet request");
|
error!("failed to encrypt packet request: {:?}", e);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
|
||||||
|
|
||||||
let data = SdlData {
|
|
||||||
is_p2p: true,
|
|
||||||
network_id: eee.network_id.load(Ordering::Relaxed),
|
|
||||||
ttl: SDLAN_DEFAULT_TTL as u32,
|
|
||||||
src_mac: Vec::from(src_mac),
|
|
||||||
dst_mac: Vec::from(mac),
|
|
||||||
data: Bytes::from(encrypted),
|
|
||||||
session_token: eee.session_token.get(),
|
|
||||||
identity_id: eee.identity_id.load(),
|
|
||||||
};
|
|
||||||
let msg =
|
|
||||||
encode_to_udp_message(Some(data), PacketType::Data as u8).unwrap();
|
|
||||||
let size = msg.len();
|
|
||||||
send_packet_to_net(eee, mac, &msg, pkt_size as u64).await;
|
|
||||||
}
|
}
|
||||||
None => {
|
let data_bytes = header.freeze();
|
||||||
header.unsplit(data);
|
|
||||||
debug!(
|
|
||||||
"find ip: {:?} => {:?}",
|
|
||||||
src.to_be_bytes(),
|
|
||||||
dstip.to_be_bytes()
|
|
||||||
);
|
|
||||||
debug!(
|
|
||||||
"no mac found for ip {:?}, sending arp request",
|
|
||||||
dstip.to_be_bytes()
|
|
||||||
);
|
|
||||||
// let _ = eee.send_arp_request(dstip, dstip).await;
|
|
||||||
|
|
||||||
if eee.device_config.contains(&Ipv4Addr::from_bits(dstip)) {
|
let data = SdlData {
|
||||||
debug!("contains dst ip {}", ip_to_string(&dstip));
|
is_p2p: true,
|
||||||
eee.arp_table.add_to_arp_wait_list(dstip, header);
|
network_id: eee.network_id.load(Ordering::Relaxed),
|
||||||
let _ = eee.send_arp_request(dstip, dstip).await;
|
ttl: SDLAN_DEFAULT_TTL as u32,
|
||||||
} else {
|
src_mac: Vec::from(src_mac),
|
||||||
debug!("try to lookup ip: {}", ip_to_string(&dstip));
|
dst_mac: Vec::from(mac),
|
||||||
if let Some((_, real_ip)) = eee.route_table.lookup(dstip) {
|
data: data_bytes,
|
||||||
eee.arp_table.add_to_arp_wait_list(
|
session_token: eee.session_token.get(),
|
||||||
u32::from_be_bytes(real_ip.octets()),
|
identity_id: eee.identity_id.load(),
|
||||||
header,
|
};
|
||||||
);
|
let msg =
|
||||||
error!("got target route: {}", real_ip);
|
encode_to_udp_message(Some(data), PacketType::Data as u8).unwrap();
|
||||||
let real_ip = u32::from_be_bytes(real_ip.octets());
|
let size = msg.len();
|
||||||
let _ = eee.send_arp_request(real_ip, dstip).await;
|
send_packet_to_net(eee, mac, &msg, pkt_size as u64).await;
|
||||||
}
|
}
|
||||||
|
None => {
|
||||||
|
header.unsplit(data);
|
||||||
|
debug!(
|
||||||
|
"find ip: {:?} => {:?}",
|
||||||
|
src.to_be_bytes(),
|
||||||
|
dstip.to_be_bytes()
|
||||||
|
);
|
||||||
|
debug!(
|
||||||
|
"no mac found for ip {:?}, sending arp request",
|
||||||
|
dstip.to_be_bytes()
|
||||||
|
);
|
||||||
|
// let _ = eee.send_arp_request(dstip, dstip).await;
|
||||||
|
|
||||||
|
if eee.device_config.contains(&Ipv4Addr::from_bits(dstip)) {
|
||||||
|
debug!("contains dst ip {}", ip_to_string(&dstip));
|
||||||
|
eee.arp_table.add_to_arp_wait_list(dstip, header);
|
||||||
|
let _ = eee.send_arp_request(dstip, dstip).await;
|
||||||
|
} else {
|
||||||
|
debug!("try to lookup ip: {}", ip_to_string(&dstip));
|
||||||
|
if let Some((_, real_ip)) = eee.route_table.lookup(dstip) {
|
||||||
|
eee.arp_table.add_to_arp_wait_list(
|
||||||
|
u32::from_be_bytes(real_ip.octets()),
|
||||||
|
header,
|
||||||
|
);
|
||||||
|
error!("got target route: {}", real_ip);
|
||||||
|
let real_ip = u32::from_be_bytes(real_ip.octets());
|
||||||
|
let _ = eee.send_arp_request(real_ip, dstip).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -730,13 +723,18 @@ impl TunTapPacketHandler for Iface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn create_wintun(path: &str, name: &str) -> std::io::Result<Iface> {
|
fn create_wintun(path: &str, name: &str) -> std::io::Result<Iface> {
|
||||||
|
Ok(Iface::new(path, name))
|
||||||
|
/*
|
||||||
let wt = unsafe { wintun::load_from_path(path) }.expect("failed to load wintun");
|
let wt = unsafe { wintun::load_from_path(path) }.expect("failed to load wintun");
|
||||||
|
|
||||||
let adapter = match wintun::Adapter::open(&wt, name) {
|
let adapter = match wintun::Adapter::open(&wt, name) {
|
||||||
Ok(a) => a,
|
Ok(a) => a,
|
||||||
Err(_e) => {
|
Err(_e) => {
|
||||||
let Ok(adapt) = wintun::Adapter::create(&wt, name, "Punchnet", None) else {
|
let Ok(adapt) = wintun::Adapter::create(&wt, name, "Punchnet", None) else {
|
||||||
return Err(std::io::Error::new(std::io::ErrorKind::Other, "failed to create Punch adapter"));
|
return Err(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::Other,
|
||||||
|
"failed to create Punch adapter",
|
||||||
|
));
|
||||||
};
|
};
|
||||||
adapt
|
adapt
|
||||||
}
|
}
|
||||||
@ -746,7 +744,10 @@ fn create_wintun(path: &str, name: &str) -> std::io::Result<Iface> {
|
|||||||
.expect("failed to get adapter index");
|
.expect("failed to get adapter index");
|
||||||
// println!("idx = {}", idx);
|
// println!("idx = {}", idx);
|
||||||
let Ok(sess) = adapter.start_session(wintun::MAX_RING_CAPACITY) else {
|
let Ok(sess) = adapter.start_session(wintun::MAX_RING_CAPACITY) else {
|
||||||
return Err(std::io::Error::new(std::io::ErrorKind::Other, "failed to start session, maybe one process is running, or not running with admin?"));
|
return Err(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::Other,
|
||||||
|
"failed to start session, maybe one process is running, or not running with admin?",
|
||||||
|
));
|
||||||
};
|
};
|
||||||
let session = Arc::new(sess);
|
let session = Arc::new(sess);
|
||||||
Ok(Iface {
|
Ok(Iface {
|
||||||
@ -755,10 +756,11 @@ fn create_wintun(path: &str, name: &str) -> std::io::Result<Iface> {
|
|||||||
session,
|
session,
|
||||||
name: name.to_owned(),
|
name: name.to_owned(),
|
||||||
})
|
})
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_iface(name: &str, _mode: Mode) -> std::io::Result<Iface> {
|
pub fn new_iface(name: &str) -> std::io::Result<Iface> {
|
||||||
create_wintun("./wintun.dll", name)
|
create_wintun("wintun.dll", name)
|
||||||
// Ok(Box::new(create_wintun("/path/to/file")))
|
// Ok(Box::new(create_wintun("/path/to/file")))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -778,8 +780,13 @@ pub fn set_dns(name: &str, _network_domain: &str, gw: &str, ifidx: u32) -> Resul
|
|||||||
.creation_flags(0x08000000)
|
.creation_flags(0x08000000)
|
||||||
.status()?;
|
.status()?;
|
||||||
if !res.success() {
|
if !res.success() {
|
||||||
error!("failed to add route for dns 100.100.100.100: {:?}", res.code());
|
error!(
|
||||||
return Err(SDLanError::IOError("failed to add route for dns".to_owned()));
|
"failed to add route for dns 100.100.100.100: {:?}",
|
||||||
|
res.code()
|
||||||
|
);
|
||||||
|
return Err(SDLanError::IOError(
|
||||||
|
"failed to add route for dns".to_owned(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
//println!("res1: {}", res.status.success());
|
//println!("res1: {}", res.status.success());
|
||||||
|
|
||||||
|
|||||||
@ -8,9 +8,17 @@ use sdlan_sn_rs::{
|
|||||||
utils::{get_current_timestamp, ip_to_string, Mac, Result},
|
utils::{get_current_timestamp, ip_to_string, Mac, Result},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(any(feature = "tun", target_os = "windows"))]
|
||||||
|
pub const LAYER: tun_rs::Layer = tun_rs::Layer::L3;
|
||||||
|
|
||||||
|
#[cfg(all(not(feature = "tun"), not(target_os = "windows")))]
|
||||||
|
pub const LAYER: tun_rs::Layer = tun_rs::Layer::L2;
|
||||||
|
|
||||||
use tracing::{debug, warn};
|
use tracing::{debug, warn};
|
||||||
|
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
#[cfg(feature = "tun")]
|
||||||
|
use tun_rs::Layer;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
network::{form_ethernet_packet, send_packet_to_net, Node, RouteInfo},
|
network::{form_ethernet_packet, send_packet_to_net, Node, RouteInfo},
|
||||||
@ -94,17 +102,16 @@ impl ArpWaitList {
|
|||||||
if (now - item.timestamp) > 5 {
|
if (now - item.timestamp) > 5 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let packet = form_ethernet_packet(src_mac, mac, item.origin_data);
|
let mut packet = form_ethernet_packet(src_mac, mac, item.origin_data);
|
||||||
|
|
||||||
let pkt_size = packet.len();
|
let pkt_size = packet.len();
|
||||||
|
|
||||||
let Ok(encrypted) = edge.encryptor.load().encrypt(&packet) else {
|
let encryptor = edge.encryptor.load();
|
||||||
// let Ok(encrypted) = edge.encryptor.read().unwrap().encrypt(&packet) else {
|
if let Err(e) = encryptor.encrypt(&mut packet) {
|
||||||
// let Ok(encrypted) = aes_encrypt(&encrypt_key, &packet) else {
|
error!("failed to encrypt packet request: {:?}", e);
|
||||||
error!("failed to encrypt packet request");
|
|
||||||
return;
|
return;
|
||||||
};
|
}
|
||||||
let data_bytes = Bytes::from(encrypted);
|
let data_bytes = packet.freeze();
|
||||||
let data = SdlData {
|
let data = SdlData {
|
||||||
is_p2p: true,
|
is_p2p: true,
|
||||||
network_id,
|
network_id,
|
||||||
|
|||||||
@ -730,12 +730,14 @@ impl ReadWriteActor {
|
|||||||
match start_stop_chan.recv().await {
|
match start_stop_chan.recv().await {
|
||||||
Some(v) => {
|
Some(v) => {
|
||||||
if !v.is_start {
|
if !v.is_start {
|
||||||
|
error!("stop called1");
|
||||||
started = false;
|
started = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_other => {
|
_other => {
|
||||||
// send chan is closed;
|
// send chan is closed;
|
||||||
|
error!("stop called2");
|
||||||
started = false;
|
started = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,16 +1,19 @@
|
|||||||
use std::{sync::atomic::{AtomicU32, Ordering}, time::{SystemTime, UNIX_EPOCH}};
|
use std::{
|
||||||
|
sync::atomic::{AtomicU32, Ordering},
|
||||||
|
time::{SystemTime, UNIX_EPOCH},
|
||||||
|
};
|
||||||
|
|
||||||
|
use bytes::BytesMut;
|
||||||
|
use chacha20poly1305::{aead::AeadInPlace, ChaCha20Poly1305, KeyInit};
|
||||||
|
use sdlan_sn_rs::utils::{aes_decrypt, aes_encrypt, Result, SDLanError};
|
||||||
|
|
||||||
use chacha20poly1305::{KeyInit, aead::Aead};
|
const COUNTER_MASK: u32 = (1 << 24) - 1;
|
||||||
use sdlan_sn_rs::utils::{Result, SDLanError, aes_decrypt, aes_encrypt};
|
|
||||||
|
|
||||||
const COUNTER_MASK: u32 = (1<<24) - 1;
|
|
||||||
|
|
||||||
pub trait Encryptor {
|
pub trait Encryptor {
|
||||||
fn is_setted(&self) -> bool;
|
fn is_setted(&self) -> bool;
|
||||||
fn set_key(&mut self, region_id: u32, key:Vec<u8>);
|
fn set_key(&mut self, region_id: u32, key: Vec<u8>);
|
||||||
fn encrypt(&self, data: &[u8]) -> Result<Vec<u8>>;
|
fn encrypt(&self, data: &mut BytesMut) -> Result<()>;
|
||||||
fn decrypt(&self, ciphered: &[u8]) -> Result<Vec<u8>>;
|
fn decrypt(&self, data: &mut BytesMut) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum MyEncryptor {
|
pub enum MyEncryptor {
|
||||||
@ -27,16 +30,12 @@ impl MyEncryptor {
|
|||||||
pub fn is_setted(&self) -> bool {
|
pub fn is_setted(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::Invalid => false,
|
Self::Invalid => false,
|
||||||
Self::Aes(aes) => {
|
Self::Aes(aes) => aes.is_setted(),
|
||||||
aes.is_setted()
|
Self::ChaChao20(cha) => cha.is_setted(),
|
||||||
}
|
|
||||||
Self::ChaChao20(cha) => {
|
|
||||||
cha.is_setted()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_key(&mut self, region_id: u32, key:Vec<u8>) {
|
pub fn set_key(&mut self, region_id: u32, key: Vec<u8>) {
|
||||||
match self {
|
match self {
|
||||||
Self::Invalid => {}
|
Self::Invalid => {}
|
||||||
Self::Aes(aes) => {
|
Self::Aes(aes) => {
|
||||||
@ -48,35 +47,25 @@ impl MyEncryptor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn encrypt(&self, data: &[u8]) -> Result<Vec<u8>> {
|
pub fn encrypt(&self, data: &mut BytesMut) -> Result<()> {
|
||||||
match self {
|
match self {
|
||||||
Self::Invalid => {
|
Self::Invalid => Err(SDLanError::EncryptError("invalid encryptor".to_owned())),
|
||||||
Err(SDLanError::EncryptError("invalid encryptor".to_owned()))
|
Self::Aes(aes) => aes.encrypt(data),
|
||||||
}
|
Self::ChaChao20(cha) => cha.encrypt(data),
|
||||||
Self::Aes(aes) => {
|
|
||||||
aes.encrypt(data)
|
|
||||||
}
|
|
||||||
Self::ChaChao20(cha) => {
|
|
||||||
cha.encrypt(data)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn decrypt(&self, ciphered: &[u8]) -> Result<Vec<u8>> {
|
|
||||||
|
pub fn decrypt(&self, data: &mut BytesMut) -> Result<()> {
|
||||||
match self {
|
match self {
|
||||||
Self::Invalid => {
|
Self::Invalid => Err(SDLanError::EncryptError("invalid encryptor".to_owned())),
|
||||||
Err(SDLanError::EncryptError("invalid encryptor".to_owned()))
|
Self::Aes(aes) => aes.decrypt(data),
|
||||||
}
|
Self::ChaChao20(cha) => cha.decrypt(data),
|
||||||
Self::Aes(aes) => {
|
|
||||||
aes.decrypt(ciphered)
|
|
||||||
}
|
|
||||||
Self::ChaChao20(cha) => {
|
|
||||||
cha.decrypt(ciphered)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Chacha20Encryptor {
|
pub struct Chacha20Encryptor {
|
||||||
|
cipher: ChaCha20Poly1305,
|
||||||
key: Vec<u8>,
|
key: Vec<u8>,
|
||||||
is_setted: bool,
|
is_setted: bool,
|
||||||
next_counter: AtomicU32,
|
next_counter: AtomicU32,
|
||||||
@ -86,6 +75,7 @@ pub struct Chacha20Encryptor {
|
|||||||
impl Chacha20Encryptor {
|
impl Chacha20Encryptor {
|
||||||
pub fn new(key: Vec<u8>, region_id: u32) -> Self {
|
pub fn new(key: Vec<u8>, region_id: u32) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
cipher: chacha20poly1305::ChaCha20Poly1305::new(key.as_slice().into()),
|
||||||
key,
|
key,
|
||||||
is_setted: true,
|
is_setted: true,
|
||||||
next_counter: AtomicU32::new(0),
|
next_counter: AtomicU32::new(0),
|
||||||
@ -95,48 +85,83 @@ impl Chacha20Encryptor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Encryptor for Chacha20Encryptor {
|
impl Encryptor for Chacha20Encryptor {
|
||||||
fn set_key(&mut self, region_id: u32, key:Vec<u8>) {
|
fn set_key(&mut self, region_id: u32, key: Vec<u8>) {
|
||||||
|
self.cipher = chacha20poly1305::ChaCha20Poly1305::new(key.as_slice().into());
|
||||||
self.key = key;
|
self.key = key;
|
||||||
self.region_id = region_id;
|
self.region_id = region_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encrypt(&self, data: &[u8]) -> Result<Vec<u8>> {
|
fn encrypt(&self, data: &mut BytesMut) -> Result<()> {
|
||||||
let cipher = chacha20poly1305::ChaCha20Poly1305::new(self.key.as_slice().into());
|
let plaintext_len = data.len();
|
||||||
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis() as u64;
|
|
||||||
|
// Prepare nonce
|
||||||
|
let now = SystemTime::now()
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.unwrap()
|
||||||
|
.as_millis() as u64;
|
||||||
|
|
||||||
let next_counter = self.next_counter.fetch_update(Ordering::Release, Ordering::Acquire, |current| {
|
let next_counter = self
|
||||||
Some((current + 1) & COUNTER_MASK)
|
.next_counter
|
||||||
}).unwrap() as u64;
|
.fetch_update(Ordering::Release, Ordering::Acquire, |current| {
|
||||||
|
Some((current + 1) & COUNTER_MASK)
|
||||||
|
})
|
||||||
|
.unwrap() as u64;
|
||||||
|
|
||||||
let mut nonce = Vec::new();
|
let mut nonce_bytes = [0u8; 12];
|
||||||
let region_id = self.region_id.to_be_bytes();
|
let region_id_bytes = self.region_id.to_be_bytes();
|
||||||
nonce.extend_from_slice(®ion_id);
|
nonce_bytes[0..4].copy_from_slice(®ion_id_bytes);
|
||||||
let next_data = (now<<24) | next_counter;
|
let next_data = (now << 24) | next_counter;
|
||||||
nonce.extend_from_slice(&next_data.to_be_bytes());
|
nonce_bytes[4..12].copy_from_slice(&next_data.to_be_bytes());
|
||||||
|
let nonce = chacha20poly1305::Nonce::from_slice(&nonce_bytes);
|
||||||
|
|
||||||
match cipher.encrypt(nonce.as_slice().into(), data) {
|
// Make room for tag (16 bytes) at the end
|
||||||
Ok(data) => {
|
data.resize(plaintext_len + 16, 0);
|
||||||
nonce.extend_from_slice(&data);
|
let (payload, tag_space) = data.split_at_mut(plaintext_len);
|
||||||
Ok(nonce)
|
|
||||||
},
|
// Encrypt payload in place and get tag
|
||||||
Err(e) => {
|
let tag = self
|
||||||
Err(SDLanError::EncryptError(e.to_string()))
|
.cipher
|
||||||
}
|
.encrypt_in_place_detached(&nonce, &[], payload)
|
||||||
}
|
.map_err(|e| SDLanError::EncryptError(e.to_string()))?;
|
||||||
|
|
||||||
|
tag_space[..16].copy_from_slice(&tag);
|
||||||
|
|
||||||
|
// Prepend nonce (12 bytes)
|
||||||
|
let mut final_buf = BytesMut::with_capacity(12 + data.len());
|
||||||
|
final_buf.extend_from_slice(&nonce_bytes);
|
||||||
|
final_buf.unsplit(data.split_off(0));
|
||||||
|
*data = final_buf;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decrypt(&self, ciphered: &[u8]) -> Result<Vec<u8>> {
|
fn decrypt(&self, data: &mut BytesMut) -> Result<()> {
|
||||||
if ciphered.len() < 12 {
|
if data.len() < 28 {
|
||||||
return Err(SDLanError::EncryptError("ciphered text size error".to_owned()))
|
return Err(SDLanError::EncryptError(
|
||||||
}
|
"ciphered text size error".to_owned(),
|
||||||
let cipher = chacha20poly1305::ChaCha20Poly1305::new(self.key.as_slice().into());
|
));
|
||||||
let nonce = &ciphered[0..12];
|
|
||||||
match cipher.decrypt(nonce.into(), &ciphered[12..]) {
|
|
||||||
Ok(data) => Ok(data),
|
|
||||||
Err(e) => {
|
|
||||||
Err(SDLanError::EncryptError(format!("failed to decyrpt: {}", e.to_string())))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Split off the 12-byte Nonce
|
||||||
|
let mut payload = data.split_off(12);
|
||||||
|
let mut nonce_bytes = [0u8; 12];
|
||||||
|
nonce_bytes.copy_from_slice(&data[0..12]);
|
||||||
|
let nonce = chacha20poly1305::Nonce::from_slice(&nonce_bytes);
|
||||||
|
|
||||||
|
// Split off the 16-byte Tag
|
||||||
|
let ciphertext_len = payload.len() - 16;
|
||||||
|
let (ciphertext, tag_space) = payload.split_at_mut(ciphertext_len);
|
||||||
|
let tag = chacha20poly1305::Tag::from_slice(&tag_space[..16]);
|
||||||
|
|
||||||
|
// Decrypt in place
|
||||||
|
self.cipher
|
||||||
|
.decrypt_in_place_detached(&nonce, &[], ciphertext, tag)
|
||||||
|
.map_err(|e| SDLanError::EncryptError(format!("failed to decrypt: {}", e.to_string())))?;
|
||||||
|
|
||||||
|
payload.truncate(ciphertext_len);
|
||||||
|
*data = payload;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_setted(&self) -> bool {
|
fn is_setted(&self) -> bool {
|
||||||
@ -159,21 +184,39 @@ impl AesEncryptor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Encryptor for AesEncryptor {
|
impl Encryptor for AesEncryptor {
|
||||||
fn decrypt(&self, ciphered: &[u8]) -> Result<Vec<u8>> {
|
fn decrypt(&self, data: &mut BytesMut) -> Result<()> {
|
||||||
aes_decrypt(&self.key, ciphered)
|
let res = aes_decrypt(&self.key, data)?;
|
||||||
|
*data = BytesMut::from(res.as_slice());
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encrypt(&self, data: &[u8]) -> Result<Vec<u8>> {
|
fn encrypt(&self, data: &mut BytesMut) -> Result<()> {
|
||||||
aes_encrypt(&self.key, data)
|
let res = aes_encrypt(&self.key, data)?;
|
||||||
|
*data = BytesMut::from(res.as_slice());
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_setted(&self) -> bool {
|
fn is_setted(&self) -> bool {
|
||||||
self.is_setted
|
self.is_setted
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_key(&mut self, _region_id: u32, key:Vec<u8>) {
|
fn set_key(&mut self, _region_id: u32, key: Vec<u8>) {
|
||||||
self.key = key;
|
self.key = key;
|
||||||
self.is_setted = true;
|
self.is_setted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_chacha20_encrypt_decrypt() {
|
||||||
|
let key = vec![0u8; 32];
|
||||||
|
let encryptor = Chacha20Encryptor::new(key, 1);
|
||||||
|
let mut data = BytesMut::from(&b"hello world"[..]);
|
||||||
|
encryptor.encrypt(&mut data).unwrap();
|
||||||
|
encryptor.decrypt(&mut data).unwrap();
|
||||||
|
assert_eq!(&data[..], b"hello world");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user