Commit 7ab2553f authored by Daniel Wolf's avatar Daniel Wolf
Browse files

Track both ipv4 and ipv6 targets for user-created dns rules

parent c79568a5
......@@ -2,7 +2,7 @@
"formatVersion": 1,
"database": {
"version": 6,
"identityHash": "d58aeff97d571489a0d8406a0863c0e0",
"identityHash": "bc5641edd5decbd17c2316602e2828c1",
"entities": [
{
"tableName": "CachedResponse",
......@@ -101,7 +101,7 @@
},
{
"tableName": "DnsRule",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `stagingType` INTEGER, `type` INTEGER NOT NULL, `host` TEXT NOT NULL, `target` TEXT NOT NULL, `importedFrom` INTEGER, FOREIGN KEY(`importedFrom`) REFERENCES `HostSource`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `stagingType` INTEGER, `type` INTEGER NOT NULL, `host` TEXT NOT NULL, `target` TEXT NOT NULL, `ipv6Target` TEXT, `importedFrom` INTEGER, FOREIGN KEY(`importedFrom`) REFERENCES `HostSource`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [
{
"fieldPath": "id",
......@@ -133,6 +133,12 @@
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "ipv6Target",
"columnName": "ipv6Target",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "importedFrom",
"columnName": "importedFrom",
......@@ -229,7 +235,7 @@
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd58aeff97d571489a0d8406a0863c0e0')"
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'bc5641edd5decbd17c2316602e2828c1')"
]
}
}
\ No newline at end of file
......@@ -51,7 +51,7 @@ private val MIGRATION_4_5 = migration(4, 5) {
}
private val MIGRATION_5_6 = migration(5, 6) {
Logger.logIfOpen("DB_MIGRATION", "Migrating from 5 to 6")
it.execSQL("CREATE TABLE IF NOT EXISTS `DnsRule` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `type` INTEGER NOT NULL, `host` TEXT NOT NULL, `target` TEXT NOT NULL, `importedFrom` INTEGER, `stagingType` INTEGER, FOREIGN KEY(`importedFrom`) REFERENCES `HostSource`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )")
it.execSQL("CREATE TABLE IF NOT EXISTS `DnsRule` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `type` INTEGER NOT NULL, `host` TEXT NOT NULL, `target` TEXT NOT NULL, `importedFrom` INTEGER, `stagingType` INTEGER, `secondaryTarget` TEXT, FOREIGN KEY(`importedFrom`) REFERENCES `HostSource`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )")
it.execSQL("CREATE TABLE IF NOT EXISTS `HostSource` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `source` TEXT NOT NULL, `enabled` INTEGER NOT NULL)")
it.execSQL("CREATE INDEX `index_DnsRule_importedFrom` ON `DnsRule` (`importedFrom`)")
it.execSQL("CREATE INDEX `index_DnsRule_host` ON `DnsRule` (`host`)")
......
......@@ -57,7 +57,7 @@ interface DnsRuleDao {
@Query("SELECT COUNT(*) FROM DnsRule WHERE importedFrom IS NULL")
fun getUserCount():Long
@Query("SELECT target FROM DnsRule WHERE host=:host AND type = :type AND (importedFrom is NULL OR (SELECT enabled FROM HostSource h WHERE h.id=importedFrom) = 1) AND (importedFrom IS NOT NULL OR :useUserRules=1)LIMIT 1")
@Query("SELECT CASE WHEN :type=28 THEN IFNULL(ipv6Target, target) ELSE target END FROM DnsRule WHERE host=:host AND (type = :type OR type=255) AND (importedFrom is NULL OR (SELECT enabled FROM HostSource h WHERE h.id=importedFrom) = 1) AND (importedFrom IS NOT NULL OR :useUserRules=1) LIMIT 1")
fun findRuleTarget(host: String, type: Record.TYPE, useUserRules:Boolean): String?
@Query("DELETE FROM DnsRule WHERE importedFrom=:sourceId")
......
......@@ -37,6 +37,7 @@ data class DnsRule(
val type:Record.TYPE,
val host: String,
val target: String,
val ipv6Target:String? = null,
val importedFrom: Long? = null
) {
@PrimaryKey(autoGenerate = true) var id: Long = 0
......
......@@ -31,7 +31,8 @@ import java.net.Inet6Address
*
* You can contact the developer at daniel.wolf@frostnerd.com.
*/
class DnsRuleDialog(context:Context, dnsRule: DnsRule? = null, onRuleCreated:(DnsRule) -> Unit): AlertDialog(context, context.getPreferences().theme.dialogStyle) {
class DnsRuleDialog(context: Context, dnsRule: DnsRule? = null, onRuleCreated: (DnsRule) -> Unit) :
AlertDialog(context, context.getPreferences().theme.dialogStyle) {
init {
val view = layoutInflater.inflate(R.layout.dialog_create_dnsrule, null, false)
setView(view)
......@@ -48,50 +49,78 @@ class DnsRuleDialog(context:Context, dnsRule: DnsRule? = null, onRuleCreated:(Dn
view.host.error = null
view.ipv4Til.error = null
view.ipv6Til.error = null
if(view.host.text.isNullOrBlank()) {
if (view.host.text.isNullOrBlank()) {
view.host.error = context.getString(R.string.dialog_newdnsrule_host_invalid)
valid = false
} else {
val ipv4Valid = isIpv4Address(view.ipv4Address.text.toString())
val ipv6Valid = isIpv6Address(view.ipv6Address.text.toString())
val bothEmpty = view.ipv4Address.text.isNullOrEmpty() && view.ipv6Address.text.isNullOrEmpty()
if(!ipv4Valid || bothEmpty) {
if (!ipv4Valid || bothEmpty) {
valid = false
view.ipv4Address.error = context.getString(R.string.dialog_newdnsrule_ipv4_invalid)
}
if(!ipv6Valid || bothEmpty) {
if (!ipv6Valid || bothEmpty) {
valid = false
view.ipv6Address.error = context.getString(R.string.dialog_newdnsrule_ipv6_invalid)
}
}
if (valid) {
dismiss()
val type = when {
!view.ipv4Address.text.isNullOrBlank() && !view.ipv6Address.text.isNullOrBlank() -> {
Record.TYPE.ANY
}
!view.ipv4Address.text.isNullOrBlank() -> Record.TYPE.A
else -> Record.TYPE.AAAA
}
val primaryTarget = when (type) {
Record.TYPE.A, Record.TYPE.ANY -> view.ipv4Address.text.toString()
else -> view.ipv6Address.text.toString()
}
val secondaryTarget = when (type) {
Record.TYPE.AAAA, Record.TYPE.ANY -> view.ipv6Address.text.toString()
else -> null
}
val newRule = dnsRule?.copy(
type = type,
host = view.host.text.toString(),
target = primaryTarget,
ipv6Target = secondaryTarget
) ?: DnsRule(Record.TYPE.A, view.host.text.toString(), view.ipv4Address.text.toString())
onRuleCreated(
dnsRule?.copy(host = view.host.text.toString(), target = view.ipv4Address.text.toString())
?: DnsRule(Record.TYPE.A, view.host.text.toString(), view.ipv4Address.text.toString())
newRule
)
}
}
}
if(dnsRule != null) {
if (dnsRule != null) {
view.host.setText(dnsRule.host)
when {
dnsRule.type == Record.TYPE.A -> view.ipv4Address.setText(dnsRule.target)
dnsRule.type == Record.TYPE.AAAA -> view.ipv4Address.setText(dnsRule.target)
dnsRule.type == Record.TYPE.ANY -> {
view.ipv4Address.setText(dnsRule.target)
view.ipv6Address.setText(dnsRule.ipv6Target)
}
}
}
}
private fun isIpv4Address(text:String?): Boolean {
private fun isIpv4Address(text: String?): Boolean {
return text.isNullOrBlank() || try {
Inet4Address.getByName(text)
true
} catch (ex:Exception) {
} catch (ex: Exception) {
false
}
}
private fun isIpv6Address(text:String?): Boolean {
private fun isIpv6Address(text: String?): Boolean {
return text.isNullOrBlank() || try {
Inet6Address.getByName(text)
true
} catch (ex:Exception) {
} catch (ex: Exception) {
false
}
}
......
......@@ -216,7 +216,7 @@ class RuleImportService : Service() {
val hosts = parsers[parsers.keys.first()]!!.second
if (hosts.size > 5000 || forceCommit) {
getDatabase().dnsRuleDao().insertAll(hosts.map {
DnsRule(it.type, it.host, it.target, source.id)
DnsRule(it.type, it.host, it.target, null, source.id)
})
ruleCount += hosts.size
hosts.clear()
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment