mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-11-08 16:37:49 +00:00
android, ios, desktop: TCP_USER_TIMEOUT setting
With the simplexmq change this depends on, a connection with unacknowledged data is failed after the keep-alive detection time instead of when the OS gives up retransmitting (~15 minutes), which is how long delivery keeps failing on a dead client when no network change is reported. It is off unless it is enabled, so that it can be tested before it becomes the default, and it is added to the keep-alive options in advanced network settings, next to the socket options it is derived from - it is removed when keep-alive is disabled, as the other options are. The option is not sent by the clients that do not have it, and the core treats it as off then.
This commit is contained in:
1 parent
680790695e
commit
8c11f93bb7
5 files changed
+32
-5
No files matched your search
@@ -235,11 +235,16 @@ struct AdvancedNetworkSettings: View {
|
||||
intSettingPicker("TCP_KEEPIDLE", selection: $keepAliveOpts.keepIdle, values: [15, 30, 60, 120, 180], label: secondsLabel)
|
||||
intSettingPicker("TCP_KEEPINTVL", selection: $keepAliveOpts.keepIntvl, values: [5, 10, 15, 30, 60], label: secondsLabel)
|
||||
intSettingPicker("TCP_KEEPCNT", selection: $keepAliveOpts.keepCnt, values: [1, 2, 4, 6, 8], label: "")
|
||||
Toggle("TCP_USER_TIMEOUT", isOn: Binding(
|
||||
get: { keepAliveOpts.unackedDataTimeout == true },
|
||||
set: { keepAliveOpts.unackedDataTimeout = $0 }
|
||||
))
|
||||
} else {
|
||||
Group {
|
||||
Text("TCP_KEEPIDLE")
|
||||
Text("TCP_KEEPINTVL")
|
||||
Text("TCP_KEEPCNT")
|
||||
Text("TCP_USER_TIMEOUT")
|
||||
}
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
}
|
||||
|
||||
@@ -438,8 +438,11 @@ public struct KeepAliveOpts: Codable, Equatable {
|
||||
public var keepIdle: Int // seconds
|
||||
public var keepIntvl: Int // seconds
|
||||
public var keepCnt: Int // times
|
||||
// a connection with unacknowledged data gets no keep-alive probes, and the OS fails it only when it
|
||||
// gives up retransmitting - ~15 minutes; when this is on it is failed after the keep-alive detection time
|
||||
public var unackedDataTimeout: Bool? = nil
|
||||
|
||||
public static let defaults: KeepAliveOpts = KeepAliveOpts(keepIdle: 30, keepIntvl: 15, keepCnt: 4)
|
||||
public static let defaults: KeepAliveOpts = KeepAliveOpts(keepIdle: 30, keepIntvl: 15, keepCnt: 4, unackedDataTimeout: nil)
|
||||
}
|
||||
|
||||
public struct NetworkProxy: Equatable, Codable {
|
||||
|
||||
@@ -57,6 +57,7 @@ let GROUP_DEFAULT_NETWORK_ENABLE_KEEP_ALIVE = "networkEnableKeepAlive"
|
||||
let GROUP_DEFAULT_NETWORK_TCP_KEEP_IDLE = "networkTCPKeepIdle"
|
||||
let GROUP_DEFAULT_NETWORK_TCP_KEEP_INTVL = "networkTCPKeepIntvl"
|
||||
let GROUP_DEFAULT_NETWORK_TCP_KEEP_CNT = "networkTCPKeepCnt"
|
||||
let GROUP_DEFAULT_NETWORK_TCP_UNACKED_DATA_TIMEOUT = "networkTCPUnackedDataTimeout"
|
||||
public let GROUP_DEFAULT_INCOGNITO = "incognito"
|
||||
let GROUP_DEFAULT_STORE_DB_PASSPHRASE = "storeDBPassphrase"
|
||||
public let GROUP_DEFAULT_INITIAL_RANDOM_DB_PASSPHRASE = "initialRandomDBPassphrase"
|
||||
@@ -90,6 +91,7 @@ public let groupAppDefaults: [String: Any] = [
|
||||
GROUP_DEFAULT_NETWORK_TCP_KEEP_IDLE: KeepAliveOpts.defaults.keepIdle,
|
||||
GROUP_DEFAULT_NETWORK_TCP_KEEP_INTVL: KeepAliveOpts.defaults.keepIntvl,
|
||||
GROUP_DEFAULT_NETWORK_TCP_KEEP_CNT: KeepAliveOpts.defaults.keepCnt,
|
||||
GROUP_DEFAULT_NETWORK_TCP_UNACKED_DATA_TIMEOUT: KeepAliveOpts.defaults.unackedDataTimeout == true,
|
||||
GROUP_DEFAULT_INCOGNITO: false,
|
||||
GROUP_DEFAULT_STORE_DB_PASSPHRASE: true,
|
||||
GROUP_DEFAULT_INITIAL_RANDOM_DB_PASSPHRASE: false,
|
||||
@@ -383,7 +385,8 @@ public func getNetCfg() -> NetCfg {
|
||||
let keepIdle = groupDefaults.integer(forKey: GROUP_DEFAULT_NETWORK_TCP_KEEP_IDLE)
|
||||
let keepIntvl = groupDefaults.integer(forKey: GROUP_DEFAULT_NETWORK_TCP_KEEP_INTVL)
|
||||
let keepCnt = groupDefaults.integer(forKey: GROUP_DEFAULT_NETWORK_TCP_KEEP_CNT)
|
||||
tcpKeepAlive = KeepAliveOpts(keepIdle: keepIdle, keepIntvl: keepIntvl, keepCnt: keepCnt)
|
||||
let unackedDataTimeout = groupDefaults.bool(forKey: GROUP_DEFAULT_NETWORK_TCP_UNACKED_DATA_TIMEOUT)
|
||||
tcpKeepAlive = KeepAliveOpts(keepIdle: keepIdle, keepIntvl: keepIntvl, keepCnt: keepCnt, unackedDataTimeout: unackedDataTimeout)
|
||||
} else {
|
||||
tcpKeepAlive = nil
|
||||
}
|
||||
@@ -427,6 +430,7 @@ public func setNetCfg(_ cfg: NetCfg, networkProxy: NetworkProxy?) {
|
||||
groupDefaults.set(tcpKeepAlive.keepIdle, forKey: GROUP_DEFAULT_NETWORK_TCP_KEEP_IDLE)
|
||||
groupDefaults.set(tcpKeepAlive.keepIntvl, forKey: GROUP_DEFAULT_NETWORK_TCP_KEEP_INTVL)
|
||||
groupDefaults.set(tcpKeepAlive.keepCnt, forKey: GROUP_DEFAULT_NETWORK_TCP_KEEP_CNT)
|
||||
groupDefaults.set(tcpKeepAlive.unackedDataTimeout == true, forKey: GROUP_DEFAULT_NETWORK_TCP_UNACKED_DATA_TIMEOUT)
|
||||
} else {
|
||||
groupDefaults.set(false, forKey: GROUP_DEFAULT_NETWORK_ENABLE_KEEP_ALIVE)
|
||||
}
|
||||
|
||||
+5
-2
@@ -5398,11 +5398,14 @@ enum class TransportSessionMode {
|
||||
data class KeepAliveOpts(
|
||||
val keepIdle: Int, // seconds
|
||||
val keepIntvl: Int, // seconds
|
||||
val keepCnt: Int // times
|
||||
val keepCnt: Int, // times
|
||||
// a connection with unacknowledged data gets no keep-alive probes, and the OS fails it only when it gives
|
||||
// up retransmitting - ~15 minutes; when this is on it is failed after the keep-alive detection time instead
|
||||
val unackedDataTimeout: Boolean? = null
|
||||
) {
|
||||
companion object {
|
||||
val defaults: KeepAliveOpts =
|
||||
KeepAliveOpts(keepIdle = 30, keepIntvl = 15, keepCnt = 4)
|
||||
KeepAliveOpts(keepIdle = 30, keepIntvl = 15, keepCnt = 4, unackedDataTimeout = null)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+13
-1
@@ -61,14 +61,17 @@ fun ModalData.AdvancedNetworkSettingsView(showModal: (@Composable ModalData.() -
|
||||
val networkTCPKeepIdle: MutableState<Int>
|
||||
val networkTCPKeepIntvl: MutableState<Int>
|
||||
val networkTCPKeepCnt: MutableState<Int>
|
||||
val networkTCPUserTimeout: MutableState<Boolean>
|
||||
if (currentCfgVal.tcpKeepAlive != null) {
|
||||
networkTCPKeepIdle = remember { mutableStateOf(currentCfgVal.tcpKeepAlive.keepIdle) }
|
||||
networkTCPKeepIntvl = remember { mutableStateOf(currentCfgVal.tcpKeepAlive.keepIntvl) }
|
||||
networkTCPKeepCnt = remember { mutableStateOf(currentCfgVal.tcpKeepAlive.keepCnt) }
|
||||
networkTCPUserTimeout = remember { mutableStateOf(currentCfgVal.tcpKeepAlive.unackedDataTimeout == true) }
|
||||
} else {
|
||||
networkTCPKeepIdle = remember { mutableStateOf(KeepAliveOpts.defaults.keepIdle) }
|
||||
networkTCPKeepIntvl = remember { mutableStateOf(KeepAliveOpts.defaults.keepIntvl) }
|
||||
networkTCPKeepCnt = remember { mutableStateOf(KeepAliveOpts.defaults.keepCnt) }
|
||||
networkTCPUserTimeout = remember { mutableStateOf(KeepAliveOpts.defaults.unackedDataTimeout == true) }
|
||||
}
|
||||
|
||||
fun buildCfg(): NetCfg {
|
||||
@@ -77,7 +80,7 @@ fun ModalData.AdvancedNetworkSettingsView(showModal: (@Composable ModalData.() -
|
||||
val keepIdle = networkTCPKeepIdle.value
|
||||
val keepIntvl = networkTCPKeepIntvl.value
|
||||
val keepCnt = networkTCPKeepCnt.value
|
||||
KeepAliveOpts(keepIdle = keepIdle, keepIntvl = keepIntvl, keepCnt = keepCnt)
|
||||
KeepAliveOpts(keepIdle = keepIdle, keepIntvl = keepIntvl, keepCnt = keepCnt, unackedDataTimeout = networkTCPUserTimeout.value)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
@@ -123,10 +126,12 @@ fun ModalData.AdvancedNetworkSettingsView(showModal: (@Composable ModalData.() -
|
||||
networkTCPKeepIdle.value = cfg.tcpKeepAlive.keepIdle
|
||||
networkTCPKeepIntvl.value = cfg.tcpKeepAlive.keepIntvl
|
||||
networkTCPKeepCnt.value = cfg.tcpKeepAlive.keepCnt
|
||||
networkTCPUserTimeout.value = cfg.tcpKeepAlive.unackedDataTimeout == true
|
||||
} else {
|
||||
networkTCPKeepIdle.value = KeepAliveOpts.defaults.keepIdle
|
||||
networkTCPKeepIntvl.value = KeepAliveOpts.defaults.keepIntvl
|
||||
networkTCPKeepCnt.value = KeepAliveOpts.defaults.keepCnt
|
||||
networkTCPUserTimeout.value = KeepAliveOpts.defaults.unackedDataTimeout == true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,6 +185,7 @@ fun ModalData.AdvancedNetworkSettingsView(showModal: (@Composable ModalData.() -
|
||||
networkTCPKeepIdle,
|
||||
networkTCPKeepIntvl,
|
||||
networkTCPKeepCnt,
|
||||
networkTCPUserTimeout,
|
||||
updateSessionMode = { sessionMode.value = it; currentCfg.value = currentCfg.value.copy(sessionMode = it) },
|
||||
updateSMPProxyMode = { smpProxyMode.value = it; currentCfg.value = currentCfg.value.copy(smpProxyMode = it) },
|
||||
updateSMPProxyFallback = { smpProxyFallback.value = it; currentCfg.value = currentCfg.value.copy(smpProxyFallback = it) },
|
||||
@@ -215,6 +221,7 @@ fun ModalData.AdvancedNetworkSettingsView(showModal: (@Composable ModalData.() -
|
||||
networkTCPKeepIdle: MutableState<Int>,
|
||||
networkTCPKeepIntvl: MutableState<Int>,
|
||||
networkTCPKeepCnt: MutableState<Int>,
|
||||
networkTCPUserTimeout: MutableState<Boolean>,
|
||||
updateSessionMode: (TransportSessionMode) -> Unit,
|
||||
updateSMPProxyMode: (SMPProxyMode) -> Unit,
|
||||
updateSMPProxyFallback: (SMPProxyFallback) -> Unit,
|
||||
@@ -318,6 +325,7 @@ fun ModalData.AdvancedNetworkSettingsView(showModal: (@Composable ModalData.() -
|
||||
SectionItemView {
|
||||
IntSettingRow("TCP_KEEPCNT", networkTCPKeepCnt, listOf(1, 2, 4, 6, 8), "")
|
||||
}
|
||||
PreferenceToggle("TCP_USER_TIMEOUT", checked = networkTCPUserTimeout.value) { networkTCPUserTimeout.value = it }
|
||||
} else {
|
||||
SectionItemView {
|
||||
Text("TCP_KEEPIDLE", color = MaterialTheme.colors.secondary)
|
||||
@@ -328,6 +336,9 @@ fun ModalData.AdvancedNetworkSettingsView(showModal: (@Composable ModalData.() -
|
||||
SectionItemView {
|
||||
Text("TCP_KEEPCNT", color = MaterialTheme.colors.secondary)
|
||||
}
|
||||
SectionItemView {
|
||||
Text("TCP_USER_TIMEOUT", color = MaterialTheme.colors.secondary)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -595,6 +606,7 @@ fun PreviewAdvancedNetworkSettingsLayout() {
|
||||
networkTCPKeepIdle = remember { mutableStateOf(10) },
|
||||
networkTCPKeepIntvl = remember { mutableStateOf(10) },
|
||||
networkTCPKeepCnt = remember { mutableStateOf(10) },
|
||||
networkTCPUserTimeout = remember { mutableStateOf(false) },
|
||||
updateSessionMode = {},
|
||||
updateSMPProxyMode = {},
|
||||
updateSMPProxyFallback = {},
|
||||
|
||||
Reference in new issue
Block a user