connection updates
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user