Compare commits

..

19 Commits

Author SHA1 Message Date
Evgeny Poberezkin 22c62d544c Merge branch 'ep/remove-mtl' into ab/ios-haskell-init 2024-03-31 12:26:52 +01:00
Evgeny Poberezkin fbe9a4da39 strict data, optimization 2024-03-31 11:54:58 +01:00
Alexander Bondarenko 2995a79041 update to deMTLd branches 2024-03-31 13:48:52 +03:00
Alexander Bondarenko da197a35a0 Merge remote-tracking branch 'origin/ep/remove-mtl' into ab/ios-haskell-init 2024-03-31 11:27:14 +03:00
Evgeny Poberezkin 6f8578d0f1 core: remove mtl typeclasses to reduce overhead 2024-03-30 23:49:50 +00:00
Alexander Bondarenko 73cabd3c69 add info tables 2024-03-30 16:35:46 +03:00
Alexander Bondarenko c30c181209 unify init_haskell to allow nse profiling 2024-03-30 15:47:48 +03:00
Alexander Bondarenko 701b4186b6 Merge remote-tracking branch 'origin/master' into ios-profiling 2024-03-30 15:47:29 +03:00
Evgeny Poberezkin 257e03f10a Merge branch 'master' into ios-profiling 2024-03-29 19:44:17 +00:00
Alexander Bondarenko 7b644c0dcf Merge remote-tracking branch 'origin/master' into ios-profiling 2024-03-28 20:10:35 +02:00
Alexander Bondarenko c3d9d9a7c3 Merge remote-tracking branch 'origin/master' into ios-profiling 2024-03-27 17:40:14 +02:00
Alexander Bondarenko 261767035e Merge remote-tracking branch 'origin/master' into ios-profiling 2024-03-20 11:22:48 +02:00
spaced4ndy c9b00b3054 Merge branch 'master' into ios-profiling 2024-03-13 11:50:17 +04:00
spaced4ndy 1697190189 remove print 2024-03-12 20:52:05 +04:00
spaced4ndy 24609a98c6 fix paths 2024-03-12 20:49:42 +04:00
Alexander Bondarenko 60752feb9c fix addr 2024-03-12 17:09:54 +02:00
Alexander Bondarenko ff5ef638cd add missing include 2024-03-12 17:09:54 +02:00
spaced4ndy df619d540b ios: save debug profile, event log buttons (#3899) 2024-03-12 19:06:25 +04:00
Alexander Bondarenko 53d8a85b8c add RTS tuning to haskell_init 2024-03-12 16:58:44 +02:00
15 changed files with 202 additions and 168 deletions
+4 -2
View File
@@ -22,8 +22,10 @@ struct SimpleXApp: App {
init() {
DispatchQueue.global(qos: .background).sync {
haskell_init()
// hs_init(0, nil)
// we have to use debug profile file name without extension here because .hp extension is added by profiler
// haskell_init(0, nil, nil)
let dummyHpPath = getAppDebugProfilePrefixPath().path + "_dummy" // not used, but required to populate eventlog
haskell_init(0, getAppEventLogPath().path, dummyHpPath)
}
UserDefaults.standard.register(defaults: appDefaults)
setGroupDefaults()
@@ -45,6 +45,11 @@ struct DeveloperView: View {
}
if developerTools {
Section {
exportDebugProfileButton()
exportEventLogButton()
}
Section {
settingsRow("key") {
Toggle("Post-quantum E2EE", isOn: $pqExperimentalEnabled)
@@ -62,6 +67,24 @@ struct DeveloperView: View {
}
}
@ViewBuilder private func exportDebugProfileButton() -> some View {
let url = getAppDebugProfilePath()
settingsRow("square.and.arrow.up") {
Button("Export debugging profile") {
showShareSheet(items: [url])
}
}.disabled(!FileManager.default.fileExists(atPath: url.path))
}
@ViewBuilder private func exportEventLogButton() -> some View {
let url = getAppEventLogPath()
settingsRow("square.and.arrow.up") {
Button("Export event log") {
showShareSheet(items: [url])
}
}.disabled(!FileManager.default.fileExists(atPath: url.path))
}
private func setPQExperimentalEnabled(_ enable: Bool) {
do {
try apiSetPQEncryption(enable)
+44 -53
View File
@@ -65,24 +65,20 @@ class NSEThreads {
}
func processNotification(_ id: ChatId, _ ntf: NSENotification) async -> Void {
var waitTime: Int64 = 5_000_000000
while waitTime > 0 {
if let (_, nse) = rcvEntityThread(id),
nse.shouldProcessNtf && nse.processReceivedNtf(ntf) {
var timeoutOfWaiting: Int64 = 5_000_000000
while timeoutOfWaiting > 0 {
let activeThread = NSEThreads.queue.sync {
activeThreads.first(where: { (_, nse) in nse.receiveEntityId == id })
}
if activeThread?.1.processReceivedNtf?(ntf) == true {
break
} else {
try? await Task.sleep(nanoseconds: 10_000000)
waitTime -= 10_000000
timeoutOfWaiting -= 10_000000
}
}
}
private func rcvEntityThread(_ id: ChatId) -> (UUID, NotificationService)? {
NSEThreads.queue.sync {
activeThreads.first(where: { (_, nse) in nse.receiveEntityId == id })
}
}
func endThread(_ t: UUID) -> Bool {
NSEThreads.queue.sync {
let tActive: UUID? = if let index = activeThreads.firstIndex(where: { $0.0 == t }) {
@@ -117,11 +113,9 @@ class NotificationService: UNNotificationServiceExtension {
// thread is added to allThreads here - if thread did not start chat,
// chat does not need to be suspended but NSE state still needs to be set to "suspended".
var threadId: UUID? = NSEThreads.shared.newThread()
var notificationInfo: NtfMessages?
var receiveEntityId: String?
var expectedMessages: Set<String> = []
// return true if the message is taken - it prevents sending it to another NotificationService instance for processing
var shouldProcessNtf = false
var processReceivedNtf: ((NSENotification) -> Bool)?
var appSubscriber: AppSubscriber?
var returnedSuspension = false
@@ -198,11 +192,39 @@ class NotificationService: UNNotificationServiceExtension {
? .nse(createConnectionEventNtf(ntfInfo.user, connEntity))
: .empty
)
if let id = connEntity.id, ntfInfo.msgTs != nil {
notificationInfo = ntfInfo
if let id = connEntity.id, let msgTs = ntfInfo.msgTs {
var expected = Set(ntfInfo.ntfMessages.map { $0.msgId })
processReceivedNtf = { ntf in
if !ntfInfo.user.showNotifications {
self.setBestAttemptNtf(.empty)
}
if case let .msgInfo(info) = ntf {
let found = expected.remove(info.msgId)
if found != nil {
logger.debug("NotificationService processNtf: msgInfo, last: \(expected.isEmpty)")
if expected.isEmpty {
self.deliverBestAttemptNtf()
}
return true
} else if info.msgTs > msgTs {
logger.debug("NotificationService processNtf: unexpected msgInfo, let other instance to process it, stopping this one")
self.deliverBestAttemptNtf()
return false
} else {
logger.debug("NotificationService processNtf: unknown message, let other instance to process it")
return false
}
} else if ntfInfo.user.showNotifications {
logger.debug("NotificationService processNtf: setting best attempt")
self.setBestAttemptNtf(ntf)
if ntf.isCallInvitation {
self.deliverBestAttemptNtf()
}
return true
}
return false
}
receiveEntityId = id
expectedMessages = Set(ntfInfo.ntfMessages.map { $0.msgId })
shouldProcessNtf = true
return
}
}
@@ -218,38 +240,6 @@ class NotificationService: UNNotificationServiceExtension {
deliverBestAttemptNtf(urgent: true)
}
func processReceivedNtf(_ ntf: NSENotification) -> Bool {
guard let ntfInfo = notificationInfo, let msgTs = ntfInfo.msgTs else { return false }
if !ntfInfo.user.showNotifications {
self.setBestAttemptNtf(.empty)
}
if case let .msgInfo(info) = ntf {
let found = expectedMessages.remove(info.msgId)
if found != nil {
logger.debug("NotificationService processNtf: msgInfo, last: \(self.expectedMessages.isEmpty)")
if expectedMessages.isEmpty {
self.deliverBestAttemptNtf()
}
return true
} else if info.msgTs > msgTs {
logger.debug("NotificationService processNtf: unexpected msgInfo, let other instance to process it, stopping this one")
self.deliverBestAttemptNtf()
return false
} else {
logger.debug("NotificationService processNtf: unknown message, let other instance to process it")
return false
}
} else if ntfInfo.user.showNotifications {
logger.debug("NotificationService processNtf: setting best attempt")
self.setBestAttemptNtf(ntf)
if ntf.isCallInvitation {
self.deliverBestAttemptNtf()
}
return true
}
return false
}
func setBadgeCount() {
badgeCount = ntfBadgeCountGroupDefault.get() + 1
ntfBadgeCountGroupDefault.set(badgeCount)
@@ -272,7 +262,7 @@ class NotificationService: UNNotificationServiceExtension {
private func deliverBestAttemptNtf(urgent: Bool = false) {
logger.debug("NotificationService.deliverBestAttemptNtf")
// stop processing other messages
shouldProcessNtf = false
processReceivedNtf = nil
let suspend: Bool
if let t = threadId {
@@ -406,7 +396,7 @@ func startChat() -> DBMigrationResult? {
startLock.wait()
defer { startLock.signal() }
if hasChatCtrl() {
return switch NSEChatState.shared.value {
case .created: doStartChat()
@@ -425,7 +415,8 @@ func startChat() -> DBMigrationResult? {
func doStartChat() -> DBMigrationResult? {
logger.debug("NotificationService: doStartChat")
haskell_init_nse()
haskell_init(1, nil, getAppDebugProfilePrefixPath().path)
// haskell_init(1, nil, nil)
let (_, dbStatus) = chatMigrateInit(confirmMigrations: defaultMigrationConfirmation(), backgroundMode: true)
logger.debug("NotificationService: doStartChat \(String(describing: dbStatus))")
if dbStatus != .ok {
+24 -54
View File
@@ -18,6 +18,11 @@
18415FEFE153C5920BFB7828 /* GroupWelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1841516F0CE5992B0EDFB377 /* GroupWelcomeView.swift */; };
3CDBCF4227FAE51000354CDD /* ComposeLinkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CDBCF4127FAE51000354CDD /* ComposeLinkView.swift */; };
3CDBCF4827FF621E00354CDD /* CILinkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CDBCF4727FF621E00354CDD /* CILinkView.swift */; };
411D3A7C2BB9601D003D9A22 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 411D3A772BB9601D003D9A22 /* libgmp.a */; };
411D3A7D2BB9601D003D9A22 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 411D3A782BB9601D003D9A22 /* libffi.a */; };
411D3A7E2BB9601D003D9A22 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 411D3A792BB9601D003D9A22 /* libgmpxx.a */; };
411D3A7F2BB9601D003D9A22 /* libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 411D3A7A2BB9601D003D9A22 /* libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv-ghc9.6.3.a */; };
411D3A802BB9601D003D9A22 /* libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 411D3A7B2BB9601D003D9A22 /* libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv.a */; };
5C00164428A26FBC0094D739 /* ContextMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C00164328A26FBC0094D739 /* ContextMenu.swift */; };
5C00168128C4FE760094D739 /* KeyChain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C00168028C4FE760094D739 /* KeyChain.swift */; };
5C029EA82837DBB3004A9677 /* CICallItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C029EA72837DBB3004A9677 /* CICallItemView.swift */; };
@@ -139,11 +144,6 @@
5CEACCED27DEA495000BD591 /* MsgContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CEACCEC27DEA495000BD591 /* MsgContentView.swift */; };
5CEBD7462A5C0A8F00665FE2 /* KeyboardPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CEBD7452A5C0A8F00665FE2 /* KeyboardPadding.swift */; };
5CEBD7482A5F115D00665FE2 /* SetDeliveryReceiptsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CEBD7472A5F115D00665FE2 /* SetDeliveryReceiptsView.swift */; };
5CF898622BB984E400EE33B6 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CF8985D2BB984E400EE33B6 /* libgmpxx.a */; };
5CF898632BB984E400EE33B6 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CF8985E2BB984E400EE33B6 /* libffi.a */; };
5CF898642BB984E400EE33B6 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CF8985F2BB984E400EE33B6 /* libgmp.a */; };
5CF898652BB984E400EE33B6 /* libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CF898602BB984E400EE33B6 /* libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv.a */; };
5CF898662BB984E400EE33B6 /* libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CF898612BB984E400EE33B6 /* libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv-ghc9.6.3.a */; };
5CF937202B24DE8C00E1D781 /* SharedFileSubscriber.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CF9371F2B24DE8C00E1D781 /* SharedFileSubscriber.swift */; };
5CF937232B2503D000E1D781 /* NSESubscriber.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CF937212B25034A00E1D781 /* NSESubscriber.swift */; };
5CFA59C42860BC6200863A68 /* MigrateToAppGroupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CFA59C32860BC6200863A68 /* MigrateToAppGroupView.swift */; };
@@ -263,6 +263,11 @@
18415FD2E36F13F596A45BB4 /* CIVideoView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CIVideoView.swift; sourceTree = "<group>"; };
3CDBCF4127FAE51000354CDD /* ComposeLinkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeLinkView.swift; sourceTree = "<group>"; };
3CDBCF4727FF621E00354CDD /* CILinkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CILinkView.swift; sourceTree = "<group>"; };
411D3A772BB9601D003D9A22 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgmp.a; path = ios/libgmp.a; sourceTree = "<group>"; };
411D3A782BB9601D003D9A22 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libffi.a; path = ios/libffi.a; sourceTree = "<group>"; };
411D3A792BB9601D003D9A22 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgmpxx.a; path = ios/libgmpxx.a; sourceTree = "<group>"; };
411D3A7A2BB9601D003D9A22 /* libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv-ghc9.6.3.a"; path = "ios/libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv-ghc9.6.3.a"; sourceTree = "<group>"; };
411D3A7B2BB9601D003D9A22 /* libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv.a"; path = "ios/libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv.a"; sourceTree = "<group>"; };
5C00164328A26FBC0094D739 /* ContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextMenu.swift; sourceTree = "<group>"; };
5C00168028C4FE760094D739 /* KeyChain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyChain.swift; sourceTree = "<group>"; };
5C029EA72837DBB3004A9677 /* CICallItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CICallItemView.swift; sourceTree = "<group>"; };
@@ -431,11 +436,6 @@
5CEACCEC27DEA495000BD591 /* MsgContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MsgContentView.swift; sourceTree = "<group>"; };
5CEBD7452A5C0A8F00665FE2 /* KeyboardPadding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardPadding.swift; sourceTree = "<group>"; };
5CEBD7472A5F115D00665FE2 /* SetDeliveryReceiptsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetDeliveryReceiptsView.swift; sourceTree = "<group>"; };
5CF8985D2BB984E400EE33B6 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
5CF8985E2BB984E400EE33B6 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
5CF8985F2BB984E400EE33B6 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
5CF898602BB984E400EE33B6 /* libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv.a"; sourceTree = "<group>"; };
5CF898612BB984E400EE33B6 /* libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv-ghc9.6.3.a"; sourceTree = "<group>"; };
5CF9371F2B24DE8C00E1D781 /* SharedFileSubscriber.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharedFileSubscriber.swift; sourceTree = "<group>"; };
5CF937212B25034A00E1D781 /* NSESubscriber.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSESubscriber.swift; sourceTree = "<group>"; };
5CFA59C32860BC6200863A68 /* MigrateToAppGroupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrateToAppGroupView.swift; sourceTree = "<group>"; };
@@ -521,13 +521,13 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
5CF898652BB984E400EE33B6 /* libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv.a in Frameworks */,
5CF898622BB984E400EE33B6 /* libgmpxx.a in Frameworks */,
5CF898642BB984E400EE33B6 /* libgmp.a in Frameworks */,
5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */,
411D3A7E2BB9601D003D9A22 /* libgmpxx.a in Frameworks */,
411D3A7C2BB9601D003D9A22 /* libgmp.a in Frameworks */,
411D3A802BB9601D003D9A22 /* libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv.a in Frameworks */,
5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */,
5CF898632BB984E400EE33B6 /* libffi.a in Frameworks */,
5CF898662BB984E400EE33B6 /* libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv-ghc9.6.3.a in Frameworks */,
411D3A7F2BB9601D003D9A22 /* libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv-ghc9.6.3.a in Frameworks */,
411D3A7D2BB9601D003D9A22 /* libffi.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -590,11 +590,11 @@
5C764E5C279C70B7000C6508 /* Libraries */ = {
isa = PBXGroup;
children = (
5CF8985E2BB984E400EE33B6 /* libffi.a */,
5CF8985F2BB984E400EE33B6 /* libgmp.a */,
5CF8985D2BB984E400EE33B6 /* libgmpxx.a */,
5CF898612BB984E400EE33B6 /* libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv-ghc9.6.3.a */,
5CF898602BB984E400EE33B6 /* libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv.a */,
411D3A782BB9601D003D9A22 /* libffi.a */,
411D3A772BB9601D003D9A22 /* libgmp.a */,
411D3A792BB9601D003D9A22 /* libgmpxx.a */,
411D3A7A2BB9601D003D9A22 /* libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv-ghc9.6.3.a */,
411D3A7B2BB9601D003D9A22 /* libHSsimplex-chat-5.6.0.4-FOF2McwHkk1EIlP5UNozOv.a */,
);
path = Libraries;
sourceTree = "<group>";
@@ -1441,7 +1441,6 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
@@ -1503,7 +1502,6 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
@@ -1532,16 +1530,12 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
CLANG_ENABLE_MODULES = YES;
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 204;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
ENABLE_PREVIEWS = YES;
GCC_OPTIMIZATION_LEVEL = s;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "SimpleX--iOS--Info.plist";
INFOPLIST_KEY_NSCameraUsageDescription = "SimpleX needs camera access to scan QR codes to connect to other users and for video calls.";
@@ -1560,13 +1554,11 @@
"$(inherited)",
"@executable_path/Frameworks",
);
LLVM_LTO = YES_THIN;
MARKETING_VERSION = 5.6;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app;
PRODUCT_NAME = SimpleX;
SDKROOT = iphoneos;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
};
@@ -1581,16 +1573,13 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
CLANG_ENABLE_MODULES = YES;
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 204;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
ENABLE_CODE_COVERAGE = NO;
ENABLE_PREVIEWS = NO;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "SimpleX--iOS--Info.plist";
INFOPLIST_KEY_NSCameraUsageDescription = "SimpleX needs camera access to scan QR codes to connect to other users and for video calls.";
@@ -1609,7 +1598,6 @@
"$(inherited)",
"@executable_path/Frameworks",
);
LLVM_LTO = YES;
MARKETING_VERSION = 5.6;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app;
PRODUCT_NAME = SimpleX;
@@ -1666,15 +1654,12 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 204;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
GCC_OPTIMIZATION_LEVEL = s;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "SimpleX NSE/Info.plist";
INFOPLIST_KEY_CFBundleDisplayName = "SimpleX NSE";
@@ -1685,7 +1670,6 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
LLVM_LTO = YES;
MARKETING_VERSION = 5.6;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE";
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -1693,7 +1677,6 @@
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Osize";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
};
@@ -1703,15 +1686,13 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 204;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
ENABLE_CODE_COVERAGE = NO;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "SimpleX NSE/Info.plist";
INFOPLIST_KEY_CFBundleDisplayName = "SimpleX NSE";
@@ -1722,7 +1703,6 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
LLVM_LTO = YES;
MARKETING_VERSION = 5.6;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE";
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -1730,7 +1710,6 @@
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Osize";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
VALIDATE_PRODUCT = YES;
@@ -1742,8 +1721,6 @@
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 204;
DEFINES_MODULE = YES;
@@ -1752,7 +1729,6 @@
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_BITCODE = NO;
GCC_OPTIMIZATION_LEVEL = s;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022 SimpleX Chat. All rights reserved.";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
@@ -1770,7 +1746,6 @@
"$(inherited)",
"$(PROJECT_DIR)/Libraries/sim",
);
LLVM_LTO = YES;
MARKETING_VERSION = 5.6;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
@@ -1780,7 +1755,6 @@
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_INCLUDE_PATHS = "";
SWIFT_OBJC_BRIDGING_HEADER = ./SimpleXChat/SimpleX.h;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
@@ -1793,17 +1767,15 @@
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 204;
DEBUG_INFORMATION_FORMAT = dwarf;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_BITCODE = NO;
ENABLE_CODE_COVERAGE = NO;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022 SimpleX Chat. All rights reserved.";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
@@ -1821,7 +1793,6 @@
"$(inherited)",
"$(PROJECT_DIR)/Libraries/sim",
);
LLVM_LTO = YES;
MARKETING_VERSION = 5.6;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
@@ -1831,7 +1802,6 @@
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_INCLUDE_PATHS = "";
SWIFT_OBJC_BRIDGING_HEADER = ./SimpleXChat/SimpleX.h;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
+16
View File
@@ -52,6 +52,10 @@ func getAppDirectory() -> URL {
let DB_FILE_PREFIX = "simplex_v1"
let DEBUG_PROFILE_PREFIX = "simplex_debug"
let DEBUG_PROFILE_EXTENSION = ".hp"
func getLegacyDatabasePath() -> URL {
getDocumentsDirectory().appendingPathComponent("mobile_v1", isDirectory: false)
}
@@ -62,6 +66,18 @@ public func getAppDatabasePath() -> URL {
: getLegacyDatabasePath()
}
public func getAppDebugProfilePrefixPath() -> URL {
getAppDirectory().appendingPathComponent(DEBUG_PROFILE_PREFIX, isDirectory: false)
}
public func getAppDebugProfilePath() -> URL {
getAppDirectory().appendingPathComponent(DEBUG_PROFILE_PREFIX + DEBUG_PROFILE_EXTENSION, isDirectory: false)
}
public func getAppEventLogPath() -> URL {
getAppDirectory().appendingPathComponent("simplex.eventlog", isDirectory: false)
}
func fileModificationDate(_ path: String) -> Date? {
do {
let attr = try FileManager.default.attributesOfItem(atPath: path)
+45 -13
View File
@@ -7,32 +7,64 @@
//
#include "hs_init.h"
#include <string.h>
extern void hs_init_with_rtsopts(int * argc, char **argv[]);
void haskell_init(void) {
int argc = 5;
char *argv[] = {
"simplex",
"+RTS", // requires `hs_init_with_rtsopts`
"-A64m", // chunk size for new allocations
"-H64m", // initial heap size
"-xn", // non-moving GC
0
};
void haskell_init(int nse, const char *eventlog, const char *heap_profile) {
// setup static arena for bump allocation and passing to RTS
char *argv[32] = {0,};
int argc = 0; // number of arguments used so far, always stands at the first NULL in argv
// common args
if (nse) {
argv[argc++] = "simplex-nse"; // fake program name
} else {
argv[argc++] = "simplex";
}
argv[argc++] = "+RTS"; // start adding RTS options
if (nse) {
argv[argc++] = "-S"; // spam stdout with GC stats
argv[argc++] = "-A1m"; // chunk size for new allocations (less frequent GC)
argv[argc++] = "-H2m"; // larger heap size on start (faster boot)
argv[argc++] = "-M12m"; // hard limit on heap
argv[argc++] = "-F0.5"; // heap growth triggering GC
argv[argc++] = "-Fd1"; // memory return
} else {
argv[argc++] = "-T"; // make GC counters available from inside the program
argv[argc++] = "-A64m"; // chunk size for new allocations (less frequent GC)
argv[argc++] = "-H64m"; // larger heap size on start (faster boot)
}
// argv[argc++] = "-M8G"; // keep memory usage under 8G, collecting more aggressively when approaching it (and crashing sooner rather than taking down the whole system)
if (eventlog) {
static char ol[1024] = "-ol";
(void)strncpy(&ol[3], eventlog, sizeof(ol) - 3);
argv[argc++] = ol;
argv[argc++] = "-l-agu"; // collect GC and user events
}
if (heap_profile) {
static char po[1024] = "-po";
(void)strncpy(&po[3], heap_profile, sizeof(po) - 3);
argv[argc++] = po; // adds ".hp" extension
argv[argc++] = "-hT"; // emit heap profile by closure type
}
if (nse) {
argv[argc++] = "-c"; // compacting garbage collector
} else {
int non_moving_gc = !heap_profile; // not compatible with heap profile
if (non_moving_gc) argv[argc++] = "-xn";
}
// wrap args as expected by RTS
char **pargv = argv;
hs_init_with_rtsopts(&argc, &pargv);
}
void haskell_init_nse(void) {
int argc = 9;
int argc = 7;
char *argv[] = {
"simplex",
"+RTS", // requires `hs_init_with_rtsopts`
"-A1m", // chunk size for new allocations
"-H1m", // initial heap size
"-M12m", // maximum heap size (25 total - 1 grace - 12 for swift), make GC work harder when approaching the limit
"-Mgrace=1m", // (default, just to make explicit) extra memory to handle "memory exhausted" exception and fail cleanly
"-F0.5", // heap growth triggering GC
"-Fd1", // memory return
"-c", // compacting garbage collector
+1 -1
View File
@@ -9,7 +9,7 @@
#ifndef hs_init_h
#define hs_init_h
void haskell_init(void);
void haskell_init(int nse, const char *eventlog, const char *heap_profile);
void haskell_init_nse(void);
+1 -1
View File
@@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd
source-repository-package
type: git
location: https://github.com/simplex-chat/simplexmq.git
tag: bfd532e833aff36754ef766f4e021f0079a7f83c
tag: 8b94264623eb8f32793a3b4129cb12770f54ef3a
source-repository-package
type: git
+3 -2
View File
@@ -1,5 +1,5 @@
name: simplex-chat
version: 5.6.1.0
version: 5.6.0.4
#synopsis:
#description:
homepage: https://github.com/simplex-chat/simplex-chat#readme
@@ -74,7 +74,6 @@ when:
library:
source-dirs: src
ghc-options: -O2
executables:
simplex-chat:
@@ -159,6 +158,8 @@ ghc-options:
- -Wincomplete-record-updates
- -Wincomplete-uni-patterns
- -Wunused-type-patterns
- -finfo-table-map
- -fdistinct-constructor-tables
default-extensions:
- StrictData
+1 -1
View File
@@ -1,5 +1,5 @@
{
"https://github.com/simplex-chat/simplexmq.git"."bfd532e833aff36754ef766f4e021f0079a7f83c" = "1xxcdadllimk2hgzz6aggvywr14zm2h0l62c92yvnyvps9j49gdx";
"https://github.com/simplex-chat/simplexmq.git"."8b94264623eb8f32793a3b4129cb12770f54ef3a" = "0n4wwpkj9dps7ansvlrdf4kiwjczij7y79i4cnr3gr0lmml8bpbs";
"https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38";
"https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "1ql13f4kfwkbaq7nygkxgw84213i0zm7c1a8hwvramayxl38dq5d";
"https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl";
+8 -8
View File
@@ -5,7 +5,7 @@ cabal-version: 1.12
-- see: https://github.com/sol/hpack
name: simplex-chat
version: 5.6.1.0
version: 5.6.0.4
category: Web, System, Services, Cryptography
homepage: https://github.com/simplex-chat/simplex-chat#readme
author: simplex.chat
@@ -183,7 +183,7 @@ library
src
default-extensions:
StrictData
ghc-options: -O2 -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns
ghc-options: -O2 -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns -finfo-table-map -fdistinct-constructor-tables
build-depends:
aeson ==2.2.*
, ansi-terminal >=0.10 && <0.12
@@ -244,7 +244,7 @@ executable simplex-bot
apps/simplex-bot
default-extensions:
StrictData
ghc-options: -O2 -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns -threaded
ghc-options: -O2 -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns -finfo-table-map -fdistinct-constructor-tables -threaded
build-depends:
aeson ==2.2.*
, ansi-terminal >=0.10 && <0.12
@@ -306,7 +306,7 @@ executable simplex-bot-advanced
apps/simplex-bot-advanced
default-extensions:
StrictData
ghc-options: -O2 -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns -threaded
ghc-options: -O2 -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns -finfo-table-map -fdistinct-constructor-tables -threaded
build-depends:
aeson ==2.2.*
, ansi-terminal >=0.10 && <0.12
@@ -371,7 +371,7 @@ executable simplex-broadcast-bot
Broadcast.Bot
Broadcast.Options
Paths_simplex_chat
ghc-options: -O2 -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns -threaded
ghc-options: -O2 -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns -finfo-table-map -fdistinct-constructor-tables -threaded
build-depends:
aeson ==2.2.*
, ansi-terminal >=0.10 && <0.12
@@ -434,7 +434,7 @@ executable simplex-chat
apps/simplex-chat
default-extensions:
StrictData
ghc-options: -O2 -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns -threaded
ghc-options: -O2 -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns -finfo-table-map -fdistinct-constructor-tables -threaded
build-depends:
aeson ==2.2.*
, ansi-terminal >=0.10 && <0.12
@@ -503,7 +503,7 @@ executable simplex-directory-service
Directory.Service
Directory.Store
Paths_simplex_chat
ghc-options: -O2 -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns -threaded
ghc-options: -O2 -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns -finfo-table-map -fdistinct-constructor-tables -threaded
build-depends:
aeson ==2.2.*
, ansi-terminal >=0.10 && <0.12
@@ -596,7 +596,7 @@ test-suite simplex-chat-test
apps/simplex-directory-service/src
default-extensions:
StrictData
ghc-options: -O2 -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns -threaded
ghc-options: -O2 -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns -finfo-table-map -fdistinct-constructor-tables -threaded
build-depends:
QuickCheck ==2.14.*
, aeson ==2.2.*
+3 -3
View File
@@ -2989,9 +2989,9 @@ agentSubscriber :: CM' ()
agentSubscriber = do
q <- asks $ subQ . smpAgent
l <- asks chatLock
forever $ atomically (readTBQueue q) >>= process l
forever $ atomically (readTBQueue q) >>= void . process l
where
process :: Lock -> (ACorrId, EntityId, APartyCmd 'Agent) -> CM' ()
process :: Lock -> (ACorrId, EntityId, APartyCmd 'Agent) -> CM' (Either ChatError ())
process l (corrId, entId, APC e msg) = run $ case e of
SAENone -> processAgentMessageNoConn msg
SAEConn -> processAgentMessage corrId entId msg
@@ -3000,7 +3000,7 @@ agentSubscriber = do
where
run action = do
let name = "agentSubscriber entity=" <> show e <> " entId=" <> str entId <> " msg=" <> str (aCommandTag msg)
withLock' l name $ action `catchChatError'` (toView' . CRChatError Nothing)
withLock l name $ runExceptT $ action `catchChatError` (toView . CRChatError Nothing)
str :: StrEncoding a => a -> String
str = B.unpack . strEncode
+1 -2
View File
@@ -62,7 +62,6 @@ import Simplex.Chat.Remote.Types
import Simplex.Chat.Store (AutoAccept, StoreError (..), UserContactLink, UserMsgReceiptSettings)
import Simplex.Chat.Types
import Simplex.Chat.Types.Preferences
import Simplex.Chat.Util (liftIOEither)
import Simplex.FileTransfer.Description (FileDescriptionURI)
import Simplex.Messaging.Agent (AgentClient, SubscriptionsInfo)
import Simplex.Messaging.Agent.Client (AgentLocks, AgentWorkersDetails (..), AgentWorkersSummary (..), ProtocolTestFailure)
@@ -1341,7 +1340,7 @@ withStore' action = withStore $ liftIO . action
withStore :: (DB.Connection -> ExceptT StoreError IO a) -> CM a
withStore action = do
ChatController {chatStore} <- ask
liftIOEither $ withTransaction chatStore (runExceptT . withExceptT ChatErrorStore . action) `E.catches` handleDBErrors
liftEither =<< liftIO (withTransaction chatStore (runExceptT . withExceptT ChatErrorStore . action) `E.catches` handleDBErrors)
withStoreBatch :: Traversable t => (DB.Connection -> t (IO (Either ChatError a))) -> CM' (t (Either ChatError a))
withStoreBatch actions = do
+21 -23
View File
@@ -353,7 +353,7 @@ storeRemoteFile rhId encrypted_ localPath = do
createDirectoryIfMissing True tmpDir
tmpFile <- liftIO $ tmpDir `uniqueCombine` takeFileName localPath
cfArgs <- atomically . CF.randomArgs =<< asks random
liftError (ChatError . CEFileWrite tmpFile) $ encryptFile localPath tmpFile cfArgs
liftEither =<< liftIO (runExceptT $ withExceptT (ChatError . CEFileWrite tmpFile) $ encryptFile localPath tmpFile cfArgs)
pure $ CryptoFile tmpFile $ Just cfArgs
getRemoteFile :: RemoteHostId -> RemoteFile -> CM ()
@@ -493,14 +493,14 @@ parseCtrlAppInfo :: JT.Value -> CM CtrlAppInfo
parseCtrlAppInfo ctrlAppInfo = do
liftEitherWith (const $ ChatErrorRemoteCtrl RCEBadInvitation) $ JT.parseEither J.parseJSON ctrlAppInfo
handleRemoteCommand :: (ByteString -> CM' ChatResponse) -> RemoteCrypto -> TBQueue ChatResponse -> HTTP2Request -> CM' ()
handleRemoteCommand :: (ByteString -> CM' ChatResponse) -> RemoteCrypto -> TBQueue ChatResponse -> HTTP2Request -> CM ()
handleRemoteCommand execChatCommand encryption remoteOutputQ HTTP2Request {request, reqBody, sendResponse} = do
logDebug "handleRemoteCommand"
liftIO (tryRemoteError' parseRequest) >>= \case
liftRC (tryRemoteError parseRequest) >>= \case
Right (getNext, rc) -> do
chatReadVar' currentUser >>= \case
chatReadVar currentUser >>= \case
Nothing -> replyError $ ChatError CENoActiveUser
Just user -> processCommand user getNext rc `catchChatError'` replyError
Just user -> processCommand user getNext rc `catchChatError` replyError
Left e -> reply $ RRProtocolError e
where
parseRequest :: ExceptT RemoteProtocolError IO (GetChunk, RemoteCommand)
@@ -510,20 +510,19 @@ handleRemoteCommand execChatCommand encryption remoteOutputQ HTTP2Request {reque
replyError = reply . RRChatResponse . CRChatCmdError Nothing
processCommand :: User -> GetChunk -> RemoteCommand -> CM ()
processCommand user getNext = \case
RCSend {command} -> lift $ handleSend execChatCommand command >>= reply
RCRecv {wait = time} -> lift $ liftIO (handleRecv time remoteOutputQ) >>= reply
RCStoreFile {fileName, fileSize, fileDigest} -> lift $ handleStoreFile encryption fileName fileSize fileDigest getNext >>= reply
RCSend {command} -> lift (handleSend execChatCommand command) >>= reply
RCRecv {wait = time} -> liftIO (handleRecv time remoteOutputQ) >>= reply
RCStoreFile {fileName, fileSize, fileDigest} -> lift (handleStoreFile encryption fileName fileSize fileDigest getNext) >>= reply
RCGetFile {file} -> handleGetFile encryption user file replyWith
reply :: RemoteResponse -> CM' ()
reply :: RemoteResponse -> CM ()
reply = (`replyWith` \_ -> pure ())
replyWith :: Respond
replyWith rr attach =
liftIO (tryRemoteError' . encryptEncodeHTTP2Body encryption $ J.encode rr) >>= \case
Right resp -> liftIO . sendResponse . responseStreaming N.status200 [] $ \send flush -> do
send resp
attach send
flush
Left e -> toView' . CRChatError Nothing . ChatErrorRemoteCtrl $ RCEProtocolError e
replyWith rr attach = do
resp <- liftRC $ encryptEncodeHTTP2Body encryption $ J.encode rr
liftIO . sendResponse . responseStreaming N.status200 [] $ \send flush -> do
send resp
attach send
flush
takeRCStep :: RCStepTMVar a -> CM a
takeRCStep = liftError' (\e -> ChatErrorAgent {agentError = RCP e, connectionEntity_ = Nothing}) . atomically . takeTMVar
@@ -532,7 +531,7 @@ type GetChunk = Int -> IO ByteString
type SendChunk = Builder -> IO ()
type Respond = RemoteResponse -> (SendChunk -> IO ()) -> CM' ()
type Respond = RemoteResponse -> (SendChunk -> IO ()) -> CM ()
liftRC :: ExceptT RemoteProtocolError IO a -> CM a
liftRC = liftError (ChatErrorRemoteCtrl . RCEProtocolError)
@@ -550,7 +549,7 @@ handleSend execChatCommand command = do
logDebug $ "Send: " <> tshow command
-- execChatCommand checks for remote-allowed commands
-- convert errors thrown in execChatCommand into error responses to prevent aborting the protocol wrapper
RRChatResponse <$> execChatCommand (encodeUtf8 command)
RRChatResponse <$> lift (execChatCommand $ encodeUtf8 command) `catchChatError'` (pure . CRChatError Nothing)
handleRecv :: Int -> TBQueue ChatResponse -> IO RemoteResponse
handleRecv time events = do
@@ -582,11 +581,11 @@ handleGetFile encryption User {userId} RemoteFile {userId = commandUserId, fileI
cf <- getLocalCryptoFile db commandUserId fileId sent
unless (cf == cf') $ throwError $ SEFileNotFound fileId
liftRC (tryRemoteError $ getFileInfo path) >>= \case
Left e -> lift $ reply (RRProtocolError e) $ \_ -> pure ()
Left e -> reply (RRProtocolError e) $ \_ -> pure ()
Right (fileSize, fileDigest) ->
ExceptT . withFile path ReadMode $ \h -> runExceptT $ do
withFile path ReadMode $ \h -> do
encFile <- liftRC $ prepareEncryptedFile encryption (h, fileSize)
lift $ reply RRFile {fileSize, fileDigest} $ sendEncryptedFile encFile
reply RRFile {fileSize, fileDigest} $ sendEncryptedFile encFile
listRemoteCtrls :: CM [RemoteCtrlInfo]
listRemoteCtrls = do
@@ -624,8 +623,7 @@ verifyRemoteCtrlSession execChatCommand sessCode' = do
rc@RemoteCtrl {remoteCtrlId} <- upsertRemoteCtrl ctrlName rcCtrlPairing
remoteOutputQ <- asks (tbqSize . config) >>= newTBQueueIO
encryption <- mkCtrlRemoteCrypto sessionKeys $ tlsUniq tls
cc <- ask
http2Server <- liftIO . async $ attachHTTP2Server tls $ \req -> handleRemoteCommand execChatCommand encryption remoteOutputQ req `runReaderT` cc
http2Server <- async $ attachHTTP2Server tls $ handleRemoteCommand execChatCommand encryption remoteOutputQ
void . forkIO $ monitor sseq http2Server
updateRemoteCtrlSession sseq $ \case
RCSessionPendingConfirmation {} -> Right RCSessionConnected {remoteCtrlId, rcsClient = client, rcsSession, tls, http2Server, remoteOutputQ}
+7 -5
View File
@@ -13,17 +13,19 @@ import Simplex.Messaging.Transport.HTTP2 (defaultHTTP2BufferSize, getHTTP2Body)
import Simplex.Messaging.Transport.HTTP2.Client (HTTP2Client, HTTP2ClientError (..), attachHTTP2Client, bodyHeadSize, connTimeout, defaultHTTP2ClientConfig)
import Simplex.Messaging.Transport.HTTP2.Server (HTTP2Request (..), runHTTP2ServerWith)
import Simplex.RemoteControl.Discovery
import UnliftIO
attachRevHTTP2Client :: IO () -> TLS -> IO (Either HTTP2ClientError HTTP2Client)
attachRevHTTP2Client disconnected = attachHTTP2Client config ANY_ADDR_V4 "0" disconnected defaultHTTP2BufferSize
where
config = defaultHTTP2ClientConfig {bodyHeadSize = doNotPrefetchHead, connTimeout = maxBound}
attachHTTP2Server :: TLS -> (HTTP2Request -> IO ()) -> IO ()
attachHTTP2Server tls processRequest =
runHTTP2ServerWith defaultHTTP2BufferSize ($ tls) $ \sessionId r sendResponse -> do
reqBody <- getHTTP2Body r doNotPrefetchHead
processRequest HTTP2Request {sessionId, request = r, reqBody, sendResponse}
attachHTTP2Server :: MonadUnliftIO m => TLS -> (HTTP2Request -> m ()) -> m ()
attachHTTP2Server tls processRequest = do
withRunInIO $ \unlift ->
runHTTP2ServerWith defaultHTTP2BufferSize ($ tls) $ \sessionId r sendResponse -> do
reqBody <- getHTTP2Body r doNotPrefetchHead
unlift $ processRequest HTTP2Request {sessionId, request = r, reqBody, sendResponse}
-- | Suppress storing initial chunk in bodyHead, forcing clients and servers to stream chunks
doNotPrefetchHead :: Int