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

Added synchronization

parent 0953691d
......@@ -34,30 +34,33 @@ import org.minidns.dnsmessage.DnsMessage
class QueryListener(private val context: Context) : QueryListener {
private val writeQueriesToLog = context.getPreferences().shouldLogDnsQueriesToConsole()
private val logQueriesToDb = context.getPreferences().queryLoggingEnabled
private val waitingQueryLogs = LinkedHashMap<Int, DnsQuery>()
private var waitingQueryLogs = LinkedHashMap<Int, DnsQuery>()
// Question ID -> <Query, Insert> (true if the query has already been inserted)
private val queryLogState: MutableMap<Int, Boolean> = mutableMapOf()
// Query -> Has already been inserted
private val doneQueries = mutableMapOf<DnsQuery, Boolean>()
private val askedServer:String
private var doneQueries = mutableMapOf<DnsQuery, Boolean>()
private val askedServer: String
private var nextQueryId = 0L
var lastDnsResponse:DnsMessage? = null
private val databaseWriteJob:Job
var lastDnsResponse: DnsMessage? = null
private val databaseWriteJob: Job
init {
val config = context.getPreferences().dnsServerConfig
askedServer = if(config.hasTlsServer()) {
askedServer = if (config.hasTlsServer()) {
"tls::" + config.servers.first().address.host!!
} else {
"https::" + (config as HttpsDnsServerInformation).serverConfigurations.values.first().urlCreator.address.getUrl(false)
"https::" + (config as HttpsDnsServerInformation).serverConfigurations.values.first().urlCreator.address.getUrl(
false
)
}
nextQueryId = context.getDatabase().dnsQueryDao().getLastInsertedId() + 1
databaseWriteJob = GlobalScope.launch(newSingleThreadContext("QueryListener-DatabaseWrite")) {
while (isActive) {
delay(1500)
insertQueries()
databaseWriteJob =
GlobalScope.launch(newSingleThreadContext("QueryListener-DatabaseWrite")) {
while (isActive) {
delay(1500)
insertQueries()
}
}
}
}
override suspend fun onDeviceQuery(questionMessage: DnsMessage, srcPort: Int) {
......@@ -73,14 +76,20 @@ class QueryListener(private val context: Context) : QueryListener {
questionTime = System.currentTimeMillis(),
responses = mutableListOf()
)
query.id = nextQueryId++
waitingQueryLogs[questionMessage.id] = query
queryLogState[questionMessage.id] = false
synchronized(waitingQueryLogs) {
query.id = nextQueryId++
waitingQueryLogs[questionMessage.id] = query
queryLogState[questionMessage.id] = false
}
}
}
override suspend fun onQueryForwarded(questionMessage: DnsMessage, destination: UpstreamAddress, usedHandle:DnsHandle) {
if(writeQueriesToLog) {
override suspend fun onQueryForwarded(
questionMessage: DnsMessage,
destination: UpstreamAddress,
usedHandle: DnsHandle
) {
if (writeQueriesToLog) {
context.log("Query with ID ${questionMessage.id} forwarded by $usedHandle")
}
......@@ -89,20 +98,25 @@ class QueryListener(private val context: Context) : QueryListener {
}
}
override suspend fun onQueryResponse(responseMessage: DnsMessage, source: QueryListener.Source) {
override suspend fun onQueryResponse(
responseMessage: DnsMessage,
source: QueryListener.Source
) {
if (writeQueriesToLog) {
context.log("Returned from $source: $responseMessage")
}
lastDnsResponse = responseMessage
if (logQueriesToDb) {
val query = waitingQueryLogs.remove(responseMessage.id)!!
val query = synchronized(waitingQueryLogs) {
waitingQueryLogs.remove(responseMessage.id)!!
}
query.responseTime = System.currentTimeMillis()
for (answer in responseMessage.answerSection) {
query.addResponse(answer)
}
query.responseSource = source
doneQueries[query] = queryLogState.remove(responseMessage.id)!!
doneQueries[query] = queryLogState.remove(responseMessage.id)!!
}
}
......@@ -114,16 +128,20 @@ class QueryListener(private val context: Context) : QueryListener {
}
private fun insertQueries() {
if(waitingQueryLogs.isEmpty() && doneQueries.isEmpty()) return
val currentInsertions = waitingQueryLogs.toMap()
val currentDoneInsertions = doneQueries.toMap()
doneQueries.clear()
if (waitingQueryLogs.isEmpty() && doneQueries.isEmpty()) return
val currentInsertions:Map<Int, DnsQuery>
val currentDoneInsertions:Map<DnsQuery, Boolean>
synchronized(waitingQueryLogs) {
currentInsertions = waitingQueryLogs.toMap()
currentDoneInsertions = doneQueries
doneQueries.clear()
}
val database = context.getDatabase()
val dao = database.dnsQueryDao()
database.runInTransaction {
currentInsertions.forEach { (key, value) ->
if(queryLogState[key]!!) {
if (queryLogState[key]!!) {
dao.insert(value)
queryLogState[key] = true
} else {
......@@ -131,10 +149,9 @@ class QueryListener(private val context: Context) : QueryListener {
}
}
currentDoneInsertions.forEach { (key, value) ->
if(value) dao.update(key)
if (value) dao.update(key)
else dao.insert(key)
}
}
}
}
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