From 41c7f5d8baa8f985c7eaa1741b8f735df4c03ad2 Mon Sep 17 00:00:00 2001 From: bemusementpark Date: Mon, 7 Oct 2024 22:15:58 +1030 Subject: [PATCH] Generate binary --- app/build.gradle | 24 ++++++++++++ app/ipToCode.kts | 38 +++++++++++++++++++ .../thoughtcrime/securesms/util/IP2Country.kt | 25 ++++++------ .../securesms/util/IP2CountryTest.kt | 5 +-- 4 files changed, 77 insertions(+), 15 deletions(-) create mode 100644 app/ipToCode.kts diff --git a/app/build.gradle b/app/build.gradle index 1d72dfb0fd..664739dd89 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -105,6 +105,12 @@ android { String sharedTestDir = 'src/sharedTest/java' test.java.srcDirs += sharedTestDir androidTest.java.srcDirs += sharedTestDir + main { + assets.srcDirs += "$buildDir/generated/binary" + } + test { + resources.srcDirs += "$buildDir/generated/binary" + } } buildTypes { @@ -219,6 +225,24 @@ android { } } +task ipToCode { + def inputFile = file("${projectDir}/src/main/assets/csv/geolite2_country_blocks_ipv4.csv") + + def outputDir = "${buildDir}/generated/binary" + def outputFile = new File(outputDir, "geolite2_country_blocks_ipv4.bin") + + outputs.file outputFile + + doLast { + exec { + commandLine "kotlin", "ipToCode.kts", inputFile.absolutePath, outputFile.absolutePath + println "Generated binary file at: ${outputFile.absolutePath}" + } + } +} + +preBuild.dependsOn ipToCode + dependencies { implementation project(':content-descriptions') diff --git a/app/ipToCode.kts b/app/ipToCode.kts new file mode 100644 index 0000000000..f73fec1cb1 --- /dev/null +++ b/app/ipToCode.kts @@ -0,0 +1,38 @@ +import java.io.File +import java.io.DataOutputStream +import java.io.FileOutputStream + +// Check that the correct number of arguments is provided +if (args.size < 2) { + throw IllegalArgumentException("Please provide both input and output file paths.") +} + +// Get the input and output file paths from the command line arguments +val inputFile = File(args[0]) +val outputFile = File(args[1]).apply { parentFile.mkdirs() } + +// Ensure the input file exists +if (!inputFile.exists()) { + throw IllegalArgumentException("Input file does not exist: ${inputFile.absolutePath}") +} + +// Create a DataOutputStream to write binary data +DataOutputStream(FileOutputStream(outputFile)).use { out -> + inputFile.useLines { lines -> + var prevCode = -1 + lines.drop(1).forEach { line -> + runCatching { + val ints = line.split(".", "/", ",") + val code = ints[5].toInt().also { if (it == prevCode) return@forEach } + val ip = ints.take(4).fold(0) { acc, s -> acc shl 8 or s.toInt() } + + out.writeInt(ip) + out.writeInt(code) + + prevCode = code + } + } + } +} + +println("Processed data written to: ${outputFile.absolutePath}") diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/IP2Country.kt b/app/src/main/java/org/thoughtcrime/securesms/util/IP2Country.kt index e56bd7209a..0700a862fd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/IP2Country.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/IP2Country.kt @@ -9,11 +9,12 @@ import com.opencsv.CSVReader import org.session.libsession.snode.OnionRequestAPI import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.ThreadUtils +import java.io.DataInputStream import java.io.InputStream import java.io.InputStreamReader import java.util.TreeMap -private fun ipv4Int(ip: String): Int { +private fun ipv4Int(ip: String): UInt { var result = 0L var currentValue = 0L var octetIndex = 0 @@ -32,7 +33,7 @@ private fun ipv4Int(ip: String): Int { // Handle the last octet result = result or (currentValue shl (8 * (3 - octetIndex))) - return result.toInt() + return result.toUInt() } class IP2Country internal constructor( @@ -41,15 +42,16 @@ class IP2Country internal constructor( ) { val countryNamesCache = mutableMapOf() - private val ipv4ToCountry: TreeMap by lazy { - openStream("csv/geolite2_country_blocks_ipv4.csv") - .let(::InputStreamReader) - .let(::CSVReader) - .use { csv -> - csv.skip(1) - - csv.associateTo(TreeMap()) { cols -> - ipv4Int(cols[0]) to cols[1].toIntOrNull() + private val ipv4ToCountry by lazy { + openStream("geolite2_country_blocks_ipv4.bin") + .let(::DataInputStream) + .use { + TreeMap().apply { + while (it.available() > 0) { + val ip = it.readInt().toUInt() + val code = it.readInt() + put(ip, code) + } } } } @@ -115,7 +117,6 @@ class IP2Country internal constructor( } } Broadcaster(context).broadcast("onionRequestPathCountriesLoaded") - Log.d("Loki", "Finished preloading onion request path countries.") } } // endregion diff --git a/app/src/test/java/org/thoughtcrime/securesms/util/IP2CountryTest.kt b/app/src/test/java/org/thoughtcrime/securesms/util/IP2CountryTest.kt index 6d75b9c736..d13ecb4c9b 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/util/IP2CountryTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/util/IP2CountryTest.kt @@ -24,12 +24,11 @@ class IP2CountryTest( @JvmStatic @Parameterized.Parameters fun data(): Collection> = listOf( - arrayOf("223.121.63.255", "Hong Kong"), arrayOf("223.121.64.0", "Hong Kong"), arrayOf("223.121.64.1", "Hong Kong"), - arrayOf("223.121.64.2", "Hong Kong"), - arrayOf("223.121.64.3", "Hong Kong"), + arrayOf("223.121.127.0", "Hong Kong"), arrayOf("223.121.128.0", "China"), + arrayOf("223.121.129.0", "China"), arrayOf("223.122.0.0", "Hong Kong"), arrayOf("223.123.0.0", "Pakistan"), arrayOf("223.123.128.0", "China"),