diff options
| author | David Lönnhager <david.l@mullvad.net> | 2024-03-18 18:23:45 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2024-03-18 18:23:45 +0100 |
| commit | 6462d2c4cf61c1f0c704c80ec79b4d2a3f28ead8 (patch) | |
| tree | 5c480e97333d5bfc373a0590ba66c24ad4a49c9f | |
| parent | 62c1f943517cc2ac28ea67e7d08988d59fd23965 (diff) | |
| parent | 3d1f1f7299f88719c593e2add0c03e14ec15ebcc (diff) | |
| download | mullvadvpn-6462d2c4cf61c1f0c704c80ec79b4d2a3f28ead8.tar.xz mullvadvpn-6462d2c4cf61c1f0c704c80ec79b4d2a3f28ead8.zip | |
Merge branch 'macos-retry-dns-resolver' into main
| -rw-r--r-- | CHANGELOG.md | 2 | ||||
| -rw-r--r-- | talpid-core/src/resolver.rs | 54 |
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. |
