Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
sausaw committed Nov 30, 2018
1 parent 1cd696a commit 12e6171
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 152 deletions.
2 changes: 0 additions & 2 deletions ios/CocoaAsyncSocket/GCDAsyncSocket.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -790,8 +790,6 @@ typedef NS_ENUM(NSInteger, GCDAsyncSocketError) {
**/
- (void)startTLS:(nullable NSDictionary <NSString*,NSObject*>*)tlsSettings;

- (void)startTLSCancelCurrentRead:(nullable NSDictionary <NSString*,NSObject*>*)tlsSettings;

#pragma mark Advanced

/**
Expand Down
15 changes: 1 addition & 14 deletions ios/CocoaAsyncSocket/GCDAsyncSocket.m
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -6407,7 +6407,7 @@ - (void)doWriteTimeoutWithExtension:(NSTimeInterval)timeoutExtension
#pragma mark Security
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

- (void)doStartTLS:(NSDictionary *)tlsSettings withCancelCurrentRead:(BOOL)cancelCurrentRead
- (void)startTLS:(NSDictionary *)tlsSettings
{
LogTrace();

Expand All @@ -6430,11 +6430,6 @@ - (void)doStartTLS:(NSDictionary *)tlsSettings withCancelCurrentRead:(BOOL)cance

if ((flags & kSocketStarted) && !(flags & kQueuedTLS) && !(flags & kForbidReadsWrites))
{
// dirty hack to fix that the client has already added a read with no timeout which we need to finish
if (currentRead && cancelCurrentRead) {
LogInfo(@"Cancelling current read as requested");
[self completeCurrentRead];
}
[readQueue addObject:packet];
[writeQueue addObject:packet];

Expand All @@ -6447,14 +6442,6 @@ - (void)doStartTLS:(NSDictionary *)tlsSettings withCancelCurrentRead:(BOOL)cance

}

- (void)startTLSCancelCurrentRead:(NSDictionary *)tlsSettings
{
[self doStartTLS:tlsSettings withCancelCurrentRead:TRUE];
}
- (void)startTLS:(NSDictionary *)tlsSettings {
[self doStartTLS:tlsSettings withCancelCurrentRead:FALSE];
}

- (void)maybeStartTLS
{
// We can't start TLS until:
Expand Down
10 changes: 4 additions & 6 deletions ios/TcpSocketClient.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ typedef enum RCTTCPError RCTTCPError;
- (void)onData:(NSNumber *)clientID data:(NSData *)data;
- (void)onClose:(TcpSocketClient*)client withError:(NSError *)err;
- (void)onError:(TcpSocketClient*)client withError:(NSError *)err;
- (void)onSecureConnect:(TcpSocketClient*)client;
- (NSNumber*)getNextTag;
- (void)setPendingSend:(RCTResponseSenderBlock)callback forKey:(NSNumber *)key;
- (RCTResponseSenderBlock)getPendingSend:(NSNumber *)key;
- (void)dropPendingSend:(NSNumber *)key;
- (NSNumber*)getNextId;

@end
Expand All @@ -40,7 +43,6 @@ typedef enum RCTTCPError RCTTCPError;

@property (nonatomic, retain) NSNumber * id;
@property (nonatomic, weak) id<SocketClientDelegate> clientDelegate;
@property (nonatomic) BOOL useSsl;

///---------------------------------------------------------------------------------------
/// @name Class Methods
Expand All @@ -64,14 +66,10 @@ typedef enum RCTTCPError RCTTCPError;
* @param port
* @param host ip address
* @param options NSDictionary which can have @"localAddress" and @"localPort" to specify the local interface
* @param useSsl BOOL Use SSL/TLS connection
* @return true if connected, false if there was an error
*/
- (BOOL)connect:(NSString *)host port:(int)port withOptions:(NSDictionary *)options useSsl:(BOOL)useSsl error:(NSError **)error;
- (BOOL)connect:(NSString *)host port:(int)port withOptions:(NSDictionary *)options error:(NSError **)error;

- (void)upgradeToSecure:(NSString *)host port:(int)port callback:(RCTResponseSenderBlock) callback;

/**
* Starts listening on a local host and port
*
Expand Down
106 changes: 12 additions & 94 deletions ios/TcpSocketClient.m
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,6 @@ @interface TcpSocketClient()
{
@private
GCDAsyncSocket *_tcpSocket;
NSString *_host;
NSMutableDictionary<NSNumber *, RCTResponseSenderBlock> *_pendingSends;
RCTResponseSenderBlock _pendingUpgrade;
NSLock *_lock;
long _sendTag;
}

- (id)initWithClientId:(NSNumber *)clientID andConfig:(id<SocketClientDelegate>)aDelegate;
Expand All @@ -45,8 +40,6 @@ - (id)initWithClientId:(NSNumber *)clientID andConfig:(id<SocketClientDelegate>)
if (self) {
_id = clientID;
_clientDelegate = aDelegate;
_pendingSends = [NSMutableDictionary dictionary];
_lock = [[NSLock alloc] init];
_tcpSocket = tcpSocket;
[_tcpSocket setUserData: clientID];
}
Expand All @@ -56,12 +49,6 @@ - (id)initWithClientId:(NSNumber *)clientID andConfig:(id<SocketClientDelegate>)

- (BOOL)connect:(NSString *)host port:(int)port withOptions:(NSDictionary *)options error:(NSError **)error
{
return [self connect:host port:port withOptions:options useSsl:NO error:error];
}

- (BOOL)connect:(NSString *)host port:(int)port withOptions:(NSDictionary *)options useSsl:(BOOL)useSsl error:(NSError **)error
{
self.useSsl = useSsl;
if (_tcpSocket) {
if (error) {
*error = [self badInvocationError:@"this client's socket is already connected"];
Expand All @@ -70,7 +57,6 @@ - (BOOL)connect:(NSString *)host port:(int)port withOptions:(NSDictionary *)opti
return false;
}

_host = host;
_tcpSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:[self methodQueue]];
[_tcpSocket setUserData: _id];

Expand All @@ -97,16 +83,6 @@ - (BOOL)connect:(NSString *)host port:(int)port withOptions:(NSDictionary *)opti
return result;
}

- (void)upgradeToSecure:(NSString *)host port:(int)port callback:(RCTResponseSenderBlock) callback;
{
if (callback) {
self->_pendingUpgrade = callback;
}
NSMutableDictionary *settings = [NSMutableDictionary dictionary];

[_tcpSocket startTLSCancelCurrentRead:settings];
}

- (NSDictionary<NSString *, id> *)getAddress
{
if (_tcpSocket)
Expand Down Expand Up @@ -153,58 +129,26 @@ - (BOOL)listen:(NSString *)host port:(int)port error:(NSError **)error
return isListening;
}

- (void)setPendingSend:(RCTResponseSenderBlock)callback forKey:(NSNumber *)key
{
[_lock lock];
@try {
[_pendingSends setObject:callback forKey:key];
}
@finally {
[_lock unlock];
}
}

- (RCTResponseSenderBlock)getPendingSend:(NSNumber *)key
{
[_lock lock];
@try {
return [_pendingSends objectForKey:key];
}
@finally {
[_lock unlock];
}
}

- (void)dropPendingSend:(NSNumber *)key
{
[_lock lock];
@try {
[_pendingSends removeObjectForKey:key];
}
@finally {
[_lock unlock];
}
}

- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)msgTag
{
NSNumber* tagNum = [NSNumber numberWithLong:msgTag];
RCTResponseSenderBlock callback = [self getPendingSend:tagNum];
RCTResponseSenderBlock callback = [_clientDelegate getPendingSend:tagNum];
if (callback) {
callback(@[]);
[self dropPendingSend:tagNum];
[_clientDelegate dropPendingSend:tagNum];
}
}

- (void) writeData:(NSData *)data
callback:(RCTResponseSenderBlock)callback
{
NSNumber *sendTag = [_clientDelegate getNextTag];
if (callback) {
[self setPendingSend:callback forKey:@(_sendTag)];
[_clientDelegate setPendingSend:callback forKey:sendTag];
}
[_tcpSocket writeData:data withTimeout:-1 tag:_sendTag];
_sendTag++;
[_tcpSocket writeData:data withTimeout:-1 tag:sendTag.longValue];

[_tcpSocket readDataWithTimeout:-1 tag:_id.longValue];
}

- (void)end
Expand All @@ -222,13 +166,10 @@ - (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)t
RCTLogWarn(@"didReadData with nil clientDelegate for %@", [sock userData]);
return;
}

[_clientDelegate onData:@(tag) data:data];

if (!_pendingUpgrade) {
// if we add a read, the special packet will not be picked up in time
[sock readDataWithTimeout:-1 tag:tag];
}
[sock readDataWithTimeout:-1 tag:tag];
}

- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket
Expand All @@ -248,34 +189,11 @@ - (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(ui
return;
}

if (self.useSsl)
{
NSMutableDictionary *settings = [NSMutableDictionary dictionary];
[sock startTLS:settings];

[_clientDelegate onConnect:self];
}
else
{
[_clientDelegate onConnect:self];
[sock readDataWithTimeout:-1 tag:_id.longValue];
}
}
[_clientDelegate onConnect:self];

- (void)socketDidSecure:(GCDAsyncSocket *)sock {
RCTLogInfo(@"socket secured");
if (self->_pendingUpgrade) {
self.useSsl= true;
self->_pendingUpgrade(@[]);
self->_pendingUpgrade = nil;
[_clientDelegate onSecureConnect:self];
}
// start receiving messages
if (self.useSsl)
{
[sock readDataWithTimeout:-1 tag:_id.longValue];
}
[sock readDataWithTimeout:-1 tag:_id.longValue];
}

- (void)socketDidCloseReadStream:(GCDAsyncSocket *)sock
{
// TODO : investigate for half-closed sockets
Expand Down
Empty file modified ios/TcpSockets.h
100644 → 100755
Empty file.
94 changes: 58 additions & 36 deletions ios/TcpSockets.m
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@
// offset native ids by 5000
#define COUNTER_OFFSET 5000

@interface TcpSockets() {

@private
NSMutableDictionary<NSNumber *, RCTResponseSenderBlock> *_pendingSends;
NSLock *_lock;
long _tag;
}
@end

@implementation TcpSockets
{
NSMutableDictionary<NSNumber *,TcpSocketClient *> *_clients;
Expand All @@ -22,13 +31,25 @@ @implementation TcpSockets

RCT_EXPORT_MODULE()

- (id)init {
self = [super init];
if (self) {
_pendingSends = [NSMutableDictionary dictionary];
_lock = [[NSLock alloc] init];
}
return self;
}

- (NSNumber*)getNextTag {
return [NSNumber numberWithLong:_tag++];
}

- (NSArray<NSString *> *)supportedEvents
{
return @[@"connect",
@"connection",
@"data",
@"close",
@"secureConnect",
@"error"];
}

Expand Down Expand Up @@ -86,39 +107,12 @@ - (TcpSocketClient *)createSocket:(nonnull NSNumber*)cId
}
}

RCT_EXPORT_METHOD(connectTls:(nonnull NSNumber*)cId
host:(NSString *)host
port:(int)port
withOptions:(NSDictionary *)options)
{
TcpSocketClient *client = _clients[cId];
if (!client) {
client = [self createSocket:cId];
}

NSError *error = nil;
if (![client connect:host port:port withOptions:options useSsl:YES error:&error])
{
[self onError:client withError:error];
return;
}
}

RCT_EXPORT_METHOD(upgradeToSecure:(nonnull NSNumber*)cId
host:(NSString *)host
port:(int)port
callback:(RCTResponseSenderBlock)callback) {
TcpSocketClient* client = [self findClient:cId];
if (!client) return;
[client upgradeToSecure:host port:port callback:callback];
}

RCT_EXPORT_METHOD(write:(nonnull NSNumber*)cId
string:(NSString *)base64String
callback:(RCTResponseSenderBlock)callback) {
TcpSocketClient* client = [self findClient:cId];
if (!client) return;

// iOS7+
// TODO: use https://github.com/nicklockwood/Base64 for compatibility with earlier iOS versions
NSData *data = [[NSData alloc] initWithBase64EncodedString:base64String options:0];
Expand Down Expand Up @@ -156,15 +150,9 @@ - (void)onConnect:(TcpSocketClient*) client
body:@{ @"id": client.id, @"address" : [client getAddress] }];
}

- (void)onSecureConnect:(TcpSocketClient*) client
{
[self sendEventWithName:@"secureConnect"
body:@{ @"id": client.id }];
}

-(void)onConnection:(TcpSocketClient *)client toClient:(NSNumber *)clientID {
_clients[client.id] = client;

[self sendEventWithName:@"connection"
body:@{ @"id": clientID, @"info": @{ @"id": client.id, @"address" : [client getAddress] } }];
}
Expand Down Expand Up @@ -234,4 +222,38 @@ -(NSNumber*)getNextId {
return @(_counter++ + COUNTER_OFFSET);
}


- (void)setPendingSend:(RCTResponseSenderBlock)callback forKey:(NSNumber *)key
{
[_lock lock];
@try {
[_pendingSends setObject:callback forKey:key];
}
@finally {
[_lock unlock];
}
}

- (RCTResponseSenderBlock)getPendingSend:(NSNumber *)key
{
[_lock lock];
@try {
return [_pendingSends objectForKey:key];
}
@finally {
[_lock unlock];
}
}

- (void)dropPendingSend:(NSNumber *)key
{
[_lock lock];
@try {
[_pendingSends removeObjectForKey:key];
}
@finally {
[_lock unlock];
}
}

@end

0 comments on commit 12e6171

Please sign in to comment.