From d818202cce7b1030e1b664ec975aa31525778fa4 Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Tue, 7 May 2024 19:15:57 +0530 Subject: [PATCH 01/27] ui: ip and domains logs screen with tabbed layout --- .../adapter/SummaryStatisticsAdapter.kt | 6 +- .../bravedns/ui/activity/AppInfoActivity.kt | 107 +++++----- .../ui/activity/AppWiseDomainLogsActivity.kt | 53 +++++ .../ui/activity/AppWiseIpLogsActivity.kt | 48 +++++ .../ui/fragment/SummaryStatisticsFragment.kt | 8 +- .../viewmodel/AppConnectionsViewModel.kt | 67 +++++- .../full/res/layout/activity_app_details.xml | 197 +++++++++--------- .../layout/list_item_app_domain_details.xml | 2 +- .../res/layout/list_item_app_ip_details.xml | 2 +- .../bravedns/database/ConnectionTrackerDAO.kt | 34 ++- .../layout/activity_app_wise_domain_logs.xml | 52 ++++- .../res/layout/activity_app_wise_ip_logs.xml | 52 ++++- 12 files changed, 450 insertions(+), 178 deletions(-) diff --git a/app/src/full/java/com/celzero/bravedns/adapter/SummaryStatisticsAdapter.kt b/app/src/full/java/com/celzero/bravedns/adapter/SummaryStatisticsAdapter.kt index ae4e85994..80214ad68 100644 --- a/app/src/full/java/com/celzero/bravedns/adapter/SummaryStatisticsAdapter.kt +++ b/app/src/full/java/com/celzero/bravedns/adapter/SummaryStatisticsAdapter.kt @@ -218,10 +218,8 @@ class SummaryStatisticsAdapter( } else { // Glide will cache the icons against the urls. To extract the fav // icon from the cache, first verify that the cache is available with - // the - // next dns url. If it is not available then glide will throw an error, - // do - // the duckduckgo url check in that case. + // the next dns url. If it is not available then glide will throw an + // error, do the duckduckgo url check in that case. displayNextDnsFavIcon(query) } } diff --git a/app/src/full/java/com/celzero/bravedns/ui/activity/AppInfoActivity.kt b/app/src/full/java/com/celzero/bravedns/ui/activity/AppInfoActivity.kt index a064c5a80..3e4b77863 100644 --- a/app/src/full/java/com/celzero/bravedns/ui/activity/AppInfoActivity.kt +++ b/app/src/full/java/com/celzero/bravedns/ui/activity/AppInfoActivity.kt @@ -31,9 +31,12 @@ import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.TooltipCompat import androidx.core.content.ContextCompat import androidx.lifecycle.lifecycleScope +import androidx.recyclerview.widget.LinearLayoutManager import by.kirich1409.viewbindingdelegate.viewBinding import com.bumptech.glide.Glide import com.celzero.bravedns.R +import com.celzero.bravedns.adapter.AppWiseDomainsAdapter +import com.celzero.bravedns.adapter.AppWiseIpsAdapter import com.celzero.bravedns.database.AppInfo import com.celzero.bravedns.database.ConnectionTrackerRepository import com.celzero.bravedns.databinding.ActivityAppDetailsBinding @@ -41,7 +44,6 @@ import com.celzero.bravedns.service.FirewallManager import com.celzero.bravedns.service.FirewallManager.updateFirewallStatus import com.celzero.bravedns.service.PersistentState import com.celzero.bravedns.service.VpnController -import com.celzero.bravedns.ui.bottomsheet.RethinkListBottomSheet import com.celzero.bravedns.util.Constants import com.celzero.bravedns.util.Constants.Companion.INVALID_UID import com.celzero.bravedns.util.Constants.Companion.VIEW_PAGER_SCREEN_TO_LOAD @@ -65,7 +67,6 @@ class AppInfoActivity : AppCompatActivity(R.layout.activity_app_details) { private val b by viewBinding(ActivityAppDetailsBinding::bind) private val persistentState by inject() - private val connectionTrackerRepository by inject() private val ipRulesViewModel: CustomIpViewModel by viewModel() private val domainRulesViewModel: CustomDomainViewModel by viewModel() @@ -74,9 +75,6 @@ class AppInfoActivity : AppCompatActivity(R.layout.activity_app_details) { private var uid: Int = INVALID_UID private lateinit var appInfo: AppInfo - private var ipListUiState: Boolean = false - private var firewallUiState: Boolean = true - private var appStatus = FirewallManager.FirewallStatus.NONE private var connStatus = FirewallManager.ConnectionStatus.ALLOW @@ -84,7 +82,6 @@ class AppInfoActivity : AppCompatActivity(R.layout.activity_app_details) { companion object { const val UID_INTENT_NAME = "UID" - const val LOG_THRESHOLD_SIZE = 100 } override fun onCreate(savedInstanceState: Bundle?) { @@ -95,9 +92,7 @@ class AppInfoActivity : AppCompatActivity(R.layout.activity_app_details) { domainRulesViewModel.setUid(uid) networkLogsViewModel.setUid(uid) init() - observeNetworkLogSize() observeAppRules() - observeDomainLogSize() setupClickListeners() } @@ -109,37 +104,7 @@ class AppInfoActivity : AppCompatActivity(R.layout.activity_app_details) { } } - private fun observeNetworkLogSize() { - networkLogsViewModel.getConnectionsCount(uid).observe(this) { - if (it == null) return@observe - - b.aadIpLogsDetail.text = it.toString() - } - } - - private fun observeDomainLogSize() { - networkLogsViewModel.getAppDomainConnectionsCount(uid).observe(this) { - if (it == null) return@observe - - b.aadDomainLogsDetail.text = it.toString() - } - } - private fun init() { - val domainTxtDesc = - getString( - R.string.two_argument_space, - getString(R.string.lbl_domain).replaceFirstChar { it.uppercase() }, - getString(R.string.lbl_logs).replaceFirstChar { it.uppercase() } - ) - val ipTxtDesc = - getString( - R.string.two_argument_space, - getString(R.string.lbl_ip).replaceFirstChar { it.uppercase() }, - getString(R.string.lbl_logs).replaceFirstChar { it.uppercase() } - ) - b.aadIpLogsDetailDesc.text = ipTxtDesc - b.aadDomainLogsDetailDesc.text = domainTxtDesc io { val appInfo = FirewallManager.getAppInfoByUid(uid) // case: app is uninstalled but still available in RethinkDNS database @@ -170,6 +135,8 @@ class AppInfoActivity : AppCompatActivity(R.layout.activity_app_details) { return@uiCtx } updateFirewallStatusUi(appStatus, connStatus) + setDomainsAdapter() + setIpAdapter() } } } @@ -369,16 +336,59 @@ class AppInfoActivity : AppCompatActivity(R.layout.activity_app_details) { b.aadDomainBlockCard.setOnClickListener { openCustomDomainScreen() } - b.aadIpLogsCard.setOnClickListener { - val intent = Intent(this, AppWiseIpLogsActivity::class.java) - intent.putExtra(UID_INTENT_NAME, uid) - startActivity(intent) + b.aadIpsChip.setOnClickListener { openAppWiseIpLogsActivity() } + + b.aadDomainsChip.setOnClickListener { openAppWiseDomainLogsActivity() } + } + + private fun openAppWiseDomainLogsActivity() { + val intent = Intent(this, AppWiseDomainLogsActivity::class.java) + intent.putExtra(UID_INTENT_NAME, uid) + startActivity(intent) + } + + private fun openAppWiseIpLogsActivity() { + val intent = Intent(this, AppWiseIpLogsActivity::class.java) + intent.putExtra(UID_INTENT_NAME, uid) + startActivity(intent) + } + + private fun setDomainsAdapter() { + val layoutManager = LinearLayoutManager(this) + b.aadMostContactedDomainRv.layoutManager = layoutManager + val adapter = AppWiseDomainsAdapter(this, this, uid) + networkLogsViewModel.getDomainLogsLimited(uid).observe(this) { + adapter.submitData(this.lifecycle, it) + } + b.aadMostContactedDomainRv.adapter = adapter + + adapter.addLoadStateListener { + if (it.append.endOfPaginationReached) { + if (adapter.itemCount < 1) { + b.aadMostContactedDomainRl.visibility = View.GONE + b.aadMostContactedIpsRv.visibility = View.GONE + } + } + } + } + + private fun setIpAdapter() { + b.aadMostContactedIpsRv.setHasFixedSize(true) + val layoutManager = LinearLayoutManager(this) + b.aadMostContactedIpsRv.layoutManager = layoutManager + val adapter = AppWiseIpsAdapter(this, this, uid) + networkLogsViewModel.getIpLogsLimited(uid).observe(this) { + adapter.submitData(this.lifecycle, it) } + b.aadMostContactedIpsRv.adapter = adapter - b.aadDomainLogsCard.setOnClickListener { - val intent = Intent(this, AppWiseDomainLogsActivity::class.java) - intent.putExtra(UID_INTENT_NAME, uid) - startActivity(intent) + adapter.addLoadStateListener { + if (it.append.endOfPaginationReached) { + if (adapter.itemCount < 1) { + b.aadMostContactedIpsRl.visibility = View.GONE + b.aadMostContactedDomainRv.visibility = View.GONE + } + } } } @@ -404,11 +414,6 @@ class AppInfoActivity : AppCompatActivity(R.layout.activity_app_details) { alertDialog.show() } - private fun rethinkListBottomSheet() { - val bottomSheetFragment = RethinkListBottomSheet() - bottomSheetFragment.show(this.supportFragmentManager, bottomSheetFragment.tag) - } - private fun toggleMobileData(appInfo: AppInfo) { // toggle mobile data: change the connection status based on the current status. // if allow -> none(app status) + metered(connection status) diff --git a/app/src/full/java/com/celzero/bravedns/ui/activity/AppWiseDomainLogsActivity.kt b/app/src/full/java/com/celzero/bravedns/ui/activity/AppWiseDomainLogsActivity.kt index 2b07d1640..7a1536e70 100644 --- a/app/src/full/java/com/celzero/bravedns/ui/activity/AppWiseDomainLogsActivity.kt +++ b/app/src/full/java/com/celzero/bravedns/ui/activity/AppWiseDomainLogsActivity.kt @@ -16,6 +16,7 @@ package com.celzero.bravedns.ui.activity import android.content.Context +import android.content.res.ColorStateList import android.content.res.Configuration import android.graphics.drawable.Drawable import android.os.Bundle @@ -36,8 +37,11 @@ import com.celzero.bravedns.service.FirewallManager import com.celzero.bravedns.service.PersistentState import com.celzero.bravedns.util.Constants.Companion.INVALID_UID import com.celzero.bravedns.util.Themes +import com.celzero.bravedns.util.UIUtils import com.celzero.bravedns.util.Utilities import com.celzero.bravedns.viewmodel.AppConnectionsViewModel +import com.google.android.material.button.MaterialButton +import com.google.android.material.button.MaterialButtonToggleGroup import com.google.android.material.dialog.MaterialAlertDialogBuilder import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -75,7 +79,47 @@ class AppWiseDomainLogsActivity : setClickListener() } + private fun setTabbedViewTxt() { + b.tbRecentToggleBtn.text = getString(R.string.ci_desc, "1", getString(R.string.lbl_hour)) + b.tbDailyToggleBtn.text = getString(R.string.ci_desc, "24", getString(R.string.lbl_hour)) + b.tbWeeklyToggleBtn.text = getString(R.string.ci_desc, "7", getString(R.string.lbl_day)) + } + + private val listViewToggleListener = + MaterialButtonToggleGroup.OnButtonCheckedListener { _, checkedId, isChecked -> + val mb: MaterialButton = b.toggleGroup.findViewById(checkedId) + if (isChecked) { + selectToggleBtnUi(mb) + val tcValue = (mb.tag as String).toIntOrNull() ?: 0 + val timeCategory = + AppConnectionsViewModel.TimeCategory.fromValue(tcValue) + ?: AppConnectionsViewModel.TimeCategory.ONE_HOUR + networkLogsViewModel.timeCategoryChanged(timeCategory, true) + return@OnButtonCheckedListener + } + + unselectToggleBtnUi(mb) + } + + private fun selectToggleBtnUi(mb: MaterialButton) { + mb.backgroundTintList = + ColorStateList.valueOf( + UIUtils.fetchToggleBtnColors(this, R.color.accentGood) + ) + mb.setTextColor(UIUtils.fetchColor(this, R.attr.homeScreenHeaderTextColor)) + } + + private fun unselectToggleBtnUi(mb: MaterialButton) { + mb.setTextColor(UIUtils.fetchColor(this, R.attr.primaryTextColor)) + mb.backgroundTintList = + ColorStateList.valueOf( + UIUtils.fetchToggleBtnColors(this, R.color.defaultToggleBtnBg) + ) + } + private fun init() { + setTabbedViewTxt() + highlightToggleBtn() io { val appInfo = FirewallManager.getAppInfoByUid(uid) // case: app is uninstalled but still available in RethinkDNS database @@ -97,7 +141,16 @@ class AppWiseDomainLogsActivity : } } + + private fun highlightToggleBtn() { + val timeCategory = "0" // default is 1 hours, "0" tag is 1 hours + val btn = b.toggleGroup.findViewWithTag(timeCategory) + btn.isChecked = true + selectToggleBtnUi(btn) + } + private fun setClickListener() { + b.toggleGroup.addOnButtonCheckedListener(listViewToggleListener) b.awlDelete.setOnClickListener { showDeleteConnectionsDialog() } b.awlSearch.setOnQueryTextListener(this) } diff --git a/app/src/full/java/com/celzero/bravedns/ui/activity/AppWiseIpLogsActivity.kt b/app/src/full/java/com/celzero/bravedns/ui/activity/AppWiseIpLogsActivity.kt index 14005ee67..3d3e0c9a5 100644 --- a/app/src/full/java/com/celzero/bravedns/ui/activity/AppWiseIpLogsActivity.kt +++ b/app/src/full/java/com/celzero/bravedns/ui/activity/AppWiseIpLogsActivity.kt @@ -16,6 +16,7 @@ package com.celzero.bravedns.ui.activity import android.content.Context +import android.content.res.ColorStateList import android.content.res.Configuration import android.graphics.drawable.Drawable import android.os.Bundle @@ -36,8 +37,11 @@ import com.celzero.bravedns.service.FirewallManager import com.celzero.bravedns.service.PersistentState import com.celzero.bravedns.util.Constants.Companion.INVALID_UID import com.celzero.bravedns.util.Themes +import com.celzero.bravedns.util.UIUtils import com.celzero.bravedns.util.Utilities import com.celzero.bravedns.viewmodel.AppConnectionsViewModel +import com.google.android.material.button.MaterialButton +import com.google.android.material.button.MaterialButtonToggleGroup import com.google.android.material.dialog.MaterialAlertDialogBuilder import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -76,6 +80,8 @@ class AppWiseIpLogsActivity : } private fun init() { + setTabbedViewTxt() + highlightToggleBtn() io { val appInfo = FirewallManager.getAppInfoByUid(uid) // case: app is uninstalled but still available in RethinkDNS database @@ -97,7 +103,49 @@ class AppWiseIpLogsActivity : } } + private fun setTabbedViewTxt() { + b.tbRecentToggleBtn.text = getString(R.string.ci_desc, "1", getString(R.string.lbl_hour)) + b.tbDailyToggleBtn.text = getString(R.string.ci_desc, "24", getString(R.string.lbl_hour)) + b.tbWeeklyToggleBtn.text = getString(R.string.ci_desc, "7", getString(R.string.lbl_day)) + } + + private val listViewToggleListener = + MaterialButtonToggleGroup.OnButtonCheckedListener { _, checkedId, isChecked -> + val mb: MaterialButton = b.toggleGroup.findViewById(checkedId) + if (isChecked) { + selectToggleBtnUi(mb) + val tcValue = (mb.tag as String).toIntOrNull() ?: 0 + val timeCategory = + AppConnectionsViewModel.TimeCategory.fromValue(tcValue) + ?: AppConnectionsViewModel.TimeCategory.ONE_HOUR + networkLogsViewModel.timeCategoryChanged(timeCategory, isDomain = false) + return@OnButtonCheckedListener + } + + unselectToggleBtnUi(mb) + } + + private fun selectToggleBtnUi(mb: MaterialButton) { + mb.backgroundTintList = + ColorStateList.valueOf(UIUtils.fetchToggleBtnColors(this, R.color.accentGood)) + mb.setTextColor(UIUtils.fetchColor(this, R.attr.homeScreenHeaderTextColor)) + } + + private fun unselectToggleBtnUi(mb: MaterialButton) { + mb.setTextColor(UIUtils.fetchColor(this, R.attr.primaryTextColor)) + mb.backgroundTintList = + ColorStateList.valueOf(UIUtils.fetchToggleBtnColors(this, R.color.defaultToggleBtnBg)) + } + + private fun highlightToggleBtn() { + val timeCategory = "0" // default is 1 hours, "0" tag is 1 hours + val btn = b.toggleGroup.findViewWithTag(timeCategory) + btn.isChecked = true + selectToggleBtnUi(btn) + } + private fun setClickListener() { + b.toggleGroup.addOnButtonCheckedListener(listViewToggleListener) b.awlDelete.setOnClickListener { showDeleteConnectionsDialog() } b.awlSearch.setOnQueryTextListener(this) } diff --git a/app/src/full/java/com/celzero/bravedns/ui/fragment/SummaryStatisticsFragment.kt b/app/src/full/java/com/celzero/bravedns/ui/fragment/SummaryStatisticsFragment.kt index fb318b5eb..6982499e5 100644 --- a/app/src/full/java/com/celzero/bravedns/ui/fragment/SummaryStatisticsFragment.kt +++ b/app/src/full/java/com/celzero/bravedns/ui/fragment/SummaryStatisticsFragment.kt @@ -171,12 +171,8 @@ class SummaryStatisticsFragment : Fragment(R.layout.fragment_summary_statistics) b.fssProgressBar.secondaryProgress = secondaryVal } - private fun calculatePercentage(currentValue: Long, maxValue: Long): Int { - // calculate the percentage as a float - val percentageFloat = currentValue.toFloat() / maxValue * 100 - - // convert the float to an int, rounding down if necessary - return percentageFloat.toInt() + private fun calculatePercentage(value: Long, maxValue: Long): Int { + return (value * 100 / maxValue).toInt() } private fun highlightToggleBtn() { diff --git a/app/src/full/java/com/celzero/bravedns/viewmodel/AppConnectionsViewModel.kt b/app/src/full/java/com/celzero/bravedns/viewmodel/AppConnectionsViewModel.kt index 1dfe03812..9ea5b7388 100644 --- a/app/src/full/java/com/celzero/bravedns/viewmodel/AppConnectionsViewModel.kt +++ b/app/src/full/java/com/celzero/bravedns/viewmodel/AppConnectionsViewModel.kt @@ -34,6 +34,24 @@ class AppConnectionsViewModel(private val nwlogDao: ConnectionTrackerDAO) : View private var domainFilter: MutableLiveData = MutableLiveData() private var uid: Int = Constants.INVALID_UID private val pagingConfig: PagingConfig + private var timeCategory: TimeCategory = TimeCategory.ONE_HOUR + private var startTime: MutableLiveData = MutableLiveData() + + companion object { + private const val ONE_HOUR_MILLIS = 1 * 60 * 60 * 1000L + private const val ONE_DAY_MILLIS = 24 * ONE_HOUR_MILLIS + private const val ONE_WEEK_MILLIS = 7 * ONE_DAY_MILLIS + } + + enum class TimeCategory(val value: Int) { + ONE_HOUR(0), + TWENTY_FOUR_HOUR(1), + SEVEN_DAYS(2); + + companion object { + fun fromValue(value: Int) = entries.firstOrNull { it.value == value } + } + } init { ipFilter.value = "" @@ -50,6 +68,29 @@ class AppConnectionsViewModel(private val nwlogDao: ConnectionTrackerDAO) : View ) } + fun timeCategoryChanged(tc: TimeCategory, isDomain: Boolean) { + timeCategory = tc + when (tc) { + TimeCategory.ONE_HOUR -> { + startTime.value = + System.currentTimeMillis() - ONE_HOUR_MILLIS + } + TimeCategory.TWENTY_FOUR_HOUR -> { + startTime.value = + System.currentTimeMillis() - ONE_DAY_MILLIS + } + TimeCategory.SEVEN_DAYS -> { + startTime.value = + System.currentTimeMillis() - ONE_WEEK_MILLIS + } + } + if (isDomain) { + domainFilter.value = "" + } else { + ipFilter.value = "" + } + } + enum class FilterType { IP, DOMAIN @@ -59,25 +100,31 @@ class AppConnectionsViewModel(private val nwlogDao: ConnectionTrackerDAO) : View val appDomainLogs = domainFilter.switchMap { input -> fetchAppDomainLogs(uid, input) } private fun fetchIpLogs(uid: Int, input: String): LiveData> { + val to = getStartTime() return if (input.isEmpty()) { - Pager(pagingConfig) { nwlogDao.getAppIpLogs(uid) } + Pager(pagingConfig) { nwlogDao.getAppIpLogs(uid, to) } } else { - Pager(pagingConfig) { nwlogDao.getAppIpLogsFiltered(uid, "%$input%") } + Pager(pagingConfig) { nwlogDao.getAppIpLogsFiltered(uid, to, "%$input%") } } .liveData .cachedIn(viewModelScope) } private fun fetchAppDomainLogs(uid: Int, input: String): LiveData> { + val to = getStartTime() return if (input.isEmpty()) { - Pager(pagingConfig) { nwlogDao.getAppDomainLogs(uid) } + Pager(pagingConfig) { nwlogDao.getAppDomainLogs(uid, to) } } else { - Pager(pagingConfig) { nwlogDao.getAppDomainLogsFiltered(uid, "%$input%") } + Pager(pagingConfig) { nwlogDao.getAppDomainLogsFiltered(uid, to, "%$input%") } } .liveData .cachedIn(viewModelScope) } + private fun getStartTime(): Long { + return startTime.value ?: (System.currentTimeMillis() - ONE_HOUR_MILLIS) + } + fun getConnectionsCount(uid: Int): LiveData { return nwlogDao.getAppConnectionsCount(uid) } @@ -86,6 +133,18 @@ class AppConnectionsViewModel(private val nwlogDao: ConnectionTrackerDAO) : View return nwlogDao.getAppDomainConnectionsCount(uid) } + fun getDomainLogsLimited(uid: Int): LiveData> { + return Pager(pagingConfig) { nwlogDao.getAppDomainLogsLimited(uid) } + .liveData + .cachedIn(viewModelScope) + } + + fun getIpLogsLimited(uid: Int): LiveData> { + return Pager(pagingConfig) { nwlogDao.getAppIpLogsLimited(uid) } + .liveData + .cachedIn(viewModelScope) + } + fun setFilter(input: String, filterType: FilterType) { if (filterType == FilterType.IP) { this.ipFilter.postValue(input) diff --git a/app/src/full/res/layout/activity_app_details.xml b/app/src/full/res/layout/activity_app_details.xml index b8cea9a4a..19580b773 100644 --- a/app/src/full/res/layout/activity_app_details.xml +++ b/app/src/full/res/layout/activity_app_details.xml @@ -1,5 +1,5 @@ - - @@ -28,7 +28,7 @@ android:layout_centerVertical="true" android:src="@drawable/dns_icon" /> - - + - - + @@ -94,7 +94,7 @@ app:cardElevation="8dp" app:cardUseCompatPadding="true"> - - - - + - - - - + + + - - - + - - + - + - + android:layout_marginTop="10dp"> - - - + android:layout_alignParentStart="true" + android:layout_centerVertical="true" + android:layout_marginStart="20dp" + android:layout_toStartOf="@id/aad_domains_chip" + android:fontFamily="sans-serif-smallcaps" + android:lineSpacingExtra="5dp" + android:padding="5dp" + android:text="@string/ssv_most_contacted_domain_heading" + android:textColor="?attr/primaryLightColorText" + android:textSize="@dimen/extra_large_font_text_view" /> + + - + - - + - + android:layout_marginTop="20dp"> - - - + android:layout_alignParentStart="true" + android:layout_centerVertical="true" + android:layout_marginStart="20dp" + android:layout_toStartOf="@id/aad_ips_chip" + android:fontFamily="sans-serif-smallcaps" + android:lineSpacingExtra="5dp" + android:padding="5dp" + android:text="@string/ssv_most_contacted_ips_heading" + android:textColor="?attr/primaryLightColorText" + android:textSize="@dimen/extra_large_font_text_view" /> + + - + - - + - + - + diff --git a/app/src/full/res/layout/list_item_app_domain_details.xml b/app/src/full/res/layout/list_item_app_domain_details.xml index 4d8c62df6..3521135b6 100644 --- a/app/src/full/res/layout/list_item_app_domain_details.xml +++ b/app/src/full/res/layout/list_item_app_domain_details.xml @@ -20,7 +20,7 @@ android:layout_centerVertical="true" android:layout_gravity="center" android:layout_marginStart="5dp" - android:alpha="0.9" + android:alpha="0.75" android:layout_marginTop="5dp" android:layout_marginEnd="5dp" android:layout_marginBottom="5dp" diff --git a/app/src/full/res/layout/list_item_app_ip_details.xml b/app/src/full/res/layout/list_item_app_ip_details.xml index 3ca987a32..b8c8fbee3 100644 --- a/app/src/full/res/layout/list_item_app_ip_details.xml +++ b/app/src/full/res/layout/list_item_app_ip_details.xml @@ -20,7 +20,7 @@ android:layout_centerVertical="true" android:layout_gravity="center" android:layout_marginStart="5dp" - android:alpha="0.9" + android:alpha="0.75" android:layout_marginTop="5dp" android:layout_marginEnd="5dp" android:layout_marginBottom="5dp" diff --git a/app/src/main/java/com/celzero/bravedns/database/ConnectionTrackerDAO.kt b/app/src/main/java/com/celzero/bravedns/database/ConnectionTrackerDAO.kt index 858dee709..7c0914911 100644 --- a/app/src/main/java/com/celzero/bravedns/database/ConnectionTrackerDAO.kt +++ b/app/src/main/java/com/celzero/bravedns/database/ConnectionTrackerDAO.kt @@ -89,29 +89,45 @@ interface ConnectionTrackerDAO { fun getBlockedConnections(query: String): PagingSource @Query( - "SELECT uid, ipAddress, port, COUNT(ipAddress) as count, flag as flag, 0 as blocked, GROUP_CONCAT(DISTINCT dnsQuery) as appOrDnsName FROM ConnectionTracker WHERE uid = :uid GROUP BY ipAddress, uid, port ORDER BY count DESC" + "SELECT uid, ipAddress, port, COUNT(ipAddress) as count, flag as flag, 0 as blocked, GROUP_CONCAT(DISTINCT dnsQuery) as appOrDnsName FROM ConnectionTracker WHERE uid = :uid and timeStamp > :to GROUP BY ipAddress, uid, port ORDER BY count DESC" ) - fun getAppIpLogs(uid: Int): PagingSource + fun getAppIpLogs(uid: Int, to: Long): PagingSource @Query( - "SELECT uid, ipAddress, port, COUNT(ipAddress) as count, flag as flag, 0 as blocked, GROUP_CONCAT(DISTINCT dnsQuery) as appOrDnsName FROM ConnectionTracker WHERE uid = :uid and ipAddress like :query GROUP BY ipAddress, uid, port ORDER BY count DESC" + "SELECT uid, ipAddress, port, COUNT(ipAddress) as count, flag as flag, 0 as blocked, '' as appOrDnsName FROM ConnectionTracker WHERE uid = :uid GROUP BY ipAddress, uid, port ORDER BY count DESC LIMIT 3" ) - fun getAppIpLogsFiltered(uid: Int, query: String): PagingSource + fun getAppIpLogsLimited(uid: Int): PagingSource @Query( - "SELECT uid, GROUP_CONCAT(DISTINCT ipAddress) as ipAddress, port, COUNT(dnsQuery) as count, flag as flag, 0 as blocked, dnsQuery as appOrDnsName FROM ConnectionTracker WHERE uid = :uid and dnsQuery != '' GROUP BY dnsQuery ORDER BY count DESC" + "SELECT uid, ipAddress, port, COUNT(ipAddress) as count, flag as flag, 0 as blocked, GROUP_CONCAT(DISTINCT dnsQuery) as appOrDnsName FROM ConnectionTracker WHERE uid = :uid and timeStamp > :to and ipAddress like :query GROUP BY ipAddress, uid, port ORDER BY count DESC" ) - fun getAppDomainLogs(uid: Int): PagingSource + fun getAppIpLogsFiltered(uid: Int, to: Long, query: String): PagingSource @Query( - "SELECT uid, GROUP_CONCAT(DISTINCT ipAddress) as ipAddress, port, COUNT(dnsQuery) as count, flag as flag, 0 as blocked, dnsQuery as appOrDnsName FROM ConnectionTracker WHERE uid = :uid and dnsQuery != '' and dnsQuery like :query GROUP BY dnsQuery ORDER BY count DESC" + "SELECT uid, GROUP_CONCAT(DISTINCT ipAddress) as ipAddress, port, COUNT(dnsQuery) as count, flag as flag, 0 as blocked, dnsQuery as appOrDnsName FROM ConnectionTracker WHERE uid = :uid and timeStamp > :to and dnsQuery != '' GROUP BY dnsQuery ORDER BY count DESC" ) - fun getAppDomainLogsFiltered(uid: Int, query: String): PagingSource + fun getAppDomainLogs(uid: Int, to: Long): PagingSource + + @Query( + "SELECT uid, '' as ipAddress, port, COUNT(dnsQuery) as count, flag as flag, 0 as blocked, dnsQuery as appOrDnsName FROM ConnectionTracker WHERE uid = :uid and dnsQuery != '' GROUP BY dnsQuery ORDER BY count DESC LIMIT 3" + ) + fun getAppDomainLogsLimited(uid: Int): PagingSource + + @Query( + "SELECT uid, GROUP_CONCAT(DISTINCT ipAddress) as ipAddress, port, COUNT(dnsQuery) as count, flag as flag, 0 as blocked, dnsQuery as appOrDnsName FROM ConnectionTracker WHERE uid = :uid and timeStamp > :to and dnsQuery != '' and dnsQuery like :query GROUP BY dnsQuery ORDER BY count DESC" + ) + fun getAppDomainLogsFiltered( + uid: Int, + to: Long, + query: String + ): PagingSource @Query("select count(DISTINCT(ipAddress)) from ConnectionTracker where uid = :uid") fun getAppConnectionsCount(uid: Int): LiveData - @Query("select count(DISTINCT(dnsQuery)) from ConnectionTracker where uid = :uid") + @Query( + "select count(DISTINCT(dnsQuery)) from ConnectionTracker where uid = :uid and dnsQuery != ''" + ) fun getAppDomainConnectionsCount(uid: Int): LiveData @Query( diff --git a/app/src/main/res/layout/activity_app_wise_domain_logs.xml b/app/src/main/res/layout/activity_app_wise_domain_logs.xml index ff61a0f8d..c2d952535 100644 --- a/app/src/main/res/layout/activity_app_wise_domain_logs.xml +++ b/app/src/main/res/layout/activity_app_wise_domain_logs.xml @@ -11,14 +11,15 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="10dp" - android:layout_marginEnd="10dp" android:layout_marginTop="10dp" + android:layout_marginEnd="10dp" android:padding="5dp"> @@ -31,11 +32,58 @@ android:layout_toEndOf="@id/awl_app_detail_icon" android:gravity="center" android:padding="5dp" - android:textColor="?primaryTextColor" + android:textColor="?primaryLightColorText" android:textSize="@dimen/large_font_text_view" /> + + + + + + + + + + @@ -31,11 +32,58 @@ android:layout_toEndOf="@id/awl_app_detail_icon" android:gravity="center" android:padding="5dp" - android:textColor="?primaryTextColor" + android:textColor="?primaryLightColorText" android:textSize="@dimen/large_font_text_view" /> + + + + + + + + + + Date: Tue, 7 May 2024 21:25:18 +0530 Subject: [PATCH 02/27] update: latest filetag for remote blocklist (1713995763912) --- app/src/main/assets/filetag.json | 2 +- app/src/main/java/com/celzero/bravedns/util/Constants.kt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/assets/filetag.json b/app/src/main/assets/filetag.json index 8b99c43c3..4039672b8 100644 --- a/app/src/main/assets/filetag.json +++ b/app/src/main/assets/filetag.json @@ -1 +1 @@ -{"171":{"value":171,"uname":"171","vname":"1Hosts (Xtra)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/badmojr/1Hosts/master/Xtra/domains.wildcards","format":"domains","pack":["extremeprivacy"],"level":[2],"entries":259001,"discards":0},"172":{"value":172,"uname":"172","vname":"Spotify Ads (GoodbyeAds)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/jerryn70/GoodbyeAds/master/Extension/GoodbyeAds-Spotify-AdBlock.txt","format":"hosts","pack":[],"level":[],"entries":3780,"discards":1503},"173":{"value":173,"uname":"173","vname":"AVG + Avast (ftprivacy)","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/ftpmorph/ftprivacy/master/blocklists/avg-avast-data-mining-full-block.txt","format":"domains","pack":["vpn & proxies"],"level":[2],"entries":349,"discards":342},"174":{"value":174,"uname":"174","vname":"Hola VPN (ftprivacy)","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/ftpmorph/ftprivacy/master/blocklists/hola-luminati-full-block.txt","format":"domains","pack":["vpn & proxies"],"level":[2],"entries":117,"discards":115},"175":{"value":175,"uname":"175","vname":"Combined Privacy Block Lists: Full (bongochong)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/bongochong/CombinedPrivacyBlockLists/master/NoFormatting/cpbl-wildcard-blacklist.txt","format":"wildcard","pack":["aggressiveprivacy"],"level":[1],"entries":140589,"discards":0},"176":{"value":176,"uname":"176","vname":"Torrent (The Block List Project)","group":"parentalcontrol","subg":"piracy","url":"https://blocklistproject.github.io/Lists/alt-version/torrent-nl.txt","format":"domains","pack":["torrents","piracy"],"level":[1,1],"entries":2623,"discards":279},"177":{"value":177,"uname":"177","vname":"Drugs (The Block List Project)","group":"parentalcontrol","subg":"threat-intelligence-feeds","url":"https://blocklistproject.github.io/Lists/alt-version/drugs-nl.txt","format":"domains","pack":["drugs"],"level":[2],"entries":26031,"discards":7014},"178":{"value":178,"uname":"178","vname":"Ransomware (The Block List Project)","group":"security","subg":"threat-intelligence-feeds","url":"https://blocklistproject.github.io/Lists/alt-version/ransomware-nl.txt","format":"domains","pack":["scams & phishing"],"level":[2],"entries":1904,"discards":1},"179":{"value":179,"uname":"179","vname":"NSFL (ShadowWhisperer)","group":"parentalcontrol","subg":"porn","url":"https://raw.githubusercontent.com/ShadowWhisperer/BlockLists/master/Lists/Shock","format":"domains","pack":["adult"],"level":[1],"entries":98,"discards":0},"180":{"value":180,"uname":"180","vname":"Cryptojacking (The Block List Project)","group":"security","subg":"cryptojacking","url":"https://blocklistproject.github.io/Lists/alt-version/crypto-nl.txt","format":"domains","pack":["crypto"],"level":[2],"entries":23761,"discards":13359},"181":{"value":181,"uname":"181","vname":"WhatsApp","group":"","subg":"","url":"","format":"domains","pack":["dead"],"level":[],"entries":0},"182":{"value":182,"uname":"182","vname":"Vaping (The Block List Project)","group":"parentalcontrol","subg":"threat-intelligence-feeds","url":"https://blocklistproject.github.io/Lists/alt-version/vaping-nl.txt","format":["domains","domains"],"pack":["drugs"],"level":[1],"entries":414,"discards":102},"183":{"value":183,"uname":"183","vname":"Piracy (The Block List Project)","group":"parentalcontrol","subg":"piracy","url":"https://blocklistproject.github.io/Lists/alt-version/piracy-nl.txt","format":"domains","pack":["piracy","file-hosts"],"level":[2,2],"entries":2153,"discards":988},"184":{"value":184,"uname":"184","vname":"Facebook (The Block List Project)","group":"parentalcontrol","subg":"services","url":"https://blocklistproject.github.io/Lists/alt-version/facebook-nl.txt","format":"domains","pack":["facebook","socialmedia"],"level":[1,2],"entries":22459,"discards":22379},"185":{"value":185,"uname":"185","vname":"Gambling (The Block List Project)","group":"parentalcontrol","subg":"gambling","url":"https://blocklistproject.github.io/Lists/alt-version/gambling-nl.txt","format":"domains","pack":["gambling"],"level":[2],"entries":2499,"discards":1121},"186":{"value":186,"uname":"186","vname":"OISD NSFW (Adult)","group":"parentalcontrol","subg":"porn","url":"https://raw.githubusercontent.com/sjhgvr/oisd/main/domainswild_nsfw.txt","format":"wildcard","pack":["adult"],"level":[1],"entries":407771,"discards":1400},"187":{"value":187,"uname":"187","vname":"Blocklists (cbuijs)","group":"privacy","subg":"","url":"https://github.com/cbuijs/accomplist/raw/master/deugniets/plain.black.domain.list","format":"domains","pack":["ignore"],"level":[2],"entries":0},"188":{"value":188,"uname":"188","vname":"Yet another small uBlock filter list","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/mtxadmin/ublock/master/hosts.txt","format":"hosts","pack":["extremeprivacy"],"level":[2],"entries":1039901,"discards":980427},"189":{"value":189,"uname":"189","vname":"URL Shorteners (PeterDaveHello + ShadowWhisperer)","group":"security","subg":"tracking-domains","url":"https://raw.githubusercontent.com/PeterDaveHello/url-shorteners/master/list","format":["domains","domains"],"pack":["url-shorteners"],"level":[1],"entries":3562,"discards":142},"190":{"value":190,"uname":"190","vname":"Persian Blocker","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/MasterKia/PersianBlocker/main/PersianBlockerHosts.txt","format":"domains","pack":["extremeprivacy"],"level":[2],"entries":264,"discards":6},"191":{"value":191,"uname":"191","vname":"1Hosts (kidSaf)","group":"parentalcontrol","subg":"porn","url":"https://raw.githubusercontent.com/badmojr/addons_1Hosts/main/kidSaf/domains.wildcards","format":"domains","pack":["adult"],"level":[2],"entries":874554,"discards":0},"192":{"value":192,"uname":"192","vname":"Adult (The Block List Project)","group":"parentalcontrol","subg":"porn","url":"https://blocklistproject.github.io/Lists/alt-version/porn-nl.txt","format":"domains","pack":["adult"],"level":[2],"entries":500280,"discards":1124},"193":{"value":193,"uname":"193","vname":"Tracking (The Block List Project)","group":"privacy","subg":"","url":"https://blocklistproject.github.io/Lists/alt-version/tracking-nl.txt","format":["domains","domains"],"pack":["spyware"],"level":[1],"entries":79505,"discards":1360},"194":{"value":194,"uname":"194","vname":"Microsoft","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/ShadowWhisperer/BlockLists/master/Lists/Microsoft","format":"domains","pack":["microsoft"],"level":[2],"entries":677,"discards":115},"195":{"value":195,"uname":"195","vname":"Bad Top-Level Domains (cbuijs)","group":"security","subg":"threat-intelligence-feeds","url":"https://github.com/cbuijs/accomplist/raw/master/tlds/plain.black.domain.list","format":"domains","pack":["spam"],"level":[2],"entries":1290,"discards":0},"196":{"value":196,"uname":"196","vname":"Tiny China Block List Replenish","group":"privacy","subg":"gambling","url":"https://raw.githubusercontent.com/tim-hub/tiny-cn-blocklist-replenish/master/common.txt","format":["domains","domains"],"pack":["liteprivacy","gambling"],"level":[0,1],"entries":78,"discards":2},"MTF":{"value":0,"uname":"MTF","vname":"Prevent bypass","group":"parentalcontrol","subg":"bypass-methods","url":"https://raw.githubusercontent.com/hagezi/dns-blocklists/main/wildcard/doh-vpn-proxy-bypass.txt","format":["wildcard","domains"],"pack":["vpn & proxies"],"level":[1],"entries":66250,"discards":987},"KBI":{"value":1,"uname":"KBI","vname":"Safe Search Only","group":"parentalcontrol","subg":"safesearch","url":"https://raw.githubusercontent.com/nextdns/no-safesearch/main/domains","format":"domains","pack":[],"level":[],"entries":175,"discards":0},"YAC":{"value":2,"uname":"YAC","vname":"Dating (Olbat + ShadowWhisperer)","group":"parentalcontrol","subg":"dating","url":"https://raw.githubusercontent.com/olbat/ut1-blacklists/master/blacklists/dating/domains","format":["domains","domains"],"pack":["dating"],"level":[0],"entries":4868,"discards":606},"HBP":{"value":3,"uname":"HBP","vname":"Gambling (Olbat + hostsVN)","group":"parentalcontrol","subg":"gambling","url":"https://raw.githubusercontent.com/olbat/ut1-blacklists/master/blacklists/gambling/domains","format":["domains","hosts"],"pack":["gambling"],"level":[0],"entries":151564,"discards":2606},"NIM":{"value":4,"uname":"NIM","vname":"Gambling (Sinfonietta)","group":"parentalcontrol","subg":"gambling","url":"https://raw.githubusercontent.com/Sinfonietta/hostfiles/master/gambling-hosts","format":"hosts","pack":["gambling"],"level":[2],"entries":2619,"discards":1173},"YWG":{"value":5,"uname":"YWG","vname":"Torrents (DHT nodes)","group":"parentalcontrol","subg":"piracy","url":"https://raw.githubusercontent.com/nextdns/piracy-blocklists/master/dht-bootstrap-nodes","format":"domains","pack":["torrents","file-hosts","piracy"],"level":[0,1,0],"entries":5,"discards":0},"SMQ":{"value":6,"uname":"SMQ","vname":"File hosting","group":"parentalcontrol","subg":"piracy","url":"https://raw.githubusercontent.com/nextdns/piracy-blocklists/master/file-hosting","format":["domains","domains","domains"],"pack":["file-hosts","piracy"],"level":[0,2],"entries":193,"discards":8},"AQX":{"value":7,"uname":"AQX","vname":"Proxies","group":"parentalcontrol","subg":"bypass-methods","url":"https://raw.githubusercontent.com/nextdns/piracy-blocklists/master/proxies","format":["domains","domains"],"pack":["vpn & proxies","piracy"],"level":[0,2],"entries":202307,"discards":93619},"BTG":{"value":8,"uname":"BTG","vname":"Streaming Audio","group":"parentalcontrol","subg":"piracy","url":"https://raw.githubusercontent.com/nextdns/piracy-blocklists/master/streaming-audio","format":"domains","pack":["streams","piracy"],"level":[0,2],"entries":65,"discards":0},"GUN":{"value":9,"uname":"GUN","vname":"Streaming Video","group":"parentalcontrol","subg":"piracy","url":"https://raw.githubusercontent.com/nextdns/piracy-blocklists/master/streaming-video","format":["domains","domains","domains"],"pack":["streams","piracy"],"level":[0,2],"entries":1099,"discards":15},"KSH":{"value":10,"uname":"KSH","vname":"Torrent Clients","group":"parentalcontrol","subg":"piracy","url":"https://raw.githubusercontent.com/nextdns/piracy-blocklists/master/torrent-clients","format":"domains","pack":["torrents","piracy"],"level":[0,1],"entries":31,"discards":0},"WAS":{"value":11,"uname":"WAS","vname":"Torrent Trackers","group":"parentalcontrol","subg":"piracy","url":"https://raw.githubusercontent.com/nextdns/piracy-blocklists/master/torrent-trackers","format":"domains","pack":["torrents","piracy"],"level":[0,1],"entries":351,"discards":14},"AZY":{"value":12,"uname":"AZY","vname":"Torrent Websites","group":"parentalcontrol","subg":"piracy","url":"https://raw.githubusercontent.com/nextdns/piracy-blocklists/master/torrent-websites","format":"domains","pack":["torrents","piracy"],"level":[0,2],"entries":1266,"discards":12},"GWB":{"value":13,"uname":"GWB","vname":"Usenet","group":"parentalcontrol","subg":"piracy","url":"https://raw.githubusercontent.com/nextdns/piracy-blocklists/master/usenet","format":"domains","pack":["file-hosts","piracy"],"level":[2,1],"entries":12,"discards":0},"YMG":{"value":14,"uname":"YMG","vname":"Warez","group":"parentalcontrol","subg":"piracy","url":"https://raw.githubusercontent.com/nextdns/piracy-blocklists/master/warez","format":"domains","pack":["file-hosts","piracy"],"level":[2,2],"entries":133,"discards":0},"CZM":{"value":15,"uname":"CZM","vname":"Adult (Tiuxo)","group":"parentalcontrol","subg":"porn","url":"https://raw.githubusercontent.com/tiuxo/hosts/master/porn","format":"hosts","pack":["adult"],"level":[0],"entries":369,"discards":2},"HYS":{"value":16,"uname":"HYS","vname":"Adult (StevenBlack)","group":"parentalcontrol","subg":"porn","url":"https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/porn/hosts","format":"hosts","pack":["adult"],"level":[0],"entries":218106,"discards":98077},"XIF":{"value":17,"uname":"XIF","vname":"Adult (cbuijs)","group":"parentalcontrol","subg":"porn","url":"https://raw.githubusercontent.com/cbuijs/accomplist/master/family-safe/plain.black.domain.list","format":"domains","pack":["adult"],"level":[1],"entries":3621660,"discards":2302797},"TQN":{"value":18,"uname":"TQN","vname":"Adult (ShadowWhisperer)","group":"parentalcontrol","subg":"porn","url":"https://raw.githubusercontent.com/ShadowWhisperer/BlockLists/master/Lists/Adult","format":"domains","pack":["adult"],"level":[2],"entries":241489,"discards":83},"ZVO":{"value":19,"uname":"ZVO","vname":"Social networks (Olbat)","group":"parentalcontrol","subg":"social-networks","url":"https://raw.githubusercontent.com/olbat/ut1-blacklists/master/blacklists/social_networks/domains","format":"domains","pack":["socialmedia"],"level":[0],"entries":701,"discards":0},"YOM":{"value":20,"uname":"YOM","vname":"9Gag","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/9gag","format":"domains","pack":["vanity"],"level":[1],"entries":2,"discards":0},"THR":{"value":21,"uname":"THR","vname":"Amazon","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nickspaargaren/no-amazon/master/amazon.txt","format":["domains","domains"],"pack":["shopping","amazon"],"level":[0,0],"entries":3552,"discards":2461},"RPW":{"value":22,"uname":"RPW","vname":"Blizzard","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/blizzard","format":"domains","pack":["gaming"],"level":[0],"entries":2,"discards":0},"AMG":{"value":23,"uname":"AMG","vname":"Daily Motion","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/dailymotion","format":"domains","pack":["streams"],"level":[0],"entries":3,"discards":0},"WTJ":{"value":24,"uname":"WTJ","vname":"Discord","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/discord","format":"domains","pack":["socialmedia"],"level":[1],"entries":5,"discards":0},"ZXU":{"value":25,"uname":"ZXU","vname":"Disney+","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/disneyplus","format":"domains","pack":["streams"],"level":[1],"entries":6,"discards":0},"FJG":{"value":26,"uname":"FJG","vname":"EBay","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/ebay","format":"domains","pack":["shopping"],"level":[0],"entries":27,"discards":0},"NYS":{"value":27,"uname":"NYS","vname":"Facebook","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/facebook","format":"domains","pack":["socialmedia","facebook"],"level":[1,0],"entries":9,"discards":0},"OKG":{"value":28,"uname":"OKG","vname":"Fortnite","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/fortnite","format":"domains","pack":["gaming"],"level":[0],"entries":1,"discards":0},"KNP":{"value":29,"uname":"KNP","vname":"Hulu","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/hulu","format":"domains","pack":["streams"],"level":[0],"entries":1,"discards":0},"FLI":{"value":30,"uname":"FLI","vname":"Imgur","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/imgur","format":"domains","pack":["vanity"],"level":[1],"entries":1,"discards":0},"RYX":{"value":31,"uname":"RYX","vname":"Instagram","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/instagram","format":"domains","pack":["socialmedia","facebook"],"level":[1,0],"entries":2,"discards":0},"CIH":{"value":32,"uname":"CIH","vname":"League of Legends","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/leagueoflegends","format":"domains","pack":["gaming"],"level":[0],"entries":2,"discards":0},"PTE":{"value":33,"uname":"PTE","vname":"Messenger","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/messenger","format":"domains","pack":["socialmedia"],"level":[1],"entries":3,"discards":0},"KEA":{"value":34,"uname":"KEA","vname":"Minecraft","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/minecraft","format":"domains","pack":["gaming"],"level":[0],"entries":3,"discards":0},"CMR":{"value":35,"uname":"CMR","vname":"Netflix","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/netflix","format":"domains","pack":["streams"],"level":[2],"entries":6,"discards":0},"DDO":{"value":36,"uname":"DDO","vname":"Pinterest","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/pinterest","format":"domains","pack":["socialmedia"],"level":[1],"entries":49,"discards":0},"VLM":{"value":37,"uname":"VLM","vname":"Reddit","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/reddit","format":"domains","pack":["socialmedia","vanity"],"level":[0,0],"entries":5,"discards":0},"JEH":{"value":38,"uname":"JEH","vname":"Roblox","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/roblox","format":"domains","pack":["gaming"],"level":[0],"entries":2,"discards":0},"XLX":{"value":39,"uname":"XLX","vname":"Skype","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/skype","format":"domains","pack":["socialmedia"],"level":[1],"entries":5,"discards":0},"OQW":{"value":40,"uname":"OQW","vname":"Snapchat","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/snapchat","format":"domains","pack":["socialmedia"],"level":[1],"entries":10,"discards":0},"FXC":{"value":41,"uname":"FXC","vname":"Spotify","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/spotify","format":"domains","pack":["shopping"],"level":[2],"entries":10,"discards":0},"HZJ":{"value":42,"uname":"HZJ","vname":"Steam","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/steam","format":"domains","pack":["gaming"],"level":[0],"entries":12,"discards":0},"SWK":{"value":43,"uname":"SWK","vname":"Telegram","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/telegram","format":"domains","pack":["socialmedia"],"level":[1],"entries":4,"discards":0},"VAM":{"value":44,"uname":"VAM","vname":"Tiktok","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/tiktok","format":["domains","domains"],"pack":["tiktok","socialmedia"],"level":[0,0],"entries":3716,"discards":3466},"AOS":{"value":45,"uname":"AOS","vname":"Tinder","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/tinder","format":"domains","pack":["socialmedia","dating"],"level":[1,0],"entries":3,"discards":0},"FAL":{"value":46,"uname":"FAL","vname":"Tumblr","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/tumblr","format":"domains","pack":["socialmedia"],"level":[1],"entries":1,"discards":0},"CZK":{"value":47,"uname":"CZK","vname":"Twitch","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/twitch","format":["domains","domains"],"pack":["gaming","streams","amazon"],"level":[1,0,2],"entries":171,"discards":160},"FZB":{"value":48,"uname":"FZB","vname":"Twitter","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/twitter","format":"domains","pack":["socialmedia"],"level":[0],"entries":7,"discards":0},"PYW":{"value":49,"uname":"PYW","vname":"Vimeo","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/vimeo","format":"domains","pack":["streams"],"level":[1],"entries":4,"discards":0},"JXA":{"value":50,"uname":"JXA","vname":"VK","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/vk","format":"domains","pack":["socialmedia"],"level":[1],"entries":8,"discards":0},"KOR":{"value":51,"uname":"KOR","vname":"WhatsApp","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/whatsapp","format":["domains","domains"],"pack":["facebook","whatsapp"],"level":[2,0],"entries":228,"discards":153},"DEP":{"value":52,"uname":"DEP","vname":"YouTube","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/youtube","format":"domains","pack":["streams","google","youtube"],"level":[1,2,0],"entries":18,"discards":0},"RFX":{"value":53,"uname":"RFX","vname":"Zoom","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/zoom","format":"domains","pack":["zoom","socialmedia"],"level":[0,2],"entries":4,"discards":0},"DTT":{"value":54,"uname":"DTT","vname":"NoCoin (hoshsadiq + ShadowWhisperer + Olbat)","group":"security","subg":"cryptojacking","url":"https://raw.githubusercontent.com/hoshsadiq/adblock-nocoin-list/master/hosts.txt","format":["hosts","domains","domains"],"pack":["crypto"],"level":[0],"entries":17598,"discards":1208},"VZP":{"value":55,"uname":"VZP","vname":"Coin Blocker (Zerodot1)","group":"security","subg":"cryptojacking","url":"https://gitlab.com/ZeroDot1/CoinBlockerLists/-/raw/master/list.txt","format":["domains","domains","domains","domains"],"pack":["crypto"],"level":[2],"entries":296600,"discards":290058},"RAF":{"value":56,"uname":"RAF","vname":"Dynamic DNS Providers","group":"security","subg":"bypass-methods","url":"https://raw.githubusercontent.com/hagezi/dns-blocklists/main/wildcard/dyndns.txt","format":"wildcard","pack":["vpn & proxies"],"level":[1],"entries":1468,"discards":0},"THG":{"value":57,"uname":"THG","vname":"Malware (UrlHaus.Abuse.Ch)","group":"security","subg":"threat-intelligence-feeds","url":"https://malware-filter.gitlab.io/malware-filter/urlhaus-filter-dnscrypt-blocked-names.txt","format":"domains","pack":["malware"],"level":[0],"entries":5238,"discards":17},"YVH":{"value":58,"uname":"YVH","vname":"Security (StevenBlack)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/StevenBlack/hosts/master/data/add.Risk/hosts","format":"hosts","pack":["malware"],"level":[0],"entries":2189,"discards":762},"XQV":{"value":59,"uname":"XQV","vname":"KADHosts (PolishFiltersTeam)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/FiltersHeroes/KADhosts/master/KADomains.txt","format":"domains","pack":["malware"],"level":[1],"entries":119298,"discards":62077},"PIB":{"value":60,"uname":"PIB","vname":"Inversion","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/elliotwutingfeng/Inversion-DNSBL-Blocklists/main/Google_hostnames.txt","format":"domains","pack":["malware"],"level":[1],"entries":508386,"discards":5},"EEN":{"value":61,"uname":"EEN","vname":"NoTrack Annoyance","group":"security","subg":"threat-intelligence-feeds","url":"https://gitlab.com/quidsup/notrack-annoyance-blocklist/-/raw/master/annoyance.list","format":"domains","pack":["spam"],"level":[0],"entries":521,"discards":0},"GDA":{"value":62,"uname":"GDA","vname":"Phishing.Army","group":"security","subg":"threat-intelligence-feeds","url":"https://phishing.army/download/phishing_army_blocklist.txt","format":"domains","pack":["scams & phishing"],"level":[2],"entries":168401,"discards":38879},"MAD":{"value":63,"uname":"MAD","vname":"Spam404","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/Spam404/lists/master/main-blacklist.txt","format":"domains","pack":["spam"],"level":[0],"entries":8143,"discards":536},"NAK":{"value":64,"uname":"NAK","vname":"NoTrack Malware","group":"security","subg":"threat-intelligence-feeds","url":"https://gitlab.com/quidsup/notrack-blocklists/-/raw/master/malware.list","format":"domains","pack":["malware"],"level":[1],"entries":1134,"discards":0},"BPZ":{"value":65,"uname":"BPZ","vname":"Badd Boyz Hosts (Mitchell Krogza)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/Ultimate-Hosts-Blacklist/BaddBoyzHosts/master/clean.list","format":"domains","pack":["malware","adult"],"level":[1,1],"entries":1048,"discards":338},"HWO":{"value":66,"uname":"HWO","vname":"Malware (Mitchell Krogza)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/mitchellkrogza/The-Big-List-of-Hacked-Malware-Web-Sites/master/hosts","format":"hosts","pack":["scams & phishing"],"level":[1],"entries":13821,"discards":48},"YUC":{"value":67,"uname":"YUC","vname":"Threats (embreaj)","group":"security","subg":"threat-intelligence-feeds","url":"https://dl.threat-list.com/2/domains.txt","format":"wildcard","pack":["malware"],"level":[2],"entries":735590,"discards":36107},"IKY":{"value":68,"uname":"IKY","vname":"Threat Intelligence Feeds (HaGeZi)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/hagezi/dns-blocklists/main/wildcard/tif.txt","format":"wildcard","pack":["spam","malware","crypto","scams & phishing"],"level":[2,2,2,2],"entries":598424,"discards":0},"LSS":{"value":69,"uname":"LSS","vname":"Malware (RPi)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/RPiList/specials/master/Blocklisten/malware","format":"domains","pack":["malware"],"level":[1],"entries":0},"NOE":{"value":70,"uname":"NOE","vname":"Child Protection (RPi)","group":"security","subg":"porn","url":"https://raw.githubusercontent.com/RPiList/specials/master/Blocklisten/child-protection","format":"domains","pack":["vanity","adult"],"level":[2,2],"entries":0},"PLR":{"value":71,"uname":"PLR","vname":"Malware (Olbat)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/olbat/ut1-blacklists/master/blacklists/malware/domains","format":["domains","domains"],"pack":["malware"],"level":[0],"entries":53817,"discards":0},"FIT":{"value":72,"uname":"FIT","vname":"Phishing (Olbat)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/olbat/ut1-blacklists/master/blacklists/phishing/domains","format":"domains","pack":["scams & phishing"],"level":[0],"entries":53680,"discards":0},"LHX":{"value":73,"uname":"LHX","vname":"Typosquatting Protection","group":"security","subg":"threat-intelligence-feeds","url":"https://github.com/cbuijs/accomplist/raw/master/typosquat/plain.black.domain.list","format":["domains","domains"],"pack":["scams & phishing"],"level":[1],"entries":150301,"discards":3553},"FOF":{"value":74,"uname":"FOF","vname":"Malware (DandelionSprout)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/DandelionSprout/adfilt/master/Alternate%20versions%20Anti-Malware%20List/AntiMalwareDomains.txt","format":"domains","pack":["malware"],"level":[1],"entries":21533,"discards":12},"DYA":{"value":75,"uname":"DYA","vname":"Free Website Hosting","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/hagezi/dns-blocklists/main/wildcard/hoster.txt","format":"wildcard","pack":["scams & phishing"],"level":[2],"entries":1981,"discards":0},"JAN":{"value":76,"uname":"JAN","vname":"Blackbook (Miroslav Stampar)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/stamparm/blackbook/master/blackbook.txt","format":"domains","pack":["malware"],"level":[0],"entries":18034,"discards":77},"FHQ":{"value":77,"uname":"FHQ","vname":"Bad Sites (phishing.mailscanner.info + MalwareFilter)","group":"security","subg":"threat-intelligence-feeds","url":"http://phishing.mailscanner.info/phishing.bad.sites.conf","format":["domains","domains"],"pack":["scams & phishing"],"level":[2],"entries":57537,"discards":30140},"CMC":{"value":78,"uname":"CMC","vname":"Scams and Phishing (infinitytec + TBLP)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/infinitytec/blocklists/master/scams-and-phishing.txt","format":["domains","domains"],"pack":["scams & phishing"],"level":[1],"entries":19186,"discards":14741},"RKG":{"value":79,"uname":"RKG","vname":"Red Flag Domains","group":"security","subg":"threat-intelligence-feeds","url":"https://dl.red.flag.domains/red.flag.domains.txt","format":"domains","pack":["scams & phishing","spam","malware"],"level":[0,0,0],"entries":20905,"discards":0},"XMK":{"value":80,"uname":"XMK","vname":"Toxic (StopForumSpam + PupFilter)","group":"security","subg":"threat-intelligence-feeds","url":"https://www.stopforumspam.com/downloads/toxic_domains_whole.txt","format":["domains","domains"],"pack":["spam"],"level":[2],"entries":48185,"discards":737},"GAX":{"value":81,"uname":"GAX","vname":"Mailtrail Malware (Miroslav Stampar)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/stamparm/aux/master/maltrail-malware-domains.txt","format":"domains","pack":["malware"],"level":[1],"entries":354308,"discards":79555},"RFI":{"value":82,"uname":"RFI","vname":"Malware Rescure (rescure.me)","group":"security","subg":"threat-intelligence-feeds","url":"https://rescure.me/rescure_domain_blacklist.txt","format":"domains","pack":["malware"],"level":[2],"entries":500,"discards":0},"AZR":{"value":83,"uname":"AZR","vname":"NSO + Others (Amnesty)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/AmnestyTech/investigations/master/2021-07-18_nso/domains.txt","format":["domains","domains","domains","hosts","domains","domains","domains"],"pack":["spyware","malware"],"level":[0,0],"entries":2218,"discards":7},"CEN":{"value":84,"uname":"CEN","vname":"Malicious domains (cbuijs)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/cbuijs/accomplist/master/malicious-dom/plain.black.domain.list","format":"domains","pack":["malware"],"level":[2],"entries":2008582,"discards":914108},"SPR":{"value":85,"uname":"SPR","vname":"Global Anti-Scam (Inversion)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/elliotwutingfeng/GlobalAntiScamOrg-blocklist/main/global-anti-scam-org-scam-urls-pihole.txt","format":"domains","pack":["scams & phishing"],"level":[1],"entries":42417,"discards":229},"MZT":{"value":86,"uname":"MZT","vname":"Threats and IoCs","group":"security","subg":"threat-intelligence-feeds","url":"https://www.botvrij.eu/data/ioclist.domain.raw","format":["domains","domains","hosts","hosts","domains","domains","hosts","domains","domains","domains","domains","domains","domains","domains","domains"],"pack":["scams & phishing","vanity"],"level":[1,2],"entries":38558,"discards":2026},"NHM":{"value":87,"uname":"NHM","vname":"Malicious domains (Sophos Labs)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/sophoslabs/covid-iocs/master/malicious_domains.txt","format":"domains","pack":["scams & phishing"],"level":[0],"entries":1959,"discards":753},"GLV":{"value":88,"uname":"GLV","vname":"Scamware","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/sophoslabs/covid-iocs/master/malware_domains.txt","format":["domains","domains"],"pack":["scams & phishing"],"level":[2],"entries":12637,"discards":15},"NUY":{"value":89,"uname":"NUY","vname":"Covid List (rescure and kriskintel)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/cbuijs/accomplist/master/covid/plain.black.domain.list","format":"domains","pack":["scams & phishing"],"level":[2],"entries":2207,"discards":473},"EDM":{"value":90,"uname":"EDM","vname":"Scamware (RPi)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/RPiList/specials/master/Blocklisten/Corona-Blocklist","format":["domains","domains"],"pack":["scams & phishing"],"level":[2],"entries":0},"ZFC":{"value":91,"uname":"ZFC","vname":"hole.cert.pl","group":"security","subg":"threat-intelligence-feeds","url":"https://hole.cert.pl/domains/domains.txt","format":"domains","pack":["malware"],"level":[1],"entries":172015,"discards":40184},"DOP":{"value":92,"uname":"DOP","vname":"Threats (osint.digitalside.it)","group":"security","subg":"threat-intelligence-feeds","url":"https://osint.digitalside.it/Threat-Intel/lists/latestdomains.txt","format":"domains","pack":["malware"],"level":[1],"entries":58,"discards":0},"XGC":{"value":93,"uname":"XGC","vname":"Bloat (ShadowWhisperer)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/ShadowWhisperer/BlockLists/master/Lists/Bloat","format":"domains","pack":["extremeprivacy"],"level":[2],"entries":885,"discards":64},"OHE":{"value":94,"uname":"OHE","vname":"1Hosts (Lite)","group":"privacy","subg":"rethinkdns-recommended","url":"https://raw.githubusercontent.com/badmojr/1Hosts/master/Lite/domains.wildcards","format":"domains","pack":["recommended","liteprivacy"],"level":[0,0],"entries":81907,"discards":0},"MYS":{"value":95,"uname":"MYS","vname":"1Hosts (mini)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/badmojr/1Hosts/master/mini/domains.wildcards","format":"domains","pack":["liteprivacy"],"level":[0],"entries":84127,"discards":0},"IAJ":{"value":96,"uname":"IAJ","vname":"1Hosts (Pro)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/badmojr/1Hosts/master/Pro/domains.wildcards","format":"domains","pack":["aggressiveprivacy"],"level":[1],"entries":159039,"discards":0},"EAQ":{"value":97,"uname":"EAQ","vname":"iVoid (intr0)","group":"security","subg":"threat-intelligence-feeds","url":"https://gitlab.com/intr0/iVOID.GitLab.io/raw/master/iVOID.hosts","format":"hosts","pack":["scams & phishing"],"level":[1],"entries":27069,"discards":6400},"AOC":{"value":98,"uname":"AOC","vname":"ABPindo","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/ABPindo/indonesianadblockrules/master/subscriptions/domain.txt","format":"domains","pack":[],"level":[],"entries":287,"discards":0},"XAT":{"value":99,"uname":"XAT","vname":"ABPVN List","group":"privacy","subg":"","url":"https://abpvn.com/android/abpvn.txt","format":"hosts","pack":["aggressiveprivacy"],"level":[1],"entries":20559,"discards":8992},"OSE":{"value":100,"uname":"OSE","vname":"Ad-Wars","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/jdlingyu/ad-wars/master/hosts","format":"hosts","pack":["aggressiveprivacy"],"level":[1],"entries":1646,"discards":237},"IBB":{"value":101,"uname":"IBB","vname":"AdGuard Tracking and Spyware","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/r-a-y/mobile-hosts/master/AdguardMobileSpyware.txt","format":["hosts","hosts"],"pack":["aggressiveprivacy"],"level":[1],"entries":1558,"discards":20},"EGX":{"value":102,"uname":"EGX","vname":"Add.2o7Net","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/FadeMind/hosts.extras/master/add.2o7Net/hosts","format":"hosts","pack":[],"level":[],"entries":2030,"discards":1447},"HZD":{"value":103,"uname":"HZD","vname":"AdGuard SDNS Filter","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/r-a-y/mobile-hosts/master/AdguardDNS.txt","format":"hosts","pack":["liteprivacy"],"level":[0],"entries":61036,"discards":6},"FLW":{"value":104,"uname":"FLW","vname":"Anti Ad","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/privacy-protection-tools/anti-AD/master/anti-ad-domains.txt","format":"domains","pack":["aggressiveprivacy"],"level":[1],"entries":94271,"discards":6222},"ULZ":{"value":105,"uname":"ULZ","vname":"Anti Pop Ads 2 (Ador Khan)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/AdroitAdorKhan/antipopads-re/master/formats/domains.txt","format":"domains","pack":[],"level":[],"entries":120758,"discards":16432},"OFY":{"value":106,"uname":"OFY","vname":"Anudeep's Blacklist","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/anudeepND/blacklist/master/adservers.txt","format":"hosts","pack":["liteprivacy"],"level":[0],"entries":42363,"discards":19455},"MLE":{"value":107,"uname":"MLE","vname":"Multi Pro (HaGeZi)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/hagezi/dns-blocklists/main/wildcard/pro.txt","format":"wildcard","pack":["aggressiveprivacy"],"level":[1],"entries":247750,"discards":0},"YER":{"value":108,"uname":"YER","vname":"Multi Pro++ (HaGeZi)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/hagezi/dns-blocklists/main/wildcard/pro.plus.txt","format":"wildcard","pack":["extremeprivacy"],"level":[2],"entries":302692,"discards":0},"DMC":{"value":109,"uname":"DMC","vname":"Bulgarian list (Adblock)","group":"privacy","subg":"","url":"https://stanev.org/abp/adblock_bg.txt","format":"abp","pack":["extremeprivacy"],"level":[2],"entries":6,"discards":0},"IJO":{"value":110,"uname":"IJO","vname":"OISD (small)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/sjhgvr/oisd/main/domainswild_small.txt","format":"wildcard","pack":["liteprivacy"],"level":[0],"entries":44408,"discards":0},"OWW":{"value":111,"uname":"OWW","vname":"Polish filters (Certyficate.IT)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/MajkiIT/polish-ads-filter/master/polish-pihole-filters/hostfile.txt","format":"hosts","pack":[],"level":[],"entries":176,"discards":0},"EMY":{"value":112,"uname":"EMY","vname":"Ads (Disconnect)","group":"privacy","subg":"","url":"https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt","format":"domains","pack":["liteprivacy"],"level":[0],"entries":2701,"discards":35},"XKM":{"value":113,"uname":"XKM","vname":"Malvertising (Disconnect)","group":"privacy","subg":"threat-intelligence-feeds","url":"https://s3.amazonaws.com/lists.disconnect.me/simple_malvertising.txt","format":"domains","pack":["malware"],"level":[0],"entries":2736,"discards":37},"CQT":{"value":114,"uname":"CQT","vname":"Tracking (Disconnect)","group":"privacy","subg":"","url":"https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt","format":"domains","pack":["spyware"],"level":[0],"entries":34,"discards":0},"ANW":{"value":115,"uname":"ANW","vname":"EasyList China","group":"privacy","subg":"","url":"https://easylist-downloads.adblockplus.org/easylistchina.txt","format":"abp","pack":["aggressiveprivacy"],"level":[1],"entries":5863,"discards":3},"DGE":{"value":116,"uname":"DGE","vname":"EasyList Czech and Slovak","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/tomasko126/easylistczechandslovak/master/filters.txt","format":"abp","pack":["extremeprivacy"],"level":[2],"entries":94,"discards":0},"BBS":{"value":117,"uname":"BBS","vname":"EasyList Dutch","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/cbuijs/accomplist/master/dutch/optimized.black.domain.list","format":"domains","pack":["extremeprivacy"],"level":[2],"entries":56,"discards":0},"OKW":{"value":118,"uname":"OKW","vname":"EasyList Germany","group":"privacy","subg":"","url":"https://easylist-downloads.adblockplus.org/easylistgermany.txt","format":"abp","pack":["extremeprivacy"],"level":[2],"entries":393,"discards":0},"ONV":{"value":119,"uname":"ONV","vname":"EasyList Hebrew","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/easylist/EasyListHebrew/master/adguard_hosts.txt","format":"domains","pack":["extremeprivacy"],"level":[2],"entries":352,"discards":0},"CDE":{"value":120,"uname":"CDE","vname":"Italy Lists (EasyList + Marco Acorte)","group":"privacy","subg":"threat-intelligence-feeds","url":"https://easylist-downloads.adblockplus.org/easylistitaly.txt","format":["abp","domains"],"pack":["extremeprivacy","spam"],"level":[2,2],"entries":1243,"discards":4},"PAL":{"value":121,"uname":"PAL","vname":"EasyList Lithuania","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/EasyList-Lithuania/easylist_lithuania/master/easylistlithuania.txt","format":"abp","pack":["extremeprivacy"],"level":[2],"entries":31,"discards":0},"DBP":{"value":122,"uname":"DBP","vname":"EasyList Basic","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/cbuijs/accomplist/master/easylist/optimized.black.domain.list","format":"domains","pack":["liteprivacy"],"level":[0],"entries":88246,"discards":0},"MHP":{"value":123,"uname":"MHP","vname":"EasyPrivacy","group":"privacy","subg":"","url":"https://easylist-downloads.adblockplus.org/easyprivacy.txt","format":"abp","pack":["aggressiveprivacy"],"level":[1],"entries":42942,"discards":121},"EPR":{"value":124,"uname":"EPR","vname":"Normal (HaGeZi)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/hagezi/dns-blocklists/main/wildcard/multi.txt","format":"wildcard","pack":["liteprivacy"],"level":[0],"entries":141156,"discards":0},"OUU":{"value":125,"uname":"OUU","vname":"Light (HaGeZi)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/hagezi/dns-blocklists/main/wildcard/light.txt","format":"wildcard","pack":["liteprivacy"],"level":[0],"entries":67792,"discards":0},"YXS":{"value":126,"uname":"YXS","vname":"Blocklist (hBlock)","group":"privacy","subg":"","url":"https://hblock.molinero.dev/hosts_domains.txt","format":"domains","pack":["aggressiveprivacy"],"level":[1],"entries":442509,"discards":155043},"UQK":{"value":127,"uname":"UQK","vname":"Ad Set Hosts (rentianyu)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/rentianyu/Ad-set-hosts/master/hosts","format":["hosts","hosts"],"pack":["aggressiveprivacy"],"level":[1],"entries":309617,"discards":98847},"GVI":{"value":128,"uname":"GVI","vname":"Blocklist (ph00lt0)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/ph00lt0/blocklists/master/pihole-blocklist.txt","format":"hosts","pack":["extremeprivacy"],"level":[2],"entries":19040,"discards":3516},"TXJ":{"value":129,"uname":"TXJ","vname":"Ultimate (HaGeZi)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/hagezi/dns-blocklists/main/wildcard/ultimate.txt","format":"wildcard","pack":["extremeprivacy"],"level":[2],"entries":360505,"discards":0},"DPY":{"value":130,"uname":"DPY","vname":"The Quantum Blocklist (AI)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/cbuijs/accomplist/master/quantum/plain.black.domain.list","format":"domains","pack":["ignore"],"level":[2],"entries":0},"DUC":{"value":131,"uname":"DUC","vname":"Fanboy's Annoyance List","group":"privacy","subg":"threat-intelligence-feeds","url":"https://secure.fanboy.co.nz/fanboy-annoyance.txt","format":"abp","pack":["spam"],"level":[2],"entries":857,"discards":4},"WYE":{"value":132,"uname":"WYE","vname":"Fanboy's Enhanced Tracking List","group":"privacy","subg":"","url":"https://fanboy.co.nz/enhancedstats.txt","format":"abp","pack":[],"level":[],"entries":0},"CGF":{"value":133,"uname":"CGF","vname":"Ads (The Block List Project)","group":"privacy","subg":"","url":"https://blocklistproject.github.io/Lists/alt-version/ads-nl.txt","format":"domains","pack":["extremeprivacy"],"level":[2],"entries":154555,"discards":84790},"JRV":{"value":134,"uname":"JRV","vname":"Frellwit's Swedish Hosts File","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/lassekongo83/Frellwits-filter-lists/master/Frellwits-Swedish-Hosts-File.txt","format":"hosts","pack":[],"level":[],"entries":1065,"discards":70},"EOK":{"value":135,"uname":"EOK","vname":"GoodbyeAds Hosts (jerryn70)","group":"privacy","subg":"rethinkdns-recommended","url":"https://raw.githubusercontent.com/jerryn70/GoodbyeAds/master/Hosts/GoodbyeAds.txt","format":"hosts","pack":["aggressiveprivacy","recommended"],"level":[1,1],"entries":323182,"discards":113422},"HQL":{"value":136,"uname":"HQL","vname":"HostsVN","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/bigdargon/hostsVN/master/option/wildcard.txt","format":"wildcard","pack":["liteprivacy"],"level":[0],"entries":10428,"discards":65},"NNH":{"value":137,"uname":"NNH","vname":"Hu Filter","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/hufilter/hufilter/master/hufilter-dns.txt","format":"domains","pack":[],"level":[],"entries":65,"discards":0},"KRM":{"value":138,"uname":"KRM","vname":"Latvian List","group":"privacy","subg":"","url":"https://notabug.org/latvian-list/adblock-latvian/raw/master/lists/latvian-list.txt","format":"abp","pack":[],"level":[],"entries":53,"discards":0},"QKN":{"value":139,"uname":"QKN","vname":"Ads & Tracking (Lighswitch05)","group":"privacy","subg":"","url":"https://www.github.developerdan.com/hosts/lists/ads-and-tracking-extended.txt","format":["hosts","domains"],"pack":["aggressiveprivacy"],"level":[1],"entries":429286,"discards":416196},"MPR":{"value":140,"uname":"MPR","vname":"Tracking Aggressive (Lightswitch05)","group":"privacy","subg":"","url":"https://www.github.developerdan.com/hosts/lists/tracking-aggressive-extended.txt","format":"hosts","pack":["extremeprivacy"],"level":[2],"entries":171820,"discards":171685},"EOO":{"value":141,"uname":"EOO","vname":"Liste AR","group":"privacy","subg":"","url":"https://easylist-downloads.adblockplus.org/Liste_AR.txt","format":"abp","pack":[],"level":[],"entries":80,"discards":0},"MDE":{"value":142,"uname":"MDE","vname":"Liste FR","group":"privacy","subg":"","url":"https://easylist-downloads.adblockplus.org/liste_fr.txt","format":"abp","pack":[],"level":[],"entries":10313,"discards":27},"WWI":{"value":143,"uname":"WWI","vname":"Ad Blocklist Japan (logroid)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/logroid/adaway-hosts/master/hosts.txt","format":"hosts","pack":[],"level":[],"entries":14984,"discards":6282},"TTI":{"value":144,"uname":"TTI","vname":"Turkey Adlist (bkrucarci)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/bkrucarci/turk-adlist/master/hosts","format":"hosts","pack":["extremeprivacy"],"level":[2],"entries":1217,"discards":87},"GFJ":{"value":145,"uname":"GFJ","vname":"StevenBlack","group":"privacy","subg":"rethinkdns-recommended","url":"https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts","format":"hosts","pack":["aggressiveprivacy","recommended"],"level":[1,1],"entries":162084,"discards":78577},"WOD":{"value":146,"uname":"WOD","vname":"VeleSila (yhosts)","group":"privacy","subg":"rethinkdns-recommended","url":"https://raw.githubusercontent.com/VeleSila/yhosts/master/hosts","format":"hosts","pack":["recommended","liteprivacy"],"level":[0,0],"entries":6422,"discards":666},"YJR":{"value":147,"uname":"YJR","vname":"Tiuxo (ads)","group":"privacy","subg":"rethinkdns-recommended","url":"https://raw.githubusercontent.com/tiuxo/hosts/master/ads","format":"hosts","pack":["recommended","liteprivacy"],"level":[0,0],"entries":1730,"discards":384},"WIB":{"value":148,"uname":"WIB","vname":"No Facebook","group":"privacy","subg":"services","url":"https://raw.githubusercontent.com/jmdugan/blocklists/master/corporations/facebook/all","format":"hosts","pack":["facebook"],"level":[0],"entries":2098,"discards":1671},"NUI":{"value":149,"uname":"NUI","vname":"No Google","group":"privacy","subg":"services","url":"https://raw.githubusercontent.com/nickspaargaren/no-google/master/wildcards-domains","format":["domains","domains"],"pack":["google"],"level":[0],"entries":616,"discards":280},"XIO":{"value":150,"uname":"XIO","vname":"NoTrack Blocklist","group":"privacy","subg":"","url":"https://gitlab.com/quidsup/notrack-blocklists/-/raw/master/trackers.list","format":"domains","pack":["aggressiveprivacy","spyware"],"level":[1,1],"entries":16830,"discards":16},"OBW":{"value":151,"uname":"OBW","vname":"Blocklists (NoTracking)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/notracking/hosts-blocklists/master/hostnames.txt","format":"hosts","pack":["aggressiveprivacy","spyware"],"level":[1,1],"entries":250170,"discards":105438},"YBO":{"value":152,"uname":"YBO","vname":"Smart TV Blocklist (Perflyst)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/Perflyst/PiHoleBlocklist/master/SmartTV.txt","format":"domains","pack":["extremeprivacy","smart-tv"],"level":[2,0],"entries":241,"discards":45},"TTW":{"value":153,"uname":"TTW","vname":"Peter Lowe","group":"privacy","subg":"","url":"https://pgl.yoyo.org/as/serverlist.php?hostformat=domains&mimetype=plaintext","format":"domains","pack":["liteprivacy"],"level":[0],"entries":3787,"discards":4},"NML":{"value":154,"uname":"NML","vname":"RU AdList","group":"privacy","subg":"","url":"https://easylist-downloads.adblockplus.org/advblock.txt","format":"abp","pack":["extremeprivacy"],"level":[2],"entries":8891,"discards":15},"MIN":{"value":155,"uname":"MIN","vname":"Combined Privacy Block Lists: Light (bongochong)","group":"privacy","subg":"rethinkdns-recommended","url":"https://raw.githubusercontent.com/bongochong/CombinedPrivacyBlockLists/master/MiniLists/NoFormatting/mini-cpbl-wildcard-blacklist.txt","format":"wildcard","pack":["liteprivacy","recommended"],"level":[0,0],"entries":106641,"discards":0},"IFD":{"value":156,"uname":"IFD","vname":"AdRules China (Cats Team)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/Cats-Team/AdRules/main/ad-domains.txt","format":"domains","pack":["extremeprivacy"],"level":[2],"entries":0},"AMI":{"value":157,"uname":"AMI","vname":"someonewhocares.org (Dan Pollock)","group":"privacy","subg":"","url":"https://someonewhocares.org/hosts/zero/hosts","format":"hosts","pack":["liteprivacy"],"level":[0],"entries":11693,"discards":2249},"TZF":{"value":158,"uname":"TZF","vname":"Unified Blocklist (vdbhb59)","group":"privacy","subg":"","url":"https://hosts.flossboxin.org.in/files/hosts","format":"hosts","pack":["aggressiveprivacy"],"level":[1],"entries":442655,"discards":155173},"VKE":{"value":159,"uname":"VKE","vname":"Personal Blocklist (WaLLy3K)","group":"privacy","subg":"","url":"https://v.firebog.net/hosts/static/w3kbl.txt","format":"domains","pack":[],"level":[],"entries":351,"discards":21},"PWQ":{"value":160,"uname":"PWQ","vname":"Windows Telemetry","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/crazy-max/WindowsSpyBlocker/master/data/dnscrypt/spy.txt","format":["wildcard","wildcard","domains"],"pack":["windows"],"level":[0],"entries":73,"discards":27},"KUA":{"value":161,"uname":"KUA","vname":"YousList","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/yous/YousList/master/hosts.txt","format":"hosts","pack":[],"level":[],"entries":609,"discards":12},"FHW":{"value":162,"uname":"FHW","vname":"Alexa (Amazon)","group":"privacy","subg":"native","url":"https://raw.githubusercontent.com/nextdns/native-tracking-domains/main/domains/alexa","format":"domains","pack":["amazon"],"level":[1],"entries":3,"discards":0},"AGZ":{"value":163,"uname":"AGZ","vname":"Apple","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/hagezi/dns-blocklists/main/wildcard/native.apple.txt","format":["wildcard","domains"],"pack":["apple"],"level":[1],"entries":52,"discards":11},"IVN":{"value":164,"uname":"IVN","vname":"Huawei","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/nextdns/native-tracking-domains/main/domains/huawei","format":["domains","wildcard"],"pack":[],"level":[],"entries":90,"discards":37},"FIB":{"value":165,"uname":"FIB","vname":"Roku","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/nextdns/native-tracking-domains/main/domains/roku","format":"domains","pack":["streams"],"level":[1],"entries":1,"discards":0},"FGF":{"value":166,"uname":"FGF","vname":"Samsung","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/nextdns/native-tracking-domains/main/domains/samsung","format":"domains","pack":[],"level":[],"entries":4,"discards":0},"FLL":{"value":167,"uname":"FLL","vname":"Sonos","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/nextdns/native-tracking-domains/main/domains/sonos","format":"domains","pack":[],"level":[],"entries":2,"discards":0},"IVO":{"value":168,"uname":"IVO","vname":"Windows","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/nextdns/native-tracking-domains/main/domains/windows","format":["domains","wildcard"],"pack":["windows"],"level":[1],"entries":76,"discards":5},"ALQ":{"value":169,"uname":"ALQ","vname":"Xiaomi","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/nextdns/native-tracking-domains/main/domains/xiaomi","format":["domains","domains"],"pack":[],"level":[],"entries":9,"discards":0},"FHM":{"value":170,"uname":"FHM","vname":"OISD (big)","group":"privacy","subg":"rethinkdns-recommended","url":"https://raw.githubusercontent.com/sjhgvr/oisd/main/domainswild_big.txt","format":"wildcard","pack":["recommended","liteprivacy"],"level":[0,0],"entries":206418,"discards":0}} \ No newline at end of file +{"171":{"value":171,"uname":"171","vname":"1Hosts (Xtra)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/badmojr/1Hosts/master/Xtra/domains.wildcards","format":"domains","pack":["extremeprivacy"],"level":[2],"entries":240972,"discards":0},"172":{"value":172,"uname":"172","vname":"Spotify Ads (GoodbyeAds)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/jerryn70/GoodbyeAds/master/Extension/GoodbyeAds-Spotify-AdBlock.txt","format":"hosts","pack":[],"level":[],"entries":3780,"discards":1503},"173":{"value":173,"uname":"173","vname":"AVG + Avast (ftprivacy)","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/ftpmorph/ftprivacy/master/blocklists/avg-avast-data-mining-full-block.txt","format":"domains","pack":["vpn & proxies"],"level":[2],"entries":349,"discards":342},"174":{"value":174,"uname":"174","vname":"Hola VPN (ftprivacy)","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/ftpmorph/ftprivacy/master/blocklists/hola-luminati-full-block.txt","format":"domains","pack":["vpn & proxies"],"level":[2],"entries":117,"discards":115},"175":{"value":175,"uname":"175","vname":"Combined Privacy Block Lists: Full (bongochong)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/bongochong/CombinedPrivacyBlockLists/master/NoFormatting/cpbl-wildcard-blacklist.txt","format":"wildcard","pack":["aggressiveprivacy"],"level":[1],"entries":148547,"discards":0},"176":{"value":176,"uname":"176","vname":"Torrent (The Block List Project)","group":"parentalcontrol","subg":"piracy","url":"https://blocklistproject.github.io/Lists/alt-version/torrent-nl.txt","format":"domains","pack":["torrents","piracy"],"level":[1,1],"entries":2623,"discards":279},"177":{"value":177,"uname":"177","vname":"Drugs (The Block List Project)","group":"parentalcontrol","subg":"threat-intelligence-feeds","url":"https://blocklistproject.github.io/Lists/alt-version/drugs-nl.txt","format":"domains","pack":["drugs"],"level":[2],"entries":26031,"discards":7014},"178":{"value":178,"uname":"178","vname":"Ransomware (The Block List Project)","group":"security","subg":"threat-intelligence-feeds","url":"https://blocklistproject.github.io/Lists/alt-version/ransomware-nl.txt","format":"domains","pack":["scams & phishing"],"level":[2],"entries":1904,"discards":1},"179":{"value":179,"uname":"179","vname":"NSFL (ShadowWhisperer)","group":"parentalcontrol","subg":"porn","url":"https://raw.githubusercontent.com/ShadowWhisperer/BlockLists/master/Lists/Shock","format":"domains","pack":["adult"],"level":[1],"entries":98,"discards":0},"180":{"value":180,"uname":"180","vname":"Cryptojacking (The Block List Project)","group":"security","subg":"cryptojacking","url":"https://blocklistproject.github.io/Lists/alt-version/crypto-nl.txt","format":"domains","pack":["crypto"],"level":[2],"entries":23761,"discards":13359},"181":{"value":181,"uname":"181","vname":"WhatsApp","group":"","subg":"","url":"","format":"domains","pack":["dead"],"level":[],"entries":0},"182":{"value":182,"uname":"182","vname":"Vaping (The Block List Project)","group":"parentalcontrol","subg":"threat-intelligence-feeds","url":"https://blocklistproject.github.io/Lists/alt-version/vaping-nl.txt","format":["domains","domains"],"pack":["drugs"],"level":[1],"entries":414,"discards":102},"183":{"value":183,"uname":"183","vname":"Piracy (The Block List Project)","group":"parentalcontrol","subg":"piracy","url":"https://blocklistproject.github.io/Lists/alt-version/piracy-nl.txt","format":"domains","pack":["piracy","file-hosts"],"level":[2,2],"entries":2153,"discards":988},"184":{"value":184,"uname":"184","vname":"Facebook (The Block List Project)","group":"parentalcontrol","subg":"services","url":"https://blocklistproject.github.io/Lists/alt-version/facebook-nl.txt","format":"domains","pack":["facebook","socialmedia"],"level":[1,2],"entries":22459,"discards":22379},"185":{"value":185,"uname":"185","vname":"Gambling (The Block List Project)","group":"parentalcontrol","subg":"gambling","url":"https://blocklistproject.github.io/Lists/alt-version/gambling-nl.txt","format":"domains","pack":["gambling"],"level":[2],"entries":2499,"discards":1121},"186":{"value":186,"uname":"186","vname":"OISD NSFW (Adult)","group":"parentalcontrol","subg":"porn","url":"https://raw.githubusercontent.com/sjhgvr/oisd/main/domainswild_nsfw.txt","format":"wildcard","pack":["adult"],"level":[1],"entries":399846,"discards":1210},"187":{"value":187,"uname":"187","vname":"Blocklists (cbuijs)","group":"privacy","subg":"","url":"https://github.com/cbuijs/accomplist/raw/master/deugniets/plain.black.domain.list","format":"domains","pack":["ignore"],"level":[2],"entries":0},"188":{"value":188,"uname":"188","vname":"Yet another small uBlock filter list","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/mtxadmin/ublock/master/hosts.txt","format":"hosts","pack":["extremeprivacy"],"level":[2],"entries":1039901,"discards":980427},"189":{"value":189,"uname":"189","vname":"URL Shorteners (PeterDaveHello + ShadowWhisperer)","group":"security","subg":"tracking-domains","url":"https://raw.githubusercontent.com/PeterDaveHello/url-shorteners/master/list","format":["domains","domains"],"pack":["url-shorteners"],"level":[1],"entries":3841,"discards":141},"190":{"value":190,"uname":"190","vname":"Persian Blocker","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/MasterKia/PersianBlocker/main/PersianBlockerHosts.txt","format":"domains","pack":["extremeprivacy"],"level":[2],"entries":265,"discards":6},"191":{"value":191,"uname":"191","vname":"1Hosts (kidSaf)","group":"parentalcontrol","subg":"porn","url":"https://raw.githubusercontent.com/badmojr/addons_1Hosts/main/kidSaf/domains.wildcards","format":"domains","pack":["adult"],"level":[2],"entries":874217,"discards":0},"192":{"value":192,"uname":"192","vname":"Adult (The Block List Project)","group":"parentalcontrol","subg":"porn","url":"https://blocklistproject.github.io/Lists/alt-version/porn-nl.txt","format":"domains","pack":["adult"],"level":[2],"entries":500280,"discards":1124},"193":{"value":193,"uname":"193","vname":"Tracking (The Block List Project)","group":"privacy","subg":"","url":"https://blocklistproject.github.io/Lists/alt-version/tracking-nl.txt","format":["domains","domains"],"pack":["spyware"],"level":[1],"entries":87451,"discards":1363},"194":{"value":194,"uname":"194","vname":"Microsoft","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/ShadowWhisperer/BlockLists/master/Lists/Microsoft","format":"domains","pack":["microsoft"],"level":[2],"entries":676,"discards":114},"195":{"value":195,"uname":"195","vname":"Bad Top-Level Domains (cbuijs)","group":"security","subg":"threat-intelligence-feeds","url":"https://github.com/cbuijs/accomplist/raw/master/tlds/plain.black.domain.list","format":"domains","pack":["spam"],"level":[2],"entries":1291,"discards":0},"196":{"value":196,"uname":"196","vname":"Tiny China Block List Replenish","group":"privacy","subg":"gambling","url":"https://raw.githubusercontent.com/tim-hub/tiny-cn-blocklist-replenish/master/common.txt","format":["domains","domains"],"pack":["liteprivacy","gambling"],"level":[0,1],"entries":78,"discards":2},"MTF":{"value":0,"uname":"MTF","vname":"Prevent bypass","group":"parentalcontrol","subg":"bypass-methods","url":"https://raw.githubusercontent.com/hagezi/dns-blocklists/main/wildcard/doh-vpn-proxy-bypass.txt","format":["wildcard","domains"],"pack":["vpn & proxies"],"level":[1],"entries":6111,"discards":1063},"KBI":{"value":1,"uname":"KBI","vname":"Safe Search Only","group":"parentalcontrol","subg":"safesearch","url":"https://raw.githubusercontent.com/nextdns/no-safesearch/main/domains","format":"domains","pack":[],"level":[],"entries":175,"discards":0},"YAC":{"value":2,"uname":"YAC","vname":"Dating (Olbat + ShadowWhisperer)","group":"parentalcontrol","subg":"dating","url":"https://raw.githubusercontent.com/olbat/ut1-blacklists/master/blacklists/dating/domains","format":["domains","domains"],"pack":["dating"],"level":[0],"entries":4881,"discards":607},"HBP":{"value":3,"uname":"HBP","vname":"Gambling (Olbat + hostsVN)","group":"parentalcontrol","subg":"gambling","url":"https://raw.githubusercontent.com/olbat/ut1-blacklists/master/blacklists/gambling/domains","format":["domains","hosts"],"pack":["gambling"],"level":[0],"entries":153133,"discards":2710},"NIM":{"value":4,"uname":"NIM","vname":"Gambling (Sinfonietta)","group":"parentalcontrol","subg":"gambling","url":"https://raw.githubusercontent.com/Sinfonietta/hostfiles/master/gambling-hosts","format":"hosts","pack":["gambling"],"level":[2],"entries":2619,"discards":1173},"YWG":{"value":5,"uname":"YWG","vname":"Torrents (DHT nodes)","group":"parentalcontrol","subg":"piracy","url":"https://raw.githubusercontent.com/nextdns/piracy-blocklists/master/dht-bootstrap-nodes","format":"domains","pack":["torrents","file-hosts","piracy"],"level":[0,1,0],"entries":5,"discards":0},"SMQ":{"value":6,"uname":"SMQ","vname":"File hosting","group":"parentalcontrol","subg":"piracy","url":"https://raw.githubusercontent.com/nextdns/piracy-blocklists/master/file-hosting","format":["domains","domains","domains"],"pack":["file-hosts","piracy"],"level":[0,2],"entries":193,"discards":8},"AQX":{"value":7,"uname":"AQX","vname":"Proxies","group":"parentalcontrol","subg":"bypass-methods","url":"https://raw.githubusercontent.com/nextdns/piracy-blocklists/master/proxies","format":["domains","domains"],"pack":["vpn & proxies","piracy"],"level":[0,2],"entries":202307,"discards":93619},"BTG":{"value":8,"uname":"BTG","vname":"Streaming Audio","group":"parentalcontrol","subg":"piracy","url":"https://raw.githubusercontent.com/nextdns/piracy-blocklists/master/streaming-audio","format":"domains","pack":["streams","piracy"],"level":[0,2],"entries":65,"discards":0},"GUN":{"value":9,"uname":"GUN","vname":"Streaming Video","group":"parentalcontrol","subg":"piracy","url":"https://raw.githubusercontent.com/nextdns/piracy-blocklists/master/streaming-video","format":["domains","domains","domains"],"pack":["streams","piracy"],"level":[0,2],"entries":1099,"discards":15},"KSH":{"value":10,"uname":"KSH","vname":"Torrent Clients","group":"parentalcontrol","subg":"piracy","url":"https://raw.githubusercontent.com/nextdns/piracy-blocklists/master/torrent-clients","format":"domains","pack":["torrents","piracy"],"level":[0,1],"entries":31,"discards":0},"WAS":{"value":11,"uname":"WAS","vname":"Torrent Trackers","group":"parentalcontrol","subg":"piracy","url":"https://raw.githubusercontent.com/nextdns/piracy-blocklists/master/torrent-trackers","format":"domains","pack":["torrents","piracy"],"level":[0,1],"entries":351,"discards":14},"AZY":{"value":12,"uname":"AZY","vname":"Torrent Websites","group":"parentalcontrol","subg":"piracy","url":"https://raw.githubusercontent.com/nextdns/piracy-blocklists/master/torrent-websites","format":"domains","pack":["torrents","piracy"],"level":[0,2],"entries":1266,"discards":12},"GWB":{"value":13,"uname":"GWB","vname":"Usenet","group":"parentalcontrol","subg":"piracy","url":"https://raw.githubusercontent.com/nextdns/piracy-blocklists/master/usenet","format":"domains","pack":["file-hosts","piracy"],"level":[2,1],"entries":12,"discards":0},"YMG":{"value":14,"uname":"YMG","vname":"Warez","group":"parentalcontrol","subg":"piracy","url":"https://raw.githubusercontent.com/nextdns/piracy-blocklists/master/warez","format":"domains","pack":["file-hosts","piracy"],"level":[2,2],"entries":133,"discards":0},"CZM":{"value":15,"uname":"CZM","vname":"Adult (Tiuxo)","group":"parentalcontrol","subg":"porn","url":"https://raw.githubusercontent.com/tiuxo/hosts/master/porn","format":"hosts","pack":["adult"],"level":[0],"entries":369,"discards":2},"HYS":{"value":16,"uname":"HYS","vname":"Adult (StevenBlack)","group":"parentalcontrol","subg":"porn","url":"https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/porn/hosts","format":"hosts","pack":["adult"],"level":[0],"entries":210326,"discards":90722},"XIF":{"value":17,"uname":"XIF","vname":"Adult (cbuijs)","group":"parentalcontrol","subg":"porn","url":"https://raw.githubusercontent.com/cbuijs/accomplist/master/family-safe/plain.black.domain.list","format":"domains","pack":["adult"],"level":[1],"entries":3754231,"discards":2373155},"TQN":{"value":18,"uname":"TQN","vname":"Adult (ShadowWhisperer)","group":"parentalcontrol","subg":"porn","url":"https://raw.githubusercontent.com/ShadowWhisperer/BlockLists/master/Lists/Adult","format":"domains","pack":["adult"],"level":[2],"entries":257121,"discards":87},"ZVO":{"value":19,"uname":"ZVO","vname":"Social networks (Olbat)","group":"parentalcontrol","subg":"social-networks","url":"https://raw.githubusercontent.com/olbat/ut1-blacklists/master/blacklists/social_networks/domains","format":"domains","pack":["socialmedia"],"level":[0],"entries":702,"discards":0},"YOM":{"value":20,"uname":"YOM","vname":"9Gag","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/9gag","format":"domains","pack":["vanity"],"level":[1],"entries":2,"discards":0},"THR":{"value":21,"uname":"THR","vname":"Amazon","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nickspaargaren/no-amazon/master/amazon.txt","format":["domains","domains"],"pack":["shopping","amazon"],"level":[0,0],"entries":3541,"discards":2461},"RPW":{"value":22,"uname":"RPW","vname":"Blizzard","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/blizzard","format":"domains","pack":["gaming"],"level":[0],"entries":2,"discards":0},"AMG":{"value":23,"uname":"AMG","vname":"Daily Motion","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/dailymotion","format":"domains","pack":["streams"],"level":[0],"entries":3,"discards":0},"WTJ":{"value":24,"uname":"WTJ","vname":"Discord","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/discord","format":"domains","pack":["socialmedia"],"level":[1],"entries":5,"discards":0},"ZXU":{"value":25,"uname":"ZXU","vname":"Disney+","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/disneyplus","format":"domains","pack":["streams"],"level":[1],"entries":6,"discards":0},"FJG":{"value":26,"uname":"FJG","vname":"EBay","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/ebay","format":"domains","pack":["shopping"],"level":[0],"entries":27,"discards":0},"NYS":{"value":27,"uname":"NYS","vname":"Facebook","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/facebook","format":"domains","pack":["socialmedia","facebook"],"level":[1,0],"entries":9,"discards":0},"OKG":{"value":28,"uname":"OKG","vname":"Fortnite","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/fortnite","format":"domains","pack":["gaming"],"level":[0],"entries":1,"discards":0},"KNP":{"value":29,"uname":"KNP","vname":"Hulu","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/hulu","format":"domains","pack":["streams"],"level":[0],"entries":1,"discards":0},"FLI":{"value":30,"uname":"FLI","vname":"Imgur","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/imgur","format":"domains","pack":["vanity"],"level":[1],"entries":1,"discards":0},"RYX":{"value":31,"uname":"RYX","vname":"Instagram","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/instagram","format":"domains","pack":["socialmedia","facebook"],"level":[1,0],"entries":2,"discards":0},"CIH":{"value":32,"uname":"CIH","vname":"League of Legends","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/leagueoflegends","format":"domains","pack":["gaming"],"level":[0],"entries":2,"discards":0},"PTE":{"value":33,"uname":"PTE","vname":"Messenger","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/messenger","format":"domains","pack":["socialmedia"],"level":[1],"entries":3,"discards":0},"KEA":{"value":34,"uname":"KEA","vname":"Minecraft","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/minecraft","format":"domains","pack":["gaming"],"level":[0],"entries":3,"discards":0},"CMR":{"value":35,"uname":"CMR","vname":"Netflix","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/netflix","format":"domains","pack":["streams"],"level":[2],"entries":6,"discards":0},"DDO":{"value":36,"uname":"DDO","vname":"Pinterest","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/pinterest","format":"domains","pack":["socialmedia"],"level":[1],"entries":49,"discards":0},"VLM":{"value":37,"uname":"VLM","vname":"Reddit","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/reddit","format":"domains","pack":["socialmedia","vanity"],"level":[0,0],"entries":5,"discards":0},"JEH":{"value":38,"uname":"JEH","vname":"Roblox","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/roblox","format":"domains","pack":["gaming"],"level":[0],"entries":2,"discards":0},"XLX":{"value":39,"uname":"XLX","vname":"Skype","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/skype","format":"domains","pack":["socialmedia"],"level":[1],"entries":5,"discards":0},"OQW":{"value":40,"uname":"OQW","vname":"Snapchat","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/snapchat","format":"domains","pack":["socialmedia"],"level":[1],"entries":10,"discards":0},"FXC":{"value":41,"uname":"FXC","vname":"Spotify","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/spotify","format":"domains","pack":["shopping"],"level":[2],"entries":10,"discards":0},"HZJ":{"value":42,"uname":"HZJ","vname":"Steam","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/steam","format":"domains","pack":["gaming"],"level":[0],"entries":12,"discards":0},"SWK":{"value":43,"uname":"SWK","vname":"Telegram","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/telegram","format":"domains","pack":["socialmedia"],"level":[1],"entries":4,"discards":0},"VAM":{"value":44,"uname":"VAM","vname":"Tiktok","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/tiktok","format":["domains","domains"],"pack":["tiktok","socialmedia"],"level":[0,0],"entries":3716,"discards":3466},"AOS":{"value":45,"uname":"AOS","vname":"Tinder","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/tinder","format":"domains","pack":["socialmedia","dating"],"level":[1,0],"entries":3,"discards":0},"FAL":{"value":46,"uname":"FAL","vname":"Tumblr","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/tumblr","format":"domains","pack":["socialmedia"],"level":[1],"entries":1,"discards":0},"CZK":{"value":47,"uname":"CZK","vname":"Twitch","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/twitch","format":["domains","domains"],"pack":["gaming","streams","amazon"],"level":[1,0,2],"entries":171,"discards":160},"FZB":{"value":48,"uname":"FZB","vname":"Twitter","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/twitter","format":"domains","pack":["socialmedia"],"level":[0],"entries":7,"discards":0},"PYW":{"value":49,"uname":"PYW","vname":"Vimeo","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/vimeo","format":"domains","pack":["streams"],"level":[1],"entries":4,"discards":0},"JXA":{"value":50,"uname":"JXA","vname":"VK","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/vk","format":"domains","pack":["socialmedia"],"level":[1],"entries":8,"discards":0},"KOR":{"value":51,"uname":"KOR","vname":"WhatsApp","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/whatsapp","format":["domains","domains"],"pack":["facebook","whatsapp"],"level":[2,0],"entries":228,"discards":153},"DEP":{"value":52,"uname":"DEP","vname":"YouTube","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/youtube","format":"domains","pack":["streams","google","youtube"],"level":[1,2,0],"entries":18,"discards":0},"RFX":{"value":53,"uname":"RFX","vname":"Zoom","group":"parentalcontrol","subg":"services","url":"https://raw.githubusercontent.com/nextdns/services/main/services/zoom","format":"domains","pack":["zoom","socialmedia"],"level":[0,2],"entries":4,"discards":0},"DTT":{"value":54,"uname":"DTT","vname":"NoCoin (hoshsadiq + ShadowWhisperer + Olbat)","group":"security","subg":"cryptojacking","url":"https://raw.githubusercontent.com/hoshsadiq/adblock-nocoin-list/master/hosts.txt","format":["hosts","domains","domains"],"pack":["crypto"],"level":[0],"entries":17702,"discards":1213},"VZP":{"value":55,"uname":"VZP","vname":"Coin Blocker (Zerodot1)","group":"security","subg":"cryptojacking","url":"https://gitlab.com/ZeroDot1/CoinBlockerLists/-/raw/master/list.txt","format":["domains","domains","domains","domains"],"pack":["crypto"],"level":[2],"entries":304475,"discards":297845},"RAF":{"value":56,"uname":"RAF","vname":"Dynamic DNS Providers","group":"security","subg":"bypass-methods","url":"https://raw.githubusercontent.com/hagezi/dns-blocklists/main/wildcard/dyndns.txt","format":"wildcard","pack":["vpn & proxies"],"level":[1],"entries":1465,"discards":0},"THG":{"value":57,"uname":"THG","vname":"Malware (UrlHaus.Abuse.Ch)","group":"security","subg":"threat-intelligence-feeds","url":"https://malware-filter.gitlab.io/malware-filter/urlhaus-filter-dnscrypt-blocked-names.txt","format":"domains","pack":["malware"],"level":[0],"entries":1490,"discards":9},"YVH":{"value":58,"uname":"YVH","vname":"Security (StevenBlack)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/StevenBlack/hosts/master/data/add.Risk/hosts","format":"hosts","pack":["malware"],"level":[0],"entries":2189,"discards":762},"XQV":{"value":59,"uname":"XQV","vname":"KADHosts (PolishFiltersTeam)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/FiltersHeroes/KADhosts/master/KADomains.txt","format":"domains","pack":["malware"],"level":[1],"entries":83611,"discards":43795},"PIB":{"value":60,"uname":"PIB","vname":"Inversion","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/elliotwutingfeng/Inversion-DNSBL-Blocklists/main/Google_hostnames.txt","format":"domains","pack":["malware"],"level":[1],"entries":508076,"discards":6},"EEN":{"value":61,"uname":"EEN","vname":"NoTrack Annoyance","group":"security","subg":"threat-intelligence-feeds","url":"https://gitlab.com/quidsup/notrack-annoyance-blocklist/-/raw/master/annoyance.list","format":"domains","pack":["spam"],"level":[0],"entries":1111,"discards":0},"GDA":{"value":62,"uname":"GDA","vname":"Phishing.Army","group":"security","subg":"threat-intelligence-feeds","url":"https://phishing.army/download/phishing_army_blocklist.txt","format":"domains","pack":["scams & phishing"],"level":[2],"entries":196309,"discards":41922},"MAD":{"value":63,"uname":"MAD","vname":"Spam404","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/Spam404/lists/master/main-blacklist.txt","format":"domains","pack":["spam"],"level":[0],"entries":8142,"discards":535},"NAK":{"value":64,"uname":"NAK","vname":"NoTrack Malware","group":"security","subg":"threat-intelligence-feeds","url":"https://gitlab.com/quidsup/notrack-blocklists/-/raw/master/malware.list","format":"domains","pack":["malware"],"level":[1],"entries":244,"discards":0},"BPZ":{"value":65,"uname":"BPZ","vname":"Badd Boyz Hosts (Mitchell Krogza)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/Ultimate-Hosts-Blacklist/BaddBoyzHosts/master/clean.list","format":"domains","pack":["malware","adult"],"level":[1,1],"entries":1147,"discards":428},"HWO":{"value":66,"uname":"HWO","vname":"Malware (Mitchell Krogza)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/mitchellkrogza/The-Big-List-of-Hacked-Malware-Web-Sites/master/hosts","format":"hosts","pack":["scams & phishing"],"level":[1],"entries":13821,"discards":48},"YUC":{"value":67,"uname":"YUC","vname":"Threats (embreaj)","group":"security","subg":"threat-intelligence-feeds","url":"https://dl.threat-list.com/2/domains.txt","format":"wildcard","pack":["malware"],"level":[2],"entries":740580,"discards":36183},"IKY":{"value":68,"uname":"IKY","vname":"Threat Intelligence Feeds (HaGeZi)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/hagezi/dns-blocklists/main/wildcard/tif.txt","format":"wildcard","pack":["spam","malware","crypto","scams & phishing"],"level":[2,2,2,2],"entries":597200,"discards":0},"LSS":{"value":69,"uname":"LSS","vname":"Malware (RPi)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/RPiList/specials/master/Blocklisten/malware","format":"domains","pack":["malware"],"level":[1],"entries":0},"NOE":{"value":70,"uname":"NOE","vname":"Child Protection (RPi)","group":"security","subg":"porn","url":"https://raw.githubusercontent.com/RPiList/specials/master/Blocklisten/child-protection","format":"domains","pack":["vanity","adult"],"level":[2,2],"entries":0},"PLR":{"value":71,"uname":"PLR","vname":"Malware (Olbat)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/olbat/ut1-blacklists/master/blacklists/malware/domains","format":["domains","domains"],"pack":["malware"],"level":[0],"entries":56501,"discards":13},"FIT":{"value":72,"uname":"FIT","vname":"Phishing (Olbat)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/olbat/ut1-blacklists/master/blacklists/phishing/domains","format":"domains","pack":["scams & phishing"],"level":[0],"entries":56261,"discards":0},"LHX":{"value":73,"uname":"LHX","vname":"Typosquatting Protection","group":"security","subg":"threat-intelligence-feeds","url":"https://github.com/cbuijs/accomplist/raw/master/typosquat/plain.black.domain.list","format":["domains","domains"],"pack":["scams & phishing"],"level":[1],"entries":150266,"discards":3553},"FOF":{"value":74,"uname":"FOF","vname":"Malware (DandelionSprout)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/DandelionSprout/adfilt/master/Alternate%20versions%20Anti-Malware%20List/AntiMalwareDomains.txt","format":"domains","pack":["malware"],"level":[1],"entries":20883,"discards":10},"DYA":{"value":75,"uname":"DYA","vname":"Free Website Hosting","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/hagezi/dns-blocklists/main/wildcard/hoster.txt","format":"wildcard","pack":["scams & phishing"],"level":[2],"entries":1833,"discards":0},"JAN":{"value":76,"uname":"JAN","vname":"Blackbook (Miroslav Stampar)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/stamparm/blackbook/master/blackbook.txt","format":"domains","pack":["malware"],"level":[0],"entries":18070,"discards":81},"FHQ":{"value":77,"uname":"FHQ","vname":"Bad Sites (phishing.mailscanner.info + MalwareFilter)","group":"security","subg":"threat-intelligence-feeds","url":"http://phishing.mailscanner.info/phishing.bad.sites.conf","format":["domains","domains"],"pack":["scams & phishing"],"level":[2],"entries":47433,"discards":3029},"CMC":{"value":78,"uname":"CMC","vname":"Scams and Phishing (infinitytec + TBLP)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/infinitytec/blocklists/master/scams-and-phishing.txt","format":["domains","domains"],"pack":["scams & phishing"],"level":[1],"entries":24022,"discards":19474},"RKG":{"value":79,"uname":"RKG","vname":"Red Flag Domains","group":"security","subg":"threat-intelligence-feeds","url":"https://dl.red.flag.domains/red.flag.domains.txt","format":"domains","pack":["scams & phishing","spam","malware"],"level":[0,0,0],"entries":22146,"discards":0},"XMK":{"value":80,"uname":"XMK","vname":"Toxic (StopForumSpam + PupFilter)","group":"security","subg":"threat-intelligence-feeds","url":"https://www.stopforumspam.com/downloads/toxic_domains_whole.txt","format":["domains","domains"],"pack":["spam"],"level":[2],"entries":49460,"discards":778},"GAX":{"value":81,"uname":"GAX","vname":"Mailtrail Malware (Miroslav Stampar)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/stamparm/aux/master/maltrail-malware-domains.txt","format":"domains","pack":["malware"],"level":[1],"entries":369806,"discards":82885},"RFI":{"value":82,"uname":"RFI","vname":"Malware Rescure (rescure.me)","group":"security","subg":"threat-intelligence-feeds","url":"https://rescure.me/rescure_domain_blacklist.txt","format":"domains","pack":["malware"],"level":[2],"entries":500,"discards":1},"AZR":{"value":83,"uname":"AZR","vname":"NSO + Others (Amnesty)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/AmnestyTech/investigations/master/2021-07-18_nso/domains.txt","format":["domains","domains","domains","hosts","domains","domains","domains"],"pack":["spyware","malware"],"level":[0,0],"entries":2958,"discards":14},"CEN":{"value":84,"uname":"CEN","vname":"Malicious domains (cbuijs)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/cbuijs/accomplist/master/malicious-dom/plain.black.domain.list","format":"domains","pack":["malware"],"level":[2],"entries":2872000,"discards":1156201},"SPR":{"value":85,"uname":"SPR","vname":"Global Anti-Scam (Inversion)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/elliotwutingfeng/GlobalAntiScamOrg-blocklist/main/global-anti-scam-org-scam-urls-pihole.txt","format":"domains","pack":["scams & phishing"],"level":[1],"entries":44849,"discards":240},"MZT":{"value":86,"uname":"MZT","vname":"Threats and IoCs","group":"security","subg":"threat-intelligence-feeds","url":"https://www.botvrij.eu/data/ioclist.domain.raw","format":["domains","domains","hosts","hosts","domains","domains","hosts","domains","domains","domains","domains","domains","domains","domains","domains"],"pack":["scams & phishing","vanity"],"level":[1,2],"entries":24363,"discards":1100},"NHM":{"value":87,"uname":"NHM","vname":"Malicious domains (Sophos Labs)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/sophoslabs/covid-iocs/master/malicious_domains.txt","format":"domains","pack":["scams & phishing"],"level":[0],"entries":1959,"discards":753},"GLV":{"value":88,"uname":"GLV","vname":"Scamware","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/sophoslabs/covid-iocs/master/malware_domains.txt","format":["domains","domains"],"pack":["scams & phishing"],"level":[2],"entries":13060,"discards":15},"NUY":{"value":89,"uname":"NUY","vname":"Covid List (rescure and kriskintel)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/cbuijs/accomplist/master/covid/plain.black.domain.list","format":"domains","pack":["scams & phishing"],"level":[2],"entries":2213,"discards":473},"EDM":{"value":90,"uname":"EDM","vname":"Scamware (RPi)","group":"security","subg":"threat-intelligence-feeds","url":"https://raw.githubusercontent.com/RPiList/specials/master/Blocklisten/Corona-Blocklist","format":["domains","domains"],"pack":["scams & phishing"],"level":[2],"entries":0},"ZFC":{"value":91,"uname":"ZFC","vname":"hole.cert.pl","group":"security","subg":"threat-intelligence-feeds","url":"https://hole.cert.pl/domains/domains.txt","format":"domains","pack":["malware"],"level":[1],"entries":196719,"discards":43151},"DOP":{"value":92,"uname":"DOP","vname":"Threats (osint.digitalside.it)","group":"security","subg":"threat-intelligence-feeds","url":"https://osint.digitalside.it/Threat-Intel/lists/latestdomains.txt","format":"domains","pack":["malware"],"level":[1],"entries":79,"discards":1},"XGC":{"value":93,"uname":"XGC","vname":"Bloat (ShadowWhisperer)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/ShadowWhisperer/BlockLists/master/Lists/Bloat","format":"domains","pack":["extremeprivacy"],"level":[2],"entries":896,"discards":64},"OHE":{"value":94,"uname":"OHE","vname":"1Hosts (Lite)","group":"privacy","subg":"rethinkdns-recommended","url":"https://raw.githubusercontent.com/badmojr/1Hosts/master/Lite/domains.wildcards","format":"domains","pack":["recommended","liteprivacy"],"level":[0,0],"entries":87309,"discards":0},"MYS":{"value":95,"uname":"MYS","vname":"1Hosts (mini)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/badmojr/1Hosts/master/mini/domains.wildcards","format":"domains","pack":["liteprivacy"],"level":[0],"entries":89636,"discards":0},"IAJ":{"value":96,"uname":"IAJ","vname":"1Hosts (Pro)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/badmojr/1Hosts/master/Pro/domains.wildcards","format":"domains","pack":["aggressiveprivacy"],"level":[1],"entries":155647,"discards":0},"EAQ":{"value":97,"uname":"EAQ","vname":"iVoid (intr0)","group":"security","subg":"threat-intelligence-feeds","url":"https://gitlab.com/intr0/iVOID.GitLab.io/raw/master/iVOID.hosts","format":"hosts","pack":["scams & phishing"],"level":[1],"entries":27359,"discards":6400},"AOC":{"value":98,"uname":"AOC","vname":"ABPindo","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/ABPindo/indonesianadblockrules/master/subscriptions/domain.txt","format":"domains","pack":[],"level":[],"entries":287,"discards":0},"XAT":{"value":99,"uname":"XAT","vname":"ABPVN List","group":"privacy","subg":"","url":"https://abpvn.com/android/abpvn.txt","format":"hosts","pack":["aggressiveprivacy"],"level":[1],"entries":20728,"discards":9026},"OSE":{"value":100,"uname":"OSE","vname":"Ad-Wars","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/jdlingyu/ad-wars/master/hosts","format":"hosts","pack":["aggressiveprivacy"],"level":[1],"entries":1646,"discards":237},"IBB":{"value":101,"uname":"IBB","vname":"AdGuard Tracking and Spyware","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/r-a-y/mobile-hosts/master/AdguardMobileSpyware.txt","format":["hosts","hosts"],"pack":["aggressiveprivacy"],"level":[1],"entries":1573,"discards":22},"EGX":{"value":102,"uname":"EGX","vname":"Add.2o7Net","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/FadeMind/hosts.extras/master/add.2o7Net/hosts","format":"hosts","pack":[],"level":[],"entries":2030,"discards":1447},"HZD":{"value":103,"uname":"HZD","vname":"AdGuard SDNS Filter","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/r-a-y/mobile-hosts/master/AdguardDNS.txt","format":"hosts","pack":["liteprivacy"],"level":[0],"entries":65855,"discards":6},"FLW":{"value":104,"uname":"FLW","vname":"Anti Ad","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/privacy-protection-tools/anti-AD/master/anti-ad-domains.txt","format":"domains","pack":["aggressiveprivacy"],"level":[1],"entries":106369,"discards":6801},"ULZ":{"value":105,"uname":"ULZ","vname":"Anti Pop Ads 2 (Ador Khan)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/AdroitAdorKhan/antipopads-re/master/formats/domains.txt","format":"domains","pack":[],"level":[],"entries":135850,"discards":17108},"OFY":{"value":106,"uname":"OFY","vname":"Anudeep's Blacklist","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/anudeepND/blacklist/master/adservers.txt","format":"hosts","pack":["liteprivacy"],"level":[0],"entries":42363,"discards":19455},"MLE":{"value":107,"uname":"MLE","vname":"Multi Pro (HaGeZi)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/hagezi/dns-blocklists/main/wildcard/pro.txt","format":"wildcard","pack":["aggressiveprivacy"],"level":[1],"entries":158943,"discards":0},"YER":{"value":108,"uname":"YER","vname":"Multi Pro++ (HaGeZi)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/hagezi/dns-blocklists/main/wildcard/pro.plus.txt","format":"wildcard","pack":["extremeprivacy"],"level":[2],"entries":179363,"discards":0},"DMC":{"value":109,"uname":"DMC","vname":"Bulgarian list (Adblock)","group":"privacy","subg":"","url":"https://stanev.org/abp/adblock_bg.txt","format":"abp","pack":["extremeprivacy"],"level":[2],"entries":6,"discards":0},"IJO":{"value":110,"uname":"IJO","vname":"OISD (small)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/sjhgvr/oisd/main/domainswild_small.txt","format":"wildcard","pack":["liteprivacy"],"level":[0],"entries":47661,"discards":0},"OWW":{"value":111,"uname":"OWW","vname":"Polish filters (Certyficate.IT)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/MajkiIT/polish-ads-filter/master/polish-pihole-filters/hostfile.txt","format":"hosts","pack":[],"level":[],"entries":190,"discards":0},"EMY":{"value":112,"uname":"EMY","vname":"Ads (Disconnect)","group":"privacy","subg":"","url":"https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt","format":"domains","pack":["liteprivacy"],"level":[0],"entries":2701,"discards":35},"XKM":{"value":113,"uname":"XKM","vname":"Malvertising (Disconnect)","group":"privacy","subg":"threat-intelligence-feeds","url":"https://s3.amazonaws.com/lists.disconnect.me/simple_malvertising.txt","format":"domains","pack":["malware"],"level":[0],"entries":2736,"discards":37},"CQT":{"value":114,"uname":"CQT","vname":"Tracking (Disconnect)","group":"privacy","subg":"","url":"https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt","format":"domains","pack":["spyware"],"level":[0],"entries":34,"discards":0},"ANW":{"value":115,"uname":"ANW","vname":"EasyList China","group":"privacy","subg":"","url":"https://easylist-downloads.adblockplus.org/easylistchina.txt","format":"abp","pack":["aggressiveprivacy"],"level":[1],"entries":5811,"discards":3},"DGE":{"value":116,"uname":"DGE","vname":"EasyList Czech and Slovak","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/tomasko126/easylistczechandslovak/master/filters.txt","format":"abp","pack":["extremeprivacy"],"level":[2],"entries":94,"discards":0},"BBS":{"value":117,"uname":"BBS","vname":"EasyList Dutch","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/cbuijs/accomplist/master/dutch/optimized.black.domain.list","format":"domains","pack":["extremeprivacy"],"level":[2],"entries":56,"discards":0},"OKW":{"value":118,"uname":"OKW","vname":"EasyList Germany","group":"privacy","subg":"","url":"https://easylist-downloads.adblockplus.org/easylistgermany.txt","format":"abp","pack":["extremeprivacy"],"level":[2],"entries":396,"discards":0},"ONV":{"value":119,"uname":"ONV","vname":"EasyList Hebrew","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/easylist/EasyListHebrew/master/adguard_hosts.txt","format":"domains","pack":["extremeprivacy"],"level":[2],"entries":352,"discards":0},"CDE":{"value":120,"uname":"CDE","vname":"Italy Lists (EasyList + Marco Acorte)","group":"privacy","subg":"threat-intelligence-feeds","url":"https://easylist-downloads.adblockplus.org/easylistitaly.txt","format":["abp","domains"],"pack":["extremeprivacy","spam"],"level":[2,2],"entries":1291,"discards":4},"PAL":{"value":121,"uname":"PAL","vname":"EasyList Lithuania","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/EasyList-Lithuania/easylist_lithuania/master/easylistlithuania.txt","format":"abp","pack":["extremeprivacy"],"level":[2],"entries":31,"discards":0},"DBP":{"value":122,"uname":"DBP","vname":"EasyList Basic","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/cbuijs/accomplist/master/easylist/optimized.black.domain.list","format":"domains","pack":["liteprivacy"],"level":[0],"entries":91687,"discards":0},"MHP":{"value":123,"uname":"MHP","vname":"EasyPrivacy","group":"privacy","subg":"","url":"https://easylist-downloads.adblockplus.org/easyprivacy.txt","format":"abp","pack":["aggressiveprivacy"],"level":[1],"entries":41399,"discards":127},"EPR":{"value":124,"uname":"EPR","vname":"Normal (HaGeZi)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/hagezi/dns-blocklists/main/wildcard/multi.txt","format":"wildcard","pack":["liteprivacy"],"level":[0],"entries":139802,"discards":0},"OUU":{"value":125,"uname":"OUU","vname":"Light (HaGeZi)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/hagezi/dns-blocklists/main/wildcard/light.txt","format":"wildcard","pack":["liteprivacy"],"level":[0],"entries":64521,"discards":0},"YXS":{"value":126,"uname":"YXS","vname":"Blocklist (hBlock)","group":"privacy","subg":"","url":"https://hblock.molinero.dev/hosts_domains.txt","format":"domains","pack":["aggressiveprivacy"],"level":[1],"entries":442076,"discards":126802},"UQK":{"value":127,"uname":"UQK","vname":"Ad Set Hosts (rentianyu)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/rentianyu/Ad-set-hosts/master/hosts","format":["hosts","hosts"],"pack":["aggressiveprivacy"],"level":[1],"entries":291335,"discards":80674},"GVI":{"value":128,"uname":"GVI","vname":"Blocklist (ph00lt0)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/ph00lt0/blocklists/master/pihole-blocklist.txt","format":"hosts","pack":["extremeprivacy"],"level":[2],"entries":19398,"discards":3530},"TXJ":{"value":129,"uname":"TXJ","vname":"Ultimate (HaGeZi)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/hagezi/dns-blocklists/main/wildcard/ultimate.txt","format":"wildcard","pack":["extremeprivacy"],"level":[2],"entries":190282,"discards":0},"DPY":{"value":130,"uname":"DPY","vname":"The Quantum Blocklist (AI)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/cbuijs/accomplist/master/quantum/plain.black.domain.list","format":"domains","pack":["ignore"],"level":[2],"entries":0},"DUC":{"value":131,"uname":"DUC","vname":"Fanboy's Annoyance List","group":"privacy","subg":"threat-intelligence-feeds","url":"https://secure.fanboy.co.nz/fanboy-annoyance.txt","format":"abp","pack":["spam"],"level":[2],"entries":870,"discards":4},"WYE":{"value":132,"uname":"WYE","vname":"Fanboy's Enhanced Tracking List","group":"privacy","subg":"","url":"https://fanboy.co.nz/enhancedstats.txt","format":"abp","pack":[],"level":[],"entries":0},"CGF":{"value":133,"uname":"CGF","vname":"Ads (The Block List Project)","group":"privacy","subg":"","url":"https://blocklistproject.github.io/Lists/alt-version/ads-nl.txt","format":"domains","pack":["extremeprivacy"],"level":[2],"entries":154555,"discards":84790},"JRV":{"value":134,"uname":"JRV","vname":"Frellwit's Swedish Hosts File","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/lassekongo83/Frellwits-filter-lists/master/Frellwits-Swedish-Hosts-File.txt","format":"hosts","pack":[],"level":[],"entries":1082,"discards":70},"EOK":{"value":135,"uname":"EOK","vname":"GoodbyeAds Hosts (jerryn70)","group":"privacy","subg":"rethinkdns-recommended","url":"https://raw.githubusercontent.com/jerryn70/GoodbyeAds/master/Hosts/GoodbyeAds.txt","format":"hosts","pack":["aggressiveprivacy","recommended"],"level":[1,1],"entries":323181,"discards":113380},"HQL":{"value":136,"uname":"HQL","vname":"HostsVN","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/bigdargon/hostsVN/master/option/wildcard.txt","format":"wildcard","pack":["liteprivacy"],"level":[0],"entries":10563,"discards":65},"NNH":{"value":137,"uname":"NNH","vname":"Hu Filter","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/hufilter/hufilter/master/hufilter-dns.txt","format":"domains","pack":[],"level":[],"entries":66,"discards":0},"KRM":{"value":138,"uname":"KRM","vname":"Latvian List","group":"privacy","subg":"","url":"https://notabug.org/latvian-list/adblock-latvian/raw/master/lists/latvian-list.txt","format":"abp","pack":[],"level":[],"entries":53,"discards":0},"QKN":{"value":139,"uname":"QKN","vname":"Ads & Tracking (Lighswitch05)","group":"privacy","subg":"","url":"https://www.github.developerdan.com/hosts/lists/ads-and-tracking-extended.txt","format":["hosts","domains"],"pack":["aggressiveprivacy"],"level":[1],"entries":429286,"discards":416196},"MPR":{"value":140,"uname":"MPR","vname":"Tracking Aggressive (Lightswitch05)","group":"privacy","subg":"","url":"https://www.github.developerdan.com/hosts/lists/tracking-aggressive-extended.txt","format":"hosts","pack":["extremeprivacy"],"level":[2],"entries":171820,"discards":171685},"EOO":{"value":141,"uname":"EOO","vname":"Liste AR","group":"privacy","subg":"","url":"https://easylist-downloads.adblockplus.org/Liste_AR.txt","format":"abp","pack":[],"level":[],"entries":80,"discards":0},"MDE":{"value":142,"uname":"MDE","vname":"Liste FR","group":"privacy","subg":"","url":"https://easylist-downloads.adblockplus.org/liste_fr.txt","format":"abp","pack":[],"level":[],"entries":8428,"discards":23},"WWI":{"value":143,"uname":"WWI","vname":"Ad Blocklist Japan (logroid)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/logroid/adaway-hosts/master/hosts.txt","format":"hosts","pack":[],"level":[],"entries":14984,"discards":6282},"TTI":{"value":144,"uname":"TTI","vname":"Turkey Adlist (bkrucarci)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/bkrucarci/turk-adlist/master/hosts","format":"hosts","pack":["extremeprivacy"],"level":[2],"entries":1217,"discards":87},"GFJ":{"value":145,"uname":"GFJ","vname":"StevenBlack","group":"privacy","subg":"rethinkdns-recommended","url":"https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts","format":"hosts","pack":["aggressiveprivacy","recommended"],"level":[1,1],"entries":127153,"discards":60543},"WOD":{"value":146,"uname":"WOD","vname":"VeleSila (yhosts)","group":"privacy","subg":"rethinkdns-recommended","url":"https://raw.githubusercontent.com/VeleSila/yhosts/master/hosts","format":"hosts","pack":["recommended","liteprivacy"],"level":[0,0],"entries":6422,"discards":666},"YJR":{"value":147,"uname":"YJR","vname":"Tiuxo (ads)","group":"privacy","subg":"rethinkdns-recommended","url":"https://raw.githubusercontent.com/tiuxo/hosts/master/ads","format":"hosts","pack":["recommended","liteprivacy"],"level":[0,0],"entries":1730,"discards":384},"WIB":{"value":148,"uname":"WIB","vname":"No Facebook","group":"privacy","subg":"services","url":"https://raw.githubusercontent.com/jmdugan/blocklists/master/corporations/facebook/all","format":"hosts","pack":["facebook"],"level":[0],"entries":2098,"discards":1671},"NUI":{"value":149,"uname":"NUI","vname":"No Google","group":"privacy","subg":"services","url":"https://raw.githubusercontent.com/nickspaargaren/no-google/master/wildcards-domains","format":["domains","domains"],"pack":["google"],"level":[0],"entries":616,"discards":280},"XIO":{"value":150,"uname":"XIO","vname":"NoTrack Blocklist","group":"privacy","subg":"","url":"https://gitlab.com/quidsup/notrack-blocklists/-/raw/master/trackers.list","format":"domains","pack":["aggressiveprivacy","spyware"],"level":[1,1],"entries":16720,"discards":7},"OBW":{"value":151,"uname":"OBW","vname":"Blocklists (NoTracking)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/notracking/hosts-blocklists/master/hostnames.txt","format":"hosts","pack":["aggressiveprivacy","spyware"],"level":[1,1],"entries":250170,"discards":105438},"YBO":{"value":152,"uname":"YBO","vname":"Smart TV Blocklist (Perflyst)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/Perflyst/PiHoleBlocklist/master/SmartTV.txt","format":"domains","pack":["extremeprivacy","smart-tv"],"level":[2,0],"entries":241,"discards":45},"TTW":{"value":153,"uname":"TTW","vname":"Peter Lowe","group":"privacy","subg":"","url":"https://pgl.yoyo.org/as/serverlist.php?hostformat=domains&mimetype=plaintext","format":"domains","pack":["liteprivacy"],"level":[0],"entries":3737,"discards":4},"NML":{"value":154,"uname":"NML","vname":"RU AdList","group":"privacy","subg":"","url":"https://easylist-downloads.adblockplus.org/advblock.txt","format":"abp","pack":["extremeprivacy"],"level":[2],"entries":8827,"discards":14},"MIN":{"value":155,"uname":"MIN","vname":"Combined Privacy Block Lists: Light (bongochong)","group":"privacy","subg":"rethinkdns-recommended","url":"https://raw.githubusercontent.com/bongochong/CombinedPrivacyBlockLists/master/MiniLists/NoFormatting/mini-cpbl-wildcard-blacklist.txt","format":"wildcard","pack":["liteprivacy","recommended"],"level":[0,0],"entries":90610,"discards":0},"IFD":{"value":156,"uname":"IFD","vname":"AdRules China (Cats Team)","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/Cats-Team/AdRules/main/ad-domains.txt","format":"domains","pack":["extremeprivacy"],"level":[2],"entries":0},"AMI":{"value":157,"uname":"AMI","vname":"someonewhocares.org (Dan Pollock)","group":"privacy","subg":"","url":"https://someonewhocares.org/hosts/zero/hosts","format":"hosts","pack":["liteprivacy"],"level":[0],"entries":11726,"discards":2250},"TZF":{"value":158,"uname":"TZF","vname":"Unified Blocklist (vdbhb59)","group":"privacy","subg":"","url":"https://hosts.flossboxin.org.in/files/hosts","format":"hosts","pack":["aggressiveprivacy"],"level":[1],"entries":442127,"discards":126839},"VKE":{"value":159,"uname":"VKE","vname":"Personal Blocklist (WaLLy3K)","group":"privacy","subg":"","url":"https://v.firebog.net/hosts/static/w3kbl.txt","format":"domains","pack":[],"level":[],"entries":350,"discards":21},"PWQ":{"value":160,"uname":"PWQ","vname":"Windows Telemetry","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/crazy-max/WindowsSpyBlocker/master/data/dnscrypt/spy.txt","format":["wildcard","wildcard","domains"],"pack":["windows"],"level":[0],"entries":73,"discards":27},"KUA":{"value":161,"uname":"KUA","vname":"YousList","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/yous/YousList/master/hosts.txt","format":"hosts","pack":[],"level":[],"entries":614,"discards":12},"FHW":{"value":162,"uname":"FHW","vname":"Alexa (Amazon)","group":"privacy","subg":"native","url":"https://raw.githubusercontent.com/nextdns/native-tracking-domains/main/domains/alexa","format":"domains","pack":["amazon"],"level":[1],"entries":3,"discards":0},"AGZ":{"value":163,"uname":"AGZ","vname":"Apple","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/hagezi/dns-blocklists/main/wildcard/native.apple.txt","format":["wildcard","domains"],"pack":["apple"],"level":[1],"entries":208,"discards":22},"IVN":{"value":164,"uname":"IVN","vname":"Huawei","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/nextdns/native-tracking-domains/main/domains/huawei","format":["domains","wildcard"],"pack":[],"level":[],"entries":125,"discards":37},"FIB":{"value":165,"uname":"FIB","vname":"Roku","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/nextdns/native-tracking-domains/main/domains/roku","format":"domains","pack":["streams"],"level":[1],"entries":1,"discards":0},"FGF":{"value":166,"uname":"FGF","vname":"Samsung","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/nextdns/native-tracking-domains/main/domains/samsung","format":"domains","pack":[],"level":[],"entries":4,"discards":0},"FLL":{"value":167,"uname":"FLL","vname":"Sonos","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/nextdns/native-tracking-domains/main/domains/sonos","format":"domains","pack":[],"level":[],"entries":2,"discards":0},"IVO":{"value":168,"uname":"IVO","vname":"Windows","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/nextdns/native-tracking-domains/main/domains/windows","format":["domains","wildcard"],"pack":["windows"],"level":[1],"entries":124,"discards":5},"ALQ":{"value":169,"uname":"ALQ","vname":"Xiaomi","group":"privacy","subg":"","url":"https://raw.githubusercontent.com/nextdns/native-tracking-domains/main/domains/xiaomi","format":["domains","domains"],"pack":[],"level":[],"entries":9,"discards":0},"FHM":{"value":170,"uname":"FHM","vname":"OISD (big)","group":"privacy","subg":"rethinkdns-recommended","url":"https://raw.githubusercontent.com/sjhgvr/oisd/main/domainswild_big.txt","format":"wildcard","pack":["recommended","liteprivacy"],"level":[0,0],"entries":250080,"discards":0}} \ No newline at end of file diff --git a/app/src/main/java/com/celzero/bravedns/util/Constants.kt b/app/src/main/java/com/celzero/bravedns/util/Constants.kt index 776601d26..ccbb61cec 100644 --- a/app/src/main/java/com/celzero/bravedns/util/Constants.kt +++ b/app/src/main/java/com/celzero/bravedns/util/Constants.kt @@ -129,8 +129,8 @@ class Constants { const val RETHINK_SEARCH_URL = "https://rethinkdns.com/search?s=" - // default filetag.json for remote blocklist (stored in assets folder) (v055b) - const val PACKAGED_REMOTE_FILETAG_TIMESTAMP: Long = 1707429361312 + // default filetag.json for remote blocklist (stored in assets folder) (v055i) + const val PACKAGED_REMOTE_FILETAG_TIMESTAMP: Long = 1713995763912 // rethinkdns sponsor link const val RETHINKDNS_SPONSOR_LINK = "https://svc.rethinkdns.com/r/sponsor" From f041f3b83194c2d12bf499f11065b054d39e9d59 Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Tue, 7 May 2024 21:30:53 +0530 Subject: [PATCH 03/27] ui: rmv unused layout from dns and network log screen --- .../layout/activity_connection_tracker.xml | 251 +++++++++--------- app/src/main/res/layout/fragment_dns_logs.xml | 189 +++++++------ 2 files changed, 217 insertions(+), 223 deletions(-) diff --git a/app/src/full/res/layout/activity_connection_tracker.xml b/app/src/full/res/layout/activity_connection_tracker.xml index 0ed3115c8..8b01153fe 100644 --- a/app/src/full/res/layout/activity_connection_tracker.xml +++ b/app/src/full/res/layout/activity_connection_tracker.xml @@ -1,147 +1,144 @@ - - + android:layout_height="wrap_content" + android:layout_margin="5dp" + android:elevation="5dp" + app:cardCornerRadius="16dp"> - + android:orientation="vertical"> - - + android:gravity="start" + android:orientation="horizontal" + android:weightSum="1"> - + + - - - - - - - - + android:layout_centerVertical="true" + android:layout_toStartOf="@id/connection_delete_icon" + android:padding="7dp" + android:src="@drawable/ic_filter" + android:visibility="visible" /> + + + + + + + + + app:singleLine="true" + app:singleSelection="false" /> + - - - - - - - - - - - - - - - - + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dns_logs.xml b/app/src/main/res/layout/fragment_dns_logs.xml index b56d87c28..10f845c3f 100644 --- a/app/src/main/res/layout/fragment_dns_logs.xml +++ b/app/src/main/res/layout/fragment_dns_logs.xml @@ -1,121 +1,118 @@ - - + android:layout_margin="5dp" + android:elevation="10dp" + app:cardCornerRadius="16dp"> - + android:gravity="start" + android:orientation="vertical"> - + android:orientation="horizontal" + android:weightSum="1"> - - - + android:layout_alignParentStart="true" + android:layout_centerVertical="true" + android:layout_gravity="start" + android:layout_toStartOf="@id/query_list_filter_icon" + android:fontFamily="sans-serif" + android:isScrollContainer="true" + app:iconifiedByDefault="false" + app:queryHint="@string/search_firewall_network_log" /> - + - + - + - - - + + + - + - + - + - - + From b0133203d50d9b81a739ae34a368c9ef556030d9 Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Tue, 7 May 2024 21:31:43 +0530 Subject: [PATCH 04/27] improvement: rmv builder obj while creating alert dialog --- .../ui/fragment/ConnectionTrackerFragment.kt | 33 +++++++++++-------- .../bravedns/ui/fragment/DnsLogFragment.kt | 28 +++++++++------- 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/app/src/full/java/com/celzero/bravedns/ui/fragment/ConnectionTrackerFragment.kt b/app/src/full/java/com/celzero/bravedns/ui/fragment/ConnectionTrackerFragment.kt index a4d97029e..3d1d234b7 100644 --- a/app/src/full/java/com/celzero/bravedns/ui/fragment/ConnectionTrackerFragment.kt +++ b/app/src/full/java/com/celzero/bravedns/ui/fragment/ConnectionTrackerFragment.kt @@ -123,6 +123,11 @@ class ConnectionTrackerFragment : remakeChildFilterChipsUi(FirewallRuleset.getBlockedRules()) } + override fun onResume() { + super.onResume() + b.connectionListRl.requestFocus() + } + private fun setupRecyclerScrollListener() { val scrollListener = object : RecyclerView.OnScrollListener() { @@ -258,22 +263,24 @@ class ConnectionTrackerFragment : } private fun showDeleteDialog() { - val builder = MaterialAlertDialogBuilder(requireContext()) - builder.setTitle(R.string.conn_track_clear_logs_title) - builder.setMessage(R.string.conn_track_clear_logs_message) - builder.setCancelable(true) - builder.setPositiveButton(getString(R.string.dns_log_dialog_positive)) { _, _ -> - io { connectionTrackerRepository.clearAllData() } - } - - builder.setNegativeButton(getString(R.string.lbl_cancel)) { _, _ -> } - builder.create().show() + MaterialAlertDialogBuilder(requireContext()) + .setTitle(R.string.conn_track_clear_logs_title) + .setMessage(R.string.conn_track_clear_logs_message) + .setCancelable(true) + .setPositiveButton(getString(R.string.dns_log_dialog_positive)) { _, _ -> + io { connectionTrackerRepository.clearAllData() } + } + .setNegativeButton(getString(R.string.lbl_cancel)) { _, _ -> } + .create() + .show() } private fun remakeChildFilterChipsUi(categories: List) { - b.filterChipGroup.removeAllViews() - for (c in categories) { - b.filterChipGroup.addView(makeChildChip(c.id, c.title)) + with(b.filterChipGroup) { + removeAllViews() + for (c in categories) { + addView(makeChildChip(c.id, c.title)) + } } } diff --git a/app/src/full/java/com/celzero/bravedns/ui/fragment/DnsLogFragment.kt b/app/src/full/java/com/celzero/bravedns/ui/fragment/DnsLogFragment.kt index f38a0c875..bef66da2b 100644 --- a/app/src/full/java/com/celzero/bravedns/ui/fragment/DnsLogFragment.kt +++ b/app/src/full/java/com/celzero/bravedns/ui/fragment/DnsLogFragment.kt @@ -98,6 +98,11 @@ class DnsLogFragment : Fragment(R.layout.fragment_dns_logs), SearchView.OnQueryT remakeFilterChipsUi() } + override fun onResume() { + super.onResume() + b.topRl.requestFocus() + } + private fun setupClickListeners() { b.queryListSearch.setOnQueryTextListener(this) b.queryListSearch.setOnClickListener { @@ -233,18 +238,19 @@ class DnsLogFragment : Fragment(R.layout.fragment_dns_logs), SearchView.OnQueryT } private fun showDnsLogsDeleteDialog() { - val builder = MaterialAlertDialogBuilder(requireContext()) - builder.setTitle(R.string.dns_query_clear_logs_title) - builder.setMessage(R.string.dns_query_clear_logs_message) - builder.setCancelable(true) - builder.setPositiveButton(getString(R.string.dns_log_dialog_positive)) { _, _ -> - io { - Glide.get(requireActivity()).clearDiskCache() - dnsLogRepository.clearAllData() + MaterialAlertDialogBuilder(requireContext()) + .setTitle(R.string.dns_query_clear_logs_title) + .setMessage(R.string.dns_query_clear_logs_message) + .setCancelable(true) + .setPositiveButton(getString(R.string.dns_log_dialog_positive)) { _, _ -> + io { + Glide.get(requireActivity()).clearDiskCache() + dnsLogRepository.clearAllData() + } } - } - builder.setNegativeButton(getString(R.string.lbl_cancel)) { _, _ -> } - builder.create().show() + .setNegativeButton(getString(R.string.lbl_cancel)) { _, _ -> } + .create() + .show() } override fun onQueryTextSubmit(query: String): Boolean { From 83fad651ab9aaab63a2e98b08cd1b9f984fa5664 Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Thu, 9 May 2024 19:11:16 +0530 Subject: [PATCH 05/27] exclude apps which are part of proxy configuration new setting whether to exclude or not in Network settings tab. --- .../ui/activity/TunnelSettingsActivity.kt | 13 +++ .../res/layout/activity_tunnel_settings.xml | 55 +++++++++++++ .../com/celzero/bravedns/data/AppConfig.kt | 8 ++ .../bravedns/database/ProxyEndpointDAO.kt | 3 +- .../database/ProxyEndpointRepository.kt | 4 +- .../bravedns/service/BraveVPNService.kt | 80 ++++++++++++++++++- .../bravedns/service/PersistentState.kt | 3 + app/src/main/res/values/strings.xml | 4 + 8 files changed, 164 insertions(+), 6 deletions(-) diff --git a/app/src/full/java/com/celzero/bravedns/ui/activity/TunnelSettingsActivity.kt b/app/src/full/java/com/celzero/bravedns/ui/activity/TunnelSettingsActivity.kt index bd1811072..08618afdd 100644 --- a/app/src/full/java/com/celzero/bravedns/ui/activity/TunnelSettingsActivity.kt +++ b/app/src/full/java/com/celzero/bravedns/ui/activity/TunnelSettingsActivity.kt @@ -71,6 +71,8 @@ class TunnelSettingsActivity : AppCompatActivity(R.layout.activity_tunnel_settin b.settingsActivityLanTrafficSwitch.isChecked = persistentState.privateIps // connectivity check b.settingsActivityConnectivityChecksSwitch.isChecked = persistentState.connectivityChecks + // exclude apps in proxy + b.settingsActivityExcludeProxyAppsSwitch.isChecked = persistentState.excludeAppsInProxy // for protocol translation, enable only on DNS/DNS+Firewall mode if (appConfig.getBraveMode().isDnsActive()) { b.settingsActivityPtransSwitch.isChecked = persistentState.protocolTranslationType @@ -99,6 +101,14 @@ class TunnelSettingsActivity : AppCompatActivity(R.layout.activity_tunnel_settin } } + b.settingsActivityExcludeProxyAppsSwitch.setOnCheckedChangeListener { _, isChecked -> + persistentState.excludeAppsInProxy = isChecked + } + + b.settingsActivityExcludeProxyAppsRl.setOnClickListener { + b.settingsActivityExcludeProxyAppsSwitch.isChecked = !b.settingsActivityExcludeProxyAppsSwitch.isChecked + } + b.settingsRInRRl.setOnClickListener { b.settingsRInRSwitch.isChecked = !b.settingsRInRSwitch.isChecked } @@ -305,15 +315,18 @@ class TunnelSettingsActivity : AppCompatActivity(R.layout.activity_tunnel_settin b.settingsActivityVpnLockdownDesc.visibility = View.VISIBLE b.settingsActivityAllowBypassRl.alpha = 0.5f b.settingsActivityLanTrafficRl.alpha = 0.5f + b.settingsActivityExcludeProxyAppsRl.alpha = 0.5f } else { b.settingsActivityVpnLockdownDesc.visibility = View.GONE b.settingsActivityAllowBypassRl.alpha = 1f b.settingsActivityLanTrafficRl.alpha = 1f + b.settingsActivityExcludeProxyAppsRl.alpha = 1f } b.settingsActivityAllowBypassSwitch.isEnabled = !isLockdown b.settingsActivityAllowBypassRl.isEnabled = !isLockdown b.settingsActivityLanTrafficSwitch.isEnabled = !isLockdown b.settingsActivityLanTrafficRl.isEnabled = !isLockdown + b.settingsActivityExcludeProxyAppsSwitch.isEnabled = !isLockdown } private fun enableAfterDelay(ms: Long, vararg views: View) { diff --git a/app/src/full/res/layout/activity_tunnel_settings.xml b/app/src/full/res/layout/activity_tunnel_settings.xml index 1d1a89649..1de24eba7 100644 --- a/app/src/full/res/layout/activity_tunnel_settings.xml +++ b/app/src/full/res/layout/activity_tunnel_settings.xml @@ -121,6 +121,61 @@ android:padding="10dp" /> + + + + + + + + + + + + + + + ) { + private fun addDisallowedApplications(builder: Builder, packages: Collection) { packages.forEach { addDisallowedApplication(builder, it) } } @@ -1393,6 +1454,7 @@ class BraveVPNService : @RequiresApi(VERSION_CODES.UPSIDE_DOWN_CAKE) private fun startForegroundService(serviceType: Int): Boolean { + Logger.vv(LOG_TAG_VPN, "startForegroundService, api: ${VERSION.SDK_INT}") try { ServiceCompat.startForeground( this, @@ -1418,6 +1480,7 @@ class BraveVPNService : } private fun startForegroundService(): Boolean { + Logger.vv(LOG_TAG_VPN, "startForegroundService, api: ${VERSION.SDK_INT}") if (isAtleastS()) { try { startForeground(SERVICE_ID, updateNotificationBuilder()) @@ -1577,6 +1640,7 @@ class BraveVPNService : addTransport() } AppConfig.DnsType.DNS_PROXY -> { + restartVpnWithNewAppConfig(reason = "dnsProxy") addTransport() } AppConfig.DnsType.RETHINK_REMOTE -> { @@ -1732,10 +1796,14 @@ class BraveVPNService : } AppConfig.ProxyProvider.ORBOT -> { // update orbot config, its treated as SOCKS5 or HTTP proxy internally + // orbot proxy requires app to be excluded from vpn, so restart vpn + restartVpnWithNewAppConfig(reason = "orbotProxy") vpnAdapter?.setCustomProxy(tunProxyMode) } AppConfig.ProxyProvider.CUSTOM -> { // custom either means socks5 or http proxy + // socks5 proxy requires app to be excluded from vpn, so restart vpn + restartVpnWithNewAppConfig(reason = "customProxy") vpnAdapter?.setCustomProxy(tunProxyMode) } } @@ -3200,6 +3268,12 @@ class BraveVPNService : // even if inactive, route connections to wg if lockdown/catch-all is enabled to // avoid leaks if (wgConfig.isActive || wgConfig.isLockdown || wgConfig.isCatchAll) { + // if lockdown is enabled, canRoute checks peer configuration and if it returns + // "false", then the connection will be sent to base and not dropped + // if lockdown is disabled, then canRoute returns default (true) which + // will have the effect of blocking all connections + // ie, if lockdown is enabled, split-tunneling happens as expected but if + // lockdown is disabled, it has the effect of blocking all connections val canRoute = vpnAdapter?.canRouteIp(proxyId, connTracker.destIP, true) return if (canRoute == true) { handleProxyHandshake(proxyId) diff --git a/app/src/main/java/com/celzero/bravedns/service/PersistentState.kt b/app/src/main/java/com/celzero/bravedns/service/PersistentState.kt index 69cd62b42..3d9f7871b 100644 --- a/app/src/main/java/com/celzero/bravedns/service/PersistentState.kt +++ b/app/src/main/java/com/celzero/bravedns/service/PersistentState.kt @@ -277,6 +277,9 @@ class PersistentState(context: Context) : SimpleKrate(context), KoinComponent { // proxy dns requests over proxy var proxyDns by booleanPref("proxy_dns").withDefault(true) + // exclude apps which are configured in proxy (socks5, http, orbot) + var excludeAppsInProxy by booleanPref("exclude_apps_in_proxy").withDefault(true) + var orbotConnectionStatus: MutableLiveData = MutableLiveData() var median: MutableLiveData = MutableLiveData() var vpnEnabledLiveData: MutableLiveData = MutableLiveData() diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3709e300c..8e7a29f9d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -112,6 +112,7 @@ 🐢 💸 🟢 + 🔴 🗝️ 🌐 🕒 @@ -432,6 +433,9 @@ Do not route Private IPs (experimental) Exclude LAN, loopback, multicast, link-local routes from Rethink\'s VPN tunnel. + Exclude Proxy apps + Exclude apps that used to setup proxies from Rethink\'s VPN tunnel. + Enable network visibility Allow requesting apps to access all available networks. These apps may bypass Rethink\'s VPN tunnel on-demand. Some audio/video conference apps like Zoom and Meet may require this to function properly. Certain options disabled when VPN is in lockdown mode. See VPN settings. From 929244f894923abc68aa4dc88f9828299233ff7e Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Thu, 9 May 2024 20:23:44 +0530 Subject: [PATCH 06/27] ui: disable exclude proxy app setting in lockdown --- .../com/celzero/bravedns/ui/activity/TunnelSettingsActivity.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/full/java/com/celzero/bravedns/ui/activity/TunnelSettingsActivity.kt b/app/src/full/java/com/celzero/bravedns/ui/activity/TunnelSettingsActivity.kt index 08618afdd..129d4639f 100644 --- a/app/src/full/java/com/celzero/bravedns/ui/activity/TunnelSettingsActivity.kt +++ b/app/src/full/java/com/celzero/bravedns/ui/activity/TunnelSettingsActivity.kt @@ -327,6 +327,7 @@ class TunnelSettingsActivity : AppCompatActivity(R.layout.activity_tunnel_settin b.settingsActivityLanTrafficSwitch.isEnabled = !isLockdown b.settingsActivityLanTrafficRl.isEnabled = !isLockdown b.settingsActivityExcludeProxyAppsSwitch.isEnabled = !isLockdown + b.settingsActivityExcludeProxyAppsRl.isEnabled = !isLockdown } private fun enableAfterDelay(ms: Long, vararg views: View) { From 1db6cf0e653e6df584842e44aaeebdef61b00abd Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Thu, 9 May 2024 20:24:31 +0530 Subject: [PATCH 07/27] getUidQ: no need to retry if uid is in cache --- .../celzero/bravedns/net/manager/ConnectionTracer.kt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/celzero/bravedns/net/manager/ConnectionTracer.kt b/app/src/main/java/com/celzero/bravedns/net/manager/ConnectionTracer.kt index e88837565..8e6b8ff71 100644 --- a/app/src/main/java/com/celzero/bravedns/net/manager/ConnectionTracer.kt +++ b/app/src/main/java/com/celzero/bravedns/net/manager/ConnectionTracer.kt @@ -71,8 +71,10 @@ class ConnectionTracer(ctx: Context) { } } catch (ignored: IllegalArgumentException) { // InetSocketAddress throws IllegalArgumentException or SecurityException + Logger.d(LOG_TAG_VPN, "err getUidQ: $ignored") return uid } catch (ignored: SecurityException) { + Logger.d(LOG_TAG_VPN, "err getUidQ: $ignored") return uid } val key = makeCacheKey(protocol, local, remote) @@ -96,7 +98,7 @@ class ConnectionTracer(ctx: Context) { Logger.e(LOG_TAG_VPN, "err getUidQ: " + ex.message, ex) } - if (retryRequired(uid, protocol, destIp)) { + if (retryRequired(uid, protocol, destIp, key)){ // change the destination IP to unspecified IP and try again for unconnected UDP val dip = if (IPAddressString(destIp).isIPv6) { @@ -119,10 +121,14 @@ class ConnectionTracer(ctx: Context) { } // handle unconnected UDP requests - private fun retryRequired(uid: Int, protocol: Int, destIp: String): Boolean { + private fun retryRequired(uid: Int, protocol: Int, destIp: String, key: String): Boolean { if (uid != Constants.INVALID_UID) { // already got the uid, no need to retry return false } + // if uid is already cached, no need to retry + if (uidCache.getIfPresent(key) != null) { + return false + } // no need to retry for protocols other than UDP if (protocol != Protocol.UDP.protocolType) { return false From 9734290a9d32e1ffcc3a29e6ac2321f34a085886 Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Thu, 9 May 2024 20:26:19 +0530 Subject: [PATCH 08/27] vpn: restart vpn on exclude apps in proxy config setting restart only if either proxy or dns proxy is enabled --- .../bravedns/service/BraveVPNService.kt | 47 +++++++++++-------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/com/celzero/bravedns/service/BraveVPNService.kt b/app/src/main/java/com/celzero/bravedns/service/BraveVPNService.kt index 618ea7c90..7f5d542d2 100644 --- a/app/src/main/java/com/celzero/bravedns/service/BraveVPNService.kt +++ b/app/src/main/java/com/celzero/bravedns/service/BraveVPNService.kt @@ -1038,12 +1038,10 @@ class BraveVPNService : if (appConfig.isCustomSocks5Enabled()) { // For Socks5 if there is a app selected, add that app in excluded list val socks5ProxyEndpoint = appConfig.getConnectedSocks5Proxy() - val appName = socks5ProxyEndpoint?.proxyAppName - Log.i(LOG_TAG_VPN, "exclude selected socks5 app $appName") - if ( - appName?.equals(getString(R.string.settings_app_list_default_app)) == false && - isExcludePossible(appName) - ) { + val appName = + socks5ProxyEndpoint?.proxyAppName + ?: getString(R.string.settings_app_list_default_app) + if (isExcludePossible(appName)) { addDisallowedApplication(builder, appName) } else { Logger.d(LOG_TAG_VPN, "exclude socks5 app not set or exclude not possible") @@ -1058,11 +1056,9 @@ class BraveVPNService : if (appConfig.isCustomHttpProxyEnabled()) { // For HTTP proxy if there is a app selected, add that app in excluded list val httpProxyEndpoint = appConfig.getConnectedHttpProxy() - val appName = httpProxyEndpoint?.proxyAppName - if ( - appName?.equals(getString(R.string.settings_app_list_default_app)) == false && - isExcludePossible(appName) - ) { + val appName = + httpProxyEndpoint?.proxyAppName ?: getString(R.string.settings_app_list_default_app) + if (isExcludePossible(appName)) { Logger.i(LOG_TAG_VPN, "exclude http proxy app $appName") addDisallowedApplication(builder, appName) } else { @@ -1075,10 +1071,7 @@ class BraveVPNService : val dnsProxyEndpoint = appConfig.getSelectedDnsProxyDetails() val appName = dnsProxyEndpoint?.proxyAppName ?: getString(R.string.settings_app_list_default_app) - if ( - appName != getString(R.string.settings_app_list_default_app) && - isExcludePossible(appName) - ) { + if (isExcludePossible(appName)) { Logger.i(LOG_TAG_VPN, "exclude dns proxy app $appName") addDisallowedApplication(builder, appName) } else { @@ -1091,11 +1084,17 @@ class BraveVPNService : private fun isExcludePossible(appName: String?): Boolean { // user settings to exclude apps in proxy mode - if (!persistentState.excludeAppsInProxy) return false + if (!persistentState.excludeAppsInProxy) { + Logger.d(LOG_TAG_VPN, "exclude apps in proxy is disabled") + return false + } - if (!VpnController.isVpnLockdown()) - return (appName?.equals(getString(R.string.settings_app_list_default_app)) == false) - return false + if (VpnController.isVpnLockdown()) { + Logger.d(LOG_TAG_VPN, "vpn is lockdown, exclude apps not possible") + return false + } + + return appName?.equals(getString(R.string.settings_app_list_default_app)) == false } private fun addDisallowedApplication(builder: Builder, pkg: String) { @@ -1724,6 +1723,16 @@ class BraveVPNService : // no-op } } + PersistentState.EXCLUDE_APPS_IN_PROXY -> { + // restart vpn to exclude apps if either proxy or dns proxy is enabled + if (appConfig.isProxyEnabled() || appConfig.isDnsProxyActive()) { + io("excludeAppsInProxy") { + restartVpnWithNewAppConfig(reason = "excludeAppsInProxy") + } + } else { + // no-op, no need to restart vpn as no proxy/dns proxy is enabled + } + } } } From 5d443995d28b60a44d03e34b8a4b84640973be2a Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Thu, 9 May 2024 20:44:03 +0530 Subject: [PATCH 09/27] log: changes in logger stmts --- .../celzero/bravedns/service/BraveVPNService.kt | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/celzero/bravedns/service/BraveVPNService.kt b/app/src/main/java/com/celzero/bravedns/service/BraveVPNService.kt index 7f5d542d2..fdf3f3137 100644 --- a/app/src/main/java/com/celzero/bravedns/service/BraveVPNService.kt +++ b/app/src/main/java/com/celzero/bravedns/service/BraveVPNService.kt @@ -1003,6 +1003,7 @@ class BraveVPNService : // route rethink traffic in rethink based on the user selection if (!persistentState.routeRethinkInRethink) { + Logger.i(LOG_TAG_VPN, "builder: exclude rethink app from builder") addDisallowedApplication(builder, this.packageName) } else { Logger.i(LOG_TAG_VPN, "builder: route rethink traffic in rethink") @@ -1029,6 +1030,7 @@ class BraveVPNService : // ignore excluded-apps settings when vpn is lockdown because // those apps would lose all internet connectivity, otherwise if (!VpnController.isVpnLockdown()) { + Logger.i(LOG_TAG_VPN, "builder, vpn is not lockdown, exclude-apps $excludedApps") addDisallowedApplications(builder, excludedApps) } else { Logger.w(LOG_TAG_VPN, "builder, vpn is lockdown, ignoring exclude-apps list") @@ -1042,9 +1044,10 @@ class BraveVPNService : socks5ProxyEndpoint?.proxyAppName ?: getString(R.string.settings_app_list_default_app) if (isExcludePossible(appName)) { + Logger.i(LOG_TAG_VPN, "exclude app for socks5, pkg: $appName") addDisallowedApplication(builder, appName) } else { - Logger.d(LOG_TAG_VPN, "exclude socks5 app not set or exclude not possible") + Logger.i(LOG_TAG_VPN, "socks5(exclude): app not set or exclude not possible") } } @@ -1059,10 +1062,10 @@ class BraveVPNService : val appName = httpProxyEndpoint?.proxyAppName ?: getString(R.string.settings_app_list_default_app) if (isExcludePossible(appName)) { - Logger.i(LOG_TAG_VPN, "exclude http proxy app $appName") + Logger.i(LOG_TAG_VPN, "exclude app for http proxy, pkg: $appName") addDisallowedApplication(builder, appName) } else { - Logger.d(LOG_TAG_VPN, "exclude http proxy app not set or exclude not possible") + Logger.i(LOG_TAG_VPN, "http proxy(exclude): app not set or exclude not possible") } } @@ -1072,10 +1075,10 @@ class BraveVPNService : val appName = dnsProxyEndpoint?.proxyAppName ?: getString(R.string.settings_app_list_default_app) if (isExcludePossible(appName)) { - Logger.i(LOG_TAG_VPN, "exclude dns proxy app $appName") + Logger.i(LOG_TAG_VPN, "exclude app for dns proxy, pkg: $appName") addDisallowedApplication(builder, appName) } else { - Logger.d(LOG_TAG_VPN, "exclude dns proxy app not set or exclude not possible") + Logger.i(LOG_TAG_VPN, "dns proxy(exclude): app not set or exclude not possible") } } @@ -1085,12 +1088,12 @@ class BraveVPNService : private fun isExcludePossible(appName: String?): Boolean { // user settings to exclude apps in proxy mode if (!persistentState.excludeAppsInProxy) { - Logger.d(LOG_TAG_VPN, "exclude apps in proxy is disabled") + Logger.i(LOG_TAG_VPN, "exclude apps in proxy is disabled") return false } if (VpnController.isVpnLockdown()) { - Logger.d(LOG_TAG_VPN, "vpn is lockdown, exclude apps not possible") + Logger.i(LOG_TAG_VPN, "vpn is lockdown, exclude apps not possible") return false } From 2e5f4adfbef0e99701c21d0e1895879b7a093652 Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Sat, 11 May 2024 18:21:59 +0530 Subject: [PATCH 10/27] ui: option to exclude app in proxy settings dialog --- .../ui/activity/ProxySettingsActivity.kt | 42 +++++++++++++++---- .../ui/activity/TunnelSettingsActivity.kt | 4 +- .../ui/fragment/DnsProxyListFragment.kt | 19 +++++++++ .../full/res/layout/dialog_set_dns_proxy.xml | 39 +++++++++++++++++ .../bravedns/service/BraveVPNService.kt | 1 + .../bravedns/service/PersistentState.kt | 5 ++- .../res/drawable/ic_firewall_exclude_off.xml | 2 +- app/src/main/res/layout/dialog_set_proxy.xml | 38 +++++++++++++++++ app/src/main/res/values/strings.xml | 4 +- 9 files changed, 140 insertions(+), 14 deletions(-) diff --git a/app/src/full/java/com/celzero/bravedns/ui/activity/ProxySettingsActivity.kt b/app/src/full/java/com/celzero/bravedns/ui/activity/ProxySettingsActivity.kt index 87379e527..a40c0dd37 100644 --- a/app/src/full/java/com/celzero/bravedns/ui/activity/ProxySettingsActivity.kt +++ b/app/src/full/java/com/celzero/bravedns/ui/activity/ProxySettingsActivity.kt @@ -62,11 +62,11 @@ import com.celzero.bravedns.util.Utilities.isAtleastQ import com.celzero.bravedns.util.Utilities.isValidPort import com.celzero.bravedns.util.Utilities.showToastUiCentered import com.google.android.material.dialog.MaterialAlertDialogBuilder +import java.util.concurrent.TimeUnit import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.koin.android.ext.android.inject -import java.util.concurrent.TimeUnit class ProxySettingsActivity : AppCompatActivity(R.layout.fragment_proxy_configure) { private val b by viewBinding(FragmentProxyConfigureBinding::bind) @@ -646,6 +646,7 @@ class ProxySettingsActivity : AppCompatActivity(R.layout.fragment_proxy_configur val headerTxt: TextView = dialogBinding.dialogProxyHeader val headerDesc: TextView = dialogBinding.dialogProxyHeaderDesc + val lockdownDesc: TextView = dialogBinding.dialogProxyHeaderLockdownDesc val applyURLBtn = dialogBinding.dialogProxyApplyBtn val cancelURLBtn = dialogBinding.dialogProxyCancelBtn val appNameSpinner: Spinner = dialogBinding.dialogProxySpinnerAppname @@ -655,8 +656,16 @@ class ProxySettingsActivity : AppCompatActivity(R.layout.fragment_proxy_configur val userNameEditText: EditText = dialogBinding.dialogProxyEditUsername val passwordEditText: EditText = dialogBinding.dialogProxyEditPassword val udpBlockCheckBox: CheckBox = dialogBinding.dialogProxyUdpCheck + val excludeAppCheckBox: CheckBox = dialogBinding.dialogProxyExcludeAppsCheck udpBlockCheckBox.isChecked = persistentState.getUdpBlocked() + excludeAppCheckBox.isChecked = !persistentState.excludeAppsInProxy + excludeAppCheckBox.isEnabled = !VpnController.isVpnLockdown() + lockdownDesc.visibility = if (VpnController.isVpnLockdown()) View.VISIBLE else View.GONE + + if (VpnController.isVpnLockdown()) { + excludeAppCheckBox.alpha = 0.5f + } val proxySpinnerAdapter = ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, appNames) @@ -691,6 +700,11 @@ class ProxySettingsActivity : AppCompatActivity(R.layout.fragment_proxy_configur headerTxt.text = getString(R.string.settings_dns_proxy_dialog_header) headerDesc.text = getString(R.string.settings_dns_proxy_dialog_app_desc) + lockdownDesc.setOnClickListener { + dialog.dismiss() + UIUtils.openVpnProfile(this) + } + applyURLBtn.setOnClickListener { var port: Int? = 0 var isValid: Boolean @@ -724,14 +738,16 @@ class ProxySettingsActivity : AppCompatActivity(R.layout.fragment_proxy_configur isUDPBlock = true } + persistentState.excludeAppsInProxy = !excludeAppCheckBox.isChecked + val userName: String = userNameEditText.text.toString() val password: String = passwordEditText.text.toString() if (isValid && isIPValid) { // Do the Socks5 Proxy setting there persistentState.setUdpBlocked(udpBlockCheckBox.isChecked) - val appName = appNameSpinner.selectedItem.toString() - insertSocks5Endpoint(endpoint.id, ip, port, appName, userName, password, isUDPBlock) - if (appName == getString(R.string.settings_app_list_default_app)) { + val app = appNameSpinner.selectedItem.toString() + insertSocks5Endpoint(endpoint.id, ip, port, app, userName, password, isUDPBlock) + if (app == getString(R.string.settings_app_list_default_app)) { b.settingsActivitySocks5Desc.text = getString( R.string.settings_socks_forwarding_desc_no_app, @@ -744,7 +760,7 @@ class ProxySettingsActivity : AppCompatActivity(R.layout.fragment_proxy_configur R.string.settings_socks_forwarding_desc, ip, port.toString(), - appName + app ) } dialog.dismiss() @@ -826,6 +842,7 @@ class ProxySettingsActivity : AppCompatActivity(R.layout.fragment_proxy_configur val headerTxt: TextView = dialogBinding.dialogProxyHeader val headerDesc: TextView = dialogBinding.dialogProxyHeaderDesc + val lockdownDesc: TextView = dialogBinding.dialogProxyHeaderLockdownDesc val applyURLBtn = dialogBinding.dialogProxyApplyBtn val cancelURLBtn = dialogBinding.dialogProxyCancelBtn val appNameSpinner: Spinner = dialogBinding.dialogProxySpinnerAppname @@ -836,6 +853,7 @@ class ProxySettingsActivity : AppCompatActivity(R.layout.fragment_proxy_configur val userNameLl: LinearLayout = dialogBinding.dialogProxyUsernameHeader val passwordLl: LinearLayout = dialogBinding.dialogProxyPasswordHeader val udpBlockLl: LinearLayout = dialogBinding.dialogProxyUdpHeader + val excludeAppCheckBox: CheckBox = dialogBinding.dialogProxyExcludeAppsCheck // do not show the UDP block option for HTTP proxy udpBlockLl.visibility = View.GONE @@ -844,6 +862,16 @@ class ProxySettingsActivity : AppCompatActivity(R.layout.fragment_proxy_configur // do not show the username/password option for HTTP proxy userNameLl.visibility = View.GONE passwordLl.visibility = View.GONE + excludeAppCheckBox.isChecked = !persistentState.excludeAppsInProxy + excludeAppCheckBox.isEnabled = !VpnController.isVpnLockdown() + if (VpnController.isVpnLockdown()) { + excludeAppCheckBox.alpha = 0.5f + } + lockdownDesc.setOnClickListener { + dialog.dismiss() + UIUtils.openVpnProfile(this) + } + lockdownDesc.visibility = if (VpnController.isVpnLockdown()) View.VISIBLE else View.GONE val proxySpinnerAdapter = ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, appNames) @@ -884,9 +912,9 @@ class ProxySettingsActivity : AppCompatActivity(R.layout.fragment_proxy_configur if (isHostValid) { errorTxt.visibility = View.INVISIBLE - val appName = appNameSpinner.selectedItem.toString() - insertHttpProxyEndpointDB(endpoint.id, host, appName) + insertHttpProxyEndpointDB(endpoint.id, host, appNameSpinner.selectedItem.toString()) dialog.dismiss() + persistentState.excludeAppsInProxy = !excludeAppCheckBox.isChecked showToastUiCentered( this, getString(R.string.settings_http_proxy_toast_success), diff --git a/app/src/full/java/com/celzero/bravedns/ui/activity/TunnelSettingsActivity.kt b/app/src/full/java/com/celzero/bravedns/ui/activity/TunnelSettingsActivity.kt index 129d4639f..6c3c466a8 100644 --- a/app/src/full/java/com/celzero/bravedns/ui/activity/TunnelSettingsActivity.kt +++ b/app/src/full/java/com/celzero/bravedns/ui/activity/TunnelSettingsActivity.kt @@ -72,7 +72,7 @@ class TunnelSettingsActivity : AppCompatActivity(R.layout.activity_tunnel_settin // connectivity check b.settingsActivityConnectivityChecksSwitch.isChecked = persistentState.connectivityChecks // exclude apps in proxy - b.settingsActivityExcludeProxyAppsSwitch.isChecked = persistentState.excludeAppsInProxy + b.settingsActivityExcludeProxyAppsSwitch.isChecked = !persistentState.excludeAppsInProxy // for protocol translation, enable only on DNS/DNS+Firewall mode if (appConfig.getBraveMode().isDnsActive()) { b.settingsActivityPtransSwitch.isChecked = persistentState.protocolTranslationType @@ -102,7 +102,7 @@ class TunnelSettingsActivity : AppCompatActivity(R.layout.activity_tunnel_settin } b.settingsActivityExcludeProxyAppsSwitch.setOnCheckedChangeListener { _, isChecked -> - persistentState.excludeAppsInProxy = isChecked + persistentState.excludeAppsInProxy = !isChecked } b.settingsActivityExcludeProxyAppsRl.setOnClickListener { diff --git a/app/src/full/java/com/celzero/bravedns/ui/fragment/DnsProxyListFragment.kt b/app/src/full/java/com/celzero/bravedns/ui/fragment/DnsProxyListFragment.kt index 744c2863f..dcca01bc8 100644 --- a/app/src/full/java/com/celzero/bravedns/ui/fragment/DnsProxyListFragment.kt +++ b/app/src/full/java/com/celzero/bravedns/ui/fragment/DnsProxyListFragment.kt @@ -33,6 +33,9 @@ import com.celzero.bravedns.database.DnsProxyEndpoint import com.celzero.bravedns.databinding.DialogSetDnsProxyBinding import com.celzero.bravedns.databinding.FragmentDnsProxyListBinding import com.celzero.bravedns.service.FirewallManager +import com.celzero.bravedns.service.PersistentState +import com.celzero.bravedns.service.VpnController +import com.celzero.bravedns.util.UIUtils import com.celzero.bravedns.util.Utilities import com.celzero.bravedns.viewmodel.DnsProxyEndpointViewModel import com.google.android.material.dialog.MaterialAlertDialogBuilder @@ -48,6 +51,7 @@ class DnsProxyListFragment : Fragment(R.layout.fragment_dns_proxy_list) { private val b by viewBinding(FragmentDnsProxyListBinding::bind) private val appConfig by inject() + private val persistentState by inject() // DNS Proxy UI Elements private lateinit var dnsProxyRecyclerAdapter: DnsProxyEndpointAdapter @@ -106,11 +110,20 @@ class DnsProxyListFragment : Fragment(R.layout.fragment_dns_proxy_list) { val applyURLBtn = dialogBinding.dialogDnsProxyApplyBtn val cancelURLBtn = dialogBinding.dialogDnsProxyCancelBtn + val lockdownDesc = dialogBinding.dialogDnsProxyLockdownDesc val proxyNameEditText = dialogBinding.dialogDnsProxyEditName val appNameSpinner = dialogBinding.dialogProxySpinnerAppname val ipAddressEditText = dialogBinding.dialogDnsProxyEditIp val portEditText = dialogBinding.dialogDnsProxyEditPort val errorTxt = dialogBinding.dialogDnsProxyErrorText + val excludeAppCheckBox = dialogBinding.dialogDnsProxyExcludeAppsCheck + + excludeAppCheckBox.isChecked = !persistentState.excludeAppsInProxy + excludeAppCheckBox.isEnabled = !VpnController.isVpnLockdown() + lockdownDesc.visibility = if (VpnController.isVpnLockdown()) View.VISIBLE else View.GONE + if (VpnController.isVpnLockdown()) { + excludeAppCheckBox.alpha = 0.5f + } proxyNameEditText.setText( getString(R.string.cd_custom_dns_proxy_name, nextIndex.toString()), TextView.BufferType.EDITABLE @@ -123,6 +136,11 @@ class DnsProxyListFragment : Fragment(R.layout.fragment_dns_proxy_list) { ArrayAdapter(requireContext(), android.R.layout.simple_spinner_dropdown_item, appNames) appNameSpinner.adapter = proxySpinnerAdapter + lockdownDesc.setOnClickListener { + dialog.dismiss() + UIUtils.openVpnProfile(requireContext()) + } + applyURLBtn.setOnClickListener { var port = 0 var isPortValid: Boolean @@ -159,6 +177,7 @@ class DnsProxyListFragment : Fragment(R.layout.fragment_dns_proxy_list) { if (isPortValid && isIpValid) { Logger.d(Logger.LOG_TAG_UI, "new value inserted into DNSProxy") io { insertDNSProxyEndpointDB(mode, name, appName, ip, port) } + persistentState.excludeAppsInProxy = !excludeAppCheckBox.isChecked dialog.dismiss() } else { Logger.i(Logger.LOG_TAG_UI, "cannot insert invalid dns-proxy IPs: $name, $appName") diff --git a/app/src/full/res/layout/dialog_set_dns_proxy.xml b/app/src/full/res/layout/dialog_set_dns_proxy.xml index edbb1bd2c..4def7b970 100644 --- a/app/src/full/res/layout/dialog_set_dns_proxy.xml +++ b/app/src/full/res/layout/dialog_set_dns_proxy.xml @@ -16,6 +16,18 @@ android:text="@string/dns_proxy_dialog_header_dns" android:textSize="@dimen/large_font_text_view" /> + + + + + + + + + + + (true) - // exclude apps which are configured in proxy (socks5, http, orbot) - var excludeAppsInProxy by booleanPref("exclude_apps_in_proxy").withDefault(true) + // exclude apps which are configured in proxy (socks5, http, dns proxy) + var excludeAppsInProxy by booleanPref("exclude_apps_in_proxy").withDefault(false) var orbotConnectionStatus: MutableLiveData = MutableLiveData() var median: MutableLiveData = MutableLiveData() diff --git a/app/src/main/res/drawable/ic_firewall_exclude_off.xml b/app/src/main/res/drawable/ic_firewall_exclude_off.xml index 0d987c2bf..22ba46375 100644 --- a/app/src/main/res/drawable/ic_firewall_exclude_off.xml +++ b/app/src/main/res/drawable/ic_firewall_exclude_off.xml @@ -1,6 +1,6 @@ diff --git a/app/src/main/res/layout/dialog_set_proxy.xml b/app/src/main/res/layout/dialog_set_proxy.xml index dd4f0a1d6..cc2119281 100644 --- a/app/src/main/res/layout/dialog_set_proxy.xml +++ b/app/src/main/res/layout/dialog_set_proxy.xml @@ -27,6 +27,17 @@ android:text="@string/settings_dns_proxy_dialog_app_desc" android:textSize="@dimen/default_font_text_view" /> + + + + + + + + + + Do not route Private IPs (experimental) Exclude LAN, loopback, multicast, link-local routes from Rethink\'s VPN tunnel. - Exclude Proxy apps - Exclude apps that used to setup proxies from Rethink\'s VPN tunnel. + Loopback proxy forwarder apps + When disabled, excludes proxy (SOCKS5, HTTP, DNS) forwarder apps from Rethink\'s VPN tunnel. Enable network visibility Allow requesting apps to access all available networks. These apps may bypass Rethink\'s VPN tunnel on-demand. Some audio/video conference apps like Zoom and Meet may require this to function properly. From 854b3aa5a3d2d533dc12fb23dafb042354948c3b Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Mon, 13 May 2024 21:17:07 +0530 Subject: [PATCH 11/27] observation: close connections on nw change --- .../celzero/bravedns/service/BraveVPNService.kt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app/src/main/java/com/celzero/bravedns/service/BraveVPNService.kt b/app/src/main/java/com/celzero/bravedns/service/BraveVPNService.kt index 1d85fb0e4..86627511b 100644 --- a/app/src/main/java/com/celzero/bravedns/service/BraveVPNService.kt +++ b/app/src/main/java/com/celzero/bravedns/service/BraveVPNService.kt @@ -2055,6 +2055,21 @@ class BraveVPNService : ) } } + + // no need to close the existing connections if the bound networks are changed + // observations on close connections: + // instagram video delays when the network changes, reconnects (5-10s), feeds take longer + // play store downloads completely broke when the network changes + // observations on not closing connections: + // instagram video delays when the network changes, reconnects (5-10s or more), feeds normal + // play store downloads continue when the network changes, resumes after reconnect (5-10s) + // so, not closing connections is better for user experience + /* if (isBoundNetworksChanged) { + logd("bound networks changed, close connections") + io("boundNetworksChanged") { vpnAdapter?.closeAllConnections() } + } */ + + // Workaround for WireGuard connection issues after network change // WireGuard may fail to connect to the server when the network changes. // refresh will do a configuration refresh in tunnel to ensure a successful From 573be6d992efcb7e809feea68349c00075afc907 Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Mon, 13 May 2024 21:18:51 +0530 Subject: [PATCH 12/27] fix: handle exception on adding default transport --- .../java/com/celzero/bravedns/net/go/GoVpnAdapter.kt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/celzero/bravedns/net/go/GoVpnAdapter.kt b/app/src/main/java/com/celzero/bravedns/net/go/GoVpnAdapter.kt index 861f06326..f88cfb36a 100644 --- a/app/src/main/java/com/celzero/bravedns/net/go/GoVpnAdapter.kt +++ b/app/src/main/java/com/celzero/bravedns/net/go/GoVpnAdapter.kt @@ -54,12 +54,12 @@ import com.celzero.bravedns.util.Utilities.showToastUiCentered import com.celzero.bravedns.wireguard.Config import intra.Intra import intra.Tunnel +import java.net.URI import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.koin.core.component.KoinComponent import org.koin.core.component.inject -import java.net.URI /** * This is a VpnAdapter that captures all traffic and routes it through a go-tun2socks instance with @@ -941,7 +941,12 @@ class GoVpnAdapter : KoinComponent { Logger.e(LOG_TAG_VPN, "err new default transport: ${e.message}", e) // most of the android devices have google dns, so add it as default transport // TODO: notify the user that the default transport could not be set - Intra.addDefaultTransport(tunnel, Backend.DNS53, defaultDns, "") + try { + Intra.addDefaultTransport(tunnel, Backend.DNS53, defaultDns, "") + } catch (e: Exception) { + // fixme: this is not expected to happen, should show a notification? + Logger.e(LOG_TAG_VPN, "err add $defaultDns transport: ${e.message}", e) + } } } From a6491c8a47bac19550fefa5f2a929b7733d05281 Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Tue, 14 May 2024 17:47:39 +0530 Subject: [PATCH 13/27] Fix: #1427, disable the Pointer Tagging feature https://github.com/celzero/rethink-app/issues/1427#issuecomment-2108636345 --- app/src/main/AndroidManifest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index cfe5ba312..6f5209cd2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -36,6 +36,7 @@ android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:largeHeap="true" + android:allowNativeHeapPointerTagging="false" android:memtagMode="off" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" From a93365e8d8e3671d83ac54d6e778afb3339133a5 Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Tue, 14 May 2024 17:48:46 +0530 Subject: [PATCH 14/27] bump firestack version for v055j --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index bedc007a9..d7f9a36c4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -247,8 +247,8 @@ dependencies { fullImplementation 'com.github.kirich1409:viewbindingpropertydelegate-noreflection:1.5.9' // from: https://jitpack.io/#celzero/firestack - download 'com.github.celzero:firestack:dd04f72717@aar' - implementation 'com.github.celzero:firestack:dd04f72717@aar' + download 'com.github.celzero:firestack:724773bd97@aar' + implementation 'com.github.celzero:firestack:724773bd97@aar' // Work manager implementation('androidx.work:work-runtime-ktx:2.9.0') { From a120c1d3d4d4c02117a1d911e5b5e8b5cd27b998 Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Tue, 14 May 2024 18:03:44 +0530 Subject: [PATCH 15/27] Fix: add available ips to transport (server_table.xml) --- app/src/main/java/com/celzero/bravedns/net/go/GoVpnAdapter.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/celzero/bravedns/net/go/GoVpnAdapter.kt b/app/src/main/java/com/celzero/bravedns/net/go/GoVpnAdapter.kt index f88cfb36a..447f254cc 100644 --- a/app/src/main/java/com/celzero/bravedns/net/go/GoVpnAdapter.kt +++ b/app/src/main/java/com/celzero/bravedns/net/go/GoVpnAdapter.kt @@ -1097,7 +1097,8 @@ class GoVpnAdapter : KoinComponent { val ips: Array? = res?.getStringArray(R.array.ips) if (urls == null) return "" for (i in urls.indices) { - if (url.contains((urls[i]))) { + // either the url is a substring of urls[i] or urls[i] is a substring of url + if ((url.contains(urls[i])) || (urls[i].contains(url))) { if (ips != null) return ips[i] } } From 203d114283584d80804483aa8b8d888717e7dd29 Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Tue, 14 May 2024 20:00:40 +0530 Subject: [PATCH 16/27] Fix: add available ips to transport --- .../main/java/com/celzero/bravedns/net/go/GoVpnAdapter.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/celzero/bravedns/net/go/GoVpnAdapter.kt b/app/src/main/java/com/celzero/bravedns/net/go/GoVpnAdapter.kt index 447f254cc..706d61f58 100644 --- a/app/src/main/java/com/celzero/bravedns/net/go/GoVpnAdapter.kt +++ b/app/src/main/java/com/celzero/bravedns/net/go/GoVpnAdapter.kt @@ -216,12 +216,12 @@ class GoVpnAdapter : KoinComponent { try { val doh = appConfig.getDOHDetails() url = doh?.dohURL + val ips: String = getIpString(context, url) // change the url from https to http if the isSecure is false if (doh?.isSecure == false) { Logger.d(LOG_TAG_VPN, "changing url from https to http for $url") url = url?.replace("https", "http") } - val ips: String = getIpString(context, url) // add replaces the existing transport with the same id if successful // so no need to remove the transport before adding Intra.addDoHTransport(tunnel, id, url, ips) @@ -240,12 +240,13 @@ class GoVpnAdapter : KoinComponent { try { val dot = appConfig.getDOTDetails() url = dot?.url + // if tls is present, remove it and pass it to getIpString + val ips: String = getIpString(context, url?.replace("tls://", "")) if (dot?.isSecure == true && url?.startsWith("tls") == false) { Logger.d(LOG_TAG_VPN, "adding tls to url for $url") // add tls to the url if isSecure is true and the url does not start with tls url = "tls://$url" } - val ips: String = getIpString(context, url) // add replaces the existing transport with the same id if successful // so no need to remove the transport before adding Intra.addDoTTransport(tunnel, id, url, ips) From 6eb3c7db1c01de8f76d8d009fc7cf4e15e1c709f Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Tue, 14 May 2024 20:19:23 +0530 Subject: [PATCH 17/27] ui: add description for loopback setting in proxy dialog --- .../ui/activity/ProxySettingsActivity.kt | 8 +- app/src/main/res/layout/dialog_set_proxy.xml | 525 +++++++++--------- app/src/main/res/values/strings.xml | 2 +- 3 files changed, 280 insertions(+), 255 deletions(-) diff --git a/app/src/full/java/com/celzero/bravedns/ui/activity/ProxySettingsActivity.kt b/app/src/full/java/com/celzero/bravedns/ui/activity/ProxySettingsActivity.kt index a40c0dd37..95c016e85 100644 --- a/app/src/full/java/com/celzero/bravedns/ui/activity/ProxySettingsActivity.kt +++ b/app/src/full/java/com/celzero/bravedns/ui/activity/ProxySettingsActivity.kt @@ -658,6 +658,7 @@ class ProxySettingsActivity : AppCompatActivity(R.layout.fragment_proxy_configur val udpBlockCheckBox: CheckBox = dialogBinding.dialogProxyUdpCheck val excludeAppCheckBox: CheckBox = dialogBinding.dialogProxyExcludeAppsCheck + headerDesc.visibility = View.GONE udpBlockCheckBox.isChecked = persistentState.getUdpBlocked() excludeAppCheckBox.isChecked = !persistentState.excludeAppsInProxy excludeAppCheckBox.isEnabled = !VpnController.isVpnLockdown() @@ -756,12 +757,7 @@ class ProxySettingsActivity : AppCompatActivity(R.layout.fragment_proxy_configur ) } else { b.settingsActivitySocks5Desc.text = - getString( - R.string.settings_socks_forwarding_desc, - ip, - port.toString(), - app - ) + getString(R.string.settings_socks_forwarding_desc, ip, port.toString(), app) } dialog.dismiss() } else { diff --git a/app/src/main/res/layout/dialog_set_proxy.xml b/app/src/main/res/layout/dialog_set_proxy.xml index cc2119281..a018f9f0b 100644 --- a/app/src/main/res/layout/dialog_set_proxy.xml +++ b/app/src/main/res/layout/dialog_set_proxy.xml @@ -1,278 +1,307 @@ - - - - - - - + app:layout_behavior="@string/appbar_scrolling_view_behavior" + app:layout_scrollFlags="scroll|enterAlways"> + android:layout_height="match_parent" + android:layout_margin="5dp" + android:orientation="vertical" + android:visibility="visible"> - - - - - - - - - - - - + android:layout_gravity="end" + android:paddingStart="10dp" + android:paddingEnd="10dp" + android:text="@string/settings_dns_proxy_dialog_app_desc" + android:textSize="@dimen/default_font_text_view" /> - - - - - - - - + + - - + + + + + + + + - - - - - - + + + + + + + + - - + + + + + + + + - - - - - - + + + + + + + + - - + + + + + + + + - - - - - - + + + + + + + + - - + + + + + + + + + + + + + + + + android:paddingStart="10dp" + android:paddingEnd="10dp" + android:textColor="@color/colorRed_A400" + android:textSize="@dimen/default_font_text_view" /> - - - - - - - - - + android:gravity="end" + android:orientation="horizontal"> + + + + + - + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 80f05f7ec..6f40f4599 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -565,7 +565,7 @@ Username Password set - The selected app will be excluded from the VPN to let it proxy connections on your behalf. + The selected app will be excluded from the VPN to let it proxy connections on your behalf. None From 9d8ccfffea50b05258b54ee027fde175eef5ebd9 Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Wed, 15 May 2024 20:45:21 +0530 Subject: [PATCH 18/27] bump firestack verison --- app/build.gradle | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index d7f9a36c4..08d4e36a4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -247,8 +247,8 @@ dependencies { fullImplementation 'com.github.kirich1409:viewbindingpropertydelegate-noreflection:1.5.9' // from: https://jitpack.io/#celzero/firestack - download 'com.github.celzero:firestack:724773bd97@aar' - implementation 'com.github.celzero:firestack:724773bd97@aar' + download 'com.github.celzero:firestack:3c9b203823@aar' + implementation 'com.github.celzero:firestack:3c9b203823@aar' // Work manager implementation('androidx.work:work-runtime-ktx:2.9.0') { @@ -285,6 +285,10 @@ dependencies { // barcode scanner for wireguard fullImplementation 'com.journeyapps:zxing-android-embedded:4.3.0' + + playImplementation platform('com.google.firebase:firebase-bom:33.0.0') + playImplementation 'com.google.firebase:firebase-crashlytics-ktx' + } // github.com/michel-kraemer/gradle-download-task/issues/131#issuecomment-464476903 From 742e3dadd21366a269e1df52d236f2c4ad61efd6 Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Thu, 16 May 2024 19:12:40 +0530 Subject: [PATCH 19/27] logs: add more logs to local blocklist download --- .../LocalBlocklistCoordinator.kt | 39 +++++++++++++++---- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/app/src/full/java/com/celzero/bravedns/customdownloader/LocalBlocklistCoordinator.kt b/app/src/full/java/com/celzero/bravedns/customdownloader/LocalBlocklistCoordinator.kt index c8a54c7cb..ac531e044 100644 --- a/app/src/full/java/com/celzero/bravedns/customdownloader/LocalBlocklistCoordinator.kt +++ b/app/src/full/java/com/celzero/bravedns/customdownloader/LocalBlocklistCoordinator.kt @@ -45,9 +45,6 @@ import com.celzero.bravedns.util.Utilities.blocklistDownloadBasePath import com.celzero.bravedns.util.Utilities.calculateMd5 import com.celzero.bravedns.util.Utilities.getTagValueFromJson import com.celzero.bravedns.util.Utilities.tempDownloadBasePath -import okhttp3.ResponseBody -import org.koin.core.component.KoinComponent -import org.koin.core.component.inject import java.io.BufferedInputStream import java.io.File import java.io.FileOutputStream @@ -57,6 +54,9 @@ import java.io.OutputStream import java.util.concurrent.CancellationException import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.TimeUnit +import okhttp3.ResponseBody +import org.koin.core.component.KoinComponent +import org.koin.core.component.inject class LocalBlocklistCoordinator(val context: Context, workerParams: WorkerParameters) : CoroutineWorker(context, workerParams), KoinComponent { @@ -89,22 +89,26 @@ class LocalBlocklistCoordinator(val context: Context, workerParams: WorkerParame val timestamp = inputData.getLong("blocklistTimestamp", 0) if (runAttemptCount > 3) { + Logger.w(LOG_TAG_DOWNLOAD, "Local blocklist download failed after 3 attempts") return Result.failure() } if (SystemClock.elapsedRealtime() - startTime > BLOCKLIST_DOWNLOAD_TIMEOUT_MS) { + Logger.w(LOG_TAG_DOWNLOAD, "Local blocklist download timeout") return Result.failure() } return when (processDownload(timestamp)) { false -> { if (isDownloadCancelled()) { + Logger.i(LOG_TAG_DOWNLOAD, "Local blocklist download cancelled") notifyDownloadCancelled(context) } Result.failure() } true -> { // update the download related persistence status on download success + Logger.i(LOG_TAG_DOWNLOAD, "Local blocklist download success, updating ts: $timestamp") updatePersistenceOnCopySuccess(timestamp) Result.success() } @@ -131,7 +135,12 @@ class LocalBlocklistCoordinator(val context: Context, workerParams: WorkerParame private suspend fun processDownload(timestamp: Long): Boolean { // create a temp folder to download, format (timestamp ==> -timestamp) - val file = makeTempDownloadDir(timestamp) ?: return false + val file = makeTempDownloadDir(timestamp) + + if (file == null) { + Logger.e(LOG_TAG_DOWNLOAD, "Error creating temp folder for download") + return false + } Constants.ONDEVICE_BLOCKLISTS_IN_APP.forEachIndexed { _, onDeviceBlocklistsMetadata -> val id = generateCustomDownloadId() @@ -139,13 +148,23 @@ class LocalBlocklistCoordinator(val context: Context, workerParams: WorkerParame downloadStatuses[id] = DownloadStatus.RUNNING val filePath = file.absolutePath + onDeviceBlocklistsMetadata.filename - if (isDownloadCancelled()) return false + Logger.i( + LOG_TAG_DOWNLOAD, + "Downloading file: ${onDeviceBlocklistsMetadata.filename}, url: ${onDeviceBlocklistsMetadata.url}, id: $id" + ) + + if (isDownloadCancelled()) { + Logger.i(LOG_TAG_DOWNLOAD, "Download cancelled, id: $id") + return false + } when (startFileDownload(context, onDeviceBlocklistsMetadata.url, filePath)) { true -> { + Logger.i(LOG_TAG_DOWNLOAD, "Download successful for id: $id") downloadStatuses[id] = DownloadStatus.SUCCESSFUL } false -> { + Logger.e(LOG_TAG_DOWNLOAD, "Download failed for id: $id") downloadStatuses[id] = DownloadStatus.FAILED return false } @@ -232,10 +251,15 @@ class LocalBlocklistCoordinator(val context: Context, workerParams: WorkerParame // create okhttp client with base url val retrofit = getBlocklistBaseBuilder(retryCount).build().create(IBlocklistDownload::class.java) + Logger.i(LOG_TAG_DOWNLOAD, "Downloading file: $fileName, url: $url") val response = retrofit.downloadLocalBlocklistFile(url, persistentState.appVersion, "") - if (response?.isSuccessful == true) { return downloadFile(context, response.body(), fileName) + } else { + Logger.e( + LOG_TAG_DOWNLOAD, + "Error in startFileDownload: ${response?.message()}, code: ${response?.code()}" + ) } } catch (e: Exception) { Logger.e(LOG_TAG_DOWNLOAD, "Error in startFileDownload: ${e.message}", e) @@ -250,6 +274,7 @@ class LocalBlocklistCoordinator(val context: Context, workerParams: WorkerParame } private fun isRetryRequired(retryCount: Int): Boolean { + Logger.i(LOG_TAG_DOWNLOAD, "Retry count: $retryCount") return retryCount < RetrofitManager.Companion.OkHttpDnsType.entries.size - 1 } @@ -335,7 +360,7 @@ class LocalBlocklistCoordinator(val context: Context, workerParams: WorkerParame File(tempDownloadBasePath(context, LOCAL_BLOCKLIST_DOWNLOAD_FOLDER_NAME, timestamp)) if (!from.isDirectory) { - Logger.d(LOG_TAG_DOWNLOAD, "Invalid from: ${from.name} dir") + Logger.i(LOG_TAG_DOWNLOAD, "Invalid from: ${from.name} dir") return false } From 71b5a7513de6bf5082bfc4b2b9543ebc9bf70938 Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Thu, 16 May 2024 19:18:16 +0530 Subject: [PATCH 20/27] wg: clean up wireguard entries in refresh database --- app/src/main/java/com/celzero/bravedns/backup/RestoreAgent.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/src/main/java/com/celzero/bravedns/backup/RestoreAgent.kt b/app/src/main/java/com/celzero/bravedns/backup/RestoreAgent.kt index 6bb8f98bc..243ad54b5 100644 --- a/app/src/main/java/com/celzero/bravedns/backup/RestoreAgent.kt +++ b/app/src/main/java/com/celzero/bravedns/backup/RestoreAgent.kt @@ -281,9 +281,7 @@ class RestoreAgent(val context: Context, workerParams: WorkerParameters) : Logger.i(LOG_TAG_BACKUP_RESTORE, "wireGuard is enabled, reset the wireguard entries") appConfig.removeAllProxies() } - // delete WireGuard related entries from database - Logger.i(LOG_TAG_BACKUP_RESTORE, "wireguard cleanup process") - WireguardManager.restoreProcessDeleteWireGuardEntries() + // cleaning up the wireguard entries are handled in RefreshDatabase } private fun isMetadataCompatible(tempDirectory: String?): Boolean { From 56e192ec75c4bc8099ea8eea596d2bfad68890bb Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Thu, 16 May 2024 20:13:27 +0530 Subject: [PATCH 21/27] ip logs: update flag and target ip if in debug mode --- .../database/ConnectionTrackerRepository.kt | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/celzero/bravedns/database/ConnectionTrackerRepository.kt b/app/src/main/java/com/celzero/bravedns/database/ConnectionTrackerRepository.kt index 293f3dae0..7e79e3b0b 100644 --- a/app/src/main/java/com/celzero/bravedns/database/ConnectionTrackerRepository.kt +++ b/app/src/main/java/com/celzero/bravedns/database/ConnectionTrackerRepository.kt @@ -16,6 +16,8 @@ package com.celzero.bravedns.database import androidx.lifecycle.LiveData +import com.celzero.bravedns.RethinkDnsApplication +import com.celzero.bravedns.RethinkDnsApplication.Companion.DEBUG import com.celzero.bravedns.data.ConnectionSummary import com.celzero.bravedns.data.DataUsage @@ -31,26 +33,27 @@ class ConnectionTrackerRepository(private val connectionTrackerDAO: ConnectionTr suspend fun updateBatch(summary: List) { summary.forEach { - if (it.targetIp.isNullOrEmpty()) { + // update the flag and target ip if in debug mode + if (DEBUG && !it.targetIp.isNullOrEmpty()) { + val flag = it.flag ?: "" connectionTrackerDAO.updateSummary( it.connId, it.downloadBytes, it.uploadBytes, it.duration, it.synack, - it.message + it.message, + it.targetIp, + flag ) } else { - val flag = it.flag ?: "" connectionTrackerDAO.updateSummary( it.connId, it.downloadBytes, it.uploadBytes, it.duration, it.synack, - it.message, - it.targetIp, - flag + it.message ) } } From 3a2996d858a3a9ca9fe002e9e150dd3f7b33729e Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Thu, 16 May 2024 20:14:27 +0530 Subject: [PATCH 22/27] migration: failure check for table changes --- .../celzero/bravedns/database/AppDatabase.kt | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/celzero/bravedns/database/AppDatabase.kt b/app/src/main/java/com/celzero/bravedns/database/AppDatabase.kt index 0aba30c6f..3bd129ca5 100644 --- a/app/src/main/java/com/celzero/bravedns/database/AppDatabase.kt +++ b/app/src/main/java/com/celzero/bravedns/database/AppDatabase.kt @@ -15,6 +15,8 @@ */ package com.celzero.bravedns.database +import Logger +import Logger.LOG_TAG_APP_DB import android.content.Context import androidx.room.Database import androidx.room.Room @@ -53,7 +55,7 @@ import java.io.File DoTEndpoint::class, ODoHEndpoint::class ], - version = 21, + version = 22, exportSchema = false ) @TypeConverters(Converters::class) @@ -94,6 +96,7 @@ abstract class AppDatabase : RoomDatabase() { .addMigrations(migration1819(context)) .addMigrations(MIGRATION_19_20) .addMigrations(MIGRATION_20_21) + .addMigrations(MIGRATION_21_22) .build() private val MIGRATION_1_2: Migration = @@ -898,6 +901,34 @@ abstract class AppDatabase : RoomDatabase() { db.execSQL("DROP TABLE IF EXISTS ProxyEndpoint_backup") } } + + private val MIGRATION_21_22: Migration = + object : Migration(21, 22) { + override fun migrate(db: SupportSQLiteDatabase) { + // fix: migration with the WgConfigFiles seen in play store crash + try { + db.execSQL( + "ALTER TABLE WgConfigFiles ADD COLUMN isLockdown INTEGER NOT NULL DEFAULT 0" + ) + } catch (e: Exception) { + Logger.i(LOG_TAG_APP_DB, "isLockdown column already exists, ignore") + } + try { + db.execSQL( + "ALTER TABLE WgConfigFiles ADD COLUMN isCatchAll INTEGER NOT NULL DEFAULT 0" + ) + } catch (e: Exception) { + Logger.i(LOG_TAG_APP_DB, "isCatchAll column already exists, ignore") + } + try { + db.execSQL( + "ALTER TABLE WgConfigFiles ADD COLUMN oneWireGuard INTEGER NOT NULL DEFAULT 0" + ) + } catch (e: Exception) { + Logger.i(LOG_TAG_APP_DB, "oneWireGuard column already exists, ignore") + } + } + } } // fixme: revisit the links to remove the pragma for each table From 9ea2a23a2e3a99cfb93f742e9875cba2554b8258 Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Fri, 17 May 2024 17:13:43 +0530 Subject: [PATCH 23/27] local blocklist check for play store version --- .../java/com/celzero/bravedns/net/go/GoVpnAdapter.kt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/celzero/bravedns/net/go/GoVpnAdapter.kt b/app/src/main/java/com/celzero/bravedns/net/go/GoVpnAdapter.kt index 706d61f58..9895cbcf2 100644 --- a/app/src/main/java/com/celzero/bravedns/net/go/GoVpnAdapter.kt +++ b/app/src/main/java/com/celzero/bravedns/net/go/GoVpnAdapter.kt @@ -50,6 +50,7 @@ import com.celzero.bravedns.util.InternetProtocol import com.celzero.bravedns.util.Utilities import com.celzero.bravedns.util.Utilities.blocklistDir import com.celzero.bravedns.util.Utilities.blocklistFile +import com.celzero.bravedns.util.Utilities.isPlayStoreFlavour import com.celzero.bravedns.util.Utilities.showToastUiCentered import com.celzero.bravedns.wireguard.Config import intra.Intra @@ -431,7 +432,7 @@ class GoVpnAdapter : KoinComponent { Logger.d(LOG_TAG_VPN, "set brave dns to tunnel (local/remote)") // enable local blocklist if enabled - if (persistentState.blocklistEnabled) { + if (persistentState.blocklistEnabled && !Utilities.isPlayStoreFlavour()) { setRDNSLocal() } else { // remove local blocklist, if any @@ -831,7 +832,7 @@ class GoVpnAdapter : KoinComponent { fun getRDNS(type: RethinkBlocklistManager.RethinkBlocklistType): backend.RDNS? { try { - return if (type.isLocal()) { + return if (type.isLocal() && !isPlayStoreFlavour()) { getRDNSResolver()?.rdnsLocal } else { getRDNSResolver()?.rdnsRemote @@ -968,7 +969,7 @@ class GoVpnAdapter : KoinComponent { // no need to send the dnsProxy.port for the below method, as it is not expecting port Intra.setSystemDNS(tunnel, sysDnsStr) } catch (e: Exception) { // this is not expected to happen - Logger.e(LOG_TAG_VPN, "set system dns: could not parse system dns", e) + Logger.e(LOG_TAG_VPN, "set system dns: could not parse: $systemDns", e) // remove the system dns, if it could not be set tunnel.resolver.remove(Backend.System) } @@ -1042,6 +1043,8 @@ class GoVpnAdapter : KoinComponent { } private fun resetLocalBlocklistStampFromTunnel() { + if (Utilities.isPlayStoreFlavour()) return + try { val rl = getRDNS(RethinkBlocklistManager.RethinkBlocklistType.LOCAL) if (rl == null) { From 6b77b2fc4cb1c280e85e8614049ff771c095023f Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Fri, 17 May 2024 17:14:09 +0530 Subject: [PATCH 24/27] wg refresh improvements --- .../bravedns/service/BraveVPNService.kt | 39 ++++++++++++------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/celzero/bravedns/service/BraveVPNService.kt b/app/src/main/java/com/celzero/bravedns/service/BraveVPNService.kt index 86627511b..75e27bd21 100644 --- a/app/src/main/java/com/celzero/bravedns/service/BraveVPNService.kt +++ b/app/src/main/java/com/celzero/bravedns/service/BraveVPNService.kt @@ -55,6 +55,7 @@ import androidx.core.app.ServiceCompat import androidx.core.content.ContextCompat import androidx.lifecycle.MutableLiveData import androidx.lifecycle.Observer +import androidx.paging.LOG_TAG import backend.Backend import backend.RDNS import backend.Stats @@ -94,6 +95,7 @@ import com.celzero.bravedns.util.Utilities.isAtleastS import com.celzero.bravedns.util.Utilities.isAtleastU import com.celzero.bravedns.util.Utilities.isMissingOrInvalidUid import com.celzero.bravedns.util.Utilities.isNetworkSame +import com.celzero.bravedns.util.Utilities.isPlayStoreFlavour import com.celzero.bravedns.util.Utilities.isUnspecifiedIp import com.celzero.bravedns.util.Utilities.showToastUiCentered import com.google.common.collect.Sets @@ -1823,6 +1825,8 @@ class BraveVPNService : } private fun spawnLocalBlocklistStampUpdate() { + if (isPlayStoreFlavour()) return + io("dnsStampUpdate") { vpnAdapter?.setRDNSStamp() } } @@ -2069,7 +2073,6 @@ class BraveVPNService : io("boundNetworksChanged") { vpnAdapter?.closeAllConnections() } } */ - // Workaround for WireGuard connection issues after network change // WireGuard may fail to connect to the server when the network changes. // refresh will do a configuration refresh in tunnel to ensure a successful @@ -2954,6 +2957,7 @@ class BraveVPNService : override fun onProxiesStopped() { // clear the proxy handshake times + logd("onProxiesStopped; clear the handshake times") wgHandShakeCheckpoints.clear() } @@ -3303,12 +3307,11 @@ class BraveVPNService : // ie, if lockdown is enabled, split-tunneling happens as expected but if // lockdown is disabled, it has the effect of blocking all connections val canRoute = vpnAdapter?.canRouteIp(proxyId, connTracker.destIP, true) + logd("flow: wg is active/lockdown/catch-all; $proxyId, $connId, $uid; canRoute? $canRoute") return if (canRoute == true) { handleProxyHandshake(proxyId) - logd("flow: wg is active/lockdown/catch-all; $proxyId, $connId, $uid") persistAndConstructFlowResponse(connTracker, proxyId, connId, uid) } else { - logd("flow: wg is active/lockdown/catch-all, but no route, $connId, $uid") persistAndConstructFlowResponse(connTracker, baseOrExit, connId, uid) } } else { @@ -3435,32 +3438,40 @@ class BraveVPNService : return } + val latestCheckpoint = wgHandShakeCheckpoints[id] + if (latestCheckpoint == null) { + Logger.w(LOG_TAG_VPN, "flow: latest checkpoint is null for $id") + return + } + + val stats = vpnAdapter?.getProxyStats(id) + if (stats == null) { + Logger.w(LOG_TAG_VPN, "flow: stats is null for $id") + return + } + val realtime = elapsedRealtime() - val latestCheckpoint = wgHandShakeCheckpoints[id] ?: return val cpInterval = realtime - latestCheckpoint val cpIntervalSecs = TimeUnit.MILLISECONDS.toSeconds(cpInterval) if (cpInterval < this.checkpointInterval) { - logd("flow: handshake skipping check for $id, $cpIntervalSecs") + logd("flow: skip refresh for $id, within interval: $cpIntervalSecs") return } - val stats = vpnAdapter?.getProxyStats(id) ?: return val lastHandShake = stats.lastOK - logd("flow: handshake check for $id, $lastHandShake, interval: $cpIntervalSecs") if (lastHandShake <= 0) { - logd("flow: handshake is not established for $id, $lastHandShake, returning") + Logger.w(LOG_TAG_VPN, "flow: skip refresh, handshake never done for $id") return } + logd("flow: handshake check for $id, $lastHandShake, interval: $cpIntervalSecs") + wgHandShakeCheckpoints[id] = realtime val currTimeMs = System.currentTimeMillis() val durationMs = currTimeMs - lastHandShake val durationSecs = TimeUnit.MILLISECONDS.toSeconds(durationMs) // if the last handshake is older than the timeout, refresh the proxy - if (durationMs > wgHandshakeTimeout) { - wgHandShakeCheckpoints[id] = realtime - Logger.i(LOG_TAG_VPN, "flow: handshake timeout for $id, $durationSecs, refreshing") + val mustRefresh = durationMs > wgHandshakeTimeout + Logger.i(LOG_TAG_VPN, "flow: refresh $id after $durationSecs: $mustRefresh") + if (mustRefresh) { io("proxyHandshake") { vpnAdapter?.refreshProxy(id) } - } else { - Logger.i(LOG_TAG_VPN, "flow: handshake is within timeout for $id, $durationSecs") - wgHandShakeCheckpoints[id] = realtime } } From 23628f257b88d552567ee6971edacf76d1903ece Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Fri, 17 May 2024 17:15:48 +0530 Subject: [PATCH 25/27] DEBUG: update debug variable in play version --- .../java/com/celzero/bravedns/RethinkDnsApplicationPlay.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/play/java/com/celzero/bravedns/RethinkDnsApplicationPlay.kt b/app/src/play/java/com/celzero/bravedns/RethinkDnsApplicationPlay.kt index 029d713c1..39b389799 100644 --- a/app/src/play/java/com/celzero/bravedns/RethinkDnsApplicationPlay.kt +++ b/app/src/play/java/com/celzero/bravedns/RethinkDnsApplicationPlay.kt @@ -31,6 +31,10 @@ class RethinkDnsApplicationPlay : Application() { override fun onCreate() { super.onCreate() + RethinkDnsApplication.DEBUG = + applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE == + ApplicationInfo.FLAG_DEBUGGABLE + startKoin { if (BuildConfig.DEBUG) androidLogger() androidContext(this@RethinkDnsApplicationPlay) From 9719e780a020b801d446dba8da29744499e9cbe4 Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Fri, 17 May 2024 17:20:20 +0530 Subject: [PATCH 26/27] logs: update log stmts --- .../customdownloader/LocalBlocklistCoordinator.kt | 1 + .../bravedns/service/RethinkBlocklistManager.kt | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/src/full/java/com/celzero/bravedns/customdownloader/LocalBlocklistCoordinator.kt b/app/src/full/java/com/celzero/bravedns/customdownloader/LocalBlocklistCoordinator.kt index ac531e044..cd35121df 100644 --- a/app/src/full/java/com/celzero/bravedns/customdownloader/LocalBlocklistCoordinator.kt +++ b/app/src/full/java/com/celzero/bravedns/customdownloader/LocalBlocklistCoordinator.kt @@ -104,6 +104,7 @@ class LocalBlocklistCoordinator(val context: Context, workerParams: WorkerParame Logger.i(LOG_TAG_DOWNLOAD, "Local blocklist download cancelled") notifyDownloadCancelled(context) } + Logger.i(LOG_TAG_DOWNLOAD, "Local blocklist download failed") Result.failure() } true -> { diff --git a/app/src/main/java/com/celzero/bravedns/service/RethinkBlocklistManager.kt b/app/src/main/java/com/celzero/bravedns/service/RethinkBlocklistManager.kt index a33e48de4..efcf8036d 100644 --- a/app/src/main/java/com/celzero/bravedns/service/RethinkBlocklistManager.kt +++ b/app/src/main/java/com/celzero/bravedns/service/RethinkBlocklistManager.kt @@ -41,12 +41,12 @@ import com.google.common.collect.Multimap import com.google.gson.Gson import com.google.gson.GsonBuilder import com.google.gson.JsonObject +import java.io.IOException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.koin.core.component.KoinComponent import org.koin.core.component.inject -import java.io.IOException object RethinkBlocklistManager : KoinComponent { @@ -373,11 +373,9 @@ object RethinkBlocklistManager : KoinComponent { suspend fun getStamp(fileValues: Set, type: RethinkBlocklistType): String { return try { val flags = convertListToCsv(fileValues) - Logger.d( - LOG_TAG_VPN, - "${type.name} flags: $flags, ${getRDNS(type)?.flagsToStamp(flags, Backend.EB32)}" - ) - getRDNS(type)?.flagsToStamp(flags, Backend.EB32) ?: "" + val flags2Stamp = getRDNS(type)?.flagsToStamp(flags, Backend.EB32) + Logger.d(LOG_TAG_VPN, "${type.name} flags: $flags; stamp: $flags2Stamp") + flags2Stamp ?: "" } catch (e: java.lang.Exception) { Logger.e(LOG_TAG_VPN, "err stamp2tags: ${e.message}, $e") "" @@ -386,7 +384,9 @@ object RethinkBlocklistManager : KoinComponent { suspend fun getTagsFromStamp(stamp: String, type: RethinkBlocklistType): Set { return try { - convertCsvToList(getRDNS(type)?.stampToFlags(stamp)) + val tags = convertCsvToList(getRDNS(type)?.stampToFlags(stamp)) + Logger.d(LOG_TAG_VPN, "${type.name} stamp: $stamp; tags: $tags") + tags } catch (e: Exception) { Logger.e(LOG_TAG_VPN, "err tags2stamp: ${e.message}, $e") setOf() From 4673aac2fc6a1d4c7715462b29e3e001f33b48ef Mon Sep 17 00:00:00 2001 From: hussainmohd-a Date: Fri, 17 May 2024 17:44:23 +0530 Subject: [PATCH 27/27] crashlytics only for play and website version --- app/build.gradle | 10 ++++++++-- app/google-services.json | 29 +++++++++++++++++++++++++++++ build.gradle | 3 ++- 3 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 app/google-services.json diff --git a/app/build.gradle b/app/build.gradle index 08d4e36a4..18526459c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,6 +4,8 @@ plugins { // to download blocklists for the headless variant id "de.undercouch.download" version "5.3.0" id 'kotlin-android' + id 'com.google.gms.google-services' + id 'com.google.firebase.crashlytics' } def keystorePropertiesFile = rootProject.file("keystore.properties") @@ -247,8 +249,8 @@ dependencies { fullImplementation 'com.github.kirich1409:viewbindingpropertydelegate-noreflection:1.5.9' // from: https://jitpack.io/#celzero/firestack - download 'com.github.celzero:firestack:3c9b203823@aar' - implementation 'com.github.celzero:firestack:3c9b203823@aar' + download 'com.github.celzero:firestack:d92f398622@aar' + implementation 'com.github.celzero:firestack:d92f398622@aar' // Work manager implementation('androidx.work:work-runtime-ktx:2.9.0') { @@ -288,7 +290,11 @@ dependencies { playImplementation platform('com.google.firebase:firebase-bom:33.0.0') playImplementation 'com.google.firebase:firebase-crashlytics-ktx' + playImplementation 'com.google.firebase:firebase-crashlytics-ndk' + websiteImplementation platform('com.google.firebase:firebase-bom:33.0.0') + websiteImplementation 'com.google.firebase:firebase-crashlytics-ktx' + websiteImplementation 'com.google.firebase:firebase-crashlytics-ndk' } // github.com/michel-kraemer/gradle-download-task/issues/131#issuecomment-464476903 diff --git a/app/google-services.json b/app/google-services.json new file mode 100644 index 000000000..8fe85e0a0 --- /dev/null +++ b/app/google-services.json @@ -0,0 +1,29 @@ +{ + "project_info": { + "project_number": "974915159594", + "project_id": "rethink-dns-firewall", + "storage_bucket": "rethink-dns-firewall.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:974915159594:android:ed4f2e6c806fa816bda553", + "android_client_info": { + "package_name": "com.celzero.bravedns" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyBsj6i5hZNgsYopDLZlqV7jFAAp1F0y6JQ" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 2867b6ccb..5f9e8e2ef 100644 --- a/build.gradle +++ b/build.gradle @@ -11,9 +11,10 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:8.3.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files + classpath 'com.google.gms:google-services:4.4.1' + classpath 'com.google.firebase:firebase-crashlytics-gradle:3.0.1' } }