45 lines
1.6 KiB
Kotlin

package net.sergeych.kiloparsec
import kotlinx.coroutines.CompletableDeferred
import net.sergeych.tools.AtomicCounter
import net.sergeych.utools.pack
private val idCounter = AtomicCounter(0)
/**
* This class is not normally used directly. This is a local interface that supports
* secure transport command layer (encrypted calls/results) to work with [KiloRemoteInterface].
*
* It is recommended to use [KiloClientConnection] and [KiloServerConnection] instead.
*/
internal class KiloL0Interface<T>(
private val clientInterface: LocalInterface<KiloScope<T>>,
private val deferredParams: CompletableDeferred<KiloParams<T>>,
) : LocalInterface<Unit>() {
override var logTag: String = "KL0:${idCounter.incrementAndGet()}"
init {
// local interface uses the same session as a client:
addErrorProvider(clientInterface)
on(L0Call) {
val params = deferredParams.await()
val call = Command.unpackCall(params.decrypt(it))
// tricky part: we need to encrypt a result or error: we can't allow default
// error transport (as it is not encrypted), so we re-use transport blocks here:
val result: Transport.Block = try {
Transport.Block.Response(
0u,
clientInterface.execute(params.scope, call.name, call.serializedArgs)
)
} catch(t: BreakConnectionException) {
throw t
}
catch (t: Throwable) {
clientInterface.encodeError(0u, t)
}
params.encrypt(pack(result))
}
}
}