init
This commit is contained in:
13
apps/android/core/domain/build.gradle.kts
Normal file
13
apps/android/core/domain/build.gradle.kts
Normal file
@@ -0,0 +1,13 @@
|
||||
plugins {
|
||||
alias(libs.plugins.android.library)
|
||||
alias(libs.plugins.kotlin.android)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "org.vpnshare.domain"
|
||||
compileSdk = 36
|
||||
|
||||
defaultConfig {
|
||||
minSdk = 26
|
||||
}
|
||||
}
|
||||
1
apps/android/core/domain/src/main/AndroidManifest.xml
Normal file
1
apps/android/core/domain/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1 @@
|
||||
<manifest />
|
||||
@@ -0,0 +1,83 @@
|
||||
package org.vpnshare.domain.model
|
||||
|
||||
import java.time.Instant
|
||||
|
||||
@JvmInline
|
||||
value class PeerId(val value: String)
|
||||
|
||||
enum class ShareTransport {
|
||||
Usb,
|
||||
Wifi,
|
||||
Hotspot
|
||||
}
|
||||
|
||||
enum class ClientPlatform {
|
||||
Windows,
|
||||
Linux,
|
||||
MacOs,
|
||||
Android,
|
||||
Ios,
|
||||
Unknown
|
||||
}
|
||||
|
||||
data class GatewayConfig(
|
||||
val preferredTransport: ShareTransport = ShareTransport.Usb,
|
||||
val allowWifiFallback: Boolean = true,
|
||||
val allowHotspot: Boolean = false,
|
||||
val maxPeers: Int = 4,
|
||||
val defaultMtu: Int = 1280
|
||||
)
|
||||
|
||||
data class VpnStatus(
|
||||
val active: Boolean,
|
||||
val networkName: String?,
|
||||
val supportsIpv4: Boolean,
|
||||
val supportsIpv6: Boolean
|
||||
)
|
||||
|
||||
data class PairingRequest(
|
||||
val requestId: String,
|
||||
val displayName: String,
|
||||
val platform: ClientPlatform,
|
||||
val transport: ShareTransport,
|
||||
val createdAt: Instant,
|
||||
val expiresAt: Instant
|
||||
) {
|
||||
fun isExpired(now: Instant): Boolean = !expiresAt.isAfter(now)
|
||||
}
|
||||
|
||||
data class PeerDevice(
|
||||
val id: PeerId,
|
||||
val displayName: String,
|
||||
val platform: ClientPlatform,
|
||||
val trustedAt: Instant,
|
||||
val lastSeenAt: Instant?,
|
||||
val revoked: Boolean = false
|
||||
)
|
||||
|
||||
data class TunnelLease(
|
||||
val peerId: PeerId,
|
||||
val ipv4Address: String,
|
||||
val ipv6Address: String?,
|
||||
val dnsGateway: String,
|
||||
val mtu: Int,
|
||||
val routes: List<String>,
|
||||
val expiresAt: Instant
|
||||
)
|
||||
|
||||
data class GatewayStats(
|
||||
val connectedPeers: Int = 0,
|
||||
val bytesFromClients: Long = 0,
|
||||
val bytesToClients: Long = 0
|
||||
)
|
||||
|
||||
sealed interface ShareState {
|
||||
data object Stopped : ShareState
|
||||
data class Starting(val config: GatewayConfig) : ShareState
|
||||
data class Running(
|
||||
val config: GatewayConfig,
|
||||
val vpnStatus: VpnStatus,
|
||||
val stats: GatewayStats
|
||||
) : ShareState
|
||||
data class Failed(val reason: String) : ShareState
|
||||
}
|
||||
19
apps/android/core/engine/build.gradle.kts
Normal file
19
apps/android/core/engine/build.gradle.kts
Normal file
@@ -0,0 +1,19 @@
|
||||
plugins {
|
||||
alias(libs.plugins.android.library)
|
||||
alias(libs.plugins.kotlin.android)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "org.vpnshare.engine"
|
||||
compileSdk = 36
|
||||
|
||||
defaultConfig {
|
||||
minSdk = 26
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":apps:android:core:domain"))
|
||||
implementation(libs.kotlinx.coroutines.android)
|
||||
implementation(libs.kotlinx.coroutines.core)
|
||||
}
|
||||
1
apps/android/core/engine/src/main/AndroidManifest.xml
Normal file
1
apps/android/core/engine/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1 @@
|
||||
<manifest />
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.vpnshare.engine
|
||||
|
||||
import org.vpnshare.domain.model.PairingRequest
|
||||
import org.vpnshare.domain.model.PeerId
|
||||
import org.vpnshare.domain.model.ShareState
|
||||
|
||||
sealed interface GatewayEvent {
|
||||
data class StateChanged(val state: ShareState) : GatewayEvent
|
||||
data class PairingRequested(val request: PairingRequest) : GatewayEvent
|
||||
data class PeerConnected(val peerId: PeerId) : GatewayEvent
|
||||
data class PeerDisconnected(val peerId: PeerId, val reason: String) : GatewayEvent
|
||||
data class Warning(val message: String) : GatewayEvent
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package org.vpnshare.engine
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.asSharedFlow
|
||||
import org.vpnshare.domain.model.GatewayConfig
|
||||
import org.vpnshare.domain.model.GatewayStats
|
||||
import org.vpnshare.domain.model.PairingRequest
|
||||
import org.vpnshare.domain.model.PeerId
|
||||
import org.vpnshare.domain.model.ShareState
|
||||
import org.vpnshare.domain.model.VpnStatus
|
||||
|
||||
class RustVpnShareEngine(
|
||||
private val versionProvider: EngineVersionProvider = JniEngineVersionProvider()
|
||||
) : VpnShareEngine {
|
||||
private val mutableEvents = MutableSharedFlow<GatewayEvent>(extraBufferCapacity = 64)
|
||||
|
||||
override val events: Flow<GatewayEvent> = mutableEvents.asSharedFlow()
|
||||
|
||||
override suspend fun startGateway(config: GatewayConfig) {
|
||||
mutableEvents.emit(GatewayEvent.StateChanged(ShareState.Starting(config)))
|
||||
mutableEvents.emit(
|
||||
GatewayEvent.StateChanged(
|
||||
ShareState.Running(
|
||||
config = config,
|
||||
vpnStatus = VpnStatus(
|
||||
active = false,
|
||||
networkName = null,
|
||||
supportsIpv4 = true,
|
||||
supportsIpv6 = false
|
||||
),
|
||||
stats = GatewayStats()
|
||||
)
|
||||
)
|
||||
)
|
||||
mutableEvents.emit(GatewayEvent.Warning("Rust core linked as ${versionProvider.version()}"))
|
||||
}
|
||||
|
||||
override suspend fun stopGateway() {
|
||||
mutableEvents.emit(GatewayEvent.StateChanged(ShareState.Stopped))
|
||||
}
|
||||
|
||||
override suspend fun approvePairing(request: PairingRequest): PeerId {
|
||||
val peerId = PeerId("peer-${request.requestId}")
|
||||
mutableEvents.emit(GatewayEvent.PeerConnected(peerId))
|
||||
return peerId
|
||||
}
|
||||
|
||||
override suspend fun rejectPairing(request: PairingRequest) {
|
||||
mutableEvents.emit(GatewayEvent.Warning("Rejected pairing request ${request.requestId}"))
|
||||
}
|
||||
}
|
||||
|
||||
interface EngineVersionProvider {
|
||||
fun version(): String
|
||||
}
|
||||
|
||||
class JniEngineVersionProvider : EngineVersionProvider {
|
||||
override fun version(): String {
|
||||
return runCatching {
|
||||
System.loadLibrary("vpnshare_ffi")
|
||||
nativeVersion()
|
||||
}.getOrDefault("unlinked")
|
||||
}
|
||||
|
||||
private external fun nativeVersion(): String
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.vpnshare.engine
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import org.vpnshare.domain.model.GatewayConfig
|
||||
import org.vpnshare.domain.model.PairingRequest
|
||||
import org.vpnshare.domain.model.PeerId
|
||||
|
||||
interface VpnShareEngine {
|
||||
val events: Flow<GatewayEvent>
|
||||
|
||||
suspend fun startGateway(config: GatewayConfig)
|
||||
|
||||
suspend fun stopGateway()
|
||||
|
||||
suspend fun approvePairing(request: PairingRequest): PeerId
|
||||
|
||||
suspend fun rejectPairing(request: PairingRequest)
|
||||
}
|
||||
Reference in New Issue
Block a user