mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-06-14 19:51:58 +08:00
feat: 支持 ipv4/ipv6 双栈访问
This commit is contained in:
@@ -610,6 +610,7 @@ impl RustDeskConfigUpdate {
|
||||
pub struct WebConfigUpdate {
|
||||
pub http_port: Option<u16>,
|
||||
pub https_port: Option<u16>,
|
||||
pub bind_addresses: Option<Vec<String>>,
|
||||
pub bind_address: Option<String>,
|
||||
pub https_enabled: Option<bool>,
|
||||
}
|
||||
@@ -626,6 +627,13 @@ impl WebConfigUpdate {
|
||||
return Err(AppError::BadRequest("HTTPS port cannot be 0".into()));
|
||||
}
|
||||
}
|
||||
if let Some(ref addrs) = self.bind_addresses {
|
||||
for addr in addrs {
|
||||
if addr.parse::<std::net::IpAddr>().is_err() {
|
||||
return Err(AppError::BadRequest("Invalid bind address".into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(ref addr) = self.bind_address {
|
||||
if addr.parse::<std::net::IpAddr>().is_err() {
|
||||
return Err(AppError::BadRequest("Invalid bind address".into()));
|
||||
@@ -641,8 +649,16 @@ impl WebConfigUpdate {
|
||||
if let Some(port) = self.https_port {
|
||||
config.https_port = port;
|
||||
}
|
||||
if let Some(ref addr) = self.bind_address {
|
||||
if let Some(ref addrs) = self.bind_addresses {
|
||||
config.bind_addresses = addrs.clone();
|
||||
if let Some(first) = addrs.first() {
|
||||
config.bind_address = first.clone();
|
||||
}
|
||||
} else if let Some(ref addr) = self.bind_address {
|
||||
config.bind_address = addr.clone();
|
||||
if config.bind_addresses.is_empty() {
|
||||
config.bind_addresses = vec![addr.clone()];
|
||||
}
|
||||
}
|
||||
if let Some(enabled) = self.https_enabled {
|
||||
config.https_enabled = enabled;
|
||||
|
||||
@@ -316,28 +316,11 @@ fn get_network_addresses() -> Vec<NetworkAddress> {
|
||||
Err(_) => return Vec::new(),
|
||||
};
|
||||
|
||||
// Build a map of interface name -> IPv4 address
|
||||
let mut ipv4_map: std::collections::HashMap<String, String> = std::collections::HashMap::new();
|
||||
for ifaddr in all_addrs {
|
||||
// Skip loopback
|
||||
if ifaddr.interface_name == "lo" {
|
||||
continue;
|
||||
}
|
||||
// Only collect IPv4 addresses (skip if already have one for this interface)
|
||||
if !ipv4_map.contains_key(&ifaddr.interface_name) {
|
||||
if let Some(addr) = ifaddr.address {
|
||||
if let Some(sockaddr_in) = addr.as_sockaddr_in() {
|
||||
ipv4_map.insert(ifaddr.interface_name.clone(), sockaddr_in.ip().to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now check which interfaces are up
|
||||
let mut addresses = Vec::new();
|
||||
// Check which interfaces are up
|
||||
let mut up_ifaces = std::collections::HashSet::new();
|
||||
let net_dir = match std::fs::read_dir("/sys/class/net") {
|
||||
Ok(dir) => dir,
|
||||
Err(_) => return addresses,
|
||||
Err(_) => return Vec::new(),
|
||||
};
|
||||
|
||||
for entry in net_dir.flatten() {
|
||||
@@ -361,12 +344,43 @@ fn get_network_addresses() -> Vec<NetworkAddress> {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get IP from pre-fetched map
|
||||
if let Some(ip) = ipv4_map.remove(&iface_name) {
|
||||
addresses.push(NetworkAddress {
|
||||
interface: iface_name,
|
||||
ip,
|
||||
});
|
||||
up_ifaces.insert(iface_name);
|
||||
}
|
||||
|
||||
let mut addresses = Vec::new();
|
||||
let mut seen = std::collections::HashSet::new();
|
||||
for ifaddr in all_addrs {
|
||||
let iface_name = &ifaddr.interface_name;
|
||||
if iface_name == "lo" || !up_ifaces.contains(iface_name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(addr) = ifaddr.address {
|
||||
if let Some(sockaddr_in) = addr.as_sockaddr_in() {
|
||||
let ip = sockaddr_in.ip();
|
||||
if ip.is_loopback() {
|
||||
continue;
|
||||
}
|
||||
let ip_str = ip.to_string();
|
||||
if seen.insert((iface_name.clone(), ip_str.clone())) {
|
||||
addresses.push(NetworkAddress {
|
||||
interface: iface_name.clone(),
|
||||
ip: ip_str,
|
||||
});
|
||||
}
|
||||
} else if let Some(sockaddr_in6) = addr.as_sockaddr_in6() {
|
||||
let ip = sockaddr_in6.ip();
|
||||
if ip.is_loopback() || ip.is_unspecified() || ip.is_unicast_link_local() {
|
||||
continue;
|
||||
}
|
||||
let ip_str = ip.to_string();
|
||||
if seen.insert((iface_name.clone(), ip_str.clone())) {
|
||||
addresses.push(NetworkAddress {
|
||||
interface: iface_name.clone(),
|
||||
ip: ip_str,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user