Skip to content

Commit df0b35c

Browse files
committed
Fixes bug where GCDAsyncSocket may stop reading (with secure stream on Mac OS X (10.7+ I believe)).
1 parent 68bd786 commit df0b35c

File tree

1 file changed

+31
-9
lines changed

1 file changed

+31
-9
lines changed

GCD/GCDAsyncSocket.m

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4048,6 +4048,7 @@ - (void)doReadData
40484048
unsigned long estimatedBytesAvailable;
40494049

40504050
#if TARGET_OS_IPHONE
4051+
{
40514052
if (flags & kSocketSecure)
40524053
{
40534054
// Relegated to using CFStream... :( Boo! Give us SecureTransport Apple!
@@ -4064,8 +4065,9 @@ - (void)doReadData
40644065
hasBytesAvailable = (estimatedBytesAvailable > 0);
40654066

40664067
}
4068+
}
40674069
#else
4068-
4070+
{
40694071
estimatedBytesAvailable = socketFDBytesAvailable;
40704072

40714073
if (flags & kSocketSecure)
@@ -4105,7 +4107,7 @@ - (void)doReadData
41054107
}
41064108

41074109
hasBytesAvailable = (estimatedBytesAvailable > 0);
4108-
4110+
}
41094111
#endif
41104112

41114113
if ((hasBytesAvailable == NO) && ([partialReadBuffer length] == 0))
@@ -4133,12 +4135,12 @@ - (void)doReadData
41334135
if (flags & kStartingWriteTLS)
41344136
{
41354137
#if !TARGET_OS_IPHONE
4136-
4138+
{
41374139
// We are in the process of a SSL Handshake.
41384140
// We were waiting for incoming data which has just arrived.
41394141

41404142
[self continueSSLHandshake];
4141-
4143+
}
41424144
#endif
41434145
}
41444146
else
@@ -4339,7 +4341,7 @@ - (void)doReadData
43394341
if (flags & kSocketSecure)
43404342
{
43414343
#if TARGET_OS_IPHONE
4342-
4344+
{
43434345
CFIndex result = CFReadStreamRead(readStream, buffer, (CFIndex)bytesToRead);
43444346
LogVerbose(@"CFReadStreamRead(): result = %i", (int)result);
43454347

@@ -4367,11 +4369,31 @@ - (void)doReadData
43674369
// The actual number of bytes read was likely more due to the overhead of the encryption.
43684370
// So we reset our flag, and rely on the next callback to alert us of more data.
43694371
flags &= ~kSecureSocketHasBytesAvailable;
4370-
4372+
}
43714373
#else
4374+
{
4375+
// The documentation from Apple states:
4376+
//
4377+
// "a read operation might return errSSLWouldBlock,
4378+
// indicating that less data than requested was actually transferred"
4379+
//
4380+
// However, starting around 10.7, the function will sometimes return noErr,
4381+
// even if it didn't read as much data as requested. So we need to watch out for that.
4382+
4383+
OSStatus result;
4384+
do
4385+
{
4386+
void *loop_buffer = buffer + bytesRead;
4387+
size_t loop_bytesToRead = (size_t)bytesToRead - bytesRead;
4388+
size_t loop_bytesRead = 0;
4389+
4390+
result = SSLRead(sslContext, loop_buffer, loop_bytesToRead, &loop_bytesRead);
4391+
LogVerbose(@"read from secure socket = %u", (unsigned)bytesRead);
4392+
4393+
bytesRead += loop_bytesRead;
4394+
4395+
} while ((result == noErr) && (bytesRead < bytesToRead));
43724396

4373-
OSStatus result = SSLRead(sslContext, buffer, (size_t)bytesToRead, &bytesRead);
4374-
LogVerbose(@"read from secure socket = %u", (unsigned)bytesRead);
43754397

43764398
if (result != noErr)
43774399
{
@@ -4395,7 +4417,7 @@ - (void)doReadData
43954417

43964418
// Do not modify socketFDBytesAvailable.
43974419
// It will be updated via the SSLReadFunction().
4398-
4420+
}
43994421
#endif
44004422
}
44014423
else

0 commit comments

Comments
 (0)