Re: Darwin SSL issue - missing bytes
Date: Sat, 9 Feb 2013 18:11:06 -0700
On Feb 8, 2013, at 7:45 PM, Bruno de Carvalho <kindernade_at_gmail.com> wrote:
> Ok, after a bit more digging got it replicating from the command line. I'm using pretty much the same tools as last time, except this time I've placed the dummy mirror server behind an HTTPS load balancer at Amazon EC2.
Thanks. Now I know what is causing the problem. I did some debugging and printf-ing, and found that the SSLWrite() function was returning that it wrote data, but the socket returned EAGAIN. At first I thought that this meant that some data was written, and it was getting to a certain point after calling write() in a loop in the SocketWrite() function that it had written enough and could write no more until next time. Then I straightened out that loop, and found that SSLWrite() was still returning that it had written data it hadn't actually sent. Huh?
So I did some searching, and found that someone else already ran into this problem: <https://github.com/robbiehanson/CocoaAsyncSocket/blob/master/GCD/GCDAsyncSocket.m> (and search for "SSLWrite" on the page)
It turns out that, when SSLWrite() returns the data it "wrote," it's not returning the data it wrote to the socket (which is what Apple's documentation infers), it's returning the data it wrote to an internal buffer, and that data wasn't written to the socket at all if errSSLWouldBlock was returned. And I didn't notice this because sending less than 32 KB or so on a connection doesn't trigger the problem. Sorry 'bout that!
I'm going to file a documentation bug with Apple. And I've attached a patch that fixes this by remembering if any data was buffered but not sent if SSLWrite() returned errSSLWouldBlock, and if so, it keeps calling SSLWrite() each time the send function is called until the buffered data is sent. Please test out this patch with all sorts of send operations and let me know if it fixes the problem or creates new ones…
- application/octet-stream attachment: darwinssl_send_2.patch