Remove ktor-network dependency use native socket

This commit is contained in:
2025-09-30 10:50:08 +08:00
parent dceb9953af
commit 52f3756be3
21 files changed
+649 -179

No files matched your search

@@ -0,0 +1,13 @@
/*
* Copyright © 2025 RTAkland
* Author: RTAkland
* Date: 9/30/25
*/
package cn.rtast.nmdns
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.BINARY)
@RequiresOptIn
public annotation class CExport
+10 -34
View File
@@ -7,40 +7,16 @@
package cn.rtast.nmdns
private val macAddresses = listOf(
"ef:42:0d:76:f1:97",
"b4:91:7c:be:84:7b",
"38:d0:d3:f5:63:d1",
"90:d0:d5:3e:5b:fa",
"4d:84:d4:dd:7e:b4",
"11:1c:fb:06:6a:4a",
"cf:97:be:b3:18:5b",
"0c:34:bf:d8:55:71",
"95:a0:71:10:31:ab",
"4c:33:b8:4a:60:8e",
"fc:89:a5:f2:b6:3c",
"a7:42:99:34:b5:21",
"9a:55:3f:5d:bb:9d",
"2b:35:ce:77:a0:7c",
"7d:51:21:72:c5:b4",
"79:7d:cc:e1:30:9b",
"aa:a2:cf:b5:e3:3c",
"8d:73:3f:8e:ef:d7",
"21:3c:a4:56:80:c5",
"c1:fa:ca:cb:ec:f3",
"51:76:e2:12:2f:af",
"a8:03:22:2d:b9:80",
"2a:84:3b:ad:9c:d9",
"24:79:c3:ab:0f:b5",
"bc:44:e3:c4:9e:be",
"cb:1b:84:c2:94:ba",
"9d:66:ce:d2:6e:4f",
"43:bf:e2:b2:e3:78",
"48:25:03:bb:9d:35",
"c3:c9:1c:3d:ae:dd"
)
import kotlin.experimental.ExperimentalNativeApi
import kotlin.native.CName
import kotlin.random.Random
/**
* get random mac address
* generate random mac address
*/
fun randomMacAddress(): String = macAddresses.random()
@OptIn(ExperimentalNativeApi::class)
@CName("random_mac_address")
public fun randomMacAddress(): String {
val bytes = ByteArray(6) { Random.nextInt(0, 256).toByte() }
return bytes.joinToString(":") { it.toHexString() }
}
@@ -5,19 +5,14 @@
*/
@file:OptIn(ExperimentalNativeApi::class)
package cn.rtast.nmdns
import io.ktor.network.selector.*
import io.ktor.network.sockets.*
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.io.Buffer
import kotlin.experimental.ExperimentalNativeApi
import kotlin.native.CName
data class NMDNSAnnouncer(
/**
* coroutine dispatcher for running server
*/
internal val dispatcher: CoroutineDispatcher = Dispatchers.Default,
public data class NMDNSAnnouncer(
/**
* service type
* airplay service type: _airplay._tcp.local.
@@ -50,12 +45,60 @@ data class NMDNSAnnouncer(
/**
* mdns socket server
*/
internal val server: BoundDatagramSocket,
internal val server: Socket1,
/**
* srv packet
*/
internal val packet: Buffer,
)
internal val packet: ByteArray,
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || this::class != other::class) return false
other as NMDNSAnnouncer
if (port != other.port) return false
if (mdnsPort != other.mdnsPort) return false
if (serviceType != other.serviceType) return false
if (serviceName != other.serviceName) return false
if (hostname != other.hostname) return false
if (ipAddress != other.ipAddress) return false
if (txtRecords != other.txtRecords) return false
if (server != other.server) return false
if (!packet.contentEquals(other.packet)) return false
return true
}
override fun hashCode(): Int {
var result = port
result = 31 * result + mdnsPort
result = 31 * result + serviceType.hashCode()
result = 31 * result + serviceName.hashCode()
result = 31 * result + hostname.hashCode()
result = 31 * result + ipAddress.hashCode()
result = 31 * result + txtRecords.hashCode()
result = 31 * result + server.hashCode()
result = 31 * result + packet.contentHashCode()
return result
}
/**
* broadcast packet
*/
public fun broadcast() {
this.server.send(packet)
}
}
/**
* export for c
*/
@CExport
@CName("broadcast")
public fun broadcast1(server: NMDNSAnnouncer) {
server.server.send(server.packet)
}
/**
* register service
@@ -68,7 +111,8 @@ data class NMDNSAnnouncer(
* "pk=f3769a660475d27b4f6040381d784645e13e21c53e6d2da6a8c3d757086fc336"
* )
*/
suspend fun registerService(
@CName("register_service")
public fun registerService(
serviceType: String,
serviceName: String,
hostname: String,
@@ -78,11 +122,9 @@ suspend fun registerService(
bindAddress: String,
txtRecords: List<String>,
): NMDNSAnnouncer {
val manager = SelectorManager(Dispatchers.Default)
val serverSocket = aSocket(manager).udp()
.bind(InetSocketAddress(bindAddress, mdnsPort))
val server = createSocket()
.bind(bindAddress, port)
return NMDNSAnnouncer(
Dispatchers.Default,
serviceType,
serviceName,
hostname,
@@ -90,18 +132,11 @@ suspend fun registerService(
port,
mdnsPort,
txtRecords,
serverSocket,
server,
buildPacket(serviceType, "$serviceName.$serviceType", hostname, ipAddress, port, txtRecords)
)
}
/**
* broadcast packet
*/
suspend fun NMDNSAnnouncer.broadcast() {
this.server.send(Datagram(packet.copy(), InetSocketAddress("224.0.0.251", 5353)))
}
internal fun buildPacket(
serviceType: String,
serviceName: String,
@@ -109,7 +144,7 @@ internal fun buildPacket(
ip: String,
port: Int,
txtRecords: List<String>,
): Buffer {
): ByteArray {
val records = mutableListOf<ByteArray>()
records += encodeRR(serviceType, 12, encodeName(serviceName))
@@ -133,8 +168,7 @@ internal fun buildPacket(
header[6] = ((records.size shr 8) and 0xFF).toByte()
header[7] = (records.size and 0xFF).toByte()
val buffer = Buffer().apply { write(header + records.reduce { acc, r -> acc + r }) }
return buffer
return header + records.reduce { acc, r -> acc + r }
}
internal fun encodeRR(name: String, type: Int, data: ByteArray): ByteArray {
@@ -11,4 +11,5 @@ package cn.rtast.nmdns
* block current thread
* unit: second
*/
internal expect fun sleep1(time: Int)
public expect fun sleep1(time: Int)
@@ -0,0 +1,38 @@
/*
* Copyright © 2025 RTAkland
* Author: RTAkland
* Date: 9/30/25
*/
@file:Suppress("unused")
package cn.rtast.nmdns
public expect class Socket1 internal constructor() {
/**
* bind to ip
*/
public fun bind(ip: String, port: Int): Socket1
/**
* send packet
*/
public fun send(packet: ByteArray)
/**
* close
*/
public fun destroy()
}
internal fun createSocket(): Socket1 = Socket1()
public fun htons(value: UShort): UShort =
(((value.toInt() and 0xFF) shl 8) or ((value.toInt() ushr 8) and 0xFF)).toUShort()
public fun htonl(value: UInt): UInt =
((value and 0xFFu) shl 24) or
((value and 0xFF00u) shl 8) or
((value and 0xFF0000u) shr 8) or
((value and 0xFF000000u) shr 24)