update CocoaAsyncSocket to latest, fix ipv6 client connecting issue

This commit is contained in:
richfisher 2016-08-13 21:33:59 +08:00
parent a66adc7e82
commit 2303105741
2 changed files with 1852 additions and 1713 deletions

View File

@ -19,6 +19,9 @@
@class GCDAsyncReadPacket;
@class GCDAsyncWritePacket;
@class GCDAsyncSocketPreBuffer;
@protocol GCDAsyncSocketDelegate;
NS_ASSUME_NONNULL_BEGIN
extern NSString *const GCDAsyncSocketException;
extern NSString *const GCDAsyncSocketErrorDomain;
@ -62,6 +65,7 @@ typedef NS_ENUM(NSInteger, GCDAsyncSocketError) {
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@interface GCDAsyncSocket : NSObject
/**
@ -80,30 +84,30 @@ typedef NS_ENUM(NSInteger, GCDAsyncSocketError) {
*
* The delegate queue and socket queue can optionally be the same.
**/
- (id)init;
- (id)initWithSocketQueue:(dispatch_queue_t)sq;
- (id)initWithDelegate:(id)aDelegate delegateQueue:(dispatch_queue_t)dq;
- (id)initWithDelegate:(id)aDelegate delegateQueue:(dispatch_queue_t)dq socketQueue:(dispatch_queue_t)sq;
- (instancetype)init;
- (instancetype)initWithSocketQueue:(nullable dispatch_queue_t)sq;
- (instancetype)initWithDelegate:(nullable id<GCDAsyncSocketDelegate>)aDelegate delegateQueue:(nullable dispatch_queue_t)dq;
- (instancetype)initWithDelegate:(nullable id<GCDAsyncSocketDelegate>)aDelegate delegateQueue:(nullable dispatch_queue_t)dq socketQueue:(nullable dispatch_queue_t)sq;
#pragma mark Configuration
@property (atomic, weak, readwrite) id delegate;
@property (atomic, weak, readwrite, nullable) id<GCDAsyncSocketDelegate> delegate;
#if OS_OBJECT_USE_OBJC
@property (atomic, strong, readwrite) dispatch_queue_t delegateQueue;
@property (atomic, strong, readwrite, nullable) dispatch_queue_t delegateQueue;
#else
@property (atomic, assign, readwrite) dispatch_queue_t delegateQueue;
@property (atomic, assign, readwrite, nullable) dispatch_queue_t delegateQueue;
#endif
- (void)getDelegate:(id *)delegatePtr delegateQueue:(dispatch_queue_t *)delegateQueuePtr;
- (void)setDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue;
- (void)getDelegate:(id<GCDAsyncSocketDelegate> __nullable * __nullable)delegatePtr delegateQueue:(dispatch_queue_t __nullable * __nullable)delegateQueuePtr;
- (void)setDelegate:(nullable id<GCDAsyncSocketDelegate>)delegate delegateQueue:(nullable dispatch_queue_t)delegateQueue;
/**
* If you are setting the delegate to nil within the delegate's dealloc method,
* you may need to use the synchronous versions below.
**/
- (void)synchronouslySetDelegate:(id)delegate;
- (void)synchronouslySetDelegateQueue:(dispatch_queue_t)delegateQueue;
- (void)synchronouslySetDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue;
- (void)synchronouslySetDelegate:(nullable id<GCDAsyncSocketDelegate>)delegate;
- (void)synchronouslySetDelegateQueue:(nullable dispatch_queue_t)delegateQueue;
- (void)synchronouslySetDelegate:(nullable id<GCDAsyncSocketDelegate>)delegate delegateQueue:(nullable dispatch_queue_t)delegateQueue;
/**
* By default, both IPv4 and IPv6 are enabled.
@ -123,11 +127,19 @@ typedef NS_ENUM(NSInteger, GCDAsyncSocketError) {
@property (atomic, assign, readwrite, getter=isIPv4PreferredOverIPv6) BOOL IPv4PreferredOverIPv6;
/**
* When connecting to both IPv4 and IPv6 using Happy Eyeballs (RFC 6555) https://tools.ietf.org/html/rfc6555
* this is the delay between connecting to the preferred protocol and the fallback protocol.
*
* Defaults to 300ms.
**/
@property (atomic, assign, readwrite) NSTimeInterval alternateAddressDelay;
/**
* User data allows you to associate arbitrary information with the socket.
* This data is not used internally by socket in any way.
**/
@property (atomic, strong, readwrite) id userData;
@property (atomic, strong, readwrite, nullable) id userData;
#pragma mark Accepting
@ -156,7 +168,7 @@ typedef NS_ENUM(NSInteger, GCDAsyncSocketError) {
*
* To accept connections on any interface pass nil, or simply use the acceptOnPort:error: method.
**/
- (BOOL)acceptOnInterface:(NSString *)interface port:(uint16_t)port error:(NSError **)errPtr;
- (BOOL)acceptOnInterface:(nullable NSString *)interface port:(uint16_t)port error:(NSError **)errPtr;
/**
* Tells the socket to begin listening and accepting connections on the unix domain at the given url.
@ -221,7 +233,7 @@ typedef NS_ENUM(NSInteger, GCDAsyncSocketError) {
**/
- (BOOL)connectToHost:(NSString *)host
onPort:(uint16_t)port
viaInterface:(NSString *)interface
viaInterface:(nullable NSString *)interface
withTimeout:(NSTimeInterval)timeout
error:(NSError **)errPtr;
@ -279,7 +291,7 @@ typedef NS_ENUM(NSInteger, GCDAsyncSocketError) {
* This feature is here for networking professionals using very advanced techniques.
**/
- (BOOL)connectToAddress:(NSData *)remoteAddr
viaInterface:(NSString *)interface
viaInterface:(nullable NSString *)interface
withTimeout:(NSTimeInterval)timeout
error:(NSError **)errPtr;
/**
@ -347,11 +359,11 @@ typedef NS_ENUM(NSInteger, GCDAsyncSocketError) {
* Returns the local or remote host and port to which this socket is connected, or nil and 0 if not connected.
* The host will be an IP address.
**/
@property (atomic, readonly) NSString *connectedHost;
@property (atomic, readonly, nullable) NSString *connectedHost;
@property (atomic, readonly) uint16_t connectedPort;
@property (atomic, readonly) NSURL *connectedUrl;
@property (atomic, readonly, nullable) NSURL *connectedUrl;
@property (atomic, readonly) NSString *localHost;
@property (atomic, readonly, nullable) NSString *localHost;
@property (atomic, readonly) uint16_t localPort;
/**
@ -363,8 +375,8 @@ typedef NS_ENUM(NSInteger, GCDAsyncSocketError) {
* @seealso localHost
* @seealso localPort
**/
@property (atomic, readonly) NSData *connectedAddress;
@property (atomic, readonly) NSData *localAddress;
@property (atomic, readonly, nullable) NSData *connectedAddress;
@property (atomic, readonly, nullable) NSData *localAddress;
/**
* Returns whether the socket is IPv4 or IPv6.
@ -419,7 +431,7 @@ typedef NS_ENUM(NSInteger, GCDAsyncSocketError) {
* the method [NSData dataWithBytesNoCopy:length:freeWhenDone:NO].
**/
- (void)readDataWithTimeout:(NSTimeInterval)timeout
buffer:(NSMutableData *)buffer
buffer:(nullable NSMutableData *)buffer
bufferOffset:(NSUInteger)offset
tag:(long)tag;
@ -442,7 +454,7 @@ typedef NS_ENUM(NSInteger, GCDAsyncSocketError) {
* the method [NSData dataWithBytesNoCopy:length:freeWhenDone:NO].
**/
- (void)readDataWithTimeout:(NSTimeInterval)timeout
buffer:(NSMutableData *)buffer
buffer:(nullable NSMutableData *)buffer
bufferOffset:(NSUInteger)offset
maxLength:(NSUInteger)length
tag:(long)tag;
@ -475,7 +487,7 @@ typedef NS_ENUM(NSInteger, GCDAsyncSocketError) {
**/
- (void)readDataToLength:(NSUInteger)length
withTimeout:(NSTimeInterval)timeout
buffer:(NSMutableData *)buffer
buffer:(nullable NSMutableData *)buffer
bufferOffset:(NSUInteger)offset
tag:(long)tag;
@ -533,7 +545,7 @@ typedef NS_ENUM(NSInteger, GCDAsyncSocketError) {
**/
- (void)readDataToData:(NSData *)data
withTimeout:(NSTimeInterval)timeout
buffer:(NSMutableData *)buffer
buffer:(nullable NSMutableData *)buffer
bufferOffset:(NSUInteger)offset
tag:(long)tag;
@ -605,7 +617,7 @@ typedef NS_ENUM(NSInteger, GCDAsyncSocketError) {
**/
- (void)readDataToData:(NSData *)data
withTimeout:(NSTimeInterval)timeout
buffer:(NSMutableData *)buffer
buffer:(nullable NSMutableData *)buffer
bufferOffset:(NSUInteger)offset
maxLength:(NSUInteger)length
tag:(long)tag;
@ -614,7 +626,7 @@ typedef NS_ENUM(NSInteger, GCDAsyncSocketError) {
* Returns progress of the current read, from 0.0 to 1.0, or NaN if no current read (use isnan() to check).
* The parameters "tag", "done" and "total" will be filled in if they aren't NULL.
**/
- (float)progressOfReadReturningTag:(long *)tagPtr bytesDone:(NSUInteger *)donePtr total:(NSUInteger *)totalPtr;
- (float)progressOfReadReturningTag:(nullable long *)tagPtr bytesDone:(nullable NSUInteger *)donePtr total:(nullable NSUInteger *)totalPtr;
#pragma mark Writing
@ -641,7 +653,7 @@ typedef NS_ENUM(NSInteger, GCDAsyncSocketError) {
* Returns progress of the current write, from 0.0 to 1.0, or NaN if no current write (use isnan() to check).
* The parameters "tag", "done" and "total" will be filled in if they aren't NULL.
**/
- (float)progressOfWriteReturningTag:(long *)tagPtr bytesDone:(NSUInteger *)donePtr total:(NSUInteger *)totalPtr;
- (float)progressOfWriteReturningTag:(nullable long *)tagPtr bytesDone:(nullable NSUInteger *)donePtr total:(nullable NSUInteger *)totalPtr;
#pragma mark Security
@ -776,7 +788,7 @@ typedef NS_ENUM(NSInteger, GCDAsyncSocketError) {
*
* You can also perform additional validation in socketDidSecure.
**/
- (void)startTLS:(NSDictionary *)tlsSettings;
- (void)startTLS:(nullable NSDictionary <NSString*,NSObject*>*)tlsSettings;
#pragma mark Advanced
@ -950,8 +962,8 @@ typedef NS_ENUM(NSInteger, GCDAsyncSocketError) {
*
* See also: (BOOL)enableBackgroundingOnSocket
**/
- (CFReadStreamRef)readStream;
- (CFWriteStreamRef)writeStream;
- (nullable CFReadStreamRef)readStream;
- (nullable CFWriteStreamRef)writeStream;
/**
* This method is only available from within the context of a performBlock: invocation.
@ -988,7 +1000,7 @@ typedef NS_ENUM(NSInteger, GCDAsyncSocketError) {
*
* Provides access to the socket's SSLContext, if SSL/TLS has been started on the socket.
**/
- (SSLContextRef)sslContext;
- (nullable SSLContextRef)sslContext;
#pragma mark Utilities
@ -1003,21 +1015,21 @@ typedef NS_ENUM(NSInteger, GCDAsyncSocketError) {
* The addresses are specifically for TCP connections.
* You can filter the addresses, if needed, using the other utility methods provided by the class.
**/
+ (NSMutableArray *)lookupHost:(NSString *)host port:(uint16_t)port error:(NSError **)errPtr;
+ (nullable NSMutableArray *)lookupHost:(NSString *)host port:(uint16_t)port error:(NSError **)errPtr;
/**
* Extracting host and port information from raw address data.
**/
+ (NSString *)hostFromAddress:(NSData *)address;
+ (nullable NSString *)hostFromAddress:(NSData *)address;
+ (uint16_t)portFromAddress:(NSData *)address;
+ (BOOL)isIPv4Address:(NSData *)address;
+ (BOOL)isIPv6Address:(NSData *)address;
+ (BOOL)getHost:(NSString **)hostPtr port:(uint16_t *)portPtr fromAddress:(NSData *)address;
+ (BOOL)getHost:( NSString * __nullable * __nullable)hostPtr port:(nullable uint16_t *)portPtr fromAddress:(NSData *)address;
+ (BOOL)getHost:(NSString **)hostPtr port:(uint16_t *)portPtr family:(sa_family_t *)afPtr fromAddress:(NSData *)address;
+ (BOOL)getHost:(NSString * __nullable * __nullable)hostPtr port:(nullable uint16_t *)portPtr family:(nullable sa_family_t *)afPtr fromAddress:(NSData *)address;
/**
* A few common line separators, for use with the readDataToData:... methods.
@ -1033,7 +1045,7 @@ typedef NS_ENUM(NSInteger, GCDAsyncSocketError) {
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@protocol GCDAsyncSocketDelegate
@protocol GCDAsyncSocketDelegate <NSObject>
@optional
/**
@ -1054,7 +1066,7 @@ typedef NS_ENUM(NSInteger, GCDAsyncSocketError) {
* dispatch_retain(myExistingQueue);
* return myExistingQueue;
**/
- (dispatch_queue_t)newSocketQueueForConnectionFromAddress:(NSData *)address onSocket:(GCDAsyncSocket *)sock;
- (nullable dispatch_queue_t)newSocketQueueForConnectionFromAddress:(NSData *)address onSocket:(GCDAsyncSocket *)sock;
/**
* Called when a socket accepts a connection.
@ -1163,7 +1175,7 @@ typedef NS_ENUM(NSInteger, GCDAsyncSocketError) {
*
* Of course, this depends on how your state machine is configured.
**/
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err;
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(nullable NSError *)err;
/**
* Called after the socket has successfully completed SSL/TLS negotiation.
@ -1195,3 +1207,4 @@ typedef NS_ENUM(NSInteger, GCDAsyncSocketError) {
completionHandler:(void (^)(BOOL shouldTrustPeer))completionHandler;
@end
NS_ASSUME_NONNULL_END

View File

@ -867,7 +867,7 @@ enum GCDAsyncSocketConfig
uint32_t flags;
uint16_t config;
__weak id delegate;
__weak id<GCDAsyncSocketDelegate> delegate;
dispatch_queue_t delegateQueue;
int socket4FD;
@ -914,6 +914,7 @@ enum GCDAsyncSocketConfig
void *IsOnSocketQueueOrTargetQueueKey;
id userData;
NSTimeInterval alternateAddressDelay;
}
- (id)init
@ -996,6 +997,7 @@ enum GCDAsyncSocketConfig
currentWrite = nil;
preBuffer = [[GCDAsyncSocketPreBuffer alloc] initWithCapacity:(1024 * 4)];
alternateAddressDelay = 0.3;
}
return self;
}
@ -1134,7 +1136,7 @@ enum GCDAsyncSocketConfig
[self setDelegateQueue:newDelegateQueue synchronously:YES];
}
- (void)getDelegate:(id *)delegatePtr delegateQueue:(dispatch_queue_t *)delegateQueuePtr
- (void)getDelegate:(id<GCDAsyncSocketDelegate> *)delegatePtr delegateQueue:(dispatch_queue_t *)delegateQueuePtr
{
if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey))
{
@ -1305,6 +1307,28 @@ enum GCDAsyncSocketConfig
dispatch_async(socketQueue, block);
}
- (NSTimeInterval) alternateAddressDelay {
__block NSTimeInterval delay;
dispatch_block_t block = ^{
delay = alternateAddressDelay;
};
if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey))
block();
else
dispatch_sync(socketQueue, block);
return delay;
}
- (void) setAlternateAddressDelay:(NSTimeInterval)delay {
dispatch_block_t block = ^{
alternateAddressDelay = delay;
};
if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey))
block();
else
dispatch_async(socketQueue, block);
}
- (id)userData
{
__block id result = nil;
@ -2226,7 +2250,7 @@ enum GCDAsyncSocketConfig
#pragma clang diagnostic warning "-Wimplicit-retain-self"
NSError *lookupErr = nil;
NSMutableArray *addresses = [GCDAsyncSocket lookupHost:hostCpy port:port error:&lookupErr];
NSMutableArray *addresses = [[self class] lookupHost:hostCpy port:port error:&lookupErr];
__strong GCDAsyncSocket *strongSelf = weakSelf;
if (strongSelf == nil) return_from_block;
@ -2245,11 +2269,11 @@ enum GCDAsyncSocketConfig
for (NSData *address in addresses)
{
if (!address4 && [GCDAsyncSocket isIPv4Address:address])
if (!address4 && [[self class] isIPv4Address:address])
{
address4 = address;
}
else if (!address6 && [GCDAsyncSocket isIPv6Address:address])
else if (!address6 && [[self class] isIPv6Address:address])
{
address6 = address;
}
@ -2426,10 +2450,10 @@ enum GCDAsyncSocketConfig
// Start the normal connection process
NSError *err = nil;
if (![self connectWithAddressUN:connectInterfaceUN error:&err])
NSError *connectError = nil;
if (![self connectWithAddressUN:connectInterfaceUN error:&connectError])
{
[self closeWithError:err];
[self closeWithError:connectError];
return_from_block;
}
@ -2527,56 +2551,8 @@ enum GCDAsyncSocketConfig
[self closeWithError:error];
}
- (BOOL)connectWithAddress4:(NSData *)address4 address6:(NSData *)address6 error:(NSError **)errPtr
- (BOOL)bindSocket:(int)socketFD toInterface:(NSData *)connectInterface error:(NSError **)errPtr
{
LogTrace();
NSAssert(dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey), @"Must be dispatched on socketQueue");
LogVerbose(@"IPv4: %@:%hu", [[self class] hostFromAddress:address4], [[self class] portFromAddress:address4]);
LogVerbose(@"IPv6: %@:%hu", [[self class] hostFromAddress:address6], [[self class] portFromAddress:address6]);
// Determine socket type
BOOL preferIPv6 = (config & kPreferIPv6) ? YES : NO;
BOOL useIPv6 = ((preferIPv6 && address6) || (address4 == nil));
// Create the socket
int socketFD;
NSData *address;
NSData *connectInterface;
if (useIPv6)
{
LogVerbose(@"Creating IPv6 socket");
socket6FD = socket(AF_INET6, SOCK_STREAM, 0);
socketFD = socket6FD;
address = address6;
connectInterface = connectInterface6;
}
else
{
LogVerbose(@"Creating IPv4 socket");
socket4FD = socket(AF_INET, SOCK_STREAM, 0);
socketFD = socket4FD;
address = address4;
connectInterface = connectInterface4;
}
if (socketFD == SOCKET_NULL)
{
if (errPtr)
*errPtr = [self errnoErrorWithReason:@"Error in socket() function"];
return NO;
}
// Bind the socket to the desired interface (if needed)
if (connectInterface)
@ -2604,14 +2580,47 @@ enum GCDAsyncSocketConfig
}
}
return YES;
}
- (int)createSocket:(int)family connectInterface:(NSData *)connectInterface errPtr:(NSError **)errPtr
{
int socketFD = socket(family, SOCK_STREAM, 0);
if (socketFD == SOCKET_NULL)
{
if (errPtr)
*errPtr = [self errnoErrorWithReason:@"Error in socket() function"];
return socketFD;
}
if (![self bindSocket:socketFD toInterface:connectInterface error:errPtr])
{
[self closeSocket:socketFD];
return SOCKET_NULL;
}
// Prevent SIGPIPE signals
int nosigpipe = 1;
setsockopt(socketFD, SOL_SOCKET, SO_NOSIGPIPE, &nosigpipe, sizeof(nosigpipe));
return socketFD;
}
- (void)connectSocket:(int)socketFD address:(NSData *)address stateIndex:(int)aStateIndex
{
// If there already is a socket connected, we close socketFD and return
if (self.isConnected)
{
[self closeSocket:socketFD];
return;
}
// Start the connection process in a background queue
int aStateIndex = stateIndex;
__weak GCDAsyncSocket *weakSelf = self;
dispatch_queue_t globalConcurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
@ -2624,27 +2633,133 @@ enum GCDAsyncSocketConfig
__strong GCDAsyncSocket *strongSelf = weakSelf;
if (strongSelf == nil) return_from_block;
if (result == 0)
{
dispatch_async(strongSelf->socketQueue, ^{ @autoreleasepool {
if (strongSelf.isConnected)
{
[strongSelf closeSocket:socketFD];
return_from_block;
}
if (result == 0)
{
[self closeUnusedSocket:socketFD];
[strongSelf didConnect:aStateIndex];
}});
}
else
{
[strongSelf closeSocket:socketFD];
// If there are no more sockets trying to connect, we inform the error to the delegate
if (strongSelf.socket4FD == SOCKET_NULL && strongSelf.socket6FD == SOCKET_NULL)
{
NSError *error = [strongSelf errnoErrorWithReason:@"Error in connect() function"];
dispatch_async(strongSelf->socketQueue, ^{ @autoreleasepool {
[strongSelf didNotConnect:aStateIndex error:error];
}});
}
}
}});
#pragma clang diagnostic pop
});
LogVerbose(@"Connecting...");
}
- (void)closeSocket:(int)socketFD
{
if (socketFD != SOCKET_NULL &&
(socketFD == socket6FD || socketFD == socket4FD))
{
close(socketFD);
if (socketFD == socket4FD)
{
LogVerbose(@"close(socket4FD)");
socket4FD = SOCKET_NULL;
}
else if (socketFD == socket6FD)
{
LogVerbose(@"close(socket6FD)");
socket6FD = SOCKET_NULL;
}
}
}
- (void)closeUnusedSocket:(int)usedSocketFD
{
if (usedSocketFD != socket4FD)
{
[self closeSocket:socket4FD];
}
else if (usedSocketFD != socket6FD)
{
[self closeSocket:socket6FD];
}
}
- (BOOL)connectWithAddress4:(NSData *)address4 address6:(NSData *)address6 error:(NSError **)errPtr
{
LogTrace();
NSAssert(dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey), @"Must be dispatched on socketQueue");
LogVerbose(@"IPv4: %@:%hu", [[self class] hostFromAddress:address4], [[self class] portFromAddress:address4]);
LogVerbose(@"IPv6: %@:%hu", [[self class] hostFromAddress:address6], [[self class] portFromAddress:address6]);
// Determine socket type
BOOL preferIPv6 = (config & kPreferIPv6) ? YES : NO;
// Create and bind the sockets
if (address4)
{
LogVerbose(@"Creating IPv4 socket");
socket4FD = [self createSocket:AF_INET connectInterface:connectInterface4 errPtr:errPtr];
}
if (address6)
{
LogVerbose(@"Creating IPv6 socket");
socket6FD = [self createSocket:AF_INET6 connectInterface:connectInterface6 errPtr:errPtr];
}
if (socket4FD == SOCKET_NULL && socket6FD == SOCKET_NULL)
{
return NO;
}
int socketFD, alternateSocketFD;
NSData *address, *alternateAddress;
if ((preferIPv6 && socket6FD != SOCKET_NULL) || socket4FD == SOCKET_NULL)
{
socketFD = socket6FD;
alternateSocketFD = socket4FD;
address = address6;
alternateAddress = address4;
}
else
{
socketFD = socket4FD;
alternateSocketFD = socket6FD;
address = address4;
alternateAddress = address6;
}
int aStateIndex = stateIndex;
[self connectSocket:socketFD address:address stateIndex:aStateIndex];
if (alternateAddress)
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(alternateAddressDelay * NSEC_PER_SEC)), socketQueue, ^{
[self connectSocket:alternateSocketFD address:alternateAddress stateIndex:aStateIndex];
});
}
return YES;
}
@ -6342,8 +6457,10 @@ enum GCDAsyncSocketConfig
#if TARGET_OS_IPHONE
{
GCDAsyncSpecialPacket *tlsPacket = (GCDAsyncSpecialPacket *)currentRead;
NSDictionary *tlsSettings = tlsPacket->tlsSettings;
NSDictionary *tlsSettings = @{};
if (tlsPacket) {
tlsSettings = tlsPacket->tlsSettings;
}
NSNumber *value = [tlsSettings objectForKey:GCDAsyncSocketUseCFStreamForTLS];
if (value && [value boolValue])
useSecureTransport = NO;
@ -7380,7 +7497,7 @@ static OSStatus SSLWriteFunction(SSLConnectionRef connection, const void *data,
[cfstreamThread cancel]; // set isCancelled flag
// wake up the thread
[GCDAsyncSocket performSelector:@selector(ignore:)
[[self class] performSelector:@selector(ignore:)
onThread:cfstreamThread
withObject:[NSNull null]
waitUntilDone:NO];
@ -8064,9 +8181,18 @@ static void CFWriteStreamCallback (CFWriteStreamRef stream, CFStreamEventType ty
}
else if (res->ai_family == AF_INET6)
{
// Fixes connection issues with IPv6
// https://github.com/robbiehanson/CocoaAsyncSocket/issues/429#issuecomment-222477158
// Found IPv6 address.
// Wrap the native address structure, and add to results.
struct sockaddr_in6 *sockaddr = (struct sockaddr_in6 *)res->ai_addr;
in_port_t *portPtr = &sockaddr->sin6_port;
if ((portPtr != NULL) && (*portPtr == 0)) {
*portPtr = htons(port);
}
NSData *address6 = [NSData dataWithBytes:res->ai_addr length:res->ai_addrlen];
[addresses addObject:address6];
}