FskErr FskUUIDCreate(FskUUID uuid) { FskTimeRecord time; static UInt32 clockSequence = 0; static FskTimeRecord lastTime; char MAC[6]; FskNetInterfaceRecord *netInterface = NULL; UInt32 numInterfaces; // find a suitable network interface to get the MAC address from numInterfaces = FskNetInterfaceEnumerate(); while (numInterfaces--) { FskNetInterfaceDescribe(numInterfaces, &netInterface); if ((0 == netInterface->MAC[0]) && (0 == netInterface->MAC[1]) && (0 == netInterface->MAC[2]) && (0 == netInterface->MAC[3]) && (0 == netInterface->MAC[4]) && (0 == netInterface->MAC[5])) { FskNetInterfaceDescriptionDispose(netInterface); netInterface = NULL; continue; } break; } if (NULL == netInterface) { // can't fail - clients need a value. make something up. (this happens if all network interfaces are disabled on a phone) int i; for (i = 0; i < 6; i++) MAC[i] = (char)FskRandom(); } else { FskMemMove(MAC, netInterface->MAC, sizeof(netInterface->MAC)); FskNetInterfaceDescriptionDispose(netInterface); } // make sure the clock sequence is good while (0 == clockSequence) clockSequence = FskRandom(); // we need the time, and make sure it is unique. FskTimeGetNow(&time); //@@ should be UTC time time.useconds = (time.useconds >> 4) | (time.seconds << 28); // only uses 60 bits of time time.seconds >>= 4; // only uses 60 bits of time if (FskTimeCompare(&time, &lastTime) <= 0) clockSequence += 1; lastTime = time; // put the pieces together time.useconds = FskEndianU32_NtoB(time.useconds); FskMemCopy(&uuid->value[0], &time.useconds, sizeof(time.useconds)); uuid->value[4] = (UInt8)time.seconds; uuid->value[5] = (UInt8)(time.seconds >> 8); uuid->value[6] = (((UInt8)(time.seconds >> 24)) & 0x0f) | 1; uuid->value[7] = (UInt8)(time.seconds >> 16); uuid->value[8] = ((UInt8)(clockSequence >> 8) & 0x3f) | 0x80; uuid->value[9] = (UInt8)clockSequence; FskMemCopy(&uuid->value[10], MAC, sizeof(MAC)); return kFskErrNone; }
FskErr KprSocketBind(KprSocket self, int port, const char *iface) { FskErr err = kFskErrNone; KprSocketListener listener = NULL; FskNetInterfaceRecord *ifc = NULL; if (self->port != 0) return kFskErrBadState; if (iface) { ifc = FskNetInterfaceFindByName((char *) iface); if (ifc == NULL) return kFskErrNotFound; bailIfError(KprSocketListenerNew(self, ifc->ip, port, &listener)); if (port == 0) { port = KprSocketListenerGetPort(listener); } } else { int i, numI; numI = FskNetInterfaceEnumerate(); for (i = 0; i < numI; i++) { int ip, status; err = FskNetInterfaceDescribe(i, &ifc); if (err) continue; ip = ifc->ip; status = ifc->status; FskNetInterfaceDescriptionDispose(ifc); ifc = NULL; if (status) { bailIfError(KprSocketListenerNew(self, ip, port, &listener)); if (port == 0) { port = KprSocketListenerGetPort(listener); } } } } self->port = port; bail: FskNetInterfaceDescriptionDispose(ifc); if (err) { KprSocketCleanup(self); } return err; }
int httpServerInterfaceChanged(FskNetInterfaceRecord *ifc, UInt32 status, void *param) { FskHTTPServer http = (FskHTTPServer)param; FskNetInterfaceRecord *newIface = NULL; FskErr err; FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "httpServerInterfaceChanged - status: %u\n", (unsigned int)status); if (status == kFskNetInterfaceStatusChanged) { newIface = FskNetInterfaceFindByName(ifc->name); FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "httpServerInterfaceChanged - newIface is: %p\n", newIface); } switch (status) { case kFskNetInterfaceStatusChanged: err = doCallCondition(http->callbacks->serverCondition, http, kFskHTTPConditionInterfaceChanged, ifc->name); if (kFskErrUnimplemented == err || kFskErrNone == err) { FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "httpServerInterfaceChanged - about to call httpServerInterfaceDown - %p: %p\n", http, ifc); httpServerInterfaceDown(http, ifc->name); if (newIface->status == 1) { FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "httpServerInterfaceChanged - about to call httpServerInterfaceUp - %p: %p\n", http, newIface); httpServerInterfaceUp(http, newIface->name); } FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "httpServerInterfaceChanged - done\n"); } break; case kFskNetInterfaceStatusRemoved: FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "httpServerInterfaceChanged - InterfaceRemoved %p: %p\n", http, ifc); err = doCallCondition(http->callbacks->serverCondition, http, kFskHTTPConditionInterfaceRemoved, ifc->name); if (kFskErrUnimplemented == err || kFskErrNone == err) { FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "httpServerInterfaceChanged - about to call httpServerInterfaceDown - %p: %p\n", http, ifc); httpServerInterfaceDown(http, ifc->name); FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "httpServerInterfaceChanged - done\n"); } break; case kFskNetInterfaceStatusNew: FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "httpServerInterfaceChanged - InterfaceNew %p: %p\n", http, ifc); err = doCallCondition(http->callbacks->serverCondition, http, kFskHTTPConditionInterfaceAdded, ifc->name); if (ifc->status == 0) { FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, " -- new interface is down\n"); } else if (kFskErrUnimplemented == err || kFskErrNone == err) { if (http->all) { FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "httpServerInterfaceChanged - about to call httpServerInterfaceUp - %p: %p\n", http, ifc); httpServerInterfaceUp(http, ifc->name); } } break; } FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "httpServerInterfaceChanged - about to call DescriptionDispose\n"); FskNetInterfaceDescriptionDispose(newIface); FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "httpServerInterfaceChanged - Done.\n"); return kFskErrNone; }
// --------------------------------------------------------------------- void doNetIfcCallback(void *a, void *b, void *c, void *d) { FskNetInterfaceChangedCallback callback = (FskNetInterfaceChangedCallback)a; FskNetInterfaceRecord *iface = (FskNetInterfaceRecord *)b; UInt32 status = (UInt32)c; void *param = (void*)d; callback(iface, status, param); FskInstrumentedTypePrintfDebug(&gNetInterfaceNotifierTypeInstrumentation, "doNetIfcCallback - about to dispose description"); FskNetInterfaceDescriptionDispose(iface); FskInstrumentedTypePrintfDebug(&gNetInterfaceNotifierTypeInstrumentation, "doNetIfcCallback - after disposing description"); }
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; }
/* interface is optional. If NULL, then all interfaces will be used */ FskErr FskHTTPServerCreate(int port, char *interfaceName, FskHTTPServer *server, void *refCon, Boolean ssl) { FskHTTPServer http; FskErr err; FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "httpServerCreate\n"); err = FskMemPtrNewClear(sizeof(FskHTTPServerRecord), (FskMemPtr*)&http); BAIL_IF_ERR(err); sFskHTTPServerUpUse(http); http->stopped = true; http->refCon = refCon; http->port = port; http->keepAliveTimeout = kFskHTTPKeepAliveTimeout; http->defaultBufferSize = kFskHTTPServerDefaultBufferSize; http->owner = FskThreadGetCurrent(); http->ssl = ssl; snprintf(http->name, 64, "%s:%d", interfaceName ? interfaceName : "all", port); FskInstrumentedItemNew(http, http->name, &gFskHTTPServerTypeInstrumentation); if (interfaceName) { err = FskHTTPServerListenerAdd(http, port, interfaceName, NULL); } else { FskNetInterfaceRecord *ifc; int i, numI; http->all = true; numI = FskNetInterfaceEnumerate(); for (i=0; i<numI; i++) { FskErr notErr = FskNetInterfaceDescribe(i, &ifc); if (notErr) continue; if (ifc->status) { notErr = FskHTTPServerListenerAdd(http, port, ifc->name, NULL); if (notErr) err = notErr; } FskNetInterfaceDescriptionDispose(ifc); } } http->interfaceNotifier = FskNetInterfaceAddNotifier(httpServerInterfaceChanged, http, "http server"); bail: *server = http; return err; }