Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Charles
Nebulo
Commits
25a2546c
Commit
25a2546c
authored
Dec 02, 2019
by
Daniel Wolf
Browse files
Merge remote-tracking branch 'origin/master'
parents
09a75acf
1c41c300
Changes
18
Expand all
Hide whitespace changes
Inline
Side-by-side
app/build.gradle
View file @
25a2546c
...
...
@@ -25,8 +25,8 @@ android {
applicationId
"com.frostnerd.smokescreen"
minSdkVersion
21
targetSdkVersion
29
versionCode
5
2
versionName
"1.
0.3
"
versionCode
5
3
versionName
"1.
1.0
"
testInstrumentationRunner
"androidx.test.runner.AndroidJUnitRunner"
buildConfigField
(
"Boolean"
,
"FROM_CI"
,
String
.
valueOf
(
getSystemVariableOrDefault
(
"CI_COMMIT_SHORT_SHA"
,
""
)
!=
""
))
...
...
@@ -85,7 +85,6 @@ android {
adblocker
{
dimension
"version"
versionNameSuffix
"-adblock"
versionCode
52
}
normal
{
dimension
"version"
...
...
@@ -125,7 +124,7 @@ dependencies {
implementation
'com.frostnerd.utilskt:preferences:1.5.17'
// https://git.frostnerd.com/AndroidUtils/preferenceskt
implementation
'com.frostnerd.utilskt:navigationdraweractivity:1.3.29'
// https://git.frostnerd.com/AndroidUtils/navigationdraweractivity
implementation
'com.frostnerd.utilskt:encrypteddnstunnelproxy:1.5.1
69
'
// https://git.frostnerd.com/AndroidUtils/encrypteddnstunnelproxy
implementation
'com.frostnerd.utilskt:encrypteddnstunnelproxy:1.5.1
71
'
// https://git.frostnerd.com/AndroidUtils/encrypteddnstunnelproxy
implementation
'com.frostnerd.utilskt:general:1.0.19'
// https://git.frostnerd.com/AndroidUtils/generalkt
implementation
'com.frostnerd.utilskt:adapters:1.1.6'
// https://git.frostnerd.com/AndroidUtils/Adapters
...
...
app/build/outputs/mapping/adblocker/fdroid/mapping.txt
View file @
25a2546c
This diff is collapsed.
Click to expand it.
app/build/outputs/mapping/normal/release/mapping.txt
View file @
25a2546c
This source diff could not be displayed because it is too large. You can
view the blob
instead.
app/src/main/java/com/frostnerd/smokescreen/SmokeScreen.kt
View file @
25a2546c
...
...
@@ -22,6 +22,7 @@ import kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.GlobalScope
import
kotlinx.coroutines.launch
import
leakcanary.LeakSentry
import
java.net.InetAddress
import
java.util.*
import
kotlin.system.exitProcess
...
...
@@ -96,59 +97,62 @@ class SmokeScreen : Application() {
fun
initSentry
(
forceStatus
:
Status
=
Status
.
NONE
)
{
if
(!
BuildConfig
.
DEBUG
&&
BuildConfig
.
SENTRY_DSN
!=
"dummy"
)
{
val
enabledType
=
getPreferences
().
crashreportingType
if
(
forceStatus
!=
Status
.
DATASAVING
&&
(
enabledType
==
Crashreporting
.
FULL
||
forceStatus
==
Status
.
ENABLED
))
{
// Enable Sentry in full mode
// This passes some device-related data, but nothing which allows user actions to be tracked across the app
// Info: Some data is attached by the AndroidEventBuilderHelper class, which is present by default
GlobalScope
.
launch
(
Dispatchers
.
IO
)
{
Sentry
.
init
(
BuildConfig
.
SENTRY_DSN
,
AndroidSentryClientFactory
(
this
@SmokeScreen
)
)
Sentry
.
getContext
().
user
=
User
(
getPreferences
().
crashReportingUUID
,
null
,
null
,
null
)
Sentry
.
getStoredClient
().
apply
{
addTag
(
"user.language"
,
Locale
.
getDefault
().
displayLanguage
)
addTag
(
"app.database_version"
,
AppDatabase
.
currentVersion
.
toString
())
addTag
(
"app.dns_server_name"
,
getPreferences
().
dnsServerConfig
.
name
)
addTag
(
"app.dns_server_primary"
,
getPreferences
().
dnsServerConfig
.
servers
[
0
].
address
.
formatToString
()
)
addTag
(
"app.dns_server_secondary"
,
getPreferences
().
dnsServerConfig
.
servers
.
getOrNull
(
1
)
?.
address
?.
formatToString
()
GlobalScope
.
launch
(
Dispatchers
.
IO
)
{
val
hostName
=
InetAddress
.
getLocalHost
().
hostName
if
(!
hostName
.
startsWith
(
"mars-sandbox"
,
true
))
{
val
enabledType
=
getPreferences
().
crashreportingType
if
(
forceStatus
!=
Status
.
DATASAVING
&&
(
enabledType
==
Crashreporting
.
FULL
||
forceStatus
==
Status
.
ENABLED
))
{
// Enable Sentry in full mode
// This passes some device-related data, but nothing which allows user actions to be tracked across the app
// Info: Some data is attached by the AndroidEventBuilderHelper class, which is present by default
Sentry
.
init
(
BuildConfig
.
SENTRY_DSN
,
AndroidSentryClientFactory
(
this
@SmokeScreen
)
)
addTag
(
"app.installer_package"
,
packageManager
.
getInstallerPackageName
(
packageName
)
Sentry
.
getContext
().
user
=
User
(
getPreferences
().
crashReportingUUID
,
null
,
null
,
null
)
Sentry
.
getStoredClient
().
apply
{
addTag
(
"user.language"
,
Locale
.
getDefault
().
displayLanguage
)
addTag
(
"app.database_version"
,
AppDatabase
.
currentVersion
.
toString
())
addTag
(
"app.dns_server_name"
,
getPreferences
().
dnsServerConfig
.
name
)
addTag
(
"app.dns_server_primary"
,
getPreferences
().
dnsServerConfig
.
servers
[
0
].
address
.
formatToString
()
)
addTag
(
"app.dns_server_secondary"
,
getPreferences
().
dnsServerConfig
.
servers
.
getOrNull
(
1
)
?.
address
?.
formatToString
()
)
addTag
(
"app.installer_package"
,
packageManager
.
getInstallerPackageName
(
packageName
)
)
addTag
(
"richdata"
,
"true"
)
addTag
(
"app.fromCi"
,
BuildConfig
.
FROM_CI
.
toString
())
addTag
(
"app.commit"
,
BuildConfig
.
COMMIT_HASH
)
}
}
else
if
(
enabledType
==
Crashreporting
.
MINIMAL
||
forceStatus
==
Status
.
DATASAVING
)
{
// Inits Sentry in datasaving mode
// Only data absolutely necessary is transmitted (Android version, app version).
// Only crashes will be reported, no regular events.
Sentry
.
init
(
BuildConfig
.
SENTRY_DSN
,
AndroidSentryClientFactory
(
this
@SmokeScreen
)
)
addTag
(
"richdata"
,
"true"
)
addTag
(
"app.fromCi"
,
BuildConfig
.
FROM_CI
.
toString
())
addTag
(
"app.commit"
,
BuildConfig
.
COMMIT_HASH
)
}
}
}
else
if
(
enabledType
==
Crashreporting
.
MINIMAL
||
forceStatus
==
Status
.
DATASAVING
){
// Inits Sentry in datasaving mode
// Only data absolutely necessary is transmitted (Android version, app version).
// Only crashes will be reported, no regular events.
GlobalScope
.
launch
(
Dispatchers
.
IO
)
{
Sentry
.
init
(
BuildConfig
.
SENTRY_DSN
,
AndroidSentryClientFactory
(
this
@SmokeScreen
)
)
Sentry
.
getContext
().
user
=
User
(
"anon-"
+
BuildConfig
.
VERSION_CODE
,
null
,
null
,
null
)
Sentry
.
getStoredClient
().
apply
{
addTag
(
"richdata"
,
"false"
)
addTag
(
"dist"
,
BuildConfig
.
VERSION_CODE
.
toString
())
addTag
(
"app.commit"
,
BuildConfig
.
COMMIT_HASH
)
addTag
(
"app.fromCi"
,
BuildConfig
.
FROM_CI
.
toString
())
addExtra
(
"dist"
,
BuildConfig
.
VERSION_CODE
)
this
.
builderHelpers
.
forEach
{
this
.
removeBuilderHelper
(
it
)
Sentry
.
getContext
().
user
=
User
(
"anon-"
+
BuildConfig
.
VERSION_CODE
,
null
,
null
,
null
)
Sentry
.
getStoredClient
().
apply
{
addTag
(
"richdata"
,
"false"
)
addTag
(
"dist"
,
BuildConfig
.
VERSION_CODE
.
toString
())
addTag
(
"app.commit"
,
BuildConfig
.
COMMIT_HASH
)
addTag
(
"app.fromCi"
,
BuildConfig
.
FROM_CI
.
toString
())
addExtra
(
"dist"
,
BuildConfig
.
VERSION_CODE
)
this
.
builderHelpers
.
forEach
{
this
.
removeBuilderHelper
(
it
)
}
this
.
addBuilderHelper
(
DatasavingSentryEventHelper
())
}
this
.
addBuilderHelper
(
DatasavingSentryEventHelper
())
}
}
}
...
...
app/src/main/java/com/frostnerd/smokescreen/dialog/ServerChoosalDialog.kt
View file @
25a2546c
...
...
@@ -41,20 +41,25 @@ import kotlinx.coroutines.launch
*/
class
ServerChoosalDialog
(
context
:
AppCompatActivity
,
selectedServer
:
DnsServerInformation
<
*
>?,
showTls
:
Boolean
=
selectedServer
?.
hasTlsServer
()
?:
true
,
onEntrySelected
:
(
config
:
DnsServerInformation
<
*
>)
->
Unit
)
:
BaseDialog
(
context
,
context
.
getPreferences
().
theme
.
dialogStyle
)
{
private
var
populationJob
:
Job
?
=
null
private
var
currentSelectedServer
:
DnsServerInformation
<
*
>
private
var
currentSelectedServer
:
DnsServerInformation
<
*
>
?
private
lateinit
var
defaultConfig
:
List
<
DnsServerInformation
<
*
>>
private
lateinit
var
userConfig
:
List
<
UserServerConfiguration
>
constructor
(
context
:
AppCompatActivity
,
onEntrySelected
:
(
config
:
DnsServerInformation
<
*
>)
->
Unit
):
this
(
context
,
context
.
getPreferences
().
dnsServerConfig
,
onEntrySelected
=
onEntrySelected
)
init
{
val
view
=
layoutInflater
.
inflate
(
R
.
layout
.
dialog_server_configuration
,
null
,
false
)
setTitle
(
R
.
string
.
dialog_serverconfiguration_title
)
setView
(
view
)
currentSelectedServer
=
context
.
getPreferences
().
dnsServerConfig
currentSelectedServer
=
selectedServer
setButton
(
DialogInterface
.
BUTTON_NEUTRAL
,
context
.
getString
(
android
.
R
.
string
.
cancel
)
...
...
@@ -62,10 +67,9 @@ class ServerChoosalDialog(
setButton
(
DialogInterface
.
BUTTON_POSITIVE
,
context
.
getString
(
android
.
R
.
string
.
ok
)
)
{
_
,
_
->
onEntry
Selected
.
invoke
(
current
Selected
Server
)
current
Selected
Server
?.
apply
(
onEntry
Selected
)
}
val
isCurrentServerTls
=
currentSelectedServer
.
hasTlsServer
()
loadServerData
(
isCurrentServerTls
)
loadServerData
(
showTls
)
val
spinnerAdapter
=
ArrayAdapter
<
String
>(
context
,
android
.
R
.
layout
.
simple_spinner_item
,
...
...
@@ -77,7 +81,7 @@ class ServerChoosalDialog(
spinnerAdapter
.
setDropDownViewResource
(
R
.
layout
.
item_tasker_action_spinner_dropdown_item
)
val
spinner
=
view
.
findViewById
<
Spinner
>(
R
.
id
.
spinner
)
spinner
.
adapter
=
spinnerAdapter
if
(
isCurrentServer
Tls
)
spinner
.
setSelection
(
1
)
if
(
show
Tls
)
spinner
.
setSelection
(
1
)
view
.
findViewById
<
RadioGroup
>(
R
.
id
.
knownServersGroup
).
setOnCheckedChangeListener
{
group
,
_
->
val
button
=
view
.
findViewById
(
group
.
checkedRadioButtonId
)
as
RadioButton
val
payload
=
button
.
tag
...
...
@@ -174,6 +178,7 @@ class ServerChoosalDialog(
}
private
fun
markCurrentSelectedServer
()
{
val
currentSelectedServer
=
this
.
currentSelectedServer
?:
return
for
(
id
in
0
until
knownServersGroup
.
childCount
)
{
val
child
=
knownServersGroup
.
getChildAt
(
id
)
as
RadioButton
val
payload
=
child
.
tag
...
...
@@ -299,7 +304,7 @@ class ServerChoosalDialog(
currentSelectedServer
=
if
(
userConfiguration
.
isHttpsServer
())
AbstractHttpsDNSHandle
.
KNOWN_DNS_SERVERS
.
minBy
{
it
.
key
}
!!
.
value
else
AbstractTLSDnsHandle
.
KNOWN_DNS_SERVERS
.
minBy
{
it
.
key
}
!!
.
value
markCurrentSelectedServer
()
context
.
getPreferences
().
dnsServerConfig
=
currentSelectedServer
context
.
getPreferences
().
dnsServerConfig
=
currentSelectedServer
!!
}
knownServersGroup
.
removeView
(
button
)
}.
show
()
...
...
@@ -348,7 +353,7 @@ class ServerChoosalDialog(
currentSelectedServer
=
if
(
isHttps
)
AbstractHttpsDNSHandle
.
KNOWN_DNS_SERVERS
.
minBy
{
it
.
key
}
!!
.
value
else
AbstractTLSDnsHandle
.
KNOWN_DNS_SERVERS
.
minBy
{
it
.
key
}
!!
.
value
markCurrentSelectedServer
()
context
.
getPreferences
().
dnsServerConfig
=
currentSelectedServer
context
.
getPreferences
().
dnsServerConfig
=
currentSelectedServer
!!
}
knownServersGroup
.
removeView
(
button
)
}.
show
()
...
...
app/src/main/java/com/frostnerd/smokescreen/tasker/ConfigureActivity.kt
View file @
25a2546c
...
...
@@ -12,12 +12,10 @@ import android.widget.ArrayAdapter
import
com.frostnerd.dnstunnelproxy.DnsServerInformation
import
com.frostnerd.encrypteddnstunnelproxy.HttpsDnsServerInformation
import
com.frostnerd.lifecyclemanagement.BaseActivity
import
com.frostnerd.smokescreen.
R
import
com.frostnerd.smokescreen.
*
import
com.frostnerd.smokescreen.activity.BackgroundVpnConfigureActivity
import
com.frostnerd.smokescreen.dialog.NewServerDialog
import
com.frostnerd.smokescreen.fromServerUrls
import
com.frostnerd.smokescreen.hasHttpsServer
import
com.frostnerd.smokescreen.tlsServerFromHosts
import
com.frostnerd.smokescreen.dialog.ServerChoosalDialog
import
com.google.android.material.textfield.TextInputEditText
import
com.google.android.material.textfield.TextInputLayout
import
kotlinx.android.synthetic.main.activity_tasker_configure.*
...
...
@@ -74,11 +72,11 @@ class ConfigureActivity : BaseActivity() {
"start"
->
{
actionType
.
setSelection
(
0
)
startIfRunning
.
isChecked
=
settings
.
getBoolean
(
TaskerHelper
.
DATA_KEY_STARTIFRUNNING
,
true
)
useServer
sFromConfig
.
isChecked
=
!
settings
.
containsKey
(
TaskerHelper
.
DATA_KEY_PRIMARYSERVER
)
&&
!
settings
.
containsKey
(
use
Custom
Server
.
isChecked
=
settings
.
containsKey
(
TaskerHelper
.
DATA_KEY_PRIMARYSERVER
)
||
settings
.
containsKey
(
BackgroundVpnConfigureActivity
.
extraKeyServerConfig
)
if
(
!
useServer
sFromConfig
.
isChecked
)
{
if
(
use
Custom
Server
.
isChecked
)
{
if
(
settings
.
containsKey
(
TaskerHelper
.
DATA_KEY_PRIMARYSERVER
))
{
serverType
.
setSelection
(
0
)
primaryServer
.
setText
(
settings
.
getString
(
TaskerHelper
.
DATA_KEY_PRIMARYSERVER
))
...
...
@@ -110,8 +108,8 @@ class ConfigureActivity : BaseActivity() {
}
private
fun
createLayout
()
{
useServer
sFromConfig
.
setOnCheckedChangeListener
{
_
,
isChecked
->
if
(
isChecked
)
{
use
Custom
Server
.
setOnCheckedChangeListener
{
_
,
isChecked
->
if
(
!
isChecked
)
{
serverConfigWrap
.
visibility
=
View
.
GONE
serverType
.
visibility
=
View
.
GONE
}
else
{
...
...
@@ -157,6 +155,15 @@ class ConfigureActivity : BaseActivity() {
setHints
()
}
}
selectServer
.
setOnClickListener
{
ServerChoosalDialog
(
this
@ConfigureActivity
,
null
,
serverType
.
selectedItemPosition
==
1
)
{
val
typePosition
=
if
(
it
.
hasTlsServer
())
1
else
0
if
(
serverType
.
selectedItemPosition
!=
typePosition
)
serverType
.
setSelection
(
typePosition
)
primaryServer
.
setText
(
it
.
servers
.
first
().
address
.
formatToString
())
if
(
it
.
servers
.
size
>
1
)
secondaryServer
.
setText
(
it
.
servers
.
last
().
address
.
formatToString
())
else
secondaryServer
.
setText
(
""
)
}.
show
()
}
addUrlTextWatcher
(
primaryServerWrap
,
primaryServer
,
false
)
addUrlTextWatcher
(
secondaryServerWrap
,
secondaryServer
,
true
)
setHints
()
...
...
@@ -213,7 +220,7 @@ class ConfigureActivity : BaseActivity() {
)
if
(
action
==
"start"
)
{
settings
.
putBoolean
(
TaskerHelper
.
DATA_KEY_STARTIFRUNNING
,
startIfRunning
.
isChecked
)
if
(
!
useServer
sFromConfig
.
isChecked
)
{
if
(
use
Custom
Server
.
isChecked
)
{
if
(
primaryServerWrap
.
error
==
null
&&
secondaryServerWrap
.
error
==
null
)
{
...
...
app/src/main/java/com/frostnerd/smokescreen/util/proxy/DnsRuleResolver.kt
View file @
25a2546c
...
...
@@ -79,86 +79,81 @@ class DnsRuleResolver(context: Context) : LocalResolver(false) {
})
}
override
suspend
fun
canResolve
(
question
:
Question
):
Boolean
{
return
if
((
ruleCount
==
0
||
(
ruleCount
!=
null
&&
ruleCount
==
whitelistCount
))
||
(
question
.
type
!=
Record
.
TYPE
.
A
&&
question
.
type
!=
Record
.
TYPE
.
AAAA
))
{
false
}
else
{
val
uniformQuestion
=
question
.
name
.
toString
().
replace
(
wwwRegex
,
""
).
toLowerCase
(
Locale
.
ROOT
)
val
hostHash
=
hashHost
(
uniformQuestion
,
question
.
type
)
val
wildcardHostHash
=
hashHost
(
uniformQuestion
,
Record
.
TYPE
.
ANY
)
private
fun
findRuleTarget
(
question
:
String
,
type
:
Record
.
TYPE
):
String
?
{
val
uniformQuestion
=
question
.
replace
(
wwwRegex
,
""
).
toLowerCase
(
Locale
.
ROOT
)
val
hostHash
=
hashHost
(
uniformQuestion
,
type
)
val
wildcardHostHash
=
hashHost
(
uniformQuestion
,
Record
.
TYPE
.
ANY
)
if
(
cachedNonIncluded
.
size
!=
0
&&
cachedNonIncluded
.
contains
(
hostHash
))
return
false
if
(
whitelistCount
!=
0
)
{
if
(
cachedNonWildcardWhitelisted
.
size
!=
0
&&
cachedNonWildcardWhitelisted
.
contains
(
wildcardHostHash
))
return
false
else
if
(
cachedWildcardWhitelisted
.
size
!=
0
&&
cachedWildcardWhitelisted
.
contains
(
wildcardHostHash
))
return
false
}
if
(
nonWildcardCount
!=
0
&&
cachedResolved
.
size
!=
0
)
{
val
res
=
cachedResolved
[
hostHash
]
if
(
res
!=
null
)
{
resolveResults
[
question
.
hashCode
()]
=
res
return
true
}
if
(
cachedNonIncluded
.
size
!=
0
&&
cachedNonIncluded
.
contains
(
hostHash
))
return
null
if
(
whitelistCount
!=
0
)
{
if
(
cachedNonWildcardWhitelisted
.
size
!=
0
&&
cachedNonWildcardWhitelisted
.
contains
(
wildcardHostHash
))
return
null
else
if
(
cachedWildcardWhitelisted
.
size
!=
0
&&
cachedWildcardWhitelisted
.
contains
(
wildcardHostHash
))
return
null
}
if
(
nonWildcardCount
!=
0
&&
cachedResolved
.
size
!=
0
)
{
val
res
=
cachedResolved
[
hostHash
]
if
(
res
!=
null
)
{
return
res
}
if
(
wildcardCount
!=
0
&&
cachedWildcardResolved
.
size
!=
0
)
{
val
res
=
cachedWildcardResolved
[
hostHash
]
if
(
res
!=
null
)
{
resolveResults
[
question
.
hashCode
()]
=
res
return
true
}
}
if
(
wildcardCount
!=
0
&&
cachedWildcardResolved
.
size
!=
0
)
{
val
res
=
cachedWildcardResolved
[
hostHash
]
if
(
res
!=
null
)
{
return
res
}
}
val
whitelistEntry
:
DnsRule
?
=
if
(
whitelistCount
!=
0
)
{
val
normal
=
if
(
nonWildcardWhitelistCount
!=
0
&&
(
nonWildcardWhitelistCount
==
null
||
nonWildcardWhitelistCount
!=
whitelistCount
))
dao
.
findNonWildcardWhitelistEntry
(
uniformQuestion
,
useUserRules
).
firstOrNull
()
else
null
normal
?:
if
(
wildcardWhitelistCount
!=
0
)
dao
.
findPossibleWildcardRuleTarget
(
uniformQuestion
,
question
.
type
,
useUserRules
,
true
,
false
).
firstOrNull
{
DnsRuleDialog
.
databaseHostToMatcher
(
it
.
host
).
reset
(
uniformQuestion
)
.
matches
()
}
else
null
val
whitelistEntry
:
DnsRule
?
=
if
(
whitelistCount
!=
0
)
{
val
normal
=
if
(
nonWildcardWhitelistCount
!=
0
&&
(
nonWildcardWhitelistCount
==
null
||
nonWildcardWhitelistCount
!=
whitelistCount
))
dao
.
findNonWildcardWhitelistEntry
(
uniformQuestion
,
useUserRules
).
firstOrNull
()
else
null
normal
?:
if
(
wildcardWhitelistCount
!=
0
)
dao
.
findPossibleWildcardRuleTarget
(
uniformQuestion
,
type
,
useUserRules
,
true
,
false
).
firstOrNull
{
DnsRuleDialog
.
databaseHostToMatcher
(
it
.
host
).
reset
(
uniformQuestion
)
.
matches
()
}
else
null
}
else
null
if
(
whitelistEntry
!=
null
)
{
if
(
whitelistEntry
.
isWildcard
)
cachedWildcardWhitelisted
.
add
(
wildcardHostHash
)
else
cachedNonWildcardWhitelisted
.
add
(
wildcardHostHash
)
if
(
cachedWildcardWhitelisted
.
size
>=
maxWhitelistCacheSize
*
2
)
cachedWildcardWhitelisted
.
clear
()
if
(
cachedNonWildcardWhitelisted
.
size
>=
maxWhitelistCacheSize
)
cachedNonWildcardWhitelisted
.
clear
()
if
(
whitelistEntry
!=
null
)
{
if
(
whitelistEntry
.
isWildcard
)
cachedWildcardWhitelisted
.
add
(
wildcardHostHash
)
else
cachedNonWildcardWhitelisted
.
add
(
wildcardHostHash
)
false
}
else
{
val
resolveResult
=
if
(
nonWildcardCount
!=
0
)
{
if
(
nonWildcardCount
==
cachedResolved
.
size
)
{
null
// We would have hit cache otherwise
}
else
{
dao
.
findRuleTarget
(
uniformQuestion
,
question
.
type
,
useUserRules
)
?.
let
{
when
(
it
)
{
"0"
->
"0.0.0.0"
"1"
->
{
if
(
question
.
type
==
Record
.
TYPE
.
AAAA
)
"::1
"
else
"127.0.0.1"
}
else
->
it
if
(
cachedWildcardWhitelisted
.
size
>=
maxWhitelistCacheSize
*
2
)
cachedWildcardWhitelisted
.
clear
()
if
(
cachedNonWildcardWhitelisted
.
size
>=
maxWhitelistCacheSize
)
cachedNonWildcardWhitelisted
.
clear
()
return
null
}
else
{
val
resolveResult
=
if
(
nonWildcardCount
!=
0
)
{
if
(
nonWildcardCount
==
cachedResolved
.
size
)
{
null
// We would have hit cache otherwise
}
else
{
dao
.
findRuleTarget
(
uniformQuestion
,
type
,
useUserRules
)
?.
let
{
when
(
it
)
{
"0"
->
"0.0.0.0
"
"1"
->
{
if
(
type
==
Record
.
TYPE
.
AAAA
)
"::1"
else
"127.0.0.1"
}
else
->
it
}
}
}
else
null
if
(
resolveResult
!=
null
)
{
}
}
}
else
null
when
{
resolveResult
!=
null
->
{
cachedResolved
[
hostHash
]
=
resolveResult
re
solveResults
[
question
.
hashCode
()]
=
resolveResult
true
}
else
if
(
wildcardCount
!=
0
)
{
re
turn
resolveResult
}
wildcardCount
!=
0
->
{
val
wildcardResolveResult
=
dao
.
findPossibleWildcardRuleTarget
(
uniformQuestion
,
question
.
type
,
type
,
useUserRules
,
false
,
true
...
...
@@ -166,37 +161,49 @@ class DnsRuleResolver(context: Context) : LocalResolver(false) {
DnsRuleDialog
.
databaseHostToMatcher
(
it
.
host
)
.
reset
(
uniformQuestion
).
matches
()
}
?.
let
{
if
(
question
.
type
==
Record
.
TYPE
.
AAAA
)
it
.
ipv6Target
if
(
type
==
Record
.
TYPE
.
AAAA
)
it
.
ipv6Target
?:
it
.
target
else
it
.
target
}
?.
let
{
when
(
it
)
{
"0"
->
"0.0.0.0"
"1"
->
{
if
(
question
.
type
==
Record
.
TYPE
.
AAAA
)
"::1"
if
(
type
==
Record
.
TYPE
.
AAAA
)
"::1"
else
"127.0.0.1"
}
else
->
it
}
}
if
(
wildcardResolveResult
!=
null
)
{
return
if
(
wildcardResolveResult
!=
null
)
{
cachedWildcardResolved
[
hostHash
]
=
wildcardResolveResult
resolveResults
[
question
.
hashCode
()]
=
wildcardResolveResult
true
wildcardResolveResult
}
else
{
if
(
cachedNonIncluded
.
size
>=
maxWhitelistCacheSize
)
cachedNonIncluded
.
clear
()
cachedNonIncluded
.
add
(
hostHash
)
false
null
}
}
else
{
}
else
->
{
if
(
cachedNonIncluded
.
size
>=
maxWhitelistCacheSize
)
cachedNonIncluded
.
clear
()
cachedNonIncluded
.
add
(
hostHash
)
false
return
null
}
}
}
}
override
suspend
fun
canResolve
(
question
:
Question
):
Boolean
{
return
if
((
ruleCount
==
0
||
(
ruleCount
!=
null
&&
ruleCount
==
whitelistCount
))
||
(
question
.
type
!=
Record
.
TYPE
.
A
&&
question
.
type
!=
Record
.
TYPE
.
AAAA
))
{
false
}
else
{
val
res
=
findRuleTarget
(
question
.
name
.
toString
(),
question
.
type
)
return
if
(
res
!=
null
)
{
resolveResults
[
question
.
hashCode
()]
=
res
true
}
else
false
}
}
// A fast hashing function with high(er) collision rate
// As only a few hosts are stored at the same time the collision rate is not important.
// The effective room is 2^31
...
...
@@ -233,7 +240,10 @@ class DnsRuleResolver(context: Context) : LocalResolver(false) {
// Handle CNAME Cloaking
// Does not need to handle whitelist as the query has already been forwarded
override
suspend
fun
mapResponse
(
message
:
DnsMessage
):
DnsMessage
{
if
(
ruleCount
==
0
||
(
ruleCount
!=
null
&&
ruleCount
==
whitelistCount
))
return
message
// No rules or only whitelist rules present
if
(
ruleCount
==
0
||
(
ruleCount
!=
null
&&
ruleCount
==
whitelistCount
)
||
message
.
questions
.
size
==
0
)
return
message
// No rules or only whitelist rules present
else
if
(
whitelistCount
!=
0
&&
hashHost
(
message
.
question
.
name
.
toString
().
replace
(
wwwRegex
,
""
).
toLowerCase
(
Locale
.
ROOT
),
message
.
question
.
type
).
let
{
cachedWildcardWhitelisted
.
contains
(
it
)
||
cachedNonWildcardWhitelisted
.
contains
(
it
)
})
return
message
else
if
(!
message
.
answerSection
.
any
{
it
.
type
==
Record
.
TYPE
.
CNAME
})
return
message
...
...
@@ -290,46 +300,7 @@ class DnsRuleResolver(context: Context) : LocalResolver(false) {
}
private
fun
resolveForCname
(
host
:
String
,
type
:
Record
.
TYPE
):
Data
?
{
val
uniformQuestion
=
host
.
replace
(
wwwRegex
,
""
).
toLowerCase
(
Locale
.
ROOT
)
var
entry
=
if
(
nonWildcardCount
!=
0
)
{
dao
.
findRuleTarget
(
uniformQuestion
,
type
,
useUserRules
)
?.
let
{
when
(
it
)
{
"0"
->
"0.0.0.0"
"1"
->
{
if
(
type
==
Record
.
TYPE
.
AAAA
)
"::1"
else
"127.0.0.1"
}
else
->
it
}
}
}
else
null
if
(
entry
==
null
&&
wildcardCount
!=
0
)
{
entry
=
dao
.
findPossibleWildcardRuleTarget
(
uniformQuestion
,
type
,
useUserRules
,
false
,
true
).
firstOrNull
{
DnsRuleDialog
.
databaseHostToMatcher
(
it
.
host
)
.
reset
(
uniformQuestion
).
matches
()
}
?.
let
{
if
(
type
==
Record
.
TYPE
.
AAAA
)
it
.
ipv6Target
?:
it
.
target
else
it
.
target
}
?.
let
{
when
(
it
)
{
"0"
->
"0.0.0.0"
"1"
->
{
if
(
type
==
Record
.
TYPE
.
AAAA
)
"::1"
else
"127.0.0.1"
}
else
->
it
}
}
}
val
entry
=
findRuleTarget
(
host
,
type
)
return
if
(
entry
!=
null
)
{
if
(
type
==
Record
.
TYPE
.
A
)
A
(
entry
)
...
...
app/src/main/res/layout/activity_tasker_configure.xml
View file @
25a2546c