(TLS is the successor to SSL, and I'll be using the two terms interchangeably.)
What was wrong with the old method?
Problem #1: Prior to these improvements, one would manually call CFReadStreamSetProperty and CFWriteStreamSetProperty to start TLS. If you're dealing with an easy-to-use Cocoa object such as AsyncSocket, it seems a bit odd to have to drop down to core foundation like this. It's like when you need to trim leading and trailing whitespace from a NSString object, and you have to call CFStringTrimWhitespace. It just looks out of place, and one wonders why there's not an equivalent method in NSString. So perhaps you add a category method, and move on. But in this particular case with AsyncSocket, adding a category just shields you from the bigger problem...
Problem #2: One of the great things about AsyncSocket is queued reads and writes. You don't have to wait for a read to finish before starting another read! All read operations get queued, in the read queue, and are processed in order. Same thing for writes. And reads and writes operate simultaneously. This allows you to focus on your protocol, and frees you to handle communication however you want to, as opposed to waiting around on the socket. So you can write code like this:
[socket writeData:data];
[socket readDataToLength:2 tag:0];
[socket readDataToData:CRLFData tag:1];
The problem with the old method is that calling CFStreamSetProperty takes immediate affect. It doesn't get queued, and occur after previously scheduled operations. In short, it doesn't follow the paradigm like the rest of AsyncSocket. This is a bigger problem with modern protocols. Don't think HTTPS, where TLS must complete before any communication starts. Think of protocols like XMPP and others, where the upgrade to TLS is negotiated later, after communication has already started.
So a new method has been added to AsyncSocket:
- (void)startTLS:(NSDictionary *)settings
And a corresponding delegate method was added:
- (void)onSocket:(AsyncSocket *)sock didSecure:(BOOL)flag
This allows you to easily handle upgrades to TLS like this:
- (void)handleClientStartTLSRequest
{
[sock writeData:serverStartTLSResponse];
// Automatically start TLS after all previously queued
// reads and writes are finished
[sock startTLS:serverTLSSettings];
}
- (void)onSocket:(AsyncSocket *)sock didSecure:(BOOL)flag
{
// Continue after TLS has finished...
}
AsyncSocket works on both Mac and the iPhone.
AsyncSocket Google Code Page
2 comments:
What's an example of what serverTLSSettings would contain?
What's an example of what serverTLSSettings would contain?
Post a Comment