// --------------------------------------------------------------------- void sNotifyInterfaceNotifiers(FskNetInterfaceRecord *iface, UInt32 status) { FskNetInterfaceNotifier callback = NULL, next; FskThread thread = FskThreadGetCurrent(); callback = (FskNetInterfaceNotifier)FskListMutexGetNext(interfaceChangeCBList, NULL); while (callback) { next = (FskNetInterfaceNotifier)FskListMutexGetNext(interfaceChangeCBList, callback); #if 0 && SUPPORT_INSTRUMENTATION if (FskInstrumentedItemHasListeners(callback)) { FskNetInterfaceRecord *iface = (FskNetInterfaceRecord *)FskNetInterfaceFindByName(ifcName); FskInterfaceInstrData data; data.notf = callback; data.ifc = iface; data.status = status; FskInstrumentedItemSendMessage(callback, kFskNetInstrMsgInterfaceNotify, &data); } #endif /* SUPPORT_INSTRUMENTATION */ if (callback->thread != thread) { FskNetInterfaceRecord *interFace; if (kFskErrNone == FskMemPtrNewFromData(sizeof(FskNetInterfaceRecord), iface, &interFace)) { interFace->next = NULL; interFace->name = FskStrDoCopy(iface->name); // POST notify FskInstrumentedTypePrintfDebug(&gNetInterfaceNotifierTypeInstrumentation, " - posting callback to thread %s for interface %s", callback->thread->name, iface->name); FskThreadPostCallback(callback->thread, doNetIfcCallback, (void*)callback->callback, (void*)interFace, (void*)status, (void*)callback->param); } } else { FskInstrumentedTypePrintfDebug(&gNetInterfaceNotifierTypeInstrumentation, "callback->thread %s - call", callback->thread->name); (callback->callback)(iface, status, callback->param); } callback = next; } }
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; }
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; }
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; }