From d7064351038b1cca5bb5dfc5f567a9485fbe502d Mon Sep 17 00:00:00 2001 From: James Magahern Date: Fri, 13 Jun 2025 14:50:13 -0700 Subject: [PATCH] pingpong prevent superclass from handling rest of ping frame --- kordophone/Bridge/MBIMPingPongWebSocket.m | 81 ++++++++++++----------- 1 file changed, 43 insertions(+), 38 deletions(-) diff --git a/kordophone/Bridge/MBIMPingPongWebSocket.m b/kordophone/Bridge/MBIMPingPongWebSocket.m index b36fba8..02004c3 100644 --- a/kordophone/Bridge/MBIMPingPongWebSocket.m +++ b/kordophone/Bridge/MBIMPingPongWebSocket.m @@ -126,6 +126,7 @@ payload = [unmaskedPayload copy]; } + NSLog(@"Sending pong response to ping with payload length: %lu", (unsigned long)[payload length]); [self sendPongWithPayload:payload socket:sock]; // Continue reading the next frame @@ -133,60 +134,64 @@ return; } - // Intercept after masking key is read for ping/pong frames - if (tag == TAG_MSG_MASKING_KEY && (nextOpCode == WS_OP_PING || nextOpCode == WS_OP_PONG)) { - // Store the masking key - maskingKey = [data copy]; - // We need to determine the payload length and read it - // The parent class should have stored this somewhere, but we'll need to track it - // For now, let's assume short payload and read what was scheduled + // Let parent handle TAG_PAYLOAD_PREFIX first to set nextOpCode + if (tag == TAG_PAYLOAD_PREFIX) { + [super socket:sock didReadData:data withTag:tag]; return; } - // Intercept the payload length phase for ping/pong frames - if (tag == TAG_PAYLOAD_LENGTH && (nextOpCode == WS_OP_PING || nextOpCode == WS_OP_PONG)) { - UInt8 frame = *(UInt8 *)[data bytes]; - BOOL masked = (frame & 0x80) != 0; - NSUInteger length = frame & 0x7F; - nextFrameMasked = masked; + // Now intercept ping/pong handling after nextOpCode is set + if (nextOpCode == WS_OP_PING || nextOpCode == WS_OP_PONG) { + if (tag == TAG_PAYLOAD_LENGTH) { + UInt8 frame = *(UInt8 *)[data bytes]; + BOOL masked = (frame & 0x80) != 0; + NSUInteger length = frame & 0x7F; + nextFrameMasked = masked; + + NSLog(@"Processing ping/pong frame, masked: %d, length: %lu", masked, (unsigned long)length); + + if (length <= 125) { + if (nextFrameMasked) { + [asyncSocket readDataToLength:4 withTimeout:TIMEOUT_NONE tag:TAG_MSG_MASKING_KEY]; + } + [asyncSocket readDataToLength:length withTimeout:TIMEOUT_NONE tag:TAG_PING_PAYLOAD]; + } + else if (length == 126) { + [asyncSocket readDataToLength:2 withTimeout:TIMEOUT_NONE tag:TAG_PAYLOAD_LENGTH16]; + } + else { + [asyncSocket readDataToLength:8 withTimeout:TIMEOUT_NONE tag:TAG_PAYLOAD_LENGTH64]; + } + return; + } - if (length <= 125) { + if (tag == TAG_MSG_MASKING_KEY) { + // Store the masking key + maskingKey = [data copy]; + NSLog(@"Stored masking key for ping/pong frame"); + return; + } + + if (tag == TAG_PAYLOAD_LENGTH16) { + UInt8 *pFrame = (UInt8 *)[data bytes]; + NSUInteger length = ((NSUInteger)pFrame[0] << 8) | (NSUInteger)pFrame[1]; + if (nextFrameMasked) { [asyncSocket readDataToLength:4 withTimeout:TIMEOUT_NONE tag:TAG_MSG_MASKING_KEY]; } [asyncSocket readDataToLength:length withTimeout:TIMEOUT_NONE tag:TAG_PING_PAYLOAD]; - } - else if (length == 126) { - [asyncSocket readDataToLength:2 withTimeout:TIMEOUT_NONE tag:TAG_PAYLOAD_LENGTH16]; - } - else { - [asyncSocket readDataToLength:8 withTimeout:TIMEOUT_NONE tag:TAG_PAYLOAD_LENGTH64]; - } - return; - } - - // Handle extended length for ping/pong - if ((tag == TAG_PAYLOAD_LENGTH16 || tag == TAG_PAYLOAD_LENGTH64) && (nextOpCode == WS_OP_PING || nextOpCode == WS_OP_PONG)) { - NSUInteger length = 0; - if (tag == TAG_PAYLOAD_LENGTH16) { - UInt8 *pFrame = (UInt8 *)[data bytes]; - length = ((NSUInteger)pFrame[0] << 8) | (NSUInteger)pFrame[1]; - } else { - // For 64-bit length, this is complex - for now just close - [self didClose]; return; } - if (nextFrameMasked) { - [asyncSocket readDataToLength:4 withTimeout:TIMEOUT_NONE tag:TAG_MSG_MASKING_KEY]; + if (tag == TAG_PAYLOAD_LENGTH64) { + // For 64-bit length, this is too complex for ping frames - just close + [self didClose]; + return; } - [asyncSocket readDataToLength:length withTimeout:TIMEOUT_NONE tag:TAG_PING_PAYLOAD]; - return; } // For all other cases, call the parent implementation [super socket:sock didReadData:data withTag:tag]; - }