67 lines
2.1 KiB
Kotlin
67 lines
2.1 KiB
Kotlin
package be.mygod.vpnhotspot
|
|
|
|
import be.mygod.vpnhotspot.App.Companion.app
|
|
import be.mygod.vpnhotspot.net.Routing
|
|
import be.mygod.vpnhotspot.net.wifi.WifiDoubleLock
|
|
import be.mygod.vpnhotspot.widget.SmartSnackbar
|
|
import timber.log.Timber
|
|
|
|
abstract class RoutingManager(private val caller: Any, val downstream: String, private val isWifi: Boolean) {
|
|
companion object {
|
|
private const val KEY_MASQUERADE_MODE = "service.masqueradeMode"
|
|
var masqueradeMode: Routing.MasqueradeMode
|
|
get() {
|
|
app.pref.getString(KEY_MASQUERADE_MODE, null)?.let { return Routing.MasqueradeMode.valueOf(it) }
|
|
return if (app.pref.getBoolean("service.masquerade", true)) // legacy settings
|
|
Routing.MasqueradeMode.Simple else Routing.MasqueradeMode.None
|
|
}
|
|
set(value) = app.pref.edit().putString(KEY_MASQUERADE_MODE, value.name).apply()
|
|
}
|
|
|
|
/**
|
|
* Both repeater and local-only hotspot are Wi-Fi based.
|
|
*/
|
|
class LocalOnly(caller: Any, downstream: String) : RoutingManager(caller, downstream, true) {
|
|
override fun Routing.configure() {
|
|
ipForward() // local only interfaces need to enable ip_forward
|
|
forward()
|
|
masquerade(masqueradeMode)
|
|
commit(true)
|
|
}
|
|
}
|
|
|
|
var routing: Routing? = null
|
|
|
|
init {
|
|
app.onPreCleanRoutings[this] = { routing?.stop() }
|
|
app.onRoutingsCleaned[this] = { initRouting() }
|
|
if (isWifi) WifiDoubleLock.acquire(this)
|
|
}
|
|
|
|
fun initRouting() = try {
|
|
routing = Routing(caller, downstream).apply {
|
|
try {
|
|
configure()
|
|
} catch (e: Exception) {
|
|
revert()
|
|
throw e
|
|
}
|
|
}
|
|
true
|
|
} catch (e: Exception) {
|
|
SmartSnackbar.make(e).show()
|
|
Timber.w(e)
|
|
routing = null
|
|
false
|
|
}
|
|
|
|
protected abstract fun Routing.configure()
|
|
|
|
fun stop() {
|
|
routing?.revert()
|
|
if (isWifi) WifiDoubleLock.release(this)
|
|
app.onPreCleanRoutings -= this
|
|
app.onRoutingsCleaned -= this
|
|
}
|
|
}
|