static FskErr httpServerListenerAcceptNewConnection(FskThreadDataHandler handler, FskThreadDataSource source, void *refCon) { FskErr err = kFskErrNone; FskHTTPServerListener listener = (FskHTTPServerListener)handler->refCon; FskSocket skt; err = FskNetAcceptConnection((FskSocket)source, &skt, "HTTP Acceptor"); if (err != kFskErrNone) return err; FskNetSocketMakeNonblocking(skt); #if CLOSED_SSL if (listener->http->ssl) { void *ssl; err = FskSSLAttach(&ssl, skt); if (err != kFskErrNone) { FskNetSocketClose(skt); return err; } if (listener->http->certs != NULL) FskSSLLoadCerts(ssl, listener->http->certs); listener->handshaking = true; err = FskSSLHandshake(ssl, sHTTPServerGotSocket, listener, false); if (err != kFskErrNone) { FskSSLDispose(ssl); FskNetSocketClose(skt); return err; } return err; } else #endif return httpServerListenerStart(listener, skt); }
static FskErr KprSocketListenerNew(KprSocket owner, int ip, int port, KprSocketListener *it) { KprSocketListener self = NULL; FskErr err; FskSocket skt = NULL; bailIfError(KprMemPtrNewClear(sizeof(KprSocketListenerRecord), &self)); bailIfError(FskNetSocketNewTCP(&skt, true, "KprSocketListener")); FskNetSocketReuseAddress(skt); FskNetSocketMakeNonblocking(skt); bailIfError(FskNetSocketBind(skt, ip, port)); bailIfError(FskNetSocketGetLocalAddress(skt, NULL, &port)); self->owner = owner; self->ip = ip; self->port = port; self->socket = skt; skt = NULL; FskListAppend(&owner->listeners, self); if (it) *it = self; bail: FskNetSocketClose(skt); if (err) { KprSocketListenerDispose(self); } return err; }
FskErr KprSocketAccept(KprSocket self, KprSocket *it) { FskErr err = kFskErrNone; FskSocket skt = NULL; KprSocket socket = NULL; KprSocketFlags flags = 0; if (self->currentListener == NULL) return kFskErrBadSocket; bailIfError(KprSocketListenerAccept(self->currentListener, &skt)); if (self->secure) flags |= kKprSocketFlagsSecure; bailIfError(KprSocketNewFromFskSocket(skt, flags, &socket)); skt = NULL; socket->server = self; if (self->secure) { bailIfError(KprSocketStartTSL(socket)); } else { if (self->callbacks.accept) { self->callbacks.accept(self, socket, self->refcon); } } *it = socket; socket = NULL; bail: FskNetSocketClose(skt); KprSocketDispose(socket); return err; }
static void KprWebSocketEndpointDisconnect(KprWebSocketEndpoint self) { if (self->socket) { KprSocketReaderDispose(self->reader); self->reader = NULL; KprSocketWriterDispose(self->writer); self->writer = NULL; FskNetSocketClose(self->socket); self->socket = NULL; self->state = kKprWebSocketStateClosed; } if (self->read.headers) { FskHeaderStructDispose(self->read.headers); self->read.headers = NULL; } if (self->read.message) { FskMemPtrDispose(self->read.message); self->read.message = NULL; } CALLBACK(closeCallback)(self, self->closeCode, self->closeReason, self->cleanClose, self->refcon); }
static void KprSocketCleanup(KprSocket self) { FskThreadRemoveDataHandler(&self->handler); KprSocketWriterDispose(self->writer); self->writer = NULL; if (self->socket) { FskNetSocketClose(self->socket); self->socket = NULL; } while (self->listeners) { KprSocketListenerDispose(self->listeners); } self->connected = false; FskMemPtrDispose((char *) self->host); self->host = NULL; self->port = 0; self->mode = kKprSocketModeFinished; FskNetUtilDisposeCertificate(self->certs); FskMemPtrDispose((void *) self->applicationProtocols); self->applicationProtocols = NULL; memset(&self->callbacks, 0, sizeof(KprSocketCallbaks)); }
static FskErr KprMQTTClientOnConnect(FskSocket skt, void *refCon) { FskErr err = kFskErrNone; KprMQTTClient self = refCon; if (!skt || 0 == skt->ipaddrRemote) { bailIfError(kFskErrSocketNotConnected); } if (self->cancelConnection) { FskNetSocketClose(skt); KprMQTTClientForceClose(self); return kFskErrNone; } bailIfError(KprMQTTEndpointNew(&self->endpoint, skt, self)); self->endpoint->messageCallback = KprMQTTClientHandleMessage; self->endpoint->errorCallback = KprMQTTClient_onEndpointError; self->state = kKprMQTTStateHandshaking; bailIfError(KprMQTTClientSendMessage(self, &self->connectMessage)); bail: if (err) { CALLBACK(errorCallback)(self, err, "connection failed", self->refcon); KprMQTTClientForceClose(self); } return err; }
static FskErr KprWebSocketServerRequestNew(KprWebSocketServerRequest *it, KprWebSocketServer server, FskSocket skt) { FskErr err = kFskErrNone; KprWebSocketServerRequest request = NULL; bailIfError(FskMemPtrNewClear(sizeof(KprWebSocketServerRequestRecord), &request)); request->server = server; request->skt = skt; skt = NULL; FskNetSocketGetRemoteAddress(request->skt, (UInt32 *)&request->requesterAddress, &request->requesterPort); FskNetSocketMakeNonblocking(request->skt); bailIfError(FskHeaderStructNew(&request->requestHeaders)); bailIfError(FskHeaderStructNew(&request->responseHeaders)); request->out.size = 512; bailIfError(FskMemPtrNew(request->out.size, &request->out.buffer)); FskThreadAddDataHandler(&request->dataHandler, (FskThreadDataSource)request->skt, (FskThreadDataReadyCallback)KprWebSocketServerRequestDoRead, true, false, request); // request->state = kHTTPNewSession; *it = request; bail: if (err) { KprWebSocketServerRequestDispose(request); FskNetSocketClose(skt); } return err; }
static FskErr KprWebSocketServerHandleRequest(KprWebSocketServerRequest request) { FskErr err = kFskErrNone; int statusCode = 101; Boolean doUpgrade = false; statusCode = KprWebSocketServerValidateRequest(request->requestHeaders, request->responseHeaders); doUpgrade = (statusCode == 101); if (doUpgrade) { KprWebSocketServerGenerateUpgradeResponse(request); } else { KprWebSocketServerGenerateErrorResponse(request, statusCode); } bailIfError(KprWebSocketServerSendResponseHeader(request)); if (doUpgrade) { KprWebSocketServer self = request->server; FskSocket skt = request->skt; FskThreadRemoveDataHandler(&request->dataHandler); request->skt = NULL; if (self->connectCallback) { self->connectCallback(self, skt, request->interfaceName, request->ip, self->refCon); } else { FskNetSocketClose(skt); } } bail: return err; }
static FskErr KprSocketOnConnect(FskSocket skt, void *refcon) { FskErr err = kFskErrNone; KprSocket self = (KprSocket) refcon; if (!skt || 0 == skt->ipaddrRemote) { bailIfError(kFskErrNameLookupFailed); } bailIfError(skt->lastErr); if (self->cancelled) { FskNetSocketClose(skt); if (self->callbacks.connectCancelled) { self->callbacks.connectCancelled(self, self->refcon); } KprSocketCleanup(self); return kFskErrNone; } bailIfError(KprSocketWriterNew(&self->writer, skt, self)); self->writer->errorCallback = KprSocketOnWriteError; self->socket = skt; skt = NULL; self->connected = true; KprSocketSetupDataReader(self); if (!(self->server && self->secure) && self->callbacks.connect) { self->callbacks.connect(self, self->refcon); } bail: FskNetSocketClose(skt); if (err) { if (self->callbacks.error) { self->callbacks.error(self, err, self->refcon); } KprSocketCleanup(self); } return err; }
void fxDisconnect(txMachine* the) { if (0 == the->connection) return; FskNetSocketClose((FskSocket)the->connection); the->connection = 0; }
void fxDisconnect(txMachine* the) { if (0 == the->connection) return; fxRemoveReadableCallback(the); FskNetSocketClose((FskSocket)the->connection); the->connection = mxNoSocket; }
void sFskHTTPServerRequestDispose(FskHTTPServerRequest request) { FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "sFskHTTPServerRequestDispose %p - useCount: %d\n", request, request ? request->useCount : 0); if (!request) return; FskInstrumentedItemDispose(request); FskNetSocketClose(request->skt); FskHeaderStructDispose(request->requestHeaders); FskHeaderStructDispose(request->responseHeaders); FskMemPtrDispose(request->in.buf); FskMemPtrDispose(request->out.buf); FskMemPtrDispose(request); }
static void KprWebSocketServerRequestDispose(KprWebSocketServerRequest request) { if (request) { FskListRemove((FskList*)&request->server->activeRequests, request); FskThreadRemoveDataHandler(&request->dataHandler); FskNetSocketClose(request->skt); FskHeaderStructDispose(request->requestHeaders); FskHeaderStructDispose(request->responseHeaders); FskStrParsedUrlDispose(request->parts); FskMemPtrDispose(request->out.buffer); FskMemPtrDispose(request); } }
static FskErr httpServerListenerStart(FskHTTPServerListener listener, FskSocket skt) { FskErr err = kFskErrNone; FskHTTPServerRequest request; if (listener->http->stopped) { FskInstrumentedItemSendMessage(listener->http, kFskHTTPInstrMsgConnectionRefusedStopped, listener); listener->http->stats.connectionsRefused++; FskNetSocketClose(skt); goto bail; } err = FskMemPtrNewClear(sizeof(FskHTTPServerRequestRecord), (FskMemPtr*)&request); BAIL_IF_ERR(err); sFskHTTPServerRequestUpUse(request); request->http = listener->http; request->skt = skt; FskNetSocketGetRemoteAddress(skt, (UInt32 *)&request->requesterAddress, &request->requesterPort); FskNetSocketMakeNonblocking(request->skt); err = FskHeaderStructNew(&request->requestHeaders); BAIL_IF_ERR(err); err = FskHeaderStructNew(&request->responseHeaders); BAIL_IF_ERR(err); request->in.bufferSize = request->http->defaultBufferSize; request->out.bufferSize = request->http->defaultBufferSize; err = FskMemPtrNew(request->in.bufferSize, (FskMemPtr*)&request->in.buf); BAIL_IF_ERR(err); err = FskMemPtrNew(request->out.bufferSize, (FskMemPtr*)&request->out.buf); BAIL_IF_ERR(err); FskListAppend((FskList*)&request->http->activeRequests, request); FskTimeCallbackNew(&request->cycleCallback); FskTimeCallbackNew(&request->keepAliveKillCallback); listener->http->stats.connectionsMade++; request->state = kHTTPNewSession; FskInstrumentedItemNew(request, NULL, &gFskHTTPServerRequestTypeInstrumentation); FskInstrumentedItemSetOwner(request, request->http); FskTimeCallbackScheduleNextRun(request->cycleCallback, httpServerTimeCycle, request); doCallCondition(request->http->callbacks->requestCondition, request, kFskHTTPConditionConnectionInitialized, request->refCon); FskTimeCallbackNew(&request->timer); FskTimeCallbackScheduleFuture(request->timer, 1, 0, KprHTTPServerTimerCallback, request); bail: if (err) FskHTTPServerRequestDispose(request); return err; }
static FskErr sHTTPServerGotSocket(struct FskSocketRecord *skt, void *refCon) { FskHTTPServerListener listener = (FskHTTPServerListener)refCon; listener->handshaking = false; FskErr err = skt != NULL ? FskNetSocketGetLastError(skt) : kFskErrOperationFailed; if (listener->http && err == kFskErrNone) return httpServerListenerStart(listener, skt); else { if (skt != NULL) FskNetSocketClose(skt); if (err != kFskErrSSLHandshakeFailed) FskHTTPServerListenerDispose(listener); return err; } }
static FskErr KprSocketListenerDispose(KprSocketListener self) { if (self) { FskThreadRemoveDataHandler(&self->dataHandler); FskNetSocketClose(self->socket); if (self->owner) { FskListRemove(&self->owner->listeners, self); } KprMemPtrDispose(self); } return kFskErrNone; }
static FskErr KprWebSocketServerAcceptNewConnection(KprSocketServer server, FskSocket skt, const char *interfaceName, void *refcon) { KprWebSocketServer self = refcon; FskErr err = kFskErrNone; KprWebSocketServerRequest request; if (self->stopped) { FskNetSocketClose(skt); goto bail; } bailIfError(KprWebSocketServerRequestNew(&request, self, skt)); FskListAppend((FskList*)&self->activeRequests, request); bail: return err; }
FskHTTPServerListener FskHTTPServerListenerNew(FskHTTPServer http, int port, char *interfaceName) { FskHTTPServerListener listener; FskErr err; FskSocket skt; FskNetInterfaceRecord *ifc = NULL; FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "httpServerListenerNew - interfaceName: %s\n", interfaceName); err = FskMemPtrNewClear(sizeof(FskHTTPServerListenerRecord), (FskMemPtr*)&listener); BAIL_IF_ERR(err); listener->http = http; listener->port = port; listener->ifcName = FskStrDoCopy(interfaceName); err = FskNetSocketNewTCP(&skt, true, "HTTP Server"); if (err) { FskInstrumentedItemSendMessage(listener->http, kFskHTTPInstrMsgErrString, "listener socket create failed."); FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "httpServerListenerNew - creating socket failed: %d\n", err); BAIL(kFskErrNoMoreSockets); } FskNetSocketReuseAddress(skt); ifc = FskNetInterfaceFindByName(listener->ifcName); if ((NULL == ifc) || (kFskErrNone != (err = FskNetSocketBind(skt, ifc->ip, listener->port)))) { FskNetSocketClose(skt); FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "httpServerListenerNew - bind failed: %d port: %d\n", err, listener->port); listener->http->stats.connectionsAborted++; if (listener->http->callbacks) err = doCallCondition(listener->http->callbacks->serverCondition, listener->http, kFskHTTPConditionNoSocket, listener->http->refCon); goto bail; } listener->skt = skt; FskNetSocketMakeNonblocking(skt); FskListAppend((FskList*)&listener->http->listeners, listener); FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "httpServerListenerNew - about to listen\n"); FskNetSocketListen(skt); FskThreadAddDataHandler(&listener->dataHandler, (FskThreadDataSource)skt, (FskThreadDataReadyCallback)httpServerListenerAcceptNewConnection, true, false, listener); FskInstrumentedItemSendMessage(listener->http, kFskHTTPInstrMsgNowListening, listener); bail: FskNetInterfaceDescriptionDispose(ifc); if (err) { FskInstrumentedItemSendMessage(listener->http, kFskHTTPInstrMsgFailedListener, listener); FskMemPtrDisposeAt((void**)&listener); } return listener; }
FskErr FskHTTPServerListenerDispose(FskHTTPServerListener listener) { FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "httpServerListenerDispose - listener: %p\n", listener); if (listener) { if (listener->http && listener->http->listeners) FskListRemove((FskList*)&listener->http->listeners, listener); if (listener->handshaking) { FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "httpServerListenerDispose - listener: %p - wait for handshaking\n", listener); listener->http = NULL; } else { FskThreadRemoveDataHandler(&listener->dataHandler); FskNetSocketClose(listener->skt); FskMemPtrDispose(listener->ifcName); FskMemPtrDispose(listener); } } return kFskErrNone; }
void KprDebugMachineDispose(KprDebugMachine self) { if (self) { KprDebug debug = self->debug; xsBeginHostSandboxCode(debug->the, debug->code); xsVars(1); KprDebugMachineCallbackText(self, "onMachineUnregistered", mxNoCommand, NULL); xsEndHostSandboxCode(); FskListRemove(&self->debug->machine, self); KprSocketWriterDispose(self->writer); self->writer = NULL; FskThreadRemoveDataHandler(&self->reader); FskNetSocketClose(self->socket); self->socket = NULL; FskMemPtrDisposeAt(&self->title); FskInstrumentedItemDispose(self); FskMemPtrDispose(self); } }
FskErr KprCoAPClientDispose(KprCoAPClient self) { FskErr err = kFskErrNone; if (self) { KprCoAPClientResolver resolver; KprCoAPClientRequest request; KprCoAPEndpoint endpoint; resolver = self->resolvers; while (resolver) { KprCoAPClientResolver next = resolver->next; KprCoAPClientResolverDispose(resolver); resolver = next; } request = self->requests; while (request) { KprCoAPClientRequest next = request->next; KprCoAPClientRequestDispose(request); request = next; } endpoint = self->endpoints; while (endpoint) { KprCoAPEndpoint next = endpoint->next; KprCoAPEndpointDispose(endpoint); endpoint = next; } KprMemoryBlockDispose(self->recycleTokens); KprCoAPReceiverDispose(self->receiver); FskNetSocketClose(self->socket); KprMemPtrDispose(self); FskDebugStr("CoAP Client disposed: %p", self); } return err; }
FskErr KprCoAPClientNew(KprCoAPClient *it, KprCoAPClientCallbacks *callbacks, void *refcon) { FskErr err = kFskErrNone; KprCoAPClient self = NULL; FskSocket socket = NULL; KprCoAPReceiver receiver = NULL; KprCoAPReceiverCallbacks receiverCallback = { KprCoAPClient_receiveCallback, KprCoAPClient_errorCallback, }; bailIfError(KprMemPtrNewClear(sizeof(KprCoAPClientRecord), &self)); bailIfError(FskNetSocketNewUDP(&socket, "KprCoAPClient")); bailIfError(FskNetSocketBind(socket, -1, 0)); bailIfError(KprCoAPReceiverNew(&receiver, socket, &receiverCallback, self)); self->socket = socket; self->receiver = receiver; self->messageId = FskRandom(); self->autoToken = false; self->nextTokenBytes = 1; self->callbacks = *callbacks; self->refcon = refcon; *it = self; FskDebugStr("CoAP Client created: %p", self); bail: if (err) { FskNetSocketClose(socket); KprCoAPReceiverDispose(receiver); KprCoAPClientDispose(self); } return err; }
static void fxDoConnect(txMachine *the) { if (!FskStrLen(debugAddress)) { char *address = FskEnvironmentGet("debugger"); if (address) FskStrCopy(debugAddress, address); #if TARGET_OS_WIN32 || (TARGET_OS_MAC && !TARGET_OS_IPHONE) else FskStrCopy(debugAddress, "localhost"); #endif } if (FskStrLen(debugAddress) && !debugAddressFailed) { FskErr err; char host[64]; char* colon; int port; FskTimeRecord expireTime, now; SInt32 waitMS; colon = FskStrNCopyUntil(host, debugAddress, 63, ':'); if (*colon) port = FskStrToNum(colon); else port = 5002; #if TARGET_OS_MAC waitMS = 0; #else waitMS = -1; #endif // Connect to the host asynchronously err = FskNetConnectToHostPrioritized(host, port, false, fxConnectComplete, the, 0, 0, NULL, "fxConnect"); if (err) goto bail; // Allow two seconds for the connection to resolve and for the socket to become readable and writable FskTimeGetNow(&expireTime); FskTimeAddSecs(&expireTime, 2); while (!the->connection) { FskTimeGetNow(&now); if (FskTimeCompare(&expireTime, &now) > 0) goto bail; FskThreadRunloopCycle(waitMS); } while (!FskNetSocketIsReadable((FskSocket)the->connection) && !FskNetSocketIsWritable((FskSocket)the->connection)) { FskTimeGetNow(&now); if (FskTimeCompare(&expireTime, &now) > 0) goto bail; FskThreadRunloopCycle(waitMS); } // Make the socket blocking FskNetSocketMakeBlocking((FskSocket)the->connection); return; bail: if (the->connection) { FskNetSocketClose((FskSocket)the->connection); the->connection = 0; } debugAddressFailed = true; } }
void fxConnect(txMachine* the) { if (!FskStrLen(debugAddress)) { char *address = FskEnvironmentGet("debugger"); if (address) FskStrCopy(debugAddress, address); #if TARGET_OS_WIN32 || (TARGET_OS_MAC && !TARGET_OS_IPHONE) else FskStrCopy(debugAddress, "localhost"); #endif } if (FskStrLen(debugAddress)) { FskErr err = kFskErrNone; char host[64]; char* colon; int port; UInt32 addr; struct sockaddr_in sockaddr; FskSocket skt = NULL; int flag; colon = FskStrNCopyUntil(host, debugAddress, 63, ':'); if (*colon) port = FskStrToNum(colon); else port = 5002; err = FskNetHostnameResolveQT(host, 0, &addr, NULL); if (err) goto bail; FskMemSet(&sockaddr, 0, sizeof(sockaddr)); sockaddr.sin_family = AF_INET; sockaddr.sin_port = htons(port); sockaddr.sin_addr.s_addr = htonl(addr); err = FskNetSocketNewTCPPrioritized(&skt, false, 0, "fxConnect"); if (err) goto bail; #if TARGET_OS_WIN32 flag = 1; if (ioctlsocket(skt->platSkt, FIONBIO, &flag)) goto bail; #else flag = fcntl(skt->platSkt, F_GETFL, 0); if (fcntl(skt->platSkt, F_SETFL, flag | O_NONBLOCK) < 0) goto bail; #endif if (connect(skt->platSkt, (struct sockaddr*)(void*)&sockaddr, sizeof(sockaddr)) < 0) { struct timeval aTimeout = { 10, 0 }; // 10 seconds, 0 micro-seconds fd_set aReadSet; fd_set aWriteSet; #if TARGET_OS_WIN32 fd_set aexceptSet; if (WSAGetLastError() != WSAEWOULDBLOCK) goto bail; #else if (errno != EINPROGRESS) goto bail; #endif FD_ZERO(&aReadSet); FD_SET(skt->platSkt, &aReadSet); aWriteSet = aReadSet; #if TARGET_OS_WIN32 // See: http://msdn.microsoft.com/en-us/library/windows/desktop/ms740141(v=vs.85).aspx aexceptSet = aReadSet; if (select(skt->platSkt + 1, &aReadSet, &aWriteSet, &aexceptSet, &aTimeout) <= 0) goto bail; if (!(FD_ISSET(skt->platSkt, &aReadSet)) && !(FD_ISSET(skt->platSkt, &aWriteSet)) && !(FD_ISSET(skt->platSkt, &aexceptSet))) goto bail; #else if (select(skt->platSkt + 1, &aReadSet, &aWriteSet, NULL, &aTimeout) <= 0) goto bail; if (!(FD_ISSET(skt->platSkt, &aReadSet)) && !(FD_ISSET(skt->platSkt, &aWriteSet))) goto bail; #endif } #if TARGET_OS_WIN32 flag = 0; if (ioctlsocket(skt->platSkt, FIONBIO, &flag)) goto bail; #else if (fcntl(skt->platSkt, F_SETFL, flag) < 0) goto bail; #endif the->connection = (txSocket)skt; fxAddReadableCallback(the); return; bail: FskNetSocketClose(skt); debugAddressFailed = true; } }