connection updates

This commit is contained in:
Mark Gregory
2026-10-19 12:23:01 +01:00
parent 69c8d2c4db
commit b06a605f38
2 changed files with 48 additions and 2 deletions
+25 -2
View File
@@ -43,8 +43,28 @@ private final class DBSynSSHTunnels {
process.standardOutput = FileHandle.nullDevice
process.standardError = FileHandle.nullDevice
do { try process.run() } catch { throw MySQLWireError(message: "Cannot launch SSH: \(error.localizedDescription)") }
Thread.sleep(forTimeInterval: 0.6)
guard process.isRunning else { throw MySQLWireError(message: "SSH tunnel failed. Check SSH key, known_hosts, target and port \(localPort). Try ssh manually for details.") }
// SSH may take several seconds to authenticate. A running process does
// not mean its local listener is ready. Probe the forwarded endpoint
// before handing it to the MySQL handshake.
let deadline = Date().addingTimeInterval(10)
var ready = false
while Date() < deadline && process.isRunning {
let probe = Process()
probe.executableURL = URL(fileURLWithPath: "/usr/bin/nc")
probe.arguments = ["-z", "-G", "1", "127.0.0.1", String(localPort)]
probe.standardInput = FileHandle.nullDevice
probe.standardOutput = FileHandle.nullDevice
probe.standardError = FileHandle.nullDevice
if (try? probe.run()) != nil {
probe.waitUntilExit()
if probe.terminationStatus == 0 { ready = true; break }
}
Thread.sleep(forTimeInterval: 0.15)
}
guard ready else {
if process.isRunning { process.terminate() }
throw MySQLWireError(message: "SSH forwarding did not become ready within 10 seconds (local port \(localPort)). Check SSH credentials, host key and target address.")
}
running[profile.id] = (process, profile, localPort)
return ("127.0.0.1", localPort)
}
@@ -225,6 +245,9 @@ final class MySQLWireConnection {
let header = try readExact(4)
let count = Int(header[0]) | Int(header[1]) << 8 | Int(header[2]) << 16
sequence = header[3] &+ 1
guard count <= maxPacket else {
throw MySQLWireError(message: "MySQL packet exceeds protocol limit")
}
return try readExact(count)
}
private func send(_ payload: [UInt8]) throws {
+23
View File
@@ -0,0 +1,23 @@
# DBSyn 74.8 — targeted reliability review
This release is **not** a claim that the entire audit backlog is complete. The macOS app cannot be compiled or integration-tested in this Linux environment.
## Implemented
- SSH tunnel startup now probes the forwarded TCP listener for up to 10 seconds instead of assuming 600 ms is enough. Failed starts terminate the child process and report an actionable error.
- Added a defensive bound on MySQL packet length before allocating the payload buffer.
- Preserved Phase 74.7 source and existing tests.
## Unresolved release blockers
1. Native TLS upgrade and hostname validation require a tested modern transport implementation; the current stream upgrade is experimental.
2. Direct TCP read/write operations have no guaranteed bounded deadlines; offline connections may remain blocked.
3. SSH port selection can collide; use OS-assigned ports and a managed listener in a subsequent transport rewrite.
4. Query results and administration operations need live MySQL 8 integration tests, including editing, limits, privileges, bcrypt verification and least-privilege errors.
5. Large-data UI and SQL import/export need memory/latency profiling; MainView remains monolithic.
6. macOS Xcode build, XCTest and runtime validation are mandatory before shipping.
## Required verification
- Xcode arm64 Debug and Release builds; run DBSynTests.
- Working → offline → working switch repeated at least 20 times.
- SSH with delayed login, refused port, invalid host key and invalid key.
- TLS valid, expired and hostname-mismatch certificates.
- MySQL user CRUD, GRANT/REVOKE, account limits, editable result rows, and Laravel Hash::check.