static void nc_trigger(int argc, char **argv) { Boolean background = FALSE; int i; CFStringRef hostName = NULL; int port = 80; for (i = 0; i < 3 && i < argc; i++) { /* Parse host name. Must be first arg. */ if (i == 0) { hostName = CFStringCreateWithCString(NULL, argv[i], kCFStringEncodingUTF8); continue; } /* Check for optional background flag */ if (strcmp(argv[i], "background") == 0) { background = TRUE; continue; } /* Parse optional port number */ CFStringRef str = CFStringCreateWithCString(NULL, argv[i], kCFStringEncodingUTF8); if (str) { int num = CFStringGetIntValue(str); if (num) { port = num; } my_CFRelease(&str); } } if (hostName) { CFReadStreamRef readStream = NULL; CFWriteStreamRef writeStream = NULL; CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, hostName, port, &readStream, &writeStream); if (background) { CFReadStreamSetProperty(readStream, CFSTR("kCFStreamNetworkServiceType"), CFSTR("kCFStreamNetworkServiceTypeBackground")); CFWriteStreamSetProperty(writeStream, CFSTR("kCFStreamNetworkServiceType"), CFSTR("kCFStreamNetworkServiceTypeBackground")); } if (readStream && writeStream) { CFReadStreamOpen(readStream); CFWriteStreamOpen(writeStream); SCPrint(TRUE, stdout, CFSTR("Opened stream to %@, port %d%s\n"), hostName, port, background ? ", background traffic class" : ""); sleep(1); } my_CFRelease(&readStream); my_CFRelease(&writeStream); } else { SCPrint(TRUE, stderr, CFSTR("Invalid or missing host name\n")); } my_CFRelease(&hostName); exit(0); }
void SocketStreamHandle::createStreams() { if (m_connectionType == Unknown) chooseProxy(); // If it's still unknown, then we're resolving a PAC file asynchronously. if (m_connectionType == Unknown) return; RetainPtr<CFStringRef> host = m_url.host().createCFString(); // Creating streams to final destination, not to proxy. CFReadStreamRef readStream = 0; CFWriteStreamRef writeStream = 0; CFStreamCreatePairWithSocketToHost(0, host.get(), port(), &readStream, &writeStream); #if PLATFORM(IOS) || (PLATFORM(MAC) && MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) // <rdar://problem/12855587> _kCFStreamSocketSetNoDelay is not exported on Windows CFWriteStreamSetProperty(writeStream, _kCFStreamSocketSetNoDelay, kCFBooleanTrue); #endif m_readStream.adoptCF(readStream); m_writeStream.adoptCF(writeStream); switch (m_connectionType) { case Unknown: ASSERT_NOT_REACHED(); break; case Direct: break; case SOCKSProxy: { // FIXME: SOCKS5 doesn't do challenge-response, should we try to apply credentials from Keychain right away? // But SOCKS5 credentials don't work at the time of this writing anyway, see <rdar://6776698>. const void* proxyKeys[] = { kCFStreamPropertySOCKSProxyHost, kCFStreamPropertySOCKSProxyPort }; const void* proxyValues[] = { m_proxyHost.get(), m_proxyPort.get() }; RetainPtr<CFDictionaryRef> connectDictionary(AdoptCF, CFDictionaryCreate(0, proxyKeys, proxyValues, WTF_ARRAY_LENGTH(proxyKeys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); CFReadStreamSetProperty(m_readStream.get(), kCFStreamPropertySOCKSProxy, connectDictionary.get()); break; } case CONNECTProxy: wkSetCONNECTProxyForStream(m_readStream.get(), m_proxyHost.get(), m_proxyPort.get()); break; } if (shouldUseSSL()) { const void* keys[] = { kCFStreamSSLPeerName, kCFStreamSSLLevel }; const void* values[] = { host.get(), kCFStreamSocketSecurityLevelNegotiatedSSL }; RetainPtr<CFDictionaryRef> settings(AdoptCF, CFDictionaryCreate(0, keys, values, WTF_ARRAY_LENGTH(keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); CFReadStreamSetProperty(m_readStream.get(), kCFStreamPropertySSLSettings, settings.get()); CFWriteStreamSetProperty(m_writeStream.get(), kCFStreamPropertySSLSettings, settings.get()); } }
bool TCPStream_CFNetwork::connect() { state = Stream::State::Opening; CFStringRef host_cfstring = CFStringCreateWithCString(kCFAllocatorDefault, remoteHostName.c_str(), kCFStringEncodingUTF8); CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, host_cfstring, remotePortNumber, &inputStream, &outputStream); CFRelease(host_cfstring); CFStreamClientContext inputStreamContext; memset(&inputStreamContext, 0, sizeof(inputStreamContext)); inputStreamContext.info = reinterpret_cast<void *>(this); CFReadStreamSetClient(inputStream, kCFStreamEventHasBytesAvailable | kCFStreamEventEndEncountered | kCFStreamEventErrorOccurred, inputStreamCallback, &inputStreamContext); CFReadStreamScheduleWithRunLoop(inputStream, CFRunLoopGetMain(), kCFRunLoopDefaultMode); if (CFReadStreamOpen(inputStream) && CFWriteStreamOpen(outputStream)) { state = Stream::State::Open; return true; } else { CFRelease(outputStream); CFRelease(inputStream); outputStream = nullptr; inputStream = nullptr; state = Stream::State::NotOpen; return false; } }
extern MyInfoRef StartWWAN(ConnectClientCallBack clientCB, void *refCon) { char host[] = kTestHost; int portNum = kTestPort; CFDataRef addressData; MyStreamInfoPtr myInfoPtr; CFStreamClientContext ctxt = {0, NULL, NULL, NULL, NULL}; Boolean errorOccurred = FALSE; myInfoPtr = malloc(sizeof(MyStreamInfo)); if (!myInfoPtr) { return NULL; } // init the allocated memory memset(myInfoPtr, 0, sizeof(MyStreamInfo)); myInfoPtr->clientCB = clientCB; myInfoPtr->refCon = refCon; ctxt.info = myInfoPtr; // Check for a dotted-quad address, if so skip any host lookups in_addr_t addr = inet_addr(host); if (addr != INADDR_NONE) { // Create the streams from numberical host struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_len= sizeof(sin); sin.sin_family = AF_INET; sin.sin_addr.s_addr = addr; sin.sin_port = htons(portNum); addressData = CFDataCreate(NULL, (UInt8 *)&sin, sizeof(sin)); CFSocketSignature sig = { AF_INET, SOCK_STREAM, IPPROTO_TCP, addressData }; // Create the streams. CFStreamCreatePairWithPeerSocketSignature(kCFAllocatorDefault, &sig, &(myInfoPtr->rStreamRef), &(myInfoPtr->wStreamRef)); CFRelease(addressData); } else { // Create the streams from ascii host name CFStringRef hostStr = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, host, kCFStringEncodingUTF8, kCFAllocatorNull); CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, hostStr, portNum, &(myInfoPtr->rStreamRef), &(myInfoPtr->wStreamRef)); //hostStr = NULL; if(hostStr) { CFRelease(hostStr); } } myInfoPtr->isConnected = FALSE; myInfoPtr->isStreamInitd = TRUE; myInfoPtr->isClientSet = FALSE; // Inform the streams to kill the socket when it is done with it. // This effects the write stream too since the pair shares the // one socket. CFWriteStreamSetProperty(myInfoPtr->wStreamRef, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue); // set up the client if (!CFWriteStreamSetClient(myInfoPtr->wStreamRef, kCFStreamEventOpenCompleted | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, MyCFWriteStreamClientCallBack, &ctxt)) { printf("CFWriteStreamSetClient failed\n"); errorOccurred = TRUE; } else myInfoPtr->isClientSet = TRUE; if (!errorOccurred) { // schedule the stream CFWriteStreamScheduleWithRunLoop(myInfoPtr->wStreamRef, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); // Try to open the stream. if (!CFWriteStreamOpen(myInfoPtr->wStreamRef)) { printf("CFWriteStreamOpen failed\n"); errorOccurred = TRUE; } } if (!errorOccurred) { // everything worked so far, so run the runloop - when the callback gets called, it will stop the run loop printf("CFWriteStreamOpen returned with no error - calling CFRunLoopRun\n"); CFRunLoopRun(); if (myInfoPtr->errorOccurred) errorOccurred = TRUE; printf("after CFRunLoopRun - returning\n"); } if (errorOccurred) { myInfoPtr->isConnected = FALSE; CleanupAfterWAAN(myInfoPtr); CloseStreams(myInfoPtr); if (myInfoPtr->isStreamInitd) { if(myInfoPtr->rStreamRef) CFRelease(myInfoPtr->rStreamRef); if(myInfoPtr->wStreamRef) CFRelease(myInfoPtr->wStreamRef); myInfoPtr->isStreamInitd = FALSE; } free(myInfoPtr); return NULL; } return (MyInfoRef)myInfoPtr; }
mailstream_low * mailstream_low_cfstream_open_voip_timeout(const char * hostname, int16_t port, int voip_enabled, time_t timeout) { #if HAVE_CFNETWORK mailstream_low * s; struct mailstream_cfstream_data * cfstream_data; CFReadStreamRef readStream; CFWriteStreamRef writeStream; CFStringRef hostString; CFOptionFlags readFlags; CFOptionFlags writeFlags; int r; hostString = CFStringCreateWithCString(NULL, hostname, kCFStringEncodingUTF8); CFStreamCreatePairWithSocketToHost(NULL, hostString, port, &readStream, &writeStream); CFRelease(hostString); #if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR if (voip_enabled) { CFReadStreamSetProperty(readStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP); CFWriteStreamSetProperty(writeStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP); } #endif cfstream_data = cfstream_data_new(readStream, writeStream); s = mailstream_low_new(cfstream_data, mailstream_cfstream_driver); mailstream_low_set_timeout(s, timeout); //fprintf(stderr, "open %s %i -> %p\n", hostname, port, s); /* setup streams */ cfstream_data->streamContext.info = s; readFlags = kCFStreamEventOpenCompleted | kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered; writeFlags = kCFStreamEventOpenCompleted | kCFStreamEventCanAcceptBytes | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered; CFReadStreamSetClient(cfstream_data->readStream, readFlags, readStreamCallback, &cfstream_data->streamContext); CFWriteStreamSetClient(cfstream_data->writeStream, writeFlags, writeStreamCallback, &cfstream_data->streamContext); CFRelease(readStream); CFRelease(writeStream); readStream = NULL; writeStream = NULL; /* setup cancel */ cfstream_data->cancelContext.info = s; cfstream_data->cancelContext.perform = cancelPerform; cfstream_data->cancelSource = CFRunLoopSourceCreate(NULL, 0, &cfstream_data->cancelContext); r = low_open(s); if (r < 0) { mailstream_low_cfstream_close(s); return NULL; } return s; #else return NULL; #endif }