#include <SystemConfiguration/SCDynamicStoreCopyDHCPInfo.h>
#include <err.h>
#include <sysexits.h>
-#include <dlfcn.h>
+
+#ifdef UNIT_TEST
+#include "unittest.h"
+#endif
#include "uDNS.h"
#include "DNSCommon.h"
#include "xpc_services.h" // Interface to XPC services
#include "helper.h"
-#if TARGET_OS_EMBEDDED
+#if AWD_METRICS
#include "Metrics.h"
#endif
#define kPreferencesKey_StrictUnicastOrdering CFSTR("StrictUnicastOrdering")
#define kPreferencesKey_OfferSleepProxyService CFSTR("OfferSleepProxyService")
#define kPreferencesKey_UseInternalSleepProxy CFSTR("UseInternalSleepProxy")
+
+#if ENABLE_BLE_TRIGGERED_BONJOUR
#define kPreferencesKey_EnableBLEBasedDiscovery CFSTR("EnableBLEBasedDiscovery")
+#define kPreferencesKey_DefaultToBLETriggered CFSTR("DefaultToBLETriggered")
+#endif // ENABLE_BLE_TRIGGERED_BONJOUR
+
+#if TARGET_OS_IPHONE
+#define kPreferencesKey_PreallocateCacheMemory CFSTR("PreallocateCacheMemory")
+#endif
#endif
//*************************************************************************************************************
// Start off with a default cache of 32K (141 records of 232 bytes each)
// Each time we grow the cache we add another 141 records
-// 141 * 164 = 32712 bytes.
+// 141 * 232 = 32712 bytes.
// This fits in eight 4kB pages, with 56 bytes spare for memory block headers and similar overhead
#define RR_CACHE_SIZE ((32*1024) / sizeof(CacheRecord))
static CacheEntity rrcachestorage[RR_CACHE_SIZE];
struct CompileTimeAssertionChecks_RR_CACHE_SIZE { char a[(RR_CACHE_SIZE >= 141) ? 1 : -1]; };
+#define kRRCacheGrowSize (sizeof(CacheEntity) * RR_CACHE_SIZE)
#ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
extern mDNSBool StrictUnicastOrdering;
extern mDNSBool AlwaysAppendSearchDomains;
+
+#if ENABLE_BLE_TRIGGERED_BONJOUR
extern mDNSBool EnableBLEBasedDiscovery;
+extern mDNSBool DefaultToBLETriggered;
+#endif // ENABLE_BLE_TRIGGERED_BONJOUR
+
+#if TARGET_OS_IPHONE
+static mDNSBool PreallocateCacheMemory = mDNSfalse;
+#define kRRCacheMemoryLimit 1000000 // For now, we limit the cache to at most 1MB on iOS devices.
+#endif
// We keep a list of client-supplied event sources in KQSocketEventSource records
typedef struct KQSocketEventSource
struct KQSocketEventSource *next;
int fd;
KQueueEntry kqs;
+ udsEventCallback callback;
+ void *context;
} KQSocketEventSource;
static KQSocketEventSource *gEventSources;
//*************************************************************************************************************
// Registration
-mDNSexport void RecordUpdatedNiceLabel(mDNS *const m, mDNSs32 delay)
+mDNSexport void RecordUpdatedNiceLabel(mDNSs32 delay)
{
- m->p->NotifyUser = NonZeroTime(m->timenow + delay);
+ mDNSStorage.p->NotifyUser = NonZeroTime(mDNSStorage.timenow + delay);
}
-mDNSlocal void mDNSPreferencesSetNames(mDNS *const m, int key, domainlabel *old, domainlabel *new)
+mDNSlocal void mDNSPreferencesSetNames(int key, domainlabel *old, domainlabel *new)
{
+ mDNS *const m = &mDNSStorage;
domainlabel *prevold, *prevnew;
switch (key)
{
mDNSlocal void mDNS_StatusCallback(mDNS *const m, mStatus result)
{
- (void)m; // Unused
if (result == mStatus_NoError)
{
if (!SameDomainLabelCS(m->p->userhostlabel.c, m->hostlabel.c))
LogInfo("Local Hostname changed from \"%#s.local\" to \"%#s.local\"", m->p->userhostlabel.c, m->hostlabel.c);
// One second pause in case we get a Computer Name update too -- don't want to alert the user twice
- RecordUpdatedNiceLabel(m, mDNSPlatformOneSecond);
+ RecordUpdatedNiceLabel(mDNSPlatformOneSecond);
}
else if (result == mStatus_NameConflict)
{
else if (m->timenow - m->p->HostNameConflict > 60 * mDNSPlatformOneSecond)
{
// Tell the helper we've given up
- mDNSPreferencesSetNames(m, kmDNSLocalHostName, &m->p->userhostlabel, NULL);
+ mDNSPreferencesSetNames(kmDNSLocalHostName, &m->p->userhostlabel, NULL);
}
}
else if (result == mStatus_GrowCache)
// Allocate another chunk of cache storage
static unsigned int allocated = 0;
#if TARGET_OS_IPHONE
- if (allocated >= 1000000) return; // For now we limit the cache to at most 1MB on iOS devices
+ if (allocated >= kRRCacheMemoryLimit) return; // For now we limit the cache to at most 1MB on iOS devices
#endif
- allocated += sizeof(CacheEntity) * RR_CACHE_SIZE;
+ allocated += kRRCacheGrowSize;
// LogMsg("GrowCache %d * %d = %d; total so far %6u", sizeof(CacheEntity), RR_CACHE_SIZE, sizeof(CacheEntity) * RR_CACHE_SIZE, allocated);
CacheEntity *storage = mallocL("mStatus_GrowCache", sizeof(CacheEntity) * RR_CACHE_SIZE);
//LogInfo("GrowCache %d * %d = %d", sizeof(CacheEntity), RR_CACHE_SIZE, sizeof(CacheEntity) * RR_CACHE_SIZE);
else if (result == mStatus_ConfigChanged)
{
// Tell the helper we've seen a change in the labels. It will dismiss the name conflict alert if needed.
- mDNSPreferencesSetNames(m, kmDNSComputerName, &m->p->usernicelabel, &m->nicelabel);
- mDNSPreferencesSetNames(m, kmDNSLocalHostName, &m->p->userhostlabel, &m->hostlabel);
+ mDNSPreferencesSetNames(kmDNSComputerName, &m->p->usernicelabel, &m->nicelabel);
+ mDNSPreferencesSetNames(kmDNSLocalHostName, &m->p->userhostlabel, &m->hostlabel);
// Then we call into the UDS daemon code, to let it do the same
udsserver_handle_configchange(m);
LogMsg("---- BEGIN STATE LOG ---- %s %s %d", mDNSResponderVersionString, OSXVers ? "OSXVers" : "iOSVers", OSXVers ? OSXVers : iOSVers);
- udsserver_info(&mDNSStorage);
+ udsserver_info();
LogMsgNoIdent("----- Platform Timers -----");
LogTimer("m->NextCacheCheck ", mDNSStorage.NextCacheCheck);
if (!mDNSStorage.p->InterfaceList) LogMsgNoIdent("<None>");
else
{
+ LogMsgNoIdent(" Struct addr Registered MAC BSSID Interface Address");
for (i = mDNSStorage.p->InterfaceList; i; i = i->next)
{
// Allow six characters for interface name, for names like "vmnet8"
if (!i->Exists)
- LogMsgNoIdent("%p %2ld, Registered %p, %s %-6s(%lu) %.6a %.6a %#-14a dormant for %d seconds",
+ LogMsgNoIdent("%p %2ld, %p, %s %-6s %.6a %.6a %#-14a dormant for %d seconds",
i, i->ifinfo.InterfaceID, i->Registered,
- i->sa_family == AF_INET ? "v4" : i->sa_family == AF_INET6 ? "v6" : "??", i->ifinfo.ifname, i->scope_id, &i->ifinfo.MAC, &i->BSSID,
+ i->sa_family == AF_INET ? "v4" : i->sa_family == AF_INET6 ? "v6" : "??", i->ifinfo.ifname, &i->ifinfo.MAC, &i->BSSID,
&i->ifinfo.ip, utc - i->LastSeen);
else
{
const CacheRecord *sps[3];
FindSPSInCache(&mDNSStorage, &i->ifinfo.NetWakeBrowse, sps);
- LogMsgNoIdent("%p %2ld, Registered %p, %s %-6s(%lu) %.6a %.6a %s %s %-15.4a %s %s %s %s %#a",
+ LogMsgNoIdent("%p %2ld, %p, %s %-6s %.6a %.6a %s %s %s %s %s %s %#a",
i, i->ifinfo.InterfaceID, i->Registered,
- i->sa_family == AF_INET ? "v4" : i->sa_family == AF_INET6 ? "v6" : "??", i->ifinfo.ifname, i->scope_id, &i->ifinfo.MAC, &i->BSSID,
+ i->sa_family == AF_INET ? "v4" : i->sa_family == AF_INET6 ? "v6" : "??", i->ifinfo.ifname, &i->ifinfo.MAC, &i->BSSID,
i->ifinfo.InterfaceActive ? "Active" : " ",
i->ifinfo.IPv4Available ? "v4" : " ",
- i->ifinfo.IPv4Available ? (mDNSv4Addr*)&i->ifa_v4addr : &zerov4Addr,
i->ifinfo.IPv6Available ? "v6" : " ",
i->ifinfo.Advertise ? "A" : " ",
i->ifinfo.McastTxRx ? "M" : " ",
!(i->ifinfo.InterfaceActive && i->ifinfo.NetWake) ? " " : !sps[0] ? "p" : "P",
&i->ifinfo.ip);
- if (sps[0]) LogMsgNoIdent(" %13d %#s", SPSMetric(sps[0]->resrec.rdata->u.name.c), sps[0]->resrec.rdata->u.name.c);
- if (sps[1]) LogMsgNoIdent(" %13d %#s", SPSMetric(sps[1]->resrec.rdata->u.name.c), sps[1]->resrec.rdata->u.name.c);
- if (sps[2]) LogMsgNoIdent(" %13d %#s", SPSMetric(sps[2]->resrec.rdata->u.name.c), sps[2]->resrec.rdata->u.name.c);
+ // Only print the discovered sleep proxies once for the lead/active interface of an interface set.
+ if (i == i->Registered && (sps[0] || sps[1] || sps[2]))
+ {
+ LogMsgNoIdent(" Sleep Proxy Metric Name");
+ if (sps[0]) LogMsgNoIdent(" %13d %#s", SPSMetric(sps[0]->resrec.rdata->u.name.c), sps[0]->resrec.rdata->u.name.c);
+ if (sps[1]) LogMsgNoIdent(" %13d %#s", SPSMetric(sps[1]->resrec.rdata->u.name.c), sps[1]->resrec.rdata->u.name.c);
+ if (sps[2]) LogMsgNoIdent(" %13d %#s", SPSMetric(sps[2]->resrec.rdata->u.name.c), sps[2]->resrec.rdata->u.name.c);
+ }
}
}
}
{
for (s = mDNSStorage.DNSServers; s; s = s->next)
{
- NetworkInterfaceInfoOSX *ifx = IfindexToInterfaceInfoOSX(&mDNSStorage, s->interface);
- LogMsgNoIdent("DNS Server %##s %s%s%#a:%d %d %s %d %d %s %s %s %s",
+ NetworkInterfaceInfoOSX *ifx = IfindexToInterfaceInfoOSX(s->interface);
+ LogMsgNoIdent("DNS Server %##s %s%s%#a:%d %d %s %d %d %s %s %s %s %s",
s->domain.c, ifx ? ifx->ifinfo.ifname : "", ifx ? " " : "", &s->addr, mDNSVal16(s->port),
s->penaltyTime ? s->penaltyTime - mDNS_TimeNow(&mDNSStorage) : 0, DNSScopeToString(s->scoped),
s->timeout, s->resGroupID,
s->req_A ? "v4" : "!v4",
s->req_AAAA ? "v6" : "!v6",
s->cellIntf ? "cell" : "!cell",
+ s->isExpensive ? "exp" : "!exp",
s->DNSSECAware ? "DNSSECAware" : "!DNSSECAware");
}
}
LogMsgNoIdent("%##s", mDNSStorage.FQDN.c);
}
-#if TARGET_OS_EMBEDDED
+#if AWD_METRICS
LogMetrics();
#endif
LogMsgNoIdent("Timenow 0x%08lX (%d)", (mDNSu32)now, now);
mDNS *const m = &mDNSStorage;
// We're running on the CFRunLoop (Mach port) thread, not the kqueue thread, so we need to grab the KQueueLock before proceeding
- KQueueLock(m);
+ KQueueLock();
switch(msg_header->msgh_id)
{
case SIGHUP: {
break;
case SIGPROF: mDNS_McastLoggingEnabled = mDNS_McastLoggingEnabled ? mDNSfalse : mDNStrue;
LogMsg("SIGPROF: Multicast Logging %s", mDNS_McastLoggingEnabled ? "Enabled" : "Disabled");
- LogMcastStateInfo(m, mDNSfalse, mDNStrue, mDNStrue);
+ LogMcastStateInfo(mDNSfalse, mDNStrue, mDNStrue);
mDNS_McastTracingEnabled = (mDNS_PacketLoggingEnabled && mDNS_McastLoggingEnabled) ? mDNStrue : mDNSfalse;
LogMsg("SIGPROF: Multicast Tracing is %s", mDNS_McastTracingEnabled ? "Enabled" : "Disabled");
UpdateDebugState();
default: LogMsg("SignalCallback: Unknown signal %d", msg_header->msgh_id); break;
}
- KQueueUnlock(m, "Unix Signal");
+ KQueueUnlock("Unix Signal");
}
// MachServerName is com.apple.mDNSResponder (Supported only till 10.9.x)
return(err);
}
+#if TARGET_OS_IPHONE
+ if (PreallocateCacheMemory)
+ {
+ const int growCount = (kRRCacheMemoryLimit + kRRCacheGrowSize - 1) / kRRCacheGrowSize;
+ int i;
+
+ for (i = 0; i < growCount; ++i)
+ {
+ mDNS_StatusCallback(&mDNSStorage, mStatus_GrowCache);
+ }
+ }
+#endif
+
CFMachPortRef i_port = CFMachPortCreate(NULL, SignalCallback, NULL, NULL);
CFRunLoopSourceRef i_rls = CFMachPortCreateRunLoopSource(NULL, i_port, 0);
signal_port = CFMachPortGetPort(i_port);
{
int sig = (int)dispatch_source_get_handle(source);
mDNS *const m = &mDNSStorage;
- KQueueLock(m);
+ KQueueLock();
switch(sig)
{
case SIGHUP: {
break;
default: LogMsg("SignalCallback: Unknown signal %d", sig); break;
}
- KQueueUnlock(m, "Unix Signal");
+ KQueueUnlock("Unix Signal");
}
mDNSlocal void mDNSSetupSignal(dispatch_queue_t queue, int sig)
// mDNS_Execute() generates packets, including multicasts that are looped back to ourself.
// If we call mDNS_Execute() first, and generate packets, and then call mDNSMacOSXNetworkChanged() immediately afterwards
// we then systematically lose our own looped-back packets.
- if (m->NetworkChanged && now - m->NetworkChanged >= 0) mDNSMacOSXNetworkChanged(m);
+ if (m->NetworkChanged && now - m->NetworkChanged >= 0) mDNSMacOSXNetworkChanged();
if (m->p->RequestReSleep && now - m->p->RequestReSleep >= 0)
{
if (!SameDomainLabelCS(m->p->usernicelabel.c, m->nicelabel.c))
{
LogMsg("Name Conflict: Updated Computer Name from \"%#s\" to \"%#s\"", m->p->usernicelabel.c, m->nicelabel.c);
- mDNSPreferencesSetNames(m, kmDNSComputerName, &m->p->usernicelabel, &m->nicelabel);
+ mDNSPreferencesSetNames(kmDNSComputerName, &m->p->usernicelabel, &m->nicelabel);
m->p->usernicelabel = m->nicelabel;
}
if (!SameDomainLabelCS(m->p->userhostlabel.c, m->hostlabel.c))
{
LogMsg("Name Conflict: Updated Local Hostname from \"%#s.local\" to \"%#s.local\"", m->p->userhostlabel.c, m->hostlabel.c);
- mDNSPreferencesSetNames(m, kmDNSLocalHostName, &m->p->userhostlabel, &m->hostlabel);
+ mDNSPreferencesSetNames(kmDNSLocalHostName, &m->p->userhostlabel, &m->hostlabel);
m->p->HostNameConflict = 0; // Clear our indicator, now name change has been successful
m->p->userhostlabel = m->hostlabel;
}
// Scheduling our wakeup for halfway in between -- 90 minutes -- avoids short wakeups while still
// allowing us an adequate safety margin to renew our lease before we lose it.
-mDNSlocal mDNSBool AllowSleepNow(mDNS *const m, mDNSs32 now)
+mDNSlocal mDNSBool AllowSleepNow(mDNSs32 now)
{
+ mDNS *const m = &mDNSStorage;
mDNSBool ready = mDNSCoreReadyForSleep(m, now);
if (m->SleepState && !ready && now - m->SleepLimit < 0) return(mDNSfalse);
m->SleepState = SleepState_Sleeping;
// Clear our interface list to empty state, ready to go to sleep
// As a side effect of doing this, we'll also cancel any outstanding SPS Resolve calls that didn't complete
- mDNSMacOSXNetworkChanged(m);
+ mDNSMacOSXNetworkChanged();
}
LogSPS("AllowSleepNow: %s(%lX) %s at %ld (%d ticks remaining)",
m->SleepLimit = 0; // Don't clear m->SleepLimit until after we've logged it above
m->TimeSlept = mDNSPlatformUTC();
- // accumulate total time awake for this statistics gathering interval
- if (m->StatStartTime)
- {
- m->ActiveStatTime += (m->TimeSlept - m->StatStartTime);
-
- // indicate this value is invalid until reinitialzed on wakeup
- m->StatStartTime = 0;
- }
-
#if !TARGET_OS_EMBEDDED && defined(kIOPMAcknowledgmentOptionSystemCapabilityRequirements)
if (m->p->IOPMConnection) IOPMConnectionAcknowledgeEventWithOptions(m->p->IOPMConnection, m->p->SleepCookie, opts);
else
}
if (m->SleepLimit)
- if (!AllowSleepNow(m, now))
+ if (!AllowSleepNow(now))
if (nextTimerEvent - m->SleepLimit >= 0)
nextTimerEvent = m->SleepLimit;
#else // MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
-mDNSlocal void KQWokenFlushBytes(int fd, __unused short filter, __unused void *context)
+mDNSlocal void KQWokenFlushBytes(int fd, __unused short filter, __unused void *context, __unused mDNSBool encounteredEOF)
{
// Read all of the bytes so we won't wake again.
char buffer[100];
}
if (m->SleepLimit)
- if (!AllowSleepNow(m, now))
+ if (!AllowSleepNow(now))
if (nextTimerEvent - m->SleepLimit >= 0)
nextTimerEvent = m->SleepLimit;
{
if (events_found > kEventsToReadAtOnce || (events_found < 0 && errno != EINTR))
{
+ const int kevent_errno = errno;
// Not sure what to do here, our kqueue has failed us - this isn't ideal
- LogMsg("ERROR: KQueueLoop - kevent failed errno %d (%s)", errno, strerror(errno));
- exit(errno);
+ LogMsg("ERROR: KQueueLoop - kevent failed errno %d (%s)", kevent_errno, strerror(kevent_errno));
+ exit(kevent_errno);
}
numevents += events_found;
const KQueueEntry *const kqentry = new_events[i].udata;
mDNSs32 stime = mDNSPlatformRawTime();
const char *const KQtask = kqentry->KQtask; // Grab a copy in case KQcallback deletes the task
- kqentry->KQcallback(new_events[i].ident, new_events[i].filter, kqentry->KQcontext);
+ kqentry->KQcallback(new_events[i].ident, new_events[i].filter, kqentry->KQcontext, (new_events[i].flags & EV_EOF) != 0);
mDNSs32 etime = mDNSPlatformRawTime();
if (etime - stime >= WatchDogReportingThreshold)
LogInfo("WARNING: %s took %dms to complete", KQtask, etime - stime);
{
// Ask launchd for our socket
int result = launch_activate_socket("Listeners", &launchd_fds, &launchd_fds_count);
- if (result != 0) { LogMsg("launch_activate_socket() failed errno %d (%s)", errno, strerror(errno)); }
+ if (result != 0) { LogMsg("launch_activate_socket() failed error %d (%s)", result, strerror(result)); }
return launchd_fds_count;
}
}
#endif
-#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
-mDNSlocal mDNSBool initialize_networkserviceproxy(void)
-{
- void *NSPImage = dlopen("/System/Library/PrivateFrameworks/NetworkServiceProxy.framework/NetworkServiceProxy", RTLD_LAZY | RTLD_LOCAL);
- if (NSPImage == NULL) {
- os_log_error(OS_LOG_DEFAULT, "dlopen NetworkServiceProxy.framework failed");
- return mDNSfalse;
- }
- return mDNStrue;
-}
-#endif
-
+#ifdef UNIT_TEST
+// Run the unit test main
+UNITTEST_MAIN
+#else
mDNSexport int main(int argc, char **argv)
{
int i;
AlwaysAppendSearchDomains = PreferencesGetValueBool(kPreferencesKey_AlwaysAppendSearchDomains, AlwaysAppendSearchDomains);
OfferSleepProxyService = PreferencesGetValueInt(kPreferencesKey_OfferSleepProxyService, OfferSleepProxyService);
UseInternalSleepProxy = PreferencesGetValueInt(kPreferencesKey_UseInternalSleepProxy, UseInternalSleepProxy);
+
+#if ENABLE_BLE_TRIGGERED_BONJOUR
EnableBLEBasedDiscovery = PreferencesGetValueBool(kPreferencesKey_EnableBLEBasedDiscovery, EnableBLEBasedDiscovery);
+ DefaultToBLETriggered = PreferencesGetValueBool(kPreferencesKey_DefaultToBLETriggered, DefaultToBLETriggered);
+#endif // ENABLE_BLE_TRIGGERED_BONJOUR
+
+#if TARGET_OS_IPHONE
+ PreallocateCacheMemory = PreferencesGetValueBool(kPreferencesKey_PreallocateCacheMemory, PreallocateCacheMemory);
+#endif
#endif
// Note that mDNSPlatformInit will set DivertMulticastAdvertisements in the mDNS structure
// Create the kqueue, mutex and thread to support KQSockets
KQueueFD = kqueue();
- if (KQueueFD == -1) { LogMsg("kqueue() failed errno %d (%s)", errno, strerror(errno)); status = errno; goto exit; }
+ if (KQueueFD == -1)
+ {
+ const int kqueue_errno = errno;
+ LogMsg("kqueue() failed errno %d (%s)", kqueue_errno, strerror(kqueue_errno));
+ status = kqueue_errno;
+ goto exit;
+ }
i = pthread_mutex_init(&PlatformStorage.BigMutex, NULL);
- if (i == -1) { LogMsg("pthread_mutex_init() failed errno %d (%s)", errno, strerror(errno)); status = errno; goto exit; }
+ if (i != 0) { LogMsg("pthread_mutex_init() failed error %d (%s)", i, strerror(i)); status = i; goto exit; }
int fdpair[2] = {0, 0};
i = socketpair(AF_UNIX, SOCK_STREAM, 0, fdpair);
- if (i == -1) { LogMsg("socketpair() failed errno %d (%s)", errno, strerror(errno)); status = errno; goto exit; }
+ if (i == -1)
+ {
+ const int socketpair_errno = errno;
+ LogMsg("socketpair() failed errno %d (%s)", socketpair_errno, strerror(socketpair_errno));
+ status = socketpair_errno;
+ goto exit;
+ }
// Socket pair returned us two identical sockets connected to each other
// We will use the first socket to send the second socket. The second socket
#endif
SandboxProcess();
-#if TARGET_OS_EMBEDDED
+#if AWD_METRICS
status = MetricsInit();
if (status) { LogMsg("Daemon start: MetricsInit failed (%d)", status); }
#endif
status = udsserver_init(launchd_fds, launchd_fds_count);
if (status) { LogMsg("Daemon start: udsserver_init failed"); goto exit; }
- mDNSMacOSXNetworkChanged(&mDNSStorage);
+ mDNSMacOSXNetworkChanged();
UpdateDebugState();
-#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
- if (initialize_networkserviceproxy() == mDNSfalse) {
- LogMsg("Failed to initialize NetworkServiceProxy");
- }
-#endif
-
#ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
LogInfo("Daemon Start: Using LibDispatch");
// CFRunLoopRun runs both CFRunLoop sources and dispatch sources
// Start the kqueue thread
pthread_t KQueueThread;
i = pthread_create(&KQueueThread, NULL, KQueueLoop, &mDNSStorage);
- if (i == -1) { LogMsg("pthread_create() failed errno %d (%s)", errno, strerror(errno)); status = errno; goto exit; }
+ if (i != 0) { LogMsg("pthread_create() failed error %d (%s)", i, strerror(i)); status = i; goto exit; }
if (status == 0)
{
CFRunLoopRun();
exit:
return(status);
}
+#endif // UNIT_TEST
// uds_daemon.c support routines /////////////////////////////////////////////
+mDNSlocal void kqUDSEventCallback(int fd, short filter, void *context, __unused mDNSBool encounteredEOF)
+{
+ const KQSocketEventSource *const source = context;
+ source->callback(fd, filter, source->context);
+}
+
// Arrange things so that when data appears on fd, callback is called with context
mDNSexport mStatus udsSupportAddFDToEventLoop(int fd, udsEventCallback callback, void *context, void **platform_data)
{
newSource->next = mDNSNULL;
newSource->fd = fd;
- newSource->kqs.KQcallback = callback;
- newSource->kqs.KQcontext = context;
+ newSource->callback = callback;
+ newSource->context = context;
+ newSource->kqs.KQcallback = kqUDSEventCallback;
+ newSource->kqs.KQcontext = newSource;
newSource->kqs.KQtask = "UDS client";
#ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
newSource->kqs.readSource = mDNSNULL;
return mStatus_NoSuchNameErr;
}
+#ifdef UNIT_TEST
+#include "../unittests/daemon_ut.c"
+#endif // UNIT_TEST
+
#if _BUILDING_XCODE_PROJECT_
// If mDNSResponder crashes, then this string will be magically included in the automatically-generated crash log
const char *__crashreporter_info__ = mDNSResponderVersionString;