mirror of
https://github.com/leonboe1/QuickDrop.git
synced 2026-11-11 02:51:11 +00:00
Refactoring
This commit is contained in:
1 parent
4262c387a2
commit
98d1596672
1 file changed
+43
-8
@@ -15,10 +15,11 @@ import BigInt
|
||||
import SwiftECC
|
||||
|
||||
class NearbyConnection {
|
||||
static let SANE_FRAME_LENGTH = 5 * 1024 * 1024
|
||||
private static let dispatchQueue = DispatchQueue(label: "com.leonboettger.quickdrop.queue", qos: .utility) // FIFO (non-concurrent) queue to avoid those exciting concurrency bugs
|
||||
|
||||
public let id: String
|
||||
private let maxFrameLength = 5 * 1024 * 1024
|
||||
private static let dispatchQueue = DispatchQueue(label: "com.leonboettger.quickdrop.queue", qos: .utility)
|
||||
|
||||
let id: String
|
||||
let connection: NWConnection
|
||||
|
||||
var remoteDeviceInfo: RemoteDeviceInfo?
|
||||
@@ -30,7 +31,7 @@ class NearbyConnection {
|
||||
private var connectionClosed: Bool = false
|
||||
|
||||
private var inactivityTimer: DispatchSourceTimer?
|
||||
private let timeoutInterval: TimeInterval = 100
|
||||
private let timeoutInterval: TimeInterval = 50
|
||||
|
||||
// UKEY2-related state
|
||||
var publicKey: ECPublicKey?
|
||||
@@ -50,11 +51,13 @@ class NearbyConnection {
|
||||
|
||||
private(set) var pinCode: String?
|
||||
|
||||
|
||||
init(connection: NWConnection, id: String) {
|
||||
self.connection = connection
|
||||
self.id = id
|
||||
}
|
||||
|
||||
|
||||
func start() {
|
||||
connection.stateUpdateHandler = { state in
|
||||
|
||||
@@ -83,7 +86,7 @@ class NearbyConnection {
|
||||
log("Connection already closed, ignoring state update: \(state)")
|
||||
}
|
||||
}
|
||||
// connection.start(queue: .global(qos: .utility))
|
||||
|
||||
connection.start(queue: NearbyConnection.dispatchQueue)
|
||||
|
||||
func recordErrorAndDisconnect(err: NWError) {
|
||||
@@ -105,38 +108,47 @@ class NearbyConnection {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func connectionReady() {}
|
||||
|
||||
|
||||
func handleConnectionClosure() {
|
||||
log("Connection closed")
|
||||
deletePartiallyReceivedFiles()
|
||||
}
|
||||
|
||||
|
||||
func protocolError() {
|
||||
log("Protocol error: \(String(describing: lastError))")
|
||||
disconnect()
|
||||
}
|
||||
|
||||
|
||||
func processReceivedFrame(frameData _: Data) {
|
||||
fatalError()
|
||||
}
|
||||
|
||||
|
||||
func processTransferSetupFrame(_: Sharing_Nearby_Frame) throws {
|
||||
fatalError()
|
||||
}
|
||||
|
||||
|
||||
func isServer() -> Bool {
|
||||
fatalError()
|
||||
}
|
||||
|
||||
|
||||
func processFileChunk(frame _: Location_Nearby_Connections_PayloadTransferFrame) throws {
|
||||
protocolError()
|
||||
}
|
||||
|
||||
|
||||
func processBytesPayload(payload _: Data, id _: Int64) throws -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
private func receiveFrameAsync() {
|
||||
connection.receive(minimumIncompleteLength: 4, maximumLength: 4) { content, _, isComplete, error in
|
||||
if self.connectionClosed {
|
||||
@@ -158,7 +170,7 @@ class NearbyConnection {
|
||||
return
|
||||
}
|
||||
let frameLength = UInt32(content[0]) << 24 | UInt32(content[1]) << 16 | UInt32(content[2]) << 8 | UInt32(content[3])
|
||||
guard frameLength < NearbyConnection.SANE_FRAME_LENGTH else {
|
||||
guard frameLength < self.maxFrameLength else {
|
||||
self.lastError = NearbyError.protocolError("Unexpected packet length")
|
||||
self.protocolError()
|
||||
return
|
||||
@@ -169,6 +181,7 @@ class NearbyConnection {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func receiveFrameAsync(length: UInt32) {
|
||||
connection.receive(minimumIncompleteLength: Int(length), maximumLength: Int(length)) { content, _, isComplete, _ in
|
||||
if self.connectionClosed {
|
||||
@@ -191,6 +204,7 @@ class NearbyConnection {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func sendFrameAsync(_ frame: Data, completion: (() -> Void)? = nil) {
|
||||
if connectionClosed {
|
||||
return
|
||||
@@ -211,6 +225,7 @@ class NearbyConnection {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
func encryptAndSendOfflineFrame(_ frame: Location_Nearby_Connections_OfflineFrame, completion: (() -> Void)? = nil) throws {
|
||||
var d2dMsg = Securegcm_DeviceToDeviceMessage()
|
||||
serverSeq += 1
|
||||
@@ -252,11 +267,13 @@ class NearbyConnection {
|
||||
try sendFrameAsync(smsg.serializedData(), completion: completion)
|
||||
}
|
||||
|
||||
|
||||
func sendTransferSetupFrame(_ frame: Sharing_Nearby_Frame) throws {
|
||||
log("Sending transfer setup frame.")
|
||||
try sendBytesPayload(data: frame.serializedData(), id: Int64.random(in: Int64.min ... Int64.max))
|
||||
}
|
||||
|
||||
|
||||
func sendBytesPayload(data: Data, id: Int64) throws {
|
||||
|
||||
log("Sending bytes payload with ID \(id) of length \(data.count)")
|
||||
@@ -285,6 +302,7 @@ class NearbyConnection {
|
||||
try encryptAndSendOfflineFrame(wrapper)
|
||||
}
|
||||
|
||||
|
||||
func decryptAndProcessReceivedSecureMessage(_ smsg: Securemessage_SecureMessage) throws {
|
||||
guard smsg.hasSignature, smsg.hasHeaderAndBody else { throw NearbyError.requiredFieldMissing("secureMessage.signature|headerAndBody") }
|
||||
|
||||
@@ -336,7 +354,7 @@ class NearbyConnection {
|
||||
|
||||
let payloadID = header.id
|
||||
|
||||
if header.totalSize > InboundNearbyConnection.SANE_FRAME_LENGTH {
|
||||
if header.totalSize > maxFrameLength {
|
||||
|
||||
payloadBuffers.removeValue(forKey: payloadID)
|
||||
throw NearbyError.protocolError("Payload too large (\(header.totalSize) bytes)")
|
||||
@@ -381,6 +399,7 @@ class NearbyConnection {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static func pinCodeFromAuthKey(_ key: SymmetricKey) -> String {
|
||||
var hash = 0
|
||||
var multiplier = 1
|
||||
@@ -397,10 +416,12 @@ class NearbyConnection {
|
||||
return String(format: "%04d", abs(hash))
|
||||
}
|
||||
|
||||
|
||||
static func hkdfExtract(salt: Data, ikm: Data) -> Data {
|
||||
return HMAC<SHA256>.authenticationCode(for: ikm, using: SymmetricKey(data: salt)).withUnsafeBytes { Data(bytes: $0.baseAddress!, count: $0.count) }
|
||||
}
|
||||
|
||||
|
||||
static func hkdfExpand(prk: Data, info: Data, length: Int) -> Data {
|
||||
var okm = Data()
|
||||
var t = Data()
|
||||
@@ -414,10 +435,12 @@ class NearbyConnection {
|
||||
return okm.subdata(in: 0 ..< length)
|
||||
}
|
||||
|
||||
|
||||
static func hkdf(inputKeyMaterial: SymmetricKey, salt: Data, info: Data, outputByteCount: Int) -> SymmetricKey {
|
||||
return HKDF<SHA256>.deriveKey(inputKeyMaterial: inputKeyMaterial, salt: salt, info: info, outputByteCount: outputByteCount)
|
||||
}
|
||||
|
||||
|
||||
func finalizeKeyExchange(peerKey: Securemessage_GenericPublicKey) throws {
|
||||
guard peerKey.hasEcP256PublicKey else { throw NearbyError.requiredFieldMissing("peerKey.ecP256PublicKey") }
|
||||
|
||||
@@ -474,6 +497,7 @@ class NearbyConnection {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func disconnect() {
|
||||
log("Disconnecting from connection.")
|
||||
|
||||
@@ -488,6 +512,7 @@ class NearbyConnection {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
func sendDisconnectionAndDisconnect() throws {
|
||||
var offlineFrame = Location_Nearby_Connections_OfflineFrame()
|
||||
offlineFrame.version = .v1
|
||||
@@ -504,6 +529,7 @@ class NearbyConnection {
|
||||
disconnect()
|
||||
}
|
||||
|
||||
|
||||
func sendUkey2Alert(type: Securegcm_Ukey2Alert.AlertType) {
|
||||
var alert = Securegcm_Ukey2Alert()
|
||||
alert.type = type
|
||||
@@ -516,6 +542,7 @@ class NearbyConnection {
|
||||
disconnect()
|
||||
}
|
||||
|
||||
|
||||
func sendKeepAlive(ack: Bool) {
|
||||
var offlineFrame = Location_Nearby_Connections_OfflineFrame()
|
||||
offlineFrame.version = .v1
|
||||
@@ -533,21 +560,29 @@ class NearbyConnection {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func startInactivityTimer() {
|
||||
inactivityTimer?.cancel() // Cancel previous timer if any
|
||||
|
||||
// Cancel previous timer if any
|
||||
inactivityTimer?.cancel()
|
||||
|
||||
inactivityTimer = DispatchSource.makeTimerSource(queue: NearbyConnection.dispatchQueue)
|
||||
inactivityTimer?.schedule(deadline: .now() + timeoutInterval)
|
||||
inactivityTimer?.setEventHandler { [weak self] in
|
||||
|
||||
guard let self = self else { return }
|
||||
|
||||
if !self.connectionClosed {
|
||||
log("Connection timeout: No message received in \(self.timeoutInterval) seconds")
|
||||
self.lastError = NearbyError.canceled(reason: .timedOut)
|
||||
self.disconnect()
|
||||
}
|
||||
}
|
||||
|
||||
inactivityTimer?.resume()
|
||||
}
|
||||
|
||||
|
||||
private func deletePartiallyReceivedFiles() {
|
||||
for (_, file) in filesToBeTransferred {
|
||||
|
||||
|
||||
Reference in new issue
Block a user