Post

Replies

Boosts

Views

Activity

Reply to TLS communication error between iPhone and iPad
Considering the effect of the cache, I initialized the iPad and iPhone and checked the operation, and the following error log was confirmed. nw_protocol_boringssl_error(1973) [C1:58][0x105964400] Lower protocol stack error pre TLS handshake. [60: ] Next, I updated OS and checked the operation, and the following error log was confirmed. (new OS version: 18.5) nw_protocol_boringssl_handshake_negotiate_proceed(787) [C2:26][0x101590a00] handshake failed at state 12288: not completed Although the investigation is still in progress, it seems that there is a problem with the options. I look forward to your help.
May ’25
Reply to TLS communication error between iPhone and iPad
Thanks for your advice! but, new two problems occurred. When exchanging values ​​using the NWconnection send and receive methods, the first 4 bytes are missing. I'm not sure how to fundamentally solve the problem. Adding 4 extra bytes to the beginning is temporarily postponing the problem... When the Server responds to the Client after receiving a value with receive, it is not returning the value. I implemented it thinking that it would be possible to return the value as is by sending it within receive. However, the response data is nil, so I think the response method is incorrect. public class NetworkSession { ... internal func send(data: Data) { connection?.send(content: data, completion: .contentProcessed({ [weak self] error in if let error { self?.logger.log("Error sending - \(error)") } })) } internal func receive() {} } public class RequestResponseSession: NetworkSession { public enum Error: Swift.Error { case requestTimeout case connectionReset case encoding(Swift.Error) case unableToDecode case unknown } private struct PendingRequest { var id: UInt32 var completion: Future<Bool, Swift.Error>.Promise } private enum Command: String, Codable { case request case acknowledge } private struct RequestData: Codable { var command: Command var requestIdentifier: UInt32 var payload: KeyCodedPayload<UInt8>? } public private(set) lazy var messagePublisher = messagesSubject.eraseToAnyPublisher() public let timeout: DispatchTimeInterval = .seconds(10) public var disconnectOnFailure: Bool = true private let dispatchQueue = DispatchQueue(label: "RequestResponseSession.dispatchQueue") private let messagesSubject = PassthroughSubject<Codable, Never>() private var pendingRequests = [UInt32: PendingRequest]() private let keyCoder = KeyCoder() private let encoder = JSONEncoder() private let decoder = JSONDecoder() ... private func request<Message: Codable>(id: UInt32, message: Message, completion: @escaping Future<Bool, Swift.Error>.Promise) { dispatchQueue.async { [weak self] in guard let self else { return } guard self.state == .connected else { completion(.failure(NetworkSession.Error.notConnected)) return } self.pendingRequests[id] = PendingRequest(id: id, completion: completion) do { let payload = try self.keyCoder.encode(value: message) let requestData = RequestData(command: .request, requestIdentifier: id, payload: payload) var encodedRequestData = try self.encoder.encode(requestData) /// ↓ Problem 1, temporary solution let addData = try self.encoder.encode("aa") encodedRequestData = addData + encodedRequestData self.send(data: encodedRequestData) } catch { completion(.failure(Error.encoding(error))) } } } override func receive() { guard let connection else { return } connection.receiveMessage { [weak self] data, context, isComplete, error in guard let self else { return } if let error { return } if let data { self.dispatchQueue.async { if let receiveData = self.decode(data: data), receiveData.command != .acknowledge { /// ↓ Problem2, Server is recieve data and send to Client do { var data = try self.encoder.encode(RequestData(command: .acknowledge, requestIdentifier: receiveData.requestIdentifier, payload: nil)) self.send(data: data) } catch { print("Error encoding acknowledgment - \(error)") } } } } if let context, context.isFinal { self.disconnect() } else { self.receive() } } } private func decode(data: Data) -> RequestData? { do { let requestData = try decoder.decode(RequestData.self, from: data) switch requestData.command { case .request: guard let payload = requestData.payload else { break } let message = try keyCoder.decode(for: payload.codingKey, data: payload.data) messagesSubject.send(message) case .acknowledge: dispatchQueue.async { [weak self] in guard let request = self?.pendingRequests[requestData.requestIdentifier] else { return } request.completion(.success(true)) } } return requestData } catch { print("Error decoding - \(error)") } return nil } } struct KeyCoder: KeyCodable { var keymap: [UInt8: Codable.Type] { [ 0: Invite.self, 1: User.self, 2: CallAction.self, 3: TextMessage.self, 4: Heartbeat.self, 5: Directory.self ] } }
Jun ’25
Reply to TLS communication error between iPhone and iPad
Considering the effect of the cache, I initialized the iPad and iPhone and checked the operation, and the following error log was confirmed. nw_protocol_boringssl_error(1973) [C1:58][0x105964400] Lower protocol stack error pre TLS handshake. [60: ] Next, I updated OS and checked the operation, and the following error log was confirmed. (new OS version: 18.5) nw_protocol_boringssl_handshake_negotiate_proceed(787) [C2:26][0x101590a00] handshake failed at state 12288: not completed Although the investigation is still in progress, it seems that there is a problem with the options. I look forward to your help.
Replies
Boosts
Views
Activity
May ’25
Reply to TLS communication error between iPhone and iPad
Thanks for your advice! but, new two problems occurred. When exchanging values ​​using the NWconnection send and receive methods, the first 4 bytes are missing. I'm not sure how to fundamentally solve the problem. Adding 4 extra bytes to the beginning is temporarily postponing the problem... When the Server responds to the Client after receiving a value with receive, it is not returning the value. I implemented it thinking that it would be possible to return the value as is by sending it within receive. However, the response data is nil, so I think the response method is incorrect. public class NetworkSession { ... internal func send(data: Data) { connection?.send(content: data, completion: .contentProcessed({ [weak self] error in if let error { self?.logger.log("Error sending - \(error)") } })) } internal func receive() {} } public class RequestResponseSession: NetworkSession { public enum Error: Swift.Error { case requestTimeout case connectionReset case encoding(Swift.Error) case unableToDecode case unknown } private struct PendingRequest { var id: UInt32 var completion: Future<Bool, Swift.Error>.Promise } private enum Command: String, Codable { case request case acknowledge } private struct RequestData: Codable { var command: Command var requestIdentifier: UInt32 var payload: KeyCodedPayload<UInt8>? } public private(set) lazy var messagePublisher = messagesSubject.eraseToAnyPublisher() public let timeout: DispatchTimeInterval = .seconds(10) public var disconnectOnFailure: Bool = true private let dispatchQueue = DispatchQueue(label: "RequestResponseSession.dispatchQueue") private let messagesSubject = PassthroughSubject<Codable, Never>() private var pendingRequests = [UInt32: PendingRequest]() private let keyCoder = KeyCoder() private let encoder = JSONEncoder() private let decoder = JSONDecoder() ... private func request<Message: Codable>(id: UInt32, message: Message, completion: @escaping Future<Bool, Swift.Error>.Promise) { dispatchQueue.async { [weak self] in guard let self else { return } guard self.state == .connected else { completion(.failure(NetworkSession.Error.notConnected)) return } self.pendingRequests[id] = PendingRequest(id: id, completion: completion) do { let payload = try self.keyCoder.encode(value: message) let requestData = RequestData(command: .request, requestIdentifier: id, payload: payload) var encodedRequestData = try self.encoder.encode(requestData) /// ↓ Problem 1, temporary solution let addData = try self.encoder.encode("aa") encodedRequestData = addData + encodedRequestData self.send(data: encodedRequestData) } catch { completion(.failure(Error.encoding(error))) } } } override func receive() { guard let connection else { return } connection.receiveMessage { [weak self] data, context, isComplete, error in guard let self else { return } if let error { return } if let data { self.dispatchQueue.async { if let receiveData = self.decode(data: data), receiveData.command != .acknowledge { /// ↓ Problem2, Server is recieve data and send to Client do { var data = try self.encoder.encode(RequestData(command: .acknowledge, requestIdentifier: receiveData.requestIdentifier, payload: nil)) self.send(data: data) } catch { print("Error encoding acknowledgment - \(error)") } } } } if let context, context.isFinal { self.disconnect() } else { self.receive() } } } private func decode(data: Data) -> RequestData? { do { let requestData = try decoder.decode(RequestData.self, from: data) switch requestData.command { case .request: guard let payload = requestData.payload else { break } let message = try keyCoder.decode(for: payload.codingKey, data: payload.data) messagesSubject.send(message) case .acknowledge: dispatchQueue.async { [weak self] in guard let request = self?.pendingRequests[requestData.requestIdentifier] else { return } request.completion(.success(true)) } } return requestData } catch { print("Error decoding - \(error)") } return nil } } struct KeyCoder: KeyCodable { var keymap: [UInt8: Codable.Type] { [ 0: Invite.self, 1: User.self, 2: CallAction.self, 3: TextMessage.self, 4: Heartbeat.self, 5: Directory.self ] } }
Replies
Boosts
Views
Activity
Jun ’25