config: add DNS import/export policies

config: move ID generation to ZoneConfig

config: serde fixes
This commit is contained in:
Luna Yao
2026-04-06 11:54:01 +02:00
parent 8a93bb311b
commit 78b2afb785
4 changed files with 79 additions and 48 deletions
+2 -1
View File
@@ -167,7 +167,8 @@ network-interface = "2.0"
# for ospf route # for ospf route
petgraph = "0.8.1" petgraph = "0.8.1"
hashbrown = "0.15.3" hashbrown = "0.15.3"
ordered_hash_map = "0.5.0" ordered_hash_map = "0.5.0"# TODO: REPLACE THIS
indexmap = "2.13.0"
# for wireguard # for wireguard
boringtun = { package = "boringtun-easytier", version = "0.6.1", optional = true } boringtun = { package = "boringtun-easytier", version = "0.6.1", optional = true }
+68 -30
View File
@@ -1,11 +1,14 @@
use crate::dns::utils::{sanitize, NameServerAddr}; use crate::dns::utils::{sanitize, NameServerAddr};
use crate::proto::dns::{DnsConfigKind, DnsConfigPb, ZoneConfigPb}; use crate::proto::dns::{DnsConfigPb, ZoneConfigPb};
use derive_more::{Deref, DerefMut};
use gethostname::gethostname; use gethostname::gethostname;
use hickory_proto::rr::LowerName; use hickory_proto::rr::LowerName;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4}; use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
use std::str::FromStr; use std::str::FromStr;
use std::sync::LazyLock; use std::sync::LazyLock;
use uuid::Uuid;
pub const DNS_DEFAULT_ADDRESS: SocketAddr = pub const DNS_DEFAULT_ADDRESS: SocketAddr =
SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(100, 100, 100, 101), 53)); SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(100, 100, 100, 101), 53));
@@ -17,6 +20,8 @@ pub static DNS_DEFAULT_TLD: LazyLock<LowerName> =
pub struct DnsConfig { pub struct DnsConfig {
#[serde(rename = "zone")] #[serde(rename = "zone")]
pub zones: Vec<ZoneConfig>, pub zones: Vec<ZoneConfig>,
#[serde(flatten)]
pub policies: HashMap<LowerName, DnsPolicyConfig>,
name: LowerName, name: LowerName,
pub domain: LowerName, pub domain: LowerName,
pub addresses: Vec<SocketAddr>, pub addresses: Vec<SocketAddr>,
@@ -43,34 +48,17 @@ impl DnsConfig {
}; };
} }
pub fn to_pb(&self, kind: DnsConfigKind) -> DnsConfigPb { pub fn export(&self) -> DnsConfigPb {
let pb = DnsConfigPb { DnsConfigPb {
kind: kind.into(), zones: self
.zones
.iter()
.filter(|z| z.policy.export.is_some()) // TODO: check policies of parent zones
.map(Into::into)
.collect(),
name: self.get_name(), name: self.get_name(),
domain: self.domain.to_string(), domain: self.domain.to_string(),
..Default::default()
};
match kind {
DnsConfigKind::Local => DnsConfigPb {
zones: self.zones.iter().map(Into::into).collect(),
addresses: self.addresses.clone().into_iter().map(Into::into).collect(),
listeners: self.listeners.iter().map(ToString::to_string).collect(),
..pb
},
DnsConfigKind::Remote => DnsConfigPb {
zones: self
.zones
.iter()
.filter(|z| z.broadcast)
.map(Into::into)
.collect(),
..pb
},
} }
} }
} }
@@ -78,19 +66,21 @@ impl DnsConfig {
impl Default for DnsConfig { impl Default for DnsConfig {
fn default() -> Self { fn default() -> Self {
Self { Self {
zones: Vec::new(),
policies: HashMap::new(),
name: LowerName::default(), name: LowerName::default(),
domain: DNS_DEFAULT_TLD.clone(), domain: DNS_DEFAULT_TLD.clone(),
addresses: vec![DNS_DEFAULT_ADDRESS], addresses: vec![DNS_DEFAULT_ADDRESS],
listeners: vec![], listeners: vec![],
zones: vec![],
} }
} }
} }
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Default)] #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Default)]
pub struct ZoneConfig { pub struct ZoneConfig {
#[serde(default)] #[serde(default = "Uuid::new_v4")]
pub broadcast: bool, #[serde(skip_serializing)]
id: Uuid,
pub origin: LowerName, pub origin: LowerName,
#[serde(default)] #[serde(default)]
pub ttl: u32, pub ttl: u32,
@@ -98,11 +88,14 @@ pub struct ZoneConfig {
pub records: Vec<String>, pub records: Vec<String>,
#[serde(default)] #[serde(default)]
pub forwarders: Vec<NameServerAddr>, pub forwarders: Vec<NameServerAddr>,
#[serde(flatten)]
pub policy: ZonePolicyConfig,
} }
impl From<&ZoneConfig> for ZoneConfigPb { impl From<&ZoneConfig> for ZoneConfigPb {
fn from(value: &ZoneConfig) -> Self { fn from(value: &ZoneConfig) -> Self {
Self { Self {
id: Some(value.id.into()),
origin: value.origin.to_string(), origin: value.origin.to_string(),
ttl: value.ttl, ttl: value.ttl,
records: value.records.clone(), records: value.records.clone(),
@@ -110,3 +103,48 @@ impl From<&ZoneConfig> for ZoneConfigPb {
} }
} }
} }
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Default)]
#[serde(default)]
pub struct AclPolicy {
pub whitelist: Option<Vec<String>>,
pub blacklist: Option<Vec<String>>,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Default, Deref, DerefMut)]
#[serde(default)]
pub struct FunctionalityPolicy {
#[serde(flatten)]
#[deref]
#[deref_mut]
acl: AclPolicy, // TODO
pub disabled: bool,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Default, Deref, DerefMut)]
#[serde(default)]
pub struct DnsPolicy<P = FunctionalityPolicy> {
#[serde(flatten)]
#[deref]
#[deref_mut]
policy: P,
pub recursive: bool, // TODO
}
pub type ZoneExportPolicy = FunctionalityPolicy;
pub type DnsExportPolicy = DnsPolicy<ZoneExportPolicy>;
pub type DnsImportPolicy = DnsPolicy<FunctionalityPolicy>;
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Default)]
#[serde(default)]
pub struct DnsPolicyConfig {
pub import: DnsImportPolicy,
pub export: Option<DnsExportPolicy>,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Default)]
#[serde(default)]
pub struct ZonePolicyConfig {
#[serde(default)]
pub export: Option<DnsExportPolicy>,
}
+1 -2
View File
@@ -40,7 +40,6 @@ use super::{
PeerPacketFilter, PeerPacketFilter,
}; };
use crate::common::config::ConfigLoader; use crate::common::config::ConfigLoader;
use crate::proto::dns::DnsConfigKind;
use crate::{ use crate::{
common::{ common::{
config::NetworkIdentity, config::NetworkIdentity,
@@ -261,7 +260,7 @@ impl RoutePeerInfo {
ipv6_addr: global_ctx.get_ipv6().map(|x| x.into()), ipv6_addr: global_ctx.get_ipv6().map(|x| x.into()),
groups: global_ctx.get_acl_groups(my_peer_id), groups: global_ctx.get_acl_groups(my_peer_id),
dns: Some(global_ctx.config.get_dns().to_pb(DnsConfigKind::Remote)), dns: Some(global_ctx.config.get_dns().export()),
noise_static_pubkey, noise_static_pubkey,
+8 -15
View File
@@ -4,23 +4,16 @@ import "common.proto";
package dns; package dns;
enum DnsConfigKind {
LOCAL = 0;
REMOTE = 1;
}
message DnsConfigPb { message DnsConfigPb {
DnsConfigKind kind = 1; repeated ZoneConfigPb zones = 1;
repeated ZoneConfigPb zones = 2; string name = 2;
string name = 3; string domain = 3;
string domain = 4;
repeated common.SocketAddr addresses = 5;
repeated string listeners = 6;
} }
message ZoneConfigPb { message ZoneConfigPb {
string origin = 1; common.UUID id = 1;
uint32 ttl = 2; string origin = 2;
repeated string records = 3; uint32 ttl = 3;
repeated string forwarders = 4; repeated string records = 4;
repeated string forwarders = 5;
} }