mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-09 11:14:30 +00:00
28fe6257be
This patch implements: 1. A dns server that handles .et.net. zone in local and forward all other queries to system dns server. 2. A dns server instance which is a singleton in one machine, using one specific tcp port to be exclusive with each other. this instance is responsible for config system dns and run the dns server to handle dns queries. 3. A dns client instance that all easytier instance will run one, this instance will try to connect to dns server instance, and update the dns record in the dns server instance. this pr only implements the system config for windows. linux & mac will do later.
132 lines
3.4 KiB
Rust
132 lines
3.4 KiB
Rust
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
|
|
mod darwin;
|
|
#[cfg(any(target_os = "linux"))]
|
|
mod netlink;
|
|
#[cfg(target_os = "windows")]
|
|
mod windows;
|
|
|
|
mod route;
|
|
|
|
use std::net::Ipv4Addr;
|
|
|
|
use async_trait::async_trait;
|
|
use tokio::process::Command;
|
|
|
|
use super::error::Error;
|
|
|
|
#[async_trait]
|
|
pub trait IfConfiguerTrait: Send + Sync {
|
|
async fn add_ipv4_route(
|
|
&self,
|
|
_name: &str,
|
|
_address: Ipv4Addr,
|
|
_cidr_prefix: u8,
|
|
_cost: Option<i32>,
|
|
) -> Result<(), Error> {
|
|
Ok(())
|
|
}
|
|
async fn remove_ipv4_route(
|
|
&self,
|
|
_name: &str,
|
|
_address: Ipv4Addr,
|
|
_cidr_prefix: u8,
|
|
) -> Result<(), Error> {
|
|
Ok(())
|
|
}
|
|
async fn add_ipv4_ip(
|
|
&self,
|
|
_name: &str,
|
|
_address: Ipv4Addr,
|
|
_cidr_prefix: u8,
|
|
) -> Result<(), Error> {
|
|
Ok(())
|
|
}
|
|
async fn set_link_status(&self, _name: &str, _up: bool) -> Result<(), Error> {
|
|
Ok(())
|
|
}
|
|
async fn remove_ip(&self, _name: &str, _ip: Option<Ipv4Addr>) -> Result<(), Error> {
|
|
Ok(())
|
|
}
|
|
async fn wait_interface_show(&self, _name: &str) -> Result<(), Error> {
|
|
return Ok(());
|
|
}
|
|
async fn set_mtu(&self, _name: &str, _mtu: u32) -> Result<(), Error> {
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
fn cidr_to_subnet_mask(prefix_length: u8) -> Ipv4Addr {
|
|
if prefix_length > 32 {
|
|
panic!("Invalid CIDR prefix length");
|
|
}
|
|
|
|
let subnet_mask: u32 = (!0u32)
|
|
.checked_shl(32 - u32::from(prefix_length))
|
|
.unwrap_or(0);
|
|
Ipv4Addr::new(
|
|
((subnet_mask >> 24) & 0xFF) as u8,
|
|
((subnet_mask >> 16) & 0xFF) as u8,
|
|
((subnet_mask >> 8) & 0xFF) as u8,
|
|
(subnet_mask & 0xFF) as u8,
|
|
)
|
|
}
|
|
|
|
async fn run_shell_cmd(cmd: &str) -> Result<(), Error> {
|
|
let cmd_out: std::process::Output;
|
|
let stdout: String;
|
|
let stderr: String;
|
|
#[cfg(target_os = "windows")]
|
|
{
|
|
const CREATE_NO_WINDOW: u32 = 0x08000000;
|
|
cmd_out = Command::new("cmd")
|
|
.stdin(std::process::Stdio::null())
|
|
.arg("/C")
|
|
.arg(cmd)
|
|
.creation_flags(CREATE_NO_WINDOW)
|
|
.output()
|
|
.await?;
|
|
stdout = crate::utils::utf8_or_gbk_to_string(cmd_out.stdout.as_slice());
|
|
stderr = crate::utils::utf8_or_gbk_to_string(cmd_out.stderr.as_slice());
|
|
};
|
|
|
|
#[cfg(not(target_os = "windows"))]
|
|
{
|
|
cmd_out = Command::new("sh").arg("-c").arg(cmd).output().await?;
|
|
stdout = String::from_utf8_lossy(cmd_out.stdout.as_slice()).to_string();
|
|
stderr = String::from_utf8_lossy(cmd_out.stderr.as_slice()).to_string();
|
|
};
|
|
|
|
let ec = cmd_out.status.code();
|
|
let succ = cmd_out.status.success();
|
|
tracing::info!(?cmd, ?ec, ?succ, ?stdout, ?stderr, "run shell cmd");
|
|
|
|
if !cmd_out.status.success() {
|
|
return Err(Error::ShellCommandError(stdout + &stderr));
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
pub struct DummyIfConfiger {}
|
|
#[async_trait]
|
|
impl IfConfiguerTrait for DummyIfConfiger {}
|
|
|
|
#[cfg(any(target_os = "linux"))]
|
|
pub type IfConfiger = netlink::NetlinkIfConfiger;
|
|
|
|
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
|
|
pub type IfConfiger = darwin::MacIfConfiger;
|
|
|
|
#[cfg(target_os = "windows")]
|
|
pub type IfConfiger = windows::WindowsIfConfiger;
|
|
|
|
#[cfg(not(any(
|
|
target_os = "macos",
|
|
target_os = "linux",
|
|
target_os = "windows",
|
|
target_os = "freebsd",
|
|
)))]
|
|
pub type IfConfiger = DummyIfConfiger;
|
|
|
|
#[cfg(target_os = "windows")]
|
|
pub use windows::RegistryManager;
|