CFSocket.h
1 /* CFSocket.h 2 Copyright (c) 1999-2019, Apple Inc. and the Swift project authors 3 4 Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors 5 Licensed under Apache License v2.0 with Runtime Library Exception 6 See http://swift.org/LICENSE.txt for license information 7 See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors 8 */ 9 10 #if !defined(__COREFOUNDATION_CFSOCKET__) 11 #define __COREFOUNDATION_CFSOCKET__ 1 12 13 #include <CoreFoundation/CFRunLoop.h> 14 #include <CoreFoundation/CFData.h> 15 16 CF_IMPLICIT_BRIDGING_ENABLED 17 CF_EXTERN_C_BEGIN 18 19 typedef struct CF_BRIDGED_MUTABLE_TYPE(id) __CFSocket * CFSocketRef; 20 21 /* A CFSocket contains a native socket within a structure that can 22 be used to read from the socket in the background and make the data 23 thus read available using a runloop source. The callback used for 24 this may be of three types, as specified by the callBackTypes 25 argument when creating the CFSocket. 26 27 If kCFSocketReadCallBack is used, then data will not be 28 automatically read, but the callback will be called when data 29 is available to be read, or a new child socket is waiting to be 30 accepted. 31 32 If kCFSocketAcceptCallBack is used, then new child sockets will be 33 accepted and passed to the callback, with the data argument being 34 a pointer to a CFSocketNativeHandle. This is usable only with 35 connection rendezvous sockets. 36 37 If kCFSocketDataCallBack is used, then data will be read in chunks 38 in the background and passed to the callback, with the data argument 39 being a CFDataRef. 40 41 These three types are mutually exclusive, but any one of them may 42 have kCFSocketConnectCallBack added to it, if the socket will be 43 used to connect in the background. Connect in the background occurs 44 if CFSocketConnectToAddress is called with a negative timeout 45 value, in which case the call returns immediately, and a 46 kCFSocketConnectCallBack is generated when the connect finishes. 47 In this case the data argument is either NULL, or a pointer to 48 an SInt32 error code if the connect failed. kCFSocketConnectCallBack 49 will never be sent more than once for a given socket. 50 51 The callback types may also have kCFSocketWriteCallBack added to 52 them, if large amounts of data are to be sent rapidly over the 53 socket and notification is desired when there is space in the 54 kernel buffers so that the socket is writable again. 55 56 With a connection-oriented socket, if the connection is broken from the 57 other end, then one final kCFSocketReadCallBack or kCFSocketDataCallBack 58 will occur. In the case of kCFSocketReadCallBack, the underlying socket 59 will have 0 bytes available to read. In the case of kCFSocketDataCallBack, 60 the data argument will be a CFDataRef of length 0. 61 62 There are socket flags that may be set to control whether callbacks of 63 a given type are automatically reenabled after they are triggered, and 64 whether the underlying native socket will be closed when the CFSocket 65 is invalidated. By default read, accept, and data callbacks are 66 automatically reenabled; write callbacks are not, and connect callbacks 67 may not be, since they are sent once only. Be careful about automatically 68 reenabling read and write callbacks, since this implies that the 69 callbacks will be sent repeatedly if the socket remains readable or 70 writable respectively. Be sure to set these flags only for callbacks 71 that your CFSocket actually possesses; the result of setting them for 72 other callback types is undefined. 73 74 Individual callbacks may also be enabled and disabled manually, whether 75 they are automatically reenabled or not. If they are not automatically 76 reenabled, then they will need to be manually reenabled when the callback 77 is ready to be received again (and not sooner). Even if they are 78 automatically reenabled, there may be occasions when it will be useful 79 to be able to manually disable them temporarily and then reenable them. 80 Be sure to enable and disable only callbacks that your CFSocket actually 81 possesses; the result of enabling and disabling other callback types is 82 undefined. 83 84 By default the underlying native socket will be closed when the CFSocket 85 is invalidated, but it will not be if kCFSocketCloseOnInvalidate is 86 turned off. This can be useful in order to destroy a CFSocket but 87 continue to use the underlying native socket. The CFSocket must 88 still be invalidated when it will no longer be used. Do not in 89 either case close the underlying native socket without invalidating 90 the CFSocket. 91 92 Addresses are stored as CFDatas containing a struct sockaddr 93 appropriate for the protocol family; make sure that all fields are 94 filled in properly when passing in an address. 95 96 */ 97 98 /* Values for CFSocketError */ 99 typedef CF_ENUM(CFIndex, CFSocketError) { 100 kCFSocketSuccess = 0, 101 kCFSocketError = -1L, 102 kCFSocketTimeout = -2L 103 }; 104 105 typedef struct { 106 SInt32 protocolFamily; 107 SInt32 socketType; 108 SInt32 protocol; 109 CFDataRef address; 110 } CFSocketSignature; 111 112 /* Values for CFSocketCallBackType */ 113 typedef CF_OPTIONS(CFOptionFlags, CFSocketCallBackType) { 114 kCFSocketNoCallBack = 0, 115 kCFSocketReadCallBack = 1, 116 kCFSocketAcceptCallBack = 2, 117 kCFSocketDataCallBack = 3, 118 kCFSocketConnectCallBack = 4, 119 kCFSocketWriteCallBack = 8 120 }; 121 122 /* Socket flags */ 123 CF_ENUM(CFOptionFlags) { 124 kCFSocketAutomaticallyReenableReadCallBack = 1, 125 kCFSocketAutomaticallyReenableAcceptCallBack = 2, 126 kCFSocketAutomaticallyReenableDataCallBack = 3, 127 kCFSocketAutomaticallyReenableWriteCallBack = 8, 128 kCFSocketLeaveErrors API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)) = 64, 129 kCFSocketCloseOnInvalidate = 128 130 }; 131 132 typedef void (*CFSocketCallBack)(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info); 133 /* If the callback wishes to keep hold of address or data after the point that it returns, then it must copy them. */ 134 135 typedef struct { 136 CFIndex version; 137 void * info; 138 const void *(*retain)(const void *info); 139 void (*release)(const void *info); 140 CFStringRef (*copyDescription)(const void *info); 141 } CFSocketContext; 142 143 #if TARGET_OS_WIN32 144 typedef uintptr_t CFSocketNativeHandle; 145 #else 146 typedef int CFSocketNativeHandle; 147 #endif 148 149 CF_EXPORT CFTypeID CFSocketGetTypeID(void); 150 151 CF_EXPORT CFSocketRef CFSocketCreate(CFAllocatorRef allocator, SInt32 protocolFamily, SInt32 socketType, SInt32 protocol, CFOptionFlags callBackTypes, CFSocketCallBack callout, const CFSocketContext *context); 152 CF_EXPORT CFSocketRef CFSocketCreateWithNative(CFAllocatorRef allocator, CFSocketNativeHandle sock, CFOptionFlags callBackTypes, CFSocketCallBack callout, const CFSocketContext *context); 153 CF_EXPORT CFSocketRef CFSocketCreateWithSocketSignature(CFAllocatorRef allocator, const CFSocketSignature *signature, CFOptionFlags callBackTypes, CFSocketCallBack callout, const CFSocketContext *context); 154 /* CFSocketCreateWithSocketSignature() creates a socket of the requested type and binds its address (using CFSocketSetAddress()) to the requested address. If this fails, it returns NULL. */ 155 CF_EXPORT CFSocketRef CFSocketCreateConnectedToSocketSignature(CFAllocatorRef allocator, const CFSocketSignature *signature, CFOptionFlags callBackTypes, CFSocketCallBack callout, const CFSocketContext *context, CFTimeInterval timeout); 156 /* CFSocketCreateConnectedToSocketSignature() creates a socket suitable for connecting to the requested type and address, and connects it (using CFSocketConnectToAddress()). If this fails, it returns NULL. */ 157 158 CF_EXPORT CFSocketError CFSocketSetAddress(CFSocketRef s, CFDataRef address); 159 CF_EXPORT CFSocketError CFSocketConnectToAddress(CFSocketRef s, CFDataRef address, CFTimeInterval timeout); 160 CF_EXPORT void CFSocketInvalidate(CFSocketRef s); 161 162 CF_EXPORT Boolean CFSocketIsValid(CFSocketRef s); 163 CF_EXPORT CFDataRef CFSocketCopyAddress(CFSocketRef s); 164 CF_EXPORT CFDataRef CFSocketCopyPeerAddress(CFSocketRef s); 165 CF_EXPORT void CFSocketGetContext(CFSocketRef s, CFSocketContext *context); 166 CF_EXPORT CFSocketNativeHandle CFSocketGetNative(CFSocketRef s); 167 168 CF_EXPORT CFRunLoopSourceRef CFSocketCreateRunLoopSource(CFAllocatorRef allocator, CFSocketRef s, CFIndex order); 169 170 CF_EXPORT CFOptionFlags CFSocketGetSocketFlags(CFSocketRef s); 171 CF_EXPORT void CFSocketSetSocketFlags(CFSocketRef s, CFOptionFlags flags); 172 CF_EXPORT void CFSocketDisableCallBacks(CFSocketRef s, CFOptionFlags callBackTypes); 173 CF_EXPORT void CFSocketEnableCallBacks(CFSocketRef s, CFOptionFlags callBackTypes); 174 175 176 /* For convenience, a function is provided to send data using the socket with a timeout. The timeout will be used only if the specified value is positive. The address should be left NULL if the socket is already connected. */ 177 CF_EXPORT CFSocketError CFSocketSendData(CFSocketRef s, CFDataRef address, CFDataRef data, CFTimeInterval timeout); 178 179 /* Generic name registry functionality (CFSocketRegisterValue, 180 CFSocketCopyRegisteredValue) allows the registration of any property 181 list type. Functions specific to CFSockets (CFSocketRegisterSocketData, 182 CFSocketCopyRegisteredSocketData) register a CFData containing the 183 components of a socket signature (protocol family, socket type, 184 protocol, and address). In each function the nameServerSignature 185 may be NULL, or any component of it may be 0, to use default values 186 (TCP, INADDR_LOOPBACK, port as set). Name registration servers might 187 not allow registration with other than TCP and INADDR_LOOPBACK. 188 The actual address of the server responding to a query may be obtained 189 by using the nameServerAddress argument. This address, the address 190 returned by CFSocketCopyRegisteredSocketSignature, and the value 191 returned by CFSocketCopyRegisteredValue must (if non-null) be released 192 by the caller. CFSocketUnregister removes any registration associated 193 with the specified name. 194 */ 195 196 CF_EXPORT CFSocketError CFSocketRegisterValue(const CFSocketSignature *nameServerSignature, CFTimeInterval timeout, CFStringRef name, CFPropertyListRef value); 197 CF_EXPORT CFSocketError CFSocketCopyRegisteredValue(const CFSocketSignature *nameServerSignature, CFTimeInterval timeout, CFStringRef name, CFPropertyListRef *value, CFDataRef *nameServerAddress); 198 199 CF_EXPORT CFSocketError CFSocketRegisterSocketSignature(const CFSocketSignature *nameServerSignature, CFTimeInterval timeout, CFStringRef name, const CFSocketSignature *signature); 200 CF_EXPORT CFSocketError CFSocketCopyRegisteredSocketSignature(const CFSocketSignature *nameServerSignature, CFTimeInterval timeout, CFStringRef name, CFSocketSignature *signature, CFDataRef *nameServerAddress); 201 202 CF_EXPORT CFSocketError CFSocketUnregister(const CFSocketSignature *nameServerSignature, CFTimeInterval timeout, CFStringRef name); 203 204 CF_EXPORT void CFSocketSetDefaultNameRegistryPortNumber(UInt16 port); 205 CF_EXPORT UInt16 CFSocketGetDefaultNameRegistryPortNumber(void); 206 207 /* Constants used in name registry server communications */ 208 CF_EXPORT const CFStringRef kCFSocketCommandKey; 209 CF_EXPORT const CFStringRef kCFSocketNameKey; 210 CF_EXPORT const CFStringRef kCFSocketValueKey; 211 CF_EXPORT const CFStringRef kCFSocketResultKey; 212 CF_EXPORT const CFStringRef kCFSocketErrorKey; 213 CF_EXPORT const CFStringRef kCFSocketRegisterCommand; 214 CF_EXPORT const CFStringRef kCFSocketRetrieveCommand; 215 216 CF_EXTERN_C_END 217 CF_IMPLICIT_BRIDGING_DISABLED 218 219 #endif /* ! __COREFOUNDATION_CFSOCKET__ */ 220