CFSocketStreamImpl.h [plain text]
#ifndef __CFSOCKETSTREAMIMPL__
#define __CFSOCKETSTREAMIMPL__
#include <CFNetwork/CFSocketStream.h>
#include "CFNetworkInternal.h"
#include <CFNetwork/CFHTTPStream.h>
#if defined(__MACH__)
#include <Security/SecureTransport.h>
#include <SystemConfiguration/SCNetworkReachability.h>
#endif
#if defined(__WIN32__)
#include <winsock2.h>
#include <ws2tcpip.h> // for ipv6
#define ioctl(a, b, c) ioctlsocket(a, b, c)
#undef EAGAIN
#define EAGAIN WSAEWOULDBLOCK
#undef ECONNABORTED
#define ECONNABORTED WSAECONNABORTED
#undef ENOTCONN
#define ENOTCONN WSAENOTCONN
#undef ECONNREFUSED
#define ECONNREFUSED WSAECONNREFUSED
#undef EBADF
#define EBADF WSAENOTSOCK
#undef ETIMEDOUT
#define ETIMEDOUT WSAETIMEDOUT
#endif
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(__WIN32__)
typedef struct _SchannelState *SchannelState;
typedef enum {
kSSLIdle = 1,
kSSLHandshake,
kSSLConnected,
kSSLClosed,
kSSLAborted
} SSLSessionState;
#endif
enum {
SHARED = 0,
CREATED_WITH_SOCKET,
OPEN_START,
OPEN_COMPLETE,
SHOULD_CLOSE,
KILL_SOCKET_ON_CLOSE,
SECURITY_CHECK_CERTIFICATE,
VERIFIED_READ_EVENT,
VERIFIED_WRITE_EVENT,
WRITE_STREAM_OPENED,
READ_STREAM_OPENED,
USE_ADDR_CACHE,
RECVD_READ,
RECVD_WRITE,
SELECT_READ,
SELECT_WRITE,
NO_REACHABILITY,
ICHAT_SUBNET_SETTING = 31
};
typedef struct {
CFMutableArrayRef runloops;
struct _CFStream *stream; } _CFSocketStreamRLSource;
typedef struct {
UInt32 socks_flags; CFHostRef host; UInt32 port; CFStringRef user; CFStringRef pass; CFIndex bytesInBuffer; UInt8* buffer; } _SOCKSInfo;
typedef struct {
CFHostRef host;
UInt32 port;
CFDictionaryRef settings;
CFDataRef request;
CFIndex left;
CFHTTPMessageRef response;
} _CONNECTInfo;
struct _CFSocketStreamContext;
typedef void (*handshakeFn)(struct _CFSocketStreamContext*);
typedef struct {
CFSpinLock_t lock; CFOptionFlags flags;
CFAllocatorRef alloc;
CFStreamError error;
CFTypeRef lookup; CFIndex attempt; CFSocketRef sock;
CFArrayRef cb;
#if defined(__MACH__)
SCNetworkReachabilityRef reachability;
#endif
union {
UInt32 port; int sock; } u;
CFSocketSignature sig;
CFMutableArrayRef runloops; _CFSocketStreamRLSource *readSource, *writeSource;
handshakeFn handshakes[4];
CFStringRef peerName; #if defined(__MACH__)
SSLContextRef security;
UInt8* sslBuffer;
CFIndex sslBufferCount;
#elif defined(__WIN32__)
SchannelState ssl;
#endif
_SOCKSInfo* socks_info;
_CONNECTInfo* connect_info;
} _CFSocketStreamContext;
extern CFIndex __fdRecv(int fd, UInt8* buffer, CFIndex bufferLength, CFStreamError* errorCode, Boolean *atEOF);
extern CFIndex __fdSend(int fd, const UInt8* buffer, CFIndex bufferLength, CFStreamError* errorCode);
extern char* __getServerName(_CFSocketStreamContext* ctxt, char *buffer, UInt32 *bufSize, CFAllocatorRef *allocator);
extern Boolean __AddHandshake_Unsafe(_CFSocketStreamContext* ctxt, handshakeFn fn);
extern void __RemoveHandshake_Unsafe(_CFSocketStreamContext* ctxt, handshakeFn fn);
extern void __WaitForHandshakeToComplete_Unsafe(_CFSocketStreamContext* ctxt);
#define __socketGetFD(ctxt) ((int)((__CFBitIsSet(ctxt->flags, CREATED_WITH_SOCKET)) ? ctxt->u.sock : (ctxt->sock ? CFSocketGetNative(ctxt->sock) : -1)))
extern CFIndex sslRecv(_CFSocketStreamContext* ctxt, UInt8* buffer, CFIndex bufferLength, CFStreamError* errorCode, Boolean *atEOF);
extern CFIndex sslSend(_CFSocketStreamContext* ctxt, const UInt8* buffer, CFIndex bufferLength, CFStreamError* errorCode);
extern void sslClose(_CFSocketStreamContext* ctxt);
extern CFIndex sslBytesAvailableForRead(_CFSocketStreamContext* ctxt);
extern void performSSLHandshake(_CFSocketStreamContext* ctxt);
extern void performSSLSendHandshake(_CFSocketStreamContext* ctxt);
extern Boolean __SetSecuritySettings_Unsafe(_CFSocketStreamContext* ctxt, CFDictionaryRef settings);
extern CFStringRef __GetSSLProtocol(_CFSocketStreamContext* ctxt);
extern SSLSessionState __GetSSLSessionState(_CFSocketStreamContext* ctxt);
#if 0
#define SSL_LOG printf
#else
#define SSL_LOG while(0) printf
#endif
#if defined(__MACH__)
#define IS_SECURE(x) ((x)->security != NULL)
#define SSL_WOULD_BLOCK(error) ((error->domain == kCFStreamErrorDomainSSL) && (errSSLWouldBlock == error->error) )
#elif defined(__WIN32__)
#define IS_SECURE(ctxt) ((ctxt)->ssl != NULL)
#define SSL_WOULD_BLOCK(error) (FALSE)
#endif
#if defined(__cplusplus)
}
#endif
#endif