deleting a repo now removes corresponding items from the dns cache

This commit is contained in:
Matthew Bogner
2025-02-11 18:05:59 +00:00
committed by Torsten Grote
parent a232994039
commit b22200fde2
6 changed files with 118 additions and 79 deletions

View File

@@ -1,6 +1,7 @@
package org.fdroid.fdroid.net;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import org.fdroid.fdroid.Preferences;
import org.junit.Test;
@@ -40,12 +41,12 @@ public class DnsWithCacheTest {
// test setup
Preferences prefs = Preferences.get();
prefs.setDnsCacheEnabledValue(true);
DnsWithCache testObject = new DnsWithCache();
DnsCache testObject = DnsCache.get();
// populate cache
testObject.updateCacheAndPrefs(URL_1, LIST_1);
testObject.updateCacheAndPrefs(URL_2, LIST_2);
testObject.updateCacheAndPrefs(URL_3, LIST_3);
testObject.insert(URL_1, LIST_1);
testObject.insert(URL_2, LIST_2);
testObject.insert(URL_3, LIST_3);
// check for cached lookup results
List<InetAddress> testList = testObject.lookup(URL_1);
@@ -58,14 +59,8 @@ public class DnsWithCacheTest {
prefs.setDnsCacheEnabledValue(false);
// attempt non-cached lookup
boolean gotException = false;
try {
testList = testObject.lookup(URL_1);
} catch (UnknownHostException e) {
// test urls are not valid
gotException = true;
}
assertEquals(true, gotException);
testList = testObject.lookup(URL_1);
assertNull(testList);
// toggle preference (true)
prefs.setDnsCacheEnabledValue(true);
@@ -74,5 +69,12 @@ public class DnsWithCacheTest {
testList = testObject.lookup(URL_2);
assertEquals(1, testList.size());
assertEquals(IP_2.getHostAddress(), testList.get(0).getHostAddress());
// test removal
testList = testObject.remove(URL_2);
assertEquals(1, testList.size());
assertEquals(IP_2.getHostAddress(), testList.get(0).getHostAddress());
testList = testObject.lookup(URL_2);
assertNull(testList);
}
}

View File

@@ -70,6 +70,7 @@ import org.fdroid.fdroid.nearby.PublicSourceDirProvider;
import org.fdroid.fdroid.nearby.SDCardScannerService;
import org.fdroid.fdroid.nearby.WifiStateChangeService;
import org.fdroid.fdroid.net.ConnectivityMonitorService;
import org.fdroid.fdroid.net.DnsCache;
import org.fdroid.fdroid.net.DownloaderFactory;
import org.fdroid.fdroid.panic.HidingManager;
import org.fdroid.fdroid.receiver.DeviceStorageReceiver;
@@ -297,6 +298,7 @@ public class FDroidApp extends Application implements androidx.work.Configuratio
.build());
}
Preferences.setup(this);
DnsCache.setup();
Languages.setLanguage(this);
Preferences preferences = Preferences.get();

View File

@@ -531,17 +531,6 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
return preferences.getBoolean(PREF_USE_DNS_CACHE, false);
}
public void updateDnsCache(String urlString, List<InetAddress> ipList) {
// existing list is replaced, so make sure new list has values
if (ipList == null || ipList.isEmpty()) {
return;
} else {
HashMap<String, List<InetAddress>> dnsMap = getDnsCache();
dnsMap.put(urlString, ipList);
setDnsCache(dnsMap);
}
}
public void setDnsCache(HashMap<String, List<InetAddress>> dnsMap) {
HashMap<String, List<String>> stringMap = new HashMap<String, List<String>>();
for (String url : dnsMap.keySet()) {
@@ -554,16 +543,6 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
preferences.edit().putString(PREF_DNS_CACHE, listMapToString(stringMap)).apply();
}
public List<InetAddress> queryDnsCache(String urlString) {
HashMap<String, List<InetAddress>> dnsMap = getDnsCache();
if (dnsMap.containsKey(urlString)) {
return dnsMap.get(urlString);
} else {
// returns empty list to avoid null issues
return new ArrayList<InetAddress>();
}
}
public HashMap<String, List<InetAddress>> getDnsCache() {
HashMap<String, List<InetAddress>> dnsMap = new HashMap<String, List<InetAddress>>();
String mapString = preferences.getString(PREF_DNS_CACHE, "");

View File

@@ -0,0 +1,86 @@
package org.fdroid.fdroid.net;
import android.util.Log;
import androidx.annotation.NonNull;
import org.fdroid.fdroid.Preferences;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public final class DnsCache {
private static final String TAG = "DnsCache";
private volatile HashMap<String, List<InetAddress>> cache;
private static final int DELAY_TIME = 1;
private static final TimeUnit DELAY_UNIT = TimeUnit.SECONDS;
private volatile boolean writeScheduled = false;
private final Runnable delayedWrite = () -> {
Preferences prefs = Preferences.get();
prefs.setDnsCache(cache);
writeScheduled = false;
};
private final ScheduledExecutorService writeExecutor = Executors.newSingleThreadScheduledExecutor();
private static DnsCache instance;
private DnsCache() {
Preferences prefs = Preferences.get();
cache = prefs.getDnsCache();
if (cache == null) {
cache = new HashMap<>();
}
}
public static void setup() {
if (instance != null) {
final String error = "DnsCache can only be initialized once";
Log.e(TAG, error);
throw new RuntimeException(error);
}
instance = new DnsCache();
}
public static DnsCache get() {
if (instance == null) {
final String error = "DnsCache must be initialized first";
Log.e(TAG, error);
throw new RuntimeException(error);
}
return instance;
}
public void insert(@NonNull String url, @NonNull List<InetAddress> ipList) {
cache.put(url, ipList);
if (!writeScheduled) {
writeScheduled = true;
writeExecutor.schedule(delayedWrite, DELAY_TIME, DELAY_UNIT);
}
}
public List<InetAddress> remove(@NonNull String url) {
List<InetAddress> removed = cache.remove(url);
if (!writeScheduled && removed != null) {
writeScheduled = true;
writeExecutor.schedule(delayedWrite, DELAY_TIME, DELAY_UNIT);
}
return removed;
}
public List<InetAddress> lookup(@NonNull String url) {
Preferences prefs = Preferences.get();
if (!prefs.isDnsCacheEnabled() || !cache.keySet().contains(url)) {
return null;
} else {
return cache.get(url);
}
}
}

View File

@@ -6,62 +6,25 @@ import org.fdroid.fdroid.Preferences;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import okhttp3.Dns;
public class DnsWithCache implements Dns {
private volatile HashMap<String, List<InetAddress>> cache;
private static final int DELAY_TIME = 1;
private static final TimeUnit DELAY_UNIT = TimeUnit.SECONDS;
private volatile boolean writeScheduled = false;
private final Runnable delayedWrite = () -> {
Preferences prefs = Preferences.get();
prefs.setDnsCache(cache);
writeScheduled = false;
};
private final ScheduledExecutorService writeExecutor = Executors.newSingleThreadScheduledExecutor();
public DnsWithCache() {
Preferences prefs = Preferences.get();
cache = prefs.getDnsCache();
}
public void updateCacheAndPrefs(@NonNull String url, @NonNull List<InetAddress> ipList) {
updateCache(url, ipList);
if (!writeScheduled) {
writeScheduled = true;
writeExecutor.schedule(delayedWrite, DELAY_TIME, DELAY_UNIT);
}
}
public void updateCache(@NonNull String url, @NonNull List<InetAddress> ipList) {
if (cache == null) {
cache = new HashMap<String, List<InetAddress>>();
}
cache.put(url, ipList);
}
@NonNull
@Override
public List<InetAddress> lookup(@NonNull String url) throws UnknownHostException {
Preferences prefs = Preferences.get();
if (!prefs.isDnsCacheEnabled()
|| cache == null
|| !cache.keySet().contains(url)) {
// do dns lookup and cache ip list
List<InetAddress> ipList = Dns.SYSTEM.lookup(url);
updateCacheAndPrefs(url, ipList);
return ipList;
} else {
// return cached ip list if available
return cache.get(url);
if (!prefs.isDnsCacheEnabled()) {
return Dns.SYSTEM.lookup(url);
}
DnsCache cache = DnsCache.get();
List<InetAddress> list = cache.lookup(url);
if (list == null) {
list = Dns.SYSTEM.lookup(url);
cache.insert(url, list);
}
return list;
}
}

View File

@@ -29,6 +29,7 @@ import org.fdroid.fdroid.FDroidApp
import org.fdroid.fdroid.R
import org.fdroid.fdroid.data.DBHelper
import org.fdroid.fdroid.generateQrBitmapKt
import org.fdroid.fdroid.net.DnsCache
import org.fdroid.fdroid.work.RepoUpdateWorker
enum class ArchiveState {
@@ -60,6 +61,7 @@ class RepoDetailsViewModel(
}
private val repoId = initialRepo.repoId
private val repoMirrors = initialRepo.getMirrors()
private val repoManager = FDroidApp.getRepoManager(app)
private val appDao = DBHelper.getDb(app).getAppDao()
@@ -105,6 +107,11 @@ class RepoDetailsViewModel(
viewModelScope.launch(Dispatchers.IO) {
repoManager.deleteRepository(repoId)
}
// clean up dns cache
val cache = DnsCache.get()
for (mirror in repoMirrors) {
cache.remove(mirror.url.host)
}
}
fun updateUsernameAndPassword(username: String, password: String) {