Skip to content

Commit

Permalink
Prepare DoH lookup
Browse files Browse the repository at this point in the history
  • Loading branch information
stoyicker committed Aug 8, 2023
1 parent 3494fa5 commit dfbe90f
Show file tree
Hide file tree
Showing 10 changed files with 119 additions and 18 deletions.
8 changes: 8 additions & 0 deletions .idea/jsLibraryMappings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 21 additions & 3 deletions library/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,38 @@ kotlin {
js(IR) {
browser()
nodejs()
binaries.executable()
}

sourceSets {
val commonMain by getting {
val versionKtor = "2.3.3"
commonMain.get().dependencies {
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
implementation("io.ktor:ktor-client-core:$versionKtor")
}
val jvmMain by getting {
dependencies {
implementation("io.ktor:ktor-client-okhttp:$versionKtor")
}
}
val androidMain by getting {
dependsOn(jvmMain)
}
val appleMain by getting {
dependencies {
implementation("io.ktor:ktor-client-darwin:$versionKtor")
}
}
val jsMain by getting {
dependencies {
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
implementation("io.ktor:ktor-client-js:$versionKtor")
}
}
}
}

android {
compileSdk = 33
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
defaultConfig {
minSdk = 1
}
Expand Down
4 changes: 4 additions & 0 deletions library/src/androidMain/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.tidal.networktime.internal

import io.ktor.client.HttpClient
import io.ktor.client.HttpClientConfig
import io.ktor.client.engine.darwin.Darwin

internal actual class HttpClientFactory {

actual operator fun invoke(config: HttpClientConfig<*>.() -> Unit) = HttpClient(Darwin, config)
}
14 changes: 8 additions & 6 deletions library/src/commonMain/kotlin/com/tidal/networktime/NTPServer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,31 @@ import kotlin.time.Duration.Companion.seconds
* Describes a host name that can resolve to any number of NTP unicast servers.
*
* @param hostName The host name.
* @param responseTimeout The timeout for receiving responses from servers resolved from [hostName].
* @param dnsResolutionStrategy Can be used for filtering resolved address on [hostName] based on
* @param lookupTimeout The timeout for DNS lookup over HTTPs.
* @param queryTimeout The timeout for receiving responses from servers resolved from [hostName].
* @param dnsLookupStrategy Can be used for filtering resolved address on [hostName] based on
* IP version.
* @param queriesPerResolvedAddress The amount of queries to perform to each resolved address. More
* queries may or may not increase precision, but they will make synchronization take longer and
* also cause more server load.
* @param waitBetweenResolvedAddressQueries The amount of time to wait before consecutive requests
* to the same resolved address.
* @param pinnedPortNumber The port number to send packets on. If null, a random choice of port
* @param pinnedPortNumber The port number to send packets on. If null, a random choice of port to
* be made for every packet, as recommended by RFC 9109.
* @param ntpVersion The version number to write in packets.
*/
class NTPServer(
val hostName: String,
val responseTimeout: Duration = 5.seconds,
val dnsResolutionStrategy: DNSResolutionStrategy = DNSResolutionStrategy.ALL,
val lookupTimeout: Duration = 3.seconds,
val queryTimeout: Duration = 5.seconds,
val dnsLookupStrategy: DNSLookupStrategy = DNSLookupStrategy.ALL,
val queriesPerResolvedAddress: Short = 3,
val waitBetweenResolvedAddressQueries: Duration = 2.seconds,
val pinnedPortNumber: Int? = null,
val ntpVersion: NTPVersion = NTPVersion.FOUR,
) {

enum class DNSResolutionStrategy {
enum class DNSLookupStrategy {
IP_V4,
IP_V6,
ALL,
Expand Down
24 changes: 15 additions & 9 deletions library/src/commonMain/kotlin/com/tidal/networktime/SNTPClient.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.tidal.networktime

import com.tidal.networktime.internal.PlatformAgnosticSNTPClient
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.GlobalScope
import kotlin.time.Duration
Expand All @@ -14,28 +15,33 @@ import kotlin.time.Duration.Companion.seconds
* information obtained from [ntpServers]. May optionally implement [WriteableClock] to be adjusted
* on every synchronization with the calculated time difference.
* @param coroutineScope The scope where synchronization will run on.
* @param syncInterval The amount of time to wait between a sync finishing and the next one being
* started.
* @param synchronizationInterval The amount of time to wait between a sync finishing and the next
* one being started.
*/
class SNTPClient(
vararg val ntpServers: NTPServer,
val referenceClock: ReadableClock,
val coroutineScope: CoroutineScope = GlobalScope,
val syncInterval: Duration = 64.seconds,
val synchronizationInterval: Duration = 64.seconds,
) {
private val delegate = PlatformAgnosticSNTPClient(
ntpServers,
referenceClock,
coroutineScope,
synchronizationInterval,
)

val synchronizedEpochTime: Duration?
get() = TODO("Getting the time")
val synchronizedEpochTime by delegate::synchronizedEpochTime

/**
* Starts periodic synchronization. If it's already started, it does nothing. Otherwise, it
* requests an immediate dispatch of a synchronization and subsequent ones [syncInterval] after
* each other.
* requests an immediate dispatch of a synchronization and subsequent ones
* [synchronizationInterval] after each other.
*/
fun startSynchronization(): Unit = TODO("Start or return")
fun startSynchronization() = delegate.startSynchronization()

/**
* Stops periodic synchronization if already started, does nothing otherwise.
*/
fun stopSynchronization(): Unit = TODO("Stop or return")
fun stopSynchronization() = delegate.stopSynchronization()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.tidal.networktime.internal

import io.ktor.client.HttpClient
import io.ktor.client.HttpClientConfig

internal expect class HttpClientFactory() {

operator fun invoke(config: HttpClientConfig<*>.() -> Unit = {}): HttpClient
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.tidal.networktime.internal

import com.tidal.networktime.NTPServer
import com.tidal.networktime.ReadableClock
import io.ktor.client.HttpClient
import kotlinx.coroutines.CoroutineScope
import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds

internal class PlatformAgnosticSNTPClient(
val ntpServers: Array<out NTPServer>,
val referenceClock: ReadableClock,
val coroutineScope: CoroutineScope,
val synchronizationInterval: Duration = 64.seconds,
httpClientFactory: HttpClientFactory = HttpClientFactory(),
) {
val synchronizedEpochTime: Duration?
get() = TODO("Get the time")
private val httpClient = httpClientFactory()

fun startSynchronization(): Unit = TODO("Start or return")

fun stopSynchronization(): Unit = TODO("Stop or return")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.tidal.networktime.internal

import io.ktor.client.HttpClient
import io.ktor.client.HttpClientConfig
import io.ktor.client.engine.js.Js

internal actual class HttpClientFactory {

actual operator fun invoke(config: HttpClientConfig<*>.() -> Unit) = HttpClient(Js, config)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.tidal.networktime.internal

import io.ktor.client.HttpClient
import io.ktor.client.HttpClientConfig
import io.ktor.client.engine.okhttp.OkHttp

internal actual class HttpClientFactory {

actual operator fun invoke(config: HttpClientConfig<*>.() -> Unit) = HttpClient(OkHttp, config)
}

0 comments on commit dfbe90f

Please sign in to comment.