From 8429fe20c27caa0eee65fbe6852f403422216b87 Mon Sep 17 00:00:00 2001 From: ekoby <7406535+ekoby@users.noreply.github.com> Date: Tue, 13 Oct 2020 17:13:47 -0400 Subject: [PATCH] handle IP client intercepts on Ziti services (#64) * handle IP client intercepts on Ziti services * update dependencies * prevent gradle OOM --- gradle.properties | 2 + samples/http-sample/build.gradle | 1 - samples/netty-http-sample/build.gradle | 1 - samples/sample/build.gradle | 1 - ziti-android/build.gradle | 4 +- ziti-netty/build.gradle | 4 +- ziti/build.gradle | 2 +- .../org/openziti/net/dns/DNSResolver.kt | 6 ++- .../org/openziti/net/dns/ZitiDNSManager.kt | 42 +++++++++++++++++-- .../openziti/net/nio/AsyncTLSSocketFactory.kt | 4 -- 10 files changed, 50 insertions(+), 17 deletions(-) diff --git a/gradle.properties b/gradle.properties index f6a4db39..37b03d3e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,6 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 + kotlin.code.style=official buildForAndroid=true diff --git a/samples/http-sample/build.gradle b/samples/http-sample/build.gradle index 2df7c163..ed3d0adf 100644 --- a/samples/http-sample/build.gradle +++ b/samples/http-sample/build.gradle @@ -22,7 +22,6 @@ plugins { dependencies { implementation project(':ziti') implementation("org.slf4j:slf4j-simple:1.7.30") - testImplementation 'junit:junit:4.12' } application { diff --git a/samples/netty-http-sample/build.gradle b/samples/netty-http-sample/build.gradle index cb9d66f5..fbf50e39 100644 --- a/samples/netty-http-sample/build.gradle +++ b/samples/netty-http-sample/build.gradle @@ -25,7 +25,6 @@ dependencies { implementation "io.netty:netty-all:4.1.52.Final" implementation "com.github.ajalt:clikt:2.7.0" implementation "org.slf4j:slf4j-simple:1.7.30" - testImplementation "junit:junit:4.12" } application { diff --git a/samples/sample/build.gradle b/samples/sample/build.gradle index f8d04d57..3b16d3bf 100644 --- a/samples/sample/build.gradle +++ b/samples/sample/build.gradle @@ -22,7 +22,6 @@ plugins { dependencies { implementation project(":ziti") - testImplementation "junit:junit:4.12" } compileJava { diff --git a/ziti-android/build.gradle b/ziti-android/build.gradle index b668bd1d..8b945791 100644 --- a/ziti-android/build.gradle +++ b/ziti-android/build.gradle @@ -81,10 +81,10 @@ dependencies { embed("com.goterl.lazycode:lazysodium-android:4.1.1@aar") embed('net.java.dev.jna:jna:5.6.0@aar') - implementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.72" + implementation "org.jetbrains.kotlin:kotlin-stdlib:1.4.10" implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.8' - testImplementation 'junit:junit:4.13' + testImplementation 'junit:junit:4.13.1' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' implementation 'com.android.support:support-compat:28.0.0' diff --git a/ziti-netty/build.gradle b/ziti-netty/build.gradle index d2905377..99c00886 100644 --- a/ziti-netty/build.gradle +++ b/ziti-netty/build.gradle @@ -27,10 +27,10 @@ repositories { dependencies { api(project(':ziti')) - implementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.72" + implementation "org.jetbrains.kotlin:kotlin-stdlib:1.4.10" implementation "io.netty:netty-all:4.1.52.Final" - testImplementation "org.jetbrains.kotlin:kotlin-test-junit:1.3.72" + testImplementation "org.jetbrains.kotlin:kotlin-test-junit:1.4.10" testImplementation "com.google.code.gson:gson:2.8.6" } diff --git a/ziti/build.gradle b/ziti/build.gradle index e6e9ce10..4cd5443b 100644 --- a/ziti/build.gradle +++ b/ziti/build.gradle @@ -22,7 +22,7 @@ plugins { } dependencies { - implementation("org.jetbrains.kotlin:kotlin-stdlib:1.3.72") + implementation("org.jetbrains.kotlin:kotlin-stdlib:1.4.10") implementation('org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.8') implementation("org.slf4j:slf4j-api:1.7.30") diff --git a/ziti/src/main/kotlin/org/openziti/net/dns/DNSResolver.kt b/ziti/src/main/kotlin/org/openziti/net/dns/DNSResolver.kt index 7bff159a..c2755f0b 100644 --- a/ziti/src/main/kotlin/org/openziti/net/dns/DNSResolver.kt +++ b/ziti/src/main/kotlin/org/openziti/net/dns/DNSResolver.kt @@ -17,8 +17,12 @@ package org.openziti.net.dns import java.net.InetAddress +import java.util.function.Consumer -@FunctionalInterface interface DNSResolver { fun resolve(hostname: String): InetAddress? + + data class DNSEvent(val hostname: String?, val ip: InetAddress, val removed: Boolean) + fun subscribe(sub: (DNSEvent) -> Unit) + fun subscribe(sub: Consumer) } diff --git a/ziti/src/main/kotlin/org/openziti/net/dns/ZitiDNSManager.kt b/ziti/src/main/kotlin/org/openziti/net/dns/ZitiDNSManager.kt index cacd3e11..fe521f8d 100644 --- a/ziti/src/main/kotlin/org/openziti/net/dns/ZitiDNSManager.kt +++ b/ziti/src/main/kotlin/org/openziti/net/dns/ZitiDNSManager.kt @@ -16,17 +16,28 @@ package org.openziti.net.dns +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.channels.BroadcastChannel +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import org.bouncycastle.util.IPAddress import org.openziti.api.Service +import java.net.Inet4Address +import java.net.Inet6Address import java.net.InetAddress import java.net.InetSocketAddress import java.util.* import java.util.concurrent.atomic.AtomicInteger +import java.util.function.Consumer +@ExperimentalCoroutinesApi internal object ZitiDNSManager : DNSResolver, ServiceMapper { - private val TAG = this::class.java.simpleName - internal val PREFIX = byteArrayOf(0xa9.toByte(), 0xfe.toByte()) internal val postfix = AtomicInteger(0x0101) // start with 1.1 postfix @@ -34,12 +45,20 @@ internal object ZitiDNSManager : DNSResolver, ServiceMapper { internal val host2Ip = mutableMapOf() internal val addr2serviceId = mutableMapOf() internal val serviceId2addr = mutableMapOf() + internal val dnsBroadCast = BroadcastChannel(Channel.BUFFERED) internal fun registerService(service: Service): InetSocketAddress? { service.dns?.hostname?.toLowerCase(Locale.getDefault())?.let { hostname -> - val ip = host2Ip.getOrPut(hostname) { - nextAddr(hostname) + + val ip = when { + IPAddress.isValidIPv4(hostname) -> Inet4Address.getByName(hostname) + IPAddress.isValidIPv6(hostname) -> Inet6Address.getByName(hostname) + else -> host2Ip.getOrPut(hostname) { nextAddr(hostname) } + } + + runBlocking { + dnsBroadCast.send(DNSResolver.DNSEvent(hostname, ip, false)) } service.dns?.port?.let { port -> @@ -59,11 +78,26 @@ internal object ZitiDNSManager : DNSResolver, ServiceMapper { val addr = serviceId2addr.get(service.id) if (addr != null) { addr2serviceId.remove(addr) + runBlocking { + GlobalScope.launch { + dnsBroadCast.send(DNSResolver.DNSEvent(service.dns?.hostname, addr.address, true)) + } + } } } override fun resolve(hostname: String): InetAddress? = host2Ip.get(hostname.toLowerCase(Locale.getDefault())) + override fun subscribe(sub: (DNSResolver.DNSEvent) -> Unit) { + runBlocking { + GlobalScope.launch { + dnsBroadCast.asFlow().collect { sub(it) } + } + } + } + + override fun subscribe(sub: Consumer) = subscribe{sub.accept(it)} + override fun getServiceIdByAddr(addr: InetSocketAddress): String? = addr2serviceId.get(addr) internal fun nextAddr(dnsname: String): InetAddress { diff --git a/ziti/src/main/kotlin/org/openziti/net/nio/AsyncTLSSocketFactory.kt b/ziti/src/main/kotlin/org/openziti/net/nio/AsyncTLSSocketFactory.kt index b1fc051f..8685d95c 100644 --- a/ziti/src/main/kotlin/org/openziti/net/nio/AsyncTLSSocketFactory.kt +++ b/ziti/src/main/kotlin/org/openziti/net/nio/AsyncTLSSocketFactory.kt @@ -39,10 +39,6 @@ class AsyncTLSSocketFactory(val ssl: SSLContext): SSLSocketFactory() { private val implField: Field? init { - val sockMethods = Socket::class.java.methods - println("methods: $sockMethods") - println("declMethods: ${Socket::class.java.declaredMethods}") - var m: Method? = null try { m = Socket::class.java.getDeclaredMethod("getImpl").apply {