summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2024-03-18 18:23:45 +0100
committerDavid Lönnhager <david.l@mullvad.net>2024-03-18 18:23:45 +0100
commit6462d2c4cf61c1f0c704c80ec79b4d2a3f28ead8 (patch)
tree5c480e97333d5bfc373a0590ba66c24ad4a49c9f
parent62c1f943517cc2ac28ea67e7d08988d59fd23965 (diff)
parent3d1f1f7299f88719c593e2add0c03e14ec15ebcc (diff)
downloadmullvadvpn-6462d2c4cf61c1f0c704c80ec79b4d2a3f28ead8.tar.xz
mullvadvpn-6462d2c4cf61c1f0c704c80ec79b4d2a3f28ead8.zip
Merge branch 'macos-retry-dns-resolver' into main
-rw-r--r--CHANGELOG.md2
-rw-r--r--talpid-core/src/resolver.rs54
2 files changed, 41 insertions, 15 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 725329acba..ca06a97679 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -50,6 +50,8 @@ Line wrap the file at 100 chars. Th
### macOS
- Fix bug that caused high CPU usage due to an infinite loop.
+- Fix bugs that caused the log to be filled with socket errors, by handling closed sockets more
+ gracefully.
### Security
#### Android
diff --git a/talpid-core/src/resolver.rs b/talpid-core/src/resolver.rs
index 71841061bf..30942d34fe 100644
--- a/talpid-core/src/resolver.rs
+++ b/talpid-core/src/resolver.rs
@@ -104,24 +104,29 @@ impl FilteringResolver {
let (tx, rx) = mpsc::channel(0);
let command_tx = Arc::new(tx);
- let mut server = ServerFuture::new(ResolverImpl {
- tx: Arc::downgrade(&command_tx),
- });
-
- let server_listening_socket =
- tokio::net::UdpSocket::bind(SocketAddr::new(Ipv4Addr::LOCALHOST.into(), 0))
- .await
- .map_err(Error::UdpBindError)?;
- let port = server_listening_socket
- .local_addr()
- .map_err(Error::GetSocketAddrError)?
- .port();
- server.register_socket(server_listening_socket);
+ let weak_tx = Arc::downgrade(&command_tx);
+ let (mut server, port) = Self::new_server(0, weak_tx.clone()).await?;
let (server_done_tx, server_done_rx) = oneshot::channel();
let server_handle = tokio::spawn(async move {
- if let Err(err) = server.block_until_done().await {
- log::error!("DNS server stopped: {}", err);
+ loop {
+ if let Err(err) = server.block_until_done().await {
+ log::error!("DNS server unexpectedly stopped: {}", err);
+
+ if weak_tx.strong_count() > 0 {
+ log::debug!("Attempting restart server");
+ match Self::new_server(port, weak_tx.clone()).await {
+ Ok((new_server, _port)) => {
+ server = new_server;
+ continue;
+ }
+ Err(error) => {
+ log::error!("Failed to restart DNS server: {error}");
+ }
+ }
+ }
+ }
+ break;
}
let _ = server_done_tx.send(());
@@ -134,6 +139,25 @@ impl FilteringResolver {
Ok((resolver, ResolverHandle::new(command_tx, port)))
}
+ async fn new_server(
+ port: u16,
+ command_tx: Weak<mpsc::Sender<ResolverMessage>>,
+ ) -> Result<(ServerFuture<ResolverImpl>, u16), Error> {
+ let mut server = ServerFuture::new(ResolverImpl { tx: command_tx });
+
+ let server_listening_socket =
+ tokio::net::UdpSocket::bind(SocketAddr::new(Ipv4Addr::LOCALHOST.into(), port))
+ .await
+ .map_err(Error::UdpBindError)?;
+ let port = server_listening_socket
+ .local_addr()
+ .map_err(Error::GetSocketAddrError)?
+ .port();
+ server.register_socket(server_listening_socket);
+
+ Ok((server, port))
+ }
+
/// Runs the filtering resolver as an actor, listening for new queries instances. When all
/// related [ResolverHandle] instances are dropped, this function will return, closing the DNS
/// server.