Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Source/CFRuntime.c
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,7 @@ GS_PRIVATE void CFNumberInitialize (void);
GS_PRIVATE void CFNumberFormatterInitialize (void);
GS_PRIVATE void CFRunLoopInitialize (void);
GS_PRIVATE void CFSetInitialize (void);
GS_PRIVATE void CFSocketInitialize (void);
GS_PRIVATE void CFStreamInitialize (void);
GS_PRIVATE void CFStringInitialize (void);
GS_PRIVATE void CFConstantStringInitialize (void);
Expand Down Expand Up @@ -530,6 +531,7 @@ CFInitialize (void)
CFNumberInitialize ();
CFNumberFormatterInitialize ();
CFSetInitialize ();
CFSocketInitialize ();
CFStreamInitialize ();
CFStringInitialize ();
CFConstantStringInitialize (); /* must be after CFStringIntialize () */
Expand Down
32 changes: 16 additions & 16 deletions Source/CFSocket.c
Original file line number Diff line number Diff line change
Expand Up @@ -375,37 +375,37 @@ CFSocketCopyAddress (CFSocketRef s)
GSMutexLock (&s->_lock);
if (s->_address == NULL)
{
struct sockaddr addr;
socklen_t addrlen;
getsockname (s->_socket, &addr, &addrlen);
s->_address = CFDataCreate (CFGetAllocator (s), (const UInt8*)&addr,
(CFIndex)addrlen);
struct sockaddr_storage addr;
socklen_t addrlen = sizeof (addr);
if (getsockname (s->_socket, (struct sockaddr*)&addr, &addrlen) == 0)
s->_address = CFDataCreate (CFGetAllocator (s), (const UInt8*)&addr,
(CFIndex)addrlen);
}
if (s->_address != NULL)
ret = CFRetain (s->_address);
GSMutexUnlock (&s->_lock);

return ret;
}

CFDataRef
CFSocketCopyPeerAddress (CFSocketRef s)
{
CFDataRef ret = NULL;

GSMutexLock (&s->_lock);
if (s->_address == NULL)
if (s->_peerAddress == NULL)
{
struct sockaddr addr;
socklen_t addrlen;
getpeername (s->_socket, &addr, &addrlen);
s->_address = CFDataCreate (CFGetAllocator (s), (const UInt8*)&addr,
(CFIndex)addrlen);
struct sockaddr_storage addr;
socklen_t addrlen = sizeof (addr);
if (getpeername (s->_socket, (struct sockaddr*)&addr, &addrlen) == 0)
s->_peerAddress = CFDataCreate (CFGetAllocator (s),
(const UInt8*)&addr, (CFIndex)addrlen);
}
if (s->_address != NULL)
ret = CFRetain (s->_address);
if (s->_peerAddress != NULL)
ret = CFRetain (s->_peerAddress);
GSMutexUnlock (&s->_lock);

return ret;
}

Expand Down
Empty file added Tests/CFSocket/TestInfo
Empty file.
78 changes: 78 additions & 0 deletions Tests/CFSocket/basic.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#include "CoreFoundation/CFRunLoop.h"
#include "CoreFoundation/CFSocket.h"
#include "CoreFoundation/CFData.h"

#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

#include "../CFTesting.h"

int
main (void)
{
CFSocketRef s;
CFSocketContext ctx;
CFSocketContext got;
int marker = 42;
struct sockaddr_in sin;
CFDataRef addrData;
CFDataRef bound;

PASS_CF(CFSocketGetTypeID () != 0, "CFSocketGetTypeID is non-zero.");

memset (&ctx, 0, sizeof ctx);
ctx.info = &marker;
s = CFSocketCreate (NULL, PF_INET, SOCK_STREAM, IPPROTO_TCP, 0, NULL, &ctx);
PASS_CF(s != NULL, "A TCP socket is created.");

PASS_CF(CFGetTypeID (s) == CFSocketGetTypeID (),
"The socket carries the socket type id.");
PASS_CF(CFSocketGetNative (s) >= 0, "The socket has a native handle.");
PASS_CF(CFSocketIsValid (s), "A fresh socket is valid.");

CFSocketSetSocketFlags (s, kCFSocketCloseOnInvalidate
| kCFSocketAutomaticallyReenableReadCallBack);
PASS_CF(CFSocketGetSocketFlags (s) == (CFOptionFlags)
(kCFSocketCloseOnInvalidate
| kCFSocketAutomaticallyReenableReadCallBack),
"Socket flags round-trip through the getter.");

memset (&got, 0, sizeof got);
CFSocketGetContext (s, &got);
PASS_CF(got.info == &marker, "The context info is returned.");

/* Bind to an ephemeral loopback port and read the address back. */
memset (&sin, 0, sizeof sin);
sin.sin_family = AF_INET;
sin.sin_port = 0;
sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
addrData = CFDataCreate (NULL, (const UInt8 *)&sin, sizeof sin);
PASS_CF(CFSocketSetAddress (s, addrData) == kCFSocketSuccess,
"Binding to a loopback address succeeds.");
CFRelease (addrData);

bound = CFSocketCopyAddress (s);
PASS_CF(bound != NULL
&& CFDataGetLength (bound) == (CFIndex)sizeof (struct sockaddr_in),
"The bound address has the length of a sockaddr_in.");
if (bound != NULL
&& CFDataGetLength (bound) == (CFIndex)sizeof (struct sockaddr_in))
{
const struct sockaddr_in *b =
(const struct sockaddr_in *)CFDataGetBytePtr (bound);
PASS_CF(b->sin_family == AF_INET
&& b->sin_addr.s_addr == htonl (INADDR_LOOPBACK),
"The bound address is the loopback address.");
}
if (bound != NULL)
CFRelease (bound);

CFSocketInvalidate (s);
PASS_CF(CFSocketIsValid (s) == false,
"An invalidated socket is no longer valid.");

CFRelease (s);

return 0;
}
48 changes: 48 additions & 0 deletions Tests/CFSocket/peeraddr.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include "CoreFoundation/CFRunLoop.h"
#include "CoreFoundation/CFSocket.h"
#include "CoreFoundation/CFData.h"

#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

#include "../CFTesting.h"

int
main (void)
{
CFSocketRef s;
struct sockaddr_in sin;
CFDataRef addrData;
CFDataRef local;
CFDataRef peer;

s = CFSocketCreate (NULL, PF_INET, SOCK_STREAM, IPPROTO_TCP, 0, NULL, NULL);
PASS_CF(s != NULL, "A TCP socket is created.");

memset (&sin, 0, sizeof sin);
sin.sin_family = AF_INET;
sin.sin_port = 0;
sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
addrData = CFDataCreate (NULL, (const UInt8 *)&sin, sizeof sin);
CFSocketSetAddress (s, addrData);
CFRelease (addrData);

/* The local address is available after binding. */
local = CFSocketCopyAddress (s);
PASS_CF(local != NULL, "A bound socket has a local address.");

/* The socket is never connected, so it has no peer address, even after
* the local address has been read.
*/
peer = CFSocketCopyPeerAddress (s);
PASS_CF(peer == NULL,
"An unconnected socket has no peer address.");

if (local != NULL) CFRelease (local);
if (peer != NULL) CFRelease (peer);
CFSocketInvalidate (s);
CFRelease (s);

return 0;
}
Loading