Skip to content
Browse files

Merge pull request #1 from zonque/localsockets

Add support for AF_LOCAL sockets
  • Loading branch information...
2 parents 24c615a + 99e9fa4 commit 12f92177e885423eab601c42321e92ee8740e9d0 @uliwitness committed May 10, 2011
Showing with 88 additions and 0 deletions.
  1. +10 −0 Classes/ULINetSocket.h
  2. +78 −0 Classes/ULINetSocket.m
View
10 Classes/ULINetSocket.h
@@ -89,6 +89,12 @@
@param inMaxPendingConnections the maximum number of pending connections that should be allowed before connections start being refused. */
-(BOOL) listenOnPort: (UInt16)inPort maxPendingConnections: (int)inMaxPendingConnections;
+/*! Starts the socket listening for connections on the specified path. This method will limit pending connections to 5.
+ @result YES if the socket is successfully put into a listening state, NO otherwise.
+ @param path is the name of the socket.
+ @param inMaxPendingConnections the maximum number of pending connections that should be allowed before connections start being refused. */
+-(BOOL) listenOnSocket: (NSString *)path maxPendingConnections: (int)inMaxPendingConnections;
+
/*! @methodgroup Connecting */
/*! Attempts to connect the socket to the specified host on the specified port.
@result YES if the socket is successfully put into a connecting state, NO otherwise.
@@ -103,6 +109,10 @@
@param inTimeout the amount of time the socket has to establish a connection. */
-(BOOL) connectToHost: (NSString*)inHostname port: (UInt16)inPort timeout: (NSTimeInterval)inTimeout;
+/*! Attempts to connect the socket on the specified path.
+ @result YES if the socket is successfully put into a connecting state, NO otherwise.
+ @param path the path of the socket. */
+-(BOOL) connectToSocket: (NSString *)path;
/*! @methodgroup Peeking */
/*! Allows you to look at the data NetSocket has ready for reading without actually advancing the current read position. Returns all of the available data that is ready for reading. */
View
78 Classes/ULINetSocket.m
@@ -28,6 +28,7 @@
#import "ULINetSocket.h"
#import <arpa/inet.h>
#import <sys/socket.h>
+#import <sys/un.h>
#import <sys/time.h>
#import <sys/ioctl.h>
#import <fcntl.h>
@@ -362,6 +363,49 @@ - (BOOL)listenOnPort:(UInt16)inPort maxPendingConnections:(int)inMaxPendingConne
return YES;
}
+-(BOOL)listenOnSocket: (NSString *)path maxPendingConnections:(int)inMaxPendingConnections
+{
+ CFSocketNativeHandle nativeSocket;
+ struct sockaddr_un socketAddress;
+ int result;
+
+ if (![self _cfsocketCreated]) {
+ int sock = socket( PF_LOCAL, SOCK_STREAM, 0 );
+ [self _cfsocketCreateForNative: sock];
+ }
+
+ // If the CFSocket was never created, is connected to another host or is already listening, we cannot use it
+ if( ![self _cfsocketCreated] || [self isConnected] || [self isListening] )
+ return NO;
+
+ // Get native socket descriptor
+ nativeSocket = [self nativeSocketHandle];
+ if( nativeSocket < 0 )
+ return NO;
+
+ // Setup socket address
+ bzero( &socketAddress, sizeof( socketAddress ) );
+ [path getCString: socketAddress.sun_path maxLength: sizeof( socketAddress.sun_path ) encoding: NSASCIIStringEncoding];
+ socketAddress.sun_family = AF_LOCAL;
+
+ unlink ([path cStringUsingEncoding: NSASCIIStringEncoding ]);
+
+ // Bind socket to the specified port
+ result = bind( nativeSocket, (struct sockaddr*)&socketAddress, sizeof( socketAddress ) );
+ if( result < 0 )
+ return NO;
+
+ // Start the socket listening on the specified port
+ result = listen( nativeSocket, inMaxPendingConnections );
+ if( result < 0 )
+ return NO;
+
+ // Note that we are actually listening now
+ mSocketListening = YES;
+
+ return YES;
+}
+
#pragma mark -
- (BOOL)connectToHost:(NSString*)inHostname port:(UInt16)inPort
@@ -409,6 +453,40 @@ - (BOOL)connectToHost:(NSString*)inHostname port:(UInt16)inPort timeout:(NSTimeI
return YES;
}
+-(BOOL)connectToSocket: (NSString *)path
+{
+ struct sockaddr_un socketAddress;
+ NSData* socketAddressData;
+ CFSocketError socketError;
+
+ if (![self _cfsocketCreated]) {
+ int sock = socket( PF_LOCAL, SOCK_STREAM, 0 );
+ [self _cfsocketCreateForNative: sock];
+ }
+
+ // If the CFSocket was never created, is connected to another host or is already listening, we cannot use it
+ if( ![self _cfsocketCreated] || [self isConnected] || [self isListening] )
+ return NO;
+
+ // Setup socket address
+ bzero( &socketAddress, sizeof( socketAddress ) );
+ [path getCString: socketAddress.sun_path maxLength: sizeof( socketAddress.sun_path ) encoding: NSASCIIStringEncoding];
+ socketAddress.sun_family = AF_LOCAL;
+
+ // Enclose socket address in an NSData object
+ socketAddressData = [NSData dataWithBytes:(void*)&socketAddress length:sizeof( socketAddress )];
+
+ // Attempt to connect our CFSocketRef to the specified host
+ socketError = CFSocketConnectToAddress( mCFSocketRef, (CFDataRef)socketAddressData, -1.0 );
+ if( socketError != kCFSocketSuccess )
+ return NO;
+
+ // Remove any data left in our outgoing buffer
+ [mIncomingBuffer setLength:0];
+
+ return YES;
+}
+
#pragma mark -
- (NSData*)peekData

0 comments on commit 12f9217

Please sign in to comment.
Something went wrong with that request. Please try again.