Skip to content

Commit dfa59aa

Browse files
committed
fix: dhcp should not block program from launching
1 parent fffc9bf commit dfa59aa

File tree

4 files changed

+40
-41
lines changed

4 files changed

+40
-41
lines changed

boltconn/src/app.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -329,11 +329,8 @@ impl App {
329329
.map_err(|e| anyhow!("Load intercept rules failed: {}", e))?,
330330
);
331331

332-
// this is atomic
333-
self.dns.replace_resolvers(&self.outbound_iface, group)?;
334-
335332
// start atomic replacing
336-
333+
self.dns.replace_resolvers(&self.outbound_iface, group);
337334
self.dns.replace_ns_policy(ns_policy);
338335
self.dns.replace_hosts(&config.dns.hosts);
339336
self.dns_hijack_ctrl.update(
@@ -456,7 +453,7 @@ async fn initialize_dns(
456453
&config.hosts,
457454
ns_policy,
458455
group,
459-
)?)
456+
))
460457
})
461458
}
462459

boltconn/src/network/dns/dns.rs

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::network::dns::hosts::HostsResolver;
44
use crate::network::dns::ns_policy::{DispatchedDnsResolver, NameserverPolicies};
55
use crate::network::dns::provider::IfaceProvider;
66
use crate::network::dns::{default_resolver_opt, AuxiliaryResolver, NameServerConfigEnum};
7-
use crate::proxy::error::{DnsError, TransportError};
7+
use crate::proxy::error::TransportError;
88
use arc_swap::ArcSwap;
99
use hickory_proto::op::{Message, MessageType, ResponseCode};
1010
use hickory_proto::rr::{DNSClass, RData, Record, RecordType};
@@ -99,17 +99,17 @@ impl Dns {
9999
hosts: &HashMap<String, IpAddr>,
100100
ns_policy: NameserverPolicies,
101101
configs: Vec<NameServerConfigEnum>,
102-
) -> Result<Dns, DnsError> {
103-
let resolvers = Self::build_resolvers(iface_name, configs)?;
102+
) -> Dns {
103+
let resolvers = Self::build_resolvers(iface_name, configs);
104104
let host_resolver = HostsResolver::new(hosts);
105-
Ok(Dns {
105+
Dns {
106106
name: name.to_string(),
107107
table: DnsTable::new(),
108108
preference,
109109
host_resolver: ArcSwap::new(Arc::new(host_resolver)),
110110
ns_policy: ArcSwap::new(Arc::new(ns_policy)),
111111
resolvers: ArcSwap::new(Arc::new(resolvers)),
112-
})
112+
}
113113
}
114114

115115
pub fn replace_hosts(&self, hosts: &HashMap<String, IpAddr>) {
@@ -122,21 +122,15 @@ impl Dns {
122122
}
123123

124124
// This function is atomic
125-
pub fn replace_resolvers(
126-
&self,
127-
iface_name: &str,
128-
configs: Vec<NameServerConfigEnum>,
129-
) -> Result<(), DnsError> {
130-
let resolvers = Self::build_resolvers(iface_name, configs)?;
125+
pub fn replace_resolvers(&self, iface_name: &str, configs: Vec<NameServerConfigEnum>) {
126+
let resolvers = Self::build_resolvers(iface_name, configs);
131127
self.resolvers.store(Arc::new(resolvers));
132-
Ok(())
133128
}
134129

135130
fn build_resolvers(
136131
iface_name: &str,
137132
configs: Vec<NameServerConfigEnum>,
138-
) -> Result<Vec<AuxiliaryResolver<AsyncResolver<GenericConnector<IfaceProvider>>>>, DnsError>
139-
{
133+
) -> Vec<AuxiliaryResolver<AsyncResolver<GenericConnector<IfaceProvider>>>> {
140134
let mut resolvers = Vec::new();
141135
for config in configs.into_iter() {
142136
let resolver = match config {
@@ -148,11 +142,11 @@ impl Dns {
148142
GenericConnector::new(IfaceProvider::new(iface_name)),
149143
))
150144
}
151-
NameServerConfigEnum::Dhcp(dhcp) => AuxiliaryResolver::new_dhcp(&dhcp)?,
145+
NameServerConfigEnum::Dhcp(dhcp) => AuxiliaryResolver::new_dhcp(&dhcp),
152146
};
153147
resolvers.push(resolver);
154148
}
155-
Ok(resolvers)
149+
resolvers
156150
}
157151
}
158152

boltconn/src/network/dns/mod.rs

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ mod ns_policy;
88
mod provider;
99

1010
use crate::config::DnsConfigError;
11-
use crate::proxy::error::{DnsError, TransportError};
11+
use crate::proxy::error::DnsError;
1212
pub use bootstrap::BootstrapResolver;
1313
pub use dns::{Dns, GenericDns};
1414
use hickory_resolver::config::{
@@ -167,32 +167,40 @@ struct DhcpDnsRecord {
167167
}
168168

169169
impl DhcpDnsRecord {
170-
pub fn new(iface: &str) -> Result<Self, DnsError> {
171-
let iface_addr = crate::platform::get_iface_address(iface)
172-
.map_err(|_| DnsError::DhcpNameServer("failed to get iface address"))?;
173-
let ns_addr = crate::platform::dhcp::get_dhcp_dns(iface)?;
174-
tracing::debug!(
175-
"DHCP DNS: iface={}, iface_addr={}, ns_addr={}",
176-
iface,
177-
iface_addr,
178-
ns_addr
179-
);
180-
Ok(Self {
170+
pub fn new(iface: &str) -> Self {
171+
let mut iface_addr = crate::platform::get_iface_address(iface).ok();
172+
let ns_addr = match crate::platform::dhcp::get_dhcp_dns(iface) {
173+
Ok(addr) => addr,
174+
Err(e) => {
175+
tracing::warn!(
176+
"DHCP DNS: iface={}, iface_addr={:?}, error={}, use empty address",
177+
iface,
178+
iface_addr,
179+
e
180+
);
181+
// we don't want the replayable fault stop the program from running
182+
// e.g. start offline but soon connect to a network with DHCP
183+
iface_addr = None;
184+
IpAddr::V4(std::net::Ipv4Addr::new(127, 0, 0, 1))
185+
}
186+
};
187+
Self {
181188
iface: iface.to_string(),
182-
iface_addr,
189+
iface_addr: iface_addr.unwrap_or(IpAddr::V4(std::net::Ipv4Addr::new(127, 0, 0, 1))),
183190
ns_addr,
184191
last_checked: std::time::Instant::now(),
185192
resolver: Self::create_resolver(ns_addr, iface),
186-
})
193+
}
187194
}
188195

189196
// return if the record is updated
190-
pub fn refresh(&mut self) -> Result<bool, TransportError> {
197+
pub fn refresh(&mut self) -> Result<bool, DnsError> {
191198
if self.last_checked.elapsed() < Duration::from_secs(30) {
192199
Ok(false)
193200
} else {
194201
// when error occurs, update the record in a best-effort way
195-
let addr = crate::platform::get_iface_address(&self.iface)?;
202+
let addr = crate::platform::get_iface_address(&self.iface)
203+
.map_err(|_| DnsError::DhcpNameServer("failed to get iface address"))?;
196204
if addr != self.iface_addr {
197205
let new_dns = crate::platform::dhcp::get_dhcp_dns(&self.iface)?;
198206
self.iface_addr = addr;
@@ -241,8 +249,8 @@ impl<T> AuxiliaryResolver<T> {
241249
Self::Resolver(resolver)
242250
}
243251

244-
pub fn new_dhcp(iface: &str) -> Result<Self, DnsError> {
245-
let record = DhcpDnsRecord::new(iface)?;
246-
Ok(Self::Dhcp(Mutex::new(record)))
252+
pub fn new_dhcp(iface: &str) -> Self {
253+
let record = DhcpDnsRecord::new(iface);
254+
Self::Dhcp(Mutex::new(record))
247255
}
248256
}

boltconn/src/network/dns/ns_policy.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ impl NameserverPolicies {
8787
}
8888
}
8989
NameServerConfigEnum::Dhcp(iface) => {
90-
DispatchedDnsResolver::Iface(AuxiliaryResolver::new_dhcp(&iface)?)
90+
DispatchedDnsResolver::Iface(AuxiliaryResolver::new_dhcp(&iface))
9191
}
9292
};
9393
let matcher = m.build();

0 commit comments

Comments
 (0)