mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-27 15:25:22 +00:00
* Fix the three follow-ups from the #1486 review Three defects shipped with the censorship-resilience merge, all confirmed against main: 1. Source-manifest verification silently accepted added files. shasum -c checks only the files the manifest lists, and the Xcode project compiles every source file present in the tree — so a hostile mirror could pass verification by adding a file rather than modifying one. The manifest header and VERIFYING-A-BUILD.md now require the completeness check (git status --porcelain, or a path diff for tarballs) alongside the hash check. 2. A relay removed while Tor was bootstrapping reconnected anyway. dropRelays never subtracted from pendingTorConnectionURLs, and a custom relay passes the allow-list filter, so draining the pending queue resurrected a relay someone had explicitly deleted. 3. Turning Tor off mid-bootstrap read as 'network may be blocking tor'. shutdownCompletely left the detached 75s poll loop running, which then stamped bootstrapDidStall over the clean shutdown state; and the stall handler guarded on torEnforced, which is compile-time true in release, instead of the runtime preference. The poll loop is now generation-fenced (shutdown, dormancy, and restart each invalidate it) and the handler consults persistedTorPreference(). Both app-side fixes carry regression tests proven to fail pre-fix. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Address Codex review: ignored files and manifest placement git status --porcelain omits ignored paths, and .gitignore covers build/ — a planted bitchat/build/Evil.swift would compile via the synchronized group while the documented check stayed silent. The checkout check now uses --ignored. The downloaded manifest also has to live outside the tree, or it trips the completeness checks itself; the doc now says so and references it at /tmp throughout. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: jack <jackjackbits@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
jack
Claude Fable 5
parent
c1ce9029d8
commit
132120a88e
@@ -84,6 +84,10 @@ public final class TorManager: ObservableObject {
|
||||
private var shutdownsInFlight = 0
|
||||
private var startPendingAfterShutdown = false
|
||||
private var bootstrapMonitorStarted = false
|
||||
// Fences the detached poll loop: shutdown, dormancy, and restart each bump
|
||||
// this, so a loop from a previous attempt cannot run out its deadline and
|
||||
// report a stall over state that a newer lifecycle event already owns.
|
||||
private var bootstrapGeneration = 0
|
||||
private var pathMonitor: NWPathMonitor?
|
||||
private var isAppForeground: Bool = true
|
||||
private var lastRestartAt: Date? = nil
|
||||
@@ -268,24 +272,25 @@ public final class TorManager: ObservableObject {
|
||||
private func startBootstrapMonitor() {
|
||||
guard !bootstrapMonitorStarted else { return }
|
||||
bootstrapMonitorStarted = true
|
||||
bootstrapGeneration += 1
|
||||
let generation = bootstrapGeneration
|
||||
Task.detached(priority: .utility) { [weak self] in
|
||||
await self?.bootstrapPollLoop()
|
||||
await self?.bootstrapPollLoop(generation: generation)
|
||||
}
|
||||
}
|
||||
|
||||
private func bootstrapPollLoop() async {
|
||||
private func bootstrapPollLoop(generation: Int) async {
|
||||
let deadline = Date().addingTimeInterval(75)
|
||||
var didComplete = false
|
||||
while Date() < deadline {
|
||||
guard generation == bootstrapGeneration else { return }
|
||||
let progress = Int(arti_bootstrap_progress())
|
||||
let summary = getBootstrapSummary()
|
||||
|
||||
await MainActor.run {
|
||||
self.bootstrapProgress = progress
|
||||
self.bootstrapSummary = summary
|
||||
if progress >= 100 { self.isStarting = false }
|
||||
self.recomputeReady()
|
||||
}
|
||||
self.bootstrapProgress = progress
|
||||
self.bootstrapSummary = summary
|
||||
if progress >= 100 { self.isStarting = false }
|
||||
self.recomputeReady()
|
||||
|
||||
if progress >= 100 {
|
||||
didComplete = true
|
||||
@@ -296,17 +301,17 @@ public final class TorManager: ObservableObject {
|
||||
|
||||
// Running out the deadline is a reportable outcome, not silence. The
|
||||
// loop previously just ended, leaving `isStarting` true forever, so a
|
||||
// blocked network was indistinguishable from a slow one.
|
||||
// blocked network was indistinguishable from a slow one. A deliberate
|
||||
// shutdown mid-bootstrap is not a stall, hence the generation check.
|
||||
if !didComplete {
|
||||
await MainActor.run {
|
||||
self.isStarting = false
|
||||
self.bootstrapDidStall = true
|
||||
SecureLogger.warning(
|
||||
"TorManager: bootstrap did not complete within its deadline (progress=\(self.bootstrapProgress)); network may be blocking Tor",
|
||||
category: .session
|
||||
)
|
||||
NotificationCenter.default.post(name: .TorBootstrapDidStall, object: nil)
|
||||
}
|
||||
guard generation == bootstrapGeneration else { return }
|
||||
self.isStarting = false
|
||||
self.bootstrapDidStall = true
|
||||
SecureLogger.warning(
|
||||
"TorManager: bootstrap did not complete within its deadline (progress=\(self.bootstrapProgress)); network may be blocking Tor",
|
||||
category: .session
|
||||
)
|
||||
NotificationCenter.default.post(name: .TorBootstrapDidStall, object: nil)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,6 +357,7 @@ public final class TorManager: ObservableObject {
|
||||
// Clear isStarting so foreground recovery can proceed if bootstrap was interrupted.
|
||||
SecureLogger.debug("TorManager: goDormantOnBackground() called", category: .session)
|
||||
Task { @MainActor in
|
||||
self.bootstrapGeneration += 1
|
||||
self.isReady = false
|
||||
self.socksReady = false
|
||||
self.isStarting = false
|
||||
@@ -361,6 +367,7 @@ public final class TorManager: ObservableObject {
|
||||
public func shutdownCompletely() {
|
||||
SecureLogger.debug("TorManager: shutdownCompletely() called", category: .session)
|
||||
startPendingAfterShutdown = false
|
||||
bootstrapGeneration += 1
|
||||
shutdownsInFlight += 1
|
||||
Task.detached { [weak self] in
|
||||
guard let self = self else { return }
|
||||
@@ -398,6 +405,7 @@ public final class TorManager: ObservableObject {
|
||||
SecureLogger.debug("TorManager: restartArti() starting", category: .session)
|
||||
await MainActor.run {
|
||||
NotificationCenter.default.post(name: .TorWillRestart, object: nil)
|
||||
self.bootstrapGeneration += 1
|
||||
self.isReady = false
|
||||
self.socksReady = false
|
||||
self.bootstrapProgress = 0
|
||||
|
||||
Reference in New Issue
Block a user