Files
awake/src/main/kotlin/Server.kt
2026-05-27 20:49:34 +03:00

105 lines
2.5 KiB
Kotlin

package su.sonoma
import kotlinx.coroutines.*
import java.io.BufferedInputStream
import java.io.BufferedOutputStream
import java.net.ServerSocket
import java.net.Socket
import java.io.DataInputStream
fun startServer(address: String, port: Int, tun: String, outIntefrace: String) = runBlocking {
val tun = TunDevice(address, "awake0")
tun.addRoute()
tun.enableIpForwarding()
tun.enableMasquerade(outIntefrace)
val server = ServerSocket(port)
println("Server started on $port")
while (true) {
val client = server.accept()
println("${client.inetAddress} Client pairing")
launch(Dispatchers.IO) {
println("${client.inetAddress} Client connected")
try {
handle(client, tun)
} catch (e: Exception) {
e.printStackTrace()
}
}
launch(Dispatchers.IO) {
try {
forward(client, tun)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}
fun handle(socket: Socket, tun: TunDevice) {
val input = BufferedInputStream(socket.getInputStream())
val buffer = ByteArray(1500)
while (true) {
val hi = input.read()
val lo = input.read()
if (hi == -1 || lo == -1) {
println("${socket.inetAddress} Client disconnected")
break
}
val len = (hi shl 8) or lo
//println("Message length: $len")
if (len <= 0 || len > buffer.size) {
println("Invalid packet size: $len")
break
}
var offset = 0
while (offset < len) {
val r = input.read(buffer, offset, len - offset)
//println("Read $r from client")
if (r == -1) {
println("${socket.inetAddress} Client closed stream")
return
}
offset += r
}
runCatching {
tun.output.write(buffer, 0, len)
tun.output.flush()
}
//println("Write in tun")
}
}
fun forward(socket: Socket, tun: TunDevice) {
val readBuffer = ByteArray(1500)
val output = BufferedOutputStream(socket.getOutputStream())
while (true) {
val responseLen = tun.input.read(readBuffer)
if (responseLen > 0) {
output.write((responseLen shr 8) and 0xFF)
output.write(responseLen and 0xFF)
output.write(readBuffer, 0, responseLen)
output.flush()
}
}
}