87 lines
2.4 KiB
Rust
Executable File
87 lines
2.4 KiB
Rust
Executable File
use std::{
|
|
net::{IpAddr, Ipv6Addr},
|
|
time::Duration,
|
|
};
|
|
|
|
use sdlan_sn_rs::{config::AF_INET6, peer::SdlanSock};
|
|
use std::sync::Arc;
|
|
use tokio::{sync::mpsc::Receiver};
|
|
use tokio_util::sync::CancellationToken;
|
|
use tracing::error;
|
|
|
|
use crate::{network::loop_socket_v6, utils::Socket};
|
|
|
|
use super::Node;
|
|
|
|
pub async fn run_ipv6(edge: &'static Node, mut v6_may_change: Receiver<bool>) {
|
|
v6_may_change.recv().await;
|
|
loop {
|
|
tokio::time::sleep(Duration::from_secs(1)).await;
|
|
let mut ipv6 = get_current_ipv6();
|
|
if ipv6.is_none() {
|
|
tokio::time::sleep(Duration::from_secs(5)).await;
|
|
ipv6 = get_current_ipv6();
|
|
if ipv6.is_none() {
|
|
v6_may_change.recv().await;
|
|
continue;
|
|
}
|
|
}
|
|
// ipv6 is not none
|
|
let ipv6 = ipv6.unwrap();
|
|
|
|
/*
|
|
let Ok(udpsocket) = UdpSocket::bind(format!("{}:0", ipv6)).await else {
|
|
tokio::time::sleep(Duration::from_secs(5)).await;
|
|
continue;
|
|
};
|
|
let port = udpsocket.local_addr().unwrap().port();
|
|
let addr = udpsocket.local_addr().unwrap().ip();
|
|
println!("ipv6: {}:{}", addr, port);
|
|
*/
|
|
|
|
let socket = Arc::new(Socket::build_v6(ipv6, 0).await.unwrap());
|
|
let port = socket.get_local_port();
|
|
let socket_clone = socket.clone();
|
|
let cancel = CancellationToken::new();
|
|
|
|
*edge.ipv6.write().unwrap() = Some(SdlanSock {
|
|
family: AF_INET6,
|
|
port,
|
|
v4: [0; 4],
|
|
v6: ipv6.octets(),
|
|
});
|
|
*edge.udp_sock_v6.write().unwrap() = Some(socket);
|
|
tokio::select! {
|
|
_ = loop_socket_v6(edge, socket_clone, cancel.clone()) => {
|
|
|
|
}
|
|
_ = v6_may_change.recv() => {
|
|
cancel.cancel()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn get_current_ipv6() -> Option<Ipv6Addr> {
|
|
let Ok(ips) = local_ip_address::list_afinet_netifas() else {
|
|
error!("failed to get ip address");
|
|
return None;
|
|
};
|
|
|
|
for (_, ip) in ips {
|
|
match ip {
|
|
IpAddr::V4(_ipv4) => {
|
|
continue;
|
|
}
|
|
IpAddr::V6(ipv6) => {
|
|
if ipv6.octets()[0] & 0x70 == 0x20 {
|
|
// println!("got global ip: {}", ipv6);
|
|
return Some(ipv6);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
None
|
|
}
|