mirror of
https://mirror.suhoan.cn/https://github.com/EasyTier/EasyTier.git
synced 2025-12-15 06:07:23 +08:00
make tunnel zero copy, for better performance. remove most of the locks in io path. introduce quic tunnel prepare for encryption
182 lines
4.5 KiB
Rust
182 lines
4.5 KiB
Rust
use crate::common::PeerId;
|
|
|
|
mod three_node;
|
|
|
|
pub fn get_guest_veth_name(net_ns: &str) -> &str {
|
|
Box::leak(format!("veth_{}_g", net_ns).into_boxed_str())
|
|
}
|
|
|
|
pub fn get_host_veth_name(net_ns: &str) -> &str {
|
|
Box::leak(format!("veth_{}_h", net_ns).into_boxed_str())
|
|
}
|
|
|
|
pub fn del_netns(name: &str) {
|
|
// del veth host
|
|
let _ = std::process::Command::new("ip")
|
|
.args(&["link", "del", get_host_veth_name(name)])
|
|
.output();
|
|
|
|
let _ = std::process::Command::new("ip")
|
|
.args(&["netns", "del", name])
|
|
.output();
|
|
}
|
|
|
|
pub fn create_netns(name: &str, ipv4: &str) {
|
|
// create netns
|
|
let _ = std::process::Command::new("ip")
|
|
.args(&["netns", "add", name])
|
|
.output()
|
|
.unwrap();
|
|
|
|
// set lo up
|
|
let _ = std::process::Command::new("ip")
|
|
.args(&["netns", "exec", name, "ip", "link", "set", "lo", "up"])
|
|
.output()
|
|
.unwrap();
|
|
|
|
let _ = std::process::Command::new("ip")
|
|
.args(&[
|
|
"link",
|
|
"add",
|
|
get_host_veth_name(name),
|
|
"type",
|
|
"veth",
|
|
"peer",
|
|
"name",
|
|
get_guest_veth_name(name),
|
|
])
|
|
.output()
|
|
.unwrap();
|
|
|
|
let _ = std::process::Command::new("ip")
|
|
.args(&["link", "set", get_guest_veth_name(name), "netns", name])
|
|
.output()
|
|
.unwrap();
|
|
|
|
let _ = std::process::Command::new("ip")
|
|
.args(&[
|
|
"netns",
|
|
"exec",
|
|
name,
|
|
"ip",
|
|
"link",
|
|
"set",
|
|
get_guest_veth_name(name),
|
|
"up",
|
|
])
|
|
.output()
|
|
.unwrap();
|
|
|
|
let _ = std::process::Command::new("ip")
|
|
.args(&["link", "set", get_host_veth_name(name), "up"])
|
|
.output()
|
|
.unwrap();
|
|
|
|
let _ = std::process::Command::new("ip")
|
|
.args(&[
|
|
"netns",
|
|
"exec",
|
|
name,
|
|
"ip",
|
|
"addr",
|
|
"add",
|
|
ipv4,
|
|
"dev",
|
|
get_guest_veth_name(name),
|
|
])
|
|
.output()
|
|
.unwrap();
|
|
}
|
|
|
|
pub fn prepare_bridge(name: &str) {
|
|
// del bridge with brctl
|
|
let _ = std::process::Command::new("brctl")
|
|
.args(&["delbr", name])
|
|
.output();
|
|
|
|
// create new br
|
|
let _ = std::process::Command::new("brctl")
|
|
.args(&["addbr", name])
|
|
.output();
|
|
}
|
|
|
|
pub fn add_ns_to_bridge(br_name: &str, ns_name: &str) {
|
|
// use brctl to add ns to bridge
|
|
let _ = std::process::Command::new("brctl")
|
|
.args(&["addif", br_name, get_host_veth_name(ns_name)])
|
|
.output()
|
|
.unwrap();
|
|
|
|
// set bridge up
|
|
let _ = std::process::Command::new("ip")
|
|
.args(&["link", "set", br_name, "up"])
|
|
.output()
|
|
.unwrap();
|
|
}
|
|
|
|
pub fn enable_log() {
|
|
let filter = tracing_subscriber::EnvFilter::builder()
|
|
.with_default_directive(tracing::level_filters::LevelFilter::TRACE.into())
|
|
.from_env()
|
|
.unwrap()
|
|
.add_directive("tarpc=error".parse().unwrap());
|
|
tracing_subscriber::fmt::fmt()
|
|
.pretty()
|
|
.with_env_filter(filter)
|
|
.init();
|
|
}
|
|
|
|
fn check_route(ipv4: &str, dst_peer_id: PeerId, routes: Vec<crate::rpc::Route>) {
|
|
let mut found = false;
|
|
for r in routes.iter() {
|
|
if r.ipv4_addr == ipv4.to_string() {
|
|
found = true;
|
|
assert_eq!(r.peer_id, dst_peer_id, "{:?}", routes);
|
|
}
|
|
}
|
|
assert!(
|
|
found,
|
|
"routes: {:?}, dst_peer_id: {}, ipv4: {}",
|
|
routes, dst_peer_id, ipv4
|
|
);
|
|
}
|
|
|
|
async fn wait_proxy_route_appear(
|
|
mgr: &std::sync::Arc<crate::peers::peer_manager::PeerManager>,
|
|
ipv4: &str,
|
|
dst_peer_id: PeerId,
|
|
proxy_cidr: &str,
|
|
) {
|
|
let now = std::time::Instant::now();
|
|
loop {
|
|
for r in mgr.list_routes().await.iter() {
|
|
let r = r;
|
|
if r.proxy_cidrs.contains(&proxy_cidr.to_owned()) {
|
|
assert_eq!(r.peer_id, dst_peer_id);
|
|
assert_eq!(r.ipv4_addr, ipv4);
|
|
return;
|
|
}
|
|
}
|
|
if now.elapsed().as_secs() > 5 {
|
|
panic!("wait proxy route appear timeout");
|
|
}
|
|
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
|
|
}
|
|
}
|
|
|
|
fn set_link_status(net_ns: &str, up: bool) {
|
|
let _ = std::process::Command::new("ip")
|
|
.args(&[
|
|
"netns",
|
|
"exec",
|
|
net_ns,
|
|
"ip",
|
|
"link",
|
|
"set",
|
|
get_guest_veth_name(net_ns),
|
|
if up { "up" } else { "down" },
|
|
])
|
|
.output()
|
|
.unwrap();
|
|
}
|