diff --git a/apps/ios/Shared/Views/UserSettings/NetworkAndServers/AdvancedNetworkSettings.swift b/apps/ios/Shared/Views/UserSettings/NetworkAndServers/AdvancedNetworkSettings.swift index 754ca3cf6b..7570b1c3e0 100644 --- a/apps/ios/Shared/Views/UserSettings/NetworkAndServers/AdvancedNetworkSettings.swift +++ b/apps/ios/Shared/Views/UserSettings/NetworkAndServers/AdvancedNetworkSettings.swift @@ -208,6 +208,14 @@ struct AdvancedNetworkSettings: View { } } + Section { + Toggle("Use web port", isOn: $netCfg.smpWebPort) + } header: { + Text("TCP port for messaging") + } footer: { + Text("Use TCP port \(netCfg.smpWebPort ? "443" : "5223") when no port is specified.") + } + Section("TCP connection") { timeoutSettingPicker("TCP connection timeout", selection: $netCfg.tcpConnectTimeout, values: [10_000000, 15_000000, 20_000000, 30_000000, 45_000000, 60_000000, 90_000000], label: secondsLabel) timeoutSettingPicker("Protocol timeout", selection: $netCfg.tcpTimeout, values: [5_000000, 7_000000, 10_000000, 15_000000, 20_000000, 30_000000], label: secondsLabel) diff --git a/apps/ios/SimpleXChat/AppGroup.swift b/apps/ios/SimpleXChat/AppGroup.swift index c754f0740d..45a05a1cd6 100644 --- a/apps/ios/SimpleXChat/AppGroup.swift +++ b/apps/ios/SimpleXChat/AppGroup.swift @@ -40,6 +40,7 @@ let GROUP_DEFAULT_NETWORK_USE_ONION_HOSTS = "networkUseOnionHosts" let GROUP_DEFAULT_NETWORK_SESSION_MODE = "networkSessionMode" let GROUP_DEFAULT_NETWORK_SMP_PROXY_MODE = "networkSMPProxyMode" let GROUP_DEFAULT_NETWORK_SMP_PROXY_FALLBACK = "networkSMPProxyFallback" +let GROUP_DEFAULT_NETWORK_SMP_WEB_PORT = "networkSMPWebPort" let GROUP_DEFAULT_NETWORK_TCP_CONNECT_TIMEOUT = "networkTCPConnectTimeout" let GROUP_DEFAULT_NETWORK_TCP_TIMEOUT = "networkTCPTimeout" let GROUP_DEFAULT_NETWORK_TCP_TIMEOUT_PER_KB = "networkTCPTimeoutPerKb" @@ -71,6 +72,7 @@ public func registerGroupDefaults() { GROUP_DEFAULT_NETWORK_SESSION_MODE: TransportSessionMode.session.rawValue, GROUP_DEFAULT_NETWORK_SMP_PROXY_MODE: SMPProxyMode.unknown.rawValue, GROUP_DEFAULT_NETWORK_SMP_PROXY_FALLBACK: SMPProxyFallback.allowProtected.rawValue, + GROUP_DEFAULT_NETWORK_SMP_WEB_PORT: false, GROUP_DEFAULT_NETWORK_TCP_CONNECT_TIMEOUT: NetCfg.defaults.tcpConnectTimeout, GROUP_DEFAULT_NETWORK_TCP_TIMEOUT: NetCfg.defaults.tcpTimeout, GROUP_DEFAULT_NETWORK_TCP_TIMEOUT_PER_KB: NetCfg.defaults.tcpTimeoutPerKb, @@ -336,6 +338,7 @@ public func getNetCfg() -> NetCfg { let sessionMode = networkSessionModeGroupDefault.get() let smpProxyMode = networkSMPProxyModeGroupDefault.get() let smpProxyFallback = networkSMPProxyFallbackGroupDefault.get() + let smpWebPort = groupDefaults.bool(forKey: GROUP_DEFAULT_NETWORK_SMP_WEB_PORT) let tcpConnectTimeout = groupDefaults.integer(forKey: GROUP_DEFAULT_NETWORK_TCP_CONNECT_TIMEOUT) let tcpTimeout = groupDefaults.integer(forKey: GROUP_DEFAULT_NETWORK_TCP_TIMEOUT) let tcpTimeoutPerKb = groupDefaults.integer(forKey: GROUP_DEFAULT_NETWORK_TCP_TIMEOUT_PER_KB) @@ -359,7 +362,7 @@ public func getNetCfg() -> NetCfg { sessionMode: sessionMode, smpProxyMode: smpProxyMode, smpProxyFallback: smpProxyFallback, - smpWebPort: false, + smpWebPort: smpWebPort, tcpConnectTimeout: tcpConnectTimeout, tcpTimeout: tcpTimeout, tcpTimeoutPerKb: tcpTimeoutPerKb, @@ -378,6 +381,7 @@ public func setNetCfg(_ cfg: NetCfg, networkProxy: NetworkProxy?) { networkSMPProxyFallbackGroupDefault.set(cfg.smpProxyFallback) let socksProxy = networkProxy?.toProxyString() groupDefaults.set(socksProxy, forKey: GROUP_DEFAULT_NETWORK_SOCKS_PROXY) + groupDefaults.set(cfg.smpWebPort, forKey: GROUP_DEFAULT_NETWORK_SMP_WEB_PORT) groupDefaults.set(cfg.tcpConnectTimeout, forKey: GROUP_DEFAULT_NETWORK_TCP_CONNECT_TIMEOUT) groupDefaults.set(cfg.tcpTimeout, forKey: GROUP_DEFAULT_NETWORK_TCP_TIMEOUT) groupDefaults.set(cfg.tcpTimeoutPerKb, forKey: GROUP_DEFAULT_NETWORK_TCP_TIMEOUT_PER_KB) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt index bf011c0bb7..94b0412821 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt @@ -172,6 +172,7 @@ class AppPreferences { val networkSMPProxyFallback = mkStrPreference(SHARED_PREFS_NETWORK_SMP_PROXY_FALLBACK, NetCfg.defaults.smpProxyFallback.name) val networkHostMode = mkStrPreference(SHARED_PREFS_NETWORK_HOST_MODE, HostMode.OnionViaSocks.name) val networkRequiredHostMode = mkBoolPreference(SHARED_PREFS_NETWORK_REQUIRED_HOST_MODE, false) + val networkSMPWebPort = mkBoolPreference(SHARED_PREFS_NETWORK_SMP_WEB_PORT, false) val networkTCPConnectTimeout = mkTimeoutPreference(SHARED_PREFS_NETWORK_TCP_CONNECT_TIMEOUT, NetCfg.defaults.tcpConnectTimeout, NetCfg.proxyDefaults.tcpConnectTimeout) val networkTCPTimeout = mkTimeoutPreference(SHARED_PREFS_NETWORK_TCP_TIMEOUT, NetCfg.defaults.tcpTimeout, NetCfg.proxyDefaults.tcpTimeout) val networkTCPTimeoutPerKb = mkTimeoutPreference(SHARED_PREFS_NETWORK_TCP_TIMEOUT_PER_KB, NetCfg.defaults.tcpTimeoutPerKb, NetCfg.proxyDefaults.tcpTimeoutPerKb) @@ -410,6 +411,7 @@ class AppPreferences { private const val SHARED_PREFS_NETWORK_SMP_PROXY_FALLBACK = "NetworkSMPProxyFallback" private const val SHARED_PREFS_NETWORK_HOST_MODE = "NetworkHostMode" private const val SHARED_PREFS_NETWORK_REQUIRED_HOST_MODE = "NetworkRequiredHostMode" + private const val SHARED_PREFS_NETWORK_SMP_WEB_PORT = "NetworkSMPWebPort" private const val SHARED_PREFS_NETWORK_TCP_CONNECT_TIMEOUT = "NetworkTCPConnectTimeout" private const val SHARED_PREFS_NETWORK_TCP_TIMEOUT = "NetworkTCPTimeout" private const val SHARED_PREFS_NETWORK_TCP_TIMEOUT_PER_KB = "networkTCPTimeoutPerKb" @@ -3249,6 +3251,7 @@ object ChatController { val sessionMode = appPrefs.networkSessionMode.get() val smpProxyMode = SMPProxyMode.valueOf(appPrefs.networkSMPProxyMode.get()!!) val smpProxyFallback = SMPProxyFallback.valueOf(appPrefs.networkSMPProxyFallback.get()!!) + val smpWebPort = appPrefs.networkSMPWebPort.get() val tcpConnectTimeout = appPrefs.networkTCPConnectTimeout.get() val tcpTimeout = appPrefs.networkTCPTimeout.get() val tcpTimeoutPerKb = appPrefs.networkTCPTimeoutPerKb.get() @@ -3271,6 +3274,7 @@ object ChatController { sessionMode = sessionMode, smpProxyMode = smpProxyMode, smpProxyFallback = smpProxyFallback, + smpWebPort = smpWebPort, tcpConnectTimeout = tcpConnectTimeout, tcpTimeout = tcpTimeout, tcpTimeoutPerKb = tcpTimeoutPerKb, @@ -3291,6 +3295,7 @@ object ChatController { appPrefs.networkSessionMode.set(cfg.sessionMode) appPrefs.networkSMPProxyMode.set(cfg.smpProxyMode.name) appPrefs.networkSMPProxyFallback.set(cfg.smpProxyFallback.name) + appPrefs.networkSMPWebPort.set(cfg.smpWebPort) appPrefs.networkTCPConnectTimeout.set(cfg.tcpConnectTimeout) appPrefs.networkTCPTimeout.set(cfg.tcpTimeout) appPrefs.networkTCPTimeoutPerKb.set(cfg.tcpTimeoutPerKb) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/AdvancedNetworkSettings.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/AdvancedNetworkSettings.kt index fc042cc46c..79314fa26f 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/AdvancedNetworkSettings.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/AdvancedNetworkSettings.kt @@ -26,6 +26,7 @@ import chat.simplex.common.views.helpers.* import chat.simplex.common.model.ChatModel.controller import chat.simplex.common.platform.ColumnWithScrollBar import chat.simplex.common.platform.chatModel +import chat.simplex.common.views.usersettings.PreferenceToggle import chat.simplex.common.views.usersettings.SettingsPreferenceItem import chat.simplex.res.MR import java.text.DecimalFormat @@ -44,6 +45,7 @@ fun ModalData.AdvancedNetworkSettingsView(showModal: (ModalData.() -> Unit) -> U val sessionMode = remember { mutableStateOf(currentCfgVal.sessionMode) } val smpProxyMode = remember { mutableStateOf(currentCfgVal.smpProxyMode) } val smpProxyFallback = remember { mutableStateOf(currentCfgVal.smpProxyFallback) } + val smpWebPort = remember { mutableStateOf(currentCfgVal.smpWebPort) } val networkTCPConnectTimeout = remember { mutableStateOf(currentCfgVal.tcpConnectTimeout) } val networkTCPTimeout = remember { mutableStateOf(currentCfgVal.tcpTimeout) } @@ -82,6 +84,7 @@ fun ModalData.AdvancedNetworkSettingsView(showModal: (ModalData.() -> Unit) -> U sessionMode = sessionMode.value, smpProxyMode = smpProxyMode.value, smpProxyFallback = smpProxyFallback.value, + smpWebPort = smpWebPort.value, tcpConnectTimeout = networkTCPConnectTimeout.value, tcpTimeout = networkTCPTimeout.value, tcpTimeoutPerKb = networkTCPTimeoutPerKb.value, @@ -96,6 +99,7 @@ fun ModalData.AdvancedNetworkSettingsView(showModal: (ModalData.() -> Unit) -> U sessionMode.value = cfg.sessionMode smpProxyMode.value = cfg.smpProxyMode smpProxyFallback.value = cfg.smpProxyFallback + smpWebPort.value = cfg.smpWebPort networkTCPConnectTimeout.value = cfg.tcpConnectTimeout networkTCPTimeout.value = cfg.tcpTimeout networkTCPTimeoutPerKb.value = cfg.tcpTimeoutPerKb @@ -150,6 +154,7 @@ fun ModalData.AdvancedNetworkSettingsView(showModal: (ModalData.() -> Unit) -> U sessionMode = sessionMode, smpProxyMode = smpProxyMode, smpProxyFallback = smpProxyFallback, + smpWebPort, networkTCPConnectTimeout, networkTCPTimeout, networkTCPTimeoutPerKb, @@ -182,6 +187,7 @@ fun ModalData.AdvancedNetworkSettingsView(showModal: (ModalData.() -> Unit) -> U sessionMode: MutableState, smpProxyMode: MutableState, smpProxyFallback: MutableState, + smpWebPort: MutableState, networkTCPConnectTimeout: MutableState, networkTCPTimeout: MutableState, networkTCPTimeoutPerKb: MutableState, @@ -214,75 +220,80 @@ fun ModalData.AdvancedNetworkSettingsView(showModal: (ModalData.() -> Unit) -> U } SectionTextFooter(stringResource(MR.strings.private_routing_explanation)) SectionDividerSpaced(maxTopPadding = true) - } - if (currentRemoteHost == null) { SectionView(stringResource(MR.strings.network_session_mode_transport_isolation).uppercase()) { SessionModePicker(sessionMode, showModal, updateSessionMode) } SectionDividerSpaced() - } + SectionView(stringResource(MR.strings.network_smp_web_port_section_title).uppercase()) { + PreferenceToggle(stringResource(MR.strings.network_smp_web_port_toggle), checked = smpWebPort.value) { + smpWebPort.value = it + } + } + SectionTextFooter(stringResource(MR.strings.private_routing_explanation)) + SectionDividerSpaced(maxTopPadding = true) - SectionView(stringResource(MR.strings.network_option_tcp_connection).uppercase()) { - SectionItemView { - TimeoutSettingRow( - stringResource(MR.strings.network_option_tcp_connection_timeout), networkTCPConnectTimeout, - listOf(10_000000, 15_000000, 20_000000, 30_000000, 45_000000, 60_000000, 90_000000), secondsLabel - ) - } - SectionItemView { - TimeoutSettingRow( - stringResource(MR.strings.network_option_protocol_timeout), networkTCPTimeout, - listOf(5_000000, 7_000000, 10_000000, 15_000000, 20_000_000, 30_000_000), secondsLabel - ) - } - SectionItemView { - // can't be higher than 130ms to avoid overflow on 32bit systems - TimeoutSettingRow( - stringResource(MR.strings.network_option_protocol_timeout_per_kb), networkTCPTimeoutPerKb, - listOf(2_500, 5_000, 10_000, 15_000, 20_000, 30_000), secondsLabel - ) - } - // SectionItemView { - // IntSettingRow( - // stringResource(MR.strings.network_option_rcv_concurrency), networkRcvConcurrency, - // listOf(1, 2, 4, 8, 12, 16, 24), "" - // ) - // } - SectionItemView { - TimeoutSettingRow( - stringResource(MR.strings.network_option_ping_interval), networkSMPPingInterval, - listOf(120_000000, 300_000000, 600_000000, 1200_000000, 2400_000000, 3600_000000), secondsLabel - ) - } - SectionItemView { - IntSettingRow( - stringResource(MR.strings.network_option_ping_count), networkSMPPingCount, - listOf(1, 2, 3, 5, 8), "" - ) - } - SectionItemView { - EnableKeepAliveSwitch(networkEnableKeepAlive) - } - if (networkEnableKeepAlive.value) { + SectionView(stringResource(MR.strings.network_option_tcp_connection).uppercase()) { SectionItemView { - IntSettingRow("TCP_KEEPIDLE", networkTCPKeepIdle, listOf(15, 30, 60, 120, 180), secondsLabel) + TimeoutSettingRow( + stringResource(MR.strings.network_option_tcp_connection_timeout), networkTCPConnectTimeout, + listOf(10_000000, 15_000000, 20_000000, 30_000000, 45_000000, 60_000000, 90_000000), secondsLabel + ) } SectionItemView { - IntSettingRow("TCP_KEEPINTVL", networkTCPKeepIntvl, listOf(5, 10, 15, 30, 60), secondsLabel) + TimeoutSettingRow( + stringResource(MR.strings.network_option_protocol_timeout), networkTCPTimeout, + listOf(5_000000, 7_000000, 10_000000, 15_000000, 20_000_000, 30_000_000), secondsLabel + ) } SectionItemView { - IntSettingRow("TCP_KEEPCNT", networkTCPKeepCnt, listOf(1, 2, 4, 6, 8), "") + // can't be higher than 130ms to avoid overflow on 32bit systems + TimeoutSettingRow( + stringResource(MR.strings.network_option_protocol_timeout_per_kb), networkTCPTimeoutPerKb, + listOf(2_500, 5_000, 10_000, 15_000, 20_000, 30_000), secondsLabel + ) } - } else { + // SectionItemView { + // IntSettingRow( + // stringResource(MR.strings.network_option_rcv_concurrency), networkRcvConcurrency, + // listOf(1, 2, 4, 8, 12, 16, 24), "" + // ) + // } SectionItemView { - Text("TCP_KEEPIDLE", color = MaterialTheme.colors.secondary) + TimeoutSettingRow( + stringResource(MR.strings.network_option_ping_interval), networkSMPPingInterval, + listOf(120_000000, 300_000000, 600_000000, 1200_000000, 2400_000000, 3600_000000), secondsLabel + ) } SectionItemView { - Text("TCP_KEEPINTVL", color = MaterialTheme.colors.secondary) + IntSettingRow( + stringResource(MR.strings.network_option_ping_count), networkSMPPingCount, + listOf(1, 2, 3, 5, 8), "" + ) } SectionItemView { - Text("TCP_KEEPCNT", color = MaterialTheme.colors.secondary) + EnableKeepAliveSwitch(networkEnableKeepAlive) + } + if (networkEnableKeepAlive.value) { + SectionItemView { + IntSettingRow("TCP_KEEPIDLE", networkTCPKeepIdle, listOf(15, 30, 60, 120, 180), secondsLabel) + } + SectionItemView { + IntSettingRow("TCP_KEEPINTVL", networkTCPKeepIntvl, listOf(5, 10, 15, 30, 60), secondsLabel) + } + SectionItemView { + IntSettingRow("TCP_KEEPCNT", networkTCPKeepCnt, listOf(1, 2, 4, 6, 8), "") + } + } else { + SectionItemView { + Text("TCP_KEEPIDLE", color = MaterialTheme.colors.secondary) + } + SectionItemView { + Text("TCP_KEEPINTVL", color = MaterialTheme.colors.secondary) + } + SectionItemView { + Text("TCP_KEEPCNT", color = MaterialTheme.colors.secondary) + } } } } @@ -537,6 +548,7 @@ fun PreviewAdvancedNetworkSettingsLayout() { sessionMode = remember { mutableStateOf(TransportSessionMode.User) }, smpProxyMode = remember { mutableStateOf(SMPProxyMode.Never) }, smpProxyFallback = remember { mutableStateOf(SMPProxyFallback.Allow) }, + smpWebPort = remember { mutableStateOf(false) }, networkTCPConnectTimeout = remember { mutableStateOf(10_000000) }, networkTCPTimeout = remember { mutableStateOf(10_000000) }, networkTCPTimeoutPerKb = remember { mutableStateOf(10_000) }, diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml index 82e4753dc9..d3256e285c 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml @@ -946,6 +946,9 @@ Message routing fallback Show message status To protect your IP address, private routing uses your SMP servers to deliver messages. + TCP port for messaging + Use web port + Use TCP port %1$s when no port is specified. Appearance Customize theme INTERFACE COLORS