From 54892a227a77839ee81df90df904675f958831a3 Mon Sep 17 00:00:00 2001
From: Guillaume Jacquart <guillaume.jacquart@hoodbrains.com>
Date: Mon, 23 Oct 2023 15:55:11 +0000
Subject: epic18: tracker control while tor is activated.

---
 .../service/TrackersServiceSupervisorImpl.kt       | 11 +++++++-
 .../trackers/service/usecases/ResolveDNSUseCase.kt | 33 ++++++++++++++++++----
 2 files changed, 37 insertions(+), 7 deletions(-)

(limited to 'trackersservicestandalone/src')

diff --git a/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorImpl.kt b/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorImpl.kt
index 25d3e2d..e2a6692 100644
--- a/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorImpl.kt
+++ b/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorImpl.kt
@@ -25,10 +25,16 @@ import foundation.e.advancedprivacy.trackers.service.data.RequestDNSRepository
 import foundation.e.advancedprivacy.trackers.service.usecases.ResolveDNSUseCase
 import kotlinx.coroutines.cancel
 import kotlinx.coroutines.flow.MutableStateFlow
+import org.koin.core.module.dsl.bind
 import org.koin.core.module.dsl.singleOf
 import org.koin.dsl.module
+import org.pcap4j.packet.DnsPacket
+import java.util.function.Function
 
-class TrackersServiceSupervisorImpl(private val context: Context) : TrackersServiceSupervisor {
+class TrackersServiceSupervisorImpl(
+    private val context: Context,
+    private val resolveDNSUseCase: ResolveDNSUseCase
+) : TrackersServiceSupervisor {
     internal val state: MutableStateFlow<FeatureServiceState> = MutableStateFlow(FeatureServiceState.OFF)
 
     override fun start(): Boolean {
@@ -54,6 +60,8 @@ class TrackersServiceSupervisorImpl(private val context: Context) : TrackersServ
     override fun isRunning(): Boolean {
         return state.value != FeatureServiceState.OFF
     }
+
+    override val dnsFilterForIpScrambling = Function<DnsPacket?, DnsPacket?> { dnsRequest -> resolveDNSUseCase.shouldBlock(dnsRequest) }
 }
 
 val trackerServiceModule = module {
@@ -61,4 +69,5 @@ val trackerServiceModule = module {
     singleOf(::RequestDNSRepository)
     singleOf(::ResolveDNSUseCase)
     singleOf(::TunLooper)
+    singleOf(::TrackersServiceSupervisorImpl) { bind<TrackersServiceSupervisor>() }
 }
diff --git a/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/usecases/ResolveDNSUseCase.kt b/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/usecases/ResolveDNSUseCase.kt
index ac8aee0..b74b9cb 100644
--- a/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/usecases/ResolveDNSUseCase.kt
+++ b/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/usecases/ResolveDNSUseCase.kt
@@ -16,6 +16,7 @@
  */
 package foundation.e.advancedprivacy.trackers.service.usecases
 
+import foundation.e.advancedprivacy.core.utils.runSuspendCatching
 import foundation.e.advancedprivacy.trackers.domain.usecases.FilterHostnameUseCase
 import foundation.e.advancedprivacy.trackers.service.data.NetworkDNSAddressRepository
 import foundation.e.advancedprivacy.trackers.service.data.RequestDNSRepository
@@ -24,6 +25,7 @@ import kotlinx.coroutines.DelicateCoroutinesApi
 import kotlinx.coroutines.GlobalScope
 import org.pcap4j.packet.DnsPacket
 import org.pcap4j.packet.namednumber.DnsRCode
+import timber.log.Timber
 import java.net.DatagramPacket
 
 @OptIn(DelicateCoroutinesApi::class)
@@ -39,16 +41,35 @@ class ResolveDNSUseCase(
         filterHostnameUseCase.writeLogJob(scope)
     }
 
+    fun shouldBlock(dnsRequest: DnsPacket?): DnsPacket? {
+        if (dnsRequest == null) return null
+
+        return runSuspendCatching {
+            val host = dnsRequest.header.questions[0].qName.name
+            if (filterHostnameUseCase.shouldBlock(host)) {
+                dnsRequest.builder
+                    .rCode(DnsRCode.NX_DOMAIN)
+                    .response(true).build()
+            } else null
+        }.onFailure {
+            Timber.e(it, "Can't find host")
+        }.getOrNull()
+    }
+
     suspend fun processDNS(dnsRequest: DnsPacket): DnsPacket? {
-        val host = dnsRequest.header.questions[0].qName.name
-        if (filterHostnameUseCase.shouldBlock(host)) {
-            return dnsRequest.builder
-                .rCode(DnsRCode.NX_DOMAIN)
-                .response(true).build()
+        val blockedDnsResponse = shouldBlock(dnsRequest)
+
+        if (blockedDnsResponse != null) {
+            return blockedDnsResponse
         }
 
         val payload = dnsRequest.rawData
-        val packet = DatagramPacket(payload, payload.size, networkDNSAddressRepository.dnsAddress, DNS_PORT)
+        val packet = DatagramPacket(
+            payload,
+            payload.size,
+            networkDNSAddressRepository.dnsAddress,
+            DNS_PORT
+        )
         return requestDNSRepository.processDNS(packet)
     }
 }
-- 
cgit v1.2.1