Skip to content

Commit a93ba5f

Browse files
committed
refactor: dns flow runtime refresh
1 parent 741cdca commit a93ba5f

File tree

24 files changed

+1765
-331
lines changed

24 files changed

+1765
-331
lines changed

landscape-common/src/config/runtime.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ pub struct MetricRuntimeConfig {
6666
pub aggregate_interval_secs: u64,
6767
}
6868

69-
#[derive(Clone, Debug, Default)]
69+
#[derive(Clone, Debug, Default, PartialEq, Eq)]
7070
pub struct DnsRuntimeConfig {
7171
pub cache_capacity: u32,
7272
pub cache_ttl: u32,

landscape-common/src/dns/config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ impl Default for DnsUpstreamConfig {
5959
}
6060
}
6161

62-
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
62+
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq)]
6363
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
6464
pub struct DnsBindConfig {
6565
/// 绑定地址 v4 (可选)

landscape-common/src/dns/mod.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,32 @@ pub mod check;
88
pub mod config;
99
pub mod redirect;
1010
pub mod rule;
11+
pub mod runtime;
1112
pub mod upstream;
1213

14+
pub use runtime::{
15+
CacheRuntimeConfig, DohRuntimeConfig, FlowDnsDependencies, FlowDnsDesiredState, RuntimeDnsRule,
16+
RuntimeRedirectRule, RuntimeUpstreamTarget,
17+
};
18+
1319
#[derive(Default, Debug)]
1420
pub struct ChainDnsServerInitInfo {
1521
pub dns_rules: Vec<DNSRuntimeRule>,
1622
pub redirect_rules: Vec<DNSRedirectRuntimeRule>,
1723
}
1824

25+
impl From<ChainDnsServerInitInfo> for FlowDnsDesiredState {
26+
fn from(value: ChainDnsServerInitInfo) -> Self {
27+
Self {
28+
flow_id: 0,
29+
dns_rules: value.dns_rules.into_iter().map(Into::into).collect(),
30+
redirect_rules: value.redirect_rules.into_iter().map(Into::into).collect(),
31+
cache_runtime: CacheRuntimeConfig::default(),
32+
doh_runtime: None,
33+
}
34+
}
35+
}
36+
1937
pub fn gen_default_dns_rule_and_upstream() -> (DNSRuleConfig, DnsUpstreamConfig) {
2038
let upstream = DnsUpstreamConfig::default();
2139
let rule = DNSRuleConfig {

landscape-common/src/dns/rule.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ pub enum DomainMatchType {
111111
Full = 3,
112112
}
113113

114-
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
114+
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq)]
115115
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
116116
#[serde(rename_all = "snake_case")]
117117
pub enum FilterResult {
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
use std::collections::HashSet;
2+
use std::net::IpAddr;
3+
4+
use serde::{Deserialize, Serialize};
5+
use uuid::Uuid;
6+
7+
use crate::dns::config::{DnsBindConfig, DnsUpstreamConfig};
8+
use crate::dns::redirect::DNSRedirectRuntimeRule;
9+
use crate::dns::redirect::DnsRedirectAnswerMode;
10+
use crate::dns::rule::{DNSRuntimeRule, DomainConfig, FilterResult};
11+
use crate::dns::upstream::DnsUpstreamMode;
12+
use crate::flow::mark::FlowMark;
13+
use crate::geo::GeoFileCacheKey;
14+
15+
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq)]
16+
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
17+
pub struct CacheRuntimeConfig {
18+
pub cache_capacity: u32,
19+
pub cache_ttl: u32,
20+
pub negative_cache_ttl: u32,
21+
}
22+
23+
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
24+
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
25+
pub struct DohRuntimeConfig {
26+
pub listen_port: u16,
27+
pub http_endpoint: String,
28+
}
29+
30+
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq)]
31+
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
32+
pub struct RuntimeUpstreamTarget {
33+
pub mode: DnsUpstreamMode,
34+
#[cfg_attr(feature = "openapi", schema(value_type = Vec<String>))]
35+
pub ips: Vec<IpAddr>,
36+
#[cfg_attr(feature = "openapi", schema(required = true, nullable = true))]
37+
pub port: Option<u16>,
38+
pub enable_ip_validation: bool,
39+
}
40+
41+
impl From<&DnsUpstreamConfig> for RuntimeUpstreamTarget {
42+
fn from(value: &DnsUpstreamConfig) -> Self {
43+
Self {
44+
mode: value.mode.clone(),
45+
ips: value.ips.clone(),
46+
port: value.port,
47+
enable_ip_validation: value.enable_ip_validation.unwrap_or(false),
48+
}
49+
}
50+
}
51+
52+
impl From<RuntimeUpstreamTarget> for DnsUpstreamConfig {
53+
fn from(value: RuntimeUpstreamTarget) -> Self {
54+
Self {
55+
id: Uuid::nil(),
56+
remark: String::new(),
57+
mode: value.mode,
58+
ips: value.ips,
59+
port: value.port,
60+
enable_ip_validation: Some(value.enable_ip_validation),
61+
update_at: 0.0,
62+
}
63+
}
64+
}
65+
66+
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq)]
67+
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
68+
pub struct RuntimeDnsRule {
69+
pub rule_id: Uuid,
70+
pub order: u32,
71+
pub filter: FilterResult,
72+
pub upstream: RuntimeUpstreamTarget,
73+
pub bind_config: DnsBindConfig,
74+
pub mark: FlowMark,
75+
pub sources: Vec<DomainConfig>,
76+
}
77+
78+
impl From<DNSRuntimeRule> for RuntimeDnsRule {
79+
fn from(value: DNSRuntimeRule) -> Self {
80+
Self {
81+
rule_id: value.id,
82+
order: value.index,
83+
filter: value.filter,
84+
upstream: RuntimeUpstreamTarget::from(&value.resolve_mode),
85+
bind_config: value.bind_config,
86+
mark: value.mark,
87+
sources: value.source,
88+
}
89+
}
90+
}
91+
92+
impl From<RuntimeDnsRule> for DNSRuntimeRule {
93+
fn from(value: RuntimeDnsRule) -> Self {
94+
Self {
95+
id: value.rule_id,
96+
name: String::new(),
97+
index: value.order,
98+
enable: true,
99+
filter: value.filter,
100+
resolve_mode: value.upstream.into(),
101+
bind_config: value.bind_config,
102+
mark: value.mark,
103+
source: value.sources,
104+
flow_id: 0,
105+
}
106+
}
107+
}
108+
109+
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq)]
110+
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
111+
pub struct RuntimeRedirectRule {
112+
#[cfg_attr(feature = "openapi", schema(nullable = false))]
113+
pub redirect_id: Option<Uuid>,
114+
#[cfg_attr(feature = "openapi", schema(nullable = false))]
115+
pub dynamic_source_id: Option<String>,
116+
pub order: u32,
117+
pub answer_mode: DnsRedirectAnswerMode,
118+
pub match_rules: Vec<DomainConfig>,
119+
#[cfg_attr(feature = "openapi", schema(value_type = Vec<String>))]
120+
pub result_ips: Vec<IpAddr>,
121+
pub ttl_secs: u32,
122+
}
123+
124+
impl From<DNSRedirectRuntimeRule> for RuntimeRedirectRule {
125+
fn from(value: DNSRedirectRuntimeRule) -> Self {
126+
Self {
127+
redirect_id: value.redirect_id,
128+
dynamic_source_id: value.dynamic_redirect_source,
129+
order: 0,
130+
answer_mode: value.answer_mode,
131+
match_rules: value.match_rules,
132+
result_ips: value.result_info,
133+
ttl_secs: value.ttl_secs,
134+
}
135+
}
136+
}
137+
138+
impl From<RuntimeRedirectRule> for DNSRedirectRuntimeRule {
139+
fn from(value: RuntimeRedirectRule) -> Self {
140+
Self {
141+
redirect_id: value.redirect_id,
142+
dynamic_redirect_source: value.dynamic_source_id,
143+
answer_mode: value.answer_mode,
144+
match_rules: value.match_rules,
145+
result_info: value.result_ips,
146+
ttl_secs: value.ttl_secs,
147+
}
148+
}
149+
}
150+
151+
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq)]
152+
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
153+
pub struct FlowDnsDesiredState {
154+
pub flow_id: u32,
155+
pub dns_rules: Vec<RuntimeDnsRule>,
156+
pub redirect_rules: Vec<RuntimeRedirectRule>,
157+
pub cache_runtime: CacheRuntimeConfig,
158+
#[cfg_attr(feature = "openapi", schema(nullable = false))]
159+
pub doh_runtime: Option<DohRuntimeConfig>,
160+
}
161+
162+
#[derive(Debug, Clone, Default, PartialEq, Eq)]
163+
pub struct FlowDnsDependencies {
164+
pub geo_keys: HashSet<GeoFileCacheKey>,
165+
pub upstream_ids: HashSet<Uuid>,
166+
pub dynamic_redirect_sources: HashSet<String>,
167+
}

landscape-common/src/dns/upstream.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub enum DnsUpstreamError {
1111
NotFound(ConfigId),
1212
}
1313

14-
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
14+
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq)]
1515
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1616
#[serde(rename_all = "snake_case")]
1717
#[serde(tag = "t")]

landscape-common/src/event/dns.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
1+
use std::collections::HashSet;
2+
3+
use uuid::Uuid;
4+
5+
use crate::geo::GeoFileCacheKey;
6+
7+
#[derive(Clone, Debug)]
18
pub enum DnsEvent {
2-
RuleUpdated { flow_id: Option<u32> },
3-
GeositeUpdated,
9+
RulesChanged { flow_id: Option<u32> },
10+
RedirectsChanged { flow_id: Option<u32> },
11+
DynamicRedirectsChanged { flow_id: Option<u32>, source_id: String },
12+
UpstreamsChanged { upstream_ids: Vec<Uuid> },
13+
GeoSitesChanged { changed_keys: Option<HashSet<GeoFileCacheKey>> },
14+
RuntimeConfigChanged,
415
FlowUpdated,
516
}
617

landscape-dns/src/bin/test_dns_server.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
1-
use landscape_common::{
2-
config::DnsRuntimeConfig, dns::rule::DNSRuntimeRule, dns::ChainDnsServerInitInfo,
3-
};
4-
use landscape_dns::server::LandscapeDnsServer;
1+
use landscape_common::{dns::rule::DNSRuntimeRule, dns::ChainDnsServerInitInfo};
2+
use landscape_dns::server::{CacheRuntimeConfig, LandscapeDnsServer};
53

64
/// cargo run --package landscape-dns --bin test_dns_server
75
#[tokio::main]
86
async fn main() -> std::io::Result<()> {
97
landscape_common::init_tracing!();
108

119
let listen_port = 54;
12-
let server = LandscapeDnsServer::new(listen_port, None, None, None);
10+
let server =
11+
LandscapeDnsServer::new(listen_port, None, CacheRuntimeConfig::default(), None, None);
1312

1413
// handler
1514
let default_rule = vec![DNSRuntimeRule::default()];
1615

1716
let info = ChainDnsServerInitInfo { dns_rules: default_rule, redirect_rules: vec![] };
1817
println!("=============================================");
19-
server.refresh_flow_server(0, info, DnsRuntimeConfig::default()).await;
18+
server.refresh_flow_server(info.into()).await;
2019

2120
let _ = tokio::signal::ctrl_c().await;
2221

landscape-dns/src/connection/mod.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,7 @@ use hickory_resolver::{
77
};
88

99
use landscape_common::{
10-
dns::{
11-
config::{DnsBindConfig, DnsUpstreamConfig},
12-
upstream::DnsUpstreamMode,
13-
},
10+
dns::{config::DnsBindConfig, upstream::DnsUpstreamMode, RuntimeUpstreamTarget},
1411
flow::mark::FlowMark,
1512
};
1613

@@ -24,7 +21,7 @@ pub(crate) fn create_resolver(
2421
flow_id: u32,
2522
mark: FlowMark,
2623
bind_config: DnsBindConfig,
27-
DnsUpstreamConfig { mode, ips, port, .. }: DnsUpstreamConfig,
24+
RuntimeUpstreamTarget { mode, ips, port, .. }: RuntimeUpstreamTarget,
2825
) -> LandscapeMarkDNSResolver {
2926
let name_server = match mode {
3027
DnsUpstreamMode::Plaintext => {

landscape-dns/src/lib.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@ pub mod error;
3535
pub mod listener;
3636
pub mod server;
3737

38-
const DEFAULT_ENABLE_IP_VALIDATION: bool = false;
39-
4038
static RESOLVER_CONF: &'static str = "/etc/resolv.conf";
4139
static RESOLVER_CONF_LD_BACK: &'static str = "/etc/resolv.conf.ld_back";
4240

@@ -68,6 +66,10 @@ fn check_resolver_conf() {
6866
std::fs::write(&resolver_file, new_content).unwrap();
6967
}
7068

69+
pub fn prepare_system_dns() {
70+
check_resolver_conf();
71+
}
72+
7173
/// 停止时恢复 /etc/resolv.conf
7274
pub fn restore_resolver_conf() {
7375
let resolver_file = PathBuf::from(RESOLVER_CONF);
@@ -101,6 +103,8 @@ pub struct CacheDNSItem {
101103
pub min_ttl: u32,
102104
pub mark: DnsRuntimeMarkInfo,
103105
pub filter: FilterResult,
106+
pub matched_rule_id: Option<uuid::Uuid>,
107+
pub matched_rule_order: Option<u32>,
104108
}
105109

106110
impl CacheDNSItem {

0 commit comments

Comments
 (0)