Skip to content

Commit f4fdfe3

Browse files
committed
Merge branch 'kn-main' of github.com:smithy-lang/smithy-kotlin into kn-platform
2 parents 426bcfe + 7c3c73f commit f4fdfe3

File tree

6 files changed

+134
-9
lines changed

6 files changed

+134
-9
lines changed

.github/workflows/continuous-integration.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ jobs:
164164
shell: bash
165165
run: |
166166
# FIXME K2. Re-enable warnings as errors after this warning is removed: https://youtrack.jetbrains.com/issue/KT-68532
167-
# echo "kotlinWarningsAsErrors=true" >> $GITHUB_WORKSPACE/local.properties
167+
# echo "kotlinWarningsAsErrors=true" >> $GITHUB_WORKSPACE/local.properties
168168
./gradlew -Paws.kotlin.native=false apiCheck
169169
./gradlew -Paws.kotlin.native=false test jvmTest
170170

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
kotlin-version = "2.1.0"
33
dokka-version = "1.9.10"
44

5-
aws-kotlin-repo-tools-version = "0.4.22-kn"
5+
aws-kotlin-repo-tools-version = "0.4.24-kn"
66

77
# libs
88
coroutines-version = "1.9.0"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip
44
networkTimeout=10000
55
zipStoreBase=GRADLE_USER_HOME
66
zipStorePath=wrapper/dists

runtime/build.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import aws.sdk.kotlin.gradle.dsl.configurePublishing
66
import aws.sdk.kotlin.gradle.kmp.*
77
import aws.sdk.kotlin.gradle.util.typedProp
8+
import org.gradle.kotlin.dsl.withType
89
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
910

1011
plugins {
@@ -112,3 +113,5 @@ subprojects {
112113
}
113114
}
114115
}
116+
117+
configureIosSimulatorTasks()
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
package aws.smithy.kotlin.runtime.net
6+
7+
import kotlinx.coroutines.test.runTest
8+
import kotlin.test.*
9+
10+
class HostResolverTest {
11+
@Test
12+
fun testResolveLocalhost() = runTest {
13+
val addresses = HostResolver.Default.resolve("localhost")
14+
assertTrue(addresses.isNotEmpty())
15+
16+
addresses.forEach { addr ->
17+
assertEquals("localhost", addr.hostname)
18+
19+
val localHostAddr = when (addr.address) {
20+
is IpV4Addr -> IpV4Addr.LOCALHOST
21+
is IpV6Addr -> IpV6Addr.LOCALHOST
22+
}
23+
assertEquals(addr.address, localHostAddr)
24+
}
25+
}
26+
27+
@Test
28+
fun testResolveIpv4Address() = runTest {
29+
val addresses = HostResolver.Default.resolve("127.0.0.1")
30+
assertTrue(addresses.isNotEmpty())
31+
32+
addresses.forEach { addr ->
33+
assertTrue(addr.address is IpV4Addr)
34+
assertContentEquals(byteArrayOf(127, 0, 0, 1), addr.address.octets)
35+
}
36+
}
37+
38+
@Test
39+
fun testResolveIpv6Address() = runTest {
40+
val addresses = HostResolver.Default.resolve("::1")
41+
assertTrue(addresses.isNotEmpty())
42+
43+
addresses.forEach { addr ->
44+
assertTrue(addr.address is IpV6Addr)
45+
val expectedBytes = ByteArray(16) { 0 }
46+
expectedBytes[15] = 1
47+
assertContentEquals(expectedBytes, addr.address.octets)
48+
}
49+
}
50+
51+
@Test
52+
fun testResolveExampleDomain() = runTest {
53+
val addresses = HostResolver.Default.resolve("example.com")
54+
assertNotNull(addresses)
55+
assertTrue(addresses.isNotEmpty())
56+
57+
addresses.forEach { addr ->
58+
assertEquals("example.com", addr.hostname)
59+
when (val ip = addr.address) {
60+
is IpV4Addr -> assertEquals(4, ip.octets.size)
61+
is IpV6Addr -> assertEquals(16, ip.octets.size)
62+
}
63+
}
64+
}
65+
66+
@Test
67+
fun testResolveInvalidDomain() = runTest {
68+
assertFails {
69+
HostResolver.Default.resolve("this-domain-definitely-does-not-exist-12345.local")
70+
}
71+
}
72+
73+
@Test
74+
fun testNoopMethods() {
75+
// Test no-op methods don't throw
76+
val dummyAddr = HostAddress("test.com", IpV4Addr(ByteArray(4)))
77+
val resolver = HostResolver.Default
78+
resolver.reportFailure(dummyAddr)
79+
resolver.purgeCache(null)
80+
resolver.purgeCache(dummyAddr)
81+
}
82+
}

runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/net/HostResolverNative.kt

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,59 @@
44
*/
55
package aws.smithy.kotlin.runtime.net
66

7-
import aws.smithy.kotlin.runtime.InternalApi
7+
import kotlinx.cinterop.*
8+
import platform.posix.*
89

910
internal actual object DefaultHostResolver : HostResolver {
10-
actual override suspend fun resolve(hostname: String): List<HostAddress> {
11-
TODO("Not yet implemented")
11+
actual override suspend fun resolve(hostname: String): List<HostAddress> = memScoped {
12+
val hints = alloc<addrinfo>().apply {
13+
ai_family = AF_UNSPEC // Allow both IPv4 and IPv6
14+
ai_socktype = SOCK_STREAM // TCP stream sockets
15+
ai_flags = AI_PASSIVE // For wildcard IP address
16+
}
17+
18+
val result = allocPointerTo<addrinfo>()
19+
20+
try {
21+
// Perform the DNS lookup
22+
val status = getaddrinfo(hostname, null, hints.ptr, result.ptr)
23+
check(status == 0) { "Failed to resolve host $hostname: ${gai_strerror(status)?.toKString()}" }
24+
25+
return generateSequence(result.value) { it.pointed.ai_next }
26+
.map { it.pointed.ai_addr!!.pointed.toIpAddr() }
27+
.map { HostAddress(hostname, it) }
28+
.toList()
29+
} finally {
30+
freeaddrinfo(result.value)
31+
}
32+
}
33+
34+
@OptIn(UnsafeNumber::class)
35+
private fun sockaddr.toIpAddr(): IpAddr {
36+
val (size, addrPtr, constructor) = when (sa_family.toInt()) {
37+
AF_INET -> Triple(
38+
4,
39+
reinterpret<sockaddr_in>().sin_addr.ptr,
40+
{ bytes: ByteArray -> IpV4Addr(bytes) },
41+
)
42+
AF_INET6 -> Triple(
43+
16,
44+
reinterpret<sockaddr_in6>().sin6_addr.ptr,
45+
{ bytes: ByteArray -> IpV6Addr(bytes) },
46+
)
47+
else -> throw IllegalArgumentException("Unsupported sockaddr family $sa_family")
48+
}
49+
50+
val ipBytes = ByteArray(size)
51+
memcpy(ipBytes.refTo(0), addrPtr, size.toULong())
52+
return constructor(ipBytes)
1253
}
1354

1455
actual override fun reportFailure(addr: HostAddress) {
15-
TODO("Not yet implemented")
56+
// No-op, same as JVM implementation
1657
}
1758

18-
@InternalApi
1959
actual override fun purgeCache(addr: HostAddress?) {
20-
TODO("Not yet implemented")
60+
// No-op, same as JVM implementation
2161
}
2262
}

0 commit comments

Comments
 (0)